added no-duplicates premade article filter + implemented dialog-based application log viewer
This commit is contained in:
parent
bac84e951f
commit
a3a77211d0
@ -60,7 +60,7 @@
|
|||||||
<content_rating type="oars-1.0" />
|
<content_rating type="oars-1.0" />
|
||||||
<content_rating type="oars-1.1" />
|
<content_rating type="oars-1.1" />
|
||||||
<releases>
|
<releases>
|
||||||
<release version="4.2.5" date="2022-11-23" />
|
<release version="4.2.5" date="2022-12-01" />
|
||||||
</releases>
|
</releases>
|
||||||
<provides>
|
<provides>
|
||||||
<binary>rssguard</binary>
|
<binary>rssguard</binary>
|
||||||
|
@ -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.
|
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).
|
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
|
### <a id="locali"></a>Localization
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
<file>scripts/filters/blacklist.js</file>
|
<file>scripts/filters/blacklist.js</file>
|
||||||
<file>scripts/filters/whitelist.js</file>
|
<file>scripts/filters/whitelist.js</file>
|
||||||
|
<file>scripts/filters/no-duplicates.js</file>
|
||||||
|
|
||||||
<file>graphics/rssguard.ico</file>
|
<file>graphics/rssguard.ico</file>
|
||||||
|
|
||||||
|
14
resources/scripts/filters/no-duplicates.js
Executable file
14
resources/scripts/filters/no-duplicates.js
Executable 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;
|
||||||
|
}
|
||||||
|
}
|
@ -69,6 +69,8 @@ set(SOURCES
|
|||||||
gui/dialogs/formdatabasecleanup.h
|
gui/dialogs/formdatabasecleanup.h
|
||||||
gui/dialogs/formmain.cpp
|
gui/dialogs/formmain.cpp
|
||||||
gui/dialogs/formmain.h
|
gui/dialogs/formmain.h
|
||||||
|
gui/dialogs/formlog.cpp
|
||||||
|
gui/dialogs/formlog.h
|
||||||
gui/dialogs/formmessagefiltersmanager.cpp
|
gui/dialogs/formmessagefiltersmanager.cpp
|
||||||
gui/dialogs/formmessagefiltersmanager.h
|
gui/dialogs/formmessagefiltersmanager.h
|
||||||
gui/dialogs/formrestoredatabasesettings.cpp
|
gui/dialogs/formrestoredatabasesettings.cpp
|
||||||
@ -438,6 +440,7 @@ set(UI_FILES
|
|||||||
gui/dialogs/formbackupdatabasesettings.ui
|
gui/dialogs/formbackupdatabasesettings.ui
|
||||||
gui/dialogs/formdatabasecleanup.ui
|
gui/dialogs/formdatabasecleanup.ui
|
||||||
gui/dialogs/formmain.ui
|
gui/dialogs/formmain.ui
|
||||||
|
gui/dialogs/formlog.ui
|
||||||
gui/dialogs/formmessagefiltersmanager.ui
|
gui/dialogs/formmessagefiltersmanager.ui
|
||||||
gui/dialogs/formrestoredatabasesettings.ui
|
gui/dialogs/formrestoredatabasesettings.ui
|
||||||
gui/dialogs/formsettings.ui
|
gui/dialogs/formsettings.ui
|
||||||
|
26
src/librssguard/gui/dialogs/formlog.cpp
Executable file
26
src/librssguard/gui/dialogs/formlog.cpp
Executable 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());
|
||||||
|
}
|
24
src/librssguard/gui/dialogs/formlog.h
Executable file
24
src/librssguard/gui/dialogs/formlog.h
Executable 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
|
71
src/librssguard/gui/dialogs/formlog.ui
Executable file
71
src/librssguard/gui/dialogs/formlog.ui
Executable 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>
|
@ -551,6 +551,7 @@ void FormMain::setupIcons() {
|
|||||||
m_ui->m_actionBackupDatabaseSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-export")));
|
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_actionRestoreDatabaseSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-import")));
|
||||||
m_ui->m_actionDonate->setIcon(icon_theme_factory->fromTheme(QSL("applications-office")));
|
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")));
|
m_ui->m_actionDisplayDocs->setIcon(icon_theme_factory->fromTheme(QSL("applications-science")));
|
||||||
|
|
||||||
// View.
|
// View.
|
||||||
@ -751,6 +752,7 @@ void FormMain::createConnections() {
|
|||||||
});
|
});
|
||||||
connect(m_ui->m_actionReportBug, &QAction::triggered, this, &FormMain::reportABug);
|
connect(m_ui->m_actionReportBug, &QAction::triggered, this, &FormMain::reportABug);
|
||||||
connect(m_ui->m_actionDonate, &QAction::triggered, this, &FormMain::donate);
|
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);
|
connect(m_ui->m_actionDisplayDocs, &QAction::triggered, this, &FormMain::showDocs);
|
||||||
|
|
||||||
// Tab widget connections.
|
// Tab widget connections.
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<addaction name="m_actionCheckForUpdates"/>
|
<addaction name="m_actionCheckForUpdates"/>
|
||||||
<addaction name="m_actionReportBug"/>
|
<addaction name="m_actionReportBug"/>
|
||||||
|
<addaction name="m_actionApplicationLog"/>
|
||||||
<addaction name="m_actionDisplayDocs"/>
|
<addaction name="m_actionDisplayDocs"/>
|
||||||
<addaction name="m_actionDonate"/>
|
<addaction name="m_actionDonate"/>
|
||||||
<addaction name="m_actionAboutGuard"/>
|
<addaction name="m_actionAboutGuard"/>
|
||||||
@ -884,6 +885,11 @@
|
|||||||
<string>Move to &bottom</string>
|
<string>Move to &bottom</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="m_actionApplicationLog">
|
||||||
|
<property name="text">
|
||||||
|
<string>Display application &log</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
@ -6,12 +6,13 @@
|
|||||||
#include "dynamic-shortcuts/dynamicshortcuts.h"
|
#include "dynamic-shortcuts/dynamicshortcuts.h"
|
||||||
#include "exceptions/applicationexception.h"
|
#include "exceptions/applicationexception.h"
|
||||||
#include "gui/dialogs/formabout.h"
|
#include "gui/dialogs/formabout.h"
|
||||||
|
#include "gui/dialogs/formlog.h"
|
||||||
#include "gui/dialogs/formmain.h"
|
#include "gui/dialogs/formmain.h"
|
||||||
#include "gui/feedmessageviewer.h"
|
#include "gui/feedmessageviewer.h"
|
||||||
#include "gui/feedsview.h"
|
#include "gui/feedsview.h"
|
||||||
#include "gui/messagebox.h"
|
#include "gui/messagebox.h"
|
||||||
#include "gui/toolbars/statusbar.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/feedreader.h"
|
||||||
#include "miscellaneous/iconfactory.h"
|
#include "miscellaneous/iconfactory.h"
|
||||||
#include "miscellaneous/iofactory.h"
|
#include "miscellaneous/iofactory.h"
|
||||||
@ -68,6 +69,7 @@ Application::Application(const QString& id, int& argc, char** argv, const QStrin
|
|||||||
m_feedReader = nullptr;
|
m_feedReader = nullptr;
|
||||||
m_quitLogicDone = false;
|
m_quitLogicDone = false;
|
||||||
m_mainForm = nullptr;
|
m_mainForm = nullptr;
|
||||||
|
m_logForm = nullptr;
|
||||||
m_trayIcon = nullptr;
|
m_trayIcon = nullptr;
|
||||||
m_settings = Settings::setupSettings(this);
|
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) {
|
if (type == QtMsgType::QtFatalMsg) {
|
||||||
qApp->exit(EXIT_FAILURE);
|
qApp->exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@ -363,6 +367,12 @@ void Application::eliminateFirstRuns() {
|
|||||||
settings()->setValue(GROUP(General), QString(General::FirstRun) + QL1C('_') + APP_VERSION, false);
|
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 {
|
int Application::customAdblockPort() const {
|
||||||
return m_customAdblockPort;
|
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) {
|
void Application::fillCmdArgumentsParser(QCommandLineParser& parser) {
|
||||||
QCommandLineOption help({QSL(CLI_HELP_SHORT), QSL(CLI_HELP_LONG)}, QSL("Displays overview of CLI."));
|
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."));
|
QCommandLineOption version({QSL(CLI_VER_SHORT), QSL(CLI_VER_LONG)}, QSL("Displays version of the application."));
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#define qApp (Application::instance())
|
#define qApp (Application::instance())
|
||||||
|
|
||||||
class FormMain;
|
class FormMain;
|
||||||
|
class FormLog;
|
||||||
class IconFactory;
|
class IconFactory;
|
||||||
class QAction;
|
class QAction;
|
||||||
class Mutex;
|
class Mutex;
|
||||||
@ -188,6 +189,8 @@ class RSSGUARD_DLLSPEC Application : public SingleApplication {
|
|||||||
void parseCmdArgumentsFromOtherInstance(const QString& message);
|
void parseCmdArgumentsFromOtherInstance(const QString& message);
|
||||||
void parseCmdArgumentsFromMyInstance(const QStringList& raw_cli_args);
|
void parseCmdArgumentsFromMyInstance(const QStringList& raw_cli_args);
|
||||||
|
|
||||||
|
void displayLog();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void fillCmdArgumentsParser(QCommandLineParser& parser);
|
void fillCmdArgumentsParser(QCommandLineParser& parser);
|
||||||
|
|
||||||
@ -219,6 +222,7 @@ class RSSGUARD_DLLSPEC Application : public SingleApplication {
|
|||||||
void setupCustomDataFolder(const QString& data_folder);
|
void setupCustomDataFolder(const QString& data_folder);
|
||||||
void determineFirstRuns();
|
void determineFirstRuns();
|
||||||
void eliminateFirstRuns();
|
void eliminateFirstRuns();
|
||||||
|
void displayLogMessageInDialog(const QString& message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList m_rawCliArgs;
|
QStringList m_rawCliArgs;
|
||||||
@ -243,6 +247,7 @@ class RSSGUARD_DLLSPEC Application : public SingleApplication {
|
|||||||
|
|
||||||
QList<QAction*> m_userActions;
|
QList<QAction*> m_userActions;
|
||||||
FormMain* m_mainForm;
|
FormMain* m_mainForm;
|
||||||
|
FormLog* m_logForm;
|
||||||
SystemTrayIcon* m_trayIcon;
|
SystemTrayIcon* m_trayIcon;
|
||||||
Settings* m_settings;
|
Settings* m_settings;
|
||||||
WebFactory* m_webFactory;
|
WebFactory* m_webFactory;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user