VirtualBox

Ignore:
Timestamp:
Mar 22, 2010 6:34:46 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
59154
Message:

FE/Qt4: 4675: Allow predefined shutdown dialog action (new core only).

Location:
trunk/src/VBox/Frontends/VirtualBox/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.cpp

    r27335 r27609  
    3939const char* VBoxDefs::GUI_MiniToolBarAutoHide = "GUI/MiniToolBarAutoHide";
    4040const char* VBoxDefs::GUI_LastCloseAction = "GUI/LastCloseAction";
     41const char* VBoxDefs::GUI_RestrictedCloseActions = "GUI/RestrictedCloseActions";
    4142const char* VBoxDefs::GUI_SuppressMessages = "GUI/SuppressMessages";
    4243const char* VBoxDefs::GUI_PermanentSharedFoldersAtRuntime = "GUI/PermanentSharedFoldersAtRuntime";
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.h

    r27335 r27609  
    157157    static const char* GUI_MiniToolBarAutoHide;
    158158    static const char* GUI_LastCloseAction;
     159    static const char* GUI_RestrictedCloseActions;
    159160    static const char* GUI_SuppressMessages;
    160161    static const char* GUI_PermanentSharedFoldersAtRuntime;
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp

    r27374 r27609  
    145145        case KMachineState_TeleportingPausedVM: // TODO: Test this!
    146146        {
     147            /* Get the machine: */
     148            CMachine machine = session().GetMachine();
     149
     150            /* Prepare close dialog: */
     151            VBoxCloseVMDlg dlg(machineWindow());
     152
     153            /* Assign close-dialog pixmap: */
     154            dlg.pmIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(machine.GetOSTypeId()));
     155
     156            /* Check which close actions are disallowed: */
     157            QStringList restictedActionsList = machine.GetExtraData(VBoxDefs::GUI_RestrictedCloseActions).split(',');
     158            bool fIsStateSavingAllowed = !restictedActionsList.contains("SaveState", Qt::CaseInsensitive);
     159            bool fIsACPIShutdownAllowed = !restictedActionsList.contains("Shutdown", Qt::CaseInsensitive);
     160            bool fIsPowerOffAllowed = (uisession()->machineState() == KMachineState_Stuck) ||
     161                                      (!restictedActionsList.contains("PowerOff", Qt::CaseInsensitive));
     162            bool fIsPowerOffAndRestoreAllowed = fIsPowerOffAllowed && restictedActionsList.contains("Restore", Qt::CaseInsensitive);
     163
     164            /* Make Save State button visible/hidden depending on restriction: */
     165            dlg.mRbSave->setVisible(fIsStateSavingAllowed);
     166            dlg.mTxSave->setVisible(fIsStateSavingAllowed);
     167            /* Make Save State button enabled/disabled depending on machine state: */
     168            dlg.mRbSave->setEnabled(uisession()->machineState() != KMachineState_Stuck);
     169
     170            /* Make ACPI shutdown button visible/hidden depending on restriction: */
     171            dlg.mRbShutdown->setVisible(fIsACPIShutdownAllowed);
     172            dlg.mTxShutdown->setVisible(fIsACPIShutdownAllowed);
     173            /* Make ACPI shutdown button enabled/disabled depending on ACPI state & machine state: */
     174            bool isACPIEnabled = session().GetConsole().GetGuestEnteredACPIMode();
     175            dlg.mRbShutdown->setEnabled(isACPIEnabled && uisession()->machineState() != KMachineState_Stuck);
     176
     177            /* Make Power Off button visible/hidden depending on restriction: */
     178            dlg.mRbPowerOff->setVisible(fIsPowerOffAllowed);
     179            dlg.mTxPowerOff->setVisible(fIsPowerOffAllowed);
     180
     181            /* Make the Restore Snapshot checkbox visible/hidden depending on snapshots count & restrictions: */
     182            dlg.mCbDiscardCurState->setVisible(fIsPowerOffAndRestoreAllowed && machine.GetSnapshotCount() > 0);
     183            if (!machine.GetCurrentSnapshot().isNull())
     184                dlg.mCbDiscardCurState->setText(dlg.mCbDiscardCurState->text().arg(machine.GetCurrentSnapshot().GetName()));
     185
     186            /* Choice string tags for close-dialog: */
     187            QString strSave("save");
     188            QString strShutdown("shutdown");
     189            QString strPowerOff("powerOff");
     190            QString strDiscardCurState("discardCurState");
     191
     192            /* Read the last user's choice for the given VM: */
     193            QStringList lastAction = machine.GetExtraData(VBoxDefs::GUI_LastCloseAction).split(',');
     194
     195            /* Check which button should be initially chosen: */
     196            QRadioButton *pRadioButton = 0;
     197
     198            /* If chosing 'last choice' is possible: */
     199            if (lastAction[0] == strSave && fIsStateSavingAllowed)
     200            {
     201                pRadioButton = dlg.mRbSave;
     202            }
     203            else if (lastAction[0] == strShutdown && fIsACPIShutdownAllowed && isACPIEnabled)
     204            {
     205                pRadioButton = dlg.mRbShutdown;
     206            }
     207            else if (lastAction[0] == strPowerOff && fIsPowerOffAllowed)
     208            {
     209                pRadioButton = dlg.mRbPowerOff;
     210                if (fIsPowerOffAndRestoreAllowed)
     211                    dlg.mCbDiscardCurState->setChecked(lastAction.count() > 1 && lastAction[1] == strDiscardCurState);
     212            }
     213            /* Else 'default choice' will be used: */
     214            else
     215            {
     216                if (fIsACPIShutdownAllowed && isACPIEnabled)
     217                    pRadioButton = dlg.mRbShutdown;
     218                else if (fIsPowerOffAllowed)
     219                    pRadioButton = dlg.mRbPowerOff;
     220                else if (fIsStateSavingAllowed)
     221                    pRadioButton = dlg.mRbSave;
     222            }
     223
     224            /* If some radio button was chosen: */
     225            if (pRadioButton)
     226            {
     227                /* Check and focus it: */
     228                pRadioButton->setChecked(true);
     229                pRadioButton->setFocus();
     230            }
     231            /* If no one of radio buttons was chosen: */
     232            else
     233            {
     234                /* Just break and leave: */
     235                break;
     236            }
     237
     238            /* This flag will keep the status of every further logical operation: */
    147239            bool success = true;
    148240
    149             /* Get the ACPI status early before pausing VM: */
    150             bool isACPIEnabled = session().GetConsole().GetGuestEnteredACPIMode();
    151 
     241            /* Pause before showing dialog if necessary: */
    152242            bool fWasPaused = uisession()->isPaused() || uisession()->machineState() == KMachineState_Stuck;
    153243            if (!fWasPaused)
    154             {
    155                 /* Suspend the VM and ignore the close event if failed to do so.
    156                  * pause() will show the error message to the user: */
    157244                success = uisession()->pause();
    158             }
    159245
    160246            if (success)
    161247            {
    162                 success = false;
    163 
    164                 /* Preventing closure right after we had paused: */
     248                /* Preventing auto-closure: */
    165249                machineLogic()->setPreventAutoClose(true);
    166 
    167                 /* Get the machine: */
    168                 CMachine machine = session().GetMachine();
    169 
    170                 /* Prepare close dialog: */
    171                 VBoxCloseVMDlg dlg(machineWindow());
    172                 QString typeId = machine.GetOSTypeId();
    173                 dlg.pmIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(typeId));
    174 
    175                 /* Make the discard checkbox invisible if there are no snapshots: */
    176                 dlg.mCbDiscardCurState->setVisible(machine.GetSnapshotCount() > 0);
    177                 if (!machine.GetCurrentSnapshot().isNull())
    178                     dlg.mCbDiscardCurState->setText(dlg.mCbDiscardCurState->text().arg(machine.GetCurrentSnapshot().GetName()));
    179 
    180                 /* Choice string tags for close-dialog: */
    181                 QString strSave("save");
    182                 QString strShutdown("shutdown");
    183                 QString strPowerOff("powerOff");
    184                 QString strDiscardCurState("discardCurState");
    185 
    186                 if (uisession()->machineState() != KMachineState_Stuck)
    187                 {
    188                     /* Read the last user's choice for the given VM: */
    189                     QStringList lastAction = machine.GetExtraData(VBoxDefs::GUI_LastCloseAction).split(',');
    190                     AssertWrapperOk(machine);
    191                     if (lastAction[0] == strSave)
    192                     {
    193                         dlg.mRbShutdown->setEnabled(isACPIEnabled);
    194                         dlg.mRbSave->setChecked(true);
    195                         dlg.mRbSave->setFocus();
    196                     }
    197                     else if (lastAction[0] == strPowerOff || !isACPIEnabled)
    198                     {
    199                         dlg.mRbShutdown->setEnabled(isACPIEnabled);
    200                         dlg.mRbPowerOff->setChecked(true);
    201                         dlg.mRbPowerOff->setFocus();
    202                     }
    203                     else /* The default is ACPI Shutdown: */
    204                     {
    205                         dlg.mRbShutdown->setChecked(true);
    206                         dlg.mRbShutdown->setFocus();
    207                     }
    208                     dlg.mCbDiscardCurState->setChecked(lastAction.count() > 1 && lastAction [1] == strDiscardCurState);
    209                 }
    210                 else
    211                 {
    212                     /* The stuck VM can only be powered off; disable anything else and choose PowerOff: */
    213                     dlg.mRbSave->setEnabled(false);
    214                     dlg.mRbShutdown->setEnabled(false);
    215                     dlg.mRbPowerOff->setChecked(true);
    216                 }
    217 
    218                 bool fWasShutdown = false;
    219250
    220251                /* If close dialog accepted: */
    221252                if (dlg.exec() == QDialog::Accepted)
    222253                {
     254                    /* Get current console: */
    223255                    CConsole console = session().GetConsole();
     256
     257                    success = false;
    224258
    225259                    if (dlg.mRbSave->isChecked())
     
    227261                        CProgress progress = console.SaveState();
    228262
    229                         if (console.isOk())
     263                        if (!console.isOk())
     264                            vboxProblem().cannotSaveMachineState(console);
     265                        else
    230266                        {
    231267                            /* Show the "VM saving" progress dialog: */
     
    236272                                success = true;
    237273                        }
    238                         else
    239                             vboxProblem().cannotSaveMachineState(console);
     274
     275                        if (success)
     276                            fCloseApplication = true;
    240277                    }
    241278                    else if (dlg.mRbShutdown->isChecked())
     
    247284                        /* Signal ACPI shutdown (if there is no ACPI device, the operation will fail): */
    248285                        console.PowerButton();
    249                         fWasShutdown = console.isOk();
    250                         if (!fWasShutdown)
     286                        if (!console.isOk())
    251287                            vboxProblem().cannotACPIShutdownMachine(console);
    252                         /* Success is always false because we never accept the close
    253                          * window action when doing ACPI shutdown: */
    254                         success = false;
     288                        else
     289                            success = true;
    255290                    }
    256291                    else if (dlg.mRbPowerOff->isChecked())
     
    258293                        CProgress progress = console.PowerDown();
    259294
    260                         if (console.isOk())
     295                        if (!console.isOk())
     296                            vboxProblem().cannotStopMachine(console);
     297                        else
    261298                        {
    262299                            /* Show the power down progress dialog: */
     
    267304                                success = true;
    268305                        }
    269                         else
    270                             vboxProblem().cannotStopMachine(console);
    271306
    272307                        if (success)
     
    275310                            if (dlg.mCbDiscardCurState->isChecked() && dlg.mCbDiscardCurState->isVisibleTo(&dlg))
    276311                            {
     312                                success = false;
    277313                                CSnapshot snapshot = machine.GetCurrentSnapshot();
    278314                                CProgress progress = console.RestoreSnapshot(snapshot);
    279                                 if (console.isOk())
     315                                if (!console.isOk())
     316                                    vboxProblem().cannotRestoreSnapshot(console, snapshot.GetName());
     317                                else
    280318                                {
    281319                                    /* Show the progress dialog: */
     
    283321                                    if (progress.GetResultCode() != 0)
    284322                                        vboxProblem().cannotRestoreSnapshot(progress, snapshot.GetName());
     323                                    else
     324                                        success = true;
    285325                                }
    286                                 else
    287                                     vboxProblem().cannotRestoreSnapshot(console, snapshot.GetName());
    288326                            }
    289327                        }
     328
     329                        if (success)
     330                            fCloseApplication = true;
    290331                    }
    291332
    292                     if (success || fWasShutdown)
     333                    if (success)
    293334                    {
    294335                        /* Read the last user's choice for the given VM: */
     
    298339                        if (dlg.mRbSave->isChecked())
    299340                            lastAction = strSave;
    300                         else if (dlg.mRbShutdown->isChecked() ||
    301                                  (dlg.mRbPowerOff->isChecked() && prevAction [0] == strShutdown && !isACPIEnabled))
     341                        else if ((dlg.mRbShutdown->isChecked()) ||
     342                                 (dlg.mRbPowerOff->isChecked() && prevAction[0] == strShutdown && !isACPIEnabled))
    302343                            lastAction = strShutdown;
    303344                        else if (dlg.mRbPowerOff->isChecked())
     
    307348                        if (dlg.mCbDiscardCurState->isChecked())
    308349                            (lastAction += ",") += strDiscardCurState;
    309                         machine.SetExtraData (VBoxDefs::GUI_LastCloseAction, lastAction);
     350                        machine.SetExtraData(VBoxDefs::GUI_LastCloseAction, lastAction);
    310351                        AssertWrapperOk(machine);
    311352                    }
    312 
    313                     fCloseApplication = success;
    314353                }
    315             }
    316 
    317             if (!success)
    318             {
     354
    319355                /* Restore the running state if needed: */
    320                 if (!fWasPaused && uisession()->machineState() == KMachineState_Paused)
     356                if (success && !fCloseApplication && !fWasPaused && uisession()->machineState() == KMachineState_Paused)
    321357                    uisession()->unpause();
    322             }
     358
     359                /* Allowing auto-closure: */
     360                machineLogic()->setPreventAutoClose(false);
     361            }
     362
    323363            break;
    324364        }
     
    327367            break;
    328368    }
    329 
    330     /* Allowing closure: */
    331     machineLogic()->setPreventAutoClose(false);
    332369
    333370    if (fCloseApplication)
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