VirtualBox

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

Last change on this file was 105804, checked in by vboxsync, 7 weeks ago

FE/Qt: Host Key Combo: Sync NLS across whole the GUI to mention key combo, not just single key.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 66.4 KB
Line 
1/* $Id: UIIndicatorsPool.cpp 105804 2024-08-21 22:51:31Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIIndicatorsPool class implementation.
4 */
5
6/*
7 * Copyright (C) 2010-2024 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 <QApplication>
30#include <QAccessibleWidget>
31#include <QHBoxLayout>
32#include <QPainter>
33#include <QRegularExpression>
34#include <QStyle>
35#include <QTimer>
36
37/* GUI includes: */
38#include "QIStatusBarIndicator.h"
39#include "UIAnimationFramework.h"
40#include "UICommon.h"
41#include "UIConverter.h"
42#include "UIExtraDataManager.h"
43#include "UIGlobalSession.h"
44#include "UIHostComboEditor.h"
45#include "UIIconPool.h"
46#include "UIIndicatorsPool.h"
47#include "UIMachine.h"
48#include "UITranslationEventListener.h"
49
50/* Other VBox includes: */
51#include "iprt/assert.h"
52
53
54/** QIStateStatusBarIndicator extension for Runtime UI. */
55class UISessionStateStatusBarIndicator : public QIStateStatusBarIndicator
56{
57 Q_OBJECT;
58
59public:
60
61 /** Constructor which remembers passed @a session object. */
62 UISessionStateStatusBarIndicator(IndicatorType enmType, UIMachine *pMachine);
63
64 /** Returns the indicator type. */
65 IndicatorType type() const { return m_enmType; }
66
67 /** Returns the indicator description. */
68 virtual QString description() const { return m_strDescription; }
69
70public slots:
71
72 /** Abstract update routine. */
73 virtual void updateAppearance() = 0;
74
75protected slots:
76
77 /** Handles translation event. */
78 virtual void sltRetranslateUI();
79
80protected:
81
82 /** Holds the indicator type. */
83 const IndicatorType m_enmType;
84
85 /** Holds the machine UI reference. */
86 UIMachine *m_pMachine;
87
88 /** Holds the indicator description. */
89 QString m_strDescription;
90
91 /** Holds the table format. */
92 static const QString s_strTable;
93 /** Holds the table row format 1. */
94 static const QString s_strTableRow1;
95 /** Holds the table row format 2. */
96 static const QString s_strTableRow2;
97 /** Holds the table row format 3. */
98 static const QString s_strTableRow3;
99 /** Holds the table row format 4. */
100 static const QString s_strTableRow4;
101};
102
103
104/** QAccessibleWidget extension used as an accessibility interface for UISessionStateStatusBarIndicator. */
105class QIAccessibilityInterfaceForUISessionStateStatusBarIndicator : public QAccessibleWidget
106{
107public:
108
109 /** Returns an accessibility interface for passed @a strClassname and @a pObject. */
110 static QAccessibleInterface *pFactory(const QString &strClassname, QObject *pObject)
111 {
112 /* Creating UISessionStateStatusBarIndicator accessibility interface: */
113 if (pObject && strClassname == QLatin1String("UISessionStateStatusBarIndicator"))
114 return new QIAccessibilityInterfaceForUISessionStateStatusBarIndicator(qobject_cast<QWidget*>(pObject));
115
116 /* Null by default: */
117 return 0;
118 }
119
120 /** Constructs an accessibility interface passing @a pWidget to the base-class. */
121 QIAccessibilityInterfaceForUISessionStateStatusBarIndicator(QWidget *pWidget)
122 : QAccessibleWidget(pWidget, QAccessible::Button)
123 {}
124
125 /** Returns a text for the passed @a enmTextRole. */
126 virtual QString text(QAccessible::Text /* enmTextRole */) const RT_OVERRIDE
127 {
128 /* Sanity check: */
129 AssertPtrReturn(indicator(), 0);
130
131 /* Return the indicator description: */
132 return indicator()->description();
133 }
134
135private:
136
137 /** Returns corresponding UISessionStateStatusBarIndicator. */
138 UISessionStateStatusBarIndicator *indicator() const { return qobject_cast<UISessionStateStatusBarIndicator*>(widget()); }
139};
140
141
142/* static */
143const QString UISessionStateStatusBarIndicator::s_strTable = QString("<table cellspacing=5 style='white-space:pre'>%1</table>");
144/* static */
145const QString UISessionStateStatusBarIndicator::s_strTableRow1 = QString("<tr><td colspan='2'><nobr><b>%1</b></nobr></td></tr>");
146/* static */
147const QString UISessionStateStatusBarIndicator::s_strTableRow2 = QString("<tr><td><nobr>%1:</nobr></td><td><nobr>%2</nobr></td></tr>");
148/* static */
149const QString UISessionStateStatusBarIndicator::s_strTableRow3 = QString("<tr><td><nobr>%1</nobr></td><td><nobr>%2</nobr></td></tr>");
150/* static */
151const QString UISessionStateStatusBarIndicator::s_strTableRow4 = QString("<tr><td><nobr>&nbsp;%1:</nobr></td><td><nobr>%2</nobr></td></tr>");
152
153
154UISessionStateStatusBarIndicator::UISessionStateStatusBarIndicator(IndicatorType enmType, UIMachine *pMachine)
155 : m_enmType(enmType)
156 , m_pMachine(pMachine)
157{
158 /* Install UISessionStateStatusBarIndicator accessibility interface factory: */
159 QAccessible::installFactory(QIAccessibilityInterfaceForUISessionStateStatusBarIndicator::pFactory);
160 connect(&translationEventListener(), &UITranslationEventListener::sigRetranslateUI,
161 this, &UISessionStateStatusBarIndicator::sltRetranslateUI);
162}
163
164void UISessionStateStatusBarIndicator::sltRetranslateUI()
165{
166 /* Translate description: */
167 m_strDescription = tr("%1 status-bar indicator", "like 'hard-disk status-bar indicator'")
168 .arg(gpConverter->toString(type()));
169}
170
171
172/** QITextStatusBarIndicator extension for Runtime UI. */
173class UISessionTextStatusBarIndicator : public QITextStatusBarIndicator
174{
175 Q_OBJECT;
176
177public:
178
179 /** Constructor which remembers passed @a session object. */
180 UISessionTextStatusBarIndicator(IndicatorType enmType);
181
182 /** Returns the indicator type. */
183 IndicatorType type() const { return m_enmType; }
184
185 /** Returns the indicator description. */
186 virtual QString description() const { return m_strDescription; }
187
188public slots:
189
190 /** Abstract update routine. */
191 virtual void updateAppearance() = 0;
192
193protected slots:
194
195 /** Handles translation event. */
196 virtual void sltRetranslateUI();
197
198protected:
199
200 /** Holds the indicator type. */
201 const IndicatorType m_enmType;
202
203 /** Holds the indicator description. */
204 QString m_strDescription;
205};
206
207
208/** QAccessibleWidget extension used as an accessibility interface for UISessionTextStatusBarIndicator. */
209class QIAccessibilityInterfaceForUISessionTextStatusBarIndicator : public QAccessibleWidget
210{
211public:
212
213 /** Returns an accessibility interface for passed @a strClassname and @a pObject. */
214 static QAccessibleInterface *pFactory(const QString &strClassname, QObject *pObject)
215 {
216 /* Creating UISessionTextStatusBarIndicator accessibility interface: */
217 if (pObject && strClassname == QLatin1String("UISessionTextStatusBarIndicator"))
218 return new QIAccessibilityInterfaceForUISessionTextStatusBarIndicator(qobject_cast<QWidget*>(pObject));
219
220 /* Null by default: */
221 return 0;
222 }
223
224 /** Constructs an accessibility interface passing @a pWidget to the base-class. */
225 QIAccessibilityInterfaceForUISessionTextStatusBarIndicator(QWidget *pWidget)
226 : QAccessibleWidget(pWidget, QAccessible::Button)
227 {}
228
229 /** Returns a text for the passed @a enmTextRole. */
230 virtual QString text(QAccessible::Text /* enmTextRole */) const RT_OVERRIDE
231 {
232 /* Sanity check: */
233 AssertPtrReturn(indicator(), 0);
234
235 /* Return the indicator description: */
236 return indicator()->description();
237 }
238
239private:
240
241 /** Returns corresponding UISessionTextStatusBarIndicator. */
242 UISessionTextStatusBarIndicator *indicator() const { return qobject_cast<UISessionTextStatusBarIndicator*>(widget()); }
243};
244
245
246UISessionTextStatusBarIndicator::UISessionTextStatusBarIndicator(IndicatorType enmType)
247 : m_enmType(enmType)
248{
249 /* Install UISessionTextStatusBarIndicator accessibility interface factory: */
250 QAccessible::installFactory(QIAccessibilityInterfaceForUISessionTextStatusBarIndicator::pFactory);
251 connect(&translationEventListener(), &UITranslationEventListener::sigRetranslateUI,
252 this, &UISessionTextStatusBarIndicator::sltRetranslateUI);
253}
254
255void UISessionTextStatusBarIndicator::sltRetranslateUI()
256{
257 /* Translate description: */
258 m_strDescription = tr("%1 status-bar indicator", "like 'hard-disk status-bar indicator'")
259 .arg(gpConverter->toString(type()));
260}
261
262
263/** UISessionStateStatusBarIndicator extension for Runtime UI: Hard-drive indicator. */
264class UIIndicatorHardDrive : public UISessionStateStatusBarIndicator
265{
266 Q_OBJECT;
267
268public:
269
270 /** Constructs indicator passing @a pMachine to the base-class. */
271 UIIndicatorHardDrive(UIMachine *pMachine)
272 : UISessionStateStatusBarIndicator(IndicatorType_HardDisks, pMachine)
273 , m_cAttachmentsCount(0)
274 {
275 /* Assign state-icons: */
276 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/hd_16px.png"));
277 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/hd_read_16px.png"));
278 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/hd_write_16px.png"));
279 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/hd_disabled_16px.png"));
280 /* Configure connection: */
281 connect(m_pMachine, &UIMachine::sigMachineStateChange,
282 this, &UIIndicatorHardDrive::updateAppearance);
283 connect(m_pMachine, &UIMachine::sigStorageDeviceChange,
284 this, &UIIndicatorHardDrive::updateAppearance);
285 connect(m_pMachine, &UIMachine::sigMediumChange,
286 this, &UIIndicatorHardDrive::updateAppearance);
287 /* Update & translate finally: */
288 updateAppearance();
289 }
290
291protected slots:
292
293 /** Update routine. */
294 virtual void updateAppearance() RT_OVERRIDE
295 {
296 /* Acquire data: */
297 QString strFullData;
298 m_cAttachmentsCount = 0;
299 m_pMachine->acquireHardDiskStatusInfo(strFullData, m_cAttachmentsCount);
300
301 /* Show/hide indicator if there are no attachments
302 * and parent is visible already: */
303 if ( parentWidget()
304 && parentWidget()->isVisible())
305 setVisible(m_cAttachmentsCount);
306
307 /* Update tool-tip: */
308 if (!strFullData.isEmpty())
309 setToolTip(s_strTable.arg(strFullData));
310 /* Update indicator state: */
311 setState(m_cAttachmentsCount ? KDeviceActivity_Idle : KDeviceActivity_Null);
312
313 /* Retranslate finally: */
314 sltRetranslateUI();
315 }
316
317 /** Handles translation event. */
318 virtual void sltRetranslateUI() RT_OVERRIDE
319 {
320 /* Call to base-class: */
321 UISessionStateStatusBarIndicator::sltRetranslateUI();
322
323 /* Append description with more info: */
324 const QString strAttachmentStatus = tr("%1 disks attached").arg(m_cAttachmentsCount);
325 m_strDescription = QString("%1, %2").arg(m_strDescription, strAttachmentStatus);
326 }
327
328private:
329
330 /** Holds the last cached attachment count. */
331 uint m_cAttachmentsCount;
332};
333
334
335/** UISessionStateStatusBarIndicator extension for Runtime UI: Optical-drive indicator. */
336class UIIndicatorOpticalDisks : public UISessionStateStatusBarIndicator
337{
338 Q_OBJECT;
339
340public:
341
342 /** Constructs indicator passing @a pMachine to the base-class. */
343 UIIndicatorOpticalDisks(UIMachine *pMachine)
344 : UISessionStateStatusBarIndicator(IndicatorType_OpticalDisks, pMachine)
345 , m_cAttachmentsCount(0)
346 , m_cAttachmentsMountedCount(0)
347 {
348 /* Assign state-icons: */
349 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/cd_16px.png"));
350 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/cd_read_16px.png"));
351 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/cd_write_16px.png"));
352 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/cd_disabled_16px.png"));
353 /* Configure connection: */
354 connect(m_pMachine, &UIMachine::sigMachineStateChange,
355 this, &UIIndicatorOpticalDisks::updateAppearance);
356 connect(m_pMachine, &UIMachine::sigStorageDeviceChange,
357 this, &UIIndicatorOpticalDisks::updateAppearance);
358 connect(m_pMachine, &UIMachine::sigMediumChange,
359 this, &UIIndicatorOpticalDisks::updateAppearance);
360 /* Update & translate finally: */
361 updateAppearance();
362 }
363
364protected slots:
365
366 /** Update routine. */
367 virtual void updateAppearance() RT_OVERRIDE
368 {
369 QString strFullData;
370 m_cAttachmentsCount = 0;
371 m_cAttachmentsMountedCount = 0;
372 m_pMachine->acquireOpticalDiskStatusInfo(strFullData, m_cAttachmentsCount, m_cAttachmentsMountedCount);
373
374 /* Show/hide indicator if there are no attachments
375 * and parent is visible already: */
376 if ( parentWidget()
377 && parentWidget()->isVisible())
378 setVisible(m_cAttachmentsCount);
379
380 /* Update tool-tip: */
381 if (!strFullData.isEmpty())
382 setToolTip(s_strTable.arg(strFullData));
383 /* Update indicator state: */
384 setState(m_cAttachmentsMountedCount ? KDeviceActivity_Idle : KDeviceActivity_Null);
385
386 /* Retranslate finally: */
387 sltRetranslateUI();
388 }
389
390 /** Handles translation event. */
391 virtual void sltRetranslateUI() RT_OVERRIDE
392 {
393 /* Call to base-class: */
394 UISessionStateStatusBarIndicator::sltRetranslateUI();
395
396 /* Append description with more info: */
397 const QString strAttachmentStatus = tr("%1 drives attached").arg(m_cAttachmentsCount);
398 const QString strMountingStatus = tr("%1 images mounted").arg(m_cAttachmentsMountedCount);
399 m_strDescription = QString("%1, %2, %3").arg(m_strDescription, strAttachmentStatus, strMountingStatus);
400 }
401
402private:
403
404 /** Holds the last cached attachment count. */
405 uint m_cAttachmentsCount;
406 /** Holds the last cached mounted attachment count. */
407 uint m_cAttachmentsMountedCount;
408};
409
410
411/** UISessionStateStatusBarIndicator extension for Runtime UI: Floppy-drive indicator. */
412class UIIndicatorFloppyDisks : public UISessionStateStatusBarIndicator
413{
414 Q_OBJECT;
415
416public:
417
418 /** Constructs indicator passing @a pMachine to the base-class. */
419 UIIndicatorFloppyDisks(UIMachine *pMachine)
420 : UISessionStateStatusBarIndicator(IndicatorType_FloppyDisks, pMachine)
421 , m_cAttachmentsCount(0)
422 , m_cAttachmentsMountedCount(0)
423 {
424 /* Assign state-icons: */
425 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/fd_16px.png"));
426 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/fd_read_16px.png"));
427 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/fd_write_16px.png"));
428 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/fd_disabled_16px.png"));
429 /* Configure connection: */
430 connect(m_pMachine, &UIMachine::sigMachineStateChange,
431 this, &UIIndicatorFloppyDisks::updateAppearance);
432 connect(m_pMachine, &UIMachine::sigStorageDeviceChange,
433 this, &UIIndicatorFloppyDisks::updateAppearance);
434 connect(m_pMachine, &UIMachine::sigMediumChange,
435 this, &UIIndicatorFloppyDisks::updateAppearance);
436 /* Update & translate finally: */
437 updateAppearance();
438 }
439
440protected slots:
441
442 /** Update routine. */
443 virtual void updateAppearance() RT_OVERRIDE
444 {
445 QString strFullData;
446 m_cAttachmentsCount = 0;
447 m_cAttachmentsMountedCount = 0;
448 m_pMachine->acquireFloppyDiskStatusInfo(strFullData, m_cAttachmentsCount, m_cAttachmentsMountedCount);
449
450 /* Show/hide indicator if there are no attachments
451 * and parent is visible already: */
452 if ( parentWidget()
453 && parentWidget()->isVisible())
454 setVisible(m_cAttachmentsCount);
455
456 /* Update tool-tip: */
457 if (!strFullData.isEmpty())
458 setToolTip(s_strTable.arg(strFullData));
459 /* Update indicator state: */
460 setState(m_cAttachmentsMountedCount ? KDeviceActivity_Idle : KDeviceActivity_Null);
461
462 /* Retranslate finally: */
463 sltRetranslateUI();
464 }
465
466 /** Handles translation event. */
467 virtual void sltRetranslateUI() RT_OVERRIDE
468 {
469 /* Call to base-class: */
470 UISessionStateStatusBarIndicator::sltRetranslateUI();
471
472 /* Append description with more info: */
473 const QString strAttachmentStatus = tr("%1 drives attached").arg(m_cAttachmentsCount);
474 const QString strMountingStatus = tr("%1 images mounted").arg(m_cAttachmentsMountedCount);
475 m_strDescription = QString("%1, %2, %3").arg(m_strDescription, strAttachmentStatus, strMountingStatus);
476 }
477
478private:
479
480 /** Holds the last cached attachment count. */
481 uint m_cAttachmentsCount;
482 /** Holds the last cached mounted attachment count. */
483 uint m_cAttachmentsMountedCount;
484};
485
486
487/** UISessionStateStatusBarIndicator extension for Runtime UI: Audio indicator. */
488class UIIndicatorAudio : public UISessionStateStatusBarIndicator
489{
490 Q_OBJECT;
491
492public:
493
494 /** Audio states. */
495 enum AudioState
496 {
497 AudioState_AllOff = 0,
498 AudioState_OutputOn = RT_BIT(0),
499 AudioState_InputOn = RT_BIT(1),
500 AudioState_AllOn = AudioState_InputOn | AudioState_OutputOn
501 };
502
503 /** Constructs indicator passing @a pMachine to the base-class. */
504 UIIndicatorAudio(UIMachine *pMachine)
505 : UISessionStateStatusBarIndicator(IndicatorType_Audio, pMachine)
506 , m_fOutputEnabled(false)
507 , m_fInputEnabled(false)
508 {
509 /* Assign state-icons: */
510 setStateIcon(AudioState_AllOff, UIIconPool::iconSet(":/audio_all_off_16px.png"));
511 setStateIcon(AudioState_OutputOn, UIIconPool::iconSet(":/audio_input_off_16px.png"));
512 setStateIcon(AudioState_InputOn, UIIconPool::iconSet(":/audio_output_off_16px.png"));
513 setStateIcon(AudioState_AllOn, UIIconPool::iconSet(":/audio_16px.png"));
514 /* Configure connection: */
515 connect(m_pMachine, &UIMachine::sigMachineStateChange,
516 this, &UIIndicatorAudio::updateAppearance);
517 connect(m_pMachine, &UIMachine::sigInitialized,
518 this, &UIIndicatorAudio::updateAppearance);
519 connect(m_pMachine, &UIMachine::sigAudioAdapterChange,
520 this, &UIIndicatorAudio::updateAppearance);
521 /* Update & translate finally: */
522 updateAppearance();
523 }
524
525protected slots:
526
527 /** Update routine. */
528 virtual void updateAppearance() RT_OVERRIDE
529 {
530 QString strFullData;
531 bool fAudioEnabled = false;
532 m_fOutputEnabled = false;
533 m_fInputEnabled = false;
534 m_pMachine->acquireAudioStatusInfo(strFullData, fAudioEnabled, m_fOutputEnabled, m_fInputEnabled);
535
536 /* Show/hide indicator if there are no attachments
537 * and parent is visible already: */
538 if ( parentWidget()
539 && parentWidget()->isVisible())
540 setVisible(fAudioEnabled);
541
542 /* Update tool-tip: */
543 if (!strFullData.isEmpty())
544 setToolTip(s_strTable.arg(strFullData));
545 /* Update indicator state: */
546 AudioState enmState = AudioState_AllOff;
547 if (m_fOutputEnabled)
548 enmState = (AudioState)(enmState | AudioState_OutputOn);
549 if (m_fInputEnabled)
550 enmState = (AudioState)(enmState | AudioState_InputOn);
551 setState(enmState);
552
553 /* Retranslate finally: */
554 sltRetranslateUI();
555 }
556
557 /** Handles translation event. */
558 virtual void sltRetranslateUI() RT_OVERRIDE
559 {
560 /* Call to base-class: */
561 UISessionStateStatusBarIndicator::sltRetranslateUI();
562
563 /* Append description with more info: */
564 const QString strOutputStatus = m_fOutputEnabled ? tr("Output enabled") : tr("Output disabled");
565 const QString strInputStatus = m_fInputEnabled ? tr("Input enabled") : tr("Input disabled");
566 m_strDescription = QString("%1, %2, %3").arg(m_strDescription, strOutputStatus, strInputStatus);
567 }
568
569private:
570
571 /** Holds whether audio output enabled. */
572 bool m_fOutputEnabled;
573 /** Holds whether audio input enabled. */
574 bool m_fInputEnabled;
575};
576
577
578/** UISessionStateStatusBarIndicator extension for Runtime UI: Network indicator. */
579class UIIndicatorNetwork : public UISessionStateStatusBarIndicator
580{
581 Q_OBJECT;
582
583public:
584
585 /** Constructs indicator passing @a pMachine to the base-class. */
586 UIIndicatorNetwork(UIMachine *pMachine)
587 : UISessionStateStatusBarIndicator(IndicatorType_Network, pMachine)
588 , m_fAdaptersPresent(false)
589 , m_fCablesDisconnected(true)
590 {
591 /* Assign state-icons: */
592 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/nw_16px.png"));
593 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/nw_read_16px.png"));
594 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/nw_write_16px.png"));
595 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/nw_disabled_16px.png"));
596 /* Configure connection: */
597 connect(m_pMachine, &UIMachine::sigMachineStateChange,
598 this, &UIIndicatorNetwork::updateAppearance);
599 connect(m_pMachine, &UIMachine::sigNetworkAdapterChange,
600 this, &UIIndicatorNetwork::updateAppearance);
601 /* Update & translate finally: */
602 updateAppearance();
603 }
604
605protected slots:
606
607 /** Update routine. */
608 virtual void updateAppearance() RT_OVERRIDE
609 {
610 QString strFullData;
611 m_fAdaptersPresent = false;
612 m_fCablesDisconnected = true;
613 m_pMachine->acquireNetworkStatusInfo(strFullData, m_fAdaptersPresent, m_fCablesDisconnected);
614
615 /* Show/hide indicator if there are no attachments
616 * and parent is visible already: */
617 if ( parentWidget()
618 && parentWidget()->isVisible())
619 setVisible(m_fAdaptersPresent);
620
621 /* Update tool-tip: */
622 if (!strFullData.isEmpty())
623 setToolTip(s_strTable.arg(strFullData));
624 /* Update indicator state: */
625 setState(m_fAdaptersPresent && !m_fCablesDisconnected ? KDeviceActivity_Idle : KDeviceActivity_Null);
626
627 /* Retranslate finally: */
628 sltRetranslateUI();
629 }
630
631 /** Handles translation event. */
632 virtual void sltRetranslateUI() RT_OVERRIDE
633 {
634 /* Call to base-class: */
635 UISessionStateStatusBarIndicator::sltRetranslateUI();
636
637 /* Append description with more info: */
638 QStringList info;
639 info << (m_fAdaptersPresent ? tr("Adapters present") : tr("No network adapters"));
640 if (m_fCablesDisconnected)
641 info << tr("All cables disconnected");
642 m_strDescription = QString("%1, %2").arg(m_strDescription, info.join(", "));
643 }
644
645private:
646
647 /** Holds whether adapters present. */
648 bool m_fAdaptersPresent;
649 /** Holds whether cables disconnected. */
650 bool m_fCablesDisconnected;
651};
652
653
654/** UISessionStateStatusBarIndicator extension for Runtime UI: USB indicator. */
655class UIIndicatorUSB : public UISessionStateStatusBarIndicator
656{
657 Q_OBJECT;
658
659public:
660
661 /** Constructs indicator passing @a pMachine to the base-class. */
662 UIIndicatorUSB(UIMachine *pMachine)
663 : UISessionStateStatusBarIndicator(IndicatorType_USB, pMachine)
664 , m_fUsbEnabled(false)
665 , m_cUsbFilterCount(0)
666 {
667 /* Assign state-icons: */
668 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/usb_16px.png"));
669 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/usb_read_16px.png"));
670 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/usb_write_16px.png"));
671 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/usb_disabled_16px.png"));
672 /* Configure connection: */
673 connect(m_pMachine, &UIMachine::sigMachineStateChange,
674 this, &UIIndicatorUSB::updateAppearance);
675 connect(m_pMachine, &UIMachine::sigUSBControllerChange,
676 this, &UIIndicatorUSB::updateAppearance);
677 connect(m_pMachine, &UIMachine::sigUSBDeviceStateChange,
678 this, &UIIndicatorUSB::updateAppearance);
679 /* Update & translate finally: */
680 updateAppearance();
681 }
682
683protected slots:
684
685 /** Update routine. */
686 virtual void updateAppearance() RT_OVERRIDE
687 {
688 QString strFullData;
689 m_fUsbEnabled = false;
690 m_cUsbFilterCount = 0;
691 m_pMachine->acquireUsbStatusInfo(strFullData, m_fUsbEnabled, m_cUsbFilterCount);
692
693 /* Show/hide indicator if there are no attachments
694 * and parent is visible already: */
695 if ( parentWidget()
696 && parentWidget()->isVisible())
697 setVisible(m_fUsbEnabled);
698
699 /* Update tool-tip: */
700 if (!strFullData.isEmpty())
701 setToolTip(s_strTable.arg(strFullData));
702 /* Update indicator state: */
703 setState(m_fUsbEnabled ? KDeviceActivity_Idle : KDeviceActivity_Null);
704
705 /* Retranslate finally: */
706 sltRetranslateUI();
707 }
708
709 /** Handles translation event. */
710 virtual void sltRetranslateUI() RT_OVERRIDE
711 {
712 /* Call to base-class: */
713 UISessionStateStatusBarIndicator::sltRetranslateUI();
714
715 /* Append description with more info: */
716 const QString strUsbStatus = m_fUsbEnabled ? tr("USB enabled") : tr("USB disabled");
717 const QString strFilterCount = m_cUsbFilterCount ? tr("%1 USB devices attached").arg(m_cUsbFilterCount)
718 : tr("No USB devices attached");
719 m_strDescription = QString("%1, %2, %3").arg(m_strDescription, strUsbStatus, strFilterCount);
720 }
721
722private:
723
724 /** Holds whether USB subsystem is enabled. */
725 bool m_fUsbEnabled;
726 /** Holds USB device filter count. */
727 uint m_cUsbFilterCount;
728};
729
730
731/** UISessionStateStatusBarIndicator extension for Runtime UI: Shared-folders indicator. */
732class UIIndicatorSharedFolders : public UISessionStateStatusBarIndicator
733{
734 Q_OBJECT;
735
736public:
737
738 /** Constructs indicator passing @a pMachine to the base-class. */
739 UIIndicatorSharedFolders(UIMachine *pMachine)
740 : UISessionStateStatusBarIndicator(IndicatorType_SharedFolders, pMachine)
741 , m_cFoldersCount(0)
742 {
743 /* Assign state-icons: */
744 setStateIcon(KDeviceActivity_Idle, UIIconPool::iconSet(":/sf_16px.png"));
745 setStateIcon(KDeviceActivity_Reading, UIIconPool::iconSet(":/sf_read_16px.png"));
746 setStateIcon(KDeviceActivity_Writing, UIIconPool::iconSet(":/sf_write_16px.png"));
747 setStateIcon(KDeviceActivity_Null, UIIconPool::iconSet(":/sf_disabled_16px.png"));
748 /* Configure connection: */
749 connect(m_pMachine, &UIMachine::sigMachineStateChange,
750 this, &UIIndicatorSharedFolders::updateAppearance);
751 connect(m_pMachine, &UIMachine::sigSharedFolderChange,
752 this, &UIIndicatorSharedFolders::updateAppearance);
753 /* Update & translate finally: */
754 updateAppearance();
755 }
756
757protected slots:
758
759 /** Update routine. */
760 virtual void updateAppearance() RT_OVERRIDE
761 {
762 QString strFullData;
763 m_cFoldersCount = 0;
764 m_pMachine->acquireSharedFoldersStatusInfo(strFullData, m_cFoldersCount);
765
766 /* Update tool-tip: */
767 if (!strFullData.isEmpty())
768 setToolTip(s_strTable.arg(strFullData));
769 /* Update indicator state: */
770 setState(m_cFoldersCount ? KDeviceActivity_Idle : KDeviceActivity_Null);
771
772 /* Retranslate finally: */
773 sltRetranslateUI();
774 }
775
776 /** Handles translation event. */
777 virtual void sltRetranslateUI() RT_OVERRIDE
778 {
779 /* Call to base-class: */
780 UISessionStateStatusBarIndicator::sltRetranslateUI();
781
782 /* Append description with more info: */
783 const QString strFoldersCount = m_cFoldersCount ? tr("%1 shared folders").arg(m_cFoldersCount)
784 : tr("No shared folders");
785 m_strDescription = QString("%1, %2").arg(m_strDescription, strFoldersCount);
786 }
787
788private:
789
790 /** Holds the amount of folders. */
791 uint m_cFoldersCount;
792};
793
794
795/** UISessionStateStatusBarIndicator extension for Runtime UI: Display indicator. */
796class UIIndicatorDisplay : public UISessionStateStatusBarIndicator
797{
798 Q_OBJECT;
799
800public:
801
802 /** Display states. */
803 enum DisplayState
804 {
805 DisplayState_Unavailable = 0,
806 DisplayState_Software = 1,
807 DisplayState_Hardware = 2
808 };
809
810 /** Constructs indicator passing @a pMachine to the base-class. */
811 UIIndicatorDisplay(UIMachine *pMachine)
812 : UISessionStateStatusBarIndicator(IndicatorType_Display, pMachine)
813 , m_uVRAMSize(0)
814 , m_cMonitorCount(0)
815 , m_fAcceleration3D(false)
816 {
817 /* Assign state-icons: */
818 setStateIcon(DisplayState_Unavailable, UIIconPool::iconSet(":/display_software_disabled_16px.png"));
819 setStateIcon(DisplayState_Software, UIIconPool::iconSet(":/display_software_16px.png"));
820 setStateIcon(DisplayState_Hardware, UIIconPool::iconSet(":/display_hardware_16px.png"));
821 /* Configure connection: */
822 connect(m_pMachine, &UIMachine::sigMachineStateChange,
823 this, &UIIndicatorDisplay::updateAppearance);
824 /* Update & translate finally: */
825 updateAppearance();
826 }
827
828protected slots:
829
830 /** Update routine. */
831 virtual void updateAppearance() RT_OVERRIDE
832 {
833 QString strFullData;
834 m_uVRAMSize = 0;
835 m_cMonitorCount = 0;
836 m_fAcceleration3D = false;
837 m_pMachine->acquireDisplayStatusInfo(strFullData, m_uVRAMSize, m_cMonitorCount, m_fAcceleration3D);
838
839 /* Update tool-tip: */
840 if (!strFullData.isEmpty())
841 setToolTip(s_strTable.arg(strFullData));
842 /* Update indicator state: */
843 DisplayState enmState = DisplayState_Unavailable;
844 if (m_pMachine->machineState() != KMachineState_Null)
845 {
846 if (!m_fAcceleration3D)
847 enmState = DisplayState_Software;
848 else
849 enmState = DisplayState_Hardware;
850 }
851 setState(enmState);
852
853 /* Retranslate finally: */
854 sltRetranslateUI();
855 }
856
857 /** Handles translation event. */
858 virtual void sltRetranslateUI() RT_OVERRIDE
859 {
860 /* Call to base-class: */
861 UISessionStateStatusBarIndicator::sltRetranslateUI();
862
863 /* Append description with more info: */
864 QStringList info;
865 info << tr("%1 MB").arg(m_uVRAMSize);
866 if (m_cMonitorCount > 1)
867 info << tr("%1 monitors connected").arg(m_cMonitorCount);
868 if (m_fAcceleration3D)
869 info << tr("3D acceleration enabled");
870 m_strDescription = QString("%1, %2").arg(m_strDescription, info.join(", "));
871 }
872
873private:
874
875 /** Holds the VRAM size. */
876 uint m_uVRAMSize;
877 /** Holds the monitor count. */
878 uint m_cMonitorCount;
879 /** Holds whether 3D acceleration is enabled. */
880 bool m_fAcceleration3D;
881};
882
883
884/** UISessionStateStatusBarIndicator extension for Runtime UI: Recording indicator. */
885class UIIndicatorRecording : public UISessionStateStatusBarIndicator
886{
887 Q_OBJECT;
888 Q_PROPERTY(double rotationAngleStart READ rotationAngleStart);
889 Q_PROPERTY(double rotationAngleFinal READ rotationAngleFinal);
890 Q_PROPERTY(double rotationAngle READ rotationAngle WRITE setRotationAngle);
891
892 /** Recording states. */
893 enum RecordingState
894 {
895 RecordingState_Unavailable = 0,
896 RecordingState_Disabled = 1,
897 RecordingState_Enabled = 2,
898 RecordingState_Paused = 3
899 };
900
901public:
902
903 /** Constructs indicator passing @a pMachine to the base-class. */
904 UIIndicatorRecording(UIMachine *pMachine)
905 : UISessionStateStatusBarIndicator(IndicatorType_Recording, pMachine)
906 , m_pAnimation(0)
907 , m_dRotationAngle(0)
908 , m_enmState(RecordingState_Unavailable)
909 {
910 /* Assign state-icons: */
911 setStateIcon(RecordingState_Unavailable, UIIconPool::iconSet(":/video_capture_disabled_16px.png"));
912 setStateIcon(RecordingState_Disabled, UIIconPool::iconSet(":/video_capture_16px.png"));
913 setStateIcon(RecordingState_Enabled, UIIconPool::iconSet(":/movie_reel_16px.png"));
914 setStateIcon(RecordingState_Paused, UIIconPool::iconSet(":/movie_reel_16px.png"));
915 /* Configure connection: */
916 connect(m_pMachine, &UIMachine::sigMachineStateChange,
917 this, &UIIndicatorRecording::updateAppearance);
918 connect(m_pMachine, &UIMachine::sigRecordingChange,
919 this, &UIIndicatorRecording::updateAppearance);
920 /* Create *enabled* state animation: */
921 m_pAnimation = UIAnimationLoop::installAnimationLoop(this, "rotationAngle",
922 "rotationAngleStart", "rotationAngleFinal",
923 1000);
924 /* Update & translate finally: */
925 updateAppearance();
926 }
927
928protected:
929
930 /** Handles paint @a pEvent. */
931 virtual void paintEvent(QPaintEvent *pEvent) RT_OVERRIDE
932 {
933 /* Call to base-class: */
934 UISessionStateStatusBarIndicator::paintEvent(pEvent);
935
936 /* Create new painter: */
937 QPainter painter(this);
938 /* Configure painter for *enabled* state: */
939 if (state() == RecordingState_Enabled)
940 {
941 /* Configure painter for smooth animation: */
942 painter.setRenderHint(QPainter::Antialiasing);
943 painter.setRenderHint(QPainter::SmoothPixmapTransform);
944 /* Shift rotation origin according pixmap center: */
945 painter.translate(height() / 2, height() / 2);
946 /* Rotate painter: */
947 painter.rotate(rotationAngle());
948 /* Unshift rotation origin according pixmap center: */
949 painter.translate(- height() / 2, - height() / 2);
950 }
951 /* Draw contents: */
952 drawContents(&painter);
953 }
954
955protected slots:
956
957 /** Update routine. */
958 virtual void updateAppearance() RT_OVERRIDE
959 {
960 QString strFullData;
961 bool fRecordingEnabled = false;
962 bool fMachinePaused = false;
963 m_pMachine->acquireRecordingStatusInfo(strFullData, fRecordingEnabled, fMachinePaused);
964
965 /* Update tool-tip: */
966 if (!strFullData.isEmpty())
967 setToolTip(s_strTable.arg(strFullData));
968 /* Set initial indicator state: */
969 m_enmState = RecordingState_Unavailable;
970 if (m_pMachine->machineState() != KMachineState_Null)
971 {
972 if (!fRecordingEnabled)
973 m_enmState = RecordingState_Disabled;
974 else if (!fMachinePaused)
975 m_enmState = RecordingState_Enabled;
976 else
977 m_enmState = RecordingState_Paused;
978 }
979 setState(m_enmState);
980
981 /* Retranslate finally: */
982 sltRetranslateUI();
983 }
984
985 /** Handles translation event. */
986 virtual void sltRetranslateUI() RT_OVERRIDE
987 {
988 /* Call to base-class: */
989 UISessionStateStatusBarIndicator::sltRetranslateUI();
990
991 /* Append description with more info: */
992 switch (m_enmState)
993 {
994 case RecordingState_Disabled:
995 m_strDescription = QString("%1, %2").arg(m_strDescription, tr("Recording stopped")); break;
996 case RecordingState_Enabled:
997 m_strDescription = QString("%1, %2").arg(m_strDescription, tr("Recording started")); break;
998 case RecordingState_Paused:
999 m_strDescription = QString("%1, %2").arg(m_strDescription, tr("Recording paused")); break;
1000 default:
1001 break;
1002 }
1003 }
1004
1005private slots:
1006
1007 /** Handles state change. */
1008 void setState(int iState) RT_OVERRIDE
1009 {
1010 /* Update animation state: */
1011 switch (iState)
1012 {
1013 case RecordingState_Disabled:
1014 m_pAnimation->stop();
1015 m_dRotationAngle = 0;
1016 break;
1017 case RecordingState_Enabled:
1018 m_pAnimation->start();
1019 break;
1020 case RecordingState_Paused:
1021 m_pAnimation->stop();
1022 break;
1023 default:
1024 break;
1025 }
1026 /* Call to base-class: */
1027 QIStateStatusBarIndicator::setState(iState);
1028 }
1029
1030private:
1031
1032 /** Returns rotation start angle. */
1033 double rotationAngleStart() const { return 0; }
1034 /** Returns rotation finish angle. */
1035 double rotationAngleFinal() const { return 360; }
1036 /** Returns current rotation angle. */
1037 double rotationAngle() const { return m_dRotationAngle; }
1038 /** Defines current rotation angle. */
1039 void setRotationAngle(double dRotationAngle) { m_dRotationAngle = dRotationAngle; update(); }
1040
1041 /** Holds the rotation animation instance. */
1042 UIAnimationLoop *m_pAnimation;
1043 /** Holds current rotation angle. */
1044 double m_dRotationAngle;
1045
1046 /** Holds the recording state. */
1047 RecordingState m_enmState;
1048};
1049
1050
1051/** UISessionStateStatusBarIndicator extension for Runtime UI: Features indicator. */
1052class UIIndicatorFeatures : public UISessionStateStatusBarIndicator
1053{
1054 Q_OBJECT;
1055
1056public:
1057
1058 /** Constructs indicator passing @a pMachine to the base-class. */
1059 UIIndicatorFeatures(UIMachine *pMachine)
1060 : UISessionStateStatusBarIndicator(IndicatorType_Features, pMachine)
1061 , m_pTimerAutoUpdate(0)
1062 , m_uEffectiveCPULoad(0)
1063 {
1064 /* Assign state-icons: */
1065 /** @todo The vtx_amdv_disabled_16px.png icon isn't really approprate anymore (no raw-mode),
1066 * might want to get something different for KVMExecutionEngine_Emulated or reuse the
1067 * vm_execution_engine_native_api_16px.png one... @bugref{9898} */
1068 setStateIcon(KVMExecutionEngine_NotSet, UIIconPool::iconSet(":/vtx_amdv_disabled_16px.png"));
1069 setStateIcon(KVMExecutionEngine_Interpreter, UIIconPool::iconSet(":/vtx_amdv_disabled_16px.png"));
1070 setStateIcon(KVMExecutionEngine_Recompiler, UIIconPool::iconSet(":/vtx_amdv_disabled_16px.png"));
1071 setStateIcon(KVMExecutionEngine_HwVirt, UIIconPool::iconSet(":/vtx_amdv_16px.png"));
1072 setStateIcon(KVMExecutionEngine_NativeApi, UIIconPool::iconSet(":/vm_execution_engine_native_api_16px.png"));
1073 /* Configure connection: */
1074 connect(m_pMachine, &UIMachine::sigMachineStateChange,
1075 this, &UIIndicatorFeatures::updateAppearance);
1076 connect(m_pMachine, &UIMachine::sigInitialized,
1077 this, &UIIndicatorFeatures::updateAppearance);
1078 connect(m_pMachine, &UIMachine::sigCPUExecutionCapChange,
1079 this, &UIIndicatorFeatures::updateAppearance);
1080 /* Configure CPU load update timer: */
1081 m_pTimerAutoUpdate = new QTimer(this);
1082 if (m_pTimerAutoUpdate)
1083 connect(m_pTimerAutoUpdate, &QTimer::timeout,
1084 this, &UIIndicatorFeatures::sltHandleTimeout);
1085 /* Update & translate finally: */
1086 updateAppearance();
1087 }
1088
1089protected:
1090
1091 /** Handles paint @a pEvent. */
1092 virtual void paintEvent(QPaintEvent *pEvent) RT_OVERRIDE
1093 {
1094 /* Call to base-class: */
1095 UISessionStateStatusBarIndicator::paintEvent(pEvent);
1096
1097 /* Create new painter: */
1098 QPainter painter(this);
1099
1100 /* Be a paranoid: */
1101 ulong uCPU = qMin(m_uEffectiveCPULoad, static_cast<ulong>(100));
1102
1103 int iBorderThickness = 1;
1104 /** Draw a black rectangle as background to the right hand side of 'this'.
1105 * A smaller and colored rectangle will be drawn on top of this: **/
1106 QPoint topLeftOut(0.76 * width() ,0);
1107 QPoint bottomRightOut(width() - 1, height() - 1);
1108 QRect outRect(topLeftOut, bottomRightOut);
1109
1110 painter.setPen(Qt::NoPen);
1111 painter.setBrush(Qt::black);
1112 painter.drawRect(outRect);
1113
1114 /* Draw a colored rectangle. Its color and height is dynamically computed from CPU usage: */
1115 int inFullHeight = outRect.height() - 2 * iBorderThickness;
1116 int inWidth = outRect.width() - 2 * iBorderThickness;
1117 int inHeight = inFullHeight * uCPU / 100.;
1118 QPoint topLeftIn(topLeftOut.x() + iBorderThickness,
1119 topLeftOut.y() + iBorderThickness + (inFullHeight - inHeight));
1120
1121 QRect inRect(topLeftIn, QSize(inWidth, inHeight));
1122 painter.setPen(Qt::NoPen);
1123
1124 /* Compute color as HSV: */
1125 int iH = 120 * (1 - uCPU / 100.);
1126 QColor fillColor;
1127 fillColor.setHsv(iH, 255 /*saturation */, 255 /* value */);
1128
1129 painter.setBrush(fillColor);
1130 painter.drawRect(inRect);
1131 }
1132
1133protected slots:
1134
1135 /** Update routine. */
1136 virtual void updateAppearance() RT_OVERRIDE
1137 {
1138 m_strFullData.clear();
1139 KVMExecutionEngine enmEngine = KVMExecutionEngine_NotSet;
1140 m_pMachine->acquireFeaturesStatusInfo(m_strFullData, enmEngine);
1141
1142 /* Update tool-tip: */
1143 if (!m_strFullData.isEmpty())
1144 setToolTip(s_strTable.arg(m_strFullData));
1145 /* Update indicator state: */
1146 setState(enmEngine);
1147
1148 /* Start or stop CPU load update timer: */
1149 if ( m_pTimerAutoUpdate
1150 && m_pMachine->machineState() == KMachineState_Running)
1151 m_pTimerAutoUpdate->start(1000);
1152 else
1153 m_pTimerAutoUpdate->stop();
1154
1155 /* Retranslate finally: */
1156 sltRetranslateUI();
1157 }
1158
1159 /** Handles translation event. */
1160 virtual void sltRetranslateUI() RT_OVERRIDE
1161 {
1162 /* Call to base-class: */
1163 UISessionStateStatusBarIndicator::sltRetranslateUI();
1164
1165 /* Append description with more info: */
1166 QString strFullData = m_strFullData;
1167 strFullData.remove(QRegularExpression("<tr>|<td>|<nobr>"));
1168 strFullData.replace("</nobr></td></tr>", ", ");
1169 strFullData.replace("</nobr></td>", " ");
1170 m_strDescription = QString("%1, %2").arg(m_strDescription, strFullData);
1171 }
1172
1173private slots:
1174
1175 /** Handles timer timeout with CPU load percentage update. */
1176 void sltHandleTimeout()
1177 {
1178 m_pMachine->acquireEffectiveCPULoad(m_uEffectiveCPULoad);
1179 update();
1180 }
1181
1182private:
1183
1184 /** Holds the auto-update timer instance. */
1185 QTimer *m_pTimerAutoUpdate;
1186
1187 /** Holds the effective CPU load. Expected to be in range [0, 100] */
1188 ulong m_uEffectiveCPULoad;
1189
1190 /** Holds the serialized tool-tip data. */
1191 QString m_strFullData;
1192};
1193
1194
1195/** UISessionStateStatusBarIndicator extension for Runtime UI: Mouse indicator. */
1196class UIIndicatorMouse : public UISessionStateStatusBarIndicator
1197{
1198 Q_OBJECT;
1199
1200 /** Possible indicator states. */
1201 enum
1202 {
1203 State_NotCaptured = 0, // 000 == !MouseCaptured
1204 State_Captured = 1, // 001 == MouseCaptured
1205 State_AbsoluteNotCaptured = 2, // 010 == !MouseCaptured & MouseSupportsAbsolute
1206 State_AbsoluteCaptured = 3, // 011 == MouseCaptured & MouseSupportsAbsolute
1207 State_Integrated = 6, // 110 == MouseSupportsAbsolute & MouseIntegrated
1208 };
1209
1210public:
1211
1212 /** Constructor, using @a pMachine for state-update routine. */
1213 UIIndicatorMouse(UIMachine *pMachine)
1214 : UISessionStateStatusBarIndicator(IndicatorType_Mouse, pMachine)
1215 {
1216 /* Assign state-icons: */
1217 setStateIcon(State_NotCaptured, UIIconPool::iconSet(":/mouse_disabled_16px.png")); // 000
1218 setStateIcon(State_Captured, UIIconPool::iconSet(":/mouse_16px.png")); // 001
1219 setStateIcon(State_AbsoluteNotCaptured, UIIconPool::iconSet(":/mouse_can_seamless_uncaptured_16px.png")); // 010
1220 setStateIcon(State_AbsoluteCaptured, UIIconPool::iconSet(":/mouse_can_seamless_16px.png")); // 011
1221 setStateIcon(State_Integrated, UIIconPool::iconSet(":/mouse_seamless_16px.png")); // 110
1222
1223 /* Configure machine connection: */
1224 connect(m_pMachine, &UIMachine::sigMouseStateChange, this, &UIIndicatorMouse::setState);
1225
1226 /* Update & translate finally: */
1227 updateAppearance();
1228 }
1229
1230protected slots:
1231
1232 /** Update routine. */
1233 virtual void updateAppearance() RT_OVERRIDE
1234 {
1235 /* Retranslate finally: */
1236 sltRetranslateUI();
1237 }
1238
1239 /** Handles translation event. */
1240 virtual void sltRetranslateUI() RT_OVERRIDE
1241 {
1242 /* Call to base-class: */
1243 UISessionStateStatusBarIndicator::sltRetranslateUI();
1244
1245 /* Update tool-tip: */
1246 const QString strToolTip = tr("Indicates whether the host mouse pointer is "
1247 "captured by the guest OS:%1", "Mouse tooltip");
1248 QString strFullData;
1249 strFullData += s_strTableRow3
1250 .arg(QString("<img src=:/mouse_disabled_16px.png/>"))
1251 .arg(tr("Pointer is not captured", "Mouse tooltip"));
1252 strFullData += s_strTableRow3
1253 .arg(QString("<img src=:/mouse_16px.png/>"))
1254 .arg(tr("Pointer is captured", "Mouse tooltip"));
1255 strFullData += s_strTableRow3
1256 .arg(QString("<img src=:/mouse_can_seamless_uncaptured_16px.png/>"))
1257 .arg(tr("Mouse integration is Off, pointer is not captured", "Mouse tooltip"));
1258 strFullData += s_strTableRow3
1259 .arg(QString("<img src=:/mouse_can_seamless_16px.png/>"))
1260 .arg(tr("Mouse integration is Off, pointer is captured", "Mouse tooltip"));
1261 strFullData += s_strTableRow3
1262 .arg(QString("<img src=:/mouse_seamless_16px.png/>"))
1263 .arg(tr("Mouse integration is On", "Mouse tooltip"));
1264 strFullData = s_strTable.arg(strFullData);
1265 strFullData += tr("Note that the mouse integration feature requires Guest "
1266 "Additions to be installed in the guest OS.", "Mouse tooltip");
1267 setToolTip(strToolTip.arg(strFullData));
1268
1269 /* Append description with more info: */
1270 QString strState;
1271 switch (state())
1272 {
1273 case State_NotCaptured:
1274 strState = tr("Pointer is not captured", "Mouse tooltip"); break;
1275 case State_Captured:
1276 strState = tr("Pointer is captured", "Mouse tooltip"); break;
1277 case State_AbsoluteNotCaptured:
1278 strState = tr("Mouse integration is Off, pointer is not captured", "Mouse tooltip"); break;
1279 case State_AbsoluteCaptured:
1280 strState = tr("Mouse integration is Off, pointer is captured", "Mouse tooltip"); break;
1281 case State_Integrated:
1282 strState = tr("Mouse integration is On", "Mouse tooltip"); break;
1283 default:
1284 break;
1285 }
1286 if (!strState.isNull())
1287 m_strDescription = QString("%1, %2").arg(m_strDescription, strState);
1288 }
1289
1290private slots:
1291
1292 /** Handles state change. */
1293 void setState(int iState) RT_OVERRIDE
1294 {
1295 /* Call to base-class: */
1296 QIStateStatusBarIndicator::setState(iState);
1297
1298 /* Update everything: */
1299 updateAppearance();
1300 }
1301};
1302
1303
1304/** UISessionStateStatusBarIndicator extension for Runtime UI: Keyboard indicator. */
1305class UIIndicatorKeyboard : public UISessionStateStatusBarIndicator
1306{
1307 Q_OBJECT;
1308
1309 /** Possible indicator states. */
1310 enum
1311 {
1312 State_KeyboardUnavailable = 0, // 0000 == KeyboardUnavailable
1313 State_KeyboardAvailable = 1, // 0001 == KeyboardAvailable
1314 State_HostKeyCaptured = 3, // 0011 == KeyboardAvailable & KeyboardCaptured
1315 State_HostKeyPressed = 5, // 0101 == KeyboardAvailable & !KeyboardCaptured & HostKeyPressed
1316 State_HostKeyCapturedPressed = 7, // 0111 == KeyboardAvailable & KeyboardCaptured & HostKeyPressed
1317 State_HostKeyChecked = 9, // 1001 == KeyboardAvailable & !KeyboardCaptured & !HostKeyPressed & HostKeyPressedInsertion
1318 State_HostKeyCapturedChecked = 11, // 1011 == KeyboardAvailable & KeyboardCaptured & !HostKeyPressed & HostKeyPressedInsertion
1319 State_HostKeyPressedChecked = 13, // 1101 == KeyboardAvailable & !KeyboardCaptured & HostKeyPressed & HostKeyPressedInsertion
1320 State_HostKeyCapturedPressedChecked = 15, // 1111 == KeyboardAvailable & KeyboardCaptured & HostKeyPressed & HostKeyPressedInsertion
1321 };
1322
1323public:
1324
1325 /** Constructor, using @a pMachine for state-update routine. */
1326 UIIndicatorKeyboard(UIMachine *pMachine)
1327 : UISessionStateStatusBarIndicator(IndicatorType_Keyboard, pMachine)
1328 {
1329 /* Assign state-icons: */
1330 setStateIcon(State_KeyboardUnavailable, UIIconPool::iconSet(":/hostkey_disabled_16px.png"));
1331 setStateIcon(State_KeyboardAvailable, UIIconPool::iconSet(":/hostkey_16px.png"));
1332 setStateIcon(State_HostKeyCaptured, UIIconPool::iconSet(":/hostkey_captured_16px.png"));
1333 setStateIcon(State_HostKeyPressed, UIIconPool::iconSet(":/hostkey_pressed_16px.png"));
1334 setStateIcon(State_HostKeyCapturedPressed, UIIconPool::iconSet(":/hostkey_captured_pressed_16px.png"));
1335 setStateIcon(State_HostKeyChecked, UIIconPool::iconSet(":/hostkey_checked_16px.png"));
1336 setStateIcon(State_HostKeyCapturedChecked, UIIconPool::iconSet(":/hostkey_captured_checked_16px.png"));
1337 setStateIcon(State_HostKeyPressedChecked, UIIconPool::iconSet(":/hostkey_pressed_checked_16px.png"));
1338 setStateIcon(State_HostKeyCapturedPressedChecked, UIIconPool::iconSet(":/hostkey_captured_pressed_checked_16px.png"));
1339
1340 /* Configure machine connection: */
1341 connect(m_pMachine, &UIMachine::sigKeyboardStateChange, this, &UIIndicatorKeyboard::setState);
1342
1343 /* Update & translate finally: */
1344 updateAppearance();
1345 }
1346
1347protected slots:
1348
1349 /** Update routine. */
1350 virtual void updateAppearance() RT_OVERRIDE
1351 {
1352 /* Retranslate finally: */
1353 sltRetranslateUI();
1354 }
1355
1356 /** Handles translation event. */
1357 virtual void sltRetranslateUI() RT_OVERRIDE
1358 {
1359 /* Call to base-class: */
1360 UISessionStateStatusBarIndicator::sltRetranslateUI();
1361
1362 /* Update tool-tip: */
1363 const QString strToolTip = tr("Indicates whether the host keyboard is "
1364 "captured by the guest OS:%1", "Keyboard tooltip");
1365 QString strFullData;
1366 strFullData += s_strTableRow3
1367 .arg(QString("<img src=:/hostkey_16px.png/>"))
1368 .arg(tr("Keyboard is not captured", "Keyboard tooltip"));
1369 strFullData += s_strTableRow3
1370 .arg(QString("<img src=:/hostkey_captured_16px.png/>"))
1371 .arg(tr("Keyboard is captured", "Keyboard tooltip"));
1372 strFullData += s_strTableRow3
1373 .arg(QString("<img src=:/hostkey_pressed_16px.png/>"))
1374 .arg(tr("Keyboard is not captured, host-combo being pressed", "Keyboard tooltip"));
1375 strFullData += s_strTableRow3
1376 .arg(QString("<img src=:/hostkey_captured_pressed_16px.png/>"))
1377 .arg(tr("Keyboard is captured, host-combo being pressed", "Keyboard tooltip"));
1378 strFullData += s_strTableRow3
1379 .arg(QString("<img src=:/hostkey_checked_16px.png/>"))
1380 .arg(tr("Keyboard is not captured, host-combo to be inserted", "Keyboard tooltip"));
1381 strFullData += s_strTableRow3
1382 .arg(QString("<img src=:/hostkey_captured_checked_16px.png/>"))
1383 .arg(tr("Keyboard is captured, host-combo to be inserted", "Keyboard tooltip"));
1384 strFullData += s_strTableRow3
1385 .arg(QString("<img src=:/hostkey_pressed_checked_16px.png/>"))
1386 .arg(tr("Keyboard is not captured, host-combo being pressed and to be inserted", "Keyboard tooltip"));
1387 strFullData += s_strTableRow3
1388 .arg(QString("<img src=:/hostkey_captured_pressed_checked_16px.png/>"))
1389 .arg(tr("Keyboard is captured, host-combo being pressed and to be inserted", "Keyboard tooltip"));
1390 strFullData = s_strTable.arg(strFullData);
1391 setToolTip(strToolTip.arg(strFullData));
1392
1393 /* Append description with more info: */
1394 const QString strStatus = state() & UIKeyboardStateType_KeyboardCaptured
1395 ? tr("Keyboard is captured", "Keyboard tooltip")
1396 : tr("Keyboard is not captured", "Keyboard tooltip");
1397 m_strDescription = QString("%1, %2").arg(m_strDescription, strStatus);
1398 }
1399
1400private slots:
1401
1402 /** Handles state change. */
1403 void setState(int iState) RT_OVERRIDE
1404 {
1405 /* Call to base-class: */
1406 QIStateStatusBarIndicator::setState(iState);
1407
1408 /* Update everything: */
1409 updateAppearance();
1410 }
1411};
1412
1413
1414/** UISessionTextStatusBarIndicator extension for Runtime UI: Keyboard-extension indicator. */
1415class UIIndicatorKeyboardExtension : public UISessionTextStatusBarIndicator
1416{
1417 Q_OBJECT;
1418
1419public:
1420
1421 /** Constructor. */
1422 UIIndicatorKeyboardExtension()
1423 : UISessionTextStatusBarIndicator(IndicatorType_KeyboardExtension)
1424 {
1425 /* Make sure host-combination label will be updated: */
1426 connect(gEDataManager, &UIExtraDataManager::sigRuntimeUIHostKeyCombinationChange,
1427 this, &UIIndicatorKeyboardExtension::updateAppearance);
1428 connect(&translationEventListener(), &UITranslationEventListener::sigRetranslateUI,
1429 this, &UIIndicatorKeyboardExtension::sltRetranslateUI);
1430
1431 /* Update & translate finally: */
1432 updateAppearance();
1433 }
1434
1435protected slots:
1436
1437 /** Update routine. */
1438 void updateAppearance()
1439 {
1440 /* Update combination: */
1441 setText(UIHostCombo::toReadableString(gEDataManager->hostKeyCombination()));
1442
1443 /* Retranslate finally: */
1444 sltRetranslateUI();
1445 }
1446
1447 /** Retranslation routine. */
1448 void sltRetranslateUI()
1449 {
1450 /* Call to base-class: */
1451 UISessionTextStatusBarIndicator::sltRetranslateUI();
1452
1453 setToolTip(tr("Shows the currently assigned Host Key Combo.<br>"
1454 "This key combo, when pressed alone, toggles the keyboard and mouse "
1455 "capture state. It can also be used in combination with other keys "
1456 "to quickly perform actions from the main menu."));
1457
1458 /* Host-combo info: */
1459 const QString strHostCombo = tr("Host Key Combo: %1").arg(text());
1460 m_strDescription = QString("%1, %2").arg(m_strDescription, strHostCombo);
1461 }
1462};
1463
1464
1465UIIndicatorsPool::UIIndicatorsPool(UIMachine *pMachine, QWidget *pParent /* = 0 */)
1466 : QWidget(pParent)
1467 , m_pMachine(pMachine)
1468 , m_fEnabled(false)
1469 , m_pMainLayout(0)
1470 , m_pTimerAutoUpdate(0)
1471{
1472 prepare();
1473}
1474
1475UIIndicatorsPool::~UIIndicatorsPool()
1476{
1477 cleanup();
1478}
1479
1480void UIIndicatorsPool::updateAppearance(IndicatorType indicatorType)
1481{
1482 /* Skip missed indicators: */
1483 if (!m_pool.contains(indicatorType))
1484 return;
1485
1486 /* Get indicator: */
1487 QIStatusBarIndicator *pIndicator = m_pool.value(indicatorType);
1488
1489 /* Assert indicators with NO appearance: */
1490 UISessionStateStatusBarIndicator *pSessionStateIndicator =
1491 qobject_cast<UISessionStateStatusBarIndicator*>(pIndicator);
1492 AssertPtrReturnVoid(pSessionStateIndicator);
1493
1494 /* Update indicator appearance: */
1495 pSessionStateIndicator->updateAppearance();
1496}
1497
1498void UIIndicatorsPool::setAutoUpdateIndicatorStates(bool fEnabled)
1499{
1500 /* Make sure auto-update timer exists: */
1501 AssertPtrReturnVoid(m_pTimerAutoUpdate);
1502
1503 /* Start/stop timer: */
1504 if (fEnabled)
1505 m_pTimerAutoUpdate->start(100);
1506 else
1507 m_pTimerAutoUpdate->stop();
1508}
1509
1510QPoint UIIndicatorsPool::mapIndicatorPositionToGlobal(IndicatorType enmIndicatorType, const QPoint &indicatorPosition)
1511{
1512 if (m_pool.contains(enmIndicatorType))
1513 return m_pool.value(enmIndicatorType)->mapToGlobal(indicatorPosition);
1514 return QPoint(0, 0);
1515}
1516
1517void UIIndicatorsPool::sltHandleConfigurationChange(const QUuid &uMachineID)
1518{
1519 /* Skip unrelated machine IDs: */
1520 if (uiCommon().managedVMUuid() != uMachineID)
1521 return;
1522
1523 /* Update pool: */
1524 updatePool();
1525}
1526
1527void UIIndicatorsPool::sltAutoUpdateIndicatorStates()
1528{
1529 /* We should update states for following indicators: */
1530 QVector<KDeviceType> deviceTypes;
1531 if (m_pool.contains(IndicatorType_HardDisks))
1532 deviceTypes.append(KDeviceType_HardDisk);
1533 if (m_pool.contains(IndicatorType_OpticalDisks))
1534 deviceTypes.append(KDeviceType_DVD);
1535 if (m_pool.contains(IndicatorType_FloppyDisks))
1536 deviceTypes.append(KDeviceType_Floppy);
1537 if (m_pool.contains(IndicatorType_USB))
1538 deviceTypes.append(KDeviceType_USB);
1539 if (m_pool.contains(IndicatorType_Network))
1540 deviceTypes.append(KDeviceType_Network);
1541 if (m_pool.contains(IndicatorType_SharedFolders))
1542 deviceTypes.append(KDeviceType_SharedFolder);
1543 if (m_pool.contains(IndicatorType_Display))
1544 deviceTypes.append(KDeviceType_Graphics3D);
1545
1546 /* Acquire current device states from the machine: */
1547 QVector<KDeviceActivity> states;
1548 m_pMachine->acquireDeviceActivity(deviceTypes, states);
1549
1550 /* Update indicators with the acquired states: */
1551 for (int iIndicator = 0; iIndicator < states.size(); ++iIndicator)
1552 {
1553 QIStatusBarIndicator *pIndicator = 0;
1554 switch (deviceTypes[iIndicator])
1555 {
1556 case KDeviceType_HardDisk: pIndicator = m_pool.value(IndicatorType_HardDisks); break;
1557 case KDeviceType_DVD: pIndicator = m_pool.value(IndicatorType_OpticalDisks); break;
1558 case KDeviceType_Floppy: pIndicator = m_pool.value(IndicatorType_FloppyDisks); break;
1559 case KDeviceType_USB: pIndicator = m_pool.value(IndicatorType_USB); break;
1560 case KDeviceType_Network: pIndicator = m_pool.value(IndicatorType_Network); break;
1561 case KDeviceType_SharedFolder: pIndicator = m_pool.value(IndicatorType_SharedFolders); break;
1562 case KDeviceType_Graphics3D: pIndicator = m_pool.value(IndicatorType_Display); break;
1563 default: AssertFailed(); break;
1564 }
1565 if (pIndicator)
1566 updateIndicatorStateForDevice(pIndicator, states[iIndicator]);
1567 }
1568}
1569
1570void UIIndicatorsPool::sltContextMenuRequest(QIStatusBarIndicator *pIndicator, QContextMenuEvent *pEvent)
1571{
1572 /* If that is one of pool indicators: */
1573 foreach (IndicatorType indicatorType, m_pool.keys())
1574 if (m_pool[indicatorType] == pIndicator)
1575 {
1576 /* Notify listener: */
1577 emit sigContextMenuRequest(indicatorType, pEvent->pos());
1578 return;
1579 }
1580}
1581
1582void UIIndicatorsPool::prepare()
1583{
1584 /* Prepare connections: */
1585 prepareConnections();
1586 /* Prepare contents: */
1587 prepareContents();
1588 /* Prepare auto-update timer: */
1589 prepareUpdateTimer();
1590}
1591
1592void UIIndicatorsPool::prepareConnections()
1593{
1594 /* Listen for the status-bar configuration changes: */
1595 connect(gEDataManager, &UIExtraDataManager::sigStatusBarConfigurationChange,
1596 this, &UIIndicatorsPool::sltHandleConfigurationChange);
1597}
1598
1599void UIIndicatorsPool::prepareContents()
1600{
1601 /* Create main-layout: */
1602 m_pMainLayout = new QHBoxLayout(this);
1603 AssertPtrReturnVoid(m_pMainLayout);
1604 {
1605 /* Configure main-layout: */
1606 m_pMainLayout->setContentsMargins(0, 0, 0, 0);
1607#ifdef VBOX_WS_MAC
1608 m_pMainLayout->setSpacing(5);
1609#else
1610 m_pMainLayout->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing) / 2);
1611#endif
1612 /* Update pool: */
1613 updatePool();
1614 }
1615}
1616
1617void UIIndicatorsPool::prepareUpdateTimer()
1618{
1619 /* Create auto-update timer: */
1620 m_pTimerAutoUpdate = new QTimer(this);
1621 AssertPtrReturnVoid(m_pTimerAutoUpdate);
1622 {
1623 /* Configure auto-update timer: */
1624 connect(m_pTimerAutoUpdate, &QTimer::timeout,
1625 this, &UIIndicatorsPool::sltAutoUpdateIndicatorStates);
1626 setAutoUpdateIndicatorStates(true);
1627 }
1628}
1629
1630void UIIndicatorsPool::updatePool()
1631{
1632 /* Acquire status-bar availability: */
1633 m_fEnabled = gEDataManager->statusBarEnabled(uiCommon().managedVMUuid());
1634 /* If status-bar is not enabled: */
1635 if (!m_fEnabled)
1636 {
1637 /* Remove all indicators: */
1638 while (!m_pool.isEmpty())
1639 {
1640 const IndicatorType firstType = m_pool.keys().first();
1641 delete m_pool.value(firstType);
1642 m_pool.remove(firstType);
1643 }
1644 /* And return: */
1645 return;
1646 }
1647
1648 /* Acquire status-bar restrictions: */
1649 m_restrictions = gEDataManager->restrictedStatusBarIndicators(uiCommon().managedVMUuid());
1650 /* Make sure 'Recording' is restricted as well if no features supported: */
1651 if ( !m_restrictions.contains(IndicatorType_Recording)
1652 && !gpGlobalSession->supportedRecordingFeatures())
1653 m_restrictions << IndicatorType_Recording;
1654
1655 /* Remove restricted indicators: */
1656 foreach (const IndicatorType &indicatorType, m_restrictions)
1657 {
1658 if (m_pool.contains(indicatorType))
1659 {
1660 delete m_pool.value(indicatorType);
1661 m_pool.remove(indicatorType);
1662 }
1663 }
1664
1665 /* Acquire status-bar order: */
1666 m_order = gEDataManager->statusBarIndicatorOrder(uiCommon().managedVMUuid());
1667 /* Make sure the order is complete taking restrictions into account: */
1668 for (int iType = IndicatorType_Invalid; iType < IndicatorType_Max; ++iType)
1669 {
1670 /* Get iterated type: */
1671 IndicatorType type = (IndicatorType)iType;
1672 /* Skip invalid type: */
1673 if (type == IndicatorType_Invalid)
1674 continue;
1675 /* Take restriction/presence into account: */
1676 bool fRestricted = m_restrictions.contains(type);
1677 bool fPresent = m_order.contains(type);
1678 if (fRestricted && fPresent)
1679 m_order.removeAll(type);
1680 else if (!fRestricted && !fPresent)
1681 m_order << type;
1682 }
1683
1684 /* Add/Update allowed indicators: */
1685 foreach (const IndicatorType &indicatorType, m_order)
1686 {
1687 /* Indicator exists: */
1688 if (m_pool.contains(indicatorType))
1689 {
1690 /* Get indicator: */
1691 QIStatusBarIndicator *pIndicator = m_pool.value(indicatorType);
1692 /* Make sure it have valid position: */
1693 const int iWantedIndex = indicatorPosition(indicatorType);
1694 const int iActualIndex = m_pMainLayout->indexOf(pIndicator);
1695 if (iActualIndex != iWantedIndex)
1696 {
1697 /* Re-inject indicator into main-layout at proper position: */
1698 m_pMainLayout->removeWidget(pIndicator);
1699 m_pMainLayout->insertWidget(iWantedIndex, pIndicator);
1700 }
1701 }
1702 /* Indicator missed: */
1703 else
1704 {
1705 /* Create indicator: */
1706 switch (indicatorType)
1707 {
1708 case IndicatorType_HardDisks: m_pool[indicatorType] = new UIIndicatorHardDrive(m_pMachine); break;
1709 case IndicatorType_OpticalDisks: m_pool[indicatorType] = new UIIndicatorOpticalDisks(m_pMachine); break;
1710 case IndicatorType_FloppyDisks: m_pool[indicatorType] = new UIIndicatorFloppyDisks(m_pMachine); break;
1711 case IndicatorType_Audio: m_pool[indicatorType] = new UIIndicatorAudio(m_pMachine); break;
1712 case IndicatorType_Network: m_pool[indicatorType] = new UIIndicatorNetwork(m_pMachine); break;
1713 case IndicatorType_USB: m_pool[indicatorType] = new UIIndicatorUSB(m_pMachine); break;
1714 case IndicatorType_SharedFolders: m_pool[indicatorType] = new UIIndicatorSharedFolders(m_pMachine); break;
1715 case IndicatorType_Display: m_pool[indicatorType] = new UIIndicatorDisplay(m_pMachine); break;
1716 case IndicatorType_Recording: m_pool[indicatorType] = new UIIndicatorRecording(m_pMachine); break;
1717 case IndicatorType_Features: m_pool[indicatorType] = new UIIndicatorFeatures(m_pMachine); break;
1718 case IndicatorType_Mouse: m_pool[indicatorType] = new UIIndicatorMouse(m_pMachine); break;
1719 case IndicatorType_Keyboard: m_pool[indicatorType] = new UIIndicatorKeyboard(m_pMachine); break;
1720 case IndicatorType_KeyboardExtension: m_pool[indicatorType] = new UIIndicatorKeyboardExtension; break;
1721 default: break;
1722 }
1723 /* Configure indicator: */
1724 connect(m_pool.value(indicatorType), &QIStatusBarIndicator::sigContextMenuRequest,
1725 this, &UIIndicatorsPool::sltContextMenuRequest);
1726 /* Insert indicator into main-layout at proper position: */
1727 m_pMainLayout->insertWidget(indicatorPosition(indicatorType), m_pool.value(indicatorType));
1728 }
1729 }
1730}
1731
1732void UIIndicatorsPool::cleanupUpdateTimer()
1733{
1734 /* Destroy auto-update timer: */
1735 AssertPtrReturnVoid(m_pTimerAutoUpdate);
1736 {
1737 m_pTimerAutoUpdate->stop();
1738 delete m_pTimerAutoUpdate;
1739 m_pTimerAutoUpdate = 0;
1740 }
1741}
1742
1743void UIIndicatorsPool::cleanupContents()
1744{
1745 /* Cleanup indicators: */
1746 while (!m_pool.isEmpty())
1747 {
1748 const IndicatorType firstType = m_pool.keys().first();
1749 delete m_pool.value(firstType);
1750 m_pool.remove(firstType);
1751 }
1752}
1753
1754void UIIndicatorsPool::cleanup()
1755{
1756 /* Cleanup auto-update timer: */
1757 cleanupUpdateTimer();
1758 /* Cleanup indicators: */
1759 cleanupContents();
1760}
1761
1762void UIIndicatorsPool::contextMenuEvent(QContextMenuEvent *pEvent)
1763{
1764 /* Do not pass-through context menu events,
1765 * otherwise they will raise the underlying status-bar context-menu. */
1766 pEvent->accept();
1767}
1768
1769int UIIndicatorsPool::indicatorPosition(IndicatorType indicatorType) const
1770{
1771 int iPosition = 0;
1772 foreach (const IndicatorType &iteratedIndicatorType, m_order)
1773 if (iteratedIndicatorType == indicatorType)
1774 return iPosition;
1775 else
1776 ++iPosition;
1777 return iPosition;
1778}
1779
1780void UIIndicatorsPool::updateIndicatorStateForDevice(QIStatusBarIndicator *pIndicator, KDeviceActivity enmState)
1781{
1782 /* Assert indicators with NO state: */
1783 QIStateStatusBarIndicator *pStateIndicator = qobject_cast<QIStateStatusBarIndicator*>(pIndicator);
1784 AssertPtrReturnVoid(pStateIndicator);
1785
1786 /* Skip indicators with NULL state: */
1787 if (pStateIndicator->state() == KDeviceActivity_Null)
1788 return;
1789
1790 /* Paused VM have all indicator states set to IDLE: */
1791 if (m_pMachine->isPaused())
1792 {
1793 /* If current state differs from IDLE => set the IDLE one: */
1794 if (pStateIndicator->state() != KDeviceActivity_Idle)
1795 pStateIndicator->setState(KDeviceActivity_Idle);
1796 }
1797 else
1798 {
1799 /* If current state differs from actual => set the actual one: */
1800 if (pStateIndicator->state() != enmState)
1801 pStateIndicator->setState(enmState);
1802 }
1803}
1804
1805#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