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