VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/VBoxUpdateDlg.cpp@ 35740

Last change on this file since 35740 was 30192, checked in by vboxsync, 14 years ago

FE/Qt4: created separate icon factory

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.5 KB
RevLine 
[10459]1/** @file
2 *
3 * VBox frontends: Qt4 GUI ("VirtualBox"):
4 * VBoxUpdateDlg class implementation
5 */
6
7/*
[28800]8 * Copyright (C) 2006-2010 Oracle Corporation
[10459]9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
[25526]19#ifdef VBOX_WITH_PRECOMPILED_HEADERS
[26079]20#include "precomp.h"
21#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
22/* Global includes */
23#include <QTimer>
24/* Local includes */
[14274]25#include "QIHttp.h"
[10459]26#include "VBoxGlobal.h"
27#include "VBoxProblemReporter.h"
[14274]28#include "VBoxUpdateDlg.h"
[30192]29#include "UIIconPool.h"
[25526]30#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
[10459]31
32/* VBoxVersion stuff */
33class VBoxVersion
34{
35public:
36
37 VBoxVersion (const QString &aVersion)
38 : x (0), y (0), z (0)
39 {
40 QStringList versionStack = aVersion.split ('.');
41 if (versionStack.size() > 0)
42 x = versionStack [0].toInt();
43 if (versionStack.size() > 1)
44 y = versionStack [1].toInt();
45 if (versionStack.size() > 2)
46 z = versionStack [2].toInt();
47 }
48
49 bool operator< (const VBoxVersion &aOther) const
50 {
[14274]51 return (x < aOther.x) ||
[11186]52 (x == aOther.x && y < aOther.y) ||
53 (x == aOther.x && y == aOther.y && z < aOther.z);
[10459]54 }
55
56 QString toString() const
57 {
58 return QString ("%1.%2.%3").arg (x).arg (y).arg (z);
59 }
60
61private:
62
63 int x;
64 int y;
65 int z;
66};
67
68/* VBoxUpdateData stuff */
[14274]69QList <UpdateDay> VBoxUpdateData::mDayList = QList <UpdateDay>();
[10459]70
71void VBoxUpdateData::populate()
72{
73 mDayList.clear();
74
75 /* To avoid re-translation complexity all
76 * have to be retranslated separately. */
77
78 /* Separately retranslate each day */
[10515]79 mDayList << UpdateDay (VBoxUpdateDlg::tr ("1 day"), "1 d");
80 mDayList << UpdateDay (VBoxUpdateDlg::tr ("2 days"), "2 d");
81 mDayList << UpdateDay (VBoxUpdateDlg::tr ("3 days"), "3 d");
82 mDayList << UpdateDay (VBoxUpdateDlg::tr ("4 days"), "4 d");
83 mDayList << UpdateDay (VBoxUpdateDlg::tr ("5 days"), "5 d");
84 mDayList << UpdateDay (VBoxUpdateDlg::tr ("6 days"), "6 d");
[10459]85
86 /* Separately retranslate each week */
[10515]87 mDayList << UpdateDay (VBoxUpdateDlg::tr ("1 week"), "1 w");
88 mDayList << UpdateDay (VBoxUpdateDlg::tr ("2 weeks"), "2 w");
89 mDayList << UpdateDay (VBoxUpdateDlg::tr ("3 weeks"), "3 w");
[10459]90
91 /* Separately retranslate each month */
[10515]92 mDayList << UpdateDay (VBoxUpdateDlg::tr ("1 month"), "1 m");
[10459]93}
94
95QStringList VBoxUpdateData::list()
96{
97 QStringList result;
98 for (int i = 0; i < mDayList.size(); ++ i)
99 result << mDayList [i].val;
100 return result;
101}
102
[10515]103VBoxUpdateData::VBoxUpdateData (const QString &aData)
104 : mData (aData)
[21770]105 , mPeriodIndex (Period1Day)
106 , mBranchIndex (BranchStable)
[10459]107{
[21770]108 decode();
[10515]109}
[10459]110
[21770]111VBoxUpdateData::VBoxUpdateData (PeriodType aPeriodIndex, BranchType aBranchIndex)
112 : mData (QString::null)
113 , mPeriodIndex (aPeriodIndex)
114 , mBranchIndex (aBranchIndex)
[10515]115{
[21770]116 encode();
[10459]117}
118
119bool VBoxUpdateData::isNecessary()
120{
[21770]121 return mPeriodIndex != PeriodNever && QDate::currentDate() >= mDate;
[10459]122}
123
[21770]124bool VBoxUpdateData::isNoNeedToCheck()
[10459]125{
[21770]126 return mPeriodIndex == PeriodNever;
[10459]127}
128
[10515]129QString VBoxUpdateData::data() const
[10459]130{
[10515]131 return mData;
132}
[10459]133
[21770]134VBoxUpdateData::PeriodType VBoxUpdateData::periodIndex() const
[10515]135{
[21770]136 return mPeriodIndex;
[10515]137}
138
139QString VBoxUpdateData::date() const
140{
[21770]141 return mPeriodIndex == PeriodNever ? VBoxUpdateDlg::tr ("Never") :
[10856]142 mDate.toString (Qt::LocaleDate);
[10515]143}
144
[21770]145VBoxUpdateData::BranchType VBoxUpdateData::branchIndex() const
[10515]146{
[21770]147 return mBranchIndex;
148}
149
150QString VBoxUpdateData::branchName() const
151{
152 switch (mBranchIndex)
153 {
154 case BranchStable:
155 return "stable";
156 case BranchAllRelease:
157 return "allrelease";
158 case BranchWithBetas:
159 return "withbetas";
160 }
161 return QString::null;
162}
163
164void VBoxUpdateData::decode()
165{
[10515]166 /* Parse standard values */
[21770]167 if (mData == "never")
168 mPeriodIndex = PeriodNever;
[10515]169 /* Parse other values */
[10459]170 else
171 {
[21770]172 QStringList parser (mData.split (", ", QString::SkipEmptyParts));
173
174 /* Parse 'period' value */
175 if (parser.size() > 0)
[10515]176 {
177 if (mDayList.isEmpty())
178 populate();
[21770]179 PeriodType index = (PeriodType) mDayList.indexOf (UpdateDay (QString::null, parser [0]));
180 mPeriodIndex = index == PeriodUndefined ? Period1Day : index;
[10515]181 }
182
[21770]183 /* Parse 'date' value */
184 if (parser.size() > 1)
[10515]185 {
[21770]186 QDate date = QDate::fromString (parser [1], Qt::ISODate);
187 mDate = date.isValid() ? date : QDate::currentDate();
[10515]188 }
[26079]189
[21770]190 /* Parse 'branch' value */
191 if (parser.size() > 2)
192 {
193 QString branch (parser [2]);
194 mBranchIndex = branch == "withbetas" ? BranchWithBetas :
195 branch == "allrelease" ? BranchAllRelease : BranchStable;
196 }
[10459]197 }
198}
199
[21770]200void VBoxUpdateData::encode()
[10459]201{
[10515]202 /* Encode standard values */
[21770]203 if (mPeriodIndex == PeriodNever)
[10515]204 mData = "never";
205 /* Encode other values */
[10459]206 else
207 {
[21770]208 /* Encode 'period' value */
[10515]209 if (mDayList.isEmpty())
210 populate();
[21770]211 QString remindPeriod = mDayList [mPeriodIndex].key;
[10515]212
213 /* Encode 'date' value */
214 mDate = QDate::currentDate();
215 QStringList parser (remindPeriod.split (' '));
[10459]216 if (parser [1] == "d")
[10515]217 mDate = mDate.addDays (parser [0].toInt());
[10459]218 else if (parser [1] == "w")
[10515]219 mDate = mDate.addDays (parser [0].toInt() * 7);
[10459]220 else if (parser [1] == "m")
[10515]221 mDate = mDate.addMonths (parser [0].toInt());
222 QString remindDate = mDate.toString (Qt::ISODate);
223
[21770]224 /* Encode 'branch' value */
225 QString branchValue = mBranchIndex == BranchWithBetas ? "withbetas" :
226 mBranchIndex == BranchAllRelease ? "allrelease" : "stable";
227
[10515]228 /* Composite mData */
[21770]229 mData = QString ("%1, %2, %3").arg (remindPeriod, remindDate, branchValue);
[10459]230 }
231}
232
233/* VBoxUpdateDlg stuff */
234bool VBoxUpdateDlg::isNecessary()
235{
236 VBoxUpdateData data (vboxGlobal().virtualBox().
[10515]237 GetExtraData (VBoxDefs::GUI_UpdateDate));
[10459]238
239 return data.isNecessary();
240}
241
[14274]242VBoxUpdateDlg::VBoxUpdateDlg (VBoxUpdateDlg **aSelf, bool aForceRun, QWidget *aParent)
[26079]243 : QIWithRetranslateUI <QDialog> (aParent)
[10459]244 , mSelf (aSelf)
[11466]245 , mUrl ("http://update.virtualbox.org/query.php")
[14274]246 , mHttp (new QIHttp (this, mUrl.host()))
[10515]247 , mForceRun (aForceRun)
[10459]248{
249 /* Store external pointer to this dialog. */
250 *mSelf = this;
251
252 /* Apply UI decorations */
253 Ui::VBoxUpdateDlg::setupUi (this);
254
[14274]255 /* Apply window icons */
[30192]256 setWindowIcon(UIIconPool::iconSetFull(QSize (32, 32), QSize (16, 16),
257 ":/refresh_32px.png", ":/refresh_16px.png"));
[14274]258
[10459]259 /* Setup other connections */
[10515]260 connect (mBtnCheck, SIGNAL (clicked()), this, SLOT (search()));
[10459]261
262 /* Setup initial condition */
[14274]263 mPbCheck->setMinimumWidth (mLogoUpdate->width() + mLogoUpdate->frameWidth() * 2);
[10459]264 mPbCheck->hide();
265 mTextSuccessInfo->hide();
266 mTextFailureInfo->hide();
267 mTextNotFoundInfo->hide();
268
269 /* Retranslate string constants */
270 retranslateUi();
271}
272
273VBoxUpdateDlg::~VBoxUpdateDlg()
274{
275 /* Erase dialog handle in config file. */
[14274]276 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_UpdateDlgWinID, QString::null);
[10459]277
278 /* Erase external pointer to this dialog. */
279 *mSelf = 0;
280}
281
[14274]282void VBoxUpdateDlg::retranslateUi()
283{
284 /* Translate uic generated strings */
285 Ui::VBoxUpdateDlg::retranslateUi (this);
286
287#if 0 /* All the text constants */
288 setWindowTitle (tr ("VirtualBox Update Wizard"));
289
290 mPageUpdateHdr->setText (tr ("Check for Updates"));
291 mBtnCheck->setText (tr ("Chec&k"));
292 mBtnCancel->setText (tr ("Cancel"));
293
294 mPageFinishHdr->setText (tr ("Summary"));
295 mBtnFinish->setText (tr ("&Close"));
296
297 mTextUpdateInfo->setText (tr ("<p>This wizard will connect to the VirtualBox "
298 "web-site and check if a newer version of "
299 "VirtualBox is available.</p><p>Use the "
300 "<b>Check</b> button to check for a new version "
301 "now or the <b>Cancel</b> button if you do not "
302 "want to perform this check.</p><p>You can run "
303 "this wizard at any time by choosing <b>Check "
304 "for Updates...</b> from the <b>Help</b> menu.</p>"));
305
306 mTextSuccessInfo->setText (tr ("<p>A new version of VirtualBox has been released! "
307 "Version <b>%1</b> is available at "
308 "<a href=\"http://www.virtualbox.org/\">virtualbox.org</a>.</p>"
[24775]309 "<p>You can download this version using the link:</p>"
[14274]310 "<p><a href=%2>%3</a></p>"));
311
312 mTextFailureInfo->setText (tr ("<p>Unable to obtain the new version information "
313 "due to the following network error:</p><p><b>%1</b></p>"));
314
[24775]315 mTextNotFoundInfo->setText (tr ("You are already running the most recent version of VirtualBox."));
[14274]316#endif
317}
318
[10459]319void VBoxUpdateDlg::accept()
320{
[10515]321 /* Recalculate new update data */
322 VBoxUpdateData oldData (vboxGlobal().virtualBox().
[14274]323 GetExtraData (VBoxDefs::GUI_UpdateDate));
[21770]324 VBoxUpdateData newData (oldData.periodIndex(), oldData.branchIndex());
[10515]325 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_UpdateDate,
326 newData.data());
[10459]327
[26079]328 QDialog::accept();
[10459]329}
330
331void VBoxUpdateDlg::search()
332{
[14274]333 /* Calculate the count of checks left */
[12286]334 int count = 1;
335 QString sc = vboxGlobal().virtualBox().GetExtraData (VBoxDefs::GUI_UpdateCheckCount);
336 if (!sc.isEmpty())
337 {
[14274]338 bool ok = false;
339 int c = sc.toLongLong (&ok);
340 if (ok) count = c;
[12286]341 }
[11446]342
[14274]343 /* Compose query */
344 QUrl url (mUrl);
[26079]345 url.addQueryItem ("platform", vboxGlobal().virtualBox().GetPackageType());
[23368]346 /* Branding: Check whether we have a local branding file which tells us our version suffix "FOO"
347 (e.g. 3.06.54321_FOO) to identify this installation */
348 if (vboxGlobal().brandingIsActive())
[26079]349 {
[23368]350 url.addQueryItem ("version", QString ("%1_%2_%3").arg (vboxGlobal().virtualBox().GetVersion())
351 .arg (vboxGlobal().virtualBox().GetRevision())
352 .arg (vboxGlobal().brandingGetKey("VerSuffix")));
353 }
354 else
355 {
356 /* Use hard coded version set by VBOX_VERSION_STRING */
357 url.addQueryItem ("version", QString ("%1_%2").arg (vboxGlobal().virtualBox().GetVersion())
358 .arg (vboxGlobal().virtualBox().GetRevision()));
359 }
[14274]360 url.addQueryItem ("count", QString::number (count));
[21770]361 url.addQueryItem ("branch", VBoxUpdateData (vboxGlobal().virtualBox().
362 GetExtraData (VBoxDefs::GUI_UpdateDate)).branchName());
[14274]363 QString userAgent (QString ("VirtualBox %1 <%2>")
364 .arg (vboxGlobal().virtualBox().GetVersion())
365 .arg (vboxGlobal().platformInfo()));
366
367 /* Show progress bar */
[11401]368 mPbCheck->show();
[10459]369
[14274]370 /* Send composed information */
371 QHttpRequestHeader header ("POST", url.toEncoded());
372 header.setValue ("Host", url.host());
373 header.setValue ("User-Agent", userAgent);
374 mHttp->disconnect (this);
375 connect (mHttp, SIGNAL (allIsDone (bool)), this, SLOT (searchResponse (bool)));
376 mHttp->request (header);
[10459]377}
378
[14274]379void VBoxUpdateDlg::searchResponse (bool aError)
[10459]380{
[14274]381 /* Block all the other incoming signals */
382 mHttp->disconnect (this);
[10459]383
[14274]384 /* Process error if present */
385 if (aError)
386 return abortRequest (mHttp->errorString());
[10459]387
388 /* Hide progress bar */
389 mPbCheck->hide();
390
[14274]391 /* Parse incoming data */
392 QString responseData (mHttp->readAll());
[10459]393
[14274]394 if (responseData.indexOf (QRegExp ("^\\d+\\.\\d+\\.\\d+ \\S+$")) == 0)
[11401]395 {
396 /* Newer version of necessary package found */
[14274]397 QStringList response = responseData.split (" ", QString::SkipEmptyParts);
[10459]398
[11401]399 if (isHidden())
[10459]400 {
[11401]401 /* For background update */
402 vboxProblem().showUpdateSuccess (vboxGlobal().mainWindow(),
[14274]403 response [0], response [1]);
[11401]404 QTimer::singleShot (0, this, SLOT (accept()));
[10459]405 }
[11401]406 else
407 {
408 /* For wizard update */
409 mTextSuccessInfo->setText (mTextSuccessInfo->text()
[14274]410 .arg (response [0], response [1], response [1]));
[11401]411 mTextSuccessInfo->show();
412 mPageStack->setCurrentIndex (1);
413 }
[10459]414 }
[14274]415 else /* if (responseData == "UPTODATE") */
[10459]416 {
[11401]417 /* No newer version of necessary package found */
418 if (isHidden())
419 {
420 /* For background update */
421 if (mForceRun)
422 vboxProblem().showUpdateNotFound (vboxGlobal().mainWindow());
423 QTimer::singleShot (0, this, SLOT (accept()));
424 }
425 else
426 {
427 /* For wizard update */
428 mTextNotFoundInfo->show();
429 mPageStack->setCurrentIndex (1);
430 }
[10459]431 }
[12286]432
[14274]433 /* Save left count of checks */
[12286]434 int count = 1;
435 bool ok = false;
436 QString sc = vboxGlobal().virtualBox().GetExtraData (VBoxDefs::GUI_UpdateCheckCount);
437 if (!sc.isEmpty())
[14274]438 count = sc.toLongLong (&ok);
[12286]439 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_UpdateCheckCount,
440 QString ("%1").arg ((qulonglong) count + 1));
[10459]441}
442
[14274]443void VBoxUpdateDlg::abortRequest (const QString &aReason)
444{
445 /* Hide progress bar */
446 mPbCheck->hide();
447
448 if (isHidden())
449 {
450 /* For background update */
451 if (mForceRun)
452 vboxProblem().showUpdateFailure (vboxGlobal().mainWindow(), aReason);
453 QTimer::singleShot (0, this, SLOT (accept()));
454 }
455 else
456 {
457 /* For wizard update */
458 mTextFailureInfo->setText (mTextFailureInfo->text().arg (aReason));
459 mTextFailureInfo->show();
460 mPageStack->setCurrentIndex (1);
461 }
462}
463
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use