VirtualBox

Changeset 3925 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 30, 2007 4:44:12 PM (18 years ago)
Author:
vboxsync
Message:

2142: GUI should download Additions:

Feature implemented:

  1. If the Guest Additions Image could not be found in local file-system (when the Install Guest Additions menu action invoked) it will be requested from the virtualbox.org site.
  2. If the image is found it's name&size will be reported to the user with the request about download it or not.
  3. If the user decided to download the image it will be asynchronously downloaded to the user's home directory.
  4. The Guest Additions Image downloading progress is displayed with using of little progress-bar at the left-bottom corner of the VM console window (status-bar left side).
  5. User can cancel the image downloading by pressing the "Cancel" button near the downloading progress-bar.
  6. When the image will be downloaded it will be automatically mounted into the CD/DVD-ROM.
Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r3908 r3925  
    8080
    8181# Sources containing local definitions of classes that use the Q_OBJECT macro
    82 VirtualBox_QT_MOCSRCS = src/VBoxSelectorWnd.cpp
     82VirtualBox_QT_MOCSRCS = src/VBoxSelectorWnd.cpp \
     83                                                src/VBoxConsoleWnd.cpp
    8384ifdef VBOX_WITH_XPCOM
    8485VirtualBox_QT_MOCSRCS += src/COMDefs.cpp
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleWnd.h

    r3802 r3925  
    7979    void popupMainMenu (bool aCenter);
    8080
     81    void installGuestAdditionsFrom (const QString &aSource);
     82
    8183public slots:
    8284
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxProblemReporter.h

    r3807 r3925  
    195195                                   const QString &, const QString &);
    196196
     197    void cannotDonwloadGuestAdditions (const QString &aName,
     198                                       const QString &aReason);
     199
     200    int warnAboutAdditionsDownload (const QString &aSrc1, const QString &aSrc2,
     201                                    const QString &aName, ulong aSize);
     202
    197203    void warnAboutTooOldAdditions (QWidget *, const QString &, const QString &);
    198204    void warnAboutOldAdditions (QWidget *, const QString &, const QString &);
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp

    r3867 r3925  
    5353#include <qtoolbutton.h>
    5454#include <qcursor.h>
     55#include <qhttp.h>
     56#include <qprogressbar.h>
    5557
    5658#include <qeventloop.h>
     
    195197
    196198    QString mTip;
     199};
     200
     201/** class VBoxGADownloader
     202 *
     203 *  The VBoxGADownloader class is an QWidget class for Guest Additions
     204 *  http backgroung downloading. This class is also used to display the
     205 *  Guest Additions download state through the progress dialog integrated
     206 *  into the VM console status bar.
     207 */
     208class VBoxGADownloader : public QWidget
     209{
     210    Q_OBJECT
     211
     212public:
     213
     214    VBoxGADownloader (QStatusBar *aStatusBar, QAction *aAction,
     215                      const QString &aSrc1, const QString &aSrc2)
     216        : QWidget (0, "VBoxGADownloader")
     217        , mStatusBar (aStatusBar)
     218        , mSrc1 (aSrc1), mSrc2 (aSrc2)
     219        , mHost (QString::null), mPath (QString::null), mFile (QString::null)
     220        , mHttp (0), mIsChecking (true)
     221        , mProgressBar (0), mCancelButton (0)
     222        , mAction (aAction), mStatus (0)
     223    {
     224        /* Disable Install Guest Additions action */
     225        mAction->setEnabled (false);
     226
     227        /* Drawing itself */
     228        mProgressBar = new QProgressBar (this);
     229        mProgressBar->setFixedWidth (100);
     230        mCancelButton = new QToolButton (this);
     231        mCancelButton->setAutoRaise (true);
     232        mCancelButton->setFocusPolicy (TabFocus);
     233        QSpacerItem *spacer = new QSpacerItem (0, 0, QSizePolicy::Expanding,
     234                                                     QSizePolicy::Fixed);
     235
     236        QHBoxLayout *mainLayout = new QHBoxLayout (this);
     237        mainLayout->addWidget (mProgressBar);
     238        mainLayout->addWidget (mCancelButton);
     239        mainLayout->addItem (spacer);
     240
     241        languageChange();
     242
     243        /* Select the product version */
     244        QString version = vboxGlobal().virtualBox().GetVersion();
     245
     246        /* Select the Guest Additions image file */
     247        mHost = "www.virtualbox.org";
     248        mPath = QString ("/download/%1/").arg (version);
     249        mFile = QString ("VBoxGuestAdditions_%1.iso").arg (version);
     250
     251        /* Initialize url operator */
     252        mHttp = new QHttp (this, "mHttp");
     253        mHttp->setHost (mHost);
     254
     255        /* Setup connections */
     256        connect (mHttp, SIGNAL (dataReadProgress (int, int)),
     257                 this, SLOT (processProgress (int, int)));
     258        connect (mHttp, SIGNAL (requestFinished (int, bool)),
     259                 this, SLOT (processFinished (int, bool)));
     260        connect (mHttp, SIGNAL (responseHeaderReceived (const QHttpResponseHeader&)),
     261                 this, SLOT (processResponse (const QHttpResponseHeader&)));
     262        connect (mCancelButton, SIGNAL (clicked()),
     263                 this, SLOT (processAbort()));
     264
     265        /* Try to get the required file for the information */
     266        mHttp->get (mPath + mFile);
     267    }
     268
     269    void languageChange()
     270    {
     271        mCancelButton->setText (tr ("Cancel"));
     272        QToolTip::add (mProgressBar, tr ("VirtualBox Guest Additions Image "
     273                                         "downloading progress"));
     274        QToolTip::add (mCancelButton, tr ("Press to cancel VirtualBox Guest "
     275                                          "Additions Image downloading process"));
     276    }
     277
     278private slots:
     279
     280    /* This slot is used to handle the progress of the file-downloading
     281     * procedure. It also checks the downloading status for the file
     282     * presence verifying purposes. */
     283    void processProgress (int aRead, int aTotal)
     284    {
     285        if (aTotal != -1)
     286        {
     287            if (mIsChecking)
     288            {
     289                mHttp->abort();
     290                if (mStatus == 404)
     291                    abortDownload (tr ("Unable to find the corresponding "
     292                                       "Guest Additions Image file."));
     293                else
     294                    processFile (aTotal);
     295            }
     296            else
     297                mProgressBar->setProgress (aRead, aTotal);
     298        }
     299        else
     300            abortDownload (tr ("Couldn't determine file size."));
     301    }
     302
     303    /* This slot is used to handle the finish signal of every operation's
     304     * response. It is used to display the errors occurred during the download
     305     * operation and for the received-buffer serialization procedure. */
     306    void processFinished (int, bool aError)
     307    {
     308        if (aError && mHttp->error() != QHttp::Aborted)
     309        {
     310            QString reason = mIsChecking ?
     311                tr ("Checking Guest Additions file presence failed (%1).") :
     312                tr ("Downloading Guest Additions file failed (%1).");
     313            abortDownload (reason.arg (mHttp->errorString()));
     314        }
     315        else if (!aError && !mIsChecking)
     316        {
     317            /* Serialize the incoming buffer into the .iso image. */
     318            QString path = QDir (QDir::home()).absFilePath (mFile);
     319            QFile file (path);
     320            if (file.open (IO_WriteOnly))
     321            {
     322                file.writeBlock (mHttp->readAll());
     323                file.close();
     324                vboxGlobal().consoleWnd().installGuestAdditionsFrom (path);
     325                QTimer::singleShot (0, this, SLOT (suicide()));
     326            }
     327            else
     328                abortDownload (tr ("Could not write the local file."));
     329        }
     330    }
     331
     332    /* This slot is used to handle the header responses about the
     333     * requested operations. Watches for the header's status-code. */
     334    void processResponse (const QHttpResponseHeader &aHeader)
     335    {
     336        mStatus = aHeader.statusCode();
     337    }
     338
     339    /* This slot is used to process cancel-button clicking signal. */
     340    void processAbort()
     341    {
     342        mHttp->abort();
     343        abortDownload (tr ("Download aborted by user."));
     344    }
     345
     346    /* This slot is used to terminate the downloader, activate the
     347     * Install Guest Additions action and removing the downloader's
     348     * sub-widgets from the VM Console status-bar. */
     349    void suicide()
     350    {
     351        mAction->setEnabled (true);
     352        mStatusBar->removeWidget (this);
     353        delete this;
     354    }
     355
     356private:
     357
     358    /* This function is used to ask the user about he wants to download the
     359     * founded Guest Additions image or not. It also shows the progress-bar
     360     * and Cancel-button widgets. */
     361    void processFile (int aSize)
     362    {
     363        /* Ask user about GA image downloading */
     364        int rc = vboxProblem().warnAboutAdditionsDownload (mSrc1, mSrc2,
     365                                          mHost + mPath + mFile, aSize);
     366        if (rc == QIMessageBox::Yes)
     367        {
     368            mStatusBar->addWidget (this);
     369            setFixedHeight (16);
     370            mIsChecking = false;
     371            mHttp->get (mPath + mFile);
     372        }
     373        else
     374            abortDownload (tr ("Download rejected by user."));
     375    }
     376
     377    /* This wrapper displays the error message box with the root cause of the
     378     * download procedure termination. It is also used to command the
     379     * downloader to terminate himself after all the events being processed. */
     380    void abortDownload (const QString &aReason)
     381    {
     382        vboxProblem().cannotDonwloadGuestAdditions (mHost + mPath + mFile,
     383                                                    aReason);
     384        /* Allows all the queued signals to be processed before quit. */
     385        QTimer::singleShot (0, this, SLOT (suicide()));
     386    }
     387
     388    QStatusBar *mStatusBar;
     389    QString mSrc1;
     390    QString mSrc2;
     391    QString mHost;
     392    QString mPath;
     393    QString mFile;
     394    QHttp *mHttp;
     395    bool mIsChecking;
     396    QProgressBar *mProgressBar;
     397    QToolButton *mCancelButton;
     398    QAction *mAction;
     399    int mStatus;
    197400};
    198401
     
    22952498void VBoxConsoleWnd::devicesInstallGuestAdditions()
    22962499{
    2297     CVirtualBox vbox = vboxGlobal().virtualBox();
    2298 
    22992500#if defined (DEBUG_dmik) /* subscribe yourself here if you care for this behavior. */
    23002501    QString src1 = qApp->applicationDirPath() + "/../../release/bin/VBoxGuestAdditions.iso";
     
    23102511    QString src2 = qApp->applicationDirPath() + "/additions/VBoxGuestAdditions.iso";
    23112512#endif
    2312     QString src;
    23132513
    23142514    if (QFile::exists (src1))
    2315         src = src1;
     2515        installGuestAdditionsFrom (src1);
    23162516    else if (QFile::exists (src2))
    2317         src = src2;
     2517        installGuestAdditionsFrom (src2);
    23182518    else
    2319     {
    2320         vboxProblem().message (this, VBoxProblemReporter::Error,
    2321             tr ("<p>Failed to find the VirtualBox Guest Additions CD image "
    2322                 "<nobr><b>%1</b></nobr> or "
    2323                 "<nobr><b>%2</b></nobr></p>")
    2324             .arg (src1).arg (src2));
    2325         return;
    2326     }
    2327 
     2519        new VBoxGADownloader (statusBar(), devicesInstallGuestToolsAction,
     2520                              src1, src2);
     2521}
     2522
     2523void VBoxConsoleWnd::installGuestAdditionsFrom (const QString &aSource)
     2524{
     2525    CVirtualBox vbox = vboxGlobal().virtualBox();
     2526
     2527    QString src (aSource);
    23282528    QUuid uuid;
    23292529    CDVDImage newImage = vbox.OpenDVDImage (src, uuid);
     
    29873187    QDialog::showEvent (aEvent);
    29883188}
     3189
     3190#include "VBoxConsoleWnd.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxProblemReporter.cpp

    r3873 r3925  
    12541254}
    12551255
     1256void VBoxProblemReporter::cannotDonwloadGuestAdditions (const QString &aName,
     1257                                                        const QString &aReason)
     1258{
     1259    QString msg = tr ("<p>Failed to download the VirtualBox Guest "
     1260        "Additions CD image <nobr><b>%1</b>.</nobr></p>").arg (aName);
     1261    msg += QString ("<p>%1</p>").arg (aReason);
     1262    message (&vboxGlobal().consoleWnd(), Error, msg);
     1263}
     1264
     1265int VBoxProblemReporter::warnAboutAdditionsDownload (const QString &aSrc1,
     1266                                                     const QString &aSrc2,
     1267                                                     const QString &aName,
     1268                                                     ulong aSize)
     1269{
     1270    QString msg = tr ("<p>Failed to find the VirtualBox Guest Additions CD image "
     1271                      "<nobr><b>%1</b></nobr> or "
     1272                      "<nobr><b>%2</b></nobr></p>").arg (aSrc1).arg (aSrc2);
     1273    msg += tr ("<p>Do you want to download this image "
     1274               "<nobr><b>%1</b></nobr> (%2 bytes)?</p>").arg (aName).arg (aSize);
     1275
     1276    return message (&vboxGlobal().consoleWnd(), Question, msg,
     1277                    0, /* autoConfirmId */
     1278                    QIMessageBox::Yes | QIMessageBox::Default,
     1279                    QIMessageBox::No | QIMessageBox::Escape);
     1280}
     1281
    12561282void VBoxProblemReporter::warnAboutTooOldAdditions (QWidget *aParent,
    12571283                                                    const QString &aInstalledVer,
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette