Fixed #91.
This commit is contained in:
parent
bc2aa7f777
commit
a539c9aacd
@ -9,6 +9,7 @@ Fixed:
|
|||||||
|
|
||||||
Added:
|
Added:
|
||||||
<ul>
|
<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>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>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>
|
<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/textfactory.h"
|
||||||
#include "miscellaneous/databasefactory.h"
|
#include "miscellaneous/databasefactory.h"
|
||||||
#include "miscellaneous/iconfactory.h"
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
#include "gui/messagebox.h"
|
||||||
|
|
||||||
#include <QSqlError>
|
#include <QSqlError>
|
||||||
#include <QSqlQuery>
|
#include <QSqlQuery>
|
||||||
#include <QSqlRecord>
|
#include <QSqlRecord>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include <QStack>
|
#include <QStack>
|
||||||
|
#include <QMimeData>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -66,6 +68,117 @@ FeedsModel::~FeedsModel() {
|
|||||||
delete m_rootItem;
|
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 {
|
QVariant FeedsModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||||
if (orientation != Qt::Horizontal) {
|
if (orientation != Qt::Horizontal) {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@ -210,8 +323,7 @@ bool FeedsModel::addCategory(FeedsModelCategory *category, FeedsModelRootItem *p
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FeedsModel::editCategory(FeedsModelCategory *original_category, FeedsModelCategory *new_category) {
|
bool FeedsModel::editCategory(FeedsModelCategory *original_category, FeedsModelCategory *new_category) {
|
||||||
QSqlDatabase database = qApp->database()->connection(objectName(),
|
QSqlDatabase database = qApp->database()->connection(objectName(), DatabaseFactory::FromSettings);
|
||||||
DatabaseFactory::FromSettings);
|
|
||||||
QSqlQuery query_update_category(database);
|
QSqlQuery query_update_category(database);
|
||||||
FeedsModelRootItem *original_parent = original_category->parent();
|
FeedsModelRootItem *original_parent = original_category->parent();
|
||||||
FeedsModelRootItem *new_parent = new_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) {
|
bool FeedsModel::editFeed(FeedsModelFeed *original_feed, FeedsModelFeed *new_feed) {
|
||||||
QSqlDatabase database = qApp->database()->connection(objectName(),
|
QSqlDatabase database = qApp->database()->connection(objectName(), DatabaseFactory::FromSettings);
|
||||||
DatabaseFactory::FromSettings);
|
|
||||||
QSqlQuery query_update_feed(database);
|
QSqlQuery query_update_feed(database);
|
||||||
FeedsModelRootItem *original_parent = original_feed->parent();
|
FeedsModelRootItem *original_parent = original_feed->parent();
|
||||||
FeedsModelRootItem *new_parent = new_feed->parent();
|
FeedsModelRootItem *new_parent = new_feed->parent();
|
||||||
|
@ -51,6 +51,11 @@ class FeedsModel : public QAbstractItemModel {
|
|||||||
return itemForIndex(index)->data(index.column(), role);
|
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;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
QModelIndex index(int row, int column, const QModelIndex &parent) const;
|
QModelIndex index(int row, int column, const QModelIndex &parent) const;
|
||||||
QModelIndex parent(const QModelIndex &child) const;
|
QModelIndex parent(const QModelIndex &child) const;
|
||||||
|
@ -75,6 +75,8 @@
|
|||||||
#define FEEDS_VIEW_INDENTATION 10
|
#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 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_NAME_SETTINGS "config"
|
||||||
#define BACKUP_SUFFIX_SETTINGS ".ini.backup"
|
#define BACKUP_SUFFIX_SETTINGS ".ini.backup"
|
||||||
#define BACKUP_NAME_DATABASE "database"
|
#define BACKUP_NAME_DATABASE "database"
|
||||||
|
@ -603,9 +603,9 @@ void FeedsView::setupAppearance() {
|
|||||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
setIndentation(FEEDS_VIEW_INDENTATION);
|
setIndentation(FEEDS_VIEW_INDENTATION);
|
||||||
setAcceptDrops(false);
|
setAcceptDrops(false);
|
||||||
setDragEnabled(false);
|
setDragEnabled(true);
|
||||||
setDropIndicatorShown(false);
|
setDropIndicatorShown(true);
|
||||||
setDragDropMode(QAbstractItemView::NoDragDrop);
|
setDragDropMode(QAbstractItemView::InternalMove);
|
||||||
setAllColumnsShowFocus(false);
|
setAllColumnsShowFocus(false);
|
||||||
setRootIsDecorated(false);
|
setRootIsDecorated(false);
|
||||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user