VirtualBox

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

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

FE/Qt: UICommon: Move extension pack related functionality to UIExtension namespace; Rework all listeners to listen for global VBox events (signals) instead of UICommon.

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