Save work.

This commit is contained in:
Martin Rotter 2017-08-21 06:53:16 +02:00
parent 79e1c9d564
commit cad2fffa87
57 changed files with 951 additions and 943 deletions

View file

@ -28,7 +28,7 @@ if [ $# -eq 0 ]; then
fi fi
ASTYLE_CMD="astyle" ASTYLE_CMD="astyle"
ASTYLE_RC=".astylerc" ASTYLE_RC="$(dirname $0)/.astylerc"
# Check all args. # Check all args.
for dir in "$@"; do for dir in "$@"; do
@ -42,11 +42,6 @@ done
for dir in "$@"; do for dir in "$@"; do
pushd "${dir}" pushd "${dir}"
if [ ! -r "$ASTYLE_RC" ]; then
echo "No $ASTYLE_RC in pwd \"$PWD\"..."
continue
fi
for f in $(find . \ for f in $(find . \
-name '*.c' \ -name '*.c' \
-o -name '*.cc' \ -o -name '*.cc' \

View file

@ -186,7 +186,8 @@ win32 {
} }
} }
DISTFILES += resources/scripts/astyle/.astylerc DISTFILES += resources/scripts/astyle/.astylerc \
resources/scripts/uncrustify/uncrustify.cfg
MOC_DIR = $$OUT_PWD/moc MOC_DIR = $$OUT_PWD/moc
RCC_DIR = $$OUT_PWD/rcc RCC_DIR = $$OUT_PWD/rcc

View file

