1 | /** @file
|
---|
2 | *
|
---|
3 | * VBox frontends: Qt GUI ("VirtualBox"):
|
---|
4 | * VBoxSelectorWnd class implementation
|
---|
5 | */
|
---|
6 |
|
---|
7 | /*
|
---|
8 | * Copyright (C) 2006-2010 Oracle Corporation
|
---|
9 | *
|
---|
10 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
11 | * available from http://www.virtualbox.org. This file is free software;
|
---|
12 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
13 | * General Public License (GPL) as published by the Free Software
|
---|
14 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
15 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
16 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
17 | */
|
---|
18 |
|
---|
19 | #ifdef VBOX_WITH_PRECOMPILED_HEADERS
|
---|
20 | # include "precomp.h"
|
---|
21 | #else /* !VBOX_WITH_PRECOMPILED_HEADERS */
|
---|
22 | #include "QISplitter.h"
|
---|
23 | #include "UIBar.h"
|
---|
24 | #include "UIDownloaderUserManual.h"
|
---|
25 | #include "UIExportApplianceWzd.h"
|
---|
26 | #include "UIIconPool.h"
|
---|
27 | #include "UIImportApplianceWzd.h"
|
---|
28 | #include "UINewVMWzd.h"
|
---|
29 | #include "UIVMDesktop.h"
|
---|
30 | #include "UIVMListView.h"
|
---|
31 | #include "UIVirtualBoxEventHandler.h"
|
---|
32 | #include "VBoxGlobal.h"
|
---|
33 | #include "VBoxMediaManagerDlg.h"
|
---|
34 | #include "VBoxProblemReporter.h"
|
---|
35 | #include "VBoxSelectorWnd.h"
|
---|
36 | #include "UISettingsDialogSpecific.h"
|
---|
37 | #include "UIToolBar.h"
|
---|
38 | #include "VBoxVMLogViewer.h"
|
---|
39 | #include "QIFileDialog.h"
|
---|
40 | #include "UISelectorShortcuts.h"
|
---|
41 | #include "UIDesktopServices.h"
|
---|
42 | #include "UIGlobalSettingsExtension.h" /* extension pack installation */
|
---|
43 |
|
---|
44 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
45 | # include "VBoxTrayIcon.h"
|
---|
46 | # include "UIExtraDataEventHandler.h"
|
---|
47 | #endif /* VBOX_GUI_WITH_SYSTRAY */
|
---|
48 |
|
---|
49 | #ifdef Q_WS_MAC
|
---|
50 | # include "VBoxUtils.h"
|
---|
51 | # include "UIWindowMenuManager.h"
|
---|
52 | # include "UIImageTools.h"
|
---|
53 | #endif
|
---|
54 |
|
---|
55 | /* Global includes */
|
---|
56 | #include <QDesktopWidget>
|
---|
57 | #include <QMenuBar>
|
---|
58 | #include <QResizeEvent>
|
---|
59 | #include <QDesktopServices>
|
---|
60 |
|
---|
61 | #include <iprt/buildconfig.h>
|
---|
62 | #include <VBox/version.h>
|
---|
63 | #ifdef Q_WS_X11
|
---|
64 | # include <iprt/env.h>
|
---|
65 | #endif
|
---|
66 | #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
|
---|
67 |
|
---|
68 | // VBoxSelectorWnd class
|
---|
69 | ////////////////////////////////////////////////////////////////////////////////
|
---|
70 |
|
---|
71 | /** \class VBoxSelectorWnd
|
---|
72 | *
|
---|
73 | * The VBoxSelectorWnd class is a VM selector window, one of two main VBox
|
---|
74 | * GUI windows.
|
---|
75 | *
|
---|
76 | * This window appears when the user starts the VirtualBox executable.
|
---|
77 | * It allows to view the list of configured VMs, their settings
|
---|
78 | * and the current state, create, reconfigure, delete and start VMs.
|
---|
79 | */
|
---|
80 |
|
---|
81 | /**
|
---|
82 | * Constructs the VM selector window.
|
---|
83 | *
|
---|
84 | * @param aSelf pointer to a variable where to store |this| right after
|
---|
85 | * this object's constructor is called (necessary to avoid
|
---|
86 | * recursion in VBoxGlobal::selectorWnd())
|
---|
87 | */
|
---|
88 | VBoxSelectorWnd::
|
---|
89 | VBoxSelectorWnd(VBoxSelectorWnd **aSelf, QWidget* aParent,
|
---|
90 | Qt::WindowFlags aFlags /* = Qt::Window */)
|
---|
91 | : QIWithRetranslateUI2<QMainWindow>(aParent, aFlags)
|
---|
92 | , mDoneInaccessibleWarningOnce(false)
|
---|
93 | {
|
---|
94 | VBoxGlobalSettings settings = vboxGlobal().settings();
|
---|
95 |
|
---|
96 | if (aSelf)
|
---|
97 | *aSelf = this;
|
---|
98 |
|
---|
99 | statusBar()->setContextMenuPolicy(Qt::CustomContextMenu);
|
---|
100 | connect(statusBar(), SIGNAL(customContextMenuRequested(const QPoint&)),
|
---|
101 | this, SLOT(showViewContextMenu(const QPoint&)));
|
---|
102 |
|
---|
103 | #ifdef Q_WS_MAC
|
---|
104 | qApp->installEventFilter(this);
|
---|
105 | #endif /* Q_WS_MAC */
|
---|
106 |
|
---|
107 | #if !(defined (Q_WS_WIN) || defined (Q_WS_MAC))
|
---|
108 | /* The application icon. On Win32, it's built-in to the executable. On Mac
|
---|
109 | * OS X the icon referenced in info.plist is used. */
|
---|
110 | setWindowIcon(QIcon(":/VirtualBox_48px.png"));
|
---|
111 | #endif
|
---|
112 |
|
---|
113 | /* actions */
|
---|
114 |
|
---|
115 | mFileMediaMgrAction = new QAction(this);
|
---|
116 | mFileMediaMgrAction->setIcon(UIIconPool::iconSet(":/diskimage_16px.png"));
|
---|
117 |
|
---|
118 | mFileApplianceImportAction = new QAction(this);
|
---|
119 | mFileApplianceImportAction->setIcon(UIIconPool::iconSet(":/import_16px.png"));
|
---|
120 |
|
---|
121 | mFileApplianceExportAction = new QAction(this);
|
---|
122 | mFileApplianceExportAction->setIcon(UIIconPool::iconSet(":/export_16px.png"));
|
---|
123 |
|
---|
124 | mFileSettingsAction = new QAction(this);
|
---|
125 | mFileSettingsAction->setMenuRole(QAction::PreferencesRole);
|
---|
126 | mFileSettingsAction->setIcon(UIIconPool::iconSet(":/global_settings_16px.png"));
|
---|
127 | mFileExitAction = new QAction(this);
|
---|
128 | mFileExitAction->setMenuRole(QAction::QuitRole);
|
---|
129 | mFileExitAction->setIcon(UIIconPool::iconSet(":/exit_16px.png"));
|
---|
130 |
|
---|
131 | mVmNewAction = new QAction(this);
|
---|
132 | mVmNewAction->setIcon(UIIconPool::iconSetFull(
|
---|
133 | QSize(32, 32), QSize(16, 16),
|
---|
134 | ":/vm_new_32px.png", ":/new_16px.png"));
|
---|
135 | mVmAddAction = new QAction(this);
|
---|
136 | mVmAddAction->setIcon(UIIconPool::iconSet(
|
---|
137 | ":/vm_add_16px.png"));
|
---|
138 | mVmConfigAction = new QAction(this);
|
---|
139 | mVmConfigAction->setIcon(UIIconPool::iconSetFull(
|
---|
140 | QSize(32, 32), QSize(16, 16),
|
---|
141 | ":/vm_settings_32px.png", ":/settings_16px.png",
|
---|
142 | ":/vm_settings_disabled_32px.png", ":/settings_dis_16px.png"));
|
---|
143 | mVmDeleteAction = new QAction(this);
|
---|
144 | mVmDeleteAction->setIcon(UIIconPool::iconSetFull(
|
---|
145 | QSize(32, 32), QSize(16, 16),
|
---|
146 | ":/vm_delete_32px.png", ":/delete_16px.png",
|
---|
147 | ":/vm_delete_disabled_32px.png", ":/delete_dis_16px.png"));
|
---|
148 | mVmStartAction = new QAction(this);
|
---|
149 | mVmStartAction->setIcon(UIIconPool::iconSetFull(
|
---|
150 | QSize(32, 32), QSize(16, 16),
|
---|
151 | ":/vm_start_32px.png", ":/start_16px.png",
|
---|
152 | ":/vm_start_disabled_32px.png", ":/start_dis_16px.png"));
|
---|
153 | mVmDiscardAction = new QAction(this);
|
---|
154 | mVmDiscardAction->setIcon(UIIconPool::iconSetFull(
|
---|
155 | QSize(32, 32), QSize(16, 16),
|
---|
156 | ":/vm_discard_32px.png", ":/discard_16px.png",
|
---|
157 | ":/vm_discard_disabled_32px.png", ":/discard_dis_16px.png"));
|
---|
158 | mVmPauseAction = new QAction(this);
|
---|
159 | mVmPauseAction->setCheckable(true);
|
---|
160 | mVmPauseAction->setIcon(UIIconPool::iconSetFull(
|
---|
161 | QSize(32, 32), QSize(16, 16),
|
---|
162 | ":/vm_pause_32px.png", ":/pause_16px.png",
|
---|
163 | ":/vm_pause_disabled_32px.png", ":/pause_disabled_16px.png"));
|
---|
164 | mVmRefreshAction = new QAction(this);
|
---|
165 | mVmRefreshAction->setIcon(UIIconPool::iconSetFull(
|
---|
166 | QSize(32, 32), QSize(16, 16),
|
---|
167 | ":/refresh_32px.png", ":/refresh_16px.png",
|
---|
168 | ":/refresh_disabled_32px.png", ":/refresh_disabled_16px.png"));
|
---|
169 | mVmShowLogsAction = new QAction(this);
|
---|
170 | mVmShowLogsAction->setIcon(UIIconPool::iconSetFull(
|
---|
171 | QSize(32, 32), QSize(16, 16),
|
---|
172 | ":/vm_show_logs_32px.png", ":/show_logs_16px.png",
|
---|
173 | ":/vm_show_logs_disabled_32px.png", ":/show_logs_disabled_16px.png"));
|
---|
174 | mVmOpenInFileManagerAction = new QAction(this);
|
---|
175 | mVmOpenInFileManagerAction->setIcon(UIIconPool::iconSet(
|
---|
176 | ":/vm_open_filemanager_16px.png", ":/vm_open_filemanager_disabled_16px.png"));
|
---|
177 | mVmCreateShortcut = new QAction(this);
|
---|
178 | mVmCreateShortcut->setIcon(UIIconPool::iconSet(
|
---|
179 | ":/vm_create_shortcut_16px.png", ":/vm_create_shortcut_disabled_16px.png"));
|
---|
180 |
|
---|
181 | mHelpActions.setup(this);
|
---|
182 |
|
---|
183 | /* VM list toolbar */
|
---|
184 | mVMToolBar = new UIToolBar(this);
|
---|
185 | mVMToolBar->setContextMenuPolicy(Qt::CustomContextMenu);
|
---|
186 | #ifndef Q_WS_MAC
|
---|
187 | connect(mVMToolBar, SIGNAL(customContextMenuRequested(const QPoint&)),
|
---|
188 | this, SLOT(showViewContextMenu(const QPoint&)));
|
---|
189 | #else /* !Q_WS_MAC */
|
---|
190 | /* A simple connect doesn't work on the Mac, also we want receive right
|
---|
191 | * click notifications on the title bar. So register our own handler. */
|
---|
192 | ::darwinRegisterForUnifiedToolbarContextMenuEvents(this);
|
---|
193 | #endif /* Q_WS_MAC */
|
---|
194 |
|
---|
195 | /* VM list view */
|
---|
196 | mVMModel = new UIVMItemModel();
|
---|
197 | mVMListView = new UIVMListView(mVMModel);
|
---|
198 | mVMListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
---|
199 | connect(mVMListView, SIGNAL(sigUrlsDropped(QList<QUrl>)),
|
---|
200 | this, SLOT(sltOpenUrls(QList<QUrl>)), Qt::QueuedConnection);
|
---|
201 |
|
---|
202 | /* Make non-possible to activate list elements by single click,
|
---|
203 | * this hack should disable the current possibility to do it if present */
|
---|
204 | if (mVMListView->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, mVMListView))
|
---|
205 | mVMListView->setStyleSheet("activate-on-singleclick : 0");
|
---|
206 |
|
---|
207 | m_pSplitter = new QISplitter(this);
|
---|
208 | m_pSplitter->setHandleType(QISplitter::Native);
|
---|
209 |
|
---|
210 | #define BIG_TOOLBAR
|
---|
211 | #if MAC_LEOPARD_STYLE
|
---|
212 | addToolBar(mVMToolBar);
|
---|
213 | /* Central widget @ horizontal layout */
|
---|
214 | setCentralWidget(m_pSplitter);
|
---|
215 | m_pSplitter->addWidget(mVMListView);
|
---|
216 | #else /* MAC_LEOPARD_STYLE */
|
---|
217 | // mVMToolBar->setContentsMargins(5, 5, 0, 0);
|
---|
218 | // addToolBar(mVMToolBar);
|
---|
219 | // m_pSplitter->addWidget(mVMListView);
|
---|
220 | QWidget *pLeftWidget = new QWidget(this);
|
---|
221 | QVBoxLayout *pLeftVLayout = new QVBoxLayout(pLeftWidget);
|
---|
222 | pLeftVLayout->setContentsMargins(0, 0, 0, 0);
|
---|
223 | pLeftVLayout->setSpacing(0);
|
---|
224 | # ifdef BIG_TOOLBAR
|
---|
225 | m_pBar = new UIMainBar(this);
|
---|
226 | m_pBar->setContentWidget(mVMToolBar);
|
---|
227 | pLeftVLayout->addWidget(m_pBar);
|
---|
228 | pLeftVLayout->addWidget(m_pSplitter);
|
---|
229 | setCentralWidget(pLeftWidget);
|
---|
230 | m_pSplitter->addWidget(mVMListView);
|
---|
231 | # else /* BIG_TOOLBAR */
|
---|
232 | pLeftVLayout->addWidget(mVMToolBar);
|
---|
233 | pLeftVLayout->addWidget(mVMListView);
|
---|
234 | setCentralWidget(m_pSplitter);
|
---|
235 | m_pSplitter->addWidget(pLeftWidget);
|
---|
236 | # endif /* BIG_TOOLBAR */
|
---|
237 | #endif /* MAC_LEOPARD_STYLE */
|
---|
238 |
|
---|
239 | /* add actions to the toolbar */
|
---|
240 |
|
---|
241 | mVMToolBar->setIconSize(QSize(32, 32));
|
---|
242 | mVMToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
---|
243 | // mVMToolBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
|
---|
244 |
|
---|
245 | mVMToolBar->addAction(mVmNewAction);
|
---|
246 | mVMToolBar->addAction(mVmConfigAction);
|
---|
247 | #if 0 /* delete action is really rare */
|
---|
248 | mVMToolBar->addAction(mVmDeleteAction);
|
---|
249 | #endif
|
---|
250 | mVMToolBar->addAction(mVmStartAction);
|
---|
251 | mVMToolBar->addAction(mVmDiscardAction);
|
---|
252 |
|
---|
253 | /* VM tab widget containing details and snapshots tabs */
|
---|
254 | QWidget *w = new QWidget();
|
---|
255 | QVBoxLayout *pVBox = new QVBoxLayout(w);
|
---|
256 | pVBox->setContentsMargins(0, 0, 0, 0);
|
---|
257 |
|
---|
258 | m_pVMDesktop = new UIVMDesktop(mVMToolBar, mVmRefreshAction, this);
|
---|
259 | pVBox->addWidget(m_pVMDesktop);
|
---|
260 |
|
---|
261 | m_pSplitter->addWidget(w);
|
---|
262 |
|
---|
263 | /* Set the initial distribution. The right site is bigger. */
|
---|
264 | m_pSplitter->setStretchFactor(0, 2);
|
---|
265 | m_pSplitter->setStretchFactor(1, 3);
|
---|
266 |
|
---|
267 | /* Configure menubar */
|
---|
268 | menuBar()->setContextMenuPolicy(Qt::CustomContextMenu);
|
---|
269 | connect(menuBar(), SIGNAL(customContextMenuRequested(const QPoint&)),
|
---|
270 | this, SLOT(showViewContextMenu(const QPoint&)));
|
---|
271 |
|
---|
272 | /* add actions to menubar */
|
---|
273 | mFileMenu = menuBar()->addMenu(QString::null);
|
---|
274 | mFileMenu->addAction(mFileMediaMgrAction);
|
---|
275 | mFileMenu->addAction(mFileApplianceImportAction);
|
---|
276 | mFileMenu->addAction(mFileApplianceExportAction);
|
---|
277 | #ifndef Q_WS_MAC
|
---|
278 | mFileMenu->addSeparator();
|
---|
279 | #endif /* Q_WS_MAC */
|
---|
280 | mFileMenu->addAction(mFileSettingsAction);
|
---|
281 | #ifndef Q_WS_MAC
|
---|
282 | mFileMenu->addSeparator();
|
---|
283 | #endif /* Q_WS_MAC */
|
---|
284 | mFileMenu->addAction(mFileExitAction);
|
---|
285 |
|
---|
286 | mVMMenu = menuBar()->addMenu(QString::null);
|
---|
287 | mVMMenu->addAction(mVmNewAction);
|
---|
288 | mVMMenu->addAction(mVmAddAction);
|
---|
289 | mVMMenu->addAction(mVmConfigAction);
|
---|
290 | mVMMenu->addAction(mVmDeleteAction);
|
---|
291 | mVMMenu->addSeparator();
|
---|
292 | mVMMenu->addAction(mVmStartAction);
|
---|
293 | mVMMenu->addAction(mVmDiscardAction);
|
---|
294 | mVMMenu->addAction(mVmPauseAction);
|
---|
295 | mVMMenu->addSeparator();
|
---|
296 | mVMMenu->addAction(mVmRefreshAction);
|
---|
297 | mVMMenu->addAction(mVmShowLogsAction);
|
---|
298 | mVMMenu->addSeparator();
|
---|
299 | mVMMenu->addAction(mVmOpenInFileManagerAction);
|
---|
300 | mVMMenu->addAction(mVmCreateShortcut);
|
---|
301 |
|
---|
302 | #ifdef Q_WS_MAC
|
---|
303 | menuBar()->addMenu(UIWindowMenuManager::instance(this)->createMenu(this));
|
---|
304 | #endif /* Q_WS_MAC */
|
---|
305 |
|
---|
306 | mVMCtxtMenu = new QMenu(this);
|
---|
307 | mVMCtxtMenu->addAction(mVmConfigAction);
|
---|
308 | mVMCtxtMenu->addAction(mVmDeleteAction);
|
---|
309 | mVMCtxtMenu->addSeparator();
|
---|
310 | mVMCtxtMenu->addAction(mVmStartAction);
|
---|
311 | mVMCtxtMenu->addAction(mVmDiscardAction);
|
---|
312 | mVMCtxtMenu->addAction(mVmPauseAction);
|
---|
313 | mVMCtxtMenu->addSeparator();
|
---|
314 | mVMCtxtMenu->addAction(mVmRefreshAction);
|
---|
315 | mVMCtxtMenu->addAction(mVmShowLogsAction);
|
---|
316 | mVMCtxtMenu->addSeparator();
|
---|
317 | mVMCtxtMenu->addAction(mVmOpenInFileManagerAction);
|
---|
318 | mVMCtxtMenu->addAction(mVmCreateShortcut);
|
---|
319 |
|
---|
320 | /* Make sure every status bar hint from the context menu is cleared when
|
---|
321 | * the menu is closed. */
|
---|
322 | connect(mVMCtxtMenu, SIGNAL(aboutToHide()),
|
---|
323 | statusBar(), SLOT(clearMessage()));
|
---|
324 |
|
---|
325 | mHelpMenu = menuBar()->addMenu(QString::null);
|
---|
326 | mHelpActions.addTo(mHelpMenu);
|
---|
327 |
|
---|
328 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
329 | mTrayIcon = new VBoxTrayIcon(this, mVMModel);
|
---|
330 | Assert(mTrayIcon);
|
---|
331 | connect(mTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
---|
332 | this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
|
---|
333 | #endif
|
---|
334 |
|
---|
335 | retranslateUi();
|
---|
336 |
|
---|
337 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
338 | /* Restore the position of the window */
|
---|
339 | {
|
---|
340 | QString winPos = vbox.GetExtraData(VBoxDefs::GUI_LastWindowPosition);
|
---|
341 |
|
---|
342 | bool ok = false, max = false;
|
---|
343 | int x = 0, y = 0, w = 0, h = 0;
|
---|
344 | x = winPos.section(',', 0, 0).toInt(&ok);
|
---|
345 | if (ok)
|
---|
346 | y = winPos.section(',', 1, 1).toInt(&ok);
|
---|
347 | if (ok)
|
---|
348 | w = winPos.section(',', 2, 2).toInt(&ok);
|
---|
349 | if (ok)
|
---|
350 | h = winPos.section(',', 3, 3).toInt(&ok);
|
---|
351 | if (ok)
|
---|
352 | max = winPos.section(',', 4, 4) == VBoxDefs::GUI_LastWindowState_Max;
|
---|
353 |
|
---|
354 | QRect ar = ok ? QApplication::desktop()->availableGeometry(QPoint(x, y)) :
|
---|
355 | QApplication::desktop()->availableGeometry(this);
|
---|
356 |
|
---|
357 | if (ok /* previous parameters were read correctly */
|
---|
358 | && (y > 0) && (y < ar.bottom()) /* check vertical bounds */
|
---|
359 | && (x + w > ar.left()) && (x < ar.right()) /* & horizontal bounds */)
|
---|
360 | {
|
---|
361 | mNormalGeo.moveTo(x, y);
|
---|
362 | mNormalGeo.setSize(QSize(w, h)
|
---|
363 | .expandedTo(minimumSizeHint())
|
---|
364 | .boundedTo(ar.size()));
|
---|
365 | #if defined(Q_WS_MAC) && (QT_VERSION >= 0x040700)
|
---|
366 | move(mNormalGeo.topLeft());
|
---|
367 | resize(mNormalGeo.size());
|
---|
368 | mNormalGeo = normalGeometry();
|
---|
369 | #else /* defined(Q_WS_MAC) && (QT_VERSION >= 0x040700) */
|
---|
370 | setGeometry(mNormalGeo);
|
---|
371 | #endif /* !(defined(Q_WS_MAC) && (QT_VERSION >= 0x040700)) */
|
---|
372 | if (max) /* maximize if needed */
|
---|
373 | showMaximized();
|
---|
374 | }
|
---|
375 | else
|
---|
376 | {
|
---|
377 | mNormalGeo.setSize(QSize(770, 550).expandedTo(minimumSizeHint())
|
---|
378 | .boundedTo(ar.size()));
|
---|
379 | mNormalGeo.moveCenter(ar.center());
|
---|
380 | setGeometry(mNormalGeo);
|
---|
381 | }
|
---|
382 | }
|
---|
383 | #if MAC_LEOPARD_STYLE
|
---|
384 | /* Enable unified toolbars on Mac OS X. Available on Qt >= 4.3. We do this
|
---|
385 | * after setting the window pos/size, cause Qt sometime includes the
|
---|
386 | * toolbar height in the content height. */
|
---|
387 | mVMToolBar->setMacToolbar();
|
---|
388 | #endif /* MAC_LEOPARD_STYLE */
|
---|
389 |
|
---|
390 | /* Update the list */
|
---|
391 | refreshVMList();
|
---|
392 |
|
---|
393 | /* Reset to the first item */
|
---|
394 | mVMListView->selectItemByRow(0);
|
---|
395 |
|
---|
396 | /* restore the position of vm selector */
|
---|
397 | {
|
---|
398 | QString prevVMId = vbox.GetExtraData(VBoxDefs::GUI_LastVMSelected);
|
---|
399 |
|
---|
400 | mVMListView->selectItemById(prevVMId);
|
---|
401 | }
|
---|
402 |
|
---|
403 | /* Read the splitter handle position */
|
---|
404 | {
|
---|
405 | QList<int> sizes = vbox.GetExtraDataIntList(VBoxDefs::GUI_SplitterSizes);
|
---|
406 | if (sizes.size() == 2)
|
---|
407 | m_pSplitter->setSizes(sizes);
|
---|
408 | }
|
---|
409 |
|
---|
410 | /* Restore toolbar and statusbar visibility */
|
---|
411 | {
|
---|
412 | QString strToolbar = vbox.GetExtraData(VBoxDefs::GUI_Toolbar);
|
---|
413 | QString strStatusbar = vbox.GetExtraData(VBoxDefs::GUI_Statusbar);
|
---|
414 |
|
---|
415 | #ifdef Q_WS_MAC
|
---|
416 | mVMToolBar->setVisible(strToolbar.isEmpty() || strToolbar == "true");
|
---|
417 | #else /* Q_WS_MAC */
|
---|
418 | m_pBar->setVisible(strToolbar.isEmpty() || strToolbar == "true");
|
---|
419 | #endif /* !Q_WS_MAC */
|
---|
420 | statusBar()->setVisible(strStatusbar.isEmpty() || strStatusbar == "true");
|
---|
421 | }
|
---|
422 |
|
---|
423 | /* refresh the details et all (necessary for the case when the stored
|
---|
424 | * selection is still the first list item) */
|
---|
425 | vmListViewCurrentChanged();
|
---|
426 |
|
---|
427 | /* signals and slots connections */
|
---|
428 | connect(mFileMediaMgrAction, SIGNAL(triggered()), this, SLOT(fileMediaMgr()));
|
---|
429 | connect(mFileApplianceImportAction, SIGNAL(triggered()), this, SLOT(fileImportAppliance()));
|
---|
430 | connect(mFileApplianceExportAction, SIGNAL(triggered()), this, SLOT(fileExportAppliance()));
|
---|
431 | connect(mFileSettingsAction, SIGNAL(triggered()), this, SLOT(fileSettings()));
|
---|
432 | connect(mFileExitAction, SIGNAL(triggered()), this, SLOT(fileExit()));
|
---|
433 | connect(mVmNewAction, SIGNAL(triggered()), this, SLOT(vmNew()));
|
---|
434 | connect(mVmAddAction, SIGNAL(triggered()), this, SLOT(vmAdd()));
|
---|
435 |
|
---|
436 | connect(mVmConfigAction, SIGNAL(triggered()), this, SLOT(vmSettings()));
|
---|
437 | connect(mVmDeleteAction, SIGNAL(triggered()), this, SLOT(vmDelete()));
|
---|
438 | connect(mVmStartAction, SIGNAL(triggered()), this, SLOT(vmStart()));
|
---|
439 | connect(mVmDiscardAction, SIGNAL(triggered()), this, SLOT(vmDiscard()));
|
---|
440 | connect(mVmPauseAction, SIGNAL(toggled(bool)), this, SLOT(vmPause(bool)));
|
---|
441 | connect(mVmRefreshAction, SIGNAL(triggered()), this, SLOT(vmRefresh()));
|
---|
442 | connect(mVmShowLogsAction, SIGNAL(triggered()), this, SLOT(vmShowLogs()));
|
---|
443 | connect(mVmOpenInFileManagerAction, SIGNAL(triggered()), this, SLOT(vmOpenInFileManager()));
|
---|
444 | connect(mVmCreateShortcut, SIGNAL(triggered()), this, SLOT(vmCreateShortcut()));
|
---|
445 |
|
---|
446 | connect(mVMListView, SIGNAL(currentChanged()),
|
---|
447 | this, SLOT(vmListViewCurrentChanged()));
|
---|
448 | connect(mVMListView, SIGNAL(activated()),
|
---|
449 | this, SLOT(vmStart()));
|
---|
450 | connect(mVMListView, SIGNAL(customContextMenuRequested(const QPoint &)),
|
---|
451 | this, SLOT(showContextMenu(const QPoint &)));
|
---|
452 |
|
---|
453 | connect(m_pVMDesktop, SIGNAL(linkClicked(const QString &)),
|
---|
454 | this, SLOT(vmSettings(const QString &)));
|
---|
455 |
|
---|
456 | /* listen to media enumeration signals */
|
---|
457 | connect(&vboxGlobal(), SIGNAL(mediumEnumStarted()),
|
---|
458 | this, SLOT(mediumEnumStarted()));
|
---|
459 | connect(&vboxGlobal(), SIGNAL(mediumEnumFinished(const VBoxMediaList &)),
|
---|
460 | this, SLOT(mediumEnumFinished(const VBoxMediaList &)));
|
---|
461 |
|
---|
462 | /* connect VirtualBox events */
|
---|
463 | connect(gVBoxEvents, SIGNAL(sigMachineStateChange(QString, KMachineState)),
|
---|
464 | this, SLOT(machineStateChanged(QString, KMachineState)));
|
---|
465 | connect(gVBoxEvents, SIGNAL(sigMachineDataChange(QString)),
|
---|
466 | this, SLOT(machineDataChanged(QString)));
|
---|
467 | connect(gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)),
|
---|
468 | this, SLOT(machineRegistered(QString, bool)));
|
---|
469 | connect(gVBoxEvents, SIGNAL(sigSessionStateChange(QString, KSessionState)),
|
---|
470 | this, SLOT(sessionStateChanged(QString, KSessionState)));
|
---|
471 | connect(gVBoxEvents, SIGNAL(sigSnapshotChange(QString, QString)),
|
---|
472 | this, SLOT(snapshotChanged(QString, QString)));
|
---|
473 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
474 | connect(gEDataEvents, SIGNAL(sigMainWindowCountChange(int)),
|
---|
475 | this, SLOT(mainWindowCountChanged(int)));
|
---|
476 | connect(gEDataEvents, SIGNAL(sigCanShowTrayIcon(bool)),
|
---|
477 | this, SLOT(trayIconCanShow(bool)));
|
---|
478 | connect(gEDataEvents, SIGNAL(sigTrayIconChange(bool)),
|
---|
479 | this, SLOT(trayIconChanged(bool)));
|
---|
480 | connect(&vboxGlobal(), SIGNAL(sigTrayIconShow(bool)),
|
---|
481 | this, SLOT(trayIconShow(bool)));
|
---|
482 | #endif
|
---|
483 |
|
---|
484 | /* Listen to potential downloaders signals: */
|
---|
485 | connect(&vboxProblem(), SIGNAL(sigDownloaderUserManualCreated()), this, SLOT(sltDownloaderUserManualEmbed()));
|
---|
486 |
|
---|
487 | /* bring the VM list to the focus */
|
---|
488 | mVMListView->setFocus();
|
---|
489 |
|
---|
490 | #ifdef Q_WS_MAC
|
---|
491 | UIWindowMenuManager::instance()->addWindow(this);
|
---|
492 | /* Beta label? */
|
---|
493 | if (vboxGlobal().isBeta())
|
---|
494 | {
|
---|
495 | QPixmap betaLabel = ::betaLabelSleeve(QSize(107, 16));
|
---|
496 | ::darwinLabelWindow(this, &betaLabel, false);
|
---|
497 | }
|
---|
498 | #endif /* Q_WS_MAC */
|
---|
499 | }
|
---|
500 |
|
---|
501 | VBoxSelectorWnd::~VBoxSelectorWnd()
|
---|
502 | {
|
---|
503 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
504 |
|
---|
505 | /* Destroy our event handlers */
|
---|
506 | UIVirtualBoxEventHandler::destroy();
|
---|
507 |
|
---|
508 | /* Save the position of the window */
|
---|
509 | {
|
---|
510 | #if defined(Q_WS_MAC) && (QT_VERSION >= 0x040700)
|
---|
511 | QRect frameGeo = frameGeometry();
|
---|
512 | QRect save(frameGeo.x(), frameGeo.y(), mNormalGeo.width(), mNormalGeo.height());
|
---|
513 | #else /* defined(Q_WS_MAC) && (QT_VERSION >= 0x040700) */
|
---|
514 | QRect save(mNormalGeo);
|
---|
515 | #endif /* !(defined(Q_WS_MAC) && (QT_VERSION >= 0x040700)) */
|
---|
516 | QString winPos = QString("%1,%2,%3,%4")
|
---|
517 | .arg(save.x()).arg(save.y())
|
---|
518 | .arg(save.width()).arg(save.height());
|
---|
519 | #ifdef Q_WS_MAC
|
---|
520 | UIWindowMenuManager::destroy();
|
---|
521 | ::darwinUnregisterForUnifiedToolbarContextMenuEvents(this);
|
---|
522 | if (::darwinIsWindowMaximized(this))
|
---|
523 | #else /* Q_WS_MAC */
|
---|
524 | if (isMaximized())
|
---|
525 | #endif /* !Q_WS_MAC */
|
---|
526 | winPos += QString(",%1").arg(VBoxDefs::GUI_LastWindowState_Max);
|
---|
527 |
|
---|
528 | vbox.SetExtraData(VBoxDefs::GUI_LastWindowPosition, winPos);
|
---|
529 | }
|
---|
530 |
|
---|
531 | /* Save VM selector position */
|
---|
532 | {
|
---|
533 | UIVMItem *item = mVMListView->selectedItem();
|
---|
534 | QString curVMId = item ?
|
---|
535 | QString(item->id()) :
|
---|
536 | QString::null;
|
---|
537 | vbox.SetExtraData(VBoxDefs::GUI_LastVMSelected, curVMId);
|
---|
538 | vbox.SetExtraDataStringList(VBoxDefs::GUI_SelectorVMPositions, mVMModel->idList());
|
---|
539 | }
|
---|
540 |
|
---|
541 | /* Save the splitter handle position */
|
---|
542 | {
|
---|
543 | vbox.SetExtraDataIntList(VBoxDefs::GUI_SplitterSizes, m_pSplitter->sizes());
|
---|
544 | }
|
---|
545 |
|
---|
546 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
547 | /* Delete systray menu object */
|
---|
548 | delete mTrayIcon;
|
---|
549 | mTrayIcon = NULL;
|
---|
550 | #endif
|
---|
551 |
|
---|
552 | /* Delete the items from our model */
|
---|
553 | mVMModel->clear();
|
---|
554 | }
|
---|
555 |
|
---|
556 | //
|
---|
557 | // Public slots
|
---|
558 | /////////////////////////////////////////////////////////////////////////////
|
---|
559 |
|
---|
560 | void VBoxSelectorWnd::fileMediaMgr()
|
---|
561 | {
|
---|
562 | VBoxMediaManagerDlg::showModeless(this);
|
---|
563 | }
|
---|
564 |
|
---|
565 | void VBoxSelectorWnd::fileImportAppliance(const QString &strFile /* = "" */)
|
---|
566 | {
|
---|
567 | #ifdef Q_WS_MAC
|
---|
568 | QString strTmpFile = ::darwinResolveAlias(strFile);
|
---|
569 | #else /* Q_WS_MAC */
|
---|
570 | QString strTmpFile = strFile;
|
---|
571 | #endif /* !Q_WS_MAC */
|
---|
572 | UIImportApplianceWzd wzd(strTmpFile, this);
|
---|
573 |
|
---|
574 | if ( strFile.isEmpty()
|
---|
575 | || wzd.isValid())
|
---|
576 | wzd.exec();
|
---|
577 | }
|
---|
578 |
|
---|
579 | void VBoxSelectorWnd::fileExportAppliance()
|
---|
580 | {
|
---|
581 | QString name;
|
---|
582 |
|
---|
583 | UIVMItem *item = mVMListView->selectedItem();
|
---|
584 | if (item)
|
---|
585 | name = item->name();
|
---|
586 |
|
---|
587 | UIExportApplianceWzd wzd(this, name);
|
---|
588 |
|
---|
589 | wzd.exec();
|
---|
590 | }
|
---|
591 |
|
---|
592 | void VBoxSelectorWnd::fileSettings()
|
---|
593 | {
|
---|
594 | VBoxGlobalSettings settings = vboxGlobal().settings();
|
---|
595 | CSystemProperties props = vboxGlobal().virtualBox().GetSystemProperties();
|
---|
596 |
|
---|
597 | UISettingsDialog *dlg = new UIGLSettingsDlg(this);
|
---|
598 | dlg->getFrom();
|
---|
599 |
|
---|
600 | if (dlg->exec() == QDialog::Accepted)
|
---|
601 | dlg->putBackTo();
|
---|
602 |
|
---|
603 | delete dlg;
|
---|
604 | }
|
---|
605 |
|
---|
606 | void VBoxSelectorWnd::fileExit()
|
---|
607 | {
|
---|
608 | /* We have to check if there are any open windows beside this mainwindow
|
---|
609 | * (e.g. VDM) and if so close them. Note that the default behavior is
|
---|
610 | * different to Qt3 where a *mainWidget* exists & if this going to close
|
---|
611 | * all other windows are closed automatically. We do the same below. */
|
---|
612 | foreach(QWidget *widget, QApplication::topLevelWidgets())
|
---|
613 | {
|
---|
614 | if (widget->isVisible() &&
|
---|
615 | widget != this)
|
---|
616 | widget->close();
|
---|
617 | }
|
---|
618 | /* We close this widget last. */
|
---|
619 | close();
|
---|
620 | }
|
---|
621 |
|
---|
622 | void VBoxSelectorWnd::vmNew()
|
---|
623 | {
|
---|
624 | UINewVMWzd wzd(this);
|
---|
625 | if (wzd.exec() == QDialog::Accepted)
|
---|
626 | {
|
---|
627 | CMachine m = wzd.machine();
|
---|
628 |
|
---|
629 | /* wait until the list is updated by OnMachineRegistered() */
|
---|
630 | QModelIndex index;
|
---|
631 | while(!index.isValid())
|
---|
632 | {
|
---|
633 | qApp->processEvents();
|
---|
634 | index = mVMModel->indexById(m.GetId());
|
---|
635 | }
|
---|
636 | mVMListView->setCurrentIndex(index);
|
---|
637 | }
|
---|
638 | }
|
---|
639 |
|
---|
640 | void VBoxSelectorWnd::vmAdd(const QString &strFile /* = "" */)
|
---|
641 | {
|
---|
642 | #ifdef Q_WS_MAC
|
---|
643 | QString strTmpFile = ::darwinResolveAlias(strFile);
|
---|
644 | #else /* Q_WS_MAC */
|
---|
645 | QString strTmpFile = strFile;
|
---|
646 | #endif /* !Q_WS_MAC */
|
---|
647 | /* Initialize variables: */
|
---|
648 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
649 | if (strTmpFile.isEmpty())
|
---|
650 | {
|
---|
651 | QString strBaseFolder = vbox.GetSystemProperties().GetDefaultMachineFolder();
|
---|
652 | QString strTitle = tr("Select a virtual machine file");
|
---|
653 | QStringList extensions;
|
---|
654 | for (int i = 0; i < VBoxDefs::VBoxFileExts.size(); ++i)
|
---|
655 | extensions << QString("*.%1").arg(VBoxDefs::VBoxFileExts[i]);
|
---|
656 | QString strFilter = tr("Virtual machine files (%1)").arg(extensions.join(" "));
|
---|
657 | /* Create open file dialog: */
|
---|
658 | QStringList fileNames = QIFileDialog::getOpenFileNames(strBaseFolder, strFilter, this, strTitle, 0, true, true);
|
---|
659 | if (!fileNames.isEmpty())
|
---|
660 | strTmpFile = fileNames.at(0);
|
---|
661 | }
|
---|
662 | if (!strTmpFile.isEmpty())
|
---|
663 | {
|
---|
664 | /* Open corresponding machine: */
|
---|
665 | CMachine newMachine = vbox.OpenMachine(strTmpFile);
|
---|
666 | /* First we should test what machine was opened: */
|
---|
667 | if (vbox.isOk() && !newMachine.isNull())
|
---|
668 | {
|
---|
669 | /* Second we should check what such machine was NOT already registered.
|
---|
670 | * Actually current Main implementation will even prevent such machine opening
|
---|
671 | * but we will perform such a check anyway: */
|
---|
672 | CMachine oldMachine = vbox.FindMachine(newMachine.GetId());
|
---|
673 | if (oldMachine.isNull())
|
---|
674 | {
|
---|
675 | /* Register that machine: */
|
---|
676 | vbox.RegisterMachine(newMachine);
|
---|
677 |
|
---|
678 | /* Wait until the list is updated by OnMachineRegistered(): */
|
---|
679 | QModelIndex index;
|
---|
680 | while(!index.isValid())
|
---|
681 | {
|
---|
682 | qApp->processEvents();
|
---|
683 | index = mVMModel->indexById(newMachine.GetId());
|
---|
684 | }
|
---|
685 | /* And choose the new machine item: */
|
---|
686 | mVMListView->setCurrentIndex(index);
|
---|
687 | }
|
---|
688 | else
|
---|
689 | vboxProblem().cannotReregisterMachine(this, strTmpFile, oldMachine.GetName());
|
---|
690 | }
|
---|
691 | else
|
---|
692 | vboxProblem().cannotOpenMachine(this, strTmpFile, vbox);
|
---|
693 | }
|
---|
694 | }
|
---|
695 |
|
---|
696 | /**
|
---|
697 | * Opens the VM settings dialog.
|
---|
698 | */
|
---|
699 | void VBoxSelectorWnd::vmSettings(const QString &aCategory /* = QString::null */,
|
---|
700 | const QString &aControl /* = QString::null */,
|
---|
701 | const QString &aUuid /* = QString::null */)
|
---|
702 | {
|
---|
703 | if (!aCategory.isEmpty() && aCategory [0] != '#')
|
---|
704 | {
|
---|
705 | /* Assume it's a href from the Details HTML */
|
---|
706 | vboxGlobal().openURL(aCategory);
|
---|
707 | return;
|
---|
708 | }
|
---|
709 | QString strCategory = aCategory;
|
---|
710 | QString strControl = aControl;
|
---|
711 | /* Maybe the control is coded into the URL by %% */
|
---|
712 | if (aControl == QString::null)
|
---|
713 | {
|
---|
714 | QStringList parts = aCategory.split("%%");
|
---|
715 | if (parts.size() == 2)
|
---|
716 | {
|
---|
717 | strCategory = parts.at(0);
|
---|
718 | strControl = parts.at(1);
|
---|
719 | }
|
---|
720 | }
|
---|
721 |
|
---|
722 | UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
|
---|
723 | mVMModel->itemById(aUuid);
|
---|
724 |
|
---|
725 | AssertMsgReturnVoid(item, ("Item must be always selected here"));
|
---|
726 |
|
---|
727 | // open a direct session to modify VM settings
|
---|
728 | QString id = item->id();
|
---|
729 | CSession session = vboxGlobal().openSession(id);
|
---|
730 | if (session.isNull())
|
---|
731 | return;
|
---|
732 |
|
---|
733 | CMachine m = session.GetMachine();
|
---|
734 | AssertMsgReturn(!m.isNull(), ("Machine must not be null"), (void) 0);
|
---|
735 |
|
---|
736 | /* Don't show the inaccessible warning if the user open the vm settings. */
|
---|
737 | mDoneInaccessibleWarningOnce = true;
|
---|
738 |
|
---|
739 | UISettingsDialog *dlg = new UIVMSettingsDlg(this, m, strCategory, strControl);
|
---|
740 | dlg->getFrom();
|
---|
741 |
|
---|
742 | if (dlg->exec() == QDialog::Accepted)
|
---|
743 | {
|
---|
744 | QString oldName = m.GetName();
|
---|
745 | dlg->putBackTo();
|
---|
746 |
|
---|
747 | m.SaveSettings();
|
---|
748 | if (!m.isOk())
|
---|
749 | vboxProblem().cannotSaveMachineSettings(m);
|
---|
750 |
|
---|
751 | /* To check use the result in future
|
---|
752 | * vboxProblem().cannotApplyMachineSettings(m, res); */
|
---|
753 | }
|
---|
754 |
|
---|
755 | delete dlg;
|
---|
756 |
|
---|
757 | mVMListView->setFocus();
|
---|
758 |
|
---|
759 | session.UnlockMachine();
|
---|
760 | }
|
---|
761 |
|
---|
762 | void VBoxSelectorWnd::vmDelete(const QString &aUuid /* = QString::null */)
|
---|
763 | {
|
---|
764 | UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() : mVMModel->itemById(aUuid);
|
---|
765 |
|
---|
766 | AssertMsgReturnVoid(item, ("Item must be always selected here"));
|
---|
767 |
|
---|
768 | CMachine machine = item->machine();
|
---|
769 | int rc = vboxProblem().confirmMachineDeletion(machine);
|
---|
770 | if (rc != QIMessageBox::Cancel)
|
---|
771 | {
|
---|
772 | if (rc == QIMessageBox::Yes)
|
---|
773 | {
|
---|
774 | /* Unregister and cleanup machine's data & hard-disks: */
|
---|
775 | CMediumVector mediums = machine.Unregister(KCleanupMode_DetachAllReturnHardDisksOnly);
|
---|
776 | if (machine.isOk())
|
---|
777 | {
|
---|
778 | /* Delete machine hard-disks: */
|
---|
779 | CProgress progress = machine.Delete(mediums);
|
---|
780 | if (machine.isOk())
|
---|
781 | {
|
---|
782 | vboxProblem().showModalProgressDialog(progress, item->name(), ":/progress_delete_90px.png", 0, true);
|
---|
783 | if (progress.GetResultCode() != 0)
|
---|
784 | vboxProblem().cannotDeleteMachine(machine);
|
---|
785 | }
|
---|
786 | }
|
---|
787 | if (!machine.isOk())
|
---|
788 | vboxProblem().cannotDeleteMachine(machine);
|
---|
789 | }
|
---|
790 | else
|
---|
791 | {
|
---|
792 | /* Just unregister machine: */
|
---|
793 | machine.Unregister(KCleanupMode_DetachAllReturnNone);
|
---|
794 | if (!machine.isOk())
|
---|
795 | vboxProblem().cannotDeleteMachine(machine);
|
---|
796 | }
|
---|
797 | }
|
---|
798 | }
|
---|
799 |
|
---|
800 | void VBoxSelectorWnd::vmStart(const QString &aUuid /* = QString::null */)
|
---|
801 | {
|
---|
802 | QUuid uuid(aUuid);
|
---|
803 | UIVMItem *item = uuid.isNull() ? mVMListView->selectedItem() :
|
---|
804 | mVMModel->itemById(aUuid);
|
---|
805 |
|
---|
806 | AssertMsgReturnVoid(item, ("Item must be always selected here"));
|
---|
807 |
|
---|
808 | /* Are we called from the mVMListView's activated() signal? */
|
---|
809 | if (uuid.isNull())
|
---|
810 | {
|
---|
811 | /* We always get here when mVMListView emits the activated() signal,
|
---|
812 | * so we must explicitly check if the action is enabled or not. */
|
---|
813 | if (!mVmStartAction->isEnabled())
|
---|
814 | return;
|
---|
815 | }
|
---|
816 |
|
---|
817 | AssertMsg(!vboxGlobal().isVMConsoleProcess(),
|
---|
818 | ("Must NOT be a VM console process"));
|
---|
819 |
|
---|
820 | CMachine machine = item->machine();
|
---|
821 | vboxGlobal().launchMachine(machine);
|
---|
822 | }
|
---|
823 |
|
---|
824 | void VBoxSelectorWnd::vmDiscard(const QString &aUuid /* = QString::null */)
|
---|
825 | {
|
---|
826 | UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
|
---|
827 | mVMModel->itemById(aUuid);
|
---|
828 |
|
---|
829 | AssertMsgReturnVoid(item, ("Item must be always selected here"));
|
---|
830 |
|
---|
831 | if (!vboxProblem().confirmDiscardSavedState(item->machine()))
|
---|
832 | return;
|
---|
833 |
|
---|
834 | /* open a session to modify VM settings */
|
---|
835 | QString id = item->id();
|
---|
836 | CSession session;
|
---|
837 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
838 | session.createInstance(CLSID_Session);
|
---|
839 | if (session.isNull())
|
---|
840 | {
|
---|
841 | vboxProblem().cannotOpenSession(session);
|
---|
842 | return;
|
---|
843 | }
|
---|
844 |
|
---|
845 | CMachine foundMachine = vbox.FindMachine(id);
|
---|
846 | if (!foundMachine.isNull())
|
---|
847 | foundMachine.LockMachine(session, KLockType_Write);
|
---|
848 | if (!vbox.isOk())
|
---|
849 | {
|
---|
850 | vboxProblem().cannotOpenSession(vbox, item->machine());
|
---|
851 | return;
|
---|
852 | }
|
---|
853 |
|
---|
854 | CConsole console = session.GetConsole();
|
---|
855 | console.DiscardSavedState(true /* fDeleteFile */);
|
---|
856 | if (!console.isOk())
|
---|
857 | vboxProblem().cannotDiscardSavedState(console);
|
---|
858 |
|
---|
859 | session.UnlockMachine();
|
---|
860 | }
|
---|
861 |
|
---|
862 | void VBoxSelectorWnd::vmPause(bool aPause, const QString &aUuid /* = QString::null */)
|
---|
863 | {
|
---|
864 | UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
|
---|
865 | mVMModel->itemById(aUuid);
|
---|
866 |
|
---|
867 | AssertMsgReturnVoid(item, ("Item must be always selected here"));
|
---|
868 |
|
---|
869 | CSession session = vboxGlobal().openExistingSession(item->id());
|
---|
870 | if (session.isNull())
|
---|
871 | return;
|
---|
872 |
|
---|
873 | CConsole console = session.GetConsole();
|
---|
874 | if (console.isNull())
|
---|
875 | return;
|
---|
876 |
|
---|
877 | if (aPause)
|
---|
878 | console.Pause();
|
---|
879 | else
|
---|
880 | console.Resume();
|
---|
881 |
|
---|
882 | bool ok = console.isOk();
|
---|
883 | if (!ok)
|
---|
884 | {
|
---|
885 | if (aPause)
|
---|
886 | vboxProblem().cannotPauseMachine(console);
|
---|
887 | else
|
---|
888 | vboxProblem().cannotResumeMachine(console);
|
---|
889 | }
|
---|
890 |
|
---|
891 | session.UnlockMachine();
|
---|
892 | }
|
---|
893 |
|
---|
894 | void VBoxSelectorWnd::vmRefresh(const QString &aUuid /* = QString::null */)
|
---|
895 | {
|
---|
896 | UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
|
---|
897 | mVMModel->itemById(aUuid);
|
---|
898 |
|
---|
899 | AssertMsgReturnVoid(item, ("Item must be always selected here"));
|
---|
900 |
|
---|
901 | refreshVMItem(item->id(),
|
---|
902 | true /* aDetails */,
|
---|
903 | true /* aSnapshot */,
|
---|
904 | true /* aDescription */);
|
---|
905 | }
|
---|
906 |
|
---|
907 | void VBoxSelectorWnd::vmShowLogs(const QString &aUuid /* = QString::null */)
|
---|
908 | {
|
---|
909 | UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
|
---|
910 | mVMModel->itemById(aUuid);
|
---|
911 |
|
---|
912 | AssertMsgReturnVoid(item, ("Item must be always selected here"));
|
---|
913 |
|
---|
914 | CMachine machine = item->machine();
|
---|
915 | VBoxVMLogViewer::createLogViewer(this, machine);
|
---|
916 | }
|
---|
917 |
|
---|
918 | void VBoxSelectorWnd::vmOpenInFileManager(const QString &aUuid /* = QString::null */)
|
---|
919 | {
|
---|
920 | UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
|
---|
921 | mVMModel->itemById(aUuid);
|
---|
922 |
|
---|
923 | AssertMsgReturnVoid(item, ("Item must be always selected here"));
|
---|
924 |
|
---|
925 | CMachine machine = item->machine();
|
---|
926 | UIDesktopServices::openInFileManager(machine.GetSettingsFilePath());
|
---|
927 | }
|
---|
928 |
|
---|
929 | void VBoxSelectorWnd::vmCreateShortcut(const QString &aUuid /* = QString::null */)
|
---|
930 | {
|
---|
931 | UIVMItem *item = aUuid.isNull() ? mVMListView->selectedItem() :
|
---|
932 | mVMModel->itemById(aUuid);
|
---|
933 |
|
---|
934 | AssertMsgReturnVoid(item, ("Item must be always selected here"));
|
---|
935 |
|
---|
936 | CMachine machine = item->machine();
|
---|
937 | UIDesktopServices::createMachineShortcut(machine.GetSettingsFilePath(), QDesktopServices::storageLocation(QDesktopServices::DesktopLocation), machine.GetName(), machine.GetId());
|
---|
938 | }
|
---|
939 |
|
---|
940 | void VBoxSelectorWnd::refreshVMList()
|
---|
941 | {
|
---|
942 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
943 | CMachineVector vec = vbox.GetMachines();
|
---|
944 | for (CMachineVector::ConstIterator m = vec.begin();
|
---|
945 | m != vec.end(); ++m)
|
---|
946 | mVMModel->addItem(*m);
|
---|
947 | /* Apply the saved sort order. */
|
---|
948 | mVMModel->sortByIdList(vbox.GetExtraDataStringList(VBoxDefs::GUI_SelectorVMPositions));
|
---|
949 | /* Update details page. */
|
---|
950 | vmListViewCurrentChanged();
|
---|
951 |
|
---|
952 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
953 | if (vboxGlobal().isTrayMenu())
|
---|
954 | mTrayIcon->refresh();
|
---|
955 | #endif
|
---|
956 | }
|
---|
957 |
|
---|
958 | void VBoxSelectorWnd::refreshVMItem(const QString &aID,
|
---|
959 | bool aDetails,
|
---|
960 | bool aSnapshots,
|
---|
961 | bool aDescription)
|
---|
962 | {
|
---|
963 | UIVMItem *item = mVMModel->itemById(aID);
|
---|
964 | if (item)
|
---|
965 | {
|
---|
966 | mVMModel->refreshItem(item);
|
---|
967 | if (item && item->id() == aID)
|
---|
968 | vmListViewCurrentChanged(aDetails, aSnapshots, aDescription);
|
---|
969 | }
|
---|
970 | }
|
---|
971 |
|
---|
972 | void VBoxSelectorWnd::showContextMenu(const QPoint &aPoint)
|
---|
973 | {
|
---|
974 | /* Send a context menu request */
|
---|
975 | const QModelIndex &index = mVMListView->indexAt(aPoint);
|
---|
976 | if (index.isValid())
|
---|
977 | if (mVMListView->model()->data(index,
|
---|
978 | UIVMItemModel::UIVMItemPtrRole).value <UIVMItem*>())
|
---|
979 | mVMCtxtMenu->exec(mVMListView->mapToGlobal(aPoint));
|
---|
980 | }
|
---|
981 |
|
---|
982 |
|
---|
983 | void VBoxSelectorWnd::sltOpenUrls(QList<QUrl> list /* = QList<QUrl>() */)
|
---|
984 | {
|
---|
985 | /* Make sure any pending D&D events are consumed. */
|
---|
986 | qApp->processEvents();
|
---|
987 | if (list.isEmpty())
|
---|
988 | {
|
---|
989 | list = vboxGlobal().argUrlList();
|
---|
990 | vboxGlobal().argUrlList().clear();
|
---|
991 | }
|
---|
992 | /* Check if we are can handle the dropped urls. */
|
---|
993 | for (int i = 0; i < list.size(); ++i)
|
---|
994 | {
|
---|
995 | #ifdef Q_WS_MAC
|
---|
996 | QString strFile = ::darwinResolveAlias(list.at(i).toLocalFile());
|
---|
997 | #else /* Q_WS_MAC */
|
---|
998 | QString strFile = list.at(i).toLocalFile();
|
---|
999 | #endif /* !Q_WS_MAC */
|
---|
1000 | if ( !strFile.isEmpty()
|
---|
1001 | && QFile::exists(strFile))
|
---|
1002 | {
|
---|
1003 | if (VBoxGlobal::hasAllowedExtension(strFile, VBoxDefs::VBoxFileExts))
|
---|
1004 | {
|
---|
1005 | /* VBox config files. */
|
---|
1006 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
1007 | CMachine machine = vbox.FindMachine(strFile);
|
---|
1008 | if (!machine.isNull())
|
---|
1009 | {
|
---|
1010 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
1011 | CMachine machine = vbox.FindMachine(strFile);
|
---|
1012 | if (!machine.isNull())
|
---|
1013 | vboxGlobal().launchMachine(machine);
|
---|
1014 | }else
|
---|
1015 | vmAdd(strFile);
|
---|
1016 | }
|
---|
1017 | else if (VBoxGlobal::hasAllowedExtension(strFile, VBoxDefs::OVFFileExts))
|
---|
1018 | {
|
---|
1019 | /* OVF/OVA. Only one file at the time. */
|
---|
1020 | fileImportAppliance(strFile);
|
---|
1021 | break;
|
---|
1022 | }
|
---|
1023 | else if (VBoxGlobal::hasAllowedExtension(strFile, VBoxDefs::VBoxExtPackFileExts))
|
---|
1024 | {
|
---|
1025 | UIGlobalSettingsExtension::doInstallation(strFile, this, NULL);
|
---|
1026 | }
|
---|
1027 | }
|
---|
1028 | }
|
---|
1029 | }
|
---|
1030 |
|
---|
1031 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
1032 |
|
---|
1033 | void VBoxSelectorWnd::trayIconActivated(QSystemTrayIcon::ActivationReason aReason)
|
---|
1034 | {
|
---|
1035 | switch (aReason)
|
---|
1036 | {
|
---|
1037 | case QSystemTrayIcon::Context:
|
---|
1038 |
|
---|
1039 | mTrayIcon->refresh();
|
---|
1040 | break;
|
---|
1041 |
|
---|
1042 | case QSystemTrayIcon::Trigger:
|
---|
1043 | break;
|
---|
1044 |
|
---|
1045 | case QSystemTrayIcon::DoubleClick:
|
---|
1046 |
|
---|
1047 | vboxGlobal().trayIconShowSelector();
|
---|
1048 | break;
|
---|
1049 |
|
---|
1050 | case QSystemTrayIcon::MiddleClick:
|
---|
1051 | break;
|
---|
1052 |
|
---|
1053 | default:
|
---|
1054 | break;
|
---|
1055 | }
|
---|
1056 | }
|
---|
1057 |
|
---|
1058 | void VBoxSelectorWnd::showWindow()
|
---|
1059 | {
|
---|
1060 | showNormal();
|
---|
1061 | raise();
|
---|
1062 | activateWindow();
|
---|
1063 | }
|
---|
1064 |
|
---|
1065 | #endif // VBOX_GUI_WITH_SYSTRAY
|
---|
1066 |
|
---|
1067 | // Protected members
|
---|
1068 | /////////////////////////////////////////////////////////////////////////////
|
---|
1069 |
|
---|
1070 | bool VBoxSelectorWnd::event(QEvent *e)
|
---|
1071 | {
|
---|
1072 | switch (e->type())
|
---|
1073 | {
|
---|
1074 | /* By handling every Resize and Move we keep track of the normal
|
---|
1075 | * (non-minimized and non-maximized) window geometry. Shame on Qt
|
---|
1076 | * that it doesn't provide this geometry in its public APIs. */
|
---|
1077 |
|
---|
1078 | case QEvent::Resize:
|
---|
1079 | {
|
---|
1080 | QResizeEvent *re = (QResizeEvent *) e;
|
---|
1081 | if ((windowState() & (Qt::WindowMaximized | Qt::WindowMinimized |
|
---|
1082 | Qt::WindowFullScreen)) == 0)
|
---|
1083 | mNormalGeo.setSize(re->size());
|
---|
1084 | break;
|
---|
1085 | }
|
---|
1086 | case QEvent::Move:
|
---|
1087 | {
|
---|
1088 | if ((windowState() & (Qt::WindowMaximized | Qt::WindowMinimized |
|
---|
1089 | Qt::WindowFullScreen)) == 0)
|
---|
1090 | mNormalGeo.moveTo(geometry().x(), geometry().y());
|
---|
1091 | break;
|
---|
1092 | }
|
---|
1093 | case QEvent::WindowDeactivate:
|
---|
1094 | {
|
---|
1095 | /* Make sure every status bar hint is cleared when the window lost
|
---|
1096 | * focus. */
|
---|
1097 | statusBar()->clearMessage();
|
---|
1098 | break;
|
---|
1099 | }
|
---|
1100 | #ifdef Q_WS_MAC
|
---|
1101 | case QEvent::ContextMenu:
|
---|
1102 | {
|
---|
1103 | /* This is the unified context menu event. Lets show the context
|
---|
1104 | * menu. */
|
---|
1105 | QContextMenuEvent *pCE = static_cast<QContextMenuEvent*>(e);
|
---|
1106 | showViewContextMenu(pCE->globalPos());
|
---|
1107 | /* Accept it to interrupt the chain. */
|
---|
1108 | pCE->accept();
|
---|
1109 | return false;
|
---|
1110 | break;
|
---|
1111 | }
|
---|
1112 | case QEvent::ToolBarChange:
|
---|
1113 | {
|
---|
1114 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
1115 | /* We have to invert the isVisible check one time, cause this event
|
---|
1116 | * is sent *before* the real toggle is done. Really intuitive
|
---|
1117 | * Trolls. */
|
---|
1118 | vbox.SetExtraData(VBoxDefs::GUI_Toolbar, !::darwinIsToolbarVisible(mVMToolBar) ? "true" : "false");
|
---|
1119 | break;
|
---|
1120 | }
|
---|
1121 | #endif /* Q_WS_MAC */
|
---|
1122 | default:
|
---|
1123 | break;
|
---|
1124 | }
|
---|
1125 |
|
---|
1126 | return QMainWindow::event(e);
|
---|
1127 | }
|
---|
1128 |
|
---|
1129 | void VBoxSelectorWnd::closeEvent(QCloseEvent *aEvent)
|
---|
1130 | {
|
---|
1131 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
1132 | /* Needed for breaking out of the while() loop in main(). */
|
---|
1133 | if (vboxGlobal().isTrayMenu())
|
---|
1134 | vboxGlobal().setTrayMenu(false);
|
---|
1135 | #endif
|
---|
1136 |
|
---|
1137 | emit closing();
|
---|
1138 | QMainWindow::closeEvent(aEvent);
|
---|
1139 | }
|
---|
1140 |
|
---|
1141 | #ifdef Q_WS_MAC
|
---|
1142 | bool VBoxSelectorWnd::eventFilter(QObject *pObject, QEvent *pEvent)
|
---|
1143 | {
|
---|
1144 | if (!isActiveWindow())
|
---|
1145 | return QIWithRetranslateUI2<QMainWindow>::eventFilter(pObject, pEvent);
|
---|
1146 |
|
---|
1147 | if (qobject_cast<QWidget*>(pObject) &&
|
---|
1148 | qobject_cast<QWidget*>(pObject)->window() != this)
|
---|
1149 | return QIWithRetranslateUI2<QMainWindow>::eventFilter(pObject, pEvent);
|
---|
1150 |
|
---|
1151 | switch (pEvent->type())
|
---|
1152 | {
|
---|
1153 | case QEvent::FileOpen:
|
---|
1154 | {
|
---|
1155 | sltOpenUrls(QList<QUrl>() << static_cast<QFileOpenEvent*>(pEvent)->file());
|
---|
1156 | pEvent->accept();
|
---|
1157 | return true;
|
---|
1158 | break;
|
---|
1159 | }
|
---|
1160 | # if (QT_VERSION < 0x040402)
|
---|
1161 | case QEvent::KeyPress:
|
---|
1162 | {
|
---|
1163 | /* Bug in Qt below 4.4.2. The key events are send to the current
|
---|
1164 | * window even if a menu is shown & has the focus. See
|
---|
1165 | * http://trolltech.com/developer/task-tracker/index_html?method=entry&id=214681. */
|
---|
1166 | if (::darwinIsMenuOpen())
|
---|
1167 | return true;
|
---|
1168 | break;
|
---|
1169 | }
|
---|
1170 | # endif
|
---|
1171 | default:
|
---|
1172 | break;
|
---|
1173 | }
|
---|
1174 | return QIWithRetranslateUI2<QMainWindow>::eventFilter(pObject, pEvent);
|
---|
1175 | }
|
---|
1176 | #endif /* Q_WS_MAC */
|
---|
1177 |
|
---|
1178 | /**
|
---|
1179 | * Sets the strings of the subwidgets using the current
|
---|
1180 | * language.
|
---|
1181 | */
|
---|
1182 | void VBoxSelectorWnd::retranslateUi()
|
---|
1183 | {
|
---|
1184 | #ifdef VBOX_OSE
|
---|
1185 | QString title(tr("VirtualBox OSE"));
|
---|
1186 | #else
|
---|
1187 | QString title(VBOX_PRODUCT);
|
---|
1188 | #endif
|
---|
1189 | title += " " + tr("Manager", "Note: main window title which is pretended by the product name.");
|
---|
1190 |
|
---|
1191 | #ifdef VBOX_BLEEDING_EDGE
|
---|
1192 | title += QString(" EXPERIMENTAL build ")
|
---|
1193 | + QString(RTBldCfgVersion())
|
---|
1194 | + QString(" r")
|
---|
1195 | + QString(RTBldCfgRevisionStr())
|
---|
1196 | + QString(" - "VBOX_BLEEDING_EDGE);
|
---|
1197 | #endif
|
---|
1198 |
|
---|
1199 | setWindowTitle(title);
|
---|
1200 |
|
---|
1201 | /* ensure the details and screenshot view are updated */
|
---|
1202 | vmListViewCurrentChanged();
|
---|
1203 |
|
---|
1204 | mFileMediaMgrAction->setText(tr("&Virtual Media Manager..."));
|
---|
1205 | mFileMediaMgrAction->setShortcut(gSS->keySequence(UISelectorShortcuts::VirtualMediaManagerShortcut));
|
---|
1206 | mFileMediaMgrAction->setStatusTip(tr("Display the Virtual Media Manager dialog"));
|
---|
1207 |
|
---|
1208 | mFileApplianceImportAction->setText(tr("&Import Appliance..."));
|
---|
1209 | mFileApplianceImportAction->setShortcut(gSS->keySequence(UISelectorShortcuts::ImportApplianceShortcut));
|
---|
1210 | mFileApplianceImportAction->setStatusTip(tr("Import an appliance into VirtualBox"));
|
---|
1211 |
|
---|
1212 | mFileApplianceExportAction->setText(tr("&Export Appliance..."));
|
---|
1213 | mFileApplianceExportAction->setShortcut(gSS->keySequence(UISelectorShortcuts::ExportApplianceShortcut));
|
---|
1214 | mFileApplianceExportAction->setStatusTip(tr("Export one or more VirtualBox virtual machines as an appliance"));
|
---|
1215 |
|
---|
1216 | mFileSettingsAction->setText(tr("&Preferences...", "global settings"));
|
---|
1217 | mFileSettingsAction->setShortcut(gSS->keySequence(UISelectorShortcuts::PreferencesShortcut));
|
---|
1218 | mFileSettingsAction->setStatusTip(tr("Display the global settings dialog"));
|
---|
1219 |
|
---|
1220 | mFileExitAction->setText(tr("E&xit"));
|
---|
1221 | mFileExitAction->setShortcut(gSS->keySequence(UISelectorShortcuts::ExitShortcut));
|
---|
1222 | mFileExitAction->setStatusTip(tr("Close application"));
|
---|
1223 |
|
---|
1224 | mVmNewAction->setText(tr("&New..."));
|
---|
1225 | mVmNewAction->setShortcut(gSS->keySequence(UISelectorShortcuts::NewVMShortcut));
|
---|
1226 | mVmNewAction->setStatusTip(tr("Create a new virtual machine"));
|
---|
1227 | mVmNewAction->setToolTip(mVmNewAction->text().remove('&').remove('.') +
|
---|
1228 | (mVmNewAction->shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(mVmNewAction->shortcut().toString())));
|
---|
1229 |
|
---|
1230 | mVmAddAction->setText(tr("&Add..."));
|
---|
1231 | mVmAddAction->setShortcut(gSS->keySequence(UISelectorShortcuts::AddVMShortcut));
|
---|
1232 | mVmAddAction->setStatusTip(tr("Add an existing virtual machine"));
|
---|
1233 |
|
---|
1234 | mVmConfigAction->setText(tr("&Settings..."));
|
---|
1235 | mVmConfigAction->setShortcut(gSS->keySequence(UISelectorShortcuts::SettingsVMShortcut));
|
---|
1236 | mVmConfigAction->setStatusTip(tr("Configure the selected virtual machine"));
|
---|
1237 | mVmConfigAction->setToolTip(mVmConfigAction->text().remove('&').remove('.') +
|
---|
1238 | (mVmConfigAction->shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(mVmConfigAction->shortcut().toString())));
|
---|
1239 |
|
---|
1240 | mVmDeleteAction->setText(tr("&Remove"));
|
---|
1241 | mVmDeleteAction->setShortcut(gSS->keySequence(UISelectorShortcuts::RemoveVMShortcut));
|
---|
1242 | mVmDeleteAction->setStatusTip(tr("Remove the selected virtual machine"));
|
---|
1243 |
|
---|
1244 | /* Note: mVmStartAction text is set up in vmListViewCurrentChanged() */
|
---|
1245 |
|
---|
1246 | mVmDiscardAction->setText(tr("D&iscard"));
|
---|
1247 | mVmDiscardAction->setShortcut(gSS->keySequence(UISelectorShortcuts::DiscardVMShortcut));
|
---|
1248 | mVmDiscardAction->setStatusTip(
|
---|
1249 | tr("Discard the saved state of the selected virtual machine"));
|
---|
1250 | mVmDiscardAction->setToolTip(mVmDiscardAction->text().remove('&').remove('.') +
|
---|
1251 | (mVmDiscardAction->shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(mVmDiscardAction->shortcut().toString())));
|
---|
1252 |
|
---|
1253 | mVmPauseAction->setText(tr("&Pause"));
|
---|
1254 | mVmPauseAction->setStatusTip(
|
---|
1255 | tr("Suspend the execution of the virtual machine"));
|
---|
1256 |
|
---|
1257 | mVmRefreshAction->setText(tr("Re&fresh"));
|
---|
1258 | mVmRefreshAction->setShortcut(gSS->keySequence(UISelectorShortcuts::RefreshVMShortcut));
|
---|
1259 | mVmRefreshAction->setStatusTip(
|
---|
1260 | tr("Refresh the accessibility state of the selected virtual machine"));
|
---|
1261 |
|
---|
1262 | mVmShowLogsAction->setText(tr("Show &Log..."));
|
---|
1263 | mVmShowLogsAction->setIconText(tr("Log", "icon text"));
|
---|
1264 | mVmShowLogsAction->setShortcut(gSS->keySequence(UISelectorShortcuts::ShowVMLogShortcut));
|
---|
1265 | mVmShowLogsAction->setStatusTip(
|
---|
1266 | tr("Show the log files of the selected virtual machine"));
|
---|
1267 |
|
---|
1268 | #if defined(Q_WS_MAC)
|
---|
1269 | mVmOpenInFileManagerAction->setText(tr("Show in Finder"));
|
---|
1270 | mVmOpenInFileManagerAction->setStatusTip(tr("Show the VirtualBox Machine Definition file in Finder."));
|
---|
1271 | mVmCreateShortcut->setText(tr("Create Alias on Desktop"));
|
---|
1272 | mVmCreateShortcut->setStatusTip(tr("Creates an Alias file to the VirtualBox Machine Definition file on your Desktop."));
|
---|
1273 | #elif defined(Q_WS_WIN)
|
---|
1274 | mVmOpenInFileManagerAction->setText(tr("Show in Explorer"));
|
---|
1275 | mVmOpenInFileManagerAction->setStatusTip(tr("Show the VirtualBox Machine Definition file in Explorer."));
|
---|
1276 | mVmCreateShortcut->setText(tr("Create Shortcut on Desktop"));
|
---|
1277 | mVmCreateShortcut->setStatusTip(tr("Creates an Shortcut file to the VirtualBox Machine Definition file on your Desktop."));
|
---|
1278 | #else
|
---|
1279 | mVmOpenInFileManagerAction->setText(tr("Show in File Manager"));
|
---|
1280 | mVmOpenInFileManagerAction->setStatusTip(tr("Show the VirtualBox Machine Definition file in the File Manager"));
|
---|
1281 | mVmCreateShortcut->setText(tr("Create Shortcut on Desktop"));
|
---|
1282 | mVmCreateShortcut->setStatusTip(tr("Creates an Shortcut file to the VirtualBox Machine Definition file on your Desktop."));
|
---|
1283 | #endif
|
---|
1284 | mVmOpenInFileManagerAction->setShortcut(gSS->keySequence(UISelectorShortcuts::ShowVMInFileManagerShortcut));
|
---|
1285 | mVmCreateShortcut->setShortcut(gSS->keySequence(UISelectorShortcuts::CreateVMAliasShortcut));
|
---|
1286 |
|
---|
1287 | mHelpActions.retranslateUi();
|
---|
1288 |
|
---|
1289 | #ifdef Q_WS_MAC
|
---|
1290 | mFileMenu->setTitle(tr("&File", "Mac OS X version"));
|
---|
1291 | #else /* Q_WS_MAC */
|
---|
1292 | mFileMenu->setTitle(tr("&File", "Non Mac OS X version"));
|
---|
1293 | #endif /* !Q_WS_MAC */
|
---|
1294 | mVMMenu->setTitle(tr("&Machine"));
|
---|
1295 | mHelpMenu->setTitle(tr("&Help"));
|
---|
1296 |
|
---|
1297 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
1298 | if (vboxGlobal().isTrayMenu())
|
---|
1299 | {
|
---|
1300 | mTrayIcon->retranslateUi();
|
---|
1301 | mTrayIcon->refresh();
|
---|
1302 | }
|
---|
1303 | #endif
|
---|
1304 |
|
---|
1305 | #ifdef QT_MAC_USE_COCOA
|
---|
1306 | /* There is a bug in Qt Cocoa which result in showing a "more arrow" when
|
---|
1307 | the necessary size of the toolbar is increased. Also for some languages
|
---|
1308 | the with doesn't match if the text increase. So manually adjust the size
|
---|
1309 | after changing the text. */
|
---|
1310 | mVMToolBar->updateLayout();
|
---|
1311 | #endif /* QT_MAC_USE_COCOA */
|
---|
1312 | }
|
---|
1313 |
|
---|
1314 |
|
---|
1315 | // Private members
|
---|
1316 | /////////////////////////////////////////////////////////////////////////////
|
---|
1317 |
|
---|
1318 | //
|
---|
1319 | // Private slots
|
---|
1320 | /////////////////////////////////////////////////////////////////////////////
|
---|
1321 |
|
---|
1322 | void VBoxSelectorWnd::vmListViewCurrentChanged(bool aRefreshDetails,
|
---|
1323 | bool aRefreshSnapshots,
|
---|
1324 | bool aRefreshDescription)
|
---|
1325 | {
|
---|
1326 | UIVMItem *item = mVMListView->selectedItem();
|
---|
1327 |
|
---|
1328 | if (item && item->accessible())
|
---|
1329 | {
|
---|
1330 | CMachine m = item->machine();
|
---|
1331 |
|
---|
1332 | KMachineState state = item->machineState();
|
---|
1333 | bool running = item->sessionState() != KSessionState_Unlocked;
|
---|
1334 | bool modifyEnabled = !running && state != KMachineState_Saved;
|
---|
1335 |
|
---|
1336 | if ( aRefreshDetails
|
---|
1337 | || aRefreshDescription)
|
---|
1338 | m_pVMDesktop->updateDetails(item, m);
|
---|
1339 | if (aRefreshSnapshots)
|
---|
1340 | m_pVMDesktop->updateSnapshots(item, m);
|
---|
1341 | // if (aRefreshDescription)
|
---|
1342 | // m_pVMDesktop->updateDescription(item, m);
|
---|
1343 |
|
---|
1344 | /* enable/disable modify actions */
|
---|
1345 | mVmConfigAction->setEnabled(modifyEnabled);
|
---|
1346 | mVmDeleteAction->setEnabled(!running);
|
---|
1347 | mVmDiscardAction->setEnabled(state == KMachineState_Saved && !running);
|
---|
1348 | mVmPauseAction->setEnabled( state == KMachineState_Running
|
---|
1349 | || state == KMachineState_Teleporting
|
---|
1350 | || state == KMachineState_LiveSnapshotting
|
---|
1351 | || state == KMachineState_Paused
|
---|
1352 | || state == KMachineState_TeleportingPausedVM /** @todo Live Migration: does this make sense? */
|
---|
1353 | );
|
---|
1354 |
|
---|
1355 | /* change the Start button text accordingly */
|
---|
1356 | if ( state == KMachineState_PoweredOff
|
---|
1357 | || state == KMachineState_Saved
|
---|
1358 | || state == KMachineState_Teleported
|
---|
1359 | || state == KMachineState_Aborted
|
---|
1360 | )
|
---|
1361 | {
|
---|
1362 | mVmStartAction->setText(tr("S&tart"));
|
---|
1363 | mVmStartAction->setShortcut(gSS->keySequence(UISelectorShortcuts::StartVMShortcut));
|
---|
1364 | mVmStartAction->setToolTip(mVmStartAction->text().remove('&').remove('.') +
|
---|
1365 | (mVmStartAction->shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(mVmStartAction->shortcut().toString())));
|
---|
1366 | #ifdef QT_MAC_USE_COCOA
|
---|
1367 | /* There is a bug in Qt Cocoa which result in showing a "more arrow" when
|
---|
1368 | the necessary size of the toolbar is increased. Also for some languages
|
---|
1369 | the with doesn't match if the text increase. So manually adjust the size
|
---|
1370 | after changing the text. */
|
---|
1371 | mVMToolBar->updateLayout();
|
---|
1372 | #endif /* QT_MAC_USE_COCOA */
|
---|
1373 | mVmStartAction->setStatusTip(
|
---|
1374 | tr("Start the selected virtual machine"));
|
---|
1375 |
|
---|
1376 | mVmStartAction->setEnabled(!running);
|
---|
1377 | }
|
---|
1378 | else
|
---|
1379 | {
|
---|
1380 | mVmStartAction->setText(tr("S&how"));
|
---|
1381 | mVmStartAction->setShortcut(gSS->keySequence(UISelectorShortcuts::StartVMShortcut));
|
---|
1382 | mVmStartAction->setToolTip(mVmStartAction->text().remove('&').remove('.') +
|
---|
1383 | (mVmStartAction->shortcut().toString().isEmpty() ? "" : QString(" (%1)").arg(mVmStartAction->shortcut().toString())));
|
---|
1384 | #ifdef QT_MAC_USE_COCOA
|
---|
1385 | /* There is a bug in Qt Cocoa which result in showing a "more arrow" when
|
---|
1386 | the necessary size of the toolbar is increased. Also for some languages
|
---|
1387 | the with doesn't match if the text increase. So manually adjust the size
|
---|
1388 | after changing the text. */
|
---|
1389 | mVMToolBar->updateLayout();
|
---|
1390 | #endif /* QT_MAC_USE_COCOA */
|
---|
1391 | mVmStartAction->setStatusTip(
|
---|
1392 | tr("Switch to the window of the selected virtual machine"));
|
---|
1393 |
|
---|
1394 | mVmStartAction->setEnabled(item->canSwitchTo());
|
---|
1395 | }
|
---|
1396 |
|
---|
1397 | /* change the Pause/Resume button text accordingly */
|
---|
1398 | if ( state == KMachineState_Paused
|
---|
1399 | || state == KMachineState_TeleportingPausedVM /*?*/
|
---|
1400 | )
|
---|
1401 | {
|
---|
1402 | mVmPauseAction->setText(tr("R&esume"));
|
---|
1403 | mVmPauseAction->setShortcut(gSS->keySequence(UISelectorShortcuts::PauseVMShortcut));
|
---|
1404 | mVmPauseAction->setStatusTip(
|
---|
1405 | tr("Resume the execution of the virtual machine"));
|
---|
1406 | mVmPauseAction->blockSignals(true);
|
---|
1407 | mVmPauseAction->setChecked(true);
|
---|
1408 | mVmPauseAction->blockSignals(false);
|
---|
1409 | }
|
---|
1410 | else
|
---|
1411 | {
|
---|
1412 | mVmPauseAction->setText(tr("&Pause"));
|
---|
1413 | mVmPauseAction->setShortcut(gSS->keySequence(UISelectorShortcuts::PauseVMShortcut));
|
---|
1414 | mVmPauseAction->setStatusTip(
|
---|
1415 | tr("Suspend the execution of the virtual machine"));
|
---|
1416 | mVmPauseAction->blockSignals(true);
|
---|
1417 | mVmPauseAction->setChecked(false);
|
---|
1418 | mVmPauseAction->blockSignals(false);
|
---|
1419 | }
|
---|
1420 |
|
---|
1421 | /* disable Refresh for accessible machines */
|
---|
1422 | mVmRefreshAction->setEnabled(false);
|
---|
1423 |
|
---|
1424 | /* enable the show log item for the selected vm */
|
---|
1425 | mVmShowLogsAction->setEnabled(true);
|
---|
1426 | /* Enable the shell interaction features. */
|
---|
1427 | mVmOpenInFileManagerAction->setEnabled(true);
|
---|
1428 | #ifdef Q_WS_MAC
|
---|
1429 | /* On Mac OS X this are real alias files, which don't work with the old
|
---|
1430 | * legacy xml files. On the other OS's some kind of start up script is
|
---|
1431 | * used. */
|
---|
1432 | mVmCreateShortcut->setEnabled(item->settingsFile().endsWith(".vbox", Qt::CaseInsensitive));
|
---|
1433 | #else /* Q_WS_MAC */
|
---|
1434 | mVmCreateShortcut->setEnabled(true);
|
---|
1435 | #endif /* Q_WS_MAC */
|
---|
1436 | }
|
---|
1437 | else
|
---|
1438 | {
|
---|
1439 | /* Note that the machine becomes inaccessible (or if the last VM gets
|
---|
1440 | * deleted), we have to update all fields, ignoring input
|
---|
1441 | * arguments. */
|
---|
1442 |
|
---|
1443 | if (item)
|
---|
1444 | {
|
---|
1445 | /* the VM is inaccessible */
|
---|
1446 | m_pVMDesktop->updateDetailsErrorText(
|
---|
1447 | VBoxProblemReporter::formatErrorInfo(item->accessError()));
|
---|
1448 | mVmRefreshAction->setEnabled(true);
|
---|
1449 | }
|
---|
1450 | else
|
---|
1451 | {
|
---|
1452 | /* default HTML support in Qt is terrible so just try to get
|
---|
1453 | * something really simple */
|
---|
1454 | m_pVMDesktop->updateDetailsText(
|
---|
1455 | tr("<h3>"
|
---|
1456 | "Welcome to VirtualBox!</h3>"
|
---|
1457 | "<p>The left part of this window is "
|
---|
1458 | "a list of all virtual machines on your computer. "
|
---|
1459 | "The list is empty now because you haven't created any virtual "
|
---|
1460 | "machines yet."
|
---|
1461 | "<img src=:/welcome.png align=right/></p>"
|
---|
1462 | "<p>In order to create a new virtual machine, press the "
|
---|
1463 | "<b>New</b> button in the main tool bar located "
|
---|
1464 | "at the top of the window.</p>"
|
---|
1465 | "<p>You can press the <b>%1</b> key to get instant help, "
|
---|
1466 | "or visit "
|
---|
1467 | "<a href=http://www.virtualbox.org>www.virtualbox.org</a> "
|
---|
1468 | "for the latest information and news.</p>").arg(QKeySequence(QKeySequence::HelpContents).toString(QKeySequence::NativeText)));
|
---|
1469 | mVmRefreshAction->setEnabled(false);
|
---|
1470 | }
|
---|
1471 |
|
---|
1472 | /* empty and disable other tabs */
|
---|
1473 | m_pVMDesktop->updateSnapshots(0, CMachine());
|
---|
1474 | // m_pVMDesktop->updateDescription(0, CMachine());
|
---|
1475 |
|
---|
1476 | /* disable modify actions */
|
---|
1477 | mVmConfigAction->setEnabled(false);
|
---|
1478 | mVmDeleteAction->setEnabled(item != NULL);
|
---|
1479 | mVmDiscardAction->setEnabled(false);
|
---|
1480 | mVmPauseAction->setEnabled(false);
|
---|
1481 |
|
---|
1482 | /* change the Start button text accordingly */
|
---|
1483 | mVmStartAction->setText(tr("S&tart"));
|
---|
1484 | mVmStartAction->setStatusTip(
|
---|
1485 | tr("Start the selected virtual machine"));
|
---|
1486 | mVmStartAction->setEnabled(false);
|
---|
1487 |
|
---|
1488 | /* disable the show log item for the selected vm */
|
---|
1489 | mVmShowLogsAction->setEnabled(false);
|
---|
1490 | /* Disable the shell interaction features. */
|
---|
1491 | mVmOpenInFileManagerAction->setEnabled(false);
|
---|
1492 | mVmCreateShortcut->setEnabled(false);
|
---|
1493 | }
|
---|
1494 | }
|
---|
1495 |
|
---|
1496 | void VBoxSelectorWnd::mediumEnumStarted()
|
---|
1497 | {
|
---|
1498 | /* refresh the current details to pick up hard disk sizes */
|
---|
1499 | vmListViewCurrentChanged(true /* aRefreshDetails */);
|
---|
1500 | }
|
---|
1501 |
|
---|
1502 | void VBoxSelectorWnd::mediumEnumFinished(const VBoxMediaList &list)
|
---|
1503 | {
|
---|
1504 | /* refresh the current details to pick up hard disk sizes */
|
---|
1505 | vmListViewCurrentChanged(true /* aRefreshDetails */);
|
---|
1506 |
|
---|
1507 | /* we warn about inaccessible media only once (after media emumeration
|
---|
1508 | * started from main() at startup), to avoid annoying the user */
|
---|
1509 | if ( mDoneInaccessibleWarningOnce
|
---|
1510 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
1511 | || vboxGlobal().isTrayMenu()
|
---|
1512 | #endif
|
---|
1513 | )
|
---|
1514 | return;
|
---|
1515 |
|
---|
1516 | mDoneInaccessibleWarningOnce = true;
|
---|
1517 |
|
---|
1518 | do
|
---|
1519 | {
|
---|
1520 | /* ignore the signal if a modal widget is currently active (we won't be
|
---|
1521 | * able to properly show the modeless VDI manager window in this case) */
|
---|
1522 | if (QApplication::activeModalWidget())
|
---|
1523 | break;
|
---|
1524 |
|
---|
1525 | /* ignore the signal if a VBoxMediaManagerDlg window is active */
|
---|
1526 | if (qApp->activeWindow() &&
|
---|
1527 | !strcmp(qApp->activeWindow()->metaObject()->className(), "VBoxMediaManagerDlg"))
|
---|
1528 | break;
|
---|
1529 |
|
---|
1530 | /* look for at least one inaccessible media */
|
---|
1531 | VBoxMediaList::const_iterator it;
|
---|
1532 | for (it = list.begin(); it != list.end(); ++ it)
|
---|
1533 | if ((*it).state() == KMediumState_Inaccessible)
|
---|
1534 | break;
|
---|
1535 |
|
---|
1536 | if (it != list.end() && vboxProblem().remindAboutInaccessibleMedia())
|
---|
1537 | {
|
---|
1538 | /* Show the VDM dialog but don't refresh once more after a
|
---|
1539 | * just-finished refresh */
|
---|
1540 | VBoxMediaManagerDlg::showModeless(this, false /* aRefresh */);
|
---|
1541 | }
|
---|
1542 | }
|
---|
1543 | while (0);
|
---|
1544 | }
|
---|
1545 |
|
---|
1546 | void VBoxSelectorWnd::machineStateChanged(QString strId, KMachineState /* state */)
|
---|
1547 | {
|
---|
1548 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
1549 | if (vboxGlobal().isTrayMenu())
|
---|
1550 | {
|
---|
1551 | /* Check if there are some machines alive - else quit, since
|
---|
1552 | * we're not needed as a systray menu anymore. */
|
---|
1553 | if (vboxGlobal().mainWindowCount() == 0)
|
---|
1554 | {
|
---|
1555 | fileExit();
|
---|
1556 | return;
|
---|
1557 | }
|
---|
1558 | }
|
---|
1559 | #endif
|
---|
1560 |
|
---|
1561 | refreshVMItem(strId,
|
---|
1562 | false /* aDetails */,
|
---|
1563 | false /* aSnapshots */,
|
---|
1564 | false /* aDescription */);
|
---|
1565 |
|
---|
1566 | /* simulate a state change signal */
|
---|
1567 | // m_pVMDesktop->updateDescriptionState();
|
---|
1568 | }
|
---|
1569 |
|
---|
1570 | void VBoxSelectorWnd::machineDataChanged(QString strId)
|
---|
1571 | {
|
---|
1572 | refreshVMItem(strId,
|
---|
1573 | true /* aDetails */,
|
---|
1574 | false /* aSnapshots */,
|
---|
1575 | true /* aDescription */);
|
---|
1576 | }
|
---|
1577 |
|
---|
1578 | void VBoxSelectorWnd::machineRegistered(QString strId, bool fRegistered)
|
---|
1579 | {
|
---|
1580 | if (fRegistered)
|
---|
1581 | {
|
---|
1582 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
1583 | CMachine m = vbox.FindMachine(strId);
|
---|
1584 | if (!m.isNull())
|
---|
1585 | {
|
---|
1586 | mVMModel->addItem(m);
|
---|
1587 | /* Make sure the description, ... pages are properly updated.
|
---|
1588 | * Actually we haven't call the next method, but unfortunately Qt
|
---|
1589 | * seems buggy if the new item is on the same position as the
|
---|
1590 | * previous one. So go on the safe side and call this by our self. */
|
---|
1591 | vmListViewCurrentChanged();
|
---|
1592 | }
|
---|
1593 | /* m.isNull() is ok (theoretically, the machine could have been
|
---|
1594 | * already deregistered by some other client at this point) */
|
---|
1595 | }
|
---|
1596 | else
|
---|
1597 | {
|
---|
1598 | UIVMItem *item = mVMModel->itemById(strId);
|
---|
1599 | if (item)
|
---|
1600 | {
|
---|
1601 | int row = mVMModel->rowById(item->id());
|
---|
1602 | mVMModel->removeItem(item);
|
---|
1603 | mVMListView->ensureSomeRowSelected(row);
|
---|
1604 | }
|
---|
1605 |
|
---|
1606 | /* item = 0 is ok (if we originated this event then the item
|
---|
1607 | * has been already removed) */
|
---|
1608 | }
|
---|
1609 | }
|
---|
1610 |
|
---|
1611 | void VBoxSelectorWnd::sessionStateChanged(QString strId, KSessionState /* state */)
|
---|
1612 | {
|
---|
1613 | refreshVMItem(strId,
|
---|
1614 | true /* aDetails */,
|
---|
1615 | false /* aSnapshots */,
|
---|
1616 | false /* aDescription */);
|
---|
1617 |
|
---|
1618 | /* simulate a state change signal */
|
---|
1619 | // m_pVMDesktop->updateDescriptionState();
|
---|
1620 | }
|
---|
1621 |
|
---|
1622 | void VBoxSelectorWnd::snapshotChanged(QString strId, QString /* strSnapshotId */)
|
---|
1623 | {
|
---|
1624 | refreshVMItem(strId,
|
---|
1625 | false /* aDetails */,
|
---|
1626 | true /* aSnapshot */,
|
---|
1627 | false /* aDescription */);
|
---|
1628 | }
|
---|
1629 |
|
---|
1630 | #ifdef VBOX_GUI_WITH_SYSTRAY
|
---|
1631 |
|
---|
1632 | void VBoxSelectorWnd::mainWindowCountChanged(int count)
|
---|
1633 | {
|
---|
1634 | if (vboxGlobal().isTrayMenu() && count <= 1)
|
---|
1635 | fileExit();
|
---|
1636 | }
|
---|
1637 |
|
---|
1638 | void VBoxSelectorWnd::trayIconCanShow(bool fEnabled)
|
---|
1639 | {
|
---|
1640 | emit trayIconChanged(VBoxChangeTrayIconEvent(vboxGlobal().settings().trayIconEnabled()));
|
---|
1641 | }
|
---|
1642 |
|
---|
1643 | void VBoxSelectorWnd::trayIconShow(bool fEnabled)
|
---|
1644 | {
|
---|
1645 | if (vboxGlobal().isTrayMenu() && mTrayIcon)
|
---|
1646 | mTrayIcon->trayIconShow(fEnabled);
|
---|
1647 | }
|
---|
1648 |
|
---|
1649 | void VBoxSelectorWnd::trayIconChanged(bool fEnabled)
|
---|
1650 | {
|
---|
1651 | /* Not used yet. */
|
---|
1652 | }
|
---|
1653 |
|
---|
1654 | #endif /* VBOX_GUI_WITH_SYSTRAY */
|
---|
1655 |
|
---|
1656 | void VBoxSelectorWnd::sltDownloaderUserManualEmbed()
|
---|
1657 | {
|
---|
1658 | /* If there is User Manual downloader created => show the process bar: */
|
---|
1659 | if (UIDownloaderUserManual *pDl = UIDownloaderUserManual::current())
|
---|
1660 | statusBar()->addWidget(pDl->processWidget(this), 0);
|
---|
1661 | }
|
---|
1662 |
|
---|
1663 | void VBoxSelectorWnd::showViewContextMenu(const QPoint &pos)
|
---|
1664 | {
|
---|
1665 | CVirtualBox vbox = vboxGlobal().virtualBox();
|
---|
1666 | QString strToolbar = vbox.GetExtraData(VBoxDefs::GUI_Toolbar);
|
---|
1667 | QString strStatusbar = vbox.GetExtraData(VBoxDefs::GUI_Statusbar);
|
---|
1668 | bool fToolbar = strToolbar.isEmpty() || strToolbar == "true";
|
---|
1669 | bool fStatusbar = strStatusbar.isEmpty() || strStatusbar == "true";
|
---|
1670 |
|
---|
1671 | QList<QAction*> actions;
|
---|
1672 | QAction *pShowToolBar = new QAction(tr("Show Toolbar"), 0);
|
---|
1673 | pShowToolBar->setCheckable(true);
|
---|
1674 | pShowToolBar->setChecked(fToolbar);
|
---|
1675 | actions << pShowToolBar;
|
---|
1676 | QAction *pShowStatusBar = new QAction(tr("Show Statusbar"), 0);
|
---|
1677 | pShowStatusBar->setCheckable(true);
|
---|
1678 | pShowStatusBar->setChecked(fStatusbar);
|
---|
1679 | actions << pShowStatusBar;
|
---|
1680 |
|
---|
1681 | QPoint gpos = pos;
|
---|
1682 | QWidget *pSender = static_cast<QWidget*>(sender());
|
---|
1683 | if (pSender)
|
---|
1684 | gpos = pSender->mapToGlobal(pos);
|
---|
1685 | QAction *pResult = QMenu::exec(actions, gpos);
|
---|
1686 | if (pResult == pShowToolBar)
|
---|
1687 | {
|
---|
1688 | if (pResult->isChecked())
|
---|
1689 | {
|
---|
1690 | #ifdef Q_WS_MAC
|
---|
1691 | mVMToolBar->show();
|
---|
1692 | #else /* Q_WS_MAC */
|
---|
1693 | m_pBar->show();
|
---|
1694 | #endif /* !Q_WS_MAC */
|
---|
1695 | vbox.SetExtraData(VBoxDefs::GUI_Toolbar, "true");
|
---|
1696 | }
|
---|
1697 | else
|
---|
1698 | {
|
---|
1699 | #ifdef Q_WS_MAC
|
---|
1700 | mVMToolBar->hide();
|
---|
1701 | #else /* Q_WS_MAC */
|
---|
1702 | m_pBar->hide();
|
---|
1703 | #endif /* !Q_WS_MAC */
|
---|
1704 | vbox.SetExtraData(VBoxDefs::GUI_Toolbar, "false");
|
---|
1705 | }
|
---|
1706 | }else if (pResult == pShowStatusBar)
|
---|
1707 | {
|
---|
1708 | if (pResult->isChecked())
|
---|
1709 | {
|
---|
1710 | statusBar()->show();
|
---|
1711 | vbox.SetExtraData(VBoxDefs::GUI_Statusbar, "true");
|
---|
1712 | }
|
---|
1713 | else
|
---|
1714 | {
|
---|
1715 | statusBar()->hide();
|
---|
1716 | vbox.SetExtraData(VBoxDefs::GUI_Statusbar, "false");
|
---|
1717 | }
|
---|
1718 | }
|
---|
1719 | }
|
---|
1720 |
|
---|