~ubuntu-branches/ubuntu/trusty/virtualbox/trusty-proposed

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp

  • Committer: Package Import Robot
  • Author(s): Felix Geyer
  • Date: 2013-03-07 16:38:36 UTC
  • mfrom: (1.1.13) (3.1.20 experimental)
  • Revision ID: package-import@ubuntu.com-20130307163836-p93jpbgx39tp3gb4
Tags: 4.2.8-dfsg-0ubuntu1
* New upstream release. (Closes: #691148)
  - Fixes compatibility with kernel 3.8. (Closes: #700823; LP: #1101867)
* Switch to my @debian.org email address.
* Move package to contrib as virtualbox 4.2 needs a non-free compiler to
  build the BIOS.
* Build-depend on libdevmapper-dev.
* Refresh patches.
  - Drop 36-fix-ftbfs-xserver-112.patch, cve-2012-3221.patch,
    CVE-2013-0420.patch 37-kcompat-3.6.patch and 38-kcompat-3.7.patch.
* Drop all virtualbox-ose transitional packages.
* Drop the virtualbox-fuse package as vdfuse fails to build with
  virtualbox 4.2.
* Update install files and VBox.sh.
* Bump required kbuild version to 0.1.9998svn2577.
* Fix path to VBoxCreateUSBNode.sh in virtualbox.postinst. (Closes: #700479)
* Add an init script to virtuabox-guest-x11 which loads the vboxvideo
  kernel module. The X Server 1.13 doesn't load it anymore. (Closes: #686994)
* Update man pages. (Closes: #680053)
* Add 36-python-multiarch.patch from Rico Tzschichholz to fix detection of
  python in multiarch paths using pkg-config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 */
7
7
 
8
8
/*
9
 
 * Copyright (C) 2010-2011 Oracle Corporation
 
9
 * Copyright (C) 2010-2013 Oracle Corporation
10
10
 *
11
11
 * This file is part of VirtualBox Open Source Edition (OSE), as
12
12
 * available from http://www.virtualbox.org. This file is free software;
17
17
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18
18
 */
19
19
 
20
 
/* Local includes */
21
 
#include "COMDefs.h"
 
20
/* Qt includes: */
 
21
#include <QDesktopWidget>
 
22
#include <QDir>
 
23
#include <QFileInfo>
 
24
#include <QImageWriter>
 
25
#include <QPainter>
 
26
#include <QTimer>
 
27
 
 
28
/* GUI includes: */
22
29
#include "QIFileDialog.h"
23
30
#include "UIActionPoolRuntime.h"
 
31
#include "UINetworkManager.h"
24
32
#include "UIDownloaderAdditions.h"
25
33
#include "UIIconPool.h"
26
34
#include "UIKeyboardHandler.h"
38
46
#include "VBoxTakeSnapshotDlg.h"
39
47
#include "VBoxVMInformationDlg.h"
40
48
#include "UISettingsDialogSpecific.h"
 
49
#include "UIVMLogViewer.h"
 
50
#include "UIConverter.h"
41
51
#ifdef Q_WS_MAC
42
52
# include "DockIconPreview.h"
43
53
# include "UIExtraDataEventHandler.h"
44
54
#endif /* Q_WS_MAC */
45
55
 
46
 
/* Global includes */
 
56
/* COM includes: */
 
57
#include "CVirtualBoxErrorInfo.h"
 
58
#include "CMachineDebugger.h"
 
59
#include "CSnapshot.h"
 
60
#include "CDisplay.h"
 
61
#include "CStorageController.h"
 
62
#include "CMediumAttachment.h"
 
63
#include "CHostUSBDevice.h"
 
64
#include "CUSBDevice.h"
 
65
#include "CVRDEServer.h"
 
66
#include "CSystemProperties.h"
 
67
#ifdef Q_WS_MAC
 
68
# include "CGuest.h"
 
69
#endif /* Q_WS_MAC */
 
70
 
 
71
/* Other VBox includes: */
47
72
#include <iprt/path.h>
48
 
 
49
73
#ifdef VBOX_WITH_DEBUGGER_GUI
50
74
# include <iprt/ldr.h>
51
75
#endif /* VBOX_WITH_DEBUGGER_GUI */
52
76
 
 
77
/* External includes: */
53
78
#ifdef Q_WS_X11
54
79
# include <XKeyboard.h>
55
80
# include <QX11Info>
56
81
#endif /* Q_WS_X11 */
57
82
 
58
 
#include <QDir>
59
 
#include <QFileInfo>
60
 
#include <QDesktopWidget>
61
 
#include <QTimer>
62
 
 
63
83
struct MediumTarget
64
84
{
65
 
    MediumTarget() : name(QString("")), port(0), device(0), id(QString()), type(VBoxDefs::MediumType_Invalid) {}
 
85
    MediumTarget() : name(QString("")), port(0), device(0), id(QString()), type(UIMediumType_Invalid) {}
66
86
    MediumTarget(const QString &strName, LONG iPort, LONG iDevice)
67
 
        : name(strName), port(iPort), device(iDevice), id(QString()), type(VBoxDefs::MediumType_Invalid) {}
 
87
        : name(strName), port(iPort), device(iDevice), id(QString()), type(UIMediumType_Invalid) {}
68
88
    MediumTarget(const QString &strName, LONG iPort, LONG iDevice, const QString &strId)
69
 
        : name(strName), port(iPort), device(iDevice), id(strId), type(VBoxDefs::MediumType_Invalid) {}
70
 
    MediumTarget(const QString &strName, LONG iPort, LONG iDevice, VBoxDefs::MediumType eType)
 
89
        : name(strName), port(iPort), device(iDevice), id(strId), type(UIMediumType_Invalid) {}
 
90
    MediumTarget(const QString &strName, LONG iPort, LONG iDevice, UIMediumType eType)
71
91
        : name(strName), port(iPort), device(iDevice), id(QString()), type(eType) {}
72
92
    QString name;
73
93
    LONG port;
74
94
    LONG device;
75
95
    QString id;
76
 
    VBoxDefs::MediumType type;
 
96
    UIMediumType type;
77
97
};
78
98
Q_DECLARE_METATYPE(MediumTarget);
79
99
 
80
100
struct RecentMediumTarget
81
101
{
82
 
    RecentMediumTarget() : name(QString("")), port(0), device(0), location(QString()), type(VBoxDefs::MediumType_Invalid) {}
83
 
    RecentMediumTarget(const QString &strName, LONG iPort, LONG iDevice, const QString &strLocation, VBoxDefs::MediumType eType)
 
102
    RecentMediumTarget() : name(QString("")), port(0), device(0), location(QString()), type(UIMediumType_Invalid) {}
 
103
    RecentMediumTarget(const QString &strName, LONG iPort, LONG iDevice, const QString &strLocation, UIMediumType eType)
84
104
        : name(strName), port(iPort), device(iDevice), location(strLocation), type(eType) {}
85
105
    QString name;
86
106
    LONG port;
87
107
    LONG device;
88
108
    QString location;
89
 
    VBoxDefs::MediumType type;
 
109
    UIMediumType type;
90
110
};
91
111
Q_DECLARE_METATYPE(RecentMediumTarget);
92
112
 
100
120
};
101
121
Q_DECLARE_METATYPE(USBTarget);
102
122
 
 
123
/* static */
103
124
UIMachineLogic* UIMachineLogic::create(QObject *pParent,
104
125
                                       UISession *pSession,
105
126
                                       UIVisualStateType visualStateType)
106
127
{
107
 
    UIMachineLogic *logic = 0;
 
128
    UIMachineLogic *pLogic = 0;
108
129
    switch (visualStateType)
109
130
    {
110
131
        case UIVisualStateType_Normal:
111
 
            logic = new UIMachineLogicNormal(pParent, pSession);
 
132
            pLogic = new UIMachineLogicNormal(pParent, pSession);
112
133
            break;
113
134
        case UIVisualStateType_Fullscreen:
114
 
            logic = new UIMachineLogicFullscreen(pParent, pSession);
 
135
            pLogic = new UIMachineLogicFullscreen(pParent, pSession);
115
136
            break;
116
137
        case UIVisualStateType_Seamless:
117
 
            logic = new UIMachineLogicSeamless(pParent, pSession);
 
138
            pLogic = new UIMachineLogicSeamless(pParent, pSession);
118
139
            break;
119
140
        case UIVisualStateType_Scale:
120
 
            logic = new UIMachineLogicScale(pParent, pSession);
 
141
            pLogic = new UIMachineLogicScale(pParent, pSession);
121
142
            break;
122
143
    }
123
 
    return logic;
124
 
}
125
 
 
126
 
bool UIMachineLogic::checkAvailability()
127
 
{
128
 
    return true;
 
144
    return pLogic;
 
145
}
 
146
 
 
147
/* static */
 
148
void UIMachineLogic::destroy(UIMachineLogic *pWhichLogic)
 
149
{
 
150
    delete pWhichLogic;
 
151
}
 
152
 
 
153
void UIMachineLogic::prepare()
 
154
{
 
155
    /* Prepare required features: */
 
156
    prepareRequiredFeatures();
 
157
 
 
158
    /* Prepare session connections: */
 
159
    prepareSessionConnections();
 
160
 
 
161
    /* Prepare action groups:
 
162
     * Note: This has to be done before prepareActionConnections
 
163
     * cause here actions/menus are recreated. */
 
164
    prepareActionGroups();
 
165
    /* Prepare action connections: */
 
166
    prepareActionConnections();
 
167
 
 
168
    /* Prepare handlers: */
 
169
    prepareHandlers();
 
170
 
 
171
    /* Prepare machine window(s): */
 
172
    prepareMachineWindows();
 
173
 
 
174
#ifdef Q_WS_MAC
 
175
    /* Prepare dock: */
 
176
    prepareDock();
 
177
#endif /* Q_WS_MAC */
 
178
 
 
179
    /* Power up machine: */
 
180
    uisession()->powerUp();
 
181
 
 
182
    /* Initialization: */
 
183
    sltMachineStateChanged();
 
184
    sltAdditionsStateChanged();
 
185
    sltMouseCapabilityChanged();
 
186
 
 
187
#ifdef VBOX_WITH_DEBUGGER_GUI
 
188
    /* Prepare debugger: */
 
189
    prepareDebugger();
 
190
#endif /* VBOX_WITH_DEBUGGER_GUI */
 
191
 
 
192
    /* Retranslate logic part: */
 
193
    retranslateUi();
 
194
}
 
195
 
 
196
void UIMachineLogic::cleanup()
 
197
{
 
198
#ifdef VBOX_WITH_DEBUGGER_GUI
 
199
    /* Cleanup debugger: */
 
200
    cleanupDebugger();
 
201
#endif /* VBOX_WITH_DEBUGGER_GUI */
 
202
 
 
203
#ifdef Q_WS_MAC
 
204
    /* Cleanup dock: */
 
205
    cleanupDock();
 
206
#endif /* Q_WS_MAC */
 
207
 
 
208
    /* Cleanup machine window(s): */
 
209
    cleanupMachineWindows();
 
210
 
 
211
    /* Cleanup handlers: */
 
212
    cleanupHandlers();
 
213
 
 
214
    /* Cleanup action groups: */
 
215
    cleanupActionGroups();
 
216
}
 
217
 
 
218
CSession& UIMachineLogic::session() const
 
219
{
 
220
    return uisession()->session();
129
221
}
130
222
 
131
223
UIMachineWindow* UIMachineLogic::mainMachineWindow() const
134
226
    if (!isMachineWindowsCreated())
135
227
        return 0;
136
228
 
 
229
    /* Otherwise return first of windows: */
137
230
    return machineWindows()[0];
138
231
}
139
232
 
140
 
UIMachineWindow* UIMachineLogic::defaultMachineWindow() const
 
233
UIMachineWindow* UIMachineLogic::activeMachineWindow() const
141
234
{
142
235
    /* Return null if windows are not created yet: */
143
236
    if (!isMachineWindowsCreated())
144
237
        return 0;
145
238
 
146
 
    /* Select main machine window by default: */
147
 
    UIMachineWindow *pWindowToPropose = mainMachineWindow();
148
 
 
149
 
    /* Check if there is active window present: */
150
 
    foreach (UIMachineWindow *pWindowToCheck, machineWindows())
 
239
    /* Check if there is an active window present: */
 
240
    for (int i = 0; i < machineWindows().size(); ++i)
151
241
    {
152
 
        if (pWindowToCheck->machineWindow()->isActiveWindow())
153
 
        {
154
 
            pWindowToPropose = pWindowToCheck;
155
 
            break;
156
 
        }
 
242
        UIMachineWindow *pIteratedWindow = machineWindows()[i];
 
243
        if (pIteratedWindow->isActiveWindow())
 
244
            return pIteratedWindow;
157
245
    }
158
246
 
159
 
    /* Return default machine window: */
160
 
    return pWindowToPropose;
 
247
    /* Return main machine window: */
 
248
    return mainMachineWindow();
161
249
}
162
250
 
163
251
#ifdef Q_WS_MAC
196
284
}
197
285
#endif /* Q_WS_MAC */
198
286
 
199
 
UIMachineLogic::UIMachineLogic(QObject *pParent,
200
 
                               UISession *pSession,
201
 
                               UIVisualStateType visualStateType)
 
287
void UIMachineLogic::sltMachineStateChanged()
 
288
{
 
289
    /* Get machine state: */
 
290
    KMachineState state = uisession()->machineState();
 
291
 
 
292
    /* Update action groups: */
 
293
    m_pRunningActions->setEnabled(uisession()->isRunning());
 
294
    m_pRunningOrPausedActions->setEnabled(uisession()->isRunning() || uisession()->isPaused());
 
295
 
 
296
    switch (state)
 
297
    {
 
298
        case KMachineState_Stuck: // TODO: Test it!
 
299
        {
 
300
            /* Prevent machine view from resizing: */
 
301
            uisession()->setGuestResizeIgnored(true);
 
302
 
 
303
            /* Get console and log folder. */
 
304
            CConsole console = session().GetConsole();
 
305
            const QString &strLogFolder = console.GetMachine().GetLogFolder();
 
306
 
 
307
            /* Take the screenshot for debugging purposes and save it. */
 
308
            takeScreenshot(strLogFolder + "/VBox.png", "png");
 
309
 
 
310
            /* Warn the user about GURU: */
 
311
            if (msgCenter().remindAboutGuruMeditation(console, QDir::toNativeSeparators(strLogFolder)))
 
312
            {
 
313
                console.PowerDown();
 
314
                if (!console.isOk())
 
315
                    msgCenter().cannotStopMachine(console);
 
316
            }
 
317
            break;
 
318
        }
 
319
        case KMachineState_Paused:
 
320
        case KMachineState_TeleportingPausedVM:
 
321
        {
 
322
            QAction *pPauseAction = gActionPool->action(UIActionIndexRuntime_Toggle_Pause);
 
323
            if (!pPauseAction->isChecked())
 
324
            {
 
325
                /* Was paused from CSession side: */
 
326
                pPauseAction->blockSignals(true);
 
327
                pPauseAction->setChecked(true);
 
328
                pPauseAction->blockSignals(false);
 
329
            }
 
330
            break;
 
331
        }
 
332
        case KMachineState_Running:
 
333
        case KMachineState_Teleporting:
 
334
        case KMachineState_LiveSnapshotting:
 
335
        {
 
336
            QAction *pPauseAction = gActionPool->action(UIActionIndexRuntime_Toggle_Pause);
 
337
            if (pPauseAction->isChecked())
 
338
            {
 
339
                /* Was resumed from CSession side: */
 
340
                pPauseAction->blockSignals(true);
 
341
                pPauseAction->setChecked(false);
 
342
                pPauseAction->blockSignals(false);
 
343
            }
 
344
            break;
 
345
        }
 
346
        case KMachineState_PoweredOff:
 
347
        case KMachineState_Saved:
 
348
        case KMachineState_Teleported:
 
349
        case KMachineState_Aborted:
 
350
        {
 
351
            /* Close VM if it was turned off and closure allowed: */
 
352
            if (!isPreventAutoClose())
 
353
            {
 
354
                /* VM has been powered off, saved or aborted, no matter
 
355
                 * internally or externally. We must *safely* close VM window(s): */
 
356
                QTimer::singleShot(0, uisession(), SLOT(sltCloseVirtualSession()));
 
357
            }
 
358
            break;
 
359
        }
 
360
#ifdef Q_WS_X11
 
361
        case KMachineState_Starting:
 
362
        case KMachineState_Restoring:
 
363
        case KMachineState_TeleportingIn:
 
364
        {
 
365
            /* The keyboard handler may wish to do some release logging on startup.
 
366
             * Tell it that the logger is now active. */
 
367
            doXKeyboardLogging(QX11Info::display());
 
368
            break;
 
369
        }
 
370
#endif
 
371
        default:
 
372
            break;
 
373
    }
 
374
 
 
375
#ifdef Q_WS_MAC
 
376
    /* Update Dock Overlay: */
 
377
    updateDockOverlay();
 
378
#endif /* Q_WS_MAC */
 
379
}
 
380
 
 
381
void UIMachineLogic::sltAdditionsStateChanged()
 
382
{
 
383
    /* Update action states: */
 
384
    gActionPool->action(UIActionIndexRuntime_Toggle_GuestAutoresize)->setEnabled(uisession()->isGuestSupportsGraphics());
 
385
    gActionPool->action(UIActionIndexRuntime_Toggle_Seamless)->setEnabled(uisession()->isGuestSupportsSeamless());
 
386
}
 
387
 
 
388
void UIMachineLogic::sltMouseCapabilityChanged()
 
389
{
 
390
    /* Variable falgs: */
 
391
    bool fIsMouseSupportsAbsolute = uisession()->isMouseSupportsAbsolute();
 
392
    bool fIsMouseSupportsRelative = uisession()->isMouseSupportsRelative();
 
393
    bool fIsMouseHostCursorNeeded = uisession()->isMouseHostCursorNeeded();
 
394
 
 
395
    /* Update action state: */
 
396
    QAction *pAction = gActionPool->action(UIActionIndexRuntime_Toggle_MouseIntegration);
 
397
    pAction->setEnabled(fIsMouseSupportsAbsolute && fIsMouseSupportsRelative && !fIsMouseHostCursorNeeded);
 
398
    if (fIsMouseHostCursorNeeded)
 
399
        pAction->setChecked(false);
 
400
}
 
401
 
 
402
void UIMachineLogic::sltUSBDeviceStateChange(const CUSBDevice &device, bool fIsAttached, const CVirtualBoxErrorInfo &error)
 
403
{
 
404
    /* Check if USB device have anything to tell us: */
 
405
    if (!error.isNull())
 
406
    {
 
407
        if (fIsAttached)
 
408
            msgCenter().cannotAttachUSBDevice(session().GetConsole(), vboxGlobal().details(device), error);
 
409
        else
 
410
            msgCenter().cannotDetachUSBDevice(session().GetConsole(), vboxGlobal().details(device), error);
 
411
    }
 
412
}
 
413
 
 
414
void UIMachineLogic::sltRuntimeError(bool fIsFatal, const QString &strErrorId, const QString &strMessage)
 
415
{
 
416
    msgCenter().showRuntimeError(session().GetConsole(), fIsFatal, strErrorId, strMessage);
 
417
}
 
418
 
 
419
#ifdef Q_WS_MAC
 
420
void UIMachineLogic::sltShowWindows()
 
421
{
 
422
    for (int i=0; i < machineWindows().size(); ++i)
 
423
    {
 
424
        UIMachineWindow *pMachineWindow = machineWindows().at(i);
 
425
        /* Dunno what Qt thinks a window that has minimized to the dock
 
426
         * should be - it is not hidden, neither is it minimized. OTOH it is
 
427
         * marked shown and visible, but not activated. This latter isn't of
 
428
         * much help though, since at this point nothing is marked activated.
 
429
         * I might have overlooked something, but I'm buggered what if I know
 
430
         * what. So, I'll just always show & activate the stupid window to
 
431
         * make it get out of the dock when the user wishes to show a VM. */
 
432
        pMachineWindow->raise();
 
433
        pMachineWindow->activateWindow();
 
434
    }
 
435
}
 
436
#endif /* Q_WS_MAC */
 
437
 
 
438
UIMachineLogic::UIMachineLogic(QObject *pParent, UISession *pSession, UIVisualStateType visualStateType)
202
439
    : QIWithRetranslateUI3<QObject>(pParent)
203
440
    , m_pSession(pSession)
204
441
    , m_visualStateType(visualStateType)
206
443
    , m_pMouseHandler(0)
207
444
    , m_pRunningActions(0)
208
445
    , m_pRunningOrPausedActions(0)
 
446
    , m_pSharedClipboardActions(0)
 
447
    , m_pDragAndDropActions(0)
209
448
    , m_fIsWindowsCreated(false)
210
449
    , m_fIsPreventAutoClose(false)
211
450
#ifdef VBOX_WITH_DEBUGGER_GUI
221
460
{
222
461
}
223
462
 
224
 
UIMachineLogic::~UIMachineLogic()
225
 
{
226
 
#ifdef VBOX_WITH_DEBUGGER_GUI
227
 
    /* Close debugger: */
228
 
    dbgDestroy();
229
 
#endif /* VBOX_WITH_DEBUGGER_GUI */
230
 
}
231
 
 
232
 
CSession& UIMachineLogic::session()
233
 
{
234
 
    return uisession()->session();
235
 
}
236
 
 
237
463
void UIMachineLogic::addMachineWindow(UIMachineWindow *pMachineWindow)
238
464
{
239
465
    m_machineWindowsList << pMachineWindow;
262
488
        }
263
489
    }
