diff --git a/resources/text/CHANGELOG b/resources/text/CHANGELOG index f9e62269e..1d16caf2e 100755 --- a/resources/text/CHANGELOG +++ b/resources/text/CHANGELOG @@ -12,6 +12,7 @@ Changed: Fixed: +▪ Expand status if items in feed list are now persistent when performing sync-in of TT-RSS accounts. (bug #149) ▪ Fixed problem with importing invalid OPML 2.0 files. (bug #145) ▪ Fixed error in SQL initialization script which led to problems with in-memory SQLite DBs. (bug #140) ▪ Fixed problem with saving sort column/order for message list. (bug #141) diff --git a/src/core/feedsmodel.cpp b/src/core/feedsmodel.cpp index e888831ce..4e383ae22 100755 --- a/src/core/feedsmodel.cpp +++ b/src/core/feedsmodel.cpp @@ -691,6 +691,7 @@ bool FeedsModel::addServiceAccount(ServiceRoot *root, bool freshly_activated) { connect(root, SIGNAL(dataChanged(QList)), this, SLOT(onItemDataChanged(QList))); connect(root, SIGNAL(reloadMessageListRequested(bool)), this, SIGNAL(reloadMessageListRequested(bool))); connect(root, SIGNAL(itemExpandRequested(QList,bool)), this, SIGNAL(itemExpandRequested(QList,bool))); + connect(root, SIGNAL(itemExpandStateSaveRequested(RootItem*)), this, SIGNAL(itemExpandStateSaveRequested(RootItem*))); root->start(freshly_activated); return true; diff --git a/src/core/feedsmodel.h b/src/core/feedsmodel.h index 605c92db6..55ef846d9 100755 --- a/src/core/feedsmodel.h +++ b/src/core/feedsmodel.h @@ -212,6 +212,10 @@ class FeedsModel : public QAbstractItemModel { // Emitted if any item requested that any view should expand it. void itemExpandRequested(QList items, bool expand); + // Emitted if any item requested that its expand states should be explicitly saved. + // NOTE: Normally expand states are saved when application quits. + void itemExpandStateSaveRequested(RootItem *subtree_root); + // Emitted when there is a need of reloading of displayed messages. void reloadMessageListRequested(bool mark_selected_messages_read); diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp index 88a4b383b..2ca41b107 100755 --- a/src/gui/feedmessageviewer.cpp +++ b/src/gui/feedmessageviewer.cpp @@ -78,7 +78,7 @@ FeedMessageViewer::~FeedMessageViewer() { void FeedMessageViewer::saveSize() { Settings *settings = qApp->settings(); - m_feedsView->saveExpandedStates(); + m_feedsView->saveAllExpandStates(); // Store offsets of splitters. settings->setValue(GROUP(GUI), GUI::SplitterFeeds, QString(m_feedSplitter->saveState().toBase64())); diff --git a/src/gui/feedsview.cpp b/src/gui/feedsview.cpp index 6fd138292..ee99f148d 100755 --- a/src/gui/feedsview.cpp +++ b/src/gui/feedsview.cpp @@ -57,6 +57,7 @@ FeedsView::FeedsView(QWidget *parent) // Connections. connect(m_sourceModel, SIGNAL(requireItemValidationAfterDragDrop(QModelIndex)), this, SLOT(validateItemAfterDragDrop(QModelIndex))); connect(m_sourceModel, SIGNAL(itemExpandRequested(QList,bool)), this, SLOT(onItemExpandRequested(QList,bool))); + connect(m_sourceModel, SIGNAL(itemExpandStateSaveRequested(RootItem*)), this, SLOT(onItemExpandStateSaveRequested(RootItem*))); connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(saveSortState(int,Qt::SortOrder))); setModel(m_proxyModel); @@ -100,23 +101,29 @@ RootItem *FeedsView::selectedItem() const { } } -void FeedsView::saveExpandedStates() { - Settings *settings = qApp->settings(); - QList expandable_items; +void FeedsView::onItemExpandStateSaveRequested(RootItem *item) { + saveExpandStates(item); +} - expandable_items.append(sourceModel()->rootItem()->getSubTree(RootItemKind::Category | RootItemKind::ServiceRoot)); +void FeedsView::saveAllExpandStates() { + saveExpandStates(sourceModel()->rootItem()); +} + +void FeedsView::saveExpandStates(RootItem *item) { + Settings *settings = qApp->settings(); + QList items = item->getSubTree(RootItemKind::Category | RootItemKind::ServiceRoot); // Iterate all categories and save their expand statuses. - foreach (RootItem *item, expandable_items) { - QString setting_name = item->hashCode(); + foreach (RootItem *item, items) { + const QString setting_name = item->hashCode(); - settings->setValue(GROUP(Categories), + settings->setValue(GROUP(CategoriesExpandStates), setting_name, isExpanded(model()->mapFromSource(sourceModel()->indexForItem(item)))); } } -void FeedsView::loadExpandedStates() { +void FeedsView::loadAllExpandStates() { Settings *settings = qApp->settings(); QList expandable_items; @@ -124,10 +131,10 @@ void FeedsView::loadExpandedStates() { // Iterate all categories and save their expand statuses. foreach (RootItem *item, expandable_items) { - QString setting_name = item->hashCode(); + const QString setting_name = item->hashCode(); setExpanded(model()->mapFromSource(sourceModel()->indexForItem(item)), - settings->value(GROUP(Categories), setting_name, item->childCount() > 0).toBool()); + settings->value(GROUP(CategoriesExpandStates), setting_name, item->childCount() > 0).toBool()); } sortByColumn(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortColumnFeeds)).toInt(), diff --git a/src/gui/feedsview.h b/src/gui/feedsview.h index 3282ba402..7b93763ea 100755 --- a/src/gui/feedsview.h +++ b/src/gui/feedsview.h @@ -58,8 +58,8 @@ class FeedsView : public QTreeView { RootItem *selectedItem() const; // Saves/loads expand states of all nodes (feeds/categories) of the list to/from settings. - void saveExpandedStates(); - void loadExpandedStates(); + void saveAllExpandStates(); + void loadAllExpandStates(); public slots: void addFeedIntoSelectedAccount(); @@ -107,6 +107,7 @@ class FeedsView : public QTreeView { void saveSortState(int column, Qt::SortOrder order); void validateItemAfterDragDrop(const QModelIndex &source_index); void onItemExpandRequested(const QList &items, bool exp); + void onItemExpandStateSaveRequested(RootItem *item); private: // Initializes context menus. @@ -118,6 +119,8 @@ class FeedsView : public QTreeView { // Sets up appearance of this widget. void setupAppearance(); + void saveExpandStates(RootItem *item); + // Handle selections. void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); diff --git a/src/main.cpp b/src/main.cpp index b1b6a29dc..0651433c0 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -119,7 +119,7 @@ int main(int argc, char *argv[]) { // Load activated accounts. qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->sourceModel()->loadActivatedServiceAccounts(); - qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->loadExpandedStates(); + qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->loadAllExpandStates(); // Setup single-instance behavior. QObject::connect(&application, SIGNAL(messageReceived(QString)), &application, SLOT(processExecutionMessage(QString))); diff --git a/src/miscellaneous/settings.cpp b/src/miscellaneous/settings.cpp index 61d21a338..0ecbb3839 100755 --- a/src/miscellaneous/settings.cpp +++ b/src/miscellaneous/settings.cpp @@ -290,7 +290,7 @@ DKEY Browser::QueueTabs = "queue_tabs"; DVALUE(bool) Browser::QueueTabsDef = true; // Categories. -DKEY Categories::ID = "categories_expand_states"; +DKEY CategoriesExpandStates::ID = "categories_expand_states"; Settings::Settings(const QString &file_name, Format format, const SettingsProperties::SettingsType &status, QObject *parent) : QSettings(file_name, format, parent), m_initializationStatus(status) { diff --git a/src/miscellaneous/settings.h b/src/miscellaneous/settings.h index 4a1f89a12..89e8a142b 100755 --- a/src/miscellaneous/settings.h +++ b/src/miscellaneous/settings.h @@ -322,7 +322,7 @@ namespace Browser { } // Categories. -namespace Categories { +namespace CategoriesExpandStates { KEY ID; } diff --git a/src/services/abstract/rootitem.cpp b/src/services/abstract/rootitem.cpp index 4f5e5749f..cc9c20097 100755 --- a/src/services/abstract/rootitem.cpp +++ b/src/services/abstract/rootitem.cpp @@ -44,10 +44,7 @@ RootItem::~RootItem() { } QString RootItem::hashCode() const { - return - QString::number(kind()) + QL1S("-") + - QString::number(qHash(title())) + QL1S("-") + - QString::number(id()); + return QString::number(kind()) + QL1S("-") + QString::number(id()); } QList RootItem::contextMenu() { diff --git a/src/services/abstract/serviceroot.cpp b/src/services/abstract/serviceroot.cpp index 1f229a9f0..d3f2d1019 100755 --- a/src/services/abstract/serviceroot.cpp +++ b/src/services/abstract/serviceroot.cpp @@ -122,10 +122,14 @@ void ServiceRoot::requestFeedReadFilterReload() { emit readFeedsFilterInvalidationRequested(); } -void ServiceRoot::requestItemExpand(const QList &items, bool expand) { +void ServiceRoot::requestItemExpand(const QList &items, bool expand) { emit itemExpandRequested(items, expand); } +void ServiceRoot::requestItemExpandStateSave(RootItem *subtree_root) { + emit itemExpandStateSaveRequested(subtree_root); +} + void ServiceRoot::requestItemReassignment(RootItem *item, RootItem *new_parent) { emit itemReassignmentRequested(item, new_parent); } diff --git a/src/services/abstract/serviceroot.h b/src/services/abstract/serviceroot.h index 0ea17a016..ff6f85c89 100755 --- a/src/services/abstract/serviceroot.h +++ b/src/services/abstract/serviceroot.h @@ -152,6 +152,7 @@ class ServiceRoot : public RootItem { void requestReloadMessageList(bool mark_selected_messages_read); void requestFeedReadFilterReload(); void requestItemExpand(const QList &items, bool expand); + void requestItemExpandStateSave(RootItem *subtree_root); void requestItemReassignment(RootItem *item, RootItem *new_parent); void requestItemRemoval(RootItem *item); @@ -174,6 +175,7 @@ class ServiceRoot : public RootItem { void readFeedsFilterInvalidationRequested(); void reloadMessageListRequested(bool mark_selected_messages_read); void itemExpandRequested(QList items, bool expand); + void itemExpandStateSaveRequested(RootItem *subtree_root); void itemReassignmentRequested(RootItem *item, RootItem *new_parent); void itemRemovalRequested(RootItem *item); diff --git a/src/services/standard/standardserviceentrypoint.cpp b/src/services/standard/standardserviceentrypoint.cpp index 7a9485013..527186891 100755 --- a/src/services/standard/standardserviceentrypoint.cpp +++ b/src/services/standard/standardserviceentrypoint.cpp @@ -77,6 +77,7 @@ ServiceRoot *StandardServiceEntryPoint::createNewRoot() { if (query.exec()) { StandardServiceRoot *root = new StandardServiceRoot(); + root->setId(id_to_assign); root->setAccountId(id_to_assign); return root; } @@ -98,6 +99,7 @@ QList StandardServiceEntryPoint::initializeSubtree() const { if (query.exec()) { while (query.next()) { StandardServiceRoot *root = new StandardServiceRoot(); + root->setId(query.value(0).toInt()); root->setAccountId(query.value(0).toInt()); roots.append(root); } diff --git a/src/services/tt-rss/ttrsscategory.cpp b/src/services/tt-rss/ttrsscategory.cpp index 506181f55..4f3ed91b1 100755 --- a/src/services/tt-rss/ttrsscategory.cpp +++ b/src/services/tt-rss/ttrsscategory.cpp @@ -41,6 +41,13 @@ TtRssCategory::TtRssCategory(const QSqlRecord &record) : Category(NULL) { TtRssCategory::~TtRssCategory() { } +QString TtRssCategory::hashCode() const { + return + QString::number(kind()) + QL1S("-") + + QString::number(const_cast(this)->getParentServiceRoot()->accountId()) + QL1S("-") + + QString::number(customId()); +} + TtRssServiceRoot *TtRssCategory::serviceRoot() { return qobject_cast(getParentServiceRoot()); } diff --git a/src/services/tt-rss/ttrsscategory.h b/src/services/tt-rss/ttrsscategory.h index 1fcd9ccf5..7b40cdd04 100755 --- a/src/services/tt-rss/ttrsscategory.h +++ b/src/services/tt-rss/ttrsscategory.h @@ -33,6 +33,8 @@ class TtRssCategory : public Category { explicit TtRssCategory(const QSqlRecord &record); virtual ~TtRssCategory(); + QString hashCode() const; + TtRssServiceRoot *serviceRoot(); bool markAsReadUnread(ReadStatus status); diff --git a/src/services/tt-rss/ttrssfeed.cpp b/src/services/tt-rss/ttrssfeed.cpp index c131320b2..0933f0020 100755 --- a/src/services/tt-rss/ttrssfeed.cpp +++ b/src/services/tt-rss/ttrssfeed.cpp @@ -50,6 +50,13 @@ TtRssFeed::TtRssFeed(const QSqlRecord &record) : Feed(NULL), m_totalCount(0), m_ TtRssFeed::~TtRssFeed() { } +QString TtRssFeed::hashCode() const { + return + QString::number(kind()) + QL1S("-") + + QString::number(const_cast(this)->getParentServiceRoot()->accountId()) + QL1S("-") + + QString::number(customId()); +} + TtRssServiceRoot *TtRssFeed::serviceRoot() { return qobject_cast(getParentServiceRoot()); } diff --git a/src/services/tt-rss/ttrssfeed.h b/src/services/tt-rss/ttrssfeed.h index 83a16eeb5..53e635d09 100755 --- a/src/services/tt-rss/ttrssfeed.h +++ b/src/services/tt-rss/ttrssfeed.h @@ -33,6 +33,8 @@ class TtRssFeed : public Feed { explicit TtRssFeed(const QSqlRecord &record); virtual ~TtRssFeed(); + QString hashCode() const; + TtRssServiceRoot *serviceRoot(); QVariant data(int column, int role) const; diff --git a/src/services/tt-rss/ttrssserviceroot.cpp b/src/services/tt-rss/ttrssserviceroot.cpp index 0524f8cf7..17bde213c 100755 --- a/src/services/tt-rss/ttrssserviceroot.cpp +++ b/src/services/tt-rss/ttrssserviceroot.cpp @@ -581,6 +581,7 @@ void TtRssServiceRoot::syncIn() { RootItem *new_tree = feed_cats_response.feedsCategories(true, m_network->url()); // Purge old data from SQL and clean all model items. + requestItemExpandStateSave(this); removeOldFeedTree(false); cleanAllItems(); @@ -602,7 +603,17 @@ void TtRssServiceRoot::syncIn() { itemChanged(all_items); requestReloadMessageList(true); - requestItemExpand(all_items, true); + + // Now we must refresh expand states. + QList items_to_expand; + + foreach (RootItem *item, all_items) { + if (qApp->settings()->value(GROUP(CategoriesExpandStates), item->hashCode(), item->childCount() > 0).toBool()) { + items_to_expand.append(item); + } + } + + requestItemExpand(items_to_expand, true); } setIcon(original_icon);