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

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/src/selector/UIVMDesktop.cpp

  • Committer: Package Import Robot
  • Author(s): Gianfranco Costamagna
  • Date: 2016-02-23 14:28:26 UTC
  • Revision ID: package-import@ubuntu.com-20160223142826-bdu69el2z6wa2a44
Tags: upstream-4.3.36-dfsg
ImportĀ upstreamĀ versionĀ 4.3.36-dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: UIVMDesktop.cpp $ */
 
2
/** @file
 
3
 *
 
4
 * VBox frontends: Qt GUI ("VirtualBox"):
 
5
 * UIVMDesktop class implementation
 
6
 */
 
7
 
 
8
/*
 
9
 * Copyright (C) 2010-2013 Oracle Corporation
 
10
 *
 
11
 * This file is part of VirtualBox Open Source Edition (OSE), as
 
12
 * available from http://www.virtualbox.org. This file is free software;
 
13
 * you can redistribute it and/or modify it under the terms of the GNU
 
14
 * General Public License (GPL) as published by the Free Software
 
15
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 
16
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 
17
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 
18
 */
 
19
 
 
20
/* Qt includes: */
 
21
#include <QLabel>
 
22
#include <QStackedLayout>
 
23
#include <QStackedWidget>
 
24
#include <QToolButton>
 
25
#ifdef Q_WS_MAC
 
26
# include <QTimer>
 
27
#endif /* Q_WS_MAC */
 
28
 
 
29
/* GUI includes */
 
30
#include "UIBar.h"
 
31
#include "UIIconPool.h"
 
32
#include "UISpacerWidgets.h"
 
33
#include "UISpecialControls.h"
 
34
#include "UIVMDesktop.h"
 
35
#include "UIVMItem.h"
 
36
#include "UIToolBar.h"
 
37
#include "VBoxSnapshotsWgt.h"
 
38
#include "VBoxUtils.h"
 
39
 
 
40
/* Other VBox includes: */
 
41
#include <iprt/assert.h>
 
42
 
 
43
//#ifdef Q_WS_MAC
 
44
# define USE_TOOLBAR
 
45
//#endif /* Q_WS_MAC */
 
46
 
 
47
#ifdef Q_WS_MAC
 
48
static const int gsLeftMargin = 5;
 
49
static const int gsTopMargin = 5;
 
50
static const int gsRightMargin = 5;
 
51
static const int gsBottomMargin = 5;
 
52
#else /* Q_WS_MAC */
 
53
static const int gsLeftMargin = 0;
 
54
static const int gsTopMargin = 5;
 
55
static const int gsRightMargin = 5;
 
56
static const int gsBottomMargin = 5;
 
57
#endif /* !Q_WS_MAC */
 
58
 
 
59
/* Container to store VM desktop panes. */
 
60
class UIVMDesktopPrivate : public QIWithRetranslateUI<QStackedWidget>
 
61
{
 
62
    Q_OBJECT;
 
63
 
 
64
public:
 
65
 
 
66
    /* Constructor: */
 
67
    UIVMDesktopPrivate(QWidget *pParent, QAction *pRefreshAction);
 
68
 
 
69
    /* API: Pane text setters stuff: */
 
70
    void setText(const QString &strText);
 
71
    void setError(const QString &strError);
 
72
 
 
73
private:
 
74
 
 
75
    /* Helper: Translate stuff: */
 
76
    void retranslateUi();
 
77
 
 
78
    /* Helpers: Prepare stuff: */
 
79
    void prepareTextPane();
 
80
    void prepareErrorPane();
 
81
 
 
82
    /* Text pane stuff: */
 
83
    QRichTextBrowser *m_pText;
 
84
 
 
85
    /* Error pane stuff: */
 
86
    QWidget *m_pErrBox;
 
87
    QLabel *m_pErrLabel;
 
88
    QTextBrowser *m_pErrText;
 
89
    QToolButton *m_pRefreshButton;
 
90
    QAction *m_pRefreshAction;
 
91
};
 
