Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.cpp	(revision 25178)
@@ -0,0 +1,1058 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxApplianceEditorWgt class implementation
+ */
+
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* VBox includes */
+#include "VBoxApplianceEditorWgt.h"
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+#include "VBoxOSTypeSelectorButton.h"
+#include "VBoxLineTextEdit.h"
+
+/* Qt includes */
+#include <QItemDelegate>
+#include <QSortFilterProxyModel>
+#include <QHeaderView>
+#include <QLineEdit>
+#include <QTextEdit>
+#include <QSpinBox>
+#include <QComboBox>
+
+////////////////////////////////////////////////////////////////////////////////
+// ModelItem
+
+/* This & the following derived classes represent the data items of a Virtual
+   System. All access/manipulation is done with the help of virtual functions
+   to keep the interface clean. ModelItem is able to handle tree structures
+   with a parent & several children's. */
+ModelItem::ModelItem (int aNumber, ModelItemType aType, ModelItem *aParent /* = NULL */)
+  : mNumber (aNumber)
+  , mType (aType)
+  , mParentItem (aParent)
+{}
+
+ModelItem::~ModelItem()
+{
+    qDeleteAll (mChildItems);
+}
+
+void ModelItem::appendChild (ModelItem *aChild)
+{
+    AssertPtr (aChild);
+    mChildItems << aChild;
+}
+
+ModelItem * ModelItem::child (int aRow) const
+{
+    return mChildItems.value (aRow);
+}
+
+int ModelItem::row() const
+{
+    if (mParentItem)
+        return mParentItem->mChildItems.indexOf (const_cast<ModelItem*> (this));
+
+    return 0;
+}
+
+int ModelItem::childCount() const
+{
+    return mChildItems.count();
+}
+
+void ModelItem::putBack (QVector<BOOL>& aFinalStates, QVector<QString>& aFinalValues, QVector<QString>& aFinalExtraValues)
+{
+    for (int i = 0; i < childCount(); ++i)
+        child (i)->putBack (aFinalStates, aFinalValues, aFinalExtraValues);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// VirtualSystemItem
+
+VirtualSystemItem::VirtualSystemItem (int aNumber, CVirtualSystemDescription aDesc, ModelItem *aParent)
+  : ModelItem (aNumber, VirtualSystemType, aParent)
+  , mDesc (aDesc)
+{}
+
+QVariant VirtualSystemItem::data (int aColumn, int aRole) const
+{
+    QVariant v;
+    if (aColumn == DescriptionSection &&
+        aRole == Qt::DisplayRole)
+        v = VBoxApplianceEditorWgt::tr ("Virtual System %1").arg (mNumber + 1);
+    return v;
+}
+
+void VirtualSystemItem::putBack (QVector<BOOL>& aFinalStates, QVector<QString>& aFinalValues, QVector<QString>& aFinalExtraValues)
+{
+    /* Resize the vectors */
+    unsigned long count = mDesc.GetCount();
+    aFinalStates.resize (count);
+    aFinalValues.resize (count);
+    aFinalExtraValues.resize (count);
+    /* Recursively fill the vectors */
+    ModelItem::putBack (aFinalStates, aFinalValues, aFinalExtraValues);
+    /* Set all final values at once */
+    mDesc.SetFinalValues (aFinalStates, aFinalValues, aFinalExtraValues);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// HardwareItem
+
+HardwareItem::HardwareItem (int aNumber,
+                            KVirtualSystemDescriptionType aType,
+                            const QString &aRef,
+                            const QString &aOrigValue,
+                            const QString &aConfigValue,
+                            const QString &aExtraConfigValue,
+                            ModelItem *aParent)
+  : ModelItem (aNumber, HardwareType, aParent)
+  , mType (aType)
+  , mRef (aRef)
+  , mOrigValue (aOrigValue)
+  , mConfigValue (aConfigValue)
+  , mConfigDefaultValue (aConfigValue)
+  , mExtraConfigValue (aExtraConfigValue)
+  , mCheckState (Qt::Checked)
+{}
+
+void HardwareItem::putBack (QVector<BOOL>& aFinalStates, QVector<QString>& aFinalValues, QVector<QString>& aFinalExtraValues)
+{
+    aFinalStates[mNumber] = mCheckState == Qt::Checked;
+    aFinalValues[mNumber] = mConfigValue;
+    aFinalExtraValues[mNumber] = mExtraConfigValue;
+    ModelItem::putBack (aFinalStates, aFinalValues, aFinalExtraValues);
+}
+
+bool HardwareItem::setData (int aColumn, const QVariant &aValue, int aRole)
+{
+    bool fDone = false;
+    switch (aRole)
+    {
+        case Qt::CheckStateRole:
+            {
+                if (aColumn == ConfigValueSection &&
+                    (mType == KVirtualSystemDescriptionType_Floppy ||
+                     mType == KVirtualSystemDescriptionType_CDROM ||
+                     mType == KVirtualSystemDescriptionType_USBController ||
+                     mType == KVirtualSystemDescriptionType_SoundCard ||
+                     mType == KVirtualSystemDescriptionType_NetworkAdapter))
+                {
+                    mCheckState = static_cast<Qt::CheckState> (aValue.toInt());
+                    fDone = true;
+                }
+                break;
+            }
+        default: break;
+    }
+    return fDone;
+}
+
+QVariant HardwareItem::data (int aColumn, int aRole) const
+{
+    QVariant v;
+    switch (aRole)
+    {
+        case Qt::DisplayRole:
+            {
+                if (aColumn == DescriptionSection)
+                {
+                    switch (mType)
+                    {
+                        case KVirtualSystemDescriptionType_Name: v = VBoxApplianceEditorWgt::tr ("Name"); break;
+                        case KVirtualSystemDescriptionType_Product: v = VBoxApplianceEditorWgt::tr ("Product"); break;
+                        case KVirtualSystemDescriptionType_ProductUrl: v = VBoxApplianceEditorWgt::tr ("Product-URL"); break;
+                        case KVirtualSystemDescriptionType_Vendor: v = VBoxApplianceEditorWgt::tr ("Vendor"); break;
+                        case KVirtualSystemDescriptionType_VendorUrl: v = VBoxApplianceEditorWgt::tr ("Vendor-URL"); break;
+                        case KVirtualSystemDescriptionType_Version: v = VBoxApplianceEditorWgt::tr ("Version"); break;
+                        case KVirtualSystemDescriptionType_Description: v = VBoxApplianceEditorWgt::tr ("Description"); break;
+                        case KVirtualSystemDescriptionType_License: v = VBoxApplianceEditorWgt::tr ("License"); break;
+                        case KVirtualSystemDescriptionType_OS: v = VBoxApplianceEditorWgt::tr ("Guest OS Type"); break;
+                        case KVirtualSystemDescriptionType_CPU: v = VBoxApplianceEditorWgt::tr ("CPU"); break;
+                        case KVirtualSystemDescriptionType_Memory: v = VBoxApplianceEditorWgt::tr ("RAM"); break;
+                        case KVirtualSystemDescriptionType_HardDiskControllerIDE: v = VBoxApplianceEditorWgt::tr ("Hard Disk Controller (IDE)"); break;
+                        case KVirtualSystemDescriptionType_HardDiskControllerSATA: v = VBoxApplianceEditorWgt::tr ("Hard Disk Controller (SATA)"); break;
+                        case KVirtualSystemDescriptionType_HardDiskControllerSCSI: v = VBoxApplianceEditorWgt::tr ("Hard Disk Controller (SCSI)"); break;
+                        case KVirtualSystemDescriptionType_CDROM: v = VBoxApplianceEditorWgt::tr ("DVD"); break;
+                        case KVirtualSystemDescriptionType_Floppy: v = VBoxApplianceEditorWgt::tr ("Floppy"); break;
+                        case KVirtualSystemDescriptionType_NetworkAdapter: v = VBoxApplianceEditorWgt::tr ("Network Adapter"); break;
+                        case KVirtualSystemDescriptionType_USBController: v = VBoxApplianceEditorWgt::tr ("USB Controller"); break;
+                        case KVirtualSystemDescriptionType_SoundCard: v = VBoxApplianceEditorWgt::tr ("Sound Card"); break;
+                        case KVirtualSystemDescriptionType_HardDiskImage: v = VBoxApplianceEditorWgt::tr ("Virtual Disk Image"); break;
+                        default: v = VBoxApplianceEditorWgt::tr ("Unknown Hardware Item"); break;
+                    }
+                }
+                else if (aColumn == OriginalValueSection)
+                    v = mOrigValue;
+                else if (aColumn == ConfigValueSection)
+                {
+                    switch (mType)
+                    {
+                        case KVirtualSystemDescriptionType_Description:
+                        case KVirtualSystemDescriptionType_License:
+                            {
+                                /* Shorten the big text if there is more than
+                                 * one line */
+                                QString tmp (mConfigValue);
+                                int i = tmp.indexOf ('\n');
+                                if (i > -1)
+                                    tmp.replace (i, tmp.length(), "...");
+                                v = tmp; break;
+                            }
+                        case KVirtualSystemDescriptionType_OS: v = vboxGlobal().vmGuestOSTypeDescription (mConfigValue); break;
+                        case KVirtualSystemDescriptionType_Memory: v = mConfigValue + " " + VBoxApplianceEditorWgt::tr ("MB"); break;
+                        case KVirtualSystemDescriptionType_SoundCard: v = vboxGlobal().toString (static_cast<KAudioControllerType> (mConfigValue.toInt())); break;
+                        case KVirtualSystemDescriptionType_NetworkAdapter: v = vboxGlobal().toString (static_cast<KNetworkAdapterType> (mConfigValue.toInt())); break;
+                        default: v = mConfigValue; break;
+                    }
+                }
+                break;
+            }
+        case Qt::ToolTipRole:
+            {
+                if (aColumn == ConfigValueSection)
+                {
+                    if (!mOrigValue.isEmpty())
+                        v = VBoxApplianceEditorWgt::tr ("<b>Original Value:</b> %1").arg (mOrigValue);
+                }
+                break;
+            }
+        case Qt::DecorationRole:
+            {
+                if (aColumn == DescriptionSection)
+                {
+                    switch (mType)
+                    {
+                        case KVirtualSystemDescriptionType_Name: v = QIcon (":/name_16px.png"); break;
+                        case KVirtualSystemDescriptionType_Product:
+                        case KVirtualSystemDescriptionType_ProductUrl:
+                        case KVirtualSystemDescriptionType_Vendor:
+                        case KVirtualSystemDescriptionType_VendorUrl:
+                        case KVirtualSystemDescriptionType_Version:
+                        case KVirtualSystemDescriptionType_Description:
+                        case KVirtualSystemDescriptionType_License: v = QIcon (":/description_16px.png"); break;
+                        case KVirtualSystemDescriptionType_OS: v = QIcon (":/os_type_16px.png"); break;
+                        case KVirtualSystemDescriptionType_CPU: v = QIcon (":/cpu_16px.png"); break;
+                        case KVirtualSystemDescriptionType_Memory: v = QIcon (":/ram_16px.png"); break;
+                        case KVirtualSystemDescriptionType_HardDiskControllerIDE: v = QIcon (":/ide_16px.png"); break;
+                        case KVirtualSystemDescriptionType_HardDiskControllerSATA: v = QIcon (":/sata_16px.png"); break;
+                        case KVirtualSystemDescriptionType_HardDiskControllerSCSI: v = QIcon (":/scsi_16px.png"); break;
+                        case KVirtualSystemDescriptionType_HardDiskImage: v = QIcon (":/hd_16px.png"); break;
+                        case KVirtualSystemDescriptionType_CDROM: v = QIcon (":/cd_16px.png"); break;
+                        case KVirtualSystemDescriptionType_Floppy: v = QIcon (":/fd_16px.png"); break;
+                        case KVirtualSystemDescriptionType_NetworkAdapter: v = QIcon (":/nw_16px.png"); break;
+                        case KVirtualSystemDescriptionType_USBController: v = QIcon (":/usb_16px.png"); break;
+                        case KVirtualSystemDescriptionType_SoundCard: v = QIcon (":/sound_16px.png"); break;
+                        default: break;
+                    }
+                }
+                else if (aColumn == ConfigValueSection &&
+                         mType == KVirtualSystemDescriptionType_OS)
+                {
+                    v = vboxGlobal().vmGuestOSTypeIcon (mConfigValue).scaledToHeight (16, Qt::SmoothTransformation);
+                }
+                break;
+            }
+        case Qt::FontRole:
+            {
+                /* If the item is unchecked mark it with italic text. */
+                if (aColumn == ConfigValueSection &&
+                    mCheckState == Qt::Unchecked)
+                {
+                    QFont font = qApp->font();
+                    font.setItalic (true);
+                    v = font;
+                }
+                break;
+            }
+        case Qt::ForegroundRole:
+            {
+                /* If the item is unchecked mark it with gray text. */
+                if (aColumn == ConfigValueSection &&
+                    mCheckState == Qt::Unchecked)
+                {
+                    QPalette pal = qApp->palette();
+                    v = pal.brush (QPalette::Disabled, QPalette::WindowText);
+                }
+                break;
+            }
+        case Qt::CheckStateRole:
+            {
+                if (aColumn == ConfigValueSection &&
+                    (mType == KVirtualSystemDescriptionType_Floppy ||
+                     mType == KVirtualSystemDescriptionType_CDROM ||
+                     mType == KVirtualSystemDescriptionType_USBController ||
+                     mType == KVirtualSystemDescriptionType_SoundCard ||
+                     mType == KVirtualSystemDescriptionType_NetworkAdapter))
+                    v = mCheckState;
+                break;
+            }
+    }
+    return v;
+}
+
+Qt::ItemFlags HardwareItem::itemFlags (int aColumn) const
+{
+    Qt::ItemFlags flags = 0;
+    if (aColumn == ConfigValueSection)
+    {
+        /* Some items are checkable */
+        if (mType == KVirtualSystemDescriptionType_Floppy ||
+            mType == KVirtualSystemDescriptionType_CDROM ||
+            mType == KVirtualSystemDescriptionType_USBController ||
+            mType == KVirtualSystemDescriptionType_SoundCard ||
+            mType == KVirtualSystemDescriptionType_NetworkAdapter)
+            flags |= Qt::ItemIsUserCheckable;
+        /* Some items are editable */
+        if ((mType == KVirtualSystemDescriptionType_Name ||
+             mType == KVirtualSystemDescriptionType_Product ||
+             mType == KVirtualSystemDescriptionType_ProductUrl ||
+             mType == KVirtualSystemDescriptionType_Vendor ||
+             mType == KVirtualSystemDescriptionType_VendorUrl ||
+             mType == KVirtualSystemDescriptionType_Version ||
+             mType == KVirtualSystemDescriptionType_Description ||
+             mType == KVirtualSystemDescriptionType_License ||
+             mType == KVirtualSystemDescriptionType_OS ||
+             mType == KVirtualSystemDescriptionType_CPU ||
+             mType == KVirtualSystemDescriptionType_Memory ||
+             mType == KVirtualSystemDescriptionType_SoundCard ||
+             mType == KVirtualSystemDescriptionType_NetworkAdapter ||
+             mType == KVirtualSystemDescriptionType_HardDiskControllerIDE ||
+             mType == KVirtualSystemDescriptionType_HardDiskImage) &&
+            mCheckState == Qt::Checked) /* Item has to be enabled */
+            flags |= Qt::ItemIsEditable;
+    }
+    return flags;
+}
+
+QWidget * HardwareItem::createEditor (QWidget *aParent, const QStyleOptionViewItem & /* aOption */, const QModelIndex &aIndex) const
+{
+    QWidget *editor = NULL;
+    if (aIndex.column() == ConfigValueSection)
+    {
+        switch (mType)
+        {
+            case KVirtualSystemDescriptionType_OS:
+                {
+                    VBoxOSTypeSelectorButton *e = new VBoxOSTypeSelectorButton (aParent);
+                    /* Fill the background with the highlight color in the case
+                     * the button hasn't a rectangle shape. This prevents the
+                     * display of parts from the current text on the Mac. */
+#ifdef QT_MAC_USE_COCOA
+                    /* Use the palette from the tree view, not the one from the
+                     * editor. */
+                    QPalette p = e->palette();
+                    p.setBrush (QPalette::Highlight, aParent->palette().brush (QPalette::Highlight));
+                    e->setPalette(p);
+#endif /* QT_MAC_USE_COCOA */
+                    e->setAutoFillBackground (true);
+                    e->setBackgroundRole (QPalette::Highlight);
+                    editor = e;
+                    break;
+                }
+            case KVirtualSystemDescriptionType_Name:
+            case KVirtualSystemDescriptionType_Product:
+            case KVirtualSystemDescriptionType_ProductUrl:
+            case KVirtualSystemDescriptionType_Vendor:
+            case KVirtualSystemDescriptionType_VendorUrl:
+            case KVirtualSystemDescriptionType_Version:
+                {
+                    QLineEdit *e = new QLineEdit (aParent);
+                    editor = e;
+                    break;
+                }
+            case KVirtualSystemDescriptionType_Description:
+            case KVirtualSystemDescriptionType_License:
+                {
+                    VBoxLineTextEdit *e = new VBoxLineTextEdit (aParent);
+                    editor = e;
+                    break;
+                }
+            case KVirtualSystemDescriptionType_CPU:
+                {
+                    QSpinBox *e = new QSpinBox (aParent);
+                    e->setRange (VBoxApplianceEditorWgt::minGuestCPUCount(), VBoxApplianceEditorWgt::maxGuestCPUCount());
+                    editor = e;
+                    break;
+                }
+            case KVirtualSystemDescriptionType_Memory:
+                {
+                    QSpinBox *e = new QSpinBox (aParent);
+                    e->setRange (VBoxApplianceEditorWgt::minGuestRAM(), VBoxApplianceEditorWgt::maxGuestRAM());
+                    e->setSuffix (" " + VBoxApplianceEditorWgt::tr ("MB"));
+                    editor = e;
+                    break;
+                }
+            case KVirtualSystemDescriptionType_SoundCard:
+                {
+                    QComboBox *e = new QComboBox (aParent);
+                    e->addItem (vboxGlobal().toString (KAudioControllerType_AC97), KAudioControllerType_AC97);
+                    e->addItem (vboxGlobal().toString (KAudioControllerType_SB16), KAudioControllerType_SB16);
+                    editor = e;
+                    break;
+                }
+            case KVirtualSystemDescriptionType_NetworkAdapter:
+                {
+                    QComboBox *e = new QComboBox (aParent);
+                    e->addItem (vboxGlobal().toString (KNetworkAdapterType_Am79C970A), KNetworkAdapterType_Am79C970A);
+                    e->addItem (vboxGlobal().toString (KNetworkAdapterType_Am79C973), KNetworkAdapterType_Am79C973);
+#ifdef VBOX_WITH_E1000
+                    e->addItem (vboxGlobal().toString (KNetworkAdapterType_I82540EM), KNetworkAdapterType_I82540EM);
+                    e->addItem (vboxGlobal().toString (KNetworkAdapterType_I82543GC), KNetworkAdapterType_I82543GC);
+                    e->addItem (vboxGlobal().toString (KNetworkAdapterType_I82545EM), KNetworkAdapterType_I82545EM);
+#endif /* VBOX_WITH_E1000 */
+#ifdef VBOX_WITH_VIRTIO
+                    e->addItem (vboxGlobal().toString (KNetworkAdapterType_Virtio), KNetworkAdapterType_Virtio);
+#endif /* VBOX_WITH_VIRTIO */
+                    editor = e;
+                    break;
+                }
+            case KVirtualSystemDescriptionType_HardDiskControllerIDE:
+                {
+                    QComboBox *e = new QComboBox (aParent);
+                    e->addItem (vboxGlobal().toString (KStorageControllerType_PIIX3), "PIIX3");
+                    e->addItem (vboxGlobal().toString (KStorageControllerType_PIIX4), "PIIX4");
+                    e->addItem (vboxGlobal().toString (KStorageControllerType_ICH6),  "ICH6");
+                    editor = e;
+                    break;
+                }
+            case KVirtualSystemDescriptionType_HardDiskImage:
+                {
+                    /* disabled for now
+                       VBoxFilePathSelectorWidget *e = new VBoxFilePathSelectorWidget (aParent);
+                       e->setMode (VBoxFilePathSelectorWidget::Mode_File);
+                       e->setResetEnabled (false);
+                       */
+                    QLineEdit *e = new QLineEdit (aParent);
+                    editor = e;
+                    break;
+                }
+            default: break;
+        }
+    }
+    return editor;
+}
+
+bool HardwareItem::setEditorData (QWidget *aEditor, const QModelIndex & /* aIndex */) const
+{
+    bool fDone = false;
+    switch (mType)
+    {
+        case KVirtualSystemDescriptionType_OS:
+            {
+                if (VBoxOSTypeSelectorButton *e = qobject_cast<VBoxOSTypeSelectorButton*> (aEditor))
+                {
+                    e->setOSTypeId (mConfigValue);
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_HardDiskControllerIDE:
+            {
+                if (QComboBox *e = qobject_cast<QComboBox*> (aEditor))
+                {
+                    int i = e->findData (mConfigValue);
+                    if (i != -1)
+                        e->setCurrentIndex (i);
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_CPU:
+        case KVirtualSystemDescriptionType_Memory:
+            {
+                if (QSpinBox *e = qobject_cast<QSpinBox*> (aEditor))
+                {
+                    e->setValue (mConfigValue.toInt());
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_Name:
+        case KVirtualSystemDescriptionType_Product:
+        case KVirtualSystemDescriptionType_ProductUrl:
+        case KVirtualSystemDescriptionType_Vendor:
+        case KVirtualSystemDescriptionType_VendorUrl:
+        case KVirtualSystemDescriptionType_Version:
+            {
+                if (QLineEdit *e = qobject_cast<QLineEdit*> (aEditor))
+                {
+                    e->setText (mConfigValue);
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_Description:
+        case KVirtualSystemDescriptionType_License:
+            {
+                if (VBoxLineTextEdit *e = qobject_cast<VBoxLineTextEdit*> (aEditor))
+                {
+                    e->setText (mConfigValue);
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_SoundCard:
+        case KVirtualSystemDescriptionType_NetworkAdapter:
+            {
+                if (QComboBox *e = qobject_cast<QComboBox*> (aEditor))
+                {
+                    int i = e->findData (mConfigValue.toInt());
+                    if (i != -1)
+                        e->setCurrentIndex (i);
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_HardDiskImage:
+            {
+                /* disabled for now
+                   if (VBoxFilePathSelectorWidget *e = qobject_cast<VBoxFilePathSelectorWidget*> (aEditor))
+                   {
+                   e->setPath (mConfigValue);
+                   }
+                   */
+                if (QLineEdit *e = qobject_cast<QLineEdit*> (aEditor))
+                {
+                    e->setText (mConfigValue);
+                    fDone = true;
+                }
+                break;
+            }
+        default: break;
+    }
+    return fDone;
+}
+
+bool HardwareItem::setModelData (QWidget *aEditor, QAbstractItemModel * /* aModel */, const QModelIndex & /* aIndex */)
+{
+    bool fDone = false;
+    switch (mType)
+    {
+        case KVirtualSystemDescriptionType_OS:
+            {
+                if (VBoxOSTypeSelectorButton *e = qobject_cast<VBoxOSTypeSelectorButton*> (aEditor))
+                {
+                    mConfigValue = e->osTypeId();
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_HardDiskControllerIDE:
+            {
+                if (QComboBox *e = qobject_cast<QComboBox*> (aEditor))
+                {
+                    mConfigValue = e->itemData (e->currentIndex()).toString();
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_CPU:
+        case KVirtualSystemDescriptionType_Memory:
+            {
+                if (QSpinBox *e = qobject_cast<QSpinBox*> (aEditor))
+                {
+                    mConfigValue = QString::number (e->value());
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_Name:
+        case KVirtualSystemDescriptionType_Product:
+        case KVirtualSystemDescriptionType_ProductUrl:
+        case KVirtualSystemDescriptionType_Vendor:
+        case KVirtualSystemDescriptionType_VendorUrl:
+        case KVirtualSystemDescriptionType_Version:
+            {
+                if (QLineEdit *e = qobject_cast<QLineEdit*> (aEditor))
+                {
+                    mConfigValue = e->text();
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_Description:
+        case KVirtualSystemDescriptionType_License:
+            {
+                if (VBoxLineTextEdit *e = qobject_cast<VBoxLineTextEdit*> (aEditor))
+                {
+                    mConfigValue = e->text();
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_SoundCard:
+        case KVirtualSystemDescriptionType_NetworkAdapter:
+            {
+                if (QComboBox *e = qobject_cast<QComboBox*> (aEditor))
+                {
+                    mConfigValue = e->itemData (e->currentIndex()).toString();
+                    fDone = true;
+                }
+                break;
+            }
+        case KVirtualSystemDescriptionType_HardDiskImage:
+            {
+                /* disabled for now
+                   if (VBoxFilePathSelectorWidget *e = qobject_cast<VBoxFilePathSelectorWidget*> (aEditor))
+                   {
+                   mConfigValue = e->path();
+                   }
+                   */
+                if (QLineEdit *e = qobject_cast<QLineEdit*> (aEditor))
+                {
+                    mConfigValue = e->text();
+                    fDone = true;
+                }
+                break;
+            }
+        default: break;
+    }
+    return fDone;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// VirtualSystemModel
+
+/* This class is a wrapper model for our ModelItem. It could be used with any
+   TreeView & forward mostly all calls to the methods of ModelItem. The
+   ModelItems itself are stored as internal pointers in the QModelIndex class. */
+VirtualSystemModel::VirtualSystemModel (QVector<CVirtualSystemDescription>& aVSDs, QObject *aParent /* = NULL */)
+   : QAbstractItemModel (aParent)
+{
+    mRootItem = new ModelItem (0, RootType);
+    for (int a = 0; a < aVSDs.size(); ++a)
+    {
+        CVirtualSystemDescription vs = aVSDs[a];
+
+        VirtualSystemItem *vi = new VirtualSystemItem (a, vs, mRootItem);
+        mRootItem->appendChild (vi);
+
+        /* @todo: ask Dmitry about include/COMDefs.h:232 */
+        QVector<KVirtualSystemDescriptionType> types;
+        QVector<QString> refs;
+        QVector<QString> origValues;
+        QVector<QString> configValues;
+        QVector<QString> extraConfigValues;
+
+        QList<int> hdIndizies;
+        QMap<int, HardwareItem*> controllerMap;
+        vs.GetDescription (types, refs, origValues, configValues, extraConfigValues);
+        for (int i = 0; i < types.size(); ++i)
+        {
+            /* We add the hard disk images in an second step, so save a
+               reference to them. */
+            if (types[i] == KVirtualSystemDescriptionType_HardDiskImage)
+                hdIndizies << i;
+            else
+            {
+                HardwareItem *hi = new HardwareItem (i, types[i], refs[i], origValues[i], configValues[i], extraConfigValues[i], vi);
+                vi->appendChild (hi);
+                /* Save the hard disk controller types in an extra map */
+                if (types[i] == KVirtualSystemDescriptionType_HardDiskControllerIDE ||
+                    types[i] == KVirtualSystemDescriptionType_HardDiskControllerSATA ||
+                    types[i] == KVirtualSystemDescriptionType_HardDiskControllerSCSI)
+                    controllerMap[i] = hi;
+            }
+        }
+        QRegExp rx ("controller=(\\d+);?");
+        /* Now process the hard disk images */
+        for (int a = 0; a < hdIndizies.size(); ++a)
+        {
+            int i = hdIndizies[a];
+            QString ecnf = extraConfigValues[i];
+            if (rx.indexIn (ecnf) != -1)
+            {
+                /* Get the controller */
+                HardwareItem *ci = controllerMap[rx.cap (1).toInt()];
+                if (ci)
+                {
+                    /* New hardware item as child of the controller */
+                    HardwareItem *hi = new HardwareItem (i, types[i], refs[i], origValues[i], configValues[i], extraConfigValues[i], ci);
+                    ci->appendChild (hi);
+                }
+            }
+        }
+    }
+}
+
+QModelIndex VirtualSystemModel::index (int aRow, int aColumn, const QModelIndex &aParent /* = QModelIndex() */) const
+{
+    if (!hasIndex (aRow, aColumn, aParent))
+        return QModelIndex();
+
+    ModelItem *parentItem;
+
+    if (!aParent.isValid())
+        parentItem = mRootItem;
+    else
+        parentItem = static_cast<ModelItem*> (aParent.internalPointer());
+
+    ModelItem *childItem = parentItem->child (aRow);
+    if (childItem)
+        return createIndex (aRow, aColumn, childItem);
+    else
+        return QModelIndex();
+}
+
+QModelIndex VirtualSystemModel::parent (const QModelIndex &aIndex) const
+{
+    if (!aIndex.isValid())
+        return QModelIndex();
+
+    ModelItem *childItem = static_cast<ModelItem*> (aIndex.internalPointer());
+    ModelItem *parentItem = childItem->parent();
+
+    if (parentItem == mRootItem)
+        return QModelIndex();
+
+    return createIndex (parentItem->row(), 0, parentItem);
+}
+
+int VirtualSystemModel::rowCount (const QModelIndex &aParent /* = QModelIndex() */) const
+{
+    ModelItem *parentItem;
+    if (aParent.column() > 0)
+        return 0;
+
+    if (!aParent.isValid())
+        parentItem = mRootItem;
+    else
+        parentItem = static_cast<ModelItem*> (aParent.internalPointer());
+
+    return parentItem->childCount();
+}
+
+int VirtualSystemModel::columnCount (const QModelIndex &aParent /* = QModelIndex() */) const
+{
+    if (aParent.isValid())
+        return static_cast<ModelItem*> (aParent.internalPointer())->columnCount();
+    else
+        return mRootItem->columnCount();
+}
+
+bool VirtualSystemModel::setData (const QModelIndex &aIndex, const QVariant &aValue, int aRole)
+{
+    if (!aIndex.isValid())
+        return false;
+
+    ModelItem *item = static_cast<ModelItem*> (aIndex.internalPointer());
+
+    return item->setData (aIndex.column(), aValue, aRole);
+}
+
+QVariant VirtualSystemModel::data (const QModelIndex &aIndex, int aRole /* = Qt::DisplayRole */) const
+{
+    if (!aIndex.isValid())
+        return QVariant();
+
+    ModelItem *item = static_cast<ModelItem*> (aIndex.internalPointer());
+
+    return item->data (aIndex.column(), aRole);
+}
+
+Qt::ItemFlags VirtualSystemModel::flags (const QModelIndex &aIndex) const
+{
+    if (!aIndex.isValid())
+        return 0;
+
+    ModelItem *item = static_cast<ModelItem*> (aIndex.internalPointer());
+
+    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | item->itemFlags (aIndex.column());
+}
+
+QVariant VirtualSystemModel::headerData (int aSection, Qt::Orientation aOrientation, int aRole) const
+{
+    if (aRole != Qt::DisplayRole ||
+        aOrientation != Qt::Horizontal)
+        return QVariant();
+
+    QString title;
+    switch (aSection)
+    {
+        case DescriptionSection: title = VBoxApplianceEditorWgt::tr ("Description"); break;
+        case ConfigValueSection: title = VBoxApplianceEditorWgt::tr ("Configuration"); break;
+    }
+    return title;
+}
+
+QModelIndex VirtualSystemModel::buddy (const QModelIndex &aIndex) const
+{
+    if (!aIndex.isValid())
+        return QModelIndex();
+
+    if (aIndex.column() == ConfigValueSection)
+        return aIndex;
+    else
+        return index (aIndex.row(), ConfigValueSection, aIndex.parent());
+}
+
+void VirtualSystemModel::restoreDefaults (const QModelIndex& aParent /* = QModelIndex() */)
+{
+    ModelItem *parentItem;
+
+    if (!aParent.isValid())
+        parentItem = mRootItem;
+    else
+        parentItem = static_cast<ModelItem*> (aParent.internalPointer());
+
+    for (int i = 0; i < parentItem->childCount(); ++i)
+    {
+        parentItem->child (i)->restoreDefaults();
+        restoreDefaults (index (i, 0, aParent));
+    }
+    emit dataChanged (index (0, 0, aParent), index (parentItem->childCount()-1, 0, aParent));
+}
+
+void VirtualSystemModel::putBack()
+{
+    QVector<BOOL> v1;
+    QVector<QString> v2;
+    QVector<QString> v3;
+    mRootItem->putBack (v1, v2, v3);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// VirtualSystemDelegate
+
+/* The delegate is used for creating/handling the different editors for the
+   various types we support. This class forward the requests to the virtual
+   methods of our different ModelItems. If this is not possible the default
+   methods of QItemDelegate are used to get some standard behavior. Note: We
+   have to handle the proxy model ourself. I really don't understand why Qt is
+   not doing this for us. */
+VirtualSystemDelegate::VirtualSystemDelegate (QAbstractProxyModel *aProxy, QObject *aParent /* = NULL */)
+  : QItemDelegate (aParent)
+  , mProxy (aProxy)
+{}
+
+QWidget * VirtualSystemDelegate::createEditor (QWidget *aParent, const QStyleOptionViewItem &aOption, const QModelIndex &aIndex) const
+{
+    if (!aIndex.isValid())
+        return QItemDelegate::createEditor (aParent, aOption, aIndex);
+
+    QModelIndex index (aIndex);
+    if (mProxy)
+        index = mProxy->mapToSource (aIndex);
+
+    ModelItem *item = static_cast<ModelItem*> (index.internalPointer());
+    QWidget *editor = item->createEditor (aParent, aOption, index);
+
+    if (editor == NULL)
+        return QItemDelegate::createEditor (aParent, aOption, index);
+    else
+        return editor;
+}
+
+void VirtualSystemDelegate::setEditorData (QWidget *aEditor, const QModelIndex &aIndex) const
+{
+    if (!aIndex.isValid())
+        return QItemDelegate::setEditorData (aEditor, aIndex);
+
+    QModelIndex index (aIndex);
+    if (mProxy)
+        index = mProxy->mapToSource (aIndex);
+
+    ModelItem *item = static_cast<ModelItem*> (index.internalPointer());
+
+    if (!item->setEditorData (aEditor, index))
+        QItemDelegate::setEditorData (aEditor, index);
+}
+
+void VirtualSystemDelegate::setModelData (QWidget *aEditor, QAbstractItemModel *aModel, const QModelIndex &aIndex) const
+{
+    if (!aIndex.isValid())
+        return QItemDelegate::setModelData (aEditor, aModel, aIndex);
+
+    QModelIndex index = aModel->index (aIndex.row(), aIndex.column());
+    if (mProxy)
+        index = mProxy->mapToSource (aIndex);
+
+    ModelItem *item = static_cast<ModelItem*> (index.internalPointer());
+    if (!item->setModelData (aEditor, aModel, index))
+        QItemDelegate::setModelData (aEditor, aModel, aIndex);
+}
+
+void VirtualSystemDelegate::updateEditorGeometry (QWidget *aEditor, const QStyleOptionViewItem &aOption, const QModelIndex & /* aIndex */) const
+{
+    if (aEditor)
+        aEditor->setGeometry (aOption.rect);
+}
+
+#ifdef QT_MAC_USE_COCOA
+bool VirtualSystemDelegate::eventFilter (QObject *aObject, QEvent *aEvent)
+{
+    if (aEvent->type() == QEvent::FocusOut)
+    {
+        /* On Mac OS X Cocoa the OS type selector widget loses it focus when
+         * the popup menu is shown. Prevent this here, cause otherwise the new
+         * selected OS will not be updated. */
+        VBoxOSTypeSelectorButton *button = qobject_cast<VBoxOSTypeSelectorButton*> (aObject);
+        if (button && button->isMenuShown())
+            return false;
+        /* The same counts for the text edit buttons of the license or
+         * description fields. */
+        else if (qobject_cast<VBoxLineTextEdit*> (aObject))
+            return false;
+    }
+
+    return QItemDelegate::eventFilter (aObject, aEvent);
+}
+#endif /* QT_MAC_USE_COCOA */
+
+////////////////////////////////////////////////////////////////////////////////
+// VirtualSystemSortProxyModel
+
+/* How to sort the items in the tree view */
+KVirtualSystemDescriptionType VirtualSystemSortProxyModel::mSortList[] =
+{
+    KVirtualSystemDescriptionType_Name,
+    KVirtualSystemDescriptionType_Product,
+    KVirtualSystemDescriptionType_ProductUrl,
+    KVirtualSystemDescriptionType_Vendor,
+    KVirtualSystemDescriptionType_VendorUrl,
+    KVirtualSystemDescriptionType_Version,
+    KVirtualSystemDescriptionType_Description,
+    KVirtualSystemDescriptionType_License,
+    KVirtualSystemDescriptionType_OS,
+    KVirtualSystemDescriptionType_CPU,
+    KVirtualSystemDescriptionType_Memory,
+    KVirtualSystemDescriptionType_Floppy,
+    KVirtualSystemDescriptionType_CDROM,
+    KVirtualSystemDescriptionType_USBController,
+    KVirtualSystemDescriptionType_SoundCard,
+    KVirtualSystemDescriptionType_NetworkAdapter,
+    KVirtualSystemDescriptionType_HardDiskControllerIDE,
+    KVirtualSystemDescriptionType_HardDiskControllerSATA,
+    KVirtualSystemDescriptionType_HardDiskControllerSCSI
+};
+
+VirtualSystemSortProxyModel::VirtualSystemSortProxyModel (QObject *aParent)
+    : QSortFilterProxyModel (aParent)
+{}
+
+bool VirtualSystemSortProxyModel::filterAcceptsRow (int aSourceRow, const QModelIndex & aSourceParent) const
+{
+    /* By default enable all, we will explicitly filter out below */
+    if (aSourceParent.isValid())
+    {
+        QModelIndex i = aSourceParent.child (aSourceRow, 0);
+        if (i.isValid())
+        {
+            ModelItem *item = static_cast<ModelItem*> (i.internalPointer());
+            /* We filter hardware types only */
+            if (item->type() == HardwareType)
+            {
+                HardwareItem *hwItem = static_cast<HardwareItem*> (item);
+                /* The license type shouldn't be displayed */
+                if (mFilterList.contains (hwItem->mType))
+                    return false;
+            }
+        }
+    }
+    return true;
+}
+
+bool VirtualSystemSortProxyModel::lessThan (const QModelIndex &aLeft, const QModelIndex &aRight) const
+{
+    if (!aLeft.isValid() ||
+        !aRight.isValid())
+        return false;
+
+    ModelItem *leftItem = static_cast<ModelItem*> (aLeft.internalPointer());
+    ModelItem *rightItem = static_cast<ModelItem*> (aRight.internalPointer());
+
+    /* We sort hardware types only */
+    if (!(leftItem->type() == HardwareType &&
+          rightItem->type() == HardwareType))
+        return false;
+
+    HardwareItem *hwLeft = static_cast<HardwareItem*> (leftItem);
+    HardwareItem *hwRight = static_cast<HardwareItem*> (rightItem);
+
+    for (unsigned int i = 0; i < RT_ELEMENTS (mSortList); ++i)
+        if (hwLeft->mType == mSortList[i])
+        {
+            for (unsigned int a = 0; a <= i; ++a)
+                if (hwRight->mType == mSortList[a])
+                    return true;
+            return false;
+        }
+
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxApplianceEditorWgt
+
+int VBoxApplianceEditorWgt::mMinGuestRAM = -1;
+int VBoxApplianceEditorWgt::mMaxGuestRAM = -1;
+int VBoxApplianceEditorWgt::mMinGuestCPUCount = -1;
+int VBoxApplianceEditorWgt::mMaxGuestCPUCount = -1;
+
+VBoxApplianceEditorWgt::VBoxApplianceEditorWgt (QWidget *aParent /* = NULL */)
+    : QIWithRetranslateUI<QWidget> (aParent)
+    , mAppliance (NULL)
+    , mModel (NULL)
+{
+    /* Make sure all static content is properly initialized */
+    initSystemSettings();
+
+    /* Apply UI decorations */
+    Ui::VBoxApplianceEditorWgt::setupUi (this);
+
+    /* Make the tree looking nicer */
+    mTvSettings->setRootIsDecorated (false);
+    mTvSettings->setAlternatingRowColors (true);
+    mTvSettings->setAllColumnsShowFocus (true);
+    mTvSettings->header()->setStretchLastSection (true);
+    mTvSettings->header()->setResizeMode (QHeaderView::ResizeToContents);
+
+    /* Applying language settings */
+    retranslateUi();
+}
+
+void VBoxApplianceEditorWgt::restoreDefaults()
+{
+    mModel->restoreDefaults();
+}
+
+void VBoxApplianceEditorWgt::retranslateUi()
+{
+    /* Translate uic generated strings */
+    Ui::VBoxApplianceEditorWgt::retranslateUi (this);
+}
+
+/* static */
+void VBoxApplianceEditorWgt::initSystemSettings()
+{
+    if (mMinGuestRAM == -1)
+    {
+        /* We need some global defaults from the current VirtualBox
+           installation */
+        CSystemProperties sp = vboxGlobal().virtualBox().GetSystemProperties();
+        mMinGuestRAM = sp.GetMinGuestRAM();
+        mMaxGuestRAM = sp.GetMaxGuestRAM();
+        mMinGuestCPUCount = sp.GetMinGuestCPUCount();
+        mMaxGuestCPUCount = sp.GetMaxGuestCPUCount();
+    }
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.h	(revision 25178)
@@ -0,0 +1,281 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxApplianceEditorWgt class declaration
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxApplianceEditorWgt_h__
+#define __VBoxApplianceEditorWgt_h__
+
+/* VBox includes */
+#include "COMDefs.h"
+#include "VBoxApplianceEditorWgt.gen.h"
+#include "QIWithRetranslateUI.h"
+
+/* Qt includes */
+#include <QSortFilterProxyModel>
+#include <QItemDelegate>
+
+/* VBox forward declarations */
+class ModelItem;
+
+////////////////////////////////////////////////////////////////////////////////
+// Globals
+
+enum TreeViewSection { DescriptionSection = 0, OriginalValueSection, ConfigValueSection };
+
+////////////////////////////////////////////////////////////////////////////////
+// ModelItem
+
+enum ModelItemType { RootType, VirtualSystemType, HardwareType };
+
+/* This & the following derived classes represent the data items of a Virtual
+   System. All access/manipulation is done with the help of virtual functions
+   to keep the interface clean. ModelItem is able to handle tree structures
+   with a parent & several children's. */
+class ModelItem
+{
+public:
+    ModelItem (int aNumber, ModelItemType aType, ModelItem *aParent = NULL);
+
+    ~ModelItem();
+
+    ModelItem *parent() const { return mParentItem; }
+
+    void appendChild (ModelItem *aChild);
+    ModelItem * child (int aRow) const;
+
+    int row() const;
+
+    int childCount() const;
+    int columnCount() const { return 3; }
+
+    virtual Qt::ItemFlags itemFlags (int /* aColumn */) const { return 0; }
+    virtual bool setData (int /* aColumn */, const QVariant & /* aValue */, int /* aRole */) { return false; }
+    virtual QVariant data (int /* aColumn */, int /* aRole */) const { return QVariant(); }
+    virtual QWidget * createEditor (QWidget * /* aParent */, const QStyleOptionViewItem & /* aOption */, const QModelIndex & /* aIndex */) const { return NULL; }
+    virtual bool setEditorData (QWidget * /* aEditor */, const QModelIndex & /* aIndex */) const { return false; }
+    virtual bool setModelData (QWidget * /* aEditor */, QAbstractItemModel * /* aModel */, const QModelIndex & /* aIndex */) { return false; }
+
+    virtual void restoreDefaults() {}
+    virtual void putBack (QVector<BOOL>& aFinalStates, QVector<QString>& aFinalValues, QVector<QString>& aFinalExtraValues);
+
+    ModelItemType type() const { return mType; }
+
+protected:
+    /* Protected member vars */
+    int mNumber;
+    ModelItemType mType;
+
+    ModelItem *mParentItem;
+    QList<ModelItem*> mChildItems;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// VirtualSystemItem
+
+/* This class represent a Virtual System with an index. */
+class VirtualSystemItem: public ModelItem
+{
+public:
+    VirtualSystemItem (int aNumber, CVirtualSystemDescription aDesc, ModelItem *aParent);
+
+    virtual QVariant data (int aColumn, int aRole) const;
+
+    virtual void putBack (QVector<BOOL>& aFinalStates, QVector<QString>& aFinalValues, QVector<QString>& aFinalExtraValues);
+
+private:
+    CVirtualSystemDescription mDesc;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// HardwareItem
+
+/* This class represent an hardware item of a Virtual System. All values of
+   KVirtualSystemDescriptionType are supported & handled differently. */
+class HardwareItem: public ModelItem
+{
+    friend class VirtualSystemSortProxyModel;
+public:
+
+    HardwareItem (int aNumber,
+                  KVirtualSystemDescriptionType aType,
+                  const QString &aRef,
+                  const QString &aOrigValue,
+                  const QString &aConfigValue,
+                  const QString &aExtraConfigValue,
+                  ModelItem *aParent);
+
+    virtual void putBack (QVector<BOOL>& aFinalStates, QVector<QString>& aFinalValues, QVector<QString>& aFinalExtraValues);
+
+    virtual bool setData (int aColumn, const QVariant &aValue, int aRole);
+    virtual QVariant data (int aColumn, int aRole) const;
+
+    virtual Qt::ItemFlags itemFlags (int aColumn) const;
+
+    virtual QWidget * createEditor (QWidget *aParent, const QStyleOptionViewItem &aOption, const QModelIndex &aIndex) const;
+    virtual bool setEditorData (QWidget *aEditor, const QModelIndex &aIndex) const;
+
+    virtual bool setModelData (QWidget *aEditor, QAbstractItemModel *aModel, const QModelIndex &aIndex);
+
+    virtual void restoreDefaults()
+    {
+        mConfigValue = mConfigDefaultValue;
+        mCheckState = Qt::Checked;
+    }
+
+private:
+
+    /* Private member vars */
+    KVirtualSystemDescriptionType mType;
+    QString mRef;
+    QString mOrigValue;
+    QString mConfigValue;
+    QString mConfigDefaultValue;
+    QString mExtraConfigValue;
+    Qt::CheckState mCheckState;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// VirtualSystemModel
+
+class VirtualSystemModel: public QAbstractItemModel
+{
+
+public:
+    VirtualSystemModel (QVector<CVirtualSystemDescription>& aVSDs, QObject *aParent = NULL);
+
+    QModelIndex index (int aRow, int aColumn, const QModelIndex &aParent = QModelIndex()) const;
+    QModelIndex parent (const QModelIndex &aIndex) const;
+    int rowCount (const QModelIndex &aParent = QModelIndex()) const;
+    int columnCount (const QModelIndex &aParent = QModelIndex()) const;
+    bool setData (const QModelIndex &aIndex, const QVariant &aValue, int aRole);
+    QVariant data (const QModelIndex &aIndex, int aRole = Qt::DisplayRole) const;
+    Qt::ItemFlags flags (const QModelIndex &aIndex) const;
+    QVariant headerData (int aSection, Qt::Orientation aOrientation, int aRole) const;
+
+    QModelIndex buddy (const QModelIndex &aIndex) const;
+
+    void restoreDefaults (const QModelIndex& aParent = QModelIndex());
+    void putBack();
+
+private:
+    /* Private member vars */
+    ModelItem *mRootItem;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// VirtualSystemDelegate
+
+/* The delegate is used for creating/handling the different editors for the
+   various types we support. This class forward the requests to the virtual
+   methods of our different ModelItems. If this is not possible the default
+   methods of QItemDelegate are used to get some standard behavior. Note: We
+   have to handle the proxy model ourself. I really don't understand why Qt is
+   not doing this for us. */
+class VirtualSystemDelegate: public QItemDelegate
+{
+public:
+    VirtualSystemDelegate (QAbstractProxyModel *aProxy, QObject *aParent = NULL);
+
+    QWidget * createEditor (QWidget *aParent, const QStyleOptionViewItem &aOption, const QModelIndex &aIndex) const;
+    void setEditorData (QWidget *aEditor, const QModelIndex &aIndex) const;
+    void setModelData (QWidget *aEditor, QAbstractItemModel *aModel, const QModelIndex &aIndex) const;
+    void updateEditorGeometry (QWidget *aEditor, const QStyleOptionViewItem &aOption, const QModelIndex &aIndex) const;
+
+    QSize sizeHint (const QStyleOptionViewItem &aOption, const QModelIndex &aIndex) const
+    {
+        QSize size = QItemDelegate::sizeHint (aOption, aIndex);
+#ifdef Q_WS_MAC
+        int h = 28;
+#else /* Q_WS_MAC */
+        int h = 24;
+#endif /* Q_WS_MAC */
+        size.setHeight (RT_MAX (h, size.height()));
+        return size;
+    }
+
+protected:
+#ifdef QT_MAC_USE_COCOA
+    bool eventFilter (QObject *aObject, QEvent *aEvent);
+#endif /* QT_MAC_USE_COCOA */
+
+private:
+    /* Private member vars */
+    QAbstractProxyModel *mProxy;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// VirtualSystemSortProxyModel
+
+class VirtualSystemSortProxyModel: public QSortFilterProxyModel
+{
+public:
+    VirtualSystemSortProxyModel (QObject *aParent = NULL);
+
+protected:
+    bool filterAcceptsRow (int aSourceRow, const QModelIndex & aSourceParent) const;
+    bool lessThan (const QModelIndex &aLeft, const QModelIndex &aRight) const;
+
+    static KVirtualSystemDescriptionType mSortList[];
+
+    QList<KVirtualSystemDescriptionType> mFilterList;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxApplianceEditorWgt
+
+class VBoxApplianceEditorWgt : public QIWithRetranslateUI<QWidget>,
+                               public Ui::VBoxApplianceEditorWgt
+{
+    Q_OBJECT;
+
+public:
+    VBoxApplianceEditorWgt (QWidget *aParent = NULL);
+
+    bool isValid() const { return mAppliance != NULL; }
+    CAppliance* appliance() const { return mAppliance; }
+
+    static int minGuestRAM() { return mMinGuestRAM; }
+    static int maxGuestRAM() { return mMaxGuestRAM; }
+    static int minGuestCPUCount() { return mMinGuestCPUCount; }
+    static int maxGuestCPUCount() { return mMaxGuestCPUCount; }
+
+public slots:
+    void restoreDefaults();
+
+protected:
+    virtual void retranslateUi();
+
+    /* Protected member vars */
+    CAppliance *mAppliance;
+    VirtualSystemModel *mModel;
+
+private:
+    static void initSystemSettings();
+
+    /* Private member vars */
+    static int mMinGuestRAM;
+    static int mMaxGuestRAM;
+    static int mMinGuestCPUCount;
+    static int mMaxGuestCPUCount;
+};
+
+#endif /* __VBoxApplianceEditorWgt_h__ */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.ui
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.ui	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxApplianceEditorWgt.ui	(revision 25178)
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <comment>
+ VBox frontends: Qt4 GUI (&quot;VirtualBox&quot;):
+
+ Copyright (C) 2009 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.
+ </comment>
+ <class>VBoxApplianceEditorWgt</class>
+ <widget class="QWidget" name="VBoxApplianceEditorWgt">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>459</width>
+    <height>305</height>
+   </rect>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QTreeView" name="mTvSettings">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="mWarningWidget" native="true">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <property name="sizeConstraint">
+       <enum>QLayout::SetDefaultConstraint</enum>
+      </property>
+      <property name="margin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>Warnings:</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QTextEdit" name="mWarningTextEdit">
+        <property name="maximumSize">
+         <size>
+          <width>16777215</width>
+          <height>107</height>
+         </size>
+        </property>
+        <property name="autoFormatting">
+         <set>QTextEdit::AutoBulletList</set>
+        </property>
+        <property name="readOnly">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxBootTable.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxBootTable.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxBootTable.cpp	(revision 25178)
@@ -0,0 +1,61 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxBootTable class implementation
+ */
+
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* Global include */
+#include <QHeaderView>
+#include <QKeyEvent>
+
+/* Local includes */
+#include "VBoxBootTable.h"
+#include "VBoxGlobal.h"
+
+VBoxBootTable::VBoxBootTable(QWidget *pParent)
+    : QTreeWidget(pParent)
+{
+    header()->hide();
+    connect(this, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(onItemChanged()));
+}
+
+void VBoxBootTable::onItemChanged()
+{
+    emit itemToggled();
+}
+
+void VBoxBootTable::keyPressEvent(QKeyEvent *pEvent)
+{
+    if (pEvent->QInputEvent::modifiers() == Qt::ControlModifier)
+    {
+        switch (pEvent->key())
+        {
+            case Qt::Key_Up:
+                emit moveItemUp();
+                return;
+            case Qt::Key_Down:
+                emit moveItemDown();
+                return;
+            default:
+                break;
+        }
+    }
+    QTreeWidget::keyPressEvent(pEvent);
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxBootTable.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxBootTable.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxBootTable.h	(revision 25178)
@@ -0,0 +1,60 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxBootTable class declaration
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxBootTable_h__
+#define __VBoxBootTable_h__
+
+/* Global includes */
+#include <QTreeWidget>
+
+/**
+ *  QTreeWidget class reimplementation to use as boot items table.
+ *  It has one unsorted column without header.
+ *  Keymapping handlers for ctrl-up & ctrl-down are translated into
+ *  boot-items up/down moving signals.
+ *  Emits itemToggled() signal when the item changed.
+ */
+class VBoxBootTable : public QTreeWidget
+{
+    Q_OBJECT;
+
+public:
+
+    VBoxBootTable(QWidget *pParent);
+
+signals:
+
+    void moveItemUp();
+    void moveItemDown();
+    void itemToggled();
+
+protected:
+
+    void keyPressEvent(QKeyEvent *pEvent);
+
+private slots:
+
+    void onItemChanged();
+};
+
+#endif // __VBoxBootTable_h__
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxDownloaderWgt.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxDownloaderWgt.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxDownloaderWgt.cpp	(revision 25178)
@@ -0,0 +1,193 @@
+/** @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 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxDownloaderWgt.h	(revision 25178)
@@ -0,0 +1,93 @@
+/** @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__
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.cpp	(revision 25178)
@@ -0,0 +1,111 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxExportApplianceWgt class implementation
+ */
+
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* VBox includes */
+#include "VBoxExportApplianceWgt.h"
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// ExportSortProxyModel
+
+class ExportSortProxyModel: public VirtualSystemSortProxyModel
+{
+public:
+    ExportSortProxyModel (QObject *aParent = NULL)
+      : VirtualSystemSortProxyModel (aParent)
+    {
+        mFilterList
+            << KVirtualSystemDescriptionType_OS
+            << KVirtualSystemDescriptionType_CPU
+            << KVirtualSystemDescriptionType_Memory
+            << KVirtualSystemDescriptionType_Floppy
+            << KVirtualSystemDescriptionType_CDROM
+            << KVirtualSystemDescriptionType_USBController
+            << KVirtualSystemDescriptionType_SoundCard
+            << KVirtualSystemDescriptionType_NetworkAdapter
+            << KVirtualSystemDescriptionType_HardDiskControllerIDE
+            << KVirtualSystemDescriptionType_HardDiskControllerSATA
+            << KVirtualSystemDescriptionType_HardDiskControllerSCSI;
+    }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxExportApplianceWgt
+
+VBoxExportApplianceWgt::VBoxExportApplianceWgt (QWidget *aParent /* = NULL */)
+  : VBoxApplianceEditorWgt (aParent)
+{
+}
+
+CAppliance* VBoxExportApplianceWgt::init()
+{
+    if (mAppliance)
+        delete mAppliance;
+    CVirtualBox vbox = vboxGlobal().virtualBox();
+    /* Create a appliance object */
+    mAppliance = new CAppliance(vbox.CreateAppliance());
+//    bool fResult = mAppliance->isOk();
+    return mAppliance;
+}
+
+void VBoxExportApplianceWgt::populate()
+{
+    if (mModel)
+        delete mModel;
+
+    QVector<CVirtualSystemDescription> vsds = mAppliance->GetVirtualSystemDescriptions();
+
+    mModel = new VirtualSystemModel (vsds, this);
+
+    ExportSortProxyModel *proxy = new ExportSortProxyModel (this);
+    proxy->setSourceModel (mModel);
+    proxy->sort (DescriptionSection, Qt::DescendingOrder);
+
+    VirtualSystemDelegate *delegate = new VirtualSystemDelegate (proxy, this);
+
+    /* Set our own model */
+    mTvSettings->setModel (proxy);
+    /* Set our own delegate */
+    mTvSettings->setItemDelegate (delegate);
+    /* For now we hide the original column. This data is displayed as tooltip
+       also. */
+    mTvSettings->setColumnHidden (OriginalValueSection, true);
+    mTvSettings->expandAll();
+
+    /* Check for warnings & if there are one display them. */
+    bool fWarningsEnabled = false;
+    QVector<QString> warnings = mAppliance->GetWarnings();
+    if (warnings.size() > 0)
+    {
+        foreach (const QString& text, warnings)
+            mWarningTextEdit->append ("- " + text);
+        fWarningsEnabled = true;
+    }
+    mWarningWidget->setShown (fWarningsEnabled);
+}
+
+void VBoxExportApplianceWgt::prepareExport()
+{
+    if (mAppliance)
+        mModel->putBack();
+}
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxExportApplianceWgt.h	(revision 25178)
@@ -0,0 +1,40 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxExportApplianceWgt class declaration
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxExportApplianceWgt_h__
+#define __VBoxExportApplianceWgt_h__
+
+#include "VBoxApplianceEditorWgt.h"
+
+class VBoxExportApplianceWgt : public VBoxApplianceEditorWgt
+{
+public:
+    VBoxExportApplianceWgt (QWidget *aParent = NULL);
+
+    CAppliance* init();
+
+    void populate();
+    void prepareExport();
+};
+
+#endif /* __VBoxExportApplianceWgt_h__ */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.cpp	(revision 25178)
@@ -0,0 +1,759 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VirtualBox Qt extensions: VBoxFilePathSelectorWidget class implementation
+ */
+
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/* VBox includes */
+#include "VBoxFilePathSelectorWidget.h"
+#include "VBoxGlobal.h"
+#include "QIFileDialog.h"
+#include "QILabel.h"
+#include "QILineEdit.h"
+
+/* Qt includes */
+#include <QAction>
+#include <QApplication>
+#include <QClipboard>
+#include <QDir>
+#include <QFileIconProvider>
+#include <QFocusEvent>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QTimer>
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxFilePathSelectorWidget
+
+enum
+{
+    PathId = 0,
+    SelectId,
+    ResetId
+};
+
+/**
+ * Returns first position of difference between passed strings.
+ */
+static int differFrom (const QString &aS1, const QString &aS2)
+{
+    if (aS1 == aS2)
+        return -1;
+
+    int minLength = qMin (aS1.size(), aS2.size());
+    int index = 0;
+    for (index = 0; index < minLength ; ++ index)
+        if (aS1 [index] != aS2 [index])
+            break;
+    return index;
+}
+
+VBoxFilePathSelectorWidget::VBoxFilePathSelectorWidget (QWidget *aParent)
+    : QIWithRetranslateUI<QComboBox> (aParent)
+    , mIconProvider (new QFileIconProvider())
+    , mCopyAction (new QAction (this))
+    , mMode (Mode_Folder)
+    , mHomeDir (QDir::current().absolutePath())
+    , mIsEditable (true)
+    , mIsEditableMode (false)
+    , mIsMouseAwaited (false)
+    , mModified (false)
+{
+    /* Populate items */
+    insertItem (PathId, "");
+    insertItem (SelectId, "");
+    insertItem (ResetId, "");
+
+    /* Attaching known icons */
+    setItemIcon (SelectId, VBoxGlobal::iconSet (":/select_file_16px.png"));
+    setItemIcon (ResetId, VBoxGlobal::iconSet (":/eraser_16px.png"));
+
+    /* Setup context menu */
+    addAction (mCopyAction);
+    mCopyAction->setShortcut (QKeySequence (QKeySequence::Copy));
+    mCopyAction->setShortcutContext (Qt::WidgetShortcut);
+
+    /* Initial Setup */
+    setInsertPolicy (QComboBox::NoInsert);
+    setContextMenuPolicy (Qt::ActionsContextMenu);
+    setMinimumWidth (200);
+
+    /* Setup connections */
+    connect (this, SIGNAL (activated (int)), this, SLOT (onActivated (int)));
+    connect (mCopyAction, SIGNAL (triggered (bool)), this, SLOT (copyToClipboard()));
+
+    /* Editable by default */
+    setEditable (true);
+
+    /* Applying language settings */
+    retranslateUi();
+}
+
+VBoxFilePathSelectorWidget::~VBoxFilePathSelectorWidget()
+{
+    delete mIconProvider;
+}
+
+void VBoxFilePathSelectorWidget::setMode (Mode aMode)
+{
+    mMode = aMode;
+}
+
+VBoxFilePathSelectorWidget::Mode VBoxFilePathSelectorWidget::mode() const
+{
+    return mMode;
+}
+
+void VBoxFilePathSelectorWidget::setEditable (bool aOn)
+{
+    mIsEditable = aOn;
+
+    if (mIsEditable)
+    {
+        QComboBox::setEditable (true);
+        Assert (lineEdit());
+        connect (lineEdit(), SIGNAL (textEdited (const QString &)),
+                 this, SLOT (onTextEdited (const QString &)));
+
+        /* Installing necessary event filters */
+        lineEdit()->installEventFilter (this);
+    }else
+    {
+        if (lineEdit())
+        {
+            /* Installing necessary event filters */
+            lineEdit()->installEventFilter (this);
+            disconnect (lineEdit(), SIGNAL (textEdited (const QString &)),
+                        this, SLOT (onTextEdited (const QString &)));
+        }
+        QComboBox::setEditable (false);
+    }
+}
+
+bool VBoxFilePathSelectorWidget::isEditable() const
+{
+    return mIsEditable;
+}
+
+void VBoxFilePathSelectorWidget::setResetEnabled (bool aEnabled)
+{
+    if (!aEnabled && count() - 1 == ResetId)
+        removeItem (ResetId);
+    else if (aEnabled && count() - 1 == ResetId - 1)
+    {
+        insertItem (ResetId, "");
+        setItemIcon (ResetId, VBoxGlobal::iconSet (":/eraser_16px.png"));
+    }
+    retranslateUi();
+}
+
+bool VBoxFilePathSelectorWidget::isResetEnabled() const
+{
+    return (count() - 1  == ResetId);
+}
+
+void VBoxFilePathSelectorWidget::resetModified()
+{
+    mModified = false;
+}
+
+bool VBoxFilePathSelectorWidget::isModified() const
+{
+    return mModified;
+}
+
+void VBoxFilePathSelectorWidget::setFileDialogTitle (const QString& aTitle)
+{
+    mFileDialogTitle = aTitle;
+}
+
+QString VBoxFilePathSelectorWidget::fileDialogTitle() const
+{
+    return mFileDialogTitle;
+}
+
+void VBoxFilePathSelectorWidget::setFileFilters (const QString& aFilters)
+{
+    mFileFilters = aFilters;
+}
+
+QString VBoxFilePathSelectorWidget::fileFilters() const
+{
+    return mFileFilters;
+}
+
+void VBoxFilePathSelectorWidget::setDefaultSaveExt (const QString &aExt)
+{
+    mDefaultSaveExt = aExt;
+}
+
+QString VBoxFilePathSelectorWidget::defaultSaveExt() const
+{
+    return mDefaultSaveExt;
+}
+
+/**
+ * Returns @c true if the selected (active) combobox item is a path item.
+ *
+ * May be used in @c activated() signal handlers to distinguish between
+ * non-path items like "Other..." or "Reset" that get temporarily activated
+ * when performing the corresponding actiojn and the item that contains a
+ * real selected file/folder path.
+ */
+bool VBoxFilePathSelectorWidget::isPathSelected() const
+{
+    return (currentIndex() == PathId);
+}
+
+QString VBoxFilePathSelectorWidget::path() const
+{
+    return mPath;
+}
+
+void VBoxFilePathSelectorWidget::setPath (const QString &aPath, bool aRefreshText /* = true */)
+{
+    mPath = aPath.isEmpty() ? QString::null :
+            QDir::toNativeSeparators (aPath);
+    if (aRefreshText)
+        refreshText();
+}
+
+void VBoxFilePathSelectorWidget::setHomeDir (const QString &aHomeDir)
+{
+    mHomeDir = aHomeDir;
+}
+
+void VBoxFilePathSelectorWidget::resizeEvent (QResizeEvent *aEvent)
+{
+    QIWithRetranslateUI<QComboBox>::resizeEvent (aEvent);
+    refreshText();
+}
+
+void VBoxFilePathSelectorWidget::focusInEvent (QFocusEvent *aEvent)
+{
+    if (isPathSelected())
+    {
+        if (mIsEditable)
+            mIsEditableMode = true;
+        if (aEvent->reason() == Qt::MouseFocusReason)
+            mIsMouseAwaited = true;
+        else
+            refreshText();
+    }
+    QIWithRetranslateUI<QComboBox>::focusInEvent (aEvent);
+}
+
+void VBoxFilePathSelectorWidget::focusOutEvent (QFocusEvent *aEvent)
+{
+    if (isPathSelected())
+    {
+        mIsEditableMode = false;
+        refreshText();
+    }
+    QIWithRetranslateUI<QComboBox>::focusOutEvent (aEvent);
+}
+
+bool VBoxFilePathSelectorWidget::eventFilter (QObject *aObj, QEvent *aEv)
+{
+    if (mIsMouseAwaited && (aEv->type() == QEvent::MouseButtonPress))
+        QTimer::singleShot (0, this, SLOT (refreshText()));
+
+    return QIWithRetranslateUI<QComboBox>::eventFilter (aObj, aEv);
+}
+
+void VBoxFilePathSelectorWidget::retranslateUi()
+{
+    /* How do we interpret the "nothing selected" item? */
+    if (isResetEnabled())
+    {
+        mNoneStr = tr ("<reset to default>");
+        mNoneTip = tr ("The actual default path value will be displayed after "
+                       "accepting the changes and opening this dialog again.");
+    }
+    else
+    {
+        mNoneStr = tr ("<not selected>");
+        mNoneTip = tr ("Please use the <b>Other...</b> item from the drop-down "
+                       "list to select a path.");
+    }
+
+    /* Retranslate 'path' item */
+    if (mPath.isNull())
+    {
+        setItemText (PathId, mNoneStr);
+        setItemData (PathId, mNoneTip, Qt::ToolTipRole);
+        setToolTip (mNoneTip);
+    }
+
+    /* Retranslate 'select' item */
+    setItemText (SelectId, tr ("Other..."));
+
+    /* Retranslate 'reset' item */
+    if (count() - 1 == ResetId)
+        setItemText (ResetId, tr ("Reset"));
+
+    /* Set tooltips of the above two items based on the mode */
+    switch (mMode)
+    {
+        case Mode_Folder:
+            setItemData (SelectId,
+                         tr ("Opens a dialog to select a different folder."),
+                         Qt::ToolTipRole);
+            setItemData (ResetId,
+                         tr ("Resets the folder path to the default value."),
+                         Qt::ToolTipRole);
+            break;
+        case Mode_File_Open:
+        case Mode_File_Save:
+            setItemData (SelectId,
+                         tr ("Opens a dialog to select a different file."),
+                         Qt::ToolTipRole);
+            setItemData (ResetId,
+                         tr ("Resets the file path to the default value."),
+                         Qt::ToolTipRole);
+            break;
+        default:
+            AssertFailedBreak();
+    }
+
+    /* Retranslate copy action */
+    mCopyAction->setText (tr ("&Copy"));
+}
+
+void VBoxFilePathSelectorWidget::onActivated (int aIndex)
+{
+    switch (aIndex)
+    {
+        case SelectId:
+        {
+            selectPath();
+            break;
+        }
+        case ResetId:
+        {
+            changePath (QString::null);
+            break;
+        }
+        default:
+            break;
+    }
+    setCurrentIndex (PathId);
+    setFocus();
+}
+
+void VBoxFilePathSelectorWidget::onTextEdited (const QString &aPath)
+{
+    changePath (aPath, false /* refresh text? */);
+}
+
+void VBoxFilePathSelectorWidget::copyToClipboard()
+{
+    QString text (fullPath());
+    /* Copy the current text to the selection and global clipboard. */
+    if (QApplication::clipboard()->supportsSelection())
+        QApplication::clipboard()->setText (text, QClipboard::Selection);
+    QApplication::clipboard()->setText (text, QClipboard::Clipboard);
+}
+
+void VBoxFilePathSelectorWidget::changePath (const QString &aPath,
+                                             bool aRefreshText /* = true */)
+{
+    QString oldPath = mPath;
+    setPath (aPath, aRefreshText);
+    if (!mModified && mPath != oldPath)
+        mModified = true;
+    emit pathChanged (aPath);
+}
+
+void VBoxFilePathSelectorWidget::selectPath()
+{
+    /* Preparing initial directory. */
+    QString initDir = mPath.isNull() ? mHomeDir :
+        QIFileDialog::getFirstExistingDir (mPath);
+    if (initDir.isNull())
+        initDir = mHomeDir;
+
+    QString selPath;
+    switch (mMode)
+    {
+        case Mode_File_Open:
+            selPath = QIFileDialog::getOpenFileName (initDir, mFileFilters, parentWidget(), mFileDialogTitle); break;
+        case Mode_File_Save:
+            {
+                selPath = QIFileDialog::getSaveFileName (initDir, mFileFilters, parentWidget(), mFileDialogTitle);
+                if (!selPath.isEmpty() && QFileInfo (selPath).suffix().isEmpty())
+                    selPath = QString ("%1.%2").arg (selPath).arg (mDefaultSaveExt);
+                break;
+            }
+        case Mode_Folder:
+            selPath = QIFileDialog::getExistingDirectory (initDir, parentWidget(), mFileDialogTitle); break;
+    }
+
+    if (selPath.isNull())
+        return;
+
+    selPath.remove (QRegExp ("[\\\\/]$"));
+    changePath (selPath);
+}
+
+QIcon VBoxFilePathSelectorWidget::defaultIcon() const
+{
+    if (mMode == Mode_Folder)
+        return mIconProvider->icon (QFileIconProvider::Folder);
+    else
+        return mIconProvider->icon (QFileIconProvider::File);
+}
+
+QString VBoxFilePathSelectorWidget::fullPath (bool aAbsolute /* = true */) const
+{
+    if (mPath.isNull())
+        return mPath;
+
+    QString result;
+    switch (mMode)
+    {
+        case Mode_Folder:
+            result = aAbsolute ? QDir (mPath).absolutePath() :
+                                 QDir (mPath).path();
+            break;
+        case Mode_File_Open:
+        case Mode_File_Save:
+            result = aAbsolute ? QFileInfo (mPath).absoluteFilePath() :
+                                 QFileInfo (mPath).filePath();
+            break;
+        default:
+            AssertFailedBreak();
+    }
+    return QDir::toNativeSeparators (result);
+}
+
+QString VBoxFilePathSelectorWidget::shrinkText (int aWidth) const
+{
+    QString fullText (fullPath (false));
+    if (fullText.isEmpty())
+        return fullText;
+
+    int oldSize = fontMetrics().width (fullText);
+    int indentSize = fontMetrics().width ("x...x");
+
+    /* Compress text */
+    int start = 0;
+    int finish = 0;
+    int position = 0;
+    int textWidth = 0;
+    do {
+        textWidth = fontMetrics().width (fullText);
+        if (textWidth + indentSize > aWidth)
+        {
+            start = 0;
+            finish = fullText.length();
+
+            /* Selecting remove position */
+            QRegExp regExp ("([\\\\/][^\\\\^/]+[\\\\/]?$)");
+            int newFinish = regExp.indexIn (fullText);
+            if (newFinish != -1)
+                finish = newFinish;
+            position = (finish - start) / 2;
+
+            if (position == finish)
+               break;
+
+            fullText.remove (position, 1);
+        }
+    } while (textWidth + indentSize > aWidth);
+
+    fullText.insert (position, "...");
+    int newSize = fontMetrics().width (fullText);
+
+    return newSize < oldSize ? fullText : fullPath (false);
+}
+
+void VBoxFilePathSelectorWidget::refreshText()
+{
+    if (mIsEditable && mIsEditableMode)
+    {
+        /* Cursor positioning variables */
+        int curPos = -1;
+        int diffPos = -1;
+        int fromRight = -1;
+
+        if (mIsMouseAwaited)
+        {
+            /* Store the cursor position */
+            curPos = lineEdit()->cursorPosition();
+            diffPos = differFrom (lineEdit()->text(), mPath);
+            fromRight = lineEdit()->text().size() - curPos;
+        }
+
+        /* In editable mode there should be no any icon
+         * and text have be corresponding real stored path
+         * which can be absolute or relative. */
+        if (lineEdit()->text() != mPath)
+            setItemText (PathId, mPath);
+        setItemIcon (PathId, QIcon());
+        setToolTip (mMode == Mode_Folder ?
+            tr ("Please type the folder path here.") :
+            tr ("Please type the file path here."));
+
+        if (mIsMouseAwaited)
+        {
+            mIsMouseAwaited = false;
+
+            /* Restore the position to the right of dots */
+            if (diffPos != -1 && curPos >= diffPos + 3)
+                lineEdit()->setCursorPosition (lineEdit()->text().size() -
+                                               fromRight);
+            /* Restore the position to the center of text */
+            else if (diffPos != -1 && curPos > diffPos)
+                lineEdit()->setCursorPosition (lineEdit()->text().size() / 2);
+            /* Restore the position to the left of dots */
+            else
+                lineEdit()->setCursorPosition (curPos);
+        }
+    }
+    else if (mPath.isNull())
+    {
+        /* If we are not in editable mode and no path is
+         * stored here - show the translated 'none' string. */
+        if (itemText (PathId) != mNoneStr)
+        {
+            setItemText (PathId, mNoneStr);
+            setItemIcon (PathId, QIcon());
+            setItemData (PathId, mNoneTip, Qt::ToolTipRole);
+            setToolTip (mNoneTip);
+        }
+    }
+    else
+    {
+        /* Compress text in combobox */
+        QStyleOptionComboBox options;
+        options.initFrom (this);
+        QRect rect = QApplication::style()->subControlRect (
+            QStyle::CC_ComboBox, &options, QStyle::SC_ComboBoxEditField);
+        setItemText (PathId, shrinkText (rect.width() - iconSize().width()));
+
+        /* Attach corresponding icon */
+        setItemIcon (PathId, QFileInfo (mPath).exists() ?
+                             mIconProvider->icon (QFileInfo (mPath)) :
+                             defaultIcon());
+
+        /* Set the tooltip */
+        setToolTip (fullPath());
+        setItemData (PathId, toolTip(), Qt::ToolTipRole);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxEmptyFileSelector
+
+VBoxEmptyFileSelector::VBoxEmptyFileSelector (QWidget *aParent /* = NULL */)
+    : QIWithRetranslateUI<QWidget> (aParent)
+    , mPathWgt (NULL)
+    , mLabel (NULL)
+    , mMode (VBoxFilePathSelectorWidget::Mode_File_Open)
+    , mLineEdit (NULL)
+    , mHomeDir (QDir::current().absolutePath())
+    , mIsModified (false)
+{
+    mMainLayout = new QHBoxLayout (this);
+    mMainLayout->setMargin (0);
+
+    mSelectButton = new QPushButton (this);
+    connect (mSelectButton, SIGNAL (clicked()),
+             this, SLOT (choose()));
+
+    mMainLayout->addWidget (mSelectButton);
+
+    setEditable (false);
+
+    retranslateUi();
+}
+
+void VBoxEmptyFileSelector::setMode (VBoxFilePathSelectorWidget::Mode aMode)
+{
+    mMode = aMode;
+}
+
+VBoxFilePathSelectorWidget::Mode VBoxEmptyFileSelector::mode() const
+{
+    return mMode;
+}
+
+void VBoxEmptyFileSelector::setButtonPosition (ButtonPosition aPos)
+{
+    if (aPos == LeftPosition)
+    {
+        mMainLayout->setDirection (QBoxLayout::LeftToRight);
+        setTabOrder (mSelectButton, mPathWgt);
+    }
+    else
+    {
+        mMainLayout->setDirection (QBoxLayout::RightToLeft);
+        setTabOrder (mPathWgt, mSelectButton);
+    }
+}
+
+VBoxEmptyFileSelector::ButtonPosition VBoxEmptyFileSelector::buttonPosition() const
+{
+    return mMainLayout->direction() == QBoxLayout::LeftToRight ? LeftPosition : RightPosition;
+}
+
+void VBoxEmptyFileSelector::setEditable (bool aOn)
+{
+    if (mPathWgt)
+    {
+        delete mPathWgt;
+        mLabel = NULL;
+        mLineEdit = NULL;
+    }
+
+    if (aOn)
+    {
+        mPathWgt = mLineEdit = new QILineEdit (this);
+        connect (mLineEdit, SIGNAL (textChanged (const QString&)),
+                 this, SLOT (textChanged (const QString&)));
+    }
+    else
+    {
+        mPathWgt = mLabel = new QILabel (this);
+        mLabel->setWordWrap (true);
+    }
+    mMainLayout->addWidget (mPathWgt, 2);
+    setButtonPosition (buttonPosition());
+
+    setPath (mPath);
+}
+
+bool VBoxEmptyFileSelector::isEditable() const
+{
+    return mLabel ? false : true;
+}
+
+void VBoxEmptyFileSelector::setChooserVisible (bool aOn)
+{
+    mSelectButton->setVisible (aOn);
+}
+
+bool VBoxEmptyFileSelector::isChooserVisible() const
+{
+    return mSelectButton->isVisible();
+}
+
+void VBoxEmptyFileSelector::setPath (const QString& aPath)
+{
+	QString tmpPath = QDir::toNativeSeparators (aPath);
+    if (mLabel)
+        mLabel->setText (QString ("<compact elipsis=\"start\">%1</compact>").arg (tmpPath));
+    else if (mLineEdit)
+        mLineEdit->setText (tmpPath);
+    textChanged(tmpPath);
+}
+
+QString VBoxEmptyFileSelector::path() const
+{
+    return mPath;
+}
+
+void VBoxEmptyFileSelector::setDefaultSaveExt (const QString &aExt)
+{
+    mDefaultSaveExt = aExt;
+}
+
+QString VBoxEmptyFileSelector::defaultSaveExt() const
+{
+    return mDefaultSaveExt;
+}
+
+void VBoxEmptyFileSelector::setFileDialogTitle (const QString& aTitle)
+{
+    mFileDialogTitle = aTitle;
+}
+
+QString VBoxEmptyFileSelector::fileDialogTitle() const
+{
+    return mFileDialogTitle;
+}
+
+void VBoxEmptyFileSelector::setFileFilters (const QString& aFilters)
+{
+    mFileFilters = aFilters;
+}
+
+QString VBoxEmptyFileSelector::fileFilters() const
+{
+    return mFileFilters;
+}
+
+void VBoxEmptyFileSelector::setHomeDir (const QString& aDir)
+{
+    mHomeDir = aDir;
+}
+
+QString VBoxEmptyFileSelector::homeDir() const
+{
+    return mHomeDir;
+}
+
+void VBoxEmptyFileSelector::retranslateUi()
+{
+    mSelectButton->setText (tr ("&Choose..."));
+}
+
+void VBoxEmptyFileSelector::choose()
+{
+    QString path = mPath;
+
+    /* Preparing initial directory. */
+    QString initDir = path.isNull() ? mHomeDir :
+        QIFileDialog::getFirstExistingDir (path);
+    if (initDir.isNull())
+        initDir = mHomeDir;
+
+    switch (mMode)
+    {
+        case VBoxFilePathSelectorWidget::Mode_File_Open:
+            path = QIFileDialog::getOpenFileName (initDir, mFileFilters, parentWidget(), mFileDialogTitle); break;
+        case VBoxFilePathSelectorWidget::Mode_File_Save:
+        {
+            path = QIFileDialog::getSaveFileName (initDir, mFileFilters, parentWidget(), mFileDialogTitle);
+            if (!path.isEmpty() && QFileInfo (path).suffix().isEmpty())
+                path = QString ("%1.%2").arg (path).arg (mDefaultSaveExt);
+            break;
+        }
+        case VBoxFilePathSelectorWidget::Mode_Folder:
+            path = QIFileDialog::getExistingDirectory (initDir, parentWidget(), mFileDialogTitle); break;
+    }
+    if (path.isEmpty())
+        return;
+
+    path.remove (QRegExp ("[\\\\/]$"));
+    setPath (path);
+}
+
+void VBoxEmptyFileSelector::textChanged (const QString& aPath)
+{
+    const QString oldPath = mPath;
+    mPath = aPath;
+    if (oldPath != mPath)
+    {
+        mIsModified = true;
+        emit pathChanged (mPath);
+    }
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxFilePathSelectorWidget.h	(revision 25178)
@@ -0,0 +1,209 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VirtualBox Qt extensions: VBoxFilePathSelectorWidget class declaration
+ */
+
+/*
+ * Copyright (C) 2008 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 __VBoxFilePathSelectorWidget_h__
+#define __VBoxFilePathSelectorWidget_h__
+
+/* VBox includes */
+#include "QIWithRetranslateUI.h"
+
+/* Qt includes */
+#include <QComboBox>
+
+/* VBox forward declarations */
+class QILabel;
+class QILineEdit;
+
+/* Qt forward declarations */
+class QHBoxLayout;
+class QFileIconProvider;
+class QAction;
+class QPushButton;
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxFilePathSelectorWidget
+
+class VBoxFilePathSelectorWidget: public QIWithRetranslateUI<QComboBox>
+{
+    Q_OBJECT;
+
+public:
+
+    enum Mode
+    {
+        Mode_Folder = 0,
+        Mode_File_Open,
+        Mode_File_Save
+    };
+
+    VBoxFilePathSelectorWidget (QWidget *aParent);
+   ~VBoxFilePathSelectorWidget();
+
+    void setMode (Mode aMode);
+    Mode mode() const;
+
+    void setEditable (bool aOn);
+    bool isEditable() const;
+
+    void setResetEnabled (bool aEnabled);
+    bool isResetEnabled () const;
+
+    void setFileDialogTitle (const QString& aTitle);
+    QString fileDialogTitle() const;
+
+    void setFileFilters (const QString& aFilters);
+    QString fileFilters() const;
+
+    void setDefaultSaveExt (const QString &aExt);
+    QString defaultSaveExt() const;
+
+    void resetModified();
+    bool isModified() const;
+    bool isPathSelected() const;
+
+    QString path() const;
+
+signals:
+    void pathChanged (const QString &);
+
+public slots:
+
+    void setPath (const QString &aPath, bool aRefreshText = true);
+    void setHomeDir (const QString &aHomeDir);
+
+protected:
+
+    void resizeEvent (QResizeEvent *aEvent);
+    void focusInEvent (QFocusEvent *aEvent);
+    void focusOutEvent (QFocusEvent *aEvent);
+    bool eventFilter (QObject *aObj, QEvent *aEv);
+    void retranslateUi();
+
+private slots:
+
+    void onActivated (int aIndex);
+    void onTextEdited (const QString &aPath);
+    void copyToClipboard();
+    void refreshText();
+
+private:
+
+    void changePath (const QString &aPath, bool aRefreshText = true);
+    void selectPath();
+    QIcon defaultIcon() const;
+    QString fullPath (bool aAbsolute = true) const;
+    QString shrinkText (int aWidth) const;
+
+    /* Private member vars */
+    QFileIconProvider *mIconProvider;
+    QAction *mCopyAction;
+    Mode mMode;
+    QString mPath;
+    QString mHomeDir;
+    QString mFileFilters;
+    QString mDefaultSaveExt;
+    QString mFileDialogTitle;
+    QString mNoneStr;
+    QString mNoneTip;
+    bool mIsEditable;
+    bool mIsEditableMode;
+    bool mIsMouseAwaited;
+
+    bool mModified;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxEmptyFileSelector
+
+class VBoxEmptyFileSelector: public QIWithRetranslateUI<QWidget>
+{
+    Q_OBJECT;
+
+public:
+    enum ButtonPosition
+    {
+        LeftPosition,
+        RightPosition
+    };
+
+    VBoxEmptyFileSelector (QWidget *aParent = NULL);
+
+    void setMode (VBoxFilePathSelectorWidget::Mode aMode);
+    VBoxFilePathSelectorWidget::Mode mode() const;
+
+    void setButtonPosition (ButtonPosition aPos);
+    ButtonPosition buttonPosition() const;
+
+    void setEditable (bool aOn);
+    bool isEditable() const;
+
+    void setChooserVisible (bool aOn);
+    bool isChooserVisible() const;
+
+    QString path() const;
+
+    void setDefaultSaveExt (const QString &aExt);
+    QString defaultSaveExt() const;
+
+    bool isModified () const { return mIsModified; }
+    void resetModified () { mIsModified = false; }
+
+    void setFileDialogTitle (const QString& aTitle);
+    QString fileDialogTitle() const;
+
+    void setFileFilters (const QString& aFilters);
+    QString fileFilters() const;
+
+    void setHomeDir (const QString& aDir);
+    QString homeDir() const;
+
+signals:
+    void pathChanged (QString);
+
+public slots:
+    void setPath (const QString& aPath);
+
+protected:
+    void retranslateUi();
+
+private slots:
+    void choose();
+    void textChanged (const QString& aPath);
+
+private:
+    /* Private member vars */
+    QHBoxLayout *mMainLayout;
+    QWidget *mPathWgt;
+    QILabel *mLabel;
+    VBoxFilePathSelectorWidget::Mode mMode;
+    QILineEdit *mLineEdit;
+    QPushButton *mSelectButton;
+    QString mFileDialogTitle;
+    QString mFileFilters;
+    QString mDefaultSaveExt;
+    QString mHomeDir;
+    bool mIsModified;
+    QString mPath;
+};
+
+#endif /* __VBoxFilePathSelectorWidget_h__ */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.cpp	(revision 25178)
@@ -0,0 +1,180 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VirtualBox Qt extensions: VBoxGuestRAMSlider class implementation
+ */
+
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* VBox includes */
+#include "VBoxGuestRAMSlider.h"
+#include "VBoxGlobal.h"
+
+VBoxGuestRAMSlider::VBoxGuestRAMSlider (QWidget *aParent /* = 0 */)
+  : QIAdvancedSlider (aParent)
+  , mMinRAM (0)
+  , mMaxRAMOpt (0)
+  , mMaxRAMAlw (0)
+  , mMaxRAM (0)
+{
+    init();
+}
+
+VBoxGuestRAMSlider::VBoxGuestRAMSlider (Qt::Orientation aOrientation, QWidget *aParent /* = 0 */)
+  : QIAdvancedSlider (aOrientation, aParent)
+  , mMinRAM (0)
+  , mMaxRAMOpt (0)
+  , mMaxRAMAlw (0)
+  , mMaxRAM (0)
+{
+    init();
+}
+
+uint VBoxGuestRAMSlider::minRAM() const
+{
+    return mMinRAM;
+}
+
+uint VBoxGuestRAMSlider::maxRAMOpt() const
+{
+    return mMaxRAMOpt;
+}
+
+uint VBoxGuestRAMSlider::maxRAMAlw() const
+{
+    return mMaxRAMAlw;
+}
+
+uint VBoxGuestRAMSlider::maxRAM() const
+{
+    return mMaxRAM;
+}
+
+void VBoxGuestRAMSlider::init()
+{
+    ulong fullSize = vboxGlobal().virtualBox().GetHost().GetMemorySize();
+    CSystemProperties sys = vboxGlobal().virtualBox().GetSystemProperties();
+    mMinRAM = sys.GetMinGuestRAM();
+    mMaxRAM = RT_MIN (RT_ALIGN (fullSize, _1G / _1M), sys.GetMaxGuestRAM());
+
+    /* Come up with some nice round percent boundaries relative to
+     * the system memory. A max of 75% on a 256GB config is ridiculous,
+     * even on an 8GB rig reserving 2GB for the OS is way to conservative.
+     * The max numbers can be estimated using the following program:
+     *
+     *      double calcMaxPct(uint64_t cbRam)
+     *      {
+     *          double cbRamOverhead = cbRam * 0.0390625; // 160 bytes per page.
+     *          double cbRamForTheOS = RT_MAX(RT_MIN(_512M, cbRam * 0.25), _64M);
+     *          double OSPct  = (cbRamOverhead + cbRamForTheOS) * 100.0 / cbRam;
+     *          double MaxPct = 100 - OSPct;
+     *          return MaxPct;
+     *      }
+     *
+     *      int main()
+     *      {
+     *          uint64_t cbRam = _1G;
+     *          for (; !(cbRam >> 33); cbRam += _1G)
+     *              printf("%8lluGB %.1f%% %8lluKB\n", cbRam >> 30, calcMaxPct(cbRam),
+     *                     (uint64_t)(cbRam * calcMaxPct(cbRam) / 100.0) >> 20);
+     *          for (; !(cbRam >> 51); cbRam <<= 1)
+     *              printf("%8lluGB %.1f%% %8lluKB\n", cbRam >> 30, calcMaxPct(cbRam),
+     *                     (uint64_t)(cbRam * calcMaxPct(cbRam) / 100.0) >> 20);
+     *          return 0;
+     *      }
+     *
+     * Note. We might wanna put these calculations somewhere global later. */
+
+    /* System RAM amount test */
+    mMaxRAMAlw  = (uint)(0.75 * fullSize);
+    mMaxRAMOpt  = (uint)(0.50 * fullSize);
+    if (fullSize < 3072)
+        /* done */;
+    else if (fullSize < 4096)   /* 3GB */
+        mMaxRAMAlw = (uint)(0.80 * fullSize);
+    else if (fullSize < 6144)   /* 4-5GB */
+    {
+        mMaxRAMAlw = (uint)(0.84 * fullSize);
+        mMaxRAMOpt = (uint)(0.60 * fullSize);
+    }
+    else if (fullSize < 8192)   /* 6-7GB */
+    {
+        mMaxRAMAlw = (uint)(0.88 * fullSize);
+        mMaxRAMOpt = (uint)(0.65 * fullSize);
+    }
+    else if (fullSize < 16384)  /* 8-15GB */
+    {
+        mMaxRAMAlw = (uint)(0.90 * fullSize);
+        mMaxRAMOpt = (uint)(0.70 * fullSize);
+    }
+    else if (fullSize < 32768)  /* 16-31GB */
+    {
+        mMaxRAMAlw = (uint)(0.93 * fullSize);
+        mMaxRAMOpt = (uint)(0.75 * fullSize);
+    }
+    else if (fullSize < 65536)  /* 32-63GB */
+    {
+        mMaxRAMAlw = (uint)(0.94 * fullSize);
+        mMaxRAMOpt = (uint)(0.80 * fullSize);
+    }
+    else if (fullSize < 131072) /* 64-127GB */
+    {
+        mMaxRAMAlw = (uint)(0.95 * fullSize);
+        mMaxRAMOpt = (uint)(0.85 * fullSize);
+    }
+    else                        /* 128GB- */
+    {
+        mMaxRAMAlw = (uint)(0.96 * fullSize);
+        mMaxRAMOpt = (uint)(0.90 * fullSize);
+    }
+    /* Now check the calculated maximums are out of the range for the guest
+     * RAM. If so change it accordingly. */
+    mMaxRAMAlw  = RT_MIN (mMaxRAMAlw, mMaxRAM);
+    mMaxRAMOpt  = RT_MIN (mMaxRAMOpt, mMaxRAM);
+
+    setPageStep (calcPageStep (mMaxRAM));
+    setSingleStep (pageStep() / 4);
+    setTickInterval (pageStep());
+    /* Setup the scale so that ticks are at page step boundaries */
+    setMinimum ((mMinRAM / pageStep()) * pageStep());
+    setMaximum (mMaxRAM);
+    setSnappingEnabled (true);
+    setOptimalHint (mMinRAM, mMaxRAMOpt);
+    setWarningHint (mMaxRAMOpt, mMaxRAMAlw);
+    setErrorHint (mMaxRAMAlw, mMaxRAM);
+}
+
+/**
+ *  Calculates a suitable page step size for the given max value. The returned
+ *  size is so that there will be no more than 32 pages. The minimum returned
+ *  page size is 4.
+ */
+int VBoxGuestRAMSlider::calcPageStep (int aMax) const
+{
+    /* reasonable max. number of page steps is 32 */
+    uint page = ((uint) aMax + 31) / 32;
+    /* make it a power of 2 */
+    uint p = page, p2 = 0x1;
+    while ((p >>= 1))
+        p2 <<= 1;
+    if (page != p2)
+        p2 <<= 1;
+    if (p2 < 4)
+        p2 = 4;
+    return (int) p2;
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxGuestRAMSlider.h	(revision 25178)
@@ -0,0 +1,54 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxGuestRAMSlider class declaration
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxGuestRAMSlider_h__
+#define __VBoxGuestRAMSlider_h__
+
+/* VBox includes */
+#include "QIAdvancedSlider.h"
+
+class VBoxGuestRAMSlider: public QIAdvancedSlider
+{
+public:
+    VBoxGuestRAMSlider (QWidget *aParent = 0);
+    VBoxGuestRAMSlider (Qt::Orientation aOrientation, QWidget *aParent = 0);
+
+    uint minRAM() const;
+    uint maxRAMOpt() const;
+    uint maxRAMAlw() const;
+    uint maxRAM() const;
+
+private:
+    /* Private methods */
+    void init();
+    int calcPageStep (int aMax) const;
+
+    /* Private member vars */
+    uint mMinRAM;
+    uint mMaxRAMOpt;
+    uint mMaxRAMAlw;
+    uint mMaxRAM;
+};
+
+#endif /* __VBoxGuestRAMSlider_h__ */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.cpp	(revision 25178)
@@ -0,0 +1,176 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxImportApplianceWgt class implementation
+ */
+
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* VBox includes */
+#include "VBoxImportApplianceWgt.h"
+#include "VBoxGlobal.h"
+#include "VBoxProblemReporter.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// ImportSortProxyModel
+
+class ImportSortProxyModel: public VirtualSystemSortProxyModel
+{
+public:
+    ImportSortProxyModel (QObject *aParent = NULL)
+      : VirtualSystemSortProxyModel (aParent)
+    {
+        mFilterList << KVirtualSystemDescriptionType_License;
+    }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxImportApplianceWgt
+
+VBoxImportApplianceWgt::VBoxImportApplianceWgt (QWidget *aParent)
+    : VBoxApplianceEditorWgt (aParent)
+{
+}
+
+bool VBoxImportApplianceWgt::setFile (const QString& aFile)
+{
+    bool fResult = false;
+    if (!aFile.isEmpty())
+    {
+        CVirtualBox vbox = vboxGlobal().virtualBox();
+        /* Create a appliance object */
+        mAppliance = new CAppliance(vbox.CreateAppliance());
+        fResult = mAppliance->isOk();
+        if (fResult)
+        {
+            /* Read the appliance */
+            CProgress progress = mAppliance->Read (aFile);
+            fResult = mAppliance->isOk();
+            if (fResult)
+            {
+                /* Show some progress, so the user know whats going on */
+                vboxProblem().showModalProgressDialog (progress, tr ("Reading Appliance ..."), this);
+                if (!progress.isOk() || progress.GetResultCode() != 0)
+                {
+                    vboxProblem().cannotImportAppliance (progress, mAppliance, this);
+                    return false;
+                }
+                /* Now we have to interpret that stuff */
+                mAppliance->Interpret();
+                fResult = mAppliance->isOk();
+                if (fResult)
+                {
+                    if (mModel)
+                        delete mModel;
+
+                    QVector<CVirtualSystemDescription> vsds = mAppliance->GetVirtualSystemDescriptions();
+
+                    mModel = new VirtualSystemModel (vsds, this);
+
+                    ImportSortProxyModel *proxy = new ImportSortProxyModel (this);
+                    proxy->setSourceModel (mModel);
+                    proxy->sort (DescriptionSection, Qt::DescendingOrder);
+
+                    VirtualSystemDelegate *delegate = new VirtualSystemDelegate (proxy, this);
+
+                    /* Set our own model */
+                    mTvSettings->setModel (proxy);
+                    /* Set our own delegate */
+                    mTvSettings->setItemDelegate (delegate);
+                    /* For now we hide the original column. This data is displayed as tooltip
+                       also. */
+                    mTvSettings->setColumnHidden (OriginalValueSection, true);
+                    mTvSettings->expandAll();
+
+                    /* Check for warnings & if there are one display them. */
+                    bool fWarningsEnabled = false;
+                    QVector<QString> warnings = mAppliance->GetWarnings();
+                    if (warnings.size() > 0)
+                    {
+                        foreach (const QString& text, warnings)
+                            mWarningTextEdit->append ("- " + text);
+                        fWarningsEnabled = true;
+                    }
+                    mWarningWidget->setShown (fWarningsEnabled);
+                }
+            }
+        }
+        if (!fResult)
+        {
+            vboxProblem().cannotImportAppliance (mAppliance, this);
+            /* Delete the appliance in a case of an error */
+            delete mAppliance;
+            mAppliance = NULL;
+        }
+    }
+    return fResult;
+}
+
+void VBoxImportApplianceWgt::prepareImport()
+{
+    if (mAppliance)
+        mModel->putBack();
+}
+
+bool VBoxImportApplianceWgt::import()
+{
+    if (mAppliance)
+    {
+        /* Start the import asynchronously */
+        CProgress progress;
+        progress = mAppliance->ImportMachines();
+        bool fResult = mAppliance->isOk();
+        if (fResult)
+        {
+            /* Show some progress, so the user know whats going on */
+            vboxProblem().showModalProgressDialog (progress, tr ("Importing Appliance ..."), this);
+            if (!progress.isOk() || progress.GetResultCode() != 0)
+            {
+                vboxProblem().cannotImportAppliance (progress, mAppliance, this);
+                return false;
+            }
+            else
+                return true;
+        }
+        if (!fResult)
+            vboxProblem().cannotImportAppliance (mAppliance, this);
+    }
+    return false;
+}
+
+QList < QPair<QString, QString> > VBoxImportApplianceWgt::licenseAgreements() const
+{
+    QList < QPair<QString, QString> > list;
+
+    CVirtualSystemDescriptionVector vsds = mAppliance->GetVirtualSystemDescriptions();
+    for (int i=0; i < vsds.size(); ++i)
+    {
+        QVector<QString> license;
+        license = vsds[i].GetValuesByType (KVirtualSystemDescriptionType_License,
+                                           KVirtualSystemDescriptionValueType_Original);
+        if (!license.isEmpty())
+        {
+            QVector<QString> name;
+            name = vsds[i].GetValuesByType (KVirtualSystemDescriptionType_Name,
+                                            KVirtualSystemDescriptionValueType_Auto);
+            list << QPair<QString, QString> (name.first(), license.first());
+        }
+    }
+
+    return list;
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxImportApplianceWgt.h	(revision 25178)
@@ -0,0 +1,44 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxImportApplianceWgt class declaration
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxImportApplianceWgt_h__
+#define __VBoxImportApplianceWgt_h__
+
+/* VBox includes */
+#include "VBoxApplianceEditorWgt.h"
+
+class VBoxImportApplianceWgt : public VBoxApplianceEditorWgt
+{
+    Q_OBJECT;
+
+public:
+    VBoxImportApplianceWgt (QWidget *aParent);
+
+    bool setFile (const QString& aFile);
+    void prepareImport();
+    bool import();
+
+    QList < QPair <QString, QString> > licenseAgreements() const;
+};
+
+#endif /* __VBoxImportApplianceWgt_h__ */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.cpp	(revision 25178)
@@ -0,0 +1,122 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxLineTextEdit class definitions
+ */
+
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* VBox includes */
+#include "VBoxGlobal.h"
+#include "VBoxLineTextEdit.h"
+#include "QIFileDialog.h"
+
+/* Qt includes */
+#include <QDialogButtonBox>
+#include <QFile>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QTextEdit>
+#include <QTextStream>
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxTextEditor
+
+VBoxTextEditor::VBoxTextEditor (QWidget *aParent /* = NULL */)
+  : QIWithRetranslateUI<QIDialog> (aParent)
+{
+    QVBoxLayout *mainLayout = new QVBoxLayout (this);
+    mainLayout->setMargin (12);
+
+    /* We need a text editor */
+    mTextEdit = new QTextEdit (this);
+    mainLayout->addWidget (mTextEdit);
+    /* and some buttons to interact with */
+    mButtonBox = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
+    mOpenBtn = new QPushButton (this);
+    mButtonBox->addButton (mOpenBtn, QDialogButtonBox::ActionRole);
+    mainLayout->addWidget (mButtonBox);
+    /* Connect the buttons so that they are useful */
+    connect (mButtonBox, SIGNAL (accepted()),
+             this, SLOT (accept()));
+    connect (mButtonBox, SIGNAL (rejected()),
+             this, SLOT (reject()));
+    connect (mOpenBtn, SIGNAL (clicked()),
+             this, SLOT (open()));
+
+    /* Applying language settings */
+    retranslateUi();
+}
+
+void VBoxTextEditor::setText (const QString& aText)
+{
+    mTextEdit->setText (aText);
+}
+
+QString VBoxTextEditor::text() const
+{
+    return mTextEdit->toPlainText();
+}
+
+void VBoxTextEditor::retranslateUi()
+{
+    setWindowTitle (tr ("Edit text"));
+    mOpenBtn->setText (tr ("&Replace..."));
+    mOpenBtn->setToolTip (tr ("Replaces the current text with the content of a file."));
+}
+
+void VBoxTextEditor::open()
+{
+    QString fileName = QIFileDialog::getOpenFileName (vboxGlobal().documentsPath(), tr("Text (*.txt);;All (*.*)"), this, tr("Select a file to open..."));
+    if (!fileName.isEmpty())
+    {
+        QFile file (fileName);
+        if (file.open(QFile::ReadOnly))
+        {
+            QTextStream in (&file);
+            mTextEdit->setPlainText (in.readAll());
+        }
+    }
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxLineTextEdit
+
+VBoxLineTextEdit::VBoxLineTextEdit (QWidget *aParent /* = NULL */)
+  : QIWithRetranslateUI<QPushButton> (aParent)
+{
+    connect (this, SIGNAL (clicked()),
+             this, SLOT (edit()));
+
+    setFocusPolicy (Qt::StrongFocus);
+    retranslateUi();
+}
+
+void VBoxLineTextEdit::retranslateUi()
+{
+    QPushButton::setText (tr ("&Edit"));
+}
+
+void VBoxLineTextEdit::edit()
+{
+    VBoxTextEditor te (this);
+    te.setText (mText);
+    if (te.exec() == QDialog::Accepted)
+        mText = te.text();
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxLineTextEdit.h	(revision 25178)
@@ -0,0 +1,88 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxLineTextEdit class declaration
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxLineTextEdit_h__
+#define __VBoxLineTextEdit_h__
+
+/* VBox includes */
+#include "QIDialog.h"
+#include "QIWithRetranslateUI.h"
+
+/* Qt includes */
+#include <QPushButton>
+
+/* Qt forward declarations */
+class QTextEdit;
+class QDialogButtonBox;
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxTextEditor
+
+class VBoxTextEditor: public QIWithRetranslateUI<QIDialog>
+{
+    Q_OBJECT;
+
+public:
+    VBoxTextEditor (QWidget *aParent = NULL);
+
+    void setText (const QString& aText);
+    QString text() const;
+
+protected:
+    void retranslateUi();
+
+private slots:
+    void open();
+
+private:
+    /* Private member vars */
+    QTextEdit *mTextEdit;
+    QDialogButtonBox *mButtonBox;
+    QPushButton *mOpenBtn;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// VBoxLineTextEdit
+
+class VBoxLineTextEdit: public QIWithRetranslateUI<QPushButton>
+{
+    Q_OBJECT;
+
+public:
+    VBoxLineTextEdit (QWidget *aParent = NULL);
+
+    void setText (const QString& aText) { mText = aText; }
+    QString text() const { return mText; }
+
+protected:
+    void retranslateUi();
+
+private slots:
+    void edit();
+
+private:
+    /* Private member vars */
+    QString mText;
+};
+
+#endif /* __VBoxLineTextEdit_h__ */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.cpp	(revision 25178)
@@ -0,0 +1,336 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxMediaComboBox 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 "VBoxMediaComboBox.h"
+
+#include <QFileInfo>
+#include <QDir>
+#include <QAbstractItemView>
+
+VBoxMediaComboBox::VBoxMediaComboBox (QWidget *aParent)
+    : QComboBox (aParent)
+    , mType (VBoxDefs::MediumType_Invalid)
+    , mLastId (QString::null)
+    , mShowDiffs (false)
+    , mShowNullItem (false)
+    , mMachineId (QString::null)
+{
+    /* Setup the elide mode */
+    view()->setTextElideMode (Qt::ElideRight);
+    QSizePolicy sp1 (QSizePolicy::Ignored, QSizePolicy::Fixed, QSizePolicy::ComboBox);
+    sp1.setHorizontalStretch (2);
+    setSizePolicy (sp1);
+
+    /* Setup enumeration handlers */
+    connect (&vboxGlobal(), SIGNAL (mediumEnumStarted()),
+             this, SLOT (mediumEnumStarted()));
+    connect (&vboxGlobal(), SIGNAL (mediumEnumerated (const VBoxMedium &)),
+             this, SLOT (mediumEnumerated (const VBoxMedium &)));
+
+    /* Setup update handlers */
+    connect (&vboxGlobal(), SIGNAL (mediumAdded (const VBoxMedium &)),
+             this, SLOT (mediumAdded (const VBoxMedium &)));
+    connect (&vboxGlobal(), SIGNAL (mediumUpdated (const VBoxMedium &)),
+             this, SLOT (mediumUpdated (const VBoxMedium &)));
+    connect (&vboxGlobal(), SIGNAL (mediumRemoved (VBoxDefs::MediumType, const QString &)),
+             this, SLOT (mediumRemoved (VBoxDefs::MediumType, const QString &)));
+
+    /* Setup other connections */
+    connect (this, SIGNAL (activated (int)),
+             this, SLOT (processActivated (int)));
+    connect (view(), SIGNAL (entered (const QModelIndex&)),
+             this, SLOT (processOnItem (const QModelIndex&)));
+}
+
+/**
+ * Fills this combobox with the current media list.
+ */
+void VBoxMediaComboBox::refresh()
+{
+    /* Clearing lists */
+    clear(), mMedia.clear();
+
+    VBoxMediaList list (vboxGlobal().currentMediaList());
+    foreach (VBoxMedium medium, list)
+        mediumAdded (medium);
+
+    /* If at least one real medium present, process null medium */
+    if (count() > 1 && (!mShowNullItem || mType == VBoxDefs::MediumType_HardDisk))
+    {
+        removeItem (0);
+        mMedia.erase (mMedia.begin());
+    }
+
+    /* Inform the interested parties about the possibly changed active item's
+     * icon, text, tooltip etc. */
+    emit activated (currentIndex());
+}
+
+/**
+ * Requests the global media list enumeration and repopulates the list with its
+ * results.
+ */
+void VBoxMediaComboBox::repopulate()
+{
+    if (!vboxGlobal().isMediaEnumerationStarted())
+        vboxGlobal().startEnumeratingMedia();
+    else
+        refresh();
+}
+
+QString VBoxMediaComboBox::id (int aIndex /*= -1*/) const
+{
+    AssertReturn (aIndex == -1 ||
+                  (aIndex >= 0 && aIndex < mMedia.size()),
+                  QString::null);
+
+    if (aIndex == -1) aIndex = currentIndex();
+    return aIndex == -1 ? QString::null : mMedia [aIndex].id;
+}
+
+QString VBoxMediaComboBox::location (int aIndex /*= -1*/) const
+{
+    AssertReturn (aIndex == -1 ||
+                  (aIndex >= 0 && aIndex < mMedia.size()),
+                  QString::null);
+
+    if (aIndex == -1) aIndex = currentIndex();
+    return aIndex == -1 ? QString::null : mMedia [aIndex].location;
+}
+
+void VBoxMediaComboBox::setCurrentItem (const QString &aId)
+{
+    mLastId = aId;
+
+    int index;
+    if (findMediaIndex (aId, index))
+    {
+        /* Note that the media combobox may be not populated here yet, so we
+         * don't assert */
+        QComboBox::setCurrentIndex (index);
+        emit activated (index);
+    }
+}
+
+void VBoxMediaComboBox::setType (VBoxDefs::MediumType aType)
+{
+    mType = aType;
+}
+
+void VBoxMediaComboBox::setMachineId (const QString &aMachineId)
+{
+    mMachineId = aMachineId;
+}
+
+void VBoxMediaComboBox::setNullItemPresent (bool aNullItemPresent)
+{
+    mShowNullItem = aNullItemPresent;
+}
+
+/**
+ * Enables or disables the "show diffs" mode.
+ *
+ * In disabled "show diffs" mode, this combobox will only include base hard
+ * disks plus differencing hard disks that are attached to the associated
+ * machine passed to the constructor in the current state (if any). Note
+ * that for these differencing hard disks, the details of their base hard disks
+ * are shown instead of their own details (human-friendly mode).
+ *
+ * In enabled "show diffs" mode, all hard disks, base and differencing, are
+ * shown.
+ *
+ * Note that you must call #refresh() in order for this change to take effect.
+ *
+ * @param aShowDiffs    @c true to enable "show diffs" mode.
+ */
+void VBoxMediaComboBox::setShowDiffs (bool aShowDiffs)
+{
+    AssertReturnVoid (aShowDiffs == true || !mMachineId.isNull());
+
+    mShowDiffs = aShowDiffs;
+}
+
+
+void VBoxMediaComboBox::mediumEnumStarted()
+{
+    refresh();
+}
+
+void VBoxMediaComboBox::mediumEnumerated (const VBoxMedium &aMedium)
+{
+    mediumUpdated (aMedium);
+}
+
+void VBoxMediaComboBox::mediumAdded (const VBoxMedium &aMedium)
+{
+    if (aMedium.isNull() || aMedium.type() == mType)
+    {
+        if (!mShowDiffs && aMedium.type() == VBoxDefs::MediumType_HardDisk)
+        {
+            if (aMedium.parent() != NULL)
+            {
+                /* In !mShowDiffs mode, we ignore all diffs except ones that are
+                 * directly attached to the related VM in the current state */
+                if (!aMedium.isAttachedInCurStateTo (mMachineId))
+                    return;
+            }
+        }
+
+        appendItem (aMedium);
+
+        /* Activate the required item if there is any */
+        if (aMedium.id() == mLastId)
+            setCurrentItem (aMedium.id());
+        /* Select last added item if there is no item selected */
+        else if (currentText().isEmpty())
+            QComboBox::setCurrentIndex (count() - 1);
+    }
+}
+
+void VBoxMediaComboBox::mediumUpdated (const VBoxMedium &aMedium)
+{
+    if (aMedium.isNull() || aMedium.type() == mType)
+    {
+        int index;
+        if (!findMediaIndex (aMedium.id(), index))
+            return;
+
+        replaceItem (index, aMedium);
+
+        /* Emit the signal to ensure the parent dialog handles the change of
+         * the selected item's data */
+        emit activated (currentIndex());
+    }
+}
+
+void VBoxMediaComboBox::mediumRemoved (VBoxDefs::MediumType aType,
+                                       const QString &aId)
+{
+    if (mType != aType)
+        return;
+
+    int index;
+    if (!findMediaIndex (aId, index))
+        return;
+
+    removeItem (index);
+    mMedia.erase (mMedia.begin() + index);
+
+    /* If no real medium left, add the null medium */
+    if (count() == 0)
+        mediumAdded (VBoxMedium());
+
+    /* Emit the signal to ensure the parent dialog handles the change of
+     * the selected item */
+    emit activated (currentIndex());
+}
+
+
+void VBoxMediaComboBox::processActivated (int aIndex)
+{
+    AssertReturnVoid (aIndex >= 0 && aIndex < mMedia.size());
+
+    mLastId = mMedia [aIndex].id;
+
+    updateToolTip (aIndex);
+}
+
+void VBoxMediaComboBox::updateToolTip (int aIndex)
+{
+    /* Set the combobox tooltip */
+    setToolTip (QString::null);
+    if (aIndex >= 0 && aIndex < mMedia.size())
+        setToolTip (mMedia [aIndex].toolTip);
+}
+
+void VBoxMediaComboBox::processOnItem (const QModelIndex &aIndex)
+{
+    /* Set the combobox item's tooltip */
+    int index = aIndex.row();
+    view()->viewport()->setToolTip (QString::null);
+    view()->viewport()->setToolTip (mMedia [index].toolTip);
+}
+
+
+void VBoxMediaComboBox::appendItem (const VBoxMedium &aMedium)
+{
+    if (!mShowDiffs && aMedium.parent() != NULL)
+    {
+        /* We are adding the direct machine diff in !mShowDiffs mode. Since its
+         * base hard disk has been already appended (enumerated before), we want
+         * to replace the base with the diff to avoid shownig both (both would
+         * be labeled using the base filename and therefore look like
+         * duplicates). Note though that these visual duplicates are still
+         * possible in !mShowDiffs mode if the same base hard disk is attached*
+         * to the VM through different diffs (this is why we don't assert
+         * below on findMediaIndex() == true). However, this situation is
+         * unavoidable so we accept it assuming that the user will switch to
+           mShowDiffs mode if he needs clarity. */
+        int index;
+        if (findMediaIndex (aMedium.root().id(), index))
+        {
+            replaceItem (index, aMedium);
+            return;
+        }
+    }
+
+    mMedia.append (Medium (aMedium.id(), aMedium.location(),
+                           aMedium.toolTipCheckRO (!mShowDiffs, mShowNullItem && mType != VBoxDefs::MediumType_HardDisk)));
+
+    insertItem (count(), aMedium.iconCheckRO (!mShowDiffs),
+                aMedium.details (!mShowDiffs));
+}
+
+void VBoxMediaComboBox::replaceItem (int aIndex, const VBoxMedium &aMedium)
+{
+    AssertReturnVoid (aIndex >= 0 && aIndex < mMedia.size());
+
+    mMedia [aIndex].id = aMedium.id();
+    mMedia [aIndex].location = aMedium.location();
+    mMedia [aIndex].toolTip = aMedium.toolTipCheckRO (!mShowDiffs, mShowNullItem && mType != VBoxDefs::MediumType_HardDisk);
+
+    setItemText (aIndex, aMedium.details (!mShowDiffs));
+    setItemIcon (aIndex, aMedium.iconCheckRO (!mShowDiffs));
+
+    if (aIndex == currentIndex())
+        updateToolTip (aIndex);
+}
+
+/**
+ * Searches for a medium with the given ID in mMedia and stores its index in @a
+ * aIndex. Returns @c true if the media was found and @c false otherwise (@a
+ * aIndex will be set to a value >= mMedia.size() in this case).
+ *
+ * @param aId       Media ID to search for.
+ * @param aIndex    Where to store the found media index.
+ */
+bool VBoxMediaComboBox::findMediaIndex (const QString &aId, int &aIndex)
+{
+    aIndex = 0;
+
+    for (; aIndex < mMedia.size(); ++ aIndex)
+        if (mMedia [aIndex].id == aId)
+            break;
+
+    return aIndex < mMedia.size();
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMediaComboBox.h	(revision 25178)
@@ -0,0 +1,105 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxMediaComboBox 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 __VBoxMediaComboBox_h__
+#define __VBoxMediaComboBox_h__
+
+#include "VBoxGlobal.h"
+
+#include <QComboBox>
+#include <QPixmap>
+
+class VBoxMediaComboBox : public QComboBox
+{
+    Q_OBJECT
+
+public:
+
+    typedef QMap <QString, QString> BaseToDiffMap;
+
+    VBoxMediaComboBox (QWidget *aParent);
+
+    void refresh();
+    void repopulate();
+
+    QString id (int = -1) const;
+    QString location (int = -1) const;
+    VBoxDefs::MediumType type() const { return mType; }
+
+    void setCurrentItem (const QString &aItemId);
+    void setType (VBoxDefs::MediumType aMediumType);
+    void setMachineId (const QString &aMachineId = QString::null);
+    void setNullItemPresent (bool aNullItemPresent);
+
+    void setShowDiffs (bool aShowDiffs);
+    bool showDiffs() const { return mShowDiffs; }
+
+protected slots:
+
+    void mediumEnumStarted();
+    void mediumEnumerated (const VBoxMedium &);
+
+    void mediumAdded (const VBoxMedium &);
+    void mediumUpdated (const VBoxMedium &);
+    void mediumRemoved (VBoxDefs::MediumType, const QString &);
+
+    void processActivated (int aIndex);
+//    void processIndexChanged (int aIndex);
+
+    void processOnItem (const QModelIndex &aIndex);
+
+protected:
+
+    void updateToolTip (int);
+
+    void appendItem (const VBoxMedium &);
+    void replaceItem (int, const VBoxMedium &);
+
+    bool findMediaIndex (const QString &aId, int &aIndex);
+
+    VBoxDefs::MediumType mType;
+
+    /** Obtruncated VBoxMedium structure. */
+    struct Medium
+    {
+        Medium() {}
+        Medium (const QString &aId, const QString &aLocation,
+                const QString aToolTip)
+            : id (aId), location (aLocation), toolTip (aToolTip) {}
+
+        QString id;
+        QString location;
+        QString toolTip;
+    };
+
+    typedef QVector <Medium> Media;
+    Media mMedia;
+
+    QString mLastId;
+
+    bool mShowDiffs : 1;
+    bool mShowNullItem : 1;
+
+    QString mMachineId;
+};
+
+#endif /* __VBoxMediaComboBox_h__ */
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.cpp	(revision 25178)
@@ -0,0 +1,417 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxMiniToolBar class declaration & implementation. This is the toolbar shown on fullscreen mode.
+ */
+
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* VBox includes */
+#include "VBoxGlobal.h"
+#include "VBoxMiniToolBar.h"
+
+/* Qt includes */
+#include <QCursor>
+#include <QDesktopWidget>
+#include <QLabel>
+#include <QMenu>
+#include <QPainter>
+#include <QPaintEvent>
+#include <QPolygon>
+#include <QRect>
+#include <QRegion>
+#include <QTimer>
+#include <QToolButton>
+
+VBoxMiniToolBar::VBoxMiniToolBar (QWidget *aParent, Alignment aAlignment, bool aActive, bool aAutoHide)
+    : VBoxToolBar (aParent)
+    , mActive (aActive)
+    , mPolished (false)
+    , mSeamless (false)
+    , mAutoHide (aAutoHide)
+    , mSlideToScreen (true)
+    , mHideAfterSlide (false)
+    , mAutoHideCounter (0)
+    , mAlignment (aAlignment)
+    , mAnimated (true)
+    , mScrollDelay (10)
+    , mAutoScrollDelay (100)
+    , mAutoHideTotalCounter (10)
+{
+    AssertMsg (parentWidget(), ("Parent widget must be set!!!\n"));
+
+    /* Various options */
+    setIconSize (QSize (16, 16));
+    setMouseTracking (mAutoHide);
+    setVisible (false);
+
+    /* Left margin of tool-bar */
+    mMargins << widgetForAction (addWidget (new QWidget (this)));
+
+    /* Add pushpin */
+    mAutoHideAct = new QAction (this);
+    mAutoHideAct->setIcon (VBoxGlobal::iconSet (":/pin_16px.png"));
+    mAutoHideAct->setToolTip (tr ("Always show the toolbar"));
+    mAutoHideAct->setCheckable (true);
+    mAutoHideAct->setChecked (!mAutoHide);
+    connect (mAutoHideAct, SIGNAL (toggled (bool)), this, SLOT (togglePushpin (bool)));
+    addAction (mAutoHideAct);
+
+    /* Left menu margin */
+    mSpacings << widgetForAction (addWidget (new QWidget (this)));
+
+    /* Right menu margin */
+    mInsertPosition = addWidget (new QWidget (this));
+    mSpacings << widgetForAction (mInsertPosition);
+
+    /* Left label margin */
+    mLabelMargins << widgetForAction (addWidget (new QWidget (this)));
+
+    /* Insert a label for VM Name */
+    mDisplayLabel = new QLabel (this);
+    mDisplayLabel->setAlignment (Qt::AlignCenter);
+    addWidget (mDisplayLabel);
+
+    /* Right label margin */
+    mLabelMargins << widgetForAction (addWidget (new QWidget (this)));
+
+    /* Exit action */
+    QAction *restoreAct = new QAction (this);
+    restoreAct->setIcon (VBoxGlobal::iconSet (":/restore_16px.png"));
+    restoreAct->setToolTip (tr ("Exit Full Screen or Seamless Mode"));
+    connect (restoreAct, SIGNAL (triggered()), this, SIGNAL (exitAction()));
+    addAction (restoreAct);
+
+    /* Close action */
+    QAction *closeAct = new QAction (this);
+    closeAct->setIcon (VBoxGlobal::iconSet (":/close_16px.png"));
+    closeAct->setToolTip (tr ("Close VM"));
+    connect (closeAct, SIGNAL (triggered()), this, SIGNAL (closeAction()));
+    addAction (closeAct);
+
+    /* Right margin of tool-bar */
+    mMargins << widgetForAction (addWidget (new QWidget (this)));
+}
+
+VBoxMiniToolBar& VBoxMiniToolBar::operator<< (QList <QMenu*> aMenus)
+{
+    for (int i = 0; i < aMenus.size(); ++ i)
+    {
+        QAction *action = aMenus [i]->menuAction();
+        insertAction (mInsertPosition, action);
+        if (QToolButton *button = qobject_cast <QToolButton*> (widgetForAction (action)))
+        {
+            button->setPopupMode (QToolButton::InstantPopup);
+            button->setAutoRaise (true);
+        }
+        if (i != aMenus.size() - 1)
+            mSpacings << widgetForAction (insertWidget (mInsertPosition, new QWidget (this)));
+    }
+    return *this;
+}
+
+void VBoxMiniToolBar::setSeamlessMode (bool aSeamless)
+{
+    mSeamless = aSeamless;
+}
+
+/* Update the display text, usually the VM Name */
+void VBoxMiniToolBar::setDisplayText (const QString &aText)
+{
+    if (mDisplayLabel->text() != aText)
+    {
+        /* Update toolbar label */
+        mDisplayLabel->setText (aText);
+
+        /* Reinitialize */
+        initialize();
+
+        if (!isHidden())
+            updateDisplay (!mAutoHide, false);
+    }
+}
+
+bool VBoxMiniToolBar::isAutoHide() const
+{
+    return mAutoHide;
+}
+
+void VBoxMiniToolBar::updateDisplay (bool aShow, bool aSetHideFlag)
+{
+    mAutoHideCounter = 0;
+
+    setMouseTracking (mAutoHide);
+
+    if (aShow)
+    {
+        if (isHidden())
+            moveToBase();
+
+        if (mAnimated)
+        {
+            if (aSetHideFlag)
+            {
+                mHideAfterSlide = false;
+                mSlideToScreen = true;
+            }
+            if (mActive) show();
+            mScrollTimer.start (mScrollDelay, this);
+        }
+        else if (mActive) show();
+
+        if (mAutoHide)
+            mAutoScrollTimer.start (mAutoScrollDelay, this);
+        else
+            mAutoScrollTimer.stop();
+    }
+    else
+    {
+        if (mAnimated)
+        {
+            if (aSetHideFlag)
+            {
+                mHideAfterSlide = true;
+                mSlideToScreen = false;
+            }
+            mScrollTimer.start (mScrollDelay, this);
+        }
+        else
+            hide();
+
+        if (mAutoHide)
+            mAutoScrollTimer.start (mAutoScrollDelay, this);
+        else
+            mAutoScrollTimer.stop();
+    }
+}
+
+void VBoxMiniToolBar::mouseMoveEvent (QMouseEvent *aEvent)
+{
+    if (!mHideAfterSlide)
+    {
+        mSlideToScreen = true;
+        mScrollTimer.start (mScrollDelay, this);
+    }
+
+    QToolBar::mouseMoveEvent (aEvent);
+}
+
+/* Handles auto hide feature of the toolbar */
+void VBoxMiniToolBar::timerEvent (QTimerEvent *aEvent)
+{
+    if (aEvent->timerId() == mScrollTimer.timerId())
+    {
+        QRect screen = mSeamless ? QApplication::desktop()->availableGeometry (window()) :
+                                   QApplication::desktop()->screenGeometry (window());
+        switch (mAlignment)
+        {
+            case AlignTop:
+            {
+                if (((mPositionY == screen.y()) && mSlideToScreen) ||
+                    ((mPositionY == screen.y() - height() + 1) && !mSlideToScreen))
+                {
+                    mScrollTimer.stop();
+                    if (mHideAfterSlide)
+                    {
+                        mHideAfterSlide = false;
+                        hide();
+                    }
+                    return;
+                }
+                mSlideToScreen ? ++ mPositionY : -- mPositionY;
+                break;
+            }
+            case AlignBottom:
+            {
+                if (((mPositionY == screen.y() + screen.height() - height()) && mSlideToScreen) ||
+                    ((mPositionY == screen.y() + screen.height() - 1) && !mSlideToScreen))
+                {
+                    mScrollTimer.stop();
+                    if (mHideAfterSlide)
+                    {
+                        mHideAfterSlide = false;
+                        hide();
+                    }
+                    return;
+                }
+                mSlideToScreen ? -- mPositionY : ++ mPositionY;
+                break;
+            }
+            default:
+                break;
+        }
+        move (mapFromScreen (QPoint (mPositionX, mPositionY)));
+        emit geometryUpdated();
+    }
+    else if (aEvent->timerId() == mAutoScrollTimer.timerId())
+    {
+        QRect rect = this->rect();
+        QPoint cursor_pos = QCursor::pos();
+        QPoint p = mapFromGlobal (cursor_pos);
+
+        if (!rect.contains (p))
+        {
+            ++ mAutoHideCounter;
+
+            if (mAutoHideCounter == mAutoHideTotalCounter)
+            {
+                mSlideToScreen = false;
+                mScrollTimer.start (mScrollDelay, this);
+            }
+        }
+        else
+            mAutoHideCounter = 0;
+    }
+    else
+        QWidget::timerEvent (aEvent);
+}
+
+void VBoxMiniToolBar::showEvent (QShowEvent *aEvent)
+{
+    if (!mPolished)
+    {
+        /* Tool-bar margins */
+        foreach (QWidget *margin, mMargins)
+            margin->setMinimumWidth (height());
+
+        /* Tool-bar spacings */
+        foreach (QWidget *spacing, mSpacings)
+            spacing->setMinimumWidth (5);
+
+        /* Title spacings */
+        foreach (QWidget *lableMargin, mLabelMargins)
+            lableMargin->setMinimumWidth (15);
+
+        /* Initialize */
+        initialize();
+
+        mPolished = true;
+    }
+
+    VBoxToolBar::showEvent (aEvent);
+}
+
+void VBoxMiniToolBar::paintEvent (QPaintEvent *aEvent)
+{
+    QPainter painter;
+    painter.begin (this);
+    painter.fillRect (aEvent->rect(), palette().brush (QPalette::Window));
+    painter.end();
+    VBoxToolBar::paintEvent (aEvent);
+}
+
+void VBoxMiniToolBar::togglePushpin (bool aOn)
+{
+    mAutoHide = !aOn;
+    updateDisplay (!mAutoHide, false);
+}
+
+void VBoxMiniToolBar::initialize()
+{
+    /* Resize to sizehint */
+    resize (sizeHint());
+
+    /* Update geometry */
+    recreateMask();
+    moveToBase();
+}
+
+void VBoxMiniToolBar::recreateMask()
+{
+    int edgeShift = height();
+    int points [8];
+    switch (mAlignment)
+    {
+        case AlignTop:
+        {
+            points [0] = 0;
+            points [1] = 0;
+
+            points [2] = edgeShift;
+            points [3] = height();
+
+            points [4] = width() - edgeShift;
+            points [5] = height();
+
+            points [6] = width();
+            points [7] = 0;
+
+            break;
+        }
+        case AlignBottom:
+        {
+            points [0] = edgeShift;
+            points [1] = 0;
+
+            points [2] = 0;
+            points [3] = height();
+
+            points [4] = width();
+            points [5] = height();
+
+            points [6] = width() - edgeShift;
+            points [7] = 0;
+
+            break;
+        }
+        default:
+            break;
+    }
+    /* Make sure any old mask is removed first */
+    clearMask();
+    /* Set the new mask */
+    QPolygon polygon;
+    polygon.setPoints (4, points);
+    setMask (polygon);
+}
+
+void VBoxMiniToolBar::moveToBase()
+{
+    QRect screen = mSeamless ? QApplication::desktop()->availableGeometry (window()) :
+                               QApplication::desktop()->screenGeometry (window());
+    mPositionX = screen.x() + screen.width() / 2 - width() / 2;
+    switch (mAlignment)
+    {
+        case AlignTop:
+        {
+            mPositionY = screen.y() - height() + 1;
+            break;
+        }
+        case AlignBottom:
+        {
+            mPositionY = screen.y() + screen.height() - 1;
+            break;
+        }
+        default:
+        {
+            mPositionY = 0;
+            break;
+        }
+    }
+    move (mapFromScreen (QPoint (mPositionX, mPositionY)));
+}
+
+QPoint VBoxMiniToolBar::mapFromScreen (const QPoint &aPoint)
+{
+    QPoint globalPosition = parentWidget()->mapFromGlobal (aPoint);
+    QRect fullArea = QApplication::desktop()->screenGeometry (window());
+    QRect realArea = mSeamless ? QApplication::desktop()->availableGeometry (window()) :
+                                 QApplication::desktop()->screenGeometry (window());
+    QPoint shiftToReal (realArea.topLeft() - fullArea.topLeft());
+    return globalPosition + shiftToReal;
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.h	(revision 25178)
@@ -0,0 +1,130 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxMiniToolBar class declaration & implementation. This is the toolbar shown on fullscreen mode.
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxMiniToolBar_h__
+#define __VBoxMiniToolBar_h__
+
+/* VBox includes */
+#include <VBoxToolBar.h>
+
+/* Qt includes */
+#include <QBasicTimer>
+
+class QLabel;
+class QMenu;
+
+/**
+ *  The VBoxMiniToolBar class is a toolbar shown inside full screen mode or seamless mode.
+ *  It supports auto hiding and animated sliding up/down.
+ */
+class VBoxMiniToolBar : public VBoxToolBar
+{
+    Q_OBJECT;
+
+public:
+
+    enum Alignment
+    {
+        AlignTop,
+        AlignBottom
+    };
+
+    VBoxMiniToolBar (QWidget *aParent, Alignment aAlignment, bool aIsActive, bool aAutoHide);
+
+    VBoxMiniToolBar& operator<< (QList <QMenu*> aMenus);
+
+    void setSeamlessMode (bool aIsSeamless);
+    void setDisplayText (const QString &aText);
+
+    bool isAutoHide() const;
+
+    void updateDisplay (bool aShow, bool aSetHideFlag);
+
+signals:
+
+    void exitAction();
+    void closeAction();
+    void geometryUpdated();
+
+protected:
+
+    void mouseMoveEvent (QMouseEvent *aEvent);
+    void timerEvent (QTimerEvent *aEvent);
+    void showEvent (QShowEvent *aEvent);
+    void paintEvent (QPaintEvent *aEvent);
+
+private slots:
+
+    void togglePushpin (bool aOn);
+
+private:
+
+    void initialize();
+    void recreateMask();
+    void moveToBase();
+    QPoint mapFromScreen (const QPoint &aPoint);
+
+    QAction *mAutoHideAct;
+    QLabel *mDisplayLabel;
+
+    QBasicTimer mScrollTimer;
+    QBasicTimer mAutoScrollTimer;
+
+    bool mActive;
+    bool mPolished;
+    bool mSeamless;
+    bool mAutoHide;
+    bool mSlideToScreen;
+    bool mHideAfterSlide;
+
+    int mAutoHideCounter;
+    int mPositionX;
+    int mPositionY;
+
+    /* Lists of used spacers */
+    QList <QWidget*> mMargins;
+    QList <QWidget*> mSpacings;
+    QList <QWidget*> mLabelMargins;
+
+    /* Menu insert position */
+    QAction *mInsertPosition;
+
+    /* Tool-bar alignment */
+    Alignment mAlignment;
+
+    /* Wether to animate showing/hiding the toolbar */
+    bool mAnimated;
+
+    /* Interval (in milli seconds) for scrolling the toolbar, default is 20 msec */
+    int mScrollDelay;
+
+    /* The wait time while the cursor is not over the window after this amount of time (in msec),
+     * the toolbar will auto hide if autohide is on. The default is 100msec. */
+    int mAutoScrollDelay;
+
+    /* Number of total steps before hiding. If it is 10 then wait 10 (steps) * 100ms (mAutoScrollDelay) = 1000ms delay.
+     * The default is 10. */
+    int mAutoHideTotalCounter;
+};
+
+#endif // __VBoxMiniToolBar_h__
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.cpp	(revision 25178)
@@ -0,0 +1,88 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxOSTypeSelectorButton class implementation
+ */
+
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* VBox includes */
+#include "VBoxOSTypeSelectorButton.h"
+#include "VBoxGlobal.h"
+
+/* Qt includes */
+#include <QMenu>
+#include <QSignalMapper>
+
+VBoxOSTypeSelectorButton::VBoxOSTypeSelectorButton (QWidget *aParent)
+  : QIWithRetranslateUI <QPushButton> (aParent)
+{
+    /* We have to make sure that the button has strong focus, otherwise the
+     * editing is ended when the menu is shown */
+    setFocusPolicy (Qt::StrongFocus);
+    setIconSize (QSize (16, 16));
+    /* Create a signal mapper so that we not have to react to every single
+     * menu activation ourself. */
+    mSignalMapper = new QSignalMapper (this);
+    connect (mSignalMapper, SIGNAL (mapped (const QString &)),
+             this, SLOT (setOSTypeId (const QString &)));
+    mMainMenu = new QMenu (aParent);
+    setMenu (mMainMenu);
+
+    retranslateUi();
+}
+
+void VBoxOSTypeSelectorButton::setOSTypeId (const QString& aOSTypeId)
+{
+    mOSTypeId = aOSTypeId;
+    CGuestOSType type = vboxGlobal().vmGuestOSType (aOSTypeId);
+    /* Looks ugly on the Mac */
+#ifndef Q_WS_MAC
+    setIcon (vboxGlobal().vmGuestOSTypeIcon (type.GetId()));
+#endif /* Q_WS_MAC */
+    setText (type.GetDescription());
+}
+
+bool VBoxOSTypeSelectorButton::isMenuShown() const
+{
+    return mMainMenu->isVisible();
+}
+
+void VBoxOSTypeSelectorButton::retranslateUi()
+{
+    populateMenu();
+}
+
+void VBoxOSTypeSelectorButton::populateMenu()
+{
+    mMainMenu->clear();
+    /* Create a list of all possible OS types */
+    QList <CGuestOSType> families = vboxGlobal().vmGuestOSFamilyList();
+    foreach (const CGuestOSType& family, families)
+    {
+        QMenu *subMenu = mMainMenu->addMenu (family.GetFamilyDescription());
+        QList <CGuestOSType> types = vboxGlobal().vmGuestOSTypeList (family.GetFamilyId());
+        foreach (const CGuestOSType& type, types)
+        {
+            QAction *a = subMenu->addAction (vboxGlobal().vmGuestOSTypeIcon (type.GetId()), type.GetDescription());
+            connect(a, SIGNAL (triggered()),
+                    mSignalMapper, SLOT(map()));
+            mSignalMapper->setMapping (a, type.GetId());
+        }
+    }
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorButton.h	(revision 25178)
@@ -0,0 +1,59 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxOSTypeSelectorButton class declaration
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxOSTypeSelectorButton_h__
+#define __VBoxOSTypeSelectorButton_h__
+
+/* VBox includes */
+#include "QIWithRetranslateUI.h"
+
+/* Qt includes */
+#include <QPushButton>
+
+class QSignalMapper;
+
+class VBoxOSTypeSelectorButton: public QIWithRetranslateUI<QPushButton>
+{
+    Q_OBJECT;
+
+public:
+    VBoxOSTypeSelectorButton (QWidget *aParent);
+    QString osTypeId() const { return mOSTypeId; }
+
+    bool isMenuShown() const;
+
+    void retranslateUi();
+
+public slots:
+    void setOSTypeId (const QString& aOSTypeId);
+
+private:
+    void populateMenu();
+
+    /* Private member vars */
+    QString mOSTypeId;
+    QMenu *mMainMenu;
+    QSignalMapper *mSignalMapper;
+};
+
+#endif /* __VBoxOSTypeSelectorButton_h__ */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.cpp	(revision 25178)
@@ -0,0 +1,229 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxOSTypeSelectorWidget class implementation
+ */
+
+/*
+ * Copyright (C) 2008 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 "VBoxOSTypeSelectorWidget.h"
+
+#include <QComboBox>
+#include <QLabel>
+#include <QVBoxLayout>
+
+enum
+{
+    RoleTypeID = Qt::UserRole + 1
+};
+
+VBoxOSTypeSelectorWidget::VBoxOSTypeSelectorWidget (QWidget *aParent)
+    : QIWithRetranslateUI <QWidget> (aParent)
+    , mTxFamilyName (new QLabel (this))
+    , mTxTypeName (new QLabel (this))
+    , mPxTypeIcon (new QLabel (this))
+    , mCbFamily (new QComboBox (this))
+    , mCbType (new QComboBox (this))
+    , mPolished (false)
+    , mLayoutPosition (-1)
+{
+    /* Setup widgets */
+    mTxFamilyName->setAlignment (Qt::AlignRight);
+    mTxTypeName->setAlignment (Qt::AlignRight);
+    mTxFamilyName->setBuddy (mCbFamily);
+    mTxTypeName->setBuddy (mCbType);
+    mTxFamilyName->setSizePolicy (QSizePolicy::Minimum, QSizePolicy::Fixed);
+    mTxTypeName->setSizePolicy (QSizePolicy::Minimum, QSizePolicy::Fixed);
+    mCbFamily->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed);
+    mCbType->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed);
+    mPxTypeIcon->setFixedSize (32, 32);
+
+    /* Fill OS family selector */
+    int maximumSize = 0;
+    QFontMetrics fm (mCbFamily->font());
+    QList <CGuestOSType> families (vboxGlobal().vmGuestOSFamilyList());
+    for (int i = 0; i < families.size(); ++ i)
+    {
+        /* Search for maximum length among family names */
+        QString familyName (families [i].GetFamilyDescription());
+        maximumSize = maximumSize < fm.width (familyName) ?
+                      fm.width (familyName) : maximumSize;
+        mCbFamily->insertItem (i, familyName);
+        mCbFamily->setItemData (i, families [i].GetFamilyId(), RoleTypeID);
+        /* Search for maximum length among type names */
+        QList <CGuestOSType> types (vboxGlobal().vmGuestOSTypeList (families [i].GetFamilyId()));
+        for (int j = 0; j < types.size(); ++ j)
+        {
+            QString typeName (types [j].GetDescription());
+            maximumSize = maximumSize < fm.width (typeName) ?
+                          fm.width (typeName) : maximumSize;
+        }
+    }
+    mCbFamily->setCurrentIndex (0);
+    onFamilyChanged (mCbFamily->currentIndex());
+
+    /* Set the minimum size for OS Type & Family selectors. */
+    QStyleOptionComboBox options;
+    options.initFrom (mCbFamily);
+    QSize size (style()->sizeFromContents (QStyle::CT_ComboBox, &options,
+                QSize (maximumSize, fm.height()), mCbFamily));
+    mCbFamily->setMinimumWidth (size.width());
+    mCbType->setMinimumWidth (size.width());
+
+    /* Slots connections */
+    connect (mCbFamily, SIGNAL (currentIndexChanged (int)),
+             this, SLOT (onFamilyChanged (int)));
+    connect (mCbType, SIGNAL (currentIndexChanged (int)),
+             this, SLOT (onTypeChanged (int)));
+
+    /* Retranslate */
+    retranslateUi();
+}
+
+void VBoxOSTypeSelectorWidget::setType (const CGuestOSType &aType)
+{
+    QString familyId (aType.GetFamilyId());
+    QString typeId (aType.GetId());
+
+    int familyIndex = mCbFamily->findData (familyId, RoleTypeID);
+    AssertMsg (familyIndex != -1, ("Family ID should be valid: '%s'", familyId.toLatin1().constData()));
+    if (familyIndex != -1)
+        mCbFamily->setCurrentIndex (familyIndex);
+
+    int typeIndex = mCbType->findData (typeId, RoleTypeID);
+    AssertMsg (typeIndex != -1, ("Type ID should be valid: '%s'", typeId.toLatin1().constData()));
+    if (typeIndex != -1)
+        mCbType->setCurrentIndex (typeIndex);
+}
+
+CGuestOSType VBoxOSTypeSelectorWidget::type() const
+{
+    return mType;
+}
+
+void VBoxOSTypeSelectorWidget::setLayoutPosition (int aPos)
+{
+    mLayoutPosition = aPos;
+}
+
+void VBoxOSTypeSelectorWidget::retranslateUi()
+{
+    mTxFamilyName->setText (tr ("Operating &System:"));
+    mCbFamily->setWhatsThis (tr ("Displays the operating system family that "
+                                 "you plan to install into this virtual machine."));
+    mTxTypeName->setText (tr ("&Version:"));
+    mCbType->setWhatsThis (tr ("Displays the operating system type that "
+                               "you plan to install into this virtual "
+                               "machine (called a guest operating system)."));
+}
+
+void VBoxOSTypeSelectorWidget::showEvent (QShowEvent *aEvent)
+{
+    if (!mPolished)
+    {
+        /* Finally polishing just before first show event */
+        mPolished = true;
+
+        /* Layouting widgets */
+        QVBoxLayout *layout1 = new QVBoxLayout();
+        layout1->setSpacing (0);
+        layout1->addWidget (mPxTypeIcon);
+        layout1->addStretch();
+
+        QGridLayout *layout2 = layout() ? static_cast <QGridLayout*> (layout()) :
+                                          new QGridLayout (this);
+        layout2->setMargin (0);
+        int row = mLayoutPosition == -1 ? layout2->rowCount() : mLayoutPosition;
+        layout2->addWidget (mTxFamilyName, row, 0);
+        layout2->addWidget (mCbFamily, row, 1);
+        layout2->addWidget (mTxTypeName, row + 1, 0);
+        layout2->addWidget (mCbType, row + 1, 1);
+        layout2->addLayout (layout1, row, 2, 2, 1);
+    }
+    QIWithRetranslateUI <QWidget>::showEvent (aEvent);
+}
+
+void VBoxOSTypeSelectorWidget::onFamilyChanged (int aIndex)
+{
+    /* Lock the signals of mCbType to prevent it's reaction on clearing */
+    mCbType->blockSignals (true);
+    mCbType->clear();
+
+    /* Check if host supports (AMD-V or VT-x) and long mode */
+    CHost host = vboxGlobal().virtualBox().GetHost();
+    bool mSupportsHWVirtEx = host.GetProcessorFeature (KProcessorFeature_HWVirtEx);
+    bool mSupportsLongMode = host.GetProcessorFeature (KProcessorFeature_LongMode);
+
+    /* Populate combo-box with OS Types related to currently selected Family ID */
+    QString familyId (mCbFamily->itemData (aIndex, RoleTypeID).toString());
+    QList <CGuestOSType> types (vboxGlobal().vmGuestOSTypeList (familyId));
+    for (int i = 0; i < types.size(); ++ i)
+    {
+        if (types [i].GetIs64Bit() && (!mSupportsHWVirtEx || !mSupportsLongMode))
+            continue;
+        int index = mCbType->count();
+        mCbType->insertItem (index, types [i].GetDescription());
+        mCbType->setItemData (index, types [i].GetId(), RoleTypeID);
+    }
+
+    /* Select the most recently chosen item */
+    if (mCurrentIds.contains (familyId))
+    {
+        QString typeId (mCurrentIds [familyId]);
+        int typeIndex = mCbType->findData (typeId, RoleTypeID);
+        if (typeIndex != -1)
+            mCbType->setCurrentIndex (typeIndex);
+    }
+    /* Or select WinXP item for Windows family as default */
+    else if (familyId == "Windows")
+    {
+        int xpIndex = mCbType->findData ("WindowsXP", RoleTypeID);
+        if (xpIndex != -1)
+            mCbType->setCurrentIndex (xpIndex);
+    }
+    /* Or select Ubuntu item for Linux family as default */
+    else if (familyId == "Linux")
+    {
+        int ubIndex = mCbType->findData ("Ubuntu", RoleTypeID);
+        if (ubIndex != -1)
+            mCbType->setCurrentIndex (ubIndex);
+    }
+    /* Else simply select the first one present */
+    else mCbType->setCurrentIndex (0);
+
+    /* Update all the stuff with new type */
+    onTypeChanged (mCbType->currentIndex());
+
+    /* Unlock the signals of mCbType */
+    mCbType->blockSignals (false);
+}
+
+void VBoxOSTypeSelectorWidget::onTypeChanged (int aIndex)
+{
+    /* Save the new selected OS Type */
+    mType = vboxGlobal().vmGuestOSType (
+        mCbType->itemData (aIndex, RoleTypeID).toString(),
+        mCbFamily->itemData (mCbFamily->currentIndex(), RoleTypeID).toString());
+    mPxTypeIcon->setPixmap (vboxGlobal().vmGuestOSTypeIcon (mType.GetId()));
+
+    /* Save the most recently used item */
+    mCurrentIds [mType.GetFamilyId()] = mType.GetId();
+
+    /* Notify connected objects about type was changed */
+    emit osTypeChanged();
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxOSTypeSelectorWidget.h	(revision 25178)
@@ -0,0 +1,78 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxOSTypeSelectorWidget class declaration
+ */
+
+/*
+ * Copyright (C) 2008 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 __VBoxOSTypeSelectorWidget_h__
+#define __VBoxOSTypeSelectorWidget_h__
+
+#include "QIWithRetranslateUI.h"
+#include "VBoxGlobal.h"
+
+#include <QWidget>
+
+class QComboBox;
+class CGuestOSType;
+class QLabel;
+
+class VBoxOSTypeSelectorWidget : public QIWithRetranslateUI <QWidget>
+{
+    Q_OBJECT;
+
+public:
+
+    VBoxOSTypeSelectorWidget (QWidget *aParent);
+
+    void setType (const CGuestOSType &aType);
+    CGuestOSType type() const;
+
+    void setLayoutPosition (int aPos);
+
+signals:
+
+    void osTypeChanged();
+
+protected:
+
+    void retranslateUi();
+    void showEvent (QShowEvent *aEvent);
+
+private slots:
+
+    void onFamilyChanged (int aIndex);
+    void onTypeChanged (int aIndex);
+
+private:
+
+    QLabel *mTxFamilyName;
+    QLabel *mTxTypeName;
+    QLabel *mPxTypeIcon;
+    QComboBox *mCbFamily;
+    QComboBox *mCbType;
+
+    CGuestOSType mType;
+    QMap <QString, QString> mCurrentIds;
+
+    bool mPolished;
+    int mLayoutPosition;
+};
+
+#endif /* __VBoxOSTypeSelectorWidget_h__ */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxProgressDialog.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxProgressDialog.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxProgressDialog.cpp	(revision 25178)
@@ -0,0 +1,277 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxProgressDialog class implementation
+ */
+
+/*
+ * Copyright (C) 2006-2009 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.
+ */
+
+/* VBox includes */
+#include "COMDefs.h"
+#include "QIDialogButtonBox.h"
+#include "QILabel.h"
+#include "VBoxGlobal.h"
+#include "VBoxProgressDialog.h"
+#include "VBoxSpecialControls.h"
+#ifdef Q_WS_MAC
+# include "VBoxUtils-darwin.h"
+#endif
+
+/* Qt includes */
+#include <QCloseEvent>
+#include <QEventLoop>
+#include <QProgressBar>
+#include <QTime>
+#include <QTimer>
+#include <QVBoxLayout>
+
+#define VBOX_SECOND 1
+#define VBOX_MINUTE VBOX_SECOND * 60
+#define VBOX_HOUR VBOX_MINUTE * 60
+#define VBOX_DAY VBOX_HOUR * 24
+
+const char *VBoxProgressDialog::sOpDescTpl = "%1... (%2/%3)";
+
+VBoxProgressDialog::VBoxProgressDialog (CProgress &aProgress,
+                                        const QString &aTitle,
+                                        int aMinDuration /* = 2000 */,
+                                        QWidget *aParent /* = 0 */)
+//  : QIDialog (aParent, Qt::Sheet | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint)
+  : QIDialog (aParent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint)
+  , mProgress (aProgress)
+  , mCancelBtn (0)
+  , mCancelEnabled (false)
+  , mOpCount (mProgress.GetOperationCount())
+  , mCurOp (mProgress.GetOperation() + 1)
+  , mEnded (false)
+{
+    setModal (true);
+
+    QVBoxLayout *pLayout1 = new QVBoxLayout (this);
+
+#ifdef Q_WS_MAC
+    ::darwinSetHidesAllTitleButtons (this);
+    ::darwinSetShowsResizeIndicator (this, false);
+    VBoxGlobal::setLayoutMargin (pLayout1, 6);
+#endif /* Q_WS_MAC */
+
+    mLabel = new QILabel (this);
+    pLayout1->addWidget (mLabel, 0, Qt::AlignHCenter);
+
+    QHBoxLayout *pLayout2 = new QHBoxLayout();
+    pLayout2->setMargin (0);
+    pLayout1->addLayout (pLayout2);
+
+    mProgressBar = new QProgressBar (this);
+    pLayout2->addWidget (mProgressBar, 0, Qt::AlignVCenter);
+
+    if (mOpCount > 1)
+        mLabel->setText (QString (sOpDescTpl)
+                         .arg (mProgress.GetOperationDescription())
+                         .arg (mCurOp).arg (mOpCount));
+    else
+        mLabel->setText (QString ("%1...")
+                         .arg (mProgress.GetOperationDescription()));
+    mProgressBar->setMaximum (100);
+    setWindowTitle (QString ("%1: %2").arg (aTitle, mProgress.GetDescription()));
+    mProgressBar->setValue (0);
+    mCancelEnabled = aProgress.GetCancelable();
+    if (mCancelEnabled)
+    {
+        mCancelBtn = new VBoxMiniCancelButton (this);
+        mCancelBtn->setFocusPolicy (Qt::ClickFocus);
+        pLayout2->addWidget (mCancelBtn, 0, Qt::AlignVCenter);
+        connect (mCancelBtn, SIGNAL (clicked()), this, SLOT (cancelOperation()));
+    }
+
+    mETA = new QILabel (this);
+    pLayout1->addWidget (mETA, 0, Qt::AlignLeft | Qt::AlignVCenter);
+
+    setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+    retranslateUi();
+
+    /* The progress dialog will be shown automatically after
+     * the duration is over if progress is not finished yet. */
+    QTimer::singleShot (aMinDuration, this, SLOT (showDialog()));
+}
+
+void VBoxProgressDialog::retranslateUi()
+{
+    mCancelText = tr ("Canceling...");
+    if (mCancelBtn)
+    {
+        mCancelBtn->setText (tr ("&Cancel"));
+        mCancelBtn->setToolTip (tr ("Cancel the current operation"));
+    }
+}
+
+int VBoxProgressDialog::run (int aRefreshInterval)
+{
+    if (mProgress.isOk())
+    {
+        /* Start refresh timer */
+        int id = startTimer (aRefreshInterval);
+
+        /* Set busy cursor */
+        QApplication::setOverrideCursor (QCursor (Qt::WaitCursor));
+
+        /* Enter the modal loop, but don't show the window immediately */
+        exec (false);
+
+        /* Kill refresh timer */
+        killTimer (id);
+
+        QApplication::restoreOverrideCursor();
+
+        return result();
+    }
+    return Rejected;
+}
+
+void VBoxProgressDialog::showDialog()
+{
+    /* We should not show progress-dialog
+     * if it was already finalized but not yet closed.
+     * This could happens in case of some other
+     * modal dialog prevents our event-loop from
+     * being exit overlapping 'this'. */
+    if (!mEnded)
+        show();
+}
+
+void VBoxProgressDialog::cancelOperation()
+{
+    if (mCancelBtn)
+        mCancelBtn->setEnabled (false);
+    mProgress.Cancel();
+}
+
+void VBoxProgressDialog::timerEvent (QTimerEvent * /* aEvent */)
+{
+    /* We should hide progress-dialog
+     * if it was already finalized but not yet closed.
+     * This could happens in case of some other
+     * modal dialog prevents our event-loop from
+     * being exit overlapping 'this'. */
+    if (mEnded && !isHidden())
+    {
+        hide();
+        return;
+    }
+    else if (mEnded)
+        return;
+
+    if (!mEnded && (!mProgress.isOk() || mProgress.GetCompleted()))
+    {
+        /* Progress finished */
+        if (mProgress.isOk())
+        {
+            mProgressBar->setValue (100);
+            done (Accepted);
+        }
+        /* Progress is not valid */
+        else
+            done (Rejected);
+
+        /* Request to exit loop */
+        mEnded = true;
+        return;
+    }
+
+    if (!mProgress.GetCanceled())
+    {
+        /* Update the progress dialog */
+        /* First ETA */
+        long newTime = mProgress.GetTimeRemaining();
+        QDateTime time;
+        time.setTime_t (newTime);
+        QDateTime refTime;
+        refTime.setTime_t (0);
+
+        int days = refTime.daysTo (time);
+        int hours = time.addDays (-days).time().hour();
+        int minutes = time.addDays (-days).time().minute();
+        int seconds = time.addDays (-days).time().second();
+
+        QString strDays = VBoxGlobal::daysToString(days);
+        QString strHours = VBoxGlobal::hoursToString(hours);
+        QString strMinutes = VBoxGlobal::minutesToString(minutes);
+        QString strSeconds = VBoxGlobal::secondsToString(seconds);
+
+        QString strTwoComp = tr ("%1, %2 remaining", "You may wish to translate this more like \"Time remaining: %1, %2\"");
+        QString strOneComp = tr ("%1 remaining", "You may wish to translate this more like \"Time remaining: %1\"");
+
+        if (newTime > VBOX_DAY * 2 + VBOX_HOUR)
+            mETA->setText (strTwoComp.arg (strDays).arg (strHours));
+        else if (newTime > VBOX_DAY * 2 + VBOX_MINUTE * 5)
+            mETA->setText (strTwoComp.arg (strDays).arg (strMinutes));
+        else if (newTime > VBOX_DAY * 2)
+            mETA->setText (strOneComp.arg (strDays));
+        else if (newTime > VBOX_DAY + VBOX_HOUR)
+            mETA->setText (strTwoComp.arg (strDays).arg (strHours));
+        else if (newTime > VBOX_DAY + VBOX_MINUTE * 5)
+            mETA->setText (strTwoComp.arg (strDays).arg (strMinutes));
+        else if (newTime > VBOX_HOUR * 23 + VBOX_MINUTE * 55)
+            mETA->setText (strOneComp.arg (strDays));
+        else if (newTime >= VBOX_HOUR * 2)
+            mETA->setText (strTwoComp.arg (strHours).arg (strMinutes));
+        else if (newTime > VBOX_HOUR + VBOX_MINUTE * 5)
+            mETA->setText (strTwoComp.arg (strHours).arg (strMinutes));
+        else if (newTime > VBOX_MINUTE * 55)
+            mETA->setText (strOneComp.arg (strHours));
+        else if (newTime > VBOX_MINUTE * 2)
+            mETA->setText (strOneComp.arg (strMinutes));
+        else if (newTime > VBOX_MINUTE + VBOX_SECOND * 5)
+            mETA->setText (strTwoComp.arg (strMinutes).arg (strSeconds));
+        else if (newTime > VBOX_SECOND * 55)
+            mETA->setText (strOneComp.arg (strMinutes));
+        else if (newTime > VBOX_SECOND * 5)
+            mETA->setText (strOneComp.arg (strSeconds));
+        else if (newTime >= 0)
+            mETA->setText (tr ("A few seconds remaining"));
+        else
+            mETA->clear();
+
+        /* Then operation text if changed */
+        ulong newOp = mProgress.GetOperation() + 1;
+        if (newOp != mCurOp)
+        {
+            mCurOp = newOp;
+            mLabel->setText (QString (sOpDescTpl)
+                             .arg (mProgress.GetOperationDescription())
+                             .arg (mCurOp).arg (mOpCount));
+        }
+        mProgressBar->setValue (mProgress.GetPercent());
+    }else
+        mETA->setText (mCancelText);
+}
+
+void VBoxProgressDialog::reject()
+{
+    if (mCancelEnabled)
+        cancelOperation();
+}
+
+void VBoxProgressDialog::closeEvent (QCloseEvent *aEvent)
+{
+    if (mCancelEnabled)
+        cancelOperation();
+    else
+        aEvent->ignore();
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxProgressDialog.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxProgressDialog.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxProgressDialog.h	(revision 25178)
@@ -0,0 +1,90 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxProgressDialog class declaration
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxProgressDialog_h__
+#define __VBoxProgressDialog_h__
+
+/* Qt includes */
+#include "QIDialog.h"
+
+/* VBox forward declarations */
+class CProgress;
+class QILabel;
+class VBoxMiniCancelButton;
+
+/* Qt forward declarations */
+class QProgressBar;
+
+/**
+ * A QProgressDialog enhancement that allows to:
+ *
+ * 1) prevent closing the dialog when it has no cancel button;
+ * 2) effectively track the IProgress object completion (w/o using
+ *    IProgress::waitForCompletion() and w/o blocking the UI thread in any other
+ *    way for too long).
+ *
+ * @note The CProgress instance is passed as a non-const reference to the
+ *       constructor (to memorize COM errors if they happen), and therefore must
+ *       not be destroyed before the created VBoxProgressDialog instance is
+ *       destroyed.
+ */
+class VBoxProgressDialog: protected QIDialog
+{
+    Q_OBJECT;
+
+public:
+    VBoxProgressDialog (CProgress &aProgress, const QString &aTitle,
+                        int aMinDuration = 2000, QWidget *aParent = 0);
+
+    int run (int aRefreshInterval);
+    bool cancelEnabled() const { return mCancelEnabled; }
+
+protected:
+    virtual void retranslateUi();
+
+    virtual void reject();
+
+    virtual void timerEvent (QTimerEvent *aEvent);
+    virtual void closeEvent (QCloseEvent *aEvent);
+
+private slots:
+    void showDialog();
+    void cancelOperation();
+
+private:
+    /* Private member vars */
+    CProgress &mProgress;
+    QILabel *mLabel;
+    QILabel *mETA;
+    QString mCancelText;
+    QProgressBar *mProgressBar;
+    VBoxMiniCancelButton *mCancelBtn;
+    bool mCancelEnabled;
+    const ulong mOpCount;
+    ulong mCurOp;
+    bool mEnded;
+
+    static const char *sOpDescTpl;
+};
+
+#endif /* __VBoxProgressDialog_h__ */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxSpecialControls.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxSpecialControls.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxSpecialControls.cpp	(revision 25178)
@@ -0,0 +1,271 @@
+/* VBox includes */
+#include "VBoxSpecialControls.h"
+
+/* VBox includes */
+#include "VBoxGlobal.h"
+
+#ifdef VBOX_DARWIN_USE_NATIVE_CONTROLS
+
+/********************************************************************************
+ *
+ * A mini cancel button in the native Cocoa version.
+ *
+ ********************************************************************************/
+VBoxMiniCancelButton::VBoxMiniCancelButton (QWidget *aParent /* = 0 */)
+  : QAbstractButton (aParent)
+{
+    setShortcut (QKeySequence (Qt::Key_Escape));
+    mButton = new VBoxCocoaButton (VBoxCocoaButton::CancelButton, this);
+    connect (mButton, SIGNAL (clicked()),
+             this, SIGNAL (clicked()));
+    setFixedSize (mButton->size());
+}
+
+/********************************************************************************
+ *
+ * A help button in the native Cocoa version.
+ *
+ ********************************************************************************/
+VBoxHelpButton::VBoxHelpButton (QWidget *aParent /* = 0 */)
+  : QPushButton (aParent)
+{
+    setShortcut (QKeySequence (QKeySequence::HelpContents));
+    mButton = new VBoxCocoaButton (VBoxCocoaButton::HelpButton, this);
+    connect (mButton, SIGNAL (clicked()),
+             this, SIGNAL (clicked()));
+    setFixedSize (mButton->size());
+}
+
+/********************************************************************************
+ *
+ * A segmented button in the native Cocoa version.
+ *
+ ********************************************************************************/
+VBoxSegmentedButton::VBoxSegmentedButton (int aCount, QWidget *aParent /* = 0 */)
+  : VBoxCocoaSegmentedButton (aCount, aParent)
+{
+}
+/********************************************************************************
+ *
+ * A search field in the native Cocoa version.
+ *
+ ********************************************************************************/
+VBoxSearchField::VBoxSearchField (QWidget *aParent /* = 0 */)
+  : VBoxCocoaSearchField (aParent)
+{
+}
+
+#else /* VBOX_DARWIN_USE_NATIVE_CONTROLS */
+
+/* Qt includes */
+#include <QPainter>
+#include <QBitmap>
+#include <QMouseEvent>
+#include <QSignalMapper>
+
+/********************************************************************************
+ *
+ * A mini cancel button for the other OS's.
+ *
+ ********************************************************************************/
+VBoxMiniCancelButton::VBoxMiniCancelButton (QWidget *aParent /* = 0 */)
+  : QIWithRetranslateUI<QIToolButton> (aParent)
+{
+    setAutoRaise (true);
+    setFocusPolicy (Qt::TabFocus);
+    setShortcut (QKeySequence (Qt::Key_Escape));
+    QIcon cancelIcon = style()->standardIcon (QStyle::SP_DialogCancelButton);
+    if (cancelIcon.isNull())
+        cancelIcon = VBoxGlobal::iconSet (":/delete_16px.png",
+                                          ":/delete_dis_16px.png");
+    setIcon (cancelIcon);
+}
+
+/********************************************************************************
+ *
+ * A help button for the other OS's.
+ *
+ ********************************************************************************/
+/* From: src/gui/styles/qmacstyle_mac.cpp */
+static const int PushButtonLeftOffset = 6;
+static const int PushButtonTopOffset = 4;
+static const int PushButtonRightOffset = 12;
+static const int PushButtonBottomOffset = 4;
+
+VBoxHelpButton::VBoxHelpButton (QWidget *aParent /* = 0 */)
+    : QIWithRetranslateUI<QPushButton> (aParent)
+{
+#ifdef Q_WS_MAC
+    mButtonPressed = false;
+    mNormalPixmap = new QPixmap (":/help_button_normal_mac_22px.png");
+    mPressedPixmap = new QPixmap (":/help_button_pressed_mac_22px.png");
+    mSize = mNormalPixmap->size();
+    mMask = new QImage (mNormalPixmap->mask().toImage());
+    mBRect = QRect (PushButtonLeftOffset,
+                    PushButtonTopOffset,
+                    mSize.width(),
+                    mSize.height());
+#endif /* Q_WS_MAC */
+    /* Applying language settings */
+    retranslateUi();
+}
+
+void VBoxHelpButton::initFrom (QPushButton *aOther)
+{
+    setIcon (aOther->icon());
+    setText (aOther->text());
+    setShortcut (aOther->shortcut());
+    setFlat (aOther->isFlat());
+    setAutoDefault (aOther->autoDefault());
+    setDefault (aOther->isDefault());
+    /* Applying language settings */
+    retranslateUi();
+}
+
+void VBoxHelpButton::retranslateUi()
+{
+    QPushButton::setText (tr ("&Help"));
+    if (QPushButton::shortcut().isEmpty())
+        QPushButton::setShortcut (QKeySequence::HelpContents);
+}
+
+#ifdef Q_WS_MAC
+VBoxHelpButton::~VBoxHelpButton()
+{
+    delete mNormalPixmap;
+    delete mPressedPixmap;
+    delete mMask;
+}
+
+QSize VBoxHelpButton::sizeHint() const
+{
+    return QSize (mSize.width() + PushButtonLeftOffset + PushButtonRightOffset,
+                  mSize.height() + PushButtonTopOffset + PushButtonBottomOffset);
+}
+
+void VBoxHelpButton::paintEvent (QPaintEvent * /* aEvent */)
+{
+    QPainter painter (this);
+    painter.drawPixmap (PushButtonLeftOffset, PushButtonTopOffset, mButtonPressed ? *mPressedPixmap: *mNormalPixmap);
+}
+
+bool VBoxHelpButton::hitButton (const QPoint &pos) const
+{
+    if (mBRect.contains (pos))
+        return  mMask->pixel (pos.x() - PushButtonLeftOffset,
+                              pos.y() - PushButtonTopOffset) == 0xff000000;
+    else
+        return false;
+}
+
+void VBoxHelpButton::mousePressEvent (QMouseEvent *aEvent)
+{
+    if (hitButton (aEvent->pos()))
+        mButtonPressed = true;
+    QPushButton::mousePressEvent (aEvent);
+    update();
+}
+
+void VBoxHelpButton::mouseReleaseEvent (QMouseEvent *aEvent)
+{
+    QPushButton::mouseReleaseEvent (aEvent);
+    mButtonPressed = false;
+    update();
+}
+
+void VBoxHelpButton::leaveEvent (QEvent * aEvent)
+{
+    QPushButton::leaveEvent (aEvent);
+    mButtonPressed = false;
+    update();
+}
+#endif /* Q_WS_MAC */
+
+/********************************************************************************
+ *
+ * A segmented button for the other OS's.
+ *
+ ********************************************************************************/
+VBoxSegmentedButton::VBoxSegmentedButton (int aCount, QWidget *aParent /* = 0 */)
+  : QWidget (aParent)
+{
+    mSignalMapper = new QSignalMapper (this);
+
+    QHBoxLayout *layout = new QHBoxLayout (this);
+    for (int i=0; i < aCount; ++i)
+    {
+        QIToolButton *button = new QIToolButton (this);
+        button->setAutoRaise (true);
+        button->setFocusPolicy (Qt::TabFocus);
+        button->setToolButtonStyle (Qt::ToolButtonTextBesideIcon);
+        mButtons.append (button);
+        layout->addWidget (button);
+        connect (button, SIGNAL(clicked()),
+                 mSignalMapper, SLOT(map()));
+        mSignalMapper->setMapping (button, i);
+    }
+    connect (mSignalMapper, SIGNAL(mapped(int)),
+             this, SIGNAL(clicked(int)));
+
+}
+
+VBoxSegmentedButton::~VBoxSegmentedButton()
+{
+    delete mSignalMapper;
+    qDeleteAll (mButtons);
+}
+
+void VBoxSegmentedButton::setTitle (int aSegment, const QString &aTitle)
+{
+    mButtons.at (aSegment)->setText (aTitle);
+}
+
+void VBoxSegmentedButton::setToolTip (int aSegment, const QString &aTip)
+{
+    mButtons.at (aSegment)->setToolTip (aTip);
+}
+
+void VBoxSegmentedButton::setIcon (int aSegment, const QIcon &aIcon)
+{
+    mButtons.at (aSegment)->setIcon (aIcon);
+}
+
+void VBoxSegmentedButton::setEnabled (int aSegment, bool fEnabled)
+{
+    mButtons.at (aSegment)->setEnabled (fEnabled);
+}
+
+void VBoxSegmentedButton::animateClick (int aSegment)
+{
+    mButtons.at (aSegment)->animateClick();
+}
+
+/********************************************************************************
+ *
+ * A search field  for the other OS's.
+ *
+ ********************************************************************************/
+VBoxSearchField::VBoxSearchField (QWidget *aParent /* = 0 */)
+  : QLineEdit (aParent)
+{
+    mBaseBrush = palette().base();
+}
+
+void VBoxSearchField::markError()
+{
+    QPalette pal = palette();
+    QColor c (Qt::red);
+    c.setAlphaF (0.3);
+    pal.setBrush (QPalette::Base, c);
+    setPalette (pal);
+}
+
+void VBoxSearchField::unmarkError()
+{
+    QPalette pal = palette();
+    pal.setBrush (QPalette::Base, mBaseBrush);
+    setPalette (pal);
+}
+
+#endif /* VBOX_DARWIN_USE_NATIVE_CONTROLS */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxSpecialControls.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxSpecialControls.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxSpecialControls.h	(revision 25178)
@@ -0,0 +1,231 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxSpecialButtons declarations
+ */
+
+/*
+ * Copyright (C) 2009 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 ___VBoxSpecialControls_h__
+#define ___VBoxSpecialControls_h__
+
+/* VBox includes */
+#include "QIWithRetranslateUI.h"
+
+/* Qt includes */
+#include <QPushButton>
+
+#ifdef VBOX_DARWIN_USE_NATIVE_CONTROLS
+
+/* VBox includes */
+#include "VBoxCocoaSpecialControls.h"
+
+/********************************************************************************
+ *
+ * A mini cancel button in the native Cocoa version.
+ *
+ ********************************************************************************/
+class VBoxMiniCancelButton: public QAbstractButton
+{
+    Q_OBJECT;
+
+public:
+    VBoxMiniCancelButton (QWidget *aParent = 0);
+
+    void setText (const QString &aText) { mButton->setText (aText); }
+    void setToolTip (const QString &aTip) { mButton->setToolTip (aTip); }
+
+protected:
+    void paintEvent (QPaintEvent * /* aEvent */) {}
+
+private:
+    VBoxCocoaButton *mButton;
+};
+
+/********************************************************************************
+ *
+ * A help button in the native Cocoa version.
+ *
+ ********************************************************************************/
+class VBoxHelpButton: public QPushButton
+{
+    Q_OBJECT;
+
+public:
+    VBoxHelpButton (QWidget *aParent = 0);
+
+    void setToolTip (const QString &aTip) { mButton->setToolTip (aTip); }
+
+    void initFrom (QPushButton * /* aOther */) {}
+
+protected:
+    void paintEvent (QPaintEvent * /* aEvent */) {}
+
+private:
+    VBoxCocoaButton *mButton;
+};
+
+/********************************************************************************
+ *
+ * A segmented button in the native Cocoa version.
+ *
+ ********************************************************************************/
+class VBoxSegmentedButton: public VBoxCocoaSegmentedButton
+{
+    Q_OBJECT;
+
+public:
+    VBoxSegmentedButton (int aCount, QWidget *aParent = 0);
+
+    void setIcon (int /* aSegment */, const QIcon & /* aIcon */) {}
+};
+
+/********************************************************************************
+ *
+ * A search field in the native Cocoa version.
+ *
+ ********************************************************************************/
+class VBoxSearchField: public VBoxCocoaSearchField
+{
+    Q_OBJECT;
+
+public:
+    VBoxSearchField (QWidget *aParent = 0);
+};
+
+#else /* VBOX_DARWIN_USE_NATIVE_CONTROLS */
+
+/* VBox includes */
+#include "QIToolButton.h"
+
+/* Qt includes */
+#include <QLineEdit>
+
+/* Qt forward declarations */
+class QSignalMapper;
+
+/********************************************************************************
+ *
+ * A mini cancel button for the other OS's.
+ *
+ ********************************************************************************/
+class VBoxMiniCancelButton: public QIWithRetranslateUI<QIToolButton>
+{
+    Q_OBJECT;
+
+public:
+    VBoxMiniCancelButton (QWidget *aParent = 0);
+
+protected:
+    void retranslateUi() {};
+};
+
+/********************************************************************************
+ *
+ * A help button for the other OS's.
+ *
+ ********************************************************************************/
+class VBoxHelpButton: public QIWithRetranslateUI<QPushButton>
+{
+    Q_OBJECT;
+
+public:
+    VBoxHelpButton (QWidget *aParent = 0);
+#ifdef Q_WS_MAC
+    ~VBoxHelpButton();
+    QSize sizeHint() const;
+#endif /* Q_WS_MAC */
+
+    void initFrom (QPushButton *aOther);
+
+protected:
+    void retranslateUi();
+
+#ifdef Q_WS_MAC
+    void paintEvent (QPaintEvent *aEvent);
+
+    bool hitButton (const QPoint &pos) const;
+
+    void mousePressEvent (QMouseEvent *aEvent);
+    void mouseReleaseEvent (QMouseEvent *aEvent);
+    void leaveEvent (QEvent *aEvent);
+
+private:
+    /* Private member vars */
+    bool mButtonPressed;
+
+    QSize mSize;
+    QPixmap *mNormalPixmap;
+    QPixmap *mPressedPixmap;
+    QImage *mMask;
+    QRect mBRect;
+#endif /* Q_WS_MAC */
+};
+
+/********************************************************************************
+ *
+ * A segmented button for the other OS's.
+ *
+ ********************************************************************************/
+class VBoxSegmentedButton: public QWidget
+{
+    Q_OBJECT;
+
+public:
+    VBoxSegmentedButton (int aCount, QWidget *aParent = 0);
+    ~VBoxSegmentedButton();
+
+    void setTitle (int aSegment, const QString &aTitle);
+    void setToolTip (int aSegment, const QString &aTip);
+    void setIcon (int aSegment, const QIcon &aIcon);
+    void setEnabled (int aSegment, bool fEnabled);
+
+    void animateClick (int aSegment);
+
+signals:
+    void clicked (int aSegment);
+
+private:
+    /* Private member vars */
+    QList<QIToolButton*> mButtons;
+    QSignalMapper *mSignalMapper;
+};
+
+/********************************************************************************
+ *
+ * A search field  for the other OS's.
+ *
+ ********************************************************************************/
+class VBoxSearchField: public QLineEdit
+{
+    Q_OBJECT;
+
+public:
+    VBoxSearchField (QWidget *aParent = 0);
+
+    void markError();
+    void unmarkError();
+
+private:
+    /* Private member vars */
+    QBrush mBaseBrush;
+};
+
+#endif /* VBOX_DARWIN_USE_NATIVE_CONTROLS */
+
+#endif /* ___VBoxSpecialControls_h__ */
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxToolBar.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxToolBar.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxToolBar.h	(revision 25178)
@@ -0,0 +1,137 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * VBoxToolBar class declaration & 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.
+ */
+
+#ifndef ___VBoxToolBar_h___
+#define ___VBoxToolBar_h___
+
+#include <QGlobalStatic> /* for Q_WS_MAC */
+#ifdef Q_WS_MAC
+#include "VBoxUtils.h"
+#endif
+
+/* Qt includes */
+#include <QLayout>
+#include <QMainWindow>
+#include <QToolBar>
+
+/* Note: This styles are available on _all_ platforms. */
+#include <QCleanlooksStyle>
+#include <QWindowsStyle>
+
+/**
+ *  The VBoxToolBar class is a simple QToolBar reimplementation to disable
+ *  its built-in context menu and add some default behavior we need.
+ */
+class VBoxToolBar : public QToolBar
+{
+
+public:
+
+    VBoxToolBar (QWidget *aParent)
+        : QToolBar (aParent)
+        , mMainWindow (qobject_cast <QMainWindow*> (aParent))
+    {
+        setFloatable (false);
+        setMovable (false);
+
+        /* Remove that ugly frame panel around the toolbar.
+         * Doing that currently for Cleanlooks & Windows styles. */
+        if (qobject_cast <QCleanlooksStyle*> (QToolBar::style()) ||
+            qobject_cast <QWindowsStyle*> (QToolBar::style()))
+            setStyleSheet ("QToolBar { border: 0px none black; }");
+
+        if (layout())
+            layout()->setContentsMargins (0, 0, 0, 0);;
+
+        setContextMenuPolicy (Qt::NoContextMenu);
+    }
+
+#ifdef Q_WS_MAC
+    void setMacToolbar()
+    {
+        if (mMainWindow)
+        {
+            mMainWindow->setUnifiedTitleAndToolBarOnMac (true);
+#ifndef QT_MAC_USE_COCOA
+            WindowRef window = ::darwinToNativeWindow (this);
+            EventHandlerUPP eventHandler = ::NewEventHandlerUPP (VBoxToolBar::macEventFilter);
+            EventTypeSpec eventTypes[2];
+            eventTypes[0].eventClass = kEventClassMouse;
+            eventTypes[0].eventKind  = kEventMouseDown;
+            eventTypes[1].eventClass = kEventClassMouse;
+            eventTypes[1].eventKind  = kEventMouseUp;
+            InstallWindowEventHandler (window, eventHandler,
+                                       RT_ELEMENTS (eventTypes), eventTypes,
+                                       NULL, NULL);
+#endif /* !QT_MAC_USE_COCOA */
+        }
+    }
+
+#ifndef QT_MAC_USE_COCOA
+    static pascal OSStatus macEventFilter (EventHandlerCallRef aNextHandler,
+                                           EventRef aEvent, void * /* aUserData */)
+    {
+        UInt32 eclass = GetEventClass (aEvent);
+        if (eclass == kEventClassMouse)
+        {
+            WindowPartCode partCode;
+            GetEventParameter (aEvent, kEventParamWindowPartCode, typeWindowPartCode, NULL, sizeof (WindowPartCode), NULL, &partCode);
+            UInt32 ekind = GetEventKind (aEvent);
+            if (partCode == 15 ||
+                partCode == 4)
+                if(ekind == kEventMouseDown || ekind == kEventMouseUp)
+                {
+                    EventMouseButton button = 0;
+                    GetEventParameter (aEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof (button), NULL, &button);
+                    if (button != kEventMouseButtonPrimary)
+                        return noErr;
+                }
+        }
+        return CallNextEventHandler (aNextHandler, aEvent);
+    }
+#endif /* !QT_MAC_USE_COCOA */
+
+    void setShowToolBarButton (bool aShow)
+    {
+        ::darwinSetShowsToolbarButton (this, aShow);
+    }
+#endif /* Q_WS_MAC */
+
+    void setUsesTextLabel (bool aEnable)
+    {
+        Qt::ToolButtonStyle tbs = Qt::ToolButtonTextUnderIcon;
+        if (!aEnable)
+            tbs = Qt::ToolButtonIconOnly;
+
+        if (mMainWindow)
+            mMainWindow->setToolButtonStyle (tbs);
+        else
+            setToolButtonStyle (tbs);
+    }
+
+private:
+
+    QMainWindow *mMainWindow;
+};
+
+#endif // !___VBoxToolBar_h___
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.cpp	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.cpp	(revision 25178)
@@ -0,0 +1,49 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxWarningPane class implementation
+ */
+
+/*
+ * Copyright (C) 2009 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.
+ */
+
+/* Global includes */
+#include <QHBoxLayout>
+
+/* Local includes */
+#include "VBoxWarningPane.h"
+#include "VBoxGlobal.h"
+
+VBoxWarningPane::VBoxWarningPane(QWidget *pParent)
+    : QWidget(pParent)
+{
+    QHBoxLayout *pLayout = new QHBoxLayout(this);
+    VBoxGlobal::setLayoutMargin(pLayout, 0);
+    pLayout->addWidget(&m_icon);
+    pLayout->addWidget(&m_label);
+    setVisible(false);
+}
+
+void VBoxWarningPane::setWarningPixmap(const QPixmap &imgPixmap)
+{
+    m_icon.setPixmap (imgPixmap);
+}
+
+void VBoxWarningPane::setWarningText(const QString &strText)
+{
+    m_label.setText (strText);
+}
+
Index: trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.h	(revision 25178)
+++ trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxWarningPane.h	(revision 25178)
@@ -0,0 +1,48 @@
+/** @file
+ *
+ * VBox frontends: Qt4 GUI ("VirtualBox"):
+ * VBoxWarningPane class declaration
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxWarningPane_h__
+#define __VBoxWarningPane_h__
+
+/* Global includes */
+#include <QWidget>
+#include <QLabel>
+
+class VBoxWarningPane: public QWidget
+{
+    Q_OBJECT;
+
+public:
+
+    VBoxWarningPane(QWidget *pParent = 0);
+
+    void setWarningPixmap(const QPixmap &imgPixmap);
+    void setWarningText(const QString &strText);
+
+private:
+
+    QLabel m_icon;
+    QLabel m_label;
+};
+
+#endif // __VBoxWarningPane_h__
+