264
490
#endif /* Q_WS_MAC */
 
491
    /* Shared Clipboard actions: */
 
492
    if (m_pSharedClipboardActions)
 
493
    {
 
494
        foreach (QAction *pAction, m_pSharedClipboardActions->actions())
 
495
            pAction->setText(gpConverter->toString(pAction->data().value<KClipboardMode>()));
 
496
    }
 
497
    if (m_pDragAndDropActions)
 
498
    {
 
499
        foreach (QAction *pAction, m_pDragAndDropActions->actions())
 
500
            pAction->setText(gpConverter->toString(pAction->data().value<KDragAndDropMode>()));
 
501
    }
265
502
}
266
503
 
267
504
#ifdef Q_WS_MAC
288
525
}
289
526
#endif /* Q_WS_MAC */
290
527
 
 
528
void UIMachineLogic::prepareRequiredFeatures()
 
529
{
 
530
#ifdef Q_WS_MAC
 
531
# ifdef VBOX_WITH_ICHAT_THEATER
 
532
    /* Init shared AV manager: */
 
533
    initSharedAVManager();
 
534
# endif /* VBOX_WITH_ICHAT_THEATER */
 
535
#endif /* Q_WS_MAC */
 
536
}
 
537
 
291
538
void UIMachineLogic::prepareSessionConnections()
292
539
{
293
 
    /* Machine power-up notifier: */
 
540
    /* We should check for entering/exiting requested modes: */
294
541
    connect(uisession(), SIGNAL(sigMachineStarted()), this, SLOT(sltCheckRequestedModes()));
 
542
    connect(uisession(), SIGNAL(sigAdditionsStateChange()), this, SLOT(sltCheckRequestedModes()));
295
543
 
296
544
    /* Machine state-change updater: */
297
545
    connect(uisession(), SIGNAL(sigMachineStateChange()), this, SLOT(sltMachineStateChanged()));
312
560
 
313
561
#ifdef Q_WS_MAC
314
562
    /* Show windows: */
315
 
    connect(uisession(), SIGNAL(sigShowWindows()),
316
 
            this, SLOT(sltShowWindows()));
317
 
#endif /* Q_WS_MAC */
 
563
    connect(uisession(), SIGNAL(sigShowWindows()), this, SLOT(sltShowWindows()));
 
564
#endif /* Q_WS_MAC */
 
565
}
 
