VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/extensionpackmanager/UIExtensionPackManager.cpp

Last change on this file was 106061, checked in by vboxsync, 2 weeks ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.7 KB
Line 
1/* $Id: UIExtensionPackManager.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIExtensionPackManager class implementation.
4 */
5
6/*
7 * Copyright (C) 2009-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QApplication>
30#include <QDir>
31#include <QHeaderView>
32#include <QPushButton>
33#include <QTextStream>
34#include <QVBoxLayout>
35
36/* GUI includes: */
37#include "QIFileDialog.h"
38#include "QIToolBar.h"
39#include "QITreeWidget.h"
40#include "UIActionPoolManager.h"
41#include "UICommon.h"
42#include "UIExtension.h"
43#include "UIExtensionPackManager.h"
44#include "UIExtraDataManager.h"
45#include "UIGlobalSession.h"
46#include "UIIconPool.h"
47#include "UIMessageCenter.h"
48#include "UINotificationCenter.h"
49#include "UIShortcutPool.h"
50#include "UITranslationEventListener.h"
51#include "UIVirtualBoxEventHandler.h"
52
53/* COM includes: */
54#include "CExtPack.h"
55#include "CExtPackManager.h"
56
57
58/** Extension pack tree-widget column indexes. */
59enum ExtensionPackColumn
60{
61 ExtensionPackColumn_Usable,
62 ExtensionPackColumn_Name,
63 ExtensionPackColumn_Version,
64 ExtensionPackColumn_Max,
65};
66
67
68/** Extension Pack Manager: Extension Pack data structure. */
69struct UIDataExtensionPack
70{
71 /** Constructs data. */
72 UIDataExtensionPack()
73 : m_strName(QString())
74 , m_strDescription(QString())
75 , m_strVersion(QString())
76 , m_uRevision(0)
77 , m_fIsUsable(false)
78 , m_strWhyUnusable(QString())
79 {}
80
81 /** Returns whether the @a other passed data is equal to this one. */
82 bool equal(const UIDataExtensionPack &other) const
83 {
84 return true
85 && (m_strName == other.m_strName)
86 && (m_strDescription == other.m_strDescription)
87 && (m_strVersion == other.m_strVersion)
88 && (m_uRevision == other.m_uRevision)
89 && (m_fIsUsable == other.m_fIsUsable)
90 && (m_strWhyUnusable == other.m_strWhyUnusable)
91 ;
92 }
93
94 /** Returns whether the @a other passed data is equal to this one. */
95 bool operator==(const UIDataExtensionPack &other) const { return equal(other); }
96 /** Returns whether the @a other passed data is different from this one. */
97 bool operator!=(const UIDataExtensionPack &other) const { return !equal(other); }
98
99 /** Holds the extension item name. */
100 QString m_strName;
101 /** Holds the extension item description. */
102 QString m_strDescription;
103 /** Holds the extension item version. */
104 QString m_strVersion;
105 /** Holds the extension item revision. */
106 ULONG m_uRevision;
107 /** Holds whether the extension item usable. */
108 bool m_fIsUsable;
109 /** Holds why the extension item is unusable. */
110 QString m_strWhyUnusable;
111};
112
113
114/** Extension Pack Manager tree-widget item. */
115class UIItemExtensionPack : public QITreeWidgetItem, public UIDataExtensionPack
116{
117 Q_OBJECT;
118
119public:
120
121 /** Updates item fields from base-class data. */
122 void updateFields();
123
124 /** Returns item name. */
125 QString name() const { return m_strName; }
126
127protected:
128
129 /** Returns default text. */
130 virtual QString defaultText() const RT_OVERRIDE;
131};
132
133
134/*********************************************************************************************************************************
135* Class UIItemExtensionPack implementation. *
136*********************************************************************************************************************************/
137
138void UIItemExtensionPack::updateFields()
139{
140 /* Icon: */
141 setIcon(ExtensionPackColumn_Usable, UIIconPool::iconSet( m_fIsUsable
142 ? ":/status_check_16px.png"
143 : ":/status_error_16px.png"));
144
145 /* Name: */
146 setText(ExtensionPackColumn_Name, m_strName);
147
148 /* Version, Revision, Edition: */
149 const QString strVersion(m_strVersion.section(QRegularExpression("[-_]"), 0, 0));
150 // WORKAROUND:
151 // for http://qt.gitorious.org/qt/qt/commit/7fc63dd0ff368a637dcd17e692b9d6b26278b538
152 QString strAppend;
153 if (m_strVersion.contains(QRegularExpression("[-_]")))
154 strAppend = m_strVersion.section(QRegularExpression("[-_]"), 1, -1, QString::SectionIncludeLeadingSep);
155 setText(ExtensionPackColumn_Version, QString("%1r%2%3").arg(strVersion).arg(m_uRevision).arg(strAppend));
156
157 /* Tool-tip: */
158 QString strTip = m_strDescription;
159 if (!m_fIsUsable)
160 {
161 strTip += QString("<hr>");
162 strTip += m_strWhyUnusable;
163 }
164 setToolTip(ExtensionPackColumn_Usable, strTip);
165 setToolTip(ExtensionPackColumn_Name, strTip);
166 setToolTip(ExtensionPackColumn_Version, strTip);
167}
168
169QString UIItemExtensionPack::defaultText() const
170{
171 return m_fIsUsable
172 ? QString("%1, %2: %3, %4")
173 .arg(text(1))
174 .arg(parentTree()->headerItem()->text(2)).arg(text(2))
175 .arg(parentTree()->headerItem()->text(0))
176 : QString("%1, %2: %3")
177 .arg(text(1))
178 .arg(parentTree()->headerItem()->text(2)).arg(text(2));
179}
180
181
182/*********************************************************************************************************************************
183* Class UIExtensionPackManagerWidget implementation. *
184*********************************************************************************************************************************/
185
186UIExtensionPackManagerWidget::UIExtensionPackManagerWidget(EmbedTo enmEmbedding, UIActionPool *pActionPool,
187 bool fShowToolbar /* = true */, QWidget *pParent /* = 0 */)
188 : QWidget(pParent)
189 , m_enmEmbedding(enmEmbedding)
190 , m_pActionPool(pActionPool)
191 , m_fShowToolbar(fShowToolbar)
192 , m_pToolBar(0)
193 , m_pTreeWidget(0)
194{
195 prepare();
196}
197
198QMenu *UIExtensionPackManagerWidget::menu() const
199{
200 return m_pActionPool->action(UIActionIndexMN_M_ExtensionWindow)->menu();
201}
202
203void UIExtensionPackManagerWidget::sltRetranslateUI()
204{
205 /* Translate tree-widget: */
206 m_pTreeWidget->setHeaderLabels( QStringList()
207 << UIExtensionPackManager::tr("Active", "ext pack")
208 << UIExtensionPackManager::tr("Name")
209 << UIExtensionPackManager::tr("Version"));
210 m_pTreeWidget->setWhatsThis(UIExtensionPackManager::tr("Registered extension packs"));
211}
212
213void UIExtensionPackManagerWidget::sltInstallExtensionPack()
214{
215 /* Show file-open dialog to let user to choose package file.
216 * The default location is the user's Download or Downloads directory
217 * with the user's home directory as a fallback. ExtPacks are downloaded. */
218 QString strBaseFolder = QDir::homePath() + "/Downloads";
219 if (!QDir(strBaseFolder).exists())
220 {
221 strBaseFolder = QDir::homePath() + "/Download";
222 if (!QDir(strBaseFolder).exists())
223 strBaseFolder = QDir::homePath();
224 }
225 const QString strTitle = UIExtensionPackManager::tr("Select an extension package file");
226 QStringList extensions;
227 for (int i = 0; i < VBoxExtPackFileExts.size(); ++i)
228 extensions << QString("*.%1").arg(VBoxExtPackFileExts[i]);
229 const QString strFilter = UIExtensionPackManager::tr("Extension package files (%1)").arg(extensions.join(" "));
230 const QStringList fileNames = QIFileDialog::getOpenFileNames(strBaseFolder, strFilter, window(), strTitle, 0, true, true);
231 QString strFilePath;
232 if (!fileNames.isEmpty())
233 strFilePath = fileNames.at(0);
234
235 /* Install the chosen package: */
236 if (!strFilePath.isEmpty())
237 UIExtension::install(strFilePath, QString(), this, NULL);
238}
239
240void UIExtensionPackManagerWidget::sltUninstallExtensionPack()
241{
242 /* Get current item: */
243 QITreeWidgetItem *pItem = QITreeWidgetItem::toItem(m_pTreeWidget->currentItem());
244 UIItemExtensionPack *pItemEP = qobject_cast<UIItemExtensionPack*>(pItem);
245
246 /* Uninstall chosen package: */
247 if (pItemEP)
248 {
249 /* Get name of current package: */
250 const QString strSelectedPackageName = pItemEP->name();
251 /* Ask user about package removing: */
252 if (msgCenter().confirmRemoveExtensionPack(strSelectedPackageName, this))
253 {
254 /* Get VirtualBox for further activities: */
255 const CVirtualBox comVBox = gpGlobalSession->virtualBox();
256 /* Get Extension Pack Manager for further activities: */
257 CExtPackManager comEPManager = comVBox.GetExtensionPackManager();
258
259 /* Show error message if necessary: */
260 if (!comVBox.isOk())
261 UINotificationMessage::cannotGetExtensionPackManager(comVBox);
262 else
263 {
264 /* Uninstall the package: */
265 /** @todo Refuse this if any VMs are running. */
266 QString displayInfo;
267#ifdef VBOX_WS_WIN
268 QTextStream stream(&displayInfo);
269 stream.setNumberFlags(QTextStream::ShowBase);
270 stream.setIntegerBase(16);
271 stream << "hwnd=" << winId();
272#endif
273
274 /* Uninstall extension pack: */
275 UINotificationProgressExtensionPackUninstall *pNotification =
276 new UINotificationProgressExtensionPackUninstall(comEPManager,
277 strSelectedPackageName,
278 displayInfo);
279 gpNotificationCenter->append(pNotification);
280 }
281 }
282 }
283}
284
285void UIExtensionPackManagerWidget::sltAdjustTreeWidget()
286{
287 /* Get the tree-widget abstract interface: */
288 QAbstractItemView *pItemView = m_pTreeWidget;
289 /* Get the tree-widget header-view: */
290 QHeaderView *pItemHeader = m_pTreeWidget->header();
291
292 /* Calculate the total tree-widget width: */
293 const int iTotal = m_pTreeWidget->viewport()->width();
294 /* Look for a minimum width hints for non-important columns: */
295 const int iMinWidth1 = qMax(pItemView->sizeHintForColumn(ExtensionPackColumn_Usable),
296 pItemHeader->sectionSizeHint(ExtensionPackColumn_Usable));
297 const int iMinWidth2 = qMax(pItemView->sizeHintForColumn(ExtensionPackColumn_Version),
298 pItemHeader->sectionSizeHint(ExtensionPackColumn_Version));
299 /* Propose suitable width hints for non-important columns: */
300 const int iWidth1 = iMinWidth1 < iTotal / ExtensionPackColumn_Max ? iMinWidth1 : iTotal / ExtensionPackColumn_Max;
301 const int iWidth2 = iMinWidth2 < iTotal / ExtensionPackColumn_Max ? iMinWidth2 : iTotal / ExtensionPackColumn_Max;
302 /* Apply the proposal: */
303 m_pTreeWidget->setColumnWidth(ExtensionPackColumn_Usable, iWidth1);
304 m_pTreeWidget->setColumnWidth(ExtensionPackColumn_Version, iWidth2);
305 m_pTreeWidget->setColumnWidth(ExtensionPackColumn_Name, iTotal - iWidth1 - iWidth2);
306}
307
308void UIExtensionPackManagerWidget::sltHandleCurrentItemChange()
309{
310 /* Check current-item type: */
311 QITreeWidgetItem *pItem = QITreeWidgetItem::toItem(m_pTreeWidget->currentItem());
312
313 /* Update actions availability: */
314 m_pActionPool->action(UIActionIndexMN_M_Extension_S_Uninstall)->setEnabled(pItem);
315}
316
317void UIExtensionPackManagerWidget::sltHandleContextMenuRequest(const QPoint &position)
318{
319 /* Check clicked-item type: */
320 QITreeWidgetItem *pItem = QITreeWidgetItem::toItem(m_pTreeWidget->itemAt(position));
321
322 /* Compose temporary context-menu: */
323 QMenu menu;
324 if (pItem)
325 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Extension_S_Uninstall));
326 else
327 menu.addAction(m_pActionPool->action(UIActionIndexMN_M_Extension_S_Install));
328
329 /* And show it: */
330 menu.exec(m_pTreeWidget->viewport()->mapToGlobal(position));
331}
332
333void UIExtensionPackManagerWidget::sltHandleExtensionPackInstalled(const QString &strName)
334{
335 /* Make sure the name was set: */
336 if (strName.isNull())
337 return;
338
339 /* Look for a list of items matching strName: */
340 const QList<QTreeWidgetItem*> items = m_pTreeWidget->findItems(strName, Qt::MatchCaseSensitive, ExtensionPackColumn_Name);
341 /* Remove first found item from the list if present: */
342 if (!items.isEmpty())
343 delete items.first();
344
345 /* [Re]insert it into the tree: */
346 CExtPackManager comManager = gpGlobalSession->virtualBox().GetExtensionPackManager();
347 const CExtPack comExtensionPack = comManager.Find(strName);
348 if (comExtensionPack.isOk())
349 {
350 /* Load extension pack data: */
351 UIDataExtensionPack extensionPackData;
352 loadExtensionPack(comExtensionPack, extensionPackData);
353 createItemForExtensionPack(extensionPackData, true /* choose item? */);
354 }
355}
356
357void UIExtensionPackManagerWidget::sltHandleExtensionPackUninstalled(const QString &strName)
358{
359 /* Make sure the name was set: */
360 if (strName.isNull())
361 return;
362
363 /* Look for a list of items matching strName: */
364 const QList<QTreeWidgetItem*> items = m_pTreeWidget->findItems(strName, Qt::MatchCaseSensitive, ExtensionPackColumn_Name);
365 AssertReturnVoid(!items.isEmpty());
366 /* Remove first found item from the list: */
367 delete items.first();
368
369 /* Adjust tree-widget: */
370 sltAdjustTreeWidget();
371}
372
373void UIExtensionPackManagerWidget::prepare()
374{
375 /* Prepare self: */
376 uiCommon().setHelpKeyword(this, "ext-pack-manager");
377
378 /* Prepare stuff: */
379 prepareActions();
380 prepareWidgets();
381 prepareConnections();
382
383 /* Apply language settings: */
384 sltRetranslateUI();
385
386 connect(&translationEventListener(), &UITranslationEventListener::sigRetranslateUI,
387 this, &UIExtensionPackManagerWidget::sltRetranslateUI);
388
389 /* Load extension packs: */
390 loadExtensionPacks();
391}
392
393void UIExtensionPackManagerWidget::prepareActions()
394{
395 /* First of all, add actions which has smaller shortcut scope: */
396 addAction(m_pActionPool->action(UIActionIndexMN_M_Extension_S_Install));
397 addAction(m_pActionPool->action(UIActionIndexMN_M_Extension_S_Uninstall));
398
399 /* Connect actions: */
400 connect(m_pActionPool->action(UIActionIndexMN_M_Extension_S_Install), &QAction::triggered,
401 this, &UIExtensionPackManagerWidget::sltInstallExtensionPack);
402 connect(m_pActionPool->action(UIActionIndexMN_M_Extension_S_Uninstall), &QAction::triggered,
403 this, &UIExtensionPackManagerWidget::sltUninstallExtensionPack);
404}
405
406void UIExtensionPackManagerWidget::prepareWidgets()
407{
408 /* Create main-layout: */
409 new QVBoxLayout(this);
410 if (layout())
411 {
412 /* Configure layout: */
413 layout()->setContentsMargins(0, 0, 0, 0);
414#ifdef VBOX_WS_MAC
415 layout()->setSpacing(10);
416#else
417 layout()->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) / 2);
418#endif
419
420 /* Prepare toolbar, if requested: */
421 if (m_fShowToolbar)
422 prepareToolBar();
423
424 /* Prepare tree-widget: */
425 prepareTreeWidget();
426 }
427}
428
429void UIExtensionPackManagerWidget::prepareToolBar()
430{
431 /* Prepare toolbar: */
432 m_pToolBar = new QIToolBar(parentWidget());
433 if (m_pToolBar)
434 {
435 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize));
436 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric));
437 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
438 m_pToolBar->addAction(m_pActionPool->action(UIActionIndexMN_M_Extension_S_Install));
439 m_pToolBar->addAction(m_pActionPool->action(UIActionIndexMN_M_Extension_S_Uninstall));
440
441#ifdef VBOX_WS_MAC
442 /* Check whether we are embedded into a stack: */
443 if (m_enmEmbedding == EmbedTo_Stack)
444 {
445 /* Add into layout: */
446 layout()->addWidget(m_pToolBar);
447 }
448#else
449 /* Add into layout: */
450 layout()->addWidget(m_pToolBar);
451#endif
452 }
453}
454
455void UIExtensionPackManagerWidget::prepareTreeWidget()
456{
457 /* Prepare tree-widget: */
458 m_pTreeWidget = new QITreeWidget(this);
459 if (m_pTreeWidget)
460 {
461 m_pTreeWidget->setRootIsDecorated(false);
462 m_pTreeWidget->setAlternatingRowColors(true);
463 m_pTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
464 m_pTreeWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
465 m_pTreeWidget->setColumnCount(ExtensionPackColumn_Max);
466 m_pTreeWidget->setSortingEnabled(true);
467 m_pTreeWidget->sortByColumn(ExtensionPackColumn_Name, Qt::AscendingOrder);
468 m_pTreeWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
469 connect(m_pTreeWidget, &QITreeWidget::resized,
470 this, &UIExtensionPackManagerWidget::sltAdjustTreeWidget, Qt::QueuedConnection);
471 connect(m_pTreeWidget->header(), &QHeaderView::sectionResized,
472 this, &UIExtensionPackManagerWidget::sltAdjustTreeWidget, Qt::QueuedConnection);
473 connect(m_pTreeWidget, &QITreeWidget::currentItemChanged,
474 this, &UIExtensionPackManagerWidget::sltHandleCurrentItemChange);
475 connect(m_pTreeWidget, &QITreeWidget::customContextMenuRequested,
476 this, &UIExtensionPackManagerWidget::sltHandleContextMenuRequest);
477
478 /* Add into layout: */
479 layout()->addWidget(m_pTreeWidget);
480 }
481}
482
483void UIExtensionPackManagerWidget::prepareConnections()
484{
485 /* Listen for extension pack being [un]installed: */
486 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigExtensionPackInstalled,
487 this, &UIExtensionPackManagerWidget::sltHandleExtensionPackInstalled);
488 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigExtensionPackUninstalled,
489 this, &UIExtensionPackManagerWidget::sltHandleExtensionPackUninstalled);
490}
491
492void UIExtensionPackManagerWidget::loadExtensionPacks()
493{
494 /* Check tree-widget: */
495 if (!m_pTreeWidget)
496 return;
497
498 /* Clear tree first of all: */
499 m_pTreeWidget->clear();
500
501 /* Get VirtualBox for further activities: */
502 const CVirtualBox comVBox = gpGlobalSession->virtualBox();
503 /* Get Extension Pack Manager for further activities: */
504 const CExtPackManager comEPManager = comVBox.GetExtensionPackManager();
505
506 /* Show error message if necessary: */
507 if (!comVBox.isOk())
508 UINotificationMessage::cannotGetExtensionPackManager(comVBox);
509 else
510 {
511 /* Get extension packs for further activities: */
512 const QVector<CExtPack> extensionPacks = comEPManager.GetInstalledExtPacks();
513
514 /* Show error message if necessary: */
515 if (!comEPManager.isOk())
516 UINotificationMessage::cannotAcquireExtensionPackManagerParameter(comEPManager);
517 else
518 {
519 /* Iterate through existing extension packs: */
520 foreach (const CExtPack &comExtensionPack, extensionPacks)
521 {
522 /* Skip if we have nothing to populate: */
523 if (comExtensionPack.isNull())
524 continue;
525
526 /* Load extension pack data: */
527 UIDataExtensionPack extensionPackData;
528 loadExtensionPack(comExtensionPack, extensionPackData);
529 createItemForExtensionPack(extensionPackData, false /* choose item? */);
530 }
531
532 /* Choose the 1st item as current if nothing chosen: */
533 if (!m_pTreeWidget->currentItem())
534 m_pTreeWidget->setCurrentItem(m_pTreeWidget->topLevelItem(0));
535 /* Handle current item change in any case: */
536 sltHandleCurrentItemChange();
537 }
538 }
539}
540
541void UIExtensionPackManagerWidget::loadExtensionPack(const CExtPack &comExtensionPack, UIDataExtensionPack &extensionPackData)
542{
543 /* Gather extension pack settings: */
544 if (comExtensionPack.isOk())
545 extensionPackData.m_strName = comExtensionPack.GetName();
546 if (comExtensionPack.isOk())
547 extensionPackData.m_strDescription = comExtensionPack.GetDescription();
548 if (comExtensionPack.isOk())
549 extensionPackData.m_strVersion = comExtensionPack.GetVersion();
550 if (comExtensionPack.isOk())
551 extensionPackData.m_uRevision = comExtensionPack.GetRevision();
552 if (comExtensionPack.isOk())
553 {
554 extensionPackData.m_fIsUsable = comExtensionPack.GetUsable();
555 if (!extensionPackData.m_fIsUsable && comExtensionPack.isOk())
556 extensionPackData.m_strWhyUnusable = comExtensionPack.GetWhyUnusable();
557 }
558
559 /* Show error message if necessary: */
560 if (!comExtensionPack.isOk())
561 UINotificationMessage::cannotAcquireExtensionPackParameter(comExtensionPack);
562}
563
564void UIExtensionPackManagerWidget::createItemForExtensionPack(const UIDataExtensionPack &extensionPackData, bool fChooseItem)
565{
566 /* Prepare new provider item: */
567 UIItemExtensionPack *pItem = new UIItemExtensionPack;
568 if (pItem)
569 {
570 pItem->UIDataExtensionPack::operator=(extensionPackData);
571 pItem->updateFields();
572
573 /* Add item to the tree: */
574 m_pTreeWidget->addTopLevelItem(pItem);
575
576 /* And choose it as current if necessary: */
577 if (fChooseItem)
578 m_pTreeWidget->setCurrentItem(pItem);
579 }
580}
581
582
583/*********************************************************************************************************************************
584* Class UIExtensionPackManagerFactory implementation. *
585*********************************************************************************************************************************/
586
587UIExtensionPackManagerFactory::UIExtensionPackManagerFactory(UIActionPool *pActionPool /* = 0 */)
588 : m_pActionPool(pActionPool)
589{
590}
591
592void UIExtensionPackManagerFactory::create(QIManagerDialog *&pDialog, QWidget *pCenterWidget)
593{
594 pDialog = new UIExtensionPackManager(pCenterWidget, m_pActionPool);
595}
596
597
598/*********************************************************************************************************************************
599* Class UIExtensionPackManager implementation. *
600*********************************************************************************************************************************/
601
602UIExtensionPackManager::UIExtensionPackManager(QWidget *pCenterWidget, UIActionPool *pActionPool)
603 : QIManagerDialog(pCenterWidget)
604 , m_pActionPool(pActionPool)
605{
606}
607
608void UIExtensionPackManager::sltRetranslateUI()
609{
610 /* Translate window title: */
611 setWindowTitle(tr("Extension Pack Manager"));
612
613 /* Translate buttons: */
614 button(ButtonType_Close)->setText(tr("Close"));
615 button(ButtonType_Help)->setText(tr("Help"));
616 button(ButtonType_Close)->setStatusTip(tr("Close dialog"));
617 button(ButtonType_Help)->setStatusTip(tr("Show dialog help"));
618 button(ButtonType_Close)->setShortcut(Qt::Key_Escape);
619 button(ButtonType_Help)->setShortcut(UIShortcutPool::standardSequence(QKeySequence::HelpContents));
620 button(ButtonType_Close)->setToolTip(tr("Close Window (%1)").arg(button(ButtonType_Close)->shortcut().toString()));
621 button(ButtonType_Help)->setToolTip(tr("Show Help (%1)").arg(button(ButtonType_Help)->shortcut().toString()));
622}
623
624void UIExtensionPackManager::configure()
625{
626#ifndef VBOX_WS_MAC
627 /* Assign window icon: */
628 setWindowIcon(UIIconPool::iconSetFull(":/extension_pack_manager_24px.png", ":/extension_pack_manager_16px.png"));
629#endif
630}
631
632void UIExtensionPackManager::configureCentralWidget()
633{
634 /* Prepare widget: */
635 UIExtensionPackManagerWidget *pWidget = new UIExtensionPackManagerWidget(EmbedTo_Dialog, m_pActionPool, true, this);
636 if (pWidget)
637 {
638 setWidget(pWidget);
639 setWidgetMenu(pWidget->menu());
640#ifdef VBOX_WS_MAC
641 setWidgetToolbar(pWidget->toolbar());
642#endif
643
644 /* Add into layout: */
645 centralWidget()->layout()->addWidget(pWidget);
646 }
647}
648
649void UIExtensionPackManager::finalize()
650{
651 /* Apply language settings: */
652 sltRetranslateUI();
653
654 connect(&translationEventListener(), &UITranslationEventListener::sigRetranslateUI,
655 this, &UIExtensionPackManager::sltRetranslateUI);
656}
657
658UIExtensionPackManagerWidget *UIExtensionPackManager::widget()
659{
660 return qobject_cast<UIExtensionPackManagerWidget*>(QIManagerDialog::widget());
661}
662
663
664#include "UIExtensionPackManager.moc"
Note: See TracBrowser for help on using the repository browser.

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