Enhanced message previewer.
This commit is contained in:
parent
2956880d10
commit
3bc79c071c
BIN
resources/graphics/icons/mini-kfaenza/image-placeholder.png
Normal file
BIN
resources/graphics/icons/mini-kfaenza/image-placeholder.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 342 B |
BIN
resources/graphics/icons/numix/image-placeholder.png
Normal file
BIN
resources/graphics/icons/numix/image-placeholder.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 342 B |
BIN
resources/graphics/icons/papirus-dark/image-placeholder.png
Normal file
BIN
resources/graphics/icons/papirus-dark/image-placeholder.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 342 B |
BIN
resources/graphics/icons/papirus/image-placeholder.png
Normal file
BIN
resources/graphics/icons/papirus/image-placeholder.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 342 B |
@ -38,8 +38,9 @@ MessagePreviewer::MessagePreviewer(QWidget *parent) : QWidget(parent),
|
||||
// User clicked some URL. Open it in external browser or download?
|
||||
MessageBox box(qApp->mainForm());
|
||||
|
||||
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);
|
||||
|
@ -20,9 +20,6 @@
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -45,16 +42,13 @@
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QTextBrowser" name="m_txtMessage">
|
||||
<widget class="MessageTextBrowser" name="m_txtMessage">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -74,6 +68,13 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>MessageTextBrowser</class>
|
||||
<extends>QTextBrowser</extends>
|
||||
<header>messagetextbrowser.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
28
src/gui/messagetextbrowser.cpp
Normal file
28
src/gui/messagetextbrowser.cpp
Normal file
@ -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();
|
||||
}
|
||||
}
|
19
src/gui/messagetextbrowser.h
Normal file
19
src/gui/messagetextbrowser.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef MESSAGETEXTBROWSER_H
|
||||
#define MESSAGETEXTBROWSER_H
|
||||
|
||||
#include <QTextBrowser>
|
||||
|
||||
|
||||
|
||||
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
|
@ -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 <QVariant>
|
||||
#include <QUrl>
|
||||
#include <QSqlError>
|
||||
@ -328,8 +333,8 @@ QList<Message> 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() {
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class DatabaseQueries {
|
||||
static bool purgeOldMessages(QSqlDatabase db, int older_than_days);
|
||||
static bool purgeRecycleBin(QSqlDatabase db);
|
||||
static QMap<int,int> 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();
|
||||
|
@ -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) {
|
||||
|
@ -128,50 +128,15 @@ bool ServiceRoot::cleanFeeds(QList<Feed*> 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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user