items are now sortable with drag/drop
This commit is contained in:
		
							parent
							
								
									3d93a40284
								
							
						
					
					
						commit
						f63af3a051
					
				
					 5 changed files with 249 additions and 225 deletions
				
			
		|  | @ -22,8 +22,6 @@ | |||
| #include <QStack> | ||||
| #include <QTimer> | ||||
| 
 | ||||
| using RootItemPtr = RootItem*; | ||||
| 
 | ||||
| FeedsModel::FeedsModel(QObject* parent) : QAbstractItemModel(parent), m_rootItem(new RootItem()) { | ||||
|   setObjectName(QSL("FeedsModel")); | ||||
| 
 | ||||
|  | @ -75,69 +73,6 @@ QStringList FeedsModel::mimeTypes() const { | |||
|   return QStringList() << QSL(MIME_TYPE_ITEM_POINTER); | ||||
| } | ||||
| 
 | ||||
| bool FeedsModel::dropMimeData(const QMimeData* data, | ||||
|                               Qt::DropAction action, | ||||
|                               int row, | ||||
|                               int column, | ||||
|                               const QModelIndex& parent) { | ||||
|   Q_UNUSED(row) | ||||
|   Q_UNUSED(column) | ||||
| 
 | ||||
|   if (action == Qt::DropAction::IgnoreAction) { | ||||
|     return true; | ||||
|   } | ||||
|   else if (action != Qt::DropAction::MoveAction) { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   QByteArray dragged_items_data = data->data(QSL(MIME_TYPE_ITEM_POINTER)); | ||||
| 
 | ||||
|   if (dragged_items_data.isEmpty()) { | ||||
|     return false; | ||||
|   } | ||||
|   else { | ||||
|     QDataStream stream(&dragged_items_data, QIODevice::OpenModeFlag::ReadOnly); | ||||
| 
 | ||||
|     while (!stream.atEnd()) { | ||||
|       quintptr pointer_to_item; | ||||
|       stream >> pointer_to_item; | ||||
| 
 | ||||
|       // We have item we want to drag, we also determine the target item.
 | ||||
|       auto* dragged_item = RootItemPtr(pointer_to_item); | ||||
|       RootItem* target_item = itemForIndex(parent); | ||||
|       ServiceRoot* dragged_item_root = dragged_item->getParentServiceRoot(); | ||||
|       ServiceRoot* target_item_root = target_item->getParentServiceRoot(); | ||||
| 
 | ||||
|       if (dragged_item == target_item || dragged_item->parent() == target_item) { | ||||
|         qDebug("Dragged item is equal to target item or its parent is equal to target item. Cancelling drag-drop " | ||||
|                "action."); | ||||
|         return false; | ||||
|       } | ||||
| 
 | ||||
|       if (dragged_item_root != target_item_root) { | ||||
|         // Transferring of items between different accounts is not possible.
 | ||||
|         qApp->showGuiMessage(Notification::Event::GeneralEvent, | ||||
|                              {tr("Cannot perform drag & drop operation"), | ||||
|                               tr("You can't transfer dragged item into different account, this is not supported."), | ||||
|                               QSystemTrayIcon::MessageIcon::Critical}); | ||||
|         qDebugNN << LOGSEC_FEEDMODEL | ||||
|                  << "Dragged item cannot be dragged into different account. Cancelling drag-drop action."; | ||||
|         return false; | ||||
|       } | ||||
| 
 | ||||
|       if (dragged_item->performDragDropChange(target_item)) { | ||||
|         // Drag & drop is supported by the dragged item and was
 | ||||
|         // completed on data level and in item hierarchy.
 | ||||
|         emit requireItemValidationAfterDragDrop(indexForItem(dragged_item)); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| Qt::DropActions FeedsModel::supportedDropActions() const { | ||||
|   return Qt::DropAction::MoveAction; | ||||
| } | ||||
|  | @ -368,7 +303,6 @@ RootItem* FeedsModel::itemForIndex(const QModelIndex& index) const { | |||
| 
 | ||||
| QModelIndex FeedsModel::indexForItem(const RootItem* item) const { | ||||
|   if (item == nullptr || item->kind() == RootItem::Kind::Root) { | ||||
| 
 | ||||
|     // Root item lies on invalid index.
 | ||||
|     return QModelIndex(); | ||||
|   } | ||||
|  | @ -598,6 +532,5 @@ QVariant FeedsModel::data(const QModelIndex& index, int role) const { | |||
| 
 | ||||
|     default: | ||||
|       return itemForIndex(index)->data(index.column(), role); | ||||
|       ; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -14,29 +14,27 @@ class ServiceEntryPoint; | |||
| class StandardServiceRoot; | ||||
| 
 | ||||
| class RSSGUARD_DLLSPEC FeedsModel : public QAbstractItemModel { | ||||
|   Q_OBJECT | ||||
|     Q_OBJECT | ||||
| 
 | ||||
|   public: | ||||
|     explicit FeedsModel(QObject* parent = nullptr); | ||||
|     virtual ~FeedsModel(); | ||||
| 
 | ||||
|     // Model implementation.
 | ||||
|     QVariant data(const QModelIndex& index, int role) const; | ||||
|     virtual QVariant data(const QModelIndex& index, int role) const; | ||||
| 
 | ||||
|     // Drag & drop.
 | ||||
|     QMimeData* mimeData(const QModelIndexList& indexes) const; | ||||
| 
 | ||||
|     QStringList mimeTypes() const; | ||||
|     bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent); | ||||
|     Qt::DropActions supportedDropActions() const; | ||||
|     Qt::ItemFlags flags(const QModelIndex& index) const; | ||||
|     virtual QMimeData* mimeData(const QModelIndexList& indexes) const; | ||||
|     virtual QStringList mimeTypes() const; | ||||
|     virtual Qt::DropActions supportedDropActions() const; | ||||
|     virtual Qt::ItemFlags flags(const QModelIndex& index) const; | ||||
| 
 | ||||
|     // Other subclassed methods.
 | ||||
|     QVariant headerData(int section, Qt::Orientation orientation, int role) const; | ||||
|     QModelIndex index(int row, int column, const QModelIndex& parent) const; | ||||
|     QModelIndex parent(const QModelIndex& child) const; | ||||
|     int columnCount(const QModelIndex& parent) const; | ||||
|     int rowCount(const QModelIndex& parent) const; | ||||
|     virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; | ||||
|     virtual QModelIndex index(int row, int column, const QModelIndex& parent) const; | ||||
|     virtual QModelIndex parent(const QModelIndex& child) const; | ||||
|     virtual int columnCount(const QModelIndex& parent) const; | ||||
|     virtual int rowCount(const QModelIndex& parent) const; | ||||
| 
 | ||||
|     // Returns counts of ALL/UNREAD (non-deleted) messages for the model.
 | ||||
|     int countOfAllMessages() const; | ||||
|  | @ -136,7 +134,7 @@ class RSSGUARD_DLLSPEC FeedsModel : public QAbstractItemModel { | |||
|     void messageCountsChanged(int unread_messages, bool any_feed_has_unread_messages); | ||||
| 
 | ||||
|     // Emitted if any item requested that any view should expand it.
 | ||||
|     void itemExpandRequested(QList<RootItem*>items, bool expand); | ||||
|     void itemExpandRequested(QList<RootItem*> 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.
 | ||||
|  | @ -145,9 +143,6 @@ class RSSGUARD_DLLSPEC FeedsModel : public QAbstractItemModel { | |||
|     // Emitted when there is a need of reloading of displayed messages.
 | ||||
|     void reloadMessageListRequested(bool mark_selected_messages_read); | ||||
| 
 | ||||
|     // There was some drag/drop operation, notify view about this.
 | ||||
|     void requireItemValidationAfterDragDrop(const QModelIndex& source_index); | ||||
| 
 | ||||
|   private: | ||||
|     RootItem* m_rootItem; | ||||
|     QList<QString> m_headerData; | ||||
|  |  | |||
|  | @ -3,17 +3,21 @@ | |||
| #include "core/feedsproxymodel.h" | ||||
| 
 | ||||
| #include "core/feedsmodel.h" | ||||
| #include "database/databasequeries.h" | ||||
| #include "definitions/definitions.h" | ||||
| #include "gui/feedsview.h" | ||||
| #include "miscellaneous/application.h" | ||||
| #include "miscellaneous/regexfactory.h" | ||||
| #include "services/abstract/rootitem.h" | ||||
| 
 | ||||
| #include <QMimeData> | ||||
| #include <QTimer> | ||||
| 
 | ||||
| using RootItemPtr = RootItem*; | ||||
| 
 | ||||
| FeedsProxyModel::FeedsProxyModel(FeedsModel* source_model, QObject* parent) | ||||
|   : QSortFilterProxyModel(parent), m_sourceModel(source_model), m_view(nullptr), | ||||
|   m_selectedItem(nullptr), m_showUnreadOnly(false), m_sortAlphabetically(true) { | ||||
|   : QSortFilterProxyModel(parent), m_sourceModel(source_model), m_view(nullptr), m_selectedItem(nullptr), | ||||
|     m_showUnreadOnly(false), m_sortAlphabetically(true) { | ||||
|   setObjectName(QSL("FeedsProxyModel")); | ||||
| 
 | ||||
|   setSortRole(Qt::ItemDataRole::EditRole); | ||||
|  | @ -28,26 +32,28 @@ FeedsProxyModel::FeedsProxyModel(FeedsModel* source_model, QObject* parent) | |||
|   // Smaller index means that item is "smaller" which
 | ||||
|   // means it should be more on top when sorting
 | ||||
|   // in ascending order.
 | ||||
|   m_priorities = { | ||||
|     RootItem::Kind::Category, | ||||
|     RootItem::Kind::Feed, | ||||
|     RootItem::Kind::Labels, | ||||
|     RootItem::Kind::Important, | ||||
|     RootItem::Kind::Unread, | ||||
|     RootItem::Kind::Bin | ||||
|   }; | ||||
|   m_priorities = {RootItem::Kind::Category, | ||||
|                   RootItem::Kind::Feed, | ||||
|                   RootItem::Kind::Labels, | ||||
|                   RootItem::Kind::Important, | ||||
|                   RootItem::Kind::Unread, | ||||
|                   RootItem::Kind::Bin}; | ||||
| } | ||||
| 
 | ||||
| FeedsProxyModel::~FeedsProxyModel() { | ||||
|   qDebugNN << LOGSEC_FEEDMODEL << "Destroying FeedsProxyModel instance"; | ||||
| } | ||||
| 
 | ||||
| QModelIndexList FeedsProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const { | ||||
| QModelIndexList FeedsProxyModel::match(const QModelIndex& start, | ||||
|                                        int role, | ||||
|                                        const QVariant& value, | ||||
|                                        int hits, | ||||
|                                        Qt::MatchFlags flags) const { | ||||
|   QModelIndexList result; | ||||
|   const int match_type = flags & 0x0F; | ||||
|   const Qt::CaseSensitivity cs = Qt::CaseSensitivity::CaseInsensitive; | ||||
|   const bool recurse = (flags& Qt::MatchFlag::MatchRecursive) > 0; | ||||
|   const bool wrap = (flags& Qt::MatchFlag::MatchWrap) > 0; | ||||
|   const bool recurse = (flags & Qt::MatchFlag::MatchRecursive) > 0; | ||||
|   const bool wrap = (flags & Qt::MatchFlag::MatchWrap) > 0; | ||||
|   const bool all_hits = (hits == -1); | ||||
|   QString entered_text; | ||||
|   const QModelIndex p = parent(start); | ||||
|  | @ -88,7 +94,9 @@ QModelIndexList FeedsProxyModel::match(const QModelIndex& start, int role, const | |||
| #endif | ||||
|             if (QRegularExpression(entered_text, | ||||
|                                    QRegularExpression::PatternOption::CaseInsensitiveOption | | ||||
|                                    QRegularExpression::PatternOption::UseUnicodePropertiesOption).match(item_text).hasMatch()) { | ||||
|                                      QRegularExpression::PatternOption::UseUnicodePropertiesOption) | ||||
|                   .match(item_text) | ||||
|                   .hasMatch()) { | ||||
|               result.append(idx); | ||||
|             } | ||||
| 
 | ||||
|  | @ -97,7 +105,9 @@ QModelIndexList FeedsProxyModel::match(const QModelIndex& start, int role, const | |||
|           case Qt::MatchFlag::MatchWildcard: | ||||
|             if (QRegularExpression(RegexFactory::wildcardToRegularExpression(entered_text), | ||||
|                                    QRegularExpression::PatternOption::CaseInsensitiveOption | | ||||
|                                    QRegularExpression::PatternOption::UseUnicodePropertiesOption).match(item_text).hasMatch()) { | ||||
|                                      QRegularExpression::PatternOption::UseUnicodePropertiesOption) | ||||
|                   .match(item_text) | ||||
|                   .hasMatch()) { | ||||
|               result.append(idx); | ||||
|             } | ||||
| 
 | ||||
|  | @ -135,9 +145,11 @@ QModelIndexList FeedsProxyModel::match(const QModelIndex& start, int role, const | |||
|       } | ||||
| 
 | ||||
|       if (recurse && hasChildren(idx)) { | ||||
|         result += | ||||
|           match(index(0, idx.column(), idx), role, (entered_text.isEmpty() ? value : entered_text), | ||||
|                 (all_hits ? -1 : hits - result.count()), flags); | ||||
|         result += match(index(0, idx.column(), idx), | ||||
|                         role, | ||||
|                         (entered_text.isEmpty() ? value : entered_text), | ||||
|                         (all_hits ? -1 : hits - result.count()), | ||||
|                         flags); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  | @ -148,6 +160,84 @@ QModelIndexList FeedsProxyModel::match(const QModelIndex& start, int role, const | |||
|   return result; | ||||
| } | ||||
| 
 | ||||
| bool FeedsProxyModel::dropMimeData(const QMimeData* data, | ||||
|                                    Qt::DropAction action, | ||||
|                                    int row, | ||||
|                                    int column, | ||||
|                                    const QModelIndex& parent) { | ||||
|   Q_UNUSED(column) | ||||
| 
 | ||||
|   if (action == Qt::DropAction::IgnoreAction) { | ||||
|     return true; | ||||
|   } | ||||
|   else if (action != Qt::DropAction::MoveAction) { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|   QByteArray dragged_items_data = data->data(QSL(MIME_TYPE_ITEM_POINTER)); | ||||
| 
 | ||||
|   if (dragged_items_data.isEmpty()) { | ||||
|     return false; | ||||
|   } | ||||
|   else { | ||||
|     QDataStream stream(&dragged_items_data, QIODevice::OpenModeFlag::ReadOnly); | ||||
|     const bool order_change = row >= 0 && !m_sortAlphabetically; | ||||
|     const QModelIndex source_parent = mapToSource(parent); | ||||
| 
 | ||||
|     while (!stream.atEnd()) { | ||||
|       quintptr pointer_to_item; | ||||
|       stream >> pointer_to_item; | ||||
| 
 | ||||
|       // We have item we want to drag, we also determine the target item.
 | ||||
|       auto* dragged_item = RootItemPtr(pointer_to_item); | ||||
|       RootItem* target_item = m_sourceModel->itemForIndex(source_parent); | ||||
|       ServiceRoot* dragged_item_root = dragged_item->getParentServiceRoot(); | ||||
|       ServiceRoot* target_item_root = target_item->getParentServiceRoot(); | ||||
| 
 | ||||
|       if ((dragged_item == target_item || dragged_item->parent() == target_item) && !order_change) { | ||||
|         qDebugNN << LOGSEC_FEEDMODEL | ||||
|                  << "Dragged item is equal to target item or its parent is equal to target item. Cancelling drag-drop " | ||||
|                     "action."; | ||||
|         return false; | ||||
|       } | ||||
| 
 | ||||
|       if (dragged_item_root != target_item_root) { | ||||
|         // Transferring of items between different accounts is not possible.
 | ||||
|         qApp->showGuiMessage(Notification::Event::GeneralEvent, | ||||
|                              {tr("Cannot perform drag & drop operation"), | ||||
|                               tr("You can't transfer dragged item into different account, this is not supported."), | ||||
|                               QSystemTrayIcon::MessageIcon::Critical}); | ||||
|         qDebugNN << LOGSEC_FEEDMODEL | ||||
|                  << "Dragged item cannot be dragged into different account. Cancelling drag-drop action."; | ||||
|         return false; | ||||
|       } | ||||
| 
 | ||||
|       if (dragged_item != target_item && dragged_item->parent() != target_item && | ||||
|           dragged_item->performDragDropChange(target_item)) { | ||||
|         // Drag & drop is supported by the dragged item and was
 | ||||
|         // completed on data level and in item hierarchy.
 | ||||
|         emit requireItemValidationAfterDragDrop(m_sourceModel->indexForItem(dragged_item)); | ||||
|       } | ||||
| 
 | ||||
|       if (order_change) { | ||||
|         auto db = qApp->database()->driver()->connection(metaObject()->className()); | ||||
| 
 | ||||
|         if (row > dragged_item->sortOrder()) { | ||||
|           row--; | ||||
|         } | ||||
| 
 | ||||
|         DatabaseQueries::moveItem(dragged_item, false, false, row, db); | ||||
|       } | ||||
| 
 | ||||
|       invalidate(); | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| bool FeedsProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const { | ||||
|   if (left.isValid() && right.isValid()) { | ||||
|     // Make necessary castings.
 | ||||
|  | @ -183,14 +273,13 @@ bool FeedsProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right | |||
|           case RootItem::Kind::Feed: | ||||
|           case RootItem::Kind::Category: | ||||
|           case RootItem::Kind::ServiceRoot: | ||||
|             return sortOrder() == Qt::SortOrder::AscendingOrder | ||||
|                 ? left_item->sortOrder() < right_item->sortOrder() | ||||
|                 : left_item->sortOrder() > right_item->sortOrder(); | ||||
|             return sortOrder() == Qt::SortOrder::AscendingOrder ? left_item->sortOrder() < right_item->sortOrder() | ||||
|                                                                 : left_item->sortOrder() > right_item->sortOrder(); | ||||
| 
 | ||||
|           default: | ||||
|             return sortOrder() == Qt::SortOrder::AscendingOrder | ||||
|                 ? QString::localeAwareCompare(left_item->title().toLower(), right_item->title().toLower()) < 0 | ||||
|                 : QString::localeAwareCompare(left_item->title().toLower(), right_item->title().toLower()) > 0; | ||||
|                      ? QString::localeAwareCompare(left_item->title().toLower(), right_item->title().toLower()) < 0 | ||||
|                      : QString::localeAwareCompare(left_item->title().toLower(), right_item->title().toLower()) > 0; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | @ -199,9 +288,8 @@ bool FeedsProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right | |||
|       auto left_priority = m_priorities.indexOf(left_item->kind()); | ||||
|       auto right_priority = m_priorities.indexOf(right_item->kind()); | ||||
| 
 | ||||
|       return sortOrder() == Qt::SortOrder::AscendingOrder | ||||
|           ? left_priority < right_priority | ||||
|           : right_priority < left_priority; | ||||
|       return sortOrder() == Qt::SortOrder::AscendingOrder ? left_priority < right_priority | ||||
|                                                           : right_priority < left_priority; | ||||
|     } | ||||
|   } | ||||
|   else { | ||||
|  | @ -212,11 +300,9 @@ bool FeedsProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right | |||
| bool FeedsProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { | ||||
|   bool should_show = filterAcceptsRowInternal(source_row, source_parent); | ||||
| 
 | ||||
|   qDebugNN << LOGSEC_CORE | ||||
|            << "Filter accepts row" | ||||
|   qDebugNN << LOGSEC_CORE << "Filter accepts row" | ||||
|            << QUOTE_W_SPACE(m_sourceModel->itemForIndex(m_sourceModel->index(source_row, 0, source_parent))->title()) | ||||
|            << "and filter result is:" | ||||
|            << QUOTE_W_SPACE_DOT(should_show); | ||||
|            << "and filter result is:" << QUOTE_W_SPACE_DOT(should_show); | ||||
| 
 | ||||
|   /*
 | ||||
|      if (should_show && (!filterRegularExpression().pattern().isEmpty() || | ||||
|  | @ -251,8 +337,7 @@ bool FeedsProxyModel::filterAcceptsRowInternal(int source_row, const QModelIndex | |||
| 
 | ||||
|   const RootItem* item = m_sourceModel->itemForIndex(idx); | ||||
| 
 | ||||
|   if (item->kind() != RootItem::Kind::Category && | ||||
|       item->kind() != RootItem::Kind::Feed && | ||||
|   if (item->kind() != RootItem::Kind::Category && item->kind() != RootItem::Kind::Feed && | ||||
|       item->kind() != RootItem::Kind::Label) { | ||||
|     // Some items are always visible.
 | ||||
|     return true; | ||||
|  | @ -271,12 +356,15 @@ bool FeedsProxyModel::filterAcceptsRowInternal(int source_row, const QModelIndex | |||
|     // particularly manifests itself if user uses "next unread item" action and
 | ||||
|     // "show unread only" is enabled too and user for example selects last unread
 | ||||
|     // article in a feed -> then the feed would disappear from list suddenly.
 | ||||
|     return | ||||
|       m_selectedItem == item || (item->countOfUnreadMessages() != 0 && | ||||
|                                  QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent)); | ||||
|     return m_selectedItem == item || | ||||
|            (item->countOfUnreadMessages() != 0 && QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| bool FeedsProxyModel::sortAlphabetically() const { | ||||
|   return m_sortAlphabetically; | ||||
| } | ||||
| 
 | ||||
| void FeedsProxyModel::sort(int column, Qt::SortOrder order) { | ||||
|   QSortFilterProxyModel::sort(column, order); | ||||
| } | ||||
|  |  | |||
|  | @ -11,17 +11,27 @@ class FeedsModel; | |||
| class FeedsView; | ||||
| 
 | ||||
| class FeedsProxyModel : public QSortFilterProxyModel { | ||||
|   Q_OBJECT | ||||
|     Q_OBJECT | ||||
| 
 | ||||
|   public: | ||||
|     explicit FeedsProxyModel(FeedsModel* source_model, QObject* parent = nullptr); | ||||
|     virtual ~FeedsProxyModel(); | ||||
| 
 | ||||
|     virtual bool dropMimeData(const QMimeData* data, | ||||
|                               Qt::DropAction action, | ||||
|                               int row, | ||||
|                               int column, | ||||
|                               const QModelIndex& parent); | ||||
| 
 | ||||
|     virtual void sort(int column, Qt::SortOrder order = Qt::SortOrder::AscendingOrder); | ||||
| 
 | ||||
|     // Returns index list of items which "match" given value.
 | ||||
|     // Used for finding items according to entered title text.
 | ||||
|     virtual QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const; | ||||
|     virtual QModelIndexList match(const QModelIndex& start, | ||||
|                                   int role, | ||||
|                                   const QVariant& value, | ||||
|                                   int hits, | ||||
|                                   Qt::MatchFlags flags) const; | ||||
| 
 | ||||
|     // Maps list of indexes.
 | ||||
|     QModelIndexList mapListToSource(const QModelIndexList& indexes) const; | ||||
|  | @ -34,6 +44,7 @@ class FeedsProxyModel : public QSortFilterProxyModel { | |||
|     void setSelectedItem(const RootItem* selected_item); | ||||
|     void setView(FeedsView* newView); | ||||
| 
 | ||||
|     bool sortAlphabetically() const; | ||||
|     void setSortAlphabetically(bool sort_alphabetically); | ||||
| 
 | ||||
|   public slots: | ||||
|  | @ -42,6 +53,9 @@ class FeedsProxyModel : public QSortFilterProxyModel { | |||
|   signals: | ||||
|     void expandAfterFilterIn(QModelIndex source_idx) const; | ||||
| 
 | ||||
|     // There was some drag/drop operation, notify view about this.
 | ||||
|     void requireItemValidationAfterDragDrop(const QModelIndex& source_index); | ||||
| 
 | ||||
|   protected: | ||||
|     virtual bool lessThan(const QModelIndex& left, const QModelIndex& right) const; | ||||
|     virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; | ||||
|  |  | |||
|  | @ -29,8 +29,8 @@ | |||
| 
 | ||||
| FeedsView::FeedsView(QWidget* parent) | ||||
|   : BaseTreeView(parent), m_contextMenuService(nullptr), m_contextMenuBin(nullptr), m_contextMenuCategories(nullptr), | ||||
|   m_contextMenuFeeds(nullptr), m_contextMenuImportant(nullptr), m_contextMenuEmptySpace(nullptr), m_contextMenuOtherItems(nullptr), | ||||
|   m_contextMenuLabel(nullptr), m_dontSaveExpandState(false) { | ||||
|     m_contextMenuFeeds(nullptr), m_contextMenuImportant(nullptr), m_contextMenuEmptySpace(nullptr), | ||||
|     m_contextMenuOtherItems(nullptr), m_contextMenuLabel(nullptr), m_dontSaveExpandState(false) { | ||||
|   setObjectName(QSL("FeedsView")); | ||||
| 
 | ||||
|   // Allocate models.
 | ||||
|  | @ -40,10 +40,13 @@ FeedsView::FeedsView(QWidget* parent) | |||
|   m_proxyModel->setView(this); | ||||
| 
 | ||||
|   // Connections.
 | ||||
|   connect(m_sourceModel, &FeedsModel::requireItemValidationAfterDragDrop, this, &FeedsView::validateItemAfterDragDrop); | ||||
|   connect(m_sourceModel, &FeedsModel::itemExpandRequested, this, &FeedsView::onItemExpandRequested); | ||||
|   connect(m_sourceModel, &FeedsModel::itemExpandStateSaveRequested, this, &FeedsView::onItemExpandStateSaveRequested); | ||||
|   connect(header(), &QHeaderView::sortIndicatorChanged, this, &FeedsView::saveSortState); | ||||
|   connect(m_proxyModel, | ||||
|           &FeedsProxyModel::requireItemValidationAfterDragDrop, | ||||
|           this, | ||||
|           &FeedsView::validateItemAfterDragDrop); | ||||
|   connect(m_proxyModel, &FeedsProxyModel::expandAfterFilterIn, this, &FeedsView::expandItemDelayed); | ||||
|   connect(this, &FeedsView::expanded, this, &FeedsView::onIndexExpanded); | ||||
|   connect(this, &FeedsView::collapsed, this, &FeedsView::onIndexCollapsed); | ||||
|  | @ -127,10 +130,10 @@ void FeedsView::addFeedIntoSelectedAccount() { | |||
|       root->addNewFeed(selected, QGuiApplication::clipboard()->text(QClipboard::Mode::Clipboard)); | ||||
|     } | ||||
|     else { | ||||
|       qApp->showGuiMessage(Notification::Event::GeneralEvent, { | ||||
|         tr("Not supported by account"), | ||||
|         tr("Selected account does not support adding of new feeds."), | ||||
|         QSystemTrayIcon::MessageIcon::Warning }); | ||||
|       qApp->showGuiMessage(Notification::Event::GeneralEvent, | ||||
|                            {tr("Not supported by account"), | ||||
|                             tr("Selected account does not support adding of new feeds."), | ||||
|                             QSystemTrayIcon::MessageIcon::Warning}); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -145,10 +148,10 @@ void FeedsView::addCategoryIntoSelectedAccount() { | |||
|       root->addNewCategory(selectedItem()); | ||||
|     } | ||||
|     else { | ||||
|       qApp->showGuiMessage(Notification::Event::GeneralEvent, { | ||||
|         tr("Not supported by account"), | ||||
|         tr("Selected account does not support adding of new categories."), | ||||
|         QSystemTrayIcon::MessageIcon::Warning }); | ||||
|       qApp->showGuiMessage(Notification::Event::GeneralEvent, | ||||
|                            {tr("Not supported by account"), | ||||
|                             tr("Selected account does not support adding of new categories."), | ||||
|                             QSystemTrayIcon::MessageIcon::Warning}); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -163,7 +166,7 @@ void FeedsView::expandCollapseCurrentItem(bool recursive) { | |||
|     } | ||||
| 
 | ||||
|     if (recursive) { | ||||
|       QList<QModelIndex> to_process = { index }; | ||||
|       QList<QModelIndex> to_process = {index}; | ||||
|       bool expa = !isExpanded(index); | ||||
| 
 | ||||
|       while (!to_process.isEmpty()) { | ||||
|  | @ -208,10 +211,10 @@ void FeedsView::editSelectedItem() { | |||
|     // Lock was not obtained because
 | ||||
|     // it is used probably by feed updater or application
 | ||||
|     // is quitting.
 | ||||
|     qApp->showGuiMessage(Notification::Event::GeneralEvent, { | ||||
|       tr("Cannot edit item"), | ||||
|       tr("Selected item cannot be edited because another critical operation is ongoing."), | ||||
|       QSystemTrayIcon::MessageIcon::Warning }); | ||||
|     qApp->showGuiMessage(Notification::Event::GeneralEvent, | ||||
|                          {tr("Cannot edit item"), | ||||
|                           tr("Selected item cannot be edited because another critical operation is ongoing."), | ||||
|                           QSystemTrayIcon::MessageIcon::Warning}); | ||||
| 
 | ||||
|     // Thus, cannot delete and quit the method.
 | ||||
|     return; | ||||
|  | @ -221,10 +224,10 @@ void FeedsView::editSelectedItem() { | |||
|     selectedItem()->editViaGui(); | ||||
|   } | ||||
|   else { | ||||
|     qApp->showGuiMessage(Notification::Event::GeneralEvent, { | ||||
|       tr("Cannot edit item"), | ||||
|       tr("Selected item cannot be edited, this is not (yet?) supported."), | ||||
|       QSystemTrayIcon::MessageIcon::Warning }); | ||||
|     qApp->showGuiMessage(Notification::Event::GeneralEvent, | ||||
|                          {tr("Cannot edit item"), | ||||
|                           tr("Selected item cannot be edited, this is not (yet?) supported."), | ||||
|                           QSystemTrayIcon::MessageIcon::Warning}); | ||||
|   } | ||||
| 
 | ||||
|   // Changes are done, unlock the update master lock.
 | ||||
|  | @ -236,10 +239,10 @@ void FeedsView::deleteSelectedItem() { | |||
|     // Lock was not obtained because
 | ||||
|     // it is used probably by feed updater or application
 | ||||
|     // is quitting.
 | ||||
|     qApp->showGuiMessage(Notification::Event::GeneralEvent, { | ||||
|       tr("Cannot delete item"), | ||||
|       tr("Selected item cannot be deleted because another critical operation is ongoing."), | ||||
|       QSystemTrayIcon::MessageIcon::Warning }); | ||||
|     qApp->showGuiMessage(Notification::Event::GeneralEvent, | ||||
|                          {tr("Cannot delete item"), | ||||
|                           tr("Selected item cannot be deleted because another critical operation is ongoing."), | ||||
|                           QSystemTrayIcon::MessageIcon::Warning}); | ||||
| 
 | ||||
|     // Thus, cannot delete and quit the method.
 | ||||
|     return; | ||||
|  | @ -261,7 +264,8 @@ void FeedsView::deleteSelectedItem() { | |||
|                        tr("Deleting \"%1\"").arg(selected_item->title()), | ||||
|                        tr("You are about to completely delete item \"%1\".").arg(selected_item->title()), | ||||
|                        tr("Are you sure?"), | ||||
|                        QString(), QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, | ||||
|                        QString(), | ||||
|                        QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, | ||||
|                        QMessageBox::StandardButton::Yes) == QMessageBox::StandardButton::No) { | ||||
|         // User refused.
 | ||||
|         qApp->feedUpdateLock()->unlock(); | ||||
|  | @ -272,17 +276,18 @@ void FeedsView::deleteSelectedItem() { | |||
|       if (!selected_item->deleteViaGui()) { | ||||
|         m_proxyModel->invalidate(); | ||||
| 
 | ||||
|         qApp->showGuiMessage(Notification::Event::GeneralEvent, { | ||||
|           tr("Cannot delete \"%1\"").arg(selected_item->title()), | ||||
|           tr("This item cannot be deleted because something critically failed. Submit bug report."), | ||||
|           QSystemTrayIcon::MessageIcon::Critical }); | ||||
|         qApp->showGuiMessage(Notification::Event::GeneralEvent, | ||||
|                              {tr("Cannot delete \"%1\"").arg(selected_item->title()), | ||||
|                               tr("This item cannot be deleted because something critically failed. Submit bug report."), | ||||
|                               QSystemTrayIcon::MessageIcon::Critical}); | ||||
|       } | ||||
|     } | ||||
|     else { | ||||
|       qApp->showGuiMessage(Notification::Event::GeneralEvent, { | ||||
|         tr("Cannot delete \"%1\"").arg(selected_item->title()), | ||||
|         tr("This item cannot be deleted, because it does not support it\nor this functionality is not implemented yet."), | ||||
|         QSystemTrayIcon::MessageIcon::Critical }); | ||||
|       qApp->showGuiMessage(Notification::Event::GeneralEvent, | ||||
|                            {tr("Cannot delete \"%1\"").arg(selected_item->title()), | ||||
|                             tr("This item cannot be deleted, because it does not support it\nor this functionality is " | ||||
|                                "not implemented yet."), | ||||
|                             QSystemTrayIcon::MessageIcon::Critical}); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|  | @ -395,7 +400,8 @@ QModelIndex FeedsView::nextUnreadItem(const QModelIndex& default_row) { | |||
|   const QModelIndex starting_row = default_row; | ||||
| 
 | ||||
|   while (true) { | ||||
|     bool has_unread = m_sourceModel->itemForIndex(m_proxyModel->mapToSource(nconst_default_row))->countOfUnreadMessages() > 0; | ||||
|     bool has_unread = | ||||
|       m_sourceModel->itemForIndex(m_proxyModel->mapToSource(nconst_default_row))->countOfUnreadMessages() > 0; | ||||
| 
 | ||||
|     if (has_unread) { | ||||
|       if (m_proxyModel->hasChildren(nconst_default_row)) { | ||||
|  | @ -435,10 +441,9 @@ QMenu* FeedsView::initializeContextMenuBin(RootItem* clicked_item) { | |||
| 
 | ||||
|   QList<QAction*> specific_actions = clicked_item->contextMenuFeedsList(); | ||||
| 
 | ||||
|   m_contextMenuBin->addActions(QList<QAction*>() << | ||||
|                                qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode << | ||||
|                                qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead << | ||||
|                                qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread); | ||||
|   m_contextMenuBin->addActions(QList<QAction*>() << qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode | ||||
|                                                  << qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead | ||||
|                                                  << qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread); | ||||
| 
 | ||||
|   if (!specific_actions.isEmpty()) { | ||||
|     m_contextMenuBin->addSeparator(); | ||||
|  | @ -458,15 +463,15 @@ QMenu* FeedsView::initializeContextMenuService(RootItem* clicked_item) { | |||
| 
 | ||||
|   QList<QAction*> specific_actions = clicked_item->contextMenuFeedsList(); | ||||
| 
 | ||||
|   m_contextMenuService->addActions({ qApp->mainForm()->m_ui->m_actionUpdateSelectedItems, | ||||
|                                      qApp->mainForm()->m_ui->m_actionEditSelectedItem, | ||||
|                                      qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed, | ||||
|                                      qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode, | ||||
|                                      qApp->mainForm()->m_ui->m_actionExpandCollapseItem, | ||||
|                                      qApp->mainForm()->m_ui->m_actionExpandCollapseItemRecursively, | ||||
|                                      qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead, | ||||
|                                      qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread, | ||||
|                                      qApp->mainForm()->m_ui->m_actionDeleteSelectedItem }); | ||||
|   m_contextMenuService->addActions({qApp->mainForm()->m_ui->m_actionUpdateSelectedItems, | ||||
|                                     qApp->mainForm()->m_ui->m_actionEditSelectedItem, | ||||
|                                     qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed, | ||||
|                                     qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode, | ||||
|                                     qApp->mainForm()->m_ui->m_actionExpandCollapseItem, | ||||
|                                     qApp->mainForm()->m_ui->m_actionExpandCollapseItemRecursively, | ||||
|                                     qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead, | ||||
|                                     qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread, | ||||
|                                     qApp->mainForm()->m_ui->m_actionDeleteSelectedItem}); | ||||
| 
 | ||||
|   auto cat_add = clicked_item->getParentServiceRoot()->supportsCategoryAdding(); | ||||
|   auto feed_add = clicked_item->getParentServiceRoot()->supportsFeedAdding(); | ||||
|  | @ -483,8 +488,7 @@ QMenu* FeedsView::initializeContextMenuService(RootItem* clicked_item) { | |||
|     m_contextMenuService->addAction(qApp->mainForm()->m_ui->m_actionAddFeedIntoSelectedItem); | ||||
|   } | ||||
| 
 | ||||
|   if (!qApp->settings()->value(GROUP(Feeds), | ||||
|                                SETTING(Feeds::SortAlphabetically)).toBool()) { | ||||
|   if (!qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::SortAlphabetically)).toBool()) { | ||||
|     m_contextMenuService->addSeparator(); | ||||
|     m_contextMenuService->addAction(qApp->mainForm()->m_ui->m_actionFeedMoveUp); | ||||
|     m_contextMenuService->addAction(qApp->mainForm()->m_ui->m_actionFeedMoveDown); | ||||
|  | @ -521,7 +525,8 @@ void FeedsView::focusInEvent(QFocusEvent* event) { | |||
|   QTreeView::focusInEvent(event); | ||||
| 
 | ||||
|   if (currentIndex().isValid()) { | ||||
|     selectionModel()->select(currentIndex(), QItemSelectionModel::SelectionFlag::Select | QItemSelectionModel::SelectionFlag::Rows); | ||||
|     selectionModel()->select(currentIndex(), | ||||
|                              QItemSelectionModel::SelectionFlag::Select | QItemSelectionModel::SelectionFlag::Rows); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -554,14 +559,11 @@ void FeedsView::onIndexExpanded(const QModelIndex& idx) { | |||
| 
 | ||||
|   const RootItem* it = m_sourceModel->itemForIndex(m_proxyModel->mapToSource(idx)); | ||||
| 
 | ||||
|   if (it != nullptr && (int(it->kind()) & int(RootItem::Kind::Category | | ||||
|                                               RootItem::Kind::ServiceRoot | | ||||
|                                               RootItem::Kind::Labels)) > 0) { | ||||
|   if (it != nullptr && | ||||
|       (int(it->kind()) & int(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | RootItem::Kind::Labels)) > 0) { | ||||
|     const QString setting_name = it->hashCode(); | ||||
| 
 | ||||
|     qApp->settings()->setValue(GROUP(CategoriesExpandStates), | ||||
|                                setting_name, | ||||
|                                true); | ||||
|     qApp->settings()->setValue(GROUP(CategoriesExpandStates), setting_name, true); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -575,14 +577,11 @@ void FeedsView::onIndexCollapsed(const QModelIndex& idx) { | |||
| 
 | ||||
|   RootItem* it = m_sourceModel->itemForIndex(m_proxyModel->mapToSource(idx)); | ||||
| 
 | ||||
|   if (it != nullptr && (int(it->kind()) & int(RootItem::Kind::Category | | ||||
|                                               RootItem::Kind::ServiceRoot | | ||||
|                                               RootItem::Kind::Labels)) > 0) { | ||||
|   if (it != nullptr && | ||||
|       (int(it->kind()) & int(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | RootItem::Kind::Labels)) > 0) { | ||||
|     const QString setting_name = it->hashCode(); | ||||
| 
 | ||||
|     qApp->settings()->setValue(GROUP(CategoriesExpandStates), | ||||
|                                setting_name, | ||||
|                                false); | ||||
|     qApp->settings()->setValue(GROUP(CategoriesExpandStates), setting_name, false); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -596,9 +595,8 @@ void FeedsView::saveAllExpandStates() { | |||
| 
 | ||||
| void FeedsView::saveExpandStates(RootItem* item) { | ||||
|   Settings* settings = qApp->settings(); | ||||
|   QList<RootItem*> items = item->getSubTree(RootItem::Kind::Category | | ||||
|                                             RootItem::Kind::ServiceRoot | | ||||
|                                             RootItem::Kind::Labels); | ||||
|   QList<RootItem*> items = | ||||
|     item->getSubTree(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | RootItem::Kind::Labels); | ||||
| 
 | ||||
|   // Iterate all categories and save their expand statuses.
 | ||||
|   for (const RootItem* it : items) { | ||||
|  | @ -606,9 +604,7 @@ void FeedsView::saveExpandStates(RootItem* item) { | |||
|     QModelIndex source_index = sourceModel()->indexForItem(it); | ||||
|     QModelIndex visible_index = model()->mapFromSource(source_index); | ||||
| 
 | ||||
|     settings->setValue(GROUP(CategoriesExpandStates), | ||||
|                        setting_name, | ||||
|                        isExpanded(visible_index)); | ||||
|     settings->setValue(GROUP(CategoriesExpandStates), setting_name, isExpanded(visible_index)); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -616,8 +612,7 @@ void FeedsView::loadAllExpandStates() { | |||
|   const Settings* settings = qApp->settings(); | ||||
|   QList<RootItem*> expandable_items; | ||||
| 
 | ||||
|   expandable_items.append(sourceModel()->rootItem()->getSubTree(RootItem::Kind::Category | | ||||
|                                                                 RootItem::Kind::ServiceRoot | | ||||
|   expandable_items.append(sourceModel()->rootItem()->getSubTree(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | | ||||
|                                                                 RootItem::Kind::Labels)); | ||||
| 
 | ||||
|   // Iterate all categories and save their expand statuses.
 | ||||
|  | @ -629,13 +624,15 @@ void FeedsView::loadAllExpandStates() { | |||
|   } | ||||
| 
 | ||||
|   sortByColumn(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortColumnFeeds)).toInt(), | ||||
|                static_cast<Qt::SortOrder>(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortOrderFeeds)).toInt())); | ||||
|                static_cast<Qt::SortOrder>(qApp->settings() | ||||
|                                             ->value(GROUP(GUI), SETTING(GUI::DefaultSortOrderFeeds)) | ||||
|                                             .toInt())); | ||||
| } | ||||
| 
 | ||||
| void FeedsView::expandItemDelayed(const QModelIndex& source_idx) { | ||||
|   //QTimer::singleShot(100, this, [=] {
 | ||||
|   // Model requests to expand some items as they are visible and there is
 | ||||
|   // a filter active, so they maybe were not visible before.
 | ||||
|   // QTimer::singleShot(100, this, [=] {
 | ||||
|   //  Model requests to expand some items as they are visible and there is
 | ||||
|   //  a filter active, so they maybe were not visible before.
 | ||||
|   QModelIndex pidx = m_proxyModel->mapFromSource(source_idx); | ||||
| 
 | ||||
|   // NOTE: These changes are caused by filtering mechanisms
 | ||||
|  | @ -663,15 +660,15 @@ QMenu* FeedsView::initializeContextMenuCategories(RootItem* clicked_item) { | |||
| 
 | ||||
|   QList<QAction*> specific_actions = clicked_item->contextMenuFeedsList(); | ||||
| 
 | ||||
|   m_contextMenuCategories->addActions({ qApp->mainForm()->m_ui->m_actionUpdateSelectedItems, | ||||
|                                         qApp->mainForm()->m_ui->m_actionEditSelectedItem, | ||||
|                                         qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed, | ||||
|                                         qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode, | ||||
|                                         qApp->mainForm()->m_ui->m_actionExpandCollapseItem, | ||||
|                                         qApp->mainForm()->m_ui->m_actionExpandCollapseItemRecursively, | ||||
|                                         qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead, | ||||
|                                         qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread, | ||||
|                                         qApp->mainForm()->m_ui->m_actionDeleteSelectedItem }); | ||||
|   m_contextMenuCategories->addActions({qApp->mainForm()->m_ui->m_actionUpdateSelectedItems, | ||||
|                                        qApp->mainForm()->m_ui->m_actionEditSelectedItem, | ||||
|                                        qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed, | ||||
|                                        qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode, | ||||
|                                        qApp->mainForm()->m_ui->m_actionExpandCollapseItem, | ||||
|                                        qApp->mainForm()->m_ui->m_actionExpandCollapseItemRecursively, | ||||
|                                        qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead, | ||||
|                                        qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread, | ||||
|                                        qApp->mainForm()->m_ui->m_actionDeleteSelectedItem}); | ||||
| 
 | ||||
|   auto cat_add = clicked_item->getParentServiceRoot()->supportsCategoryAdding(); | ||||
|   auto feed_add = clicked_item->getParentServiceRoot()->supportsFeedAdding(); | ||||
|  | @ -688,8 +685,7 @@ QMenu* FeedsView::initializeContextMenuCategories(RootItem* clicked_item) { | |||
|     m_contextMenuCategories->addAction(qApp->mainForm()->m_ui->m_actionAddFeedIntoSelectedItem); | ||||
|   } | ||||
| 
 | ||||
|   if (!qApp->settings()->value(GROUP(Feeds), | ||||
|                                SETTING(Feeds::SortAlphabetically)).toBool()) { | ||||
|   if (!qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::SortAlphabetically)).toBool()) { | ||||
|     m_contextMenuCategories->addSeparator(); | ||||
|     m_contextMenuCategories->addAction(qApp->mainForm()->m_ui->m_actionFeedMoveUp); | ||||
|     m_contextMenuCategories->addAction(qApp->mainForm()->m_ui->m_actionFeedMoveDown); | ||||
|  | @ -715,14 +711,13 @@ QMenu* FeedsView::initializeContextMenuFeeds(RootItem* clicked_item) { | |||
| 
 | ||||
|   QList<QAction*> specific_actions = clicked_item->contextMenuFeedsList(); | ||||
| 
 | ||||
|   m_contextMenuFeeds->addActions(QList<QAction*>() << | ||||
|                                  qApp->mainForm()->m_ui->m_actionUpdateSelectedItems << | ||||
|                                  qApp->mainForm()->m_ui->m_actionEditSelectedItem << | ||||
|                                  qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed << | ||||
|                                  qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode << | ||||
|                                  qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead << | ||||
|                                  qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread << | ||||
|                                  qApp->mainForm()->m_ui->m_actionDeleteSelectedItem); | ||||
|   m_contextMenuFeeds->addActions(QList<QAction*>() << qApp->mainForm()->m_ui->m_actionUpdateSelectedItems | ||||
|                                                    << qApp->mainForm()->m_ui->m_actionEditSelectedItem | ||||
|                                                    << qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed | ||||
|                                                    << qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode | ||||
|                                                    << qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead | ||||
|                                                    << qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread | ||||
|                                                    << qApp->mainForm()->m_ui->m_actionDeleteSelectedItem); | ||||
| 
 | ||||
|   auto cat_add = clicked_item->getParentServiceRoot()->supportsCategoryAdding(); | ||||
|   auto feed_add = clicked_item->getParentServiceRoot()->supportsFeedAdding(); | ||||
|  | @ -739,8 +734,7 @@ QMenu* FeedsView::initializeContextMenuFeeds(RootItem* clicked_item) { | |||
|     m_contextMenuFeeds->addAction(qApp->mainForm()->m_ui->m_actionAddFeedIntoSelectedItem); | ||||
|   } | ||||
| 
 | ||||
|   if (!qApp->settings()->value(GROUP(Feeds), | ||||
|                                SETTING(Feeds::SortAlphabetically)).toBool()) { | ||||
|   if (!qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::SortAlphabetically)).toBool()) { | ||||
|     m_contextMenuFeeds->addSeparator(); | ||||
|     m_contextMenuFeeds->addAction(qApp->mainForm()->m_ui->m_actionFeedMoveUp); | ||||
|     m_contextMenuFeeds->addAction(qApp->mainForm()->m_ui->m_actionFeedMoveDown); | ||||
|  | @ -766,10 +760,9 @@ QMenu* FeedsView::initializeContextMenuImportant(RootItem* clicked_item) { | |||
| 
 | ||||
|   QList<QAction*> specific_actions = clicked_item->contextMenuFeedsList(); | ||||
| 
 | ||||
|   m_contextMenuImportant->addActions(QList<QAction*>() << | ||||
|                                      qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode << | ||||
|                                      qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead << | ||||
|                                      qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread); | ||||
|   m_contextMenuImportant->addActions(QList<QAction*>() << qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode | ||||
|                                                        << qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead | ||||
|                                                        << qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread); | ||||
| 
 | ||||
|   if (!specific_actions.isEmpty()) { | ||||
|     m_contextMenuImportant->addSeparator(); | ||||
|  | @ -849,15 +842,17 @@ void FeedsView::setupAppearance() { | |||
|   setExpandsOnDoubleClick(true); | ||||
|   setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers); | ||||
|   setIndentation(FEEDS_VIEW_INDENTATION); | ||||
|   setAcceptDrops(false); | ||||
|   setAcceptDrops(true); | ||||
|   viewport()->setAcceptDrops(true); | ||||
|   setDragEnabled(true); | ||||
|   setDropIndicatorShown(true); | ||||
|   setDragDropMode(QAbstractItemView::DragDropMode::InternalMove); | ||||
|   setAllColumnsShowFocus(false); | ||||
|   setRootIsDecorated(false); | ||||
|   setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); | ||||
|   setItemDelegate(new StyledItemDelegateWithoutFocus(qApp->settings()->value(GROUP(GUI), | ||||
|                                                                              SETTING(GUI::HeightRowFeeds)).toInt(), | ||||
|   setItemDelegate(new StyledItemDelegateWithoutFocus(qApp->settings() | ||||
|                                                        ->value(GROUP(GUI), SETTING(GUI::HeightRowFeeds)) | ||||
|                                                        .toInt(), | ||||
|                                                      -1, | ||||
|                                                      this)); | ||||
| } | ||||
|  | @ -904,8 +899,7 @@ void FeedsView::contextMenuEvent(QContextMenuEvent* event) { | |||
|       // Display context menu for feeds.
 | ||||
|       initializeContextMenuFeeds(clicked_item)->exec(event->globalPos()); | ||||
|     } | ||||
|     else if (clicked_item->kind() == RootItem::Kind::Important || | ||||
|              clicked_item->kind() == RootItem::Kind::Unread) { | ||||
|     else if (clicked_item->kind() == RootItem::Kind::Important || clicked_item->kind() == RootItem::Kind::Unread) { | ||||
|       initializeContextMenuImportant(clicked_item)->exec(event->globalPos()); | ||||
|     } | ||||
|     else if (clicked_item->kind() == RootItem::Kind::Bin) { | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue