diff --git a/CMakeLists.txt b/CMakeLists.txt index e2c967a58..2880ce56a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -383,6 +383,7 @@ set(APP_SOURCES src/miscellaneous/iconfactory.cpp src/miscellaneous/iofactory.cpp src/miscellaneous/autosaver.cpp + src/miscellaneous/mutex.cpp # EXCEPTIONS sources. src/exceptions/applicationexception.cpp @@ -476,6 +477,7 @@ set(APP_HEADERS src/miscellaneous/iconfactory.h src/miscellaneous/skinfactory.h src/miscellaneous/autosaver.h + src/miscellaneous/mutex.h # CORE headers. src/core/messagesmodel.h diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp index fa270386b..223374ea1 100755 --- a/src/gui/feedmessageviewer.cpp +++ b/src/gui/feedmessageviewer.cpp @@ -21,6 +21,7 @@ #include "miscellaneous/databasefactory.h" #include "miscellaneous/systemfactory.h" #include "miscellaneous/iconfactory.h" +#include "miscellaneous/mutex.h" #include "core/messagesproxymodel.h" #include "core/feeddownloader.h" #include "core/feedsmodelfeed.h" diff --git a/src/gui/feedsview.cpp b/src/gui/feedsview.cpp index 63ea5e77c..c16837afa 100755 --- a/src/gui/feedsview.cpp +++ b/src/gui/feedsview.cpp @@ -26,6 +26,7 @@ #include "core/feedsmodelrecyclebin.h" #include "core/feedsmodelfeed.h" #include "miscellaneous/systemfactory.h" +#include "miscellaneous/mutex.h" #include "gui/formmain.h" #include "gui/formcategorydetails.h" #include "gui/formfeeddetails.h" @@ -202,8 +203,7 @@ void FeedsView::executeNextAutoUpdate() { return; } - // If global auto-update is enabled - // and its interval counter reached zero, + // If global auto-update is enabled and its interval counter reached zero, // then we need to restore it. if (m_globalAutoUpdateEnabled && --m_globalAutoUpdateRemainingInterval < 0) { // We should start next auto-update interval. diff --git a/src/gui/formimportexport.h b/src/gui/formimportexport.h index d3bebf653..cab60cc05 100644 --- a/src/gui/formimportexport.h +++ b/src/gui/formimportexport.h @@ -36,6 +36,7 @@ class FormImportExport : public QDialog { OPML20 = 0 }; + // Constructors. explicit FormImportExport(QWidget *parent = 0); virtual ~FormImportExport(); diff --git a/src/gui/formmain.cpp b/src/gui/formmain.cpp index 606f37754..1475ca50d 100755 --- a/src/gui/formmain.cpp +++ b/src/gui/formmain.cpp @@ -21,6 +21,7 @@ #include "miscellaneous/settings.h" #include "miscellaneous/application.h" #include "miscellaneous/systemfactory.h" +#include "miscellaneous/mutex.h" #include "miscellaneous/databasefactory.h" #include "miscellaneous/iconfactory.h" #include "network-web/webfactory.h" diff --git a/src/miscellaneous/application.cpp b/src/miscellaneous/application.cpp index 62a6931cd..202b7b20f 100755 --- a/src/miscellaneous/application.cpp +++ b/src/miscellaneous/application.cpp @@ -19,6 +19,7 @@ #include "miscellaneous/iconfactory.h" #include "miscellaneous/iofactory.h" +#include "miscellaneous/mutex.h" #include "gui/feedsview.h" #include "gui/feedmessageviewer.h" #include "gui/messagebox.h" @@ -66,13 +67,20 @@ DownloadManager *Application::downloadManager() { m_downloadManager = new DownloadManager(); connect(m_downloadManager, SIGNAL(downloadFinished()), mainForm()->statusBar(), SLOT(clearProgressDownload())); - connect(m_downloadManager, SIGNAL(downloadProgress(int,QString)), - mainForm()->statusBar(), SLOT(showProgressDownload(int,QString))); + connect(m_downloadManager, SIGNAL(downloadProgress(int,QString)), mainForm()->statusBar(), SLOT(showProgressDownload(int,QString))); } return m_downloadManager; } +Mutex *Application::feedUpdateLock() { + if (m_updateFeedsLock == NULL) { + m_updateFeedsLock = new Mutex(); + } + + return m_updateFeedsLock; +} + void Application::backupDatabaseSettings(bool backup_database, bool backup_settings, const QString &target_path, const QString &backup_name) { if (!QFileInfo(target_path).isWritable()) { diff --git a/src/miscellaneous/application.h b/src/miscellaneous/application.h index a6b057572..b25bddb76 100755 --- a/src/miscellaneous/application.h +++ b/src/miscellaneous/application.h @@ -30,7 +30,6 @@ #include "gui/systemtrayicon.h" #include "network-web/downloadmanager.h" -#include #include #if defined(qApp) @@ -44,6 +43,7 @@ class FormMain; class IconFactory; class QAction; +class Mutex; class Application : public QtSingleApplication { Q_OBJECT @@ -99,13 +99,7 @@ class Application : public QtSingleApplication { } // Access to application-wide close lock. - inline QMutex *feedUpdateLock() { - if (m_updateFeedsLock == NULL) { - m_updateFeedsLock = new QMutex(); - } - - return m_updateFeedsLock; - } + Mutex *feedUpdateLock(); inline FormMain *mainForm() { return m_mainForm; @@ -178,7 +172,7 @@ class Application : public QtSingleApplication { // But of user decides to close the application (in other words, // tries to lock the lock for writing), then no other // action will be allowed to lock for reading. - QMutex *m_updateFeedsLock; + Mutex *m_updateFeedsLock; QList m_userActions; FormMain *m_mainForm; SystemTrayIcon *m_trayIcon; diff --git a/src/miscellaneous/iofactory.cpp b/src/miscellaneous/iofactory.cpp index 8beaeb902..44ad97dad 100755 --- a/src/miscellaneous/iofactory.cpp +++ b/src/miscellaneous/iofactory.cpp @@ -59,76 +59,3 @@ bool IOFactory::copyFile(const QString &source, const QString &destination) { return QFile::copy(source, destination); } - -bool IOFactory::removeFolder(const QString& directory_name, - const QStringList& exception_file_list, - const QStringList& exception_folder_list) { - bool result = true; - QDir dir(directory_name); - - if (dir.exists(directory_name)) { - foreach (QFileInfo info, - dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | - QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) { - if (info.isDir()) { - if (!exception_folder_list.contains(info.fileName())) { - result &= removeFolder(info.absoluteFilePath(), exception_file_list, exception_folder_list); - } - } - else if (!exception_file_list.contains(info.fileName())) { - if (!QFile::remove(info.absoluteFilePath())) { - result &= false; - qDebug("Failed to remove file \'%s\'.", qPrintable(QDir::toNativeSeparators(info.absoluteFilePath()))); - } - else { - result &= true; - } - } - } - - if (dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files).isEmpty()) { - result &= dir.rmdir(directory_name); - } - } - - return result; -} - -bool IOFactory::copyFolder(const QString &source, const QString &destination) { - QDir dir_source(source); - - if (!dir_source.exists()) { - return false; - } - - QDir dir_destination(destination); - - if (!dir_destination.exists()) { - dir_destination.mkpath(destination); - } - - foreach (QString d, dir_source.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { - QString dst_path = destination + QDir::separator() + d; - dir_source.mkpath(dst_path); - copyFolder(source + QDir::separator() + d, dst_path); - } - - foreach (QString f, dir_source.entryList(QDir::Files)) { - QString original_file = source + QDir::separator() + f; - QString destination_file = destination + QDir::separator() + f; - - if (!QFile::exists(destination_file) || QFile::remove(destination_file)) { - if (QFile::copy(original_file, destination_file)) { - qDebug("Copied file \'%s\'.", qPrintable(f)); - } - else { - qDebug("Failed to copy file \'%s\'.", qPrintable(QDir::toNativeSeparators(original_file))); - } - } - else { - qDebug("Failed to remove file \'%s\'.", qPrintable(QDir::toNativeSeparators(original_file))); - } - } - - return true; -} diff --git a/src/miscellaneous/iofactory.h b/src/miscellaneous/iofactory.h index 6cf54868b..d692ddb99 100755 --- a/src/miscellaneous/iofactory.h +++ b/src/miscellaneous/iofactory.h @@ -18,7 +18,6 @@ #ifndef IOFACTORY_H #define IOFACTORY_H -#include #include #if QT_VERSION >= 0x050000 @@ -40,19 +39,12 @@ class IOFactory { // Returns system-wide folder according to type. static QString getSystemFolder(SYSTEM_FOLDER_ENUM::StandardLocation location); + // Returns contents of a file. + // Throws exception when no such file exists. static QByteArray readTextFile(const QString &file_path); // Copies file, overwrites destination. static bool copyFile(const QString &source, const QString &destination); - - // Copy whole directory recursively. - // Destination path is created if it does not exist. - static bool copyFolder(const QString &source, const QString &destination); - - // Removes directory recursively and skips given folders/files. - static bool removeFolder(const QString &directory_name, - const QStringList &exception_file_list = QStringList(), - const QStringList &exception_folder_list = QStringList()); }; #endif // IOFACTORY_H diff --git a/src/miscellaneous/mutex.cpp b/src/miscellaneous/mutex.cpp new file mode 100644 index 000000000..dfe00410d --- /dev/null +++ b/src/miscellaneous/mutex.cpp @@ -0,0 +1,71 @@ +// This file is part of RSS Guard. +// +// Copyright (C) 2011-2015 by Martin Rotter +// +// RSS Guard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// RSS Guard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with RSS Guard. If not, see . + +#include "miscellaneous/mutex.h" + + +Mutex::Mutex(QMutex::RecursionMode mode, QObject *parent) : QObject(parent), m_mutex(new QMutex(mode)), m_isLocked(false) { +} + +Mutex::~Mutex() { + qDebug("Destroying Mutex instance."); + delete m_mutex; +} + +void Mutex::lock() { + m_mutex->lock(); + setLocked(); +} + +bool Mutex::tryLock() { + bool result; + + if (result = m_mutex->tryLock()) { + setLocked(); + } + + return result; +} + +bool Mutex::tryLock(int timeout) { + bool result; + + if (result = m_mutex->tryLock(timeout)) { + setLocked(); + } + + return result; +} + +void Mutex::unlock() { + m_mutex->unlock(); + setUnlocked(); +} + +void Mutex::setLocked() { + m_isLocked = true; + emit locked(); +} + +void Mutex::setUnlocked() { + m_isLocked = false; + emit unlocked(); +} + +bool Mutex::isLocked() const { + return m_isLocked; +} diff --git a/src/miscellaneous/mutex.h b/src/miscellaneous/mutex.h new file mode 100644 index 000000000..3c3c3eff2 --- /dev/null +++ b/src/miscellaneous/mutex.h @@ -0,0 +1,56 @@ +// This file is part of RSS Guard. +// +// Copyright (C) 2011-2015 by Martin Rotter +// +// RSS Guard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// RSS Guard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with RSS Guard. If not, see . + +#ifndef MUTEX_H +#define MUTEX_H + +#include +#include + + +class Mutex : public QObject { + Q_OBJECT + + public: + // Constructors. + explicit Mutex(QMutex::RecursionMode mode = QMutex::NonRecursive, QObject *parent = 0); + virtual ~Mutex(); + + // Main methods. + void lock(); + bool tryLock(); + bool tryLock(int timeout); + void unlock(); + + // Identifies if mutes is locked or not. + bool isLocked() const; + + protected: + // These methods set proper value for m_isLocked and emit signals. + void setLocked(); + void setUnlocked(); + + signals: + void locked(); + void unlocked(); + + private: + QMutex *m_mutex; + bool m_isLocked; +}; + +#endif // MUTEX_H diff --git a/src/miscellaneous/settings.h b/src/miscellaneous/settings.h index 42a938244..9b8990e2f 100755 --- a/src/miscellaneous/settings.h +++ b/src/miscellaneous/settings.h @@ -294,7 +294,7 @@ class Settings : public QSettings { return m_initializationStatus; } - // Getter/setter for settings values. + // Getters/setters for settings values. inline QVariant value(const QString §ion, const QString &key, const QVariant &default_value = QVariant()) { return QSettings::value(QString("%1/%2").arg(section, key), default_value); } diff --git a/src/miscellaneous/systemfactory.h b/src/miscellaneous/systemfactory.h index d729175c5..aa5fcacaa 100755 --- a/src/miscellaneous/systemfactory.h +++ b/src/miscellaneous/systemfactory.h @@ -83,6 +83,7 @@ class SystemFactory : public QObject { // Tries to download list with new updates. QPair checkForUpdates(); + // Checks if update is newer than current application version. static bool isUpdateNewer(const QString &update_version); public slots: diff --git a/src/network-web/webbrowser.h b/src/network-web/webbrowser.h index 699c00148..3c3f7266a 100755 --- a/src/network-web/webbrowser.h +++ b/src/network-web/webbrowser.h @@ -132,6 +132,8 @@ class WebBrowser : public TabContent { void onTitleChanged(const QString &new_title); void onIconChanged(); + // User selected any feed from website to add to reader. + // This copies feed link to clipboard and triggers "add feed" dialog. void addFeedFromWebsite(const QString &feed_link); signals: diff --git a/src/network-web/webpage.cpp b/src/network-web/webpage.cpp index e8c4610e2..6097aafe6 100644 --- a/src/network-web/webpage.cpp +++ b/src/network-web/webpage.cpp @@ -74,6 +74,7 @@ bool WebPage::acceptNavigationRequest(QWebFrame *frame, QString scheme = request.url().scheme(); if (scheme == "mailto" || scheme == "ftp") { + qWarning("Received request with scheme '%s', blocking it.", qPrintable(scheme)); return false; } @@ -85,6 +86,5 @@ bool WebPage::acceptNavigationRequest(QWebFrame *frame, } qDebug("Accepting request '%s'.", qPrintable(request.url().toString())); - return QWebPage::acceptNavigationRequest(frame, request, type); } diff --git a/src/network-web/webview.h b/src/network-web/webview.h index 2a0c9f12a..3766531d3 100644 --- a/src/network-web/webview.h +++ b/src/network-web/webview.h @@ -66,12 +66,11 @@ class WebView : public QWebView { void openImageInNewTab(); void searchTextViaGoogle(); void saveCurrentPageToFile(); + void printCurrentPage(); // Provides custom context menu. void popupContextMenu(const QPoint &pos); - void printCurrentPage(); - private slots: void downloadLink(const QNetworkRequest &request);