~ubuntu-branches/ubuntu/precise/virtualbox/precise-updates

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/src/VBoxUpdateDlg.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-10-17 23:23:09 UTC
  • mfrom: (3.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20111017232309-kzm6841lzk61ranj
Tags: 4.1.4-dfsg-1
* New upstream release.
  - Fixes missing icons when using pt_BR locale. (Closes: #507188)
  - Fixes guest additions download url. (Closes: #637349; LP: #840668)
* Refresh patches.
* Drop the vboxmouse x11 driver. The mouse integration is now completely
  handled by the kernel module.
* Restrict dh_pycentral to the virtualbox binary package.
* Merge changes from the Ubuntu package but use them only when built
  on Ubuntu:
  - Add an Apport hook.
  - Add vboxguest modalias to the package control field.
* Pass KBUILD_VERBOSE=2 to kmk.
* Add 36-fix-text-mode.patch to fix text mode when using the vboxvideo driver.

Show diffs side-by-side

added added

removed removed

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