VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIIndicatorsPool.cpp@ 103977

Last change on this file since 103977 was 103977, checked in by vboxsync, 9 months ago

Apply RT_OVERRIDE/NS_OVERRIDE where required to shut up clang.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 50.3 KB
Line 
1/* $Id: UIIndicatorsPool.cpp 103977 2024-03-21 02:04:52Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIIndicatorsPool class implementation.
4 */
5
6/*
7 * Copyright (C) 2010-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QAccessibleWidget>
30#include <QHBoxLayout>
31#include <QPainter>
32#include <QStyle>
33#include <QTimer>
34
35/* GUI includes: */
36#include "QIStatusBarIndicator.h"
37#include "QIWithRetranslateUI.h"
38#include "UIAnimationFramework.h"
39#include "UICommon.h"
40#include "UIConverter.h"
41#include "UIExtraDataManager.h"
42#include "UIHostComboEditor.h"
43#include "UIIconPool.h"
44#include "UIIndicatorsPool.h"
45#include "UIMachine.h"
46
47
48/** QIStateStatusBarIndicator extension for Runtime UI. */
49class UISessionStateStatusBarIndicator : public QIWithRetranslateUI<QIStateStatusBarIndicator>
50{
51 Q_OBJECT;
52
53public:
54
55 /** Constructor which remembers passed @a session object. */
56 UISessionStateStatusBarIndicator(IndicatorType enmType, UIMachine *pMachine);
57
58 /** Returns the indicator type. */
59 IndicatorType type() const { return m_enmType; }
60
61 /** Returns the indicator description. */
62 virtual QString description() const { return m_strDescription; }
63
64public slots:
65
66 /** Abstract update routine. */
67 virtual void updateAppearance() = 0;
68
69protected:
70
71 /** Handles translation event. */
72 virtual void retranslateUi() RT_OVERRIDE;
73
74 /** Holds the indicator type. */
75 const IndicatorType m_enmType;
76
77 /** Holds the machine UI reference. */
78 UIMachine *m_pMachine;
79
80 /** Holds the indicator description. */
81 QString m_strDescription;
82
83 /** Holds the table format. */
84 static const QString s_strTable;
85 /** Holds the table row format 1. */
86 static const QString s_strTableRow1;
87 /** Holds the table row format 2. */
88 static const QString s_strTableRow2;
89 /** Holds the table row format 3. */
90 static const QString s_strTableRow3;
91 /** Holds the table row format 4. */
92 static const QString s_strTableRow4;
93};
94
95
96/* static */
97const QString UISessionStateStatusBarIndicator::s_strTable = QString("<table cellspacing=5 style='white-space:pre'>%1</table>");
98/* static */
99const QString UISessionStateStatusBarIndicator::s_strTableRow1 = QString("<tr><td colspan='2'><nobr><b>%1</b></nobr></td></tr>");
100/* static */
101const QString UISessionStateStatusBarIndicator::s_strTableRow2 = QString("<tr><td><nobr>%1:</nobr></td><td><nobr>%2</nobr></td></tr>");
102/* static */
103const QString UISessionStateStatusBarIndicator::s_strTableRow3 = QString("<tr><td><nobr>%1</nobr></td><td><nobr>%2</nobr></td></tr>");
104/* static */
105const QString UISessionStateStatusBarIndicator::s_strTableRow4 = QString("<tr><td><nobr>&nbsp;%1:</nobr></td><td><nobr>%2</nobr></td></tr>");
106
107
108/** QAccessibleWidget extension used as an accessibility interface for UISessionStateStatusBarIndicator. */
109class QIAccessibilityInterfaceForUISessionStateStatusBarIndicator : public QAccessibleWidget
110{
111public:
112
113 /** Returns an accessibility interface for passed @a strClassname and @a pObject. */
114 static QAccessibleInterface *pFactory(const QString &strClassname, QObject *pObject)
115 {
116 /* Creating UISessionStateStatusBarIndicator accessibility interface: */
117 if (pObject && strClassname == QLatin1String("UISessionStateStatusBarIndicator"))
118 return new QIAccessibilityInterfaceForUISessionStateStatusBarIndicator(qobject_cast<QWidget*>(pObject));
119
120 /* Null by default: */
121 return 0;
122 }
123
124 /** Constructs an accessibility interface passing @a pWidget to the base-class. */
125 QIAccessibilityInterfaceForUISessionStateStatusBarIndicator(QWidget *pWidget)
126 : QAccessibleWidget(pWidget, QAccessible::Button)
127 {}
128
129 /** Returns a text for the passed @a enmTextRole. */
130 virtual QString text(QAccessible::Text /* enmTextRole */) const RT_OVERRIDE
131 {
132 /* Sanity check: */
133 AssertPtrReturn(indicator(), 0);
134
135 /* Return the indicator description: */
136 return indicator()->description();
137 }
138
139private:
140
141 /** Returns corresponding UISessionStateStatusBarIndicator. */
142 UISessionStateStatusBarIndicator *indicator() const { return qobject_cast<UISessionStateStatusBarIndicator*>(widget()); }
143};
144
145
146UISessionStateStatusBarIndicator::UISessionStateStatusBarIndicator(IndicatorType enmType, UIMachine *pMachine)
147 : m_enmType(enmType)
148 , m_pMachine(pMachine)
149{
150 /* Install UISessionStateStatusBarIndicator accessibility interface factory: */
151 QAccessible::installFactory(QIAccessibilityInterfaceForUISessionStateStatusBarIndicator::pFactory);
152}
153
154void UISessionStateStatusBarIndicator::retranslateUi()
155{
156 /* Translate description: */
157 m_strDescription = tr("%1 status-bar indicator", "like 'hard-disk status-bar indicator'")
158 .arg(gpConverter->toString(type()));
159
160 /* Update appearance finally: */
161 updateAppearance();
162}
163
164
165/** UISessionStateStatusBarIndicator extension for Runtime UI: Hard-drive indicator. */
166class UIIndicatorHardDrive : public UISessionStateStatusBarIndicator
167{
168 Q_OBJECT;
169
170public:
171
172 /** Constructs indicator passing @a pMachine to the base-class. */
173 UIIndicatorHardDrive(UIMachine *pMachine)
174 : UISessionStateStatusBarIndicator(IndicatorType_HardDisks, pMachine)
175 {
176 /* Assign state-icons: */
177 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/hd_16px.png"));
178 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/hd_read_16px.png"));
179 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/hd_write_16px.png"));
180 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/hd_disabled_16px.png"));
181 /* Configure connection: */
182 connect(m_pMachine, &UIMachine::sigMachineStateChange,
183 this, &UIIndicatorHardDrive::updateAppearance);
184 connect(m_pMachine, &UIMachine::sigStorageDeviceChange,
185 this, &UIIndicatorHardDrive::updateAppearance);
186 connect(m_pMachine, &UIMachine::sigMediumChange,
187 this, &UIIndicatorHardDrive::updateAppearance);
188 /* Translate finally: */
189 retranslateUi();
190 }
191
192protected slots:
193
194 /** Update routine. */
195 virtual void updateAppearance() RT_OVERRIDE
196 {
197 /* Acquire data: */
198 QString strFullData;
199 bool fAttachmentsPresent = false;
200 m_pMachine->acquireHardDiskStatusInfo(strFullData, fAttachmentsPresent);
201
202 /* Show/hide indicator if there are no attachments
203 * and parent is visible already: */
204 if ( parentWidget()
205 && parentWidget()->isVisible())
206 setVisible(fAttachmentsPresent);
207
208 /* Update tool-tip: */
209 if (!strFullData.isEmpty())
210 setToolTip(s_strTable.arg(strFullData));
211 /* Update indicator state: */
212 setState(fAttachmentsPresent ? KDeviceActivity_Idle : KDeviceActivity_Null);
213 }
214};
215
216
217/** UISessionStateStatusBarIndicator extension for Runtime UI: Optical-drive indicator. */
218class UIIndicatorOpticalDisks : public UISessionStateStatusBarIndicator
219{
220 Q_OBJECT;
221
222public:
223
224 /** Constructs indicator passing @a pMachine to the base-class. */
225 UIIndicatorOpticalDisks(UIMachine *pMachine)
226 : UISessionStateStatusBarIndicator(IndicatorType_OpticalDisks, pMachine)
227 {
228 /* Assign state-icons: */
229 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/cd_16px.png"));
230 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/cd_read_16px.png"));
231 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/cd_write_16px.png"));
232 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/cd_disabled_16px.png"));
233 /* Configure connection: */
234 connect(m_pMachine, &UIMachine::sigMachineStateChange,
235 this, &UIIndicatorOpticalDisks::updateAppearance);
236 connect(m_pMachine, &UIMachine::sigStorageDeviceChange,
237 this, &UIIndicatorOpticalDisks::updateAppearance);
238 connect(m_pMachine, &UIMachine::sigMediumChange,
239 this, &UIIndicatorOpticalDisks::updateAppearance);
240 /* Translate finally: */
241 retranslateUi();
242 }
243
244protected slots:
245
246 /** Update routine. */
247 virtual void updateAppearance() RT_OVERRIDE
248 {
249 QString strFullData;
250 bool fAttachmentsPresent = false;
251 bool fAttachmentsMounted = false;
252 m_pMachine->acquireOpticalDiskStatusInfo(strFullData, fAttachmentsPresent, fAttachmentsMounted);
253
254 /* Show/hide indicator if there are no attachments
255 * and parent is visible already: */
256 if ( parentWidget()
257 && parentWidget()->isVisible())
258 setVisible(fAttachmentsPresent);
259
260 /* Update tool-tip: */
261 if (!strFullData.isEmpty())
262 setToolTip(s_strTable.arg(strFullData));
263 /* Update indicator state: */
264 setState(fAttachmentsMounted ? KDeviceActivity_Idle : KDeviceActivity_Null);
265 }
266};
267
268
269/** UISessionStateStatusBarIndicator extension for Runtime UI: Floppy-drive indicator. */
270class UIIndicatorFloppyDisks : public UISessionStateStatusBarIndicator
271{
272 Q_OBJECT;
273
274public:
275
276 /** Constructs indicator passing @a pMachine to the base-class. */
277 UIIndicatorFloppyDisks(UIMachine *pMachine)
278 : UISessionStateStatusBarIndicator(IndicatorType_FloppyDisks, pMachine)
279 {
280 /* Assign state-icons: */
281 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/fd_16px.png"));
282 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/fd_read_16px.png"));
283 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/fd_write_16px.png"));
284 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/fd_disabled_16px.png"));
285 /* Configure connection: */
286 connect(m_pMachine, &UIMachine::sigMachineStateChange,
287 this, &UIIndicatorFloppyDisks::updateAppearance);
288 connect(m_pMachine, &UIMachine::sigStorageDeviceChange,
289 this, &UIIndicatorFloppyDisks::updateAppearance);
290 connect(m_pMachine, &UIMachine::sigMediumChange,
291 this, &UIIndicatorFloppyDisks::updateAppearance);
292 /* Translate finally: */
293 retranslateUi();
294 }
295
296protected slots:
297
298 /** Update routine. */
299 virtual void updateAppearance() RT_OVERRIDE
300 {
301 QString strFullData;
302 bool fAttachmentsPresent = false;
303 bool fAttachmentsMounted = false;
304 m_pMachine->acquireFloppyDiskStatusInfo(strFullData, fAttachmentsPresent, fAttachmentsMounted);
305
306 /* Show/hide indicator if there are no attachments
307 * and parent is visible already: */
308 if ( parentWidget()
309 && parentWidget()->isVisible())
310 setVisible(fAttachmentsPresent);
311
312 /* Update tool-tip: */
313 if (!strFullData.isEmpty())
314 setToolTip(s_strTable.arg(strFullData));
315 /* Update indicator state: */
316 setState(fAttachmentsMounted ? KDeviceActivity_Idle : KDeviceActivity_Null);
317 }
318};
319
320
321/** UISessionStateStatusBarIndicator extension for Runtime UI: Audio indicator. */
322class UIIndicatorAudio : public UISessionStateStatusBarIndicator
323{
324 Q_OBJECT;
325
326public:
327
328 /** Audio states. */
329 enum AudioState
330 {
331 AudioState_AllOff = 0,
332 AudioState_OutputOn = RT_BIT(0),
333 AudioState_InputOn = RT_BIT(1),
334 AudioState_AllOn = AudioState_InputOn | AudioState_OutputOn
335 };
336
337 /** Constructs indicator passing @a pMachine to the base-class. */
338 UIIndicatorAudio(UIMachine *pMachine)
339 : UISessionStateStatusBarIndicator(IndicatorType_Audio, pMachine)
340 {
341 /* Assign state-icons: */
342 setStateIcon(AudioState_AllOff, UIIconPool::iconSet(":/audio_all_off_16px.png"));
343 setStateIcon(AudioState_OutputOn, UIIconPool::iconSet(":/audio_input_off_16px.png"));
344 setStateIcon(AudioState_InputOn, UIIconPool::iconSet(":/audio_output_off_16px.png"));
345 setStateIcon(AudioState_AllOn, UIIconPool::iconSet(":/audio_16px.png"));
346 /* Configure connection: */
347 connect(m_pMachine, &UIMachine::sigMachineStateChange,
348 this, &UIIndicatorAudio::updateAppearance);
349 connect(m_pMachine, &UIMachine::sigInitialized,
350 this, &UIIndicatorAudio::updateAppearance);
351 connect(m_pMachine, &UIMachine::sigAudioAdapterChange,
352 this, &UIIndicatorAudio::updateAppearance);
353 /* Translate finally: */
354 retranslateUi();
355 }
356
357protected slots:
358
359 /** Update routine. */
360 virtual void updateAppearance() RT_OVERRIDE
361 {
362 QString strFullData;
363 bool fAudioEnabled = false;
364 bool fEnabledOutput = false;
365 bool fEnabledInput = false;
366 m_pMachine->acquireAudioStatusInfo(strFullData, fAudioEnabled, fEnabledOutput, fEnabledInput);
367
368 /* Show/hide indicator if there are no attachments
369 * and parent is visible already: */
370 if ( parentWidget()
371 && parentWidget()->isVisible())
372 setVisible(fAudioEnabled);
373
374 /* Update tool-tip: */
375 if (!strFullData.isEmpty())
376 setToolTip(s_strTable.arg(strFullData));
377 /* Update indicator state: */
378 AudioState enmState = AudioState_AllOff;
379 if (fEnabledOutput)
380 enmState = (AudioState)(enmState | AudioState_OutputOn);
381 if (fEnabledInput)
382 enmState = (AudioState)(enmState | AudioState_InputOn);
383 setState(enmState);
384 }
385};
386
387
388/** UISessionStateStatusBarIndicator extension for Runtime UI: Network indicator. */
389class UIIndicatorNetwork : public UISessionStateStatusBarIndicator
390{
391 Q_OBJECT;
392
393public:
394
395 /** Constructs indicator passing @a pMachine to the base-class. */
396 UIIndicatorNetwork(UIMachine *pMachine)
397 : UISessionStateStatusBarIndicator(IndicatorType_Network, pMachine)
398 {
399 /* Assign state-icons: */
400 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/nw_16px.png"));
401 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/nw_read_16px.png"));
402 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/nw_write_16px.png"));
403 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/nw_disabled_16px.png"));
404 /* Configure connection: */
405 connect(m_pMachine, &UIMachine::sigMachineStateChange,
406 this, &UIIndicatorNetwork::updateAppearance);
407 connect(m_pMachine, &UIMachine::sigNetworkAdapterChange,
408 this, &UIIndicatorNetwork::updateAppearance);
409 /* Translate finally: */
410 retranslateUi();
411 }
412
413protected slots:
414
415 /** Update routine. */
416 virtual void updateAppearance() RT_OVERRIDE
417 {
418 QString strFullData;
419 bool fAdaptersPresent = false;
420 bool fCablesDisconnected = true;
421 m_pMachine->acquireNetworkStatusInfo(strFullData, fAdaptersPresent, fCablesDisconnected);
422
423 /* Show/hide indicator if there are no attachments
424 * and parent is visible already: */
425 if ( parentWidget()
426 && parentWidget()->isVisible())
427 setVisible(fAdaptersPresent);
428
429 /* Update tool-tip: */
430 if (!strFullData.isEmpty())
431 setToolTip(s_strTable.arg(strFullData));
432 /* Update indicator state: */
433 setState(fAdaptersPresent && !fCablesDisconnected ? KDeviceActivity_Idle : KDeviceActivity_Null);
434 }
435};
436
437
438/** UISessionStateStatusBarIndicator extension for Runtime UI: USB indicator. */
439class UIIndicatorUSB : public UISessionStateStatusBarIndicator
440{
441 Q_OBJECT;
442
443public:
444
445 /** Constructs indicator passing @a pMachine to the base-class. */
446 UIIndicatorUSB(UIMachine *pMachine)
447 : UISessionStateStatusBarIndicator(IndicatorType_USB, pMachine)
448 {
449 /* Assign state-icons: */
450 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/usb_16px.png"));
451 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/usb_read_16px.png"));
452 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/usb_write_16px.png"));
453 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/usb_disabled_16px.png"));
454 /* Configure connection: */
455 connect(m_pMachine, &UIMachine::sigMachineStateChange,
456 this, &UIIndicatorUSB::updateAppearance);
457 connect(m_pMachine, &UIMachine::sigUSBControllerChange,
458 this, &UIIndicatorUSB::updateAppearance);
459 connect(m_pMachine, &UIMachine::sigUSBDeviceStateChange,
460 this, &UIIndicatorUSB::updateAppearance);
461 /* Translate finally: */
462 retranslateUi();
463 }
464
465protected slots:
466
467 /** Update routine. */
468 virtual void updateAppearance() RT_OVERRIDE
469 {
470 QString strFullData;
471 bool fUsbEnabled = false;
472 m_pMachine->acquireUsbStatusInfo(strFullData, fUsbEnabled);
473
474 /* Show/hide indicator if there are no attachments
475 * and parent is visible already: */
476 if ( parentWidget()
477 && parentWidget()->isVisible())
478 setVisible(fUsbEnabled);
479
480 /* Update tool-tip: */
481 if (!strFullData.isEmpty())
482 setToolTip(s_strTable.arg(strFullData));
483 /* Update indicator state: */
484 setState(fUsbEnabled ? KDeviceActivity_Idle : KDeviceActivity_Null);
485 }
486};
487
488
489/** UISessionStateStatusBarIndicator extension for Runtime UI: Shared-folders indicator. */
490class UIIndicatorSharedFolders : public UISessionStateStatusBarIndicator
491{
492 Q_OBJECT;
493
494public:
495
496 /** Constructs indicator passing @a pMachine to the base-class. */
497 UIIndicatorSharedFolders(UIMachine *pMachine)
498 : UISessionStateStatusBarIndicator(IndicatorType_SharedFolders, pMachine)
499 {
500 /* Assign state-icons: */
501 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/sf_16px.png"));
502 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/sf_read_16px.png"));
503 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/sf_write_16px.png"));
504 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/sf_disabled_16px.png"));
505 /* Configure connection: */
506 connect(m_pMachine, &UIMachine::sigMachineStateChange,
507 this, &UIIndicatorSharedFolders::updateAppearance);
508 connect(m_pMachine, &UIMachine::sigSharedFolderChange,
509 this, &UIIndicatorSharedFolders::updateAppearance);
510 /* Translate finally: */
511 retranslateUi();
512 }
513
514protected slots:
515
516 /** Update routine. */
517 virtual void updateAppearance() RT_OVERRIDE
518 {
519 QString strFullData;
520 bool fFoldersPresent = false;
521 m_pMachine->acquireSharedFoldersStatusInfo(strFullData, fFoldersPresent);
522
523 /* Update tool-tip: */
524 if (!strFullData.isEmpty())
525 setToolTip(s_strTable.arg(strFullData));
526 /* Update indicator state: */
527 setState(fFoldersPresent ? KDeviceActivity_Idle : KDeviceActivity_Null);
528 }
529};
530
531
532/** UISessionStateStatusBarIndicator extension for Runtime UI: Display indicator. */
533class UIIndicatorDisplay : public UISessionStateStatusBarIndicator
534{
535 Q_OBJECT;
536
537public:
538
539 /** Display states. */
540 enum DisplayState
541 {
542 DisplayState_Unavailable = 0,
543 DisplayState_Software = 1,
544 DisplayState_Hardware = 2
545 };
546
547 /** Constructs indicator passing @a pMachine to the base-class. */
548 UIIndicatorDisplay(UIMachine *pMachine)
549 : UISessionStateStatusBarIndicator(IndicatorType_Display, pMachine)
550 {
551 /* Assign state-icons: */
552 setStateIcon(DisplayState_Unavailable, UIIconPool::iconSet(":/display_software_disabled_16px.png"));
553 setStateIcon(DisplayState_Software, UIIconPool::iconSet(":/display_software_16px.png"));
554 setStateIcon(DisplayState_Hardware, UIIconPool::iconSet(":/display_hardware_16px.png"));
555 /* Configure connection: */
556 connect(m_pMachine, &UIMachine::sigMachineStateChange,
557 this, &UIIndicatorDisplay::updateAppearance);
558 /* Translate finally: */
559 retranslateUi();
560 }
561
562protected slots:
563
564 /** Update routine. */
565 virtual void updateAppearance() RT_OVERRIDE
566 {
567 QString strFullData;
568 bool fAcceleration3D = false;
569 m_pMachine->acquireDisplayStatusInfo(strFullData, fAcceleration3D);
570
571 /* Update tool-tip: */
572 if (!strFullData.isEmpty())
573 setToolTip(s_strTable.arg(strFullData));
574 /* Update indicator state: */
575 DisplayState enmState = DisplayState_Unavailable;
576 if (m_pMachine->machineState() != KMachineState_Null)
577 {
578 if (!fAcceleration3D)
579 enmState = DisplayState_Software;
580 else
581 enmState = DisplayState_Hardware;
582 }
583 setState(enmState);
584 }
585};
586
587
588/** UISessionStateStatusBarIndicator extension for Runtime UI: Recording indicator. */
589class UIIndicatorRecording : public UISessionStateStatusBarIndicator
590{
591 Q_OBJECT;
592 Q_PROPERTY(double rotationAngleStart READ rotationAngleStart);
593 Q_PROPERTY(double rotationAngleFinal READ rotationAngleFinal);
594 Q_PROPERTY(double rotationAngle READ rotationAngle WRITE setRotationAngle);
595
596 /** Recording states. */
597 enum RecordingState
598 {
599 RecordingState_Unavailable = 0,
600 RecordingState_Disabled = 1,
601 RecordingState_Enabled = 2,
602 RecordingState_Paused = 3
603 };
604
605public:
606
607 /** Constructs indicator passing @a pMachine to the base-class. */
608 UIIndicatorRecording(UIMachine *pMachine)
609 : UISessionStateStatusBarIndicator(IndicatorType_Recording, pMachine)
610 , m_pAnimation(0)
611 , m_dRotationAngle(0)
612 {
613 /* Assign state-icons: */
614 setStateIcon(RecordingState_Unavailable, UIIconPool::iconSet(":/video_capture_disabled_16px.png"));
615 setStateIcon(RecordingState_Disabled, UIIconPool::iconSet(":/video_capture_16px.png"));
616 setStateIcon(RecordingState_Enabled, UIIconPool::iconSet(":/movie_reel_16px.png"));
617 setStateIcon(RecordingState_Paused, UIIconPool::iconSet(":/movie_reel_16px.png"));
618 /* Configure connection: */
619 connect(m_pMachine, &UIMachine::sigMachineStateChange,
620 this, &UIIndicatorRecording::updateAppearance);
621 connect(m_pMachine, &UIMachine::sigRecordingChange,
622 this, &UIIndicatorRecording::updateAppearance);
623 /* Create *enabled* state animation: */
624 m_pAnimation = UIAnimationLoop::installAnimationLoop(this, "rotationAngle",
625 "rotationAngleStart", "rotationAngleFinal",
626 1000);
627 /* Translate finally: */
628 retranslateUi();
629 }
630
631protected:
632
633 /** Handles paint @a pEvent. */
634 virtual void paintEvent(QPaintEvent *pEvent) RT_OVERRIDE
635 {
636 /* Call to base-class: */
637 UISessionStateStatusBarIndicator::paintEvent(pEvent);
638
639 /* Create new painter: */
640 QPainter painter(this);
641 /* Configure painter for *enabled* state: */
642 if (state() == RecordingState_Enabled)
643 {
644 /* Configure painter for smooth animation: */
645 painter.setRenderHint(QPainter::Antialiasing);
646 painter.setRenderHint(QPainter::SmoothPixmapTransform);
647 /* Shift rotation origin according pixmap center: */
648 painter.translate(height() / 2, height() / 2);
649 /* Rotate painter: */
650 painter.rotate(rotationAngle());
651 /* Unshift rotation origin according pixmap center: */
652 painter.translate(- height() / 2, - height() / 2);
653 }
654 /* Draw contents: */
655 drawContents(&painter);
656 }
657
658protected slots:
659
660 /** Update routine. */
661 virtual void updateAppearance() RT_OVERRIDE
662 {
663 QString strFullData;
664 bool fRecordingEnabled = false;
665 bool fMachinePaused = false;
666 m_pMachine->acquireRecordingStatusInfo(strFullData, fRecordingEnabled, fMachinePaused);
667
668 /* Update tool-tip: */
669 if (!strFullData.isEmpty())
670 setToolTip(s_strTable.arg(strFullData));
671 /* Set initial indicator state: */
672 RecordingState enmState = RecordingState_Unavailable;
673 if (m_pMachine->machineState() != KMachineState_Null)
674 {
675 if (!fRecordingEnabled)
676 enmState = RecordingState_Disabled;
677 else if (!fMachinePaused)
678 enmState = RecordingState_Enabled;
679 else
680 enmState = RecordingState_Paused;
681 }
682 setState(enmState);
683 }
684
685private slots:
686
687 /** Handles state change. */
688 void setState(int iState) RT_OVERRIDE
689 {
690 /* Update animation state: */
691 switch (iState)
692 {
693 case RecordingState_Disabled:
694 m_pAnimation->stop();
695 m_dRotationAngle = 0;
696 break;
697 case RecordingState_Enabled:
698 m_pAnimation->start();
699 break;
700 case RecordingState_Paused:
701 m_pAnimation->stop();
702 break;
703 default:
704 break;
705 }
706 /* Call to base-class: */
707 QIStateStatusBarIndicator::setState(iState);
708 }
709
710private:
711
712 /** Returns rotation start angle. */
713 double rotationAngleStart() const { return 0; }
714 /** Returns rotation finish angle. */
715 double rotationAngleFinal() const { return 360; }
716 /** Returns current rotation angle. */
717 double rotationAngle() const { return m_dRotationAngle; }
718 /** Defines current rotation angle. */
719 void setRotationAngle(double dRotationAngle) { m_dRotationAngle = dRotationAngle; update(); }
720
721 /** Holds the rotation animation instance. */
722 UIAnimationLoop *m_pAnimation;
723 /** Holds current rotation angle. */
724 double m_dRotationAngle;
725};
726
727
728/** UISessionStateStatusBarIndicator extension for Runtime UI: Features indicator. */
729class UIIndicatorFeatures : public UISessionStateStatusBarIndicator
730{
731 Q_OBJECT;
732
733public:
734
735 /** Constructs indicator passing @a pMachine to the base-class. */
736 UIIndicatorFeatures(UIMachine *pMachine)
737 : UISessionStateStatusBarIndicator(IndicatorType_Features, pMachine)
738 , m_uEffectiveCPULoad(0)
739 {
740 /* Assign state-icons: */
741 /** @todo The vtx_amdv_disabled_16px.png icon isn't really approprate anymore (no raw-mode),
742 * might want to get something different for KVMExecutionEngine_Emulated or reuse the
743 * vm_execution_engine_native_api_16px.png one... @bugref{9898} */
744 setStateIcon(KVMExecutionEngine_NotSet, UIIconPool::iconSet(":/vtx_amdv_disabled_16px.png"));
745 setStateIcon(KVMExecutionEngine_Interpreter, UIIconPool::iconSet(":/vtx_amdv_disabled_16px.png"));
746 setStateIcon(KVMExecutionEngine_Recompiler, UIIconPool::iconSet(":/vtx_amdv_disabled_16px.png"));
747 setStateIcon(KVMExecutionEngine_HwVirt, UIIconPool::iconSet(":/vtx_amdv_16px.png"));
748 setStateIcon(KVMExecutionEngine_NativeApi, UIIconPool::iconSet(":/vm_execution_engine_native_api_16px.png"));
749 /* Configure connection: */
750 connect(m_pMachine, &UIMachine::sigMachineStateChange,
751 this, &UIIndicatorFeatures::sltHandleMachineStateChange);
752 connect(m_pMachine, &UIMachine::sigInitialized,
753 this, &UIIndicatorFeatures::updateAppearance);
754 connect(m_pMachine, &UIMachine::sigCPUExecutionCapChange,
755 this, &UIIndicatorFeatures::updateAppearance);
756 /* Configure CPU load update timer: */
757 m_pTimerAutoUpdate = new QTimer(this);
758 if (m_pTimerAutoUpdate)
759 {
760 connect(m_pTimerAutoUpdate, &QTimer::timeout,
761 this, &UIIndicatorFeatures::sltHandleTimeout);
762 /* Start the timer immediately if the machine is running: */
763 sltHandleMachineStateChange();
764 }
765 /* Translate finally: */
766 retranslateUi();
767 }
768
769protected:
770
771 /** Handles paint @a pEvent. */
772 virtual void paintEvent(QPaintEvent *pEvent) RT_OVERRIDE
773 {
774 /* Call to base-class: */
775 UISessionStateStatusBarIndicator::paintEvent(pEvent);
776
777 /* Create new painter: */
778 QPainter painter(this);
779
780 /* Be a paranoid: */
781 ulong uCPU = qMin(m_uEffectiveCPULoad, static_cast<ulong>(100));
782
783 int iBorderThickness = 1;
784 /** Draw a black rectangle as background to the right hand side of 'this'.
785 * A smaller and colored rectangle will be drawn on top of this: **/
786 QPoint topLeftOut(0.76 * width() ,0);
787 QPoint bottomRightOut(width() - 1, height() - 1);
788 QRect outRect(topLeftOut, bottomRightOut);
789
790 painter.setPen(Qt::NoPen);
791 painter.setBrush(Qt::black);
792 painter.drawRect(outRect);
793
794 /* Draw a colored rectangle. Its color and height is dynamically computed from CPU usage: */
795 int inFullHeight = outRect.height() - 2 * iBorderThickness;
796 int inWidth = outRect.width() - 2 * iBorderThickness;
797 int inHeight = inFullHeight * uCPU / 100.;
798 QPoint topLeftIn(topLeftOut.x() + iBorderThickness,
799 topLeftOut.y() + iBorderThickness + (inFullHeight - inHeight));
800
801 QRect inRect(topLeftIn, QSize(inWidth, inHeight));
802 painter.setPen(Qt::NoPen);
803
804 /* Compute color as HSV: */
805 int iH = 120 * (1 - uCPU / 100.);
806 QColor fillColor;
807 fillColor.setHsv(iH, 255 /*saturation */, 255 /* value */);
808
809 painter.setBrush(fillColor);
810 painter.drawRect(inRect);
811 }
812
813protected slots:
814
815 /** Update routine. */
816 virtual void updateAppearance() RT_OVERRIDE
817 {
818 QString strFullData;
819 KVMExecutionEngine enmEngine = KVMExecutionEngine_NotSet;
820 m_pMachine->acquireFeaturesStatusInfo(strFullData, enmEngine);
821
822 /* Update tool-tip: */
823 if (!strFullData.isEmpty())
824 setToolTip(s_strTable.arg(strFullData));
825 /* Update indicator state: */
826 setState(enmEngine);
827 }
828
829private slots:
830
831 /** Updates auto-update timer depending on machine state. */
832 void sltHandleMachineStateChange()
833 {
834 /* Update appearance first of all: */
835 updateAppearance();
836
837 /* Start or stop CPU load update timer: */
838 if (m_pMachine->machineState() == KMachineState_Running)
839 m_pTimerAutoUpdate->start(1000);
840 else
841 m_pTimerAutoUpdate->stop();
842 }
843
844 /** Handles timer timeout with CPU load percentage update. */
845 void sltHandleTimeout()
846 {
847 m_pMachine->acquireEffectiveCPULoad(m_uEffectiveCPULoad);
848 update();
849 }
850
851private:
852
853 /** Holds the auto-update timer instance. */
854 QTimer *m_pTimerAutoUpdate;
855
856 /** Holds the effective CPU load. Expected to be in range [0, 100] */
857 ulong m_uEffectiveCPULoad;
858};
859
860
861/** UISessionStateStatusBarIndicator extension for Runtime UI: Mouse indicator. */
862class UIIndicatorMouse : public UISessionStateStatusBarIndicator
863{
864 Q_OBJECT;
865
866public:
867
868 /** Constructor, using @a pMachine for state-update routine. */
869 UIIndicatorMouse(UIMachine *pMachine)
870 : UISessionStateStatusBarIndicator(IndicatorType_Mouse, pMachine)
871 {
872 /* Assign state-icons: */
873 setStateIcon(0, UIIconPool::iconSet(":/mouse_disabled_16px.png"));
874 setStateIcon(1, UIIconPool::iconSet(":/mouse_16px.png"));
875 setStateIcon(2, UIIconPool::iconSet(":/mouse_seamless_16px.png"));
876 setStateIcon(3, UIIconPool::iconSet(":/mouse_can_seamless_16px.png"));
877 setStateIcon(4, UIIconPool::iconSet(":/mouse_can_seamless_uncaptured_16px.png"));
878 /* Configure connection: */
879 connect(m_pMachine, &UIMachine::sigMouseStateChange,
880 this, static_cast<void(UIIndicatorMouse::*)(int)>(&UIIndicatorMouse::setState)); // us to blame ..
881 /* Translate finally: */
882 retranslateUi();
883 }
884
885protected slots:
886
887 /** Update routine. */
888 virtual void updateAppearance() RT_OVERRIDE
889 {
890 const QString strToolTip = QApplication::translate("UIIndicatorsPool",
891 "Indicates whether the host mouse pointer is "
892 "captured by the guest OS:%1", "Mouse tooltip");
893 QString strFullData;
894 strFullData += s_strTableRow3
895 .arg(QString("<img src=:/mouse_disabled_16px.png/>"))
896 .arg(QApplication::translate("UIIndicatorsPool", "pointer is not captured", "Mouse tooltip"));
897 strFullData += s_strTableRow3
898 .arg(QString("<img src=:/mouse_16px.png/>"))
899 .arg(QApplication::translate("UIIndicatorsPool", "pointer is captured", "Mouse tooltip"));
900 strFullData += s_strTableRow3
901 .arg(QString("<img src=:/mouse_seamless_16px.png/>"))
902 .arg(QApplication::translate("UIIndicatorsPool", "mouse integration (MI) is On", "Mouse tooltip"));
903 strFullData += s_strTableRow3
904 .arg(QString("<img src=:/mouse_can_seamless_16px.png/>"))
905 .arg(QApplication::translate("UIIndicatorsPool", "MI is Off, pointer is captured", "Mouse tooltip"));
906 strFullData += s_strTableRow3
907 .arg(QString("<img src=:/mouse_can_seamless_uncaptured_16px.png/>"))
908 .arg(QApplication::translate("UIIndicatorsPool", "MI is Off, pointer is not captured", "Mouse tooltip"));
909 strFullData = s_strTable.arg(strFullData);
910 strFullData += QApplication::translate("UIIndicatorsPool",
911 "Note that the mouse integration feature requires Guest "
912 "Additions to be installed in the guest OS.", "Mouse tooltip");
913
914 /* Update tool-tip: */
915 setToolTip(strToolTip.arg(strFullData));
916 }
917
918private slots:
919
920 /** Handles state change. */
921 void setState(int iState) RT_OVERRIDE
922 {
923 if ((iState & UIMouseStateType_MouseAbsoluteDisabled) &&
924 (iState & UIMouseStateType_MouseAbsolute) &&
925 !(iState & UIMouseStateType_MouseCaptured))
926 {
927 QIStateStatusBarIndicator::setState(4);
928 }
929 else
930 {
931 QIStateStatusBarIndicator::setState(iState & (UIMouseStateType_MouseAbsolute | UIMouseStateType_MouseCaptured));
932 }
933 }
934};
935
936/** UISessionStateStatusBarIndicator extension for Runtime UI: Keyboard indicator. */
937class UIIndicatorKeyboard : public UISessionStateStatusBarIndicator
938{
939 Q_OBJECT;
940
941public:
942
943 /** Constructor, using @a pMachine for state-update routine. */
944 UIIndicatorKeyboard(UIMachine *pMachine)
945 : UISessionStateStatusBarIndicator(IndicatorType_Keyboard, pMachine)
946 {
947 /* Assign state-icons: */
948 setStateIcon(0, UIIconPool::iconSet(":/hostkey_disabled_16px.png"));
949 setStateIcon(1, UIIconPool::iconSet(":/hostkey_16px.png"));
950 setStateIcon(3, UIIconPool::iconSet(":/hostkey_captured_16px.png"));
951 setStateIcon(5, UIIconPool::iconSet(":/hostkey_pressed_16px.png"));
952 setStateIcon(7, UIIconPool::iconSet(":/hostkey_captured_pressed_16px.png"));
953 setStateIcon(9, UIIconPool::iconSet(":/hostkey_checked_16px.png"));
954 setStateIcon(11, UIIconPool::iconSet(":/hostkey_captured_checked_16px.png"));
955 setStateIcon(13, UIIconPool::iconSet(":/hostkey_pressed_checked_16px.png"));
956 setStateIcon(15, UIIconPool::iconSet(":/hostkey_captured_pressed_checked_16px.png"));
957 /* Configure connection: */
958 connect(m_pMachine, &UIMachine::sigKeyboardStateChange,
959 this, static_cast<void(UIIndicatorKeyboard::*)(int)>(&UIIndicatorKeyboard::setState)); // us to blame ..
960 /* Translate finally: */
961 retranslateUi();
962 }
963
964protected slots:
965
966 /** Update routine. */
967 virtual void updateAppearance() RT_OVERRIDE
968 {
969 const QString strToolTip = QApplication::translate("UIIndicatorsPool",
970 "Indicates whether the host keyboard is "
971 "captured by the guest OS:%1", "Keyboard tooltip");
972 QString strFullData;
973 strFullData += s_strTableRow3
974 .arg(QString("<img src=:/hostkey_16px.png/>"))
975 .arg(QApplication::translate("UIIndicatorsPool", "keyboard is not captured", "Keyboard tooltip"));
976 strFullData += s_strTableRow3
977 .arg(QString("<img src=:/hostkey_captured_16px.png/>"))
978 .arg(QApplication::translate("UIIndicatorsPool", "keyboard is captured", "Keyboard tooltip"));
979 strFullData = s_strTable.arg(strFullData);
980
981 /* Update tool-tip: */
982 setToolTip(strToolTip.arg(strFullData));
983 }
984};
985
986/** QITextStatusBarIndicator extension for Runtime UI: Keyboard-extension indicator. */
987class UIIndicatorKeyboardExtension : public QIWithRetranslateUI<QITextStatusBarIndicator>
988{
989 Q_OBJECT;
990
991public:
992
993 /** Constructor. */
994 UIIndicatorKeyboardExtension()
995 {
996 /* Make sure host-combination label will be updated: */
997 connect(gEDataManager, &UIExtraDataManager::sigRuntimeUIHostKeyCombinationChange,
998 this, &UIIndicatorKeyboardExtension::sltUpdateAppearance);
999 /* Translate finally: */
1000 retranslateUi();
1001 }
1002
1003public slots:
1004
1005 /** Update routine. */
1006 void sltUpdateAppearance()
1007 {
1008 setText(UIHostCombo::toReadableString(gEDataManager->hostKeyCombination()));
1009 }
1010
1011private:
1012
1013 /** Retranslation routine. */
1014 virtual void retranslateUi() RT_OVERRIDE
1015 {
1016 sltUpdateAppearance();
1017 setToolTip(QApplication::translate("UIMachineWindowNormal",
1018 "Shows the currently assigned Host key.<br>"
1019 "This key, when pressed alone, toggles the keyboard and mouse "
1020 "capture state. It can also be used in combination with other keys "
1021 "to quickly perform actions from the main menu."));
1022 }
1023};
1024
1025
1026UIIndicatorsPool::UIIndicatorsPool(UIMachine *pMachine, QWidget *pParent /* = 0 */)
1027 : QWidget(pParent)
1028 , m_pMachine(pMachine)
1029 , m_fEnabled(false)
1030 , m_pMainLayout(0)
1031 , m_pTimerAutoUpdate(0)
1032{
1033 prepare();
1034}
1035
1036UIIndicatorsPool::~UIIndicatorsPool()
1037{
1038 cleanup();
1039}
1040
1041void UIIndicatorsPool::updateAppearance(IndicatorType indicatorType)
1042{
1043 /* Skip missed indicators: */
1044 if (!m_pool.contains(indicatorType))
1045 return;
1046
1047 /* Get indicator: */
1048 QIStatusBarIndicator *pIndicator = m_pool.value(indicatorType);
1049
1050 /* Assert indicators with NO appearance: */
1051 UISessionStateStatusBarIndicator *pSessionStateIndicator =
1052 qobject_cast<UISessionStateStatusBarIndicator*>(pIndicator);
1053 AssertPtrReturnVoid(pSessionStateIndicator);
1054
1055 /* Update indicator appearance: */
1056 pSessionStateIndicator->updateAppearance();
1057}
1058
1059void UIIndicatorsPool::setAutoUpdateIndicatorStates(bool fEnabled)
1060{
1061 /* Make sure auto-update timer exists: */
1062 AssertPtrReturnVoid(m_pTimerAutoUpdate);
1063
1064 /* Start/stop timer: */
1065 if (fEnabled)
1066 m_pTimerAutoUpdate->start(100);
1067 else
1068 m_pTimerAutoUpdate->stop();
1069}
1070
1071QPoint UIIndicatorsPool::mapIndicatorPositionToGlobal(IndicatorType enmIndicatorType, const QPoint &indicatorPosition)
1072{
1073 if (m_pool.contains(enmIndicatorType))
1074 return m_pool.value(enmIndicatorType)->mapToGlobal(indicatorPosition);
1075 return QPoint(0, 0);
1076}
1077
1078void UIIndicatorsPool::sltHandleConfigurationChange(const QUuid &uMachineID)
1079{
1080 /* Skip unrelated machine IDs: */
1081 if (uiCommon().managedVMUuid() != uMachineID)
1082 return;
1083
1084 /* Update pool: */
1085 updatePool();
1086}
1087
1088void UIIndicatorsPool::sltAutoUpdateIndicatorStates()
1089{
1090 /* We should update states for following indicators: */
1091 QVector<KDeviceType> deviceTypes;
1092 if (m_pool.contains(IndicatorType_HardDisks))
1093 deviceTypes.append(KDeviceType_HardDisk);
1094 if (m_pool.contains(IndicatorType_OpticalDisks))
1095 deviceTypes.append(KDeviceType_DVD);
1096 if (m_pool.contains(IndicatorType_FloppyDisks))
1097 deviceTypes.append(KDeviceType_Floppy);
1098 if (m_pool.contains(IndicatorType_USB))
1099 deviceTypes.append(KDeviceType_USB);
1100 if (m_pool.contains(IndicatorType_Network))
1101 deviceTypes.append(KDeviceType_Network);
1102 if (m_pool.contains(IndicatorType_SharedFolders))
1103 deviceTypes.append(KDeviceType_SharedFolder);
1104 if (m_pool.contains(IndicatorType_Display))
1105 deviceTypes.append(KDeviceType_Graphics3D);
1106
1107 /* Acquire current device states from the machine: */
1108 QVector<KDeviceActivity> states;
1109 m_pMachine->acquireDeviceActivity(deviceTypes, states);
1110
1111 /* Update indicators with the acquired states: */
1112 for (int iIndicator = 0; iIndicator < states.size(); ++iIndicator)
1113 {
1114 QIStatusBarIndicator *pIndicator = 0;
1115 switch (deviceTypes[iIndicator])
1116 {
1117 case KDeviceType_HardDisk: pIndicator = m_pool.value(IndicatorType_HardDisks); break;
1118 case KDeviceType_DVD: pIndicator = m_pool.value(IndicatorType_OpticalDisks); break;
1119 case KDeviceType_Floppy: pIndicator = m_pool.value(IndicatorType_FloppyDisks); break;
1120 case KDeviceType_USB: pIndicator = m_pool.value(IndicatorType_USB); break;
1121 case KDeviceType_Network: pIndicator = m_pool.value(IndicatorType_Network); break;
1122 case KDeviceType_SharedFolder: pIndicator = m_pool.value(IndicatorType_SharedFolders); break;
1123 case KDeviceType_Graphics3D: pIndicator = m_pool.value(IndicatorType_Display); break;
1124 default: AssertFailed(); break;
1125 }
1126 if (pIndicator)
1127 updateIndicatorStateForDevice(pIndicator, states[iIndicator]);
1128 }
1129}
1130
1131void UIIndicatorsPool::sltContextMenuRequest(QIStatusBarIndicator *pIndicator, QContextMenuEvent *pEvent)
1132{
1133 /* If that is one of pool indicators: */
1134 foreach (IndicatorType indicatorType, m_pool.keys())
1135 if (m_pool[indicatorType] == pIndicator)
1136 {
1137 /* Notify listener: */
1138 emit sigContextMenuRequest(indicatorType, pEvent->pos());
1139 return;
1140 }
1141}
1142
1143void UIIndicatorsPool::prepare()
1144{
1145 /* Prepare connections: */
1146 prepareConnections();
1147 /* Prepare contents: */
1148 prepareContents();
1149 /* Prepare auto-update timer: */
1150 prepareUpdateTimer();
1151}
1152
1153void UIIndicatorsPool::prepareConnections()
1154{
1155 /* Listen for the status-bar configuration changes: */
1156 connect(gEDataManager, &UIExtraDataManager::sigStatusBarConfigurationChange,
1157 this, &UIIndicatorsPool::sltHandleConfigurationChange);
1158}
1159
1160void UIIndicatorsPool::prepareContents()
1161{
1162 /* Create main-layout: */
1163 m_pMainLayout = new QHBoxLayout(this);
1164 AssertPtrReturnVoid(m_pMainLayout);
1165 {
1166 /* Configure main-layout: */
1167 m_pMainLayout->setContentsMargins(0, 0, 0, 0);
1168#ifdef VBOX_WS_MAC
1169 m_pMainLayout->setSpacing(5);
1170#else
1171 m_pMainLayout->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing) / 2);
1172#endif
1173 /* Update pool: */
1174 updatePool();
1175 }
1176}
1177
1178void UIIndicatorsPool::prepareUpdateTimer()
1179{
1180 /* Create auto-update timer: */
1181 m_pTimerAutoUpdate = new QTimer(this);
1182 AssertPtrReturnVoid(m_pTimerAutoUpdate);
1183 {
1184 /* Configure auto-update timer: */
1185 connect(m_pTimerAutoUpdate, &QTimer::timeout,
1186 this, &UIIndicatorsPool::sltAutoUpdateIndicatorStates);
1187 setAutoUpdateIndicatorStates(true);
1188 }
1189}
1190
1191void UIIndicatorsPool::updatePool()
1192{
1193 /* Acquire status-bar availability: */
1194 m_fEnabled = gEDataManager->statusBarEnabled(uiCommon().managedVMUuid());
1195 /* If status-bar is not enabled: */
1196 if (!m_fEnabled)
1197 {
1198 /* Remove all indicators: */
1199 while (!m_pool.isEmpty())
1200 {
1201 const IndicatorType firstType = m_pool.keys().first();
1202 delete m_pool.value(firstType);
1203 m_pool.remove(firstType);
1204 }
1205 /* And return: */
1206 return;
1207 }
1208
1209 /* Acquire status-bar restrictions: */
1210 m_restrictions = gEDataManager->restrictedStatusBarIndicators(uiCommon().managedVMUuid());
1211 /* Make sure 'Recording' is restricted as well if no features supported: */
1212 if ( !m_restrictions.contains(IndicatorType_Recording)
1213 && !uiCommon().supportedRecordingFeatures())
1214 m_restrictions << IndicatorType_Recording;
1215
1216 /* Remove restricted indicators: */
1217 foreach (const IndicatorType &indicatorType, m_restrictions)
1218 {
1219 if (m_pool.contains(indicatorType))
1220 {
1221 delete m_pool.value(indicatorType);
1222 m_pool.remove(indicatorType);
1223 }
1224 }
1225
1226 /* Acquire status-bar order: */
1227 m_order = gEDataManager->statusBarIndicatorOrder(uiCommon().managedVMUuid());
1228 /* Make sure the order is complete taking restrictions into account: */
1229 for (int iType = IndicatorType_Invalid; iType < IndicatorType_Max; ++iType)
1230 {
1231 /* Get iterated type: */
1232 IndicatorType type = (IndicatorType)iType;
1233 /* Skip invalid type: */
1234 if (type == IndicatorType_Invalid)
1235 continue;
1236 /* Take restriction/presence into account: */
1237 bool fRestricted = m_restrictions.contains(type);
1238 bool fPresent = m_order.contains(type);
1239 if (fRestricted && fPresent)
1240 m_order.removeAll(type);
1241 else if (!fRestricted && !fPresent)
1242 m_order << type;
1243 }
1244
1245 /* Add/Update allowed indicators: */
1246 foreach (const IndicatorType &indicatorType, m_order)
1247 {
1248 /* Indicator exists: */
1249 if (m_pool.contains(indicatorType))
1250 {
1251 /* Get indicator: */
1252 QIStatusBarIndicator *pIndicator = m_pool.value(indicatorType);
1253 /* Make sure it have valid position: */
1254 const int iWantedIndex = indicatorPosition(indicatorType);
1255 const int iActualIndex = m_pMainLayout->indexOf(pIndicator);
1256 if (iActualIndex != iWantedIndex)
1257 {
1258 /* Re-inject indicator into main-layout at proper position: */
1259 m_pMainLayout->removeWidget(pIndicator);
1260 m_pMainLayout->insertWidget(iWantedIndex, pIndicator);
1261 }
1262 }
1263 /* Indicator missed: */
1264 else
1265 {
1266 /* Create indicator: */
1267 switch (indicatorType)
1268 {
1269 case IndicatorType_HardDisks: m_pool[indicatorType] = new UIIndicatorHardDrive(m_pMachine); break;
1270 case IndicatorType_OpticalDisks: m_pool[indicatorType] = new UIIndicatorOpticalDisks(m_pMachine); break;
1271 case IndicatorType_FloppyDisks: m_pool[indicatorType] = new UIIndicatorFloppyDisks(m_pMachine); break;
1272 case IndicatorType_Audio: m_pool[indicatorType] = new UIIndicatorAudio(m_pMachine); break;
1273 case IndicatorType_Network: m_pool[indicatorType] = new UIIndicatorNetwork(m_pMachine); break;
1274 case IndicatorType_USB: m_pool[indicatorType] = new UIIndicatorUSB(m_pMachine); break;
1275 case IndicatorType_SharedFolders: m_pool[indicatorType] = new UIIndicatorSharedFolders(m_pMachine); break;
1276 case IndicatorType_Display: m_pool[indicatorType] = new UIIndicatorDisplay(m_pMachine); break;
1277 case IndicatorType_Recording: m_pool[indicatorType] = new UIIndicatorRecording(m_pMachine); break;
1278 case IndicatorType_Features: m_pool[indicatorType] = new UIIndicatorFeatures(m_pMachine); break;
1279 case IndicatorType_Mouse: m_pool[indicatorType] = new UIIndicatorMouse(m_pMachine); break;
1280 case IndicatorType_Keyboard: m_pool[indicatorType] = new UIIndicatorKeyboard(m_pMachine); break;
1281 case IndicatorType_KeyboardExtension: m_pool[indicatorType] = new UIIndicatorKeyboardExtension; break;
1282 default: break;
1283 }
1284 /* Configure indicator: */
1285 connect(m_pool.value(indicatorType), &QIStatusBarIndicator::sigContextMenuRequest,
1286 this, &UIIndicatorsPool::sltContextMenuRequest);
1287 /* Insert indicator into main-layout at proper position: */
1288 m_pMainLayout->insertWidget(indicatorPosition(indicatorType), m_pool.value(indicatorType));
1289 }
1290 }
1291}
1292
1293void UIIndicatorsPool::cleanupUpdateTimer()
1294{
1295 /* Destroy auto-update timer: */
1296 AssertPtrReturnVoid(m_pTimerAutoUpdate);
1297 {
1298 m_pTimerAutoUpdate->stop();
1299 delete m_pTimerAutoUpdate;
1300 m_pTimerAutoUpdate = 0;
1301 }
1302}
1303
1304void UIIndicatorsPool::cleanupContents()
1305{
1306 /* Cleanup indicators: */
1307 while (!m_pool.isEmpty())
1308 {
1309 const IndicatorType firstType = m_pool.keys().first();
1310 delete m_pool.value(firstType);
1311 m_pool.remove(firstType);
1312 }
1313}
1314
1315void UIIndicatorsPool::cleanup()
1316{
1317 /* Cleanup auto-update timer: */
1318 cleanupUpdateTimer();
1319 /* Cleanup indicators: */
1320 cleanupContents();
1321}
1322
1323void UIIndicatorsPool::contextMenuEvent(QContextMenuEvent *pEvent)
1324{
1325 /* Do not pass-through context menu events,
1326 * otherwise they will raise the underlying status-bar context-menu. */
1327 pEvent->accept();
1328}
1329
1330int UIIndicatorsPool::indicatorPosition(IndicatorType indicatorType) const
1331{
1332 int iPosition = 0;
1333 foreach (const IndicatorType &iteratedIndicatorType, m_order)
1334 if (iteratedIndicatorType == indicatorType)
1335 return iPosition;
1336 else
1337 ++iPosition;
1338 return iPosition;
1339}
1340
1341void UIIndicatorsPool::updateIndicatorStateForDevice(QIStatusBarIndicator *pIndicator, KDeviceActivity enmState)
1342{
1343 /* Assert indicators with NO state: */
1344 QIStateStatusBarIndicator *pStateIndicator = qobject_cast<QIStateStatusBarIndicator*>(pIndicator);
1345 AssertPtrReturnVoid(pStateIndicator);
1346
1347 /* Skip indicators with NULL state: */
1348 if (pStateIndicator->state() == KDeviceActivity_Null)
1349 return;
1350
1351 /* Paused VM have all indicator states set to IDLE: */
1352 if (m_pMachine->isPaused())
1353 {
1354 /* If current state differs from IDLE => set the IDLE one: */
1355 if (pStateIndicator->state() != KDeviceActivity_Idle)
1356 pStateIndicator->setState(KDeviceActivity_Idle);
1357 }
1358 else
1359 {
1360 /* If current state differs from actual => set the actual one: */
1361 if (pStateIndicator->state() != enmState)
1362 pStateIndicator->setState(enmState);
1363 }
1364}
1365
1366#include "UIIndicatorsPool.moc"
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette