Fixed #91.
This commit is contained in:
parent
bc2aa7f777
commit
a539c9aacd
@ -9,6 +9,7 @@ Fixed:
|
||||
|
||||
Added:
|
||||
<ul>
|
||||
<li>Items in feed list (categories and feeds) now can be re-arranged via drag-drop functionality (issue report #91).</li>
|
||||
<li>Tray icon now displays blue number of unread messages if any of those messages is newly downloaded from online feed (enhancement #87).</li>
|
||||
<li>Fixed issue request #95: items are now permanently hidden (not deleted from database) when "deleted" from recycle bin.</li>
|
||||
<li>Issue request #95: moreover custom incremental ability to update database schema was added to keep RSS Guard 2.0.0.4+ fully compatible with previous releases. Incremental algorithm supports both database backends.</li>
|
||||
|
@ -25,12 +25,14 @@
|
||||
#include "miscellaneous/textfactory.h"
|
||||
#include "miscellaneous/databasefactory.h"
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "gui/messagebox.h"
|
||||
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlRecord>
|
||||
#include <QPair>
|
||||
#include <QStack>
|
||||
#include <QMimeData>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -66,6 +68,117 @@ FeedsModel::~FeedsModel() {
|
||||
delete m_rootItem;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
FeedsModelRootItem *item_for_index = itemForIndex(index);
|
||||
|
||||
if (item_for_index->kind() != FeedsModelRootItem::RootItem) {
|
||||
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.
|
||||
FeedsModelRootItem *dragged_item = (FeedsModelRootItem*) pointer_to_item;
|
||||
FeedsModelRootItem *target_item = itemForIndex(parent);
|
||||
|
||||
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->kind() == FeedsModelRootItem::Feed) {
|
||||
qDebug("Drag-drop action for feed '%s' detected, editing the feed.", qPrintable(dragged_item->title()));
|
||||
|
||||
FeedsModelFeed *actual_feed = static_cast<FeedsModelFeed*>(dragged_item);
|
||||
FeedsModelFeed *feed_new = new FeedsModelFeed(*actual_feed);
|
||||
|
||||
feed_new->setParent(target_item);
|
||||
editFeed(actual_feed, feed_new);
|
||||
}
|
||||
else if (dragged_item->kind() == FeedsModelRootItem::Category) {
|
||||
qDebug("Drag-drop action for category '%s' detected, editing the feed.", qPrintable(dragged_item->title()));
|
||||
|
||||
FeedsModelCategory *actual_category = static_cast<FeedsModelCategory*>(dragged_item);
|
||||
FeedsModelCategory *category_new = new FeedsModelCategory(*actual_category);
|
||||
|
||||
category_new->clearChildren();
|
||||
category_new->setParent(target_item);
|
||||
editCategory(actual_category, category_new);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Qt::DropActions FeedsModel::supportedDropActions() const {
|
||||
return Qt::MoveAction;
|
||||
}
|
||||
|
||||
Qt::ItemFlags FeedsModel::flags(const QModelIndex &index) const {
|
||||
Qt::ItemFlags base_flags = QAbstractItemModel::flags(index);
|
||||
FeedsModelRootItem *item_for_index = itemForIndex(index);
|
||||
|
||||
switch (item_for_index->kind()) {
|
||||
case FeedsModelRootItem::RecycleBin:
|
||||
return base_flags;
|
||||
|
||||
case FeedsModelRootItem::Category:
|
||||
return base_flags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
|
||||
|
||||
case FeedsModelRootItem::Feed:
|
||||
return base_flags | Qt::ItemIsDragEnabled;
|
||||
|
||||
case FeedsModelRootItem::RootItem:
|
||||
default:
|
||||
return base_flags | Qt::ItemIsDropEnabled;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Pokračovat tady: http://qt-project.org/doc/qt-4.8/model-view-programming.html#using-drag-and-drop-with-item-views
|
||||
// neumožnit drag ani drop nad odpadkovým košem
|
||||
}
|
||||
|
||||
QVariant FeedsModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||
if (orientation != Qt::Horizontal) {
|
||||
return QVariant();
|
||||
@ -210,8 +323,7 @@ bool FeedsModel::addCategory(FeedsModelCategory *category, FeedsModelRootItem *p
|
||||
}
|
||||
|
||||
bool FeedsModel::editCategory(FeedsModelCategory *original_category, FeedsModelCategory *new_category) {
|
||||
QSqlDatabase database = qApp->database()->connection(objectName(),
|
||||
DatabaseFactory::FromSettings);
|
||||
QSqlDatabase database = qApp->database()->connection(objectName(), DatabaseFactory::FromSettings);
|
||||
QSqlQuery query_update_category(database);
|
||||
FeedsModelRootItem *original_parent = original_category->parent();
|
||||
FeedsModelRootItem *new_parent = new_category->parent();
|
||||
@ -313,8 +425,7 @@ bool FeedsModel::addFeed(FeedsModelFeed *feed, FeedsModelRootItem *parent) {
|
||||
}
|
||||
|
||||
bool FeedsModel::editFeed(FeedsModelFeed *original_feed, FeedsModelFeed *new_feed) {
|
||||
QSqlDatabase database = qApp->database()->connection(objectName(),
|
||||
DatabaseFactory::FromSettings);
|
||||
QSqlDatabase database = qApp->database()->connection(objectName(), DatabaseFactory::FromSettings);
|
||||
QSqlQuery query_update_feed(database);
|
||||
FeedsModelRootItem *original_parent = original_feed->parent();
|
||||
FeedsModelRootItem *new_parent = new_feed->parent();
|
||||
|
@ -51,6 +51,11 @@ class FeedsModel : public QAbstractItemModel {
|
||||
return itemForIndex(index)->data(index.column(), role);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -75,6 +75,8 @@
|
||||
#define FEEDS_VIEW_INDENTATION 10
|
||||
#define ACCEPT_HEADER_FOR_FEED_DOWNLOADER "application/atom+xml,application/xml;q=0.9,text/xml;q=0.8,*/*;q=0.7"
|
||||
|
||||
#define MIME_TYPE_ITEM_POINTER "rssguard/itempointer"
|
||||
|
||||
#define BACKUP_NAME_SETTINGS "config"
|
||||
#define BACKUP_SUFFIX_SETTINGS ".ini.backup"
|
||||
#define BACKUP_NAME_DATABASE "database"
|
||||
|
@ -603,9 +603,9 @@ void FeedsView::setupAppearance() {
|
||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
setIndentation(FEEDS_VIEW_INDENTATION);
|
||||
setAcceptDrops(false);
|
||||
setDragEnabled(false);
|
||||
setDropIndicatorShown(false);
|
||||
setDragDropMode(QAbstractItemView::NoDragDrop);
|
||||
setDragEnabled(true);
|
||||
setDropIndicatorShown(true);
|
||||
setDragDropMode(QAbstractItemView::InternalMove);
|
||||
setAllColumnsShowFocus(false);
|
||||
setRootIsDecorated(false);
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
Loading…
x
Reference in New Issue
Block a user