566
 
 
567
void UIMachineLogic::prepareActionGroups()
 
568
{
 
569
#ifdef Q_WS_MAC
 
570
    /* On Mac OS X, all QMenu's are consumed by Qt after they are added to
 
571
     * another QMenu or a QMenuBar. This means we have to recreate all QMenus
 
572
     * when creating a new QMenuBar. */
 
573
    gActionPool->recreateMenus();
 
574
#endif /* Q_WS_MAC */
 
575
 
 
576
    /* Create group for all actions that are enabled only when the VM is running.
 
577
     * Note that only actions whose enabled state depends exclusively on the
 
578
     * execution state of the VM are added to this group. */
 
579
    m_pRunningActions = new QActionGroup(this);
 
580
    m_pRunningActions->setExclusive(false);
 
581
 
 
582
    /* Create group for all actions that are enabled when the VM is running or paused.
 
583
     * Note that only actions whose enabled state depends exclusively on the
 
584
     * execution state of the VM are added to this group. */
 
585
    m_pRunningOrPausedActions = new QActionGroup(this);
 
586
    m_pRunningOrPausedActions->setExclusive(false);
 
587
 
 
588
    /* Move actions into running actions group: */
 
589
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_TypeCAD));
 
590
#ifdef Q_WS_X11
 
591
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_TypeCABS));
 
592
#endif
 
593
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_Reset));
 
594
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_Shutdown));
 
595
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen));
 
596
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_Seamless));
 
597
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_Scale));
 
598
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_GuestAutoresize));
 
599
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_AdjustWindow));
 
600
 
 
601
    /* Move actions into running-n-paused actions group: */
 
602
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_SettingsDialog));
 
603
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_TakeSnapshot));
 
604
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_TakeScreenshot));
 
605
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_InformationDialog));
 
606
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_MouseIntegration));
 
607
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_MouseIntegration));
 
608
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_Pause));
 
609
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_OpticalDevices));
 
610
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_FloppyDevices));
 
611
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_USBDevices));
 
612
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_SharedClipboard));
 
613
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_DragAndDrop));
 
614
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_NetworkAdapters));
 
615
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_NetworkAdaptersDialog));
 
616
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_SharedFolders));
 
617
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_SharedFoldersDialog));
 
618
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_VRDEServer));
 
619
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_InstallGuestTools));
318
620
}
319
621
 
320
622
void UIMachineLogic::prepareActionConnections()
324
626
            this, SLOT(sltOpenVMSettingsDialog()));
325
627
    connect(gActionPool->action(UIActionIndexRuntime_Simple_TakeSnapshot), SIGNAL(triggered()),
326
628
            this, SLOT(sltTakeSnapshot()));
 
629
    connect(gActionPool->action(UIActionIndexRuntime_Simple_TakeScreenshot), SIGNAL(triggered()),
 
630
            this, SLOT(sltTakeScreenshot()));
327
631
    connect(gActionPool->action(UIActionIndexRuntime_Simple_InformationDialog), SIGNAL(triggered()),
328
632
            this, SLOT(sltShowInformationDialog()));
329
633
    connect(gActionPool->action(UIActionIndexRuntime_Toggle_MouseIntegration), SIGNAL(toggled(bool)),
356
660
            this, SLOT(sltPrepareStorageMenu()));
357
661
    connect(gActionPool->action(UIActionIndexRuntime_Menu_USBDevices)->menu(), SIGNAL(aboutToShow()),
358
662
            this, SLOT(sltPrepareUSBMenu()));
 
663
    connect(gActionPool->action(UIActionIndexRuntime_Menu_SharedClipboard)->menu(), SIGNAL(aboutToShow()),
 
664
            this, SLOT(sltPrepareSharedClipboardMenu()));
 
665
    connect(gActionPool->action(UIActionIndexRuntime_Menu_DragAndDrop)->menu(), SIGNAL(aboutToShow()),
 
666
            this, SLOT(sltPrepareDragAndDropMenu()));
359
667
    connect(gActionPool->action(UIActionIndexRuntime_Simple_NetworkAdaptersDialog), SIGNAL(triggered()),
360
668
            this, SLOT(sltOpenNetworkAdaptersDialog()));
361
669
    connect(gActionPool->action(UIActionIndexRuntime_Simple_SharedFoldersDialog), SIGNAL(triggered()),
375
683
            this, SLOT(sltShowDebugCommandLine()));
376
684
    connect(gActionPool->action(UIActionIndexRuntime_Toggle_Logging), SIGNAL(toggled(bool)),
377
685
            this, SLOT(sltLoggingToggled(bool)));
378
 
#endif
379
 
}
380
 
 
381
 
void UIMachineLogic::prepareActionGroups()
382
 
{
383
 
#ifdef Q_WS_MAC
384
 
    /* On Mac OS X, all QMenu's are consumed by Qt after they are added to
385
 
     * another QMenu or a QMenuBar. This means we have to recreate all QMenus
386
 
     * when creating a new QMenuBar. */
387
 
    gActionPool->recreateMenus();
388
 
#endif /* Q_WS_MAC */
389
 
 
390
 
    /* Create group for all actions that are enabled only when the VM is running.
391
 
     * Note that only actions whose enabled state depends exclusively on the
392
 
     * execution state of the VM are added to this group. */
393
 
    m_pRunningActions = new QActionGroup(this);
394
 
    m_pRunningActions->setExclusive(false);
395
 
 
396
 
    /* Create group for all actions that are enabled when the VM is running or paused.
397
 
     * Note that only actions whose enabled state depends exclusively on the
398
 
     * execution state of the VM are added to this group. */
399
 
    m_pRunningOrPausedActions = new QActionGroup(this);
400
 
    m_pRunningOrPausedActions->setExclusive(false);
401
 
 
402
 
    /* Move actions into running actions group: */
403
 
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_TypeCAD));
404
 
#ifdef Q_WS_X11
405
 
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_TypeCABS));
406
 
#endif
407
 
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_Reset));
408
 
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_Shutdown));
409
 
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen));
410
 
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_Seamless));
411
 
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_Scale));
412
 
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_GuestAutoresize));
413
 
    m_pRunningActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_AdjustWindow));
