Index: trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 27374)
@@ -357,5 +357,6 @@
 	src/widgets/VBoxApplianceEditorWgt.h \
 	src/widgets/VBoxBootTable.h \
-	src/widgets/VBoxDownloaderWgt.h \
+	src/widgets/UIDownloader.h \
+	src/widgets/UIDownloaderAdditions.h \
 	src/widgets/VBoxExportApplianceWgt.h \
 	src/widgets/VBoxFilePathSelectorWidget.h \
@@ -485,5 +486,6 @@
 	src/widgets/VBoxApplianceEditorWgt.cpp \
 	src/widgets/VBoxBootTable.cpp \
-	src/widgets/VBoxDownloaderWgt.cpp \
+	src/widgets/UIDownloader.cpp \
+	src/widgets/UIDownloaderAdditions.cpp \
 	src/widgets/VBoxExportApplianceWgt.cpp \
 	src/widgets/VBoxFilePathSelectorWidget.cpp \
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 27374)
@@ -52,5 +52,5 @@
 #include "VBoxConsoleView.h"
 #include "VBoxCloseVMDlg.h"
-#include "VBoxDownloaderWgt.h"
+#include "UIDownloaderAdditions.h"
 #include "VBoxGlobal.h"
 #include "VBoxMediaManagerDlg.h"
@@ -102,102 +102,4 @@
 
     QString mTip;
-};
-
-class VBoxAdditionsDownloader : public VBoxDownloaderWgt
-{
-    Q_OBJECT;
-
-public:
-
-    VBoxAdditionsDownloader (const QString &aSource, const QString &aTarget, QAction *aAction)
-        : VBoxDownloaderWgt (aSource, aTarget)
-        , mAction (aAction)
-    {
-        mAction->setEnabled (false);
-        retranslateUi();
-    }
-
-    void start()
-    {
-        acknowledgeStart();
-    }
-
-protected:
-
-    void retranslateUi()
-    {
-        mCancelButton->setText (tr ("Cancel"));
-        mProgressBar->setToolTip (tr ("Downloading the VirtualBox Guest Additions "
-                                      "CD image from <nobr><b>%1</b>...</nobr>")
-                                      .arg (mSource.toString()));
-        mCancelButton->setToolTip (tr ("Cancel the VirtualBox Guest "
-                                       "Additions CD image download"));
-    }
-
-private slots:
-
-    void downloadFinished (bool aError)
-    {
-        if (aError)
-            VBoxDownloaderWgt::downloadFinished (aError);
-        else
-        {
-            QByteArray receivedData (mHttp->readAll());
-            /* Serialize the incoming buffer into the .iso image. */
-            while (true)
-            {
-                QFile file (mTarget);
-                if (file.open (QIODevice::WriteOnly))
-                {
-                    file.write (receivedData);
-                    file.close();
-                    if (vboxProblem().confirmMountAdditions (mSource.toString(),
-                        QDir::toNativeSeparators (mTarget)))
-                        vboxGlobal().consoleWnd().installGuestAdditionsFrom (mTarget);
-                    QTimer::singleShot (0, this, SLOT (suicide()));
-                    break;
-                }
-                else
-                {
-                    vboxProblem().message (window(), VBoxProblemReporter::Error,
-                        tr ("<p>Failed to save the downloaded file as "
-                            "<nobr><b>%1</b>.</nobr></p>")
-                        .arg (QDir::toNativeSeparators (mTarget)));
-                }
-
-                QString target = QIFileDialog::getExistingDirectory (
-                    QFileInfo (mTarget).absolutePath(), this,
-                    tr ("Select folder to save Guest Additions image to"), true);
-                if (target.isNull())
-                    QTimer::singleShot (0, this, SLOT (suicide()));
-                else
-                    mTarget = QDir (target).absoluteFilePath (QFileInfo (mTarget).fileName());
-            }
-        }
-    }
-
-    void suicide()
-    {
-        QStatusBar *sb = qobject_cast <QStatusBar*> (parent());
-        Assert (sb);
-        sb->removeWidget (this);
-        mAction->setEnabled (true);
-        VBoxDownloaderWgt::suicide();
-    }
-
-private:
-
-    bool confirmDownload()
-    {
-        return vboxProblem().confirmDownloadAdditions (mSource.toString(),
-            mHttp->lastResponse().contentLength());
-    }
-
-    void warnAboutError (const QString &aError)
-    {
-        return vboxProblem().cannotDownloadGuestAdditions (mSource.toString(), aError);
-    }
-
-    QAction *mAction;
 };
 
@@ -1123,85 +1025,4 @@
     mMainMenu->activateWindow();
 #endif
-}
-
-void VBoxConsoleWnd::installGuestAdditionsFrom (const QString &aSource)
-{
-    CVirtualBox vbox = vboxGlobal().virtualBox();
-    QString uuid;
-
-    CMedium image = vbox.FindDVDImage (aSource);
-    if (image.isNull())
-    {
-        image = vbox.OpenDVDImage (aSource, uuid);
-        if (vbox.isOk())
-            uuid = image.GetId();
-    }
-    else
-        uuid = image.GetId();
-
-    if (!vbox.isOk())
-        return vboxProblem().cannotOpenMedium (this, vbox, VBoxDefs::MediumType_DVD, aSource);
-
-    Assert (!uuid.isNull());
-    CMachine m = mSession.GetMachine();
-
-    QString ctrName;
-    LONG ctrPort = -1, ctrDevice = -1;
-    /* Searching for the first suitable slot */
-    {
-        CStorageControllerVector controllers = m.GetStorageControllers();
-        int i = 0;
-        while (i < controllers.size() && ctrName.isNull())
-        {
-            CStorageController controller = controllers [i];
-            CMediumAttachmentVector attachments = m.GetMediumAttachmentsOfController (controller.GetName());
-            int j = 0;
-            while (j < attachments.size() && ctrName.isNull())
-            {
-                CMediumAttachment attachment = attachments [j];
-                if (attachment.GetType() == KDeviceType_DVD)
-                {
-                    ctrName = controller.GetName();
-                    ctrPort = attachment.GetPort();
-                    ctrDevice = attachment.GetDevice();
-                }
-                ++ j;
-            }
-            ++ i;
-        }
-    }
-
-    if (!ctrName.isNull())
-    {
-        bool isMounted = false;
-
-        /* Mount medium to the predefined port/device */
-        m.MountMedium (ctrName, ctrPort, ctrDevice, uuid, false /* force */);
-        if (m.isOk())
-            isMounted = true;
-        else
-        {
-            /* Ask for force mounting */
-            if (vboxProblem().cannotRemountMedium (this, m, VBoxMedium (image, VBoxDefs::MediumType_DVD), true /* mount? */, true /* retry? */) == QIMessageBox::Ok)
-            {
-                /* Force mount medium to the predefined port/device */
-                m.MountMedium (ctrName, ctrPort, ctrDevice, uuid, true /* force */);
-                if (m.isOk())
-                    isMounted = true;
-                else
-                    vboxProblem().cannotRemountMedium (this, m, VBoxMedium (image, VBoxDefs::MediumType_DVD), true /* mount? */, false /* retry? */);
-            }
-        }
-
-        /* Save medium mounted at runtime */
-        if (isMounted && mIsAutoSaveMedia)
-        {
-            m.SaveSettings();
-            if (!m.isOk())
-                vboxProblem().cannotSaveMachineSettings (m);
-        }
-    }
-    else
-        vboxProblem().cannotMountGuestAdditions (m.GetName());
 }
 
