VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachine.cpp@ 82781

Last change on this file since 82781 was 80932, checked in by vboxsync, 5 years ago

FE/Qt: bugref:8472: Proper comments for different cases of medium-enumeration calls.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.0 KB
Line 
1/* $Id: UIMachine.cpp 80932 2019-09-22 10:54:36Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachine class implementation.
4 */
5
6/*
7 * Copyright (C) 2010-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/* GUI includes: */
19#include "UICommon.h"
20#include "UIExtraDataManager.h"
21#include "UIMachine.h"
22#include "UISession.h"
23#include "UIActionPoolRuntime.h"
24#include "UIMachineLogic.h"
25#include "UIMachineWindow.h"
26#include "UIMessageCenter.h"
27
28/* COM includes: */
29#include "CMachine.h"
30#include "CSession.h"
31#include "CConsole.h"
32#include "CSnapshot.h"
33#include "CProgress.h"
34
35
36/* static */
37UIMachine *UIMachine::m_spInstance = 0;
38
39/* static */
40bool UIMachine::startMachine(const QUuid &uID)
41{
42 /* Make sure machine is not created: */
43 AssertReturn(!m_spInstance, false);
44
45 /* Restore current snapshot if requested: */
46 if (uiCommon().shouldRestoreCurrentSnapshot())
47 {
48 /* Create temporary session: */
49 CSession session = uiCommon().openSession(uID, KLockType_VM);
50 if (session.isNull())
51 return false;
52
53 /* Which VM we operate on? */
54 CMachine machine = session.GetMachine();
55 /* Which snapshot we are restoring? */
56 CSnapshot snapshot = machine.GetCurrentSnapshot();
57
58 /* Prepare restore-snapshot progress: */
59 CProgress progress = machine.RestoreSnapshot(snapshot);
60 if (!machine.isOk())
61 return msgCenter().cannotRestoreSnapshot(machine, snapshot.GetName(), machine.GetName());
62
63 /* Show the snapshot-discarding progress: */
64 msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_snapshot_discard_90px.png");
65 if (progress.GetResultCode() != 0)
66 return msgCenter().cannotRestoreSnapshot(progress, snapshot.GetName(), machine.GetName());
67
68 /* Unlock session finally: */
69 session.UnlockMachine();
70
71 /* Clear snapshot-restoring request: */
72 uiCommon().setShouldRestoreCurrentSnapshot(false);
73 }
74
75 /* For separate process we should launch VM before UI: */
76 if (uiCommon().isSeparateProcess())
77 {
78 /* Get corresponding machine: */
79 CMachine machine = uiCommon().virtualBox().FindMachine(uiCommon().managedVMUuid().toString());
80 AssertMsgReturn(!machine.isNull(), ("UICommon::managedVMUuid() should have filter that case before!\n"), false);
81
82 /* Try to launch corresponding machine: */
83 if (!uiCommon().launchMachine(machine, UICommon::LaunchMode_Separate))
84 return false;
85 }
86
87 /* Try to create machine UI: */
88 return create();
89}
90
91/* static */
92bool UIMachine::create()
93{
94 /* Make sure machine is not created: */
95 AssertReturn(!m_spInstance, false);
96
97 /* Create machine UI: */
98 new UIMachine;
99 /* Make sure it's prepared: */
100 if (!m_spInstance->prepare())
101 {
102 /* Destroy machine UI otherwise: */
103 destroy();
104 /* False in that case: */
105 return false;
106 }
107 /* True by default: */
108 return true;
109}
110
111/* static */
112void UIMachine::destroy()
113{
114 /* Make sure machine is created: */
115 if (!m_spInstance)
116 return;
117
118 /* Protect versus recursive call: */
119 UIMachine *pInstance = m_spInstance;
120 m_spInstance = 0;
121 /* Cleanup machine UI: */
122 pInstance->cleanup();
123 /* Destroy machine UI: */
124 delete pInstance;
125}
126
127QWidget* UIMachine::activeWindow() const
128{
129 return machineLogic() && machineLogic()->activeMachineWindow()
130 ? machineLogic()->activeMachineWindow()
131 : 0;
132}
133
134void UIMachine::asyncChangeVisualState(UIVisualStateType visualState)
135{
136 emit sigRequestAsyncVisualStateChange(visualState);
137}
138
139void UIMachine::closeRuntimeUI()
140{
141 /* Quit application: */
142 QApplication::quit();
143}
144
145void UIMachine::sltChangeVisualState(UIVisualStateType visualState)
146{
147 /* Create new machine-logic: */
148 UIMachineLogic *pMachineLogic = UIMachineLogic::create(this, m_pSession, visualState);
149
150 /* First we have to check if the selected machine-logic is available at all.
151 * Only then we delete the old machine-logic and switch to the new one. */
152 if (pMachineLogic->checkAvailability())
153 {
154 /* Delete previous machine-logic if exists: */
155 if (m_pMachineLogic)
156 {
157 m_pMachineLogic->cleanup();
158 UIMachineLogic::destroy(m_pMachineLogic);
159 m_pMachineLogic = 0;
160 }
161
162 /* Set the new machine-logic as current one: */
163 m_pMachineLogic = pMachineLogic;
164 m_pMachineLogic->prepare();
165
166 /* Remember new visual state: */
167 m_visualState = visualState;
168 }
169 else
170 {
171 /* Delete temporary created machine-logic: */
172 pMachineLogic->cleanup();
173 UIMachineLogic::destroy(pMachineLogic);
174 }
175
176 /* Make sure machine-logic exists: */
177 if (!m_pMachineLogic)
178 {
179 /* Reset initial visual state to normal: */
180 m_initialVisualState = UIVisualStateType_Normal;
181 /* Enter initial visual state again: */
182 enterInitialVisualState();
183 }
184}
185
186UIMachine::UIMachine()
187 : QObject(0)
188 , m_pSession(0)
189 , m_allowedVisualStates(UIVisualStateType_Invalid)
190 , m_initialVisualState(UIVisualStateType_Normal)
191 , m_visualState(UIVisualStateType_Invalid)
192 , m_pMachineLogic(0)
193{
194 m_spInstance = this;
195}
196
197UIMachine::~UIMachine()
198{
199 m_spInstance = 0;
200}
201
202bool UIMachine::prepare()
203{
204 /* Try to prepare session UI: */
205 if (!prepareSession())
206 return false;
207
208 /* Cache media data early if necessary: */
209 if (uiCommon().agressiveCaching())
210 {
211 AssertReturn(m_pSession, false);
212 uiCommon().enumerateMedia(m_pSession->machineMedia());
213 }
214
215 /* Prepare machine-logic: */
216 prepareMachineLogic();
217
218 /* Try to initialize session UI: */
219 if (!uisession()->initialize())
220 return false;
221
222 /* True by default: */
223 return true;
224}
225
226bool UIMachine::prepareSession()
227{
228 /* Try to create session UI: */
229 if (!UISession::create(m_pSession, this))
230 return false;
231
232 /* True by default: */
233 return true;
234}
235
236void UIMachine::prepareMachineLogic()
237{
238 /* Prepare async visual state type change handler: */
239 qRegisterMetaType<UIVisualStateType>();
240 connect(this, &UIMachine::sigRequestAsyncVisualStateChange,
241 this, &UIMachine::sltChangeVisualState,
242 Qt::QueuedConnection);
243
244 /* Load restricted visual states: */
245 UIVisualStateType restrictedVisualStates = gEDataManager->restrictedVisualStates(uiCommon().managedVMUuid());
246 /* Acquire allowed visual states: */
247 m_allowedVisualStates = static_cast<UIVisualStateType>(UIVisualStateType_All ^ restrictedVisualStates);
248
249 /* Load requested visual state: */
250 UIVisualStateType requestedVisualState = gEDataManager->requestedVisualState(uiCommon().managedVMUuid());
251 /* Check if requested visual state is allowed: */
252 if (isVisualStateAllowed(requestedVisualState))
253 {
254 switch (requestedVisualState)
255 {
256 /* Direct transition to scale/fullscreen mode allowed: */
257 case UIVisualStateType_Scale: m_initialVisualState = UIVisualStateType_Scale; break;
258 case UIVisualStateType_Fullscreen: m_initialVisualState = UIVisualStateType_Fullscreen; break;
259 /* While to seamless is not, so we have to make request to do transition later: */
260 case UIVisualStateType_Seamless: uisession()->setRequestedVisualState(UIVisualStateType_Seamless); break;
261 default: break;
262 }
263 }
264
265 /* Enter initial visual state: */
266 enterInitialVisualState();
267}
268
269void UIMachine::cleanupMachineLogic()
270{
271 /* Session UI can have requested visual state: */
272 if (uisession())
273 {
274 /* Get requested visual state: */
275 UIVisualStateType requestedVisualState = uisession()->requestedVisualState();
276 /* Or current visual state if requested is invalid: */
277 if (requestedVisualState == UIVisualStateType_Invalid)
278 requestedVisualState = m_visualState;
279
280 /* Save requested visual state: */
281 gEDataManager->setRequestedVisualState(requestedVisualState, uiCommon().managedVMUuid());
282 }
283
284 /* Destroy machine-logic if exists: */
285 if (m_pMachineLogic)
286 {
287 m_pMachineLogic->cleanup();
288 UIMachineLogic::destroy(m_pMachineLogic);
289 m_pMachineLogic = 0;
290 }
291}
292
293void UIMachine::cleanupSession()
294{
295 /* Destroy session UI if exists: */
296 if (uisession())
297 UISession::destroy(m_pSession);
298}
299
300void UIMachine::cleanup()
301{
302 /* Preprocess all the meta-events: */
303 QApplication::sendPostedEvents(0, QEvent::MetaCall);
304
305 /* Cleanup machine-logic: */
306 cleanupMachineLogic();
307
308 /* Cleanup session UI: */
309 cleanupSession();
310}
311
312void UIMachine::enterInitialVisualState()
313{
314 sltChangeVisualState(m_initialVisualState);
315}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use