@@ -55,60 +55,68 @@ Application::Application(int& argc, char** argv)
5555 processEvents ();
5656 }
5757
58+ _cmdLine = new QCommandLineParser ();
59+ _cmdLine->setSingleDashWordOptionMode (QCommandLineParser::ParseAsLongOptions);
60+ _cmdLine->addOptions (
61+ {
62+ { " updateResult" , tr (" Update result code, 0 if succeeded." ), tr (" updateResult" ) },
63+ { " updateMessage" , tr (" Update results messaged by an updater." ), tr (" updateMessage" ) },
64+ });
65+ _cmdLine->process (*this );
66+
5867 _network = new QNetworkAccessManager (this );
5968
6069 _mainWindow = new MainWindow ();
6170
6271 ImagesetEditor::createToolbar (*this );
6372 LayoutEditor::createToolbar (*this );
6473
65- _mainWindow->show ();
66- _mainWindow->raise ();
67-
6874 if (splash)
6975 {
7076 splash->finish (_mainWindow);
7177 delete splash;
7278 }
7379
74- _cmdLine = new QCommandLineParser ();
75- _cmdLine->setSingleDashWordOptionMode (QCommandLineParser::ParseAsLongOptions);
76- _cmdLine->addOptions (
77- {
78- { " updateResult" , tr (" Update result code, 0 if succeeded." ), tr (" updateResult" ) },
79- { " updateMessage" , tr (" Update results messaged by an updater." ), tr (" updateMessage" ) },
80- });
81- _cmdLine->process (*this );
80+ // Bring our application to front before we show any message box
81+ // TODO: leave only necessary calls
82+ _mainWindow->show ();
83+ _mainWindow->raise ();
84+ _mainWindow->activateWindow ();
85+ _mainWindow->setWindowState (_mainWindow->windowState () | Qt::WindowState::WindowActive);
8286
83- if (_cmdLine->positionalArguments ().size () > 0 )
84- {
85- // Load project specified in a command line
86- _mainWindow->loadProject (_cmdLine->positionalArguments ().first ());
87- }
88- else
87+ checkUpdateResults ();
88+
89+ // Checking for updates is async, initialization will continue after it finishes
90+ checkForUpdates (false , [this ]()
8991 {
90- // Perform a startup action
91- const auto action = _settings->getEntryValue (" global/app/startup_action" ).toInt ();
92- switch (action)
92+ _mainWindow->setStatusMessage (" " );
93+
94+ // Now we can load requested project, if any
95+ if (_cmdLine->positionalArguments ().size () > 0 )
96+ {
97+ // Load project specified in a command line
98+ _mainWindow->loadProject (_cmdLine->positionalArguments ().first ());
99+ }
100+ else
93101 {
94- case 1 :
102+ // Perform a startup action
103+ const auto action = _settings->getEntryValue (" global/app/startup_action" ).toInt ();
104+ switch (action)
95105 {
96- if (_settings-> getQSettings ()-> contains ( " lastProject " ))
106+ case 1 :
97107 {
98- const QString lastProject = _settings->getQSettings ()->value (" lastProject" ).toString ();
99- if (QFileInfo::exists (lastProject))
100- _mainWindow->loadProject (lastProject);
108+ if (_settings->getQSettings ()->contains (" lastProject" ))
109+ {
110+ const QString lastProject = _settings->getQSettings ()->value (" lastProject" ).toString ();
111+ if (QFileInfo::exists (lastProject))
112+ _mainWindow->loadProject (lastProject);
113+ }
114+ break ;
101115 }
102- break ;
116+ default : break ; // 0: empty environment
103117 }
104- default : break ; // 0: empty environment
105118 }
106- }
107-
108- checkUpdateResults ();
109-
110- // TODO: if not disabled in settings / if time has come
111- checkForUpdates (false );
119+ });
112120}
113121
114122Application::~Application ()
@@ -205,28 +213,56 @@ QString Application::getUpdatePath() const
205213 return QDir::temp ().absoluteFilePath (" CEEDUpdate" );
206214}
207215
208- void Application::checkForUpdates (bool manual)
216+ void Application::checkForUpdates (bool manual, const std::function< void ()>& cb )
209217{
210218 if (!Utils::isInternetConnected ())
211219 {
212220 qCritical () << " No Internet connection, update check skipped" ;
221+ if (cb) cb ();
213222 return ;
214223 }
215224
216- const QUrl infoUrl = _settings->getQSettings ()->value (" updateInfoUrl" , " https://api.github.com/repos/cegui/ceed-cpp/releases/latest" ).toUrl ();
225+ const auto currTime = QDateTime::currentSecsSinceEpoch ();
226+
227+ // Automatic update checks should honor their settings
228+ if (!manual)
229+ {
230+ const auto updateCheckFrequencySec = _settings->getEntryValue (" global/app/update_check_frequency" ).toInt ();
231+ if (updateCheckFrequencySec < 0 )
232+ {
233+ if (cb) cb ();
234+ return ;
235+ }
236+
237+ const auto lastUpdateCheckTime = _settings->getQSettings ()->value (" update/lastTimestamp" , 0 ).toLongLong ();
238+ if (currTime - lastUpdateCheckTime < updateCheckFrequencySec)
239+ {
240+ if (cb) cb ();
241+ return ;
242+ }
243+ }
244+
245+ _settings->getQSettings ()->setValue (" update/lastTimestamp" , currTime);
246+
247+ const QUrl infoUrl = _settings->getQSettings ()->value (" update/url" , " https://api.github.com/repos/cegui/ceed-cpp/releases/latest" ).toUrl ();
217248
218249 _mainWindow->setStatusMessage (" Checking for updates..." );
219250
220251 QNetworkReply* infoReply = _network->get (QNetworkRequest (infoUrl));
221- QObject::connect (infoReply, &QNetworkReply::errorOccurred, [this , infoReply](QNetworkReply::NetworkError)
252+ QObject::connect (infoReply, &QNetworkReply::errorOccurred, [this , cb, infoReply](QNetworkReply::NetworkError)
222253 {
223254 onUpdateError (infoReply->url (), infoReply->errorString ());
255+ if (cb) cb ();
224256 });
225257
226- QObject::connect (infoReply, &QNetworkReply::finished, [this , infoReply, manual]()
258+ QObject::connect (infoReply, &QNetworkReply::finished, [this , cb, infoReply, manual]()
227259 {
228260 // Already processed by QNetworkReply::errorOccurred handler
229- if (infoReply->error () != QNetworkReply::NoError) return ;
261+ if (infoReply->error () != QNetworkReply::NoError)
262+ {
263+ if (cb) cb ();
264+ return ;
265+ }
230266
231267 try
232268 {
@@ -251,6 +287,7 @@ void Application::checkForUpdates(bool manual)
251287 _mainWindow->setStatusMessage (msg);
252288 if (manual)
253289 QMessageBox::warning (_mainWindow, tr (" Auto-update blocked" ), msg);
290+ if (cb) cb ();
254291 return ;
255292 }
256293 else
@@ -276,10 +313,9 @@ void Application::checkForUpdates(bool manual)
276313 catch (const std::exception& e)
277314 {
278315 onUpdateError (infoReply->url (), e.what ());
279- return ;
280316 }
281317
282- _mainWindow-> setStatusMessage ( " " );
318+ if (cb) cb ( );
283319 });
284320}
285321
@@ -295,8 +331,6 @@ void Application::onUpdateError(const QUrl& url, const QString& errorString)
295331
296332 if (response == QMessageBox::Yes)
297333 QDesktopServices::openUrl (QUrl (" https://github.com/cegui/ceed-cpp/releases" ));
298-
299- _mainWindow->setStatusMessage (" " );
300334}
301335
302336void Application::checkUpdateResults ()
@@ -394,6 +428,12 @@ void Application::createSettingsEntries()
394428 " combobox" , false , 1 , { {0 , " Empty environment" }, {1 , " Most recent project" } }));
395429 secApp->addEntry (std::move (entry));
396430
431+ entry.reset (new SettingsEntry (*secApp, " update_check_frequency" , 0 , " Check for updates" ,
432+ " How frequently an update should be checked" ,
433+ " combobox" , false , 1 , { {7 * 86400 , " Once a week" }, {86400 , " Once a day" }, {0 , " Every launch" }, {-1 , " Never" } }));
434+ secApp->addEntry (std::move (entry));
435+
436+
397437 // By default we limit the undo stack to 500 undo commands, should be enough and should
398438 // avoid memory drainage. Keep in mind that every tabbed editor has it's own undo stack,
399439 // so the overall command limit is number_of_tabs * 500!
0 commit comments