@@ -2261,8 +2082,18 @@
                                .absoluteFilePath (name);
 
-        VBoxAdditionsDownloader *dl =
-            new VBoxAdditionsDownloader (source, target, mDevicesInstallGuestToolsAction);
-        statusBar()->addWidget (dl, 0);
-        dl->start();
+        UIDownloaderAdditions *pDl = UIDownloaderAdditions::create();
+        /* Configure the additions downloader. */
+        pDl->setSource(source);
+        pDl->setTarget(target);
+        pDl->setAction(mDevicesInstallGuestToolsAction);
+        pDl->setParentWidget(this);
+        /* After the download is finished the user may like to install the
+         * additions.*/
+        connect(pDl, SIGNAL(downloadFinished(const QString&)),
+                this, SLOT(installGuestAdditionsFrom(const QString&)));
+        /* Add the progress bar widget to the statusbar. */
+        statusBar()->addWidget(pDl->processWidget(this), 0);
+        /* Start the download: */
+        pDl->startDownload();
     }
 }
@@ -2958,4 +2789,85 @@
 }
 
+void VBoxConsoleWnd::installGuestAdditionsFrom (const QString &aSource)
+{
+    CVirtualBox vbox = vboxGlobal().virtualBox();
+    QString uuid;
+
+    CMedium image = vbox.FindDVDImage (aSource);
+    if (image.isNull())
+    {
+        image = vbox.OpenDVDImage (aSource, uuid);
+        if (vbox.isOk())
+            uuid = image.GetId();
+    }
+    else
+        uuid = image.GetId();
+
+    if (!vbox.isOk())
+        return vboxProblem().cannotOpenMedium (this, vbox, VBoxDefs::MediumType_DVD, aSource);
+
+    Assert (!uuid.isNull());
+    CMachine m = mSession.GetMachine();
+
+    QString ctrName;
+    LONG ctrPort = -1, ctrDevice = -1;
+    /* Searching for the first suitable slot */
+    {
+        CStorageControllerVector controllers = m.GetStorageControllers();
+        int i = 0;
+        while (i < controllers.size() && ctrName.isNull())
+        {
+            CStorageController controller = controllers [i];
+            CMediumAttachmentVector attachments = m.GetMediumAttachmentsOfController (controller.GetName());
+            int j = 0;
+            while (j < attachments.size() && ctrName.isNull())
+            {
+                CMediumAttachment attachment = attachments [j];
+                if (attachment.GetType() == KDeviceType_DVD)
+                {
+                    ctrName = controller.GetName();
+                    ctrPort = attachment.GetPort();
+                    ctrDevice = attachment.GetDevice();
+                }
+                ++ j;
+            }
+            ++ i;
+        }
+    }
+
+    if (!ctrName.isNull())
+    {
+        bool isMounted = false;
+
+        /* Mount medium to the predefined port/device */
+        m.MountMedium (ctrName, ctrPort, ctrDevice, uuid, false /* force */);
+        if (m.isOk())
+            isMounted = true;
+        else
+        {
+            /* Ask for force mounting */
+            if (vboxProblem().cannotRemountMedium (this, m, VBoxMedium (image, VBoxDefs::MediumType_DVD), true /* mount? */, true /* retry? */) == QIMessageBox::Ok)
+            {
+                /* Force mount medium to the predefined port/device */
+                m.MountMedium (ctrName, ctrPort, ctrDevice, uuid, true /* force */);
+                if (m.isOk())
+                    isMounted = true;
+                else
+                    vboxProblem().cannotRemountMedium (this, m, VBoxMedium (image, VBoxDefs::MediumType_DVD), true /* mount? */, false /* retry? */);
+            }
+        }
+
+        /* Save medium mounted at runtime */
+        if (isMounted && mIsAutoSaveMedia)
+        {
+            m.SaveSettings();
+            if (!m.isOk())
+                vboxProblem().cannotSaveMachineSettings (m);
+        }
+    }
+    else
+        vboxProblem().cannotMountGuestAdditions (m.GetName());
+}
+
 /**
  *  This function checks the status of required features and
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.h	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.h	(revision 27374)
@@ -107,6 +107,4 @@
     void popupMainMenu (bool aCenter);
 
-    void installGuestAdditionsFrom (const QString &aSource);
-
     void setMask (const QRegion &aRegion);
     void clearMask();
@@ -186,4 +184,6 @@
     void changePresentationMode (const VBoxChangePresentationModeEvent &aEvent);
     void processGlobalSettingChange (const char *aPublicName, const char *aName);
+
+    void installGuestAdditionsFrom (const QString &aSource);
 
 #ifdef RT_OS_DARWIN /* Stupid moc doesn't recognize Q_WS_MAC */
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp	(revision 27374)
@@ -37,9 +37,8 @@
 #include "VBoxVMSettingsNetwork.h"
 #include "VBoxVMSettingsSF.h"
+#include "UIDownloaderAdditions.h"
 #ifdef Q_WS_MAC
 # include "DockIconPreview.h"
 #endif /* Q_WS_MAC */
-
-//#include "VBoxDownloaderWgt.h"
 
 #include "QIFileDialog.h"
@@ -1476,7 +1475,7 @@
     /* Check the standard image locations */
     if (QFile::exists(strSrc1))
-        return installGuestAdditionsFrom(strSrc1);
+        return uisession()->sltInstallGuestAdditionsFrom(strSrc1);
     else if (QFile::exists(strSrc2))
-        return installGuestAdditionsFrom(strSrc2);
+        return uisession()->sltInstallGuestAdditionsFrom(strSrc2);
 
     /* Check for the already registered image */