414
 
 
415
 
    /* Move actions into running-n-paused actions group: */
416
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_SettingsDialog));
417
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_TakeSnapshot));
418
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_InformationDialog));
419
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_MouseIntegration));
420
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_MouseIntegration));
421
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_Pause));
422
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_OpticalDevices));
423
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_FloppyDevices));
424
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_USBDevices));
425
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_NetworkAdapters));
426
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_NetworkAdaptersDialog));
427
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Menu_SharedFolders));
428
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_SharedFoldersDialog));
429
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Toggle_VRDEServer));
430
 
    m_pRunningOrPausedActions->addAction(gActionPool->action(UIActionIndexRuntime_Simple_InstallGuestTools));
 
686
    connect(gActionPool->action(UIActionIndex_Simple_LogDialog), SIGNAL(triggered()),
 
687
            this, SLOT(sltShowLogDialog()));
 
688
#endif
431
689
}
432
690
 
433
691
void UIMachineLogic::prepareHandlers()
470
728
    if (cGuestScreens > 1)
471
729
    {
472
730
        pDockSettingsMenu->addSeparator();
473
 
        m_DockIconPreviewMonitor = qMin(session().GetMachine().GetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateMonitor).toInt(), cGuestScreens - 1);
 
731
        m_DockIconPreviewMonitor = qMin(session().GetMachine().GetExtraData(GUI_RealtimeDockIconUpdateMonitor).toInt(), cGuestScreens - 1);
474
732
        m_pDockPreviewSelectMonitorGroup = new QActionGroup(this);
475
733
        for (int i = 0; i < cGuestScreens; ++i)
476
734
        {
492
750
 
493
751
    /* Now the dock icon preview */
494
752
    QString osTypeId = session().GetConsole().GetGuest().GetOSTypeId();
495
 
    m_pDockIconPreview = new UIDockIconPreview(m_pSession, vboxGlobal().vmGuestOSTypeIcon(osTypeId));
 
753
    m_pDockIconPreview = new UIDockIconPreview(uisession(), vboxGlobal().vmGuestOSTypeIcon(osTypeId));
496
754
 
497
 
    QString strTest = session().GetMachine().GetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateEnabled).toLower();
 
755
    QString strTest = session().GetMachine().GetExtraData(GUI_RealtimeDockIconUpdateEnabled).toLower();
498
756
    /* Default to true if it is an empty value */
499
757
    bool f = (strTest.isEmpty() || strTest == "true");
500
758
    if (f)
512
770
}
513
771
#endif /* Q_WS_MAC */
514
772
 
515
 
void UIMachineLogic::prepareRequiredFeatures()
516
 
{
517
 
#ifdef Q_WS_MAC
518
 
# ifdef VBOX_WITH_ICHAT_THEATER
519
 
    /* Init shared AV manager: */
520
 
    initSharedAVManager();
521
 
# endif
522
 
#endif
523
 
}
524
 
 
525
773
#ifdef VBOX_WITH_DEBUGGER_GUI
526
774
void UIMachineLogic::prepareDebugger()
527
775
{
546
794
}
547
795
#endif /* VBOX_WITH_DEBUGGER_GUI */
548
796
 
 
797
#ifdef VBOX_WITH_DEBUGGER_GUI
 
798
void UIMachineLogic::cleanupDebugger()
 
799
{
 
800
    /* Close debugger: */
 
801
    dbgDestroy();
 
802
}
 
803
#endif /* VBOX_WITH_DEBUGGER_GUI */
 
804
 
549
805
#ifdef Q_WS_MAC
550
806
void UIMachineLogic::cleanupDock()
551
807
{
566
822
    UIKeyboardHandler::destroy(keyboardHandler());
567
823
}
568
824
 
569
 
void UIMachineLogic::sltMachineStateChanged()
570
 
{
571
 
    /* Get machine state: */
572
 
    KMachineState state = uisession()->machineState();
573
 
 
574
 
    /* Update action groups: */
575
 
    m_pRunningActions->setEnabled(uisession()->isRunning());
576
 
    m_pRunningOrPausedActions->setEnabled(uisession()->isRunning() || uisession()->isPaused());
577
 
 
578
 
    switch (state)
579
 
    {
580
 
        case KMachineState_Stuck: // TODO: Test it!
581
 
        {
582
 
            /* Prevent machine view from resizing: */
583
 
            uisession()->setGuestResizeIgnored(true);
584
 
 
585
 
            /* Get console: */
586
 
            CConsole console = session().GetConsole();
587
 
 
588
 
            /* Take the screenshot for debugging purposes and save it. */
589
 
            QString strLogFolder = console.GetMachine().GetLogFolder();
590
 
            CDisplay display = console.GetDisplay();
591
 
            int cGuestScreens = uisession()->session().GetMachine().GetMonitorCount();
592
 
            for (int i=0; i < cGuestScreens; ++i)
593
 
            {
594
 
                QString strFileName;
595
 
                if (i == 0)
596
 
                    strFileName = strLogFolder + "/VBox.png";
597
 
                else
598
 
                    strFileName = QString("%1/VBox.%2.png").arg(strLogFolder).arg(i);
599
 
                ULONG width = 0;
600
 
                ULONG height = 0;
601
 
                ULONG bpp = 0;
602
 
                display.GetScreenResolution(i, width, height, bpp);
603
 
                QImage shot = QImage(width, height, QImage::Format_RGB32);
604
 
                display.TakeScreenShot(i, shot.bits(), shot.width(), shot.height());
605
 
                shot.save(QFile::encodeName(strFileName), "PNG");
606
 
            }
607
 
 
608
 
            /* Warn the user about GURU: */
609
 
            if (msgCenter().remindAboutGuruMeditation(console, QDir::toNativeSeparators(strLogFolder)))
610
 
            {
611
 
                console.PowerDown();
612
 
                if (!console.isOk())
613
 
                    msgCenter().cannotStopMachine(console);
614
 
            }
615
 
            break;
616
 
        }
617
 
        case KMachineState_Paused:
618
 
        case KMachineState_TeleportingPausedVM:
619
 
        {
620
 
            QAction *pPauseAction = gActionPool->action(UIActionIndexRuntime_Toggle_Pause);
621
 
            if (!pPauseAction->isChecked())
622
 
            {
623
 
                /* Was paused from CSession side: */
624
 
                pPauseAction->blockSignals(true);
625
 
                pPauseAction->setChecked(true);
626
 
                pPauseAction->blockSignals(false);
627
 
            }
628
 
            break;
629
 
        }
630
 
        case KMachineState_Running:
631
 
        case KMachineState_Teleporting:
632
 
        case KMachineState_LiveSnapshotting:
633
 
        {
634
 
            QAction *pPauseAction = gActionPool->action(UIActionIndexRuntime_Toggle_Pause);
635
 
            if (pPauseAction->isChecked())
636
 
            {
637
 
                /* Was resumed from CSession side: */
638
 
                pPauseAction->blockSignals(true);
639
 
                pPauseAction->setChecked(false);
640
 
                pPauseAction->blockSignals(false);
641
 
            }
642
 
            break;
643
 
        }
644
 
        case KMachineState_PoweredOff:
645
 
        case KMachineState_Saved:
646
 
        case KMachineState_Teleported:
647
 
        case KMachineState_Aborted:
648
 
        {
649
 
            /* Close VM if it was turned off and closure allowed: */
650
 
            if (!isPreventAutoClose())
651
 
            {
652
 
                /* VM has been powered off, saved or aborted, no matter
653
 
                 * internally or externally. We must *safely* close VM window(s): */
654
 
                QTimer::singleShot(0, uisession(), SLOT(sltCloseVirtualSession()));
655
 
            }
656
 
            break;
657
 
        }
658
 
#ifdef Q_WS_X11
659
 
        case KMachineState_Starting:
660
 
        case KMachineState_Restoring:
661
 
        case KMachineState_TeleportingIn:
662
 
        {
663
 
            /* The keyboard handler may wish to do some release logging on startup.
664
 
             * Tell it that the logger is now active. */
665
 
            doXKeyboardLogging(QX11Info::display());
666
 
            break;
667
 
        }
668
 
#endif
669
 
        default:
670
 
            break;
671
 
    }
672
 
 
673
 
#ifdef Q_WS_MAC
674
 
    /* Update Dock Overlay: */
675
 
    updateDockOverlay();
676
 
#endif /* Q_WS_MAC */
677
 
}
678
 
 
679
 
void UIMachineLogic::sltAdditionsStateChanged()
680
 
{
681
 
    /* Variable flags: */
682
 
    bool fIsSupportsGraphics = uisession()->isGuestSupportsGraphics();
683
 
    bool fIsSupportsSeamless = uisession()->isGuestSupportsSeamless();
684
 
 
685
 
    /* Update action states: */
686
 
    gActionPool->action(UIActionIndexRuntime_Toggle_GuestAutoresize)->setEnabled(fIsSupportsGraphics);
687
 
    gActionPool->action(UIActionIndexRuntime_Toggle_Seamless)->setEnabled(fIsSupportsSeamless);
688
 
 
689
 
    /* Check if we should enter some extended mode: */
690
 
    sltCheckRequestedModes();
691
 
}
692
 
 
693
 
void UIMachineLogic::sltMouseCapabilityChanged()
694
 
{
695
 
    /* Variable falgs: */
696
 
    bool fIsMouseSupportsAbsolute = uisession()->isMouseSupportsAbsolute();
697
 
    bool fIsMouseSupportsRelative = uisession()->isMouseSupportsRelative();
698
 
    bool fIsMouseHostCursorNeeded = uisession()->isMouseHostCursorNeeded();
699
 
 
700
 
    /* Update action state: */
701
 
    QAction *pAction = gActionPool->action(UIActionIndexRuntime_Toggle_MouseIntegration);
702
 
    pAction->setEnabled(fIsMouseSupportsAbsolute && fIsMouseSupportsRelative && !fIsMouseHostCursorNeeded);
703
 
    if (fIsMouseHostCursorNeeded)
704
 
        pAction->setChecked(false);
705
 
}
706
 
 
707
 
