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
Line 
1/** @file
2 *
3 * VBox frontends: Qt4 GUI ("VirtualBox"):
4 * VBoxUpdateDlg class implementation
5 */
6
7/*
8 * Copyright (C) 2006-2010 Oracle Corporation
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
19#ifdef VBOX_WITH_PRECOMPILED_HEADERS
20#include "precomp.h"
21#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
22/* Global includes */
23#include <QTimer>
24/* Local includes */
25#include "QIHttp.h"
26#include "VBoxGlobal.h"
27#include "VBoxProblemReporter.h"
28#include "VBoxUpdateDlg.h"
29#include "UIIconPool.h"
30#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
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 {
51 return (x < aOther.x) ||
52 (x == aOther.x && y < aOther.y) ||
53 (x == aOther.x && y == aOther.y && z < aOther.z);
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 */
69QList <UpdateDay> VBoxUpdateData::mDayList = QList <UpdateDay>();
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 */
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");
85
86 /* Separately retranslate each week */
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");
90
91 /* Separately retranslate each month */
92 mDayList << UpdateDay (VBoxUpdateDlg::tr ("1 month"), "1 m");
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
103VBoxUpdateData::VBoxUpdateData (const QString &aData)
104 : mData (aData)
105 , mPeriodIndex (Period1Day)
106 , mBranchIndex (BranchStable)
107{
108 decode();
109}
110
111VBoxUpdateData::VBoxUpdateData (PeriodType aPeriodIndex, BranchType aBranchIndex)
112 : mData (QString::null)
113 , mPeriodIndex (aPeriodIndex)
114 , mBranchIndex (aBranchIndex)
115{
116 encode();
117}
118
119bool VBoxUpdateData::isNecessary()
120{
121 return mPeriodIndex != PeriodNever && QDate::currentDate() >= mDate;
122}
123
124bool VBoxUpdateData::isNoNeedToCheck()
125{
126 return mPeriodIndex == PeriodNever;
127}
128
129QString VBoxUpdateData::data() const
130{
131 return mData;
132}
133
134VBoxUpdateData::PeriodType VBoxUpdateData::periodIndex() const
135{
136 return mPeriodIndex;
137}
138
139QString VBoxUpdateData::date() const
140{
141 return mPeriodIndex == PeriodNever ? VBoxUpdateDlg::tr ("Never") :
142 mDate.toString (Qt::LocaleDate);
143}
144
145VBoxUpdateData::BranchType VBoxUpdateData::branchIndex() const
146{
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{
166 /* Parse standard values */
167 if (mData == "never")
168 mPeriodIndex = PeriodNever;
169 /* Parse other values */
170 else
171 {
172 QStringList parser (mData.split (", ", QString::SkipEmptyParts));
173
174 /* Parse 'period' value */
175 if (parser.size() > 0)
176 {
177 if (mDayList.isEmpty())
178 populate();
179 PeriodType index = (PeriodType) mDayList.indexOf (UpdateDay (QString::null, parser [0]));
180 mPeriodIndex = index == PeriodUndefined ? Period1Day : index;
181 }
182
183 /* Parse 'date' value */
184 if (parser.size() > 1)
185 {
186 QDate date = QDate::fromString (parser [1], Qt::ISODate);
187 mDate = date.isValid() ? date : QDate::currentDate();
188 }
189
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 }
197 }
198}
199
200void VBoxUpdateData::encode()
201{
202 /* Encode standard values */
203 if (mPeriodIndex == PeriodNever)
204 mData = "never";
205 /* Encode other values */
206 else
207 {
208 /* Encode 'period' value */
209 if (mDayList.isEmpty())
210 populate();
211 QString remindPeriod = mDayList [mPeriodIndex].key;
212
213 /* Encode 'date' value */
214 mDate = QDate::currentDate();
215 QStringList parser (remindPeriod.split (' '));
216 if (parser [1] == "d")
217 mDate = mDate.addDays (parser [0].toInt());
218 else if (parser [1] == "w")
219 mDate = mDate.addDays (parser [0].toInt() * 7);
220 else if (parser [1] == "m")
221 mDate = mDate.addMonths (parser [0].toInt());
222 QString remindDate = mDate.toString (Qt::ISODate);
223
224 /* Encode 'branch' value */
225 QString branchValue = mBranchIndex == BranchWithBetas ? "withbetas" :
226 mBranchIndex == BranchAllRelease ? "allrelease" : "stable";
227
228 /* Composite mData */
229 mData = QString ("%1, %2, %3").arg (remindPeriod, remindDate, branchValue);
230 }
231}
232
233/* VBoxUpdateDlg stuff */
234bool VBoxUpdateDlg::isNecessary()
235{
236 VBoxUpdateData data (vboxGlobal().virtualBox().
237 GetExtraData (VBoxDefs::GUI_UpdateDate));
238
239 return data.isNecessary();
240}
241
242VBoxUpdateDlg::VBoxUpdateDlg (VBoxUpdateDlg **aSelf, bool aForceRun, QWidget *aParent)
243 : QIWithRetranslateUI <QDialog> (aParent)
244 , mSelf (aSelf)
245 , mUrl ("http://update.virtualbox.org/query.php")
246 , mHttp (new QIHttp (this, mUrl.host()))
247 , mForceRun (aForceRun)
248{
249 /* Store external pointer to this dialog. */
250 *mSelf = this;
251
252 /* Apply UI decorations */
253 Ui::VBoxUpdateDlg::setupUi (this);
254
255 /* Apply window icons */
256 setWindowIcon(UIIconPool::iconSetFull(QSize (32, 32), QSize (16, 16),
257 ":/refresh_32px.png", ":/refresh_16px.png"));
258
259 /* Setup other connections */
260 connect (mBtnCheck, SIGNAL (clicked()), this, SLOT (search()));
261
262 /* Setup initial condition */
263 mPbCheck->setMinimumWidth (mLogoUpdate->width() + mLogoUpdate->frameWidth() * 2);
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. */
276 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_UpdateDlgWinID, QString::null);
277
278 /* Erase external pointer to this dialog. */
279 *mSelf = 0;
280}
281
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>"
309 "<p>You can download this version using the link:</p>"
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
315 mTextNotFoundInfo->setText (tr ("You are already running the most recent version of VirtualBox."));
316#endif
317}
318
319void VBoxUpdateDlg::accept()
320{
321 /* Recalculate new update data */
322 VBoxUpdateData oldData (vboxGlobal().virtualBox().
323 GetExtraData (VBoxDefs::GUI_UpdateDate));
324 VBoxUpdateData newData (oldData.periodIndex(), oldData.branchIndex());
325 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_UpdateDate,
326 newData.data());
327
328 QDialog::accept();
329}
330
331void VBoxUpdateDlg::search()
332{
333 /* Calculate the count of checks left */
334 int count = 1;
335 QString sc = vboxGlobal().virtualBox().GetExtraData (VBoxDefs::GUI_UpdateCheckCount);
336 if (!sc.isEmpty())
337 {
338 bool ok = false;
339 int c = sc.toLongLong (&ok);
340 if (ok) count = c;
341 }
342
343 /* Compose query */
344 QUrl url (mUrl);
345 url.addQueryItem ("platform", vboxGlobal().virtualBox().GetPackageType());
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())
349 {
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 }
360 url.addQueryItem ("count", QString::number (count));
361 url.addQueryItem ("branch", VBoxUpdateData (vboxGlobal().virtualBox().
362 GetExtraData (VBoxDefs::GUI_UpdateDate)).branchName());
363 QString userAgent (QString ("VirtualBox %1 <%2>")
364 .arg (vboxGlobal().virtualBox().GetVersion())
365 .arg (vboxGlobal().platformInfo()));
366
367 /* Show progress bar */
368 mPbCheck->show();
369
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);
377}
378
379void VBoxUpdateDlg::searchResponse (bool aError)
380{
381 /* Block all the other incoming signals */
382 mHttp->disconnect (this);
383
384 /* Process error if present */
385 if (aError)
386 return abortRequest (mHttp->errorString());
387
388 /* Hide progress bar */
389 mPbCheck->hide();
390
391 /* Parse incoming data */
392 QString responseData (mHttp->readAll());
393
394 if (responseData.indexOf (QRegExp ("^\\d+\\.\\d+\\.\\d+ \\S+$")) == 0)
395 {
396 /* Newer version of necessary package found */
397 QStringList response = responseData.split (" ", QString::SkipEmptyParts);
398
399 if (isHidden())
400 {
401 /* For background update */
402 vboxProblem().showUpdateSuccess (vboxGlobal().mainWindow(),
403 response [0], response [1]);
404 QTimer::singleShot (0, this, SLOT (accept()));
405 }
406 else
407 {
408 /* For wizard update */
409 mTextSuccessInfo->setText (mTextSuccessInfo->text()
410 .arg (response [0], response [1], response [1]));
411 mTextSuccessInfo->show();
412 mPageStack->setCurrentIndex (1);
413 }
414 }
415 else /* if (responseData == "UPTODATE") */
416 {
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 }
431 }
432
433 /* Save left count of checks */
434 int count = 1;
435 bool ok = false;
436 QString sc = vboxGlobal().virtualBox().GetExtraData (VBoxDefs::GUI_UpdateCheckCount);
437 if (!sc.isEmpty())
438 count = sc.toLongLong (&ok);
439 vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_UpdateCheckCount,
440 QString ("%1").arg ((qulonglong) count + 1));
441}
442
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