- Timestamp:
- Feb 28, 2010 5:41:34 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp
r26890 r26892 130 130 void UIMachineWindow::closeEvent(QCloseEvent *pEvent) 131 131 { 132 static const char *pstrSave = "save";133 static const char *pstrShutdown = "shutdown";134 static const char *pstrPowerOff = "powerOff";135 static const char *pstrDiscardCurState = "discardCurState";136 137 if (!machineWindow())138 {139 pEvent->accept();140 return;141 }142 143 132 switch (uisession()->machineState()) 144 133 { 145 case KMachineState_PoweredOff:146 case KMachineState_Saved:147 case KMachineState_Teleported:148 case KMachineState_Aborted:149 /* The machine has been already powered off or saved or aborted -- close the window immediately. */150 pEvent->accept();151 break;152 153 default:154 /* The machine is in some temporary state like Saving or Stopping.155 * Ignore the close event. When it is Stopping, it will be soon closed anyway from sltUpdatmachineState().156 * In all other cases, an appropriate progress dialog will be shown within a few seconds. */157 pEvent->ignore();158 break;159 160 case KMachineState_Teleporting: /** @todo Live Migration: Test closing a VM that's being teleported or snapshotted. */161 case KMachineState_LiveSnapshotting:162 134 case KMachineState_Running: 163 135 case KMachineState_Paused: 164 case KMachineState_TeleportingPausedVM: /** @todo Live Migration: Check out this. */165 136 case KMachineState_Stuck: 166 /* Start with ignoring the close event */ 137 case KMachineState_LiveSnapshotting: 138 case KMachineState_Teleporting: // TODO: Test this! 139 case KMachineState_TeleportingPausedVM: // TODO: Test this! 140 { 141 /* Ignoring close event initially: */ 167 142 pEvent->ignore(); 168 143 169 bool isACPIEnabled = session().GetConsole().GetGuestEnteredACPIMode();170 171 144 bool success = true; 172 145 173 bool wasPaused = uisession()->isPaused() || uisession()->machineState() == KMachineState_Stuck;174 if (! wasPaused)146 bool fWasPaused = uisession()->isPaused() || uisession()->machineState() == KMachineState_Stuck; 147 if (!fWasPaused) 175 148 { 176 149 /* Suspend the VM and ignore the close event if failed to do so. 177 * pause() will show the error message to the user .*/150 * pause() will show the error message to the user: */ 178 151 success = uisession()->pause(); 179 152 } … … 183 156 success = false; 184 157 158 /* Get the machine: */ 185 159 CMachine machine = session().GetMachine(); 160 161 /* Get the ACPI status: */ 162 bool isACPIEnabled = session().GetConsole().GetGuestEnteredACPIMode(); 163 164 /* Prepare close dialog: */ 186 165 VBoxCloseVMDlg dlg(machineWindow()); 187 166 QString typeId = machine.GetOSTypeId(); 188 167 dlg.pmIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(typeId)); 189 168 190 /* Make the Discard checkbox invisible if there are no snapshots*/169 /* Make the discard checkbox invisible if there are no snapshots: */ 191 170 dlg.mCbDiscardCurState->setVisible(machine.GetSnapshotCount() > 0); 192 171 if (!machine.GetCurrentSnapshot().isNull()) 193 172 dlg.mCbDiscardCurState->setText(dlg.mCbDiscardCurState->text().arg(machine.GetCurrentSnapshot().GetName())); 194 173 174 /* Close choice string tags: */ 175 QString strSave("save"); 176 QString strShutdown("shutdown"); 177 QString strPowerOff("powerOff"); 178 QString strDiscardCurState("discardCurState"); 179 195 180 if (uisession()->machineState() != KMachineState_Stuck) 196 181 { 197 /* Read the last user's choice for the given VM */182 /* Read the last user's choice for the given VM: */ 198 183 QStringList lastAction = machine.GetExtraData(VBoxDefs::GUI_LastCloseAction).split(','); 199 184 AssertWrapperOk(machine); 200 if (lastAction[0] == pstrSave)185 if (lastAction[0] == strSave) 201 186 { 202 187 dlg.mRbShutdown->setEnabled(isACPIEnabled); … … 204 189 dlg.mRbSave->setFocus(); 205 190 } 206 else if (lastAction[0] == pstrPowerOff || !isACPIEnabled)191 else if (lastAction[0] == strPowerOff || !isACPIEnabled) 207 192 { 208 193 dlg.mRbShutdown->setEnabled(isACPIEnabled); … … 210 195 dlg.mRbPowerOff->setFocus(); 211 196 } 212 else /* The default is ACPI Shutdown */197 else /* The default is ACPI Shutdown: */ 213 198 { 214 199 dlg.mRbShutdown->setChecked(true); 215 200 dlg.mRbShutdown->setFocus(); 216 201 } 217 dlg.mCbDiscardCurState->setChecked(lastAction.count() > 1 && lastAction [1] == pstrDiscardCurState);202 dlg.mCbDiscardCurState->setChecked(lastAction.count() > 1 && lastAction [1] == strDiscardCurState); 218 203 } 219 204 else 220 205 { 221 /* The stuck VM can only be powered off; disable anything else and choose PowerOff */206 /* The stuck VM can only be powered off; disable anything else and choose PowerOff: */ 222 207 dlg.mRbSave->setEnabled(false); 223 208 dlg.mRbShutdown->setEnabled(false); … … 225 210 } 226 211 227 bool wasShutdown = false; 228 212 bool fWasShutdown = false; 213 214 /* If close dialog accepted: */ 229 215 if (dlg.exec() == QDialog::Accepted) 230 216 { 231 /* Disable auto closure because we want to have a chance to show232 * the error dialog on save state / power off failure. */233 machineLogic()->setPreventAutoClose(true);234 235 217 CConsole console = session().GetConsole(); 236 218 … … 241 223 if (console.isOk()) 242 224 { 243 /* Show the "VM saving" progress dialog */225 /* Show the "VM saving" progress dialog: */ 244 226 vboxProblem().showModalProgressDialog(progress, machine.GetName(), 0, 0); 245 227 if (progress.GetResultCode() != 0) … … 253 235 else if (dlg.mRbShutdown->isChecked()) 254 236 { 255 /* Unpause the VM to let it grab the ACPI shutdown event */237 /* Unpause the VM to let it grab the ACPI shutdown event: */ 256 238 uisession()->unpause(); 257 /* Prevent the subsequent unpause request */ 258 wasPaused = true; 259 /* Signal ACPI shutdown (if there is no ACPI device, the 260 * operation will fail) */ 239 /* Prevent the subsequent unpause request: */ 240 fWasPaused = true; 241 /* Signal ACPI shutdown (if there is no ACPI device, the operation will fail): */ 261 242 console.PowerButton(); 262 wasShutdown = console.isOk();263 if (! wasShutdown)243 fWasShutdown = console.isOk(); 244 if (!fWasShutdown) 264 245 vboxProblem().cannotACPIShutdownMachine(console); 265 246 /* Success is always false because we never accept the close 266 * window action when doing ACPI shutdown */247 * window action when doing ACPI shutdown: */ 267 248 success = false; 268 249 } … … 273 254 if (console.isOk()) 274 255 { 275 /* Show the power down progress dialog */256 /* Show the power down progress dialog: */ 276 257 vboxProblem().showModalProgressDialog(progress, machine.GetName(), 0); 277 258 if (progress.GetResultCode() != 0) … … 285 266 if (success) 286 267 { 287 /* Note: leave success = true even if we fail to 288 * discard the current state later -- the console window 289 * will closed anyway */ 290 291 /* Discard the current state if requested */ 268 /* Discard the current state if requested: */ 292 269 if (dlg.mCbDiscardCurState->isChecked() && dlg.mCbDiscardCurState->isVisibleTo(&dlg)) 293 270 { … … 296 273 if (console.isOk()) 297 274 { 298 /* Show the progress dialog */275 /* Show the progress dialog: */ 299 276 vboxProblem().showModalProgressDialog(progress, machine.GetName(), 0); 300 277 if (progress.GetResultCode() != 0) … … 309 286 if (success) 310 287 { 311 /* Accept the close action on success */288 /* Accept the close action on success: */ 312 289 pEvent->accept(); 313 290 } 314 291 315 if (success || wasShutdown)316 { 317 /* Read the last user's choice for the given VM */292 if (success || fWasShutdown) 293 { 294 /* Read the last user's choice for the given VM: */ 318 295 QStringList prevAction = machine.GetExtraData(VBoxDefs::GUI_LastCloseAction).split(','); 319 /* Memorize the last user's choice for the given VM */320 QString lastAction = pstrPowerOff;296 /* Memorize the last user's choice for the given VM: */ 297 QString lastAction = strPowerOff; 321 298 if (dlg.mRbSave->isChecked()) 322 lastAction = pstrSave;299 lastAction = strSave; 323 300 else if (dlg.mRbShutdown->isChecked() || 324 (dlg.mRbPowerOff->isChecked() && prevAction [0] == pstrShutdown && !isACPIEnabled))325 lastAction = pstrShutdown;301 (dlg.mRbPowerOff->isChecked() && prevAction [0] == strShutdown && !isACPIEnabled)) 302 lastAction = strShutdown; 326 303 else if (dlg.mRbPowerOff->isChecked()) 327 lastAction = pstrPowerOff;304 lastAction = strPowerOff; 328 305 else 329 306 AssertFailed(); 330 307 if (dlg.mCbDiscardCurState->isChecked()) 331 (lastAction += ",") += pstrDiscardCurState;308 (lastAction += ",") += strDiscardCurState; 332 309 machine.SetExtraData (VBoxDefs::GUI_LastCloseAction, lastAction); 333 310 AssertWrapperOk(machine); … … 335 312 } 336 313 } 337 338 machineLogic()->setPreventAutoClose(false);339 314 340 315 if (uisession()->machineState() == KMachineState_PoweredOff || … … 344 319 { 345 320 /* The machine has been stopped while showing the Close or the Pause 346 * failure dialog - - accept the close event immediately.*/321 * failure dialog - accept the close event immediately: */ 347 322 pEvent->accept(); 348 323 } … … 351 326 if (!success) 352 327 { 353 /* Restore the running state if needed */354 if (! wasPaused && uisession()->machineState() == KMachineState_Paused)328 /* Restore the running state if needed: */ 329 if (!fWasPaused && uisession()->machineState() == KMachineState_Paused) 355 330 uisession()->unpause(); 356 331 } 357 332 } 358 333 break; 334 } 335 336 #if 0 // TODO: Check if all those states processing is really needed: 337 case KMachineState_PoweredOff: 338 case KMachineState_Saved: 339 case KMachineState_Teleported: 340 case KMachineState_Aborted: 341 { 342 /* The machine has been already powered off or saved or aborted - close the window immediately: */ 343 pEvent->accept(); 344 break; 345 } 346 #endif 347 348 default: 349 { 350 /* The machine is in some temporary state like Saving or Stopping. 351 * Ignore the close event. It will be processed later if something will be failed: */ 352 pEvent->ignore(); 353 break; 354 } 359 355 } 360 356 357 /* Postprocess event if accepted: */ 361 358 if (pEvent->isAccepted()) 362 359 { … … 371 368 #endif 372 369 373 /* Make sure all events are delievered */ 374 qApp->processEvents(); 375 376 /* Notify all the top-level dialogs about closing */ 370 /* Notify all the top-level child dialogs about closing: */ 377 371 // TODO: Notify about closing! 378 372 //emit closing();
Note:
See TracChangeset
for help on using the changeset viewer.