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