@@ -1491,8 +1490,7 @@
         QString fn = QFileInfo(path).fileName();
         if (RTPathCompare(name.toUtf8().constData(), fn.toUtf8().constData()) == 0)
-            return installGuestAdditionsFrom(path);
-    }
-
-#if 0 // TODO: Rework additions downloader logic...
+            return uisession()->sltInstallGuestAdditionsFrom(path);
+    }
+
     /* Download the required image */
     int result = vboxProblem().cannotFindGuestAdditions(QDir::toNativeSeparators(strSrc1), QDir::toNativeSeparators(strSrc2));
@@ -1502,9 +1500,20 @@
         QString target = QDir(vboxGlobal().virtualBox().GetHomeFolder()).absoluteFilePath(name);
 
-        //UIAdditionsDownloader *pdl = new UIAdditionsDownloader(source, target, mDevicesInstallGuestToolsAction);
-        //machineWindowWrapper()->statusBar()->addWidget(pdl, 0);
-        //pdl->start();
-    }
-#endif
+        UIDownloaderAdditions *pDl = UIDownloaderAdditions::create();
+        /* Configure the additions downloader. */
+        pDl->setSource(source);
+        pDl->setTarget(target);
+        pDl->setAction(actionsPool()->action(UIActionIndex_Simple_InstallGuestTools));
+        pDl->setParentWidget(mainMachineWindow()->machineWindow());
+        /* After the download is finished the user may like to install the
+         * additions.*/
+        connect(pDl, SIGNAL(downloadFinished(const QString&)),
+                uisession(), SLOT(sltInstallGuestAdditionsFrom(const QString&)));
+        /* Some of the modes may show additional info of the download progress. */
+        foreach (UIMachineWindow *pWindow, machineWindows())
+            pWindow->prepareAdditionsDownloader();
+        /* Start the download: */
+        pDl->startDownload();
+    }
 }
 
@@ -1597,82 +1606,4 @@
 }
 #endif /* Q_WS_MAC */
-
-void UIMachineLogic::installGuestAdditionsFrom(const QString &strSource)
-{
-    CMachine machine = session().GetMachine();
-    CVirtualBox vbox = vboxGlobal().virtualBox();
-    QString strUuid;
-
-    CMedium image = vbox.FindDVDImage(strSource);
-    if (image.isNull())
-    {
-        image = vbox.OpenDVDImage(strSource, strUuid);
-        if (vbox.isOk())
-            strUuid = image.GetId();
-    }
-    else
-        strUuid = image.GetId();
-
-    if (!vbox.isOk())
-    {
-        vboxProblem().cannotOpenMedium(0, vbox, VBoxDefs::MediumType_DVD, strSource);
-        return;
-    }
-
-    AssertMsg(!strUuid.isNull(), ("Guest Additions image UUID should be valid!\n"));
-
-    QString strCntName;
-    LONG iCntPort = -1, iCntDevice = -1;
-    /* Searching for the first suitable slot */
-    {
-        CStorageControllerVector controllers = machine.GetStorageControllers();
-        int i = 0;
-        while (i < controllers.size() && strCntName.isNull())
-        {
-            CStorageController controller = controllers[i];
-            CMediumAttachmentVector attachments = machine.GetMediumAttachmentsOfController(controller.GetName());
-            int j = 0;
-            while (j < attachments.size() && strCntName.isNull())
-            {
-                CMediumAttachment attachment = attachments[j];
-                if (attachment.GetType() == KDeviceType_DVD)
-                {
-                    strCntName = controller.GetName();
-                    iCntPort = attachment.GetPort();
-                    iCntDevice = attachment.GetDevice();
-                }
-                ++ j;
-            }
-            ++ i;
-        }
-    }
-
-    if (!strCntName.isNull())
-    {
-        bool fIsMounted = false;
-
-        /* Mount medium to the predefined port/device */
-        machine.MountMedium(strCntName, iCntPort, iCntDevice, strUuid, false /* force */);
-        if (machine.isOk())
-            fIsMounted = true;
-        else
-        {
-            /* Ask for force mounting */
-            if (vboxProblem().cannotRemountMedium(0, machine, VBoxMedium(image, VBoxDefs::MediumType_DVD),
-                                                  true /* mount? */, true /* retry? */) == QIMessageBox::Ok)
-            {
-                /* Force mount medium to the predefined port/device */
-                machine.MountMedium(strCntName, iCntPort, iCntDevice, strUuid, true /* force */);
-                if (machine.isOk())
-                    fIsMounted = true;
-                else
-                    vboxProblem().cannotRemountMedium(0, machine, VBoxMedium(image, VBoxDefs::MediumType_DVD),
-                                                      true /* mount? */, false /* retry? */);
-            }
-        }
-    }
-    else
-        vboxProblem().cannotMountGuestAdditions(machine.GetName());
-}
 
 int UIMachineLogic::searchMaxSnapshotIndex(const CMachine &machine,
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h	(revision 27374)
@@ -177,5 +177,4 @@
 
     /* Utility functions: */
-    void installGuestAdditionsFrom(const QString &strSource);
     static int searchMaxSnapshotIndex(const CMachine &machine,
                                       const CSnapshot &snapshot,
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp	(revision 27374)
@@ -357,4 +357,8 @@
     /* Machine state-change updater: */
     QObject::connect(uisession(), SIGNAL(sigMachineStateChange()), machineWindow(), SLOT(sltMachineStateChanged()));
+}
+
+void UIMachineWindow::prepareAdditionsDownloader()
+{
 }
 
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h	(revision 27374)
@@ -77,4 +77,5 @@
     virtual void prepareWindowIcon();
     virtual void prepareConsoleConnections();
+    virtual void prepareAdditionsDownloader();
     virtual void prepareMachineViewContainer();
     //virtual void loadWindowSettings() {}
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 27374)
@@ -728,4 +728,82 @@
 }
 
