added no-duplicates premade article filter + implemented dialog-based application log viewer

This commit is contained in:
Martin Rotter 2022-12-01 08:17:39 +01:00
parent bac84e951f
commit a3a77211d0
12 changed files with 175 additions and 3 deletions

View File

@ -60,7 +60,7 @@
<content_rating type="oars-1.0" />
<content_rating type="oars-1.1" />
<releases>
<release version="4.2.5" date="2022-11-23" />
<release version="4.2.5" date="2022-12-01" />
</releases>
<provides>
<binary>rssguard</binary>

View File

@ -604,6 +604,8 @@ Please report all issues/bugs/ideas to [Issues](https://github.com/martinrotter/
If you report any bug, you must provide application debug log. So make sure to start RSS Guard from command line (`cmd.exe` on Windows) with `--log` switch and path where you want to store log file, for example `rssguard.exe --log '.\rssguard.log'` which will save log file into your RSS Guard folder. After you've started RSS Guard this way, then reproduce your problem and upload log file to the ticket.
You can also display application log directly in RSS Guard, see `Application log` menu item in `Help` menu. Note that log messages are only pumped into the dialog when the dialog is opened (can be minimized).
Also, for some broader questions or general ideas, use [discussions](https://github.com/martinrotter/rssguard/discussions) rather than [issues](https://github.com/martinrotter/rssguard/issues).
### <a id="locali"></a>Localization

View File

@ -22,6 +22,7 @@
<file>scripts/filters/blacklist.js</file>
<file>scripts/filters/whitelist.js</file>
<file>scripts/filters/no-duplicates.js</file>
<file>graphics/rssguard.ico</file>

View File

@ -0,0 +1,14 @@
// This filter ensures that there are no duplicate
// articles received across all feeds
//
// Remember you have to assign this filter to all your feeds
// you want to de-duplicate.
function filterMessage() {
if (msg.isAlreadyInDatabase(MessageObject.SameTitle | MessageObject.AllFeedsSameAccount)) {
return MessageObject.Ignore;
}
else {
return MessageObject.Accept;
}
}

View File

@ -69,6 +69,8 @@ set(SOURCES
gui/dialogs/formdatabasecleanup.h
gui/dialogs/formmain.cpp
gui/dialogs/formmain.h
gui/dialogs/formlog.cpp
gui/dialogs/formlog.h
gui/dialogs/formmessagefiltersmanager.cpp
gui/dialogs/formmessagefiltersmanager.h
gui/dialogs/formrestoredatabasesettings.cpp
@ -438,6 +440,7 @@ set(UI_FILES
gui/dialogs/formbackupdatabasesettings.ui
gui/dialogs/formdatabasecleanup.ui
gui/dialogs/formmain.ui
gui/dialogs/formlog.ui
gui/dialogs/formmessagefiltersmanager.ui
gui/dialogs/formrestoredatabasesettings.ui
gui/dialogs/formsettings.ui

View File

@ -0,0 +1,26 @@
// For license of this file, see <project-root-folder>/LICENSE.md.
#include "gui/dialogs/formlog.h"
#include "gui/guiutilities.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include <QScrollBar>
FormLog::FormLog(QWidget* parent) : QDialog(parent) {
m_ui.setupUi(this);
GuiUtilities::applyDialogProperties(*this,
qApp->icons()->fromTheme(QSL("dialog-information")),
tr("Application log"));
setWindowFlags(Qt::WindowType::WindowMinimizeButtonHint | windowFlags());
}
FormLog::~FormLog() {}
void FormLog::appendLogMessage(const QString& message) {
m_ui.m_txtLog->appendPlainText(message);
m_ui.m_txtLog->verticalScrollBar()->setValue(m_ui.m_txtLog->verticalScrollBar()->maximum());
}

View File

@ -0,0 +1,24 @@
// For license of this file, see <project-root-folder>/LICENSE.md.
#ifndef FORMLOG_H
#define FORMLOG_H
#include <QDialog>
#include "ui_formlog.h"
class FormLog : public QDialog {
Q_OBJECT
public:
explicit FormLog(QWidget* parent = nullptr);
virtual ~FormLog();
public slots:
void appendLogMessage(const QString& message);
private:
Ui::FormLog m_ui;
};
#endif // FORMLOG_H

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FormLog</class>
<widget class="QDialog" name="FormLog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>480</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="1" column="0" colspan="2">
<widget class="QDialogButtonBox" name="m_btnBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QPlainTextEdit" name="m_txtLog">
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>m_btnBox</sender>
<signal>accepted()</signal>
<receiver>FormLog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_btnBox</sender>
<signal>rejected()</signal>
<receiver>FormLog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -551,6 +551,7 @@ void FormMain::setupIcons() {
m_ui->m_actionBackupDatabaseSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-export")));
m_ui->m_actionRestoreDatabaseSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-import")));
m_ui->m_actionDonate->setIcon(icon_theme_factory->fromTheme(QSL("applications-office")));
m_ui->m_actionApplicationLog->setIcon(icon_theme_factory->fromTheme(QSL("dialog-information")));
m_ui->m_actionDisplayDocs->setIcon(icon_theme_factory->fromTheme(QSL("applications-science")));
// View.
@ -751,6 +752,7 @@ void FormMain::createConnections() {
});
connect(m_ui->m_actionReportBug, &QAction::triggered, this, &FormMain::reportABug);
connect(m_ui->m_actionDonate, &QAction::triggered, this, &FormMain::donate);
connect(m_ui->m_actionApplicationLog, &QAction::triggered, qApp, &Application::displayLog);
connect(m_ui->m_actionDisplayDocs, &QAction::triggered, this, &FormMain::showDocs);
// Tab widget connections.

View File

@ -64,6 +64,7 @@
</property>
<addaction name="m_actionCheckForUpdates"/>
<addaction name="m_actionReportBug"/>
<addaction name="m_actionApplicationLog"/>
<addaction name="m_actionDisplayDocs"/>
<addaction name="m_actionDonate"/>
<addaction name="m_actionAboutGuard"/>
@ -884,6 +885,11 @@
<string>Move to &amp;bottom</string>
</property>
</action>
<action name="m_actionApplicationLog">
<property name="text">
<string>Display application &amp;log</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@ -6,12 +6,13 @@
#include "dynamic-shortcuts/dynamicshortcuts.h"
#include "exceptions/applicationexception.h"
#include "gui/dialogs/formabout.h"
#include "gui/dialogs/formlog.h"
#include "gui/dialogs/formmain.h"
#include "gui/feedmessageviewer.h"
#include "gui/feedsview.h"
#include "gui/messagebox.h"
#include "gui/toolbars/statusbar.h"
#include "gui/webviewers/qtextbrowser/textbrowserviewer.h" // QTextBrowser-based web browsing.
#include "gui/webviewers/qtextbrowser/textbrowserviewer.h"
#include "miscellaneous/feedreader.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/iofactory.h"
@ -68,6 +69,7 @@ Application::Application(const QString& id, int& argc, char** argv, const QStrin
m_feedReader = nullptr;
m_quitLogicDone = false;
m_mainForm = nullptr;
m_logForm = nullptr;
m_trayIcon = nullptr;
m_settings = Settings::setupSettings(this);
@ -237,6 +239,8 @@ void Application::performLogging(QtMsgType type, const QMessageLogContext& conte
}
}
qApp->displayLogMessageInDialog(console_message);
if (type == QtMsgType::QtFatalMsg) {
qApp->exit(EXIT_FAILURE);
}
@ -363,6 +367,12 @@ void Application::eliminateFirstRuns() {
settings()->setValue(GROUP(General), QString(General::FirstRun) + QL1C('_') + APP_VERSION, false);
}
void Application::displayLogMessageInDialog(const QString& message) {
if (m_logForm != nullptr && m_logForm->isVisible()) {
m_logForm->appendLogMessage(message);
}
}
int Application::customAdblockPort() const {
return m_customAdblockPort;
}
@ -1059,6 +1069,14 @@ void Application::parseCmdArgumentsFromMyInstance(const QStringList& raw_cli_arg
}
}
void Application::displayLog() {
if (m_logForm == nullptr) {
m_logForm = new FormLog(m_mainForm);
}
m_logForm->show();
}
void Application::fillCmdArgumentsParser(QCommandLineParser& parser) {
QCommandLineOption help({QSL(CLI_HELP_SHORT), QSL(CLI_HELP_LONG)}, QSL("Displays overview of CLI."));
QCommandLineOption version({QSL(CLI_VER_SHORT), QSL(CLI_VER_LONG)}, QSL("Displays version of the application."));

View File

@ -31,6 +31,7 @@
#define qApp (Application::instance())
class FormMain;
class FormLog;
class IconFactory;
class QAction;
class Mutex;
@ -188,6 +189,8 @@ class RSSGUARD_DLLSPEC Application : public SingleApplication {
void parseCmdArgumentsFromOtherInstance(const QString& message);
void parseCmdArgumentsFromMyInstance(const QStringList& raw_cli_args);
void displayLog();
private slots:
void fillCmdArgumentsParser(QCommandLineParser& parser);
@ -219,6 +222,7 @@ class RSSGUARD_DLLSPEC Application : public SingleApplication {
void setupCustomDataFolder(const QString& data_folder);
void determineFirstRuns();
void eliminateFirstRuns();
void displayLogMessageInDialog(const QString& message);
private:
QStringList m_rawCliArgs;
@ -243,6 +247,7 @@ class RSSGUARD_DLLSPEC Application : public SingleApplication {
QList<QAction*> m_userActions;
FormMain* m_mainForm;
FormLog* m_logForm;
SystemTrayIcon* m_trayIcon;
Settings* m_settings;
WebFactory* m_webFactory;