VirtualBox

Changeset 30868 in vbox


Ignore:
Timestamp:
Jul 16, 2010 9:42:12 AM (15 years ago)
Author:
vboxsync
Message:

FE/Qt4: new VMDesktop view in selector window; file system restructure

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
7 added
9 edited
3 copied
11 moved

Legend:

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

    r30753 r30868  
    148148endif
    149149ifdef VBOX_BLEEDING_EDGE
    150 VirtualBox_src/VBoxSelectorWnd.cpp_DEFS += \
     150VirtualBox_src/selector/VBoxSelectorWnd.cpp_DEFS += \
    151151    VBOX_BLEEDING_EDGE=\"$(VBOX_BLEEDING_EDGE)\"
    152152VirtualBox_src/runtime/UIMachineWindow.cpp_DEFS += \
     
    174174        ./src/X11 \
    175175        ./src/darwin \
     176        ./src/selector \
    176177        ./src/runtime \
    177178        ./src/runtime/normal \
     
    246247        src/VBoxGlobalSettings.h \
    247248        src/VBoxMediaManagerDlg.h \
    248         src/VBoxSelectorWnd.h \
    249249        src/VBoxSnapshotDetailsDlg.h \
    250         src/VBoxSnapshotsWgt.h \
    251250        src/VBoxTakeSnapshotDlg.h \
    252251        src/VBoxUpdateDlg.h \
    253252        src/VBoxVMInformationDlg.h \
    254         src/UIVMListView.h \
    255         src/UIVirtualBoxEventHandler.h \
    256253        src/VBoxVMLogViewer.h \
    257254        src/globals/VBoxGlobal.h \
     
    310307        src/wizards/exportappliance/UIExportApplianceWzd.h \
    311308        src/wizards/importappliance/UIImportApplianceWzd.h \
     309        src/widgets/UIBar.h \
    312310        src/widgets/UIDownloader.h \
    313311        src/widgets/UIDownloaderAdditions.h \
    314312        src/widgets/UIDownloaderUserManual.h \
     313        src/widgets/UIPopupBox.h \
    315314        src/widgets/UISpacerWidgets.h \
    316315        src/widgets/UISpecialControls.h \
     
    327326        src/widgets/VBoxProgressDialog.h \
    328327        src/widgets/VBoxWarningPane.h \
     328        src/selector/UIVMDesktop.h \
     329        src/selector/UIVMListView.h \
     330        src/selector/UIVMPreviewWindow.h \
     331        src/selector/UIVirtualBoxEventHandler.h \
     332        src/selector/VBoxSelectorWnd.h \
     333        src/selector/VBoxSnapshotsWgt.h \
    329334        src/runtime/UIMachine.h \
    330335        src/runtime/UISession.h \
     
    361366# Sources containing local definitions of classes that use the Q_OBJECT macro.
    362367VirtualBox_QT_MOCSRCS = \
    363         src/VBoxSelectorWnd.cpp \
    364368        src/VBoxMediaManagerDlg.cpp \
     369        src/globals/UIExtraDataEventHandler.cpp \
     370        src/extensions/QISplitter.cpp \
     371        src/selector/UIVMDesktop.cpp \
    365372        src/runtime/UIActionsPool.cpp \
    366         src/runtime/UIMachineMenuBar.cpp \
    367373        src/runtime/UIIndicatorsPool.cpp \
    368374        src/runtime/UIMachine.cpp \
    369375        src/runtime/UIMachineLogic.cpp \
    370         src/extensions/QISplitter.cpp \
    371         src/globals/UIExtraDataEventHandler.cpp
     376        src/runtime/UIMachineMenuBar.cpp
    372377
    373378ifdef VBOX_WITH_XPCOM
     
    393398        src/VBoxMediaManagerDlg.cpp \
    394399        src/VBoxMedium.cpp \
    395         src/VBoxSelectorWnd.cpp \
    396400        src/VBoxSnapshotDetailsDlg.cpp \
    397         src/VBoxSnapshotsWgt.cpp \
    398401        src/VBoxTakeSnapshotDlg.cpp \
    399402        src/VBoxUpdateDlg.cpp \
    400403        src/VBoxVMInformationDlg.cpp \
    401         src/UIVMItem.cpp \
    402         src/UIVMListView.cpp \
    403         src/UIVirtualBoxEventHandler.cpp \
    404404        src/VBoxVMLogViewer.cpp \
    405405        src/globals/COMDefs.cpp \
     
    459459        src/wizards/exportappliance/UIExportApplianceWzd.cpp \
    460460        src/wizards/importappliance/UIImportApplianceWzd.cpp \
     461        src/widgets/UIBar.cpp \
    461462        src/widgets/UIDownloader.cpp \
    462463        src/widgets/UIDownloaderAdditions.cpp \
    463464        src/widgets/UIDownloaderUserManual.cpp \
     465        src/widgets/UIPopupBox.cpp \
    464466        src/widgets/UISpecialControls.cpp \
    465467        src/widgets/VBoxApplianceEditorWgt.cpp \
     
    476478        src/widgets/VBoxProgressDialog.cpp \
    477479        src/widgets/VBoxWarningPane.cpp \
     480        src/selector/UIVMDesktop.cpp \
     481        src/selector/UIVMItem.cpp \
     482        src/selector/UIVMListView.cpp \
     483        src/selector/UIVMPreviewWindow.cpp \
     484        src/selector/UIVirtualBoxEventHandler.cpp \
     485        src/selector/VBoxSelectorWnd.cpp \
     486        src/selector/VBoxSnapshotsWgt.cpp \
    478487        src/runtime/UIMachine.cpp \
    479488        src/runtime/UISession.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/VBoxUI.pro

    r28800 r30868  
    2626    src/VBoxMediaManagerDlg.ui \
    2727    src/VBoxSnapshotDetailsDlg.ui \
    28     src/VBoxSnapshotsWgt.ui \
    2928    src/VBoxTakeSnapshotDlg.ui \
    3029    src/VBoxUpdateDlg.ui \
     
    6867    src/wizards/importappliance/UIImportApplianceWzdPage2.ui \
    6968    src/wizards/registration/UIRegistrationWzdPage1.ui \
    70     src/widgets/VBoxApplianceEditorWgt.ui
     69    src/widgets/VBoxApplianceEditorWgt.ui \
     70    src/selector/VBoxSnapshotsWgt.ui
    7171
    7272TRANSLATIONS = \
  • trunk/src/VBox/Frontends/VirtualBox/src/extensions/QILabel.cpp

    r28800 r30868  
    237237        style()->drawPrimitive (QStyle::PE_FrameFocusRect, &option, &painter, this);
    238238    }
     239}
     240
     241void QILabel::showEvent(QShowEvent *pEvent)
     242{
     243    QLabel::showEvent(pEvent);
     244    emit shown();
    239245}
    240246
  • trunk/src/VBox/Frontends/VirtualBox/src/extensions/QILabel.h

    r28800 r30868  
    66
    77/*
    8  * Copyright (C) 2006-2009 Oracle Corporation
     8 * Copyright (C) 2006-2010 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4848    QString text() const;
    4949
     50signals:
     51    void shown();
     52
    5053public slots:
    5154
     
    6467    void focusOutEvent (QFocusEvent *aEvent);
    6568    void paintEvent (QPaintEvent *aEvent);
     69    void showEvent(QShowEvent *pEvent);
    6670
    6771private:
  • trunk/src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.cpp

    r30087 r30868  
    1818 */
    1919
     20/* Local includes */
     21#include "QISplitter.h"
     22
    2023/* Global includes */
    2124#include <QApplication>
     
    2326#include <QPainter>
    2427#include <QPaintEvent>
    25 
    26 /* Local includes */
    27 #include "QISplitter.h"
    2828
    2929/* A simple shaded line. */
     
    121121}
    122122
    123 QISplitter::QISplitter(Qt::Orientation orientation /* = Qt::Horizontal */, QWidget *pParent /* = 0 */)
     123QISplitter::QISplitter(Qt::Orientation orientation, QWidget *pParent /* = 0 */)
    124124    : QSplitter(orientation, pParent)
    125125    , m_fPolished(false)
  • trunk/src/VBox/Frontends/VirtualBox/src/extensions/QISplitter.h

    r30087 r30868  
    3232
    3333    QISplitter(QWidget *pParent = 0);
    34     QISplitter(Qt::Orientation orientation = Qt::Horizontal, QWidget *pParent = 0);
     34    QISplitter(Qt::Orientation orientation, QWidget *pParent = 0);
    3535
    3636    void setHandleType(Type type) { m_type = type; }
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.cpp

    r30753 r30868  
    4444const char* VBoxDefs::GUI_PermanentSharedFoldersAtRuntime = "GUI/PermanentSharedFoldersAtRuntime";
    4545const char* VBoxDefs::GUI_LanguageId = "GUI/LanguageID";
     46const char* VBoxDefs::GUI_PreviewUpdate = "GUI/PreviewUpdate";
     47const char* VBoxDefs::GUI_DetailsPageBoxes = "GUI/DetailsPageBoxes";
    4648#ifdef Q_WS_X11
    4749const char* VBoxDefs::GUI_LicenseKey = "GUI/LicenseAgreed";
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.h

    r30753 r30868  
    122122    static const char* GUI_PermanentSharedFoldersAtRuntime;
    123123    static const char* GUI_LanguageId;
     124    static const char* GUI_PreviewUpdate;
     125    static const char* GUI_DetailsPageBoxes;
    124126#ifdef Q_WS_X11
    125127    static const char* GUI_LicenseKey;
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp

    r30798 r30868  
     1/* $Id$ */
    12/** @file
    23 *
    34 * VBox frontends: Qt GUI ("VirtualBox"):
    4  * VBoxSelectorWnd class implementation
     5 * UIVMDesktop class implementation
    56 */
    67
    78/*
    8  * Copyright (C) 2006-2010 Oracle Corporation
     9 * Copyright (C) 2010 Oracle Corporation
    910 *
    1011 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1718 */
    1819
    19 #ifdef VBOX_WITH_PRECOMPILED_HEADERS
    20 # include "precomp.h"
    21 #else  /* !VBOX_WITH_PRECOMPILED_HEADERS */
    22 #include "QISplitter.h"
    23 #include "QITabWidget.h"
    24 #include "UIExportApplianceWzd.h"
     20/* Local includes */
     21#include "QILabel.h"
     22#include "UIBar.h"
    2523#include "UIIconPool.h"
    26 #include "UIImportApplianceWzd.h"
    27 #include "UINewVMWzd.h"
     24#include "UIImageTools.h"
     25#include "UIPopupBox.h"
    2826#include "UISpacerWidgets.h"
    2927#include "UISpecialControls.h"
    30 #include "UIVMListView.h"
    31 #include "VBoxGlobal.h"
    32 #include "VBoxMediaManagerDlg.h"
    33 #include "VBoxProblemReporter.h"
    34 #include "VBoxSelectorWnd.h"
    35 #include "VBoxSettingsDialogSpecific.h"
     28#include "UIVMDesktop.h"
     29#include "UIVMItem.h"
     30#include "UIVMPreviewWindow.h"
     31#include "UIVirtualBoxEventHandler.h"
    3632#include "VBoxSnapshotsWgt.h"
    3733#include "VBoxToolBar.h"
     34
    3835#include "VBoxUtils.h"
    39 #include "VBoxVMLogViewer.h"
    40 #include "UIVirtualBoxEventHandler.h"
    41 
    42 #include "UIDownloaderUserManual.h"
    43 
    44 #ifdef Q_WS_X11
    45 #include <iprt/env.h>
    46 #endif
    47 
    48 /* Qt includes */
    49 #include <QTextBrowser>
    50 #include <QMenuBar>
    51 #include <QMenu>
    52 #include <QMenuItem>
     36
     37/* Global includes */
     38#include <QDir>
     39#include <QLabel>
     40#include <QScrollArea>
     41#include <QStackedLayout>
    5342#include <QStackedWidget>
    54 #include <QDesktopWidget>
    5543#include <QToolButton>
    56 
    57 #include <iprt/buildconfig.h>
    58 #include <VBox/version.h>
    59 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    60 
    61 // VBoxVMDetailsView class
    62 ////////////////////////////////////////////////////////////////////////////////
     44#include <QUrl>
     45
     46#include <iprt/assert.h>
     47
     48/*
     49 * Todo:
     50 * - dynamically change size of preview window!
     51 */
     52
     53//#ifdef Q_WS_MAC
     54# define DARWIN_USE_TOOLBAR
     55//#endif /* Q_WS_MAC */
     56
     57static const QString sTableTpl =
     58"<table border=0 cellspacing=1 cellpadding=0>%1</table>";
     59static const QString sSectionItemTpl1 =
     60"<tr><td width=40%><nobr><i>%1</i></nobr></td><td/><td/></tr>";
     61static const QString sSectionItemTpl2 =
     62"<tr><td><nobr>%1:</nobr></td><td/><td>%2</td></tr>";
     63//        "<tr><td width=40%><nobr>%1:</nobr></td><td/><td>%2</td></tr>";
     64static const QString sSectionItemTpl3 =
     65"<tr><td width=40%><nobr>%1</nobr></td><td/><td/></tr>";
     66
     67#ifdef Q_WS_MAC
     68static const int gsLeftMargin = 5;
     69static const int gsTopMargin = 5;
     70static const int gsRightMargin = 5;
     71static const int gsBottomMargin = 5;
     72#else /* Q_WS_MAC */
     73static const int gsLeftMargin = 0;
     74static const int gsTopMargin = 5;
     75static const int gsRightMargin = 5;
     76static const int gsBottomMargin = 5;
     77#endif /* !Q_WS_MAC */
    6378
    6479/**
    65  *  Two-page widget stack to represent VM details: one page for normal details
    66  *  and another one for inaccessibility errors.
     80 *  UIDescriptionPagePrivate
    6781 */
    68 class VBoxVMDetailsView : public QIWithRetranslateUI<QStackedWidget>
     82class UIDetailsPagePrivate : public QIWithRetranslateUI<QStackedWidget>
    6983{
    7084    Q_OBJECT;
    7185
     86    enum Section
     87    {
     88        GeneralSec,
     89        SystemSec,
     90        PreviewSec,
     91        DisplaySec,
     92        StorageSec,
     93        AudioSec,
     94        NetworkSec,
     95        SerialPortsSec,
     96#ifdef VBOX_WITH_PARALLEL_PORTS
     97        ParallelPortsSec,
     98#endif /* VBOX_WITH_PARALLEL_PORTS */
     99        USBSec,
     100        SharedFoldersSec,
     101        EndSec
     102    };
     103
    72104public:
    73105
    74     VBoxVMDetailsView (QWidget *aParent,
    75                        QAction *aRefreshAction = NULL);
    76 
    77     void setDetailsText (const QString &aText)
    78     {
    79         mDetailsText->setText (aText);
    80         setCurrentIndex (0);
    81     }
    82 
    83     void setErrorText (const QString &aText)
    84     {
     106    UIDetailsPagePrivate(QWidget *aParent, QAction *aRefreshAction = 0);
     107    ~UIDetailsPagePrivate();
     108
     109    void setMachine(const CMachine& machine);
     110
     111    void setText(const QString &aText)
     112    {
     113        m_machine = CMachine();
     114        createTextPage();
     115        m_pText->setText(aText);
     116        setCurrentIndex(indexOf(m_pText));
     117    }
     118
     119    void setErrorText(const QString &aText)
     120    {
     121        m_machine = CMachine();
    85122        createErrPage();
    86         mErrText->setText (aText);
    87         setCurrentIndex (1);
    88     }
    89 
    90     void setEmpty()
    91     {
    92         mDetailsText->setText (QString::null);
    93         setCurrentIndex (0);
    94     }
    95 
     123        m_pErrText->setText(aText);
     124        setCurrentIndex(indexOf(m_pErrBox));
     125    }
    96126signals:
    97127
    98     void linkClicked (const QString &aURL);
     128    void linkClicked(const QString &aURL);
    99129
    100130protected:
     
    104134private slots:
    105135
    106     void gotLinkClicked (const QUrl &aURL)
    107     {
    108         emit linkClicked (aURL.toString());
     136    void sltUpdateGeneral();
     137    void sltUpdatePreview();
     138    void sltUpdateSystem();
     139    void sltUpdateDisplay();
     140    void sltUpdateStorage();
     141    void sltUpdateAudio();
     142    void sltUpdateNetwork();
     143    void sltUpdateSerialPorts();
     144#ifdef VBOX_WITH_PARALLEL_PORTS
     145    void sltUpdateParallelPorts();
     146#endif /* VBOX_WITH_PARALLEL_PORTS */
     147    void sltUpdateUSB();
     148    void sltUpdateSharedFolders();
     149
     150    void sltContextMenuRequested(const QPoint &pos);
     151
     152    void gotLinkClicked(const QUrl &aURL)
     153    {
     154        emit linkClicked(aURL.toString());
    109155    }
    110156
    111157private:
    112158
     159    void createTextPage();
    113160    void createErrPage();
    114161
    115     QRichTextBrowser *mDetailsText;
    116 
    117     QWidget *mErrBox;
    118     QLabel *mErrLabel;
    119     QTextBrowser *mErrText;
     162    /* Private member vars */
     163    CVirtualBox m_vbox;
     164    CMachine m_machine;
     165
     166    /* Details view */
     167    QWidget *m_pDetails;
     168    QHash<Section, QString> m_EDStrs;
     169    QHash<Section, QAction*> m_actions;
     170    QHash<Section, UIPopupBox*> m_secBoxes;
     171    bool m_fChangeable;
     172    bool m_fUSBAvailable;
     173
     174    /* Free text */
     175    QRichTextBrowser *m_pText;
     176
     177    /* Error text */
     178    QWidget *m_pErrBox;
     179    QLabel *m_pErrLabel;
     180    QTextBrowser *m_pErrText;
    120181    QToolButton *mRefreshButton;
    121182    QAction *mRefreshAction;
    122183};
    123184
    124 VBoxVMDetailsView::VBoxVMDetailsView (QWidget *aParent,
    125                                       QAction *aRefreshAction /* = NULL */)
    126     : QIWithRetranslateUI<QStackedWidget> (aParent)
    127     , mErrBox (NULL), mErrLabel (NULL), mErrText (NULL)
    128     , mRefreshButton (NULL)
    129     , mRefreshAction (aRefreshAction)
    130 {
    131     Assert (mRefreshAction);
    132 
    133     /* create normal details page */
    134 
    135     mDetailsText = new QRichTextBrowser (mErrBox);
    136     mDetailsText->setViewportMargins (10, 10, 10, 10);
    137     mDetailsText->setFocusPolicy (Qt::StrongFocus);
    138     mDetailsText->document()->setDefaultStyleSheet ("a { text-decoration: none; }");
    139     /* make "transparent" */
    140     mDetailsText->setFrameShape (QFrame::NoFrame);
    141     mDetailsText->viewport()->setAutoFillBackground (false);
    142     mDetailsText->setOpenLinks (false);
    143 
    144     connect (mDetailsText, SIGNAL (anchorClicked (const QUrl &)),
    145              this, SLOT (gotLinkClicked (const QUrl &)));
    146 
    147     addWidget (mDetailsText);
    148 }
    149 
    150 void VBoxVMDetailsView::createErrPage()
    151 {
    152     /* create inaccessible details page */
    153 
    154     if (mErrBox)
     185UIDetailsPagePrivate::UIDetailsPagePrivate(QWidget *aParent,
     186                                           QAction *aRefreshAction /* = 0 */)
     187    : QIWithRetranslateUI<QStackedWidget>(aParent)
     188    , m_vbox(vboxGlobal().virtualBox())
     189    , m_fChangeable(false)
     190    , m_fUSBAvailable(true)
     191    , m_pText(0)
     192    , m_pErrBox(0), m_pErrLabel(0), m_pErrText(0)
     193    , mRefreshButton(0)
     194    , mRefreshAction(aRefreshAction)
     195{
     196    Assert(mRefreshAction);
     197
     198    /* The names for the extra data list */
     199    m_EDStrs[GeneralSec]       = "general";
     200    m_EDStrs[SystemSec]        = "system";
     201    m_EDStrs[PreviewSec]       = "preview";
     202    m_EDStrs[DisplaySec]       = "display";
     203    m_EDStrs[StorageSec]       = "storage";
     204    m_EDStrs[AudioSec]         = "audio";
     205    m_EDStrs[NetworkSec]       = "network";
     206    m_EDStrs[SerialPortsSec]   = "serialPorts";
     207#ifdef VBOX_WITH_PARALLEL_PORTS
     208    m_EDStrs[ParallelPortsSec] = "parallelPorts";
     209#endif /* VBOX_WITH_PARALLEL_PORTS */
     210    m_EDStrs[USBSec]           = "usb";
     211    m_EDStrs[SharedFoldersSec] = "sharedFolders";
     212
     213    QScrollArea *pSArea = new QScrollArea(this);
     214    pSArea->setFrameStyle(QFrame::NoFrame);
     215    m_pDetails = new QWidget(this);
     216    QVBoxLayout *pMainLayout = new QVBoxLayout(m_pDetails);
     217    pMainLayout->setContentsMargins(gsLeftMargin, gsTopMargin, gsRightMargin, gsBottomMargin);
     218
     219    /* Create the context menu, which allows showing/hiding of the boxes */
     220    m_pDetails->setContextMenuPolicy(Qt::CustomContextMenu);
     221    connect(m_pDetails, SIGNAL(customContextMenuRequested(const QPoint&)),
     222            this, SLOT(sltContextMenuRequested(const QPoint&)));
     223    for(int i = 0; i < EndSec; ++i)
     224    {
     225        /* Create the context menu actions */
     226        QAction *pAction = new QAction(this);
     227        pAction->setData(i);
     228        pAction->setCheckable(true);
     229        m_actions[static_cast<Section>(i)] = pAction;
     230
     231        /* Create the popup boxes */
     232        UIPopupBox *pPopup = new UIPopupBox(this);
     233        connect(pPopup, SIGNAL(titleClicked(const QString)),
     234                this, SIGNAL(linkClicked(const QString)));
     235        pPopup->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
     236        m_secBoxes[static_cast<Section>(i)] = pPopup;
     237    }
     238
     239    /* General */
     240    {
     241        QILabel *pLabel= new QILabel(m_secBoxes.value(GeneralSec));
     242        connect(pLabel, SIGNAL(shown()),
     243                this, SLOT(sltUpdateGeneral()));
     244        m_secBoxes.value(GeneralSec)->setTitleIcon(UIIconPool::iconSet(":/machine_16px.png"));
     245        m_secBoxes.value(GeneralSec)->setTitleLink("#general");
     246        m_secBoxes.value(GeneralSec)->setContentWidget(pLabel);
     247        m_secBoxes.value(GeneralSec)->hide();
     248    }
     249
     250    /* System */
     251    {
     252        QILabel *pLabel= new QILabel(this);
     253        connect(pLabel, SIGNAL(shown()),
     254                this, SLOT(sltUpdateSystem()));
     255        m_secBoxes.value(SystemSec)->setTitleIcon(UIIconPool::iconSet(":/chipset_16px.png"));
     256        m_secBoxes.value(SystemSec)->setTitleLink("#system");
     257        m_secBoxes.value(SystemSec)->setContentWidget(pLabel);
     258        m_secBoxes.value(SystemSec)->hide();
     259    }
     260
     261    /* Preview */
     262    {
     263        UIVMPreviewWindow *pWidget = new UIVMPreviewWindow(this);
     264        m_secBoxes.value(PreviewSec)->setTitleIcon(UIIconPool::iconSet(":/machine_16px.png"));
     265        m_secBoxes.value(PreviewSec)->setContentWidget(pWidget);
     266        m_secBoxes.value(PreviewSec)->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
     267        /* Make sure the width is always the same, regardless if the preview is
     268         * shown or not. */
     269        m_secBoxes.value(PreviewSec)->setFixedWidth(m_secBoxes.value(PreviewSec)->sizeHint().width());
     270        m_secBoxes.value(PreviewSec)->hide();
     271    }
     272
     273    QHBoxLayout *tt1 = new QHBoxLayout();
     274    QVBoxLayout *tt2 = new QVBoxLayout();
     275    tt2->addWidget(m_secBoxes.value(GeneralSec));
     276    tt2->addWidget(m_secBoxes.value(SystemSec));
     277    tt2->addStretch(1);
     278    tt1->addLayout(tt2);
     279    QVBoxLayout *tt3 = new QVBoxLayout();
     280    tt3->addWidget(m_secBoxes.value(PreviewSec));
     281    tt3->addStretch(1);
     282    tt1->addLayout(tt3);
     283    pMainLayout->addLayout(tt1);
     284
     285    /* Display */
     286    {
     287        QILabel *pLabel= new QILabel(this);
     288        connect(pLabel, SIGNAL(shown()),
     289                this, SLOT(sltUpdateDisplay()));
     290        m_secBoxes.value(DisplaySec)->setTitleIcon(UIIconPool::iconSet(":/vrdp_16px.png"));
     291        m_secBoxes.value(DisplaySec)->setTitleLink("#display");
     292        m_secBoxes.value(DisplaySec)->setContentWidget(pLabel);
     293        m_secBoxes.value(DisplaySec)->hide();
     294        pMainLayout->addWidget(m_secBoxes.value(DisplaySec));
     295    }
     296
     297    /* Storage */
     298    {
     299        QILabel *pLabel= new QILabel(this);
     300        connect(pLabel, SIGNAL(shown()),
     301                this, SLOT(sltUpdateStorage()));
     302        m_secBoxes.value(StorageSec)->setTitleIcon(UIIconPool::iconSet(":/attachment_16px.png"));
     303        m_secBoxes.value(StorageSec)->setTitleLink("#storage");
     304        m_secBoxes.value(StorageSec)->setContentWidget(pLabel);
     305        m_secBoxes.value(StorageSec)->hide();
     306        pMainLayout->addWidget(m_secBoxes.value(StorageSec));
     307    }
     308
     309    /* Audio */
     310    {
     311        QILabel *pLabel= new QILabel(this);
     312        connect(pLabel, SIGNAL(shown()),
     313                this, SLOT(sltUpdateAudio()));
     314        m_secBoxes.value(AudioSec)->setTitleIcon(UIIconPool::iconSet(":/sound_16px.png"));
     315        m_secBoxes.value(AudioSec)->setTitleLink("#audio");
     316        m_secBoxes.value(AudioSec)->setContentWidget(pLabel);
     317        m_secBoxes.value(AudioSec)->hide();
     318        pMainLayout->addWidget(m_secBoxes.value(AudioSec));
     319    }
     320
     321    /* Network */
     322    {
     323        QILabel *pLabel= new QILabel(this);
     324        connect(pLabel, SIGNAL(shown()),
     325                this, SLOT(sltUpdateNetwork()));
     326        m_secBoxes.value(NetworkSec)->setTitleIcon(UIIconPool::iconSet(":/nw_16px.png"));
     327        m_secBoxes.value(NetworkSec)->setTitleLink("#network");
     328        m_secBoxes.value(NetworkSec)->setContentWidget(pLabel);
     329        m_secBoxes.value(NetworkSec)->hide();
     330        pMainLayout->addWidget(m_secBoxes.value(NetworkSec));
     331    }
     332
     333    /* Serial Ports */
     334    {
     335        QILabel *pLabel= new QILabel(this);
     336        connect(pLabel, SIGNAL(shown()),
     337                this, SLOT(sltUpdateSerialPorts()));
     338        m_secBoxes.value(SerialPortsSec)->setTitleIcon(UIIconPool::iconSet(":/serial_port_16px.png"));
     339        m_secBoxes.value(SerialPortsSec)->setTitleLink("#serialPorts");
     340        m_secBoxes.value(SerialPortsSec)->setContentWidget(pLabel);
     341        m_secBoxes.value(SerialPortsSec)->hide();
     342        pMainLayout->addWidget(m_secBoxes.value(SerialPortsSec));
     343    }
     344
     345#ifdef VBOX_WITH_PARALLEL_PORTS
     346    /* Parallel Ports */
     347    {
     348        QILabel *pLabel= new QILabel(this);
     349        connect(pLabel, SIGNAL(shown()),
     350                this, SLOT(sltUpdateParallelPorts()));
     351        m_secBoxes.value(ParallelPortsSec)->setTitleIcon(UIIconPool::iconSet(":/parallel_port_16px.png"));
     352        m_secBoxes.value(ParallelPortsSec)->setTitleLink("#parallelPorts");
     353        m_secBoxes.value(ParallelPortsSec)->setContentWidget(pLabel);
     354        m_secBoxes.value(ParallelPortsSec)->hide();
     355        pMainLayout->addWidget(m_secBoxes.value(ParallelPortsSec));
     356    }
     357#endif /* VBOX_WITH_PARALLEL_PORTS */
     358
     359    /* USB */
     360    {
     361        QILabel *pLabel= new QILabel(this);
     362        connect(pLabel, SIGNAL(shown()),
     363                this, SLOT(sltUpdateUSB()));
     364        m_secBoxes.value(USBSec)->setTitleIcon(UIIconPool::iconSet(":/usb_16px.png"));
     365        m_secBoxes.value(USBSec)->setTitleLink("#usb");
     366        m_secBoxes.value(USBSec)->setContentWidget(pLabel);
     367        m_secBoxes.value(USBSec)->hide();
     368        pMainLayout->addWidget(m_secBoxes.value(USBSec));
     369    }
     370
     371    /* Shared Folders */
     372    {
     373        QILabel *pLabel= new QILabel(this);
     374        connect(pLabel, SIGNAL(shown()),
     375                this, SLOT(sltUpdateSharedFolders()));
     376        m_secBoxes.value(SharedFoldersSec)->setTitleIcon(UIIconPool::iconSet(":/shared_folder_16px.png"));
     377        m_secBoxes.value(SharedFoldersSec)->setTitleLink("#sfolders");
     378        m_secBoxes.value(SharedFoldersSec)->setContentWidget(pLabel);
     379        m_secBoxes.value(SharedFoldersSec)->hide();
     380        pMainLayout->addWidget(m_secBoxes.value(SharedFoldersSec));
     381    }
     382
     383    pMainLayout->addStretch(1);
     384
     385    pSArea->setWidget(m_pDetails);
     386    pSArea->setWidgetResizable(true);
     387    addWidget(pSArea);
     388
     389    /* Read the configuration from extra data. Defaults are provided in place. */
     390    QStringList boxes = vboxGlobal().virtualBox().GetExtraDataStringList(VBoxDefs::GUI_DetailsPageBoxes,
     391                                                                         /* Defaults */
     392                                                                         QStringList()
     393                                                                         << m_EDStrs.value(GeneralSec)
     394                                                                         << m_EDStrs.value(SystemSec)
     395                                                                         << m_EDStrs.value(PreviewSec)
     396                                                                         << m_EDStrs.value(DisplaySec)
     397                                                                         << m_EDStrs.value(StorageSec)
     398                                                                         << m_EDStrs.value(AudioSec)
     399                                                                         << m_EDStrs.value(NetworkSec)
     400                                                                         << m_EDStrs.value(USBSec)
     401                                                                         << m_EDStrs.value(SharedFoldersSec));
     402    for (int i = 0; i < boxes.size(); ++i)
     403    {
     404        QString strED = boxes.value(i);
     405        bool fOpen = !strED.endsWith("Closed");
     406        Section sec = m_EDStrs.key(fOpen ? strED : strED.remove("Closed"), EndSec);
     407        if (sec != EndSec)
     408        {
     409            m_actions[sec]->setChecked(true);
     410            m_secBoxes.value(sec)->setOpen(fOpen);
     411            m_secBoxes.value(sec)->show();
     412        }
     413    }
     414
     415    retranslateUi();
     416}
     417
     418UIDetailsPagePrivate::~UIDetailsPagePrivate()
     419{
     420    /* Save the configuration to extra data at destruction */
     421    QStringList boxes;
     422    for (int i = 0; i < EndSec; ++i)
     423    {
     424        if (m_actions[static_cast<Section>(i)]->isChecked())
     425        {
     426            QString strED = m_EDStrs.value(static_cast<Section>(i));
     427            if (!m_secBoxes.value(static_cast<Section>(i))->isOpen())
     428                strED += "Closed";
     429            boxes << strED;
     430        }
     431    }
     432    vboxGlobal().virtualBox().SetExtraDataStringList(VBoxDefs::GUI_DetailsPageBoxes,
     433                                                     boxes);
     434}
     435
     436void UIDetailsPagePrivate::sltUpdateGeneral()
     437{
     438    m_secBoxes.value(GeneralSec)->setTitleLinkEnabled(m_fChangeable);
     439    QILabel *pLabel = qobject_cast<QILabel*>(m_secBoxes.value(GeneralSec)->contentWidget());
     440    if (pLabel->isVisible())
     441    {
     442        if (!m_machine.isNull())
     443        {
     444            QString item = sSectionItemTpl2.arg(tr("Name", "details report"),
     445                                                m_machine.GetName())
     446                + sSectionItemTpl2.arg(tr("OS Type", "details report"),
     447                                       vboxGlobal().vmGuestOSTypeDescription(m_machine.GetOSTypeId()));
     448
     449            QString table = sTableTpl.arg(item);
     450            pLabel->setText(table);
     451
     452        }else
     453            pLabel->setText("");
     454    }
     455}
     456
     457void UIDetailsPagePrivate::sltUpdateSystem()
     458{
     459    m_secBoxes.value(SystemSec)->setTitleLinkEnabled(m_fChangeable);
     460    QILabel *pLabel = qobject_cast<QILabel*>(m_secBoxes.value(SystemSec)->contentWidget());
     461    if (pLabel->isVisible())
     462    {
     463        if (!m_machine.isNull())
     464        {
     465            QString item = sSectionItemTpl2.arg(tr("Base Memory", "details report"),
     466                                                tr("<nobr>%1 MB</nobr>", "details report"))
     467                .arg(m_machine.GetMemorySize());
     468
     469            int cCPU = m_machine.GetCPUCount();
     470            if (cCPU > 1)
     471                item += sSectionItemTpl2.arg(tr("Processors", "details report"),
     472                                             tr("<nobr>%1</nobr>", "details report"))
     473                    .arg(cCPU);
     474
     475            /* Boot order */
     476            QStringList bootOrder;
     477            for (ulong i = 1; i <= m_vbox.GetSystemProperties().GetMaxBootPosition(); ++i)
     478            {
     479                KDeviceType device = m_machine.GetBootOrder(i);
     480                if (device == KDeviceType_Null)
     481                    continue;
     482                bootOrder << vboxGlobal().toString(device);
     483            }
     484            if (bootOrder.isEmpty())
     485                bootOrder << vboxGlobal().toString(KDeviceType_Null);
     486
     487            item += sSectionItemTpl2.arg(tr("Boot Order", "details report"), bootOrder.join(", "));
     488
     489#ifdef VBOX_WITH_FULL_DETAILS_REPORT
     490            /* BIOS Settings holder */
     491            const CBIOSSettings &biosSettings = m_machine.GetBIOSSettings();
     492            QStringList bios;
     493            /* ACPI */
     494            if (biosSettings.GetACPIEnabled())
     495                bios << tr("ACPI", "details report");
     496
     497            /* IO APIC */
     498            if (biosSettings.GetIOAPICEnabled())
     499                bios << tr("IO APIC", "details report");
     500
     501            if (!bios.isEmpty())
     502                item += sSectionItemTpl2.arg(tr("BIOS", "details report"), bios.join(", "));
     503#endif /* VBOX_WITH_FULL_DETAILS_REPORT */
     504
     505            QStringList accel;
     506            if (m_vbox.GetHost().GetProcessorFeature(KProcessorFeature_HWVirtEx))
     507            {
     508
     509                /* VT-x/AMD-V */
     510                if (m_machine.GetHWVirtExProperty(KHWVirtExPropertyType_Enabled))
     511                    accel << tr("VT-x/AMD-V", "details report");
     512
     513                /* Nested Paging */
     514                if (m_machine.GetHWVirtExProperty(KHWVirtExPropertyType_NestedPaging))
     515                    accel << tr("Nested Paging", "details report");
     516
     517            }
     518            /* PAE/NX */
     519            if (m_machine.GetCPUProperty(KCPUPropertyType_PAE))
     520                accel << tr("PAE/NX", "details report");
     521
     522            if (!accel.isEmpty())
     523                item += sSectionItemTpl2.arg(tr("Acceleration", "details report"), accel.join(", "));
     524
     525            QString table = sTableTpl.arg(item);
     526            pLabel->setText(table);
     527        } else
     528            pLabel->setText("");
     529    }
     530}
     531
     532void UIDetailsPagePrivate::sltUpdatePreview()
     533{
     534    qobject_cast<UIVMPreviewWindow*>(m_secBoxes.value(PreviewSec)->contentWidget())->setMachine(m_machine);
     535}
     536
     537void UIDetailsPagePrivate::sltUpdateDisplay()
     538{
     539    m_secBoxes.value(DisplaySec)->setTitleLinkEnabled(m_fChangeable);
     540    QILabel *pLabel = qobject_cast<QILabel*>(m_secBoxes.value(DisplaySec)->contentWidget());
     541    if (pLabel->isVisible())
     542    {
     543        if (!m_machine.isNull())
     544        {
     545            /* Video tab */
     546            QString item = QString(sSectionItemTpl2)
     547                .arg(tr("Video Memory", "details report"),
     548                     tr("<nobr>%1 MB</nobr>", "details report"))
     549                .arg(m_machine.GetVRAMSize());
     550
     551            int cGuestScreens = m_machine.GetMonitorCount();
     552            if (cGuestScreens > 1)
     553            {
     554                item += QString(sSectionItemTpl2)
     555                    .arg(tr("Screens", "details report"))
     556                    .arg(cGuestScreens);
     557            }
     558
     559            QStringList accel;
     560#ifdef VBOX_WITH_VIDEOHWACCEL
     561            if (m_machine.GetAccelerate2DVideoEnabled())
     562                accel << tr("2D Video", "details report");
     563#endif /* VBOX_WITH_VIDEOHWACCEL */
     564            if (m_machine.GetAccelerate3DEnabled())
     565                accel << tr("3D", "details report");
     566
     567            if (!accel.isEmpty())
     568                item += sSectionItemTpl2.arg(tr("Acceleration", "details report"), accel.join(", "));
     569
     570            /* VRDP tab */
     571            const CVRDPServer &srv = m_machine.GetVRDPServer();
     572            if (!srv.isNull())
     573            {
     574                if (srv.GetEnabled())
     575                    item += QString(sSectionItemTpl2)
     576                        .arg(tr("Remote Display Server Port", "details report (VRDP Server)"))
     577                        .arg(srv.GetPorts());
     578                else
     579                    item += QString(sSectionItemTpl2)
     580                        .arg(tr("Remote Display Server", "details report (VRDP Server)"))
     581                        .arg(tr("Disabled", "details report (VRDP Server)"));
     582            }
     583
     584            QString table = sTableTpl.arg(item);
     585            pLabel->setText(table);
     586        } else
     587            pLabel->setText("");
     588    }
     589}
     590
     591void UIDetailsPagePrivate::sltUpdateStorage()
     592{
     593    m_secBoxes.value(StorageSec)->setTitleLinkEnabled(m_fChangeable);
     594    QILabel *pLabel = qobject_cast<QILabel*>(m_secBoxes.value(StorageSec)->contentWidget());
     595    if (pLabel->isVisible())
     596    {
     597        if (!m_machine.isNull())
     598        {
     599            QString item;
     600            /* Iterate over the all machine controllers: */
     601            const CStorageControllerVector &controllers = m_machine.GetStorageControllers();
     602            for (int i = 0; i < controllers.size(); ++i)
     603            {
     604                /* Get current controller: */
     605                const CStorageController &controller = controllers[i];
     606                /* Add controller information: */
     607                item += QString(sSectionItemTpl3).arg(controller.GetName());
     608
     609                /* Populate sorted map with attachments information: */
     610                QMap<StorageSlot,QString> attachmentsMap;
     611                const CMediumAttachmentVector &attachments = m_machine.GetMediumAttachmentsOfController(controller.GetName());
     612                for (int j = 0; j < attachments.size(); ++j)
     613                {
     614                    /* Get current attachment: */
     615                    const CMediumAttachment &attachment = attachments[j];
     616                    /* Prepare current storage slot: */
     617                    StorageSlot attachmentSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice());
     618                    /* Append 'device slot name' with 'device type name' for CD/DVD devices only: */
     619                    QString strDeviceType = attachment.GetType() == KDeviceType_DVD ? tr("(CD/DVD)") : QString();
     620                    if (!strDeviceType.isNull())
     621                        strDeviceType.prepend(' ');
     622                    /* Prepare current medium object: */
     623                    const CMedium &medium = attachment.GetMedium();
     624                    /* Prepare information about current medium & attachment: */
     625                    QString strAttachmentInfo = !attachment.isOk() ? QString() :
     626                        QString(sSectionItemTpl2)
     627                        .arg(QString("&nbsp;&nbsp;") +
     628                             vboxGlobal().toString(StorageSlot(controller.GetBus(),
     629                                                               attachment.GetPort(),
     630                                                               attachment.GetDevice())) + strDeviceType)
     631                        .arg(vboxGlobal().details(medium, false));
     632                    /* Insert that attachment into map: */
     633                    if (!strAttachmentInfo.isNull())
     634                        attachmentsMap.insert(attachmentSlot, strAttachmentInfo);
     635                }
     636
     637                /* Iterate over the sorted map with attachments information: */
     638                QMapIterator<StorageSlot,QString> it(attachmentsMap);
     639                while (it.hasNext())
     640                {
     641                    /* Add controller information: */
     642                    it.next();
     643                    item += it.value();
     644                }
     645            }
     646
     647            if (item.isNull())
     648            {
     649                item = QString(sSectionItemTpl1)
     650                    .arg(tr("Not Attached", "details report (Storage)"));
     651            }
     652
     653            QString table = sTableTpl.arg(item);
     654            pLabel->setText(table);
     655        } else
     656            pLabel->setText("");
     657    }
     658}
     659
     660void UIDetailsPagePrivate::sltUpdateAudio()
     661{
     662    m_secBoxes.value(AudioSec)->setTitleLinkEnabled(m_fChangeable);
     663    QILabel *pLabel = qobject_cast<QILabel*>(m_secBoxes.value(AudioSec)->contentWidget());
     664    if (pLabel->isVisible())
     665    {
     666        if (!m_machine.isNull())
     667        {
     668            QString item;
     669
     670            const CAudioAdapter &audio = m_machine.GetAudioAdapter();
     671            if (audio.GetEnabled())
     672                item = QString(sSectionItemTpl2)
     673                    .arg(tr("Host Driver", "details report (audio)"),
     674                         vboxGlobal().toString(audio.GetAudioDriver())) +
     675                    QString(sSectionItemTpl2)
     676                    .arg(tr("Controller", "details report (audio)"),
     677                         vboxGlobal().toString(audio.GetAudioController()));
     678            else
     679                item = QString(sSectionItemTpl1)
     680                    .arg(tr("Disabled", "details report (audio)"));
     681
     682            QString table = sTableTpl.arg(item);
     683            pLabel->setText(table);
     684        } else
     685            pLabel->setText("");
     686    }
     687}
     688
     689void UIDetailsPagePrivate::sltUpdateNetwork()
     690{
     691    m_secBoxes.value(NetworkSec)->setTitleLinkEnabled(m_fChangeable);
     692    QILabel *pLabel = qobject_cast<QILabel*>(m_secBoxes.value(NetworkSec)->contentWidget());
     693    if (pLabel->isVisible())
     694    {
     695        if (!m_machine.isNull())
     696        {
     697            QString item;
     698
     699            ulong count = m_vbox.GetSystemProperties().GetNetworkAdapterCount();
     700            for (ulong slot = 0; slot < count; slot ++)
     701            {
     702                const CNetworkAdapter &adapter = m_machine.GetNetworkAdapter(slot);
     703                if (adapter.GetEnabled())
     704                {
     705                    KNetworkAttachmentType type = adapter.GetAttachmentType();
     706                    QString attType = vboxGlobal().toString(adapter.GetAdapterType())
     707                        .replace(QRegExp("\\s\\(.+\\)"), " (%1)");
     708                    /* don't use the adapter type string for types that have
     709                     * an additional symbolic network/interface name field, use
     710                     * this name instead */
     711                    if (type == KNetworkAttachmentType_Bridged)
     712                        attType = attType.arg(tr("Bridged adapter, %1",
     713                                                 "details report (network)").arg(adapter.GetHostInterface()));
     714                    else if (type == KNetworkAttachmentType_Internal)
     715                        attType = attType.arg(tr("Internal network, '%1'",
     716                                                 "details report (network)").arg(adapter.GetInternalNetwork()));
     717                    else if (type == KNetworkAttachmentType_HostOnly)
     718                        attType = attType.arg(tr("Host-only adapter, '%1'",
     719                                                 "details report (network)").arg(adapter.GetHostInterface()));
     720#ifdef VBOX_WITH_VDE
     721                    else if (type == KNetworkAttachmentType_VDE)
     722                        attType = attType.arg(tr("VDE network, '%1'",
     723                                                 "details report (network)").arg(adapter.GetVDENetwork()));
     724#endif
     725                    else
     726                        attType = attType.arg(vboxGlobal().toString(type));
     727
     728                    item += QString(sSectionItemTpl2)
     729                        .arg(tr("Adapter %1", "details report (network)")
     730                             .arg(adapter.GetSlot() + 1))
     731                        .arg(attType);
     732                }
     733            }
     734            if (item.isNull())
     735            {
     736                item = QString(sSectionItemTpl1)
     737                    .arg(tr("Disabled", "details report (network)"));
     738            }
     739
     740            QString table = sTableTpl.arg(item);
     741            pLabel->setText(table);
     742        } else
     743            pLabel->setText("");
     744    }
     745}
     746
     747void UIDetailsPagePrivate::sltUpdateSerialPorts()
     748{
     749    m_secBoxes.value(SerialPortsSec)->setTitleLinkEnabled(m_fChangeable);
     750    QILabel *pLabel = qobject_cast<QILabel*>(m_secBoxes.value(SerialPortsSec)->contentWidget());
     751    if (pLabel->isVisible())
     752    {
     753        if (!m_machine.isNull())
     754        {
     755            QString item;
     756
     757            ulong count = m_vbox.GetSystemProperties().GetSerialPortCount();
     758            for (ulong slot = 0; slot < count; slot ++)
     759            {
     760                const CSerialPort &port = m_machine.GetSerialPort(slot);
     761                if (port.GetEnabled())
     762                {
     763                    KPortMode mode = port.GetHostMode();
     764                    QString data =
     765                        vboxGlobal().toCOMPortName(port.GetIRQ(), port.GetIOBase()) + ", ";
     766                    if (mode == KPortMode_HostPipe ||
     767                        mode == KPortMode_HostDevice ||
     768                        mode == KPortMode_RawFile)
     769                        data += QString("%1 (<nobr>%2</nobr>)")
     770                            .arg(vboxGlobal().toString(mode))
     771                            .arg(QDir::toNativeSeparators(port.GetPath()));
     772                    else
     773                        data += vboxGlobal().toString(mode);
     774
     775                    item += QString(sSectionItemTpl2)
     776                        .arg(tr("Port %1", "details report (serial ports)")
     777                             .arg(port.GetSlot() + 1))
     778                        .arg(data);
     779                }
     780            }
     781            if (item.isNull())
     782            {
     783                item = QString(sSectionItemTpl1)
     784                    .arg(tr("Disabled", "details report (serial ports)"));
     785            }
     786
     787            QString table = sTableTpl.arg(item);
     788            pLabel->setText(table);
     789        } else
     790            pLabel->setText("");
     791    }
     792}
     793
     794#ifdef VBOX_WITH_PARALLEL_PORTS
     795void UIDetailsPagePrivate::sltUpdateParallelPorts()
     796{
     797    m_secBoxes.value(ParallelPortsSec)->setTitleLinkEnabled(m_fChangeable);
     798    QILabel *pLabel = qobject_cast<QILabel*>(m_secBoxes.value(ParallelPortsSec)->contentWidget());
     799    if (pLabel->isVisible())
     800    {
     801        if (!m_machine.isNull())
     802        {
     803            QString item;
     804
     805            ulong count = m_vbox.GetSystemProperties().GetParallelPortCount();
     806            for (ulong slot = 0; slot < count; slot ++)
     807            {
     808                const CParallelPort &port = m_machine.GetParallelPort(slot);
     809                if (port.GetEnabled())
     810                {
     811                    QString data =
     812                        vboxGlobal().toLPTPortName(port.GetIRQ(), port.GetIOBase()) +
     813                        QString(" (<nobr>%1</nobr>)")
     814                        .arg(QDir::toNativeSeparators(port.GetPath()));
     815
     816                    item += QString(sSectionItemTpl2)
     817                        .arg(tr("Port %1", "details report (parallel ports)")
     818                             .arg(port.GetSlot() + 1))
     819                        .arg(data);
     820                }
     821            }
     822            if (item.isNull())
     823            {
     824                item = QString(sSectionItemTpl1)
     825                    .arg(tr("Disabled", "details report (parallel ports)"));
     826            }
     827
     828            /* Currently disabled */
     829            QString table = sTableTpl.arg(item);
     830            pLabel->setText(table);
     831        } else
     832            pLabel->setText("");
     833    }
     834}
     835#endif /* VBOX_WITH_PARALLEL_PORTS */
     836
     837void UIDetailsPagePrivate::sltUpdateUSB()
     838{
     839    m_secBoxes.value(USBSec)->setTitleLinkEnabled(m_fChangeable);
     840    QILabel *pLabel = qobject_cast<QILabel*>(m_secBoxes.value(USBSec)->contentWidget());
     841    if (pLabel->isVisible())
     842    {
     843        if (!m_machine.isNull())
     844        {
     845            QString item;
     846
     847            const CUSBController &ctl = m_machine.GetUSBController();
     848            if (   !ctl.isNull()
     849                && ctl.GetProxyAvailable())
     850            {
     851                m_fUSBAvailable = true;
     852                /* the USB controller may be unavailable (i.e. in VirtualBox OSE) */
     853                if (ctl.GetEnabled())
     854                {
     855                    const CUSBDeviceFilterVector &coll = ctl.GetDeviceFilters();
     856                    uint active = 0;
     857                    for (int i = 0; i < coll.size(); ++i)
     858                        if (coll[i].GetActive())
     859                            active ++;
     860
     861                    item = QString(sSectionItemTpl2)
     862                        .arg(tr("Device Filters", "details report (USB)"),
     863                             tr("%1 (%2 active)", "details report (USB)")
     864                             .arg(coll.size()).arg(active));
     865                }
     866                else
     867                    item = QString(sSectionItemTpl1)
     868                        .arg(tr("Disabled", "details report (USB)"));
     869
     870                QString table = sTableTpl.arg(item);
     871                pLabel->setText(table);
     872            } else
     873            {
     874                m_fUSBAvailable = false;
     875                /* Fully hide when USB is not available */
     876                m_secBoxes.value(USBSec)->hide();
     877            }
     878        } else
     879            pLabel->setText("");
     880    }
     881}
     882
     883void UIDetailsPagePrivate::sltUpdateSharedFolders()
     884{
     885    m_secBoxes.value(SharedFoldersSec)->setTitleLinkEnabled(m_fChangeable);
     886    QILabel *pLabel = qobject_cast<QILabel*>(m_secBoxes.value(SharedFoldersSec)->contentWidget());
     887    if (pLabel->isVisible())
     888    {
     889        if (!m_machine.isNull())
     890        {
     891            QString item;
     892
     893            ulong count = m_machine.GetSharedFolders().size();
     894            if (count > 0)
     895            {
     896                item = QString(sSectionItemTpl2)
     897                    .arg(tr("Shared Folders", "details report (shared folders)"))
     898                    .arg(count);
     899            }
     900            else
     901                item = QString(sSectionItemTpl1)
     902                    .arg(tr("None", "details report (shared folders)"));
     903
     904            QString table = sTableTpl.arg(item);
     905            pLabel->setText(table);
     906        } else
     907            pLabel->setText("");
     908    }
     909}
     910
     911void UIDetailsPagePrivate::sltContextMenuRequested(const QPoint &pos)
     912{
     913    QList<QAction*> actions = m_actions.values();
     914    if (!m_fUSBAvailable)
     915        actions.removeOne(m_actions.value(USBSec));
     916    QAction *pReturn = QMenu::exec(actions, m_pDetails->mapToGlobal(pos), 0, this);
     917    if (pReturn)
     918    {
     919        UIPopupBox *pBox = m_secBoxes.value(static_cast<Section>(pReturn->data().toInt()));
     920        if (pReturn->isChecked())
     921            pBox->show();
     922        else
     923            pBox->hide();
     924    }
     925}
     926
     927void UIDetailsPagePrivate::setMachine(const CMachine& machine)
     928{
     929    m_machine = machine;
     930    if (m_machine.isNull())
     931        m_fChangeable = false;
     932    else
     933    {
     934        KMachineState state = m_machine.GetState();
     935        bool running = m_machine.GetSessionState() != KSessionState_Closed;
     936        m_fChangeable = !running && state != KMachineState_Saved;
     937    }
     938
     939    sltUpdateGeneral();
     940    sltUpdateSystem();
     941    sltUpdatePreview();
     942    sltUpdateDisplay();
     943    sltUpdateStorage();
     944    sltUpdateAudio();
     945    sltUpdateNetwork();
     946    sltUpdateSerialPorts();
     947#ifdef VBOX_WITH_PARALLEL_PORTS
     948    sltUpdateParallelPorts();
     949#endif /* VBOX_WITH_PARALLEL_PORTS */
     950    sltUpdateUSB();
     951    sltUpdateSharedFolders();
     952
     953    setCurrentIndex(0);
     954}
     955
     956void UIDetailsPagePrivate::createTextPage()
     957{
     958    if (m_pText)
    155959        return;
    156960
    157     mErrBox = new QWidget();
    158 
    159     QVBoxLayout *vLayout = new QVBoxLayout (mErrBox);
    160     vLayout->setSpacing (10);
    161 
    162     mErrLabel = new QLabel (mErrBox);
    163     mErrLabel->setWordWrap (true);
    164     mErrLabel->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed);
    165     vLayout->addWidget (mErrLabel);
    166 
    167     mErrText = new QTextBrowser (mErrBox);
    168     mErrText->setFocusPolicy (Qt::StrongFocus);
    169     mErrText->document()->setDefaultStyleSheet ("a { text-decoration: none; }");
    170     vLayout->addWidget (mErrText);
     961    /* Create normal text page */
     962    m_pText = new QRichTextBrowser(this);
     963    m_pText->setFocusPolicy(Qt::StrongFocus);
     964    m_pText->document()->setDefaultStyleSheet("a { text-decoration: none; }");
     965    /* Make "transparent" */
     966    m_pText->setFrameShape(QFrame::NoFrame);
     967    m_pText->viewport()->setAutoFillBackground(false);
     968    m_pText->setOpenLinks(false);
     969
     970    connect(m_pText, SIGNAL(anchorClicked(const QUrl &)),
     971            this, SLOT(gotLinkClicked(const QUrl &)));
     972
     973    addWidget(m_pText);
     974}
     975
     976void UIDetailsPagePrivate::createErrPage()
     977{
     978    if (m_pErrBox)
     979        return;
     980
     981    /* Create inaccessible details page */
     982    m_pErrBox = new QWidget();
     983
     984    QVBoxLayout *vLayout = new QVBoxLayout(m_pErrBox);
     985    vLayout->setSpacing(10);
     986    vLayout->setContentsMargins(gsLeftMargin, gsTopMargin, gsRightMargin, gsBottomMargin);
     987
     988    m_pErrLabel = new QLabel(m_pErrBox);
     989    m_pErrLabel->setWordWrap(true);
     990    m_pErrLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
     991    vLayout->addWidget(m_pErrLabel);
     992
     993    m_pErrText = new QTextBrowser(m_pErrBox);
     994    m_pErrText->setFocusPolicy(Qt::StrongFocus);
     995    m_pErrText->document()->setDefaultStyleSheet("a { text-decoration: none; }");
     996    vLayout->addWidget(m_pErrText);
    171997
    172998    if (mRefreshAction)
    173999    {
    174         mRefreshButton = new QToolButton (mErrBox);
    175         mRefreshButton->setFocusPolicy (Qt::StrongFocus);
    176 
    177         QHBoxLayout *hLayout = new QHBoxLayout ();
    178         vLayout->addLayout (hLayout);
    179         hLayout->addItem (new QSpacerItem (0, 0, QSizePolicy::Expanding,
     1000        mRefreshButton = new QToolButton(m_pErrBox);
     1001        mRefreshButton->setFocusPolicy(Qt::StrongFocus);
     1002
     1003        QHBoxLayout *hLayout = new QHBoxLayout();
     1004        vLayout->addLayout(hLayout);
     1005        hLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding,
    1801006                                                 QSizePolicy::Minimum));
    181         hLayout->addWidget (mRefreshButton);
    182 
    183         connect (mRefreshButton, SIGNAL (clicked()),
    184                  mRefreshAction, SIGNAL (triggered()));
    185     }
    186 
    187     vLayout->addItem (new QSpacerItem (0, 0, QSizePolicy::Minimum,
    188                                              QSizePolicy::Expanding));
    189 
    190     addWidget (mErrBox);
     1007        hLayout->addWidget(mRefreshButton);
     1008
     1009        connect(mRefreshButton, SIGNAL(clicked()),
     1010                mRefreshAction, SIGNAL(triggered()));
     1011    }
     1012
     1013    vLayout->addItem(new QSpacerItem(0, 0,
     1014                                     QSizePolicy::Minimum,
     1015                                     QSizePolicy::Expanding));
     1016
     1017    addWidget(m_pErrBox);
    1911018
    1921019    retranslateUi();
    1931020}
    1941021
    195 void VBoxVMDetailsView::retranslateUi()
    196 {
    197     if (mErrLabel)
    198         mErrLabel->setText (tr (
     1022void UIDetailsPagePrivate::retranslateUi()
     1023{
     1024    if (m_pErrLabel)
     1025        m_pErrLabel->setText(tr(
    1991026            "The selected virtual machine is <i>inaccessible</i>. Please "
    2001027            "inspect the error message shown below and press the "
     
    2041031    if (mRefreshAction && mRefreshButton)
    2051032    {
    206         mRefreshButton->setText (mRefreshAction->text());
    207         mRefreshButton->setIcon (mRefreshAction->icon());
    208         mRefreshButton->setToolButtonStyle (Qt::ToolButtonTextBesideIcon);
    209     }
    210 }
    211 
    212 // VBoxVMDescriptionPage class
    213 ////////////////////////////////////////////////////////////////////////////////
     1033        mRefreshButton->setText(mRefreshAction->text());
     1034        mRefreshButton->setIcon(mRefreshAction->icon());
     1035        mRefreshButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
     1036    }
     1037
     1038    /* General */
     1039    {
     1040        m_secBoxes.value(GeneralSec)->setTitle(tr("General", "details report"));
     1041        m_actions.value(GeneralSec)->setText(m_secBoxes.value(GeneralSec)->title());
     1042    }
     1043
     1044    /* System */
     1045    {
     1046        m_secBoxes.value(SystemSec)->setTitle(tr("System", "details report"));
     1047        m_actions.value(SystemSec)->setText(m_secBoxes.value(SystemSec)->title());
     1048    }
     1049
     1050    /* Preview */
     1051    {
     1052        m_secBoxes.value(PreviewSec)->setTitle(tr("Preview", "details report"));
     1053        m_actions.value(PreviewSec)->setText(m_secBoxes.value(PreviewSec)->title());
     1054    }
     1055
     1056    /* Display */
     1057    {
     1058        m_secBoxes.value(DisplaySec)->setTitle(tr("Display", "details report"));
     1059        m_actions.value(DisplaySec)->setText(m_secBoxes.value(DisplaySec)->title());
     1060    }
     1061
     1062    /* Storage */
     1063    {
     1064        m_secBoxes.value(StorageSec)->setTitle(tr("Storage", "details report"));
     1065        m_actions.value(StorageSec)->setText(m_secBoxes.value(StorageSec)->title());
     1066    }
     1067
     1068    /* Audio */
     1069    {
     1070        m_secBoxes.value(AudioSec)->setTitle(tr("Audio", "details report"));
     1071        m_actions.value(AudioSec)->setText(m_secBoxes.value(AudioSec)->title());
     1072    }
     1073
     1074    /* Network */
     1075    {
     1076        m_secBoxes.value(NetworkSec)->setTitle(tr("Network", "details report"));
     1077        m_actions.value(NetworkSec)->setText(m_secBoxes.value(NetworkSec)->title());
     1078    }
     1079
     1080    /* Serial Ports */
     1081    {
     1082        m_secBoxes.value(SerialPortsSec)->setTitle(tr("Serial Ports", "details report"));
     1083        m_actions.value(SerialPortsSec)->setText(m_secBoxes.value(SerialPortsSec)->title());
     1084    }
     1085
     1086#ifdef VBOX_WITH_PARALLEL_PORTS
     1087    /* Parallel Ports */
     1088    {
     1089        m_secBoxes.value(ParallelPortsSec)->setTitle(tr("Parallel Ports", "details report"));
     1090        m_actions.value(ParallelPortsSec)->setText(m_secBoxes.value(ParallelPortsSec)->title());
     1091    }
     1092#endif /* VBOX_WITH_PARALLEL_PORTS */
     1093
     1094    /* USB */
     1095    {
     1096        m_secBoxes.value(USBSec)->setTitle(tr("USB", "details report"));
     1097        m_actions.value(USBSec)->setText(m_secBoxes.value(USBSec)->title());
     1098    }
     1099
     1100    /* Shared Folders */
     1101    {
     1102        m_secBoxes.value(SharedFoldersSec)->setTitle(tr("Shared Folders", "details report"));
     1103        m_actions.value(SharedFoldersSec)->setText(m_secBoxes.value(SharedFoldersSec)->title());
     1104    }
     1105}
    2141106
    2151107/**
    216  *  Comments page widget to represent VM comments.
     1108 *  UIDescriptionPagePrivate
    2171109 */
    218 class VBoxVMDescriptionPage : public QIWithRetranslateUI<QWidget>
     1110class UIDescriptionPagePrivate : public QIWithRetranslateUI<QWidget>
    2191111{
    2201112    Q_OBJECT;
     
    2221114public:
    2231115
    224     VBoxVMDescriptionPage (VBoxSelectorWnd *);
    225     ~VBoxVMDescriptionPage() {}
    226 
    227     void setMachineItem (UIVMItem *aItem);
     1116    UIDescriptionPagePrivate(QWidget *pParent = 0);
     1117    ~UIDescriptionPagePrivate() {}
     1118
     1119    void setMachineItem(UIVMItem *pVMItem);
    2281120
    2291121    void updateState();
    2301122
     1123signals:
     1124
     1125    void linkClicked(const QString &aURL);
     1126
    2311127protected:
    2321128
     
    2391135private:
    2401136
    241     UIVMItem *mItem;
    242 
    243     VBoxSelectorWnd *mParent;
    244     QToolButton *mBtnEdit;
    245     QTextBrowser *mBrowser;
    246     QLabel *mLabel;
     1137    UIVMItem *m_pVMItem;
     1138
     1139    QToolButton *m_pEditBtn;
     1140    QTextBrowser *m_pBrowser;
     1141    QLabel *m_pLabel;
    2471142};
    2481143
    249 VBoxVMDescriptionPage::VBoxVMDescriptionPage (VBoxSelectorWnd *aParent)
    250     : QIWithRetranslateUI<QWidget> (aParent)
    251     , mItem (NULL), mParent (aParent)
    252     , mBtnEdit (0), mBrowser (0), mLabel (0)
    253 {
    254     /* main layout */
    255     QVBoxLayout *vMainLayout = new QVBoxLayout (this);
    256     vMainLayout->setSpacing (10);
    257     VBoxGlobal::setLayoutMargin (vMainLayout, 0);
    258 
    259     /* mBrowser */
    260     mBrowser = new QTextBrowser (this);
    261     mBrowser->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
    262     mBrowser->setFocusPolicy (Qt::StrongFocus);
    263     mBrowser->document()->setDefaultStyleSheet ("a { text-decoration: none; }");
    264     vMainLayout->addWidget (mBrowser);
     1144UIDescriptionPagePrivate::UIDescriptionPagePrivate(QWidget *pParent /* = 0 */)
     1145    : QIWithRetranslateUI<QWidget>(pParent)
     1146    , m_pVMItem(0)
     1147    , m_pEditBtn(0)
     1148    , m_pBrowser(0)
     1149    , m_pLabel(0)
     1150{
     1151    /* Main layout */
     1152    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     1153    pMainLayout->setSpacing(10);
     1154    VBoxGlobal::setLayoutMargin(pMainLayout, 0);
     1155
     1156    /* m_pBrowser */
     1157    m_pBrowser = new QTextBrowser(this);
     1158    m_pBrowser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
     1159    m_pBrowser->setFocusPolicy(Qt::StrongFocus);
     1160    m_pBrowser->document()->setDefaultStyleSheet("a { text-decoration: none; }");
     1161    pMainLayout->addWidget(m_pBrowser);
    2651162    /* hidden by default */
    266     mBrowser->setHidden (true);
    267 
    268     mLabel = new QLabel (this);
    269     mLabel->setFrameStyle (mBrowser->frameStyle());
    270     mLabel->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
    271     mLabel->setAlignment (Qt::AlignCenter);
    272     mLabel->setWordWrap (true);
    273     vMainLayout->addWidget (mLabel);
     1163    m_pBrowser->setHidden(true);
     1164
     1165    m_pLabel = new QLabel(this);
     1166    m_pLabel->setFrameStyle(m_pBrowser->frameStyle());
     1167    m_pLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
     1168    m_pLabel->setAlignment(Qt::AlignCenter);
     1169    m_pLabel->setWordWrap(true);
     1170    pMainLayout->addWidget(m_pLabel);
    2741171    /* always disabled */
    275     mLabel->setEnabled (false);
     1172    m_pLabel->setEnabled(false);
    2761173
    2771174    /* button layout */
    278     QHBoxLayout *hBtnLayout = new QHBoxLayout ();
    279     vMainLayout->addLayout (hBtnLayout);
    280     hBtnLayout->setSpacing (10);
    281     hBtnLayout->addItem (new QSpacerItem (0, 0,
    282                                           QSizePolicy::Expanding,
    283                                           QSizePolicy::Minimum));
     1175    QHBoxLayout *hBtnLayout = new QHBoxLayout();
     1176    pMainLayout->addLayout(hBtnLayout);
     1177    hBtnLayout->setSpacing(10);
     1178    hBtnLayout->addItem(new QSpacerItem(0, 0,
     1179                                        QSizePolicy::Expanding,
     1180                                        QSizePolicy::Minimum));
    2841181
    2851182    /* button */
    286     mBtnEdit = new QToolButton (this);
    287     mBtnEdit->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Fixed);
    288     mBtnEdit->setFocusPolicy (Qt::StrongFocus);
    289     mBtnEdit->setIcon(UIIconPool::iconSet(":/edit_description_16px.png",
    290                                           ":/edit_description_disabled_16px.png"));
    291     mBtnEdit->setToolButtonStyle (Qt::ToolButtonTextBesideIcon);
    292     connect (mBtnEdit, SIGNAL (clicked()), this, SLOT (goToSettings()));
    293     hBtnLayout->addWidget (mBtnEdit);
    294 
    295     vMainLayout->addItem (new QSpacerItem (0, 0,
    296                                            QSizePolicy::Expanding,
    297                                            QSizePolicy::Minimum));
     1183    m_pEditBtn = new QToolButton(this);
     1184    m_pEditBtn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
     1185    m_pEditBtn->setFocusPolicy(Qt::StrongFocus);
     1186    m_pEditBtn->setIcon(UIIconPool::iconSet(":/edit_description_16px.png",
     1187                                            ":/edit_description_disabled_16px.png"));
     1188    m_pEditBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
     1189    connect(m_pEditBtn, SIGNAL(clicked()), this, SLOT(goToSettings()));
     1190    hBtnLayout->addWidget(m_pEditBtn);
     1191
     1192    pMainLayout->addItem(new QSpacerItem(0, 0,
     1193                                         QSizePolicy::Expanding,
     1194                                         QSizePolicy::Minimum));
    2981195
    2991196    /* apply language settings */
     
    3041201
    3051202/**
    306  * The machine list @a aItem is used to access cached machine data w/o making
     1203 * The machine list @a pVMItem is used to access cached machine data w/o making
    3071204 * unnecessary RPC calls.
    3081205 */
    309 void VBoxVMDescriptionPage::setMachineItem (UIVMItem *aItem)
    310 {
    311     mItem = aItem;
    312 
    313     QString text = aItem ? aItem->machine().GetDescription() : QString::null;
     1206void UIDescriptionPagePrivate::setMachineItem(UIVMItem *pVMItem)
     1207{
     1208    m_pVMItem = pVMItem;
     1209
     1210    QString text = pVMItem ? pVMItem->machine().GetDescription() : QString::null;
    3141211
    3151212    if (!text.isEmpty())
    3161213    {
    317         mLabel->setHidden (true);
    318         mBrowser->setText (text);
    319         mBrowser->setVisible (true);
     1214        m_pLabel->setHidden(true);
     1215        m_pBrowser->setText(text);
     1216        m_pBrowser->setVisible(true);
    3201217    }
    3211218    else
    3221219    {
    323         mBrowser->setHidden (true);
    324         mBrowser->clear();
    325         mLabel->setVisible (true);
     1220        m_pBrowser->setHidden(true);
     1221        m_pBrowser->clear();
     1222        m_pLabel->setVisible(true);
    3261223    }
    3271224
     
    3301227}
    3311228
    332 void VBoxVMDescriptionPage::retranslateUi()
    333 {
    334     mLabel->setText (tr ("No description. Press the Edit button below to add it."));
    335 
    336     mBtnEdit->setText (tr ("Edit"));
    337     mBtnEdit->setShortcut (QKeySequence ("Ctrl+E"));
    338     mBtnEdit->setToolTip (tr ("Edit (Ctrl+E)"));
    339     mBtnEdit->adjustSize();
    340     mBtnEdit->updateGeometry();
     1229void UIDescriptionPagePrivate::retranslateUi()
     1230{
     1231    m_pLabel->setText(tr("No description. Press the Edit button below to add it."));
     1232
     1233    m_pEditBtn->setText(tr("Edit"));
     1234    m_pEditBtn->setShortcut(QKeySequence("Ctrl+E"));
     1235    m_pEditBtn->setToolTip(tr("Edit (Ctrl+E)"));
     1236    m_pEditBtn->adjustSize();
     1237    m_pEditBtn->updateGeometry();
    3411238}
    3421239
     
    3471244 * first.
    3481245 */
    349 void VBoxVMDescriptionPage::updateState()
     1246void UIDescriptionPagePrivate::updateState()
    3501247{
    3511248    /// @todo disabling the edit button for a saved VM will not be necessary
     
    3531250    /// that can be changed in the saved state, can be changed.
    3541251
    355     if (mItem)
    356     {
    357         bool saved = mItem->state() == KMachineState_Saved;
    358         bool busy = mItem->sessionState() != KSessionState_Closed;
    359         mBtnEdit->setEnabled (!saved && !busy);
     1252    if (m_pVMItem)
     1253    {
     1254        bool saved = m_pVMItem->state() == KMachineState_Saved;
     1255        bool busy = m_pVMItem->sessionState() != KSessionState_Closed;
     1256        m_pEditBtn->setEnabled(!saved && !busy);
    3601257    }
    3611258    else
    362         mBtnEdit->setEnabled (false);
    363 }
    364 
    365 void VBoxVMDescriptionPage::goToSettings()
    366 {
    367     mParent->vmSettings ("#general", "mTeDescription");
    368 }
    369 
    370 // VBoxSelectorWnd class
    371 ////////////////////////////////////////////////////////////////////////////////
    372 
    373 /** \class VBoxSelectorWnd
    374  *
    375  *  The VBoxSelectorWnd class is a VM selector window, one of two main VBox
    376  *  GUI windows.
    377  *
    378  *  This window appears when the user starts the VirtualBox executable.
    379  *  It allows to view the list of configured VMs, their settings
    380  *  and the current state, create, reconfigure, delete and start VMs.
     1259        m_pEditBtn->setEnabled(false);
     1260}
     1261
     1262void UIDescriptionPagePrivate::goToSettings()
     1263{
     1264    emit linkClicked("#general%%mTeDescription");
     1265}
     1266
     1267/**
     1268 *  UIVMDesktop
    3811269 */
    382 
    383 /**
    384  *  Constructs the VM selector window.
    385  *
    386  *  @param aSelf pointer to a variable where to store |this| right after
    387  *               this object's constructor is called (necessary to avoid
    388  *               recursion in VBoxGlobal::selectorWnd())
    389  */
    390 VBoxSelectorWnd::
    391 VBoxSelectorWnd (VBoxSelectorWnd **aSelf, QWidget* aParent,
    392                  Qt::WindowFlags aFlags /* = Qt::Window */)
    393     : QIWithRetranslateUI2<QMainWindow> (aParent, aFlags)
    394     , mDoneInaccessibleWarningOnce (false)
    395 {
    396     VBoxGlobalSettings settings = vboxGlobal().settings();
    397 
    398     if (aSelf)
    399         *aSelf = this;
    400 
    401     statusBar()->setContextMenuPolicy(Qt::CustomContextMenu);
    402     connect(statusBar(), SIGNAL(customContextMenuRequested(const QPoint&)),
    403             this, SLOT(showViewContextMenu(const QPoint&)));
    404 
    405 #if defined (Q_WS_MAC) && (QT_VERSION < 0x040402)
    406     qApp->installEventFilter (this);
    407 #endif /* defined (Q_WS_MAC) && (QT_VERSION < 0x040402) */
    408 
    409 #if !(defined (Q_WS_WIN) || defined (Q_WS_MAC))
    410     /* The application icon. On Win32, it's built-in to the executable. On Mac
    411      * OS X the icon referenced in info.plist is used. */
    412     setWindowIcon (QIcon (":/VirtualBox_48px.png"));
    413 #endif
    414 
    415     /* actions */
    416 
    417     mFileMediaMgrAction = new QAction (this);
    418     mFileMediaMgrAction->setIcon(UIIconPool::iconSet(":/diskimage_16px.png"));
    419 
    420     mFileApplianceImportAction = new QAction (this);
    421     mFileApplianceImportAction->setIcon(UIIconPool::iconSet(":/import_16px.png"));
    422 
    423     mFileApplianceExportAction = new QAction (this);
    424     mFileApplianceExportAction->setIcon(UIIconPool::iconSet(":/export_16px.png"));
    425 
    426     mFileSettingsAction = new QAction(this);
    427     mFileSettingsAction->setMenuRole (QAction::PreferencesRole);
    428     mFileSettingsAction->setIcon(UIIconPool::iconSet(":/global_settings_16px.png"));
    429     mFileExitAction = new QAction (this);
    430     mFileExitAction->setMenuRole (QAction::QuitRole);
    431     mFileExitAction->setIcon(UIIconPool::iconSet(":/exit_16px.png"));
    432 
    433     mVmNewAction = new QAction (this);
    434     mVmNewAction->setIcon(UIIconPool::iconSetFull(
    435         QSize (32, 32), QSize (16, 16),
    436         ":/vm_new_32px.png", ":/new_16px.png"));
    437     mVmConfigAction = new QAction (this);
    438     mVmConfigAction->setIcon(UIIconPool::iconSetFull(
    439         QSize (32, 32), QSize (16, 16),
    440         ":/vm_settings_32px.png", ":/settings_16px.png",
    441         ":/vm_settings_disabled_32px.png", ":/settings_dis_16px.png"));
    442     mVmDeleteAction = new QAction (this);
    443     mVmDeleteAction->setIcon(UIIconPool::iconSetFull(
    444         QSize (32, 32), QSize (16, 16),
    445         ":/vm_delete_32px.png", ":/delete_16px.png",
    446         ":/vm_delete_disabled_32px.png", ":/delete_dis_16px.png"));
    447     mVmStartAction = new QAction (this);
    448     mVmStartAction->setIcon(UIIconPool::iconSetFull(
    449         QSize (32, 32), QSize (16, 16),
    450         ":/vm_start_32px.png", ":/start_16px.png",
    451         ":/vm_start_disabled_32px.png", ":/start_dis_16px.png"));
    452     mVmDiscardAction = new QAction (this);
    453     mVmDiscardAction->setIcon(UIIconPool::iconSetFull(
    454         QSize (32, 32), QSize (16, 16),
    455         ":/vm_discard_32px.png", ":/discard_16px.png",
    456         ":/vm_discard_disabled_32px.png", ":/discard_dis_16px.png"));
    457     mVmPauseAction = new QAction (this);
    458     mVmPauseAction->setCheckable (true);
    459     mVmPauseAction->setIcon(UIIconPool::iconSetFull(
    460         QSize (32, 32), QSize (16, 16),
    461         ":/vm_pause_32px.png", ":/pause_16px.png",
    462         ":/vm_pause_disabled_32px.png", ":/pause_disabled_16px.png"));
    463     mVmRefreshAction = new QAction (this);
    464     mVmRefreshAction->setIcon(UIIconPool::iconSetFull(
    465         QSize (32, 32), QSize (16, 16),
    466         ":/refresh_32px.png", ":/refresh_16px.png",
    467         ":/refresh_disabled_32px.png", ":/refresh_disabled_16px.png"));
    468     mVmShowLogsAction = new QAction (this);
    469     mVmShowLogsAction->setIcon(UIIconPool::iconSetFull(
    470         QSize (32, 32), QSize (16, 16),
    471         ":/vm_show_logs_32px.png", ":/show_logs_16px.png",
    472         ":/vm_show_logs_disabled_32px.png", ":/show_logs_disabled_16px.png"));
    473 
    474     mHelpActions.setup (this);
    475 
    476     QISplitter *pSplitter = new QISplitter(this);
    477     pSplitter->setHandleType(QISplitter::Native);
    478     /* Central widget @ horizontal layout */
    479     setCentralWidget(pSplitter);
    480 
    481     /* VM list toolbar */
    482     mVMToolBar = new VBoxToolBar(this);
    483     mVMToolBar->setContextMenuPolicy(Qt::CustomContextMenu);
     1270enum
     1271{
     1272    Dtls = 0,
     1273    Snap,
     1274    Desc
     1275};
     1276
     1277UIVMDesktop::UIVMDesktop(VBoxToolBar *pToolBar, QAction *pRefreshAction, QWidget *pParent /* = 0 */)
     1278  : QIWithRetranslateUI<QWidget>(pParent)
     1279{
     1280    m_pHeaderBtn = new UITexturedSegmentedButton(3);
     1281    m_pHeaderBtn->setIcon(Dtls, UIIconPool::iconSet(":/settings_16px.png"));
     1282    m_pHeaderBtn->setIcon(Snap, UIIconPool::iconSet(":/take_snapshot_16px.png",
     1283                                                    ":/take_snapshot_dis_16px.png"));
     1284    m_pHeaderBtn->setIcon(Desc, UIIconPool::iconSet(":/description_16px.png",
     1285                                                    ":/description_disabled_16px.png"));
     1286    m_pHeaderBtn->animateClick(0);
     1287
     1288    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     1289    pMainLayout->setContentsMargins(0, 0, 0, 0);
     1290
     1291    /* The header to select the different pages. Has different styles on the
     1292     * different platforms. */
     1293#ifdef DARWIN_USE_TOOLBAR
     1294    if (pToolBar)
     1295    {
     1296        pToolBar->addWidget(new UIHorizontalSpacerWidget(this));
     1297        pToolBar->addWidget(m_pHeaderBtn);
     1298        pToolBar->addWidget(new UIHorizontalSpacerWidget(this));
     1299        pToolBar->updateLayout();
     1300    } else
     1301#else /* DARWIN_USE_TOOLBAR */
     1302        NOREF(pToolBar);
     1303#endif /* !DARWIN_USE_TOOLBAR */
     1304    {
     1305        UIBar *pBar = new UIBar(this);
    4841306#ifndef Q_WS_MAC
    485     connect(mVMToolBar, SIGNAL(customContextMenuRequested(const QPoint&)),
    486             this, SLOT(showViewContextMenu(const QPoint&)));
    487 #else /* !Q_WS_MAC */
    488     /* A simple connect doesn't work on the Mac, also we want receive right
    489      * click notifications on the title bar. So register our own handler. */
    490     ::darwinRegisterForUnifiedToolbarContextMenuEvents(this);
    491 #endif /* Q_WS_MAC */
    492 
    493     /* VM list view */
    494     mVMListView = new UIVMListView();
    495     mVMModel = new UIVMItemModel(mVMListView);
    496     mVMListView->setModel(mVMModel);
    497     mVMListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    498 
    499     /* Make non-possible to activate list elements by single click,
    500      * this hack should disable the current possibility to do it if present */
    501     if (mVMListView->style()->styleHint (QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, mVMListView))
    502         mVMListView->setStyleSheet ("activate-on-singleclick : 0");
    503 
    504 #if MAC_LEOPARD_STYLE
    505     /* Enable unified toolbars on Mac OS X. Available on Qt >= 4.3 */
    506     addToolBar (mVMToolBar);
    507     mVMToolBar->setMacToolbar();
    508     pSplitter->addWidget (mVMListView);
    509 #else /* MAC_LEOPARD_STYLE */
    510     QWidget *pLeftWidget = new QWidget(this);
    511     QVBoxLayout *pLeftVLayout = new QVBoxLayout(pLeftWidget);
    512     pLeftVLayout->setContentsMargins(5, 5, 0, 0);
    513     pLeftVLayout->addWidget(mVMToolBar);
    514     pLeftVLayout->addWidget(mVMListView);
    515     pSplitter->addWidget(pLeftWidget);
    516 #endif /* MAC_LEOPARD_STYLE */
    517 
    518      /* VM tab widget containing details and snapshots tabs */
    519     mVmTabWidget = new QITabWidget();
    520     pSplitter->addWidget (mVmTabWidget);
    521 
    522     /* Set the initial distribution. The right site is bigger. */
    523     pSplitter->setStretchFactor(0, 2);
    524     pSplitter->setStretchFactor(1, 3);
    525 
    526 
    527     /* VM details view */
    528     mVmDetailsView = new VBoxVMDetailsView (NULL, mVmRefreshAction);
    529     mVmTabWidget->addTab(mVmDetailsView,
    530                          UIIconPool::iconSet(":/settings_16px.png"),
    531                          QString::null);
    532 
    533     /* VM snapshots list */
    534     mVmSnapshotsWgt = new VBoxSnapshotsWgt (NULL);
    535     mVmTabWidget->addTab(mVmSnapshotsWgt,
    536                          UIIconPool::iconSet(":/take_snapshot_16px.png",
    537                                              ":/take_snapshot_dis_16px.png"),
    538                          QString::null);
    539     mVmSnapshotsWgt->setContentsMargins (10, 10, 10, 10);
    540 
    541     /* VM comments page */
    542     mVmDescriptionPage = new VBoxVMDescriptionPage (this);
    543     mVmTabWidget->addTab(mVmDescriptionPage,
    544                          UIIconPool::iconSet(":/description_16px.png",
    545                                              ":/description_disabled_16px.png"),
    546                          QString::null);
    547     mVmDescriptionPage->setContentsMargins (10, 10, 10, 10);
    548 
    549     /* add actions to the toolbar */
    550 
    551     mVMToolBar->setIconSize (QSize (32, 32));
    552     mVMToolBar->setToolButtonStyle (Qt::ToolButtonTextUnderIcon);
    553     mVMToolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Preferred);
    554 
    555     mVMToolBar->addAction (mVmNewAction);
    556     mVMToolBar->addAction (mVmConfigAction);
    557 #if 0 /* delete action is really rare */
    558     mVMToolBar->addAction (mVmDeleteAction);
    559 #endif
    560     mVMToolBar->addAction (mVmStartAction);
    561     mVMToolBar->addAction (mVmDiscardAction);
    562 
    563     /* Configure menubar */
    564     menuBar()->setContextMenuPolicy(Qt::CustomContextMenu);
    565     connect(menuBar(), SIGNAL(customContextMenuRequested(const QPoint&)),
    566             this, SLOT(showViewContextMenu(const QPoint&)));
    567 
    568     /* add actions to menubar */
    569     mFileMenu = menuBar()->addMenu (QString::null);
    570     mFileMenu->addAction (mFileMediaMgrAction);
    571     mFileMenu->addAction (mFileApplianceImportAction);
    572     mFileMenu->addAction (mFileApplianceExportAction);
    573 #ifndef Q_WS_MAC
    574     mFileMenu->addSeparator();
    575 #endif /* Q_WS_MAC */
    576     mFileMenu->addAction (mFileSettingsAction);
    577 #ifndef Q_WS_MAC
    578     mFileMenu->addSeparator();
    579 #endif /* Q_WS_MAC */
    580     mFileMenu->addAction (mFileExitAction);
    581 
    582     mVMMenu = menuBar()->addMenu (QString::null);
    583     mVMMenu->addAction (mVmNewAction);
    584     mVMMenu->addAction (mVmConfigAction);
    585     mVMMenu->addAction (mVmDeleteAction);
    586     mVMMenu->addSeparator();
    587     mVMMenu->addAction (mVmStartAction);
    588     mVMMenu->addAction (mVmDiscardAction);
    589     mVMMenu->addAction (mVmPauseAction);
    590     mVMMenu->addSeparator();
    591     mVMMenu->addAction (mVmRefreshAction);
    592     mVMMenu->addAction (mVmShowLogsAction);
    593 
    594     mVMCtxtMenu = new QMenu (this);
    595     mVMCtxtMenu->addAction (mVmConfigAction);
    596     mVMCtxtMenu->addAction (mVmDeleteAction);
    597     mVMCtxtMenu->addSeparator();
    598     mVMCtxtMenu->addAction (mVmStartAction);
    599     mVMCtxtMenu->addAction (mVmDiscardAction);
    600     mVMCtxtMenu->addAction (mVmPauseAction);
    601     mVMCtxtMenu->addSeparator();
    602     mVMCtxtMenu->addAction (mVmRefreshAction);
    603     mVMCtxtMenu->addAction (mVmShowLogsAction);
    604 
    605     /* Make sure every status bar hint from the context menu is cleared when
    606      * the menu is closed. */
    607     connect (mVMCtxtMenu, SIGNAL(aboutToHide()),
    608              statusBar(), SLOT(clearMessage()));
    609 
    610     mHelpMenu = menuBar()->addMenu (QString::null);
    611     mHelpActions.addTo (mHelpMenu);
    612 
    613 #ifdef VBOX_GUI_WITH_SYSTRAY
    614     mTrayIcon = new VBoxTrayIcon (this, mVMModel);
    615     Assert (mTrayIcon);
    616     connect (mTrayIcon, SIGNAL (activated (QSystemTrayIcon::ActivationReason)),
    617              this, SLOT (trayIconActivated (QSystemTrayIcon::ActivationReason)));
    618 #endif
     1307//        pBar->setFixedHeight(65);
     1308#endif /* !Q_WS_MAC */
     1309        pBar->setContentWidget(m_pHeaderBtn);
     1310        pMainLayout->addWidget(pBar);
     1311    }
     1312
     1313    /* Add the pages */
     1314    QStackedLayout *pStack = new QStackedLayout(pMainLayout);
     1315
     1316    m_pDetails = new UIDetailsPagePrivate(this, pRefreshAction);
     1317    connect(m_pDetails, SIGNAL(linkClicked(const QString&)),
     1318            this, SIGNAL(linkClicked(const QString&)));
     1319    pStack->addWidget(m_pDetails);
     1320    m_pSnapshotsPage = new VBoxSnapshotsWgt(this);
     1321    m_pSnapshotsPage->setContentsMargins(gsLeftMargin, gsTopMargin, gsRightMargin, gsBottomMargin);
     1322    pStack->addWidget(m_pSnapshotsPage);
     1323    m_pDescription = new UIDescriptionPagePrivate(this);
     1324    connect(m_pDescription, SIGNAL(linkClicked(const QString&)),
     1325            this, SIGNAL(linkClicked(const QString&)));
     1326    m_pDescription->setContentsMargins(gsLeftMargin, gsTopMargin, gsRightMargin, gsBottomMargin);
     1327    pStack->addWidget(m_pDescription);
     1328
     1329    /* Connect the header buttons with the stack layout. */
     1330    connect(m_pHeaderBtn, SIGNAL(clicked(int)),
     1331            pStack, SLOT(setCurrentIndex(int)));
    6191332
    6201333    retranslateUi();
    621 
    622     CVirtualBox vbox = vboxGlobal().virtualBox();
    623     /* Restore the position of the window */
    624     {
    625         QString winPos = vbox.GetExtraData (VBoxDefs::GUI_LastWindowPosition);
    626 
    627         bool ok = false, max = false;
    628         int x = 0, y = 0, w = 0, h = 0;
    629         x = winPos.section (',', 0, 0).toInt (&ok);
    630         if (ok)
    631             y = winPos.section (',', 1, 1).toInt (&ok);
    632         if (ok)
    633             w = winPos.section (',', 2, 2).toInt (&ok);
    634         if (ok)
    635             h = winPos.section (',', 3, 3).toInt (&ok);
    636         if (ok)
    637             max = winPos.section (',', 4, 4) == VBoxDefs::GUI_LastWindowState_Max;
    638 
    639         QRect ar = ok ? QApplication::desktop()->availableGeometry (QPoint (x, y)) :
    640                         QApplication::desktop()->availableGeometry (this);
    641 
    642         if (ok /* previous parameters were read correctly */
    643             && (y > 0) && (y < ar.bottom()) /* check vertical bounds */
    644             && (x + w > ar.left()) && (x < ar.right()) /* & horizontal bounds */)
    645         {
    646             mNormalGeo.moveTo (x, y);
    647             mNormalGeo.setSize (QSize (w, h).expandedTo (minimumSizeHint())
    648                                             .boundedTo (ar.size()));
    649             setGeometry (mNormalGeo);
    650             if (max) /* maximize if needed */
    651                 showMaximized();
    652         }
    653         else
    654         {
    655             mNormalGeo.setSize (QSize (770, 550).expandedTo (minimumSizeHint())
    656                                                 .boundedTo (ar.size()));
    657             mNormalGeo.moveCenter (ar.center());
    658             setGeometry (mNormalGeo);
    659         }
    660     }
    661 
    662     /* Update the list */
    663     refreshVMList();
    664 
    665     /* Reset to the first item */
    666     mVMListView->selectItemByRow (0);
    667 
    668     /* restore the position of vm selector */
    669     {
    670         QString prevVMId = vbox.GetExtraData (VBoxDefs::GUI_LastVMSelected);
    671 
    672         mVMListView->selectItemById (prevVMId);
    673     }
    674 
    675     /* Read the splitter handle position */
    676     {
    677         QString sliderPos = vbox.GetExtraData(VBoxDefs::GUI_SplitterSizes);
    678         QStringList strSizes = sliderPos.split(",");
    679         if (strSizes.size() == 2)
    680         {
    681             QList<int> sizes;
    682             for (int i=0; i <  strSizes.size(); ++i)
    683                 sizes << strSizes.at(i).toInt();
    684             pSplitter->setSizes(sizes);
    685         }
    686     }
    687 
    688     /* Restore toolbar and statusbar visibility */
    689     {
    690         QString strToolbar = vbox.GetExtraData(VBoxDefs::GUI_Toolbar);
    691         QString strStatusbar = vbox.GetExtraData(VBoxDefs::GUI_Statusbar);
    692 
    693         mVMToolBar->setVisible(strToolbar.isEmpty() || strToolbar == "true");
    694         statusBar()->setVisible(strStatusbar.isEmpty() || strStatusbar == "true");
    695     }
    696 
    697     /* refresh the details et all (necessary for the case when the stored
    698      * selection is still the first list item) */
    699     vmListViewCurrentChanged();
    700 
    701     /* signals and slots connections */
    702     connect (mFileMediaMgrAction, SIGNAL (triggered()), this, SLOT (fileMediaMgr()));
    703     connect (mFileApplianceImportAction, SIGNAL (triggered()), this, SLOT (fileImportAppliance()));
    704     connect (mFileApplianceExportAction, SIGNAL (triggered()), this, SLOT (fileExportAppliance()));
    705     connect (mFileSettingsAction, SIGNAL (triggered()), this, SLOT (fileSettings()));
    706     connect (mFileExitAction, SIGNAL (triggered()), this, SLOT (fileExit()));
    707     connect (mVmNewAction, SIGNAL (triggered()), this, SLOT (vmNew()));
    708 
    709     connect (mVmConfigAction, SIGNAL (triggered()), this, SLOT (vmSettings()));
    710     connect (mVmDeleteAction, SIGNAL (triggered()), this, SLOT (vmDelete()));
    711     connect (mVmStartAction, SIGNAL (triggered()), this, SLOT (vmStart()));
    712     connect (mVmDiscardAction, SIGNAL (triggered()), this, SLOT (vmDiscard()));
    713     connect (mVmPauseAction, SIGNAL (toggled (bool)), this, SLOT (vmPause (bool)));
    714     connect (mVmRefreshAction, SIGNAL (triggered()), this, SLOT (vmRefresh()));
    715     connect (mVmShowLogsAction, SIGNAL (triggered()), this, SLOT (vmShowLogs()));
    716 
    717     connect (mVMListView, SIGNAL (currentChanged()),
    718              this, SLOT (vmListViewCurrentChanged()));
    719     connect (mVMListView, SIGNAL (activated()),
    720              this, SLOT (vmStart()));
    721     connect (mVMListView, SIGNAL (customContextMenuRequested (const QPoint &)),
    722              this, SLOT (showContextMenu (const QPoint &)));
    723 
    724     connect (mVmDetailsView, SIGNAL (linkClicked (const QString &)),
    725              this, SLOT(vmSettings(const QString &)));
    726 
    727     /* listen to media enumeration signals */
    728     connect (&vboxGlobal(), SIGNAL (mediumEnumStarted()),
    729              this, SLOT (mediumEnumStarted()));
    730     connect (&vboxGlobal(), SIGNAL (mediumEnumFinished (const VBoxMediaList &)),
    731              this, SLOT (mediumEnumFinished (const VBoxMediaList &)));
    732 
    733     /* connect VirtualBox events */
    734     connect (gVBoxEvents, SIGNAL(sigMachineStateChange(QString, KMachineState)),
    735              this, SLOT(machineStateChanged(QString, KMachineState)));
    736     connect (gVBoxEvents, SIGNAL(sigMachineDataChange(QString)),
    737              this, SLOT(machineDataChanged(QString)));
    738     connect (gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)),
    739              this, SLOT(machineRegistered(QString, bool)));
    740     connect (gVBoxEvents, SIGNAL(sigSessionStateChange(QString, KSessionState)),
    741              this, SLOT(sessionStateChanged(QString, KSessionState)));
    742     connect (gVBoxEvents, SIGNAL(sigSnapshotChange(QString, QString)),
    743              this, SLOT(snapshotChanged(QString, QString)));
    744 #ifdef VBOX_GUI_WITH_SYSTRAY
    745     connect (gEDataEvents, SIGNAL(sigMainWindowCountChange(int)),
    746              this, SLOT(mainWindowCountChanged(int)));
    747     connect (gEDataEvents, SIGNAL(sigCanShowTrayIcon(bool)),
    748              this, SLOT(trayIconCanShow(bool)));
    749     connect (gEDataEvents, SIGNAL(sigTrayIconChange(bool)),
    750              this, SLOT(trayIconChanged(bool)));
    751     connect (&vboxGlobal(), SIGNAL(sigTrayIconShow(bool)),
    752              this, SLOT(trayIconShow(bool)));
    753 #endif
    754 
    755     /* Listen to potential downloaders signals: */
    756     connect(&vboxProblem(), SIGNAL(sigDownloaderUserManualCreated()), this, SLOT(sltDownloaderUserManualEmbed()));
    757 
    758     /* bring the VM list to the focus */
    759     mVMListView->setFocus();
    760 }
    761 
    762 VBoxSelectorWnd::~VBoxSelectorWnd()
    763 {
    764     /* Destroy our event handlers */
    765     UIVirtualBoxEventHandler::destroy();
    766 
    767     CVirtualBox vbox = vboxGlobal().virtualBox();
    768 
    769     /* Save the position of the window */
    770     {
    771         int y = mNormalGeo.y();
    772         QString winPos = QString ("%1,%2,%3,%4")
    773             .arg (mNormalGeo.x()).arg (y)
    774             .arg (mNormalGeo.width()).arg (mNormalGeo.height());
    775 #ifdef Q_WS_MAC
    776         ::darwinUnregisterForUnifiedToolbarContextMenuEvents(this);
    777         if (::darwinIsWindowMaximized(this))
    778 #else /* Q_WS_MAC */
    779         if (isMaximized())
    780 #endif /* !Q_WS_MAC */
    781             winPos += QString (",%1").arg (VBoxDefs::GUI_LastWindowState_Max);
    782 
    783         vbox.SetExtraData (VBoxDefs::GUI_LastWindowPosition, winPos);
    784     }
    785 
    786     /* Save VM selector position */
    787     {
    788         UIVMItem *item = mVMListView->selectedItem();
    789         QString curVMId = item ?
    790             QString (item->id()) :
    791             QString::null;
    792         vbox.SetExtraData (VBoxDefs::GUI_LastVMSelected, curVMId);
    793     }
    794 
    795     /* Save the splitter handle position */
    796     {
    797         QSplitter *pSplitter = static_cast<QSplitter*>(centralWidget());
    798         QList<int> sizes = pSplitter->sizes();
    799         QStringList strSizes;
    800         for (int i=0; i < sizes.size(); ++i)
    801             strSizes << QString::number(sizes.at(i));
    802         vbox.SetExtraData(VBoxDefs::GUI_SplitterSizes, strSizes.join(","));
    803     }
    804 
    805 #ifdef VBOX_GUI_WITH_SYSTRAY
    806     /* Delete systray menu object */
    807     delete mTrayIcon;
    808     mTrayIcon = NULL;
    809 #endif
    810 
    811     /* Delete the items from our model */
    812     mVMModel->clear();
    813 }
    814 
    815 //
    816 // Public slots
    817 /////////////////////////////////////////////////////////////////////////////
    818 
    819 void VBoxSelectorWnd::fileMediaMgr()
    820 {
    821     VBoxMediaManagerDlg::showModeless (this);
    822 }
    823 
    824 void VBoxSelectorWnd::fileImportAppliance()
    825 {
    826     UIImportApplianceWzd wzd (this);
    827 
    828     wzd.exec();
    829 }
    830 
    831 void VBoxSelectorWnd::fileExportAppliance()
    832 {
    833     QString name;
    834 
    835     UIVMItem *item = mVMListView->selectedItem();
    836     if (item)
    837         name = item->name();
    838 
    839     UIExportApplianceWzd wzd (this, name);
    840 
    841     wzd.exec();
    842 }
    843 
    844 void VBoxSelectorWnd::fileSettings()
    845 {
    846     VBoxGlobalSettings settings = vboxGlobal().settings();
    847     CSystemProperties props = vboxGlobal().virtualBox().GetSystemProperties();
    848 
    849     VBoxSettingsDialog *dlg = new VBoxGLSettingsDlg (this);
    850     dlg->getFrom();
    851 
    852     if (dlg->exec() == QDialog::Accepted)
    853         dlg->putBackTo();
    854 
    855     delete dlg;
    856 }
    857 
    858 void VBoxSelectorWnd::fileExit()
    859 {
    860     /* We have to check if there are any open windows beside this mainwindow
    861      * (e.g. VDM) and if so close them. Note that the default behavior is
    862      * different to Qt3 where a *mainWidget* exists & if this going to close
    863      * all other windows are closed automatically. We do the same below. */
    864     foreach (QWidget *widget, QApplication::topLevelWidgets())
    865     {
    866         if (widget->isVisible() &&
    867             widget != this)
    868             widget->close();
    869     }
    870     /* We close this widget last. */
    871     close();
    872 }
    873 
    874 void VBoxSelectorWnd::vmNew()
    875 {
    876     UINewVMWzd wzd (this);
    877     if (wzd.exec() == QDialog::Accepted)
    878     {
    879         CMachine m = wzd.machine();
    880 
    881         /* wait until the list is updated by OnMachineRegistered() */
    882         QModelIndex index;
    883         while (!index.isValid())
    884         {
    885             qApp->processEvents();
    886             index = mVMModel->indexById (m.GetId());
    887         }
    888         mVMListView->setCurrentIndex (index);
    889     }
    890 }
    891 
    892 /**
    893  *  Opens the VM settings dialog.
    894  */
    895 void VBoxSelectorWnd::vmSettings (const QString &aCategory, const QString &aControl,
    896                                   const QString &aUuid /* = QString::null */)
    897 {
    898     if (!aCategory.isEmpty() && aCategory [0] != '#')
    899     {
    900         /* Assume it's a href from the Details HTML */
    901         vboxGlobal().openURL (aCategory);
    902         return;
    903     }
    904 
    905     UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
    906                        mVMModel->itemById (aUuid);
    907 
    908     AssertMsgReturnVoid (item, ("Item must be always selected here"));
    909 
    910     // open a direct session to modify VM settings
    911     QString id = item->id();
    912     CSession session = vboxGlobal().openSession (id);
    913     if (session.isNull())
    914         return;
    915 
    916     CMachine m = session.GetMachine();
    917     AssertMsgReturn (!m.isNull(), ("Machine must not be null"), (void) 0);
    918 
    919     VBoxSettingsDialog *dlg = new VBoxVMSettingsDlg (this, m, aCategory, aControl);
    920     dlg->getFrom();
    921 
    922     if (dlg->exec() == QDialog::Accepted)
    923     {
    924         QString oldName = m.GetName();
    925         dlg->putBackTo();
    926 
    927         m.SaveSettings();
    928         if (m.isOk())
    929         {
    930             if (oldName.compare (m.GetName()))
    931                 mVMModel->sort();
    932         }
    933         else
    934             vboxProblem().cannotSaveMachineSettings (m);
    935 
    936         /* To check use the result in future
    937          * vboxProblem().cannotApplyMachineSettings (m, res); */
    938     }
    939 
    940     delete dlg;
    941 
    942     mVMListView->setFocus();
    943 
    944     session.Close();
    945 }
    946 
    947 void VBoxSelectorWnd::vmDelete (const QString &aUuid /* = QString::null */)
    948 {
    949     UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
    950                        mVMModel->itemById (aUuid);
    951 
    952     AssertMsgReturnVoid (item, ("Item must be always selected here"));
    953 
    954     if (vboxProblem().confirmMachineDeletion (item->machine()))
    955     {
    956         CVirtualBox vbox = vboxGlobal().virtualBox();
    957         QString id = item->id();
    958         bool ok = false;
    959         if (item->accessible())
    960         {
    961             /* Open a direct session to modify VM settings */
    962             CSession session = vboxGlobal().openSession (id);
    963             if (session.isNull())
    964                 return;
    965             CMachine machine = session.GetMachine();
    966             /* Detach all attached Hard Disks */
    967             CMediumAttachmentVector vec = machine.GetMediumAttachments();
    968             for (int i = 0; i < vec.size(); ++ i)
    969             {
    970                 CMediumAttachment hda = vec [i];
    971                 const QString ctlName = hda.GetController();
    972 
    973                 machine.DetachDevice(ctlName, hda.GetPort(), hda.GetDevice());
    974                 if (!machine.isOk())
    975                 {
    976                     CStorageController ctl = machine.GetStorageControllerByName(ctlName);
    977                     vboxProblem().cannotDetachDevice (this, machine, VBoxDefs::MediumType_HardDisk,
    978                         vboxGlobal().getMedium (CMedium (hda.GetMedium())).location(),
    979                         ctl.GetBus(), hda.GetPort(), hda.GetDevice());
    980                 }
    981             }
    982             /* Commit changes */
    983             machine.SaveSettings();
    984             if (!machine.isOk())
    985                 vboxProblem().cannotSaveMachineSettings (machine);
    986             else
    987                 ok = true;
    988             session.Close();
    989         }
    990         else
    991             ok = true;
    992 
    993         if (ok)
    994         {
    995             CMachine machine = item->machine();
    996             vbox.UnregisterMachine (id);
    997             if (vbox.isOk() && item->accessible())
    998             {
    999                 /* delete machine settings */
    1000                 machine.DeleteSettings();
    1001                 /* remove the item shortly: cmachine it refers to is no longer valid! */
    1002                 int row = mVMModel->rowById (item->id());
    1003                 mVMModel->removeItem (item);
    1004                 delete item;
    1005                 mVMListView->ensureSomeRowSelected (row);
    1006             }
    1007             if (!vbox.isOk() || !machine.isOk())
    1008                 vboxProblem().cannotDeleteMachine (vbox, machine);
    1009         }
    1010     }
    1011 }
    1012 
    1013 void VBoxSelectorWnd::vmStart (const QString &aUuid /* = QString::null */)
    1014 {
    1015     QUuid uuid (aUuid);
    1016     UIVMItem *item = uuid.isNull() ? mVMListView->selectedItem() :
    1017                        mVMModel->itemById (aUuid);
    1018 
    1019     AssertMsgReturnVoid (item, ("Item must be always selected here"));
    1020 
    1021     /* Are we called from the mVMListView's activated() signal? */
    1022     if (uuid.isNull())
    1023     {
    1024         /* We always get here when mVMListView emits the activated() signal,
    1025          * so we must explicitly check if the action is enabled or not. */
    1026         if (!mVmStartAction->isEnabled())
    1027             return;
    1028     }
    1029 
    1030     AssertMsg (!vboxGlobal().isVMConsoleProcess(),
    1031                ("Must NOT be a VM console process"));
    1032 
    1033     /* just switch to the VM window if it already exists */
    1034     if (item->canSwitchTo())
    1035     {
    1036         item->switchTo();
    1037         return;
    1038     }
    1039 
    1040     AssertMsg (   item->state() == KMachineState_PoweredOff
    1041                || item->state() == KMachineState_Saved
    1042                || item->state() == KMachineState_Teleported
    1043                || item->state() == KMachineState_Aborted
    1044                , ("Machine must be PoweredOff/Saved/Aborted (%d)", item->state()));
    1045 
    1046     QString id = item->id();
    1047     CVirtualBox vbox = vboxGlobal().virtualBox();
    1048     CSession session;
    1049 
    1050     session.createInstance (CLSID_Session);
    1051     if (session.isNull())
    1052     {
    1053         vboxProblem().cannotOpenSession (session);
    1054         return;
    1055     }
    1056 
    1057 #if defined (Q_OS_WIN32)
    1058     /* allow the started VM process to make itself the foreground window */
    1059     AllowSetForegroundWindow (ASFW_ANY);
    1060 #endif
    1061 
    1062     QString env;
    1063 #if defined (Q_WS_X11)
    1064     /* make sure the VM process will start on the same display as the Selector */
    1065     const char *display = RTEnvGet ("DISPLAY");
    1066     if (display)
    1067         env.append(QString("DISPLAY=%1\n").arg(display));
    1068     const char *xauth = RTEnvGet ("XAUTHORITY");
    1069     if (xauth)
    1070         env.append(QString("XAUTHORITY=%1\n").arg(xauth));
    1071 #endif
    1072 
    1073     CProgress progress = vbox.OpenRemoteSession (session, id, "GUI/Qt", env);
    1074     if (!vbox.isOk())
    1075     {
    1076         vboxProblem().cannotOpenSession (vbox, item->machine());
    1077         return;
    1078     }
    1079 
    1080     /* Hide the "VM spawning" progress dialog */
    1081     /* I hope 1 minute will be enough to spawn any running VM silently, isn't it? */
    1082     int iSpawningDuration = 60000;
    1083     vboxProblem().showModalProgressDialog(progress, item->name(), this, iSpawningDuration);
    1084     if (progress.GetResultCode() != 0)
    1085         vboxProblem().cannotOpenSession(vbox, item->machine(), progress);
    1086 
    1087     session.Close();
    1088 }
    1089 
    1090 void VBoxSelectorWnd::vmDiscard (const QString &aUuid /* = QString::null */)
    1091 {
    1092     UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
    1093                        mVMModel->itemById (aUuid);
    1094 
    1095     AssertMsgReturnVoid (item, ("Item must be always selected here"));
    1096 
    1097     if (!vboxProblem().confirmDiscardSavedState (item->machine()))
    1098         return;
    1099 
    1100     /* open a session to modify VM settings */
    1101     QString id = item->id();
    1102     CSession session;
    1103     CVirtualBox vbox = vboxGlobal().virtualBox();
    1104     session.createInstance (CLSID_Session);
    1105     if (session.isNull())
    1106     {
    1107         vboxProblem().cannotOpenSession (session);
    1108         return;
    1109     }
    1110     vbox.OpenSession (session, id);
    1111     if (!vbox.isOk())
    1112     {
    1113         vboxProblem().cannotOpenSession (vbox, item->machine());
    1114         return;
    1115     }
    1116 
    1117     CConsole console = session.GetConsole();
    1118     console.ForgetSavedState(true);
    1119     if (!console.isOk())
    1120         vboxProblem().cannotDiscardSavedState (console);
    1121 
    1122     session.Close();
    1123 }
    1124 
    1125 void VBoxSelectorWnd::vmPause (bool aPause, const QString &aUuid /* = QString::null */)
    1126 {
    1127     UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
    1128                        mVMModel->itemById (aUuid);
    1129 
    1130     AssertMsgReturnVoid (item, ("Item must be always selected here"));
    1131 
    1132     CSession session = vboxGlobal().openExistingSession (item->id());
    1133     if (session.isNull())
    1134         return;
    1135 
    1136     CConsole console = session.GetConsole();
    1137     if (console.isNull())
    1138         return;
    1139 
    1140     if (aPause)
    1141         console.Pause();
    1142     else
    1143         console.Resume();
    1144 
    1145     bool ok = console.isOk();
    1146     if (!ok)
    1147     {
    1148         if (aPause)
    1149             vboxProblem().cannotPauseMachine (console);
    1150         else
    1151             vboxProblem().cannotResumeMachine (console);
    1152     }
    1153 
    1154     session.Close();
    1155 }
    1156 
    1157 void VBoxSelectorWnd::vmRefresh (const QString &aUuid /* = QString::null */)
    1158 {
    1159     UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
    1160                        mVMModel->itemById (aUuid);
    1161 
    1162     AssertMsgReturnVoid (item, ("Item must be always selected here"));
    1163 
    1164     refreshVMItem (item->id(),
    1165                    true /* aDetails */,
    1166                    true /* aSnapshot */,
    1167                    true /* aDescription */);
    1168 }
    1169 
    1170 void VBoxSelectorWnd::vmShowLogs (const QString &aUuid /* = QString::null */)
    1171 {
    1172     UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
    1173                        mVMModel->itemById (aUuid);
    1174 
    1175     AssertMsgReturnVoid (item, ("Item must be always selected here"));
    1176 
    1177     CMachine machine = item->machine();
    1178     VBoxVMLogViewer::createLogViewer (this, machine);
    1179 }
    1180 
    1181 void VBoxSelectorWnd::refreshVMList()
    1182 {
    1183     CVirtualBox vbox = vboxGlobal().virtualBox();
    1184     CMachineVector vec = vbox.GetMachines();
    1185     for (CMachineVector::ConstIterator m = vec.begin();
    1186          m != vec.end(); ++ m)
    1187         mVMModel->addItem (new UIVMItem (*m));
    1188     mVMModel->sort();
    1189 
    1190     vmListViewCurrentChanged();
    1191 
    1192 #ifdef VBOX_GUI_WITH_SYSTRAY
    1193     if (vboxGlobal().isTrayMenu())
    1194         mTrayIcon->refresh();
    1195 #endif
    1196 }
    1197 
    1198 void VBoxSelectorWnd::refreshVMItem (const QString &aID, bool aDetails,
    1199                                                        bool aSnapshots,
    1200                                                        bool aDescription)
    1201 {
    1202     UIVMItem *item = mVMModel->itemById (aID);
    1203     if (item)
    1204     {
    1205         mVMModel->refreshItem (item);
    1206         if (item && item->id() == aID)
    1207             vmListViewCurrentChanged (aDetails, aSnapshots, aDescription);
    1208     }
    1209 }
    1210 
    1211 void VBoxSelectorWnd::showContextMenu (const QPoint &aPoint)
    1212 {
    1213     /* Send a context menu request */
    1214     const QModelIndex &index = mVMListView->indexAt (aPoint);
    1215     if (index.isValid())
    1216         if (mVMListView->model()->data (index,
    1217             UIVMItemModel::UIVMItemPtrRole).value <UIVMItem*>())
    1218                 mVMCtxtMenu->exec (mVMListView->mapToGlobal (aPoint));
    1219 }
    1220 
    1221 #ifdef VBOX_GUI_WITH_SYSTRAY
    1222 
    1223 void VBoxSelectorWnd::trayIconActivated (QSystemTrayIcon::ActivationReason aReason)
    1224 {
    1225     switch (aReason)
    1226     {
    1227         case QSystemTrayIcon::Context:
    1228 
    1229             mTrayIcon->refresh();
    1230             break;
    1231 
    1232         case QSystemTrayIcon::Trigger:
    1233             break;
    1234 
    1235         case QSystemTrayIcon::DoubleClick:
    1236 
    1237             vboxGlobal().trayIconShowSelector();
    1238             break;
    1239 
    1240         case QSystemTrayIcon::MiddleClick:
    1241             break;
    1242 
    1243         default:
    1244             break;
    1245     }
    1246 }
    1247 
    1248 void VBoxSelectorWnd::showWindow()
    1249 {
    1250     showNormal();
    1251     raise();
    1252     activateWindow();
    1253 }
    1254 
    1255 #endif // VBOX_GUI_WITH_SYSTRAY
    1256 
    1257 // Protected members
    1258 /////////////////////////////////////////////////////////////////////////////
    1259 
    1260 bool VBoxSelectorWnd::event (QEvent *e)
    1261 {
    1262     switch (e->type())
    1263     {
    1264         /* By handling every Resize and Move we keep track of the normal
    1265          * (non-minimized and non-maximized) window geometry. Shame on Qt
    1266          * that it doesn't provide this geometry in its public APIs. */
    1267 
    1268         case QEvent::Resize:
    1269         {
    1270             QResizeEvent *re = (QResizeEvent *) e;
    1271             if ((windowState() & (Qt::WindowMaximized | Qt::WindowMinimized |
    1272                                   Qt::WindowFullScreen)) == 0)
    1273                 mNormalGeo.setSize (re->size());
    1274             break;
    1275         }
    1276         case QEvent::Move:
    1277         {
    1278             if ((windowState() & (Qt::WindowMaximized | Qt::WindowMinimized |
    1279                                   Qt::WindowFullScreen)) == 0)
    1280                 mNormalGeo.moveTo (geometry().x(), geometry().y());
    1281             break;
    1282         }
    1283         case QEvent::WindowDeactivate:
    1284         {
    1285             /* Make sure every status bar hint is cleared when the window lost
    1286              * focus. */
    1287             statusBar()->clearMessage();
    1288             break;
    1289         }
    1290 #ifdef Q_WS_MAC
    1291         case QEvent::ContextMenu:
    1292         {
    1293             /* This is the unified context menu event. Lets show the context
    1294              * menu. */
    1295             QContextMenuEvent *pCE = static_cast<QContextMenuEvent*>(e);
    1296             showViewContextMenu(pCE->globalPos());
    1297             /* Accept it to interrupt the chain. */
    1298             pCE->accept();
    1299             return false;
    1300             break;
    1301         }
    1302         case QEvent::ToolBarChange:
    1303         {
    1304             CVirtualBox vbox = vboxGlobal().virtualBox();
    1305             /* We have to invert the isVisible check one time, cause this event
    1306              * is sent *before* the real toggle is done. Really intuitive
    1307              * Trolls. */
    1308             vbox.SetExtraData(VBoxDefs::GUI_Toolbar, !::darwinIsToolbarVisible(mVMToolBar) ? "true" : "false");
    1309             break;
    1310         }
    1311 #endif /* Q_WS_MAC */
    1312         default:
    1313             break;
    1314     }
    1315 
    1316     return QMainWindow::event (e);
    1317 }
    1318 
    1319 void VBoxSelectorWnd::closeEvent (QCloseEvent *aEvent)
    1320 {
    1321 #ifdef VBOX_GUI_WITH_SYSTRAY
    1322     /* Needed for breaking out of the while() loop in main(). */
    1323     if (vboxGlobal().isTrayMenu())
    1324         vboxGlobal().setTrayMenu (false);
    1325 #endif
    1326 
    1327     emit closing();
    1328     QMainWindow::closeEvent (aEvent);
    1329 }
    1330 
    1331 #if defined (Q_WS_MAC) && (QT_VERSION < 0x040402)
    1332 bool VBoxSelectorWnd::eventFilter (QObject *aObject, QEvent *aEvent)
    1333 {
    1334     if (!isActiveWindow())
    1335         return QIWithRetranslateUI2<QMainWindow>::eventFilter (aObject, aEvent);
    1336 
    1337     if (qobject_cast<QWidget*> (aObject) &&
    1338         qobject_cast<QWidget*> (aObject)->window() != this)
    1339         return QIWithRetranslateUI2<QMainWindow>::eventFilter (aObject, aEvent);
    1340 
    1341     switch (aEvent->type())
    1342     {
    1343         case QEvent::KeyPress:
    1344             {
    1345                 /* Bug in Qt below 4.4.2. The key events are send to the current
    1346                  * window even if a menu is shown & has the focus. See
    1347                  * http://trolltech.com/developer/task-tracker/index_html?method=entry&id=214681. */
    1348                 if (::darwinIsMenuOpen())
    1349                     return true;
    1350             }
    1351         default:
    1352             break;
    1353     }
    1354     return QIWithRetranslateUI2<QMainWindow>::eventFilter (aObject, aEvent);
    1355 }
    1356 #endif /* defined (Q_WS_MAC) && (QT_VERSION < 0x040402) */
    1357 
    1358 /**
    1359  *  Sets the strings of the subwidgets using the current
    1360  *  language.
    1361  */
    1362 void VBoxSelectorWnd::retranslateUi()
    1363 {
    1364 #ifdef VBOX_OSE
    1365     QString title (tr ("VirtualBox OSE"));
    1366 #else
    1367     QString title (VBOX_PRODUCT);
    1368 #endif
    1369 
    1370 #ifdef VBOX_BLEEDING_EDGE
    1371     title += QString(" EXPERIMENTAL build ")
    1372           +  QString(RTBldCfgVersion())
    1373           +  QString(" r")
    1374           +  QString(RTBldCfgRevisionStr())
    1375           +  QString(" - "VBOX_BLEEDING_EDGE);
    1376 #endif
    1377 
    1378     setWindowTitle (title);
    1379 
    1380     mVmTabWidget->setTabText (mVmTabWidget->indexOf (mVmDetailsView), tr ("&Details"));
    1381     /* note: Snapshots and Details tabs are changed dynamically by
    1382      * vmListViewCurrentChanged() */
    1383 
    1384     /* ensure the details and screenshot view are updated */
    1385     vmListViewCurrentChanged();
    1386 
    1387     mFileMediaMgrAction->setText (tr ("&Virtual Media Manager..."));
    1388     mFileMediaMgrAction->setShortcut (QKeySequence ("Ctrl+D"));
    1389     mFileMediaMgrAction->setStatusTip (tr ("Display the Virtual Media Manager dialog"));
    1390 
    1391     mFileApplianceImportAction->setText (tr ("&Import Appliance..."));
    1392     mFileApplianceImportAction->setShortcut (QKeySequence ("Ctrl+I"));
    1393     mFileApplianceImportAction->setStatusTip (tr ("Import an appliance into VirtualBox"));
    1394 
    1395     mFileApplianceExportAction->setText (tr ("&Export Appliance..."));
    1396     mFileApplianceExportAction->setShortcut (QKeySequence ("Ctrl+E"));
    1397     mFileApplianceExportAction->setStatusTip (tr ("Export one or more VirtualBox virtual machines as an appliance"));
    1398 
    1399 #ifdef Q_WS_MAC
    1400     /*
    1401      * Macification: Getting the right menu as application preference menu item.
    1402      *
    1403      * QMenuBar::isCommand() in qmenubar_mac.cpp doesn't recognize "Setting"(s)
    1404      * unless it's in the first position. So, we use the Mac term here to make
    1405      * sure we get picked instead of the VM settings.
    1406      *
    1407      * Now, since both QMenuBar and we translate these strings, it's going to
    1408      * be really interesting to see how this plays on non-english systems...
    1409      */
    1410     mFileSettingsAction->setText (tr ("&Preferences...", "global settings"));
    1411 #else
    1412     /*
    1413      * ...and on other platforms we use "Preferences" as well. The #ifdef is
    1414      * left because of the possible localization problems on Mac we first need
    1415      * to figure out.
    1416      */
    1417     mFileSettingsAction->setText (tr ("&Preferences...", "global settings"));
    1418 #endif
    1419     mFileSettingsAction->setShortcut (QKeySequence ("Ctrl+G"));
    1420     mFileSettingsAction->setStatusTip (tr ("Display the global settings dialog"));
    1421 
    1422     mFileExitAction->setText (tr ("E&xit"));
    1423     mFileExitAction->setShortcut (QKeySequence ("Ctrl+Q"));
    1424     mFileExitAction->setStatusTip (tr ("Close application"));
    1425 
    1426     mVmNewAction->setText (tr ("&New..."));
    1427     mVmNewAction->setShortcut (QKeySequence ("Ctrl+N"));
    1428     mVmNewAction->setStatusTip (tr ("Create a new virtual machine"));
    1429     mVmNewAction->setToolTip (mVmNewAction->text().remove ('&').remove ('.') +
    1430         QString (" (%1)").arg (mVmNewAction->shortcut().toString()));
    1431 
    1432     mVmConfigAction->setText (tr ("&Settings..."));
    1433     mVmConfigAction->setShortcut (QKeySequence ("Ctrl+S"));
    1434     mVmConfigAction->setStatusTip (tr ("Configure the selected virtual machine"));
    1435     mVmConfigAction->setToolTip (mVmConfigAction->text().remove ('&').remove ('.') +
    1436         QString (" (%1)").arg (mVmConfigAction->shortcut().toString()));
    1437 
    1438     mVmDeleteAction->setText (tr ("&Delete"));
    1439     mVmDeleteAction->setShortcut (QKeySequence ("Ctrl+R"));
    1440     mVmDeleteAction->setStatusTip (tr ("Delete the selected virtual machine"));
    1441 
    1442     /* Note: mVmStartAction text is set up in vmListViewCurrentChanged() */
    1443 
    1444     mVmDiscardAction->setText (tr ("D&iscard"));
    1445     mVmDiscardAction->setStatusTip (
    1446         tr ("Discard the saved state of the selected virtual machine"));
    1447 
    1448     mVmPauseAction->setText (tr ("&Pause"));
    1449     mVmPauseAction->setStatusTip (
    1450         tr ("Suspend the execution of the virtual machine"));
    1451 
    1452     mVmRefreshAction->setText (tr ("Re&fresh"));
    1453     mVmRefreshAction->setStatusTip (
    1454         tr ("Refresh the accessibility state of the selected virtual machine"));
    1455 
    1456     mVmShowLogsAction->setText (tr ("Show &Log..."));
    1457     mVmShowLogsAction->setIconText (tr ("Log", "icon text"));
    1458     mVmShowLogsAction->setShortcut (QKeySequence ("Ctrl+L"));
    1459     mVmShowLogsAction->setStatusTip (
    1460         tr ("Show the log files of the selected virtual machine"));
    1461 
    1462     mHelpActions.retranslateUi();
    1463 
    1464 #ifdef Q_WS_MAC
    1465     mFileMenu->setTitle (tr("&File", "Mac OS X version"));
    1466 #else /* Q_WS_MAC */
    1467     mFileMenu->setTitle (tr("&File", "Non Mac OS X version"));
    1468 #endif /* !Q_WS_MAC */
    1469     mVMMenu->setTitle (tr ("&Machine"));
    1470     mHelpMenu->setTitle (tr ("&Help"));
    1471 
    1472 #ifdef VBOX_GUI_WITH_SYSTRAY
    1473     if (vboxGlobal().isTrayMenu())
    1474     {
    1475         mTrayIcon->retranslateUi();
    1476         mTrayIcon->refresh();
    1477     }
    1478 #endif
    1479 
    1480 #ifdef QT_MAC_USE_COCOA
    1481     /* There is a bug in Qt Cocoa which result in showing a "more arrow" when
    1482        the necessary size of the toolbar is increased. Also for some languages
    1483        the with doesn't match if the text increase. So manually adjust the size
    1484        after changing the text. */
    1485     mVMToolBar->updateLayout();
    1486 #endif /* QT_MAC_USE_COCOA */
    1487 }
    1488 
    1489 
    1490 // Private members
    1491 /////////////////////////////////////////////////////////////////////////////
    1492 
    1493 //
    1494 // Private slots
    1495 /////////////////////////////////////////////////////////////////////////////
    1496 
    1497 void VBoxSelectorWnd::vmListViewCurrentChanged (bool aRefreshDetails,
    1498                                                 bool aRefreshSnapshots,
    1499                                                 bool aRefreshDescription)
    1500 {
    1501     UIVMItem *item = mVMListView->selectedItem();
    1502 
    1503     if (item && item->accessible())
    1504     {
    1505         CMachine m = item->machine();
    1506 
    1507         KMachineState state = item->state();
    1508         bool running = item->sessionState() != KSessionState_Closed;
    1509         bool modifyEnabled = !running && state != KMachineState_Saved;
    1510 
    1511         if (aRefreshDetails)
    1512         {
    1513             mVmDetailsView->setDetailsText (
    1514                 vboxGlobal().detailsReport (m, modifyEnabled /* withLinks */));
    1515         }
    1516         if (aRefreshSnapshots)
    1517         {
    1518             /* update the snapshots tab name */
    1519             QString name = tr ("&Snapshots");
    1520             ULONG count = item->snapshotCount();
    1521             if (count)
    1522                 name += QString (" (%1)").arg (count);
    1523             mVmTabWidget->setTabText (mVmTabWidget->indexOf (mVmSnapshotsWgt), name);
    1524             /* refresh the snapshots widget */
    1525             mVmSnapshotsWgt->setMachine (m);
    1526             /* ensure the tab is enabled */
    1527             mVmTabWidget->setTabEnabled (mVmTabWidget->indexOf (mVmSnapshotsWgt), true);
    1528         }
    1529         if (aRefreshDescription)
    1530         {
    1531             /* update the description tab name */
    1532             QString name = m.GetDescription().isEmpty() ?
    1533                 tr ("D&escription") : tr ("D&escription *");
    1534             mVmTabWidget->setTabText (mVmTabWidget->indexOf (mVmDescriptionPage), name);
    1535             /* refresh the description widget */
    1536             mVmDescriptionPage->setMachineItem (item);
    1537             /* ensure the tab is enabled */
    1538             mVmTabWidget->setTabEnabled (mVmTabWidget->indexOf (mVmDescriptionPage), true);
    1539         }
    1540 
    1541         /* enable/disable modify actions */
    1542         mVmConfigAction->setEnabled (modifyEnabled);
    1543         mVmDeleteAction->setEnabled (modifyEnabled);
    1544         mVmDiscardAction->setEnabled (state == KMachineState_Saved && !running);
    1545         mVmPauseAction->setEnabled (   state == KMachineState_Running
    1546                                     || state == KMachineState_Teleporting
    1547                                     || state == KMachineState_LiveSnapshotting
    1548                                     || state == KMachineState_Paused
    1549                                     || state == KMachineState_TeleportingPausedVM /** @todo Live Migration: does this make sense? */
    1550                                    );
    1551 
    1552         /* change the Start button text accordingly */
    1553         if (   state == KMachineState_PoweredOff
    1554             || state == KMachineState_Saved
    1555             || state == KMachineState_Teleported
    1556             || state == KMachineState_Aborted
    1557            )
    1558         {
    1559             mVmStartAction->setText (tr ("S&tart"));
    1560 #ifdef QT_MAC_USE_COCOA
    1561             /* There is a bug in Qt Cocoa which result in showing a "more arrow" when
    1562                the necessary size of the toolbar is increased. Also for some languages
    1563                the with doesn't match if the text increase. So manually adjust the size
    1564                after changing the text. */
    1565             mVMToolBar->updateLayout();
    1566 #endif /* QT_MAC_USE_COCOA */
    1567             mVmStartAction->setStatusTip (
    1568                 tr ("Start the selected virtual machine"));
    1569 
    1570             mVmStartAction->setEnabled (!running);
    1571         }
    1572         else
    1573         {
    1574             mVmStartAction->setText (tr ("S&how"));
    1575 #ifdef QT_MAC_USE_COCOA
    1576             /* There is a bug in Qt Cocoa which result in showing a "more arrow" when
    1577                the necessary size of the toolbar is increased. Also for some languages
    1578                the with doesn't match if the text increase. So manually adjust the size
    1579                after changing the text. */
    1580             mVMToolBar->updateLayout();
    1581 #endif /* QT_MAC_USE_COCOA */
    1582             mVmStartAction->setStatusTip (
    1583                 tr ("Switch to the window of the selected virtual machine"));
    1584 
    1585             mVmStartAction->setEnabled (item->canSwitchTo());
    1586         }
    1587 
    1588         /* change the Pause/Resume button text accordingly */
    1589         if (   state == KMachineState_Paused
    1590             || state == KMachineState_TeleportingPausedVM /*?*/
    1591            )
    1592         {
    1593             mVmPauseAction->setText (tr ("R&esume"));
    1594             mVmPauseAction->setShortcut (QKeySequence ("Ctrl+P"));
    1595             mVmPauseAction->setStatusTip (
    1596                 tr ("Resume the execution of the virtual machine"));
    1597             mVmPauseAction->blockSignals (true);
    1598             mVmPauseAction->setChecked (true);
    1599             mVmPauseAction->blockSignals (false);
    1600         }
    1601         else
    1602         {
    1603             mVmPauseAction->setText (tr ("&Pause"));
    1604             mVmPauseAction->setShortcut (QKeySequence ("Ctrl+P"));
    1605             mVmPauseAction->setStatusTip (
    1606                 tr ("Suspend the execution of the virtual machine"));
    1607             mVmPauseAction->blockSignals (true);
    1608             mVmPauseAction->setChecked (false);
    1609             mVmPauseAction->blockSignals (false);
    1610         }
    1611 
    1612         /* disable Refresh for accessible machines */
    1613         mVmRefreshAction->setEnabled (false);
    1614 
    1615         /* enable the show log item for the selected vm */
    1616         mVmShowLogsAction->setEnabled (true);
    1617     }
    1618     else
    1619     {
    1620         /* Note that the machine becomes inaccessible (or if the last VM gets
    1621          * deleted), we have to update all fields, ignoring input
    1622          * arguments. */
    1623 
    1624         if (item)
    1625         {
    1626             /* the VM is inaccessible */
    1627             mVmDetailsView->setErrorText (
    1628                 VBoxProblemReporter::formatErrorInfo (item->accessError()));
    1629             mVmRefreshAction->setEnabled (true);
    1630         }
    1631         else
    1632         {
    1633             /* default HTML support in Qt is terrible so just try to get
    1634              * something really simple */
    1635             mVmDetailsView->setDetailsText
    1636                 (tr ("<h3>"
    1637                      "Welcome to VirtualBox!</h3>"
    1638                      "<p>The left part of this window is  "
    1639                      "a list of all virtual machines on your computer. "
    1640                      "The list is empty now because you haven't created any virtual "
    1641                      "machines yet."
    1642                      "<img src=:/welcome.png align=right/></p>"
    1643                      "<p>In order to create a new virtual machine, press the "
    1644                      "<b>New</b> button in the main tool bar located "
    1645                      "at the top of the window.</p>"
    1646                      "<p>You can press the <b>%1</b> key to get instant help, "
    1647                      "or visit "
    1648                      "<a href=http://www.virtualbox.org>www.virtualbox.org</a> "
    1649                      "for the latest information and news.</p>").arg (QKeySequence (QKeySequence::HelpContents).toString (QKeySequence::NativeText)));
    1650             mVmRefreshAction->setEnabled (false);
    1651         }
    1652 
    1653         /* empty and disable other tabs */
    1654 
    1655         mVmSnapshotsWgt->setMachine (CMachine());
    1656         mVmTabWidget->setTabText (mVmTabWidget->indexOf (mVmSnapshotsWgt), tr ("&Snapshots"));
    1657         mVmTabWidget->setTabEnabled (mVmTabWidget->indexOf (mVmSnapshotsWgt), false);
    1658 
    1659         mVmDescriptionPage->setMachineItem (NULL);
    1660         mVmTabWidget->setTabText (mVmTabWidget->indexOf (mVmDescriptionPage), tr ("D&escription"));
    1661         mVmTabWidget->setTabEnabled (mVmTabWidget->indexOf (mVmDescriptionPage), false);
    1662 
    1663         /* disable modify actions */
    1664         mVmConfigAction->setEnabled (false);
    1665         mVmDeleteAction->setEnabled (item != NULL);
    1666         mVmDiscardAction->setEnabled (false);
    1667         mVmPauseAction->setEnabled (false);
    1668 
    1669         /* change the Start button text accordingly */
    1670         mVmStartAction->setText (tr ("S&tart"));
    1671         mVmStartAction->setStatusTip (
    1672             tr ("Start the selected virtual machine"));
    1673         mVmStartAction->setEnabled (false);
    1674 
    1675         /* disable the show log item for the selected vm */
    1676         mVmShowLogsAction->setEnabled (false);
    1677     }
    1678 }
    1679 
    1680 void VBoxSelectorWnd::mediumEnumStarted()
    1681 {
    1682     /* refresh the current details to pick up hard disk sizes */
    1683     vmListViewCurrentChanged (true /* aRefreshDetails */);
    1684 }
    1685 
    1686 void VBoxSelectorWnd::mediumEnumFinished (const VBoxMediaList &list)
    1687 {
    1688     /* refresh the current details to pick up hard disk sizes */
    1689     vmListViewCurrentChanged (true /* aRefreshDetails */);
    1690 
    1691     /* we warn about inaccessible media only once (after media emumeration
    1692      * started from main() at startup), to avoid annoying the user */
    1693     if (   mDoneInaccessibleWarningOnce
    1694 #ifdef VBOX_GUI_WITH_SYSTRAY
    1695         || vboxGlobal().isTrayMenu()
    1696 #endif
    1697        )
    1698         return;
    1699 
    1700     mDoneInaccessibleWarningOnce = true;
    1701 
    1702     do
    1703     {
    1704         /* ignore the signal if a modal widget is currently active (we won't be
    1705          * able to properly show the modeless VDI manager window in this case) */
    1706         if (QApplication::activeModalWidget())
    1707             break;
    1708 
    1709         /* ignore the signal if a VBoxMediaManagerDlg window is active */
    1710         if (qApp->activeWindow() &&
    1711             !strcmp (qApp->activeWindow()->metaObject()->className(), "VBoxMediaManagerDlg"))
    1712             break;
    1713 
    1714         /* look for at least one inaccessible media */
    1715         VBoxMediaList::const_iterator it;
    1716         for (it = list.begin(); it != list.end(); ++ it)
    1717             if ((*it).state() == KMediumState_Inaccessible)
    1718                 break;
    1719 
    1720         if (it != list.end() && vboxProblem().remindAboutInaccessibleMedia())
    1721         {
    1722             /* Show the VDM dialog but don't refresh once more after a
    1723              * just-finished refresh */
    1724             VBoxMediaManagerDlg::showModeless (this, false /* aRefresh */);
    1725         }
    1726     }
    1727     while (0);
    1728 }
    1729 
    1730 void VBoxSelectorWnd::machineStateChanged(QString strId, KMachineState /* state */)
    1731 {
    1732 #ifdef VBOX_GUI_WITH_SYSTRAY
    1733     if (vboxGlobal().isTrayMenu())
    1734     {
    1735         /* Check if there are some machines alive - else quit, since
    1736          * we're not needed as a systray menu anymore. */
    1737         if (vboxGlobal().mainWindowCount() == 0)
    1738         {
    1739             fileExit();
    1740             return;
    1741         }
    1742     }
    1743 #endif
    1744 
    1745     refreshVMItem (strId,
    1746                    false /* aDetails */,
    1747                    false /* aSnapshots */,
    1748                    false /* aDescription */);
    1749 
    1750     /* simulate a state change signal */
    1751     mVmDescriptionPage->updateState();
    1752 }
    1753 
    1754 void VBoxSelectorWnd::machineDataChanged(QString strId)
    1755 {
    1756     refreshVMItem (strId,
    1757                    true  /* aDetails */,
    1758                    false /* aSnapshots */,
    1759                    true  /* aDescription */);
    1760 }
    1761 
    1762 void VBoxSelectorWnd::machineRegistered(QString strId, bool fRegistered)
    1763 {
    1764     if (fRegistered)
    1765     {
    1766         CVirtualBox vbox = vboxGlobal().virtualBox();
    1767         CMachine m = vbox.GetMachine (strId);
    1768         if (!m.isNull())
    1769         {
    1770             mVMModel->addItem (new UIVMItem (m));
    1771             mVMModel->sort();
    1772             /* Make sure the description, ... pages are properly updated.
    1773              * Actualy we haven't call the next method, but unfortunately Qt
    1774              * seems buggy if the new item is on the same position as the
    1775              * previous one. So go on the safe side and call this by our self. */
    1776             vmListViewCurrentChanged();
    1777         }
    1778         /* m.isNull() is ok (theoretically, the machine could have been
    1779          * already deregistered by some other client at this point) */
    1780     }
    1781     else
    1782     {
    1783         UIVMItem *item = mVMModel->itemById (strId);
    1784         if (item)
    1785         {
    1786             int row = mVMModel->rowById (item->id());
    1787             mVMModel->removeItem (item);
    1788             delete item;
    1789             mVMListView->ensureSomeRowSelected (row);
    1790         }
    1791 
    1792         /* item = 0 is ok (if we originated this event then the item
    1793          * has been already removed) */
    1794     }
    1795 }
    1796 
    1797 void VBoxSelectorWnd::sessionStateChanged(QString strId, KSessionState /* state */)
    1798 {
    1799     refreshVMItem (strId,
    1800                    true  /* aDetails */,
    1801                    false /* aSnapshots */,
    1802                    false /* aDescription */);
    1803 
    1804     /* simulate a state change signal */
    1805     mVmDescriptionPage->updateState();
    1806 }
    1807 
    1808 void VBoxSelectorWnd::snapshotChanged(QString strId, QString /* strSnapshotId */)
    1809 {
    1810     refreshVMItem (strId,
    1811                    false /* aDetails */,
    1812                    true  /* aSnapshot */,
    1813                    false /* aDescription */);
    1814 }
    1815 
    1816 #ifdef VBOX_GUI_WITH_SYSTRAY
    1817 
    1818 void VBoxSelectorWnd::mainWindowCountChanged(int count)
    1819 {
    1820     if (vboxGlobal().isTrayMenu() && count <= 1)
    1821         fileExit();
    1822 }
    1823 
    1824 void VBoxSelectorWnd::trayIconCanShow(bool fEnabled)
    1825 {
    1826     emit trayIconChanged(VBoxChangeTrayIconEvent (vboxGlobal().settings().trayIconEnabled()));
    1827 }
    1828 
    1829 void VBoxSelectorWnd::trayIconShow(bool fEnabled)
    1830 {
    1831     if (vboxGlobal().isTrayMenu() && mTrayIcon)
    1832         mTrayIcon->trayIconShow(fEnabled);
    1833 }
    1834 
    1835 void VBoxSelectorWnd::trayIconChanged(bool fEnabled)
    1836 {
    1837     /* Not used yet. */
    1838 }
    1839 
    1840 VBoxTrayIcon::VBoxTrayIcon (VBoxSelectorWnd* aParent, UIVMItemModel* aVMModel)
    1841 {
    1842     mParent = aParent;
    1843     mVMModel = aVMModel;
    1844 
    1845     mShowSelectorAction = new QAction (this);
    1846     Assert (mShowSelectorAction);
    1847     mShowSelectorAction->setIcon(UIIconPool::iconSet(":/VirtualBox_16px.png"));
    1848 
    1849     mHideSystrayMenuAction = new QAction (this);
    1850     Assert (mHideSystrayMenuAction);
    1851     mHideSystrayMenuAction->setIcon(UIIconPool::iconSet(":/exit_16px.png"));
    1852 
    1853     /* reuse parent action data */
    1854 
    1855     mVmConfigAction = new QAction (this);
    1856     Assert (mVmConfigAction);
    1857     mVmConfigAction->setIcon (mParent->vmConfigAction()->icon());
    1858 
    1859     mVmDeleteAction = new QAction (this);
    1860     Assert (mVmDeleteAction);
    1861     mVmDeleteAction->setIcon (mParent->vmDeleteAction()->icon());
    1862 
    1863     mVmStartAction = new QAction (this);
    1864     Assert (mVmStartAction);
    1865     mVmStartAction->setIcon (mParent->vmStartAction()->icon());
    1866 
    1867     mVmDiscardAction = new QAction (this);
    1868     Assert (mVmDiscardAction);
    1869     mVmDiscardAction->setIcon (mParent->vmDiscardAction()->icon());
    1870 
    1871     mVmPauseAction = new QAction (this);
    1872     Assert (mVmPauseAction);
    1873     mVmPauseAction->setCheckable (true);
    1874     mVmPauseAction->setIcon (mParent->vmPauseAction()->icon());
    1875 
    1876     mVmRefreshAction = new QAction (this);
    1877     Assert (mVmRefreshAction);
    1878     mVmRefreshAction->setIcon (mParent->vmRefreshAction()->icon());
    1879 
    1880     mVmShowLogsAction = new QAction (this);
    1881     Assert (mVmConfigAction);
    1882     mVmShowLogsAction->setIcon (mParent->vmShowLogsAction()->icon());
    1883 
    1884     mTrayIconMenu = new QMenu (aParent);
    1885     Assert (mTrayIconMenu);
    1886 
    1887     setIcon (QIcon (":/VirtualBox_16px.png"));
    1888     setContextMenu (mTrayIconMenu);
    1889 
    1890     connect (mShowSelectorAction, SIGNAL (triggered()), mParent, SLOT (showWindow()));
    1891     connect (mHideSystrayMenuAction, SIGNAL (triggered()), this, SLOT (trayIconShow()));
    1892 }
    1893 
    1894 VBoxTrayIcon::~VBoxTrayIcon ()
    1895 {
    1896     /* Erase dialog handle in config file. */
    1897     if (mActive)
    1898     {
    1899         vboxGlobal().virtualBox().SetExtraData (VBoxDefs::GUI_TrayIconWinID,
    1900                                                 QString::null);
    1901         hide();
    1902     }
    1903 }
    1904 
    1905 void VBoxTrayIcon::retranslateUi ()
    1906 {
    1907     if (!mActive)
    1908         return;
    1909 
    1910     mShowSelectorAction->setText (tr ("Show Selector Window"));
    1911     mShowSelectorAction->setStatusTip (tr (
    1912         "Show the selector window assigned to this menu"));
    1913 
    1914     mHideSystrayMenuAction->setText (tr ("Hide Tray Icon"));
    1915     mHideSystrayMenuAction->setStatusTip (tr (
    1916         "Remove this icon from the system tray"));
    1917 
    1918     /* reuse parent action data */
    1919 
    1920     mVmConfigAction->setText (mParent->vmConfigAction()->text());
    1921     mVmConfigAction->setStatusTip (mParent->vmConfigAction()->statusTip());
    1922 
    1923     mVmDeleteAction->setText (mParent->vmDeleteAction()->text());
    1924     mVmDeleteAction->setStatusTip (mParent->vmDeleteAction()->statusTip());
    1925 
    1926     mVmPauseAction->setText (mParent->vmPauseAction()->text());
    1927     mVmPauseAction->setStatusTip (mParent->vmPauseAction()->statusTip());
    1928 
    1929     mVmDiscardAction->setText (mParent->vmDiscardAction()->text());
    1930     mVmDiscardAction->setStatusTip (mParent->vmDiscardAction()->statusTip());
    1931 
    1932     mVmShowLogsAction->setText (mParent->vmShowLogsAction()->text());
    1933     mVmShowLogsAction->setStatusTip (mParent->vmShowLogsAction()->statusTip());
    1934 }
    1935 
    1936 void VBoxTrayIcon::showSubMenu ()
    1937 {
    1938     if (!mActive)
    1939         return;
    1940 
    1941     UIVMItem* pItem = NULL;
    1942     QMenu *pMenu = NULL;
    1943     QVariant vID;
    1944 
    1945     if ((pMenu = qobject_cast<QMenu*>(sender())))
    1946     {
    1947         vID = pMenu->menuAction()->data();
    1948         if (vID.canConvert<QString>() && mVMModel)
    1949             pItem = mVMModel->itemById (qvariant_cast<QString>(vID));
    1950     }
    1951 
    1952     mVmConfigAction->setData (vID);
    1953     mVmDeleteAction->setData (vID);
    1954     mVmDiscardAction->setData (vID);
    1955     mVmStartAction->setData (vID);
    1956     mVmPauseAction->setData (vID);
    1957     mVmShowLogsAction->setData (vID);
    1958 
    1959     if (pItem && pItem->accessible())
    1960     {
    1961         /* look at vmListViewCurrentChanged() */
    1962         CMachine m = pItem->machine();
    1963         KMachineState s = pItem->state();
    1964         bool running = pItem->sessionState() != KSessionState_Closed;
    1965         bool modifyEnabled = !running && s != KMachineState_Saved;
    1966 
    1967         /* Settings */
    1968         mVmConfigAction->setEnabled (modifyEnabled);
    1969 
    1970         /* Delete */
    1971         mVmDeleteAction->setEnabled (modifyEnabled);
    1972 
    1973         /* Discard */
    1974         mVmDiscardAction->setEnabled (s == KMachineState_Saved && !running);
    1975 
    1976         /* Change the Start button text accordingly */
    1977         if (   s == KMachineState_PoweredOff
    1978             || s == KMachineState_Saved
    1979             || s == KMachineState_Teleported
    1980             || s == KMachineState_Aborted
    1981            )
    1982         {
    1983             mVmStartAction->setText (UIVMListView::tr ("S&tart"));
    1984             mVmStartAction->setStatusTip (
    1985                   UIVMListView::tr ("Start the selected virtual machine"));
    1986             mVmStartAction->setEnabled (!running);
    1987         }
    1988         else
    1989         {
    1990             mVmStartAction->setText (UIVMListView::tr ("S&how"));
    1991             mVmStartAction->setStatusTip (
    1992                   UIVMListView::tr ("Switch to the window of the selected virtual machine"));
    1993             mVmStartAction->setEnabled (pItem->canSwitchTo());
    1994         }
    1995 
    1996         /* Change the Pause/Resume button text accordingly */
    1997         mVmPauseAction->setEnabled (   s == KMachineState_Running
    1998                                     || s == KMachineState_Teleporting
    1999                                     || s == KMachineState_LiveSnapshotting
    2000                                     || s == KMachineState_Paused
    2001                                     || s == KMachineState_TeleportingPausedVM
    2002                                    );
    2003 
    2004         if (   s == KMachineState_Paused
    2005             || s == KMachineState_TeleportingPausedVM /*?*/
    2006            )
    2007         {
    2008             mVmPauseAction->setText (UIVMListView::tr ("R&esume"));
    2009             mVmPauseAction->setStatusTip (
    2010                   UIVMListView::tr ("Resume the execution of the virtual machine"));
    2011             mVmPauseAction->blockSignals (true);
    2012             mVmPauseAction->setChecked (true);
    2013             mVmPauseAction->blockSignals (false);
    2014         }
    2015         else
    2016         {
    2017             mVmPauseAction->setText (UIVMListView::tr ("&Pause"));
    2018             mVmPauseAction->setStatusTip (
    2019                   UIVMListView::tr ("Suspend the execution of the virtual machine"));
    2020             mVmPauseAction->blockSignals (true);
    2021             mVmPauseAction->setChecked (false);
    2022             mVmPauseAction->blockSignals (false);
    2023         }
    2024 
    2025         mVmShowLogsAction->setEnabled (true);
    2026 
    2027         /* Disconnect old slot which maybe was connected from another selected sub menu. */
    2028         disconnect (mVmConfigAction, SIGNAL (triggered()), this, SLOT (vmSettings()));
    2029         disconnect (mVmDeleteAction, SIGNAL (triggered()), this, SLOT (vmDelete()));
    2030         disconnect (mVmDiscardAction, SIGNAL (triggered()), this, SLOT (vmDiscard()));
    2031         disconnect (mVmStartAction, SIGNAL (triggered()), this, SLOT (vmStart()));
    2032         disconnect (mVmPauseAction, SIGNAL (toggled (bool)), this, SLOT (vmPause (bool)));
    2033         disconnect (mVmShowLogsAction, SIGNAL (triggered()), this, SLOT (vmShowLogs()));
    2034 
    2035         /* Connect new sub menu with slots. */
    2036         connect (mVmConfigAction, SIGNAL (triggered()), this, SLOT (vmSettings()));
    2037         connect (mVmDeleteAction, SIGNAL (triggered()), this, SLOT (vmDelete()));
    2038         connect (mVmDiscardAction, SIGNAL (triggered()), this, SLOT (vmDiscard()));
    2039         connect (mVmStartAction, SIGNAL (triggered()), this, SLOT (vmStart()));
    2040         connect (mVmPauseAction, SIGNAL (toggled (bool)), this, SLOT (vmPause (bool)));
    2041         connect (mVmShowLogsAction, SIGNAL (triggered()), this, SLOT (vmShowLogs()));
    2042     }
    2043     else    /* Item is not accessible. */
    2044     {
    2045         mVmConfigAction->setEnabled (false);
    2046         mVmDeleteAction->setEnabled (pItem != NULL);
    2047         mVmDiscardAction->setEnabled (false);
    2048         mVmPauseAction->setEnabled (false);
    2049 
    2050         /* Set the Start button text accordingly. */
    2051         mVmStartAction->setText (UIVMListView::tr ("S&tart"));
    2052         mVmStartAction->setStatusTip (
    2053               UIVMListView::tr ("Start the selected virtual machine"));
    2054         mVmStartAction->setEnabled (false);
    2055 
    2056         /* Disable the show log item for the selected vm. */
    2057         mVmShowLogsAction->setEnabled (false);
    2058     }
    2059 
    2060     /* Build sub menu entries (add rest of sub menu entries later here). */
    2061     pMenu->addAction (mVmStartAction);
    2062     pMenu->addAction (mVmPauseAction);
    2063 }
    2064 
    2065 void VBoxTrayIcon::hideSubMenu ()
    2066 {
    2067     if (!mActive)
    2068         return;
    2069 
    2070     UIVMItem* pItem = NULL;
    2071     QVariant vID;
    2072 
    2073     if (QMenu *pMenu = qobject_cast<QMenu*>(sender()))
    2074     {
    2075         vID = pMenu->menuAction()->data();
    2076         if (vID.canConvert<QString>() && mVMModel)
    2077             pItem = mVMModel->itemById (qvariant_cast<QString>(vID));
    2078     }
    2079 
    2080     /* Nothing to do here yet. */
    2081 
    2082     Assert (pItem);
    2083 }
    2084 
    2085 void VBoxTrayIcon::refresh ()
    2086 {
    2087     if (!mActive)
    2088         return;
    2089 
    2090     AssertReturnVoid (mVMModel);
    2091     AssertReturnVoid (mTrayIconMenu);
    2092 
    2093     mTrayIconMenu->clear();
    2094 
    2095     UIVMItem* pItem = NULL;
    2096     QMenu* pCurMenu = mTrayIconMenu;
    2097     QMenu* pSubMenu = NULL;
    2098 
    2099     int iCurItemCount = 0;
    2100 
    2101     mTrayIconMenu->addAction (mShowSelectorAction);
    2102     mTrayIconMenu->setDefaultAction (mShowSelectorAction);
    2103 
    2104     if (mVMModel->rowCount() > 0)
    2105         mTrayIconMenu->addSeparator();
    2106 
    2107     for (int i = 0; i < mVMModel->rowCount(); i++, iCurItemCount++)
    2108     {
    2109         pItem = mVMModel->itemByRow(i);
    2110         Assert(pItem);
    2111 
    2112         if (iCurItemCount > 10) /* 10 machines per sub menu. */
    2113         {
    2114             pSubMenu = new QMenu (tr ("&Other Machines...", "tray menu"));
    2115             Assert (pSubMenu);
    2116             pCurMenu->addMenu (pSubMenu);
    2117             pCurMenu = pSubMenu;
    2118             iCurItemCount = 0;
    2119         }
    2120 
    2121         pSubMenu = new QMenu (QString ("&%1. %2")
    2122                               .arg ((iCurItemCount + 1) % 100).arg (pItem->name()));
    2123         Assert (pSubMenu);
    2124         pSubMenu->setIcon (pItem->sessionStateIcon());
    2125 
    2126         QAction *pAction = NULL;
    2127         QVariant vID;
    2128         vID.setValue (pItem->id());
    2129 
    2130         pSubMenu->menuAction()->setData (vID);
    2131         connect (pSubMenu, SIGNAL (aboutToShow()), this, SLOT (showSubMenu()));
    2132         connect (pSubMenu, SIGNAL (aboutToHide()), this, SLOT (hideSubMenu()));
    2133         pCurMenu->addMenu (pSubMenu);
    2134     }
    2135 
    2136     if (mVMModel->rowCount() > 0)
    2137         mTrayIconMenu->addSeparator();
    2138 
    2139     mTrayIconMenu->addAction (mHideSystrayMenuAction);
    2140 
    2141     /* We're done constructing the menu, show it */
    2142     setVisible (true);
    2143 }
    2144 
    2145 UIVMItem* VBoxTrayIcon::GetItem (QObject* aObject)
    2146 {
    2147     UIVMItem* pItem = NULL;
    2148     if (QAction *pAction = qobject_cast<QAction*>(sender()))
    2149     {
    2150         QVariant v = pAction->data();
    2151         if (v.canConvert<QString>() && mVMModel)
    2152             pItem = mVMModel->itemById (qvariant_cast<QString>(v));
    2153     }
    2154 
    2155     Assert (pItem);
    2156     return pItem;
    2157 }
    2158 
    2159 void VBoxTrayIcon::trayIconShow (bool aShow)
    2160 {
    2161     if (!vboxGlobal().isTrayMenu())
    2162         return;
    2163 
    2164     mActive = aShow;
    2165     if (mActive)
    2166     {
    2167         refresh();
    2168         retranslateUi();
    2169     }
    2170     setVisible (mActive);
    2171 
    2172     if (!mActive)
    2173         mParent->fileExit();
    2174 }
    2175 
    2176 void VBoxTrayIcon::vmSettings()
    2177 {
    2178     UIVMItem* pItem = GetItem (sender());
    2179     mParent->vmSettings (NULL, NULL, pItem->id());
    2180 }
    2181 
    2182 void VBoxTrayIcon::vmDelete()
    2183 {
    2184     UIVMItem* pItem = GetItem (sender());
    2185     mParent->vmDelete (pItem->id());
    2186 }
    2187 
    2188 void VBoxTrayIcon::vmStart()
    2189 {
    2190     UIVMItem* pItem = GetItem (sender());
    2191     mParent->vmStart (pItem->id());
    2192 }
    2193 
    2194 void VBoxTrayIcon::vmDiscard()
    2195 {
    2196     UIVMItem* pItem = GetItem (sender());
    2197     mParent->vmDiscard (pItem->id());
    2198 }
    2199 
    2200 void VBoxTrayIcon::vmPause(bool aPause)
    2201 {
    2202     UIVMItem* pItem = GetItem (sender());
    2203     mParent->vmPause (aPause, pItem->id());
    2204 }
    2205 
    2206 void VBoxTrayIcon::vmRefresh()
    2207 {
    2208     UIVMItem* pItem = GetItem (sender());
    2209     mParent->vmRefresh (pItem->id());
    2210 }
    2211 
    2212 void VBoxTrayIcon::vmShowLogs()
    2213 {
    2214     UIVMItem* pItem = GetItem (sender());
    2215     mParent->vmShowLogs (pItem->id());
    2216 }
    2217 
    2218 #endif // VBOX_GUI_WITH_SYSTRAY
    2219 
    2220 void VBoxSelectorWnd::sltDownloaderUserManualEmbed()
    2221 {
    2222     /* If there is User Manual downloader created => show the process bar: */
    2223     if (UIDownloaderUserManual *pDl = UIDownloaderUserManual::current())
    2224         statusBar()->addWidget(pDl->processWidget(this), 0);
    2225 }
    2226 
    2227 void VBoxSelectorWnd::showViewContextMenu(const QPoint &pos)
    2228 {
    2229     CVirtualBox vbox = vboxGlobal().virtualBox();
    2230     QString strToolbar = vbox.GetExtraData(VBoxDefs::GUI_Toolbar);
    2231     QString strStatusbar = vbox.GetExtraData(VBoxDefs::GUI_Statusbar);
    2232     bool fToolbar = strToolbar.isEmpty() || strToolbar == "true";
    2233     bool fStatusbar = strStatusbar.isEmpty() || strStatusbar == "true";
    2234 
    2235     QList<QAction*> actions;
    2236     QAction *pShowToolBar = new QAction(tr("Show Toolbar"), 0);
    2237     pShowToolBar->setCheckable(true);
    2238     pShowToolBar->setChecked(fToolbar);
    2239     actions << pShowToolBar;
    2240     QAction *pShowStatusBar = new QAction(tr("Show Statusbar"), 0);
    2241     pShowStatusBar->setCheckable(true);
    2242     pShowStatusBar->setChecked(fStatusbar);
    2243     actions << pShowStatusBar;
    2244 
    2245     QPoint gpos = pos;
    2246     QWidget *pSender = static_cast<QWidget*>(sender());
    2247     if (pSender)
    2248         gpos = pSender->mapToGlobal(pos);
    2249     QAction *pResult = QMenu::exec(actions, gpos);
    2250     if (pResult == pShowToolBar)
    2251     {
    2252         if (pResult->isChecked())
    2253         {
    2254             mVMToolBar->show();
    2255             vbox.SetExtraData(VBoxDefs::GUI_Toolbar, "true");
    2256         }
    2257         else
    2258         {
    2259             mVMToolBar->hide();
    2260             vbox.SetExtraData(VBoxDefs::GUI_Toolbar, "false");
    2261         }
    2262     }else if (pResult == pShowStatusBar)
    2263     {
    2264         if (pResult->isChecked())
    2265         {
    2266             statusBar()->show();
    2267             vbox.SetExtraData(VBoxDefs::GUI_Statusbar, "true");
    2268         }
    2269         else
    2270         {
    2271             statusBar()->hide();
    2272             vbox.SetExtraData(VBoxDefs::GUI_Statusbar, "false");
    2273         }
    2274     }
    2275 }
    2276 
    2277 #include "VBoxSelectorWnd.moc"
     1334}
     1335
     1336void UIVMDesktop::retranslateUi()
     1337{
     1338    m_pHeaderBtn->setTitle(Dtls, tr("&Details"));
     1339}
     1340
     1341void UIVMDesktop::updateDetails(UIVMItem * /* pVMItem */, const CMachine& machine)
     1342{
     1343//    KMachineState state = pVMItem->state();
     1344//    bool fRunning = pVMItem->sessionState() != KSessionState_Closed;
     1345//    bool fModifyEnabled = !fRunning && state != KMachineState_Saved;
     1346    m_pDetails->setMachine(machine);
     1347}
     1348
     1349void UIVMDesktop::updateDetailsText(const QString &strText)
     1350{
     1351    m_pDetails->setText(strText);
     1352}
     1353
     1354void UIVMDesktop::updateDetailsErrorText(const QString &strText)
     1355{
     1356    m_pDetails->setErrorText(strText);
     1357}
     1358
     1359void UIVMDesktop::updateSnapshots(UIVMItem *pVMItem, const CMachine& machine)
     1360{
     1361    /* Update the snapshots header name */
     1362    QString name = tr("&Snapshots");
     1363    if (pVMItem)
     1364    {
     1365        ULONG count = pVMItem->snapshotCount();
     1366        if (count)
     1367            name += QString(" (%1)").arg(count);
     1368    }
     1369    m_pHeaderBtn->setTitle(Snap, name);
     1370    /* Refresh the snapshots widget */
     1371    if (!machine.isNull())
     1372    {
     1373        m_pHeaderBtn->setEnabled(Snap, true);
     1374        m_pSnapshotsPage->setMachine(machine);
     1375    } else
     1376    {
     1377        m_pHeaderBtn->animateClick(Dtls);
     1378        m_pHeaderBtn->setEnabled(Snap, false);
     1379    }
     1380}
     1381
     1382void UIVMDesktop::updateDescription(UIVMItem *pVMItem, const CMachine& machine)
     1383{
     1384    /* Update the description header name */
     1385    QString name = tr("D&escription");
     1386    if (pVMItem)
     1387    {
     1388         if(!machine.GetDescription().isEmpty())
     1389             name += " *";
     1390    }
     1391    m_pHeaderBtn->setTitle(Desc, name);
     1392    /* refresh the description widget */
     1393    if (!machine.isNull())
     1394    {
     1395        m_pHeaderBtn->setEnabled(Desc, true);
     1396        m_pDescription->setMachineItem(pVMItem);
     1397    } else
     1398    {
     1399        m_pHeaderBtn->animateClick(Dtls);
     1400        m_pHeaderBtn->setEnabled(Desc, false);
     1401    }
     1402}
     1403
     1404void UIVMDesktop::updateDescriptionState()
     1405{
     1406    m_pDescription->updateState();
     1407}
     1408
     1409#include "UIVMDesktop.moc"
     1410
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.h

    r30798 r30868  
    22 *
    33 * VBox frontends: Qt GUI ("VirtualBox"):
    4  * VBoxSelectorWnd class declaration
     4 * UIVMDesktop class declarations
    55 */
    66
    77/*
    8  * Copyright (C) 2006-2008 Oracle Corporation
     8 * Copyright (C) 2010 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1717 */
    1818
    19 #ifndef __VBoxSelectorWnd_h__
    20 #define __VBoxSelectorWnd_h__
     19#ifndef __UIVMDesktop_h__
     20#define __UIVMDesktop_h__
    2121
    22 #include "COMDefs.h"
    23 
     22/* Local includes */
    2423#include "QIWithRetranslateUI.h"
    2524
    26 #include "VBoxGlobal.h"
    27 #include "VBoxProblemReporter.h"
    28 #include "VBoxHelpActions.h"
    29 
    30 /* Qt includes */
    31 #include <QMainWindow>
    32 #ifdef VBOX_GUI_WITH_SYSTRAY
    33     #include <QSystemTrayIcon>
    34 #endif
     25/* Global includes */
     26#include <QWidget>
    3527
    3628/* Local forward declarations */
    37 class QITabWidget;
     29class CMachine;
     30class UIDescriptionPagePrivate;
     31class UIDetailsPagePrivate;
     32class UITexturedSegmentedButton;
    3833class UIVMItem;
    39 class UIVMItemModel;
    40 class UIVMListView;
    4134class VBoxSnapshotsWgt;
    4235class VBoxToolBar;
    43 class VBoxTrayIcon;
    44 class VBoxVMDescriptionPage;
    45 class VBoxVMDetailsView;
    46 class VBoxVMLogViewer;
    4736
    48 /* Global forward declarations */
    49 class QEvent;
    50 class QListView;
    51 
    52 class VBoxSelectorWnd : public QIWithRetranslateUI2 <QMainWindow>
     37class UIVMDesktop: public QIWithRetranslateUI<QWidget>
    5338{
    5439    Q_OBJECT;
     
    5641public:
    5742
    58     VBoxSelectorWnd (VBoxSelectorWnd **aSelf,
    59                      QWidget* aParent = 0,
    60                      Qt::WindowFlags aFlags = Qt::Window);
    61     virtual ~VBoxSelectorWnd();
     43    UIVMDesktop(VBoxToolBar *pToolBar, QAction *pRefreshAction, QWidget *pParent = 0);
     44
     45    void updateDetails(UIVMItem *pVMItem, const CMachine& machine);
     46    void updateDetailsText(const QString &strText);
     47    void updateDetailsErrorText(const QString &strText);
     48
     49    void updateSnapshots(UIVMItem *pVMItem, const CMachine& machine);
     50    void updateDescription(UIVMItem *pVMItem, const CMachine& machine);
     51    void updateDescriptionState();
    6252
    6353signals:
    6454
    65     void closing();
    66 
    67 public slots:
    68 
    69     void fileMediaMgr();
    70     void fileImportAppliance();
    71     void fileExportAppliance();
    72     void fileSettings();
    73     void fileExit();
    74 
    75     void vmNew();
    76     void vmSettings (const QString &aCategory = QString::null,
    77                      const QString &aControl = QString::null,
    78                      const QString & = QString::null);
    79     void vmDelete (const QString & = QString::null);
    80     void vmStart (const QString & = QString::null);
    81     void vmDiscard (const QString & = QString::null);
    82     void vmPause (bool, const QString & = QString::null);
    83     void vmRefresh (const QString & = QString::null);
    84     void vmShowLogs (const QString & = QString::null);
    85 
    86     void refreshVMList();
    87     void refreshVMItem (const QString &aID, bool aDetails,
    88                                           bool aSnapshots,
    89                                           bool aDescription);
    90 
    91     void showContextMenu (const QPoint &aPoint);
    92 
    93 #ifdef VBOX_GUI_WITH_SYSTRAY
    94     void trayIconActivated (QSystemTrayIcon::ActivationReason aReason);
    95     void showWindow();
    96 #endif
    97 
    98     const QAction *vmNewAction() const { return mVmNewAction; }
    99     const QAction *vmConfigAction() const { return mVmConfigAction; }
    100     const QAction *vmDeleteAction() const { return mVmDeleteAction; }
    101     const QAction *vmStartAction() const { return mVmStartAction; }
    102     const QAction *vmDiscardAction() const { return mVmDiscardAction; }
    103     const QAction *vmPauseAction() const { return mVmPauseAction; }
    104     const QAction *vmRefreshAction() const { return mVmRefreshAction; }
    105     const QAction *vmShowLogsAction() const { return mVmShowLogsAction; }
     55    void linkClicked(const QString &strURL);
    10656
    10757protected:
    10858
    109     /* Events */
    110     bool event (QEvent *aEvent);
    111     void closeEvent (QCloseEvent *aEvent);
    112 //#if defined (Q_WS_MAC) && (QT_VERSION < 0x040402)
    113 //    bool eventFilter (QObject *aObject, QEvent *aEvent);
    114 //#endif /* defined (Q_WS_MAC) && (QT_VERSION < 0x040402) */
    115 
    11659    void retranslateUi();
    117 
    118 private slots:
    119 
    120     void vmListViewCurrentChanged (bool aRefreshDetails = true,
    121                                    bool aRefreshSnapshots = true,
    122                                    bool aRefreshDescription = true);
    123 
    124     void mediumEnumStarted();
    125     void mediumEnumFinished (const VBoxMediaList &);
    126 
    127     /* VirtualBox callback events we're interested in */
    128 
    129     void machineStateChanged(QString strId, KMachineState state);
    130     void machineDataChanged(QString strId);
    131     void machineRegistered(QString strID, bool fRegistered);
    132     void sessionStateChanged(QString strId, KSessionState state);
    133     void snapshotChanged(QString strId, QString strSnapshotId);
    134 #ifdef VBOX_GUI_WITH_SYSTRAY
    135     void mainWindowCountChanged(int count);
    136     void trayIconCanShow(bool fEnabled);
    137     void trayIconShow(bool fEnabled);
    138     void trayIconChanged(bool fEnabled);
    139 #endif
    140 
    141     void sltDownloaderUserManualEmbed();
    142 
    143     void showViewContextMenu(const QPoint &pos);
    14460
    14561private:
    14662
    147     /* Main menus */
    148     QMenu *mFileMenu;
    149     QMenu *mVMMenu;
    150     QMenu *mHelpMenu;
    151 
    152     /* Main toolbar */
    153     VBoxToolBar *mVMToolBar;
    154 
    155     /* VM list context menu */
    156     QMenu *mVMCtxtMenu;
    157 //    UIOSDMenu *mVMCtxtMenu;
    158 
    159     /* Actions */
    160     QAction *mFileMediaMgrAction;
    161     QAction *mFileApplianceImportAction;
    162     QAction *mFileApplianceExportAction;
    163     QAction *mFileSettingsAction;
    164     QAction *mFileExitAction;
    165     QAction *mVmNewAction;
    166     QAction *mVmConfigAction;
    167     QAction *mVmDeleteAction;
    168     QAction *mVmStartAction;
    169     QAction *mVmDiscardAction;
    170     QAction *mVmPauseAction;
    171     QAction *mVmRefreshAction;
    172     QAction *mVmShowLogsAction;
    173 
    174     VBoxHelpActions mHelpActions;
    175 
    176 #ifdef VBOX_GUI_WITH_SYSTRAY
    177     /* The systray icon */
    178     VBoxTrayIcon *mTrayIcon;
    179 #endif
    180 
    181     /* The vm list view/model */
    182     UIVMListView *mVMListView;
    183     UIVMItemModel *mVMModel;
    184 
    185     /* The right information widgets */
    186     QITabWidget *mVmTabWidget;
    187     VBoxVMDetailsView *mVmDetailsView;
    188     VBoxSnapshotsWgt *mVmSnapshotsWgt;
    189     VBoxVMDescriptionPage *mVmDescriptionPage;
    190 
    191     QRect mNormalGeo;
    192 
    193     bool mDoneInaccessibleWarningOnce : 1;
     63    /* Private member vars */
     64    UITexturedSegmentedButton *m_pHeaderBtn;
     65    UIDetailsPagePrivate *m_pDetails;
     66    VBoxSnapshotsWgt *m_pSnapshotsPage;
     67    UIDescriptionPagePrivate *m_pDescription;
    19468};
    19569
    196 #ifdef VBOX_GUI_WITH_SYSTRAY
     70#endif /* !__UIVMDesktop_h__ */
    19771
    198 Q_DECLARE_METATYPE(QString);
    199 
    200 class VBoxTrayIcon : public QSystemTrayIcon
    201 {
    202     Q_OBJECT;
    203 
    204 public:
    205 
    206     VBoxTrayIcon (VBoxSelectorWnd* aParent, UIVMItemModel* aVMModel);
    207     virtual ~VBoxTrayIcon ();
    208 
    209     void refresh ();
    210     void retranslateUi ();
    211 
    212 protected:
    213 
    214     UIVMItem* GetItem (QObject* aObject);
    215 
    216 signals:
    217 
    218 public slots:
    219 
    220     void trayIconShow (bool aShow = false);
    221 
    222 private slots:
    223 
    224     void showSubMenu();
    225     void hideSubMenu ();
    226 
    227     void vmSettings();
    228     void vmDelete();
    229     void vmStart();
    230     void vmDiscard();
    231     void vmPause(bool aPause);
    232     void vmRefresh();
    233     void vmShowLogs();
    234 
    235 private:
    236 
    237     bool mActive;           /* Is systray menu active/available? */
    238 
    239     /* The vm list model */
    240     UIVMItemModel *mVMModel;
    241 
    242     VBoxSelectorWnd* mParent;
    243     QMenu *mTrayIconMenu;
    244 
    245     QAction *mShowSelectorAction;
    246     QAction *mHideSystrayMenuAction;
    247     QAction *mVmConfigAction;
    248     QAction *mVmDeleteAction;
    249     QAction *mVmStartAction;
    250     QAction *mVmDiscardAction;
    251     QAction *mVmPauseAction;
    252     QAction *mVmRefreshAction;
    253     QAction *mVmShowLogsAction;
    254 };
    255 
    256 #endif // VBOX_GUI_WITH_SYSTRAY
    257 
    258 #endif // __VBoxSelectorWnd_h__
    259 
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.cpp

    r30866 r30868  
    2121#else  /* !VBOX_WITH_PRECOMPILED_HEADERS */
    2222#include "QISplitter.h"
    23 #include "QITabWidget.h"
     23#include "UIBar.h"
     24#include "UIDownloaderUserManual.h"
    2425#include "UIExportApplianceWzd.h"
    2526#include "UIIconPool.h"
    2627#include "UIImportApplianceWzd.h"
    2728#include "UINewVMWzd.h"
    28 #include "UISpacerWidgets.h"
    29 #include "UISpecialControls.h"
     29#include "UIVMDesktop.h"
    3030#include "UIVMListView.h"
     31#include "UIVirtualBoxEventHandler.h"
    3132#include "VBoxGlobal.h"
    3233#include "VBoxMediaManagerDlg.h"
     
    3435#include "VBoxSelectorWnd.h"
    3536#include "VBoxSettingsDialogSpecific.h"
    36 #include "VBoxSnapshotsWgt.h"
    3737#include "VBoxToolBar.h"
    38 #include "VBoxUtils.h"
    3938#include "VBoxVMLogViewer.h"
    40 #include "UIVirtualBoxEventHandler.h"
    41 
    42 #include "UIDownloaderUserManual.h"
    43 
    44 #ifdef Q_WS_X11
    45 #include <iprt/env.h>
    46 #endif
    47 
    48 /* Qt includes */
    49 #include <QTextBrowser>
     39
     40/* Global includes */
     41#include <QDesktopWidget>
    5042#include <QMenuBar>
    51 #include <QMenu>
    52 #include <QMenuItem>
    53 #include <QStackedWidget>
    54 #include <QDesktopWidget>
    55 #include <QToolButton>
     43#include <QResizeEvent>
    5644
    5745#include <iprt/buildconfig.h>
    5846#include <VBox/version.h>
     47#ifdef Q_WS_X11
     48# include <iprt/env.h>
     49#endif
    5950#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    60 
    61 // VBoxVMDetailsView class
    62 ////////////////////////////////////////////////////////////////////////////////
    63 
    64 /**
    65  *  Two-page widget stack to represent VM details: one page for normal details
    66  *  and another one for inaccessibility errors.
    67  */
    68 class VBoxVMDetailsView : public QIWithRetranslateUI<QStackedWidget>
    69 {
    70     Q_OBJECT;
    71 
    72 public:
    73 
    74     VBoxVMDetailsView (QWidget *aParent,
    75                        QAction *aRefreshAction = NULL);
    76 
    77     void setDetailsText (const QString &aText)
    78     {
    79         mDetailsText->setText (aText);
    80         setCurrentIndex (0);
    81     }
    82 
    83     void setErrorText (const QString &aText)
    84     {
    85         createErrPage();
    86         mErrText->setText (aText);
    87         setCurrentIndex (1);
    88     }
    89 
    90     void setEmpty()
    91     {
    92         mDetailsText->setText (QString::null);
    93         setCurrentIndex (0);
    94     }
    95 
    96 signals:
    97 
    98     void linkClicked (const QString &aURL);
    99 
    100 protected:
    101 
    102     void retranslateUi();
    103 
    104 private slots:
    105 
    106     void gotLinkClicked (const QUrl &aURL)
    107     {
    108         emit linkClicked (aURL.toString());
    109     }
    110 
    111 private:
    112 
    113     void createErrPage();
    114 
    115     QRichTextBrowser *mDetailsText;
    116 
    117     QWidget *mErrBox;
    118     QLabel *mErrLabel;
    119     QTextBrowser *mErrText;
    120     QToolButton *mRefreshButton;
    121     QAction *mRefreshAction;
    122 };
    123 
    124 VBoxVMDetailsView::VBoxVMDetailsView (QWidget *aParent,
    125                                       QAction *aRefreshAction /* = NULL */)
    126     : QIWithRetranslateUI<QStackedWidget> (aParent)
    127     , mErrBox (NULL), mErrLabel (NULL), mErrText (NULL)
    128     , mRefreshButton (NULL)
    129     , mRefreshAction (aRefreshAction)
    130 {
    131     Assert (mRefreshAction);
    132 
    133     /* create normal details page */
    134 
    135     mDetailsText = new QRichTextBrowser (mErrBox);
    136     mDetailsText->setViewportMargins (10, 10, 10, 10);
    137     mDetailsText->setFocusPolicy (Qt::StrongFocus);
    138     mDetailsText->document()->setDefaultStyleSheet ("a { text-decoration: none; }");
    139     /* make "transparent" */
    140     mDetailsText->setFrameShape (QFrame::NoFrame);
    141     mDetailsText->viewport()->setAutoFillBackground (false);
    142     mDetailsText->setOpenLinks (false);
    143 
    144     connect (mDetailsText, SIGNAL (anchorClicked (const QUrl &)),
    145              this, SLOT (gotLinkClicked (const QUrl &)));
    146 
    147     addWidget (mDetailsText);
    148 }
    149 
    150 void VBoxVMDetailsView::createErrPage()
    151 {
    152     /* create inaccessible details page */
    153 
    154     if (mErrBox)
    155         return;
    156 
    157     mErrBox = new QWidget();
    158 
    159     QVBoxLayout *vLayout = new QVBoxLayout (mErrBox);
    160     vLayout->setSpacing (10);
    161 
    162     mErrLabel = new QLabel (mErrBox);
    163     mErrLabel->setWordWrap (true);
    164     mErrLabel->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed);
    165     vLayout->addWidget (mErrLabel);
    166 
    167     mErrText = new QTextBrowser (mErrBox);
    168     mErrText->setFocusPolicy (Qt::StrongFocus);
    169     mErrText->document()->setDefaultStyleSheet ("a { text-decoration: none; }");
    170     vLayout->addWidget (mErrText);
    171 
    172     if (mRefreshAction)
    173     {
    174         mRefreshButton = new QToolButton (mErrBox);
    175         mRefreshButton->setFocusPolicy (Qt::StrongFocus);
    176 
    177         QHBoxLayout *hLayout = new QHBoxLayout ();
    178         vLayout->addLayout (hLayout);
    179         hLayout->addItem (new QSpacerItem (0, 0, QSizePolicy::Expanding,
    180                                                  QSizePolicy::Minimum));
    181         hLayout->addWidget (mRefreshButton);
    182 
    183         connect (mRefreshButton, SIGNAL (clicked()),
    184                  mRefreshAction, SIGNAL (triggered()));
    185     }
    186 
    187     vLayout->addItem (new QSpacerItem (0, 0, QSizePolicy::Minimum,
    188                                              QSizePolicy::Expanding));
    189 
    190     addWidget (mErrBox);
    191 
    192     retranslateUi();
    193 }
    194 
    195 void VBoxVMDetailsView::retranslateUi()
    196 {
    197     if (mErrLabel)
    198         mErrLabel->setText (tr (
    199             "The selected virtual machine is <i>inaccessible</i>. Please "
    200             "inspect the error message shown below and press the "
    201             "<b>Refresh</b> button if you want to repeat the accessibility "
    202             "check:"));
    203 
    204     if (mRefreshAction && mRefreshButton)
    205     {
    206         mRefreshButton->setText (mRefreshAction->text());
    207         mRefreshButton->setIcon (mRefreshAction->icon());
    208         mRefreshButton->setToolButtonStyle (Qt::ToolButtonTextBesideIcon);
    209     }
    210 }
    211 
    212 // VBoxVMDescriptionPage class
    213 ////////////////////////////////////////////////////////////////////////////////
    214 
    215 /**
    216  *  Comments page widget to represent VM comments.
    217  */
    218 class VBoxVMDescriptionPage : public QIWithRetranslateUI<QWidget>
    219 {
    220     Q_OBJECT;
    221 
    222 public:
    223 
    224     VBoxVMDescriptionPage (VBoxSelectorWnd *);
    225     ~VBoxVMDescriptionPage() {}
    226 
    227     void setMachineItem (UIVMItem *aItem);
    228 
    229     void updateState();
    230 
    231 protected:
    232 
    233     void retranslateUi();
    234 
    235 private slots:
    236 
    237     void goToSettings();
    238 
    239 private:
    240 
    241     UIVMItem *mItem;
    242 
    243     VBoxSelectorWnd *mParent;
    244     QToolButton *mBtnEdit;
    245     QTextBrowser *mBrowser;
    246     QLabel *mLabel;
    247 };
    248 
    249 VBoxVMDescriptionPage::VBoxVMDescriptionPage (VBoxSelectorWnd *aParent)
    250     : QIWithRetranslateUI<QWidget> (aParent)
    251     , mItem (NULL), mParent (aParent)
    252     , mBtnEdit (0), mBrowser (0), mLabel (0)
    253 {
    254     /* main layout */
    255     QVBoxLayout *vMainLayout = new QVBoxLayout (this);
    256     vMainLayout->setSpacing (10);
    257     VBoxGlobal::setLayoutMargin (vMainLayout, 0);
    258 
    259     /* mBrowser */
    260     mBrowser = new QTextBrowser (this);
    261     mBrowser->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
    262     mBrowser->setFocusPolicy (Qt::StrongFocus);
    263     mBrowser->document()->setDefaultStyleSheet ("a { text-decoration: none; }");
    264     vMainLayout->addWidget (mBrowser);
    265     /* hidden by default */
    266     mBrowser->setHidden (true);
    267 
    268     mLabel = new QLabel (this);
    269     mLabel->setFrameStyle (mBrowser->frameStyle());
    270     mLabel->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
    271     mLabel->setAlignment (Qt::AlignCenter);
    272     mLabel->setWordWrap (true);
    273     vMainLayout->addWidget (mLabel);
    274     /* always disabled */
    275     mLabel->setEnabled (false);
    276 
    277     /* button layout */
    278     QHBoxLayout *hBtnLayout = new QHBoxLayout ();
    279     vMainLayout->addLayout (hBtnLayout);
    280     hBtnLayout->setSpacing (10);
    281     hBtnLayout->addItem (new QSpacerItem (0, 0,
    282                                           QSizePolicy::Expanding,
    283                                           QSizePolicy::Minimum));
    284 
    285     /* button */
    286     mBtnEdit = new QToolButton (this);
    287     mBtnEdit->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Fixed);
    288     mBtnEdit->setFocusPolicy (Qt::StrongFocus);
    289     mBtnEdit->setIcon(UIIconPool::iconSet(":/edit_description_16px.png",
    290                                           ":/edit_description_disabled_16px.png"));
    291     mBtnEdit->setToolButtonStyle (Qt::ToolButtonTextBesideIcon);
    292     connect (mBtnEdit, SIGNAL (clicked()), this, SLOT (goToSettings()));
    293     hBtnLayout->addWidget (mBtnEdit);
    294 
    295     vMainLayout->addItem (new QSpacerItem (0, 0,
    296                                            QSizePolicy::Expanding,
    297                                            QSizePolicy::Minimum));
    298 
    299     /* apply language settings */
    300     retranslateUi();
    301 
    302     updateState();
    303 }
    304 
    305 /**
    306  * The machine list @a aItem is used to access cached machine data w/o making
    307  * unnecessary RPC calls.
    308  */
    309 void VBoxVMDescriptionPage::setMachineItem (UIVMItem *aItem)
    310 {
    311     mItem = aItem;
    312 
    313     QString text = aItem ? aItem->machine().GetDescription() : QString::null;
    314 
    315     if (!text.isEmpty())
    316     {
    317         mLabel->setHidden (true);
    318         mBrowser->setText (text);
    319         mBrowser->setVisible (true);
    320     }
    321     else
    322     {
    323         mBrowser->setHidden (true);
    324         mBrowser->clear();
    325         mLabel->setVisible (true);
    326     }
    327 
    328     /* check initial machine and session states */
    329     updateState();
    330 }
    331 
    332 void VBoxVMDescriptionPage::retranslateUi()
    333 {
    334     mLabel->setText (tr ("No description. Press the Edit button below to add it."));
    335 
    336     mBtnEdit->setText (tr ("Edit"));
    337     mBtnEdit->setShortcut (QKeySequence ("Ctrl+E"));
    338     mBtnEdit->setToolTip (tr ("Edit (Ctrl+E)"));
    339     mBtnEdit->adjustSize();
    340     mBtnEdit->updateGeometry();
    341 }
    342 
    343 /**
    344  * Called by the parent from machineStateChanged() and sessionStateChanged()
    345  * signal handlers. We cannot connect to these signals ourselves because we
    346  * use the UIVMListBoxItem which needs to be properly updated by the parent
    347  * first.
    348  */
    349 void VBoxVMDescriptionPage::updateState()
    350 {
    351     /// @todo disabling the edit button for a saved VM will not be necessary
    352     /// when we implement the selective VM Settings dialog, where only fields
    353     /// that can be changed in the saved state, can be changed.
    354 
    355     if (mItem)
    356     {
    357         bool saved = mItem->state() == KMachineState_Saved;
    358         bool busy = mItem->sessionState() != KSessionState_Closed;
    359         mBtnEdit->setEnabled (!saved && !busy);
    360     }
    361     else
    362         mBtnEdit->setEnabled (false);
    363 }
    364 
    365 void VBoxVMDescriptionPage::goToSettings()
    366 {
    367     mParent->vmSettings ("#general", "mTeDescription");
    368 }
    36951
    37052// VBoxSelectorWnd class
     
    474156    mHelpActions.setup (this);
    475157
    476     QISplitter *pSplitter = new QISplitter(this);
    477     pSplitter->setHandleType(QISplitter::Native);
    478     /* Central widget @ horizontal layout */
    479     setCentralWidget(pSplitter);
    480 
    481158    /* VM list toolbar */
    482159    mVMToolBar = new VBoxToolBar(this);
     
    502179        mVMListView->setStyleSheet ("activate-on-singleclick : 0");
    503180
     181    m_pSplitter = new QISplitter(this);
     182    m_pSplitter->setHandleType(QISplitter::Native);
     183
     184#define BIG_TOOLBAR
    504185#if MAC_LEOPARD_STYLE
    505186    /* Enable unified toolbars on Mac OS X. Available on Qt >= 4.3 */
    506187    addToolBar (mVMToolBar);
    507188    mVMToolBar->setMacToolbar();
    508     pSplitter->addWidget (mVMListView);
     189    /* Central widget @ horizontal layout */
     190    setCentralWidget(m_pSplitter);
     191    m_pSplitter->addWidget (mVMListView);
    509192#else /* MAC_LEOPARD_STYLE */
     193//    mVMToolBar->setContentsMargins(5, 5, 0, 0);
     194//    addToolBar (mVMToolBar);
     195//    m_pSplitter->addWidget (mVMListView);
    510196    QWidget *pLeftWidget = new QWidget(this);
    511197    QVBoxLayout *pLeftVLayout = new QVBoxLayout(pLeftWidget);
    512     pLeftVLayout->setContentsMargins(5, 5, 0, 0);
     198    pLeftVLayout->setContentsMargins(0, 0, 0, 0);
     199    pLeftVLayout->setSpacing(0);
     200# ifdef BIG_TOOLBAR
     201    m_pBar = new UIBar(this);
     202    m_pBar->setContentWidget(mVMToolBar);
     203    pLeftVLayout->addWidget(m_pBar);
     204    pLeftVLayout->addWidget(m_pSplitter);
     205    setCentralWidget(pLeftWidget);
     206    m_pSplitter->addWidget(mVMListView);
     207# else /* BIG_TOOLBAR */
    513208    pLeftVLayout->addWidget(mVMToolBar);
    514209    pLeftVLayout->addWidget(mVMListView);
    515     pSplitter->addWidget(pLeftWidget);
     210    setCentralWidget(m_pSplitter);
     211    m_pSplitter->addWidget(pLeftWidget);
     212# endif /* BIG_TOOLBAR */
    516213#endif /* MAC_LEOPARD_STYLE */
    517 
    518      /* VM tab widget containing details and snapshots tabs */
    519     mVmTabWidget = new QITabWidget();
    520     pSplitter->addWidget (mVmTabWidget);
    521 
    522     /* Set the initial distribution. The right site is bigger. */
    523     pSplitter->setStretchFactor(0, 2);
    524     pSplitter->setStretchFactor(1, 3);
    525 
    526 
    527     /* VM details view */
    528     mVmDetailsView = new VBoxVMDetailsView (NULL, mVmRefreshAction);
    529     mVmTabWidget->addTab(mVmDetailsView,
    530                          UIIconPool::iconSet(":/settings_16px.png"),
    531                          QString::null);
    532 
    533     /* VM snapshots list */
    534     mVmSnapshotsWgt = new VBoxSnapshotsWgt (NULL);
    535     mVmTabWidget->addTab(mVmSnapshotsWgt,
    536                          UIIconPool::iconSet(":/take_snapshot_16px.png",
    537                                              ":/take_snapshot_dis_16px.png"),
    538                          QString::null);
    539     mVmSnapshotsWgt->setContentsMargins (10, 10, 10, 10);
    540 
    541     /* VM comments page */
    542     mVmDescriptionPage = new VBoxVMDescriptionPage (this);
    543     mVmTabWidget->addTab(mVmDescriptionPage,
    544                          UIIconPool::iconSet(":/description_16px.png",
    545                                              ":/description_disabled_16px.png"),
    546                          QString::null);
    547     mVmDescriptionPage->setContentsMargins (10, 10, 10, 10);
    548214
    549215    /* add actions to the toolbar */
     
    551217    mVMToolBar->setIconSize (QSize (32, 32));
    552218    mVMToolBar->setToolButtonStyle (Qt::ToolButtonTextUnderIcon);
    553     mVMToolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Preferred);
     219//    mVMToolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Preferred);
    554220
    555221    mVMToolBar->addAction (mVmNewAction);
     
    560226    mVMToolBar->addAction (mVmStartAction);
    561227    mVMToolBar->addAction (mVmDiscardAction);
     228
     229    /* VM tab widget containing details and snapshots tabs */
     230    QWidget *w = new QWidget();
     231    QVBoxLayout *pVBox = new QVBoxLayout(w);
     232    pVBox->setContentsMargins(0, 0, 0, 0);
     233
     234    m_pVMDesktop = new UIVMDesktop(mVMToolBar, mVmRefreshAction, this);
     235    pVBox->addWidget(m_pVMDesktop);
     236
     237    m_pSplitter->addWidget (w);
     238
     239    /* Set the initial distribution. The right site is bigger. */
     240    m_pSplitter->setStretchFactor(0, 2);
     241    m_pSplitter->setStretchFactor(1, 3);
    562242
    563243    /* Configure menubar */
     
    675355    /* Read the splitter handle position */
    676356    {
    677         QString sliderPos = vbox.GetExtraData(VBoxDefs::GUI_SplitterSizes);
    678         QStringList strSizes = sliderPos.split(",");
    679         if (strSizes.size() == 2)
    680         {
    681             QList<int> sizes;
    682             for (int i=0; i <  strSizes.size(); ++i)
    683                 sizes << strSizes.at(i).toInt();
    684             pSplitter->setSizes(sizes);
    685         }
     357        QList<int> sizes = vbox.GetExtraDataIntList(VBoxDefs::GUI_SplitterSizes);
     358        if (sizes.size() == 2)
     359            m_pSplitter->setSizes(sizes);
    686360    }
    687361
     
    691365        QString strStatusbar = vbox.GetExtraData(VBoxDefs::GUI_Statusbar);
    692366
     367#ifdef Q_WS_MAC
    693368        mVMToolBar->setVisible(strToolbar.isEmpty() || strToolbar == "true");
     369#else /* Q_WS_MAC */
     370        m_pBar->setVisible(strToolbar.isEmpty() || strToolbar == "true");
     371#endif /* !Q_WS_MAC */
    694372        statusBar()->setVisible(strStatusbar.isEmpty() || strStatusbar == "true");
    695373    }
     
    722400             this, SLOT (showContextMenu (const QPoint &)));
    723401
    724     connect (mVmDetailsView, SIGNAL (linkClicked (const QString &)),
     402    connect (m_pVMDesktop, SIGNAL(linkClicked(const QString &)),
    725403             this, SLOT(vmSettings(const QString &)));
    726404
     
    762440VBoxSelectorWnd::~VBoxSelectorWnd()
    763441{
     442    CVirtualBox vbox = vboxGlobal().virtualBox();
     443
    764444    /* Destroy our event handlers */
    765445    UIVirtualBoxEventHandler::destroy();
    766 
    767     CVirtualBox vbox = vboxGlobal().virtualBox();
    768446
    769447    /* Save the position of the window */
     
    795473    /* Save the splitter handle position */
    796474    {
    797         QSplitter *pSplitter = static_cast<QSplitter*>(centralWidget());
    798         QList<int> sizes = pSplitter->sizes();
    799         QStringList strSizes;
    800         for (int i=0; i < sizes.size(); ++i)
    801             strSizes << QString::number(sizes.at(i));
    802         vbox.SetExtraData(VBoxDefs::GUI_SplitterSizes, strSizes.join(","));
     475        vbox.SetExtraDataIntList(VBoxDefs::GUI_SplitterSizes, m_pSplitter->sizes());
    803476    }
    804477
     
    893566 *  Opens the VM settings dialog.
    894567 */
    895 void VBoxSelectorWnd::vmSettings (const QString &aCategory, const QString &aControl,
     568void VBoxSelectorWnd::vmSettings (const QString &aCategory /* = QString::null */,
     569                                  const QString &aControl /* = QString::null */,
    896570                                  const QString &aUuid /* = QString::null */)
    897571{
     
    901575        vboxGlobal().openURL (aCategory);
    902576        return;
     577    }
     578    QString strCategory = aCategory;
     579    QString strControl = aControl;
     580    /* Maybe the control is coded into the URL by %% */
     581    if (aControl == QString::null)
     582    {
     583        QStringList parts = aCategory.split("%%");
     584        if (parts.size() == 2)
     585        {
     586            strCategory = parts.at(0);
     587            strControl = parts.at(1);
     588        }
    903589    }
    904590
     
    917603    AssertMsgReturn (!m.isNull(), ("Machine must not be null"), (void) 0);
    918604
    919     VBoxSettingsDialog *dlg = new VBoxVMSettingsDlg (this, m, aCategory, aControl);
     605    VBoxSettingsDialog *dlg = new VBoxVMSettingsDlg (this, m, strCategory, strControl);
    920606    dlg->getFrom();
    921607
     
    13771063
    13781064    setWindowTitle (title);
    1379 
    1380     mVmTabWidget->setTabText (mVmTabWidget->indexOf (mVmDetailsView), tr ("&Details"));
    1381     /* note: Snapshots and Details tabs are changed dynamically by
    1382      * vmListViewCurrentChanged() */
    13831065
    13841066    /* ensure the details and screenshot view are updated */
     
    15101192
    15111193        if (aRefreshDetails)
    1512         {
    1513             mVmDetailsView->setDetailsText (
    1514                 vboxGlobal().detailsReport (m, modifyEnabled /* withLinks */));
    1515         }
     1194            m_pVMDesktop->updateDetails(item, m);
    15161195        if (aRefreshSnapshots)
    1517         {
    1518             /* update the snapshots tab name */
    1519             QString name = tr ("&Snapshots");
    1520             ULONG count = item->snapshotCount();
    1521             if (count)
    1522                 name += QString (" (%1)").arg (count);
    1523             mVmTabWidget->setTabText (mVmTabWidget->indexOf (mVmSnapshotsWgt), name);
    1524             /* refresh the snapshots widget */
    1525             mVmSnapshotsWgt->setMachine (m);
    1526             /* ensure the tab is enabled */
    1527             mVmTabWidget->setTabEnabled (mVmTabWidget->indexOf (mVmSnapshotsWgt), true);
    1528         }
     1196            m_pVMDesktop->updateSnapshots(item, m);
    15291197        if (aRefreshDescription)
    1530         {
    1531             /* update the description tab name */
    1532             QString name = m.GetDescription().isEmpty() ?
    1533                 tr ("D&escription") : tr ("D&escription *");
    1534             mVmTabWidget->setTabText (mVmTabWidget->indexOf (mVmDescriptionPage), name);
    1535             /* refresh the description widget */
    1536             mVmDescriptionPage->setMachineItem (item);
    1537             /* ensure the tab is enabled */
    1538             mVmTabWidget->setTabEnabled (mVmTabWidget->indexOf (mVmDescriptionPage), true);
    1539         }
     1198            m_pVMDesktop->updateDescription(item, m);
    15401199
    15411200        /* enable/disable modify actions */
     
    16251284        {
    16261285            /* the VM is inaccessible */
    1627             mVmDetailsView->setErrorText (
    1628                 VBoxProblemReporter::formatErrorInfo (item->accessError()));
    1629             mVmRefreshAction->setEnabled (true);
     1286            m_pVMDesktop->updateDetailsErrorText(
     1287                VBoxProblemReporter::formatErrorInfo(item->accessError()));
     1288            mVmRefreshAction->setEnabled(true);
    16301289        }
    16311290        else
     
    16331292            /* default HTML support in Qt is terrible so just try to get
    16341293             * something really simple */
    1635             mVmDetailsView->setDetailsText
    1636                 (tr ("<h3>"
    1637                      "Welcome to VirtualBox!</h3>"
    1638                      "<p>The left part of this window is  "
    1639                      "a list of all virtual machines on your computer. "
    1640                      "The list is empty now because you haven't created any virtual "
    1641                      "machines yet."
    1642                      "<img src=:/welcome.png align=right/></p>"
    1643                      "<p>In order to create a new virtual machine, press the "
    1644                      "<b>New</b> button in the main tool bar located "
    1645                      "at the top of the window.</p>"
    1646                      "<p>You can press the <b>%1</b> key to get instant help, "
    1647                      "or visit "
    1648                      "<a href=http://www.virtualbox.org>www.virtualbox.org</a> "
    1649                      "for the latest information and news.</p>").arg (QKeySequence (QKeySequence::HelpContents).toString (QKeySequence::NativeText)));
    1650             mVmRefreshAction->setEnabled (false);
     1294            m_pVMDesktop->updateDetailsText(
     1295                tr("<h3>"
     1296                   "Welcome to VirtualBox!</h3>"
     1297                   "<p>The left part of this window is  "
     1298                   "a list of all virtual machines on your computer. "
     1299                   "The list is empty now because you haven't created any virtual "
     1300                   "machines yet."
     1301                   "<img src=:/welcome.png align=right/></p>"
     1302                   "<p>In order to create a new virtual machine, press the "
     1303                   "<b>New</b> button in the main tool bar located "
     1304                   "at the top of the window.</p>"
     1305                   "<p>You can press the <b>%1</b> key to get instant help, "
     1306                   "or visit "
     1307                   "<a href=http://www.virtualbox.org>www.virtualbox.org</a> "
     1308                   "for the latest information and news.</p>").arg (QKeySequence (QKeySequence::HelpContents).toString (QKeySequence::NativeText)));
     1309            mVmRefreshAction->setEnabled(false);
    16511310        }
    16521311
    16531312        /* empty and disable other tabs */
    1654 
    1655         mVmSnapshotsWgt->setMachine (CMachine());
    1656         mVmTabWidget->setTabText (mVmTabWidget->indexOf (mVmSnapshotsWgt), tr ("&Snapshots"));
    1657         mVmTabWidget->setTabEnabled (mVmTabWidget->indexOf (mVmSnapshotsWgt), false);
    1658 
    1659         mVmDescriptionPage->setMachineItem (NULL);
    1660         mVmTabWidget->setTabText (mVmTabWidget->indexOf (mVmDescriptionPage), tr ("D&escription"));
    1661         mVmTabWidget->setTabEnabled (mVmTabWidget->indexOf (mVmDescriptionPage), false);
     1313        m_pVMDesktop->updateSnapshots(0, CMachine());
     1314        m_pVMDesktop->updateDescription(0, CMachine());
    16621315
    16631316        /* disable modify actions */
     
    17491402
    17501403    /* simulate a state change signal */
    1751     mVmDescriptionPage->updateState();
     1404    m_pVMDesktop->updateDescriptionState();
    17521405}
    17531406
     
    18031456
    18041457    /* simulate a state change signal */
    1805     mVmDescriptionPage->updateState();
     1458    m_pVMDesktop->updateDescriptionState();
    18061459}
    18071460
     
    22521905        if (pResult->isChecked())
    22531906        {
     1907#ifdef Q_WS_MAC
    22541908            mVMToolBar->show();
     1909#else /* Q_WS_MAC */
     1910            m_pBar->show();
     1911#endif /* !Q_WS_MAC */
    22551912            vbox.SetExtraData(VBoxDefs::GUI_Toolbar, "true");
    22561913        }
    22571914        else
    22581915        {
     1916#ifdef Q_WS_MAC
    22591917            mVMToolBar->hide();
     1918#else /* Q_WS_MAC */
     1919            m_pBar->hide();
     1920#endif /* !Q_WS_MAC */
    22601921            vbox.SetExtraData(VBoxDefs::GUI_Toolbar, "false");
    22611922        }
     
    22751936}
    22761937
    2277 #include "VBoxSelectorWnd.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/VBoxSelectorWnd.h

    r30866 r30868  
    2020#define __VBoxSelectorWnd_h__
    2121
     22/* Local includes */
    2223#include "COMDefs.h"
    23 
    2424#include "QIWithRetranslateUI.h"
    25 
    2625#include "VBoxGlobal.h"
     26#include "VBoxHelpActions.h"
    2727#include "VBoxProblemReporter.h"
    28 #include "VBoxHelpActions.h"
    29 
    30 /* Qt includes */
     28
     29/* Global includes */
    3130#include <QMainWindow>
    3231#ifdef VBOX_GUI_WITH_SYSTRAY
    33     #include <QSystemTrayIcon>
     32# include <QSystemTrayIcon>
    3433#endif
    3534
    3635/* Local forward declarations */
    37 class QITabWidget;
     36class QISplitter;
     37class UIBar;
     38class UIVMDesktop;
    3839class UIVMItem;
    3940class UIVMItemModel;
    4041class UIVMListView;
    41 class VBoxSnapshotsWgt;
    4242class VBoxToolBar;
    4343class VBoxTrayIcon;
    44 class VBoxVMDescriptionPage;
    45 class VBoxVMDetailsView;
    4644class VBoxVMLogViewer;
    4745
    48 /* Global forward declarations */
    49 class QEvent;
    50 class QListView;
    51 
    52 class VBoxSelectorWnd : public QIWithRetranslateUI2 <QMainWindow>
     46class VBoxSelectorWnd : public QIWithRetranslateUI2<QMainWindow>
    5347{
    5448    Q_OBJECT;
     
    150144    QMenu *mHelpMenu;
    151145
     146    /* Central splitter window */
     147    QISplitter *m_pSplitter;
     148
    152149    /* Main toolbar */
     150#ifndef Q_WS_MAC
     151    UIBar *m_pBar;
     152#endif /* !Q_WS_MAC */
    153153    VBoxToolBar *mVMToolBar;
    154154
    155155    /* VM list context menu */
    156156    QMenu *mVMCtxtMenu;
    157 //    UIOSDMenu *mVMCtxtMenu;
    158157
    159158    /* Actions */
     
    184183
    185184    /* The right information widgets */
    186     QITabWidget *mVmTabWidget;
    187     VBoxVMDetailsView *mVmDetailsView;
    188     VBoxSnapshotsWgt *mVmSnapshotsWgt;
    189     VBoxVMDescriptionPage *mVmDescriptionPage;
     185    UIVMDesktop *m_pVMDesktop;
    190186
    191187    QRect mNormalGeo;
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UISpacerWidgets.h

    r30188 r30868  
    3232      : QWidget(pParent)
    3333    {
     34        setContentsMargins(0, 0, 0, 0);
    3435        setOrientation(Qt::Horizontal);
    3536    }
     
    4546    Qt::Orientation orientation() const { return m_orientation; }
    4647
    47     QSize sizeHint() const { return QSize(1, 1); }
     48    QSize sizeHint() const { return QSize(0, 0); }
    4849
    4950private:
Note: See TracChangeset for help on using the changeset viewer.

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