Skip to content

Commit b8e1af4

Browse files
committed
Update improvements. Fix #113, Fix #114.
1 parent 5b29bcc commit b8e1af4

File tree

2 files changed

+83
-43
lines changed

2 files changed

+83
-43
lines changed

src/Application.cpp

Lines changed: 82 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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

114122
Application::~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

302336
void 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!

src/Application.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class Application : public QApplication
3434
QString getDocumentationPath() const;
3535
QString getUpdatePath() const;
3636

37-
void checkForUpdates(bool manual);
37+
void checkForUpdates(bool manual, const std::function<void()>& cb = nullptr);
3838

3939
private:
4040

0 commit comments

Comments
 (0)