Empty initial drag/drop support.

This commit is contained in:
Martin Rotter 2015-11-25 09:37:40 +01:00
parent 8ae9c97248
commit b685f1fc86
12 changed files with 155 additions and 3 deletions

View File

@ -204,6 +204,122 @@ DatabaseCleaner *FeedsModel::databaseCleaner() {
return m_dbCleaner;
}
QMimeData *FeedsModel::mimeData(const QModelIndexList &indexes) const {
QMimeData *mime_data = new QMimeData();
QByteArray encoded_data;
QDataStream stream(&encoded_data, QIODevice::WriteOnly);
foreach (const QModelIndex &index, indexes) {
if (index.column() != 0) {
continue;
}
RootItem *item_for_index = itemForIndex(index);
if (item_for_index->kind() != RootItemKind::Root) {
stream << (quintptr) item_for_index;
}
}
mime_data->setData(MIME_TYPE_ITEM_POINTER, encoded_data);
return mime_data;
}
QStringList FeedsModel::mimeTypes() const {
return QStringList() << 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::IgnoreAction) {
return true;
}
else if (action != Qt::MoveAction) {
return false;
}
QByteArray dragged_items_data = data->data(MIME_TYPE_ITEM_POINTER);
if (dragged_items_data.isEmpty()) {
return false;
}
else {
QDataStream stream(&dragged_items_data, QIODevice::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.
RootItem *dragged_item = (RootItem*) 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(tr("Cannot perform drag \& drop operation."),
tr("You can't transfer dragged item into different account, this is not supported."),
QSystemTrayIcon::Warning,
qApp->mainForm(),
true);
qDebug("Dragged item cannot be dragged into different account. Cancelling drag-drop action.");
return false;
}
/*
if (dragged_item->kind() == RootItem::Feeed) {
qDebug("Drag-drop action for feed '%s' detected, editing the feed.", qPrintable(dragged_item->title()));
Feed *actual_feed = dragged_item->toFeed();
Feed *feed_new = new Feed(*actual_feed);
feed_new->setParent(target_item);
editFeed(actual_feed, feed_new);
emit requireItemValidationAfterDragDrop(indexForItem(actual_feed));
}
else if (dragged_item->kind() == RootItem::Cattegory) {
qDebug("Drag-drop action for category '%s' detected, editing the feed.", qPrintable(dragged_item->title()));
Category *actual_category = dragged_item->toCategory();
Category *category_new = new Category(*actual_category);
category_new->clearChildren();
category_new->setParent(target_item);
editCategory(actual_category, category_new);
emit requireItemValidationAfterDragDrop(indexForItem(actual_category));
}
*/
}
return true;
}
return false;
}
Qt::DropActions FeedsModel::supportedDropActions() const {
return Qt::MoveAction;
}
Qt::ItemFlags FeedsModel::flags(const QModelIndex &index) const {
Qt::ItemFlags base_flags = QAbstractItemModel::flags(index);
RootItem *item_for_index = itemForIndex(index);
Qt::ItemFlags additional_flags = item_for_index->additionalFlags();
return base_flags | additional_flags;
}
void FeedsModel::executeNextAutoUpdate() {
if (!qApp->feedUpdateLock()->tryLock()) {
qDebug("Delaying scheduled feed auto-updates for one minute due to another running update.");

View File

@ -47,6 +47,13 @@ class FeedsModel : public QAbstractItemModel {
return itemForIndex(index)->data(index.column(), role);
}
// 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;
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;
@ -181,8 +188,11 @@ class FeedsModel : public QAbstractItemModel {
void onFeedUpdatesFinished(FeedDownloadResults results);
signals:
// Update of feeds is finished.
void feedsUpdateFinished();
// Counts of unread messages are changed in some feeds,
// notify view about this shit.
void readFeedsFilterInvalidationRequested();
// Emitted when model requests update of some feeds.
@ -194,6 +204,10 @@ class 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.
// NOTE: View will probably expand dropped index.
void requireItemValidationAfterDragDrop(const QModelIndex &source_index);
private:
// Returns converted ids of given feeds
// which are suitable as IN clause for SQL queries.

View File

@ -206,7 +206,9 @@ bool FeedsProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source
return true;
}
else {
return item->countOfUnreadMessages() > 0;
// NOTE: If item has < 0 of unread message it may mean, that the count
// of unread messages is not (yet) known, display that item too.
return item->countOfUnreadMessages() != 0;
}
}

View File

@ -166,6 +166,10 @@ QVariant RootItem::data(int column, int role) const {
}
}
Qt::ItemFlags RootItem::additionalFlags() const {
return Qt::NoItemFlags;
}
int RootItem::countOfAllMessages() const {
int total_count = 0;

View File

@ -74,8 +74,7 @@ class RootItem : public QObject {
/////////////////////////////////////////
// Returns list of specific actions which can be done with the item.
// Do not include general actions here like actions:
// Mark as read, Update, ...
// Do not include general actions here like actions: Mark as read, Update, ...
// NOTE: Ownership of returned actions is not switched to caller, free them when needed.
virtual QList<QAction*> contextMenuActions();
@ -113,6 +112,7 @@ class RootItem : public QObject {
virtual int row() const;
virtual QVariant data(int column, int role) const;
virtual Qt::ItemFlags additionalFlags() const;
// Each item offers "counts" of messages.
// Returns counts of messages of all child items summed up.

View File

@ -54,6 +54,7 @@ FeedsView::FeedsView(QWidget *parent)
m_sourceModel = m_proxyModel->sourceModel();
// Connections.
connect(m_sourceModel, SIGNAL(requireItemValidationAfterDragDrop(QModelIndex)), this, SLOT(validateItemAfterDragDrop(QModelIndex)));
connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(saveSortState(int,Qt::SortOrder)));
setModel(m_proxyModel);

View File

@ -90,6 +90,10 @@ QVariant StandardCategory::data(int column, int role) const {
}
}
Qt::ItemFlags StandardCategory::additionalFlags() const {
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}
bool StandardCategory::editViaGui() {
QPointer<FormStandardCategoryDetails> form_pointer = new FormStandardCategoryDetails(serviceRoot(), qApp->mainForm());

View File

@ -44,6 +44,7 @@ class StandardCategory : public Category {
// Returns the actual data representation of standard category.
QVariant data(int column, int role) const;
Qt::ItemFlags additionalFlags() const;
bool canBeEdited() {
return true;

View File

@ -436,6 +436,10 @@ QVariant StandardFeed::data(int column, int role) const {
}
}
Qt::ItemFlags StandardFeed::additionalFlags() const {
return Qt::ItemIsDragEnabled;
}
int StandardFeed::update() {
QByteArray feed_contents;
int download_timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();

View File

@ -81,6 +81,7 @@ class StandardFeed : public Feed {
// Obtains data related to this feed.
QVariant data(int column, int role) const;
Qt::ItemFlags additionalFlags() const;
// Perform fetching of new messages. Returns number of newly updated messages.
int update();

View File

@ -128,6 +128,10 @@ QVariant StandardServiceRoot::data(int column, int role) const {
}
}
Qt::ItemFlags StandardServiceRoot::additionalFlags() const {
return Qt::ItemIsDropEnabled;
}
RecycleBin *StandardServiceRoot::recycleBin() {
return m_recycleBin;
}

View File

@ -50,6 +50,7 @@ class StandardServiceRoot : public ServiceRoot {
bool canBeEdited();
bool canBeDeleted();
QVariant data(int column, int role) const;
Qt::ItemFlags additionalFlags() const;
RecycleBin *recycleBin();