VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp@ 36357

Last change on this file since 36357 was 36357, checked in by vboxsync, 13 years ago

FE/Qt: 3887: Make certain VM settings editable during runtime (initial commit).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 64.8 KB
Line 
1/* $Id: UIMachineLogic.cpp 36357 2011-03-23 09:36:05Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * UIMachineLogic class implementation
6 */
7
8/*
9 * Copyright (C) 2010-2011 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* Local includes */
21#include "COMDefs.h"
22#include "QIFileDialog.h"
23#include "UIActionsPool.h"
24#include "UIDownloaderAdditions.h"
25#include "UIIconPool.h"
26#include "UIKeyboardHandler.h"
27#include "UIMouseHandler.h"
28#include "UIMachineLogic.h"
29#include "UIMachineLogicFullscreen.h"
30#include "UIMachineLogicNormal.h"
31#include "UIMachineLogicSeamless.h"
32#include "UIMachineLogicScale.h"
33#include "UIMachineView.h"
34#include "UIMachineWindow.h"
35#include "UISession.h"
36#include "VBoxGlobal.h"
37#include "VBoxProblemReporter.h"
38#include "VBoxTakeSnapshotDlg.h"
39#include "VBoxVMInformationDlg.h"
40#include "UISettingsDialogSpecific.h"
41#ifdef Q_WS_MAC
42# include "DockIconPreview.h"
43# include "UIExtraDataEventHandler.h"
44#endif /* Q_WS_MAC */
45
46/* Global includes */
47#include <iprt/path.h>
48#include <VBox/VMMDev.h>
49
50#ifdef VBOX_WITH_DEBUGGER_GUI
51# include <iprt/ldr.h>
52#endif /* VBOX_WITH_DEBUGGER_GUI */
53
54#ifdef Q_WS_X11
55# include <XKeyboard.h>
56# include <QX11Info>
57#endif /* Q_WS_X11 */
58
59#include <QDir>
60#include <QFileInfo>
61#include <QDesktopWidget>
62#include <QTimer>
63
64struct MediumTarget
65{
66 MediumTarget() : name(QString("")), port(0), device(0), id(QString()), type(VBoxDefs::MediumType_Invalid) {}
67 MediumTarget(const QString &strName, LONG iPort, LONG iDevice)
68 : name(strName), port(iPort), device(iDevice), id(QString()), type(VBoxDefs::MediumType_Invalid) {}
69 MediumTarget(const QString &strName, LONG iPort, LONG iDevice, const QString &strId)
70 : name(strName), port(iPort), device(iDevice), id(strId), type(VBoxDefs::MediumType_Invalid) {}
71 MediumTarget(const QString &strName, LONG iPort, LONG iDevice, VBoxDefs::MediumType eType)
72 : name(strName), port(iPort), device(iDevice), id(QString()), type(eType) {}
73 QString name;
74 LONG port;
75 LONG device;
76 QString id;
77 VBoxDefs::MediumType type;
78};
79Q_DECLARE_METATYPE(MediumTarget);
80
81struct RecentMediumTarget
82{
83 RecentMediumTarget() : name(QString("")), port(0), device(0), location(QString()), type(VBoxDefs::MediumType_Invalid) {}
84 RecentMediumTarget(const QString &strName, LONG iPort, LONG iDevice, const QString &strLocation, VBoxDefs::MediumType eType)
85 : name(strName), port(iPort), device(iDevice), location(strLocation), type(eType) {}
86 QString name;
87 LONG port;
88 LONG device;
89 QString location;
90 VBoxDefs::MediumType type;
91};
92Q_DECLARE_METATYPE(RecentMediumTarget);
93
94struct USBTarget
95{
96 USBTarget() : attach(false), id(QString()) {}
97 USBTarget(bool fAttach, const QString &strId)
98 : attach(fAttach), id(strId) {}
99 bool attach;
100 QString id;
101};
102Q_DECLARE_METATYPE(USBTarget);
103
104UIMachineLogic* UIMachineLogic::create(QObject *pParent,
105 UISession *pSession,
106 UIActionsPool *pActionsPool,
107 UIVisualStateType visualStateType)
108{
109 UIMachineLogic *logic = 0;
110 switch (visualStateType)
111 {
112 case UIVisualStateType_Normal:
113 logic = new UIMachineLogicNormal(pParent, pSession, pActionsPool);
114 break;
115 case UIVisualStateType_Fullscreen:
116 logic = new UIMachineLogicFullscreen(pParent, pSession, pActionsPool);
117 break;
118 case UIVisualStateType_Seamless:
119 logic = new UIMachineLogicSeamless(pParent, pSession, pActionsPool);
120 break;
121 case UIVisualStateType_Scale:
122 logic = new UIMachineLogicScale(pParent, pSession, pActionsPool);
123 break;
124 }
125 return logic;
126}
127
128bool UIMachineLogic::checkAvailability()
129{
130 return true;
131}
132
133UIMachineWindow* UIMachineLogic::mainMachineWindow() const
134{
135 /* Return null if windows are not created yet: */
136 if (!isMachineWindowsCreated())
137 return 0;
138
139 return machineWindows()[0];
140}
141
142UIMachineWindow* UIMachineLogic::defaultMachineWindow() const
143{
144 /* Return null if windows are not created yet: */
145 if (!isMachineWindowsCreated())
146 return 0;
147
148 /* Select main machine window by default: */
149 UIMachineWindow *pWindowToPropose = mainMachineWindow();
150
151 /* Check if there is active window present: */
152 foreach (UIMachineWindow *pWindowToCheck, machineWindows())
153 {
154 if (pWindowToCheck->machineWindow()->isActiveWindow())
155 {
156 pWindowToPropose = pWindowToCheck;
157 break;
158 }
159 }
160
161 /* Return default machine window: */
162 return pWindowToPropose;
163}
164
165#ifdef Q_WS_MAC
166void UIMachineLogic::updateDockIcon()
167{
168 if (!isMachineWindowsCreated())
169 return;
170
171 if ( m_fIsDockIconEnabled
172 && m_pDockIconPreview)
173 if(UIMachineView *pView = machineWindows().at(m_DockIconPreviewMonitor)->machineView())
174 if (CGImageRef image = pView->vmContentImage())
175 {
176 m_pDockIconPreview->updateDockPreview(image);
177 CGImageRelease(image);
178 }
179}
180
181void UIMachineLogic::updateDockIconSize(int screenId, int width, int height)
182{
183 if (!isMachineWindowsCreated())
184 return;
185
186 if ( m_fIsDockIconEnabled
187 && m_pDockIconPreview
188 && m_DockIconPreviewMonitor == screenId)
189 m_pDockIconPreview->setOriginalSize(width, height);
190}
191
192UIMachineView* UIMachineLogic::dockPreviewView() const
193{
194 if ( m_fIsDockIconEnabled
195 && m_pDockIconPreview)
196 return machineWindows().at(m_DockIconPreviewMonitor)->machineView();
197 return 0;
198}
199#endif /* Q_WS_MAC */
200
201UIMachineLogic::UIMachineLogic(QObject *pParent,
202 UISession *pSession,
203 UIActionsPool *pActionsPool,
204 UIVisualStateType visualStateType)
205 : QIWithRetranslateUI3<QObject>(pParent)
206 , m_pSession(pSession)
207 , m_pActionsPool(pActionsPool)
208 , m_visualStateType(visualStateType)
209 , m_pKeyboardHandler(0)
210 , m_pMouseHandler(0)
211 , m_pRunningActions(0)
212 , m_pRunningOrPausedActions(0)
213 , m_fIsWindowsCreated(false)
214 , m_fIsPreventAutoClose(false)
215#ifdef VBOX_WITH_DEBUGGER_GUI
216 , m_pDbgGui(0)
217 , m_pDbgGuiVT(0)
218#endif /* VBOX_WITH_DEBUGGER_GUI */
219#ifdef Q_WS_MAC
220 , m_fIsDockIconEnabled(true)
221 , m_pDockIconPreview(0)
222 , m_pDockPreviewSelectMonitorGroup(0)
223 , m_DockIconPreviewMonitor(0)
224#endif /* Q_WS_MAC */
225{
226}
227
228UIMachineLogic::~UIMachineLogic()
229{
230#ifdef VBOX_WITH_DEBUGGER_GUI
231 /* Close debugger: */
232 dbgDestroy();
233#endif /* VBOX_WITH_DEBUGGER_GUI */
234}
235
236CSession& UIMachineLogic::session()
237{
238 return uisession()->session();
239}
240
241void UIMachineLogic::addMachineWindow(UIMachineWindow *pMachineWindow)
242{
243 m_machineWindowsList << pMachineWindow;
244}
245
246void UIMachineLogic::setKeyboardHandler(UIKeyboardHandler *pKeyboardHandler)
247{
248 m_pKeyboardHandler = pKeyboardHandler;
249}
250
251void UIMachineLogic::setMouseHandler(UIMouseHandler *pMouseHandler)
252{
253 m_pMouseHandler = pMouseHandler;
254}
255
256void UIMachineLogic::retranslateUi()
257{
258#ifdef Q_WS_MAC
259 if (m_pDockPreviewSelectMonitorGroup)
260 {
261 const QList<QAction*> &actions = m_pDockPreviewSelectMonitorGroup->actions();
262 for (int i = 0; i < actions.size(); ++i)
263 {
264 QAction *pAction = actions.at(i);
265 pAction->setText(QApplication::translate("UIMachineLogic", "Preview Monitor %1").arg(pAction->data().toInt() + 1));
266 }
267 }
268#endif /* Q_WS_MAC */
269}
270
271#ifdef Q_WS_MAC
272void UIMachineLogic::updateDockOverlay()
273{
274 /* Only to an update to the realtime preview if this is enabled by the user
275 * & we are in an state where the framebuffer is likely valid. Otherwise to
276 * the overlay stuff only. */
277 KMachineState state = uisession()->machineState();
278 if (m_fIsDockIconEnabled &&
279 (state == KMachineState_Running ||
280 state == KMachineState_Paused ||
281 state == KMachineState_Teleporting ||
282 state == KMachineState_LiveSnapshotting ||
283 state == KMachineState_Restoring ||
284 state == KMachineState_TeleportingPausedVM ||
285 state == KMachineState_TeleportingIn ||
286 state == KMachineState_Saving ||
287 state == KMachineState_DeletingSnapshotOnline ||
288 state == KMachineState_DeletingSnapshotPaused))
289 updateDockIcon();
290 else if (m_pDockIconPreview)
291 m_pDockIconPreview->updateDockOverlay();
292}
293#endif /* Q_WS_MAC */
294
295void UIMachineLogic::prepareSessionConnections()
296{
297 /* Machine power-up notifier: */
298 connect(uisession(), SIGNAL(sigMachineStarted()), this, SLOT(sltCheckRequestedModes()));
299
300 /* Machine state-change updater: */
301 connect(uisession(), SIGNAL(sigMachineStateChange()), this, SLOT(sltMachineStateChanged()));
302
303 /* Guest additions state-change updater: */
304 connect(uisession(), SIGNAL(sigAdditionsStateChange()), this, SLOT(sltAdditionsStateChanged()));
305
306 /* Mouse capability state-change updater: */
307 connect(uisession(), SIGNAL(sigMouseCapabilityChange()), this, SLOT(sltMouseCapabilityChanged()));
308
309 /* USB devices state-change updater: */
310 connect(uisession(), SIGNAL(sigUSBDeviceStateChange(const CUSBDevice &, bool, const CVirtualBoxErrorInfo &)),
311 this, SLOT(sltUSBDeviceStateChange(const CUSBDevice &, bool, const CVirtualBoxErrorInfo &)));
312
313 /* Runtime errors notifier: */
314 connect(uisession(), SIGNAL(sigRuntimeError(bool, const QString &, const QString &)),
315 this, SLOT(sltRuntimeError(bool, const QString &, const QString &)));
316
317#ifdef Q_WS_MAC
318 /* Show windows: */
319 connect(uisession(), SIGNAL(sigShowWindows()),
320 this, SLOT(sltShowWindows()));
321#endif /* Q_WS_MAC */
322}
323
324void UIMachineLogic::prepareActionConnections()
325{
326 /* "Machine" actions connections: */
327 connect(actionsPool()->action(UIActionIndex_Simple_SettingsDialog), SIGNAL(triggered()),
328 this, SLOT(sltOpenVMSettingsDialog()));
329 connect(actionsPool()->action(UIActionIndex_Simple_TakeSnapshot), SIGNAL(triggered()),
330 this, SLOT(sltTakeSnapshot()));
331 connect(actionsPool()->action(UIActionIndex_Simple_InformationDialog), SIGNAL(triggered()),
332 this, SLOT(sltShowInformationDialog()));
333 connect(actionsPool()->action(UIActionIndex_Toggle_MouseIntegration), SIGNAL(toggled(bool)),
334 this, SLOT(sltToggleMouseIntegration(bool)));
335 connect(actionsPool()->action(UIActionIndex_Simple_TypeCAD), SIGNAL(triggered()),
336 this, SLOT(sltTypeCAD()));
337#ifdef Q_WS_X11
338 connect(actionsPool()->action(UIActionIndex_Simple_TypeCABS), SIGNAL(triggered()),
339 this, SLOT(sltTypeCABS()));
340#endif
341 connect(actionsPool()->action(UIActionIndex_Toggle_Pause), SIGNAL(toggled(bool)),
342 this, SLOT(sltPause(bool)));
343 connect(actionsPool()->action(UIActionIndex_Simple_Reset), SIGNAL(triggered()),
344 this, SLOT(sltReset()));
345 connect(actionsPool()->action(UIActionIndex_Simple_Shutdown), SIGNAL(triggered()),
346 this, SLOT(sltACPIShutdown()));
347 connect(actionsPool()->action(UIActionIndex_Simple_Close), SIGNAL(triggered()),
348 this, SLOT(sltClose()));
349
350 /* "View" actions connections: */
351 connect(actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize), SIGNAL(toggled(bool)),
352 this, SLOT(sltToggleGuestAutoresize(bool)));
353 connect(actionsPool()->action(UIActionIndex_Simple_AdjustWindow), SIGNAL(triggered()),
354 this, SLOT(sltAdjustWindow()));
355
356 /* "Devices" actions connections: */
357 connect(actionsPool()->action(UIActionIndex_Menu_OpticalDevices)->menu(), SIGNAL(aboutToShow()),
358 this, SLOT(sltPrepareStorageMenu()));
359 connect(actionsPool()->action(UIActionIndex_Menu_FloppyDevices)->menu(), SIGNAL(aboutToShow()),
360 this, SLOT(sltPrepareStorageMenu()));
361 connect(actionsPool()->action(UIActionIndex_Menu_USBDevices)->menu(), SIGNAL(aboutToShow()),
362 this, SLOT(sltPrepareUSBMenu()));
363 connect(actionsPool()->action(UIActionIndex_Simple_NetworkAdaptersDialog), SIGNAL(triggered()),
364 this, SLOT(sltOpenNetworkAdaptersDialog()));
365 connect(actionsPool()->action(UIActionIndex_Simple_SharedFoldersDialog), SIGNAL(triggered()),
366 this, SLOT(sltOpenSharedFoldersDialog()));
367 connect(actionsPool()->action(UIActionIndex_Toggle_VRDEServer), SIGNAL(toggled(bool)),
368 this, SLOT(sltSwitchVrde(bool)));
369 connect(actionsPool()->action(UIActionIndex_Simple_InstallGuestTools), SIGNAL(triggered()),
370 this, SLOT(sltInstallGuestAdditions()));
371
372#ifdef VBOX_WITH_DEBUGGER_GUI
373 /* "Debug" actions connections: */
374 connect(actionsPool()->action(UIActionIndex_Menu_Debug)->menu(), SIGNAL(aboutToShow()),
375 this, SLOT(sltPrepareDebugMenu()));
376 connect(actionsPool()->action(UIActionIndex_Simple_Statistics), SIGNAL(triggered()),
377 this, SLOT(sltShowDebugStatistics()));
378 connect(actionsPool()->action(UIActionIndex_Simple_CommandLine), SIGNAL(triggered()),
379 this, SLOT(sltShowDebugCommandLine()));
380 connect(actionsPool()->action(UIActionIndex_Toggle_Logging), SIGNAL(toggled(bool)),
381 this, SLOT(sltLoggingToggled(bool)));
382#endif
383}
384
385void UIMachineLogic::prepareActionGroups()
386{
387#ifdef Q_WS_MAC
388 /* On Mac OS X, all QMenu's are consumed by Qt after they are added to
389 * another QMenu or a QMenuBar. This means we have to recreate all QMenus
390 * when creating a new QMenuBar. */
391 uisession()->actionsPool()->createMenus();
392#endif /* Q_WS_MAC */
393
394 /* Create group for all actions that are enabled only when the VM is running.
395 * Note that only actions whose enabled state depends exclusively on the
396 * execution state of the VM are added to this group. */
397 m_pRunningActions = new QActionGroup(this);
398 m_pRunningActions->setExclusive(false);
399
400 /* Create group for all actions that are enabled when the VM is running or paused.
401 * Note that only actions whose enabled state depends exclusively on the
402 * execution state of the VM are added to this group. */
403 m_pRunningOrPausedActions = new QActionGroup(this);
404 m_pRunningOrPausedActions->setExclusive(false);
405
406 /* Move actions into running actions group: */
407 m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_TypeCAD));
408#ifdef Q_WS_X11
409 m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_TypeCABS));
410#endif
411 m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_Reset));
412 m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_Shutdown));
413 m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Fullscreen));
414 m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Seamless));
415 m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Scale));
416 m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize));
417 m_pRunningActions->addAction(actionsPool()->action(UIActionIndex_Simple_AdjustWindow));
418
419 /* Move actions into running-n-paused actions group: */
420 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Simple_SettingsDialog));
421 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Simple_TakeSnapshot));
422 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Simple_InformationDialog));
423 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Menu_MouseIntegration));
424 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Toggle_MouseIntegration));
425 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Toggle_Pause));
426 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Menu_OpticalDevices));
427 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Menu_FloppyDevices));
428 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Menu_USBDevices));
429 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Menu_NetworkAdapters));
430 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Simple_NetworkAdaptersDialog));
431 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Menu_SharedFolders));
432 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Simple_SharedFoldersDialog));
433 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Toggle_VRDEServer));
434 m_pRunningOrPausedActions->addAction(actionsPool()->action(UIActionIndex_Simple_InstallGuestTools));
435}
436
437void UIMachineLogic::prepareHandlers()
438{
439 /* Create keyboard-handler: */
440 setKeyboardHandler(UIKeyboardHandler::create(this, visualStateType()));
441
442 /* Create mouse-handler: */
443 setMouseHandler(UIMouseHandler::create(this, visualStateType()));
444}
445
446#ifdef Q_WS_MAC
447void UIMachineLogic::prepareDock()
448{
449 QMenu *pDockMenu = actionsPool()->action(UIActionIndex_Menu_Dock)->menu();
450
451 /* Add all VM menu entries to the dock menu. Leave out close and stuff like
452 * this. */
453 QList<QAction*> actions = actionsPool()->action(UIActionIndex_Menu_Machine)->menu()->actions();
454 for (int i=0; i < actions.size(); ++i)
455 if (actions.at(i)->menuRole() == QAction::NoRole)
456 pDockMenu->addAction(actions.at(i));
457 pDockMenu->addSeparator();
458
459 QMenu *pDockSettingsMenu = actionsPool()->action(UIActionIndex_Menu_DockSettings)->menu();
460 QActionGroup *pDockPreviewModeGroup = new QActionGroup(this);
461 QAction *pDockDisablePreview = actionsPool()->action(UIActionIndex_Toggle_DockDisableMonitor);
462 pDockPreviewModeGroup->addAction(pDockDisablePreview);
463 QAction *pDockEnablePreviewMonitor = actionsPool()->action(UIActionIndex_Toggle_DockPreviewMonitor);
464 pDockPreviewModeGroup->addAction(pDockEnablePreviewMonitor);
465 pDockSettingsMenu->addActions(pDockPreviewModeGroup->actions());
466
467 connect(pDockPreviewModeGroup, SIGNAL(triggered(QAction*)),
468 this, SLOT(sltDockPreviewModeChanged(QAction*)));
469 connect(gEDataEvents, SIGNAL(sigDockIconAppearanceChange(bool)),
470 this, SLOT(sltChangeDockIconUpdate(bool)));
471
472 /* Monitor selection if there are more than one monitor */
473 int cGuestScreens = uisession()->session().GetMachine().GetMonitorCount();
474 if (cGuestScreens > 1)
475 {
476 pDockSettingsMenu->addSeparator();
477 m_DockIconPreviewMonitor = qMin(session().GetMachine().GetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateMonitor).toInt(), cGuestScreens - 1);
478 m_pDockPreviewSelectMonitorGroup = new QActionGroup(this);
479 for (int i = 0; i < cGuestScreens; ++i)
480 {
481 QAction *pAction = new QAction(m_pDockPreviewSelectMonitorGroup);
482 pAction->setCheckable(true);
483 pAction->setData(i);
484 if (m_DockIconPreviewMonitor == i)
485 pAction->setChecked(true);
486 }
487 pDockSettingsMenu->addActions(m_pDockPreviewSelectMonitorGroup->actions());
488 connect(m_pDockPreviewSelectMonitorGroup, SIGNAL(triggered(QAction*)),
489 this, SLOT(sltDockPreviewMonitorChanged(QAction*)));
490 }
491
492 pDockMenu->addMenu(pDockSettingsMenu);
493
494 /* Add it to the dock. */
495 ::darwinSetDockIconMenu(pDockMenu);
496
497 /* Now the dock icon preview */
498 QString osTypeId = session().GetConsole().GetGuest().GetOSTypeId();
499 m_pDockIconPreview = new UIDockIconPreview(m_pSession, vboxGlobal().vmGuestOSTypeIcon(osTypeId));
500
501 QString strTest = session().GetMachine().GetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateEnabled).toLower();
502 /* Default to true if it is an empty value */
503 bool f = (strTest.isEmpty() || strTest == "true");
504 if (f)
505 pDockEnablePreviewMonitor->setChecked(true);
506 else
507 {
508 pDockDisablePreview->setChecked(true);
509 if(m_pDockPreviewSelectMonitorGroup)
510 m_pDockPreviewSelectMonitorGroup->setEnabled(false);
511 }
512
513 /* Default to true if it is an empty value */
514 setDockIconPreviewEnabled(f);
515 updateDockOverlay();
516}
517#endif /* Q_WS_MAC */
518
519void UIMachineLogic::prepareRequiredFeatures()
520{
521#ifdef Q_WS_MAC
522# ifdef VBOX_WITH_ICHAT_THEATER
523 /* Init shared AV manager: */
524 initSharedAVManager();
525# endif
526#endif
527}
528
529#ifdef VBOX_WITH_DEBUGGER_GUI
530void UIMachineLogic::prepareDebugger()
531{
532 CMachine machine = uisession()->session().GetMachine();
533 if (!machine.isNull() && vboxGlobal().isDebuggerAutoShowEnabled(machine))
534 {
535 /* console in upper left corner of the desktop. */
536// QRect rct (0, 0, 0, 0);
537// QDesktopWidget *desktop = QApplication::desktop();
538// if (desktop)
539// rct = desktop->availableGeometry(pos());
540// move (QPoint (rct.x(), rct.y()));
541
542 if (vboxGlobal().isDebuggerAutoShowStatisticsEnabled(machine))
543 sltShowDebugStatistics();
544 if (vboxGlobal().isDebuggerAutoShowCommandLineEnabled(machine))
545 sltShowDebugCommandLine();
546
547 if (!vboxGlobal().isStartPausedEnabled())
548 sltPause(false);
549 }
550}
551#endif /* VBOX_WITH_DEBUGGER_GUI */
552
553#ifdef Q_WS_MAC
554void UIMachineLogic::cleanupDock()
555{
556 if (m_pDockIconPreview)
557 {
558 delete m_pDockIconPreview;
559 m_pDockIconPreview = 0;
560 }
561}
562#endif /* Q_WS_MAC */
563
564void UIMachineLogic::cleanupHandlers()
565{
566 /* Cleanup mouse-handler: */
567 UIMouseHandler::destroy(mouseHandler());
568
569 /* Cleanup keyboard-handler: */
570 UIKeyboardHandler::destroy(keyboardHandler());
571}
572
573void UIMachineLogic::sltMachineStateChanged()
574{
575 /* Get machine state: */
576 KMachineState state = uisession()->machineState();
577
578 /* Update action groups: */
579 m_pRunningActions->setEnabled(uisession()->isRunning());
580 m_pRunningOrPausedActions->setEnabled(uisession()->isRunning() || uisession()->isPaused());
581
582 switch (state)
583 {
584 case KMachineState_Stuck: // TODO: Test it!
585 {
586 /* Prevent machine view from resizing: */
587 uisession()->setGuestResizeIgnored(true);
588
589 /* Get console: */
590 CConsole console = session().GetConsole();
591
592 /* Take the screenshot for debugging purposes and save it. */
593 QString strLogFolder = console.GetMachine().GetLogFolder();
594 CDisplay display = console.GetDisplay();
595 int cGuestScreens = uisession()->session().GetMachine().GetMonitorCount();
596 for (int i=0; i < cGuestScreens; ++i)
597 {
598 QString strFileName;
599 if (i == 0)
600 strFileName = strLogFolder + "/VBox.png";
601 else
602 strFileName = QString("%1/VBox.%2.png").arg(strLogFolder).arg(i);
603 ULONG width = 0;
604 ULONG height = 0;
605 ULONG bpp = 0;
606 display.GetScreenResolution(i, width, height, bpp);
607 QImage shot = QImage(width, height, QImage::Format_RGB32);
608 display.TakeScreenShot(i, shot.bits(), shot.width(), shot.height());
609 shot.save(QFile::encodeName(strFileName), "PNG");
610 }
611
612 /* Warn the user about GURU: */
613 if (vboxProblem().remindAboutGuruMeditation(console, QDir::toNativeSeparators(strLogFolder)))
614 {
615 console.PowerDown();
616 if (!console.isOk())
617 vboxProblem().cannotStopMachine(console);
618 }
619 break;
620 }
621 case KMachineState_Paused:
622 case KMachineState_TeleportingPausedVM:
623 {
624 QAction *pPauseAction = actionsPool()->action(UIActionIndex_Toggle_Pause);
625 if (!pPauseAction->isChecked())
626 {
627 /* Was paused from CSession side: */
628 pPauseAction->blockSignals(true);
629 pPauseAction->setChecked(true);
630 pPauseAction->blockSignals(false);
631 }
632 break;
633 }
634 case KMachineState_Running:
635 case KMachineState_Teleporting:
636 case KMachineState_LiveSnapshotting:
637 {
638 QAction *pPauseAction = actionsPool()->action(UIActionIndex_Toggle_Pause);
639 if (pPauseAction->isChecked())
640 {
641 /* Was resumed from CSession side: */
642 pPauseAction->blockSignals(true);
643 pPauseAction->setChecked(false);
644 pPauseAction->blockSignals(false);
645 }
646 break;
647 }
648 case KMachineState_PoweredOff:
649 case KMachineState_Saved:
650 case KMachineState_Teleported:
651 case KMachineState_Aborted:
652 {
653 /* Close VM if it was turned off and closure allowed: */
654 if (!isPreventAutoClose())
655 {
656 /* VM has been powered off, saved or aborted, no matter
657 * internally or externally. We must *safely* close VM window(s): */
658 QTimer::singleShot(0, uisession(), SLOT(sltCloseVirtualSession()));
659 }
660 break;
661 }
662#ifdef Q_WS_X11
663 case KMachineState_Starting:
664 case KMachineState_Restoring:
665 case KMachineState_TeleportingIn:
666 {
667 /* The keyboard handler may wish to do some release logging on startup.
668 * Tell it that the logger is now active. */
669 doXKeyboardLogging(QX11Info::display());
670 break;
671 }
672#endif
673 default:
674 break;
675 }
676
677#ifdef Q_WS_MAC
678 /* Update Dock Overlay: */
679 updateDockOverlay();
680#endif /* Q_WS_MAC */
681}
682
683void UIMachineLogic::sltAdditionsStateChanged()
684{
685 /* Variable flags: */
686 bool fIsSupportsGraphics = uisession()->isGuestSupportsGraphics();
687 bool fIsSupportsSeamless = uisession()->isGuestSupportsSeamless();
688
689 /* Update action states: */
690 actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize)->setEnabled(fIsSupportsGraphics);
691 actionsPool()->action(UIActionIndex_Toggle_Seamless)->setEnabled(fIsSupportsSeamless);
692
693 /* Check if we should enter some extended mode: */
694 sltCheckRequestedModes();
695}
696
697void UIMachineLogic::sltMouseCapabilityChanged()
698{
699 /* Variable falgs: */
700 bool fIsMouseSupportsAbsolute = uisession()->isMouseSupportsAbsolute();
701 bool fIsMouseSupportsRelative = uisession()->isMouseSupportsRelative();
702 bool fIsMouseHostCursorNeeded = uisession()->isMouseHostCursorNeeded();
703
704 /* Update action state: */
705 QAction *pAction = actionsPool()->action(UIActionIndex_Toggle_MouseIntegration);
706 pAction->setEnabled(fIsMouseSupportsAbsolute && fIsMouseSupportsRelative && !fIsMouseHostCursorNeeded);
707 if (fIsMouseHostCursorNeeded)
708 pAction->setChecked(false);
709}
710
711void UIMachineLogic::sltUSBDeviceStateChange(const CUSBDevice &device, bool fIsAttached, const CVirtualBoxErrorInfo &error)
712{
713 bool fSuccess = error.isNull();
714
715 if (!fSuccess)
716 {
717 if (fIsAttached)
718 vboxProblem().cannotAttachUSBDevice(session().GetConsole(), vboxGlobal().details(device), error);
719 else
720 vboxProblem().cannotDetachUSBDevice(session().GetConsole(), vboxGlobal().details(device), error);
721 }
722}
723
724void UIMachineLogic::sltRuntimeError(bool fIsFatal, const QString &strErrorId, const QString &strMessage)
725{
726 vboxProblem().showRuntimeError(session().GetConsole(), fIsFatal, strErrorId, strMessage);
727}
728
729#ifdef Q_WS_MAC
730void UIMachineLogic::sltShowWindows()
731{
732 for (int i=0; i < m_machineWindowsList.size(); ++i)
733 {
734 UIMachineWindow *pMachineWindow = m_machineWindowsList.at(i);
735 /* Dunno what Qt thinks a window that has minimized to the dock
736 * should be - it is not hidden, neither is it minimized. OTOH it is
737 * marked shown and visible, but not activated. This latter isn't of
738 * much help though, since at this point nothing is marked activated.
739 * I might have overlooked something, but I'm buggered what if I know
740 * what. So, I'll just always show & activate the stupid window to
741 * make it get out of the dock when the user wishes to show a VM. */
742 pMachineWindow->machineWindow()->raise();
743 pMachineWindow->machineWindow()->activateWindow();
744 }
745}
746#endif /* Q_WS_MAC */
747
748void UIMachineLogic::sltCheckRequestedModes()
749{
750 /* Do not try to enter extended mode if machine was not started yet: */
751 if (!uisession()->isRunning() && !uisession()->isPaused())
752 return;
753
754 /* If seamless mode is requested, supported and we are NOT currently in seamless mode: */
755 if (uisession()->isSeamlessModeRequested() &&
756 uisession()->isGuestSupportsSeamless() &&
757 visualStateType() != UIVisualStateType_Seamless)
758 {
759 uisession()->setSeamlessModeRequested(false);
760 QAction *pSeamlessModeAction = actionsPool()->action(UIActionIndex_Toggle_Seamless);
761 AssertMsg(!pSeamlessModeAction->isChecked(), ("Seamless action should not be triggered before us!\n"));
762 QTimer::singleShot(0, pSeamlessModeAction, SLOT(trigger()));
763 }
764 /* If seamless mode is NOT requested, NOT supported and we are currently in seamless mode: */
765 else if (!uisession()->isSeamlessModeRequested() &&
766 !uisession()->isGuestSupportsSeamless() &&
767 visualStateType() == UIVisualStateType_Seamless)
768 {
769 uisession()->setSeamlessModeRequested(true);
770 QAction *pSeamlessModeAction = actionsPool()->action(UIActionIndex_Toggle_Seamless);
771 AssertMsg(pSeamlessModeAction->isChecked(), ("Seamless action should not be triggered before us!\n"));
772 QTimer::singleShot(0, pSeamlessModeAction, SLOT(trigger()));
773 }
774}
775
776void UIMachineLogic::sltToggleGuestAutoresize(bool fEnabled)
777{
778 /* Do not process if window(s) missed! */
779 if (!isMachineWindowsCreated())
780 return;
781
782 /* Toggle guest-autoresize feature for all view(s)! */
783 foreach(UIMachineWindow *pMachineWindow, machineWindows())
784 pMachineWindow->machineView()->setGuestAutoresizeEnabled(fEnabled);
785}
786
787void UIMachineLogic::sltAdjustWindow()
788{
789 /* Do not process if window(s) missed! */
790 if (!isMachineWindowsCreated())
791 return;
792
793 /* Adjust all window(s)! */
794 foreach(UIMachineWindow *pMachineWindow, machineWindows())
795 {
796 /* Exit maximized window state if actual: */
797 if (pMachineWindow->machineWindow()->isMaximized())
798 pMachineWindow->machineWindow()->showNormal();
799
800 /* Normalize view's geometry: */
801 pMachineWindow->machineView()->normalizeGeometry(true);
802 }
803}
804
805void UIMachineLogic::sltToggleMouseIntegration(bool fOff)
806{
807 /* Do not process if window(s) missed! */
808 if (!isMachineWindowsCreated())
809 return;
810
811 /* Disable/Enable mouse-integration for all view(s): */
812 m_pMouseHandler->setMouseIntegrationEnabled(!fOff);
813}
814
815void UIMachineLogic::sltTypeCAD()
816{
817 CKeyboard keyboard = session().GetConsole().GetKeyboard();
818 Assert(!keyboard.isNull());
819 keyboard.PutCAD();
820 AssertWrapperOk(keyboard);
821}
822
823#ifdef Q_WS_X11
824void UIMachineLogic::sltTypeCABS()
825{
826 CKeyboard keyboard = session().GetConsole().GetKeyboard();
827 Assert(!keyboard.isNull());
828 static QVector<LONG> aSequence(6);
829 aSequence[0] = 0x1d; /* Ctrl down */
830 aSequence[1] = 0x38; /* Alt down */
831 aSequence[2] = 0x0E; /* Backspace down */
832 aSequence[3] = 0x8E; /* Backspace up */
833 aSequence[4] = 0xb8; /* Alt up */
834 aSequence[5] = 0x9d; /* Ctrl up */
835 keyboard.PutScancodes(aSequence);
836 AssertWrapperOk(keyboard);
837}
838#endif
839
840void UIMachineLogic::sltTakeSnapshot()
841{
842 /* Do not process if window(s) missed! */
843 if (!isMachineWindowsCreated())
844 return;
845
846 /* Remember the paused state. */
847 bool fWasPaused = uisession()->isPaused();
848 if (!fWasPaused)
849 {
850 /* Suspend the VM and ignore the close event if failed to do so.
851 * pause() will show the error message to the user. */
852 if (!uisession()->pause())
853 return;
854 }
855
856 CMachine machine = session().GetMachine();
857
858 VBoxTakeSnapshotDlg dlg(defaultMachineWindow()->machineWindow(), machine);
859
860 QString strTypeId = machine.GetOSTypeId();
861 dlg.mLbIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(strTypeId));
862
863 /* Search for the max available filter index. */
864 QString strNameTemplate = QApplication::translate("UIMachineLogic", "Snapshot %1");
865 int iMaxSnapshotIndex = searchMaxSnapshotIndex(machine, machine.FindSnapshot(QString()), strNameTemplate);
866 dlg.mLeName->setText(strNameTemplate.arg(++ iMaxSnapshotIndex));
867
868 if (dlg.exec() == QDialog::Accepted)
869 {
870 CConsole console = session().GetConsole();
871
872 CProgress progress = console.TakeSnapshot(dlg.mLeName->text().trimmed(), dlg.mTeDescription->toPlainText());
873
874 if (console.isOk())
875 {
876 /* Show the "Taking Snapshot" progress dialog */
877 vboxProblem().showModalProgressDialog(progress, machine.GetName(), ":/progress_snapshot_create_90px.png", 0, true);
878
879 if (progress.GetResultCode() != 0)
880 vboxProblem().cannotTakeSnapshot(progress);
881 }
882 else
883 vboxProblem().cannotTakeSnapshot(console);
884 }
885
886 /* Restore the running state if needed. */
887 if (!fWasPaused)
888 {
889 /* Make sure machine-state-change callback is processed: */
890 QApplication::sendPostedEvents(uisession(), UIConsoleEventType_StateChange);
891 /* Unpause VM: */
892 uisession()->unpause();
893 }
894}
895
896void UIMachineLogic::sltShowInformationDialog()
897{
898 /* Do not process if window(s) missed! */
899 if (!isMachineWindowsCreated())
900 return;
901
902 VBoxVMInformationDlg::createInformationDlg(mainMachineWindow());
903}
904
905void UIMachineLogic::sltReset()
906{
907 /* Confirm/Reset current console: */
908 if (vboxProblem().confirmVMReset(0))
909 session().GetConsole().Reset();
910
911 /* TODO_NEW_CORE: On reset the additional screens didn't get a display
912 update. Emulate this for now until it get fixed. */
913 ulong uMonitorCount = session().GetMachine().GetMonitorCount();
914 for (ulong uScreenId = 1; uScreenId < uMonitorCount; ++uScreenId)
915 machineWindows().at(uScreenId)->machineWindow()->update();
916}
917
918void UIMachineLogic::sltPause(bool fOn)
919{
920 uisession()->setPause(fOn);
921}
922
923void UIMachineLogic::sltACPIShutdown()
924{
925 /* Get console: */
926 CConsole console = session().GetConsole();
927
928 /* Warn the user about ACPI is not available if so: */
929 if (!console.GetGuestEnteredACPIMode())
930 return vboxProblem().cannotSendACPIToMachine();
931
932 /* Send ACPI shutdown signal, warn if failed: */
933 console.PowerButton();
934 if (!console.isOk())
935 vboxProblem().cannotACPIShutdownMachine(console);
936}
937
938void UIMachineLogic::sltClose()
939{
940 /* Do not process if window(s) missed! */
941 if (!isMachineWindowsCreated())
942 return;
943
944 /* Propose to close default machine window: */
945 defaultMachineWindow()->sltTryClose();
946}
947
948void UIMachineLogic::sltOpenVMSettingsDialog(const QString &strCategory /* = QString() */)
949{
950 /* Do not process if window(s) missed! */
951 if (!isMachineWindowsCreated())
952 return;
953
954 /* Open shared session: */
955 CSession sharedSession = vboxGlobal().openSession(session().GetMachine().GetId(), true);
956 if (sharedSession.isNull())
957 return;
958
959 /* Get machine: */
960 CMachine sharedMachine = sharedSession.GetMachine();
961 if (sharedMachine.isNull())
962 return;
963
964 /* Prepare VM settings dialog: */
965 UISettingsDialog *pDlg = new UISettingsDialogMachine(defaultMachineWindow()->machineWindow(),
966 VBoxDefs::SettingsDialogType_Runtime,
967 sharedMachine, session().GetConsole(),
968 strCategory, QString());
969 pDlg->getFrom();
970
971 /* Show VM settings dialog: */
972 if (pDlg->exec() == QDialog::Accepted)
973 {
974 /* If dialog was accepted => save changed settings: */
975 pDlg->putBackTo();
976 sharedMachine.SaveSettings();
977 /* If settings were failed to be saved => show the error: */
978 if (!sharedMachine.isOk())
979 vboxProblem().cannotSaveMachineSettings(sharedMachine);
980 }
981
982 /* Delete VM settings dialog: */
983 delete pDlg;
984
985 /* Unlock machine: */
986 sharedSession.UnlockMachine();
987}
988
989void UIMachineLogic::sltOpenNetworkAdaptersDialog()
990{
991 /* Open VM settings : Network page: */
992 sltOpenVMSettingsDialog("#network");
993}
994
995void UIMachineLogic::sltOpenSharedFoldersDialog()
996{
997 /* Do not process if additions are not loaded! */
998 if (!uisession()->isGuestAdditionsActive())
999 vboxProblem().remindAboutGuestAdditionsAreNotActive(defaultMachineWindow()->machineWindow());
1000
1001 /* Open VM settings : Shared folders page: */
1002 sltOpenVMSettingsDialog("#sfolders");
1003}
1004
1005void UIMachineLogic::sltPrepareStorageMenu()
1006{
1007 /* Get the sender() menu: */
1008 QMenu *pMenu = qobject_cast<QMenu*>(sender());
1009 AssertMsg(pMenu, ("This slot should only be called on hovering storage menu!\n"));
1010 pMenu->clear();
1011
1012 /* Short way to common storage menus: */
1013 QMenu *pOpticalDevicesMenu = actionsPool()->action(UIActionIndex_Menu_OpticalDevices)->menu();
1014 QMenu *pFloppyDevicesMenu = actionsPool()->action(UIActionIndex_Menu_FloppyDevices)->menu();
1015
1016 /* Determine medium & device types: */
1017 VBoxDefs::MediumType mediumType = pMenu == pOpticalDevicesMenu ? VBoxDefs::MediumType_DVD :
1018 pMenu == pFloppyDevicesMenu ? VBoxDefs::MediumType_Floppy :
1019 VBoxDefs::MediumType_Invalid;
1020 KDeviceType deviceType = vboxGlobal().mediumTypeToGlobal(mediumType);
1021 AssertMsg(mediumType != VBoxDefs::MediumType_Invalid, ("Incorrect storage medium type!\n"));
1022 AssertMsg(deviceType != KDeviceType_Null, ("Incorrect storage device type!\n"));
1023
1024 /* Fill attachments menu: */
1025 const CMachine &machine = session().GetMachine();
1026 const CMediumAttachmentVector &attachments = machine.GetMediumAttachments();
1027 for (int iAttachmentIndex = 0; iAttachmentIndex < attachments.size(); ++iAttachmentIndex)
1028 {
1029 /* Current attachment: */
1030 const CMediumAttachment &attachment = attachments[iAttachmentIndex];
1031 /* Current controller: */
1032 const CStorageController &controller = machine.GetStorageControllerByName(attachment.GetController());
1033 /* If controller present and device type correct: */
1034 if (!controller.isNull() && (attachment.GetType() == deviceType))
1035 {
1036 /* Current attachment attributes: */
1037 const CMedium &currentMedium = attachment.GetMedium();
1038 QString strCurrentId = currentMedium.isNull() ? QString::null : currentMedium.GetId();
1039 QString strCurrentLocation = currentMedium.isNull() ? QString::null : currentMedium.GetLocation();
1040
1041 /* Attachment menu item: */
1042 QMenu *pAttachmentMenu = 0;
1043 if (pMenu->menuAction()->data().toInt() > 1)
1044 {
1045 pAttachmentMenu = new QMenu(pMenu);
1046 pAttachmentMenu->setTitle(QString("%1 (%2)").arg(controller.GetName())
1047 .arg(vboxGlobal().toString(StorageSlot(controller.GetBus(),
1048 attachment.GetPort(),
1049 attachment.GetDevice()))));
1050 switch (controller.GetBus())
1051 {
1052 case KStorageBus_IDE:
1053 pAttachmentMenu->setIcon(QIcon(":/ide_16px.png")); break;
1054 case KStorageBus_SATA:
1055 pAttachmentMenu->setIcon(QIcon(":/sata_16px.png")); break;
1056 case KStorageBus_SCSI:
1057 pAttachmentMenu->setIcon(QIcon(":/scsi_16px.png")); break;
1058 case KStorageBus_Floppy:
1059 pAttachmentMenu->setIcon(QIcon(":/floppy_16px.png")); break;
1060 default:
1061 break;
1062 }
1063 pMenu->addMenu(pAttachmentMenu);
1064 }
1065 else pAttachmentMenu = pMenu;
1066
1067 /* Prepare choose-existing-medium action: */
1068 QAction *pChooseExistingMediumAction = pAttachmentMenu->addAction(QIcon(":/select_file_16px.png"), QString(),
1069 this, SLOT(sltMountStorageMedium()));
1070 pChooseExistingMediumAction->setData(QVariant::fromValue(MediumTarget(controller.GetName(), attachment.GetPort(),
1071 attachment.GetDevice(), mediumType)));
1072
1073 /* Prepare choose-particular-medium actions: */
1074 CMediumVector mediums;
1075 QString strRecentMediumAddress;
1076 switch (mediumType)
1077 {
1078 case VBoxDefs::MediumType_DVD:
1079 mediums = vboxGlobal().virtualBox().GetHost().GetDVDDrives();
1080 strRecentMediumAddress = VBoxDefs::GUI_RecentListCD;
1081 break;
1082 case VBoxDefs::MediumType_Floppy:
1083 mediums = vboxGlobal().virtualBox().GetHost().GetFloppyDrives();
1084 strRecentMediumAddress = VBoxDefs::GUI_RecentListFD;
1085 break;
1086 default:
1087 break;
1088 }
1089
1090 /* Prepare choose-host-drive actions: */
1091 for (int iHostDriveIndex = 0; iHostDriveIndex < mediums.size(); ++iHostDriveIndex)
1092 {
1093 const CMedium &medium = mediums[iHostDriveIndex];
1094 bool fIsHostDriveUsed = false;
1095 for (int iOtherAttachmentIndex = 0; iOtherAttachmentIndex < attachments.size(); ++iOtherAttachmentIndex)
1096 {
1097 const CMediumAttachment &otherAttachment = attachments[iOtherAttachmentIndex];
1098 if (otherAttachment != attachment)
1099 {
1100 const CMedium &otherMedium = otherAttachment.GetMedium();
1101 if (!otherMedium.isNull() && otherMedium.GetId() == medium.GetId())
1102 {
1103 fIsHostDriveUsed = true;
1104 break;
1105 }
1106 }
1107 }
1108 if (!fIsHostDriveUsed)
1109 {
1110 QAction *pChooseHostDriveAction = pAttachmentMenu->addAction(VBoxMedium(medium, mediumType).name(),
1111 this, SLOT(sltMountStorageMedium()));
1112 pChooseHostDriveAction->setCheckable(true);
1113 pChooseHostDriveAction->setChecked(!currentMedium.isNull() && medium.GetId() == strCurrentId);
1114 pChooseHostDriveAction->setData(QVariant::fromValue(MediumTarget(controller.GetName(), attachment.GetPort(),
1115 attachment.GetDevice(), medium.GetId())));
1116 }
1117 }
1118
1119 /* Prepare choose-recent-medium actions: */
1120 QStringList recentMediumList = vboxGlobal().virtualBox().GetExtraData(strRecentMediumAddress).split(';');
1121 /* For every list-item: */
1122 for (int i = 0; i < recentMediumList.size(); ++i)
1123 {
1124 QString strRecentMediumLocation = QDir::toNativeSeparators(recentMediumList[i]);
1125 if (QFile::exists(strRecentMediumLocation))
1126 {
1127 bool fIsRecentMediumUsed = false;
1128 for (int iOtherAttachmentIndex = 0; iOtherAttachmentIndex < attachments.size(); ++iOtherAttachmentIndex)
1129 {
1130 const CMediumAttachment &otherAttachment = attachments[iOtherAttachmentIndex];
1131 if (otherAttachment != attachment)
1132 {
1133 const CMedium &otherMedium = otherAttachment.GetMedium();
1134 if (!otherMedium.isNull() && otherMedium.GetLocation() == strRecentMediumLocation)
1135 {
1136 fIsRecentMediumUsed = true;
1137 break;
1138 }
1139 }
1140 }
1141 if (!fIsRecentMediumUsed)
1142 {
1143 QAction *pChooseRecentMediumAction = pAttachmentMenu->addAction(QFileInfo(strRecentMediumLocation).fileName(),
1144 this, SLOT(sltMountRecentStorageMedium()));
1145 pChooseRecentMediumAction->setCheckable(true);
1146 pChooseRecentMediumAction->setChecked(!currentMedium.isNull() && strRecentMediumLocation == strCurrentLocation);
1147 pChooseRecentMediumAction->setData(QVariant::fromValue(RecentMediumTarget(controller.GetName(), attachment.GetPort(),
1148 attachment.GetDevice(), strRecentMediumLocation, mediumType)));
1149 }
1150 }
1151 }
1152
1153 /* Insert separator: */
1154 pAttachmentMenu->addSeparator();
1155
1156 /* Unmount Medium action: */
1157 QAction *unmountMediumAction = new QAction(pAttachmentMenu);
1158 unmountMediumAction->setEnabled(!currentMedium.isNull());
1159 unmountMediumAction->setData(QVariant::fromValue(MediumTarget(controller.GetName(),
1160 attachment.GetPort(),
1161 attachment.GetDevice())));
1162 connect(unmountMediumAction, SIGNAL(triggered(bool)), this, SLOT(sltMountStorageMedium()));
1163 pAttachmentMenu->addAction(unmountMediumAction);
1164
1165 /* Switch CD/FD naming */
1166 switch (mediumType)
1167 {
1168 case VBoxDefs::MediumType_DVD:
1169 pChooseExistingMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a virtual CD/DVD disk file..."));
1170 unmountMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
1171 unmountMediumAction->setIcon(UIIconPool::iconSet(":/cd_unmount_16px.png",
1172 ":/cd_unmount_dis_16px.png"));
1173 break;
1174 case VBoxDefs::MediumType_Floppy:
1175 pChooseExistingMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a virtual floppy disk file..."));
1176 unmountMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
1177 unmountMediumAction->setIcon(UIIconPool::iconSet(":/fd_unmount_16px.png",
1178 ":/fd_unmount_dis_16px.png"));
1179 break;
1180 default:
1181 break;
1182 }
1183 }
1184 }
1185
1186 if (pMenu->menuAction()->data().toInt() == 0)
1187 {
1188 /* Empty menu item */
1189 Assert(pMenu->isEmpty());
1190 QAction *pEmptyMenuAction = new QAction(pMenu);
1191 pEmptyMenuAction->setEnabled(false);
1192 switch (mediumType)
1193 {
1194 case VBoxDefs::MediumType_DVD:
1195 pEmptyMenuAction->setText(QApplication::translate("UIMachineLogic", "No CD/DVD Devices Attached"));
1196 pEmptyMenuAction->setToolTip(QApplication::translate("UIMachineLogic", "No CD/DVD devices attached to that VM"));
1197 break;
1198 case VBoxDefs::MediumType_Floppy:
1199 pEmptyMenuAction->setText(QApplication::translate("UIMachineLogic", "No Floppy Devices Attached"));
1200 pEmptyMenuAction->setToolTip(QApplication::translate("UIMachineLogic", "No floppy devices attached to that VM"));
1201 break;
1202 default:
1203 break;
1204 }
1205 pEmptyMenuAction->setIcon(UIIconPool::iconSet(":/delete_16px.png", ":/delete_dis_16px.png"));
1206 pMenu->addAction(pEmptyMenuAction);
1207 }
1208}
1209
1210void UIMachineLogic::sltMountStorageMedium()
1211{
1212 /* Get sender action: */
1213 QAction *action = qobject_cast<QAction*>(sender());
1214 AssertMsg(action, ("This slot should only be called on selecting storage menu item!\n"));
1215
1216 /* Get current machine: */
1217 CMachine machine = session().GetMachine();
1218
1219 /* Get mount-target: */
1220 MediumTarget target = action->data().value<MediumTarget>();
1221
1222 /* Current mount-target attributes: */
1223 CMediumAttachment currentAttachment = machine.GetMediumAttachment(target.name, target.port, target.device);
1224 CMedium currentMedium = currentAttachment.GetMedium();
1225 QString currentId = currentMedium.isNull() ? QString("") : currentMedium.GetId();
1226
1227 /* New mount-target attributes: */
1228 QString newId = QString("");
1229 bool fSelectWithMediaManager = target.type != VBoxDefs::MediumType_Invalid;
1230
1231 /* Open Virtual Media Manager to select image id: */
1232 if (fSelectWithMediaManager)
1233 {
1234 /* Search for already used images: */
1235 QStringList usedImages;
1236 foreach (const CMediumAttachment &attachment, machine.GetMediumAttachments())
1237 {
1238 CMedium medium = attachment.GetMedium();
1239 if (attachment != currentAttachment && !medium.isNull() && !medium.GetHostDrive())
1240 usedImages << medium.GetId();
1241 }
1242 /* Call for file-open window: */
1243 QString strMachineFolder(QFileInfo(machine.GetSettingsFilePath()).absolutePath());
1244 QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(target.type, defaultMachineWindow()->machineWindow(),
1245 strMachineFolder);
1246 defaultMachineWindow()->machineView()->setFocus();
1247 if (!strMediumId.isNull())
1248 newId = strMediumId;
1249 else return;
1250 }
1251 /* Use medium which was sent: */
1252 else if (!target.id.isNull() && target.id != currentId)
1253 newId = target.id;
1254
1255 bool fMount = !newId.isEmpty();
1256
1257 VBoxMedium vmedium = vboxGlobal().findMedium(newId);
1258 CMedium medium = vmedium.medium(); // @todo r=dj can this be cached somewhere?
1259
1260 /* Remount medium to the predefined port/device: */
1261 bool fWasMounted = false;
1262 machine.MountMedium(target.name, target.port, target.device, medium, false /* force */);
1263 if (machine.isOk())
1264 fWasMounted = true;
1265 else
1266 {
1267 /* Ask for force remounting: */
1268 if (vboxProblem().cannotRemountMedium(0, machine, vboxGlobal().findMedium (fMount ? newId : currentId), fMount, true /* retry? */) == QIMessageBox::Ok)
1269 {
1270 /* Force remount medium to the predefined port/device: */
1271 machine.MountMedium(target.name, target.port, target.device, medium, true /* force */);
1272 if (machine.isOk())
1273 fWasMounted = true;
1274 else
1275 vboxProblem().cannotRemountMedium(0, machine, vboxGlobal().findMedium (fMount ? newId : currentId), fMount, false /* retry? */);
1276 }
1277 }
1278
1279 /* Save medium mounted at runtime */
1280 if (fWasMounted && !uisession()->isIgnoreRuntimeMediumsChanging())
1281 {
1282 machine.SaveSettings();
1283 if (!machine.isOk())
1284 vboxProblem().cannotSaveMachineSettings(machine);
1285 }
1286}
1287
1288void UIMachineLogic::sltMountRecentStorageMedium()
1289{
1290 /* Get sender action: */
1291 QAction *pSender = qobject_cast<QAction*>(sender());
1292 AssertMsg(pSender, ("This slot should only be called on selecting storage menu item!\n"));
1293
1294 /* Get mount-target: */
1295 RecentMediumTarget target = pSender->data().value<RecentMediumTarget>();
1296
1297 /* Get new medium id: */
1298 QString strNewId = vboxGlobal().openMedium(target.type, target.location);
1299
1300 if (!strNewId.isEmpty())
1301 {
1302 /* Get current machine: */
1303 CMachine machine = session().GetMachine();
1304
1305 /* Get current medium id: */
1306 const CMediumAttachment &currentAttachment = machine.GetMediumAttachment(target.name, target.port, target.device);
1307 CMedium currentMedium = currentAttachment.GetMedium();
1308 QString strCurrentId = currentMedium.isNull() ? QString("") : currentMedium.GetId();
1309
1310 /* Should we mount or unmount? */
1311 bool fMount = strNewId != strCurrentId;
1312
1313 /* Prepare target medium: */
1314 const VBoxMedium &vboxMedium = fMount ? vboxGlobal().findMedium(strNewId) : VBoxMedium();
1315 const CMedium &comMedium = fMount ? vboxMedium.medium() : CMedium();
1316
1317 /* 'Mounted' flag: */
1318 bool fWasMounted = false;
1319
1320 /* Try to mount medium to the predefined port/device: */
1321 machine.MountMedium(target.name, target.port, target.device, comMedium, false /* force? */);
1322 if (machine.isOk())
1323 fWasMounted = true;
1324 else
1325 {
1326 /* Ask for force remounting: */
1327 if (vboxProblem().cannotRemountMedium(0, machine, vboxGlobal().findMedium(fMount ? strNewId : strCurrentId), fMount, true /* retry? */) == QIMessageBox::Ok)
1328 {
1329 /* Force remount medium to the predefined port/device: */
1330 machine.MountMedium(target.name, target.port, target.device, comMedium, true /* force? */);
1331 if (machine.isOk())
1332 fWasMounted = true;
1333 else
1334 vboxProblem().cannotRemountMedium(0, machine, vboxGlobal().findMedium(fMount ? strNewId : strCurrentId), fMount, false /* retry? */);
1335 }
1336 }
1337
1338 /* Save medium mounted at runtime if necessary: */
1339 if (fWasMounted && !uisession()->isIgnoreRuntimeMediumsChanging())
1340 {
1341 machine.SaveSettings();
1342 if (!machine.isOk())
1343 vboxProblem().cannotSaveMachineSettings(machine);
1344 }
1345 }
1346}
1347
1348void UIMachineLogic::sltPrepareUSBMenu()
1349{
1350 /* Get the sender() menu: */
1351 QMenu *pMenu = qobject_cast<QMenu*>(sender());
1352#ifdef RT_STRICT
1353 QMenu *pUSBDevicesMenu = actionsPool()->action(UIActionIndex_Menu_USBDevices)->menu();
1354#endif
1355 AssertMsg(pMenu == pUSBDevicesMenu, ("This slot should only be called on hovering USB menu!\n"));
1356 pMenu->clear();
1357
1358 /* Get HOST: */
1359 CHost host = vboxGlobal().virtualBox().GetHost();
1360
1361 /* Get USB devices list: */
1362 CHostUSBDeviceVector devices = host.GetUSBDevices();
1363
1364 /* Fill USB devices menu: */
1365 bool fIsUSBListEmpty = devices.size() == 0;
1366 if (fIsUSBListEmpty)
1367 {
1368 /* Fill USB devices menu: */
1369 QAction *pEmptyMenuAction = new QAction(pMenu);
1370 pEmptyMenuAction->setEnabled(false);
1371 pEmptyMenuAction->setText(QApplication::translate("UIMachineLogic", "No USB Devices Connected"));
1372 pEmptyMenuAction->setIcon(UIIconPool::iconSet(":/delete_16px.png", ":/delete_dis_16px.png"));
1373 pEmptyMenuAction->setToolTip(QApplication::translate("UIMachineLogic", "No supported devices connected to the host PC"));
1374 }
1375 else
1376 {
1377 foreach (const CHostUSBDevice hostDevice, devices)
1378 {
1379 /* Get common USB device: */
1380 CUSBDevice device(hostDevice);
1381
1382 /* Create USB device action: */
1383 QAction *attachUSBAction = new QAction(vboxGlobal().details(device), pMenu);
1384 attachUSBAction->setCheckable(true);
1385 connect(attachUSBAction, SIGNAL(triggered(bool)), this, SLOT(sltAttachUSBDevice()));
1386 pMenu->addAction(attachUSBAction);
1387
1388 /* Check if that USB device was already attached to this session: */
1389 CConsole console = session().GetConsole();
1390 CUSBDevice attachedDevice = console.FindUSBDeviceById(device.GetId());
1391 attachUSBAction->setChecked(!attachedDevice.isNull());
1392 attachUSBAction->setEnabled(hostDevice.GetState() != KUSBDeviceState_Unavailable);
1393
1394 /* Set USB attach data: */
1395 attachUSBAction->setData(QVariant::fromValue(USBTarget(!attachUSBAction->isChecked(), device.GetId())));
1396 attachUSBAction->setToolTip(vboxGlobal().toolTip(device));
1397 }
1398 }
1399}
1400
1401void UIMachineLogic::sltAttachUSBDevice()
1402{
1403 /* Get sender action: */
1404 QAction *action = qobject_cast<QAction*>(sender());
1405 AssertMsg(action, ("This slot should only be called on selecting USB menu item!\n"));
1406
1407 /* Get current console: */
1408 CConsole console = session().GetConsole();
1409
1410 /* Get USB target: */
1411 USBTarget target = action->data().value<USBTarget>();
1412 CUSBDevice device = console.FindUSBDeviceById(target.id);
1413
1414 /* Attach USB device: */
1415 if (target.attach)
1416 {
1417 console.AttachUSBDevice(target.id);
1418 if (!console.isOk())
1419 vboxProblem().cannotAttachUSBDevice(console, vboxGlobal().details(device));
1420 }
1421 else
1422 {
1423 console.DetachUSBDevice(target.id);
1424 if (!console.isOk())
1425 vboxProblem().cannotDetachUSBDevice(console, vboxGlobal().details(device));
1426 }
1427}
1428
1429void UIMachineLogic::sltSwitchVrde(bool fOn)
1430{
1431 /* Enable VRDE server if possible: */
1432 CVRDEServer server = session().GetMachine().GetVRDEServer();
1433 AssertMsg(!server.isNull(), ("VRDE server should not be null!\n"));
1434 server.SetEnabled(fOn);
1435}
1436
1437void UIMachineLogic::sltInstallGuestAdditions()
1438{
1439 /* Do not process if window(s) missed! */
1440 if (!isMachineWindowsCreated())
1441 return;
1442
1443 char strAppPrivPath[RTPATH_MAX];
1444 int rc = RTPathAppPrivateNoArch(strAppPrivPath, sizeof(strAppPrivPath));
1445 AssertRC (rc);
1446
1447 QString strSrc1 = QString(strAppPrivPath) + "/VBoxGuestAdditions.iso";
1448 QString strSrc2 = qApp->applicationDirPath() + "/additions/VBoxGuestAdditions.iso";
1449
1450 /* Check the standard image locations */
1451 if (QFile::exists(strSrc1))
1452 return uisession()->sltInstallGuestAdditionsFrom(strSrc1);
1453 else if (QFile::exists(strSrc2))
1454 return uisession()->sltInstallGuestAdditionsFrom(strSrc2);
1455
1456 /* Check for the already registered image */
1457 CVirtualBox vbox = vboxGlobal().virtualBox();
1458 QString name = QString("VBoxGuestAdditions_%1.iso").arg(vbox.GetVersion().remove("_OSE"));
1459
1460 CMediumVector vec = vbox.GetDVDImages();
1461 for (CMediumVector::ConstIterator it = vec.begin(); it != vec.end(); ++ it)
1462 {
1463 QString path = it->GetLocation();
1464 /* Compare the name part ignoring the file case */
1465 QString fn = QFileInfo(path).fileName();
1466 if (RTPathCompare(name.toUtf8().constData(), fn.toUtf8().constData()) == 0)
1467 return uisession()->sltInstallGuestAdditionsFrom(path);
1468 }
1469
1470 /* Download the required image */
1471 int result = vboxProblem().cannotFindGuestAdditions(QDir::toNativeSeparators(strSrc1), QDir::toNativeSeparators(strSrc2));
1472 if (result == QIMessageBox::Yes)
1473 {
1474 QString source = QString("http://download.virtualbox.org/virtualbox/%1/").arg(vbox.GetVersion().remove("_OSE")) + name;
1475 QString target = QDir(vboxGlobal().virtualBox().GetHomeFolder()).absoluteFilePath(name);
1476
1477 UIDownloaderAdditions *pDl = UIDownloaderAdditions::create();
1478 /* Configure the additions downloader. */
1479 pDl->setSource(source);
1480 pDl->setTarget(target);
1481 pDl->setAction(actionsPool()->action(UIActionIndex_Simple_InstallGuestTools));
1482 pDl->setParentWidget(mainMachineWindow()->machineWindow());
1483 /* After the download is finished the user may like to install the
1484 * additions.*/
1485 connect(pDl, SIGNAL(downloadFinished(const QString&)),
1486 uisession(), SLOT(sltInstallGuestAdditionsFrom(const QString&)));
1487 /* Some of the modes may show additional info of the download progress: */
1488 emit sigDownloaderAdditionsCreated();
1489 /* Start the download: */
1490 pDl->startDownload();
1491 }
1492}
1493
1494#ifdef VBOX_WITH_DEBUGGER_GUI
1495void UIMachineLogic::sltPrepareDebugMenu()
1496{
1497 /* The "Logging" item. */
1498 bool fEnabled = false;
1499 bool fChecked = false;
1500 CConsole console = session().GetConsole();
1501 if (console.isOk())
1502 {
1503 CMachineDebugger cdebugger = console.GetDebugger();
1504 if (console.isOk())
1505 {
1506 fEnabled = true;
1507 fChecked = cdebugger.GetLogEnabled() != FALSE;
1508 }
1509 }
1510 if (fEnabled != actionsPool()->action(UIActionIndex_Toggle_Logging)->isEnabled())
1511 actionsPool()->action(UIActionIndex_Toggle_Logging)->setEnabled(fEnabled);
1512 if (fChecked != actionsPool()->action(UIActionIndex_Toggle_Logging)->isChecked())
1513 actionsPool()->action(UIActionIndex_Toggle_Logging)->setChecked(fChecked);
1514}
1515
1516void UIMachineLogic::sltShowDebugStatistics()
1517{
1518 if (dbgCreated())
1519 m_pDbgGuiVT->pfnShowStatistics(m_pDbgGui);
1520}
1521
1522void UIMachineLogic::sltShowDebugCommandLine()
1523{
1524 if (dbgCreated())
1525 m_pDbgGuiVT->pfnShowCommandLine(m_pDbgGui);
1526}
1527
1528void UIMachineLogic::sltLoggingToggled(bool fState)
1529{
1530 NOREF(fState);
1531 CConsole console = session().GetConsole();
1532 if (console.isOk())
1533 {
1534 CMachineDebugger cdebugger = console.GetDebugger();
1535 if (console.isOk())
1536 cdebugger.SetLogEnabled(fState);
1537 }
1538}
1539#endif
1540
1541#ifdef Q_WS_MAC
1542void UIMachineLogic::sltDockPreviewModeChanged(QAction *pAction)
1543{
1544 CMachine machine = m_pSession->session().GetMachine();
1545 if (!machine.isNull())
1546 {
1547 bool fEnabled = true;
1548 if (pAction == actionsPool()->action(UIActionIndex_Toggle_DockDisableMonitor))
1549 fEnabled = false;
1550
1551 machine.SetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateEnabled, fEnabled ? "true" : "false");
1552 updateDockOverlay();
1553 }
1554}
1555
1556void UIMachineLogic::sltDockPreviewMonitorChanged(QAction *pAction)
1557{
1558 CMachine machine = m_pSession->session().GetMachine();
1559 if (!machine.isNull())
1560 {
1561 int monitor = pAction->data().toInt();
1562 machine.SetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateMonitor, QString::number(monitor));
1563 updateDockOverlay();
1564 }
1565}
1566
1567void UIMachineLogic::sltChangeDockIconUpdate(bool fEnabled)
1568{
1569 if (isMachineWindowsCreated())
1570 {
1571 setDockIconPreviewEnabled(fEnabled);
1572 if (m_pDockPreviewSelectMonitorGroup)
1573 {
1574 m_pDockPreviewSelectMonitorGroup->setEnabled(fEnabled);
1575 CMachine machine = session().GetMachine();
1576 m_DockIconPreviewMonitor = qMin(machine.GetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateMonitor).toInt(), (int)machine.GetMonitorCount() - 1);
1577 }
1578 /* Resize the dock icon in the case the preview monitor has changed. */
1579 QSize size = machineWindows().at(m_DockIconPreviewMonitor)->machineView()->size();
1580 updateDockIconSize(m_DockIconPreviewMonitor, size.width(), size.height());
1581 updateDockOverlay();
1582 }
1583}
1584#endif /* Q_WS_MAC */
1585
1586int UIMachineLogic::searchMaxSnapshotIndex(const CMachine &machine,
1587 const CSnapshot &snapshot,
1588 const QString &strNameTemplate)
1589{
1590 int iMaxIndex = 0;
1591 QRegExp regExp(QString("^") + strNameTemplate.arg("([0-9]+)") + QString("$"));
1592 if (!snapshot.isNull())
1593 {
1594 /* Check the current snapshot name */
1595 QString strName = snapshot.GetName();
1596 int iPos = regExp.indexIn(strName);
1597 if (iPos != -1)
1598 iMaxIndex = regExp.cap(1).toInt() > iMaxIndex ? regExp.cap(1).toInt() : iMaxIndex;
1599 /* Traversing all the snapshot children */
1600 foreach (const CSnapshot &child, snapshot.GetChildren())
1601 {
1602 int iMaxIndexOfChildren = searchMaxSnapshotIndex(machine, child, strNameTemplate);
1603 iMaxIndex = iMaxIndexOfChildren > iMaxIndex ? iMaxIndexOfChildren : iMaxIndex;
1604 }
1605 }
1606 return iMaxIndex;
1607}
1608
1609#ifdef VBOX_WITH_DEBUGGER_GUI
1610bool UIMachineLogic::dbgCreated()
1611{
1612 if (m_pDbgGui)
1613 return true;
1614
1615 RTLDRMOD hLdrMod = vboxGlobal().getDebuggerModule();
1616 if (hLdrMod == NIL_RTLDRMOD)
1617 return false;
1618
1619 PFNDBGGUICREATE pfnGuiCreate;
1620 int rc = RTLdrGetSymbol(hLdrMod, "DBGGuiCreate", (void**)&pfnGuiCreate);
1621 if (RT_SUCCESS(rc))
1622 {
1623 ISession *pISession = session().raw();
1624 rc = pfnGuiCreate(pISession, &m_pDbgGui, &m_pDbgGuiVT);
1625 if (RT_SUCCESS(rc))
1626 {
1627 if (DBGGUIVT_ARE_VERSIONS_COMPATIBLE(m_pDbgGuiVT->u32Version, DBGGUIVT_VERSION) ||
1628 m_pDbgGuiVT->u32EndVersion == m_pDbgGuiVT->u32Version)
1629 {
1630 m_pDbgGuiVT->pfnSetParent(m_pDbgGui, defaultMachineWindow()->machineWindow());
1631 m_pDbgGuiVT->pfnSetMenu(m_pDbgGui, actionsPool()->action(UIActionIndex_Menu_Debug));
1632 dbgAdjustRelativePos();
1633 return true;
1634 }
1635
1636 LogRel(("DBGGuiCreate failed, incompatible versions (loaded %#x/%#x, expected %#x)\n",
1637 m_pDbgGuiVT->u32Version, m_pDbgGuiVT->u32EndVersion, DBGGUIVT_VERSION));
1638 }
1639 else
1640 LogRel(("DBGGuiCreate failed, rc=%Rrc\n", rc));
1641 }
1642 else
1643 LogRel(("RTLdrGetSymbol(,\"DBGGuiCreate\",) -> %Rrc\n", rc));
1644
1645 m_pDbgGui = 0;
1646 m_pDbgGuiVT = 0;
1647 return false;
1648}
1649
1650void UIMachineLogic::dbgDestroy()
1651{
1652 if (m_pDbgGui)
1653 {
1654 m_pDbgGuiVT->pfnDestroy(m_pDbgGui);
1655 m_pDbgGui = 0;
1656 m_pDbgGuiVT = 0;
1657 }
1658}
1659
1660void UIMachineLogic::dbgAdjustRelativePos()
1661{
1662 if (m_pDbgGui)
1663 {
1664 QRect rct = defaultMachineWindow()->machineWindow()->frameGeometry();
1665 m_pDbgGuiVT->pfnAdjustRelativePos(m_pDbgGui, rct.x(), rct.y(), rct.width(), rct.height());
1666 }
1667}
1668#endif
1669
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use