From 3bc79c071cedad64dfc19f54eee1bd927fc39b94 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Wed, 6 Apr 2016 09:16:49 +0200 Subject: [PATCH] Enhanced message previewer. --- .../icons/mini-kfaenza/image-placeholder.png | Bin 0 -> 342 bytes .../icons/numix/image-placeholder.png | Bin 0 -> 342 bytes .../icons/papirus-dark/image-placeholder.png | Bin 0 -> 342 bytes .../icons/papirus/image-placeholder.png | Bin 0 -> 342 bytes src/gui/messagepreviewer.cpp | 3 +- src/gui/messagepreviewer.ui | 15 +- src/gui/messagetextbrowser.cpp | 28 ++++ src/gui/messagetextbrowser.h | 19 +++ src/miscellaneous/databasequeries.cpp | 130 +++++++++++++++++- src/miscellaneous/databasequeries.h | 6 +- src/miscellaneous/iconfactory.h | 9 ++ src/services/abstract/serviceroot.cpp | 81 ++--------- 12 files changed, 204 insertions(+), 87 deletions(-) create mode 100644 resources/graphics/icons/mini-kfaenza/image-placeholder.png create mode 100644 resources/graphics/icons/numix/image-placeholder.png create mode 100644 resources/graphics/icons/papirus-dark/image-placeholder.png create mode 100644 resources/graphics/icons/papirus/image-placeholder.png create mode 100644 src/gui/messagetextbrowser.cpp create mode 100644 src/gui/messagetextbrowser.h diff --git a/resources/graphics/icons/mini-kfaenza/image-placeholder.png b/resources/graphics/icons/mini-kfaenza/image-placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..fada9038b7baf221b7db2bf46d0757c292271982 GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0y~yU|a&ijLbk0m!`vIK#DEEC&cx`hY!^&E^g%9Y6lcy zED7=pW^j0RBMr#mEbxdd2GSm2>~=C6q@vx^#WAGf*4vv0IU5WFTn|QgdTrf0C56#x zk4jY(M^i@1y^ouN4=z*joFu1pJuLI^rFL7Jg&JLpAZSJSRfp+T(T5-F9t{+6g`z9G zQ(srKLRA3OJqxY<^{## zRdP`(kYX@0Ff`LOFwr$I3o$UVGBUR^w$wE+wK6c6#H+p(MMG|WN@iLmZVitE=1T%K OFnGH9xvX~=C6q@vx^#WAGf*4vv0IU5WFTn|QgdTrf0C56#x zk4jY(M^i@1y^ouN4=z*joFu1pJuLI^rFL7Jg&JLpAZSJSRfp+T(T5-F9t{+6g`z9G zQ(srKLRA3OJqxY<^{## zRdP`(kYX@0Ff`LOFwr$I3o$UVGBUR^w$wE+wK6c6#H+p(MMG|WN@iLmZVitE=1T%K OFnGH9xvX~=C6q@vx^#WAGf*4vv0IU5WFTn|QgdTrf0C56#x zk4jY(M^i@1y^ouN4=z*joFu1pJuLI^rFL7Jg&JLpAZSJSRfp+T(T5-F9t{+6g`z9G zQ(srKLRA3OJqxY<^{## zRdP`(kYX@0Ff`LOFwr$I3o$UVGBUR^w$wE+wK6c6#H+p(MMG|WN@iLmZVitE=1T%K OFnGH9xvX~=C6q@vx^#WAGf*4vv0IU5WFTn|QgdTrf0C56#x zk4jY(M^i@1y^ouN4=z*joFu1pJuLI^rFL7Jg&JLpAZSJSRfp+T(T5-F9t{+6g`z9G zQ(srKLRA3OJqxY<^{## zRdP`(kYX@0Ff`LOFwr$I3o$UVGBUR^w$wE+wK6c6#H+p(MMG|WN@iLmZVitE=1T%K OFnGH9xvXmainForm()); - box.setText(tr("You clicked link \"%1\". You can download the link contents or open it in external web browser.").arg(url.toString())); + box.setText(tr("You clicked some link. You can download the link contents or open it in external web browser.")); box.setInformativeText(tr("What action do you want to take?")); + box.setDetailedText(url.toString()); QAbstractButton *btn_open = box.addButton(tr("Open in external browser"), QMessageBox::AcceptRole); QAbstractButton *btn_download = box.addButton(tr("Download"), QMessageBox::RejectRole); QAbstractButton *btn_cancel = box.addButton(QMessageBox::Cancel); diff --git a/src/gui/messagepreviewer.ui b/src/gui/messagepreviewer.ui index 0166bd4d3..99b6606e1 100644 --- a/src/gui/messagepreviewer.ui +++ b/src/gui/messagepreviewer.ui @@ -20,9 +20,6 @@ 0 - - 0 - 0 @@ -45,16 +42,13 @@ true - - 5 - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - + true @@ -74,6 +68,13 @@ + + + MessageTextBrowser + QTextBrowser +
messagetextbrowser.h
+
+
diff --git a/src/gui/messagetextbrowser.cpp b/src/gui/messagetextbrowser.cpp new file mode 100644 index 000000000..c395ac800 --- /dev/null +++ b/src/gui/messagetextbrowser.cpp @@ -0,0 +1,28 @@ +#include "gui/messagetextbrowser.h" + +#include "miscellaneous/application.h" +#include "miscellaneous/iconfactory.h" + + +MessageTextBrowser::MessageTextBrowser(QWidget *parent) : QTextBrowser(parent) { +} + +MessageTextBrowser::~MessageTextBrowser() { +} + +QVariant MessageTextBrowser::loadResource(int type, const QUrl &name) { + Q_UNUSED(name) + + switch (type) { + case QTextDocument::ImageResource: { + if (m_imagePlaceholder.isNull()) { + m_imagePlaceholder = qApp->icons()->pixmap(QSL("image-placeholder")).scaledToWidth(20, Qt::FastTransformation); + } + + return m_imagePlaceholder; + } + + default: + return QVariant(); + } +} diff --git a/src/gui/messagetextbrowser.h b/src/gui/messagetextbrowser.h new file mode 100644 index 000000000..02c0d1c99 --- /dev/null +++ b/src/gui/messagetextbrowser.h @@ -0,0 +1,19 @@ +#ifndef MESSAGETEXTBROWSER_H +#define MESSAGETEXTBROWSER_H + +#include + + + +class MessageTextBrowser : public QTextBrowser { + public: + explicit MessageTextBrowser(QWidget *parent = 0); + virtual ~MessageTextBrowser(); + + QVariant loadResource(int type, const QUrl &name); + + private: + QPixmap m_imagePlaceholder; +}; + +#endif // MESSAGETEXTBROWSER_H diff --git a/src/miscellaneous/databasequeries.cpp b/src/miscellaneous/databasequeries.cpp index 46e29cbc1..8c9ef8fc5 100644 --- a/src/miscellaneous/databasequeries.cpp +++ b/src/miscellaneous/databasequeries.cpp @@ -17,6 +17,11 @@ #include "miscellaneous/databasequeries.h" +#include "services/abstract/category.h" +#include "services/abstract/feed.h" +#include "miscellaneous/application.h" +#include "miscellaneous/iconfactory.h" + #include #include #include @@ -328,8 +333,8 @@ QList DatabaseQueries::getUndeletedMessagesForAccount(QSqlDatabase db, QSqlQuery q(db); q.setForwardOnly(true); q.prepare("SELECT * " - "FROM Messages " - "WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;"); + "FROM Messages " + "WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;"); q.bindValue(QSL(":account_id"), account_id); if (q.exec()) { @@ -616,13 +621,13 @@ bool DatabaseQueries::cleanFeeds(QSqlDatabase db, const QStringList &ids, bool c if (clean_read_only) { q.prepare(QString("UPDATE Messages SET is_deleted = :deleted " - "WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 1 AND account_id = :account_id;") - .arg(ids.join(QSL(", ")))); + "WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 1 AND account_id = :account_id;") + .arg(ids.join(QSL(", ")))); } else { q.prepare(QString("UPDATE Messages SET is_deleted = :deleted " - "WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;") - .arg(ids.join(QSL(", ")))); + "WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;") + .arg(ids.join(QSL(", ")))); } q.bindValue(QSL(":deleted"), 1); @@ -653,5 +658,118 @@ bool DatabaseQueries::deleteLeftoverMessages(QSqlDatabase db, int account_id) { } } +bool DatabaseQueries::storeAccountTree(QSqlDatabase db, RootItem *tree_root, int account_id) { + QSqlQuery query_category(db); + QSqlQuery query_feed(db); + query_category.setForwardOnly(true); + query_feed.setForwardOnly(true); + query_category.prepare("INSERT INTO Categories (parent_id, title, account_id, custom_id) " + "VALUES (:parent_id, :title, :account_id, :custom_id);"); + query_feed.prepare("INSERT INTO Feeds (title, icon, category, protected, update_type, update_interval, account_id, custom_id) " + "VALUES (:title, :icon, :category, :protected, :update_type, :update_interval, :account_id, :custom_id);"); + + // Iterate all children. + foreach (RootItem *child, tree_root->getSubTree()) { + if (child->kind() == RootItemKind::Category) { + query_category.bindValue(QSL(":parent_id"), child->parent()->id()); + query_category.bindValue(QSL(":title"), child->title()); + query_category.bindValue(QSL(":account_id"), account_id); + query_category.bindValue(QSL(":custom_id"), QString::number(child->toCategory()->customId())); + + if (query_category.exec()) { + child->setId(query_category.lastInsertId().toInt()); + } + else { + return false; + } + } + else if (child->kind() == RootItemKind::Feed) { + Feed *feed = child->toFeed(); + + query_feed.bindValue(QSL(":title"), feed->title()); + query_feed.bindValue(QSL(":icon"), qApp->icons()->toByteArray(feed->icon())); + query_feed.bindValue(QSL(":category"), feed->parent()->customId()); + query_feed.bindValue(QSL(":protected"), 0); + query_feed.bindValue(QSL(":update_type"), (int) feed->autoUpdateType()); + query_feed.bindValue(QSL(":update_interval"), feed->autoUpdateInitialInterval()); + query_feed.bindValue(QSL(":account_id"), account_id); + query_feed.bindValue(QSL(":custom_id"), feed->customId()); + + if (query_feed.exec()) { + feed->setId(query_feed.lastInsertId().toInt()); + } + else { + return false; + } + } + } + + return true; +} + +QStringList DatabaseQueries::customIdsOfMessagesFromAccount(QSqlDatabase db, int account_id, bool *ok) { + QSqlQuery query(db); + QStringList ids; + query.setForwardOnly(true); + query.prepare(QSL("SELECT custom_id FROM Messages WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;")); + query.bindValue(QSL(":account_id"), account_id); + + if (ok != NULL) { + *ok = query.exec(); + } + else { + query.exec(); + } + + while (query.next()) { + ids.append(query.value(0).toString()); + } + + return ids; +} + +QStringList DatabaseQueries::customIdsOfMessagesFromBin(QSqlDatabase db, int account_id, bool *ok) { + QSqlQuery query(db); + QStringList ids; + query.setForwardOnly(true); + query.prepare(QSL("SELECT custom_id FROM Messages WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;")); + query.bindValue(QSL(":account_id"), account_id); + + if (ok != NULL) { + *ok = query.exec(); + } + else { + query.exec(); + } + + while (query.next()) { + ids.append(query.value(0).toString()); + } + + return ids; +} + +QStringList DatabaseQueries::customIdsOfMessagesFromFeed(QSqlDatabase db, int feed_custom_id, int account_id, bool *ok) { + QSqlQuery query(db); + QStringList ids; + query.setForwardOnly(true); + query.prepare(QSL("SELECT custom_id FROM Messages WHERE is_deleted = 0 AND is_pdeleted = 0 AND feed = :feed AND account_id = :account_id;")); + query.bindValue(QSL(":account_id"), account_id); + query.bindValue(QSL(":feed"), feed_custom_id); + + if (ok != NULL) { + *ok = query.exec(); + } + else { + query.exec(); + } + + while (query.next()) { + ids.append(query.value(0).toString()); + } + + return ids; +} + DatabaseQueries::DatabaseQueries() { } diff --git a/src/miscellaneous/databasequeries.h b/src/miscellaneous/databasequeries.h index af89dba58..8f9264b8e 100644 --- a/src/miscellaneous/databasequeries.h +++ b/src/miscellaneous/databasequeries.h @@ -38,7 +38,7 @@ class DatabaseQueries { static bool purgeOldMessages(QSqlDatabase db, int older_than_days); static bool purgeRecycleBin(QSqlDatabase db); static QMap getMessageCountsForCategory(QSqlDatabase db, int custom_id, int account_id, - bool including_total_counts, bool *ok = NULL); + bool including_total_counts, bool *ok = NULL); 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); @@ -52,6 +52,10 @@ class DatabaseQueries { 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); static bool deleteLeftoverMessages(QSqlDatabase db, int account_id); + static bool storeAccountTree(QSqlDatabase db, RootItem *tree_root, int account_id); + 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); private: explicit DatabaseQueries(); diff --git a/src/miscellaneous/iconfactory.h b/src/miscellaneous/iconfactory.h index e165a7274..4d46c66a1 100755 --- a/src/miscellaneous/iconfactory.h +++ b/src/miscellaneous/iconfactory.h @@ -46,6 +46,15 @@ class IconFactory : public QObject { void clearCache(); + inline QPixmap pixmap(const QString &name) { + if (m_currentIconTheme == APP_NO_THEME) { + return QPixmap(); + } + else { + return QPixmap(APP_THEME_PATH + QDir::separator() + m_currentIconTheme + QDir::separator() + name + APP_THEME_SUFFIX); + } + } + // Returns icon from active theme or invalid icon if // "no icon theme" is set. inline QIcon fromTheme(const QString &name) { diff --git a/src/services/abstract/serviceroot.cpp b/src/services/abstract/serviceroot.cpp index a69bbe117..d4636dbb6 100755 --- a/src/services/abstract/serviceroot.cpp +++ b/src/services/abstract/serviceroot.cpp @@ -128,50 +128,15 @@ bool ServiceRoot::cleanFeeds(QList items, bool clean_read_only) { void ServiceRoot::storeNewFeedTree(RootItem *root) { QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - QSqlQuery query_category(database); - QSqlQuery query_feed(database); - query_category.prepare("INSERT INTO Categories (parent_id, title, account_id, custom_id) " - "VALUES (:parent_id, :title, :account_id, :custom_id);"); - query_feed.prepare("INSERT INTO Feeds (title, icon, category, protected, update_type, update_interval, account_id, custom_id) " - "VALUES (:title, :icon, :category, :protected, :update_type, :update_interval, :account_id, :custom_id);"); + if (DatabaseQueries::storeAccountTree(database, root, accountId())) { + RecycleBin *bin = recycleBin(); - // Iterate all children. - foreach (RootItem *child, root->getSubTree()) { - if (child->kind() == RootItemKind::Category) { - query_category.bindValue(QSL(":parent_id"), child->parent()->id()); - query_category.bindValue(QSL(":title"), child->title()); - query_category.bindValue(QSL(":account_id"), accountId()); - query_category.bindValue(QSL(":custom_id"), QString::number(child->toCategory()->customId())); - - if (query_category.exec()) { - child->setId(query_category.lastInsertId().toInt()); - } + if (bin != NULL && !childItems().contains(bin)) { + // As the last item, add recycle bin, which is needed. + appendChild(bin); + bin->updateCounts(true); } - else if (child->kind() == RootItemKind::Feed) { - Feed *feed = child->toFeed(); - - query_feed.bindValue(QSL(":title"), feed->title()); - query_feed.bindValue(QSL(":icon"), qApp->icons()->toByteArray(feed->icon())); - query_feed.bindValue(QSL(":category"), feed->parent()->customId()); - query_feed.bindValue(QSL(":protected"), 0); - query_feed.bindValue(QSL(":update_type"), (int) feed->autoUpdateType()); - query_feed.bindValue(QSL(":update_interval"), feed->autoUpdateInitialInterval()); - query_feed.bindValue(QSL(":account_id"), accountId()); - query_feed.bindValue(QSL(":custom_id"), feed->customId()); - - if (query_feed.exec()) { - feed->setId(query_feed.lastInsertId().toInt()); - } - } - } - - RecycleBin *bin = recycleBin(); - - if (bin != NULL && !childItems().contains(bin)) { - // As the last item, add recycle bin, which is needed. - appendChild(bin); - bin->updateCounts(true); } } @@ -289,47 +254,19 @@ QStringList ServiceRoot::customIDSOfMessagesForItem(RootItem *item) { case RootItemKind::ServiceRoot: { QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - QSqlQuery query(database); - - query.prepare(QSL("SELECT custom_id FROM Messages WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;")); - query.bindValue(QSL(":account_id"), accountId()); - query.exec(); - - while (query.next()) { - list.append(query.value(0).toString()); - } - + list = DatabaseQueries::customIdsOfMessagesFromAccount(database, accountId()); break; } case RootItemKind::Bin: { QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - QSqlQuery query(database); - - query.prepare(QSL("SELECT custom_id FROM Messages WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;")); - query.bindValue(QSL(":account_id"), accountId()); - query.exec(); - - while (query.next()) { - list.append(query.value(0).toString()); - } - + list = DatabaseQueries::customIdsOfMessagesFromBin(database, accountId()); break; } case RootItemKind::Feed: { QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); - QSqlQuery query(database); - - query.prepare(QSL("SELECT custom_id FROM Messages WHERE is_deleted = 0 AND is_pdeleted = 0 AND feed = :feed AND account_id = :account_id;")); - query.bindValue(QSL(":account_id"), accountId()); - query.bindValue(QSL(":feed"), item->customId()); - query.exec(); - - while (query.next()) { - list.append(query.value(0).toString()); - } - + list = DatabaseQueries::customIdsOfMessagesFromFeed(database, item->customId(), accountId()); break; }