void UIMachineLogic::sltUSBDeviceStateChange(const CUSBDevice &device, bool fIsAttached, const CVirtualBoxErrorInfo &error)
708
 
{
709
 
    bool fSuccess = error.isNull();
710
 
 
711
 
    if (!fSuccess)
712
 
    {
713
 
        if (fIsAttached)
714
 
            msgCenter().cannotAttachUSBDevice(session().GetConsole(), vboxGlobal().details(device), error);
715
 
        else
716
 
            msgCenter().cannotDetachUSBDevice(session().GetConsole(), vboxGlobal().details(device), error);
717
 
    }
718
 
}
719
 
 
720
 
void UIMachineLogic::sltRuntimeError(bool fIsFatal, const QString &strErrorId, const QString &strMessage)
721
 
{
722
 
    msgCenter().showRuntimeError(session().GetConsole(), fIsFatal, strErrorId, strMessage);
723
 
}
724
 
 
725
 
#ifdef Q_WS_MAC
726
 
void UIMachineLogic::sltShowWindows()
727
 
{
728
 
    for (int i=0; i < m_machineWindowsList.size(); ++i)
729
 
    {
730
 
        UIMachineWindow *pMachineWindow = m_machineWindowsList.at(i);
731
 
        /* Dunno what Qt thinks a window that has minimized to the dock
732
 
         * should be - it is not hidden, neither is it minimized. OTOH it is
733
 
         * marked shown and visible, but not activated. This latter isn't of
734
 
         * much help though, since at this point nothing is marked activated.
735
 
         * I might have overlooked something, but I'm buggered what if I know
736
 
         * what. So, I'll just always show & activate the stupid window to
737
 
         * make it get out of the dock when the user wishes to show a VM. */
738
 
        pMachineWindow->machineWindow()->raise();
739
 
        pMachineWindow->machineWindow()->activateWindow();
740
 
    }
741
 
}
742
 
#endif /* Q_WS_MAC */
 
825
void UIMachineLogic::cleanupActionGroups()
 
826
{
 
827
}
743
828
 
744
829
void UIMachineLogic::sltCheckRequestedModes()
745
830
{
790
875
    foreach(UIMachineWindow *pMachineWindow, machineWindows())
791
876
    {
792
877
        /* Exit maximized window state if actual: */
793
 
        if (pMachineWindow->machineWindow()->isMaximized())
794
 
            pMachineWindow->machineWindow()->showNormal();
 
878
        if (pMachineWindow->isMaximized())
 
879
            pMachineWindow->showNormal();
795
880
 
796
881
        /* Normalize view's geometry: */
797
882
        pMachineWindow->machineView()->normalizeGeometry(true);
805
890
        return;
806
891
 
807
892
    /* Disable/Enable mouse-integration for all view(s): */
808
 
    m_pMouseHandler->setMouseIntegrationEnabled(!fOff);
 
893
    mouseHandler()->setMouseIntegrationEnabled(!fOff);
809
894
}
810
895
 
811
896
void UIMachineLogic::sltTypeCAD()
831
916
    keyboard.PutScancodes(aSequence);
832
917
    AssertWrapperOk(keyboard);
833
918
}
834
 
#endif
 
919
#endif /* Q_WS_X11 */
835
920
 
836
921
void UIMachineLogic::sltTakeSnapshot()
837
922
{
839
924
    if (!isMachineWindowsCreated())
840
925
        return;
841
926
 
842
 
    /* Remember the paused state. */
 
927
    /* Remember the paused state: */
843
928
    bool fWasPaused = uisession()->isPaused();
844
929
    if (!fWasPaused)
845
930
    {
849
934
            return;
850
935
    }
851
936
 
 
937
    /* Get current machine: */
852
938
    CMachine machine = session().GetMachine();
853
939
 
854
 
    VBoxTakeSnapshotDlg dlg(defaultMachineWindow()->machineWindow(), machine);
 
940
    /* Create take-snapshot dialog: */
 
941
    QPointer<VBoxTakeSnapshotDlg> pDlg = new VBoxTakeSnapshotDlg(activeMachineWindow(), machine);
855
942
 
 
943
    /* Assign corresponding icon: */
856
944
    QString strTypeId = machine.GetOSTypeId();
857
 
    dlg.mLbIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(strTypeId));
 
945
    pDlg->mLbIcon->setPixmap(vboxGlobal().vmGuestOSTypeIcon(strTypeId));
858
946
 
859
 
    /* Search for the max available filter index. */
 
947
    /* Search for the max available filter index: */
860
948
    QString strNameTemplate = QApplication::translate("UIMachineLogic", "Snapshot %1");
861
949
    int iMaxSnapshotIndex = searchMaxSnapshotIndex(machine, machine.FindSnapshot(QString()), strNameTemplate);
862
 
    dlg.mLeName->setText(strNameTemplate.arg(++ iMaxSnapshotIndex));
863
 
 
864
 
    if (dlg.exec() == QDialog::Accepted)
 
950
    pDlg->mLeName->setText(strNameTemplate.arg(++ iMaxSnapshotIndex));
 
951
 
 
952
    /* Exec the dialog: */
 
953
    bool fDialogAccepted = pDlg->exec() == QDialog::Accepted;
 
954
 
 
955
    /* Is the dialog still valid? */
 
956
    if (pDlg)
865
957
    {
866
 
        CConsole console = session().GetConsole();
867
 
 
868
 
        CProgress progress = console.TakeSnapshot(dlg.mLeName->text().trimmed(), dlg.mTeDescription->toPlainText());
869
 
 
870
 
        if (console.isOk())
 
958
        /* Acquire variables: */
 
959
        QString strSnapshotName = pDlg->mLeName->text().trimmed();
 
960
        QString strSnapshotDescription = pDlg->mTeDescription->toPlainText();
 
961
 
 
962
        /* Destroy dialog early: */
 
963
        delete pDlg;
 
964
 
 
965
        /* Was the dialog accepted? */
 
966
        if (fDialogAccepted)
871
967
        {
872
 
            /* Show the "Taking Snapshot" progress dialog */
873
 
            msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_snapshot_create_90px.png", 0, true);
874
 
 
875
 
            if (progress.GetResultCode() != 0)
876
 
                msgCenter().cannotTakeSnapshot(progress);
 
968
            /* Prepare the take-snapshot progress: */
 
969
            CConsole console = session().GetConsole();
 
970
            CProgress progress = console.TakeSnapshot(strSnapshotName, strSnapshotDescription);
 
971
            if (console.isOk())
 
972
            {
 
973
                /* Show the take-snapshot progress: */
 
974
                msgCenter().showModalProgressDialog(progress, machine.GetName(), ":/progress_snapshot_create_90px.png", 0, true);
 
975
                if (progress.GetResultCode() != 0)
 
976
                    msgCenter().cannotTakeSnapshot(progress);
 
977
            }
 
978
            else
 
979
                msgCenter().cannotTakeSnapshot(console);
877
980
        }
878
 
        else
879
 
            msgCenter().cannotTakeSnapshot(console);
880
981
    }
881
982
 
882
 
    /* Restore the running state if needed. */
 
983
    /* Restore the running state if needed: */
883
984
    if (!fWasPaused)
884
985
    {
885
986
        /* Make sure machine-state-change callback is processed: */
889
990
    }
890
991
}
891
992
 
 
993
void UIMachineLogic::sltTakeScreenshot()
 
994
{
 
995
    /* Do not process if window(s) missed! */
 
996
    if (!isMachineWindowsCreated())
 
997
        return;
 
998
 
 
999
    /* Which image formats for writing does this Qt version know of? */
 
1000
    QList<QByteArray> formats = QImageWriter::supportedImageFormats();
 
1001
    QStringList filters;
 
1002
    /* Build a filters list out of it. */
 
1003
    for (int i = 0; i < formats.size(); ++i)
 
1004
    {
 
1005
        const QString &s = formats.at(i) + " (*." + formats.at(i).toLower() + ")";
 
1006
        /* Check there isn't an entry already (even if it just uses another capitalization) */
 
1007
        if (filters.indexOf(QRegExp(QRegExp::escape(s), Qt::CaseInsensitive)) == -1)
 
1008
            filters << s;
 
1009
    }
 
1010
    /* Try to select some common defaults. */
 
1011
    QString strFilter;
 
1012
    int i = filters.indexOf(QRegExp(".*png.*", Qt::CaseInsensitive));
 
1013
    if (i == -1)
 
1014
    {
 
1015
        i = filters.indexOf(QRegExp(".*jpe+g.*", Qt::CaseInsensitive));
 
1016
        if (i == -1)
 
1017
            i = filters.indexOf(QRegExp(".*bmp.*", Qt::CaseInsensitive));
 
1018
    }
 
1019
    if (i != -1)
 
1020
    {
 
1021
        filters.prepend(filters.takeAt(i));
 
1022
        strFilter = filters.first();
 
1023
    }
 
1024
 
 
1025
#ifdef Q_WS_WIN
 
1026
    /* Due to Qt bug, modal QFileDialog appeared above the active machine-window
 
1027
     * does not retreive the focus from the currently focused machine-view,
 
1028
     * as the result guest keyboard remains captured, so we should
 
1029
     * clear the focus from this machine-view initially: */
 
1030
    if (activeMachineWindow())
 
1031
        activeMachineWindow()->machineView()->clearFocus();
 
1032
#endif /* Q_WS_WIN */
 
1033
 
 
1034
    /* Request the filename from the user. */
 
1035
    const CMachine &machine = session().GetMachine();
 
1036
    QFileInfo fi(machine.GetSettingsFilePath());
 
1037
    QString strAbsolutePath(fi.absolutePath());
 
1038
    QString strCompleteBaseName(fi.completeBaseName());
 
1039
    QString strStart = QDir(strAbsolutePath).absoluteFilePath(strCompleteBaseName);
 
1040
    QString strFilename = QIFileDialog::getSaveFileName(strStart,
 
1041
                                                        filters.join(";;"),
 
1042
                                                        activeMachineWindow(),
 
1043
                                                        tr("Select a filename for the screenshot ..."),
 
1044
                                                        &strFilter,
 
1045
                                                        true /* resolve symlinks */,
 
1046
                                                        true /* confirm overwrite */);
 
1047
 
 
1048
#ifdef Q_WS_WIN
 
1049
    /* Due to Qt bug, modal QFileDialog appeared above the active machine-window
 
1050
     * does not retreive the focus from the currently focused machine-view,
 
1051
     * as the result guest keyboard remains captured, so we already
 
1052
     * cleared the focus from this machine-view and should return
 
1053
     * that focus finally: */
 
1054
    if (activeMachineWindow())
 
1055
        activeMachineWindow()->machineView()->setFocus();
 
1056
#endif /* Q_WS_WIN */
 
1057
 
 
1058
    /* Do the screenshot. */
 
1059
    if (!strFilename.isEmpty())
 
1060
        takeScreenshot(strFilename, strFilter.split(" ").value(0, "png"));
 
1061
}
 