+void UISession::sltInstallGuestAdditionsFrom(const QString &strSource)
+{
+    CMachine machine = session().GetMachine();
+    CVirtualBox vbox = vboxGlobal().virtualBox();
+    QString strUuid;
+
+    CMedium image = vbox.FindDVDImage(strSource);
+    if (image.isNull())
+    {
+        image = vbox.OpenDVDImage(strSource, strUuid);
+        if (vbox.isOk())
+            strUuid = image.GetId();
+    }
+    else
+        strUuid = image.GetId();
+
+    if (!vbox.isOk())
+    {
+        vboxProblem().cannotOpenMedium(0, vbox, VBoxDefs::MediumType_DVD, strSource);
+        return;
+    }
+
+    AssertMsg(!strUuid.isNull(), ("Guest Additions image UUID should be valid!\n"));
+
+    QString strCntName;
+    LONG iCntPort = -1, iCntDevice = -1;
+    /* Searching for the first suitable slot */
+    {
+        CStorageControllerVector controllers = machine.GetStorageControllers();
+        int i = 0;
+        while (i < controllers.size() && strCntName.isNull())
+        {
+            CStorageController controller = controllers[i];
+            CMediumAttachmentVector attachments = machine.GetMediumAttachmentsOfController(controller.GetName());
+            int j = 0;
+            while (j < attachments.size() && strCntName.isNull())
+            {
+                CMediumAttachment attachment = attachments[j];
+                if (attachment.GetType() == KDeviceType_DVD)
+                {
+                    strCntName = controller.GetName();
+                    iCntPort = attachment.GetPort();
+                    iCntDevice = attachment.GetDevice();
+                }
+                ++ j;
+            }
+            ++ i;
+        }
+    }
+
+    if (!strCntName.isNull())
+    {
+        bool fIsMounted = false;
+
+        /* Mount medium to the predefined port/device */
+        machine.MountMedium(strCntName, iCntPort, iCntDevice, strUuid, false /* force */);
+        if (machine.isOk())
+            fIsMounted = true;
+        else
+        {
+            /* Ask for force mounting */
+            if (vboxProblem().cannotRemountMedium(0, machine, VBoxMedium(image, VBoxDefs::MediumType_DVD),
+                                                  true /* mount? */, true /* retry? */) == QIMessageBox::Ok)
+            {
+                /* Force mount medium to the predefined port/device */
+                machine.MountMedium(strCntName, iCntPort, iCntDevice, strUuid, true /* force */);
+                if (machine.isOk())
+                    fIsMounted = true;
+                else
+                    vboxProblem().cannotRemountMedium(0, machine, VBoxMedium(image, VBoxDefs::MediumType_DVD),
+                                                      true /* mount? */, false /* retry? */);
+            }
+        }
+    }
+    else
+        vboxProblem().cannotMountGuestAdditions(machine.GetName());
+}
+
 void UISession::sltCloseVirtualSession()
 {
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.h	(revision 27374)
@@ -37,7 +37,8 @@
 
 /* Local forwards */
-class UIMachine;
 class UIActionsPool;
 class UIConsoleCallback;
+class UIDownloaderAdditions;
+class UIMachine;
 class UIMachineMenuBar;
 
@@ -165,4 +166,8 @@
     void sigMouseCapturedStatusChanged();
 
+public slots:
+
+    void sltInstallGuestAdditionsFrom(const QString &strSource);
+
 private slots:
 
@@ -233,4 +238,6 @@
     bool m_fIsHidingHostPointer : 1;
 
+    UIDownloaderAdditions *m_pDownloaderAdditions;
+
     /* Friend classes: */
     friend class UIConsoleCallback;
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineLogicNormal.cpp	(revision 27374)
@@ -30,9 +30,10 @@
 #include "VBoxProblemReporter.h"
 
+#include "UIActionsPool.h"
+#include "UIDownloaderAdditions.h"
+#include "UIMachineLogicNormal.h"
+#include "UIMachineView.h"
+#include "UIMachineWindow.h"
 #include "UISession.h"
-#include "UIActionsPool.h"
-#include "UIMachineLogicNormal.h"
-#include "UIMachineWindow.h"
-#include "UIMachineView.h"
 
 #include "VBoxUtils.h"
@@ -65,4 +66,8 @@
     /* Prepare normal machine window: */
     prepareMachineWindows();
+
+    /* If there is an Additions download running show the process bar. */
+    if (UIDownloaderAdditions *pDl = UIDownloaderAdditions::current())
+        pDl->setParentWidget(mainMachineWindow()->machineWindow());
 
 #ifdef Q_WS_MAC
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp	(revision 27374)
@@ -31,10 +31,11 @@
 #include "VBoxGlobal.h"
 
-#include "UISession.h"
 #include "UIActionsPool.h"
+#include "UIDownloaderAdditions.h"
 #include "UIIndicatorsPool.h"
 #include "UIMachineLogic.h"
 #include "UIMachineView.h"
 #include "UIMachineWindowNormal.h"
+#include "UISession.h"
 
 #include "QIStatusBar.h"
@@ -416,4 +417,8 @@
     statusBar()->addPermanentWidget(pIndicatorBox, 0);
 
+    /* Add the additions downloader progress bar to the status bar, if a
+     * download is actually running. */
+    prepareAdditionsDownloader();
+
     /* Create & start timer to update LEDs: */
     m_pIdleTimer = new QTimer(this);
@@ -425,4 +430,11 @@
     setUnifiedTitleAndToolBarOnMac(true);
 #endif
+}
+
+void UIMachineWindowNormal::prepareAdditionsDownloader()
+{
+    /* If there is an Additions download running show the process bar. */
+    if (UIDownloaderAdditions *pDl = UIDownloaderAdditions::current())
+        statusBar()->addWidget(pDl->processWidget(this), 0);
 }
 
Index: trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h	(revision 27373)
+++ trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h	(revision 27374)
@@ -91,4 +91,5 @@
     void prepareMenu();
     void prepareStatusBar();
