VirtualBox

Changeset 45212 in vbox for trunk/src


Ignore:
Timestamp:
Mar 27, 2013 4:03:37 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
84576
Message:

FE/Qt: Runtime UI: Close VM dialog general rework/cleanup (part 2).

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
1 deleted
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/VBoxUI.pro

    r44528 r45212  
    5050    src/settings/machine/UIMachineSettingsSFDetails.ui \
    5151    src/widgets/UIApplianceEditorWidget.ui \
    52     src/selector/VBoxSnapshotsWgt.ui \
    53     src/runtime/UIVMCloseDialog.ui
     52    src/selector/VBoxSnapshotsWgt.ui
    5453
    5554TRANSLATIONS = \
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp

    r45203 r45212  
    265265
    266266    /* Get the machine: */
    267     CMachine m = machine();
     267    CMachine machineCopy = machine();
    268268
    269269    /* If there is a close hook script defined: */
    270     const QString& strScript = m.GetExtraData(GUI_CloseActionHook);
     270    const QString& strScript = machineCopy.GetExtraData(GUI_CloseActionHook);
    271271    if (!strScript.isEmpty())
    272272    {
    273273        /* Execute asynchronously and leave: */
    274         QProcess::startDetached(strScript, QStringList() << m.GetId());
     274        QProcess::startDetached(strScript, QStringList() << machineCopy.GetId());
    275275        return;
    276276    }
     
    278278    /* Prepare close-dialog: */
    279279    QWidget *pParentDlg = mwManager().realParentWindow(this);
    280     QPointer<UIVMCloseDialog> pCloseDlg = new UIVMCloseDialog(pParentDlg);
     280    QPointer<UIVMCloseDialog> pCloseDlg = new UIVMCloseDialog(pParentDlg, machineCopy, session());
    281281    mwManager().registerNewParent(pCloseDlg, pParentDlg);
    282282
    283     /* Assign close-dialog pixmap: */
    284     pCloseDlg->pmIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(m.GetOSTypeId()));
    285 
    286     /* Check which close-actions are resticted: */
    287     QStringList restictedActionsList = m.GetExtraData(GUI_RestrictedCloseActions).split(',');
    288     bool fIsStateSavingAllowed = !restictedActionsList.contains("SaveState", Qt::CaseInsensitive);
    289     bool fIsACPIShutdownAllowed = !restictedActionsList.contains("Shutdown", Qt::CaseInsensitive);
    290     bool fIsPowerOffAllowed = !restictedActionsList.contains("PowerOff", Qt::CaseInsensitive);
    291     bool fIsPowerOffAndRestoreAllowed = fIsPowerOffAllowed && !restictedActionsList.contains("Restore", Qt::CaseInsensitive);
    292 
    293     /* Make 'Save state' button visible/hidden depending on restriction: */
    294     pCloseDlg->mRbSave->setVisible(fIsStateSavingAllowed);
    295     pCloseDlg->mTxSave->setVisible(fIsStateSavingAllowed);
    296     /* Make 'Save state' button enabled/disabled depending on machine-state: */
    297     pCloseDlg->mRbSave->setEnabled(machineState != KMachineState_Stuck);
    298 
    299     /* Make 'ACPI shutdown button' visible/hidden depending on restriction: */
    300     pCloseDlg->mRbShutdown->setVisible(fIsACPIShutdownAllowed);
    301     pCloseDlg->mTxShutdown->setVisible(fIsACPIShutdownAllowed);
    302     /* Make 'ACPI shutdown button' enabled/disabled depending on ACPI-state & machine-state: */
    303     bool fIsACPIEnabled = session().GetConsole().GetGuestEnteredACPIMode();
    304     pCloseDlg->mRbShutdown->setEnabled(fIsACPIEnabled && machineState != KMachineState_Stuck);
    305 
    306     /* Make 'Power off' button visible/hidden depending on restriction: */
    307     pCloseDlg->mRbPowerOff->setVisible(fIsPowerOffAllowed);
    308     pCloseDlg->mTxPowerOff->setVisible(fIsPowerOffAllowed);
    309 
    310     /* Make the Restore Snapshot checkbox visible/hidden depending on snapshot count & restrictions: */
    311     pCloseDlg->mCbDiscardCurState->setVisible(fIsPowerOffAndRestoreAllowed && m.GetSnapshotCount() > 0);
    312     if (!m.GetCurrentSnapshot().isNull())
    313         pCloseDlg->mCbDiscardCurState->setText(pCloseDlg->mCbDiscardCurState->text().arg(m.GetCurrentSnapshot().GetName()));
    314 
    315     /* Possible extra-data option values for close-dialog: */
    316     QString strSave("save");
    317     QString strShutdown("shutdown");
    318     QString strPowerOff("powerOff");
    319     QString strDiscardCurState("discardCurState");
    320 
    321     /* Read the last user's choice for the given VM: */
    322     QStringList lastAction = m.GetExtraData(GUI_LastCloseAction).split(',');
    323 
    324     /* Check which button should be initially chosen: */
    325     QRadioButton *pRadioButtonToChoose = 0;
    326 
    327     /* If choosing 'last choice' is possible: */
    328     if (lastAction[0] == strSave && fIsStateSavingAllowed)
    329     {
    330         pRadioButtonToChoose = pCloseDlg->mRbSave;
    331     }
    332     else if (lastAction[0] == strShutdown && fIsACPIShutdownAllowed && fIsACPIEnabled)
    333     {
    334         pRadioButtonToChoose = pCloseDlg->mRbShutdown;
    335     }
    336     else if (lastAction[0] == strPowerOff && fIsPowerOffAllowed)
    337     {
    338         pRadioButtonToChoose = pCloseDlg->mRbPowerOff;
    339         if (fIsPowerOffAndRestoreAllowed)
    340             pCloseDlg->mCbDiscardCurState->setChecked(lastAction.count() > 1 && lastAction[1] == strDiscardCurState);
    341     }
    342     /* Else 'default choice' will be used: */
    343     else
    344     {
    345         if (fIsACPIShutdownAllowed && fIsACPIEnabled)
    346             pRadioButtonToChoose = pCloseDlg->mRbShutdown;
    347         else if (fIsPowerOffAllowed)
    348             pRadioButtonToChoose = pCloseDlg->mRbPowerOff;
    349         else if (fIsStateSavingAllowed)
    350             pRadioButtonToChoose = pCloseDlg->mRbSave;
    351     }
    352 
    353     /* If some radio button chosen: */
    354     if (pRadioButtonToChoose)
    355     {
    356         /* Check and focus it: */
    357         pRadioButtonToChoose->setChecked(true);
    358         pRadioButtonToChoose->setFocus();
    359     }
    360     /* If no one of radio buttons was chosen: */
    361     else
     283    /* Makes sure the dialog is valid: */
     284    if (!pCloseDlg->isValid())
    362285    {
    363286        /* Destroy and leave: */
     
    384307
    385308        /* Show the close-dialog: */
    386         bool fDialogAccepted = pCloseDlg->exec() == QDialog::Accepted;
    387 
    388         /* What was the decision? */
    389         enum DialogDecision { DD_Cancel, DD_Save, DD_Shutdown, DD_PowerOff };
    390         DialogDecision decision;
    391         if (!fDialogAccepted)
    392             decision = DD_Cancel;
    393         else if (pCloseDlg->mRbSave->isChecked())
    394             decision = DD_Save;
    395         else if (pCloseDlg->mRbShutdown->isChecked())
    396             decision = DD_Shutdown;
    397         else
    398             decision = DD_PowerOff;
    399         bool fDiscardCurState = pCloseDlg->mCbDiscardCurState->isChecked();
    400         bool fDiscardCheckboxVisible = pCloseDlg->mCbDiscardCurState->isVisibleTo(pCloseDlg);
     309        UIVMCloseDialog::ResultCode dialogResult = (UIVMCloseDialog::ResultCode)pCloseDlg->exec();
    401310
    402311        /* Destroy the dialog early: */
     
    404313
    405314        /* Was dialog accepted? */
    406         if (fDialogAccepted)
     315        if (dialogResult != UIVMCloseDialog::ResultCode_Cancel)
    407316        {
    408317            /* Process decision: */
    409318            CConsole console = session().GetConsole();
    410             switch (decision)
     319            switch (dialogResult)
    411320            {
    412                 case DD_Save:
     321                case UIVMCloseDialog::ResultCode_Save:
    413322                {
    414323                    /* Prepare the saving progress: */
     
    418327                    {
    419328                        /* Show the saving progress dialog: */
    420                         msgCenter().showModalProgressDialog(progress, m.GetName(), ":/progress_state_save_90px.png", this);
     329                        msgCenter().showModalProgressDialog(progress, machineCopy.GetName(), ":/progress_state_save_90px.png", this);
    421330                        fSuccess = progress.GetResultCode() == 0;
    422331                        if (fSuccess)
     
    429338                    break;
    430339                }
    431                 case DD_Shutdown:
     340                case UIVMCloseDialog::ResultCode_Shutdown:
    432341                {
    433342                    /* Unpause VM to let it grab the ACPI shutdown event: */
     
    445354                    break;
    446355                }
    447                 case DD_PowerOff:
     356                case UIVMCloseDialog::ResultCode_PowerOff:
     357                case UIVMCloseDialog::ResultCode_PowerOff_With_Discarding:
    448358                {
    449359                    /* Prepare the power down progress: */
     
    453363                    {
    454364                        /* Show the power down progress: */
    455                         msgCenter().showModalProgressDialog(progress, m.GetName(), ":/progress_poweroff_90px.png", this);
     365                        msgCenter().showModalProgressDialog(progress, machineCopy.GetName(), ":/progress_poweroff_90px.png", this);
    456366                        fSuccess = progress.GetResultCode() == 0;
    457367                        if (fSuccess)
    458368                        {
    459369                            /* Discard the current state if requested: */
    460                             if (fDiscardCurState && fDiscardCheckboxVisible)
     370                            if (dialogResult == UIVMCloseDialog::ResultCode_PowerOff_With_Discarding)
    461371                            {
    462372                                /* Prepare the snapshot discard progress: */
    463                                 CSnapshot snapshot = m.GetCurrentSnapshot();
     373                                CSnapshot snapshot = machineCopy.GetCurrentSnapshot();
    464374                                CProgress progress = console.RestoreSnapshot(snapshot);
    465375                                fSuccess = console.isOk();
     
    467377                                {
    468378                                    /* Show the snapshot discard progress: */
    469                                     msgCenter().showModalProgressDialog(progress, m.GetName(), ":/progress_snapshot_discard_90px.png", this);
     379                                    msgCenter().showModalProgressDialog(progress, machineCopy.GetName(), ":/progress_snapshot_discard_90px.png", this);
    470380                                    fSuccess = progress.GetResultCode() == 0;
    471381                                    if (!fSuccess)
     
    495405                    break;
    496406            }
    497 
    498             if (fSuccess)
    499             {
    500                 /* Read the last user's choice for the given VM: */
    501                 QStringList prevAction = m.GetExtraData(GUI_LastCloseAction).split(',');
    502                 /* Memorize the last user's choice for the given VM: */
    503                 QString strLastAction = strPowerOff;
    504                 switch (decision)
    505                 {
    506                     case DD_Save: strLastAction = strSave; break;
    507                     case DD_Shutdown: strLastAction = strShutdown; break;
    508                     case DD_PowerOff:
    509                     {
    510                         if (prevAction[0] == strShutdown && !fIsACPIEnabled)
    511                             strLastAction = strShutdown;
    512                         else
    513                             strLastAction = strPowerOff;
    514                         break;
    515                     }
    516                     default: break;
    517                 }
    518                 /* Memorize additional options for the given VM: */
    519                 if (fDiscardCurState)
    520                     (strLastAction += ",") += strDiscardCurState;
    521                 /* Save the last user's choice for the given VM: */
    522                 m.SetExtraData(GUI_LastCloseAction, strLastAction);
    523             }
    524407        }
    525408
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIVMCloseDialog.cpp

    r45206 r45212  
    2121# include "precomp.h"
    2222#else  /* !VBOX_WITH_PRECOMPILED_HEADERS */
     23
    2324/* Qt includes: */
    24 #include <QPushButton>
     25# include <QVBoxLayout>
     26# include <QHBoxLayout>
     27# include <QGridLayout>
     28# include <QLabel>
     29# include <QRadioButton>
     30# include <QCheckBox>
     31# include <QPushButton>
    2532
    2633/* GUI includes: */
    27 #include "UIVMCloseDialog.h"
    28 #include "UIMessageCenter.h"
    29 #include "UIMachineWindowNormal.h"
     34# include "UIVMCloseDialog.h"
     35# include "UIMessageCenter.h"
     36# include "VBoxGlobal.h"
     37# include "QIDialogButtonBox.h"
     38
     39/* COM includes: */
     40# include "CSession.h"
     41# include "CConsole.h"
     42# include "CSnapshot.h"
     43
    3044#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    3145
    32 UIVMCloseDialog::UIVMCloseDialog(QWidget *pParent)
     46UIVMCloseDialog::UIVMCloseDialog(QWidget *pParent, const CMachine &machine, const CSession &session)
    3347    : QIWithRetranslateUI<QIDialog>(pParent)
    34 {
    35     /* Apply UI decorations: */
    36     Ui::UIVMCloseDialog::setupUi(this);
    37 
    38 #ifdef Q_WS_MAC
    39     /* Add more space around the content: */
    40     hboxLayout->setContentsMargins(40, 0, 40, 0);
    41     vboxLayout2->insertSpacing(1, 20);
    42     /* And more space between the radio buttons: */
    43     gridLayout->setSpacing(15);
    44 #endif /* Q_WS_MAC */
    45 
    46     /* Configure default button connections: */
    47     connect(mButtonBox, SIGNAL(helpRequested()),
    48             &msgCenter(), SLOT(sltShowHelpHelpDialog()));
     48    , m_strExtraDataOptionSave("save")
     49    , m_strExtraDataOptionShutdown("shutdown")
     50    , m_strExtraDataOptionPowerOff("powerOff")
     51    , m_strExtraDataOptionDiscard("discardCurState")
     52    , m_fValid(false)
     53    , m_fIsACPIEnabled(false)
     54{
     55    /* Prepare: */
     56    prepare();
     57
     58    /* Configure: */
     59    setSizeGripEnabled(false);
     60    configure(machine, session);
     61
     62    /* Retranslate finally: */
     63    retranslateUi();
     64}
     65
     66void UIVMCloseDialog::sltUpdateWidgetAvailability()
     67{
     68    /* Discard option should be enabled only on power-off action: */
     69    m_pDiscardCheckBox->setEnabled(m_pPowerOffRadio->isChecked());
     70}
     71
     72void UIVMCloseDialog::accept()
     73{
     74    /* Calculate result: */
     75    if (m_pSaveRadio->isChecked())
     76        setResult(ResultCode_Save);
     77    else if (m_pShutdownRadio->isChecked())
     78        setResult(ResultCode_Shutdown);
     79    else if (m_pPowerOffRadio->isChecked())
     80    {
     81        if (!m_pDiscardCheckBox->isChecked())
     82            setResult(ResultCode_PowerOff);
     83        else
     84            setResult(ResultCode_PowerOff_With_Discarding);
     85    }
     86
     87    /* Read the last user's choice for the given VM: */
     88    QStringList previousChoice = m_machine.GetExtraData(GUI_LastCloseAction).split(',');
     89    /* Memorize the last user's choice for the given VM: */
     90    QString strLastAction = m_strExtraDataOptionPowerOff;
     91    switch (result())
     92    {
     93        case ResultCode_Save:
     94        {
     95            strLastAction = m_strExtraDataOptionSave;
     96            break;
     97        }
     98        case ResultCode_Shutdown:
     99        {
     100            strLastAction = m_strExtraDataOptionShutdown;
     101            break;
     102        }
     103        case ResultCode_PowerOff:
     104        {
     105            if (previousChoice[0] == m_strExtraDataOptionShutdown && !m_fIsACPIEnabled)
     106                strLastAction = m_strExtraDataOptionShutdown;
     107            else
     108                strLastAction = m_strExtraDataOptionPowerOff;
     109            break;
     110        }
     111        case ResultCode_PowerOff_With_Discarding:
     112        {
     113            strLastAction = m_strExtraDataOptionPowerOff + "," +
     114                            m_strExtraDataOptionDiscard;
     115        }
     116        default: break;
     117    }
     118    m_machine.SetExtraData(GUI_LastCloseAction, strLastAction);
     119
     120    /* Hide the dialog: */
     121    hide();
     122}
     123
     124void UIVMCloseDialog::setPixmap(const QPixmap &pixmap)
     125{
     126    /* Make sure pixmap is valid: */
     127    if (pixmap.isNull())
     128        return;
     129
     130    /* Assign new pixmap: */
     131    m_pIcon->setPixmap(pixmap);
     132}
     133
     134void UIVMCloseDialog::setSaveButtonEnabled(bool fEnabled)
     135{
     136    m_pSaveIcon->setEnabled(fEnabled);
     137    m_pSaveRadio->setEnabled(fEnabled);
     138}
     139
     140void UIVMCloseDialog::setSaveButtonVisible(bool fVisible)
     141{
     142    m_pSaveIcon->setVisible(fVisible);
     143    m_pSaveRadio->setVisible(fVisible);
     144}
     145
     146void UIVMCloseDialog::setShutdownButtonEnabled(bool fEnabled)
     147{
     148    m_pShutdownIcon->setEnabled(fEnabled);
     149    m_pShutdownRadio->setEnabled(fEnabled);
     150}
     151
     152void UIVMCloseDialog::setShutdownButtonVisible(bool fVisible)
     153{
     154    m_pShutdownIcon->setVisible(fVisible);
     155    m_pShutdownRadio->setVisible(fVisible);
     156}
     157
     158void UIVMCloseDialog::setPowerOffButtonEnabled(bool fEnabled)
     159{
     160    m_pPowerOffIcon->setEnabled(fEnabled);
     161    m_pPowerOffRadio->setEnabled(fEnabled);
     162}
     163
     164void UIVMCloseDialog::setPowerOffButtonVisible(bool fVisible)
     165{
     166    m_pPowerOffIcon->setVisible(fVisible);
     167    m_pPowerOffRadio->setVisible(fVisible);
     168}
     169
     170void UIVMCloseDialog::setDiscardCheckBoxVisible(bool fVisible)
     171{
     172    m_pDiscardCheckBox->setVisible(fVisible);
     173}
     174
     175void UIVMCloseDialog::prepare()
     176{
     177    /* Prepare 'main' layout: */
     178    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
     179    {
     180        /* Prepare 'top' layout: */
     181        QHBoxLayout *pTopLayout = new QHBoxLayout;
     182        {
     183            /* Prepare 'top-left' layout: */
     184            QVBoxLayout *pTopLeftLayout = new QVBoxLayout;
     185            {
     186                /* Prepare 'icon': */
     187                m_pIcon = new QLabel(this);
     188                {
     189                    /* Configure icon: */
     190                    m_pIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
     191                    m_pIcon->setPixmap(QPixmap(":/os_unknown.png"));
     192                }
     193                /* Configure layout: */
     194                pTopLeftLayout->setSpacing(0);
     195                pTopLeftLayout->setContentsMargins(0, 0, 0, 0);
     196                pTopLeftLayout->addWidget(m_pIcon);
     197                pTopLeftLayout->addStretch();
     198            }
     199            /* Prepare 'top-right' layout: */
     200            QVBoxLayout *pTopRightLayout = new QVBoxLayout;
     201            {
     202                /* Prepare 'text' label: */
     203                m_pLabel = new QLabel(this);
     204                /* Prepare 'choice' layout: */
     205                QGridLayout *pChoiceLayout = new QGridLayout;
     206                {
     207                    /* Prepare 'save' icon: */
     208                    m_pSaveIcon = new QLabel(this);
     209                    {
     210                        /* Configure icon: */
     211                        m_pSaveIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
     212                        m_pSaveIcon->setPixmap(QPixmap(":/state_saved_16px.png"));
     213                    }
     214                    /* Prepare 'save' radio-button: */
     215                    m_pSaveRadio = new QRadioButton(this);
     216                    {
     217                        /* Configure button: */
     218                        connect(m_pSaveRadio, SIGNAL(toggled(bool)), this, SLOT(sltUpdateWidgetAvailability()));
     219                    }
     220                    /* Prepare 'shutdown' icon: */
     221                    m_pShutdownIcon = new QLabel(this);
     222                    {
     223                        /* Configure icon: */
     224                        m_pShutdownIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
     225                        m_pShutdownIcon->setPixmap(QPixmap(":/acpi_16px.png"));
     226                    }
     227                    /* Prepare 'shutdown' radio-button: */
     228                    m_pShutdownRadio = new QRadioButton(this);
     229                    {
     230                        /* Configure button: */
     231                        connect(m_pShutdownRadio, SIGNAL(toggled(bool)), this, SLOT(sltUpdateWidgetAvailability()));
     232                    }
     233                    /* Prepare 'power-off' icon: */
     234                    m_pPowerOffIcon = new QLabel(this);
     235                    {
     236                        /* Configure icon: */
     237                        m_pPowerOffIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
     238                        m_pPowerOffIcon->setPixmap(QPixmap(":/poweroff_16px.png"));
     239                    }
     240                    /* Prepare 'shutdown' radio-button: */
     241                    m_pPowerOffRadio = new QRadioButton(this);
     242                    {
     243                        /* Configure button: */
     244                        connect(m_pPowerOffRadio, SIGNAL(toggled(bool)), this, SLOT(sltUpdateWidgetAvailability()));
     245                    }
     246                    /* Prepare 'discard' check-box: */
     247                    m_pDiscardCheckBox = new QCheckBox(this);
     248                    /* Configure layout: */
     249                    pChoiceLayout->setSpacing(15);
     250                    pChoiceLayout->setContentsMargins(0, 0, 0, 0);
     251                    pChoiceLayout->addWidget(m_pSaveIcon, 0, 0);
     252                    pChoiceLayout->addWidget(m_pSaveRadio, 0, 1);
     253                    pChoiceLayout->addWidget(m_pShutdownIcon, 1, 0);
     254                    pChoiceLayout->addWidget(m_pShutdownRadio, 1, 1);
     255                    pChoiceLayout->addWidget(m_pPowerOffIcon, 2, 0);
     256                    pChoiceLayout->addWidget(m_pPowerOffRadio, 2, 1);
     257                    pChoiceLayout->addWidget(m_pDiscardCheckBox, 3, 1);
     258                }
     259                /* Configure layout: */
     260                pTopRightLayout->setSpacing(15);
     261                pTopRightLayout->setContentsMargins(0, 0, 0, 0);
     262                pTopRightLayout->addWidget(m_pLabel);
     263                pTopRightLayout->addItem(pChoiceLayout);
     264            }
     265            /* Configure layout: */
     266            pTopLayout->setSpacing(20);
     267            pTopLayout->setContentsMargins(0, 0, 0, 0);
     268            pTopLayout->addItem(pTopLeftLayout);
     269            pTopLayout->addItem(pTopRightLayout);
     270        }
     271        /* Button-box: */
     272        QIDialogButtonBox *pButtonBox = new QIDialogButtonBox(this);
     273        {
     274            pButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::NoButton | QDialogButtonBox::Ok);
     275            connect(pButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
     276            connect(pButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
     277            connect(pButtonBox, SIGNAL(helpRequested()), &msgCenter(), SLOT(sltShowHelpHelpDialog()));
     278        }
     279        /* Configure layout: */
     280        pMainLayout->setSpacing(20);
     281        pMainLayout->setContentsMargins(40, 20, 40, 20);
     282        pMainLayout->addItem(pTopLayout);
     283        pMainLayout->addWidget(pButtonBox);
     284    }
     285}
     286
     287void UIVMCloseDialog::configure(const CMachine &machine, const CSession &session)
     288{
     289    /* Assign machine: */
     290    m_machine = machine;
     291
     292    /* Get machine-state: */
     293    KMachineState machineState = m_machine.GetState();
     294
     295    /* Assign pixmap: */
     296    setPixmap(vboxGlobal().vmGuestOSTypeIcon(m_machine.GetOSTypeId()));
     297
     298    /* Check which close-actions are resticted: */
     299    QStringList restictedActionsList = m_machine.GetExtraData(GUI_RestrictedCloseActions).split(',');
     300    bool fIsStateSavingAllowed = !restictedActionsList.contains("SaveState", Qt::CaseInsensitive);
     301    bool fIsACPIShutdownAllowed = !restictedActionsList.contains("Shutdown", Qt::CaseInsensitive);
     302    bool fIsPowerOffAllowed = !restictedActionsList.contains("PowerOff", Qt::CaseInsensitive);
     303    bool fIsPowerOffAndRestoreAllowed = fIsPowerOffAllowed && !restictedActionsList.contains("Restore", Qt::CaseInsensitive);
     304
     305    /* Make 'Save state' button visible/hidden depending on restriction: */
     306    setSaveButtonVisible(fIsStateSavingAllowed);
     307    /* Make 'Save state' button enabled/disabled depending on machine-state: */
     308    setSaveButtonEnabled(machineState != KMachineState_Stuck);
     309    /* Make 'Shutdown button' visible/hidden depending on restriction: */
     310    setShutdownButtonVisible(fIsACPIShutdownAllowed);
     311    /* Make 'Shutdown button' enabled/disabled depending on ACPI-state & machine-state: */
     312    m_fIsACPIEnabled = session.GetConsole().GetGuestEnteredACPIMode();
     313    setShutdownButtonEnabled(m_fIsACPIEnabled && machineState != KMachineState_Stuck);
     314    /* Make 'Power off' button visible/hidden depending on restriction: */
     315    setPowerOffButtonVisible(fIsPowerOffAllowed);
     316    /* Make the Restore Snapshot checkbox visible/hidden depending on snapshot count & restrictions: */
     317    setDiscardCheckBoxVisible(fIsPowerOffAndRestoreAllowed && m_machine.GetSnapshotCount() > 0);
     318    /* Assign Restore Snapshot checkbox text: */
     319    if (!m_machine.GetCurrentSnapshot().isNull())
     320        m_strDiscardCheckBoxText = m_machine.GetCurrentSnapshot().GetName();
     321
     322    /* Read the last user's choice for the given VM: */
     323    QStringList lastAction = m_machine.GetExtraData(GUI_LastCloseAction).split(',');
     324
     325    /* Check which radio-button should be initially chosen: */
     326    QRadioButton *pRadioButtonToChoose = 0;
     327    /* If choosing 'last choice' is possible: */
     328    if (lastAction[0] == m_strExtraDataOptionSave && fIsStateSavingAllowed)
     329    {
     330        pRadioButtonToChoose = m_pSaveRadio;
     331    }
     332    else if (lastAction[0] == m_strExtraDataOptionShutdown && fIsACPIShutdownAllowed && m_fIsACPIEnabled)
     333    {
     334        pRadioButtonToChoose = m_pShutdownRadio;
     335    }
     336    else if (lastAction[0] == m_strExtraDataOptionPowerOff && fIsPowerOffAllowed)
     337    {
     338        pRadioButtonToChoose = m_pPowerOffRadio;
     339        if (fIsPowerOffAndRestoreAllowed)
     340            m_pDiscardCheckBox->setChecked(lastAction.count() > 1 && lastAction[1] == m_strExtraDataOptionDiscard);
     341    }
     342    /* Else 'default choice' will be used: */
     343    else
     344    {
     345        if (fIsACPIShutdownAllowed && m_fIsACPIEnabled)
     346            pRadioButtonToChoose = m_pShutdownRadio;
     347        else if (fIsStateSavingAllowed)
     348            pRadioButtonToChoose = m_pSaveRadio;
     349        else if (fIsPowerOffAllowed)
     350            pRadioButtonToChoose = m_pPowerOffRadio;
     351    }
     352
     353    /* If some radio-button chosen: */
     354    if (pRadioButtonToChoose)
     355    {
     356        /* Check and focus it: */
     357        pRadioButtonToChoose->setChecked(true);
     358        pRadioButtonToChoose->setFocus();
     359        sltUpdateWidgetAvailability();
     360        m_fValid = true;
     361    }
    49362}
    50363
    51364void UIVMCloseDialog::retranslateUi()
    52365{
    53     /* Translate uic generated strings: */
    54     Ui::UIVMCloseDialog::retranslateUi(this);
     366    /* Translate title: */
     367    setWindowTitle(tr("Close Virtual Machine"));
     368
     369    /* Translate 'text' label: */
     370    m_pLabel->setText(tr("You want to:"));
     371
     372    /* Translate radio-buttons: */
     373    m_pSaveRadio->setText(tr("&Save the machine state"));
     374    m_pSaveRadio->setWhatsThis(tr("<p>Saves the current execution state of the virtual machine to the physical hard disk of the host PC.</p>"
     375                                  "<p>Next time this machine is started, it will be restored from the saved state and continue execution "
     376                                  "from the same place you saved it at, which will let you continue your work immediately.</p>"
     377                                  "<p>Note that saving the machine state may take a long time, depending on the guest operating "
     378                                  "system type and the amount of memory you assigned to the virtual machine.</p>"));
     379    m_pShutdownRadio->setText(tr("S&end the shutdown signal"));
     380    m_pShutdownRadio->setWhatsThis(tr("<p>Sends the ACPI Power Button press event to the virtual machine.</p>"
     381                                      "<p>Normally, the guest operating system running inside the virtual machine will detect this event "
     382                                      "and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine "
     383                                      "because all applications running inside it will get a chance to save their data and state.</p>"
     384                                      "<p>If the machine doesn't respond to this action then the guest operating system may be misconfigured "
     385                                      "or doesn't understand ACPI Power Button events at all. In this case you should select the "
     386                                      "<b>Power off the machine</b> action to stop virtual machine execution.</p>"));
     387    m_pPowerOffRadio->setText(tr("&Power off the machine"));
     388    m_pPowerOffRadio->setWhatsThis(tr("<p>Turns off the virtual machine.</p>"
     389                                      "<p>Note that this action will stop machine execution immediately so that the guest operating system "
     390                                      "running inside it will not be able to perform a clean shutdown procedure which may result in "
     391                                      "<i>data loss</i> inside the virtual machine. Selecting this action is recommended only if the "
     392                                      "virtual machine does not respond to the <b>Send the shutdown signal</b> action.</p>"));
     393    m_pDiscardCheckBox->setText(tr("&Restore current snapshot '%1'").arg(m_strDiscardCheckBoxText));
     394    m_pDiscardCheckBox->setToolTip(tr("Restore the machine state stored in the current snapshot"));
     395    m_pDiscardCheckBox->setWhatsThis(tr("<p>When checked, the machine will be returned to the state stored in the current snapshot after "
     396                                        "it is turned off. This is useful if you are sure that you want to discard the results of your "
     397                                        "last sessions and start again at that snapshot.</p>"));
    55398}
    56399
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIVMCloseDialog.h

    r45206 r45212  
    2323#include "QIDialog.h"
    2424#include "QIWithRetranslateUI.h"
    25 #include "UIVMCloseDialog.gen.h"
     25
     26/* COM includes: */
     27#include "COMEnums.h"
     28#include "CMachine.h"
     29
     30/* Forward declarations: */
     31class CSession;
     32class QLabel;
     33class QRadioButton;
     34class QCheckBox;
    2635
    2736/* QIDialog extension to handle Runtime UI close-event: */
    28 class UIVMCloseDialog : public QIWithRetranslateUI<QIDialog>,
    29                         public Ui::UIVMCloseDialog
     37class UIVMCloseDialog : public QIWithRetranslateUI<QIDialog>
    3038{
    3139    Q_OBJECT;
     
    3341public:
    3442
     43    /* Dialog result-code enumerator: */
     44    enum ResultCode
     45    {
     46        ResultCode_Cancel = 0,
     47        ResultCode_Save,
     48        ResultCode_Shutdown,
     49        ResultCode_PowerOff,
     50        ResultCode_PowerOff_With_Discarding
     51    };
     52
    3553    /* Constructor: */
    36     UIVMCloseDialog(QWidget *pParent);
     54    UIVMCloseDialog(QWidget *pParent, const CMachine &machine, const CSession &session);
     55
     56    /* API: Validation stuff: */
     57    bool isValid() const { return m_fValid; }
     58
     59private slots:
     60
     61    /* Handler: Update stuff: */
     62    void sltUpdateWidgetAvailability();
     63
     64    /* Handler: Accept stuff: */
     65    void accept();
    3766
    3867private:
     68
     69    /* API: Pixmap stuff: */
     70    void setPixmap(const QPixmap &pixmap);
     71
     72    /* API: Save-button stuff: */
     73    void setSaveButtonEnabled(bool fEnabled);
     74    void setSaveButtonVisible(bool fVisible);
     75    /* API: Shutdown-button stuff: */
     76    void setShutdownButtonEnabled(bool fEnabled);
     77    void setShutdownButtonVisible(bool fVisible);
     78    /* API: Power-off-button stuff: */
     79    void setPowerOffButtonEnabled(bool fEnabled);
     80    void setPowerOffButtonVisible(bool fVisible);
     81    /* API: Discard-check-box stuff: */
     82    void setDiscardCheckBoxVisible(bool fVisible);
     83
     84    /* Helpers: Prepare stuff: */
     85    void prepare();
     86    void configure(const CMachine &machine, const CSession &session);
    3987
    4088    /* Helper: Translate stuff: */
     
    4391    /* Handler: Polish-event stuff: */
    4492    void polishEvent(QShowEvent *pEvent);
     93
     94    /* Widgets: */
     95    QLabel *m_pIcon;
     96    QLabel *m_pLabel;
     97    QLabel *m_pSaveIcon;
     98    QRadioButton *m_pSaveRadio;
     99    QLabel *m_pShutdownIcon;
     100    QRadioButton *m_pShutdownRadio;
     101    QLabel *m_pPowerOffIcon;
     102    QRadioButton *m_pPowerOffRadio;
     103    QCheckBox *m_pDiscardCheckBox;
     104
     105    /* Variables: */
     106    const QString m_strExtraDataOptionSave;
     107    const QString m_strExtraDataOptionShutdown;
     108    const QString m_strExtraDataOptionPowerOff;
     109    const QString m_strExtraDataOptionDiscard;
     110    bool m_fValid;
     111    CMachine m_machine;
     112    bool m_fIsACPIEnabled;
     113    QString m_strDiscardCheckBoxText;
    45114};
    46115
Note: See TracChangeset for help on using the changeset viewer.

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