@ -20,22 +20,20 @@
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
#include "miscellaneous/textfactory.h" #include "miscellaneous/textfactory.h"
#include "miscellaneous/settingsproperties.h" #include "miscellaneous/settingsproperties.h"
#include "gui/guiutilities.h"
#include "exceptions/applicationexception.h"
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>
FormAbout::FormAbout(QWidget* parent) : QDialog(parent), m_ui(new Ui::FormAbout()) { FormAbout::FormAbout(QWidget* parent) : QDialog(parent) {
m_ui->setupUi(this); m_ui.setupUi(this);
// Set flags and attributes. m_ui.m_lblIcon->setPixmap(QPixmap(APP_ICON_PATH));
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("help-about"))); GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("help-about")), tr("About %1").arg(APP_NAME));
//: About RSS Guard dialog title.
setWindowTitle(tr("About %1").arg(APP_NAME));
m_ui->m_lblIcon->setPixmap(QPixmap(APP_ICON_PATH));
// Load information from embedded text files.
loadLicenseAndInformation(); loadLicenseAndInformation();
// Load additional paths information.
loadSettingsAndPaths(); loadSettingsAndPaths();
} }
@ -45,57 +43,51 @@ FormAbout::~FormAbout() {
void FormAbout::loadSettingsAndPaths() { void FormAbout::loadSettingsAndPaths() {
if (qApp->settings()->type() == SettingsProperties::Portable) { if (qApp->settings()->type() == SettingsProperties::Portable) {
m_ui->m_txtPathsSettingsType->setText(tr("FULLY portable")); m_ui.m_txtPathsSettingsType->setText(tr("FULLY portable"));
} }
else { else {
m_ui->m_txtPathsSettingsType->setText(tr("NOT portable")); m_ui.m_txtPathsSettingsType->setText(tr("NOT portable"));
} }
m_ui->m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->getUserDataPath() + m_ui.m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->userDataPath() +
QDir::separator() + QDir::separator() +
QString(APP_DB_SQLITE_PATH))); QString(APP_DB_SQLITE_PATH)));
m_ui->m_txtPathsSettingsFile->setText(QDir::toNativeSeparators(qApp->settings()->fileName())); m_ui.m_txtPathsSettingsFile->setText(QDir::toNativeSeparators(qApp->settings()->fileName()));
m_ui->m_txtPathsSkinsRoot->setText(QDir::toNativeSeparators(qApp->skins()->getUserSkinBaseFolder())); m_ui.m_txtPathsSkinsRoot->setText(QDir::toNativeSeparators(qApp->skins()->customSkinBaseFolder()));
} }
void FormAbout::loadLicenseAndInformation() { void FormAbout::loadLicenseAndInformation() {
QFile file; try {
file.setFileName(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")); m_ui.m_txtLicenseGnu->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")));
}
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { catch (...) {
m_ui->m_txtLicenseGnu->setText(QString::fromUtf8(file.readAll())); m_ui.m_txtLicenseGnu->setText(tr("License not found."));
} }
else { try {
m_ui->m_txtLicenseGnu->setText(tr("License not found.")); m_ui.m_txtLicenseGnu->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")));
}
catch (...) {
m_ui.m_txtLicenseGnu->setText(tr("License not found."));
} }
file.close(); try {
file.setFileName(APP_INFO_PATH + QL1S("/COPYING_BSD")); m_ui.m_txtChangelog->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/CHANGELOG")));
}
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { catch (...) {
m_ui->m_txtLicenseBsd->setText(QString::fromUtf8(file.readAll())); m_ui.m_txtChangelog->setText(tr("Changelog not found."));
} }
else { try {
m_ui->m_txtLicenseBsd->setText(tr("License not found.")); m_ui.m_txtLicenseBsd->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_BSD")));
}
catch (...) {
m_ui.m_txtLicenseBsd->setText(tr("License not found."));
} }
file.close();
file.setFileName(APP_INFO_PATH + QL1S("/CHANGELOG"));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_ui->m_txtChangelog->setText(QString::fromUtf8(file.readAll()));
}
else {
m_ui->m_txtChangelog->setText(tr("Changelog not found."));
}
file.close();
// Set other informative texts. // Set other informative texts.
m_ui->m_lblDesc->setText(tr("<b>%8</b><br>" m_ui.m_lblDesc->setText(tr("<b>%8</b><br>"
"<b>Version:</b> %1 (built on %2/%3)<br>" "<b>Version:</b> %1 (built on %2/%3)<br>"
"<b>Revision:</b> %4<br>" "<b>Revision:</b> %4<br>"
"<b>Build date:</b> %5<br>" "<b>Build date:</b> %5<br>"
@ -108,7 +100,7 @@ void FormAbout::loadLicenseAndInformation() {
qVersion(), qVersion(),
QT_VERSION_STR, QT_VERSION_STR,
APP_NAME)); APP_NAME));
m_ui->m_txtInfo->setText(tr("<body>%5 is a (very) tiny feed reader." m_ui.m_txtInfo->setText(tr("<body>%5 is a (very) tiny feed reader."
"<br><br>This software is distributed under the terms of GNU General Public License, version 3." "<br><br>This software is distributed under the terms of GNU General Public License, version 3."
"<br><br>Contacts:" "<br><br>Contacts:"
"<ul><li><a href=\"mailto://%1\">%1</a> ~e-mail</li>" "<ul><li><a href=\"mailto://%1\">%1</a> ~e-mail</li>"

View file

@ -37,7 +37,7 @@ class FormAbout : public QDialog {
void loadLicenseAndInformation(); void loadLicenseAndInformation();
void loadSettingsAndPaths(); void loadSettingsAndPaths();
QScopedPointer<Ui::FormAbout> m_ui; Ui::FormAbout m_ui;
}; };
#endif // FORMABOUT_H #endif // FORMABOUT_H

View file

@ -582,27 +582,39 @@ void FormMain::createConnections() {
connect(m_ui->m_menuAccounts, &QMenu::aboutToShow, this, &FormMain::updateAccountsMenu); connect(m_ui->m_menuAccounts, &QMenu::aboutToShow, this, &FormMain::updateAccountsMenu);
connect(m_ui->m_actionServiceDelete, &QAction::triggered, m_ui->m_actionDeleteSelectedItem, &QAction::triggered); connect(m_ui->m_actionServiceDelete, &QAction::triggered, m_ui->m_actionDeleteSelectedItem, &QAction::triggered);
connect(m_ui->m_actionServiceEdit, &QAction::triggered, m_ui->m_actionEditSelectedItem, &QAction::triggered); connect(m_ui->m_actionServiceEdit, &QAction::triggered, m_ui->m_actionEditSelectedItem, &QAction::triggered);
// Menu "File" connections. // Menu "File" connections.
connect(m_ui->m_actionBackupDatabaseSettings, &QAction::triggered, this, &FormMain::backupDatabaseSettings); connect(m_ui->m_actionBackupDatabaseSettings, &QAction::triggered, this, &FormMain::backupDatabaseSettings);
connect(m_ui->m_actionRestoreDatabaseSettings, &QAction::triggered, this, &FormMain::restoreDatabaseSettings); connect(m_ui->m_actionRestoreDatabaseSettings, &QAction::triggered, this, &FormMain::restoreDatabaseSettings);
connect(m_ui->m_actionQuit, &QAction::triggered, qApp, &Application::quit); connect(m_ui->m_actionQuit, &QAction::triggered, qApp, &Application::quit);
connect(m_ui->m_actionServiceAdd, &QAction::triggered, this, &FormMain::showAddAccountDialog); connect(m_ui->m_actionServiceAdd, &QAction::triggered, this, &FormMain::showAddAccountDialog);
connect(m_ui->m_actionRestart, &QAction::triggered, qApp, &Application::restart); connect(m_ui->m_actionRestart, &QAction::triggered, qApp, &Application::restart);
// Menu "View" connections. // Menu "View" connections.
connect(m_ui->m_actionFullscreen, &QAction::toggled, this, &FormMain::switchFullscreenMode); connect(m_ui->m_actionFullscreen, &QAction::toggled, this, &FormMain::switchFullscreenMode);
connect(m_ui->m_actionSwitchMainMenu, &QAction::toggled, m_ui->m_menuBar, &QMenuBar::setVisible); connect(m_ui->m_actionSwitchMainMenu, &QAction::toggled, m_ui->m_menuBar, &QMenuBar::setVisible);
connect(m_ui->m_actionSwitchMainWindow, &QAction::triggered, this, &FormMain::switchVisibility); connect(m_ui->m_actionSwitchMainWindow, &QAction::triggered, this, &FormMain::switchVisibility);
connect(m_ui->m_actionSwitchStatusBar, &QAction::toggled, statusBar(), &StatusBar::setVisible); connect(m_ui->m_actionSwitchStatusBar, &QAction::toggled, statusBar(), &StatusBar::setVisible);
// Menu "Tools" connections. // Menu "Tools" connections.
connect(m_ui->m_actionSettings, &QAction::triggered, this, &FormMain::showSettings); connect(m_ui->m_actionSettings, &QAction::triggered, [this]() {
FormSettings(*this).exec();
});
connect(m_ui->m_actionDownloadManager, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::showDownloadManager); connect(m_ui->m_actionDownloadManager, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::showDownloadManager);
connect(m_ui->m_actionCleanupDatabase, &QAction::triggered, this, &FormMain::showDbCleanupAssistant); connect(m_ui->m_actionCleanupDatabase, &QAction::triggered, this, &FormMain::showDbCleanupAssistant);
// Menu "Help" connections. // Menu "Help" connections.
connect(m_ui->m_actionAboutGuard, &QAction::triggered, this, &FormMain::showAbout); connect(m_ui->m_actionAboutGuard, &QAction::triggered, [this]() {
connect(m_ui->m_actionCheckForUpdates, &QAction::triggered, this, &FormMain::showUpdates); FormAbout(this).exec();
});
connect(m_ui->m_actionCheckForUpdates, &QAction::triggered, [this]() {
FormUpdate(this).exec();
});
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_actionDisplayWiki, &QAction::triggered, this, &FormMain::showWiki); connect(m_ui->m_actionDisplayWiki, &QAction::triggered, this, &FormMain::showWiki);
// Tab widget connections. // Tab widget connections.
connect(m_ui->m_actionTabsCloseAllExceptCurrent, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabsExceptCurrent); connect(m_ui->m_actionTabsCloseAllExceptCurrent, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabsExceptCurrent);
connect(m_ui->m_actionTabsCloseAll, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabs); connect(m_ui->m_actionTabsCloseAll, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabs);
@ -617,6 +629,7 @@ void FormMain::createConnections() {
connect(qApp->feedReader(), &FeedReader::feedUpdatesStarted, this, &FormMain::onFeedUpdatesStarted); connect(qApp->feedReader(), &FeedReader::feedUpdatesStarted, this, &FormMain::onFeedUpdatesStarted);
connect(qApp->feedReader(), &FeedReader::feedUpdatesProgress, this, &FormMain::onFeedUpdatesProgress); connect(qApp->feedReader(), &FeedReader::feedUpdatesProgress, this, &FormMain::onFeedUpdatesProgress);
connect(qApp->feedReader(), &FeedReader::feedUpdatesFinished, this, &FormMain::onFeedUpdatesFinished); connect(qApp->feedReader(), &FeedReader::feedUpdatesFinished, this, &FormMain::onFeedUpdatesFinished);
// Toolbar forwardings. // Toolbar forwardings.
connect(m_ui->m_actionAddFeedIntoSelectedAccount, &QAction::triggered, connect(m_ui->m_actionAddFeedIntoSelectedAccount, &QAction::triggered,
tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::addFeedIntoSelectedAccount); tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::addFeedIntoSelectedAccount);
@ -694,10 +707,10 @@ void FormMain::backupDatabaseSettings() {
} }
void FormMain::restoreDatabaseSettings() { void FormMain::restoreDatabaseSettings() {
QScopedPointer<FormRestoreDatabaseSettings> form(new FormRestoreDatabaseSettings(this)); FormRestoreDatabaseSettings form(*this);
form->exec(); form.exec();
if (form->shouldRestart()) { if (form.shouldRestart()) {
qApp->restart(); qApp->restart();
} }
} }
@ -722,16 +735,6 @@ void FormMain::changeEvent(QEvent* event) {
QMainWindow::changeEvent(event); QMainWindow::changeEvent(event);
} }
void FormMain::showAbout() {
QScopedPointer<FormAbout> form_pointer(new FormAbout(this));
form_pointer->exec();
}
void FormMain::showUpdates() {
QScopedPointer<FormUpdate> form_update(new FormUpdate(this));
form_update->exec();
}
void FormMain::showWiki() { void FormMain::showWiki() {
if (!qApp->web()->openUrlInExternalBrowser(APP_URL_WIKI)) { if (!qApp->web()->openUrlInExternalBrowser(APP_URL_WIKI)) {
qApp->showGuiMessage(tr("Cannot open external browser"), qApp->showGuiMessage(tr("Cannot open external browser"),
@ -762,8 +765,3 @@ void FormMain::donate() {
QSystemTrayIcon::Warning, this, true); QSystemTrayIcon::Warning, this, true);
} }
} }
void FormMain::showSettings() {
QScopedPointer<FormSettings> form_pointer(new FormSettings(this));
form_pointer->exec();
}

View file

@ -80,9 +80,6 @@ class FormMain : public QMainWindow {
// Displays various dialogs. // Displays various dialogs.
void backupDatabaseSettings(); void backupDatabaseSettings();
void restoreDatabaseSettings(); void restoreDatabaseSettings();
void showSettings();
void showAbout();
void showUpdates();
void showWiki(); void showWiki();
void showAddAccountDialog(); void showAddAccountDialog();
void showDbCleanupAssistant(); void showDbCleanupAssistant();

View file

@ -25,21 +25,24 @@
#include "QFileDialog" #include "QFileDialog"
FormRestoreDatabaseSettings::FormRestoreDatabaseSettings(QWidget* parent) FormRestoreDatabaseSettings::FormRestoreDatabaseSettings(QWidget& parent)
: QDialog(parent), m_ui(new Ui::FormRestoreDatabaseSettings), m_shouldRestart(false) { : QDialog(&parent), m_shouldRestart(false) {
m_ui->setupUi(this); m_ui.setupUi(this);
m_btnRestart = m_ui->m_buttonBox->addButton(tr("Restart"), QDialogButtonBox::ActionRole);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Warning, tr("No operation executed yet."), tr("No operation executed yet.")); m_btnRestart = m_ui.m_buttonBox->addButton(tr("Restart"), QDialogButtonBox::ActionRole);
m_ui.m_lblResult->setStatus(WidgetWithStatus::Warning, tr("No operation executed yet."), tr("No operation executed yet."));
setWindowIcon(qApp->icons()->fromTheme(QSL("document-import"))); setWindowIcon(qApp->icons()->fromTheme(QSL("document-import")));
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
connect(m_btnRestart, &QPushButton::clicked, this, [ = ]() { connect(m_btnRestart, &QPushButton::clicked, this, [ = ]() {
m_shouldRestart = true; m_shouldRestart = true;
close(); close();
}); });
connect(m_ui->m_btnSelectFolder, SIGNAL(clicked()), this, SLOT(selectFolder())); connect(m_ui.m_btnSelectFolder, SIGNAL(clicked()), this, SLOT(selectFolder()));
connect(m_ui->m_groupDatabase, SIGNAL(toggled(bool)), this, SLOT(checkOkButton())); connect(m_ui.m_groupDatabase, SIGNAL(toggled(bool)), this, SLOT(checkOkButton()));
connect(m_ui->m_groupSettings, SIGNAL(toggled(bool)), this, SLOT(checkOkButton())); connect(m_ui.m_groupSettings, SIGNAL(toggled(bool)), this, SLOT(checkOkButton()));
connect(m_ui->m_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(performRestoration())); connect(m_ui.m_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(performRestoration()));
selectFolder(qApp->getDocumentsFolderPath()); selectFolder(qApp->getDocumentsFolderPath());
} }
@ -48,35 +51,34 @@ FormRestoreDatabaseSettings::~FormRestoreDatabaseSettings() {
} }
void FormRestoreDatabaseSettings::performRestoration() { void FormRestoreDatabaseSettings::performRestoration() {
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); m_ui.m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
try { try {
qApp->restoreDatabaseSettings(m_ui->m_groupDatabase->isChecked(), qApp->restoreDatabaseSettings(m_ui.m_groupDatabase->isChecked(),
m_ui->m_groupSettings->isChecked(), m_ui.m_groupSettings->isChecked(),
m_ui->m_listDatabase->currentRow() >= 0 ? m_ui.m_listDatabase->currentRow() >= 0 ?
m_ui->m_listDatabase->currentItem()->data(Qt::UserRole).toString() : m_ui.m_listDatabase->currentItem()->data(Qt::UserRole).toString() :
QString(), QString(),
m_ui->m_listSettings->currentRow() >= 0 ? m_ui.m_listSettings->currentRow() >= 0 ?
m_ui->m_listSettings->currentItem()->data(Qt::UserRole).toString() : m_ui.m_listSettings->currentItem()->data(Qt::UserRole).toString() :
QString()); QString());
m_btnRestart->setEnabled(true); m_btnRestart->setEnabled(true);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Restoration was initiated. Restart to proceed."), m_ui.m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Restoration was initiated. Restart to proceed."),
tr("You need to restart application for restoration process to finish.")); tr("You need to restart application for restoration process to finish."));
} }
catch (const ApplicationException& ex) { catch (const ApplicationException& ex) {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(), m_ui.m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(),
tr("Database and/or settings were not copied to restoration directory successully.")); tr("Database and/or settings were not copied to restoration directory successully."));
} }
} }
void FormRestoreDatabaseSettings::checkOkButton() { void FormRestoreDatabaseSettings::checkOkButton() {
m_btnRestart->setEnabled(false); m_btnRestart->setEnabled(false);
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!m_ui->m_lblSelectFolder->label()->text().isEmpty() && m_ui.m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!m_ui.m_lblSelectFolder->label()->text().isEmpty() &&
((m_ui->m_groupDatabase->isChecked() && ((m_ui.m_groupDatabase->isChecked() &&
m_ui->m_listDatabase->currentRow() >= 0) || m_ui.m_listDatabase->currentRow() >= 0) ||
(m_ui->m_groupSettings->isChecked() && (m_ui.m_groupSettings->isChecked() &&
m_ui->m_listSettings->currentRow() >= 0))); m_ui.m_listSettings->currentRow() >= 0)));
} }
void FormRestoreDatabaseSettings::selectFolderWithGui() { void FormRestoreDatabaseSettings::selectFolderWithGui() {
@ -85,11 +87,11 @@ void FormRestoreDatabaseSettings::selectFolderWithGui() {
void FormRestoreDatabaseSettings::selectFolder(QString folder) { void FormRestoreDatabaseSettings::selectFolder(QString folder) {
if (folder.isEmpty()) { if (folder.isEmpty()) {
folder = QFileDialog::getExistingDirectory(this, tr("Select source directory"), m_ui->m_lblSelectFolder->label()->text()); folder = QFileDialog::getExistingDirectory(this, tr("Select source directory"), m_ui.m_lblSelectFolder->label()->text());
} }
if (!folder.isEmpty()) { if (!folder.isEmpty()) {
m_ui->m_lblSelectFolder->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(folder), m_ui.m_lblSelectFolder->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(folder),
tr("Good source directory is specified.")); tr("Good source directory is specified."));
} }
@ -108,29 +110,29 @@ void FormRestoreDatabaseSettings::selectFolder(QString folder) {
QDir::Files | QDir::NoDotAndDotDot | QDir::Readable | QDir::Files | QDir::NoDotAndDotDot | QDir::Readable |
QDir::CaseSensitive | QDir::NoSymLinks, QDir::CaseSensitive | QDir::NoSymLinks,
QDir::Name); QDir::Name);
m_ui->m_listDatabase->clear(); m_ui.m_listDatabase->clear();
m_ui->m_listSettings->clear(); m_ui.m_listSettings->clear();
foreach (const QFileInfo& database_file, available_databases) { foreach (const QFileInfo& database_file, available_databases) {
QListWidgetItem* database_item = new QListWidgetItem(database_file.fileName(), m_ui->m_listDatabase); QListWidgetItem* database_item = new QListWidgetItem(database_file.fileName(), m_ui.m_listDatabase);
database_item->setData(Qt::UserRole, database_file.absoluteFilePath()); database_item->setData(Qt::UserRole, database_file.absoluteFilePath());
database_item->setToolTip(QDir::toNativeSeparators(database_file.absoluteFilePath())); database_item->setToolTip(QDir::toNativeSeparators(database_file.absoluteFilePath()));
} }
foreach (const QFileInfo& settings_file, available_settings) { foreach (const QFileInfo& settings_file, available_settings) {
QListWidgetItem* settings_item = new QListWidgetItem(settings_file.fileName(), m_ui->m_listSettings); QListWidgetItem* settings_item = new QListWidgetItem(settings_file.fileName(), m_ui.m_listSettings);
settings_item->setData(Qt::UserRole, settings_file.absoluteFilePath()); settings_item->setData(Qt::UserRole, settings_file.absoluteFilePath());
settings_item->setToolTip(QDir::toNativeSeparators(settings_file.absoluteFilePath())); settings_item->setToolTip(QDir::toNativeSeparators(settings_file.absoluteFilePath()));
} }
if (!available_databases.isEmpty()) { if (!available_databases.isEmpty()) {
m_ui->m_listDatabase->setCurrentRow(0); m_ui.m_listDatabase->setCurrentRow(0);
} }
if (!available_settings.isEmpty()) { if (!available_settings.isEmpty()) {
m_ui->m_listSettings->setCurrentRow(0); m_ui.m_listSettings->setCurrentRow(0);
} }
m_ui->m_groupDatabase->setChecked(!available_databases.isEmpty()); m_ui.m_groupDatabase->setChecked(!available_databases.isEmpty());
m_ui->m_groupSettings->setChecked(!available_settings.isEmpty()); m_ui.m_groupSettings->setChecked(!available_settings.isEmpty());
} }

