maybe some fixups for filtering with custom id + separate widths storing for layouts
This commit is contained in:
parent
ff228d7992
commit
2f39114e8a
@ -26,7 +26,7 @@
|
||||
<url type="donation">https://github.com/sponsors/martinrotter</url>
|
||||
<content_rating type="oars-1.1" />
|
||||
<releases>
|
||||
<release version="4.0.3" date="2021-10-05"/>
|
||||
<release version="4.0.3" date="2021-10-08"/>
|
||||
</releases>
|
||||
<content_rating type="oars-1.0">
|
||||
<content_attribute id="violence-cartoon">none</content_attribute>
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "core/messageobject.h"
|
||||
|
||||
#include "3rd-party/boolinq/boolinq.h"
|
||||
#include "database/databasefactory.h"
|
||||
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlError>
|
||||
@ -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;
|
||||
|
@ -12,7 +12,9 @@
|
||||
#include "miscellaneous/textfactory.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QSqlDriver>
|
||||
#include <QSqlError>
|
||||
#include <QSqlField>
|
||||
#include <QSqlQuery>
|
||||
#include <QVariant>
|
||||
|
||||
@ -78,6 +80,25 @@ DatabaseDriver* DatabaseFactory::driverForType(DatabaseDriver::DriverType d) con
|
||||
});
|
||||
}
|
||||
|
||||
QString DatabaseFactory::lastExecutedQuery(const QSqlQuery& query) {
|
||||
QString str = query.lastQuery();
|
||||
QMapIterator<QString, QVariant> 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("''"));
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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<int>(settings->value(GROUP(GUI),
|
||||
SETTING(GUI::SplitterFeeds))));
|
||||
|
||||
if (!settings->value(GROUP(GUI), SETTING(GUI::SplitterMessagesIsVertical)).toBool()) {
|
||||
switchMessageSplitterOrientation(false);
|
||||
m_messageSplitter->setSizes(toList<int>(settings->value(GROUP(GUI),
|
||||
SETTING(GUI::SplitterMessagesHorizontal))));
|
||||
}
|
||||
else {
|
||||
m_messageSplitter->setSizes(toList<int>(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<int>(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<int>(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) {
|
||||
|
@ -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);
|
||||
|
@ -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<QVariant>) 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<QVariant>) GUI::SplitterMessagesVerticalDef = {};
|
||||
|
||||
DKEY GUI::SplitterMessagesHorizontal = "splitter_messages_horizontal";
|
||||
DVALUE(QList<QVariant>) GUI::SplitterMessagesHorizontalDef = {};
|
||||
|
||||
DKEY GUI::ToolbarStyle = "toolbar_style";
|
||||
DVALUE(Qt::ToolButtonStyle) GUI::ToolbarStyleDef = Qt::ToolButtonIconOnly;
|
||||
|
@ -157,10 +157,16 @@ namespace GUI {
|
||||
VALUE(QString) MessageViewStateDef;
|
||||
|
||||
KEY SplitterFeeds;
|
||||
VALUE(char*) SplitterFeedsDef;
|
||||
VALUE(QList<QVariant>) SplitterFeedsDef;
|
||||
|
||||
KEY SplitterMessages;
|
||||
VALUE(char*) SplitterMessagesDef;
|
||||
KEY SplitterMessagesIsVertical;
|
||||
VALUE(bool) SplitterMessagesIsVerticalDef;
|
||||
|
||||
KEY SplitterMessagesVertical;
|
||||
VALUE(QList<QVariant>) SplitterMessagesVerticalDef;
|
||||
|
||||
KEY SplitterMessagesHorizontal;
|
||||
VALUE(QList<QVariant>) SplitterMessagesHorizontalDef;
|
||||
|
||||
KEY ToolbarStyle;
|
||||
VALUE(Qt::ToolButtonStyle) ToolbarStyleDef;
|
||||
|
@ -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.";
|
||||
|
@ -1,4 +1,28 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#ifndef TEMPLATES_H
|
||||
#define TEMPLATES_H
|
||||
|
||||
#include <QVariantList>
|
||||
|
||||
template <class T> static QVariant toVariant(const QList<T>& list) {
|
||||
QVariantList variant_list; variant_list.reserve(list.size());
|
||||
|
||||
for (const auto& v : list) {
|
||||
variant_list.append(v);
|
||||
}
|
||||
|
||||
return variant_list;
|
||||
}
|
||||
|
||||
template <class T> static QList<T> toList(const QVariant& qv) {
|
||||
QList <T> data_list;
|
||||
|
||||
foreach(QVariant v, qv.value<QVariantList>()) {
|
||||
data_list << v.value<T>();
|
||||
}
|
||||
|
||||
return data_list;
|
||||
}
|
||||
|
||||
#endif // TEMPLATES_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user