VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIMenuBarEditorWindow.cpp@ 100347

Last change on this file since 100347 was 100064, checked in by vboxsync, 19 months ago

FE/Qt: bugref:10421. Replacing VBOX_WS_X11 with VBOX_WS_NIX.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 61.1 KB
Line 
1/* $Id: UIMenuBarEditorWindow.cpp 100064 2023-06-04 09:10:01Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMenuBarEditorWindow class implementation.
4 */
5
6/*
7 * Copyright (C) 2014-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QAccessibleWidget>
30#include <QHBoxLayout>
31#include <QMenu>
32#include <QMenuBar>
33#include <QMetaEnum>
34#include <QPainter>
35#include <QPaintEvent>
36#include <QStyleOptionToolButton>
37#ifndef VBOX_WS_MAC
38# include <QCheckBox>
39#endif
40
41/* GUI includes: */
42#include "QIToolButton.h"
43#include "UICommon.h"
44#include "UIActionPoolRuntime.h"
45#include "UIConverter.h"
46#include "UIExtraDataManager.h"
47#include "UIIconPool.h"
48#include "UIMachineWindow.h"
49#include "UIMenuBarEditorWindow.h"
50#include "QIToolBar.h"
51
52/* Forward declarations: */
53class QAccessibleInterface;
54class QRect;
55class UIAccessibilityInterfaceForUIMenuBarEditorButton;
56
57
58/** Menu-bar editor button segment types. */
59enum UIMenuBarEditorSegment
60{
61 UIMenuBarEditorSegment_Button,
62 UIMenuBarEditorSegment_Menu,
63 UIMenuBarEditorSegment_Max,
64};
65
66
67/** QAccessibleWidget extension used as an accessibility interface for UIMenuBarEditor button segments. */
68class UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment : public QAccessibleInterface
69{
70public:
71
72 /** Constructs an accessibility interface.
73 * @param pParent Brings the parent interface we are linked to.
74 * @param enmIndex Brings the index of segment we are referring to. */
75 UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment(UIAccessibilityInterfaceForUIMenuBarEditorButton *pParent,
76 UIMenuBarEditorSegment enmIndex);
77
78 /** Returns whether the interface is valid. */
79 virtual bool isValid() const RT_OVERRIDE { return true; }
80
81 /** Returns the wrapped object. */
82 virtual QObject *object() const RT_OVERRIDE { return 0; }
83 /** Returns the parent. */
84 virtual QAccessibleInterface *parent() const RT_OVERRIDE;
85
86 /** Returns the number of children. */
87 virtual int childCount() const RT_OVERRIDE { return 0; }
88 /** Returns the child with the passed @a iIndex. */
89 virtual QAccessibleInterface *child(int /* iIndex */) const RT_OVERRIDE { return 0; }
90 /** Returns the child at position QPoint(@a x, @a y). */
91 virtual QAccessibleInterface *childAt(int /* x */, int /* y */) const RT_OVERRIDE { return 0; }
92 /** Returns the index of the passed @a pChild. */
93 virtual int indexOfChild(const QAccessibleInterface * /* pChild */) const RT_OVERRIDE { return -1; }
94
95 /** Returns the rect. */
96 virtual QRect rect() const RT_OVERRIDE;
97
98 /** Defines a @a strText for the passed @a enmTextRole. */
99 virtual void setText(QAccessible::Text /* enmTextRole */, const QString & /* strText */) RT_OVERRIDE {}
100 /** Returns a text for the passed @a enmTextRole. */
101 virtual QString text(QAccessible::Text /* enmTextRole */) const RT_OVERRIDE;
102
103 /** Returns the role. */
104 virtual QAccessible::Role role() const RT_OVERRIDE { return QAccessible::Button; }
105 /** Returns the state. */
106 virtual QAccessible::State state() const RT_OVERRIDE { return QAccessible::State(); }
107
108private:
109
110 /** Holds the parent interface we are linked to. */
111 UIAccessibilityInterfaceForUIMenuBarEditorButton *m_pParent;
112
113 /** Holds the index of segment we are referring to. */
114 const UIMenuBarEditorSegment m_enmIndex;
115};
116
117
118/** QAccessibleWidget extension used as an accessibility interface for UIMenuBarEditor buttons. */
119class UIAccessibilityInterfaceForUIMenuBarEditorButton : public QAccessibleWidget
120{
121public:
122
123 /** Returns an accessibility interface for passed @a strClassname and @a pObject. */
124 static QAccessibleInterface *pFactory(const QString &strClassname, QObject *pObject);
125
126 /** Constructs an accessibility interface passing @a pWidget to the base-class. */
127 UIAccessibilityInterfaceForUIMenuBarEditorButton(QWidget *pWidget);
128 /** Destructs an accessibility interface. */
129 ~UIAccessibilityInterfaceForUIMenuBarEditorButton();
130
131 /** Returns the number of children. */
132 virtual int childCount() const RT_OVERRIDE;
133 /** Returns the child with the passed @a iIndex. */
134 virtual QAccessibleInterface *child(int iIndex) const RT_OVERRIDE;
135
136 /** Returns the role. */
137 virtual QAccessible::Role role() const RT_OVERRIDE;
138
139 /** Returns the rect of sub-element @a enmSegment. */
140 QRect subRect(UIMenuBarEditorSegment enmSegment) const;
141 /** Returns the text of sub-element @a enmSegment. */
142 QString subText(UIMenuBarEditorSegment enmSegment) const;
143
144private:
145
146 /** Returns corresponding toolbar button. */
147 QToolButton *button() const { return qobject_cast<QToolButton*>(widget()); }
148
149 /** Holds the map of instances of sub-element interfaces. */
150 QMap<UIMenuBarEditorSegment, UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment*> m_elements;
151};
152
153
154/*********************************************************************************************************************************
155* Class UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment implementation. *
156*********************************************************************************************************************************/
157
158UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment::UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment(
159 UIAccessibilityInterfaceForUIMenuBarEditorButton *pParent,
160 UIMenuBarEditorSegment enmIndex)
161 : m_pParent(pParent)
162 , m_enmIndex(enmIndex)
163{
164}
165
166QAccessibleInterface *UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment::parent() const
167{
168 return m_pParent;
169}
170
171QRect UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment::rect() const
172{
173 return m_pParent->subRect(m_enmIndex);
174}
175
176QString UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment::text(QAccessible::Text) const
177{
178 return m_pParent->subText(m_enmIndex);
179}
180
181
182/*********************************************************************************************************************************
183* Class UIAccessibilityInterfaceForUIMenuBarEditorButton implementation. *
184*********************************************************************************************************************************/
185
186/* static */
187QAccessibleInterface *UIAccessibilityInterfaceForUIMenuBarEditorButton::pFactory(const QString &strClassname, QObject *pObject)
188{
189 /* Creating toolbar button accessibility interface: */
190 if ( pObject
191 && strClassname == QLatin1String("QToolButton")
192 && pObject->property("Belongs to") == "UIMenuBarEditorWidget")
193 return new UIAccessibilityInterfaceForUIMenuBarEditorButton(qobject_cast<QWidget*>(pObject));
194
195 /* Null by default: */
196 return 0;
197}
198
199UIAccessibilityInterfaceForUIMenuBarEditorButton::UIAccessibilityInterfaceForUIMenuBarEditorButton(QWidget *pWidget)
200 : QAccessibleWidget(pWidget, QAccessible::Button)
201{
202 /* Prepare button with popup menu: */
203 if (button()->popupMode() == QToolButton::MenuButtonPopup)
204 {
205 for (int iIndex = 0; iIndex < (int)UIMenuBarEditorSegment_Max; ++iIndex)
206 m_elements[(UIMenuBarEditorSegment)iIndex] =
207 new UIAccessibilityInterfaceForUIMenuBarEditorButtonSegment(this, (UIMenuBarEditorSegment)iIndex);
208 }
209}
210
211UIAccessibilityInterfaceForUIMenuBarEditorButton::~UIAccessibilityInterfaceForUIMenuBarEditorButton()
212{
213 /* Cleanup button with popup menu: */
214 qDeleteAll(m_elements);
215 m_elements.clear();
216}
217
218int UIAccessibilityInterfaceForUIMenuBarEditorButton::childCount() const
219{
220 /* Sanity check: */
221 AssertPtrReturn(button(), 0);
222
223 /* Return child count for a button with popup menu: */
224 if (button()->popupMode() == QToolButton::MenuButtonPopup)
225 return UIMenuBarEditorSegment_Max;
226
227 /* Call to base-class: */
228 return QAccessibleWidget::childCount();
229}
230
231QAccessibleInterface *UIAccessibilityInterfaceForUIMenuBarEditorButton::child(int iIndex) const
232{
233 /* Sanity check: */
234 AssertPtrReturn(button(), 0);
235 AssertReturn(iIndex >= 0 && iIndex < childCount(), 0);
236
237 /* Return the child with the passed iIndex for a button with popup menu: */
238 if (button()->popupMode() == QToolButton::MenuButtonPopup)
239 return m_elements.value((UIMenuBarEditorSegment)iIndex);
240
241 /* Call to base-class: */
242 return QAccessibleWidget::child(iIndex);
243}
244
245QAccessible::Role UIAccessibilityInterfaceForUIMenuBarEditorButton::role() const
246{
247 /* Sanity check: */
248 AssertPtrReturn(button(), QAccessibleWidget::role());
249
250 /* Return role for button with popup menu: */
251 if (button()->popupMode() == QToolButton::MenuButtonPopup)
252 return QAccessible::ToolBar;
253
254 /* Call to base-class: */
255 return QAccessibleWidget::role();
256}
257
258QRect UIAccessibilityInterfaceForUIMenuBarEditorButton::subRect(UIMenuBarEditorSegment enmSegment) const
259{
260 /* Sanity check: */
261 AssertReturn(button()->popupMode() == QToolButton::MenuButtonPopup, QRect());
262
263 /* Return the rect of segment with the passed enmIndex for a button with popup menu: */
264 switch (enmSegment)
265 {
266 case UIMenuBarEditorSegment_Button:
267 {
268 QStyleOptionToolButton options;
269 options.initFrom(button());
270 options.features |= QStyleOptionToolButton::MenuButtonPopup;
271 QRect rect = button()->style()->subControlRect(QStyle::CC_ToolButton, &options, QStyle::SC_ToolButton);
272 rect.moveTo(button()->mapToGlobal(rect.topLeft()));
273 return rect;
274 }
275 case UIMenuBarEditorSegment_Menu:
276 {
277 QStyleOptionToolButton options;
278 options.initFrom(button());
279 options.features |= QStyleOptionToolButton::MenuButtonPopup;
280 QRect rect = button()->style()->subControlRect(QStyle::CC_ToolButton, &options, QStyle::SC_ToolButtonMenu);
281 rect.moveTo(button()->mapToGlobal(rect.topLeft()));
282 return rect;
283 }
284 default:
285 break;
286 }
287
288 /* Null rect by default: */
289 return QRect();
290}
291
292QString UIAccessibilityInterfaceForUIMenuBarEditorButton::subText(UIMenuBarEditorSegment enmSegment) const
293{
294 /* Sanity check: */
295 AssertReturn(button()->popupMode() == QToolButton::MenuButtonPopup, QString());
296
297 /* Return the text of segment with the passed enmIndex for a button with popup menu: */
298 switch (enmSegment)
299 {
300 case UIMenuBarEditorSegment_Button:
301 return UIMenuBarEditorWidget::tr("Toggle menu %1").arg(QAccessibleWidget::text(QAccessible::Description));
302 case UIMenuBarEditorSegment_Menu:
303 return UIMenuBarEditorWidget::tr("Popup menu %1").arg(QAccessibleWidget::text(QAccessible::Description));
304 default:
305 break;
306 }
307
308 /* Null string by default: */
309 return QString();
310}
311
312
313/*********************************************************************************************************************************
314* Class UIMenuBarEditorWindow implementation. *
315*********************************************************************************************************************************/
316
317UIMenuBarEditorWindow::UIMenuBarEditorWindow(UIMachineWindow *pParent, UIActionPool *pActionPool)
318#ifndef VBOX_WS_MAC
319 : UISlidingToolBar(pParent, pParent->menuBar(), new UIMenuBarEditorWidget(0, false, uiCommon().managedVMUuid(), pActionPool), UISlidingToolBar::Position_Top)
320#else
321 : UISlidingToolBar(pParent, 0, new UIMenuBarEditorWidget(0, false, uiCommon().managedVMUuid(), pActionPool), UISlidingToolBar::Position_Top)
322#endif
323{
324}
325
326
327/*********************************************************************************************************************************
328* Class UIMenuBarEditorWidget implementation. *
329*********************************************************************************************************************************/
330
331UIMenuBarEditorWidget::UIMenuBarEditorWidget(QWidget *pParent,
332 bool fStartedFromVMSettings /* = true */,
333 const QUuid &uMachineID /* = QUuid() */,
334 UIActionPool *pActionPool /* = 0 */)
335 : QIWithRetranslateUI2<QWidget>(pParent)
336 , m_fPrepared(false)
337 , m_fStartedFromVMSettings(fStartedFromVMSettings)
338 , m_uMachineID(uMachineID)
339 , m_pActionPool(pActionPool)
340 , m_pMainLayout(0)
341 , m_pToolBar(0)
342 , m_pButtonClose(0)
343#ifndef VBOX_WS_MAC
344 , m_pCheckBoxEnable(0)
345#endif
346 , m_restrictionsOfMenuBar(UIExtraDataMetaDefs::MenuType_Invalid)
347 , m_restrictionsOfMenuApplication(UIExtraDataMetaDefs::MenuApplicationActionType_Invalid)
348 , m_restrictionsOfMenuMachine(UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Invalid)
349 , m_restrictionsOfMenuView(UIExtraDataMetaDefs::RuntimeMenuViewActionType_Invalid)
350 , m_restrictionsOfMenuInput(UIExtraDataMetaDefs::RuntimeMenuInputActionType_Invalid)
351 , m_restrictionsOfMenuDevices(UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_Invalid)
352#ifdef VBOX_WITH_DEBUGGER_GUI
353 , m_restrictionsOfMenuDebug(UIExtraDataMetaDefs::RuntimeMenuDebuggerActionType_Invalid)
354#endif
355#ifdef VBOX_WS_MAC
356 , m_restrictionsOfMenuWindow(UIExtraDataMetaDefs::MenuWindowActionType_Invalid)
357#endif
358 , m_restrictionsOfMenuHelp(UIExtraDataMetaDefs::MenuHelpActionType_Invalid)
359
360{
361 /* Prepare: */
362 prepare();
363}
364
365void UIMenuBarEditorWidget::setMachineID(const QUuid &uMachineID)
366{
367 /* Remember new machine ID: */
368 m_uMachineID = uMachineID;
369 /* Prepare: */
370 prepare();
371}
372
373void UIMenuBarEditorWidget::setActionPool(UIActionPool *pActionPool)
374{
375 /* Remember new action-pool: */
376 m_pActionPool = pActionPool;
377 /* Prepare: */
378 prepare();
379}
380
381#ifndef VBOX_WS_MAC
382bool UIMenuBarEditorWidget::isMenuBarEnabled() const
383{
384 /* For VM settings only: */
385 AssertReturn(m_fStartedFromVMSettings, false);
386
387 /* Acquire enable-checkbox if possible: */
388 AssertPtrReturn(m_pCheckBoxEnable, false);
389 return m_pCheckBoxEnable->isChecked();
390}
391
392void UIMenuBarEditorWidget::setMenuBarEnabled(bool fEnabled)
393{
394 /* For VM settings only: */
395 AssertReturnVoid(m_fStartedFromVMSettings);
396
397 /* Update enable-checkbox if possible: */
398 AssertPtrReturnVoid(m_pCheckBoxEnable);
399 m_pCheckBoxEnable->setChecked(fEnabled);
400}
401#endif /* !VBOX_WS_MAC */
402
403void UIMenuBarEditorWidget::setRestrictionsOfMenuBar(UIExtraDataMetaDefs::MenuType restrictions)
404{
405 /* Cache passed restrictions: */
406 m_restrictionsOfMenuBar = restrictions;
407 /* Get static meta-object: */
408 const QMetaObject &smo = UIExtraDataMetaDefs::staticMetaObject;
409
410 /* We have UIExtraDataMetaDefs::MenuType enum registered, so we can enumerate it: */
411 const int iEnumIndex = smo.indexOfEnumerator("MenuType");
412 const QMetaEnum metaEnum = smo.enumerator(iEnumIndex);
413 /* Handle other enum-values: */
414 for (int iKeyIndex = 0; iKeyIndex < metaEnum.keyCount(); ++iKeyIndex)
415 {
416 /* Get iterated enum-value: */
417 const UIExtraDataMetaDefs::MenuType enumValue =
418 static_cast<UIExtraDataMetaDefs::MenuType>(metaEnum.keyToValue(metaEnum.key(iKeyIndex)));
419 /* Skip MenuType_Invalid & MenuType_All enum-value: */
420 if (enumValue == UIExtraDataMetaDefs::MenuType_Invalid ||
421 enumValue == UIExtraDataMetaDefs::MenuType_All)
422 continue;
423 /* Which key required action registered under? */
424 const QString strKey = gpConverter->toInternalString(enumValue);
425 if (!m_actions.contains(strKey))
426 continue;
427 /* Update action 'checked' state: */
428 m_actions.value(strKey)->setChecked(!(m_restrictionsOfMenuBar & enumValue));
429 }
430}
431
432void UIMenuBarEditorWidget::setRestrictionsOfMenuApplication(UIExtraDataMetaDefs::MenuApplicationActionType restrictions)
433{
434 /* Cache passed restrictions: */
435 m_restrictionsOfMenuApplication = restrictions;
436 /* Get static meta-object: */
437 const QMetaObject &smo = UIExtraDataMetaDefs::staticMetaObject;
438
439 /* We have UIExtraDataMetaDefs::MenuApplicationActionType enum registered, so we can enumerate it: */
440 const int iEnumIndex = smo.indexOfEnumerator("MenuApplicationActionType");
441 QMetaEnum metaEnum = smo.enumerator(iEnumIndex);
442 /* Handle other enum-values: */
443 for (int iKeyIndex = 0; iKeyIndex < metaEnum.keyCount(); ++iKeyIndex)
444 {
445 /* Get iterated enum-value: */
446 const UIExtraDataMetaDefs::MenuApplicationActionType enumValue =
447 static_cast<UIExtraDataMetaDefs::MenuApplicationActionType>(metaEnum.keyToValue(metaEnum.key(iKeyIndex)));
448 /* Skip MenuApplicationActionType_Invalid & MenuApplicationActionType_All enum-value: */
449 if (enumValue == UIExtraDataMetaDefs::MenuApplicationActionType_Invalid ||
450 enumValue == UIExtraDataMetaDefs::MenuApplicationActionType_All)
451 continue;
452 /* Which key required action registered under? */
453 const QString strKey = gpConverter->toInternalString(enumValue);
454 if (!m_actions.contains(strKey))
455 continue;
456 /* Update action 'checked' state: */
457 m_actions.value(strKey)->setChecked(!(m_restrictionsOfMenuApplication & enumValue));
458 }
459}
460
461void UIMenuBarEditorWidget::setRestrictionsOfMenuMachine(UIExtraDataMetaDefs::RuntimeMenuMachineActionType restrictions)
462{
463 /* Cache passed restrictions: */
464 m_restrictionsOfMenuMachine = restrictions;
465 /* Get static meta-object: */
466 const QMetaObject &smo = UIExtraDataMetaDefs::staticMetaObject;
467
468 /* We have UIExtraDataMetaDefs::RuntimeMenuMachineActionType enum registered, so we can enumerate it: */
469 const int iEnumIndex = smo.indexOfEnumerator("RuntimeMenuMachineActionType");
470 QMetaEnum metaEnum = smo.enumerator(iEnumIndex);
471 /* Handle other enum-values: */
472 for (int iKeyIndex = 0; iKeyIndex < metaEnum.keyCount(); ++iKeyIndex)
473 {
474 /* Get iterated enum-value: */
475 const UIExtraDataMetaDefs::RuntimeMenuMachineActionType enumValue =
476 static_cast<UIExtraDataMetaDefs::RuntimeMenuMachineActionType>(metaEnum.keyToValue(metaEnum.key(iKeyIndex)));
477 /* Skip RuntimeMenuMachineActionType_Invalid & RuntimeMenuMachineActionType_All enum-value: */
478 if (enumValue == UIExtraDataMetaDefs::RuntimeMenuMachineActionType_Invalid ||
479 enumValue == UIExtraDataMetaDefs::RuntimeMenuMachineActionType_All)
480 continue;
481 /* Which key required action registered under? */
482 const QString strKey = gpConverter->toInternalString(enumValue);
483 if (!m_actions.contains(strKey))
484 continue;
485 /* Update action 'checked' state: */
486 m_actions.value(strKey)->setChecked(!(m_restrictionsOfMenuMachine & enumValue));
487 }
488}
489
490void UIMenuBarEditorWidget::setRestrictionsOfMenuView(UIExtraDataMetaDefs::RuntimeMenuViewActionType restrictions)
491{
492 /* Cache passed restrictions: */
493 m_restrictionsOfMenuView = restrictions;
494 /* Get static meta-object: */
495 const QMetaObject &smo = UIExtraDataMetaDefs::staticMetaObject;
496
497 /* We have UIExtraDataMetaDefs::RuntimeMenuViewActionType enum registered, so we can enumerate it: */
498 const int iEnumIndex = smo.indexOfEnumerator("RuntimeMenuViewActionType");
499 QMetaEnum metaEnum = smo.enumerator(iEnumIndex);
500 /* Handle other enum-values: */
501 for (int iKeyIndex = 0; iKeyIndex < metaEnum.keyCount(); ++iKeyIndex)
502 {
503 /* Get iterated enum-value: */
504 const UIExtraDataMetaDefs::RuntimeMenuViewActionType enumValue =
505 static_cast<UIExtraDataMetaDefs::RuntimeMenuViewActionType>(metaEnum.keyToValue(metaEnum.key(iKeyIndex)));
506 /* Skip RuntimeMenuViewActionType_Invalid & RuntimeMenuViewActionType_All enum-value: */
507 if (enumValue == UIExtraDataMetaDefs::RuntimeMenuViewActionType_Invalid ||
508 enumValue == UIExtraDataMetaDefs::RuntimeMenuViewActionType_All)
509 continue;
510 /* Which key required action registered under? */
511 const QString strKey = gpConverter->toInternalString(enumValue);
512 if (!m_actions.contains(strKey))
513 continue;
514 /* Update action 'checked' state: */
515 m_actions.value(strKey)->setChecked(!(m_restrictionsOfMenuView & enumValue));
516 }
517}
518
519void UIMenuBarEditorWidget::setRestrictionsOfMenuInput(UIExtraDataMetaDefs::RuntimeMenuInputActionType restrictions)
520{
521 /* Cache passed restrictions: */
522 m_restrictionsOfMenuInput = restrictions;
523 /* Get static meta-object: */
524 const QMetaObject &smo = UIExtraDataMetaDefs::staticMetaObject;
525
526 /* We have UIExtraDataMetaDefs::RuntimeMenuInputActionType enum registered, so we can enumerate it: */
527 const int iEnumIndex = smo.indexOfEnumerator("RuntimeMenuInputActionType");
528 QMetaEnum metaEnum = smo.enumerator(iEnumIndex);
529 /* Handle other enum-values: */
530 for (int iKeyIndex = 0; iKeyIndex < metaEnum.keyCount(); ++iKeyIndex)
531 {
532 /* Get iterated enum-value: */
533 const UIExtraDataMetaDefs::RuntimeMenuInputActionType enumValue =
534 static_cast<UIExtraDataMetaDefs::RuntimeMenuInputActionType>(metaEnum.keyToValue(metaEnum.key(iKeyIndex)));
535 /* Skip RuntimeMenuInputActionType_Invalid & RuntimeMenuInputActionType_All enum-value: */
536 if (enumValue == UIExtraDataMetaDefs::RuntimeMenuInputActionType_Invalid ||
537 enumValue == UIExtraDataMetaDefs::RuntimeMenuInputActionType_All)
538 continue;
539 /* Which key required action registered under? */
540 const QString strKey = gpConverter->toInternalString(enumValue);
541 if (!m_actions.contains(strKey))
542 continue;
543 /* Update action 'checked' state: */
544 m_actions.value(strKey)->setChecked(!(m_restrictionsOfMenuInput & enumValue));
545 }
546}
547
548void UIMenuBarEditorWidget::setRestrictionsOfMenuDevices(UIExtraDataMetaDefs::RuntimeMenuDevicesActionType restrictions)
549{
550 /* Cache passed restrictions: */
551 m_restrictionsOfMenuDevices = restrictions;
552 /* Get static meta-object: */
553 const QMetaObject &smo = UIExtraDataMetaDefs::staticMetaObject;
554
555 /* We have UIExtraDataMetaDefs::RuntimeMenuDevicesActionType enum registered, so we can enumerate it: */
556 const int iEnumIndex = smo.indexOfEnumerator("RuntimeMenuDevicesActionType");
557 QMetaEnum metaEnum = smo.enumerator(iEnumIndex);
558 /* Handle other enum-values: */
559 for (int iKeyIndex = 0; iKeyIndex < metaEnum.keyCount(); ++iKeyIndex)
560 {
561 /* Get iterated enum-value: */
562 const UIExtraDataMetaDefs::RuntimeMenuDevicesActionType enumValue =
563 static_cast<UIExtraDataMetaDefs::RuntimeMenuDevicesActionType>(metaEnum.keyToValue(metaEnum.key(iKeyIndex)));
564 /* Skip RuntimeMenuDevicesActionType_Invalid & RuntimeMenuDevicesActionType_All enum-value: */
565 if (enumValue == UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_Invalid ||
566 enumValue == UIExtraDataMetaDefs::RuntimeMenuDevicesActionType_All)
567 continue;
568 /* Which key required action registered under? */
569 const QString strKey = gpConverter->toInternalString(enumValue);
570 if (!m_actions.contains(strKey))
571 continue;
572 /* Update action 'checked' state: */
573 m_actions.value(strKey)->setChecked(!(m_restrictionsOfMenuDevices & enumValue));
574 }
575}
576
577#ifdef VBOX_WITH_DEBUGGER_GUI
578void UIMenuBarEditorWidget::setRestrictionsOfMenuDebug(UIExtraDataMetaDefs::RuntimeMenuDebuggerActionType restrictions)
579{
580 /* Cache passed restrictions: */
581 m_restrictionsOfMenuDebug = restrictions;
582 /* Get static meta-object: */
583 const QMetaObject &smo = UIExtraDataMetaDefs::staticMetaObject;
584
585 /* We have UIExtraDataMetaDefs::RuntimeMenuDebuggerActionType enum registered, so we can enumerate it: */
586 const int iEnumIndex = smo.indexOfEnumerator("RuntimeMenuDebuggerActionType");
587 QMetaEnum metaEnum = smo.enumerator(iEnumIndex);
588 /* Handle other enum-values: */
589 for (int iKeyIndex = 0; iKeyIndex < metaEnum.keyCount(); ++iKeyIndex)
590 {
591 /* Get iterated enum-value: */
592 const UIExtraDataMetaDefs::RuntimeMenuDebuggerActionType enumValue =
593 static_cast<UIExtraDataMetaDefs::RuntimeMenuDebuggerActionType>(metaEnum.keyToValue(metaEnum.key(iKeyIndex)));
594 /* Skip RuntimeMenuDebuggerActionType_Invalid & RuntimeMenuDebuggerActionType_All enum-value: */
595 if (enumValue == UIExtraDataMetaDefs::RuntimeMenuDebuggerActionType_Invalid ||
596 enumValue == UIExtraDataMetaDefs::RuntimeMenuDebuggerActionType_All)
597 continue;
598 /* Which key required action registered under? */
599 const QString strKey = gpConverter->toInternalString(enumValue);
600 if (!m_actions.contains(strKey))
601 continue;
602 /* Update action 'checked' state: */
603 m_actions.value(strKey)->setChecked(!(m_restrictionsOfMenuDebug & enumValue));
604 }
605}
606#endif /* VBOX_WITH_DEBUGGER_GUI */
607
608#ifdef VBOX_WS_MAC
609void UIMenuBarEditorWidget::setRestrictionsOfMenuWindow(UIExtraDataMetaDefs::MenuWindowActionType restrictions)
610{
611 /* Cache passed restrictions: */
612 m_restrictionsOfMenuWindow = restrictions;
613 /* Get static meta-object: */
614 const QMetaObject &smo = UIExtraDataMetaDefs::staticMetaObject;
615
616 /* We have UIExtraDataMetaDefs::MenuWindowActionType enum registered, so we can enumerate it: */
617 const int iEnumIndex = smo.indexOfEnumerator("MenuWindowActionType");
618 QMetaEnum metaEnum = smo.enumerator(iEnumIndex);
619 /* Handle other enum-values: */
620 for (int iKeyIndex = 0; iKeyIndex < metaEnum.keyCount(); ++iKeyIndex)
621 {
622 /* Get iterated enum-value: */
623 const UIExtraDataMetaDefs::MenuWindowActionType enumValue =
624 static_cast<const UIExtraDataMetaDefs::MenuWindowActionType>(metaEnum.keyToValue(metaEnum.key(iKeyIndex)));
625 /* Skip MenuWindowActionType_Invalid & MenuWindowActionType_All enum-value: */
626 if (enumValue == UIExtraDataMetaDefs::MenuWindowActionType_Invalid ||
627 enumValue == UIExtraDataMetaDefs::MenuWindowActionType_All)
628 continue;
629 /* Which key required action registered under? */
630 const QString strKey = gpConverter->toInternalString(enumValue);
631 if (!m_actions.contains(strKey))
632 continue;
633 /* Update action 'checked' state: */
634 m_actions.value(strKey)->setChecked(!(m_restrictionsOfMenuWindow & enumValue));
635 }
636}
637#endif /* VBOX_WS_MAC */
638
639void UIMenuBarEditorWidget::setRestrictionsOfMenuHelp(UIExtraDataMetaDefs::MenuHelpActionType restrictions)
640{
641 /* Cache passed restrictions: */
642 m_restrictionsOfMenuHelp = restrictions;
643 /* Get static meta-object: */
644 const QMetaObject &smo = UIExtraDataMetaDefs::staticMetaObject;
645
646 /* We have UIExtraDataMetaDefs::MenuHelpActionType enum registered, so we can enumerate it: */
647 const int iEnumIndex = smo.indexOfEnumerator("MenuHelpActionType");
648 QMetaEnum metaEnum = smo.enumerator(iEnumIndex);
649 /* Handle other enum-values: */
650 for (int iKeyIndex = 0; iKeyIndex < metaEnum.keyCount(); ++iKeyIndex)
651 {
652 /* Get iterated enum-value: */
653 const UIExtraDataMetaDefs::MenuHelpActionType enumValue =
654 static_cast<UIExtraDataMetaDefs::MenuHelpActionType>(metaEnum.keyToValue(metaEnum.key(iKeyIndex)));
655 /* Skip MenuHelpActionType_Invalid & MenuHelpActionType_All enum-value: */
656 if (enumValue == UIExtraDataMetaDefs::MenuHelpActionType_Invalid ||
657 enumValue == UIExtraDataMetaDefs::MenuHelpActionType_All)
658 continue;
659 /* Which key required action registered under? */
660 const QString strKey = gpConverter->toInternalString(enumValue);
661 if (!m_actions.contains(strKey))
662 continue;
663 /* Update action 'checked' state: */
664 m_actions.value(strKey)->setChecked(!(m_restrictionsOfMenuHelp & enumValue));
665 }
666}
667
668void UIMenuBarEditorWidget::retranslateUi()
669{
670 /* Translate widget itself: */
671 setToolTip(tr("Allows to modify VM menu-bar contents."));
672
673 /* Translate close-button if necessary: */
674 if (!m_fStartedFromVMSettings && m_pButtonClose)
675 m_pButtonClose->setToolTip(tr("Close"));
676#ifndef VBOX_WS_MAC
677 /* Translate enable-checkbox if necessary: */
678 if (m_fStartedFromVMSettings && m_pCheckBoxEnable)
679 m_pCheckBoxEnable->setToolTip(tr("Enable Menu Bar"));
680#endif
681}
682
683void UIMenuBarEditorWidget::paintEvent(QPaintEvent *)
684{
685 /* Prepare painter: */
686 QPainter painter(this);
687
688 /* Prepare palette colors: */
689 const QPalette pal = QApplication::palette();
690 QColor color0 = pal.color(QPalette::Window);
691 QColor color1 = pal.color(QPalette::Window).lighter(110);
692 color1.setAlpha(0);
693 QColor color2 = pal.color(QPalette::Window).darker(200);
694#if defined(VBOX_WS_WIN) || defined(VBOX_WS_NIX)
695 QColor color3 = pal.color(QPalette::Window).darker(120);
696#endif /* VBOX_WS_WIN || VBOX_WS_NIX */
697
698 /* Acquire metric: */
699 const int iMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4;
700
701 /* Left corner: */
702 QRadialGradient grad1(QPointF(iMetric, height() - iMetric), iMetric);
703 {
704 grad1.setColorAt(0, color2);
705 grad1.setColorAt(1, color1);
706 }
707 /* Right corner: */
708 QRadialGradient grad2(QPointF(width() - iMetric, height() - iMetric), iMetric);
709 {
710 grad2.setColorAt(0, color2);
711 grad2.setColorAt(1, color1);
712 }
713 /* Bottom line: */
714 QLinearGradient grad3(QPointF(iMetric, height()), QPointF(iMetric, height() - iMetric));
715 {
716 grad3.setColorAt(0, color1);
717 grad3.setColorAt(1, color2);
718 }
719 /* Left line: */
720 QLinearGradient grad4(QPointF(0, height() - iMetric), QPointF(iMetric, height() - iMetric));
721 {
722 grad4.setColorAt(0, color1);
723 grad4.setColorAt(1, color2);
724 }
725 /* Right line: */
726 QLinearGradient grad5(QPointF(width(), height() - iMetric), QPointF(width() - iMetric, height() - iMetric));
727 {
728 grad5.setColorAt(0, color1);
729 grad5.setColorAt(1, color2);
730 }
731
732 /* Paint shape/shadow: */
733 painter.fillRect(QRect(iMetric, 0, width() - iMetric * 2, height() - iMetric), color0); // background
734 painter.fillRect(QRect(0, height() - iMetric, iMetric, iMetric), grad1); // left corner
735 painter.fillRect(QRect(width() - iMetric, height() - iMetric, iMetric, iMetric), grad2); // right corner
736 painter.fillRect(QRect(iMetric, height() - iMetric, width() - iMetric * 2, iMetric), grad3); // bottom line
737 painter.fillRect(QRect(0, 0, iMetric, height() - iMetric), grad4); // left line
738 painter.fillRect(QRect(width() - iMetric, 0, iMetric, height() - iMetric), grad5); // right line
739
740#if defined(VBOX_WS_WIN) || defined(VBOX_WS_NIX)
741 /* Paint frames: */
742 painter.save();
743 painter.setPen(color3);
744 painter.drawLine(QLine(QPoint(iMetric + 1, 0),
745 QPoint(iMetric + 1, height() - 1 - iMetric - 1)));
746 painter.drawLine(QLine(QPoint(iMetric + 1, height() - 1 - iMetric - 1),
747 QPoint(width() - 1 - iMetric - 1, height() - 1 - iMetric - 1)));
748 painter.drawLine(QLine(QPoint(width() - 1 - iMetric - 1, height() - 1 - iMetric - 1),
749 QPoint(width() - 1 - iMetric - 1, 0)));
750 if (m_fStartedFromVMSettings)
751 painter.drawLine(QLine(QPoint(width() - 1 - iMetric - 1, 0), QPoint(iMetric + 1, 0)));
752 painter.restore();
753#endif /* VBOX_WS_WIN || VBOX_WS_NIX */
754}
755
756void UIMenuBarEditorWidget::sltHandleConfigurationChange(const QUuid &uMachineID)
757{
758 /* Skip unrelated machine IDs: */
759 if (machineID() != uMachineID)
760 return;
761
762 /* Recache menu-bar configuration: */
763 setRestrictionsOfMenuBar(gEDataManager->restrictedRuntimeMenuTypes(machineID()));
764 setRestrictionsOfMenuApplication(gEDataManager->restrictedRuntimeMenuApplicationActionTypes(machineID()));
765 setRestrictionsOfMenuMachine(gEDataManager->restrictedRuntimeMenuMachineActionTypes(machineID()));
766 setRestrictionsOfMenuView(gEDataManager->restrictedRuntimeMenuViewActionTypes(machineID()));
767 setRestrictionsOfMenuInput(gEDataManager->restrictedRuntimeMenuInputActionTypes(machineID()));
768 setRestrictionsOfMenuDevices(gEDataManager->restrictedRuntimeMenuDevicesActionTypes(machineID()));
769#ifdef VBOX_WITH_DEBUGGER_GUI
770 setRestrictionsOfMenuDebug(gEDataManager->restrictedRuntimeMenuDebuggerActionTypes(machineID()));
771#endif
772#ifdef VBOX_WS_MAC
773 setRestrictionsOfMenuWindow(gEDataManager->restrictedRuntimeMenuWindowActionTypes(machineID()));
774#endif
775 setRestrictionsOfMenuHelp(gEDataManager->restrictedRuntimeMenuHelpActionTypes(machineID()));
776}
777
778void UIMenuBarEditorWidget::sltHandleMenuBarMenuClick()
779{
780 /* Make sure sender is valid: */
781 QAction *pAction = qobject_cast<QAction*>(sender());
782 AssertPtrReturnVoid(pAction);
783
784 /* Depending on triggered action class: */
785 switch (pAction->property("class").toInt())
786 {
787 case UIExtraDataMetaDefs::MenuType_All:
788 {
789 /* Get sender type: */
790 const UIExtraDataMetaDefs::MenuType enmType =
791 static_cast<UIExtraDataMetaDefs::MenuType>(pAction->property("type").toInt());
792 /* Invert restriction for sender type: */
793 m_restrictionsOfMenuBar = (UIExtraDataMetaDefs::MenuType)(m_restrictionsOfMenuBar ^ enmType);
794 if (m_fStartedFromVMSettings)
795 {
796 /* Reapply menu-bar restrictions from cache: */
797 setRestrictionsOfMenuBar(m_restrictionsOfMenuBar);
798 }
799 else
800 {
801 /* Save updated menu-bar restrictions: */
802 gEDataManager->setRestrictedRuntimeMenuTypes(m_restrictionsOfMenuBar, machineID());
803 }
804 break;
805 }
806 case UIExtraDataMetaDefs::MenuType_Application:
807 {
808 /* Get sender type: */
809 const UIExtraDataMetaDefs::MenuApplicationActionType enmType =
810 static_cast<UIExtraDataMetaDefs::MenuApplicationActionType>(pAction->property("type").toInt());
811 /* Invert restriction for sender type: */
812 m_restrictionsOfMenuApplication = (UIExtraDataMetaDefs::MenuApplicationActionType)(m_restrictionsOfMenuApplication ^ enmType);
813 if (m_fStartedFromVMSettings)
814 {
815 /* Reapply menu-bar restrictions from cache: */
816 setRestrictionsOfMenuApplication(m_restrictionsOfMenuApplication);
817 }
818 else
819 {
820 /* Save updated menu-bar restrictions: */
821 gEDataManager->setRestrictedRuntimeMenuApplicationActionTypes(m_restrictionsOfMenuApplication, machineID());
822 }
823 break;
824 }
825 case UIExtraDataMetaDefs::MenuType_Machine:
826 {
827 /* Get sender type: */
828 const UIExtraDataMetaDefs::RuntimeMenuMachineActionType enmType =
829 static_cast<UIExtraDataMetaDefs::RuntimeMenuMachineActionType>(pAction->property("type").toInt());
830 /* Invert restriction for sender type: */
831 m_restrictionsOfMenuMachine = (UIExtraDataMetaDefs::RuntimeMenuMachineActionType)(m_restrictionsOfMenuMachine ^ enmType);
832 if (m_fStartedFromVMSettings)
833 {
834 /* Reapply menu-bar restrictions from cache: */
835 setRestrictionsOfMenuMachine(m_restrictionsOfMenuMachine);
836 }
837 else
838 {
839 /* Save updated menu-bar restrictions: */
840 gEDataManager->setRestrictedRuntimeMenuMachineActionTypes(m_restrictionsOfMenuMachine, machineID());
841 }
842 break;
843 }
844 case UIExtraDataMetaDefs::MenuType_View:
845 {
846 /* Get sender type: */
847 const UIExtraDataMetaDefs::RuntimeMenuViewActionType enmType =
848 static_cast<UIExtraDataMetaDefs::RuntimeMenuViewActionType>(pAction->property("type").toInt());
849 /* Invert restriction for sender type: */
850 m_restrictionsOfMenuView = (UIExtraDataMetaDefs::RuntimeMenuViewActionType)(m_restrictionsOfMenuView ^ enmType);
851 if (m_fStartedFromVMSettings)
852 {
853 /* Reapply menu-bar restrictions from cache: */
854 setRestrictionsOfMenuView(m_restrictionsOfMenuView);
855 }
856 else
857 {
858 /* Save updated menu-bar restrictions: */
859 gEDataManager->setRestrictedRuntimeMenuViewActionTypes(m_restrictionsOfMenuView, machineID());
860 }
861 break;
862 }
863 case UIExtraDataMetaDefs::MenuType_Input:
864 {
865 /* Get sender type: */
866 const UIExtraDataMetaDefs::RuntimeMenuInputActionType enmType =
867 static_cast<UIExtraDataMetaDefs::RuntimeMenuInputActionType>(pAction->property("type").toInt());
868 /* Invert restriction for sender type: */
869 m_restrictionsOfMenuInput = (UIExtraDataMetaDefs::RuntimeMenuInputActionType)(m_restrictionsOfMenuInput ^ enmType);
870 if (m_fStartedFromVMSettings)
871 {
872 /* Reapply menu-bar restrictions from cache: */
873 setRestrictionsOfMenuInput(m_restrictionsOfMenuInput);
874 }
875 else
876 {
877 /* Save updated menu-bar restrictions: */
878 gEDataManager->setRestrictedRuntimeMenuInputActionTypes(m_restrictionsOfMenuInput, machineID());
879 }
880 break;
881 }
882 case UIExtraDataMetaDefs::MenuType_Devices:
883 {
884 /* Get sender type: */
885 const UIExtraDataMetaDefs::RuntimeMenuDevicesActionType enmType =
886 static_cast<UIExtraDataMetaDefs::RuntimeMenuDevicesActionType>(pAction->property("type").toInt());
887 /* Invert restriction for sender type: */
888 m_restrictionsOfMenuDevices = (UIExtraDataMetaDefs::RuntimeMenuDevicesActionType)(m_restrictionsOfMenuDevices ^ enmType);
889 if (m_fStartedFromVMSettings)
890 {
891 /* Reapply menu-bar restrictions from cache: */
892 setRestrictionsOfMenuDevices(m_restrictionsOfMenuDevices);
893 }
894 else
895 {
896 /* Save updated menu-bar restrictions: */
897 gEDataManager->setRestrictedRuntimeMenuDevicesActionTypes(m_restrictionsOfMenuDevices, machineID());
898 }
899 break;
900 }
901#ifdef VBOX_WITH_DEBUGGER_GUI
902 case UIExtraDataMetaDefs::MenuType_Debug:
903 {
904 /* Get sender type: */
905 const UIExtraDataMetaDefs::RuntimeMenuDebuggerActionType enmType =
906 static_cast<UIExtraDataMetaDefs::RuntimeMenuDebuggerActionType>(pAction->property("type").toInt());
907 /* Invert restriction for sender type: */
908 m_restrictionsOfMenuDebug = (UIExtraDataMetaDefs::RuntimeMenuDebuggerActionType)(m_restrictionsOfMenuDebug ^ enmType);
909 if (m_fStartedFromVMSettings)
910 {
911 /* Reapply menu-bar restrictions from cache: */
912 setRestrictionsOfMenuDebug(m_restrictionsOfMenuDebug);
913 }
914 else
915 {
916 /* Save updated menu-bar restrictions: */
917 gEDataManager->setRestrictedRuntimeMenuDebuggerActionTypes(m_restrictionsOfMenuDebug, machineID());
918 }
919 break;
920 }
921#endif /* VBOX_WITH_DEBUGGER_GUI */
922#ifdef VBOX_WS_MAC
923 case UIExtraDataMetaDefs::MenuType_Window:
924 {
925 /* Get sender type: */
926 const UIExtraDataMetaDefs::MenuWindowActionType enmType =
927 static_cast<UIExtraDataMetaDefs::MenuWindowActionType>(pAction->property("type").toInt());
928 /* Invert restriction for sender type: */
929 m_restrictionsOfMenuWindow = (UIExtraDataMetaDefs::MenuWindowActionType)(m_restrictionsOfMenuWindow ^ enmType);
930 if (m_fStartedFromVMSettings)
931 {
932 /* Reapply menu-bar restrictions from cache: */
933 setRestrictionsOfMenuWindow(m_restrictionsOfMenuWindow);
934 }
935 else
936 {
937 /* Save updated menu-bar restrictions: */
938 gEDataManager->setRestrictedRuntimeMenuWindowActionTypes(m_restrictionsOfMenuWindow, machineID());
939 }
940 break;
941 }
942#endif /* VBOX_WS_MAC */
943 case UIExtraDataMetaDefs::MenuType_Help:
944 {
945 /* Get sender type: */
946 const UIExtraDataMetaDefs::MenuHelpActionType enmType =
947 static_cast<UIExtraDataMetaDefs::MenuHelpActionType>(pAction->property("type").toInt());
948 /* Invert restriction for sender type: */
949 m_restrictionsOfMenuHelp = (UIExtraDataMetaDefs::MenuHelpActionType)(m_restrictionsOfMenuHelp ^ enmType);
950 if (m_fStartedFromVMSettings)
951 {
952 /* Reapply menu-bar restrictions from cache: */
953 setRestrictionsOfMenuHelp(m_restrictionsOfMenuHelp);
954 }
955 else
956 {
957 /* Save updated menu-bar restrictions: */
958 gEDataManager->setRestrictedRuntimeMenuHelpActionTypes(m_restrictionsOfMenuHelp, machineID());
959 } break;
960 }
961 default: break;
962 }
963}
964
965void UIMenuBarEditorWidget::prepare()
966{
967 /* Do nothing if already prepared: */
968 if (m_fPrepared)
969 return;
970
971 /* Do not prepare if machine ID or action-pool is not set: */
972 if (m_uMachineID.isNull() || !m_pActionPool)
973 return;
974
975 /* Install tool-bar button accessibility interface factory: */
976 QAccessible::installFactory(UIAccessibilityInterfaceForUIMenuBarEditorButton::pFactory);
977
978 /* Create main-layout: */
979 m_pMainLayout = new QHBoxLayout(this);
980 AssertPtrReturnVoid(m_pMainLayout);
981 {
982 /* Configure main-layout: */
983 int iLeft, iTop, iRight, iBottom;
984 m_pMainLayout->getContentsMargins(&iLeft, &iTop, &iRight, &iBottom);
985 /* Acquire metric: */
986 const int iStandardMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 2;
987 const int iMinimumMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4;
988 /* Standard margins should not be too small/large: */
989 iLeft = iStandardMetric;
990 iTop = iStandardMetric;
991 iRight = iStandardMetric;
992 iBottom = iStandardMetric;
993 /* Top margin should be smaller for the common case: */
994 if (iTop >= iMinimumMetric)
995 iTop -= iMinimumMetric;
996#ifndef VBOX_WS_MAC
997 /* Right margin should be bigger for the settings case: */
998 if (m_fStartedFromVMSettings)
999 iRight += iMinimumMetric;
1000#endif /* !VBOX_WS_MAC */
1001 /* Apply margins/spacing finally: */
1002 m_pMainLayout->setContentsMargins(iLeft, iTop, iRight, iBottom);
1003 m_pMainLayout->setSpacing(0);
1004 /* Create tool-bar: */
1005 m_pToolBar = new QIToolBar;
1006 AssertPtrReturnVoid(m_pToolBar);
1007 {
1008 /* Prepare menus: */
1009 prepareMenus();
1010 /* Add tool-bar into main-layout: */
1011 m_pMainLayout->addWidget(m_pToolBar);
1012 }
1013 /* Insert stretch: */
1014 m_pMainLayout->addStretch();
1015 /* Create close-button if necessary: */
1016 if (!m_fStartedFromVMSettings)
1017 {
1018 m_pButtonClose = new QIToolButton;
1019 AssertPtrReturnVoid(m_pButtonClose);
1020 {
1021 /* Configure close-button: */
1022 m_pButtonClose->setFocusPolicy(Qt::StrongFocus);
1023 m_pButtonClose->setShortcut(Qt::Key_Escape);
1024 m_pButtonClose->setIcon(UIIconPool::iconSet(":/ok_16px.png"));
1025 connect(m_pButtonClose, SIGNAL(clicked(bool)), this, SIGNAL(sigCancelClicked()));
1026 /* Add close-button into main-layout: */
1027 m_pMainLayout->addWidget(m_pButtonClose);
1028 }
1029 }
1030#ifndef VBOX_WS_MAC
1031 /* Create enable-checkbox if necessary: */
1032 else
1033 {
1034 m_pCheckBoxEnable = new QCheckBox;
1035 AssertPtrReturnVoid(m_pCheckBoxEnable);
1036 {
1037 /* Configure enable-checkbox: */
1038 m_pCheckBoxEnable->setFocusPolicy(Qt::StrongFocus);
1039 /* Add enable-checkbox into main-layout: */
1040 m_pMainLayout->addWidget(m_pCheckBoxEnable);
1041 }
1042 }
1043#endif /* !VBOX_WS_MAC */
1044 }
1045
1046 /* Mark as prepared: */
1047 m_fPrepared = true;
1048
1049 /* Translate contents: */
1050 retranslateUi();
1051}
1052
1053void UIMenuBarEditorWidget::prepareMenus()
1054{
1055 /* Create menus: */
1056 prepareMenuApplication();
1057 prepareMenuMachine();
1058 prepareMenuView();
1059 prepareMenuInput();
1060 prepareMenuDevices();
1061#ifdef VBOX_WITH_DEBUGGER_GUI
1062 prepareMenuDebug();
1063#endif
1064#ifdef VBOX_WS_MAC
1065 prepareMenuWindow();
1066#endif
1067 prepareMenuHelp();
1068
1069 if (!m_fStartedFromVMSettings)
1070 {
1071 /* Cache menu-bar configuration: */
1072 setRestrictionsOfMenuBar(gEDataManager->restrictedRuntimeMenuTypes(machineID()));
1073 setRestrictionsOfMenuApplication(gEDataManager->restrictedRuntimeMenuApplicationActionTypes(machineID()));
1074 setRestrictionsOfMenuMachine(gEDataManager->restrictedRuntimeMenuMachineActionTypes(machineID()));
1075 setRestrictionsOfMenuView(gEDataManager->restrictedRuntimeMenuViewActionTypes(machineID()));
1076 setRestrictionsOfMenuInput(gEDataManager->restrictedRuntimeMenuInputActionTypes(machineID()));
1077 setRestrictionsOfMenuDevices(gEDataManager->restrictedRuntimeMenuDevicesActionTypes(machineID()));
1078#ifdef VBOX_WITH_DEBUGGER_GUI
1079 setRestrictionsOfMenuDebug(gEDataManager->restrictedRuntimeMenuDebuggerActionTypes(machineID()));
1080#endif
1081#ifdef VBOX_WS_MAC
1082 setRestrictionsOfMenuWindow(gEDataManager->restrictedRuntimeMenuWindowActionTypes(machineID()));
1083#endif
1084 setRestrictionsOfMenuHelp(gEDataManager->restrictedRuntimeMenuHelpActionTypes(machineID()));
1085 /* And listen for the menu-bar configuration changes after that: */
1086 connect(gEDataManager, &UIExtraDataManager::sigMenuBarConfigurationChange,
1087 this, &UIMenuBarEditorWidget::sltHandleConfigurationChange);
1088 }
1089}
1090
1091#ifdef VBOX_WS_MAC
1092QMenu *UIMenuBarEditorWidget::prepareNamedMenu(const QString &strName)
1093{
1094 /* Create named menu: */
1095 QMenu *pNamedMenu = new QMenu(strName, m_pToolBar);
1096 AssertPtrReturn(pNamedMenu, 0);
1097 {
1098 /* Configure named menu: */
1099 pNamedMenu->setProperty("class", UIExtraDataMetaDefs::MenuType_Application);
1100 /* Get named menu action: */
1101 QAction *pNamedMenuAction = pNamedMenu->menuAction();
1102 AssertPtrReturn(pNamedMenuAction, 0);
1103 {
1104 /* Add menu action into tool-bar: */
1105 m_pToolBar->addAction(pNamedMenuAction);
1106 /* Get named menu tool-button: */
1107 QToolButton *pNamedMenuToolButton = qobject_cast<QToolButton*>(m_pToolBar->widgetForAction(pNamedMenuAction));
1108 AssertPtrReturn(pNamedMenuToolButton, 0);
1109 {
1110 /* Configure named menu tool-button: */
1111 pNamedMenuToolButton->setProperty("Belongs to", "UIMenuBarEditorWidget");
1112 pNamedMenuToolButton->setPopupMode(QToolButton::MenuButtonPopup);
1113 pNamedMenuToolButton->setAutoRaise(true);
1114 /* Update the accessibility interface to take "Belongs to" into account: */
1115 QAccessibleInterface *pInterface = QAccessible::queryAccessibleInterface(pNamedMenuToolButton);
1116 if (pInterface)
1117 {
1118 QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(pInterface));
1119 QAccessible::queryAccessibleInterface(pNamedMenuToolButton); // <= new one, proper..
1120 }
1121 /* Create spacing after named menu tool-button: */
1122 QWidget *pSpacing = new QWidget;
1123 AssertPtrReturn(pSpacing, 0);
1124 {
1125 /* Configure spacing: */
1126 pSpacing->setFixedSize(5, 1);
1127 /* Add spacing into tool-bar: */
1128 m_pToolBar->addWidget(pSpacing);
1129 }
1130 }
1131 }
1132 }
1133 /* Return named menu: */
1134 return pNamedMenu;
1135}
1136#endif /* VBOX_WS_MAC */
1137
1138QMenu *UIMenuBarEditorWidget::prepareCopiedMenu(const UIAction *pAction)
1139{
1140 /* Create copied menu: */
1141 QMenu *pCopiedMenu = new QMenu(pAction->name(), m_pToolBar);
1142 AssertPtrReturn(pCopiedMenu, 0);
1143 {
1144 /* Configure copied menu: */
1145 pCopiedMenu->setProperty("class", pAction->extraDataID());
1146 /* Get copied menu action: */
1147 QAction *pCopiedMenuAction = pCopiedMenu->menuAction();
1148 AssertPtrReturn(pCopiedMenuAction, 0);
1149 {
1150 /* Configure copied menu action: */
1151 pCopiedMenuAction->setCheckable(true);
1152 pCopiedMenuAction->setProperty("class", UIExtraDataMetaDefs::MenuType_All);
1153 pCopiedMenuAction->setProperty("type", pAction->extraDataID());
1154 connect(pCopiedMenuAction, &QAction::triggered, this, &UIMenuBarEditorWidget::sltHandleMenuBarMenuClick);
1155 m_actions.insert(pAction->extraDataKey(), pCopiedMenuAction);
1156 /* Add menu action into tool-bar: */
1157 m_pToolBar->addAction(pCopiedMenuAction);
1158 /* Get copied menu tool-button: */
1159 QToolButton *pCopiedMenuToolButton = qobject_cast<QToolButton*>(m_pToolBar->widgetForAction(pCopiedMenuAction));
1160 AssertPtrReturn(pCopiedMenuToolButton, 0);
1161 {
1162 /* Configure copied menu tool-button: */
1163 pCopiedMenuToolButton->setProperty("Belongs to", "UIMenuBarEditorWidget");
1164 pCopiedMenuToolButton->setPopupMode(QToolButton::MenuButtonPopup);
1165 pCopiedMenuToolButton->setAutoRaise(true);
1166 /* Update the accessibility interface to take "Belongs to" into account: */
1167 QAccessibleInterface *pInterface = QAccessible::queryAccessibleInterface(pCopiedMenuToolButton);
1168 if (pInterface)
1169 {
1170 QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(pInterface));
1171 QAccessible::queryAccessibleInterface(pCopiedMenuToolButton); // <= new one, proper..
1172 }
1173 /* Create spacing after copied menu tool-button: */
1174 QWidget *pSpacing = new QWidget;
1175 AssertPtrReturn(pSpacing, 0);
1176 {
1177 /* Configure spacing: */
1178 pSpacing->setFixedSize(5, 1);
1179 /* Add spacing into tool-bar: */
1180 m_pToolBar->addWidget(pSpacing);
1181 }
1182 }
1183 }
1184 }
1185 /* Return copied menu: */
1186 return pCopiedMenu;
1187}
1188
1189#if 0
1190QMenu *UIMenuBarEditorWidget::prepareCopiedSubMenu(QMenu *pMenu, const UIAction *pAction)
1191{
1192 /* Create copied sub-menu: */
1193 QMenu *pCopiedMenu = pMenu->addMenu(pAction->name());
1194 AssertPtrReturn(pCopiedMenu, 0);
1195 {
1196 /* Configure copied sub-menu: */
1197 pCopiedMenu->setProperty("class", pMenu->property("class"));
1198 /* Get copied sub-menu action: */
1199 QAction *pCopiedMenuAction = pCopiedMenu->menuAction();
1200 AssertPtrReturn(pCopiedMenuAction, 0);
1201 {
1202 /* Configure copied sub-menu: */
1203 pCopiedMenuAction->setCheckable(true);
1204 pCopiedMenuAction->setProperty("class", pCopiedMenu->property("class"));
1205 pCopiedMenuAction->setProperty("type", pAction->extraDataID());
1206 connect(pCopiedMenuAction, &QAction::triggered, &UIMenuBarEditorWidget::sltHandleMenuBarMenuClick);
1207 m_actions.insert(pAction->extraDataKey(), pCopiedMenuAction);
1208 }
1209 }
1210 /* Return copied sub-menu: */
1211 return pCopiedMenu;
1212}
1213#endif
1214
1215QAction *UIMenuBarEditorWidget::prepareNamedAction(QMenu *pMenu, const QString &strName,
1216 int iExtraDataID, const QString &strExtraDataID)
1217{
1218 /* Create copied action: */
1219 QAction *pCopiedAction = pMenu->addAction(strName);
1220 AssertPtrReturn(pCopiedAction, 0);
1221 {
1222 /* Configure copied action: */
1223 pCopiedAction->setCheckable(true);
1224 pCopiedAction->setProperty("class", pMenu->property("class"));
1225 pCopiedAction->setProperty("type", iExtraDataID);
1226 connect(pCopiedAction, &QAction::triggered, this, &UIMenuBarEditorWidget::sltHandleMenuBarMenuClick);
1227 m_actions.insert(strExtraDataID, pCopiedAction);
1228 }
1229 /* Return copied action: */
1230 return pCopiedAction;
1231}
1232
1233QAction *UIMenuBarEditorWidget::prepareCopiedAction(QMenu *pMenu, const UIAction *pAction)
1234{
1235 /* Create copied action: */
1236 QAction *pCopiedAction = pMenu->addAction(pAction->name());
1237 AssertPtrReturn(pCopiedAction, 0);
1238 {
1239 /* Configure copied action: */
1240 pCopiedAction->setCheckable(true);
1241 pCopiedAction->setProperty("class", pMenu->property("class"));
1242 pCopiedAction->setProperty("type", pAction->extraDataID());
1243 connect(pCopiedAction, &QAction::triggered, this, &UIMenuBarEditorWidget::sltHandleMenuBarMenuClick);
1244 m_actions.insert(pAction->extraDataKey(), pCopiedAction);
1245 }
1246 /* Return copied action: */
1247 return pCopiedAction;
1248}
1249
1250void UIMenuBarEditorWidget::prepareMenuApplication()
1251{
1252 /* Copy menu: */
1253#ifdef VBOX_WS_MAC
1254 QMenu *pMenu = prepareNamedMenu("Application");
1255#else /* !VBOX_WS_MAC */
1256 QMenu *pMenu = prepareCopiedMenu(actionPool()->action(UIActionIndex_M_Application));
1257#endif /* !VBOX_WS_MAC */
1258 AssertPtrReturnVoid(pMenu);
1259 {
1260#ifdef VBOX_WS_MAC
1261 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_About));
1262 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_ResetWarnings));
1263 pMenu->addSeparator();
1264 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_Preferences));
1265#else /* !VBOX_WS_MAC */
1266 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_Preferences));
1267 pMenu->addSeparator();
1268 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Application_S_ResetWarnings));
1269#endif /* !VBOX_WS_MAC */
1270 }
1271}
1272
1273void UIMenuBarEditorWidget::prepareMenuMachine()
1274{
1275 /* Copy menu: */
1276 QMenu *pMenu = prepareCopiedMenu(actionPool()->action(UIActionIndexRT_M_Machine));
1277 AssertPtrReturnVoid(pMenu);
1278 {
1279 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_S_Settings));
1280 pMenu->addSeparator();
1281 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_S_TakeSnapshot));
1282 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_S_ShowInformation));
1283 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_S_ShowFileManager));
1284 pMenu->addSeparator();
1285 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_T_Pause));
1286 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_S_Reset));
1287 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_S_Detach));
1288 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_S_SaveState));
1289 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_S_Shutdown));
1290 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_S_PowerOff));
1291 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Machine_S_ShowLogDialog));
1292 }
1293}
1294
1295void UIMenuBarEditorWidget::prepareMenuView()
1296{
1297 /* Copy menu: */
1298 QMenu *pMenu = prepareCopiedMenu(actionPool()->action(UIActionIndexRT_M_View));
1299 AssertPtrReturnVoid(pMenu);
1300 {
1301 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_T_Fullscreen));
1302 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_T_Seamless));
1303 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_T_Scale));
1304 pMenu->addSeparator();
1305 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_S_AdjustWindow));
1306 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize));
1307 pMenu->addSeparator();
1308 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_S_TakeScreenshot));
1309 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_M_Recording_T_Start));
1310 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_T_VRDEServer));
1311 pMenu->addSeparator();
1312 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_M_MenuBar));
1313 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_View_M_StatusBar));
1314 pMenu->addSeparator();
1315 prepareNamedAction(pMenu, tr("Virtual Screen Resize"),
1316 UIExtraDataMetaDefs::RuntimeMenuViewActionType_Resize,
1317 gpConverter->toInternalString(UIExtraDataMetaDefs::RuntimeMenuViewActionType_Resize));
1318 prepareNamedAction(pMenu, tr("Virtual Screen Remap"),
1319 UIExtraDataMetaDefs::RuntimeMenuViewActionType_Remap,
1320 gpConverter->toInternalString(UIExtraDataMetaDefs::RuntimeMenuViewActionType_Remap));
1321 prepareNamedAction(pMenu, tr("Virtual Screen Rescale"),
1322 UIExtraDataMetaDefs::RuntimeMenuViewActionType_Rescale,
1323 gpConverter->toInternalString(UIExtraDataMetaDefs::RuntimeMenuViewActionType_Rescale));
1324 }
1325}
1326
1327void UIMenuBarEditorWidget::prepareMenuInput()
1328{
1329 /* Copy menu: */
1330 QMenu *pMenu = prepareCopiedMenu(actionPool()->action(UIActionIndexRT_M_Input));
1331 AssertPtrReturnVoid(pMenu);
1332 {
1333 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Input_M_Keyboard));
1334 pMenu->addSeparator();
1335 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Input_M_Mouse_T_Integration));
1336 }
1337}
1338
1339void UIMenuBarEditorWidget::prepareMenuDevices()
1340{
1341 /* Copy menu: */
1342 QMenu *pMenu = prepareCopiedMenu(actionPool()->action(UIActionIndexRT_M_Devices));
1343 AssertPtrReturnVoid(pMenu);
1344 {
1345 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_M_HardDrives));
1346 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_M_OpticalDevices));
1347 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_M_FloppyDevices));
1348 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_M_Audio));
1349 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_M_Network));
1350 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_M_USBDevices));
1351 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_M_WebCams));
1352 pMenu->addSeparator();
1353 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_M_SharedFolders));
1354 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_M_SharedClipboard));
1355 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_M_DragAndDrop));
1356 pMenu->addSeparator();
1357 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_S_InsertGuestAdditionsDisk));
1358 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Devices_S_UpgradeGuestAdditions));
1359 }
1360}
1361
1362#ifdef VBOX_WITH_DEBUGGER_GUI
1363void UIMenuBarEditorWidget::prepareMenuDebug()
1364{
1365 /* Copy menu: */
1366 QMenu *pMenu = prepareCopiedMenu(actionPool()->action(UIActionIndexRT_M_Debug));
1367 AssertPtrReturnVoid(pMenu);
1368 {
1369 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Debug_S_ShowStatistics));
1370 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Debug_S_ShowCommandLine));
1371 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndexRT_M_Debug_T_Logging));
1372 }
1373}
1374#endif /* VBOX_WITH_DEBUGGER_GUI */
1375
1376#ifdef VBOX_WS_MAC
1377void UIMenuBarEditorWidget::prepareMenuWindow()
1378{
1379 /* Copy menu: */
1380 QMenu *pMenu = prepareCopiedMenu(actionPool()->action(UIActionIndex_M_Window));
1381 AssertPtrReturnVoid(pMenu);
1382 {
1383 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_M_Window_S_Minimize));
1384 pMenu->addSeparator();
1385 prepareNamedAction(pMenu, tr("Switch"),
1386 UIExtraDataMetaDefs::MenuWindowActionType_Switch,
1387 gpConverter->toInternalString(UIExtraDataMetaDefs::MenuWindowActionType_Switch));
1388 }
1389}
1390#endif /* VBOX_WS_MAC */
1391
1392void UIMenuBarEditorWidget::prepareMenuHelp()
1393{
1394 /* Copy menu: */
1395 QMenu *pMenu = prepareCopiedMenu(actionPool()->action(UIActionIndex_Menu_Help));
1396 AssertPtrReturnVoid(pMenu);
1397 {
1398 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_Contents));
1399 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_WebSite));
1400 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_BugTracker));
1401 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_Forums));
1402 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_Oracle));
1403 pMenu->addSeparator();
1404#ifndef VBOX_WS_MAC
1405 prepareCopiedAction(pMenu, actionPool()->action(UIActionIndex_Simple_About));
1406#endif
1407 }
1408}
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