Changeset 51931 in vbox for trunk/src/VBox/Frontends
- Timestamp:
- Jul 8, 2014 1:20:51 PM (11 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.cpp
r51679 r51931 134 134 #endif /* VBOX_WITH_DEBUGGER_GUI */ 135 135 136 #ifdef DEBUG 137 /* VirtualBox: Extra-data Manager window: */ 138 const char* UIExtraDataDefs::GUI_ExtraDataManager_Geometry = "GUI/ExtraDataManager/Geometry"; 139 const char* UIExtraDataDefs::GUI_ExtraDataManager_SplitterHints = "GUI/ExtraDataManager/SplitterHints"; 140 #endif /* DEBUG */ 141 -
trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h
r51679 r51931 238 238 239 239 #ifdef VBOX_WITH_DEBUGGER_GUI 240 /** @name Virtual Machine Debug UI240 /** @name Virtual Machine: Debug UI 241 241 * @{ */ 242 242 /** Holds whether debugger UI enabled. */ … … 246 246 /** @} */ 247 247 #endif /* VBOX_WITH_DEBUGGER_GUI */ 248 249 #ifdef DEBUG 250 /** @name VirtualBox: Extra-data Manager window 251 * @{ */ 252 /** Holds extra-data manager geometry. */ 253 extern const char* GUI_ExtraDataManager_Geometry; 254 /** Holds extra-data manager splitter hints. */ 255 extern const char* GUI_ExtraDataManager_SplitterHints; 256 /** @} */ 257 #endif /* DEBUG */ 248 258 } 249 259 -
trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.cpp
r51930 r51931 19 19 #include <QMutex> 20 20 #include <QDesktopWidget> 21 #ifdef DEBUG 22 # include <QMainWindow> 23 # include <QMenuBar> 24 # include <QListView> 25 # include <QTableView> 26 # include <QHeaderView> 27 # include <QStandardItemModel> 28 # include <QSortFilterProxyModel> 29 # include <QStyledItemDelegate> 30 # include <QPainter> 31 # include <QLabel> 32 # include <QLineEdit> 33 # include <QPushButton> 34 # include <QXmlStreamWriter> 35 # include <QXmlStreamReader> 36 #endif /* DEBUG */ 21 37 22 38 /* GUI includes: */ … … 27 43 #include "UIActionPool.h" 28 44 #include "UIConverter.h" 45 #ifdef DEBUG 46 # include "VBoxUtils.h" 47 # include "UIMessageCenter.h" 48 # include "UIVirtualBoxEventHandler.h" 49 # include "UIIconPool.h" 50 # include "UIToolBar.h" 51 # include "QIWidgetValidator.h" 52 # include "QIDialogButtonBox.h" 53 # include "QIFileDialog.h" 54 # include "QISplitter.h" 55 # include "QIDialog.h" 56 #endif /* DEBUG */ 29 57 30 58 /* COM includes: */ … … 117 145 118 146 147 #ifdef DEBUG 148 /** Data fields. */ 149 enum Field 150 { 151 Field_ID = Qt::UserRole + 1, 152 Field_Name, 153 Field_OsTypeID, 154 Field_Known 155 }; 156 157 158 /** QStyledItemDelegate extension 159 * reflecting items of Extra Data Manager window: Chooser pane. */ 160 class UIChooserPaneDelegate : public QStyledItemDelegate 161 { 162 Q_OBJECT; 163 164 public: 165 166 /** Constructor. */ 167 UIChooserPaneDelegate(QObject *pParent); 168 169 private: 170 171 /** Size-hint calculation routine. */ 172 QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; 173 174 /** Paint routine. */ 175 void paint(QPainter *pPainter, const QStyleOptionViewItem &option, const QModelIndex &index) const; 176 177 /** Fetch pixmap info for passed QModelIndex. */ 178 static void fetchPixmapInfo(const QModelIndex &index, QPixmap &pixmap, QSize &pixmapSize); 179 180 /** Margin. */ 181 int m_iMargin; 182 /** Spacing. */ 183 int m_iSpacing; 184 }; 185 186 UIChooserPaneDelegate::UIChooserPaneDelegate(QObject *pParent) 187 : QStyledItemDelegate(pParent) 188 , m_iMargin(3) 189 , m_iSpacing(3) 190 { 191 } 192 193 QSize UIChooserPaneDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const 194 { 195 /* Font metrics: */ 196 const QFontMetrics &fm = option.fontMetrics; 197 /* Pixmap: */ 198 QPixmap pixmap; 199 QSize pixmapSize; 200 fetchPixmapInfo(index, pixmap, pixmapSize); 201 202 /* Calculate width: */ 203 const int iWidth = m_iMargin + 204 pixmapSize.width() + 205 2 * m_iSpacing + 206 qMax(fm.width(index.data(Field_Name).toString()), 207 fm.width(index.data(Field_ID).toString())) + 208 m_iMargin; 209 /* Calculate height: */ 210 const int iHeight = m_iMargin + 211 qMax(pixmapSize.height(), 212 fm.height() + m_iSpacing + fm.height()) + 213 m_iMargin; 214 215 /* Return result: */ 216 return QSize(iWidth, iHeight); 217 } 218 219 void UIChooserPaneDelegate::paint(QPainter *pPainter, const QStyleOptionViewItem &option, const QModelIndex &index) const 220 { 221 /* Item rect: */ 222 const QRect &optionRect = option.rect; 223 /* Palette: */ 224 const QPalette &palette = option.palette; 225 /* Font metrics: */ 226 const QFontMetrics &fm = option.fontMetrics; 227 /* Pixmap: */ 228 QPixmap pixmap; 229 QSize pixmapSize; 230 fetchPixmapInfo(index, pixmap, pixmapSize); 231 232 /* If item selected: */ 233 if (option.state & QStyle::State_Selected) 234 { 235 /* Fill background with selection color: */ 236 QColor highlight = palette.color(option.state & QStyle::State_Active ? 237 QPalette::Active : QPalette::Inactive, 238 QPalette::Highlight); 239 QLinearGradient bgGrad(optionRect.topLeft(), optionRect.bottomLeft()); 240 bgGrad.setColorAt(0, highlight.lighter(120)); 241 bgGrad.setColorAt(1, highlight); 242 pPainter->fillRect(optionRect, bgGrad); 243 /* Draw focus frame: */ 244 QStyleOptionFocusRect focusOption; 245 focusOption.rect = optionRect; 246 QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect, &focusOption, pPainter); 247 } 248 249 /* Draw pixmap: */ 250 const QPoint pixmapOrigin = optionRect.topLeft() + 251 QPoint(m_iMargin, m_iMargin); 252 pPainter->drawPixmap(pixmapOrigin, pixmap); 253 254 /* Is that known item? */ 255 bool fKnown = index.data(Field_Known).toBool(); 256 if (fKnown) 257 { 258 pPainter->save(); 259 QFont font = pPainter->font(); 260 font.setBold(true); 261 pPainter->setFont(font); 262 } 263 264 /* Draw item name: */ 265 const QPoint nameOrigin = pixmapOrigin + 266 QPoint(pixmapSize.width(), 0) + 267 QPoint(2 * m_iSpacing, 0) + 268 QPoint(0, fm.ascent()); 269 pPainter->drawText(nameOrigin, index.data(Field_Name).toString()); 270 271 /* Was that known item? */ 272 if (fKnown) 273 pPainter->restore(); 274 275 /* Draw item ID: */ 276 const QPoint idOrigin = nameOrigin + 277 QPoint(0, m_iSpacing) + 278 QPoint(0, fm.height()); 279 pPainter->drawText(idOrigin, index.data(Field_ID).toString()); 280 } 281 282 /* static */ 283 void UIChooserPaneDelegate::fetchPixmapInfo(const QModelIndex &index, QPixmap &pixmap, QSize &pixmapSize) 284 { 285 /* If proper machine ID passed => return corresponding pixmap/size: */ 286 if (index.data(Field_ID).toString() != UIExtraDataManager::GlobalID) 287 pixmap = vboxGlobal().vmGuestOSTypeIcon(index.data(Field_OsTypeID).toString(), &pixmapSize); 288 else 289 { 290 /* For global ID we return static pixmap/size: */ 291 const QIcon icon = UIIconPool::iconSet(":/edataglobal_32px.png"); 292 pixmapSize = icon.availableSizes().first(); 293 pixmap = icon.pixmap(pixmapSize); 294 } 295 } 296 297 298 /** QSortFilterProxyModel extension 299 * used by the chooser-pane of the UIExtraDataManagerWindow. */ 300 class UIChooserPaneSortingModel : public QSortFilterProxyModel 301 { 302 Q_OBJECT; 303 304 public: 305 306 /** Constructor, passes @a pParent to the QIRichToolButton constructor. */ 307 UIChooserPaneSortingModel(QObject *pParent) : QSortFilterProxyModel(pParent) {} 308 309 protected: 310 311 /** Returns true if the value of the item referred to by the given index left 312 * is less than the value of the item referred to by the given index right, 313 * otherwise returns false. */ 314 bool lessThan(const QModelIndex &leftIdx, const QModelIndex &rightIdx) const 315 { 316 /* Compare by ID first: */ 317 const QString strID1 = leftIdx.data(Field_ID).toString(); 318 const QString strID2 = rightIdx.data(Field_ID).toString(); 319 if (strID1 == UIExtraDataManager::GlobalID) 320 return true; 321 else if (strID2 == UIExtraDataManager::GlobalID) 322 return false; 323 /* Compare role finally: */ 324 return QSortFilterProxyModel::lessThan(leftIdx, rightIdx); 325 } 326 }; 327 328 329 /** QMainWindow extension 330 * providing Extra Data Manager with UI features. */ 331 class UIExtraDataManagerWindow : public QMainWindow 332 { 333 Q_OBJECT; 334 335 public: 336 337 /** @name Constructor/Destructor 338 * @{ */ 339 /** Extra-data Manager Window constructor. */ 340 UIExtraDataManagerWindow(); 341 /** Extra-data Manager Window destructor. */ 342 ~UIExtraDataManagerWindow(); 343 /** @} */ 344 345 /** @name Management 346 * @{ */ 347 /** Show and raise. */ 348 void showAndRaise(QWidget *pCenterWidget); 349 /** @} */ 350 351 private slots: 352 353 /** @name General 354 * @{ */ 355 /** Handles machine (un)registration. */ 356 void sltMachineRegistered(QString strID, bool fAdded); 357 /** Handles extra-data change. */ 358 void sltExtraDataChange(QString strID, QString strKey, QString strValue); 359 /** @} */ 360 361 /** @name Chooser-pane 362 * @{ */ 363 /** Handles filter-apply signal for the chooser-pane. */ 364 void sltChooserApplyFilter(const QString &strFilter); 365 /** Handles current-changed signal for the chooser-pane: */ 366 void sltChooserHandleCurrentChanged(const QModelIndex &index); 367 /** Handles item-selection-changed signal for the chooser-pane: */ 368 void sltChooserHandleSelectionChanged(const QItemSelection &selected, 369 const QItemSelection &deselected); 370 /** @} */ 371 372 /** @name Data-pane 373 * @{ */ 374 /** Handles filter-apply signal for the data-pane. */ 375 void sltDataApplyFilter(const QString &strFilter); 376 /** Handles item-selection-changed signal for the data-pane: */ 377 void sltDataHandleSelectionChanged(const QItemSelection &selected, 378 const QItemSelection &deselected); 379 /** Handles item-changed signal for the data-pane: */ 380 void sltDataHandleItemChanged(QStandardItem *pItem); 381 /** Handles context-menu-requested signal for the data-pane: */ 382 void sltDataHandleCustomContextMenuRequested(const QPoint &pos); 383 /** @} */ 384 385 /** @name Actions 386 * @{ */ 387 /** Add handler. */ 388 void sltAdd(); 389 /** Remove handler. */ 390 void sltDel(); 391 /** Save handler. */ 392 void sltSave(); 393 /** Load handler. */ 394 void sltLoad(); 395 /** @} */ 396 397 private: 398 399 /** @name Prepare/Cleanup 400 * @{ */ 401 /** Prepare instance. */ 402 void prepare(); 403 /** Prepare this. */ 404 void prepareThis(); 405 /** Prepare connections. */ 406 void prepareConnections(); 407 /** Prepare menu. */ 408 void prepareMenu(); 409 /** Prepare central widget. */ 410 void prepareCentralWidget(); 411 /** Prepare tool-bar. */ 412 void prepareToolBar(); 413 /** Prepare splitter. */ 414 void prepareSplitter(); 415 /** Prepare panes: */ 416 void preparePanes(); 417 /** Prepare chooser pane. */ 418 void preparePaneChooser(); 419 /** Prepare data pane. */ 420 void preparePaneData(); 421 /** Prepare button-box. */ 422 void prepareButtonBox(); 423 /** Load window settings. */ 424 void loadSettings(); 425 426 /** Save window settings. */ 427 void saveSettings(); 428 /** Cleanup instance. */ 429 void cleanup(); 430 /** @} */ 431 432 /** @name Event Processing 433 * @{ */ 434 /** Common event-handler. */ 435 bool event(QEvent *pEvent); 436 /** @} */ 437 438 /** @name Actions 439 * @{ */ 440 /** */ 441 void updateActionsAvailability(); 442 /** @} */ 443 444 /** @name Chooser-pane 445 * @{ */ 446 /** Returns chooser index for @a iRow. */ 447 QModelIndex chooserIndex(int iRow) const; 448 /** Returns current chooser index. */ 449 QModelIndex currentChooserIndex() const; 450 451 /** Returns chooser ID for @a iRow. */ 452 QString chooserID(int iRow) const; 453 /** Returns current chooser ID. */ 454 QString currentChooserID() const; 455 456 /** Returns chooser Name for @a iRow. */ 457 QString chooserName(int iRow) const; 458 /** Returns current Name. */ 459 QString currentChooserName() const; 460 461 /** Adds chooser item. */ 462 void addChooserItem(const QString &strID, 463 const QString &strName, 464 const QString &strOsTypeID, 465 const int iPosition = -1); 466 /** Adds chooser item by machine. */ 467 void addChooserItemByMachine(const CMachine &machine, 468 const int iPosition = -1); 469 /** Adds chooser item by ID. */ 470 void addChooserItemByID(const QString &strID, 471 const int iPosition = -1); 472 473 /** Make sure chooser have current-index if possible. */ 474 void makeSureChooserHaveCurrentIndexIfPossible(); 475 /** @} */ 476 477 /** @name Data-pane 478 * @{ */ 479 /** Returns data index for @a iRow and @a iColumn. */ 480 QModelIndex dataIndex(int iRow, int iColumn) const; 481 482 /** Returns data-key index for @a iRow. */ 483 QModelIndex dataKeyIndex(int iRow) const; 484 485 /** Returns data-value index for @a iRow. */ 486 QModelIndex dataValueIndex(int iRow) const; 487 488 /** Returns current data-key. */ 489 QString dataKey(int iRow) const; 490 491 /** Returns current data-value. */ 492 QString dataValue(int iRow) const; 493 494 /** Adds data item. */ 495 void addDataItem(const QString &strKey, 496 const QString &strValue, 497 const int iPosition = -1); 498 499 /** Sorts data items. */ 500 void sortData(); 501 /** @} */ 502 503 504 /** @name General 505 * @{ */ 506 /** Current geometry. */ 507 QRect m_geometry; 508 QVBoxLayout *m_pMainLayout; 509 /** Data pane: Tool-bar. */ 510 UIToolBar *m_pToolBar; 511 /** Splitter. */ 512 QISplitter *m_pSplitter; 513 /** @} */ 514 515 /** @name Chooser-pane 516 * @{ */ 517 /** Chooser pane. */ 518 QWidget *m_pPaneOfChooser; 519 /** Chooser filter. */ 520 QLineEdit *m_pFilterOfChooser; 521 /** Chooser pane: List-view. */ 522 QListView *m_pViewOfChooser; 523 /** Chooser pane: Source-model. */ 524 QStandardItemModel *m_pModelSourceOfChooser; 525 /** Chooser pane: Proxy-model. */ 526 UIChooserPaneSortingModel *m_pModelProxyOfChooser; 527 /** @} */ 528 529 /** @name Data-pane 530 * @{ */ 531 /** Data pane. */ 532 QWidget *m_pPaneOfData; 533 /** Dta filter. */ 534 QLineEdit *m_pFilterOfData; 535 /** Data pane: Table-view. */ 536 QTableView *m_pViewOfData; 537 /** Data pane: Item-model. */ 538 QStandardItemModel *m_pModelSourceOfData; 539 /** Data pane: Proxy-model. */ 540 QSortFilterProxyModel *m_pModelProxyOfData; 541 /** @} */ 542 543 /** @name Button Box 544 * @{ */ 545 /** Dialog button-box. */ 546 QIDialogButtonBox *m_pButtonBox; 547 /** @} */ 548 549 /** @name Actions 550 * @{ */ 551 /** Add action. */ 552 QAction *m_pActionAdd; 553 /** Del action. */ 554 QAction *m_pActionDel; 555 /** Load action. */ 556 QAction *m_pActionLoad; 557 /** Save action. */ 558 QAction *m_pActionSave; 559 /** @} */ 560 }; 561 562 UIExtraDataManagerWindow::UIExtraDataManagerWindow() 563 : m_pMainLayout(0), m_pToolBar(0), m_pSplitter(0) 564 , m_pPaneOfChooser(0), m_pFilterOfChooser(0), m_pViewOfChooser(0) 565 , m_pModelSourceOfChooser(0), m_pModelProxyOfChooser(0) 566 , m_pPaneOfData(0), m_pFilterOfData(0), m_pViewOfData(0), 567 m_pModelSourceOfData(0), m_pModelProxyOfData(0) 568 , m_pButtonBox(0) 569 , m_pActionAdd(0), m_pActionDel(0) 570 , m_pActionLoad(0), m_pActionSave(0) 571 { 572 /* Prepare: */ 573 prepare(); 574 } 575 576 UIExtraDataManagerWindow::~UIExtraDataManagerWindow() 577 { 578 /* Cleanup: */ 579 cleanup(); 580 } 581 582 void UIExtraDataManagerWindow::showAndRaise(QWidget *pCenterWidget) 583 { 584 /* Show: */ 585 show(); 586 /* Restore from minimized state: */ 587 setWindowState(windowState() & ~Qt::WindowMinimized); 588 /* Raise: */ 589 activateWindow(); 590 // /* Center according passed widget: */ 591 // VBoxGlobal::centerWidget(this, pCenterWidget, false); 592 } 593 594 void UIExtraDataManagerWindow::sltMachineRegistered(QString strID, bool fRegistered) 595 { 596 /* Machine registered: */ 597 if (fRegistered) 598 { 599 /* Gather list of 'known IDs': */ 600 QStringList knownIDs; 601 for (int iRow = 0; iRow < m_pModelSourceOfChooser->rowCount(); ++iRow) 602 knownIDs << chooserID(iRow); 603 604 /* Get machine items: */ 605 const CMachineVector machines = vboxGlobal().virtualBox().GetMachines(); 606 /* Look for the proper place to insert new machine item: */ 607 QString strPositionID = UIExtraDataManager::GlobalID; 608 foreach (const CMachine &machine, machines) 609 { 610 /* Get iterated machine ID: */ 611 const QString strIteratedID = machine.GetId(); 612 /* If 'iterated ID' equal to 'added ID' => break now: */ 613 if (strIteratedID == strID) 614 break; 615 /* If 'iterated ID' is 'known ID' => remember it: */ 616 if (knownIDs.contains(strIteratedID)) 617 strPositionID = strIteratedID; 618 } 619 620 /* Add new chooser item into source-model: */ 621 addChooserItemByID(strID, knownIDs.indexOf(strPositionID) + 1); 622 /* And sort proxy-model: */ 623 m_pModelProxyOfChooser->sort(0, Qt::AscendingOrder); 624 /* Make sure chooser have current-index if possible: */ 625 makeSureChooserHaveCurrentIndexIfPossible(); 626 } 627 /* Machine unregistered: */ 628 else 629 { 630 /* Remove chooser item with 'removed ID' if it is among 'known IDs': */ 631 for (int iRow = 0; iRow < m_pModelSourceOfChooser->rowCount(); ++iRow) 632 if (chooserID(iRow) == strID) 633 m_pModelSourceOfChooser->removeRow(iRow); 634 } 635 } 636 637 void UIExtraDataManagerWindow::sltExtraDataChange(QString strID, QString strKey, QString strValue) 638 { 639 /* Skip unrelated IDs: */ 640 if (currentChooserID() != strID) 641 return; 642 643 /* List of 'known keys': */ 644 QStringList knownKeys; 645 for (int iRow = 0; iRow < m_pModelSourceOfData->rowCount(); ++iRow) 646 knownKeys << dataKey(iRow); 647 648 /* Check if 'changed key' is 'known key': */ 649 int iPosition = knownKeys.indexOf(strKey); 650 /* If that is 'known key': */ 651 if (iPosition != -1) 652 { 653 /* If 'changed value' is empty => REMOVE item: */ 654 if (strValue.isEmpty()) 655 m_pModelSourceOfData->removeRow(iPosition); 656 /* If 'changed value' is NOT empty => UPDATE item: */ 657 else 658 m_pModelSourceOfData->itemFromIndex(dataValueIndex(iPosition))->setText(strValue); 659 } 660 /* Else if 'changed value' is NOT empty: */ 661 else if (!strValue.isEmpty()) 662 { 663 /* Look for the proper place for 'changed key': */ 664 QString strPositionKey; 665 foreach (const QString &strIteratedKey, gEDataManager->map(strID).keys()) 666 { 667 /* If 'iterated key' equal to 'changed key' => break now: */ 668 if (strIteratedKey == strKey) 669 break; 670 /* If 'iterated key' is 'known key' => remember it: */ 671 if (knownKeys.contains(strIteratedKey)) 672 strPositionKey = strIteratedKey; 673 } 674 /* Calculate resulting position: */ 675 iPosition = knownKeys.indexOf(strPositionKey) + 1; 676 /* INSERT item to the required position: */ 677 addDataItem(strKey, strValue, iPosition); 678 /* And sort proxy-model: */ 679 sortData(); 680 } 681 } 682 683 void UIExtraDataManagerWindow::sltChooserApplyFilter(const QString &strFilter) 684 { 685 /* Apply filtering rule: */ 686 m_pModelProxyOfChooser->setFilterWildcard(strFilter); 687 /* Make sure chooser have current-index if possible: */ 688 makeSureChooserHaveCurrentIndexIfPossible(); 689 } 690 691 void UIExtraDataManagerWindow::sltChooserHandleCurrentChanged(const QModelIndex &index) 692 { 693 /* Remove all the old items first: */ 694 while (m_pModelSourceOfData->rowCount()) 695 m_pModelSourceOfData->removeRow(0); 696 697 /* Ignore invalid indexes: */ 698 if (!index.isValid()) 699 return; 700 701 /* Add all the new items finally: */ 702 const QString strID = index.data(Field_ID).toString(); 703 AssertReturnVoid(gEDataManager->contains(strID)); 704 const ExtraDataMap data = gEDataManager->map(strID); 705 foreach (const QString &strKey, data.keys()) 706 addDataItem(strKey, data.value(strKey)); 707 /* And sort proxy-model: */ 708 sortData(); 709 } 710 711 void UIExtraDataManagerWindow::sltChooserHandleSelectionChanged(const QItemSelection &selected, 712 const QItemSelection &deselected) 713 { 714 /* Update actions availability: */ 715 updateActionsAvailability(); 716 } 717 718 void UIExtraDataManagerWindow::sltDataApplyFilter(const QString &strFilter) 719 { 720 /* Apply filtering rule: */ 721 m_pModelProxyOfData->setFilterWildcard(strFilter); 722 } 723 724 void UIExtraDataManagerWindow::sltDataHandleSelectionChanged(const QItemSelection &selected, 725 const QItemSelection &deselected) 726 { 727 /* Update actions availability: */ 728 updateActionsAvailability(); 729 } 730 731 void UIExtraDataManagerWindow::sltDataHandleItemChanged(QStandardItem *pItem) 732 { 733 /* Value-data index: */ 734 const QModelIndex valueIndex = m_pModelSourceOfData->indexFromItem(pItem); 735 const int iRow = valueIndex.row(); 736 const int iColumn = valueIndex.column(); 737 AssertMsgReturnVoid(iColumn == 1, ("Only 2nd column can be changed!\n")); 738 739 /* Key-data index: */ 740 const QModelIndex keyIndex = dataKeyIndex(iRow); 741 742 /* Update extra-data: */ 743 gEDataManager->setExtraDataString(keyIndex.data().toString(), 744 valueIndex.data().toString(), 745 currentChooserID()); 746 } 747 748 void UIExtraDataManagerWindow::sltDataHandleCustomContextMenuRequested(const QPoint &pos) 749 { 750 /* Prepare menu: */ 751 QMenu menu; 752 menu.addAction(m_pActionDel); 753 menu.addAction(m_pActionSave); 754 /* Execute menu: */ 755 m_pActionSave->setProperty("CalledFromContextMenu", true); 756 menu.exec(m_pViewOfData->viewport()->mapToGlobal(pos)); 757 m_pActionSave->setProperty("CalledFromContextMenu", QVariant()); 758 } 759 760 void UIExtraDataManagerWindow::sltAdd() 761 { 762 /* Make sure this slot called by corresponding action only: */ 763 QAction *pSenderAction = qobject_cast<QAction*>(sender()); 764 AssertReturnVoid(pSenderAction && m_pActionAdd); 765 766 /* Create input-dialog: */ 767 QPointer<QIDialog> pInputDialog = new QIDialog(this); 768 AssertPtrReturnVoid(pInputDialog.data()); 769 { 770 /* Configure input-dialog: */ 771 pInputDialog->setWindowTitle("Add extra-data record.."); 772 pInputDialog->setMinimumWidth(400); 773 /* Create main-layout: */ 774 QVBoxLayout *pMainLayout = new QVBoxLayout(pInputDialog); 775 AssertPtrReturnVoid(pMainLayout); 776 { 777 /* Create dialog validator group: */ 778 QObjectValidatorGroup *pValidatorGroup = new QObjectValidatorGroup(pInputDialog); 779 AssertReturnVoid(pValidatorGroup); 780 /* Create input-layout: */ 781 QGridLayout *pInputLayout = new QGridLayout; 782 AssertPtrReturnVoid(pInputLayout); 783 { 784 /* Create key-label: */ 785 QLabel *pLabelKey = new QLabel("&Name:"); 786 { 787 /* Configure key-label: */ 788 pLabelKey->setAlignment(Qt::AlignRight); 789 /* Add key-label into input-layout: */ 790 pInputLayout->addWidget(pLabelKey, 0, 0); 791 } 792 /* Create key-editor: */ 793 QLineEdit *pEditorKey = new QLineEdit; 794 { 795 /* Configure key-editor: */ 796 pLabelKey->setBuddy(pEditorKey); 797 /* Create key-editor property setter: */ 798 QObjectPropertySetter *pKeyPropertySetter = new QObjectPropertySetter(pInputDialog, "Key"); 799 AssertPtrReturnVoid(pKeyPropertySetter); 800 { 801 /* Configure key-editor property setter: */ 802 connect(pEditorKey, SIGNAL(textEdited(const QString&)), 803 pKeyPropertySetter, SLOT(sltAssignProperty(const QString&))); 804 } 805 /* Create key-editor validator: */ 806 QObjectValidator *pKeyValidator = new QObjectValidator(new QRegExpValidator(QRegExp("[\\s\\S]+"))); 807 AssertPtrReturnVoid(pKeyValidator); 808 { 809 /* Configure key-editor validator: */ 810 connect(pEditorKey, SIGNAL(textEdited(const QString&)), 811 pKeyValidator, SLOT(sltValidate(QString))); 812 /* Add key-editor validator into dialog validator group: */ 813 pValidatorGroup->addObjectValidator(pKeyValidator); 814 } 815 /* Add key-editor into input-layout: */ 816 pInputLayout->addWidget(pEditorKey, 0, 1); 817 } 818 /* Create value-label: */ 819 QLabel *pLabelValue = new QLabel("&Value:"); 820 { 821 /* Configure value-label: */ 822 pLabelValue->setAlignment(Qt::AlignRight); 823 /* Add value-label into input-layout: */ 824 pInputLayout->addWidget(pLabelValue, 1, 0); 825 } 826 /* Create value-editor: */ 827 QLineEdit *pEditorValue = new QLineEdit; 828 { 829 /* Configure value-editor: */ 830 pLabelValue->setBuddy(pEditorValue); 831 /* Create value-editor property setter: */ 832 QObjectPropertySetter *pValuePropertySetter = new QObjectPropertySetter(pInputDialog, "Value"); 833 AssertPtrReturnVoid(pValuePropertySetter); 834 { 835 /* Configure value-editor property setter: */ 836 connect(pEditorValue, SIGNAL(textEdited(const QString&)), 837 pValuePropertySetter, SLOT(sltAssignProperty(const QString&))); 838 } 839 /* Create value-editor validator: */ 840 QObjectValidator *pValueValidator = new QObjectValidator(new QRegExpValidator(QRegExp("[\\s\\S]+"))); 841 AssertPtrReturnVoid(pValueValidator); 842 { 843 /* Configure value-editor validator: */ 844 connect(pEditorValue, SIGNAL(textEdited(const QString&)), 845 pValueValidator, SLOT(sltValidate(QString))); 846 /* Add value-editor validator into dialog validator group: */ 847 pValidatorGroup->addObjectValidator(pValueValidator); 848 } 849 /* Add value-editor into input-layout: */ 850 pInputLayout->addWidget(pEditorValue, 1, 1); 851 } 852 /* Add input-layout into main-layout: */ 853 pMainLayout->addLayout(pInputLayout); 854 } 855 /* Create stretch: */ 856 pMainLayout->addStretch(); 857 /* Create dialog button-box: */ 858 QIDialogButtonBox *pButtonBox = new QIDialogButtonBox; 859 AssertPtrReturnVoid(pButtonBox); 860 { 861 /* Configure button-box: */ 862 pButtonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); 863 pButtonBox->button(QDialogButtonBox::Ok)->setDefault(true); 864 pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(pValidatorGroup->result()); 865 pButtonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::Key_Escape); 866 connect(pValidatorGroup, SIGNAL(sigValidityChange(bool)), 867 pButtonBox->button(QDialogButtonBox::Ok), SLOT(setEnabled(bool))); 868 connect(pButtonBox, SIGNAL(accepted()), pInputDialog, SLOT(accept())); 869 connect(pButtonBox, SIGNAL(rejected()), pInputDialog, SLOT(reject())); 870 /* Add button-box into main-layout: */ 871 pMainLayout->addWidget(pButtonBox); 872 } 873 } 874 } 875 876 /* Execute input-dialog: */ 877 if (pInputDialog->exec() == QDialog::Accepted) 878 { 879 gEDataManager->setExtraDataString(pInputDialog->property("Key").toString(), 880 pInputDialog->property("Value").toString(), 881 currentChooserID()); 882 } 883 884 /* Destroy input-dialog: */ 885 if (pInputDialog) 886 delete pInputDialog; 887 } 888 889 void UIExtraDataManagerWindow::sltDel() 890 { 891 /* Make sure this slot called by corresponding action only: */ 892 QAction *pSenderAction = qobject_cast<QAction*>(sender()); 893 AssertReturnVoid(pSenderAction && m_pActionDel); 894 895 /* Gather the map of chosen items: */ 896 QMap<QString, QString> items; 897 foreach (const QModelIndex &keyIndex, m_pViewOfData->selectionModel()->selectedRows(0)) 898 items.insert(keyIndex.data().toString(), dataValueIndex(keyIndex.row()).data().toString()); 899 900 /* Prepare details: */ 901 const QString strTableTemplate("<!--EOM--><table border=0 cellspacing=10 cellpadding=0 width=500>%1</table>"); 902 const QString strRowTemplate("<tr><td><tt>%1</tt></td><td align=right><tt>%2</tt></td></tr>"); 903 QString strDetails; 904 foreach (const QString &strKey, items.keys()) 905 strDetails += strRowTemplate.arg(strKey, items.value(strKey)); 906 strDetails = strTableTemplate.arg(strDetails); 907 908 /* Ask for user' confirmation: */ 909 if (!msgCenter().errorWithQuestion(this, MessageType_Question, 910 QString("<p>Do you really wish to " 911 "remove chosen records?</p>"), 912 strDetails)) 913 return; 914 915 /* Erase all the chosen extra-data records: */ 916 foreach (const QString &strKey, items.keys()) 917 gEDataManager->setExtraDataString(strKey, QString(), currentChooserID()); 918 } 919 920 void UIExtraDataManagerWindow::sltSave() 921 { 922 /* Make sure this slot called by corresponding action only: */ 923 QAction *pSenderAction = qobject_cast<QAction*>(sender()); 924 AssertReturnVoid(pSenderAction && m_pActionSave); 925 926 /* Compose initial file-name: */ 927 const CVirtualBox vbox = vboxGlobal().virtualBox(); 928 const QString strInitialFileName = QDir(vbox.GetHomeFolder()).absoluteFilePath(QString("%1_ExtraData.xml").arg(currentChooserName())); 929 /* Open file-save dialog to choose file to save extra-data into: */ 930 const QString strFileName = QIFileDialog::getSaveFileName(strInitialFileName, "XML files (*.xml)", this, 931 "Choose file to save extra-data into..", 0, true, true); 932 /* Make sure file-name was chosen: */ 933 if (strFileName.isEmpty()) 934 return; 935 936 /* Create file: */ 937 QFile output(strFileName); 938 /* Open file for writing: */ 939 bool fOpened = output.open(QIODevice::WriteOnly); 940 AssertReturnVoid(fOpened); 941 { 942 /* Create XML stream writer: */ 943 QXmlStreamWriter stream(&output); 944 /* Configure XML stream writer: */ 945 stream.setAutoFormatting(true); 946 stream.setAutoFormattingIndent(2); 947 /* Write document: */ 948 stream.writeStartDocument(); 949 { 950 stream.writeStartElement("VirtualBox"); 951 { 952 const QString strID = currentChooserID(); 953 bool fIsMachine = strID != UIExtraDataManager::GlobalID; 954 const QString strType = fIsMachine ? "Machine" : "Global"; 955 stream.writeStartElement(strType); 956 { 957 if (fIsMachine) 958 stream.writeAttribute("uuid", QString("{%1}").arg(strID)); 959 stream.writeStartElement("ExtraData"); 960 { 961 /* Called from context-menu: */ 962 if (pSenderAction->property("CalledFromContextMenu").toBool() && 963 !m_pViewOfData->selectionModel()->selection().isEmpty()) 964 { 965 foreach (const QModelIndex &keyIndex, m_pViewOfData->selectionModel()->selectedRows()) 966 { 967 /* Get data-value index: */ 968 const QModelIndex valueIndex = dataValueIndex(keyIndex.row()); 969 /* Write corresponding extra-data item into stream: */ 970 stream.writeStartElement("ExtraDataItem"); 971 { 972 stream.writeAttribute("name", keyIndex.data().toString()); 973 stream.writeAttribute("value", valueIndex.data().toString()); 974 } 975 stream.writeEndElement(); /* ExtraDataItem */ 976 } 977 } 978 /* Called from menu-bar/tool-bar: */ 979 else 980 { 981 for (int iRow = 0; iRow < m_pModelProxyOfData->rowCount(); ++iRow) 982 { 983 /* Get indexes: */ 984 const QModelIndex keyIndex = m_pModelProxyOfData->index(iRow, 0); 985 const QModelIndex valueIndex = m_pModelProxyOfData->index(iRow, 1); 986 /* Write corresponding extra-data item into stream: */ 987 stream.writeStartElement("ExtraDataItem"); 988 { 989 stream.writeAttribute("name", keyIndex.data().toString()); 990 stream.writeAttribute("value", valueIndex.data().toString()); 991 } 992 stream.writeEndElement(); /* ExtraDataItem */ 993 } 994 } 995 } 996 stream.writeEndElement(); /* ExtraData */ 997 } 998 stream.writeEndElement(); /* strType */ 999 } 1000 stream.writeEndElement(); /* VirtualBox */ 1001 } 1002 stream.writeEndDocument(); 1003 /* Close file: */ 1004 output.close(); 1005 } 1006 } 1007 1008 void UIExtraDataManagerWindow::sltLoad() 1009 { 1010 /* Make sure this slot called by corresponding action only: */ 1011 QAction *pSenderAction = qobject_cast<QAction*>(sender()); 1012 AssertReturnVoid(pSenderAction && m_pActionLoad); 1013 1014 /* Compose initial file-name: */ 1015 const CVirtualBox vbox = vboxGlobal().virtualBox(); 1016 const QString strInitialFileName = QDir(vbox.GetHomeFolder()).absoluteFilePath(QString("%1_ExtraData.xml").arg(currentChooserName())); 1017 /* Open file-open dialog to choose file to open extra-data into: */ 1018 const QString strFileName = QIFileDialog::getOpenFileName(strInitialFileName, "XML files (*.xml)", this, 1019 "Choose file to load extra-data from.."); 1020 /* Make sure file-name was chosen: */ 1021 if (strFileName.isEmpty()) 1022 return; 1023 1024 /* Create file: */ 1025 QFile input(strFileName); 1026 /* Open file for writing: */ 1027 bool fOpened = input.open(QIODevice::ReadOnly); 1028 AssertReturnVoid(fOpened); 1029 { 1030 /* Create XML stream reader: */ 1031 QXmlStreamReader stream(&input); 1032 /* Read XML stream: */ 1033 while (!stream.atEnd()) 1034 { 1035 /* Read subsequent token: */ 1036 const QXmlStreamReader::TokenType tokenType = stream.readNext(); 1037 /* Skip non-interesting tokens: */ 1038 if (tokenType != QXmlStreamReader::StartElement) 1039 continue; 1040 1041 /* Get the name of the current element: */ 1042 const QStringRef strElementName = stream.name(); 1043 1044 /* Search for the scope ID: */ 1045 QString strLoadingID; 1046 if (strElementName == "Global") 1047 strLoadingID = UIExtraDataManager::GlobalID; 1048 else if (strElementName == "Machine") 1049 { 1050 const QXmlStreamAttributes attributes = stream.attributes(); 1051 if (attributes.hasAttribute("uuid")) 1052 { 1053 const QString strUuid = attributes.value("uuid").toString(); 1054 const QUuid uuid = strUuid; 1055 if (!uuid.isNull()) 1056 strLoadingID = uuid.toString().remove(QRegExp("[{}]")); 1057 else 1058 msgCenter().alert(this, MessageType_Warning, 1059 QString("<p>Invalid extra-data ID:</p>" 1060 "<p>%1</p>").arg(strUuid)); 1061 } 1062 } 1063 /* Look particular extra-data entries: */ 1064 else if (strElementName == "ExtraDataItem") 1065 { 1066 const QXmlStreamAttributes attributes = stream.attributes(); 1067 if (attributes.hasAttribute("name") && attributes.hasAttribute("value")) 1068 { 1069 const QString strName = attributes.value("name").toString(); 1070 const QString strValue = attributes.value("value").toString(); 1071 gEDataManager->setExtraDataString(strName, strValue, currentChooserID()); 1072 } 1073 } 1074 1075 /* Check extra-data ID: */ 1076 if (!strLoadingID.isNull() && strLoadingID != currentChooserID() && 1077 !msgCenter().questionBinary(this, MessageType_Question, 1078 QString("<p>Inconsistent extra-data ID:</p>" 1079 "<p>Current: {%1}</p>" 1080 "<p>Loading: {%2}</p>" 1081 "<p>Continue with loading?</p>") 1082 .arg(currentChooserID(), strLoadingID))) 1083 break; 1084 } 1085 /* Handle XML stream error: */ 1086 if (stream.hasError()) 1087 msgCenter().alert(this, MessageType_Warning, 1088 QString("<p>Error reading XML file:</p>" 1089 "<p>%1</p>").arg(stream.error())); 1090 /* Close file: */ 1091 input.close(); 1092 } 1093 } 1094 1095 void UIExtraDataManagerWindow::prepare() 1096 { 1097 /* Prepare this: */ 1098 prepareThis(); 1099 /* Prepare connections: */ 1100 prepareConnections(); 1101 /* Prepare menu: */ 1102 prepareMenu(); 1103 /* Prepare central-widget: */ 1104 prepareCentralWidget(); 1105 /* Load settings: */ 1106 loadSettings(); 1107 } 1108 1109 void UIExtraDataManagerWindow::prepareThis() 1110 { 1111 #ifndef Q_WS_MAC 1112 /* Apply window icons: */ 1113 setWindowIcon(UIIconPool::iconSetFull(":/edataman_32px.png", 1114 ":/edataman_16px.png")); 1115 #endif /* !Q_WS_MAC */ 1116 1117 /* Apply window title: */ 1118 setWindowTitle("Extra-data Manager"); 1119 1120 /* Do not count that window as important for application, 1121 * it will NOT be taken into account when other top-level windows will be closed: */ 1122 setAttribute(Qt::WA_QuitOnClose, false); 1123 1124 /* Delete window when closed: */ 1125 setAttribute(Qt::WA_DeleteOnClose); 1126 } 1127 1128 void UIExtraDataManagerWindow::prepareConnections() 1129 { 1130 /* Prepare connections: */ 1131 connect(gVBoxEvents, SIGNAL(sigMachineRegistered(QString, bool)), 1132 this, SLOT(sltMachineRegistered(QString, bool))); 1133 } 1134 1135 void UIExtraDataManagerWindow::prepareMenu() 1136 { 1137 /* Create 'Actions' menu: */ 1138 QMenu *pActionsMenu = menuBar()->addMenu("Actions"); 1139 AssertReturnVoid(pActionsMenu); 1140 { 1141 /* Create 'Add' action: */ 1142 m_pActionAdd = pActionsMenu->addAction("Add"); 1143 AssertReturnVoid(m_pActionAdd); 1144 { 1145 /* Configure 'Add' action: */ 1146 m_pActionAdd->setIcon(UIIconPool::iconSetFull(":/edata_add_22px.png", ":/edata_add_16px.png", 1147 ":/edata_add_disabled_22px.png", ":/edata_add_disabled_16px.png")); 1148 m_pActionAdd->setShortcut(Qt::Key_Insert); 1149 connect(m_pActionAdd, SIGNAL(triggered(bool)), this, SLOT(sltAdd())); 1150 } 1151 /* Create 'Del' action: */ 1152 m_pActionDel = pActionsMenu->addAction("Remove"); 1153 AssertReturnVoid(m_pActionDel); 1154 { 1155 /* Configure 'Del' action: */ 1156 m_pActionDel->setIcon(UIIconPool::iconSetFull(":/edata_remove_22px.png", ":/edata_remove_16px.png", 1157 ":/edata_remove_disabled_22px.png", ":/edata_remove_disabled_16px.png")); 1158 m_pActionDel->setShortcut(Qt::Key_Delete); 1159 connect(m_pActionDel, SIGNAL(triggered(bool)), this, SLOT(sltDel())); 1160 } 1161 1162 /* Add separator: */ 1163 pActionsMenu->addSeparator(); 1164 1165 /* Create 'Load' action: */ 1166 m_pActionLoad = pActionsMenu->addAction("Load"); 1167 AssertReturnVoid(m_pActionLoad); 1168 { 1169 /* Configure 'Load' action: */ 1170 m_pActionLoad->setIcon(UIIconPool::iconSetFull(":/edata_load_22px.png", ":/edata_load_16px.png", 1171 ":/edata_load_disabled_22px.png", ":/edata_load_disabled_16px.png")); 1172 m_pActionLoad->setShortcut(QKeySequence("Ctrl+L")); 1173 connect(m_pActionLoad, SIGNAL(triggered(bool)), this, SLOT(sltLoad())); 1174 } 1175 /* Create 'Save' action: */ 1176 m_pActionSave = pActionsMenu->addAction("Save"); 1177 AssertReturnVoid(m_pActionSave); 1178 { 1179 /* Configure 'Save' action: */ 1180 m_pActionSave->setIcon(UIIconPool::iconSetFull(":/edata_save_22px.png", ":/edata_save_16px.png", 1181 ":/edata_save_disabled_22px.png", ":/edata_save_disabled_16px.png")); 1182 m_pActionSave->setShortcut(QKeySequence("Ctrl+S")); 1183 connect(m_pActionSave, SIGNAL(triggered(bool)), this, SLOT(sltSave())); 1184 } 1185 } 1186 } 1187 1188 void UIExtraDataManagerWindow::prepareCentralWidget() 1189 { 1190 /* Prepare central-widget: */ 1191 setCentralWidget(new QWidget); 1192 AssertPtrReturnVoid(centralWidget()); 1193 { 1194 /* Prepare layout: */ 1195 m_pMainLayout = new QVBoxLayout(centralWidget()); 1196 AssertReturnVoid(m_pMainLayout && centralWidget()->layout() && 1197 m_pMainLayout == centralWidget()->layout()); 1198 { 1199 #if MAC_LEOPARD_STYLE 1200 /* No spacing/margins on the Mac: */ 1201 m_pMainLayout->setContentsMargins(0, 0, 0, 0); 1202 m_pMainLayout->insertSpacing(0, 10); 1203 #else /* !MAC_LEOPARD_STYLE */ 1204 /* Set spacing/margin like in the selector window: */ 1205 m_pMainLayout->setSpacing(5); 1206 m_pMainLayout->setContentsMargins(5, 5, 5, 5); 1207 #endif /* !MAC_LEOPARD_STYLE */ 1208 /* Prepare tool-bar: */ 1209 prepareToolBar(); 1210 /* Prepare splitter: */ 1211 prepareSplitter(); 1212 /* Prepare button-box: */ 1213 prepareButtonBox(); 1214 } 1215 /* Initial focus: */ 1216 m_pViewOfChooser->setFocus(); 1217 } 1218 } 1219 1220 void UIExtraDataManagerWindow::prepareToolBar() 1221 { 1222 /* Create tool-bar: */ 1223 m_pToolBar = new UIToolBar; 1224 AssertPtrReturnVoid(m_pToolBar); 1225 { 1226 /* Configure tool-bar: */ 1227 m_pToolBar->setIconSize(QSize(22, 22)); 1228 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 1229 /* Add actions: */ 1230 m_pToolBar->addAction(m_pActionAdd); 1231 m_pToolBar->addAction(m_pActionDel); 1232 m_pToolBar->addSeparator(); 1233 m_pToolBar->addAction(m_pActionLoad); 1234 m_pToolBar->addAction(m_pActionSave); 1235 /* Integrate tool-bar into dialog: */ 1236 #if MAC_LEOPARD_STYLE 1237 /* Enable unified tool-bars on Mac OS X. Available on Qt >= 4.3: */ 1238 addToolBar(m_pToolBar); 1239 m_pToolBar->setMacToolbar(); 1240 #else /* !MAC_LEOPARD_STYLE */ 1241 /* Add tool-bar into main-layout: */ 1242 m_pMainLayout->addWidget(m_pToolBar); 1243 #endif /* !MAC_LEOPARD_STYLE */ 1244 } 1245 } 1246 1247 void UIExtraDataManagerWindow::prepareSplitter() 1248 { 1249 /* Create splitter: */ 1250 m_pSplitter = new QISplitter; 1251 AssertPtrReturnVoid(m_pSplitter); 1252 { 1253 /* Prepare panes: */ 1254 preparePanes(); 1255 /* Configure splitter: */ 1256 m_pSplitter->setChildrenCollapsible(false); 1257 m_pSplitter->setStretchFactor(0, 0); 1258 m_pSplitter->setStretchFactor(1, 1); 1259 /* Add splitter into main layout: */ 1260 m_pMainLayout->addWidget(m_pSplitter); 1261 } 1262 } 1263 1264 void UIExtraDataManagerWindow::preparePanes() 1265 { 1266 /* Prepare chooser-pane: */ 1267 preparePaneChooser(); 1268 /* Prepare data-pane: */ 1269 preparePaneData(); 1270 /* Link chooser and data panes: */ 1271 connect(m_pViewOfChooser->selectionModel(), 1272 SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), 1273 this, SLOT(sltChooserHandleCurrentChanged(const QModelIndex&))); 1274 connect(m_pViewOfChooser->selectionModel(), 1275 SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), 1276 this, SLOT(sltChooserHandleSelectionChanged(const QItemSelection&, const QItemSelection&))); 1277 connect(m_pViewOfData->selectionModel(), 1278 SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), 1279 this, SLOT(sltDataHandleSelectionChanged(const QItemSelection&, const QItemSelection&))); 1280 connect(m_pModelSourceOfData, SIGNAL(itemChanged(QStandardItem*)), 1281 this, SLOT(sltDataHandleItemChanged(QStandardItem*))); 1282 /* Make sure chooser have current-index if possible: */ 1283 makeSureChooserHaveCurrentIndexIfPossible(); 1284 } 1285 1286 void UIExtraDataManagerWindow::preparePaneChooser() 1287 { 1288 /* Create chooser-pane: */ 1289 m_pPaneOfChooser = new QWidget; 1290 AssertPtrReturnVoid(m_pPaneOfChooser); 1291 { 1292 /* Create layout: */ 1293 QVBoxLayout *pLayout = new QVBoxLayout(m_pPaneOfChooser); 1294 AssertReturnVoid(pLayout && m_pPaneOfChooser->layout() && 1295 pLayout == m_pPaneOfChooser->layout()); 1296 { 1297 /* Configure layout: */ 1298 pLayout->setContentsMargins(0, 0, 3, 0); 1299 /* Create chooser-filter: */ 1300 m_pFilterOfChooser = new QLineEdit; 1301 { 1302 /* Configure chooser-filter: */ 1303 m_pFilterOfChooser->setPlaceholderText("Search.."); 1304 connect(m_pFilterOfChooser, SIGNAL(textChanged(const QString&)), 1305 this, SLOT(sltChooserApplyFilter(const QString&))); 1306 /* Add chooser-filter into layout: */ 1307 pLayout->addWidget(m_pFilterOfChooser); 1308 } 1309 /* Create chooser-view: */ 1310 m_pViewOfChooser = new QListView; 1311 AssertPtrReturnVoid(m_pViewOfChooser); 1312 { 1313 /* Configure chooser-view: */ 1314 delete m_pViewOfChooser->itemDelegate(); 1315 m_pViewOfChooser->setItemDelegate(new UIChooserPaneDelegate(m_pViewOfChooser)); 1316 m_pViewOfChooser->setSelectionMode(QAbstractItemView::SingleSelection); 1317 /* Create source-model: */ 1318 m_pModelSourceOfChooser = new QStandardItemModel(m_pViewOfChooser); 1319 AssertPtrReturnVoid(m_pModelSourceOfChooser); 1320 { 1321 /* Create proxy-model: */ 1322 m_pModelProxyOfChooser = new UIChooserPaneSortingModel(m_pViewOfChooser); 1323 AssertPtrReturnVoid(m_pModelProxyOfChooser); 1324 { 1325 /* Configure proxy-model: */ 1326 m_pModelProxyOfChooser->setSortRole(Field_Name); 1327 m_pModelProxyOfChooser->setFilterRole(Field_Name); 1328 m_pModelProxyOfChooser->setSortCaseSensitivity(Qt::CaseInsensitive); 1329 m_pModelProxyOfChooser->setFilterCaseSensitivity(Qt::CaseInsensitive); 1330 m_pModelProxyOfChooser->setSourceModel(m_pModelSourceOfChooser); 1331 m_pViewOfChooser->setModel(m_pModelProxyOfChooser); 1332 } 1333 /* Add global chooser item into source-model: */ 1334 addChooserItemByID(UIExtraDataManager::GlobalID); 1335 /* Add machine chooser items into source-model: */ 1336 CMachineVector machines = vboxGlobal().virtualBox().GetMachines(); 1337 foreach (const CMachine &machine, machines) 1338 addChooserItemByMachine(machine); 1339 /* And sort proxy-model: */ 1340 m_pModelProxyOfChooser->sort(0, Qt::AscendingOrder); 1341 } 1342 /* Add chooser-view into layout: */ 1343 pLayout->addWidget(m_pViewOfChooser); 1344 } 1345 } 1346 /* Add chooser-pane into splitter: */ 1347 m_pSplitter->addWidget(m_pPaneOfChooser); 1348 } 1349 } 1350 1351 void UIExtraDataManagerWindow::preparePaneData() 1352 { 1353 /* Create data-pane: */ 1354 m_pPaneOfData = new QWidget; 1355 AssertPtrReturnVoid(m_pPaneOfData); 1356 { 1357 /* Create layout: */ 1358 QVBoxLayout *pLayout = new QVBoxLayout(m_pPaneOfData); 1359 AssertReturnVoid(pLayout && m_pPaneOfData->layout() && 1360 pLayout == m_pPaneOfData->layout()); 1361 { 1362 /* Configure layout: */ 1363 pLayout->setContentsMargins(3, 0, 0, 0); 1364 /* Create data-filter: */ 1365 m_pFilterOfData = new QLineEdit; 1366 { 1367 /* Configure data-filter: */ 1368 m_pFilterOfData->setPlaceholderText("Search.."); 1369 connect(m_pFilterOfData, SIGNAL(textChanged(const QString&)), 1370 this, SLOT(sltDataApplyFilter(const QString&))); 1371 /* Add data-filter into layout: */ 1372 pLayout->addWidget(m_pFilterOfData); 1373 } 1374 /* Create data-view: */ 1375 m_pViewOfData = new QTableView; 1376 AssertPtrReturnVoid(m_pViewOfData); 1377 { 1378 /* Create item-model: */ 1379 m_pModelSourceOfData = new QStandardItemModel(0, 2, m_pViewOfData); 1380 AssertPtrReturnVoid(m_pModelSourceOfData); 1381 { 1382 /* Create proxy-model: */ 1383 m_pModelProxyOfData = new QSortFilterProxyModel(m_pViewOfChooser); 1384 AssertPtrReturnVoid(m_pModelProxyOfData); 1385 { 1386 /* Configure proxy-model: */ 1387 m_pModelProxyOfData->setSortCaseSensitivity(Qt::CaseInsensitive); 1388 m_pModelProxyOfData->setFilterCaseSensitivity(Qt::CaseInsensitive); 1389 m_pModelProxyOfData->setSourceModel(m_pModelSourceOfData); 1390 m_pViewOfData->setModel(m_pModelProxyOfData); 1391 } 1392 /* Configure item-model: */ 1393 m_pModelSourceOfData->setHorizontalHeaderLabels(QStringList() << "Key" << "Value"); 1394 } 1395 /* Configure data-view: */ 1396 m_pViewOfData->setSortingEnabled(true); 1397 m_pViewOfData->setAlternatingRowColors(true); 1398 m_pViewOfData->setContextMenuPolicy(Qt::CustomContextMenu); 1399 m_pViewOfData->setSelectionMode(QAbstractItemView::ExtendedSelection); 1400 m_pViewOfData->setSelectionBehavior(QAbstractItemView::SelectRows); 1401 connect(m_pViewOfData, SIGNAL(customContextMenuRequested(const QPoint&)), 1402 this, SLOT(sltDataHandleCustomContextMenuRequested(const QPoint&))); 1403 QHeaderView *pVHeader = m_pViewOfData->verticalHeader(); 1404 QHeaderView *pHHeader = m_pViewOfData->horizontalHeader(); 1405 pVHeader->hide(); 1406 pHHeader->setSortIndicator(0, Qt::AscendingOrder); 1407 pHHeader->resizeSection(0, qMin(300, pHHeader->width() / 3)); 1408 pHHeader->setStretchLastSection(true); 1409 /* Add data-view into layout: */ 1410 pLayout->addWidget(m_pViewOfData); 1411 } 1412 } 1413 /* Add data-pane into splitter: */ 1414 m_pSplitter->addWidget(m_pPaneOfData); 1415 } 1416 } 1417 1418 void UIExtraDataManagerWindow::prepareButtonBox() 1419 { 1420 /* Create button-box: */ 1421 m_pButtonBox = new QIDialogButtonBox; 1422 AssertPtrReturnVoid(m_pButtonBox); 1423 { 1424 /* Configure button-box: */ 1425 m_pButtonBox->setStandardButtons(QDialogButtonBox::Help | QDialogButtonBox::Close); 1426 m_pButtonBox->button(QDialogButtonBox::Close)->setShortcut(Qt::Key_Escape); 1427 connect(m_pButtonBox, SIGNAL(helpRequested()), &msgCenter(), SLOT(sltShowHelpHelpDialog())); 1428 connect(m_pButtonBox, SIGNAL(rejected()), this, SLOT(close())); 1429 /* Add button-box into main layout: */ 1430 m_pMainLayout->addWidget(m_pButtonBox); 1431 } 1432 } 1433 1434 void UIExtraDataManagerWindow::loadSettings() 1435 { 1436 /* Load window geometry: */ 1437 { 1438 /* Load geometry: */ 1439 m_geometry = gEDataManager->extraDataManagerGeometry(this); 1440 #ifdef Q_WS_MAC 1441 move(m_geometry.topLeft()); 1442 resize(m_geometry.size()); 1443 #else /* Q_WS_MAC */ 1444 setGeometry(m_geometry); 1445 #endif /* !Q_WS_MAC */ 1446 LogRel(("UIExtraDataManagerWindow: Geometry loaded to: %dx%d @ %dx%d.\n", 1447 m_geometry.x(), m_geometry.y(), m_geometry.width(), m_geometry.height())); 1448 1449 /* Maximize (if necessary): */ 1450 if (gEDataManager->extraDataManagerShouldBeMaximized()) 1451 showMaximized(); 1452 } 1453 1454 /* Load splitter hints: */ 1455 { 1456 m_pSplitter->setSizes(gEDataManager->extraDataManagerSplitterHints(this)); 1457 } 1458 } 1459 1460 void UIExtraDataManagerWindow::saveSettings() 1461 { 1462 /* Save splitter hints: */ 1463 { 1464 gEDataManager->setExtraDataManagerSplitterHints(m_pSplitter->sizes()); 1465 } 1466 1467 /* Save window geometry: */ 1468 { 1469 /* Save geometry: */ 1470 #ifdef Q_WS_MAC 1471 gEDataManager->setExtraDataManagerGeometry(m_geometry, ::darwinIsWindowMaximized(this)); 1472 #else /* Q_WS_MAC */ 1473 gEDataManager->setExtraDataManagerGeometry(m_geometry, isMaximized()); 1474 #endif /* !Q_WS_MAC */ 1475 LogRel(("UIExtraDataManagerWindow: Geometry saved as: %dx%d @ %dx%d.\n", 1476 m_geometry.x(), m_geometry.y(), m_geometry.width(), m_geometry.height())); 1477 } 1478 } 1479 1480 void UIExtraDataManagerWindow::cleanup() 1481 { 1482 /* Save settings: */ 1483 saveSettings(); 1484 } 1485 1486 bool UIExtraDataManagerWindow::event(QEvent *pEvent) 1487 { 1488 /* Pre-process through base-class: */ 1489 bool fResult = QMainWindow::event(pEvent); 1490 1491 /* Process required events: */ 1492 switch (pEvent->type()) 1493 { 1494 /* Handle every Resize and Move we keep track of the geometry. */ 1495 case QEvent::Resize: 1496 { 1497 if (isVisible() && (windowState() & (Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen)) == 0) 1498 { 1499 QResizeEvent *pResizeEvent = static_cast<QResizeEvent*>(pEvent); 1500 m_geometry.setSize(pResizeEvent->size()); 1501 } 1502 break; 1503 } 1504 case QEvent::Move: 1505 { 1506 if (isVisible() && (windowState() & (Qt::WindowMaximized | Qt::WindowMinimized | Qt::WindowFullScreen)) == 0) 1507 { 1508 #ifdef Q_WS_MAC 1509 QMoveEvent *pMoveEvent = static_cast<QMoveEvent*>(pEvent); 1510 m_geometry.moveTo(pMoveEvent->pos()); 1511 #else /* !Q_WS_MAC */ 1512 m_geometry.moveTo(geometry().x(), geometry().y()); 1513 #endif /* !Q_WS_MAC */ 1514 } 1515 break; 1516 } 1517 default: 1518 break; 1519 } 1520 1521 /* Return result: */ 1522 return fResult; 1523 } 1524 1525 void UIExtraDataManagerWindow::updateActionsAvailability() 1526 { 1527 /* Is there something selected in chooser-view? */ 1528 bool fChooserHasSelection = !m_pViewOfChooser->selectionModel()->selection().isEmpty(); 1529 /* Is there something selected in data-view? */ 1530 bool fDataHasSelection = !m_pViewOfData->selectionModel()->selection().isEmpty(); 1531 1532 /* Enable/disable corresponding actions: */ 1533 m_pActionAdd->setEnabled(fChooserHasSelection); 1534 m_pActionDel->setEnabled(fChooserHasSelection && fDataHasSelection); 1535 m_pActionLoad->setEnabled(fChooserHasSelection); 1536 m_pActionSave->setEnabled(fChooserHasSelection); 1537 } 1538 1539 QModelIndex UIExtraDataManagerWindow::chooserIndex(int iRow) const 1540 { 1541 return m_pModelSourceOfChooser->index(iRow, 0); 1542 } 1543 1544 QModelIndex UIExtraDataManagerWindow::currentChooserIndex() const 1545 { 1546 return m_pViewOfChooser->currentIndex(); 1547 } 1548 1549 QString UIExtraDataManagerWindow::chooserID(int iRow) const 1550 { 1551 return chooserIndex(iRow).data(Field_ID).toString(); 1552 } 1553 1554 QString UIExtraDataManagerWindow::currentChooserID() const 1555 { 1556 return currentChooserIndex().data(Field_ID).toString(); 1557 } 1558 1559 QString UIExtraDataManagerWindow::chooserName(int iRow) const 1560 { 1561 return chooserIndex(iRow).data(Field_Name).toString(); 1562 } 1563 1564 QString UIExtraDataManagerWindow::currentChooserName() const 1565 { 1566 return currentChooserIndex().data(Field_Name).toString(); 1567 } 1568 1569 void UIExtraDataManagerWindow::addChooserItem(const QString &strID, 1570 const QString &strName, 1571 const QString &strOsTypeID, 1572 const int iPosition /* = -1 */) 1573 { 1574 /* Create item: */ 1575 QStandardItem *pItem = new QStandardItem; 1576 AssertPtrReturnVoid(pItem); 1577 { 1578 /* Which is NOT editable: */ 1579 pItem->setEditable(false); 1580 /* Contains passed ID: */ 1581 pItem->setData(strID, Field_ID); 1582 /* Contains passed name: */ 1583 pItem->setData(strName, Field_Name); 1584 /* Contains passed OS Type ID: */ 1585 pItem->setData(strOsTypeID, Field_OsTypeID); 1586 /* And designated as known/unknown depending on extra-data manager status: */ 1587 pItem->setData(gEDataManager->contains(strID), Field_Known); 1588 /* If insert position defined: */ 1589 if (iPosition != -1) 1590 { 1591 /* Insert this item at specified position: */ 1592 m_pModelSourceOfChooser->insertRow(iPosition, pItem); 1593 } 1594 /* If insert position undefined: */ 1595 else 1596 { 1597 /* Add this item as the last one: */ 1598 m_pModelSourceOfChooser->appendRow(pItem); 1599 } 1600 } 1601 } 1602 1603 void UIExtraDataManagerWindow::addChooserItemByMachine(const CMachine &machine, 1604 const int iPosition /* = -1 */) 1605 { 1606 /* Call to wrapper above: */ 1607 addChooserItem(machine.GetId(), machine.GetName(), machine.GetOSTypeId(), iPosition); 1608 } 1609 1610 void UIExtraDataManagerWindow::addChooserItemByID(const QString &strID, 1611 const int iPosition /* = -1 */) 1612 { 1613 /* Prepare arguments: */ 1614 QString strName; 1615 QString strOsTypeID; 1616 /* Global ID? */ 1617 if (strID == UIExtraDataManager::GlobalID) 1618 strName = "Global"; 1619 /* Machine ID? */ 1620 else 1621 { 1622 /* Search for the corresponding machine by ID: */ 1623 CVirtualBox vbox = vboxGlobal().virtualBox(); 1624 const CMachine machine = vbox.FindMachine(strID); 1625 /* Acquire actual arguments if possible: */ 1626 if (vbox.isOk() && !machine.isNull()) 1627 { 1628 strName = machine.GetName(); 1629 strOsTypeID = machine.GetOSTypeId(); 1630 } 1631 /* Or use default: */ 1632 else 1633 { 1634 strName = "Unknown VM"; 1635 strOsTypeID = "Other"; 1636 } 1637 } 1638 /* Call to wrapper above: */ 1639 addChooserItem(strID, strName, strOsTypeID, iPosition); 1640 } 1641 1642 void UIExtraDataManagerWindow::makeSureChooserHaveCurrentIndexIfPossible() 1643 { 1644 /* Make sure chooser have current-index if possible: */ 1645 if (!m_pViewOfChooser->currentIndex().isValid()) 1646 { 1647 /* Do we still have anything to select? */ 1648 const QModelIndex firstIndex = m_pModelProxyOfChooser->index(0, 0); 1649 if (firstIndex.isValid()) 1650 m_pViewOfChooser->setCurrentIndex(firstIndex); 1651 } 1652 } 1653 1654 QModelIndex UIExtraDataManagerWindow::dataIndex(int iRow, int iColumn) const 1655 { 1656 return m_pModelSourceOfData->index(iRow, iColumn); 1657 } 1658 1659 QModelIndex UIExtraDataManagerWindow::dataKeyIndex(int iRow) const 1660 { 1661 return dataIndex(iRow, 0); 1662 } 1663 1664 QModelIndex UIExtraDataManagerWindow::dataValueIndex(int iRow) const 1665 { 1666 return dataIndex(iRow, 1); 1667 } 1668 1669 QString UIExtraDataManagerWindow::dataKey(int iRow) const 1670 { 1671 return dataKeyIndex(iRow).data().toString(); 1672 } 1673 1674 QString UIExtraDataManagerWindow::dataValue(int iRow) const 1675 { 1676 return dataValueIndex(iRow).data().toString(); 1677 } 1678 1679 void UIExtraDataManagerWindow::addDataItem(const QString &strKey, 1680 const QString &strValue, 1681 const int iPosition /* = -1 */) 1682 { 1683 /* Prepare items: */ 1684 QList<QStandardItem*> items; 1685 /* Create key item: */ 1686 items << new QStandardItem(strKey); 1687 items.last()->setEditable(false); 1688 AssertPtrReturnVoid(items.last()); 1689 /* Create value item: */ 1690 items << new QStandardItem(strValue); 1691 AssertPtrReturnVoid(items.last()); 1692 /* If insert position defined: */ 1693 if (iPosition != -1) 1694 { 1695 /* Insert these items as the row at the required position: */ 1696 m_pModelSourceOfData->insertRow(iPosition, items); 1697 } 1698 /* If insert position undefined: */ 1699 else 1700 { 1701 /* Add these items as the last one row: */ 1702 m_pModelSourceOfData->appendRow(items); 1703 } 1704 } 1705 1706 void UIExtraDataManagerWindow::sortData() 1707 { 1708 /* Sort using current rules: */ 1709 const QHeaderView *pHHeader = m_pViewOfData->horizontalHeader(); 1710 const int iSortSection = pHHeader->sortIndicatorSection(); 1711 const Qt::SortOrder sortOrder = pHHeader->sortIndicatorOrder(); 1712 m_pModelProxyOfData->sort(iSortSection, sortOrder); 1713 } 1714 #endif /* DEBUG */ 1715 1716 119 1717 /* static */ 120 1718 UIExtraDataManager *UIExtraDataManager::m_spInstance = 0; … … 144 1742 } 145 1743 } 1744 1745 #ifdef DEBUG 1746 /* static */ 1747 void UIExtraDataManager::openWindow(QWidget *pCenterWidget) 1748 { 1749 /* Pass to instance: */ 1750 instance()->open(pCenterWidget); 1751 } 1752 #endif /* DEBUG */ 146 1753 147 1754 QString UIExtraDataManager::extraDataString(const QString &strKey, const QString &strID /* = GlobalID */) … … 1254 2861 } 1255 2862 #endif /* VBOX_WITH_DEBUGGER_GUI */ 2863 2864 #ifdef DEBUG 2865 QRect UIExtraDataManager::extraDataManagerGeometry(QWidget *pWidget) 2866 { 2867 /* Get corresponding extra-data: */ 2868 const QStringList data = extraDataStringList(GUI_ExtraDataManager_Geometry); 2869 2870 /* Parse loaded data: */ 2871 int iX = 0, iY = 0, iW = 0, iH = 0; 2872 bool fOk = data.size() >= 4; 2873 do 2874 { 2875 if (!fOk) break; 2876 iX = data[0].toInt(&fOk); 2877 if (!fOk) break; 2878 iY = data[1].toInt(&fOk); 2879 if (!fOk) break; 2880 iW = data[2].toInt(&fOk); 2881 if (!fOk) break; 2882 iH = data[3].toInt(&fOk); 2883 } 2884 while (0); 2885 2886 /* Use geometry (loaded or default): */ 2887 QRect geometry = fOk ? QRect(iX, iY, iW, iH) : QRect(0, 0, 800, 600); 2888 2889 /* Take hint-widget into account: */ 2890 if (pWidget) 2891 geometry.setSize(geometry.size().expandedTo(pWidget->minimumSizeHint())); 2892 2893 /* Get screen-geometry [of screen with point (iX, iY) if possible]: */ 2894 const QRect screenGeometry = fOk ? QApplication::desktop()->availableGeometry(QPoint(iX, iY)) : 2895 QApplication::desktop()->availableGeometry(); 2896 2897 /* Make sure resulting geometry is within current bounds: */ 2898 geometry = geometry.intersected(screenGeometry); 2899 2900 /* Move default-geometry to current screen center: */ 2901 if (!fOk) 2902 geometry.moveCenter(screenGeometry.center()); 2903 2904 /* Return result: */ 2905 return geometry; 2906 } 2907 2908 bool UIExtraDataManager::extraDataManagerShouldBeMaximized() 2909 { 2910 /* Get corresponding extra-data: */ 2911 const QStringList data = extraDataStringList(GUI_ExtraDataManager_Geometry); 2912 2913 /* Make sure 5th item has required value: */ 2914 return data.size() == 5 && data[4] == GUI_Geometry_State_Max; 2915 } 2916 2917 void UIExtraDataManager::setExtraDataManagerGeometry(const QRect &geometry, bool fMaximized) 2918 { 2919 /* Serialize passed values: */ 2920 QStringList data; 2921 data << QString::number(geometry.x()); 2922 data << QString::number(geometry.y()); 2923 data << QString::number(geometry.width()); 2924 data << QString::number(geometry.height()); 2925 if (fMaximized) 2926 data << GUI_Geometry_State_Max; 2927 2928 /* Re-cache corresponding extra-data: */ 2929 setExtraDataStringList(GUI_ExtraDataManager_Geometry, data); 2930 } 2931 2932 QList<int> UIExtraDataManager::extraDataManagerSplitterHints(QWidget *pWidget) 2933 { 2934 /* Get corresponding extra-data: */ 2935 const QStringList data = extraDataStringList(GUI_ExtraDataManager_SplitterHints); 2936 2937 /* Parse loaded data: */ 2938 int iLeft = 0, iRight = 0; 2939 bool fOk = data.size() == 2; 2940 do 2941 { 2942 if (!fOk) break; 2943 iLeft = data[0].toInt(&fOk); 2944 if (!fOk) break; 2945 iRight = data[1].toInt(&fOk); 2946 } 2947 while (0); 2948 2949 /* Prepare hints (loaded or adviced): */ 2950 QList<int> hints; 2951 if (fOk) 2952 { 2953 hints << iLeft; 2954 hints << iRight; 2955 } 2956 else 2957 { 2958 hints << pWidget->width() * .9 * (1.0 / 3); 2959 hints << pWidget->width() * .9 * (2.0 / 3); 2960 } 2961 2962 /* Return hints: */ 2963 return hints; 2964 } 2965 2966 void UIExtraDataManager::setExtraDataManagerSplitterHints(const QList<int> &hints) 2967 { 2968 /* Parse passed hints: */ 2969 QStringList data; 2970 data << (hints.size() > 0 ? QString::number(hints[0]) : QString()); 2971 data << (hints.size() > 1 ? QString::number(hints[1]) : QString()); 2972 2973 /* Re-cache corresponding extra-data: */ 2974 setExtraDataStringList(GUI_ExtraDataManager_SplitterHints, data); 2975 } 2976 #endif /* DEBUG */ 1256 2977 1257 2978 void UIExtraDataManager::sltExtraDataChange(QString strMachineID, QString strKey, QString strValue) … … 1369 3090 } 1370 3091 3092 #ifdef DEBUG 3093 void UIExtraDataManager::cleanupWindow() 3094 { 3095 delete m_pWindow; 3096 } 3097 #endif /* DEBUG */ 3098 1371 3099 void UIExtraDataManager::cleanupMainEventListener() 1372 3100 { … … 1378 3106 void UIExtraDataManager::cleanup() 1379 3107 { 3108 #ifdef DEBUG 3109 /* Cleanup window: */ 3110 cleanupWindow(); 3111 #endif /* DEBUG */ 1380 3112 /* Cleanup Main event-listener: */ 1381 3113 cleanupMainEventListener(); 1382 3114 } 3115 3116 #ifdef DEBUG 3117 void UIExtraDataManager::open(QWidget *pCenterWidget) 3118 { 3119 /* If necessary: */ 3120 if (!m_pWindow) 3121 { 3122 /* Create window: */ 3123 m_pWindow = new UIExtraDataManagerWindow; 3124 /* Configure window connections: */ 3125 connect(this, SIGNAL(sigExtraDataChange(QString, QString, QString)), 3126 m_pWindow, SLOT(sltExtraDataChange(QString, QString, QString))); 3127 } 3128 /* Show and raise window: */ 3129 m_pWindow->showAndRaise(pCenterWidget); 3130 } 3131 #endif /* DEBUG */ 1383 3132 1384 3133 void UIExtraDataManager::hotloadMachineExtraDataMap(const QString &strID) -
trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.h
r51930 r51931 21 21 #include <QObject> 22 22 #include <QMap> 23 #ifdef DEBUG 24 # include <QPointer> 25 #endif /* DEBUG */ 23 26 24 27 /* GUI includes: */ … … 30 33 /* Forward declarations: */ 31 34 class UIExtraDataEventHandler; 35 #ifdef DEBUG 36 class UIExtraDataManagerWindow; 37 #endif /* DEBUG */ 32 38 33 39 /* Type definitions: */ … … 78 84 /** Static Extra-data Manager destructor. */ 79 85 static void destroy(); 86 87 #ifdef DEBUG 88 /** Static show and raise API. */ 89 static void openWindow(QWidget *pCenterWidget); 90 #endif /* DEBUG */ 80 91 81 92 /** @name General … … 406 417 #endif /* VBOX_WITH_DEBUGGER_GUI */ 407 418 419 #ifdef DEBUG 420 /** @name VirtualBox: Extra-data Manager window 421 * @{ */ 422 /** Returns Extra-data Manager geometry using @a pWidget as hint. */ 423 QRect extraDataManagerGeometry(QWidget *pWidget); 424 /** Returns whether Extra-data Manager should be maximized or not. */ 425 bool extraDataManagerShouldBeMaximized(); 426 /** Defines Extra-data Manager @a geometry and @a fMaximized state. */ 427 void setExtraDataManagerGeometry(const QRect &geometry, bool fMaximized); 428 429 /** Returns Extra-data Manager splitter hints using @a pWidget as hint. */ 430 QList<int> extraDataManagerSplitterHints(QWidget *pWidget); 431 /** Defines Extra-data Manager splitter @a hints. */ 432 void setExtraDataManagerSplitterHints(const QList<int> &hints); 433 /** @} */ 434 #endif /* DEBUG */ 435 408 436 private slots: 409 437 … … 421 449 /** Prepare Main event-listener. */ 422 450 void prepareMainEventListener(); 423 451 #ifdef DEBUG 452 // /** Prepare window. */ 453 // void prepareWindow(); 454 455 /** Cleanup window. */ 456 void cleanupWindow(); 457 #endif /* DEBUG */ 424 458 /** Cleanup Main event-listener. */ 425 459 void cleanupMainEventListener(); … … 431 465 void cleanup(); 432 466 467 #ifdef DEBUG 468 /** Open window. */ 469 void open(QWidget *pCenterWidget); 470 #endif /* DEBUG */ 471 433 472 /** Hot-load machine extra-data map. */ 434 473 void hotloadMachineExtraDataMap(const QString &strID); … … 460 499 /** Holds extra-data map instance. */ 461 500 QMap<QString, ExtraDataMap> m_data; 501 502 #ifdef DEBUG 503 /** Holds Extra-data Manager window instance. */ 504 QPointer<UIExtraDataManagerWindow> m_pWindow; 505 #endif /* DEBUG */ 462 506 }; 463 507 -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UIActionPoolSelector.cpp
r51668 r51931 144 144 } 145 145 }; 146 147 #ifdef DEBUG 148 class UIActionSimpleExtraDataManagerWindow : public UIActionSimple 149 { 150 Q_OBJECT; 151 152 public: 153 154 UIActionSimpleExtraDataManagerWindow(UIActionPool *pParent) 155 : UIActionSimple(pParent, ":/edataman_16px.png") 156 { 157 retranslateUi(); 158 } 159 160 protected: 161 162 QString shortcutExtraDataID() const 163 { 164 return QString("ExtraDataManager"); 165 } 166 167 QKeySequence defaultShortcut(UIActionPoolType) const 168 { 169 return QKeySequence("Ctrl+X"); 170 } 171 172 void retranslateUi() 173 { 174 setName(QApplication::translate("UIActionPool", "E&xtra Data Manager...")); 175 setStatusTip(QApplication::translate("UIActionPool", "Display the Extra Data Manager window")); 176 } 177 }; 178 #endif /* DEBUG */ 146 179 147 180 class UIActionSimpleExit : public UIActionSimple … … 979 1012 m_pool[UIActionIndexSelector_Simple_File_ImportApplianceWizard] = new UIActionSimpleImportApplianceWizard(this); 980 1013 m_pool[UIActionIndexSelector_Simple_File_ExportApplianceWizard] = new UIActionSimpleExportApplianceWizard(this); 1014 #ifdef DEBUG 1015 m_pool[UIActionIndexSelector_Simple_File_ExtraDataManagerWindow] = new UIActionSimpleExtraDataManagerWindow(this); 1016 #endif /* DEBUG */ 981 1017 m_pool[UIActionIndexSelector_Simple_File_Exit] = new UIActionSimpleExit(this); 982 1018 -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UIActionPoolSelector.h
r51390 r51931 31 31 UIActionIndexSelector_Simple_File_ImportApplianceWizard, 32 32 UIActionIndexSelector_Simple_File_ExportApplianceWizard, 33 #ifdef DEBUG 34 UIActionIndexSelector_Simple_File_ExtraDataManagerWindow, 35 #endif /* DEBUG */ 33 36 UIActionIndexSelector_Simple_File_Exit, 34 37 -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.cpp
r51679 r51931 310 310 } 311 311 312 #ifdef DEBUG 313 void UISelectorWindow::sltOpenExtraDataManagerWindow() 314 { 315 gEDataManager->openWindow(this); 316 } 317 #endif /* DEBUG */ 318 312 319 void UISelectorWindow::sltShowPreferencesDialog() 313 320 { … … 1147 1154 pMenu->addSeparator(); 1148 1155 #endif /* Q_WS_MAC */ 1156 #ifdef DEBUG 1157 m_pExtraDataManagerWindowAction = gActionPool->action(UIActionIndexSelector_Simple_File_ExtraDataManagerWindow); 1158 pMenu->addAction(m_pExtraDataManagerWindowAction); 1159 #endif /* DEBUG */ 1149 1160 m_pPreferencesDialogAction = gActionPool->action(UIActionIndex_Simple_Preferences); 1150 1161 pMenu->addAction(m_pPreferencesDialogAction); … … 1422 1433 connect(m_pImportApplianceWizardAction, SIGNAL(triggered()), this, SLOT(sltShowImportApplianceWizard())); 1423 1434 connect(m_pExportApplianceWizardAction, SIGNAL(triggered()), this, SLOT(sltShowExportApplianceWizard())); 1435 #ifdef DEBUG 1436 connect(m_pExtraDataManagerWindowAction, SIGNAL(triggered()), this, SLOT(sltOpenExtraDataManagerWindow())); 1437 #endif /* DEBUG */ 1424 1438 connect(m_pPreferencesDialogAction, SIGNAL(triggered()), this, SLOT(sltShowPreferencesDialog())); 1425 1439 connect(m_pExitAction, SIGNAL(triggered()), this, SLOT(sltPerformExit())); -
trunk/src/VBox/Frontends/VirtualBox/src/selector/UISelectorWindow.h
r51665 r51931 72 72 void sltShowImportApplianceWizard(const QString &strFileName = QString()); 73 73 void sltShowExportApplianceWizard(); 74 #ifdef DEBUG 75 void sltOpenExtraDataManagerWindow(); 76 #endif /* DEBUG */ 74 77 void sltShowPreferencesDialog(); 75 78 void sltPerformExit(); … … 182 185 UIAction *m_pExportApplianceWizardAction; 183 186 UIAction *m_pPreferencesDialogAction; 187 #ifdef DEBUG 188 UIAction *m_pExtraDataManagerWindowAction; 189 #endif /* DEBUG */ 184 190 UIAction *m_pExitAction; 185 191
Note:
See TracChangeset
for help on using the changeset viewer.