Saving of multicolumn sorts enabled.

This commit is contained in:
martinrotter 2017-05-09 11:13:15 +02:00
parent 78872dfa21
commit 4abdc1738c
23 changed files with 89 additions and 67 deletions

View File

@ -48,7 +48,7 @@ class Message {
// Creates Message from given record, which contains
// row from query SELECT * FROM Messages WHERE ....;
static Message fromSqlRecord(const QSqlRecord &record, bool *result = NULL);
static Message fromSqlRecord(const QSqlRecord &record, bool *result = nullptr);
QString m_title;
QString m_url;

View File

@ -25,25 +25,40 @@
#include "miscellaneous/databasequeries.h"
#include "services/abstract/serviceroot.h"
#include <QSqlField>
MessagesModel::MessagesModel(QObject *parent)
: QSqlRelationalTableModel(parent, qApp->database()->connection(QSL("MessagesModel"), DatabaseFactory::FromSettings)),
m_fieldNames(QHash<int,QString>()), m_sortColumn(QList<int>()), m_sortOrder(QList<Qt::SortOrder>()),
m_fieldNames(QMap<int,QString>()), m_sortColumn(QList<int>()), m_sortOrder(QList<Qt::SortOrder>()),
m_messageHighlighter(NoHighlighting), m_customDateFormat(QString()) {
setupFonts();
setupIcons();
setupHeaderData();
updateDateFormat();
//m_fieldNames[0] =
m_fieldNames[MSG_DB_ID_INDEX] = "Messages.id";
m_fieldNames[MSG_DB_READ_INDEX] = "Messages.is_read";
m_fieldNames[MSG_DB_DELETED_INDEX] = "Messages.is_deleted";
m_fieldNames[MSG_DB_IMPORTANT_INDEX] = "Messages.is_important";
m_fieldNames[MSG_DB_FEED_TITLE_INDEX] = "Feeds.title";
m_fieldNames[MSG_DB_TITLE_INDEX] = "Messages.title";
m_fieldNames[MSG_DB_URL_INDEX] = "Messages.url";
m_fieldNames[MSG_DB_AUTHOR_INDEX] = "Messages.author";
m_fieldNames[MSG_DB_DCREATED_INDEX] = "Messages.date_created";
m_fieldNames[MSG_DB_CONTENTS_INDEX] = "Messages.contents";
m_fieldNames[MSG_DB_PDELETED_INDEX] = "Messages.is_pdeleted";
m_fieldNames[MSG_DB_ENCLOSURES_INDEX] = "Messages.enclosures";
m_fieldNames[MSG_DB_ACCOUNT_ID_INDEX] = "Messages.account_id";
m_fieldNames[MSG_DB_CUSTOM_ID_INDEX] = "Messages.custom_id";
m_fieldNames[MSG_DB_CUSTOM_HASH_INDEX] = "Messages.custom_hash";
m_fieldNames[MSG_DB_FEED_CUSTOM_ID_INDEX] = "Messages.feed";
// Set desired table and edit strategy.
// NOTE: Changes to the database are actually NOT submitted
// via model, but via DIRECT SQL calls are used to do persistent messages.
setEditStrategy(QSqlTableModel::OnManualSubmit);
setTable(QSL("Messages"));
//setRelation(MSG_DB_FEED_INDEX, QSqlRelation("Feeds", "custom_id", "title"));
setEditStrategy(QSqlTableModel::OnManualSubmit);
loadMessages(nullptr);
}
@ -51,23 +66,31 @@ MessagesModel::~MessagesModel() {
qDebug("Destroying MessagesModel instance.");
}
QString MessagesModel::selectStatement() const {
//return QSqlRelationalTableModel::selectStatement();
QString MessagesModel::formatFields() const {
return m_fieldNames.values().join(QSL(", "));
}
return QL1S("SELECT Messages.id, is_read, is_deleted, is_important, Feeds.title, Messages.title, Messages.url, author, Messages.date_created, contents, is_pdeleted, enclosures, Messages.account_id, Messages.custom_id, custom_hash, Messages.feed "
"FROM Messages LEFT JOIN Feeds ON Messages.feed = Feeds.custom_id WHERE ") +
filter() + " " + orderByClause();
QString MessagesModel::selectStatement() const {
return QL1S("SELECT ") + formatFields() +
QSL(" FROM Messages LEFT JOIN Feeds ON Messages.feed = Feeds.custom_id WHERE ") +
filter() + orderByClause() + QL1C(';');
}
QString MessagesModel::orderByClause() const {
if (m_sortColumn.isEmpty()) {
return QString();
}
else {
QStringList sorts;
auto aaa = record().fieldName(4);
return QSqlRelationalTableModel::orderByClause();
QString clause(QSL("ORDER BY "));
for (int i = m_sortColumn.size() - 1; i >= 0; i--) {
QString field_name(m_fieldNames[m_sortColumn[i]]);
sorts.append(field_name + (m_sortOrder[i] == Qt::AscendingOrder ? QSL(" ASC") : QSL(" DESC")));
}
return QL1S(" ORDER BY ") + sorts.join(QSL(", "));
}
}
void MessagesModel::setupIcons() {
@ -101,6 +124,8 @@ void MessagesModel::addSortState(int column, Qt::SortOrder order) {
m_sortColumn.append(column);
m_sortOrder.append(order);
qDebug("Added sort state, select statement is now:\n'%s'", qPrintable(selectStatement()));
}
void MessagesModel::setupFonts() {
@ -127,8 +152,6 @@ void MessagesModel::loadMessages(RootItem *item) {
}
}
qDebug("Select statement when selecting msg from item:\n'%s'", qPrintable(selectStatement()));
fetchAllData();
}

View File

@ -50,9 +50,6 @@ class MessagesModel : public QSqlRelationalTableModel {
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QString orderByClause() const;
QString selectStatement() const;
// Returns message at given index.
Message messageAt(int row_index) const;
int messageId(int row_index) const;
@ -102,13 +99,17 @@ class MessagesModel : public QSqlRelationalTableModel {
void setupFonts();
void setupIcons();
QString orderByClause() const;
QString selectStatement() const;
QString formatFields() const;
// Fetches ALL available data to the model.
void fetchAllData();
// NOTE: These two lists contain data for multicolumn sorting.
// They are always same length. Most important sort column/order
// are located in the end of these lists.
QHash<int,QString> m_fieldNames;
QMap<int,QString> m_fieldNames;
QList<int> m_sortColumn;
QList<Qt::SortOrder> m_sortOrder;

View File

@ -584,6 +584,4 @@ void MessagesView::onSortIndicatorChanged(int column, Qt::SortOrder order) {
// Repopulate the shit.
sort(column, order, true, false, false);
emit currentMessageRemoved();
qDebug("Current order by clause is '%s'.", qPrintable(m_sourceModel->orderByClause()));
}

View File

@ -57,8 +57,8 @@ class SystemTrayIcon : public QSystemTrayIcon {
void setNumber(int number = -1, bool any_new_message = false);
void showMessage(const QString &title, const QString &message, MessageIcon icon = Information,
int milliseconds_timeout_hint = TRAY_ICON_BUBBLE_TIMEOUT, QObject *click_target = NULL,
const char *click_slot = NULL);
int milliseconds_timeout_hint = TRAY_ICON_BUBBLE_TIMEOUT, QObject *click_target = nullptr,
const char *click_slot = nullptr);
// Returns true if tray icon CAN be constructed on this machine.
static bool isSystemTrayAvailable();

View File

@ -107,8 +107,8 @@ class Application : public QtSingleApplication {
// Displays given simple message in tray icon bubble or OSD
// or in message box if tray icon is disabled.
void showGuiMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon message_type,
QWidget *parent = NULL, bool show_at_least_msgbox = false,
QObject *invokation_target = NULL, const char *invokation_slot = NULL);
QWidget *parent = nullptr, bool show_at_least_msgbox = false,
QObject *invokation_target = nullptr, const char *invokation_slot = nullptr);
// Returns pointer to "GOD" application singleton.
inline static Application *instance() {

46
src/miscellaneous/databasequeries.h Normal file → Executable file
View File

@ -49,26 +49,26 @@ class DatabaseQueries {
// Obtain counts of unread/all messages.
static QMap<int,QPair<int,int> > getMessageCountsForCategory(QSqlDatabase db, int custom_id, int account_id,
bool including_total_counts, bool *ok = NULL);
bool including_total_counts, bool *ok = nullptr);
static QMap<int,QPair<int,int> > getMessageCountsForAccount(QSqlDatabase db, int account_id,
bool including_total_counts, bool *ok = NULL);
bool including_total_counts, bool *ok = nullptr);
static int getMessageCountsForFeed(QSqlDatabase db, int feed_custom_id, int account_id,
bool including_total_counts, bool *ok = NULL);
static int getMessageCountsForBin(QSqlDatabase db, int account_id, bool including_total_counts, bool *ok = NULL);
bool including_total_counts, bool *ok = nullptr);
static int getMessageCountsForBin(QSqlDatabase db, int account_id, bool including_total_counts, bool *ok = nullptr);
// Get messages (for newspaper view for example).
static QList<Message> getUndeletedMessagesForFeed(QSqlDatabase db, int feed_custom_id, int account_id, bool *ok = NULL);
static QList<Message> getUndeletedMessagesForBin(QSqlDatabase db, int account_id, bool *ok = NULL);
static QList<Message> getUndeletedMessagesForAccount(QSqlDatabase db, int account_id, bool *ok = NULL);
static QList<Message> getUndeletedMessagesForFeed(QSqlDatabase db, int feed_custom_id, int account_id, bool *ok = nullptr);
static QList<Message> getUndeletedMessagesForBin(QSqlDatabase db, int account_id, bool *ok = nullptr);
static QList<Message> getUndeletedMessagesForAccount(QSqlDatabase db, int account_id, bool *ok = nullptr);
// Custom ID accumulators.
static QStringList customIdsOfMessagesFromAccount(QSqlDatabase db, int account_id, bool *ok = NULL);
static QStringList customIdsOfMessagesFromBin(QSqlDatabase db, int account_id, bool *ok = NULL);
static QStringList customIdsOfMessagesFromFeed(QSqlDatabase db, int feed_custom_id, int account_id, bool *ok = NULL);
static QStringList customIdsOfMessagesFromAccount(QSqlDatabase db, int account_id, bool *ok = nullptr);
static QStringList customIdsOfMessagesFromBin(QSqlDatabase db, int account_id, bool *ok = nullptr);
static QStringList customIdsOfMessagesFromFeed(QSqlDatabase db, int feed_custom_id, int account_id, bool *ok = nullptr);
// Common accounts methods.
static int updateMessages(QSqlDatabase db, const QList<Message> &messages, int feed_custom_id,
int account_id, const QString &url, bool *any_message_changed, bool *ok = NULL);
int account_id, const QString &url, bool *any_message_changed, bool *ok = nullptr);
static bool deleteAccount(QSqlDatabase db, int account_id);
static bool deleteAccountData(QSqlDatabase db, int account_id, bool delete_messages_too);
static bool cleanFeeds(QSqlDatabase db, const QStringList &ids, bool clean_read_only, int account_id);
@ -78,21 +78,21 @@ class DatabaseQueries {
int auto_update_interval);
// ownCloud account.
static QList<ServiceRoot*> getOwnCloudAccounts(QSqlDatabase db, bool *ok = NULL);
static QList<ServiceRoot*> getOwnCloudAccounts(QSqlDatabase db, bool *ok = nullptr);
static bool deleteOwnCloudAccount(QSqlDatabase db, int account_id);
static bool overwriteOwnCloudAccount(QSqlDatabase db, const QString &username, const QString &password,
const QString &url, bool force_server_side_feed_update, int account_id);
static bool createOwnCloudAccount(QSqlDatabase db, int id_to_assign, const QString &username, const QString &password,
const QString &url, bool force_server_side_feed_update);
static int createAccount(QSqlDatabase db, const QString &code, bool *ok = NULL);
static Assignment getOwnCloudCategories(QSqlDatabase db, int account_id, bool *ok = NULL);
static Assignment getOwnCloudFeeds(QSqlDatabase db, int account_id, bool *ok = NULL);
static int createAccount(QSqlDatabase db, const QString &code, bool *ok = nullptr);
static Assignment getOwnCloudCategories(QSqlDatabase db, int account_id, bool *ok = nullptr);
static Assignment getOwnCloudFeeds(QSqlDatabase db, int account_id, bool *ok = nullptr);
// Standard account.
static bool deleteFeed(QSqlDatabase db, int feed_custom_id, int account_id);
static bool deleteCategory(QSqlDatabase db, int id);
static int addCategory(QSqlDatabase db, int parent_id, int account_id, const QString &title,
const QString &description, QDateTime creation_date, const QIcon &icon, bool *ok = NULL);
const QString &description, QDateTime creation_date, const QIcon &icon, bool *ok = nullptr);
static bool editCategory(QSqlDatabase db, int parent_id, int category_id,
const QString &title, const QString &description, const QIcon &icon);
static int addFeed(QSqlDatabase db, int parent_id, int account_id, const QString &title,
@ -100,18 +100,18 @@ class DatabaseQueries {
const QString &encoding, const QString &url, bool is_protected,
const QString &username, const QString &password,
Feed::AutoUpdateType auto_update_type,
int auto_update_interval, StandardFeed::Type feed_format, bool *ok = NULL);
int auto_update_interval, StandardFeed::Type feed_format, bool *ok = nullptr);
static bool editFeed(QSqlDatabase db, int parent_id, int feed_id, const QString &title,
const QString &description, const QIcon &icon,
const QString &encoding, const QString &url, bool is_protected,
const QString &username, const QString &password, Feed::AutoUpdateType auto_update_type,
int auto_update_interval, StandardFeed::Type feed_format);
static QList<ServiceRoot*> getAccounts(QSqlDatabase db, bool *ok = NULL);
static Assignment getCategories(QSqlDatabase db, int account_id, bool *ok = NULL);
static Assignment getFeeds(QSqlDatabase db, int account_id, bool *ok = NULL);
static QList<ServiceRoot*> getAccounts(QSqlDatabase db, bool *ok = nullptr);
static Assignment getCategories(QSqlDatabase db, int account_id, bool *ok = nullptr);
static Assignment getFeeds(QSqlDatabase db, int account_id, bool *ok = nullptr);
// TT-RSS acccount.
static QList<ServiceRoot*> getTtRssAccounts(QSqlDatabase db, bool *ok = NULL);
static QList<ServiceRoot*> getTtRssAccounts(QSqlDatabase db, bool *ok = nullptr);
static bool deleteTtRssAccount(QSqlDatabase db, int account_id);
static bool overwriteTtRssAccount(QSqlDatabase db, const QString &username, const QString &password,
bool auth_protected, const QString &auth_username, const QString &auth_password,
@ -120,8 +120,8 @@ class DatabaseQueries {
const QString &password, bool auth_protected, const QString &auth_username,
const QString &auth_password, const QString &url,
bool force_server_side_feed_update);
static Assignment getTtRssCategories(QSqlDatabase db, int account_id, bool *ok = NULL);
static Assignment getTtRssFeeds(QSqlDatabase db, int account_id, bool *ok = NULL);
static Assignment getTtRssCategories(QSqlDatabase db, int account_id, bool *ok = nullptr);
static Assignment getTtRssFeeds(QSqlDatabase db, int account_id, bool *ok = nullptr);
private:
explicit DatabaseQueries();

View File

@ -61,7 +61,7 @@ class SkinFactory : public QObject {
QString selectedSkinName() const;
// Gets skin about a particular skin.
Skin skinInfo(const QString &skin_name, bool *ok = NULL) const;
Skin skinInfo(const QString &skin_name, bool *ok = nullptr) const;
// Returns list of installed skins.
QList<Skin> installedSkins() const;

View File

@ -25,7 +25,7 @@ class Category : public RootItem {
Q_OBJECT
public:
explicit Category(RootItem *parent = NULL);
explicit Category(RootItem *parent = nullptr);
virtual ~Category();
void updateCounts(bool including_total_count);

View File

@ -50,7 +50,7 @@ class Feed : public RootItem, public QRunnable {
};
// Constructors.
explicit Feed(RootItem *parent = NULL);
explicit Feed(RootItem *parent = nullptr);
virtual ~Feed();
QList<Message> undeletedMessages() const;

View File

@ -25,7 +25,7 @@ class RecycleBin : public RootItem {
Q_OBJECT
public:
explicit RecycleBin(RootItem *parent_item = NULL);
explicit RecycleBin(RootItem *parent_item = nullptr);
virtual ~RecycleBin();
QVariant data(int column, int role) const;

View File

@ -67,7 +67,7 @@ class RootItem : public QObject {
};
// Constructors and destructors.
explicit RootItem(RootItem *parent_item = NULL);
explicit RootItem(RootItem *parent_item = nullptr);
virtual ~RootItem();
virtual QString hashCode() const;

View File

@ -42,7 +42,7 @@ class ServiceRoot : public RootItem {
Q_OBJECT
public:
explicit ServiceRoot(RootItem *parent = NULL);
explicit ServiceRoot(RootItem *parent = nullptr);
virtual ~ServiceRoot();
bool deleteViaGui();

View File

@ -25,7 +25,7 @@ class OwnCloudCategory : public Category {
Q_OBJECT
public:
explicit OwnCloudCategory(RootItem *parent = NULL);
explicit OwnCloudCategory(RootItem *parent = nullptr);
explicit OwnCloudCategory(const QSqlRecord &record);
virtual ~OwnCloudCategory();
};

View File

@ -27,7 +27,7 @@ class OwnCloudFeed : public Feed {
Q_OBJECT
public:
explicit OwnCloudFeed(RootItem *parent = NULL);
explicit OwnCloudFeed(RootItem *parent = nullptr);
explicit OwnCloudFeed(const QSqlRecord &record);
virtual ~OwnCloudFeed();

View File

@ -27,7 +27,7 @@ class OwnCloudRecycleBin : public RecycleBin {
Q_OBJECT
public:
explicit OwnCloudRecycleBin(RootItem *parent = NULL);
explicit OwnCloudRecycleBin(RootItem *parent = nullptr);
virtual ~OwnCloudRecycleBin();
OwnCloudServiceRoot *serviceRoot();

View File

@ -35,7 +35,7 @@ class StandardCategory : public Category {
public:
// Constructors and destructors
explicit StandardCategory(RootItem *parent_item = NULL);
explicit StandardCategory(RootItem *parent_item = nullptr);
explicit StandardCategory(const StandardCategory &other);
explicit StandardCategory(const QSqlRecord &record);
virtual ~StandardCategory();

View File

@ -48,7 +48,7 @@ class StandardFeed : public Feed {
};
// Constructors and destructors.
explicit StandardFeed(RootItem *parent_item = NULL);
explicit StandardFeed(RootItem *parent_item = nullptr);
explicit StandardFeed(const StandardFeed &other);
explicit StandardFeed(const QSqlRecord &record);
virtual ~StandardFeed();

View File

@ -34,7 +34,7 @@ class StandardServiceRoot : public ServiceRoot {
Q_OBJECT
public:
explicit StandardServiceRoot(RootItem *parent = NULL);
explicit StandardServiceRoot(RootItem *parent = nullptr);
virtual ~StandardServiceRoot();
// Start/stop root.

View File

@ -29,7 +29,7 @@ class TtRssCategory : public Category {
Q_OBJECT
public:
explicit TtRssCategory(RootItem *parent = NULL);
explicit TtRssCategory(RootItem *parent = nullptr);
explicit TtRssCategory(const QSqlRecord &record);
virtual ~TtRssCategory();

View File

@ -29,7 +29,7 @@ class TtRssFeed : public Feed {
Q_OBJECT
public:
explicit TtRssFeed(RootItem *parent = NULL);
explicit TtRssFeed(RootItem *parent = nullptr);
explicit TtRssFeed(const QSqlRecord &record);
virtual ~TtRssFeed();

View File

@ -27,7 +27,7 @@ class TtRssRecycleBin : public RecycleBin {
Q_OBJECT
public:
explicit TtRssRecycleBin(RootItem *parent = NULL);
explicit TtRssRecycleBin(RootItem *parent = nullptr);
virtual ~TtRssRecycleBin();
TtRssServiceRoot *serviceRoot();

View File

@ -33,7 +33,7 @@ class TtRssServiceRoot : public ServiceRoot, public CacheForServiceRoot {
Q_OBJECT
public:
explicit TtRssServiceRoot(RootItem *parent = NULL);
explicit TtRssServiceRoot(RootItem *parent = nullptr);
virtual ~TtRssServiceRoot();
void start(bool freshly_activated);