Skip to content

Commit

Permalink
items are now sortable with drag/drop
Browse files Browse the repository at this point in the history
  • Loading branch information
martinrotter committed Aug 26, 2022
1 parent 3d93a40 commit f63af3a
Show file tree
Hide file tree
Showing 5 changed files with 249 additions and 225 deletions.
67 changes: 0 additions & 67 deletions src/librssguard/core/feedsmodel.cpp
Expand Up @@ -22,8 +22,6 @@
#include <QStack>
#include <QTimer>

using RootItemPtr = RootItem*;

FeedsModel::FeedsModel(QObject* parent) : QAbstractItemModel(parent), m_rootItem(new RootItem()) {
setObjectName(QSL("FeedsModel"));

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -598,6 +532,5 @@ QVariant FeedsModel::data(const QModelIndex& index, int role) const {

default:
return itemForIndex(index)->data(index.column(), role);
;
}
}
29 changes: 12 additions & 17 deletions src/librssguard/core/feedsmodel.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand All @@ -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;
Expand Down

0 comments on commit f63af3a

Please sign in to comment.