92
 
 
93
UIVMDesktopPrivate::UIVMDesktopPrivate(QWidget *pParent, QAction *pRefreshAction)
 
94
    : QIWithRetranslateUI<QStackedWidget>(pParent)
 
95
    , m_pText(0)
 
96
    , m_pErrBox(0), m_pErrLabel(0), m_pErrText(0)
 
97
    , m_pRefreshButton(0), m_pRefreshAction(pRefreshAction)
 
98
{
 
99
    /* Make sure refresh action was passed: */
 
100
    AssertMsg(m_pRefreshAction, ("Refresh action was NOT passed!"));
 
101
 
 
102
    /* Translate finally: */
 
103
    retranslateUi();
 
104
}
 
105
 
 
106
void UIVMDesktopPrivate::setText(const QString &strText)
 
107
{
 
108
    /* Prepare text pane if necessary: */
 
109
    prepareTextPane();
 
110
 
 
111
    /* Assign corresponding text: */
 
112
    m_pText->setText(strText);
 
113
 
 
114
    /* Raise corresponding widget: */
 
115
    setCurrentIndex(indexOf(m_pText));
 
116
}
 
117
 
 
118
void UIVMDesktopPrivate::setError(const QString &strError)
 
119
{
 
120
    /* Prepare error pane if necessary: */
 
121
    prepareErrorPane();
 
122
 
 
123
    /* Assign corresponding text: */
 
124
    m_pErrText->setText(strError);
 
125
 
 
126
    /* Raise corresponding widget: */
 
127
    setCurrentIndex(indexOf(m_pErrBox));
 
128
}
 
129
 
 
130
void UIVMDesktopPrivate::retranslateUi()
 
131
{
 
132
    /* Translate error-label text: */
 
133
    if (m_pErrLabel)
 
134
        m_pErrLabel->setText(QApplication::translate("UIDetailsPagePrivate",
 
135
                                 "The selected virtual machine is <i>inaccessible</i>. "
 
136
                                 "Please inspect the error message shown below and press the "
 
137
                                 "<b>Refresh</b> button if you want to repeat the accessibility check:"));
 
138
 
 
139
    /* Translate refresh button & action text: */
 
140
    if (m_pRefreshAction && m_pRefreshButton)
 
141
    {
 
142
        m_pRefreshButton->setText(m_pRefreshAction->text());
 
143
        m_pRefreshButton->setIcon(m_pRefreshAction->icon());
 
144
        m_pRefreshButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
 
145
    }
 
146
}
 
147
 
 
148
void UIVMDesktopPrivate::prepareTextPane()
 
149
{
 
150
    if (m_pText)
 
151
        return;
 
152
 
 
153
    /* Create text pane: */
 
154
    m_pText = new QRichTextBrowser(this);
 
155
    m_pText->setFocusPolicy(Qt::StrongFocus);
 
156
    m_pText->document()->setDefaultStyleSheet("a { text-decoration: none; }");
 
157
    /* Make text pane transparent: */
 
158
    m_pText->setFrameShape(QFrame::NoFrame);
 
159
    m_pText->viewport()->setAutoFillBackground(false);
 
160
    m_pText->setOpenLinks(false);
 
161
 
 
162
    /* Add into the stack: */
 
163
    addWidget(m_pText);
 
164
 
 
165
    /* Retranslate finally: */
 
166
    retranslateUi();
 
167
}
 
168
 
 
169
void UIVMDesktopPrivate::prepareErrorPane()
 
