1 // For license of this file, see <project-root-folder>/LICENSE.md.
2 
3 #ifndef APPLICATION_H
4 #define APPLICATION_H
5 
6 #include "core/feeddownloader.h"
7 #include "database/databasefactory.h"
8 #include "definitions/definitions.h"
9 #include "gui/systemtrayicon.h"
10 #include "miscellaneous/feedreader.h"
11 #include "miscellaneous/iofactory.h"
12 #include "miscellaneous/localization.h"
13 #include "miscellaneous/notification.h"
14 #include "miscellaneous/settings.h"
15 #include "miscellaneous/singleapplication.h"
16 #include "miscellaneous/skinfactory.h"
17 #include "miscellaneous/systemfactory.h"
18 #include "network-web/downloadmanager.h"
19 
20 #include <QCommandLineParser>
21 #include <QList>
22 
23 #include <functional>
24 
25 #if defined(qApp)
26 #undef qApp
27 #endif
28 
29 // Define new qApp macro. Yeaaaaah.
30 #define qApp (Application::instance())
31 
32 class FormMain;
33 class IconFactory;
34 class QAction;
35 class Mutex;
36 class QWebEngineDownloadItem;
37 class WebFactory;
38 class NotificationFactory;
39 
40 class RSSGUARD_DLLSPEC Application : public SingleApplication {
41   Q_OBJECT
42 
43   public:
44     explicit Application(const QString& id, int& argc, char** argv);
45     virtual ~Application();
46 
47     void reactOnForeignNotifications();
48     void hideOrShowMainForm();
49     void loadDynamicShortcuts();
50     void showPolls() const;
51     void offerChanges() const;
52 
53     bool isAlreadyRunning();
54 
55     QStringList builtinSounds() const;
56 
57     FeedReader* feedReader();
58     void setFeedReader(FeedReader* feed_reader);
59 
60     // Globally accessible actions.
61     QList<QAction*> userActions();
62 
63     // Check whether this application starts for the first time (ever).
64     bool isFirstRun() const;
65 
66     // Check whether CURRENT VERSION of the application starts for the first time.
67     bool isFirstRunCurrentVersion() const;
68 
69     QCommandLineParser* cmdParser();
70     WebFactory* web() const;
71     SystemFactory* system();
72     SkinFactory* skins();
73     Localization* localization();
74     DatabaseFactory* database();
75     IconFactory* icons();
76     DownloadManager* downloadManager();
77     Settings* settings() const;
78     Mutex* feedUpdateLock();
79     FormMain* mainForm();
80     QWidget* mainFormWidget();
81     SystemTrayIcon* trayIcon();
82     NotificationFactory* notifications() const;
83 
84     QIcon desktopAwareIcon() const;
85 
86     QString tempFolder() const;
87     QString documentsFolder() const;
88     QString homeFolder() const;
89     QString configFolder() const;
90 
91     // These return user ready folders.
92     QString userDataAppFolder() const;
93     QString userDataHomeFolder() const;
94     QString customDataFolder() const;
95 
96     // Returns the base folder to which store user data, the "data" folder.
97     // NOTE: Use this to get correct path under which store user data.
98     QString userDataFolder();
99 
100     QString replaceDataUserDataFolderPlaceholder(QString text) const;
101     QStringList replaceDataUserDataFolderPlaceholder(QStringList texts) const;
102 
103     void setMainForm(FormMain* main_form);
104 
105     void backupDatabaseSettings(bool backup_database, bool backup_settings,
106                                 const QString& target_path, const QString& backup_name);
107     void restoreDatabaseSettings(bool restore_database, bool restore_settings,
108                                  const QString& source_database_file_path = QString(),
109                                  const QString& source_settings_file_path = QString());
110 
111     void showTrayIcon();
112     void deleteTrayIcon();
113 
114     // Displays given simple message in tray icon bubble or OSD
115     // or in message box if tray icon is disabled.
116     void showGuiMessage(Notification::Event event, const QString& title, const QString& message,
117                         QSystemTrayIcon::MessageIcon message_type, bool show_at_least_msgbox = false,
118                         QWidget* parent = nullptr, const QString& functor_heading = {},
119                         std::function<void()> functor = nullptr);
120 
121     // Returns pointer to "GOD" application singleton.
122     static Application* instance();
123 
124     // Custom debug/console log handler.
125     static void performLogging(QtMsgType type, const QMessageLogContext& context, const QString& msg);
126 
127   public slots:
128 
129     // Restarts the application.
130     void restart();
131 
132     // Processes incoming message from another RSS Guard instance.
133     void parseCmdArgumentsFromOtherInstance(const QString& message);
134     void parseCmdArgumentsFromMyInstance();
135 
136   private slots:
137     void onCommitData(QSessionManager& manager);
138     void onSaveState(QSessionManager& manager);
139     void onAboutToQuit();
140     void showMessagesNumber(int unread_messages, bool any_feed_has_unread_messages);
141 
142 #if defined(USE_WEBENGINE)
143     void downloadRequested(QWebEngineDownloadItem* download_item);
144     void onAdBlockFailure();
145 #endif
146 
147     void onFeedUpdatesFinished(const FeedDownloadResults& results);
148 
149   private:
150     void setupCustomDataFolder(const QString& data_folder);
151     void determineFirstRuns();
152     void eliminateFirstRuns();
153 
154   private:
155     QCommandLineParser m_cmdParser;
156     FeedReader* m_feedReader;
157 
158     bool m_quitLogicDone;
159 
160     // This read-write lock is used by application on its close.
161     // Application locks this lock for WRITING.
162     // This means that if application locks that lock, then
163     // no other transaction-critical action can acquire lock
164     // for reading and won't be executed, so no critical action
165     // will be running when application quits
166     //
167     // EACH critical action locks this lock for READING.
168     // Several actions can lock this lock for reading.
169     // But of user decides to close the application (in other words,
170     // tries to lock the lock for writing), then no other
171     // action will be allowed to lock for reading.
172     QScopedPointer<Mutex> m_updateFeedsLock;
173 
174     QList<QAction*> m_userActions;
175     FormMain* m_mainForm;
176     SystemTrayIcon* m_trayIcon;
177     Settings* m_settings;
178     WebFactory* m_webFactory;
179     SystemFactory* m_system;
180     SkinFactory* m_skins;
181     Localization* m_localization;
182     IconFactory* m_icons;
183     DatabaseFactory* m_database;
184     DownloadManager* m_downloadManager;
185     NotificationFactory* m_notifications;
186     bool m_shouldRestart;
187     bool m_firstRunEver;
188     bool m_firstRunCurrentVersion;
189     QString m_customDataFolder;
190     bool m_allowMultipleInstances;
191 };
192 
instance()193 inline Application* Application::instance() {
194   return static_cast<Application*>(QCoreApplication::instance());
195 }
196 
197 #endif // APPLICATION_H
198