View file

@ -28,7 +28,7 @@ class FormRestoreDatabaseSettings : public QDialog {
public: public:
// Constructors and destructors. // Constructors and destructors.
explicit FormRestoreDatabaseSettings(QWidget* parent = 0); explicit FormRestoreDatabaseSettings(QWidget& parent);
virtual ~FormRestoreDatabaseSettings(); virtual ~FormRestoreDatabaseSettings();
bool shouldRestart() const { bool shouldRestart() const {
@ -42,7 +42,7 @@ class FormRestoreDatabaseSettings : public QDialog {
void selectFolder(QString folder = QString()); void selectFolder(QString folder = QString());
private: private:
QScopedPointer<Ui::FormRestoreDatabaseSettings> m_ui; Ui::FormRestoreDatabaseSettings m_ui;
QPushButton* m_btnRestart; QPushButton* m_btnRestart;
bool m_shouldRestart; bool m_shouldRestart;

View file

@ -33,27 +33,30 @@
#include "gui/settings/settingsshortcuts.h" #include "gui/settings/settingsshortcuts.h"
FormSettings::FormSettings(QWidget* parent) : QDialog(parent), m_panels(QList<SettingsPanel*>()), m_ui(new Ui::FormSettings), FormSettings::FormSettings(QWidget& parent)
m_settings(qApp->settings()) { : QDialog(&parent), m_panels(QList<SettingsPanel*>()), m_settings(*qApp->settings()) {
m_ui->setupUi(this); m_ui.setupUi(this);
// Set flags and attributes. // Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("emblem-system"))); setWindowIcon(qApp->icons()->fromTheme(QSL("emblem-system")));
m_btnApply = m_ui->m_buttonBox->button(QDialogButtonBox::Apply); m_btnApply = m_ui.m_buttonBox->button(QDialogButtonBox::Apply);
m_btnApply->setEnabled(false); m_btnApply->setEnabled(false);
// Establish needed connections. // Establish needed connections.
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormSettings::saveSettings); connect(m_ui.m_buttonBox, &QDialogButtonBox::accepted, this, &FormSettings::saveSettings);
connect(m_ui->m_buttonBox, &QDialogButtonBox::rejected, this, &FormSettings::cancelSettings); connect(m_ui.m_buttonBox, &QDialogButtonBox::rejected, this, &FormSettings::cancelSettings);
connect(m_btnApply, &QPushButton::clicked, this, &FormSettings::applySettings); connect(m_btnApply, &QPushButton::clicked, this, &FormSettings::applySettings);
addSettingsPanel(new SettingsGeneral(m_settings, this)); addSettingsPanel(new SettingsGeneral(&m_settings, this));
addSettingsPanel(new SettingsDatabase(m_settings, this)); addSettingsPanel(new SettingsDatabase(&m_settings, this));
addSettingsPanel(new SettingsGui(m_settings, this)); addSettingsPanel(new SettingsGui(&m_settings, this));
addSettingsPanel(new SettingsLocalization(m_settings, this)); addSettingsPanel(new SettingsLocalization(&m_settings, this));
addSettingsPanel(new SettingsShortcuts(m_settings, this)); addSettingsPanel(new SettingsShortcuts(&m_settings, this));
addSettingsPanel(new SettingsBrowserMail(m_settings, this)); addSettingsPanel(new SettingsBrowserMail(&m_settings, this));
addSettingsPanel(new SettingsDownloads(m_settings, this)); addSettingsPanel(new SettingsDownloads(&m_settings, this));
addSettingsPanel(new SettingsFeedsMessages(m_settings, this)); addSettingsPanel(new SettingsFeedsMessages(&m_settings, this));
m_ui->m_listSettings->setCurrentRow(0);
m_ui.m_listSettings->setCurrentRow(0);
} }
FormSettings::~FormSettings() { FormSettings::~FormSettings() {
@ -67,7 +70,7 @@ void FormSettings::saveSettings() {
void FormSettings::applySettings() { void FormSettings::applySettings() {
// Save all settings. // Save all settings.
m_settings->checkSettings(); m_settings.checkSettings();
QStringList panels_for_restart; QStringList panels_for_restart;
foreach (SettingsPanel* panel, m_panels) { foreach (SettingsPanel* panel, m_panels) {
@ -130,10 +133,11 @@ void FormSettings::cancelSettings() {
} }
void FormSettings::addSettingsPanel(SettingsPanel* panel) { void FormSettings::addSettingsPanel(SettingsPanel* panel) {
m_ui->m_listSettings->addItem(panel->title()); m_ui.m_listSettings->addItem(panel->title());
m_panels.append(panel); m_panels.append(panel);
m_ui->m_stackedSettings->addWidget(panel); m_ui.m_stackedSettings->addWidget(panel);
panel->loadSettings(); panel->loadSettings();
connect(panel, &SettingsPanel::settingsChanged, [this]() { connect(panel, &SettingsPanel::settingsChanged, [this]() {
m_btnApply->setEnabled(true); m_btnApply->setEnabled(true);
}); });

View file

@ -31,7 +31,7 @@ class FormSettings : public QDialog {
public: public:
// Constructors and destructors. // Constructors and destructors.
explicit FormSettings(QWidget* parent = 0); explicit FormSettings(QWidget& parent);
virtual ~FormSettings(); virtual ~FormSettings();
private slots: private slots:
@ -43,10 +43,11 @@ class FormSettings : public QDialog {
private: private:
void addSettingsPanel(SettingsPanel* panel); void addSettingsPanel(SettingsPanel* panel);
QList<SettingsPanel*> m_panels; Ui::FormSettings m_ui;
QScopedPointer<Ui::FormSettings> m_ui;
QPushButton* m_btnApply; QPushButton* m_btnApply;
Settings* m_settings;
QList<SettingsPanel*> m_panels;
Settings& m_settings;
}; };
#endif // FORMSETTINGS_H #endif // FORMSETTINGS_H

View file

@ -24,6 +24,7 @@
#include "network-web/webfactory.h" #include "network-web/webfactory.h"
#include "network-web/downloader.h" #include "network-web/downloader.h"
#include "gui/messagebox.h" #include "gui/messagebox.h"
#include "gui/guiutilities.h"
#include <QNetworkReply> #include <QNetworkReply>
#include <QProcess> #include <QProcess>
@ -34,21 +35,24 @@
FormUpdate::FormUpdate(QWidget* parent) FormUpdate::FormUpdate(QWidget* parent)
: QDialog(parent), m_downloader(nullptr), m_readyToInstall(false), m_ui(new Ui::FormUpdate), m_lastDownloadedBytes(0) { : QDialog(parent) {
m_ui->setupUi(this); m_ui.setupUi(this);
m_ui->m_lblCurrentRelease->setText(APP_VERSION); m_ui.m_lblCurrentRelease->setText(APP_VERSION);
m_ui->m_tabInfo->removeTab(1); m_ui.m_tabInfo->removeTab(1);
m_ui.m_buttonBox->setEnabled(false);
// Set flags and attributes. // Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint); GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("help-about")));
setWindowIcon(qApp->icons()->fromTheme(QSL("help-about")));
connect(&m_downloader, &Downloader::progress, this, &FormUpdate::updateProgress);
connect(&m_downloader, &Downloader::completed, this, &FormUpdate::updateCompleted);
if (isSelfUpdateSupported()) { if (isSelfUpdateSupported()) {
m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Download selected update"), QDialogButtonBox::ActionRole); m_btnUpdate = m_ui.m_buttonBox->addButton(tr("Download selected update"), QDialogButtonBox::ActionRole);
m_btnUpdate->setToolTip(tr("Download new installation files.")); m_btnUpdate->setToolTip(tr("Download new installation files."));
} }
else { else {
m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Go to application website"), QDialogButtonBox::ActionRole); m_btnUpdate = m_ui.m_buttonBox->addButton(tr("Go to application website"), QDialogButtonBox::ActionRole);
m_btnUpdate->setToolTip(tr("Go to application website to get update packages manually.")); m_btnUpdate->setToolTip(tr("Go to application website to get update packages manually."));
} }
@ -69,29 +73,30 @@ bool FormUpdate::isSelfUpdateSupported() const {
} }
void FormUpdate::checkForUpdates() { void FormUpdate::checkForUpdates() {
const QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> update = qApp->system()->checkForUpdates(); connect(qApp->system(), &SystemFactory::updatesChecked, [this](QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> update) {
m_ui.m_buttonBox->setEnabled(true);
disconnect(qApp->system(), &SystemFactory::updatesChecked, nullptr, nullptr);
if (update.second != QNetworkReply::NoError) { if (update.second != QNetworkReply::NoError) {
m_updateInfo = UpdateInfo(); m_updateInfo = UpdateInfo();
m_ui->m_tabInfo->setEnabled(false); m_ui.m_tabInfo->setEnabled(false);
//: Unknown release. //: Unknown release.
m_ui->m_lblAvailableRelease->setText(tr("unknown")); m_ui.m_lblAvailableRelease->setText(tr("unknown"));
m_ui->m_txtChanges->clear(); m_ui.m_txtChanges->clear();
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Error, m_ui.m_lblStatus->setStatus(WidgetWithStatus::Error,
tr("Error: '%1'.").arg(NetworkFactory::networkErrorText(update.second)), tr("Error: '%1'.").arg(NetworkFactory::networkErrorText(update.second)),
tr("List with updates was not\ndownloaded successfully.")); tr("List with updates was not\ndownloaded successfully."));
} }
else { else {
const bool self_update_supported = isSelfUpdateSupported(); const bool self_update_supported = isSelfUpdateSupported();
m_updateInfo = update.first.at(0); m_updateInfo = update.first.at(0);
m_ui->m_tabInfo->setEnabled(true); m_ui.m_tabInfo->setEnabled(true);
m_ui->m_lblAvailableRelease->setText(m_updateInfo.m_availableVersion); m_ui.m_lblAvailableRelease->setText(m_updateInfo.m_availableVersion);
m_ui->m_txtChanges->setText(m_updateInfo.m_changes); m_ui.m_txtChanges->setText(m_updateInfo.m_changes);
if (SystemFactory::isVersionNewer(m_updateInfo.m_availableVersion, APP_VERSION)) { if (SystemFactory::isVersionNewer(m_updateInfo.m_availableVersion, APP_VERSION)) {
m_btnUpdate->setVisible(true); m_btnUpdate->setVisible(true);
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok, m_ui.m_lblStatus->setStatus(WidgetWithStatus::Ok,
tr("New release available."), tr("New release available."),
tr("This is new version which can be\ndownloaded.")); tr("This is new version which can be\ndownloaded."));
@ -99,18 +104,20 @@ void FormUpdate::checkForUpdates() {
loadAvailableFiles(); loadAvailableFiles();
} }
} }
else { else {
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Warning, m_ui.m_lblStatus->setStatus(WidgetWithStatus::Warning,
tr("No new release available."), tr("No new release available."),
tr("This release is not newer than\ncurrently installed one.")); tr("This release is not newer than\ncurrently installed one."));
} }
} }
});
qApp->system()->checkForUpdates();
} }
void FormUpdate::updateProgress(qint64 bytes_received, qint64 bytes_total) { void FormUpdate::updateProgress(qint64 bytes_received, qint64 bytes_total) {
if (bytes_received - m_lastDownloadedBytes > 500000 || m_lastDownloadedBytes == 0) { if (bytes_received - m_lastDownloadedBytes > 500000 || m_lastDownloadedBytes == 0) {
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Information, m_ui.m_lblStatus->setStatus(WidgetWithStatus::Information,
tr("Downloaded %1% (update size is %2 kB).").arg(QString::number(bytes_total == 0 ? 0 : (bytes_received * 100.0) / bytes_total, tr("Downloaded %1% (update size is %2 kB).").arg(QString::number(bytes_total == 0 ? 0 : (bytes_received * 100.0) / bytes_total,
'f', 'f',
2), 2),
@ -118,13 +125,13 @@ void FormUpdate::updateProgress(qint64 bytes_received, qint64 bytes_total) {
'f', 'f',
2)), 2)),
tr("Downloading update...")); tr("Downloading update..."));
m_ui->m_lblStatus->repaint(); m_ui.m_lblStatus->repaint();
m_lastDownloadedBytes = bytes_received; m_lastDownloadedBytes = bytes_received;
} }
} }
void FormUpdate::saveUpdateFile(const QByteArray& file_contents) { void FormUpdate::saveUpdateFile(const QByteArray& file_contents) {
const QString url_file = m_ui->m_listFiles->currentItem()->data(Qt::UserRole).toString(); const QString url_file = m_ui.m_listFiles->currentItem()->data(Qt::UserRole).toString();
const QString temp_directory = qApp->getTempFolderPath(); const QString temp_directory = qApp->getTempFolderPath();
if (!temp_directory.isEmpty()) { if (!temp_directory.isEmpty()) {
@ -141,38 +148,35 @@ void FormUpdate::saveUpdateFile(const QByteArray& file_contents) {
m_updateFilePath = output_file.fileName(); m_updateFilePath = output_file.fileName();
m_readyToInstall = true; m_readyToInstall = true;
} }
else { else {
qDebug("Cannot save downloaded update file because target temporary file '%s' cannot be " qDebug("Cannot save downloaded update file because target temporary file '%s' cannot be "
"opened for writing.", qPrintable(output_file_name)); "opened for writing.", qPrintable(output_file_name));
} }
} }
else { else {
qDebug("Cannot save downloaded update file because no TEMP directory is available."); qDebug("Cannot save downloaded update file because no TEMP directory is available.");
} }
} }
void FormUpdate::loadAvailableFiles() { void FormUpdate::loadAvailableFiles() {
m_ui->m_listFiles->clear(); m_ui.m_listFiles->clear();
foreach (const UpdateUrl& url, m_updateInfo.m_urls) { foreach (const UpdateUrl& url, m_updateInfo.m_urls) {
QListWidgetItem* item = new QListWidgetItem(url.m_name + tr(" (size ") + url.m_size + QSL(")")); QListWidgetItem* item = new QListWidgetItem(url.m_name + tr(" (size ") + url.m_size + QSL(")"));
item->setData(Qt::UserRole, url.m_fileUrl); item->setData(Qt::UserRole, url.m_fileUrl);
item->setToolTip(url.m_fileUrl); item->setToolTip(url.m_fileUrl);
m_ui->m_listFiles->addItem(item); m_ui.m_listFiles->addItem(item);
} }
if (m_ui->m_listFiles->count() > 0) { if (m_ui.m_listFiles->count() > 0) {
m_ui->m_listFiles->setCurrentRow(0); m_ui.m_listFiles->setCurrentRow(0);
} }
else { else {
m_btnUpdate->setEnabled(false); m_btnUpdate->setEnabled(false);
} }
m_ui->m_tabInfo->addTab(m_ui->tabFiles, tr("Available update files")); m_ui.m_tabInfo->addTab(m_ui.tabFiles, tr("Available update files"));
m_ui->m_tabInfo->setCurrentIndex(1); m_ui.m_tabInfo->setCurrentIndex(1);
} }
void FormUpdate::updateCompleted(QNetworkReply::NetworkError status, QByteArray contents) { void FormUpdate::updateCompleted(QNetworkReply::NetworkError status, QByteArray contents) {
@ -181,14 +185,14 @@ void FormUpdate::updateCompleted(QNetworkReply::NetworkError status, QByteArray
switch (status) { switch (status) {
case QNetworkReply::NoError: case QNetworkReply::NoError:
saveUpdateFile(contents); saveUpdateFile(contents);
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok, tr("Downloaded successfully"), m_ui.m_lblStatus->setStatus(WidgetWithStatus::Ok, tr("Downloaded successfully"),
tr("Package was downloaded successfully.\nYou can install it now.")); tr("Package was downloaded successfully.\nYou can install it now."));
m_btnUpdate->setText(tr("Install")); m_btnUpdate->setText(tr("Install"));
m_btnUpdate->setEnabled(true); m_btnUpdate->setEnabled(true);
break; break;
default: default:
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Error, tr("Error occured"), tr("Error occured during downloading of the package.")); m_ui.m_lblStatus->setStatus(WidgetWithStatus::Error, tr("Error occured"), tr("Error occured during downloading of the package."));
m_btnUpdate->setText(tr("Error occured")); m_btnUpdate->setText(tr("Error occured"));
break; break;
} }
@ -198,11 +202,10 @@ void FormUpdate::startUpdate() {
QString url_file; QString url_file;
const bool update_for_this_system = isSelfUpdateSupported(); const bool update_for_this_system = isSelfUpdateSupported();
if (update_for_this_system && m_ui->m_listFiles->currentItem() != nullptr) { if (update_for_this_system && m_ui.m_listFiles->currentItem() != nullptr) {
url_file = m_ui->m_listFiles->currentItem()->data(Qt::UserRole).toString(); url_file = m_ui.m_listFiles->currentItem()->data(Qt::UserRole).toString();
m_ui->m_listFiles->setEnabled(false); m_ui.m_listFiles->setEnabled(false);
} }
else { else {
url_file = APP_URL; url_file = APP_URL;
} }
@ -224,7 +227,6 @@ void FormUpdate::startUpdate() {
tr("Cannot launch external updater. Update application manually."), tr("Cannot launch external updater. Update application manually."),
QSystemTrayIcon::Warning, this); QSystemTrayIcon::Warning, this);
} }
else { else {
qApp->quit(); qApp->quit();
} }
@ -233,19 +235,11 @@ void FormUpdate::startUpdate() {
} }
else if (update_for_this_system) { else if (update_for_this_system) {
// Nothing is downloaded yet, but update for this system
// is available and self-update feature is present.
if (m_downloader == nullptr) {
// Initialie downloader.
m_downloader = new Downloader(this);
connect(m_downloader, &Downloader::progress, this, &FormUpdate::updateProgress);
connect(m_downloader, &Downloader::completed, this, &FormUpdate::updateCompleted);
updateProgress(0, 100); updateProgress(0, 100);
}
m_btnUpdate->setText(tr("Downloading update...")); m_btnUpdate->setText(tr("Downloading update..."));
m_btnUpdate->setEnabled(false); m_btnUpdate->setEnabled(false);
m_downloader->downloadFile(url_file); m_downloader.downloadFile(url_file);
} }
else { else {

View file

@ -23,19 +23,18 @@
#include "ui_formupdate.h" #include "ui_formupdate.h"
#include "miscellaneous/systemfactory.h" #include "miscellaneous/systemfactory.h"
#include "network-web/downloader.h"
#include <QPushButton> #include <QPushButton>
#include <QNetworkReply> #include <QNetworkReply>
class Downloader;
class FormUpdate : public QDialog { class FormUpdate : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
// Constructors and destructors. // Constructors and destructors.
explicit FormUpdate(QWidget* parent = 0); explicit FormUpdate(QWidget* parent);
virtual ~FormUpdate(); virtual ~FormUpdate();
// Returns true if application can self-update // Returns true if application can self-update
@ -54,13 +53,14 @@ class FormUpdate : public QDialog {
private: private:
void loadAvailableFiles(); void loadAvailableFiles();
Downloader* m_downloader; Ui::FormUpdate m_ui;
bool m_readyToInstall;
QString m_updateFilePath;
QScopedPointer<Ui::FormUpdate> m_ui;
UpdateInfo m_updateInfo;
QPushButton* m_btnUpdate; QPushButton* m_btnUpdate;
qint64 m_lastDownloadedBytes;
Downloader m_downloader;
QString m_updateFilePath;
UpdateInfo m_updateInfo;
bool m_readyToInstall = false;
qint64 m_lastDownloadedBytes = 0;
}; };
#endif // FORMUPDATE_H #endif // FORMUPDATE_H

View file

@ -19,20 +19,24 @@
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include <QLabel>
void GuiUtilities::setLabelAsNotice(QLabel& label, bool is_warning) {
void GuiUtilities::setLabelAsNotice(QLabel* label, bool is_warning) { label.setMargin(6);
label->setMargin(6);
if (is_warning) { if (is_warning) {
label->setStyleSheet(QSL("font-weight: bold; font-style: italic; color: red")); label.setStyleSheet(QSL("font-weight: bold; font-style: italic; color: red"));
} }
else { else {
label->setStyleSheet(QSL("font-style: italic;")); label.setStyleSheet(QSL("font-style: italic;"));
} }
} }
GuiUtilities::GuiUtilities() { void GuiUtilities::applyDialogProperties(QWidget& widget, const QIcon& icon, const QString& title) {
widget.setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
widget.setWindowIcon(icon);
if (!title.isEmpty()) {
widget.setWindowTitle(title);
}
} }

View file

@ -18,15 +18,19 @@
#ifndef GUIUTILITIES_H #ifndef GUIUTILITIES_H
#define GUIUTILITIES_H #define GUIUTILITIES_H
#include <QWidget>
#include <QLabel>
class QLabel;
class GuiUtilities { class GuiUtilities {
public: public:
static void setLabelAsNotice(QLabel* label, bool is_warning); static void setLabelAsNotice(QLabel& label, bool is_warning);
static void applyDialogProperties(QWidget& widget, const QIcon& icon, const QString& title = QString());
private: private:
explicit GuiUtilities(); explicit GuiUtilities();
}; };
inline GuiUtilities::GuiUtilities() {}
#endif // GUIUTILITIES_H #endif // GUIUTILITIES_H

View file

@ -29,14 +29,16 @@
SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent) SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsBrowserMail) { : SettingsPanel(settings, parent), m_ui(new Ui::SettingsBrowserMail) {
m_ui->setupUi(this); m_ui->setupUi(this);
GuiUtilities::setLabelAsNotice(m_ui->label, false); GuiUtilities::setLabelAsNotice(*m_ui->label, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblExternalEmailInfo, false); GuiUtilities::setLabelAsNotice(*m_ui->m_lblExternalEmailInfo, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblProxyInfo, false); GuiUtilities::setLabelAsNotice(*m_ui->m_lblProxyInfo, false);
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
m_ui->m_checkOpenLinksInExternal->setVisible(false); m_ui->m_checkOpenLinksInExternal->setVisible(false);
#else #else
connect(m_ui->m_checkOpenLinksInExternal, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings); connect(m_ui->m_checkOpenLinksInExternal, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings);
#endif #endif
connect(m_ui->m_cmbProxyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, connect(m_ui->m_cmbProxyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
&SettingsBrowserMail::dirtifySettings); &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtProxyHost, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings); connect(m_ui->m_txtProxyHost, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
@ -76,11 +78,10 @@ void SettingsBrowserMail::selectBrowserExecutable() {
qApp->getHomeFolderPath(), qApp->getHomeFolderPath(),
//: File filter for external browser selection dialog. //: File filter for external browser selection dialog.
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
tr("Executables (*)") tr("Executables (*)"));
#else #else
tr("Executables (*.*)") tr("Executables (*.*)"));
#endif #endif
);
if (!executable_file.isEmpty()) { if (!executable_file.isEmpty()) {
m_ui->m_txtExternalBrowserExecutable->setText(QDir::toNativeSeparators(executable_file)); m_ui->m_txtExternalBrowserExecutable->setText(QDir::toNativeSeparators(executable_file));
@ -124,11 +125,10 @@ void SettingsBrowserMail::selectEmailExecutable() {
qApp->getHomeFolderPath(), qApp->getHomeFolderPath(),
//: File filter for external e-mail selection dialog. //: File filter for external e-mail selection dialog.
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
tr("Executables (*)") tr("Executables (*)"));
#else #else
tr("Executables (*.*)") tr("Executables (*.*)"));
#endif #endif
);
if (!executable_file.isEmpty()) { if (!executable_file.isEmpty()) {
m_ui->m_txtExternalEmailExecutable->setText(QDir::toNativeSeparators(executable_file)); m_ui->m_txtExternalEmailExecutable->setText(QDir::toNativeSeparators(executable_file));
@ -137,10 +137,12 @@ void SettingsBrowserMail::selectEmailExecutable() {
void SettingsBrowserMail::loadSettings() { void SettingsBrowserMail::loadSettings() {
onBeginLoadSettings(); onBeginLoadSettings();
#if !defined(USE_WEBENGINE) #if !defined(USE_WEBENGINE)
m_ui->m_checkOpenLinksInExternal->setChecked(settings()->value(GROUP(Browser), m_ui->m_checkOpenLinksInExternal->setChecked(settings()->value(GROUP(Browser),
SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool()); SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool());
#endif #endif
// Load settings of web browser GUI. // Load settings of web browser GUI.
m_ui->m_cmbExternalBrowserPreset->addItem(tr("Opera 12 or older"), QSL("-nosession %1")); m_ui->m_cmbExternalBrowserPreset->addItem(tr("Opera 12 or older"), QSL("-nosession %1"));
m_ui->m_txtExternalBrowserExecutable->setText(settings()->value(GROUP(Browser), m_ui->m_txtExternalBrowserExecutable->setText(settings()->value(GROUP(Browser),
@ -148,6 +150,7 @@ void SettingsBrowserMail::loadSettings() {
m_ui->m_txtExternalBrowserArguments->setText(settings()->value(GROUP(Browser), m_ui->m_txtExternalBrowserArguments->setText(settings()->value(GROUP(Browser),
SETTING(Browser::CustomExternalBrowserArguments)).toString()); SETTING(Browser::CustomExternalBrowserArguments)).toString());
m_ui->m_grpCustomExternalBrowser->setChecked(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserEnabled)).toBool()); m_ui->m_grpCustomExternalBrowser->setChecked(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserEnabled)).toBool());
// Load settings of e-mail. // Load settings of e-mail.
m_ui->m_cmbExternalEmailPreset->addItem(tr("Mozilla Thunderbird"), QSL("-compose \"subject='%1',body='%2'\"")); m_ui->m_cmbExternalEmailPreset->addItem(tr("Mozilla Thunderbird"), QSL("-compose \"subject='%1',body='%2'\""));
m_ui->m_txtExternalEmailExecutable->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailExecutable)).toString()); m_ui->m_txtExternalEmailExecutable->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailExecutable)).toString());
@ -157,6 +160,7 @@ void SettingsBrowserMail::loadSettings() {
m_ui->m_cmbProxyType->addItem(tr("System proxy"), QNetworkProxy::DefaultProxy); m_ui->m_cmbProxyType->addItem(tr("System proxy"), QNetworkProxy::DefaultProxy);
m_ui->m_cmbProxyType->addItem(tr("Socks5"), QNetworkProxy::Socks5Proxy); m_ui->m_cmbProxyType->addItem(tr("Socks5"), QNetworkProxy::Socks5Proxy);
m_ui->m_cmbProxyType->addItem(tr("Http"), QNetworkProxy::HttpProxy); m_ui->m_cmbProxyType->addItem(tr("Http"), QNetworkProxy::HttpProxy);
// Load the settings. // Load the settings.
QNetworkProxy::ProxyType selected_proxy_type = static_cast<QNetworkProxy::ProxyType>(settings()->value(GROUP(Proxy), QNetworkProxy::ProxyType selected_proxy_type = static_cast<QNetworkProxy::ProxyType>(settings()->value(GROUP(Proxy),
SETTING(Proxy::Type)).toInt()); SETTING(Proxy::Type)).toInt());
@ -170,13 +174,16 @@ void SettingsBrowserMail::loadSettings() {
void SettingsBrowserMail::saveSettings() { void SettingsBrowserMail::saveSettings() {
onBeginSaveSettings(); onBeginSaveSettings();
#if !defined(USE_WEBENGINE) #if !defined(USE_WEBENGINE)
settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, m_ui->m_checkOpenLinksInExternal->isChecked()); settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, m_ui->m_checkOpenLinksInExternal->isChecked());
#endif #endif
// Save settings of GUI of web browser. // Save settings of GUI of web browser.
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserEnabled, m_ui->m_grpCustomExternalBrowser->isChecked()); settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserEnabled, m_ui->m_grpCustomExternalBrowser->isChecked());
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserExecutable, m_ui->m_txtExternalBrowserExecutable->text()); settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserExecutable, m_ui->m_txtExternalBrowserExecutable->text());
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserArguments, m_ui->m_txtExternalBrowserArguments->text()); settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserArguments, m_ui->m_txtExternalBrowserArguments->text());
// Save settings of e-mail. // Save settings of e-mail.
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailExecutable, m_ui->m_txtExternalEmailExecutable->text()); settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailExecutable, m_ui->m_txtExternalEmailExecutable->text());
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailArguments, m_ui->m_txtExternalEmailArguments->text()); settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailArguments, m_ui->m_txtExternalEmailArguments->text());
@ -186,6 +193,7 @@ void SettingsBrowserMail::saveSettings() {
settings()->setValue(GROUP(Proxy), Proxy::Username, m_ui->m_txtProxyUsername->text()); settings()->setValue(GROUP(Proxy), Proxy::Username, m_ui->m_txtProxyUsername->text());
settings()->setValue(GROUP(Proxy), Proxy::Password, TextFactory::encrypt(m_ui->m_txtProxyPassword->text())); settings()->setValue(GROUP(Proxy), Proxy::Password, TextFactory::encrypt(m_ui->m_txtProxyPassword->text()));
settings()->setValue(GROUP(Proxy), Proxy::Port, m_ui->m_spinProxyPort->value()); settings()->setValue(GROUP(Proxy), Proxy::Port, m_ui->m_spinProxyPort->value());
// Reload settings for all network access managers. // Reload settings for all network access managers.
SilentNetworkAccessManager::instance()->loadSettings(); SilentNetworkAccessManager::instance()->loadSettings();
onEndSaveSettings(); onEndSaveSettings();

View file

@ -27,9 +27,9 @@
SettingsDatabase::SettingsDatabase(Settings* settings, QWidget* parent) SettingsDatabase::SettingsDatabase(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsDatabase) { : SettingsPanel(settings, parent), m_ui(new Ui::SettingsDatabase) {
m_ui->setupUi(this); m_ui->setupUi(this);
GuiUtilities::setLabelAsNotice(m_ui->m_lblDataStorageWarning, true); GuiUtilities::setLabelAsNotice(*m_ui->m_lblDataStorageWarning, true);
GuiUtilities::setLabelAsNotice(m_ui->m_lblMysqlInfo, false); GuiUtilities::setLabelAsNotice(*m_ui->m_lblMysqlInfo, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblSqliteInMemoryWarnings, true); GuiUtilities::setLabelAsNotice(*m_ui->m_lblSqliteInMemoryWarnings, true);
connect(m_ui->m_cmbDatabaseDriver, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, connect(m_ui->m_cmbDatabaseDriver, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
&SettingsDatabase::dirtifySettings); &SettingsDatabase::dirtifySettings);
connect(m_ui->m_checkSqliteUseInMemoryDatabase, &QCheckBox::toggled, this, &SettingsDatabase::dirtifySettings); connect(m_ui->m_checkSqliteUseInMemoryDatabase, &QCheckBox::toggled, this, &SettingsDatabase::dirtifySettings);

View file

@ -11,6 +11,18 @@
</rect> </rect>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QCheckBox" name="m_checkOpenManagerWhenDownloadStarts"> <widget class="QCheckBox" name="m_checkOpenManagerWhenDownloadStarts">
<property name="text"> <property name="text">

View file

@ -34,7 +34,7 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsFeedsMessages) { : SettingsPanel(settings, parent), m_ui(new Ui::SettingsFeedsMessages) {
m_ui->setupUi(this); m_ui->setupUi(this);
initializeMessageDateFormats(); initializeMessageDateFormats();
GuiUtilities::setLabelAsNotice(m_ui->label_9, false); GuiUtilities::setLabelAsNotice(*m_ui->label_9, false);
connect(m_ui->m_checkAutoUpdateNotification, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkAutoUpdateNotification, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkAutoUpdate, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkAutoUpdate, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkKeppMessagesInTheMiddle, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkKeppMessagesInTheMiddle, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);

View file

@ -38,14 +38,14 @@ void SettingsGeneral::loadSettings() {
onBeginLoadSettings(); onBeginLoadSettings();
m_ui->m_checkForUpdatesOnStart->setChecked(settings()->value(GROUP(General), SETTING(General::UpdateOnStartup)).toBool()); m_ui->m_checkForUpdatesOnStart->setChecked(settings()->value(GROUP(General), SETTING(General::UpdateOnStartup)).toBool());
// Load auto-start status. // Load auto-start status.
const SystemFactory::AutoStartStatus autostart_status = qApp->system()->getAutoStartStatus(); const SystemFactory::AutoStartStatus autostart_status = qApp->system()->autoStartStatus();
switch (autostart_status) { switch (autostart_status) {
case SystemFactory::Enabled: case SystemFactory::AutoStartStatus::Enabled:
m_ui->m_checkAutostart->setChecked(true); m_ui->m_checkAutostart->setChecked(true);
break; break;
case SystemFactory::Disabled: case SystemFactory::AutoStartStatus::Disabled:
m_ui->m_checkAutostart->setChecked(false); m_ui->m_checkAutostart->setChecked(false);
break; break;
@ -69,11 +69,11 @@ void SettingsGeneral::saveSettings() {
// If auto-start feature is available and user wants to turn it on, then turn it on. // If auto-start feature is available and user wants to turn it on, then turn it on.
if (m_ui->m_checkAutostart->isChecked()) { if (m_ui->m_checkAutostart->isChecked()) {
qApp->system()->setAutoStartStatus(SystemFactory::Enabled); qApp->system()->setAutoStartStatus(SystemFactory::AutoStartStatus::Enabled);
} }
else { else {
qApp->system()->setAutoStartStatus(SystemFactory::Disabled); qApp->system()->setAutoStartStatus(SystemFactory::AutoStartStatus::Disabled);
} }
settings()->setValue(GROUP(General), General::UpdateOnStartup, m_ui->m_checkForUpdatesOnStart->isChecked()); settings()->setValue(GROUP(General), General::UpdateOnStartup, m_ui->m_checkForUpdatesOnStart->isChecked());

View file

@ -49,15 +49,14 @@ bool TrayIconMenu::event(QEvent* event) {
SystemTrayIcon::SystemTrayIcon(const QString& normal_icon, const QString& plain_icon, FormMain* parent) SystemTrayIcon::SystemTrayIcon(const QString& normal_icon, const QString& plain_icon, FormMain* parent)
: QSystemTrayIcon(parent), : QSystemTrayIcon(parent),
m_normalIcon(normal_icon), m_normalIcon(normal_icon),
m_plainPixmap(plain_icon), m_plainPixmap(plain_icon) {
m_font(QFont()),
m_bubbleClickTarget(nullptr),
m_bubbleClickSlot(nullptr) {
qDebug("Creating SystemTrayIcon instance."); qDebug("Creating SystemTrayIcon instance.");
m_font.setBold(true); m_font.setBold(true);
// Initialize icon. // Initialize icon.
setNumber(); setNumber();
setContextMenu(parent->trayMenu()); setContextMenu(parent->trayMenu());
// Create necessary connections. // Create necessary connections.
connect(this, &SystemTrayIcon::activated, this, &SystemTrayIcon::onActivated); connect(this, &SystemTrayIcon::activated, this, &SystemTrayIcon::onActivated);
} }
@ -97,9 +96,11 @@ void SystemTrayIcon::showPrivate() {
// the settings window) gets closed. Behavior for main window // the settings window) gets closed. Behavior for main window
// is handled explicitly by FormMain::closeEvent() method. // is handled explicitly by FormMain::closeEvent() method.
qApp->setQuitOnLastWindowClosed(false); qApp->setQuitOnLastWindowClosed(false);
// Display the tray icon. // Display the tray icon.
QSystemTrayIcon::show(); QSystemTrayIcon::show();
emit shown(); emit shown();
qDebug("Tray icon displayed."); qDebug("Tray icon displayed.");
} }
@ -120,11 +121,11 @@ void SystemTrayIcon::setNumber(int number, bool any_new_message) {
setToolTip(QSL(APP_LONG_NAME)); setToolTip(QSL(APP_LONG_NAME));
QSystemTrayIcon::setIcon(QIcon(m_normalIcon)); QSystemTrayIcon::setIcon(QIcon(m_normalIcon));
} }
else { else {
setToolTip(tr("%1\nUnread news: %2").arg(QSL(APP_LONG_NAME), QString::number(number))); setToolTip(tr("%1\nUnread news: %2").arg(QSL(APP_LONG_NAME), QString::number(number)));
QPixmap background(m_plainPixmap); QPixmap background(m_plainPixmap);
QPainter tray_painter; QPainter tray_painter;
// FIXME: Here draw different background instead of different color of number. // FIXME: Here draw different background instead of different color of number.
tray_painter.begin(&background); tray_painter.begin(&background);
tray_painter.setPen(any_new_message ? Qt::black : Qt::black); tray_painter.setPen(any_new_message ? Qt::black : Qt::black);
@ -138,17 +139,14 @@ void SystemTrayIcon::setNumber(int number, bool any_new_message) {
tray_painter.setFont(m_font); tray_painter.setFont(m_font);
tray_painter.drawText(QRect(0, 0, 128, 128), Qt::AlignVCenter | Qt::AlignCenter, QChar(8734)); tray_painter.drawText(QRect(0, 0, 128, 128), Qt::AlignVCenter | Qt::AlignCenter, QChar(8734));
} }
else { else {
// Smaller number if it has 3 digits. // Smaller number if it has 3 digits.
if (number > 99) { if (number > 99) {
m_font.setPixelSize(55); m_font.setPixelSize(55);
} }
else if (number > 9) { else if (number > 9) {
m_font.setPixelSize(80); m_font.setPixelSize(80);
} }
// Bigger number if it has just one digit. // Bigger number if it has just one digit.
else { else {
m_font.setPixelSize(100); m_font.setPixelSize(100);
@ -164,18 +162,15 @@ void SystemTrayIcon::setNumber(int number, bool any_new_message) {
} }
void SystemTrayIcon::showMessage(const QString& title, const QString& message, QSystemTrayIcon::MessageIcon icon, void SystemTrayIcon::showMessage(const QString& title, const QString& message, QSystemTrayIcon::MessageIcon icon,
int milliseconds_timeout_hint, QObject* click_target, const char* click_slot) { int milliseconds_timeout_hint, std::function<void()> functor) {
if (m_bubbleClickTarget != nullptr && m_bubbleClickSlot != nullptr) { if (m_connection) {
// Disconnect previous bubble click signalling. // Disconnect previous bubble click signalling.
disconnect(this, SIGNAL(messageClicked()), m_bubbleClickTarget, m_bubbleClickSlot); disconnect(m_connection);
} }
m_bubbleClickSlot = (char*) click_slot; if (functor) {
m_bubbleClickTarget = click_target;
if (click_target != nullptr && click_slot != nullptr) {
// Establish new connection for bubble click. // Establish new connection for bubble click.
connect(this, SIGNAL(messageClicked()), click_target, click_slot); m_connection = connect(this, &SystemTrayIcon::messageClicked, functor);
} }
// NOTE: If connections do not work, then use QMetaObject::invokeMethod(...). // NOTE: If connections do not work, then use QMetaObject::invokeMethod(...).

View file

@ -57,8 +57,7 @@ class SystemTrayIcon : public QSystemTrayIcon {
void setNumber(int number = -1, bool any_new_message = false); void setNumber(int number = -1, bool any_new_message = false);
void showMessage(const QString& title, const QString& message, MessageIcon icon = Information, void showMessage(const QString& title, const QString& message, MessageIcon icon = Information,
int milliseconds_timeout_hint = TRAY_ICON_BUBBLE_TIMEOUT, QObject* click_target = nullptr, int milliseconds_timeout_hint = TRAY_ICON_BUBBLE_TIMEOUT, std::function<void()> functor = nullptr);
const char* click_slot = nullptr);
// Returns true if tray icon CAN be constructed on this machine. // Returns true if tray icon CAN be constructed on this machine.
static bool isSystemTrayAvailable(); static bool isSystemTrayAvailable();
@ -83,10 +82,9 @@ class SystemTrayIcon : public QSystemTrayIcon {
private: private:
QIcon m_normalIcon; QIcon m_normalIcon;
QPixmap m_plainPixmap; QPixmap m_plainPixmap;
QFont m_font; QFont m_font = QFont();
QObject* m_bubbleClickTarget; QMetaObject::Connection m_connection;
char* m_bubbleClickSlot;
}; };
#endif // SYSTEMTRAYICON_H #endif // SYSTEMTRAYICON_H

View file

@ -26,6 +26,8 @@
#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/dialogs/formupdate.h"
#include "gui/dialogs/formabout.h"
#include "network-web/silentnetworkaccessmanager.h" #include "network-web/silentnetworkaccessmanager.h"
#include "network-web/webfactory.h" #include "network-web/webfactory.h"
@ -138,7 +140,9 @@ int main(int argc, char* argv[]) {
if (qApp->isFirstRun() || qApp->isFirstRun(APP_VERSION)) { if (qApp->isFirstRun() || qApp->isFirstRun(APP_VERSION)) {
qApp->showGuiMessage(QSL(APP_NAME), QObject::tr("Welcome to %1.\n\nPlease, check NEW stuff included in this\n" qApp->showGuiMessage(QSL(APP_NAME), QObject::tr("Welcome to %1.\n\nPlease, check NEW stuff included in this\n"
"version by clicking this popup notification.").arg(APP_LONG_NAME), "version by clicking this popup notification.").arg(APP_LONG_NAME),
QSystemTrayIcon::NoIcon, 0, false, &main_window, SLOT(showAbout())); QSystemTrayIcon::NoIcon, 0, false, [] {
FormAbout(qApp->mainForm()).exec();
});
} }
else { else {
@ -146,7 +150,20 @@ int main(int argc, char* argv[]) {
} }
if (qApp->settings()->value(GROUP(General), SETTING(General::UpdateOnStartup)).toBool()) { if (qApp->settings()->value(GROUP(General), SETTING(General::UpdateOnStartup)).toBool()) {
QTimer::singleShot(STARTUP_UPDATE_DELAY, application.system(), SLOT(checkForUpdatesOnStartup())); QObject::connect(qApp->system(), &SystemFactory::updatesChecked, [](QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> updates) {
QObject::disconnect(qApp->system(), &SystemFactory::updatesChecked, nullptr, nullptr);
if (!updates.first.isEmpty() && updates.second == QNetworkReply::NoError &&
!SystemFactory::isVersionNewer(updates.first.at(0).m_availableVersion, APP_VERSION)) {
qApp->showGuiMessage(QObject::tr("New version available"),
QObject::tr("Click the bubble for more information."),
QSystemTrayIcon::Information, qApp->mainForm(), false,
[] {
FormUpdate(qApp->mainForm()).exec();
});
}
});
qApp->system()->checkForUpdates();
} }
qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->loadAllExpandStates(); qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->loadAllExpandStates();

View file

@ -224,7 +224,7 @@ QString Application::getUserDataAppPath() {
return applicationDirPath() + QDir::separator() + QSL("data"); return applicationDirPath() + QDir::separator() + QSL("data");
} }
QString Application::getUserDataPath() { QString Application::userDataPath() {
if (settings()->type() == SettingsProperties::Portable) { if (settings()->type() == SettingsProperties::Portable) {
return getUserDataAppPath(); return getUserDataAppPath();
} }
@ -368,17 +368,14 @@ void Application::deleteTrayIcon() {
void Application::showGuiMessage(const QString& title, const QString& message, void Application::showGuiMessage(const QString& title, const QString& message,
QSystemTrayIcon::MessageIcon message_type, QWidget* parent, QSystemTrayIcon::MessageIcon message_type, QWidget* parent,
bool show_at_least_msgbox, QObject* invokation_target, bool show_at_least_msgbox, std::function<void()> functor) {
const char* invokation_slot) {
if (SystemTrayIcon::areNotificationsEnabled() && SystemTrayIcon::isSystemTrayActivated()) { if (SystemTrayIcon::areNotificationsEnabled() && SystemTrayIcon::isSystemTrayActivated()) {
trayIcon()->showMessage(title, message, message_type, TRAY_ICON_BUBBLE_TIMEOUT, invokation_target, invokation_slot); trayIcon()->showMessage(title, message, message_type, TRAY_ICON_BUBBLE_TIMEOUT, functor);
} }
else if (show_at_least_msgbox) { else if (show_at_least_msgbox) {
// Tray icon or OSD is not available, display simple text box. // Tray icon or OSD is not available, display simple text box.
MessageBox::show(parent, (QMessageBox::Icon) message_type, title, message); MessageBox::show(parent, (QMessageBox::Icon) message_type, title, message);
} }
else { else {
qDebug("Silencing GUI message: '%s'.", qPrintable(message)); qDebug("Silencing GUI message: '%s'.", qPrintable(message));
} }
@ -422,7 +419,6 @@ void Application::onAboutToQuit() {
// We locked the lock to exit peacefully, unlock it to avoid warnings. // We locked the lock to exit peacefully, unlock it to avoid warnings.
feedUpdateLock()->unlock(); feedUpdateLock()->unlock();
} }
else { else {
// Request for write lock timed-out. This means // Request for write lock timed-out. This means
// that some critical action can be processed right now. // that some critical action can be processed right now.
@ -439,7 +435,6 @@ void Application::onAboutToQuit() {
if (QProcess::startDetached(QString("\"") + QDir::toNativeSeparators(applicationFilePath()) + QString("\""))) { if (QProcess::startDetached(QString("\"") + QDir::toNativeSeparators(applicationFilePath()) + QString("\""))) {
qDebug("New application instance was started."); qDebug("New application instance was started.");
} }
else { else {
qWarning("New application instance was not started successfully."); qWarning("New application instance was not started successfully.");
} }

View file

@ -101,7 +101,7 @@ class Application : public QtSingleApplication {
// Returns the base folder to which store user data, the "data" folder. // Returns the base folder to which store user data, the "data" folder.
// NOTE: Use this to get correct path under which store user data. // NOTE: Use this to get correct path under which store user data.
QString getUserDataPath(); QString userDataPath();
void setMainForm(FormMain* main_form); void setMainForm(FormMain* main_form);
@ -118,7 +118,7 @@ class Application : public QtSingleApplication {
// or in message box if tray icon is disabled. // or in message box if tray icon is disabled.
void showGuiMessage(const QString& title, const QString& message, QSystemTrayIcon::MessageIcon message_type, void showGuiMessage(const QString& title, const QString& message, QSystemTrayIcon::MessageIcon message_type,
QWidget* parent = nullptr, bool show_at_least_msgbox = false, QWidget* parent = nullptr, bool show_at_least_msgbox = false,
QObject* invokation_target = nullptr, const char* invokation_slot = nullptr); std::function<void()> functor = nullptr);
// Returns pointer to "GOD" application singleton. // Returns pointer to "GOD" application singleton.
inline static Application* instance() { inline static Application* instance() {

View file

@ -195,7 +195,7 @@ void DatabaseFactory::finishRestoration() {
} }
void DatabaseFactory::sqliteAssemblyDatabaseFilePath() { void DatabaseFactory::sqliteAssemblyDatabaseFilePath() {
m_sqliteDatabaseFilePath = qApp->getUserDataPath() + QDir::separator() + QString(APP_DB_SQLITE_PATH); m_sqliteDatabaseFilePath = qApp->userDataPath() + QDir::separator() + QString(APP_DB_SQLITE_PATH);
} }
QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() { QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {

View file

@ -71,8 +71,8 @@ void SkinFactory::setCurrentSkinName(const QString& skin_name) {
qApp->settings()->setValue(GROUP(GUI), GUI::Skin, skin_name); qApp->settings()->setValue(GROUP(GUI), GUI::Skin, skin_name);
} }
QString SkinFactory::getUserSkinBaseFolder() const { QString SkinFactory::customSkinBaseFolder() const {
return qApp->getUserDataPath() + QDir::separator() + APP_SKIN_USER_FOLDER; return qApp->userDataPath() + QDir::separator() + APP_SKIN_USER_FOLDER;
} }
QString SkinFactory::selectedSkinName() const { QString SkinFactory::selectedSkinName() const {
@ -92,7 +92,7 @@ Skin SkinFactory::skinInfo(const QString& skin_name, bool* ok) const {
Skin skin; Skin skin;
QStringList base_skin_folders; QStringList base_skin_folders;
base_skin_folders.append(APP_SKIN_PATH); base_skin_folders.append(APP_SKIN_PATH);
base_skin_folders.append(getUserSkinBaseFolder()); base_skin_folders.append(customSkinBaseFolder());
while (!base_skin_folders.isEmpty()) { while (!base_skin_folders.isEmpty()) {
const QString skin_folder = base_skin_folders.takeAt(0) + QDir::separator() + skin_name + QDir::separator(); const QString skin_folder = base_skin_folders.takeAt(0) + QDir::separator() + skin_name + QDir::separator();
@ -164,7 +164,7 @@ QList<Skin> SkinFactory::installedSkins() const {
QDir::NoDotAndDotDot | QDir::NoDotAndDotDot |
QDir::NoSymLinks | QDir::NoSymLinks |
QDir::Readable); QDir::Readable);
skin_directories.append(QDir(getUserSkinBaseFolder()).entryList(QDir::Dirs | skin_directories.append(QDir(customSkinBaseFolder()).entryList(QDir::Dirs |
QDir::NoDotAndDotDot | QDir::NoDotAndDotDot |
QDir::NoSymLinks | QDir::NoSymLinks |
QDir::Readable)); QDir::Readable));

View file

@ -72,7 +72,7 @@ class SkinFactory : public QObject {
// Sets the desired skin as the active one if it exists. // Sets the desired skin as the active one if it exists.
void setCurrentSkinName(const QString& skin_name); void setCurrentSkinName(const QString& skin_name);
QString getUserSkinBaseFolder() const; QString customSkinBaseFolder() const;
private: private:

View file

@ -46,7 +46,7 @@ SystemFactory::SystemFactory(QObject* parent) : QObject(parent) {
SystemFactory::~SystemFactory() { SystemFactory::~SystemFactory() {
} }
SystemFactory::AutoStartStatus SystemFactory::getAutoStartStatus() const { SystemFactory::AutoStartStatus SystemFactory::autoStartStatus() const {
// User registry way to auto-start the application on Windows. // User registry way to auto-start the application on Windows.
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
QSettings registry_key(QSL("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"), QSettings registry_key(QSL("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"),
@ -57,17 +57,17 @@ SystemFactory::AutoStartStatus SystemFactory::getAutoStartStatus() const {
Application::applicationFilePath(); Application::applicationFilePath();
if (autostart_enabled) { if (autostart_enabled) {
return SystemFactory::Enabled; return AutoStartStatus::Enabled;
} }
else { else {
return SystemFactory::Disabled; return AutoStartStatus::Disabled;
} }
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
// Use proper freedesktop.org way to auto-start the application on Linux. // Use proper freedesktop.org way to auto-start the application on Linux.
// INFO: http://standards.freedesktop.org/autostart-spec/latest/ // INFO: http://standards.freedesktop.org/autostart-spec/latest/
const QString desktop_file_location = getAutostartDesktopFileLocation(); const QString desktop_file_location = autostartDesktopFileLocation();
// No correct path was found. // No correct path was found.
if (desktop_file_location.isEmpty()) { if (desktop_file_location.isEmpty()) {
@ -94,7 +94,7 @@ SystemFactory::AutoStartStatus SystemFactory::getAutoStartStatus() const {
} }
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
QString SystemFactory::getAutostartDesktopFileLocation() const { QString SystemFactory::autostartDesktopFileLocation() const {
const QString xdg_config_path(qgetenv("XDG_CONFIG_HOME")); const QString xdg_config_path(qgetenv("XDG_CONFIG_HOME"));
QString desktop_file_location; QString desktop_file_location;
@ -119,11 +119,11 @@ QString SystemFactory::getAutostartDesktopFileLocation() const {
} }
#endif #endif
bool SystemFactory::setAutoStartStatus(const AutoStartStatus& new_status) { bool SystemFactory::setAutoStartStatus(AutoStartStatus new_status) {
const SystemFactory::AutoStartStatus current_status = SystemFactory::getAutoStartStatus(); const SystemFactory::AutoStartStatus current_status = SystemFactory::autoStartStatus();
// Auto-start feature is not even available, exit. // Auto-start feature is not even available, exit.
if (current_status == SystemFactory::Unavailable) { if (current_status == AutoStartStatus::Unavailable) {
return false; return false;
} }
@ -131,12 +131,12 @@ bool SystemFactory::setAutoStartStatus(const AutoStartStatus& new_status) {
QSettings registry_key(QSL("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"), QSettings::NativeFormat); QSettings registry_key(QSL("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"), QSettings::NativeFormat);
switch (new_status) { switch (new_status) {
case SystemFactory::Enabled: case AutoStartStatus::Enabled:
registry_key.setValue(APP_LOW_NAME, registry_key.setValue(APP_LOW_NAME,
Application::applicationFilePath().replace(QL1C('/'), QL1C('\\'))); Application::applicationFilePath().replace(QL1C('/'), QL1C('\\')));
return true; return true;
case SystemFactory::Disabled: case AutoStartStatus::Disabled:
registry_key.remove(APP_LOW_NAME); registry_key.remove(APP_LOW_NAME);
return true; return true;
@ -147,11 +147,11 @@ bool SystemFactory::setAutoStartStatus(const AutoStartStatus& new_status) {
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
// Note that we expect here that no other program uses // Note that we expect here that no other program uses
// "rssguard.desktop" desktop file. // "rssguard.desktop" desktop file.
const QString destination_file = getAutostartDesktopFileLocation(); const QString destination_file = autostartDesktopFileLocation();
const QString destination_folder = QFileInfo(destination_file).absolutePath(); const QString destination_folder = QFileInfo(destination_file).absolutePath();
switch (new_status) { switch (new_status) {
case SystemFactory::Enabled: { case AutoStartStatus::Enabled: {
if (QFile::exists(destination_file)) { if (QFile::exists(destination_file)) {
if (!QFile::remove(destination_file)) { if (!QFile::remove(destination_file)) {
return false; return false;
@ -166,7 +166,7 @@ bool SystemFactory::setAutoStartStatus(const AutoStartStatus& new_status) {
return QFile::copy(source_autostart_desktop_file, destination_file); return QFile::copy(source_autostart_desktop_file, destination_file);
} }
case SystemFactory::Disabled: case AutoStartStatus::Disabled:
return QFile::remove(destination_file); return QFile::remove(destination_file);
default: default:
@ -193,7 +193,7 @@ bool SystemFactory::removeTrolltechJunkRegistryKeys() {
} }
#endif #endif
QString SystemFactory::getUsername() const { QString SystemFactory::loggedInUser() const {
QString name = qgetenv("USER"); QString name = qgetenv("USER");
if (name.isEmpty()) { if (name.isEmpty()) {
@ -207,17 +207,24 @@ QString SystemFactory::getUsername() const {
return name; return name;
} }
QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> SystemFactory::checkForUpdates() const { void SystemFactory::checkForUpdates() const {
Downloader* downloader = new Downloader();
connect(downloader, &Downloader::completed, [this, downloader]() {
QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> result; QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> result;
QByteArray releases_json; result.second = downloader->lastOutputError();
result.second = NetworkFactory::performNetworkOperation(RELEASES_LIST, DOWNLOAD_TIMEOUT, QByteArray(), QString(),
releases_json, QNetworkAccessManager::GetOperation).first;
if (result.second == QNetworkReply::NoError) { if (result.second == QNetworkReply::NoError) {
result.first = parseUpdatesFile(releases_json); QByteArray obtained_data = downloader->lastOutputData();
result.first = parseUpdatesFile(obtained_data);
} }
return result; emit updatesChecked(result);
downloader->deleteLater();
});
downloader->downloadFile(RELEASES_LIST);
} }
bool SystemFactory::isVersionNewer(const QString& new_version, const QString& base_version) { bool SystemFactory::isVersionNewer(const QString& new_version, const QString& base_version) {
@ -297,15 +304,3 @@ QList<UpdateInfo> SystemFactory::parseUpdatesFile(const QByteArray& updates_file
}); });
return updates; return updates;
} }
void SystemFactory::checkForUpdatesOnStartup() {
const QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> updates = checkForUpdates();
if (!updates.first.isEmpty() && updates.second == QNetworkReply::NoError && isVersionNewer(updates.first.at(0).m_availableVersion,
APP_VERSION)) {
qApp->showGuiMessage(tr("New version available"),
tr("Click the bubble for more information."),
QSystemTrayIcon::Information,
nullptr, true, qApp->mainFormWidget(), SLOT(showUpdates()));
}
}

View file

@ -20,6 +20,8 @@
#include <QObject> #include <QObject>
#include "network-web/downloader.h"
#include <QMetaType> #include <QMetaType>
#include <QHash> #include <QHash>
#include <QPair> #include <QPair>
@ -35,9 +37,6 @@ class UpdateUrl {
class UpdateInfo { class UpdateInfo {
public: public:
explicit UpdateInfo() : m_availableVersion(QString()), m_changes(QString()), m_urls(QList<UpdateUrl>()) {
}
QString m_availableVersion; QString m_availableVersion;
QString m_changes; QString m_changes;
QList<UpdateUrl> m_urls; QList<UpdateUrl> m_urls;
@ -51,25 +50,22 @@ class SystemFactory : public QObject {
public: public:
// Specifies possible states of auto-start functionality. // Specifies possible states of auto-start functionality.
enum AutoStartStatus { enum class AutoStartStatus {
Enabled, Enabled,
Disabled, Disabled,
Unavailable Unavailable
}; };
// Constructors and destructors. explicit SystemFactory(QObject* parent = nullptr);
explicit SystemFactory(QObject* parent = 0);
// Constructors and destructors.
virtual ~SystemFactory(); virtual ~SystemFactory();
// Returns current status of auto-start function. // Returns current status of auto-start function.
SystemFactory::AutoStartStatus getAutoStartStatus() const; SystemFactory::AutoStartStatus autoStartStatus() const;
// Sets new status for auto-start function. // Sets new status for auto-start function.
// Function returns false if setting of // Function returns false if setting of
// new status failed. // new status failed.
bool setAutoStartStatus(const SystemFactory::AutoStartStatus& new_status); bool setAutoStartStatus(AutoStartStatus new_status);
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
bool removeTrolltechJunkRegistryKeys(); bool removeTrolltechJunkRegistryKeys();
@ -78,14 +74,14 @@ class SystemFactory : public QObject {
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
// Returns standard location where auto-start .desktop files // Returns standard location where auto-start .desktop files
// should be placed. // should be placed.
QString getAutostartDesktopFileLocation() const; QString autostartDesktopFileLocation() const;
#endif #endif
// Retrieves username of currently logged-in user. // Retrieves username of currently logged-in user.
QString getUsername() const; QString loggedInUser() const;
// Tries to download list with new updates. // Tries to download list with new updates.
QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> checkForUpdates() const; void checkForUpdates() const;
// Checks if update is newer than current application version. // Checks if update is newer than current application version.
static bool isVersionNewer(const QString& new_version, const QString& base_version); static bool isVersionNewer(const QString& new_version, const QString& base_version);
@ -93,8 +89,8 @@ class SystemFactory : public QObject {
static bool openFolderFile(const QString& file_path); static bool openFolderFile(const QString& file_path);
public slots: signals:
void checkForUpdatesOnStartup(); void updatesChecked(QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> updates) const;
private: private:
// Performs parsing of downloaded file with list of updates. // Performs parsing of downloaded file with list of updates.

View file

@ -223,7 +223,7 @@ AdBlockCustomList* AdBlockManager::customList() const {
} }
QString AdBlockManager::storedListsPath() { QString AdBlockManager::storedListsPath() {
return qApp->getUserDataPath() + QDir::separator() + ADBLOCK_LISTS_SUBDIRECTORY; return qApp->userDataPath() + QDir::separator() + ADBLOCK_LISTS_SUBDIRECTORY;
} }
void AdBlockManager::load() { void AdBlockManager::load() {

View file

@ -187,6 +187,7 @@ void Downloader::runGetRequest(const QNetworkRequest& request) {
m_activeReply->setProperty("protected", m_targetProtected); m_activeReply->setProperty("protected", m_targetProtected);
m_activeReply->setProperty("username", m_targetUsername); m_activeReply->setProperty("username", m_targetUsername);
m_activeReply->setProperty("password", m_targetPassword); m_activeReply->setProperty("password", m_targetPassword);
connect(m_activeReply, &QNetworkReply::downloadProgress, this, &Downloader::progressInternal); connect(m_activeReply, &QNetworkReply::downloadProgress, this, &Downloader::progressInternal);
connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished); connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished);
} }

View file

@ -34,7 +34,7 @@ class Downloader : public QObject {
public: public:
// Constructors and destructors. // Constructors and destructors.
explicit Downloader(QObject* parent = 0); explicit Downloader(QObject* parent = nullptr);
virtual ~Downloader(); virtual ~Downloader();
// Access to last received full output data/error/content-type. // Access to last received full output data/error/content-type.
@ -55,9 +55,6 @@ class Downloader : public QObject {
bool protected_contents = false, const QString& username = QString(), bool protected_contents = false, const QString& username = QString(),
const QString& password = QString()); const QString& password = QString());
// Performs asynchronous upload of given data as HTTP POST.
// User needs to setup "Content-Encoding" header which
// matches encoding of the data.
void manipulateData(const QString& url, QNetworkAccessManager::Operation operation, void manipulateData(const QString& url, QNetworkAccessManager::Operation operation,
const QByteArray& data = QByteArray(), const QByteArray& data = QByteArray(),
int timeout = DOWNLOAD_TIMEOUT, bool protected_contents = false, int timeout = DOWNLOAD_TIMEOUT, bool protected_contents = false,

View file

@ -416,7 +416,9 @@ void DownloadItem::finished() {
if (downloadedSuccessfully()) { if (downloadedSuccessfully()) {
qApp->showGuiMessage(tr("Download finished"), qApp->showGuiMessage(tr("Download finished"),
tr("File '%1' is downloaded.\nClick here to open parent directory.").arg(QDir::toNativeSeparators(m_output.fileName())), tr("File '%1' is downloaded.\nClick here to open parent directory.").arg(QDir::toNativeSeparators(m_output.fileName())),
QSystemTrayIcon::Information, 0, false, this, SLOT(openFolder())); QSystemTrayIcon::Information, 0, false, [this] {
openFolder();
});
} }
} }

View file

@ -46,7 +46,7 @@ StandardServiceRoot::StandardServiceRoot(RootItem* parent)
: ServiceRoot(parent), m_recycleBin(new RecycleBin(this)), : ServiceRoot(parent), m_recycleBin(new RecycleBin(this)),
m_actionExportFeeds(nullptr), m_actionImportFeeds(nullptr), m_serviceMenu(QList<QAction*>()), m_actionExportFeeds(nullptr), m_actionImportFeeds(nullptr), m_serviceMenu(QList<QAction*>()),
m_feedContextMenu(QList<QAction*>()), m_actionFeedFetchMetadata(nullptr) { m_feedContextMenu(QList<QAction*>()), m_actionFeedFetchMetadata(nullptr) {
setTitle(qApp->system()->getUsername() + QL1S("@") + QL1S(APP_LOW_NAME)); setTitle(qApp->system()->loggedInUser() + QL1S("@") + QL1S(APP_LOW_NAME));
setIcon(StandardServiceEntryPoint().icon()); setIcon(StandardServiceEntryPoint().icon());
setDescription(tr("This is obligatory service account for standard RSS/RDF/ATOM feeds.")); setDescription(tr("This is obligatory service account for standard RSS/RDF/ATOM feeds."));
} }