1062
 
892
1063
void UIMachineLogic::sltShowInformationDialog()
893
1064
{
894
1065
    /* Do not process if window(s) missed! */
908
1079
       update. Emulate this for now until it get fixed. */
909
1080
    ulong uMonitorCount = session().GetMachine().GetMonitorCount();
910
1081
    for (ulong uScreenId = 1; uScreenId < uMonitorCount; ++uScreenId)
911
 
        machineWindows().at(uScreenId)->machineWindow()->update();
 
1082
        machineWindows().at(uScreenId)->update();
912
1083
}
913
1084
 
914
1085
void UIMachineLogic::sltPause(bool fOn)
937
1108
    if (!isMachineWindowsCreated())
938
1109
        return;
939
1110
 
940
 
    /* Propose to close default machine window: */
941
 
    defaultMachineWindow()->sltTryClose();
 
1111
    /* Do not try to close machine-window if restricted: */
 
1112
    if (isPreventAutoClose())
 
1113
        return;
 
1114
 
 
1115
    /* First, we have to close/hide any opened modal & popup application widgets.
 
1116
     * We have to make sure such window is hidden even if close-event was rejected.
 
1117
     * We are re-throwing this slot if any widget present to test again.
 
1118
     * If all opened widgets are closed/hidden, we can try to close machine-window: */
 
1119
    QWidget *pWidget = QApplication::activeModalWidget() ? QApplication::activeModalWidget() :
 
1120
                       QApplication::activePopupWidget() ? QApplication::activePopupWidget() : 0;
 
1121
    if (pWidget)
 
1122
    {
 
1123
        /* Closing/hiding all we found: */
 
1124
        pWidget->close();
 
1125
        if (!pWidget->isHidden())
 
1126
            pWidget->hide();
 
1127
        QTimer::singleShot(0, this, SLOT(sltClose()));
 
1128
        return;
 
1129
    }
 
1130
 
 
1131
    /* Try to close active machine-window: */
 
1132
    activeMachineWindow()->close();
942
1133
}
943
1134
 
944
1135
void UIMachineLogic::sltOpenVMSettingsDialog(const QString &strCategory /* = QString() */)
947
1138
    if (!isMachineWindowsCreated())
948
1139
        return;
949
1140
 
950
 
    /* Create and execute current VM settings dialog: */
951
 
    UISettingsDialogMachine dlg(defaultMachineWindow()->machineWindow(),
952
 
                                session().GetMachine().GetId(), strCategory, QString());
953
 
    dlg.execute();
 
1141
    /* Create VM settings dialog on the heap!
 
1142
     * Its necessary to allow QObject hierarchy cleanup to delete this dialog if necessary: */
 
1143
    QPointer<UISettingsDialogMachine> pDialog = new UISettingsDialogMachine(activeMachineWindow(),
 
1144
                                                                            session().GetMachine().GetId(),
 
1145
                                                                            strCategory, QString());
 
1146
    /* Executing VM settings dialog.
 
1147
     * This blocking function calls for the internal event-loop to process all further events,
 
1148
     * including event which can delete the dialog itself. */
 
1149
    pDialog->execute();
 
1150
    /* Delete dialog if its still valid: */
 
1151
    if (pDialog)
 
1152
        delete pDialog;
954
1153
}
955
1154
 
956
1155
void UIMachineLogic::sltOpenNetworkAdaptersDialog()
963
1162
{
964
1163
    /* Do not process if additions are not loaded! */
965
1164
    if (!uisession()->isGuestAdditionsActive())
966
 
        msgCenter().remindAboutGuestAdditionsAreNotActive(defaultMachineWindow()->machineWindow());
 
1165
        msgCenter().remindAboutGuestAdditionsAreNotActive(activeMachineWindow());
967
1166
 
968
1167
    /* Open VM settings : Shared folders page: */
969
 
    sltOpenVMSettingsDialog("#sfolders");
 
1168
    sltOpenVMSettingsDialog("#sharedFolders");
970
1169
}
971
1170
 
972
1171
void UIMachineLogic::sltPrepareStorageMenu()
981
1180
    QMenu *pFloppyDevicesMenu = gActionPool->action(UIActionIndexRuntime_Menu_FloppyDevices)->menu();
982
1181
 
983
1182
    /* Determine medium & device types: */
984
 
    VBoxDefs::MediumType mediumType = pMenu == pOpticalDevicesMenu ? VBoxDefs::MediumType_DVD :
985
 
                                      pMenu == pFloppyDevicesMenu  ? VBoxDefs::MediumType_Floppy :
986
 
                                                                     VBoxDefs::MediumType_Invalid;
987
 
    KDeviceType deviceType = vboxGlobal().mediumTypeToGlobal(mediumType);
988
 
    AssertMsg(mediumType != VBoxDefs::MediumType_Invalid, ("Incorrect storage medium type!\n"));
 
1183
    UIMediumType mediumType = pMenu == pOpticalDevicesMenu ? UIMediumType_DVD :
 
1184
                                      pMenu == pFloppyDevicesMenu  ? UIMediumType_Floppy :
 
1185
                                                                     UIMediumType_Invalid;
 
1186
    KDeviceType deviceType = mediumTypeToGlobal(mediumType);
 
1187
    AssertMsg(mediumType != UIMediumType_Invalid, ("Incorrect storage medium type!\n"));
989
1188
    AssertMsg(deviceType != KDeviceType_Null, ("Incorrect storage device type!\n"));
990
1189
 
991
1190
    /* Fill attachments menu: */
