diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml
index 3c5eb5c37..83f988c6b 100644
--- a/resources/desktop/com.github.rssguard.appdata.xml
+++ b/resources/desktop/com.github.rssguard.appdata.xml
@@ -26,7 +26,7 @@
https://github.com/sponsors/martinrotter
-
+
none
diff --git a/src/librssguard/core/messageobject.cpp b/src/librssguard/core/messageobject.cpp
index 8d9603c4c..e99bed915 100644
--- a/src/librssguard/core/messageobject.cpp
+++ b/src/librssguard/core/messageobject.cpp
@@ -3,6 +3,7 @@
#include "core/messageobject.h"
#include "3rd-party/boolinq/boolinq.h"
+#include "database/databasefactory.h"
#include
#include
@@ -65,9 +66,8 @@ bool MessageObject::isDuplicateWithAttribute(MessageObject::DuplicationAttribute
QString full_query = QSL("SELECT COUNT(*) FROM Messages WHERE ") + where_clauses.join(QSL(" AND ")) + QSL(";");
qDebugNN << LOGSEC_MESSAGEMODEL
- << "Query for MSG duplicate identification is: '"
- << full_query
- << "'.";
+ << "Prepared query for MSG duplicate identification is:"
+ << QUOTE_W_SPACE_DOT(full_query);
q.setForwardOnly(true);
q.prepare(full_query);
@@ -77,20 +77,23 @@ bool MessageObject::isDuplicateWithAttribute(MessageObject::DuplicationAttribute
}
if (q.exec() && q.next()) {
+ qDebugNN << LOGSEC_DB
+ << "Executed SQL for message duplicates check:"
+ << QUOTE_W_SPACE_DOT(DatabaseFactory::lastExecutedQuery(q));
+
if (q.record().value(0).toInt() > 0) {
// Whoops, we have the "same" message in database.
- qDebugNN << LOGSEC_MESSAGEMODEL
- << "Message '"
- << title()
- << "' was identified as duplicate by filter script.";
+ qDebugNN << LOGSEC_CORE
+ << "Message"
+ << QUOTE_W_SPACE(title())
+ << "was identified as duplicate by filter script.";
return true;
}
}
else if (q.lastError().isValid()) {
- qWarningNN << LOGSEC_MESSAGEMODEL
- << "Error when checking for duplicate messages via filtering system, error: '"
- << q.lastError().text()
- << "'.";
+ qWarningNN << LOGSEC_CORE
+ << "Error when checking for duplicate messages via filtering system, error:"
+ << QUOTE_W_SPACE_DOT(q.lastError().text());
}
return false;
diff --git a/src/librssguard/database/databasefactory.cpp b/src/librssguard/database/databasefactory.cpp
index 98bd56311..3e6ab929f 100644
--- a/src/librssguard/database/databasefactory.cpp
+++ b/src/librssguard/database/databasefactory.cpp
@@ -12,7 +12,9 @@
#include "miscellaneous/textfactory.h"
#include
+#include
#include
+#include
#include
#include
@@ -78,6 +80,25 @@ DatabaseDriver* DatabaseFactory::driverForType(DatabaseDriver::DriverType d) con
});
}
+QString DatabaseFactory::lastExecutedQuery(const QSqlQuery& query) {
+ QString str = query.lastQuery();
+ QMapIterator it(query.boundValues());
+
+ while (it.hasNext()) {
+ it.next();
+
+ if (it.value().type() == QVariant::Type::Char ||
+ it.value().type() == QVariant::Type::String) {
+ str.replace(it.key(), QSL("'%1'").arg(it.value().toString()));
+ }
+ else {
+ str.replace(it.key(), it.value().toString());
+ }
+ }
+
+ return str;
+}
+
QString DatabaseFactory::escapeQuery(const QString& query) {
return QString(query)
.replace(QSL("'"), QSL("''"));
diff --git a/src/librssguard/database/databasefactory.h b/src/librssguard/database/databasefactory.h
index 2c24c6bbe..726f50cf5 100644
--- a/src/librssguard/database/databasefactory.h
+++ b/src/librssguard/database/databasefactory.h
@@ -24,6 +24,7 @@ class DatabaseFactory : public QObject {
DatabaseDriver* driver() const;
DatabaseDriver* driverForType(DatabaseDriver::DriverType d) const;
+ static QString lastExecutedQuery(const QSqlQuery& query);
static QString escapeQuery(const QString& query);
private:
diff --git a/src/librssguard/gui/dialogs/formmain.cpp b/src/librssguard/gui/dialogs/formmain.cpp
index 5c1ff8131..43824495b 100644
--- a/src/librssguard/gui/dialogs/formmain.cpp
+++ b/src/librssguard/gui/dialogs/formmain.cpp
@@ -804,7 +804,9 @@ void FormMain::createConnections() {
connect(m_ui->m_actionSelectPreviousMessage,
&QAction::triggered, tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::selectPreviousItem);
connect(m_ui->m_actionSwitchMessageListOrientation, &QAction::triggered,
- tabWidget()->feedMessageViewer(), &FeedMessageViewer::switchMessageSplitterOrientation);
+ tabWidget()->feedMessageViewer(), [this]() {
+ tabWidget()->feedMessageViewer()->switchMessageSplitterOrientation(true);
+ });
connect(m_ui->m_actionShowOnlyUnreadItems, &QAction::toggled,
tabWidget()->feedMessageViewer(), &FeedMessageViewer::toggleShowOnlyUnreadFeeds);
connect(m_ui->m_actionShowTreeBranches, &QAction::toggled,
diff --git a/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp b/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp
index 3d0193a51..27908a3f3 100644
--- a/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp
+++ b/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp
@@ -596,6 +596,7 @@ Message FormMessageFiltersManager::testingMessage() const {
msg.m_feedId = NO_PARENT_CATEGORY;
msg.m_url = m_ui.m_txtSampleUrl->text();
+ msg.m_customId = m_ui.m_txtSampleUrl->text();
msg.m_title = m_ui.m_txtSampleTitle->text();
msg.m_author = m_ui.m_txtSampleAuthor->text();
msg.m_isRead = m_ui.m_cbSampleRead->isChecked();
diff --git a/src/librssguard/gui/feedmessageviewer.cpp b/src/librssguard/gui/feedmessageviewer.cpp
index 5c7343fb7..70e78e450 100644
--- a/src/librssguard/gui/feedmessageviewer.cpp
+++ b/src/librssguard/gui/feedmessageviewer.cpp
@@ -2,6 +2,7 @@
#include "gui/feedmessageviewer.h"
+#include "3rd-party/boolinq/boolinq.h"
#include "core/feeddownloader.h"
#include "core/feedsproxymodel.h"
#include "core/messagesproxymodel.h"
@@ -23,6 +24,7 @@
#include "miscellaneous/mutex.h"
#include "miscellaneous/settings.h"
#include "miscellaneous/systemfactory.h"
+#include "miscellaneous/templates.h"
#include "services/standard/standardfeed.h"
#include "services/standard/standardfeedsimportexportmodel.h"
#include "services/standard/standardserviceroot.h"
@@ -87,8 +89,19 @@ void FeedMessageViewer::saveSize() {
m_feedsView->saveAllExpandStates();
// Store offsets of splitters.
- settings->setValue(GROUP(GUI), GUI::SplitterFeeds, QString(m_feedSplitter->saveState().toBase64()));
- settings->setValue(GROUP(GUI), GUI::SplitterMessages, QString(m_messageSplitter->saveState().toBase64()));
+ settings->setValue(GROUP(GUI), GUI::SplitterFeeds, toVariant(m_feedSplitter->sizes()));
+
+ if (!settings->value(GROUP(GUI), SETTING(GUI::SplitterMessagesIsVertical)).toBool()) {
+ settings->setValue(GROUP(GUI),
+ GUI::SplitterMessagesHorizontal,
+ toVariant(m_messageSplitter->sizes()));
+ }
+ else {
+ settings->setValue(GROUP(GUI),
+ GUI::SplitterMessagesVertical,
+ toVariant(m_messageSplitter->sizes()));
+ }
+
settings->setValue(GROUP(GUI), GUI::MessageViewState, QString(m_messagesView->saveHeaderState().toBase64()));
// Store "visibility" of toolbars and list headers.
@@ -100,9 +113,19 @@ void FeedMessageViewer::loadSize() {
const Settings* settings = qApp->settings();
// Restore offsets of splitters.
- m_feedSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::SplitterFeeds)).toString().toLocal8Bit()));
- m_messageSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI),
- SETTING(GUI::SplitterMessages)).toString().toLocal8Bit()));
+ m_feedSplitter->setSizes(toList(settings->value(GROUP(GUI),
+ SETTING(GUI::SplitterFeeds))));
+
+ if (!settings->value(GROUP(GUI), SETTING(GUI::SplitterMessagesIsVertical)).toBool()) {
+ switchMessageSplitterOrientation(false);
+ m_messageSplitter->setSizes(toList(settings->value(GROUP(GUI),
+ SETTING(GUI::SplitterMessagesHorizontal))));
+ }
+ else {
+ m_messageSplitter->setSizes(toList(settings->value(GROUP(GUI),
+ SETTING(GUI::SplitterMessagesVertical))));
+
+ }
QString settings_msg_header = settings->value(GROUP(GUI), SETTING(GUI::MessageViewState)).toString();
@@ -125,13 +148,33 @@ bool FeedMessageViewer::areListHeadersEnabled() const {
return m_listHeadersEnabled;
}
-void FeedMessageViewer::switchMessageSplitterOrientation() {
+void FeedMessageViewer::switchMessageSplitterOrientation(bool save_settings) {
if (m_messageSplitter->orientation() == Qt::Orientation::Vertical) {
+ if (save_settings) {
+ qApp->settings()->setValue(GROUP(GUI),
+ GUI::SplitterMessagesVertical,
+ toVariant(m_messageSplitter->sizes()));
+ }
+
m_messageSplitter->setOrientation(Qt::Orientation::Horizontal);
+ m_messageSplitter->setSizes(toList(qApp->settings()->value(GROUP(GUI),
+ SETTING(GUI::SplitterMessagesHorizontal))));
}
else {
+ if (save_settings) {
+ qApp->settings()->setValue(GROUP(GUI),
+ GUI::SplitterMessagesHorizontal,
+ toVariant(m_messageSplitter->sizes()));
+ }
+
m_messageSplitter->setOrientation(Qt::Orientation::Vertical);
+ m_messageSplitter->setSizes(toList(qApp->settings()->value(GROUP(GUI),
+ SETTING(GUI::SplitterMessagesVertical))));
}
+
+ qApp->settings()->setValue(GROUP(GUI),
+ GUI::SplitterMessagesIsVertical,
+ m_messageSplitter->orientation() == Qt::Orientation::Vertical);
}
void FeedMessageViewer::setToolBarsEnabled(bool enable) {
diff --git a/src/librssguard/gui/feedmessageviewer.h b/src/librssguard/gui/feedmessageviewer.h
index 26caa3f84..2343ced02 100644
--- a/src/librssguard/gui/feedmessageviewer.h
+++ b/src/librssguard/gui/feedmessageviewer.h
@@ -51,7 +51,7 @@ class RSSGUARD_DLLSPEC FeedMessageViewer : public TabContent {
void loadMessageViewerFonts();
// Switches orientation horizontal/vertical.
- void switchMessageSplitterOrientation();
+ void switchMessageSplitterOrientation(bool save_settings);
// Enables/disables main toolbars or list headers.
void setToolBarsEnabled(bool enable);
diff --git a/src/librssguard/miscellaneous/settings.cpp b/src/librssguard/miscellaneous/settings.cpp
index c89d59b00..798beb93d 100644
--- a/src/librssguard/miscellaneous/settings.cpp
+++ b/src/librssguard/miscellaneous/settings.cpp
@@ -135,10 +135,16 @@ DKEY GUI::MessageViewState = "msg_view_state";
DVALUE(QString) GUI::MessageViewStateDef = QString();
DKEY GUI::SplitterFeeds = "splitter_feeds";
-DVALUE(char*) GUI::SplitterFeedsDef = "";
+DVALUE(QList) GUI::SplitterFeedsDef = {};
-DKEY GUI::SplitterMessages = "splitter_messages";
-DVALUE(char*) GUI::SplitterMessagesDef = "";
+DKEY GUI::SplitterMessagesIsVertical = "splitter_messages_is_vertical";
+DVALUE(bool) GUI::SplitterMessagesIsVerticalDef = true;
+
+DKEY GUI::SplitterMessagesVertical = "splitter_messages_vertical";
+DVALUE(QList) GUI::SplitterMessagesVerticalDef = {};
+
+DKEY GUI::SplitterMessagesHorizontal = "splitter_messages_horizontal";
+DVALUE(QList) GUI::SplitterMessagesHorizontalDef = {};
DKEY GUI::ToolbarStyle = "toolbar_style";
DVALUE(Qt::ToolButtonStyle) GUI::ToolbarStyleDef = Qt::ToolButtonIconOnly;
diff --git a/src/librssguard/miscellaneous/settings.h b/src/librssguard/miscellaneous/settings.h
index 47b8670f2..30bf883db 100644
--- a/src/librssguard/miscellaneous/settings.h
+++ b/src/librssguard/miscellaneous/settings.h
@@ -157,10 +157,16 @@ namespace GUI {
VALUE(QString) MessageViewStateDef;
KEY SplitterFeeds;
- VALUE(char*) SplitterFeedsDef;
+ VALUE(QList) SplitterFeedsDef;
- KEY SplitterMessages;
- VALUE(char*) SplitterMessagesDef;
+ KEY SplitterMessagesIsVertical;
+ VALUE(bool) SplitterMessagesIsVerticalDef;
+
+ KEY SplitterMessagesVertical;
+ VALUE(QList) SplitterMessagesVerticalDef;
+
+ KEY SplitterMessagesHorizontal;
+ VALUE(QList) SplitterMessagesHorizontalDef;
KEY ToolbarStyle;
VALUE(Qt::ToolButtonStyle) ToolbarStyleDef;
diff --git a/src/librssguard/miscellaneous/skinfactory.cpp b/src/librssguard/miscellaneous/skinfactory.cpp
index 96c4d3cc1..3fb863d98 100644
--- a/src/librssguard/miscellaneous/skinfactory.cpp
+++ b/src/librssguard/miscellaneous/skinfactory.cpp
@@ -156,7 +156,7 @@ Skin SkinFactory::skinInfo(const QString& skin_name, bool* ok) const {
skin.m_layoutMarkupWrapper = skin.m_layoutMarkupWrapper.replace(QSL(SKIN_STYLE_PLACEHOLDER),
QString::fromUtf8(custom_css));
}
- catch (const IOException& ex) {
+ catch (...) {
qWarningNN << "Skin"
<< QUOTE_W_SPACE(skin_name)
<< "does not support separated custom CSS.";
diff --git a/src/librssguard/miscellaneous/templates.h b/src/librssguard/miscellaneous/templates.h
index 323dc9d15..406adb53a 100644
--- a/src/librssguard/miscellaneous/templates.h
+++ b/src/librssguard/miscellaneous/templates.h
@@ -1,4 +1,28 @@
+// For license of this file, see /LICENSE.md.
+
#ifndef TEMPLATES_H
#define TEMPLATES_H
+#include
+
+template static QVariant toVariant(const QList& list) {
+ QVariantList variant_list; variant_list.reserve(list.size());
+
+ for (const auto& v : list) {
+ variant_list.append(v);
+ }
+
+ return variant_list;
+}
+
+template static QList toList(const QVariant& qv) {
+ QList data_list;
+
+ foreach(QVariant v, qv.value()) {
+ data_list << v.value();
+ }
+
+ return data_list;
+}
+
#endif // TEMPLATES_H