+    void prepareAdditionsDownloader();
     void prepareConnections();
     void prepareMachineView();
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.cpp	(revision 27374)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.cpp	(revision 27374)
@@ -0,0 +1,266 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIDownloader class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Local includes */
+#include "UIDownloader.h"
+#include "QIHttp.h"
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+
+/* Global includes */
+#include <QFile>
+#include <QProgressBar>
+
+UIMiniProcessWidget::UIMiniProcessWidget(QWidget *pParent /* = 0 */)
+    : QWidget(pParent)
+    , m_pProgressBar(new QProgressBar(this))
+    , m_pCancelButton(new QToolButton(this))
+{
+    /* Progress Bar setup */
+    m_pProgressBar->setFixedWidth(100);
+    m_pProgressBar->setFormat("%p%");
+    m_pProgressBar->setValue(0);
+
+    /* Cancel Button setup */
+    m_pCancelButton->setAutoRaise(true);
+    m_pCancelButton->setFocusPolicy(Qt::TabFocus);
+    connect(m_pCancelButton, SIGNAL(clicked()),
+            this, SIGNAL(sigCancel()));
+
+    /* Layout setup */
+    setFixedHeight(16);
+    QHBoxLayout *pMainLayout = new QHBoxLayout(this);
+    pMainLayout->setSpacing(0);
+    VBoxGlobal::setLayoutMargin(pMainLayout, 0);
+    pMainLayout->addWidget(m_pProgressBar);
+    pMainLayout->addWidget(m_pCancelButton);
+    pMainLayout->addStretch(1);
+}
+
+void UIMiniProcessWidget::setCancelButtonText(const QString &strText)
+{
+    m_pCancelButton->setText(strText);
+}
+
+QString UIMiniProcessWidget::cancelButtonText() const
+{
+    return m_pCancelButton->text();
+}
+
+void UIMiniProcessWidget::setCancelButtonToolTip(const QString &strText)
+{
+    m_pCancelButton->setToolTip(strText);
+}
+
+QString UIMiniProcessWidget::cancelButtonToolTip() const
+{
+    return m_pCancelButton->toolTip();
+}
+
+void UIMiniProcessWidget::setProgressBarToolTip(const QString &strText)
+{
+    m_pProgressBar->setToolTip(strText);
+}
+
+QString UIMiniProcessWidget::progressBarToolTip() const
+{
+    return m_pProgressBar->toolTip();
+}
+
+void UIMiniProcessWidget::setSource(const QString &strSource)
+{
+    m_strSource = strSource;
+}
+
+QString UIMiniProcessWidget::source() const
+{
+    return m_strSource;
+}
+
+void UIMiniProcessWidget::sltProcess(int cDone, int cTotal)
+{
+    m_pProgressBar->setMaximum(cTotal);
+    m_pProgressBar->setValue(cDone);
+}
+
+UIDownloader::UIDownloader()
+    : m_pHttp(0)
+{
+}
+
+void UIDownloader::setSource(const QString &strSource)
+{
+    m_source = strSource;
+}
+
+QString UIDownloader::source() const
+{
+    return m_source.toString();
+}
+
+void UIDownloader::setTarget(const QString &strTarget)
+{
+    m_strTarget = strTarget;
+}
+
+QString UIDownloader::target() const
+{
+    return m_strTarget;
+}
+
+void UIDownloader::startDownload()
+{
+    /* By default we are not using acknowledging step, so
+     * making downloading immediately */
+    downloadStart();
+}
+
+/* This function is used to start acknowledging mechanism:
+ * checking file presence & size */
+void UIDownloader::acknowledgeStart()
+{
+    delete m_pHttp;
+    m_pHttp = new QIHttp(this, m_source.host());
+    connect(m_pHttp, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
+            this, SLOT(acknowledgeProcess(const QHttpResponseHeader &)));
+    connect(m_pHttp, SIGNAL(allIsDone(bool)),
+            this, SLOT(acknowledgeFinished(bool)));
+    m_pHttp->get(m_source.toEncoded());
+}
+
+/* This function is used to store content length */
+void UIDownloader::acknowledgeProcess(const QHttpResponseHeader & /* response */)
+{
+    /* Abort connection as we already got all we need */
+    m_pHttp->abort();
+}
+
+/* This function is used to ask the user about if he really want
+ * to download file of proposed size if no error present or
+ * abort download progress if error is present */
+void UIDownloader::acknowledgeFinished(bool fError)
+{
+    NOREF(fError);
+
+    AssertMsg(fError, ("Error must be 'true' due to aborting.\n"));
+
+    m_pHttp->disconnect(this);
+
+    switch (m_pHttp->errorCode())
+    {
+        case QIHttp::Aborted:
+        {
+            /* Ask the user if he wish to download it */
+            if (confirmDownload())
+                QTimer::singleShot(0, this, SLOT(downloadStart()));
+            else
+                QTimer::singleShot(0, this, SLOT(suicide()));
+            break;
+        }
+        case QIHttp::MovedPermanentlyError:
+        case QIHttp::MovedTemporarilyError:
+        {
+            /* Restart downloading at new location */
+            m_source = m_pHttp->lastResponse().value("location");
+            QTimer::singleShot(0, this, SLOT(acknowledgeStart()));
+            break;
+        }
+        default:
+        {
+            /* Show error happens during acknowledging */
+            abortDownload(m_pHttp->errorString());
+            break;
+        }
+    }
+}
+
+/* This function is used to start downloading mechanism:
+ * downloading and saving the target */
+void UIDownloader::downloadStart()
+{
+    delete m_pHttp;
+    m_pHttp = new QIHttp(this, m_source.host());
+    connect(m_pHttp, SIGNAL(dataReadProgress (int, int)),
+            this, SLOT (downloadProcess(int, int)));
+    connect(m_pHttp, SIGNAL(allIsDone(bool)),
+            this, SLOT(downloadFinished(bool)));
+    m_pHttp->get(m_source.toEncoded());
+}
+
+/* this function is used to observe the downloading progress through
+ * changing the corresponding qprogressbar value */
+void UIDownloader::downloadProcess(int cDone, int cTotal)
+{
+    emit sigDownloadProcess(cDone, cTotal);
+}
+
+/* This function is used to handle the 'downloading finished' issue
+ * through saving the downloaded into the file if there in no error or
+ * notifying the user about error happens */
+void UIDownloader::downloadFinished(bool fError)
+{
+    m_pHttp->disconnect(this);
+
+    if (fError)
+    {
+        /* Show information about error happens */
+        if (m_pHttp->errorCode() == QIHttp::Aborted)
+            abortDownload(tr("The download process has been canceled by the user."));
+        else
+            abortDownload(m_pHttp->errorString());
+    }
+    else
+    {
+        /* Trying to serialize the incoming buffer into the target, this is the
+         * default behavior which have to be reimplemented in sub-class */
+        QFile file(m_strTarget);
+        if (file.open(QIODevice::WriteOnly))
+        {
+            file.write(m_pHttp->readAll());
+            file.close();
+        }
+        QTimer::singleShot(0, this, SLOT(suicide()));
+    }
+}
+
+/* This slot is used to process cancel-button clicking */
+void UIDownloader::cancelDownloading()
+{
+    QTimer::singleShot(0, this, SLOT(suicide()));
+}
+
+/* This function is used to abort download by showing aborting reason
+ * and calling the downloader's delete function */
+void UIDownloader::abortDownload(const QString &strError)
+{
+    warnAboutError(strError);
+    QTimer::singleShot(0, this, SLOT(suicide()));
+}
+
+/* This function is used to delete the downloader widget itself,
+ * should be reimplemented to enhance necessary functionality in sub-class */
+void UIDownloader::suicide()
+{
+    delete this;
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.h	(revision 27374)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloader.h	(revision 27374)
@@ -0,0 +1,135 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIDownloader class declaration
+ */
+
+/*
+ * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __UIDownloader_h__
+#define __UIDownloader_h__
+
+/* Global includes */
+#include <QUrl>
+#include <QWidget>
+
+/* Global forward declarations */
+class QIHttp;
+class QHttpResponseHeader;
+class QProgressBar;
+class QToolButton;
+
+class UIMiniProcessWidget : public QWidget
+{
+    Q_OBJECT;
+
+public:
+
+    UIMiniProcessWidget(QWidget *pParent = 0);
+
+    void setCancelButtonText(const QString &strText);
+    QString cancelButtonText() const;
+
+    void setCancelButtonToolTip(const QString &strText);
+    QString cancelButtonToolTip() const;
+
+    void setProgressBarToolTip(const QString &strText);
+    QString progressBarToolTip() const;
+
+    void setSource(const QString &strSource);
+    QString source() const;
+
+signals:
+
+    void sigCancel();
+
+public slots:
+
+    virtual void sltProcess(int cDone, int cTotal);
+
+private:
+
+    /* Private member vars */
+    QProgressBar *m_pProgressBar;
+    QToolButton *m_pCancelButton;
+    QString m_strSource;
+};
+
+/**
+ * The UIDownloader class is QWidget class re-implementation which embeds
+ * into the Dialog's status-bar and allows background http downloading.
+ * This class is not supposed to be used itself and made for sub-classing only.
+ *
+ * This class has two parts:
+ * 1. Acknowledging (getting information about target presence and size).
+ * 2. Downloading (starting and handling file downloading process).
+ * Every subclass can determine using or not those two parts and handling
+ * the result of those parts itself.
+ */
+class UIDownloader : public QObject
+{
+    Q_OBJECT;
+
+public:
+
+    UIDownloader();
+
+    void setSource(const QString &strSource);
+    QString source() const;
+    void setTarget(const QString &strTarget);
+    QString target() const;
+
+    virtual void startDownload() = 0;
+
+signals:
+    void sigDownloadProcess(int cDone, int cTotal);
+    void sigFinished();
+
+protected slots:
+
+    /* Acknowledging part */
+    virtual void acknowledgeStart();
+    virtual void acknowledgeProcess(const QHttpResponseHeader &response);
+    virtual void acknowledgeFinished(bool fError);
+
+    /* Downloading part */
+    virtual void downloadStart();
+    virtual void downloadProcess(int cDone, int cTotal);
+    virtual void downloadFinished(bool fError);
+
+    /* Common slots */
+    virtual void cancelDownloading();
+    virtual void abortDownload(const QString &strError);
+    virtual void suicide();
+
+protected:
+
+    /* In sub-class this function will show the user downloading object size
+     * and ask him about downloading confirmation. Returns user response. */
+    virtual bool confirmDownload() = 0;
+
+    /* In sub-class this function will show the user which error happens
+     * in context of downloading file and executing his request. */
+    virtual void warnAboutError(const QString &strError) = 0;
+
+    QUrl m_source;
+    QString m_strTarget;
+    QIHttp *m_pHttp;
+};
+
+#endif // __UIDownloader_h__
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.cpp	(revision 27374)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.cpp	(revision 27374)
@@ -0,0 +1,163 @@
+/* $Id$ */
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIDownloaderAdditions class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+/* Local includes */
+#include "UIDownloaderAdditions.h"
+#include "QIFileDialog.h"
+#include "QIHttp.h"
+#include "VBoxProblemReporter.h"
+
+/* Global includes */
+#include <QAction>
+#include <QDir>
+#include <QFile>
+UIDownloaderAdditions *UIDownloaderAdditions::m_pInstance = 0;
+
+UIDownloaderAdditions *UIDownloaderAdditions::create()
+{
+    if (!m_pInstance)
+        m_pInstance = new UIDownloaderAdditions;
+
+    return m_pInstance;
+}
+
+UIDownloaderAdditions *UIDownloaderAdditions::current()
+{
+    return m_pInstance;
+}
+
+void UIDownloaderAdditions::destroy()
+{
+    if (m_pInstance)
+        delete m_pInstance;
+    m_pInstance = 0;
+}
+
+void UIDownloaderAdditions::setAction(QAction *pAction)
+{
+    m_pAction = pAction;
+    if (m_pAction)
+        m_pAction->setEnabled(false);
+}
+
+QAction *UIDownloaderAdditions::action() const
+{
+    return m_pAction;
+}
+
+void UIDownloaderAdditions::setParentWidget(QWidget *pParent)
+{
+    m_pParent = pParent;
+}
+
+QWidget *UIDownloaderAdditions::parentWidget() const
+{
+    return m_pParent;
+}
+
+UIMiniProcessWidgetAdditions* UIDownloaderAdditions::processWidget(QWidget *pParent /* = 0 */) const
+{
+    UIMiniProcessWidgetAdditions *pWidget = new UIMiniProcessWidgetAdditions(m_source.toString(), pParent);
+
+    /* Connect the cancel signal. */
+    connect(pWidget, SIGNAL(sigCancel()),
+            this, SLOT(cancelDownloading()));
+    /* Connect the signal to notify about the download process. */
+    connect(this, SIGNAL(sigDownloadProcess(int, int)),
+            pWidget, SLOT(sltProcess(int, int)));
+    /* Make sure the widget is destroyed when this class is deleted. */
+    connect(this, SIGNAL(destroyed(QObject*)),
+            pWidget, SLOT(close()));
+
+    return pWidget;
+}
+
+void UIDownloaderAdditions::startDownload()
+{
+    acknowledgeStart();
+}
+
+void UIDownloaderAdditions::downloadFinished(bool fError)
+{
+    if (fError)
+        UIDownloader::downloadFinished(fError);
+    else
+    {
+        QByteArray receivedData(m_pHttp->readAll());
+        /* Serialize the incoming buffer into the .iso image. */
+        while (true)
+        {
+            QFile file(m_strTarget);
+            if (file.open(QIODevice::WriteOnly))
+            {
+                file.write(receivedData);
+                file.close();
+                if (vboxProblem().confirmMountAdditions(m_source.toString(),
+                                                        QDir::toNativeSeparators(m_strTarget)))
+                    emit downloadFinished(m_strTarget);
+                QTimer::singleShot(0, this, SLOT(suicide()));
+                break;
+            }
+            else
+            {
+                vboxProblem().message(m_pParent, VBoxProblemReporter::Error,
+                                      tr("<p>Failed to save the downloaded file as "
+                                         "<nobr><b>%1</b>.</nobr></p>")
+                                      .arg(QDir::toNativeSeparators(m_strTarget)));
+            }
+
+            QString target = QIFileDialog::getExistingDirectory(QFileInfo(m_strTarget).absolutePath(), m_pParent,
+                                                                tr("Select folder to save Guest Additions image to"), true);
+            if (target.isNull())
+                QTimer::singleShot(0, this, SLOT(suicide()));
+            else
+                m_strTarget = QDir(target).absoluteFilePath(QFileInfo(m_strTarget).fileName());
+        }
+    }
+}
+
+void UIDownloaderAdditions::suicide()
+{
+    if (m_pAction)
+        m_pAction->setEnabled(true);
+    UIDownloaderAdditions::destroy();
+}
+
+UIDownloaderAdditions::UIDownloaderAdditions()
+    : UIDownloader()
+    , m_pAction(0)
+    , m_pParent(0)
+{
+}
+
+bool UIDownloaderAdditions::confirmDownload()
+{
+    return vboxProblem().confirmDownloadAdditions(m_source.toString(),
+                                                  m_pHttp->lastResponse().contentLength());
+}
+
+void UIDownloaderAdditions::warnAboutError(const QString &strError)
+{
+    return vboxProblem().cannotDownloadGuestAdditions(m_source.toString(), strError);
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.h	(revision 27374)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIDownloaderAdditions.h	(revision 27374)
@@ -0,0 +1,103 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * UIDownloaderAdditions class declaration
+ */
+
+/*
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+#ifndef __UIDownloaderAdditions_h__
+#define __UIDownloaderAdditions_h__
+
+/* Local includes */
+#include "QIWithRetranslateUI.h"
+#include "UIDownloader.h"
+
+/* Global includes */
+#include <QPointer>
+
+class UIMiniProcessWidgetAdditions : public QIWithRetranslateUI<UIMiniProcessWidget>
+{
+    Q_OBJECT;
+
+public:
+
+    UIMiniProcessWidgetAdditions(const QString &strSource, QWidget *pParent = 0)
+      : QIWithRetranslateUI<UIMiniProcessWidget>(pParent)
+    {
+        setSource(strSource);
+        retranslateUi();
+    }
+
+protected:
+
+    void retranslateUi()
+    {
+        setCancelButtonText(tr("Cancel"));
+        setCancelButtonToolTip(tr("Cancel the VirtualBox Guest "
+                                  "Additions CD image download"));
+        setProgressBarToolTip((tr("Downloading the VirtualBox Guest Additions "
+                                  "CD image from <nobr><b>%1</b>...</nobr>")
+                               .arg(source())));
+    }
+};
+
+class UIDownloaderAdditions : public UIDownloader
+{
+    Q_OBJECT;
+
+public:
+    static UIDownloaderAdditions* create();
+    static UIDownloaderAdditions* current();
+    static void destroy();
+
+    void setAction(QAction *pAction);
+    QAction *action() const;
+
+    void setParentWidget(QWidget *pParent);
+    QWidget *parentWidget() const;
+
+    UIMiniProcessWidgetAdditions* processWidget(QWidget *pParent = 0) const;
+    void startDownload();
+
+signals:
+    void downloadFinished(const QString &strFile);
+
+private slots:
+
+    void downloadFinished(bool fError);
+    void suicide();
+
+private:
+
+    UIDownloaderAdditions();
+
+    bool confirmDownload();
+    void warnAboutError(const QString &strError);
+
+    /* Private member vars */
+    static UIDownloaderAdditions *m_pInstance;
+
+    /* We use QPointer here, cause these items could be deleted in the life of
+     * this object. QPointer guarantees that the ptr itself is zero in that
+     * case. */
+    QPointer<QAction> m_pAction;
+    QPointer<QWidget> m_pParent;
+};
+
+#endif // __UIDownloaderAdditions_h__
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxDownloaderWgt.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxDownloaderWgt.cpp	(revision 27373)
+++ 	(revision )
@@ -1,194 +1,0 @@
-/* $Id$ */
-/** @file
- *
- * VBox frontends: Qt GUI ("VirtualBox"):
- * VBoxDownloaderWgt class implementation
- */
-
-/*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
- */
-
-#include "QIHttp.h"
-#include "VBoxDownloaderWgt.h"
-#include "VBoxGlobal.h"
-
-/* Qt includes */
-#include <QFile>
-#include <QHBoxLayout>
-#include <QHttpResponseHeader>
-#include <QProgressBar>
-#include <QToolButton>
-
-VBoxDownloaderWgt::VBoxDownloaderWgt (const QString &aSource, const QString &aTarget)
-    : mSource (aSource), mTarget (aTarget), mHttp (0)
-    , mProgressBar (new QProgressBar (this))
-    , mCancelButton (new QToolButton (this))
-{
-    /* Progress Bar setup */
-    mProgressBar->setFixedWidth (100);
-    mProgressBar->setFormat ("%p%");
-    mProgressBar->setValue (0);
-
-    /* Cancel Button setup */
-    mCancelButton->setAutoRaise (true);
-    mCancelButton->setFocusPolicy (Qt::TabFocus);
-    connect (mCancelButton, SIGNAL (clicked()), this, SLOT (cancelDownloading()));
-
-    /* Downloader setup */
-    setFixedHeight (16);
-    QHBoxLayout *mainLayout = new QHBoxLayout (this);
-    mainLayout->setSpacing (0);
-    VBoxGlobal::setLayoutMargin (mainLayout, 0);
-    mainLayout->addWidget (mProgressBar);
-    mainLayout->addWidget (mCancelButton);
-    mainLayout->addStretch (1);
-}
-
-void VBoxDownloaderWgt::start()
-{
-    /* By default we are not using acknowledging step, so
-     * making downloading immediately */
-    downloadStart();
-}
-
-/* This function is used to start acknowledging mechanism:
- * checking file presence & size */
-void VBoxDownloaderWgt::acknowledgeStart()
-{
-    delete mHttp;
-    mHttp = new QIHttp (this, mSource.host());
-    connect (mHttp, SIGNAL (responseHeaderReceived (const QHttpResponseHeader &)),
-             this, SLOT (acknowledgeProcess (const QHttpResponseHeader &)));
-    connect (mHttp, SIGNAL (allIsDone (bool)), this, SLOT (acknowledgeFinished (bool)));
-    mHttp->get (mSource.toEncoded());
-}
-
-/* This function is used to store content length */
-void VBoxDownloaderWgt::acknowledgeProcess (const QHttpResponseHeader & /* aResponse */)
-{
-    /* Abort connection as we already got all we need */
-    mHttp->abort();
-}
-
-/* This function is used to ask the user about if he really want
- * to download file of proposed size if no error present or
- * abort download progress if error is present */
-void VBoxDownloaderWgt::acknowledgeFinished (bool aError)
-{
-    NOREF(aError);
-
-    AssertMsg (aError, ("Error must be 'true' due to aborting.\n"));
-
-    mHttp->disconnect (this);
-
-    switch (mHttp->errorCode())
-    {
-        case QIHttp::Aborted:
-        {
-            /* Ask the user if he wish to download it */
-            if (confirmDownload())
-                QTimer::singleShot (0, this, SLOT (downloadStart()));
-            else
-                QTimer::singleShot (0, this, SLOT (suicide()));
-            break;
-        }
-        case QIHttp::MovedPermanentlyError:
-        case QIHttp::MovedTemporarilyError:
-        {
-            /* Restart downloading at new location */
-            mSource = mHttp->lastResponse().value ("location");
-            QTimer::singleShot (0, this, SLOT (acknowledgeStart()));
-            break;
-        }
-        default:
-        {
-            /* Show error happens during acknowledging */
-            abortDownload (mHttp->errorString());
-            break;
-        }
-    }
-}
-
-/* This function is used to start downloading mechanism:
- * downloading and saving the target */
-void VBoxDownloaderWgt::downloadStart()
-{
-    delete mHttp;
-    mHttp = new QIHttp (this, mSource.host());
-    connect (mHttp, SIGNAL (dataReadProgress (int, int)),
-             this, SLOT (downloadProcess (int, int)));
-    connect (mHttp, SIGNAL (allIsDone (bool)), this, SLOT (downloadFinished (bool)));
-    mHttp->get (mSource.toEncoded());
-}
-
-/* this function is used to observe the downloading progress through
- * changing the corresponding qprogressbar value */
-void VBoxDownloaderWgt::downloadProcess (int aDone, int aTotal)
-{
-    mProgressBar->setMaximum (aTotal);
-    mProgressBar->setValue (aDone);
-}
-
-/* This function is used to handle the 'downloading finished' issue
- * through saving the downloaded into the file if there in no error or
- * notifying the user about error happens */
-void VBoxDownloaderWgt::downloadFinished (bool aError)
-{
-    mHttp->disconnect (this);
-
-    if (aError)
-    {
-        /* Show information about error happens */
-        if (mHttp->errorCode() == QIHttp::Aborted)
-            abortDownload (tr ("The download process has been cancelled by the user."));
-        else
-            abortDownload (mHttp->errorString());
-    }
-    else
-    {
-        /* Trying to serialize the incoming buffer into the target, this is the
-         * default behavior which have to be reimplemented in sub-class */
-        QFile file (mTarget);
-        if (file.open (QIODevice::WriteOnly))
-        {
-            file.write (mHttp->readAll());
-            file.close();
-        }
-        QTimer::singleShot (0, this, SLOT (suicide()));
-    }
-}
-
-/* This slot is used to process cancel-button clicking */
-void VBoxDownloaderWgt::cancelDownloading()
-{
-    QTimer::singleShot (0, this, SLOT (suicide()));
-}
-
-/* This function is used to abort download by showing aborting reason
- * and calling the downloader's delete function */
-void VBoxDownloaderWgt::abortDownload (const QString &aError)
-{
-    warnAboutError (aError);
-    QTimer::singleShot (0, this, SLOT (suicide()));
-}
-
-/* This function is used to delete the downloader widget itself,
- * should be reimplemented to enhanse necessary functionality in sub-class */
-void VBoxDownloaderWgt::suicide()
-{
-    delete this;
-}
-
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxDownloaderWgt.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxDownloaderWgt.h	(revision 27373)
+++ 	(revision )
@@ -1,93 +1,0 @@
-/** @file
- *
- * VBox frontends: Qt GUI ("VirtualBox"):
- * VBoxDownloaderWgt class declaration
- */
-
-/*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
- * Clara, CA 95054 USA or visit http://www.sun.com if you need
- * additional information or have any questions.
- */
-
-#ifndef __VBoxDownloaderWgt_h__
-#define __VBoxDownloaderWgt_h__
-
-#include "QIWithRetranslateUI.h"
-
-/* Qt includes */
-#include <QUrl>
-#include <QWidget>
-
-class QIHttp;
-class QHttpResponseHeader;
-class QProgressBar;
-class QToolButton;
-
-/**
- * The VBoxDownloaderWgt class is QWidget class re-implementation which embeds
- * into the Dialog's status-bar and allows background http downloading.
- * This class is not supposed to be used itself and made for sub-classing only.
- *
- * This class has two parts:
- * 1. Acknowledging (getting information about target presence and size).
- * 2. Downloading (starting and handling file downloading process).
- * Every subclass can determine using or not those two parts and handling
- * the result of those parts itself.
- */
-class VBoxDownloaderWgt : public QIWithRetranslateUI <QWidget>
-{
-    Q_OBJECT;
-
-public:
-
-    VBoxDownloaderWgt (const QString &aSource, const QString &aTarget);
-
-    virtual void start();
-
-protected slots:
-
-    /* Acknowledging part */
-    virtual void acknowledgeStart();
-    virtual void acknowledgeProcess (const QHttpResponseHeader &aResponse);
-    virtual void acknowledgeFinished (bool aError);
-
-    /* Downloading part */
-    virtual void downloadStart();
-    virtual void downloadProcess (int aDone, int aTotal);
-    virtual void downloadFinished (bool aError);
-
-    /* Common slots */
-    virtual void cancelDownloading();
-    virtual void abortDownload (const QString &aError);
-    virtual void suicide();
-
-protected:
-
-    /* In sub-class this function will show the user downloading object size
-     * and ask him about downloading confirmation. Returns user response. */
-    virtual bool confirmDownload() = 0;
-
-    /* In sub-class this function will show the user which error happens
-     * in context of downloading file and executing his request. */
-    virtual void warnAboutError (const QString &aError) = 0;
-
-    QUrl mSource;
-    QString mTarget;
-    QIHttp *mHttp;
-    QProgressBar *mProgressBar;
-    QToolButton *mCancelButton;
-};
-
-#endif // __VBoxDownloaderWgt_h__
-
