UIMachineLogic.cpp revision e009c4337a160bcb2a46d7ec828d0016bf5627c5
/* $Id$ */
/** @file
*
* VBox frontends: Qt GUI ("VirtualBox"):
* UIMachineLogic class implementation
*/
/*
* Copyright (C) 2010-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/* Qt includes: */
#include <QDesktopWidget>
#include <QDir>
#include <QFileInfo>
#include <QImageWriter>
#include <QPainter>
#include <QTimer>
#ifdef Q_WS_MAC
# include <QMenuBar>
#endif /* Q_WS_MAC */
/* GUI includes: */
#include "QIFileDialog.h"
#include "UIActionPoolRuntime.h"
#include "UINetworkManager.h"
#include "UIDownloaderAdditions.h"
#include "UIIconPool.h"
#include "UIKeyboardHandler.h"
#include "UIMouseHandler.h"
#include "UIMachineLogic.h"
#include "UIMachineLogicFullscreen.h"
#include "UIMachineLogicNormal.h"
#include "UIMachineLogicSeamless.h"
#include "UIMachineLogicScale.h"
#include "UIMachineView.h"
#include "UIMachineWindow.h"
#include "UISession.h"
#include "VBoxGlobal.h"
#include "UIMessageCenter.h"
#include "VBoxTakeSnapshotDlg.h"
#include "VBoxVMInformationDlg.h"
#include "UISettingsDialogSpecific.h"
#include "UIVMLogViewer.h"
#include "UIConverter.h"
#ifdef Q_WS_MAC
# include "DockIconPreview.h"
# include "UIExtraDataEventHandler.h"
#endif /* Q_WS_MAC */
/* COM includes: */
#include "CVirtualBoxErrorInfo.h"
#include "CMachineDebugger.h"
#include "CSnapshot.h"
#include "CDisplay.h"
#include "CStorageController.h"
#include "CMediumAttachment.h"
#include "CHostUSBDevice.h"
#include "CUSBDevice.h"
#include "CVRDEServer.h"
#include "CSystemProperties.h"
#ifdef Q_WS_MAC
# include "CGuest.h"
#endif /* Q_WS_MAC */
/* Other VBox includes: */
#ifdef VBOX_WITH_DEBUGGER_GUI
#endif /* VBOX_WITH_DEBUGGER_GUI */
/* External includes: */
#ifdef Q_WS_X11
# include <XKeyboard.h>
# include <QX11Info>
#endif /* Q_WS_X11 */
struct MediumTarget
{
MediumTarget() : name(QString("")), port(0), device(0), id(QString()), type(UIMediumType_Invalid) {}
};
struct RecentMediumTarget
{
RecentMediumTarget() : name(QString("")), port(0), device(0), location(QString()), type(UIMediumType_Invalid) {}
RecentMediumTarget(const QString &strName, LONG iPort, LONG iDevice, const QString &strLocation, UIMediumType eType)
};
struct USBTarget
{
bool attach;
};
/* static */
{
UIMachineLogic *pLogic = 0;
switch (visualStateType)
{
case UIVisualStateType_Normal:
break;
break;
break;
case UIVisualStateType_Scale:
break;
}
return pLogic;
}
/* static */
{
delete pWhichLogic;
}
void UIMachineLogic::prepare()
{
/* Prepare required features: */
/* Prepare session connections: */
/* Prepare action groups:
* Note: This has to be done before prepareActionConnections
/* Prepare action connections: */
/* Prepare other connections: */
/* Prepare handlers: */
/* Prepare machine window(s): */
#ifdef Q_WS_MAC
/* Prepare menu-bar: */
/* Prepare dock: */
prepareDock();
#endif /* Q_WS_MAC */
/* Power up machine: */
/* Initialization: */
#ifdef VBOX_WITH_DEBUGGER_GUI
/* Prepare debugger: */
#endif /* VBOX_WITH_DEBUGGER_GUI */
/* Retranslate logic part: */
}
void UIMachineLogic::cleanup()
{
#ifdef VBOX_WITH_DEBUGGER_GUI
/* Cleanup debugger: */
#endif /* VBOX_WITH_DEBUGGER_GUI */
#ifdef Q_WS_MAC
/* Cleanup dock: */
cleanupDock();
/* Cleanup menu-bar: */
#endif /* Q_WS_MAC */
/* Cleanup machine window(s): */
/* Cleanup handlers: */
/* Cleanup action groups: */
}
{
}
{
/* Return null if windows are not created yet: */
if (!isMachineWindowsCreated())
return 0;
/* Otherwise return first of windows: */
return machineWindows()[0];
}
{
/* Return null if windows are not created yet: */
if (!isMachineWindowsCreated())
return 0;
/* Check if there is an active window present: */
for (int i = 0; i < machineWindows().size(); ++i)
{
if (pIteratedWindow->isActiveWindow())
return pIteratedWindow;
}
/* Return main machine window: */
return mainMachineWindow();
}
#ifdef Q_WS_MAC
void UIMachineLogic::updateDockIcon()
{
if (!isMachineWindowsCreated())
return;
if ( m_fIsDockIconEnabled
{
}
}
{
if (!isMachineWindowsCreated())
return;
if ( m_fIsDockIconEnabled
&& m_DockIconPreviewMonitor == screenId)
}
{
if ( m_fIsDockIconEnabled
return 0;
}
#endif /* Q_WS_MAC */
void UIMachineLogic::sltMachineStateChanged()
{
/* Get machine state: */
/* Update action groups: */
switch (state)
{
case KMachineState_Stuck: // TODO: Test it!
{
/* Prevent machine view from resizing: */
uisession()->setGuestResizeIgnored(true);
/* Get console and log folder. */
/* Take the screenshot for debugging purposes and save it. */
/* Warn the user about GURU: */
{
}
break;
}
case KMachineState_Paused:
{
if (!pPauseAction->isChecked())
{
/* Was paused from CSession side: */
pPauseAction->blockSignals(true);
pPauseAction->setChecked(true);
pPauseAction->blockSignals(false);
}
break;
}
case KMachineState_Running:
{
if (pPauseAction->isChecked())
{
/* Was resumed from CSession side: */
pPauseAction->blockSignals(true);
pPauseAction->setChecked(false);
pPauseAction->blockSignals(false);
}
break;
}
case KMachineState_PoweredOff:
case KMachineState_Saved:
case KMachineState_Teleported:
case KMachineState_Aborted:
{
/* Close VM if it was turned off and closure allowed: */
if (!isPreventAutoClose())
{
/* VM has been powered off, saved or aborted, no matter
* internally or externally. We must *safely* close VM window(s): */
}
break;
}
#ifdef Q_WS_X11
case KMachineState_Starting:
case KMachineState_Restoring:
{
/* The keyboard handler may wish to do some release logging on startup.
* Tell it that the logger is now active. */
break;
}
#endif
default:
break;
}
#ifdef Q_WS_MAC
/* Update Dock Overlay: */
#endif /* Q_WS_MAC */
}
{
/* Update action states: */
gActionPool->action(UIActionIndexRuntime_Toggle_GuestAutoresize)->setEnabled(uisession()->isGuestSupportsGraphics());
gActionPool->action(UIActionIndexRuntime_Toggle_Seamless)->setEnabled(uisession()->isGuestSupportsSeamless());
}
{
/* Variable falgs: */
/* Update action state: */
pAction->setEnabled(fIsMouseSupportsAbsolute && fIsMouseSupportsRelative && !fIsMouseHostCursorNeeded);
pAction->setChecked(false);
}
void UIMachineLogic::sltUSBDeviceStateChange(const CUSBDevice &device, bool fIsAttached, const CVirtualBoxErrorInfo &error)
{
/* Check if USB device have anything to tell us: */
{
if (fIsAttached)
else
}
}
void UIMachineLogic::sltRuntimeError(bool fIsFatal, const QString &strErrorId, const QString &strMessage)
{
}
#ifdef Q_WS_MAC
void UIMachineLogic::sltShowWindows()
{
for (int i=0; i < machineWindows().size(); ++i)
{
/* Dunno what Qt thinks a window that has minimized to the dock
* should be - it is not hidden, neither is it minimized. OTOH it is
* marked shown and visible, but not activated. This latter isn't of
* much help though, since at this point nothing is marked activated.
* I might have overlooked something, but I'm buggered what if I know
* what. So, I'll just always show & activate the stupid window to
* make it get out of the dock when the user wishes to show a VM. */
pMachineWindow->raise();
}
}
#endif /* Q_WS_MAC */
{
/* Deliver event to corresponding machine-window: */
}
{
/* Deliver event to all machine-windows: */
}
UIMachineLogic::UIMachineLogic(QObject *pParent, UISession *pSession, UIVisualStateType visualStateType)
, m_pKeyboardHandler(0)
, m_pMouseHandler(0)
, m_pRunningActions(0)
, m_fIsWindowsCreated(false)
, m_fIsPreventAutoClose(false)
#ifdef VBOX_WITH_DEBUGGER_GUI
, m_pDbgGui(0)
, m_pDbgGuiVT(0)
#endif /* VBOX_WITH_DEBUGGER_GUI */
#ifdef Q_WS_MAC
, m_pMenuBar(0)
, m_fIsDockIconEnabled(true)
, m_pDockIconPreview(0)
#endif /* Q_WS_MAC */
{
}
{
}
{
}
{
}
void UIMachineLogic::retranslateUi()
{
#ifdef Q_WS_MAC
{
{
pAction->setText(QApplication::translate("UIMachineLogic", "Preview Monitor %1").arg(pAction->data().toInt() + 1));
}
}
#endif /* Q_WS_MAC */
/* Shared Clipboard actions: */
{
}
{
}
}
#ifdef Q_WS_MAC
void UIMachineLogic::updateDockOverlay()
{
/* Only to an update to the realtime preview if this is enabled by the user
* & we are in an state where the framebuffer is likely valid. Otherwise to
* the overlay stuff only. */
if (m_fIsDockIconEnabled &&
(state == KMachineState_Running ||
state == KMachineState_Paused ||
state == KMachineState_Restoring ||
state == KMachineState_Saving ||
else if (m_pDockIconPreview)
}
#endif /* Q_WS_MAC */
{
#ifdef Q_WS_MAC
# ifdef VBOX_WITH_ICHAT_THEATER
/* Init shared AV manager: */
# endif /* VBOX_WITH_ICHAT_THEATER */
#endif /* Q_WS_MAC */
}
{
/* Machine state-change updater: */
/* Guest additions state-change updater: */
/* Mouse capability state-change updater: */
/* USB devices state-change updater: */
connect(uisession(), SIGNAL(sigUSBDeviceStateChange(const CUSBDevice &, bool, const CVirtualBoxErrorInfo &)),
/* Runtime errors notifier: */
#ifdef Q_WS_MAC
/* Show windows: */
#endif /* Q_WS_MAC */
/* Guest-monitor-change updater: */
/* Host-screen-change updater: */
this, SLOT(sltHostScreenCountChanged(int)));
}
void UIMachineLogic::prepareActionGroups()
{
#ifdef Q_WS_MAC
/* On Mac OS X, all QMenu's are consumed by Qt after they are added to
* another QMenu or a QMenuBar. This means we have to recreate all QMenus
* when creating a new QMenuBar. */
#endif /* Q_WS_MAC */
/* Create group for all actions that are enabled only when the VM is running.
* Note that only actions whose enabled state depends exclusively on the
* execution state of the VM are added to this group. */
m_pRunningActions = new QActionGroup(this);
m_pRunningActions->setExclusive(false);
/* Create group for all actions that are enabled when the VM is running or paused.
* Note that only actions whose enabled state depends exclusively on the
* execution state of the VM are added to this group. */
m_pRunningOrPausedActions = new QActionGroup(this);
m_pRunningOrPausedActions->setExclusive(false);
/* Move actions into running actions group: */
#ifdef Q_WS_X11
#endif
/* Move actions into running-n-paused actions group: */
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_SettingsDialog));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_TakeSnapshot));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_TakeScreenshot));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_InformationDialog));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_MouseIntegration));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_MouseIntegration));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_OpticalDevices));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_SharedClipboard));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_NetworkAdapters));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_NetworkAdaptersDialog));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_SharedFoldersDialog));
m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_InstallGuestTools));
}
{
/* "Machine" actions connections: */
this, SLOT(sltOpenVMSettingsDialog()));
this, SLOT(sltTakeSnapshot()));
this, SLOT(sltTakeScreenshot()));
this, SLOT(sltShowInformationDialog()));
this, SLOT(sltToggleMouseIntegration(bool)));
this, SLOT(sltTypeCAD()));
#ifdef Q_WS_X11
this, SLOT(sltTypeCABS()));
#endif
this, SLOT(sltACPIShutdown()));
/* "View" actions connections: */
this, SLOT(sltToggleGuestAutoresize(bool)));
this, SLOT(sltAdjustWindow()));
/* "Devices" actions connections: */
connect(gActionPool->action(UIActionIndexRuntime_Menu_OpticalDevices)->menu(), SIGNAL(aboutToShow()),
this, SLOT(sltPrepareStorageMenu()));
connect(gActionPool->action(UIActionIndexRuntime_Menu_FloppyDevices)->menu(), SIGNAL(aboutToShow()),
this, SLOT(sltPrepareStorageMenu()));
this, SLOT(sltPrepareUSBMenu()));
connect(gActionPool->action(UIActionIndexRuntime_Menu_SharedClipboard)->menu(), SIGNAL(aboutToShow()),
this, SLOT(sltPrepareSharedClipboardMenu()));
this, SLOT(sltPrepareDragAndDropMenu()));
connect(gActionPool->action(UIActionIndexRuntime_Simple_NetworkAdaptersDialog), SIGNAL(triggered()),
this, SLOT(sltOpenNetworkAdaptersDialog()));
this, SLOT(sltOpenSharedFoldersDialog()));
this, SLOT(sltSwitchVrde(bool)));
this, SLOT(sltInstallGuestAdditions()));
#ifdef VBOX_WITH_DEBUGGER_GUI
/* "Debug" actions connections: */
this, SLOT(sltPrepareDebugMenu()));
this, SLOT(sltShowDebugStatistics()));
this, SLOT(sltShowDebugCommandLine()));
this, SLOT(sltLoggingToggled(bool)));
this, SLOT(sltShowLogDialog()));
#endif
}
void UIMachineLogic::prepareHandlers()
{
/* Create keyboard-handler: */
/* Create mouse-handler: */
}
#ifdef Q_WS_MAC
void UIMachineLogic::prepareMenuBar()
{
}
void UIMachineLogic::prepareDock()
{
/* Add all VM menu entries to the dock menu. Leave out close and stuff like
* this. */
QList<QAction*> actions = gActionPool->action(UIActionIndexRuntime_Menu_Machine)->menu()->actions();
QAction *pDockEnablePreviewMonitor = gActionPool->action(UIActionIndexRuntime_Toggle_DockPreviewMonitor);
this, SLOT(sltChangeDockIconUpdate(bool)));
/* Monitor selection if there are more than one monitor */
if (cGuestScreens > 1)
{
m_DockIconPreviewMonitor = qMin(session().GetMachine().GetExtraData(GUI_RealtimeDockIconUpdateMonitor).toInt(), cGuestScreens - 1);
m_pDockPreviewSelectMonitorGroup = new QActionGroup(this);
for (int i = 0; i < cGuestScreens; ++i)
{
pAction->setCheckable(true);
if (m_DockIconPreviewMonitor == i)
pAction->setChecked(true);
}
}
/* Add it to the dock. */
/* Now the dock icon preview */
/* Default to true if it is an empty value */
if (f)
pDockEnablePreviewMonitor->setChecked(true);
else
{
pDockDisablePreview->setChecked(true);
}
/* Default to true if it is an empty value */
}
#endif /* Q_WS_MAC */
#ifdef VBOX_WITH_DEBUGGER_GUI
void UIMachineLogic::prepareDebugger()
{
{
/* console in upper left corner of the desktop. */
// QRect rct (0, 0, 0, 0);
// QDesktopWidget *desktop = QApplication::desktop();
// if (desktop)
// rct = desktop->availableGeometry(pos());
// move (QPoint (rct.x(), rct.y()));
if (!vboxGlobal().isStartPausedEnabled())
sltPause(false);
}
}
#endif /* VBOX_WITH_DEBUGGER_GUI */
#ifdef VBOX_WITH_DEBUGGER_GUI
void UIMachineLogic::cleanupDebugger()
{
/* Close debugger: */
dbgDestroy();
}
#endif /* VBOX_WITH_DEBUGGER_GUI */
#ifdef Q_WS_MAC
void UIMachineLogic::cleanupDock()
{
if (m_pDockIconPreview)
{
delete m_pDockIconPreview;
m_pDockIconPreview = 0;
}
}
void UIMachineLogic::cleanupMenuBar()
{
delete m_pMenuBar;
m_pMenuBar = 0;
}
#endif /* Q_WS_MAC */
void UIMachineLogic::cleanupHandlers()
{
/* Cleanup mouse-handler: */
/* Cleanup keyboard-handler: */
}
void UIMachineLogic::cleanupActionGroups()
{
}
void UIMachineLogic::sltCheckRequestedModes()
{
/* Do not try to enter extended mode if machine was not started yet: */
return;
/* If seamless mode is requested, supported and we are NOT currently in seamless mode: */
if (uisession()->isSeamlessModeRequested() &&
uisession()->isGuestSupportsSeamless() &&
{
uisession()->setSeamlessModeRequested(false);
AssertMsg(!pSeamlessModeAction->isChecked(), ("Seamless action should not be triggered before us!\n"));
}
/* If seamless mode is NOT requested, NOT supported and we are currently in seamless mode: */
else if (!uisession()->isSeamlessModeRequested() &&
!uisession()->isGuestSupportsSeamless() &&
{
uisession()->setSeamlessModeRequested(true);
AssertMsg(pSeamlessModeAction->isChecked(), ("Seamless action should not be triggered before us!\n"));
}
}
{
/* Do not process if window(s) missed! */
if (!isMachineWindowsCreated())
return;
/* Toggle guest-autoresize feature for all view(s)! */
}
void UIMachineLogic::sltAdjustWindow()
{
/* Do not process if window(s) missed! */
if (!isMachineWindowsCreated())
return;
/* Adjust all window(s)! */
{
/* Exit maximized window state if actual: */
if (pMachineWindow->isMaximized())
/* Normalize view's geometry: */
}
}
{
/* Do not process if window(s) missed! */
if (!isMachineWindowsCreated())
return;
}
void UIMachineLogic::sltTypeCAD()
{
}
#ifdef Q_WS_X11
void UIMachineLogic::sltTypeCABS()
{
}
#endif /* Q_WS_X11 */
void UIMachineLogic::sltTakeSnapshot()
{
/* Do not process if window(s) missed! */
if (!isMachineWindowsCreated())
return;
/* Remember the paused state: */
if (!fWasPaused)
{
/* Suspend the VM and ignore the close event if failed to do so.
* pause() will show the error message to the user. */
return;
}
/* Get current machine: */
/* Create take-snapshot dialog: */
/* Assign corresponding icon: */
/* Search for the max available filter index: */
int iMaxSnapshotIndex = searchMaxSnapshotIndex(machine, machine.FindSnapshot(QString()), strNameTemplate);
/* Exec the dialog: */
/* Is the dialog still valid? */
if (pDlg)
{
/* Acquire variables: */
/* Destroy dialog early: */
delete pDlg;
/* Was the dialog accepted? */
if (fDialogAccepted)
{
/* Prepare the take-snapshot progress: */
{
/* Show the take-snapshot progress: */
msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_snapshot_create_90px.png", 0, true);
if (progress.GetResultCode() != 0)
}
else
}
}
/* Restore the running state if needed: */
if (!fWasPaused)
{
/* Make sure machine-state-change callback is processed: */
/* Unpause VM: */
}
}
void UIMachineLogic::sltTakeScreenshot()
{
/* Do not process if window(s) missed! */
if (!isMachineWindowsCreated())
return;
/* Which image formats for writing does this Qt version know of? */
/* Build a filters list out of it. */
{
/* Check there isn't an entry already (even if it just uses another capitalization) */
filters << s;
}
/* Try to select some common defaults. */
if (i == -1)
{
if (i == -1)
}
if (i != -1)
{
}
#ifdef Q_WS_WIN
/* Due to Qt bug, modal QFileDialog appeared above the active machine-window
* does not retreive the focus from the currently focused machine-view,
* as the result guest keyboard remains captured, so we should
* clear the focus from this machine-view initially: */
if (activeMachineWindow())
#endif /* Q_WS_WIN */
/* Request the filename from the user. */
tr("Select a filename for the screenshot ..."),
true /* resolve symlinks */,
true /* confirm overwrite */);
#ifdef Q_WS_WIN
/* Due to Qt bug, modal QFileDialog appeared above the active machine-window
* does not retreive the focus from the currently focused machine-view,
* as the result guest keyboard remains captured, so we already
* cleared the focus from this machine-view and should return
* that focus finally: */
if (activeMachineWindow())
#endif /* Q_WS_WIN */
/* Do the screenshot. */
if (!strFilename.isEmpty())
}
{
/* Do not process if window(s) missed! */
if (!isMachineWindowsCreated())
return;
}
void UIMachineLogic::sltReset()
{
if (msgCenter().confirmVMReset(0))
/* TODO_NEW_CORE: On reset the additional screens didn't get a display
update. Emulate this for now until it get fixed. */
}
{
}
void UIMachineLogic::sltACPIShutdown()
{
/* Get console: */
/* Warn the user about ACPI is not available if so: */
if (!console.GetGuestEnteredACPIMode())
return msgCenter().cannotSendACPIToMachine();
/* Send ACPI shutdown signal, warn if failed: */
}
void UIMachineLogic::sltClose()
{
/* Do not process if window(s) missed! */
if (!isMachineWindowsCreated())
return;
/* Do not try to close machine-window if restricted: */
if (isPreventAutoClose())
return;
* We have to make sure such window is hidden even if close-event was rejected.
* We are re-throwing this slot if any widget present to test again.
if (pWidget)
{
return;
}
/* Try to close active machine-window: */
activeMachineWindow()->close();
}
{
/* Do not process if window(s) missed! */
if (!isMachineWindowsCreated())
return;
/* Create VM settings dialog on the heap!
* Its necessary to allow QObject hierarchy cleanup to delete this dialog if necessary: */
strCategory, QString());
/* Executing VM settings dialog.
* This blocking function calls for the internal event-loop to process all further events,
* including event which can delete the dialog itself. */
/* Delete dialog if its still valid: */
if (pDialog)
delete pDialog;
}
{
/* Open VM settings : Network page: */
sltOpenVMSettingsDialog("#network");
}
{
/* Do not process if additions are not loaded! */
if (!uisession()->isGuestAdditionsActive())
/* Open VM settings : Shared folders page: */
sltOpenVMSettingsDialog("#sharedFolders");
}
void UIMachineLogic::sltPrepareStorageMenu()
{
/* Get the sender() menu: */
/* Short way to common storage menus: */
/* Determine medium & device types: */
/* Fill attachments menu: */
{
/* Current attachment: */
/* Current controller: */
const CStorageController &controller = machine.GetStorageControllerByName(attachment.GetController());
/* If controller present and device type correct: */
{
/* Current attachment attributes: */
/* Attachment menu item: */
QMenu *pAttachmentMenu = 0;
{
attachment.GetDevice()))));
switch (controller.GetBus())
{
case KStorageBus_IDE:
case KStorageBus_SATA:
case KStorageBus_SCSI:
case KStorageBus_Floppy:
default:
break;
}
}
else pAttachmentMenu = pMenu;
/* Prepare choose-existing-medium action: */
QAction *pChooseExistingMediumAction = pAttachmentMenu->addAction(QIcon(":/select_file_16px.png"), QString(),
this, SLOT(sltMountStorageMedium()));
pChooseExistingMediumAction->setData(QVariant::fromValue(MediumTarget(controller.GetName(), attachment.GetPort(),
/* Prepare choose-particular-medium actions: */
switch (mediumType)
{
case UIMediumType_DVD:
break;
case UIMediumType_Floppy:
break;
default:
break;
}
/* Prepare choose-host-drive actions: */
{
bool fIsHostDriveUsed = false;
for (int iOtherAttachmentIndex = 0; iOtherAttachmentIndex < attachments.size(); ++iOtherAttachmentIndex)
{
if (otherAttachment != attachment)
{
{
fIsHostDriveUsed = true;
break;
}
}
}
if (!fIsHostDriveUsed)
{
this, SLOT(sltMountStorageMedium()));
pChooseHostDriveAction->setCheckable(true);
pChooseHostDriveAction->setData(QVariant::fromValue(MediumTarget(controller.GetName(), attachment.GetPort(),
}
}
/* Prepare choose-recent-medium actions: */
QStringList recentMediumList = vboxGlobal().virtualBox().GetExtraData(strRecentMediumAddress).split(';');
/* For every list-item: */
for (int i = 0; i < recentMediumList.size(); ++i)
{
{
bool fIsRecentMediumUsed = false;
for (int iOtherAttachmentIndex = 0; iOtherAttachmentIndex < attachments.size(); ++iOtherAttachmentIndex)
{
if (otherAttachment != attachment)
{
{
fIsRecentMediumUsed = true;
break;
}
}
}
if (!fIsRecentMediumUsed)
{
QAction *pChooseRecentMediumAction = pAttachmentMenu->addAction(QFileInfo(strRecentMediumLocation).fileName(),
this, SLOT(sltMountRecentStorageMedium()));
pChooseRecentMediumAction->setChecked(!currentMedium.isNull() && strRecentMediumLocation == strCurrentLocation);
pChooseRecentMediumAction->setData(QVariant::fromValue(RecentMediumTarget(controller.GetName(), attachment.GetPort(),
}
}
}
/* Insert separator: */
/* Unmount Medium action: */
attachment.GetDevice())));
switch (mediumType)
{
case UIMediumType_DVD:
pChooseExistingMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a virtual CD/DVD disk file..."));
unmountMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
":/cd_unmount_dis_16px.png"));
break;
case UIMediumType_Floppy:
pChooseExistingMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a virtual floppy disk file..."));
unmountMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
":/fd_unmount_dis_16px.png"));
break;
default:
break;
}
}
}
{
/* Empty menu item */
pEmptyMenuAction->setEnabled(false);
switch (mediumType)
{
case UIMediumType_DVD:
pEmptyMenuAction->setToolTip(QApplication::translate("UIMachineLogic", "No CD/DVD devices attached to that VM"));
break;
case UIMediumType_Floppy:
pEmptyMenuAction->setToolTip(QApplication::translate("UIMachineLogic", "No floppy devices attached to that VM"));
break;
default:
break;
}
}
}
void UIMachineLogic::sltMountStorageMedium()
{
/* Get sender action: */
/* Get current machine: */
/* Get mount-target: */
/* Current mount-target attributes: */
CMediumAttachment currentAttachment = machine.GetMediumAttachment(target.name, target.port, target.device);
/* New mount-target attributes: */
/* Open Virtual Media Manager to select image id: */
{
/* Search for already used images: */
{
}
/* To that moment application focus already returned to machine-view,
* so the keyboard already captured too.
* We should clear application focus from machine-view now
* to let file-open dialog get it. That way the keyboard will be released too: */
if (QApplication::focusWidget())
/* Call for file-open window: */
if (!strMediumId.isNull())
newId = strMediumId;
else return;
}
/* Use medium which was sent: */
bool fWasMounted = false;
fWasMounted = true;
else
{
/* Ask for force remounting: */
if (msgCenter().cannotRemountMedium(0, machine, vboxGlobal().findMedium (fMount ? newId : currentId), fMount, true /* retry? */) == QIMessageBox::Ok)
{
fWasMounted = true;
else
msgCenter().cannotRemountMedium(0, machine, vboxGlobal().findMedium (fMount ? newId : currentId), fMount, false /* retry? */);
}
}
/* Save medium mounted at runtime */
{
}
}
{
/* Get sender action: */
/* Get mount-target: */
/* Get new medium id: */
{
/* Get current machine: */
/* Get current medium id: */
const CMediumAttachment ¤tAttachment = machine.GetMediumAttachment(target.name, target.port, target.device);
/* Should we mount or unmount? */
/* Prepare target medium: */
/* 'Mounted' flag: */
bool fWasMounted = false;
fWasMounted = true;
else
{
/* Ask for force remounting: */
if (msgCenter().cannotRemountMedium(0, machine, vboxGlobal().findMedium(fMount ? strNewId : strCurrentId), fMount, true /* retry? */) == QIMessageBox::Ok)
{
fWasMounted = true;
else
msgCenter().cannotRemountMedium(0, machine, vboxGlobal().findMedium(fMount ? strNewId : strCurrentId), fMount, false /* retry? */);
}
}
/* Save medium mounted at runtime if necessary: */
{
}
}
}
void UIMachineLogic::sltPrepareUSBMenu()
{
/* Get and check the sender menu object: */
/* Clear menu initially: */
/* Get current host: */
/* Get host USB device list: */
/* Fill USB device menu: */
/* If device list is empty: */
if (fIsUSBListEmpty)
{
/* Add only one - "empty" action: */
pEmptyMenuAction->setEnabled(false);
}
/* If device list is NOT empty: */
else
{
/* Populate menu with host USB devices: */
{
/* Get current host USB device: */
/* Get USB device from current host USB device: */
/* Create USB device action: */
pAttachUSBAction->setCheckable(true);
/* Check if that USB device was already attached to this session: */
/* Set USB attach data: */
pAttachUSBAction->setData(QVariant::fromValue(USBTarget(!pAttachUSBAction->isChecked(), device.GetId())));
}
}
}
void UIMachineLogic::sltAttachUSBDevice()
{
/* Get and check sender action object: */
/* Get operation target: */
/* Get current console: */
/* Attach USB device: */
{
/* Try to attach corresponding device: */
/* Check if console is OK: */
{
/* Get current host: */
/* Search the host for the corresponding USB device: */
/* Get USB device from host USB device: */
/* Show a message about procedure failure: */
}
}
/* Detach USB device: */
else
{
/* Search the console for the corresponding USB device: */
/* Try to detach corresponding device: */
/* Check if console is OK: */
{
/* Show a message about procedure failure: */
}
}
}
{
/* Get and check the sender menu object: */
QMenu *pSharedClipboardMenu = gActionPool->action(UIActionIndexRuntime_Menu_SharedClipboard)->menu();
AssertMsg(pMenu == pSharedClipboardMenu, ("This slot should only be called on hovering Shared Clipboard menu!\n"));
/* First run: */
{
m_pSharedClipboardActions = new QActionGroup(this);
for (int i = KClipboardMode_Disabled; i < KClipboardMode_Max; ++i)
{
pAction->setCheckable(true);
}
}
/* Subsequent runs: */
else
pAction->setChecked(true);
}
{
/* Assign new mode (without save): */
}
{
/* Get and check the sender menu object: */
AssertMsg(pMenu == pDragAndDropMenu, ("This slot should only be called on hovering Drag'n'drop menu!\n"));
/* First run: */
if (!m_pDragAndDropActions)
{
m_pDragAndDropActions = new QActionGroup(this);
for (int i = KDragAndDropMode_Disabled; i < KDragAndDropMode_Max; ++i)
{
pAction->setCheckable(true);
}
}
/* Subsequent runs: */
else
pAction->setChecked(true);
}
{
/* Assign new mode (without save): */
}
{
/* Enable VRDE server if possible: */
}
{
/* Do not process if window(s) missed! */
if (!isMachineWindowsCreated())
return;
/* Check for the already registered image */
const QString &name = QString("VBoxGuestAdditions_%1.iso").arg(vboxGlobal().vboxVersionStringNormalized());
{
/* Compare the name part ignoring the file case */
}
/* If downloader is running already: */
if (UIDownloaderAdditions::current())
{
/* Just show network access manager: */
gNetworkManager->show();
}
/* Else propose to download additions: */
else if (msgCenter().cannotFindGuestAdditions())
{
/* Create Additions downloader: */
/* After downloading finished => propose to install the Additions: */
connect(pDl, SIGNAL(sigDownloadFinished(const QString&)), uisession(), SLOT(sltInstallGuestAdditionsFrom(const QString&)));
/* Start downloading: */
}
}
#ifdef VBOX_WITH_DEBUGGER_GUI
void UIMachineLogic::sltPrepareDebugMenu()
{
/* The "Logging" item. */
bool fEnabled = false;
bool fChecked = false;
{
{
fEnabled = true;
}
}
}
void UIMachineLogic::sltShowDebugStatistics()
{
if (dbgCreated())
{
}
}
{
if (dbgCreated())
{
}
}
{
{
}
}
void UIMachineLogic::sltShowLogDialog()
{
/* Show VM Log Viewer: */
}
#endif /* VBOX_WITH_DEBUGGER_GUI */
#ifdef Q_WS_MAC
{
{
bool fEnabled = true;
fEnabled = false;
}
}
{
{
}
}
{
if (isMachineWindowsCreated())
{
{
m_DockIconPreviewMonitor = qMin(machine.GetExtraData(GUI_RealtimeDockIconUpdateMonitor).toInt(), (int)machine.GetMonitorCount() - 1);
}
/* Resize the dock icon in the case the preview monitor has changed. */
}
}
#endif /* Q_WS_MAC */
const QString &strNameTemplate)
{
int iMaxIndex = 0;
{
/* Check the current snapshot name */
if (iPos != -1)
/* Traversing all the snapshot children */
{
}
}
return iMaxIndex;
}
void UIMachineLogic::takeScreenshot(const QString &strFile, const QString &strFormat /* = "png" */) const
{
/* Get console: */
ULONG uMaxHeight = 0;
/* First create screenshots of all guest screens and save them in a list.
* Also sum the width of all images and search for the biggest image height. */
for (int i = 0; i < cGuestScreens; ++i)
{
}
/* Create a image which will hold all sub images vertically. */
ULONG w = 0;
/* Paint them. */
{
}
p.end();
/* Save the big image in the requested format: */
bigImg.save(QDir::toNativeSeparators(QFile::encodeName(QString("%1.%2").arg(strPathWithoutSuffix, strSuffix))),
}
#ifdef VBOX_WITH_DEBUGGER_GUI
bool UIMachineLogic::dbgCreated()
{
if (m_pDbgGui)
return true;
if (hLdrMod == NIL_RTLDRMOD)
return false;
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
{
{
return true;
}
LogRel(("DBGGuiCreate failed, incompatible versions (loaded %#x/%#x, expected %#x)\n",
}
else
}
else
m_pDbgGui = 0;
m_pDbgGuiVT = 0;
return false;
}
void UIMachineLogic::dbgDestroy()
{
if (m_pDbgGui)
{
m_pDbgGui = 0;
m_pDbgGuiVT = 0;
}
}
void UIMachineLogic::dbgAdjustRelativePos()
{
if (m_pDbgGui)
{
}
}
#endif