1011
1210
            {
1012
1211
                pAttachmentMenu = new QMenu(pMenu);
1013
1212
                pAttachmentMenu->setTitle(QString("%1 (%2)").arg(controller.GetName())
1014
 
                                          .arg(vboxGlobal().toString(StorageSlot(controller.GetBus(),
 
1213
                                          .arg(gpConverter->toString(StorageSlot(controller.GetBus(),
1015
1214
                                                                                 attachment.GetPort(),
1016
1215
                                                                                 attachment.GetDevice()))));
1017
1216
                switch (controller.GetBus())
1042
1241
            QString strRecentMediumAddress;
1043
1242
            switch (mediumType)
1044
1243
            {
1045
 
                case VBoxDefs::MediumType_DVD:
 
1244
                case UIMediumType_DVD:
1046
1245
                    mediums = vboxGlobal().host().GetDVDDrives();
1047
 
                    strRecentMediumAddress = VBoxDefs::GUI_RecentListCD;
 
1246
                    strRecentMediumAddress = GUI_RecentListCD;
1048
1247
                    break;
1049
 
                case VBoxDefs::MediumType_Floppy:
 
1248
                case UIMediumType_Floppy:
1050
1249
                    mediums = vboxGlobal().host().GetFloppyDrives();
1051
 
                    strRecentMediumAddress = VBoxDefs::GUI_RecentListFD;
 
1250
                    strRecentMediumAddress = GUI_RecentListFD;
1052
1251
                    break;
1053
1252
                default:
1054
1253
                    break;
1074
1273
                }
1075
1274
                if (!fIsHostDriveUsed)
1076
1275
                {
1077
 
                    QAction *pChooseHostDriveAction = pAttachmentMenu->addAction(VBoxMedium(medium, mediumType).name(),
 
1276
                    QAction *pChooseHostDriveAction = pAttachmentMenu->addAction(UIMedium(medium, mediumType).name(),
1078
1277
                                                                                 this, SLOT(sltMountStorageMedium()));
1079
1278
                    pChooseHostDriveAction->setCheckable(true);
1080
1279
                    pChooseHostDriveAction->setChecked(!currentMedium.isNull() && medium.GetId() == strCurrentId);
1113
1312
                        pChooseRecentMediumAction->setChecked(!currentMedium.isNull() && strRecentMediumLocation == strCurrentLocation);
1114
1313
                        pChooseRecentMediumAction->setData(QVariant::fromValue(RecentMediumTarget(controller.GetName(), attachment.GetPort(),
1115
1314
                                                                                                  attachment.GetDevice(), strRecentMediumLocation, mediumType)));
 
1315
                        pChooseRecentMediumAction->setToolTip(strRecentMediumLocation);
 
1316
 
1116
1317
                    }
1117
1318
                }
1118
1319
            }
1132
1333
            /* Switch CD/FD naming */
1133
1334
            switch (mediumType)
1134
1335
            {
1135
 
                case VBoxDefs::MediumType_DVD:
 
1336
                case UIMediumType_DVD:
1136
1337
                    pChooseExistingMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a virtual CD/DVD disk file..."));
1137
1338
                    unmountMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
1138
1339
                    unmountMediumAction->setIcon(UIIconPool::iconSet(":/cd_unmount_16px.png",
1139
1340
                                                                     ":/cd_unmount_dis_16px.png"));
1140
1341
                    break;
1141
 
                case VBoxDefs::MediumType_Floppy:
 
1342
                case UIMediumType_Floppy:
1142
1343
                    pChooseExistingMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Choose a virtual floppy disk file..."));
1143
1344
                    unmountMediumAction->setText(QApplication::translate("UIMachineSettingsStorage", "Remove disk from virtual drive"));
1144
1345
                    unmountMediumAction->setIcon(UIIconPool::iconSet(":/fd_unmount_16px.png",
1158
1359
        pEmptyMenuAction->setEnabled(false);
1159
1360
        switch (mediumType)
1160
1361
        {
1161
 
            case VBoxDefs::MediumType_DVD:
 
1362
            case UIMediumType_DVD:
1162
1363
                pEmptyMenuAction->setText(QApplication::translate("UIMachineLogic", "No CD/DVD Devices Attached"));
1163
1364
                pEmptyMenuAction->setToolTip(QApplication::translate("UIMachineLogic", "No CD/DVD devices attached to that VM"));
1164
1365
                break;
1165
 
            case VBoxDefs::MediumType_Floppy:
 
1366
            case UIMediumType_Floppy:
1166
1367
                pEmptyMenuAction->setText(QApplication::translate("UIMachineLogic", "No Floppy Devices Attached"));
1167
1368
                pEmptyMenuAction->setToolTip(QApplication::translate("UIMachineLogic", "No floppy devices attached to that VM"));
1168
1369
                break;
1193
1394
 
1194
1395
    /* New mount-target attributes: */
1195
1396
    QString newId = QString("");
1196
 
    bool fSelectWithMediaManager = target.type != VBoxDefs::MediumType_Invalid;
 
1397
    bool fSelectWithMediaManager = target.type != UIMediumType_Invalid;
1197
1398
 
1198
1399
    /* Open Virtual Media Manager to select image id: */
1199
1400
    if (fSelectWithMediaManager)
1214
1415
            QApplication::focusWidget()->clearFocus();
1215
1416
        /* Call for file-open window: */
1216
1417
        QString strMachineFolder(QFileInfo(machine.GetSettingsFilePath()).absolutePath());
1217
 
        QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(target.type, defaultMachineWindow()->machineWindow(),
 
1418
        QString strMediumId = vboxGlobal().openMediumWithFileOpenDialog(target.type, activeMachineWindow(),
1218
1419
                                                                        strMachineFolder);
1219
 
        defaultMachineWindow()->machineView()->setFocus();
 
1420
        activeMachineWindow()->machineView()->setFocus();
1220
1421
        if (!strMediumId.isNull())
1221
1422
            newId = strMediumId;
1222
1423
        else return;
1227
1428
 
1228
1429
    bool fMount = !newId.isEmpty();
1229
1430
 
1230
 
    VBoxMedium vmedium = vboxGlobal().findMedium(newId);
 
1431
    UIMedium vmedium = vboxGlobal().findMedium(newId);
1231
1432
    CMedium medium = vmedium.medium();              // @todo r=dj can this be cached somewhere?
1232
1433
 
1233
1434
    /* Remount medium to the predefined port/device: */
1284
1485
        bool fMount = strNewId != strCurrentId;
1285
1486
 
1286
1487
        /* Prepare target medium: */
1287
 
        const VBoxMedium &vboxMedium = fMount ? vboxGlobal().findMedium(strNewId) : VBoxMedium();
 
1488
        const UIMedium &vboxMedium = fMount ? vboxGlobal().findMedium(strNewId) : UIMedium();
1288
1489
        const CMedium &comMedium = fMount ? vboxMedium.medium() : CMedium();
1289
1490
 
1290
1491
        /* 'Mounted' flag: */
1424
1625
    }
1425
1626
}
1426
1627
 
 
1628
void UIMachineLogic::sltPrepareSharedClipboardMenu()
 
1629
{
 
1630
    /* Get and check the sender menu object: */
 
1631
    QMenu *pMenu = qobject_cast<QMenu*>(sender());
 
1632
    QMenu *pSharedClipboardMenu = gActionPool->action(UIActionIndexRuntime_Menu_SharedClipboard)->menu();
 
1633
    AssertMsg(pMenu == pSharedClipboardMenu, ("This slot should only be called on hovering Shared Clipboard menu!\n"));
 
1634
    Q_UNUSED(pSharedClipboardMenu);
 
1635
 
 
1636
    /* First run: */
 
1637
    if (!m_pSharedClipboardActions)
 
1638
    {
 
1639
        m_pSharedClipboardActions = new QActionGroup(this);
 
1640
        for (int i = KClipboardMode_Disabled; i < KClipboardMode_Max; ++i)
 
1641
        {
 
1642
            KClipboardMode mode = (KClipboardMode)i;
 
1643
            QAction *pAction = new QAction(gpConverter->toString(mode), m_pSharedClipboardActions);
 
1644
            pMenu->addAction(pAction);
 
1645
            pAction->setData(QVariant::fromValue(mode));
 
1646
            pAction->setCheckable(true);
 
1647
            pAction->setChecked(session().GetMachine().GetClipboardMode() == mode);
 
1648
        }
 
1649
        connect(m_pSharedClipboardActions, SIGNAL(triggered(QAction*)),
 
1650
                this, SLOT(sltChangeSharedClipboardType(QAction*)));
 
1651
    }
 
1652
    /* Subsequent runs: */
 
1653
    else
 
1654
        foreach (QAction *pAction, m_pSharedClipboardActions->actions())
 
1655
            if (pAction->data().value<KClipboardMode>() == session().GetMachine().GetClipboardMode())
 
1656
                pAction->setChecked(true);
 
1657
}
 
1658
 
 
1659
void UIMachineLogic::sltChangeSharedClipboardType(QAction *pAction)
 
1660
{
 
1661
    /* Assign new mode (without save): */
 
1662
    KClipboardMode mode = pAction->data().value<KClipboardMode>();
 
1663
    session().GetMachine().SetClipboardMode(mode);
 
1664
}
 
1665
 
 
1666
void UIMachineLogic::sltPrepareDragAndDropMenu()
 
1667
{
 
1668
    /* Get and check the sender menu object: */
 
1669
    QMenu *pMenu = qobject_cast<QMenu*>(sender());
 
1670
    QMenu *pDragAndDropMenu = gActionPool->action(UIActionIndexRuntime_Menu_DragAndDrop)->menu();
 
1671
    AssertMsg(pMenu == pDragAndDropMenu, ("This slot should only be called on hovering Drag'n'drop menu!\n"));
 
1672
    Q_UNUSED(pDragAndDropMenu);
 
1673
 
 
1674
    /* First run: */
 
1675
    if (!m_pDragAndDropActions)
 
1676
    {
 
1677
        m_pDragAndDropActions = new QActionGroup(this);
 
1678
        for (int i = KDragAndDropMode_Disabled; i < KDragAndDropMode_Max; ++i)
 
1679
        {
 
1680
            KDragAndDropMode mode = (KDragAndDropMode)i;
 
1681
            QAction *pAction = new QAction(gpConverter->toString(mode), m_pDragAndDropActions);
 
1682
            pMenu->addAction(pAction);
 
1683
            pAction->setData(QVariant::fromValue(mode));
 
1684
            pAction->setCheckable(true);
 
1685
            pAction->setChecked(session().GetMachine().GetDragAndDropMode() == mode);
 
1686
        }
 
1687
        connect(m_pDragAndDropActions, SIGNAL(triggered(QAction*)),
 
1688
                this, SLOT(sltChangeDragAndDropType(QAction*)));
 
1689
    }
 
1690
    /* Subsequent runs: */
 
1691
    else
 
1692
        foreach (QAction *pAction, m_pDragAndDropActions->actions())
 
1693
            if (pAction->data().value<KDragAndDropMode>() == session().GetMachine().GetDragAndDropMode())
 
1694
                pAction->setChecked(true);
 
1695
}
 
1696
 
 
1697
void UIMachineLogic::sltChangeDragAndDropType(QAction *pAction)
 
1698
{
 
1699
    /* Assign new mode (without save): */
 
1700
    KDragAndDropMode mode = pAction->data().value<KDragAndDropMode>();
 
1701
    session().GetMachine().SetDragAndDropMode(mode);
 
1702
}
 
1703
 
1427
1704
void UIMachineLogic::sltSwitchVrde(bool fOn)
1428
1705
{
1429
1706
    /* Enable VRDE server if possible: */
1438
1715
    if (!isMachineWindowsCreated())
1439
1716
        return;
1440
1717
 
1441
 
    char strAppPrivPath[RTPATH_MAX];
1442
 
    int rc = RTPathAppPrivateNoArch(strAppPrivPath, sizeof(strAppPrivPath));
1443
 
    AssertRC (rc);
1444
 
 
1445
 
    QString strSrc1 = QString(strAppPrivPath) + "/VBoxGuestAdditions.iso";
1446
 
    QString strSrc2 = qApp->applicationDirPath() + "/additions/VBoxGuestAdditions.iso";
1447
 
 
1448
 
    /* Check the standard image locations */
1449
 
    if (QFile::exists(strSrc1))
1450
 
        return uisession()->sltInstallGuestAdditionsFrom(strSrc1);
1451
 
    else if (QFile::exists(strSrc2))
1452
 
        return uisession()->sltInstallGuestAdditionsFrom(strSrc2);
 
1718
    CSystemProperties systemProperties = vboxGlobal().virtualBox().GetSystemProperties();
 
1719
    QString strAdditions = systemProperties.GetDefaultAdditionsISO();
 
1720
    if (systemProperties.isOk() && !strAdditions.isEmpty())
 
1721
        return uisession()->sltInstallGuestAdditionsFrom(strAdditions);
1453
1722
 
1454
1723
    /* Check for the already registered image */
1455
1724
    CVirtualBox vbox = vboxGlobal().virtualBox();
1465
1734
            return uisession()->sltInstallGuestAdditionsFrom(path);
1466
1735
    }
1467
1736
 
1468
 
    /* Download the required image */
1469
 
    int result = msgCenter().cannotFindGuestAdditions(QDir::toNativeSeparators(strSrc1), QDir::toNativeSeparators(strSrc2));
1470
 
    if (result == QIMessageBox::Yes)
1471
 
    {
1472
 
        const QString &source = QString("http://download.virtualbox.org/virtualbox/%1/").arg(vboxGlobal().vboxVersionStringNormalized()) + name;
1473
 
        const QString &target = QDir(vboxGlobal().virtualBox().GetHomeFolder()).absoluteFilePath(name);
1474
 
 
 
1737
    /* If downloader is running already: */
 
1738
    if (UIDownloaderAdditions::current())
 
1739
    {
 
1740
        /* Just show network access manager: */
 
1741
        gNetworkManager->show();
 
1742
    }
 
1743
    /* Else propose to download additions: */
 
1744
    else if (msgCenter().cannotFindGuestAdditions())
 
1745
    {
 
1746
        /* Create Additions downloader: */
1475
1747
        UIDownloaderAdditions *pDl = UIDownloaderAdditions::create();
1476
 
        /* Configure the additions downloader. */
1477
 
        pDl->setSource(source);
1478
 
        pDl->setTarget(target);
1479
 
        pDl->setAction(gActionPool->action(UIActionIndexRuntime_Simple_InstallGuestTools));
1480
 
        pDl->setParentWidget(mainMachineWindow()->machineWindow());
1481
 
        /* After the download is finished the user may like to install the
1482
 
         * additions.*/
1483
 
        connect(pDl, SIGNAL(sigDownloadFinished(const QString&)),
1484
 
                uisession(), SLOT(sltInstallGuestAdditionsFrom(const QString&)));
1485
 
        /* Some of the modes may show additional info of the download progress: */
1486
 
        emit sigDownloaderAdditionsCreated();
1487
 
        /* Start the download: */
 
1748
        /* After downloading finished => propose to install the Additions: */
 
1749
        connect(pDl, SIGNAL(sigDownloadFinished(const QString&)), uisession(), SLOT(sltInstallGuestAdditionsFrom(const QString&)));
 
1750
        /* Start downloading: */
1488
1751
        pDl->start();
1489
1752
    }
1490
1753
}
1491
1754
 
1492
1755
#ifdef VBOX_WITH_DEBUGGER_GUI
 
1756
 
1493
1757
void UIMachineLogic::sltPrepareDebugMenu()
1494
1758
{
1495
1759
    /* The "Logging" item. */
1514
1778
void UIMachineLogic::sltShowDebugStatistics()
1515
1779
{
1516
1780
    if (dbgCreated())
 
1781
    {
 
1782
        keyboardHandler()->setDebuggerActive();
1517
1783
        m_pDbgGuiVT->pfnShowStatistics(m_pDbgGui);
 
1784
    }
1518
1785
}
1519
1786
 
1520
1787
void UIMachineLogic::sltShowDebugCommandLine()
1521
1788
{
1522
1789
    if (dbgCreated())
 
1790
    {
 
1791
        keyboardHandler()->setDebuggerActive();
1523
1792
        m_pDbgGuiVT->pfnShowCommandLine(m_pDbgGui);
 
1793
    }
1524
1794
}
1525
1795
 
1526
1796
void UIMachineLogic::sltLoggingToggled(bool fState)
1534
1804
            cdebugger.SetLogEnabled(fState);
1535
1805
    }
1536
1806
}
1537
 
#endif
 
1807
 
 
1808
void UIMachineLogic::sltShowLogDialog()
 
1809
{
 
1810
    /* Show VM Log Viewer: */
 
1811
    UIVMLogViewer::showLogViewerFor(activeMachineWindow(), session().GetMachine());
 
1812
}
 
1813
 
 
1814
#endif /* VBOX_WITH_DEBUGGER_GUI */
1538
1815
 
1539
1816
#ifdef Q_WS_MAC
1540
1817
void UIMachineLogic::sltDockPreviewModeChanged(QAction *pAction)
1541
1818
{
1542
 
    CMachine machine = m_pSession->session().GetMachine();
 
1819
    CMachine machine = session().GetMachine();
1543
1820
    if (!machine.isNull())
1544
1821
    {
1545
1822
        bool fEnabled = true;
1546
1823
        if (pAction == gActionPool->action(UIActionIndexRuntime_Toggle_DockDisableMonitor))
1547
1824
            fEnabled = false;
1548
1825
 
1549
 
        machine.SetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateEnabled, fEnabled ? "true" : "false");
 
1826
        machine.SetExtraData(GUI_RealtimeDockIconUpdateEnabled, fEnabled ? "true" : "false");
1550
1827
        updateDockOverlay();
1551
1828
    }
1552
1829
}
1553
1830
 
1554
1831
void UIMachineLogic::sltDockPreviewMonitorChanged(QAction *pAction)
1555
1832
{
1556
 
    CMachine machine = m_pSession->session().GetMachine();
 
1833
    CMachine machine = session().GetMachine();
1557
1834
    if (!machine.isNull())
1558
1835
    {
1559
1836
        int monitor = pAction->data().toInt();
1560
 
        machine.SetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateMonitor, QString::number(monitor));
 
1837
        machine.SetExtraData(GUI_RealtimeDockIconUpdateMonitor, QString::number(monitor));
1561
1838
        updateDockOverlay();
1562
1839
    }
1563
1840
}
1571
1848
        {
1572
1849
            m_pDockPreviewSelectMonitorGroup->setEnabled(fEnabled);
1573
1850
            CMachine machine = session().GetMachine();
1574
 
            m_DockIconPreviewMonitor = qMin(machine.GetExtraData(VBoxDefs::GUI_RealtimeDockIconUpdateMonitor).toInt(), (int)machine.GetMonitorCount() - 1);
 
1851
            m_DockIconPreviewMonitor = qMin(machine.GetExtraData(GUI_RealtimeDockIconUpdateMonitor).toInt(), (int)machine.GetMonitorCount() - 1);
1575
1852
        }
1576
1853
        /* Resize the dock icon in the case the preview monitor has changed. */
1577
1854
        QSize size = machineWindows().at(m_DockIconPreviewMonitor)->machineView()->size();
1604
1881
    return iMaxIndex;
1605
1882
}
1606
1883
 
 
1884
void UIMachineLogic::takeScreenshot(const QString &strFile, const QString &strFormat /* = "png" */) const
 
1885
{
 
1886
    /* Get console: */
 
1887
    const CConsole &console = session().GetConsole();
 
1888
    CDisplay display = console.GetDisplay();
 
1889
    const int cGuestScreens = uisession()->session().GetMachine().GetMonitorCount();
 
1890
    QList<QImage> images;
 
1891
    ULONG uMaxWidth  = 0;
 
1892
    ULONG uMaxHeight = 0;
 
1893
    /* First create screenshots of all guest screens and save them in a list.
 
1894
     * Also sum the width of all images and search for the biggest image height. */
 
1895
    for (int i = 0; i < cGuestScreens; ++i)
 
1896
    {
 
1897
        ULONG width  = 0;
 
1898
        ULONG height = 0;
 
1899
        ULONG bpp    = 0;
 
1900
        display.GetScreenResolution(i, width, height, bpp);
 
1901
        uMaxWidth  += width;
 
1902
        uMaxHeight  = RT_MAX(uMaxHeight, height);
 
1903
        QImage shot = QImage(width, height, QImage::Format_RGB32);
 
1904
        display.TakeScreenShot(i, shot.bits(), shot.width(), shot.height());
 
1905
        images << shot;
 
1906
    }
 
1907
    /* Create a image which will hold all sub images vertically. */
 
1908
    QImage bigImg = QImage(uMaxWidth, uMaxHeight, QImage::Format_RGB32);
 
1909
    QPainter p(&bigImg);
 
1910
    ULONG w = 0;
 
1911
    /* Paint them. */
 
1912
    for (int i = 0; i < images.size(); ++i)
 
1913
    {
 
1914
        p.drawImage(w, 0, images.at(i));
 
1915
        w += images.at(i).width();
 
1916
    }
 
1917
    p.end();
 
1918
 
 
1919
    /* Save the big image in the requested format: */
 
1920
    const QFileInfo fi(strFile);
 
1921
    const QString &strPathWithoutSuffix = QDir(fi.absolutePath()).absoluteFilePath(fi.baseName());
 
1922
    const QString &strSuffix = fi.suffix().isEmpty() ? strFormat : fi.suffix();
 
1923
    bigImg.save(QDir::toNativeSeparators(QFile::encodeName(QString("%1.%2").arg(strPathWithoutSuffix, strSuffix))),
 
1924
                strFormat.toAscii().constData());
 
1925
}
 
1926
 
1607
1927
#ifdef VBOX_WITH_DEBUGGER_GUI
1608
1928
bool UIMachineLogic::dbgCreated()
1609
1929
{
1622
1942
        rc = pfnGuiCreate(pISession, &m_pDbgGui, &m_pDbgGuiVT);
1623
1943
        if (RT_SUCCESS(rc))
1624
1944
        {
1625
 
            if (DBGGUIVT_ARE_VERSIONS_COMPATIBLE(m_pDbgGuiVT->u32Version, DBGGUIVT_VERSION) ||
1626
 
                m_pDbgGuiVT->u32EndVersion == m_pDbgGuiVT->u32Version)
 
1945
            if (   DBGGUIVT_ARE_VERSIONS_COMPATIBLE(m_pDbgGuiVT->u32Version, DBGGUIVT_VERSION)
 
1946
                || m_pDbgGuiVT->u32EndVersion == m_pDbgGuiVT->u32Version)
1627
1947
            {
1628
 
                m_pDbgGuiVT->pfnSetParent(m_pDbgGui, defaultMachineWindow()->machineWindow());
 
1948
                m_pDbgGuiVT->pfnSetParent(m_pDbgGui, activeMachineWindow());
1629
1949
                m_pDbgGuiVT->pfnSetMenu(m_pDbgGui, gActionPool->action(UIActionIndexRuntime_Menu_Debug));
1630
1950
                dbgAdjustRelativePos();
1631
1951
                return true;
1659
1979
{
1660
1980
    if (m_pDbgGui)
1661
1981
    {
1662
 
        QRect rct = defaultMachineWindow()->machineWindow()->frameGeometry();
 
1982
        QRect rct = activeMachineWindow()->frameGeometry();
1663
1983
        m_pDbgGuiVT->pfnAdjustRelativePos(m_pDbgGui, rct.x(), rct.y(), rct.width(), rct.height());
1664
1984
    }
1665
1985
}