170
{
 
171
    if (m_pErrBox)
 
172
        return;
 
173
 
 
174
    /* Create error pane: */
 
175
    m_pErrBox = new QWidget;
 
176
 
 
177
    /* Create main layout: */
 
178
    QVBoxLayout *pMainLayout = new QVBoxLayout(m_pErrBox);
 
179
    pMainLayout->setContentsMargins(gsLeftMargin, gsTopMargin, gsRightMargin, gsBottomMargin);
 
180
    pMainLayout->setSpacing(10);
 
181
 
 
182
    /* Create error label: */
 
183
    m_pErrLabel = new QLabel(m_pErrBox);
 
184
    m_pErrLabel->setWordWrap(true);
 
185
    m_pErrLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
 
186
    pMainLayout->addWidget(m_pErrLabel);
 
187
 
 
188
    /* Create error text browser: */
 
189
    m_pErrText = new QTextBrowser(m_pErrBox);
 
190
    m_pErrText->setFocusPolicy(Qt::StrongFocus);
 
191
    m_pErrText->document()->setDefaultStyleSheet("a { text-decoration: none; }");
 
192
    pMainLayout->addWidget(m_pErrText);
 
193
 
 
194
    /* If refresh action was set: */
 
195
    if (m_pRefreshAction)
 
196
    {
 
197
        /* Create refresh button: */
 
198
        m_pRefreshButton = new QToolButton(m_pErrBox);
 
199
        m_pRefreshButton->setFocusPolicy(Qt::StrongFocus);
 
200
 
 
201
        /* Create refresh button layout: */
 
202
        QHBoxLayout *pButtonLayout = new QHBoxLayout;
 
203
        pMainLayout->addLayout(pButtonLayout);
 
204
        pButtonLayout->addStretch();
 
205
        pButtonLayout->addWidget(m_pRefreshButton);
 
206
 
 
207
        /* Connect refresh button: */
 
208
        connect(m_pRefreshButton, SIGNAL(clicked()), m_pRefreshAction, SIGNAL(triggered()));
 
209
    }
 
210
 
 
211
    pMainLayout->addStretch();
 
212
 
 
213
    /* Add into the stack: */
 
214
    addWidget(m_pErrBox);
 
215
 
 
216
    /* Retranslate finally: */
 
217
    retranslateUi();
 
218
}
 
219
 
 
220
enum
 
221
{
 
222
    Dtls = 0,
 
223
    Snap
 
224
};
 
225
 
 
226
UIVMDesktop::UIVMDesktop(UIToolBar *pToolBar, QAction *pRefreshAction, QWidget *pParent)
 
227
    : QIWithRetranslateUI<QWidget>(pParent)
 
