Mercurial > trustbridge
comparison ui/mainwindow.cpp @ 551:15121735805e
Start implementation of software update installation
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Tue, 20 May 2014 16:40:28 +0000 |
parents | c84dc8f6d017 |
children | d512d8eef8f6 |
comparison
equal
deleted
inserted
replaced
550:0ec3516bf65c | 551:15121735805e |
---|---|
6 * See LICENSE.txt for details. | 6 * See LICENSE.txt for details. |
7 */ | 7 */ |
8 #include "mainwindow.h" | 8 #include "mainwindow.h" |
9 | 9 |
10 #include <QDebug> | 10 #include <QDebug> |
11 #include <QProcess> | |
11 #include <QProgressDialog> | 12 #include <QProgressDialog> |
12 #include <QMessageBox> | 13 #include <QMessageBox> |
13 #include <QSystemTrayIcon> | 14 #include <QSystemTrayIcon> |
14 #include <QAction> | 15 #include <QAction> |
15 #include <QDialog> | 16 #include <QDialog> |
33 #define APPNAME "TrustBridge" | 34 #define APPNAME "TrustBridge" |
34 #endif | 35 #endif |
35 | 36 |
36 #define SERVER_URL "https://files.intevation.de:443" | 37 #define SERVER_URL "https://files.intevation.de:443" |
37 #define LIST_RESOURCE "/users/aheinecke/zertifikatsliste.txt" | 38 #define LIST_RESOURCE "/users/aheinecke/zertifikatsliste.txt" |
38 #define SW_RESOURCE "/users/aheinecke/zertifikatsliste.txt" | 39 #define SW_RESOURCE "/users/aheinecke/trustbridge.exe" |
39 #ifdef Q_OS_WIN | 40 #ifdef Q_OS_WIN |
40 #define SW_RESOURCE_VERSION "/users/aheinecke/trustbridge-%1.exe" | 41 #define SW_RESOURCE_VERSION "/users/aheinecke/trustbridge-%1.exe" |
41 #else | 42 #else |
42 #define SW_RESOURCE_VERSION "/users/aheinecke/trustbridge-%1.sh" | 43 #define SW_RESOURCE_VERSION "/users/aheinecke/trustbridge-%1.sh" |
43 #endif | 44 #endif |
48 #include "aboutdialog.h" | 49 #include "aboutdialog.h" |
49 #include "certificateitemdelegate.h" | 50 #include "certificateitemdelegate.h" |
50 #include "separatoritemdelegate.h" | 51 #include "separatoritemdelegate.h" |
51 #include "installwrapper.h" | 52 #include "installwrapper.h" |
52 #include "util.h" | 53 #include "util.h" |
54 #include "logging.h" | |
53 | 55 |
54 MainWindow::MainWindow(bool trayMode): | 56 MainWindow::MainWindow(bool trayMode): |
55 mTrayMode(trayMode) | 57 mTrayMode(trayMode) |
56 { | 58 { |
57 createActions(); | 59 createActions(); |
95 void MainWindow::messageClicked() | 97 void MainWindow::messageClicked() |
96 { | 98 { |
97 if (mCurState == NewListAvailable) { | 99 if (mCurState == NewListAvailable) { |
98 show(); | 100 show(); |
99 } | 101 } |
102 | |
103 if (mCurState == NewSoftwareAvailable) { | |
104 checkUpdates(true); | |
105 mCurState = DownloadingSW; | |
106 } | |
100 } | 107 } |
101 | 108 |
102 void MainWindow::showMessage() | 109 void MainWindow::showMessage() |
103 { | 110 { |
104 if (!isVisible() && !mCurMessage.isEmpty()) { | 111 if (!isVisible() && !mCurMessage.isEmpty()) { |
146 mSettings.remove("List/installed"); | 153 mSettings.remove("List/installed"); |
147 mSettings.remove("List/installedDate"); | 154 mSettings.remove("List/installedDate"); |
148 } | 155 } |
149 | 156 |
150 if (!swFileName.isEmpty()) { | 157 if (!swFileName.isEmpty()) { |
151 // TODO | 158 // TODO Verify integrity of the software |
152 } else { | 159 } else { |
153 mSettings.remove("Software/available"); | 160 mSettings.remove("Software/available"); |
154 mSettings.remove("Software/availableDate"); | 161 mSettings.remove("Software/availableDate"); |
155 } | 162 } |
156 } | 163 } |
174 loadCertificateList(); | 181 loadCertificateList(); |
175 } | 182 } |
176 } | 183 } |
177 | 184 |
178 void MainWindow::handleNewSW(const QString& fileName, const QDateTime& modDate) { | 185 void MainWindow::handleNewSW(const QString& fileName, const QDateTime& modDate) { |
179 mCurMessage = tr("An update for %1 is available. Click here to install.").arg( | 186 mCurMessage = tr("<h3>An update for %1 is available.</h3>\n" |
187 "Click here to download and install the update.").arg( | |
180 QApplication::applicationName()); | 188 QApplication::applicationName()); |
181 setState(NewSoftwareAvailable); | 189 setState(NewSoftwareAvailable); |
182 mSettings.setValue("Software/available", fileName); | 190 mSettings.setValue("Software/available", fileName); |
183 mSettings.setValue("Software/availableDate", modDate); | 191 mSettings.setValue("Software/availableDate", modDate); |
184 | 192 |
185 mSettings.sync(); | 193 mSettings.sync(); |
186 showMessage(); | 194 showMessage(); |
187 } | 195 } |
188 | 196 |
197 void MainWindow::installNewSW(const QString& fileName, const QDateTime& modDate) { | |
198 QFileInfo instProcInfo = QFileInfo(fileName); | |
199 if (!instProcInfo.isExecutable()) { | |
200 qWarning() << "Downloaded file: " << fileName << " is not executable."; | |
201 setState(TransferError); | |
202 return; | |
203 } | |
204 #ifdef WIN32 | |
205 SHELLEXECUTEINFOW shExecInfo; | |
206 shExecInfo.lpFile = reinterpret_cast<LPCWSTR> (fileName.utf16()); | |
207 | |
208 if (!is_admin()) { | |
209 shExecInfo.lpVerb = L"open"; | |
210 } else { | |
211 shExecInfo.lpVerb = L"runas"; | |
212 } | |
213 | |
214 qDebug() << "Starting process " << fileName; | |
215 | |
216 if (!ShellExecuteExW(&shExecInfo)) { | |
217 /* Execution failed, maybe the user aborted the UAC check? */ | |
218 char* errmsg = getLastErrorMsg(); | |
219 QString qerrmsg = QString::fromUtf8(errmsg); | |
220 free(errmsg); | |
221 qDebug() << "Failed to start process: " << qerrmsg; | |
222 setState(NewSoftwareAvailable); | |
223 return; | |
224 } | |
225 | |
226 #else /* WIN32 */ | |
227 QProcess installerProcess; | |
228 installerProcess.setProgram(fileName); | |
229 | |
230 qDebug() << "Starting process " << fileName; | |
231 | |
232 if (!installerProcess.waitForStarted() || | |
233 installerProcess.state() == QProcess::NotRunning) { | |
234 qDebug() << "Failed to start process."; | |
235 return; | |
236 } | |
237 #endif | |
238 /* Installer process should now be running. We exit */ | |
239 | |
240 closeApp(); | |
241 } | |
242 | |
189 void MainWindow::checkUpdates(bool downloadSW) | 243 void MainWindow::checkUpdates(bool downloadSW) |
190 { | 244 { |
191 verifyAvailableData(); | 245 verifyAvailableData(); |
192 | 246 |
193 if (!mSettings.contains("Software/installedDate")) { | 247 if (!mSettings.contains("Software/installedDate") || |
194 lookUpDateForVersion(); | 248 mSettings.value("Software/installedVersion").toString() != QApplication::applicationVersion()) { |
249 /* This should only happen on initial startup and after an update has | |
250 * been installed */ | |
251 getLastModForCurrentVersion(); | |
195 return; | 252 return; |
196 } | 253 } |
197 QDateTime listInstalledLastMod = mSettings.value("List/installedDate").toDateTime(); | 254 QDateTime listInstalledLastMod = mSettings.value("List/installedDate").toDateTime(); |
198 QDateTime swInstalledLastMod = mSettings.value("Software/installedDate").toDateTime(); | 255 QDateTime swInstalledLastMod = mSettings.value("Software/installedDate").toDateTime(); |
199 | 256 |
208 | 265 |
209 | 266 |
210 Downloader* downloader = new Downloader(this, | 267 Downloader* downloader = new Downloader(this, |
211 QString::fromLatin1(SERVER_URL), | 268 QString::fromLatin1(SERVER_URL), |
212 QByteArray(), | 269 QByteArray(), |
213 QDateTime::currentDateTime(), | 270 swInstalledLastMod, |
214 // TODO swInstalledLastMod, | |
215 listInstalledLastMod, | 271 listInstalledLastMod, |
216 swResource, | 272 swResource, |
217 listResource, | 273 listResource, |
218 downloadSW); | 274 downloadSW); |
219 | 275 |
220 connect(downloader, SIGNAL(newListAvailable(const QString&, const QDateTime&)), | 276 connect(downloader, SIGNAL(newListAvailable(const QString&, const QDateTime&)), |
221 this, SLOT(handleNewList(const QString&, const QDateTime&))); | 277 this, SLOT(handleNewList(const QString&, const QDateTime&))); |
222 if (!downloadSW) { | 278 if (!downloadSW) { |
223 connect(downloader, SIGNAL(newSoftwareAvailable(const QString&, const QDateTime&)), | 279 connect(downloader, SIGNAL(newSoftwareAvailable(const QString&, const QDateTime&)), |
224 this, SLOT(newSWAvailable(const QString&, const QDateTime&))); | 280 this, SLOT(handleNewSW(const QString&, const QDateTime&))); |
225 } | 281 } else { |
226 else { | |
227 connect(downloader, SIGNAL(newSoftwareAvailable(const QString&, const QDateTime&)), | 282 connect(downloader, SIGNAL(newSoftwareAvailable(const QString&, const QDateTime&)), |
228 this, SLOT(handleNewSW(const QString&, const QDateTime&))); | 283 this, SLOT(installNewSW(const QString&, const QDateTime&))); |
229 } | 284 } |
285 | |
230 connect(downloader, SIGNAL(finished()), downloader, SLOT(deleteLater())); | 286 connect(downloader, SIGNAL(finished()), downloader, SLOT(deleteLater())); |
231 connect(downloader, SIGNAL(error(const QString &, SSLConnection::ErrorCode)), | 287 connect(downloader, SIGNAL(error(const QString &, SSLConnection::ErrorCode)), |
232 this, SLOT(downloaderError(const QString &, SSLConnection::ErrorCode))); | 288 this, SLOT(downloaderError(const QString &, SSLConnection::ErrorCode))); |
233 downloader->start(); | 289 downloader->start(); |
234 } | 290 } |
235 | 291 |
236 void MainWindow::lookUpDateForVersion() | 292 void MainWindow::getLastModForCurrentVersion() |
237 { | 293 { |
238 QString softwareVersion = QString::fromLatin1(SW_RESOURCE_VERSION).arg( | 294 QString softwareVersion = QString::fromLatin1(SW_RESOURCE_VERSION).arg( |
239 QApplication::applicationVersion()); | 295 QApplication::applicationVersion()); |
240 qDebug() << softwareVersion; | 296 qDebug() << softwareVersion; |
241 QString listResource = QString::fromLatin1(LIST_RESOURCE); | 297 QString listResource = QString::fromLatin1(LIST_RESOURCE); |
249 false); | 305 false); |
250 connect(downloader, SIGNAL(finished()), downloader, SLOT(deleteLater())); | 306 connect(downloader, SIGNAL(finished()), downloader, SLOT(deleteLater())); |
251 connect(downloader, SIGNAL(error(const QString &, SSLConnection::ErrorCode)), | 307 connect(downloader, SIGNAL(error(const QString &, SSLConnection::ErrorCode)), |
252 this, SLOT(downloaderError(const QString &, SSLConnection::ErrorCode))); | 308 this, SLOT(downloaderError(const QString &, SSLConnection::ErrorCode))); |
253 connect(downloader, SIGNAL(lastModifiedDate(const QDateTime&)), | 309 connect(downloader, SIGNAL(lastModifiedDate(const QDateTime&)), |
254 this, SLOT(setLastModifiedDate(const QDateTime&))); | 310 this, SLOT(setLastModifiedSWDate(const QDateTime&))); |
255 | 311 |
256 downloader->start(); | 312 downloader->start(); |
257 } | 313 } |
258 | 314 |
259 void MainWindow::setLastModifiedDate(const QDateTime &date) | 315 void MainWindow::setLastModifiedSWDate(const QDateTime &date) |
260 { | 316 { |
261 mSettings.beginGroup("Software"); | 317 mSettings.beginGroup("Software"); |
262 mSettings.setValue("installedDate", date); | 318 mSettings.setValue("installedDate", date); |
319 mSettings.setValue("installedVersion", QApplication::applicationVersion()); | |
263 mSettings.endGroup(); | 320 mSettings.endGroup(); |
264 checkUpdates(); | 321 checkUpdates(); |
265 } | 322 } |
266 | 323 |
267 void MainWindow::newSWAvailable(const QString &fileName, const QDateTime &date) { | |
268 QMessageBox msgBox; | |
269 msgBox.setIcon(QMessageBox::Information); | |
270 msgBox.setText("<h3>" + tr("New Software version is available.") + "</h3>"); | |
271 msgBox.setInformativeText(tr("Do you want to install the new Version?")); | |
272 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); | |
273 msgBox.setDefaultButton(QMessageBox::Yes); | |
274 int selection = msgBox.exec(); | |
275 if (selection == QMessageBox::Yes) { | |
276 checkUpdates(true); | |
277 } | |
278 } | |
279 | |
280 void MainWindow::downloaderError(const QString &message, SSLConnection::ErrorCode error) | 324 void MainWindow::downloaderError(const QString &message, SSLConnection::ErrorCode error) |
281 { | 325 { |
326 /* TODO logging and handle error according to a plan */ | |
282 mCurMessage = message; | 327 mCurMessage = message; |
283 showMessage(); | 328 showMessage(); |
284 } | 329 setState(TransferError); |
285 | 330 } |
286 | 331 |
287 void MainWindow::createActions() | 332 void MainWindow::createActions() |
288 { | 333 { |
289 mCheckUpdates = new QAction(tr("Check for Updates"), this); | 334 mCheckUpdates = new QAction(tr("Check for Updates"), this); |
290 connect(mCheckUpdates, SIGNAL(triggered()), this, SLOT(checkUpdates())); | 335 connect(mCheckUpdates, SIGNAL(triggered()), this, SLOT(checkUpdates())); |