228
{
 
229
    /* Prepare buttons: */
 
230
    m_pHeaderBtn = new UITexturedSegmentedButton(2);
 
231
    m_pHeaderBtn->setIcon(Dtls, UIIconPool::iconSet(":/vm_settings_16px.png"));
 
232
    m_pHeaderBtn->setIcon(Snap, UIIconPool::iconSet(":/snapshot_take_16px.png",
 
233
                                                    ":/snapshot_take_disabled_16px.png"));
 
234
#ifdef Q_WS_MAC
 
235
    /* Cocoa stuff should be async...
 
236
     * Do not ask me why but otherwise
 
237
     * it conflicts with native handlers. */
 
238
    QTimer::singleShot(0, this, SLOT(sltInit()));
 
239
#else /* !Q_WS_MAC */
 
240
    sltInit();
 
241
#endif /* !Q_WS_MAC */
 
242
 
 
243
    /* Prepare main layout: */
 
244
    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
 
245
    pMainLayout->setContentsMargins(0, 0, 0, 0);
 
246
 
 
247
    /* The header to select the different pages.
 
248
     * Has different styles on the different platforms. */
 
249
#ifdef USE_TOOLBAR
 
250
    if (pToolBar)
 
251
    {
 
252
        pToolBar->addWidget(new UIHorizontalSpacerWidget(this));
 
253
        pToolBar->addWidget(m_pHeaderBtn);
 
254
        QWidget *pSpace = new QWidget(this);
 
255
        /* We need a little bit more space for the beta label. */
 
256
        if (vboxGlobal().isBeta())
 
257
            pSpace->setFixedSize(28, 1);
 
258
        else
 
259
            pSpace->setFixedSize(10, 1);
 
260
        pToolBar->addWidget(pSpace);
 
261
#ifdef Q_WS_MAC
 
262
        pToolBar->updateLayout();
 
263
#endif /* Q_WS_MAC */
 
264
    }
 
265
    else
 
266
#else /* USE_TOOLBAR */
 
267
        NOREF(pToolBar);
 
268
#endif /* !USE_TOOLBAR */
 
269
    {
 
270
        UIBar *pBar = new UIBar(this);
 
271
        pBar->setContentWidget(m_pHeaderBtn);
 
272
        pMainLayout->addWidget(pBar);
 
273
    }
 
274
 
 
275
    /* Create desktop pane: */
 
276
    m_pDesktopPrivate = new UIVMDesktopPrivate(this, pRefreshAction);
 
277
 
 
278
    /* Create snapshot pane: */
 
279
    m_pSnapshotsPane = new VBoxSnapshotsWgt(this);
 
280
    m_pSnapshotsPane->setContentsMargins(gsLeftMargin, gsTopMargin, gsRightMargin, gsBottomMargin);
 
281
 
 
282
    /* Add the pages: */
 
283
    m_pStackedLayout = new QStackedLayout(pMainLayout);
 
284
    m_pStackedLayout->addWidget(m_pDesktopPrivate);
 
285
    m_pStackedLayout->addWidget(m_pSnapshotsPane);
 
286
 
 
287
    /* Connect the header buttons with the stack layout: */
 
288
    connect(m_pHeaderBtn, SIGNAL(clicked(int)), m_pStackedLayout, SLOT(setCurrentIndex(int)));
 
289
    connect(m_pStackedLayout, SIGNAL(currentChanged(int)), this, SIGNAL(sigCurrentChanged(int)));
 
290
 
 
291
    /* Translate finally: */
 
292
    retranslateUi();
 
293
}
 
294
 
 
295
int UIVMDesktop::widgetIndex() const
 
296
{
 
297
    return m_pStackedLayout->currentIndex();
 
298
}
 
299
 
 
300
void UIVMDesktop::updateDetailsText(const QString &strText)
 
301
{
 
302
    m_pDesktopPrivate->setText(strText);
 
303
}
 
304
 
 
305
void UIVMDesktop::updateDetailsError(const QString &strError)
 
306
{
 
307
    m_pDesktopPrivate->setError(strError);
 
308
}
 
309
 
 
310
void UIVMDesktop::updateSnapshots(UIVMItem *pVMItem, const CMachine& machine)
 
311
{
 
312
    /* Update the snapshots header name: */
 
313
    QString name = tr("&Snapshots");
 
314
    if (pVMItem)
 
315
    {
 
316
        ULONG count = pVMItem->snapshotCount();
 
317
        if (count)
 
318
            name += QString(" (%1)").arg(count);
 
319
    }
 
320
    m_pHeaderBtn->setTitle(Snap, name);
 
321
 
 
322
    /* Refresh the snapshots widget: */
 
323
    if (!machine.isNull())
 
324
    {
 
325
        m_pHeaderBtn->setEnabled(Snap, true);
 
326
        m_pSnapshotsPane->setMachine(machine);
 
327
    }
 
328
    else
 
329
        lockSnapshots();
 
330
}
 
331
 
 
332
void UIVMDesktop::lockSnapshots()
 
333
{
 
334
    m_pHeaderBtn->animateClick(Dtls);
 
335
    m_pHeaderBtn->setEnabled(Snap, false);
 
336
}
 
337
 
 
338
void UIVMDesktop::sltInit()
 
339
{
 
340
    m_pHeaderBtn->animateClick(0);
 
341
}
 
342
 
 
343
void UIVMDesktop::retranslateUi()
 
344
{
 
345
    m_pHeaderBtn->setTitle(Dtls, tr("&Details"));
 
346
}
 
347
 
 
348
#include "UIVMDesktop.moc"
 
349