- Timestamp:
- May 28, 2018 2:37:10 PM (7 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 2 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r72350 r72357 673 673 src/medium/UIMediumDetailsWidget.h \ 674 674 src/medium/UIMediumManager.h \ 675 src/medium/UIMediumSelector.h \ 675 676 src/selector/UIDesktopPane.h \ 676 677 src/selector/UIVMItem.h \ … … 1312 1313 src/medium/UIMediumDetailsWidget.cpp \ 1313 1314 src/medium/UIMediumManager.cpp \ 1315 src/medium/UIMediumSelector.cpp \ 1314 1316 src/selector/UIDesktopPane.cpp \ 1315 1317 src/selector/UIVMItem.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIManagerDialog.h
r71871 r72357 59 59 class SHARED_LIBRARY_STUFF QIManagerDialogFactory 60 60 { 61 61 62 public: 62 63 -
trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumSelector.cpp
r72344 r72357 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIMedium Manager class implementation.3 * VBox Qt GUI - UIMediumSelector class implementation. 4 4 */ 5 5 … … 28 28 # include <QProgressBar> 29 29 # include <QPushButton> 30 # include <QVBoxLayout> 30 31 31 32 /* GUI includes: */ … … 38 39 # include "VBoxGlobal.h" 39 40 # include "UIExtraDataManager.h" 40 # include "UIMediumDetailsWidget.h"41 41 # include "UIMediumManager.h" 42 # include "UIMediumSelector.h" 42 43 # include "UIWizardCloneVD.h" 43 44 # include "UIMessageCenter.h" … … 61 62 62 63 63 /** QITreeWidgetItem extension representing Media Manager item. */ 64 class UIMediumItem : public QITreeWidgetItem, public UIDataMedium 64 UIMediumSelector::UIMediumSelector(KDeviceType deviceType, QWidget *pParent /* = 0 */, Qt::WindowFlags enmFlags /* = 0 */) 65 :QIWithRetranslateUI<QIDialog>(pParent) 66 , m_pMainLayout(0) 67 , m_pTreeWidget(0) 65 68 { 66 public: 67 68 /** Constructs top-level item. 69 * @param guiMedium Brings the medium to wrap around. 70 * @param pParent Brings the parent tree reference. */ 71 UIMediumItem(const UIMedium &guiMedium, QITreeWidget *pParent); 72 /** Constructs sub-level item. 73 * @param guiMedium Brings the medium to wrap around. 74 * @param pParent Brings the parent item reference. */ 75 UIMediumItem(const UIMedium &guiMedium, UIMediumItem *pParent); 76 77 /** Copies UIMedium wrapped by <i>this</i> item. */ 78 virtual bool copy(); 79 /** Moves UIMedium wrapped by <i>this</i> item. */ 80 virtual bool move(); 81 /** Removes UIMedium wrapped by <i>this</i> item. */ 82 virtual bool remove() = 0; 83 /** Releases UIMedium wrapped by <i>this</i> item. 84 * @param fInduced Brings whether this action is caused by other user's action, 85 * not a direct order to release particularly selected medium. */ 86 virtual bool release(bool fInduced = false); 87 88 /** Refreshes item fully. */ 89 void refreshAll(); 90 91 /** Returns UIMedium wrapped by <i>this</i> item. */ 92 const UIMedium &medium() const { return m_guiMedium; } 93 /** Defines UIMedium wrapped by <i>this</i> item. */ 94 void setMedium(const UIMedium &guiMedium); 95 96 /** Returns UIMediumType of the wrapped UIMedium. */ 97 UIMediumType mediumType() const { return m_guiMedium.type(); } 98 99 /** Returns KMediumState of the wrapped UIMedium. */ 100 KMediumState state() const { return m_guiMedium.state(); } 101 102 /** Returns QString <i>ID</i> of the wrapped UIMedium. */ 103 QString id() const { return m_guiMedium.id(); } 104 /** Returns QString <i>location</i> of the wrapped UIMedium. */ 105 QString location() const { return m_guiMedium.location(); } 106 107 /** Returns QString <i>hard-disk format</i> of the wrapped UIMedium. */ 108 QString hardDiskFormat() const { return m_guiMedium.hardDiskFormat(); } 109 /** Returns QString <i>hard-disk type</i> of the wrapped UIMedium. */ 110 QString hardDiskType() const { return m_guiMedium.hardDiskType(); } 111 112 /** Returns QString <i>storage details</i> of the wrapped UIMedium. */ 113 QString details() const { return m_guiMedium.storageDetails(); } 114 /** Returns QString <i>encryption password ID</i> of the wrapped UIMedium. */ 115 QString encryptionPasswordID() const { return m_guiMedium.encryptionPasswordID(); } 116 117 /** Returns QString <i>tool-tip</i> of the wrapped UIMedium. */ 118 QString toolTip() const { return m_guiMedium.toolTip(); } 119 120 /** Returns a vector of IDs of all machines wrapped UIMedium is attached to. */ 121 const QList<QString> &machineIds() const { return m_guiMedium.machineIds(); } 122 /** Returns QString <i>usage</i> of the wrapped UIMedium. */ 123 QString usage() const { return m_guiMedium.usage(); } 124 /** Returns whether wrapped UIMedium is used. */ 125 bool isUsed() const { return m_guiMedium.isUsed(); } 126 /** Returns whether wrapped UIMedium is used in snapshots. */ 127 bool isUsedInSnapshots() const { return m_guiMedium.isUsedInSnapshots(); } 128 129 /** Returns whether <i>this</i> item is less than @a other one. */ 130 bool operator<(const QTreeWidgetItem &other) const; 131 132 protected: 133 134 /** Release UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */ 135 virtual bool releaseFrom(CMachine comMachine) = 0; 136 137 /** Returns default text. */ 138 virtual QString defaultText() const /* override */; 139 140 private: 141 142 /** Refreshes item information such as icon, text and tool-tip. */ 143 void refresh(); 144 145 /** Releases UIMedium wrapped by <i>this</i> item from virtual machine with @a strMachineId. */ 146 bool releaseFrom(const QString &strMachineId); 147 148 /** Formats field text. */ 149 static QString formatFieldText(const QString &strText, bool fCompact = true, const QString &strElipsis = "middle"); 150 151 /** Holds the UIMedium wrapped by <i>this</i> item. */ 152 UIMedium m_guiMedium; 153 }; 154 155 156 /** UIMediumItem extension representing hard-disk item. */ 157 class UIMediumItemHD : public UIMediumItem 158 { 159 public: 160 161 /** Constructs top-level item. 162 * @param guiMedium Brings the medium to wrap around. 163 * @param pParent Brings the parent tree reference. */ 164 UIMediumItemHD(const UIMedium &guiMedium, QITreeWidget *pParent); 165 /** Constructs sub-level item. 166 * @param guiMedium Brings the medium to wrap around. 167 * @param pParent Brings the parent item reference. */ 168 UIMediumItemHD(const UIMedium &guiMedium, UIMediumItem *pParent); 169 170 protected: 171 172 /** Removes UIMedium wrapped by <i>this</i> item. */ 173 virtual bool remove() /* override */; 174 /** Releases UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */ 175 virtual bool releaseFrom(CMachine comMachine) /* override */; 176 177 private: 178 179 /** Proposes user to remove CMedium storage wrapped by <i>this</i> item. */ 180 bool maybeRemoveStorage(); 181 }; 182 183 /** UIMediumItem extension representing optical-disk item. */ 184 class UIMediumItemCD : public UIMediumItem 185 { 186 public: 187 188 /** Constructs top-level item. 189 * @param guiMedium Brings the medium to wrap around. 190 * @param pParent Brings the parent tree reference. */ 191 UIMediumItemCD(const UIMedium &guiMedium, QITreeWidget *pParent); 192 193 protected: 194 195 /** Removes UIMedium wrapped by <i>this</i> item. */ 196 virtual bool remove() /* override */; 197 /** Releases UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */ 198 virtual bool releaseFrom(CMachine comMachine) /* override */; 199 }; 200 201 /** UIMediumItem extension representing floppy-disk item. */ 202 class UIMediumItemFD : public UIMediumItem 203 { 204 public: 205 206 /** Constructs top-level item. 207 * @param guiMedium Brings the medium to wrap around. 208 * @param pParent Brings the parent tree reference. */ 209 UIMediumItemFD(const UIMedium &guiMedium, QITreeWidget *pParent); 210 211 protected: 212 213 /** Removes UIMedium wrapped by <i>this</i> item. */ 214 virtual bool remove() /* override */; 215 /** Releases UIMedium wrapped by <i>this</i> item from virtual @a comMachine. */ 216 virtual bool releaseFrom(CMachine comMachine) /* override */; 217 }; 218 219 220 /** Functor allowing to check if passed UIMediumItem is suitable by @a strID. */ 221 class CheckIfSuitableByID : public CheckIfSuitableBy 222 { 223 public: 224 /** Constructor accepting @a strID to compare with. */ 225 CheckIfSuitableByID(const QString &strID) : m_strID(strID) {} 226 227 private: 228 /** Determines whether passed UIMediumItem is suitable by @a strID. */ 229 bool isItSuitable(UIMediumItem *pItem) const { return pItem->id() == m_strID; } 230 /** Holds the @a strID to compare to. */ 231 QString m_strID; 232 }; 233 234 /** Functor allowing to check if passed UIMediumItem is suitable by @a state. */ 235 class CheckIfSuitableByState : public CheckIfSuitableBy 236 { 237 public: 238 /** Constructor accepting @a state to compare with. */ 239 CheckIfSuitableByState(KMediumState state) : m_state(state) {} 240 241 private: 242 /** Determines whether passed UIMediumItem is suitable by @a state. */ 243 bool isItSuitable(UIMediumItem *pItem) const { return pItem->state() == m_state; } 244 /** Holds the @a state to compare to. */ 245 KMediumState m_state; 246 }; 247 248 249 /********************************************************************************************************************************* 250 * Class UIMediumItem implementation. * 251 *********************************************************************************************************************************/ 252 253 UIMediumItem::UIMediumItem(const UIMedium &guiMedium, QITreeWidget *pParent) 254 : QITreeWidgetItem(pParent) 255 , m_guiMedium(guiMedium) 256 { 257 refresh(); 69 configure(); 70 finalize(); 258 71 } 259 72 260 UIMediumItem::UIMediumItem(const UIMedium &guiMedium, UIMediumItem *pParent) 261 : QITreeWidgetItem(pParent) 262 , m_guiMedium(guiMedium) 263 { 264 refresh(); 265 } 266 267 bool UIMediumItem::move() 268 { 269 /* Open file-save dialog to choose location for current medium: */ 270 const QString strFileName = QIFileDialog::getSaveFileName(location(), 271 UIMediumManager::tr("Current extension (*.%1)") 272 .arg(QFileInfo(location()).suffix()), 273 treeWidget(), 274 UIMediumManager::tr("Choose the location of this medium"), 275 0, true, true); 276 /* Negative if nothing changed: */ 277 if (strFileName.isNull()) 278 return false; 279 280 /* Search for corresponding medium: */ 281 CMedium comMedium = medium().medium(); 282 283 /* Try to assign new medium location: */ 284 if ( comMedium.isOk() 285 && strFileName != location()) 286 { 287 /* Prepare move storage progress: */ 288 CProgress comProgress = comMedium.SetLocation(strFileName); 289 290 /* Show error message if necessary: */ 291 if (!comMedium.isOk()) 292 { 293 msgCenter().cannotMoveMediumStorage(comMedium, location(), 294 strFileName, treeWidget()); 295 /* Negative if failed: */ 296 return false; 297 } 298 else 299 { 300 /* Show move storage progress: */ 301 msgCenter().showModalProgressDialog(comProgress, UIMediumManager::tr("Moving medium..."), 302 ":/progress_media_move_90px.png", treeWidget()); 303 304 /* Show error message if necessary: */ 305 if (!comProgress.isOk() || comProgress.GetResultCode() != 0) 306 { 307 msgCenter().cannotMoveMediumStorage(comProgress, location(), 308 strFileName, treeWidget()); 309 /* Negative if failed: */ 310 return false; 311 } 312 } 313 } 314 315 /* Recache item: */ 316 refreshAll(); 317 318 /* Positive: */ 319 return true; 320 } 321 322 bool UIMediumItem::copy() 323 { 324 /* Show Clone VD wizard: */ 325 UISafePointerWizard pWizard = new UIWizardCloneVD(treeWidget(), medium().medium()); 326 pWizard->prepare(); 327 pWizard->exec(); 328 329 /* Delete if still exists: */ 330 if (pWizard) 331 delete pWizard; 332 333 /* True by default: */ 334 return true; 335 } 336 337 bool UIMediumItem::release(bool fInduced /* = false */) 338 { 339 /* Refresh medium and item: */ 340 m_guiMedium.refresh(); 341 refresh(); 342 343 /* Make sure medium was not released yet: */ 344 if (medium().curStateMachineIds().isEmpty()) 345 return true; 346 347 /* Confirm release: */ 348 if (!msgCenter().confirmMediumRelease(medium(), fInduced, treeWidget())) 349 return false; 350 351 /* Release: */ 352 foreach (const QString &strMachineId, medium().curStateMachineIds()) 353 if (!releaseFrom(strMachineId)) 354 return false; 355 356 /* True by default: */ 357 return true; 358 } 359 360 void UIMediumItem::refreshAll() 361 { 362 m_guiMedium.blockAndQueryState(); 363 refresh(); 364 } 365 366 void UIMediumItem::setMedium(const UIMedium &guiMedium) 367 { 368 m_guiMedium = guiMedium; 369 refresh(); 370 } 371 372 bool UIMediumItem::operator<(const QTreeWidgetItem &other) const 373 { 374 int iColumn = treeWidget()->sortColumn(); 375 ULONG64 uThisValue = vboxGlobal().parseSize( text(iColumn)); 376 ULONG64 uThatValue = vboxGlobal().parseSize(other.text(iColumn)); 377 return uThisValue && uThatValue ? uThisValue < uThatValue : QTreeWidgetItem::operator<(other); 378 } 379 380 QString UIMediumItem::defaultText() const 381 { 382 return UIMediumManager::tr("%1, %2: %3, %4: %5", "col.1 text, col.2 name: col.2 text, col.3 name: col.3 text") 383 .arg(text(0)) 384 .arg(parentTree()->headerItem()->text(1)).arg(text(1)) 385 .arg(parentTree()->headerItem()->text(2)).arg(text(2)); 386 } 387 388 void UIMediumItem::refresh() 389 { 390 /* Fill-in columns: */ 391 setIcon(0, m_guiMedium.icon()); 392 setText(0, m_guiMedium.name()); 393 setText(1, m_guiMedium.logicalSize()); 394 setText(2, m_guiMedium.size()); 395 /* All columns get the same tooltip: */ 396 QString strToolTip = m_guiMedium.toolTip(); 397 for (int i = 0; i < treeWidget()->columnCount(); ++i) 398 setToolTip(i, strToolTip); 399 400 /* Gather medium data: */ 401 m_fValid = !m_guiMedium.isNull() 402 && m_guiMedium.state() != KMediumState_Inaccessible; 403 m_enmType = m_guiMedium.type(); 404 m_enmVariant = m_guiMedium.mediumVariant(); 405 m_fHasChildren = m_guiMedium.hasChildren(); 406 /* Gather medium options data: */ 407 m_options.m_enmType = m_guiMedium.mediumType(); 408 m_options.m_strLocation = m_guiMedium.location(); 409 m_options.m_uLogicalSize = m_guiMedium.logicalSizeInBytes(); 410 m_options.m_strDescription = m_guiMedium.description(); 411 /* Gather medium details data: */ 412 m_details.m_aFields.clear(); 413 switch (m_enmType) 414 { 415 case UIMediumType_HardDisk: 416 { 417 m_details.m_aLabels << UIMediumManager::tr("Format:"); 418 m_details.m_aLabels << UIMediumManager::tr("Storage details:"); 419 m_details.m_aLabels << UIMediumManager::tr("Attached to:"); 420 m_details.m_aLabels << UIMediumManager::tr("Encrypted with key:"); 421 m_details.m_aLabels << UIMediumManager::tr("UUID:"); 422 423 m_details.m_aFields << hardDiskFormat(); 424 m_details.m_aFields << details(); 425 m_details.m_aFields << (usage().isNull() ? 426 formatFieldText(UIMediumManager::tr("<i>Not Attached</i>"), false) : 427 formatFieldText(usage())); 428 m_details.m_aFields << (encryptionPasswordID().isNull() ? 429 formatFieldText(UIMediumManager::tr("<i>Not Encrypted</i>"), false) : 430 formatFieldText(encryptionPasswordID())); 431 m_details.m_aFields << id(); 432 433 break; 434 } 435 case UIMediumType_DVD: 436 case UIMediumType_Floppy: 437 { 438 m_details.m_aLabels << UIMediumManager::tr("Attached to:"); 439 m_details.m_aLabels << UIMediumManager::tr("UUID:"); 440 441 m_details.m_aFields << (usage().isNull() ? 442 formatFieldText(UIMediumManager::tr("<i>Not Attached</i>"), false) : 443 formatFieldText(usage())); 444 m_details.m_aFields << id(); 445 break; 446 } 447 default: 448 break; 449 } 450 } 451 452 bool UIMediumItem::releaseFrom(const QString &strMachineId) 453 { 454 /* Open session: */ 455 CSession session = vboxGlobal().openSession(strMachineId); 456 if (session.isNull()) 457 return false; 458 459 /* Get machine: */ 460 CMachine machine = session.GetMachine(); 461 462 /* Prepare result: */ 463 bool fSuccess = false; 464 465 /* Release medium from machine: */ 466 if (releaseFrom(machine)) 467 { 468 /* Save machine settings: */ 469 machine.SaveSettings(); 470 if (!machine.isOk()) 471 msgCenter().cannotSaveMachineSettings(machine, treeWidget()); 472 else 473 fSuccess = true; 474 } 475 476 /* Close session: */ 477 session.UnlockMachine(); 478 479 /* Return result: */ 480 return fSuccess; 481 } 482 483 /* static */ 484 QString UIMediumItem::formatFieldText(const QString &strText, bool fCompact /* = true */, 485 const QString &strElipsis /* = "middle" */) 486 { 487 QString strCompactString = QString("<compact elipsis=\"%1\">").arg(strElipsis); 488 QString strInfo = QString("<nobr>%1%2%3</nobr>") 489 .arg(fCompact ? strCompactString : "") 490 .arg(strText.isEmpty() ? UIMediumManager::tr("--", "no info") : strText) 491 .arg(fCompact ? "</compact>" : ""); 492 return strInfo; 493 } 494 495 496 /********************************************************************************************************************************* 497 * Class UIMediumItemHD implementation. * 498 *********************************************************************************************************************************/ 499 500 UIMediumItemHD::UIMediumItemHD(const UIMedium &guiMedium, QITreeWidget *pParent) 501 : UIMediumItem(guiMedium, pParent) 73 void UIMediumSelector::retranslateUi() 502 74 { 503 75 } 504 76 505 UIMediumItemHD::UIMediumItemHD(const UIMedium &guiMedium, UIMediumItem *pParent) 506 : UIMediumItem(guiMedium, pParent) 77 void UIMediumSelector::configure() 507 78 { 508 } 509 510 bool UIMediumItemHD::remove() 511 { 512 /* Confirm medium removal: */ 513 if (!msgCenter().confirmMediumRemoval(medium(), treeWidget())) 514 return false; 515 516 /* Remember some of hard-disk attributes: */ 517 CMedium hardDisk = medium().medium(); 518 QString strMediumID = id(); 519 520 /* Propose to remove medium storage: */ 521 if (!maybeRemoveStorage()) 522 return false; 523 524 /* Close hard-disk: */ 525 hardDisk.Close(); 526 if (!hardDisk.isOk()) 527 { 528 msgCenter().cannotCloseMedium(medium(), hardDisk, treeWidget()); 529 return false; 530 } 531 532 /* Remove UIMedium finally: */ 533 vboxGlobal().deleteMedium(strMediumID); 534 535 /* True by default: */ 536 return true; 537 } 538 539 bool UIMediumItemHD::releaseFrom(CMachine comMachine) 540 { 541 /* Enumerate attachments: */ 542 CMediumAttachmentVector attachments = comMachine.GetMediumAttachments(); 543 foreach (const CMediumAttachment &attachment, attachments) 544 { 545 /* Skip non-hard-disks: */ 546 if (attachment.GetType() != KDeviceType_HardDisk) 547 continue; 548 549 /* Skip unrelated hard-disks: */ 550 if (attachment.GetMedium().GetId() != id()) 551 continue; 552 553 /* Remember controller: */ 554 CStorageController controller = comMachine.GetStorageControllerByName(attachment.GetController()); 555 556 /* Try to detach device: */ 557 comMachine.DetachDevice(attachment.GetController(), attachment.GetPort(), attachment.GetDevice()); 558 if (!comMachine.isOk()) 559 { 560 /* Return failure: */ 561 msgCenter().cannotDetachDevice(comMachine, UIMediumType_HardDisk, location(), 562 StorageSlot(controller.GetBus(), attachment.GetPort(), attachment.GetDevice()), 563 treeWidget()); 564 return false; 565 } 566 567 /* Return success: */ 568 return true; 569 } 570 571 /* False by default: */ 572 return false; 573 } 574 575 bool UIMediumItemHD::maybeRemoveStorage() 576 { 577 /* Remember some of hard-disk attributes: */ 578 CMedium hardDisk = medium().medium(); 579 QString strLocation = location(); 580 581 /* We don't want to try to delete inaccessible storage as it will most likely fail. 582 * Note that UIMessageCenter::confirmMediumRemoval() is aware of that and 583 * will give a corresponding hint. Therefore, once the code is changed below, 584 * the hint should be re-checked for validity. */ 585 bool fDeleteStorage = false; 586 qulonglong uCapability = 0; 587 QVector<KMediumFormatCapabilities> capabilities = hardDisk.GetMediumFormat().GetCapabilities(); 588 foreach (KMediumFormatCapabilities capability, capabilities) 589 uCapability |= capability; 590 if (state() != KMediumState_Inaccessible && uCapability & KMediumFormatCapabilities_File) 591 { 592 int rc = msgCenter().confirmDeleteHardDiskStorage(strLocation, treeWidget()); 593 if (rc == AlertButton_Cancel) 594 return false; 595 fDeleteStorage = rc == AlertButton_Choice1; 596 } 597 598 /* If user wish to delete storage: */ 599 if (fDeleteStorage) 600 { 601 /* Prepare delete storage progress: */ 602 CProgress progress = hardDisk.DeleteStorage(); 603 if (!hardDisk.isOk()) 604 { 605 msgCenter().cannotDeleteHardDiskStorage(hardDisk, strLocation, treeWidget()); 606 return false; 607 } 608 /* Show delete storage progress: */ 609 msgCenter().showModalProgressDialog(progress, UIMediumManager::tr("Removing medium..."), 610 ":/progress_media_delete_90px.png", treeWidget()); 611 if (!progress.isOk() || progress.GetResultCode() != 0) 612 { 613 msgCenter().cannotDeleteHardDiskStorage(progress, strLocation, treeWidget()); 614 return false; 615 } 616 } 617 618 /* True by default: */ 619 return true; 620 } 621 622 623 /********************************************************************************************************************************* 624 * Class UIMediumItemCD implementation. * 625 *********************************************************************************************************************************/ 626 627 UIMediumItemCD::UIMediumItemCD(const UIMedium &guiMedium, QITreeWidget *pParent) 628 : UIMediumItem(guiMedium, pParent) 629 { 630 } 631 632 bool UIMediumItemCD::remove() 633 { 634 /* Confirm medium removal: */ 635 if (!msgCenter().confirmMediumRemoval(medium(), treeWidget())) 636 return false; 637 638 /* Remember some of optical-disk attributes: */ 639 CMedium image = medium().medium(); 640 QString strMediumID = id(); 641 642 /* Close optical-disk: */ 643 image.Close(); 644 if (!image.isOk()) 645 { 646 msgCenter().cannotCloseMedium(medium(), image, treeWidget()); 647 return false; 648 } 649 650 /* Remove UIMedium finally: */ 651 vboxGlobal().deleteMedium(strMediumID); 652 653 /* True by default: */ 654 return true; 655 } 656 657 bool UIMediumItemCD::releaseFrom(CMachine comMachine) 658 { 659 /* Enumerate attachments: */ 660 CMediumAttachmentVector attachments = comMachine.GetMediumAttachments(); 661 foreach (const CMediumAttachment &attachment, attachments) 662 { 663 /* Skip non-optical-disks: */ 664 if (attachment.GetType() != KDeviceType_DVD) 665 continue; 666 667 /* Skip unrelated optical-disks: */ 668 if (attachment.GetMedium().GetId() != id()) 669 continue; 670 671 /* Try to unmount device: */ 672 comMachine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */); 673 if (!comMachine.isOk()) 674 { 675 /* Return failure: */ 676 msgCenter().cannotRemountMedium(comMachine, medium(), false /* mount? */, false /* retry? */, treeWidget()); 677 return false; 678 } 679 680 /* Return success: */ 681 return true; 682 } 683 684 /* Return failure: */ 685 return false; 686 } 687 688 689 /********************************************************************************************************************************* 690 * Class UIMediumItemFD implementation. * 691 *********************************************************************************************************************************/ 692 693 UIMediumItemFD::UIMediumItemFD(const UIMedium &guiMedium, QITreeWidget *pParent) 694 : UIMediumItem(guiMedium, pParent) 695 { 696 } 697 698 bool UIMediumItemFD::remove() 699 { 700 /* Confirm medium removal: */ 701 if (!msgCenter().confirmMediumRemoval(medium(), treeWidget())) 702 return false; 703 704 /* Remember some of floppy-disk attributes: */ 705 CMedium image = medium().medium(); 706 QString strMediumID = id(); 707 708 /* Close floppy-disk: */ 709 image.Close(); 710 if (!image.isOk()) 711 { 712 msgCenter().cannotCloseMedium(medium(), image, treeWidget()); 713 return false; 714 } 715 716 /* Remove UIMedium finally: */ 717 vboxGlobal().deleteMedium(strMediumID); 718 719 /* True by default: */ 720 return true; 721 } 722 723 bool UIMediumItemFD::releaseFrom(CMachine comMachine) 724 { 725 /* Enumerate attachments: */ 726 CMediumAttachmentVector attachments = comMachine.GetMediumAttachments(); 727 foreach (const CMediumAttachment &attachment, attachments) 728 { 729 /* Skip non-floppy-disks: */ 730 if (attachment.GetType() != KDeviceType_Floppy) 731 continue; 732 733 /* Skip unrelated floppy-disks: */ 734 if (attachment.GetMedium().GetId() != id()) 735 continue; 736 737 /* Try to unmount device: */ 738 comMachine.MountMedium(attachment.GetController(), attachment.GetPort(), attachment.GetDevice(), CMedium(), false /* force */); 739 if (!comMachine.isOk()) 740 { 741 /* Return failure: */ 742 msgCenter().cannotRemountMedium(comMachine, medium(), false /* mount? */, false /* retry? */, treeWidget()); 743 return false; 744 } 745 746 /* Return success: */ 747 return true; 748 } 749 750 /* Return failure: */ 751 return false; 752 } 753 754 755 /********************************************************************************************************************************* 756 * Class UIEnumerationProgressBar implementation. * 757 *********************************************************************************************************************************/ 758 759 UIEnumerationProgressBar::UIEnumerationProgressBar(QWidget *pParent /* = 0 */) 760 : QWidget(pParent) 761 { 762 /* Prepare: */ 763 prepare(); 764 } 765 766 void UIEnumerationProgressBar::setText(const QString &strText) 767 { 768 m_pLabel->setText(strText); 769 } 770 771 int UIEnumerationProgressBar::value() const 772 { 773 return m_pProgressBar->value(); 774 } 775 776 void UIEnumerationProgressBar::setValue(int iValue) 777 { 778 m_pProgressBar->setValue(iValue); 779 } 780 781 void UIEnumerationProgressBar::setMaximum(int iValue) 782 { 783 m_pProgressBar->setMaximum(iValue); 784 } 785 786 void UIEnumerationProgressBar::prepare() 787 { 788 /* Create layout: */ 789 QHBoxLayout *pLayout = new QHBoxLayout(this); 790 { 791 /* Configure layout: */ 792 pLayout->setContentsMargins(0, 0, 0, 0); 793 /* Create label: */ 794 m_pLabel = new QLabel; 795 /* Create progress-bar: */ 796 m_pProgressBar = new QProgressBar; 797 { 798 /* Configure progress-bar: */ 799 m_pProgressBar->setTextVisible(false); 800 } 801 /* Add widgets into layout: */ 802 pLayout->addWidget(m_pLabel); 803 pLayout->addWidget(m_pProgressBar); 804 } 805 } 806 807 808 /********************************************************************************************************************************* 809 * Class UIMediumManagerWidget implementation. * 810 *********************************************************************************************************************************/ 811 812 UIMediumManagerWidget::UIMediumManagerWidget(EmbedTo enmEmbedding, QWidget *pParent /* = 0 */) 813 : QIWithRetranslateUI<QWidget>(pParent) 814 , m_enmEmbedding(enmEmbedding) 815 , m_fPreventChangeCurrentItem(false) 816 , m_pTabWidget(0) 817 , m_iTabCount(3) 818 , m_fInaccessibleHD(false) 819 , m_fInaccessibleCD(false) 820 , m_fInaccessibleFD(false) 821 , m_iconHD(UIIconPool::iconSet(":/hd_16px.png", ":/hd_disabled_16px.png")) 822 , m_iconCD(UIIconPool::iconSet(":/cd_16px.png", ":/cd_disabled_16px.png")) 823 , m_iconFD(UIIconPool::iconSet(":/fd_16px.png", ":/fd_disabled_16px.png")) 824 , m_pDetailsWidget(0) 825 , m_pToolBar(0) 826 , m_pContextMenu(0) 827 , m_pMenu(0) 828 , m_pActionAdd(0), m_pActionCopy(0), m_pActionMove(0), m_pActionRemove(0) 829 , m_pActionRelease(0), m_pActionDetails(0) 830 , m_pActionRefresh(0) 831 , m_pProgressBar(0) 832 { 833 /* Prepare: */ 834 prepare(); 835 } 836 837 void UIMediumManagerWidget::setProgressBar(UIEnumerationProgressBar *pProgressBar) 838 { 839 /* Cache progress-bar reference:*/ 840 m_pProgressBar = pProgressBar; 841 842 /* Update translation: */ 843 retranslateUi(); 844 } 845 846 void UIMediumManagerWidget::retranslateUi() 847 { 848 /* Translate menu: */ 849 if (m_pMenu) 850 m_pMenu->setTitle(UIMediumManager::tr("&Medium")); 851 852 /* Translate actions: */ 853 if (m_pActionAdd) 854 { 855 m_pActionAdd->setText(UIMediumManager::tr("&Add...")); 856 m_pActionAdd->setToolTip(UIMediumManager::tr("Add Disk Image File (%1)")); 857 m_pActionAdd->setStatusTip(UIMediumManager::tr("Add disk image file")); 858 } 859 if (m_pActionCopy) 860 { 861 m_pActionCopy->setText(UIMediumManager::tr("&Copy...")); 862 m_pActionCopy->setToolTip(UIMediumManager::tr("Copy Disk Image File (%1)").arg(m_pActionCopy->shortcut().toString())); 863 m_pActionCopy->setStatusTip(UIMediumManager::tr("Copy selected disk image file")); 864 } 865 if (m_pActionMove) 866 { 867 m_pActionMove->setText(UIMediumManager::tr("&Move...")); 868 m_pActionMove->setToolTip(UIMediumManager::tr("Move Disk Image File (%1)").arg(m_pActionMove->shortcut().toString())); 869 m_pActionMove->setStatusTip(UIMediumManager::tr("Move selected disk image file")); 870 } 871 if (m_pActionRemove) 872 { 873 m_pActionRemove->setText(UIMediumManager::tr("&Remove...")); 874 m_pActionRemove->setToolTip(UIMediumManager::tr("Remove Disk Image File (%1)").arg(m_pActionRemove->shortcut().toString())); 875 m_pActionRemove->setStatusTip(UIMediumManager::tr("Remove selected disk image file")); 876 } 877 if (m_pActionRelease) 878 { 879 m_pActionRelease->setText(UIMediumManager::tr("Re&lease...")); 880 m_pActionRelease->setToolTip(UIMediumManager::tr("Release Disk Image File (%1)").arg(m_pActionRelease->shortcut().toString())); 881 m_pActionRelease->setStatusTip(UIMediumManager::tr("Release selected disk image file by detaching it from machines")); 882 } 883 if (m_pActionDetails) 884 { 885 m_pActionDetails->setText(UIMediumManager::tr("&Properties...")); 886 m_pActionDetails->setToolTip(UIMediumManager::tr("Open Disk Image File Properties (%1)").arg(m_pActionDetails->shortcut().toString())); 887 m_pActionDetails->setStatusTip(UIMediumManager::tr("Open pane with selected disk image file properties")); 888 } 889 if (m_pActionRefresh) 890 { 891 m_pActionRefresh->setText(UIMediumManager::tr("Re&fresh")); 892 m_pActionRefresh->setToolTip(UIMediumManager::tr("Refresh Disk Image Files (%1)").arg(m_pActionRefresh->shortcut().toString())); 893 m_pActionRefresh->setStatusTip(UIMediumManager::tr("Refresh the list of disk image files")); 894 } 895 896 /* Translate toolbar: */ 897 #ifdef VBOX_WS_MAC 898 // WORKAROUND: 899 // There is a bug in Qt Cocoa which result in showing a "more arrow" when 900 // the necessary size of the toolbar is increased. Also for some languages 901 // the with doesn't match if the text increase. So manually adjust the size 902 // after changing the text. */ 903 if (m_pToolBar) 904 m_pToolBar->updateLayout(); 905 #endif 906 907 /* Translate tab-widget: */ 908 if (m_pTabWidget) 909 { 910 m_pTabWidget->setTabText(tabIndex(UIMediumType_HardDisk), UIMediumManager::tr("&Hard disks")); 911 m_pTabWidget->setTabText(tabIndex(UIMediumType_DVD), UIMediumManager::tr("&Optical disks")); 912 m_pTabWidget->setTabText(tabIndex(UIMediumType_Floppy), UIMediumManager::tr("&Floppy disks")); 913 } 914 915 /* Translate HD tree-widget: */ 916 QITreeWidget *pTreeWidgetHD = treeWidget(UIMediumType_HardDisk); 917 if (pTreeWidgetHD) 918 { 919 pTreeWidgetHD->headerItem()->setText(0, UIMediumManager::tr("Name")); 920 pTreeWidgetHD->headerItem()->setText(1, UIMediumManager::tr("Virtual Size")); 921 pTreeWidgetHD->headerItem()->setText(2, UIMediumManager::tr("Actual Size")); 922 } 923 924 /* Translate CD tree-widget: */ 925 QITreeWidget *pTreeWidgetCD = treeWidget(UIMediumType_DVD); 926 if (pTreeWidgetCD) 927 { 928 pTreeWidgetCD->headerItem()->setText(0, UIMediumManager::tr("Name")); 929 pTreeWidgetCD->headerItem()->setText(1, UIMediumManager::tr("Size")); 930 } 931 932 /* Translate FD tree-widget: */ 933 QITreeWidget *pTreeWidgetFD = treeWidget(UIMediumType_Floppy); 934 if (pTreeWidgetFD) 935 { 936 pTreeWidgetFD->headerItem()->setText(0, UIMediumManager::tr("Name")); 937 pTreeWidgetFD->headerItem()->setText(1, UIMediumManager::tr("Size")); 938 } 939 940 /* Translate progress-bar: */ 941 if (m_pProgressBar) 942 { 943 m_pProgressBar->setText(UIMediumManager::tr("Checking accessibility")); 944 #ifdef VBOX_WS_MAC 945 /* Make sure that the widgets aren't jumping around 946 * while the progress-bar get visible. */ 947 m_pProgressBar->adjustSize(); 948 //int h = m_pProgressBar->height(); 949 //if (m_pButtonBox) 950 // m_pButtonBox->setMinimumHeight(h + 12); 951 #endif 952 } 953 954 /* Full refresh if there is at least one item present: */ 955 if ( (pTreeWidgetHD && pTreeWidgetHD->topLevelItemCount()) 956 || (pTreeWidgetCD && pTreeWidgetCD->topLevelItemCount()) 957 || (pTreeWidgetFD && pTreeWidgetFD->topLevelItemCount())) 958 sltRefreshAll(); 959 } 960 961 void UIMediumManagerWidget::showEvent(QShowEvent *pEvent) 962 { 963 /* Call to base-class: */ 964 QIWithRetranslateUI<QWidget>::showEvent(pEvent); 965 966 /* Focus current tree-widget: */ 967 if (currentTreeWidget()) 968 currentTreeWidget()->setFocus(); 969 } 970 971 void UIMediumManagerWidget::sltResetMediumDetailsChanges() 972 { 973 /* Push the current item data into details-widget: */ 974 sltHandleCurrentTabChanged(); 975 } 976 977 void UIMediumManagerWidget::sltApplyMediumDetailsChanges() 978 { 979 /* Get current medium-item: */ 980 UIMediumItem *pMediumItem = currentMediumItem(); 981 AssertMsgReturnVoid(pMediumItem, ("Current item must not be null")); 982 AssertReturnVoid(!pMediumItem->id().isNull()); 983 984 /* Get item data: */ 985 UIDataMedium oldData = *pMediumItem; 986 UIDataMedium newData = m_pDetailsWidget->data(); 987 988 /* Search for corresponding medium: */ 989 CMedium comMedium = vboxGlobal().medium(pMediumItem->id()).medium(); 990 991 /* Try to assign new medium type: */ 992 if ( comMedium.isOk() 993 && newData.m_options.m_enmType != oldData.m_options.m_enmType) 994 { 995 /* Check if we need to release medium first: */ 996 bool fDo = true; 997 if ( pMediumItem->machineIds().size() > 1 998 || ( ( newData.m_options.m_enmType == KMediumType_Immutable 999 || newData.m_options.m_enmType == KMediumType_MultiAttach) 1000 && pMediumItem->machineIds().size() > 0)) 1001 fDo = pMediumItem->release(true); 1002 1003 if (fDo) 1004 { 1005 comMedium.SetType(newData.m_options.m_enmType); 1006 1007 /* Show error message if necessary: */ 1008 if (!comMedium.isOk()) 1009 msgCenter().cannotChangeMediumType(comMedium, oldData.m_options.m_enmType, newData.m_options.m_enmType, this); 1010 } 1011 } 1012 1013 /* Try to assign new medium location: */ 1014 if ( comMedium.isOk() 1015 && newData.m_options.m_strLocation != oldData.m_options.m_strLocation) 1016 { 1017 /* Prepare move storage progress: */ 1018 CProgress comProgress = comMedium.SetLocation(newData.m_options.m_strLocation); 1019 1020 /* Show error message if necessary: */ 1021 if (!comMedium.isOk()) 1022 msgCenter().cannotMoveMediumStorage(comMedium, 1023 oldData.m_options.m_strLocation, 1024 newData.m_options.m_strLocation, 1025 this); 1026 else 1027 { 1028 /* Show move storage progress: */ 1029 msgCenter().showModalProgressDialog(comProgress, UIMediumManager::tr("Moving medium..."), 1030 ":/progress_media_move_90px.png", this); 1031 1032 /* Show error message if necessary: */ 1033 if (!comProgress.isOk() || comProgress.GetResultCode() != 0) 1034 msgCenter().cannotMoveMediumStorage(comProgress, 1035 oldData.m_options.m_strLocation, 1036 newData.m_options.m_strLocation, 1037 this); 1038 } 1039 } 1040 1041 /* Try to assign new medium size: */ 1042 if ( comMedium.isOk() 1043 && newData.m_options.m_uLogicalSize != oldData.m_options.m_uLogicalSize) 1044 { 1045 /* Prepare resize storage progress: */ 1046 CProgress comProgress = comMedium.Resize(newData.m_options.m_uLogicalSize); 1047 1048 /* Show error message if necessary: */ 1049 if (!comMedium.isOk()) 1050 msgCenter().cannotResizeHardDiskStorage(comMedium, 1051 oldData.m_options.m_strLocation, 1052 vboxGlobal().formatSize(oldData.m_options.m_uLogicalSize), 1053 vboxGlobal().formatSize(newData.m_options.m_uLogicalSize), 1054 this); 1055 else 1056 { 1057 /* Show resize storage progress: */ 1058 msgCenter().showModalProgressDialog(comProgress, UIMediumManager::tr("Moving medium..."), 1059 ":/progress_media_move_90px.png", this); 1060 1061 /* Show error message if necessary: */ 1062 if (!comProgress.isOk() || comProgress.GetResultCode() != 0) 1063 msgCenter().cannotResizeHardDiskStorage(comProgress, 1064 oldData.m_options.m_strLocation, 1065 vboxGlobal().formatSize(oldData.m_options.m_uLogicalSize), 1066 vboxGlobal().formatSize(newData.m_options.m_uLogicalSize), 1067 this); 1068 } 1069 } 1070 1071 /* Try to assign new medium description: */ 1072 if ( comMedium.isOk() 1073 && newData.m_options.m_strDescription != oldData.m_options.m_strDescription) 1074 { 1075 comMedium.SetDescription(newData.m_options.m_strDescription); 1076 1077 /* Show error message if necessary: */ 1078 if (!comMedium.isOk()) 1079 msgCenter().cannotChangeMediumDescription(comMedium, 1080 oldData.m_options.m_strLocation, 1081 this); 1082 } 1083 1084 /* Recache current item: */ 1085 pMediumItem->refreshAll(); 1086 1087 /* Push the current item data into details-widget: */ 1088 sltHandleCurrentTabChanged(); 1089 } 1090 1091 void UIMediumManagerWidget::sltHandleMediumCreated(const QString &strMediumID) 1092 { 1093 /* Search for corresponding medium: */ 1094 UIMedium medium = vboxGlobal().medium(strMediumID); 1095 1096 /* Ignore non-interesting mediums: */ 1097 if (medium.isNull() || medium.isHostDrive()) 1098 return; 1099 1100 /* Ignore mediums (and their children) which are 1101 * marked as hidden or attached to hidden machines only: */ 1102 if (UIMedium::isMediumAttachedToHiddenMachinesOnly(medium)) 1103 return; 1104 1105 /* Create medium-item for corresponding medium: */ 1106 UIMediumItem *pMediumItem = createMediumItem(medium); 1107 1108 /* Make sure medium-item was created: */ 1109 if (!pMediumItem) 1110 return; 1111 1112 /* If medium-item change allowed and 1113 * 1. medium-enumeration is not currently in progress or 1114 * 2. if there is no currently medium-item selected 1115 * we have to choose newly added medium-item as current one: */ 1116 if ( !m_fPreventChangeCurrentItem 1117 && ( !vboxGlobal().isMediumEnumerationInProgress() 1118 || !mediumItem(medium.type()))) 1119 setCurrentItem(treeWidget(medium.type()), pMediumItem); 1120 } 1121 1122 void UIMediumManagerWidget::sltHandleMediumDeleted(const QString &strMediumID) 1123 { 1124 /* Make sure corresponding medium-item deleted: */ 1125 deleteMediumItem(strMediumID); 1126 } 1127 1128 void UIMediumManagerWidget::sltHandleMediumEnumerationStart() 1129 { 1130 /* Disable 'refresh' action: */ 1131 if (m_pActionRefresh) 1132 m_pActionRefresh->setEnabled(false); 1133 1134 /* Disable details-widget: */ 1135 if (m_pDetailsWidget) 1136 m_pDetailsWidget->setOptionsEnabled(false); 1137 1138 /* Reset and show progress-bar: */ 1139 if (m_pProgressBar) 1140 { 1141 m_pProgressBar->setMaximum(vboxGlobal().mediumIDs().size()); 1142 m_pProgressBar->setValue(0); 1143 m_pProgressBar->show(); 1144 } 1145 1146 /* Reset inaccessibility flags: */ 1147 m_fInaccessibleHD = 1148 m_fInaccessibleCD = 1149 m_fInaccessibleFD = false; 1150 1151 /* Reset tab-widget icons: */ 1152 if (m_pTabWidget) 1153 { 1154 m_pTabWidget->setTabIcon(tabIndex(UIMediumType_HardDisk), m_iconHD); 1155 m_pTabWidget->setTabIcon(tabIndex(UIMediumType_DVD), m_iconCD); 1156 m_pTabWidget->setTabIcon(tabIndex(UIMediumType_Floppy), m_iconFD); 1157 } 1158 1159 /* Repopulate tree-widgets content: */ 1160 repopulateTreeWidgets(); 1161 1162 /* Re-fetch all current medium-items: */ 1163 refetchCurrentMediumItems(); 1164 refetchCurrentChosenMediumItem(); 1165 } 1166 1167 void UIMediumManagerWidget::sltHandleMediumEnumerated(const QString &strMediumID) 1168 { 1169 /* Search for corresponding medium: */ 1170 UIMedium medium = vboxGlobal().medium(strMediumID); 1171 1172 /* Ignore non-interesting mediums: */ 1173 if (medium.isNull() || medium.isHostDrive()) 1174 return; 1175 1176 /* Ignore mediums (and their children) which are 1177 * marked as hidden or attached to hidden machines only: */ 1178 if (UIMedium::isMediumAttachedToHiddenMachinesOnly(medium)) 1179 return; 1180 1181 /* Update medium-item for corresponding medium: */ 1182 updateMediumItem(medium); 1183 1184 /* Advance progress-bar: */ 1185 if (m_pProgressBar) 1186 m_pProgressBar->setValue(m_pProgressBar->value() + 1); 1187 } 1188 1189 void UIMediumManagerWidget::sltHandleMediumEnumerationFinish() 1190 { 1191 /* Hide progress-bar: */ 1192 if (m_pProgressBar) 1193 m_pProgressBar->hide(); 1194 1195 /* Enable details-widget: */ 1196 if (m_pDetailsWidget) 1197 m_pDetailsWidget->setOptionsEnabled(true); 1198 1199 /* Enable 'refresh' action: */ 1200 if (m_pActionRefresh) 1201 m_pActionRefresh->setEnabled(true); 1202 1203 /* Re-fetch all current medium-items: */ 1204 refetchCurrentMediumItems(); 1205 refetchCurrentChosenMediumItem(); 1206 } 1207 1208 void UIMediumManagerWidget::sltAddMedium() 1209 { 1210 QString strDefaultMachineFolder = vboxGlobal().virtualBox().GetSystemProperties().GetDefaultMachineFolder(); 1211 vboxGlobal().openMediumWithFileOpenDialog(currentMediumType(), this, strDefaultMachineFolder); 1212 } 1213 1214 void UIMediumManagerWidget::sltCopyMedium() 1215 { 1216 /* Get current medium-item: */ 1217 UIMediumItem *pMediumItem = currentMediumItem(); 1218 AssertMsgReturnVoid(pMediumItem, ("Current item must not be null")); 1219 AssertReturnVoid(!pMediumItem->id().isNull()); 1220 1221 /* Copy current medium-item: */ 1222 pMediumItem->copy(); 1223 } 1224 1225 void UIMediumManagerWidget::sltMoveMedium() 1226 { 1227 /* Get current medium-item: */ 1228 UIMediumItem *pMediumItem = currentMediumItem(); 1229 AssertMsgReturnVoid(pMediumItem, ("Current item must not be null")); 1230 AssertReturnVoid(!pMediumItem->id().isNull()); 1231 1232 /* Copy current medium-item: */ 1233 pMediumItem->move(); 1234 1235 /* Push the current item data into details-widget: */ 1236 sltHandleCurrentTabChanged(); 1237 } 1238 1239 void UIMediumManagerWidget::sltRemoveMedium() 1240 { 1241 /* Get current medium-item: */ 1242 UIMediumItem *pMediumItem = currentMediumItem(); 1243 AssertMsgReturnVoid(pMediumItem, ("Current item must not be null")); 1244 AssertReturnVoid(!pMediumItem->id().isNull()); 1245 1246 /* Remove current medium-item: */ 1247 pMediumItem->remove(); 1248 } 1249 1250 void UIMediumManagerWidget::sltReleaseMedium() 1251 { 1252 /* Get current medium-item: */ 1253 UIMediumItem *pMediumItem = currentMediumItem(); 1254 AssertMsgReturnVoid(pMediumItem, ("Current item must not be null")); 1255 AssertReturnVoid(!pMediumItem->id().isNull()); 1256 1257 /* Remove current medium-item: */ 1258 bool fResult = pMediumItem->release(); 1259 1260 /* Refetch currently chosen medium-item: */ 1261 if (fResult) 1262 refetchCurrentChosenMediumItem(); 1263 } 1264 1265 void UIMediumManagerWidget::sltToggleMediumDetailsVisibility(bool fVisible) 1266 { 1267 /* Save the setting: */ 1268 gEDataManager->setVirtualMediaManagerDetailsExpanded(fVisible); 1269 /* Toggle medium details visibility: */ 1270 if (m_pDetailsWidget) 1271 m_pDetailsWidget->setVisible(fVisible); 1272 /* Notify external lsiteners: */ 1273 emit sigMediumDetailsVisibilityChanged(fVisible); 1274 } 1275 1276 void UIMediumManagerWidget::sltRefreshAll() 1277 { 1278 /* Start medium-enumeration: */ 1279 vboxGlobal().startMediumEnumeration(); 1280 } 1281 1282 void UIMediumManagerWidget::sltHandleCurrentTabChanged() 1283 { 1284 /* Get current tree-widget: */ 1285 QITreeWidget *pTreeWidget = currentTreeWidget(); 1286 if (pTreeWidget) 1287 { 1288 /* If another tree-widget was focused before, 1289 * move focus to current tree-widget: */ 1290 if (qobject_cast<QITreeWidget*>(focusWidget())) 1291 pTreeWidget->setFocus(); 1292 } 1293 1294 /* Update action icons: */ 1295 updateActionIcons(); 1296 1297 /* Raise the required information-container: */ 1298 if (m_pDetailsWidget) 1299 m_pDetailsWidget->setCurrentType(currentMediumType()); 1300 /* Re-fetch currently chosen medium-item: */ 1301 refetchCurrentChosenMediumItem(); 1302 } 1303 1304 void UIMediumManagerWidget::sltHandleCurrentItemChanged() 1305 { 1306 /* Get sender() tree-widget: */ 1307 QITreeWidget *pTreeWidget = qobject_cast<QITreeWidget*>(sender()); 1308 AssertMsgReturnVoid(pTreeWidget, ("This slot should be called by tree-widget only!\n")); 1309 1310 /* Re-fetch current medium-item of required type: */ 1311 refetchCurrentMediumItem(mediumType(pTreeWidget)); 1312 } 1313 1314 void UIMediumManagerWidget::sltHandleContextMenuCall(const QPoint &position) 1315 { 1316 /* Get current tree-widget: */ 1317 QITreeWidget *pTreeWidget = currentTreeWidget(); 1318 AssertPtrReturnVoid(pTreeWidget); 1319 1320 /* Make sure underlaying item was found: */ 1321 QTreeWidgetItem *pItem = pTreeWidget->itemAt(position); 1322 if (!pItem) 1323 return; 1324 1325 /* Make sure that item is current one: */ 1326 setCurrentItem(pTreeWidget, pItem); 1327 1328 /* Show item context menu: */ 1329 if (m_pContextMenu) 1330 m_pContextMenu->exec(pTreeWidget->viewport()->mapToGlobal(position)); 1331 } 1332 1333 void UIMediumManagerWidget::sltPerformTablesAdjustment() 1334 { 1335 /* Get all the tree-widgets: */ 1336 const QList<QITreeWidget*> trees = m_trees.values(); 1337 1338 /* Calculate deduction for every header: */ 1339 QList<int> deductions; 1340 foreach (QITreeWidget *pTreeWidget, trees) 1341 { 1342 int iDeduction = 0; 1343 for (int iHeaderIndex = 1; iHeaderIndex < pTreeWidget->header()->count(); ++iHeaderIndex) 1344 iDeduction += pTreeWidget->header()->sectionSize(iHeaderIndex); 1345 deductions << iDeduction; 1346 } 1347 1348 /* Adjust the table's first column: */ 1349 for (int iTreeIndex = 0; iTreeIndex < trees.size(); ++iTreeIndex) 1350 { 1351 QITreeWidget *pTreeWidget = trees[iTreeIndex]; 1352 int iSize0 = pTreeWidget->viewport()->width() - deductions[iTreeIndex]; 1353 if (pTreeWidget->header()->sectionSize(0) != iSize0) 1354 pTreeWidget->header()->resizeSection(0, iSize0); 1355 } 1356 } 1357 1358 void UIMediumManagerWidget::prepare() 1359 { 1360 /* Prepare this: */ 1361 prepareThis(); 1362 1363 /* Load settings: */ 1364 loadSettings(); 1365 1366 /* Apply language settings: */ 1367 retranslateUi(); 1368 1369 /* Start medium-enumeration (if necessary): */ 1370 if (!vboxGlobal().isMediumEnumerationInProgress()) 1371 vboxGlobal().startMediumEnumeration(); 1372 /* Emulate medium-enumeration otherwise: */ 1373 else 1374 { 1375 /* Start medium-enumeration: */ 1376 sltHandleMediumEnumerationStart(); 1377 1378 /* Finish medium-enumeration (if necessary): */ 1379 if (!vboxGlobal().isMediumEnumerationInProgress()) 1380 sltHandleMediumEnumerationFinish(); 1381 } 1382 } 1383 1384 void UIMediumManagerWidget::prepareThis() 1385 { 1386 /* Prepare connections: */ 1387 prepareConnections(); 1388 /* Prepare actions: */ 1389 prepareActions(); 1390 /* Prepare central-widget: */ 79 /* Apply window icons: */ 80 setWindowIcon(UIIconPool::iconSetFull(":/diskimage_32px.png", ":/diskimage_16px.png")); 1391 81 prepareWidgets(); 1392 82 } 1393 83 1394 void UIMedium ManagerWidget::prepareConnections()84 void UIMediumSelector::prepareWidgets() 1395 85 { 1396 /* Configure medium-processing connections: */ 1397 connect(&vboxGlobal(), &VBoxGlobal::sigMediumCreated, 1398 this, &UIMediumManagerWidget::sltHandleMediumCreated); 1399 connect(&vboxGlobal(), &VBoxGlobal::sigMediumDeleted, 1400 this, &UIMediumManagerWidget::sltHandleMediumDeleted); 86 m_pMainLayout = new QVBoxLayout; 87 if (!m_pMainLayout) 88 return; 89 setLayout(m_pMainLayout); 1401 90 1402 /* Configure medium-enumeration connections: */ 1403 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationStarted, 1404 this, &UIMediumManagerWidget::sltHandleMediumEnumerationStart); 1405 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerated, 1406 this, &UIMediumManagerWidget::sltHandleMediumEnumerated); 1407 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationFinished, 1408 this, &UIMediumManagerWidget::sltHandleMediumEnumerationFinish); 91 m_pTreeWidget = new QITreeWidget; 92 if (m_pTreeWidget) 93 { 94 m_pMainLayout->addWidget(m_pTreeWidget); 95 } 96 //m_pMainLayout->addWidget( 1409 97 } 1410 98 1411 void UIMediumManagerWidget::prepareActions() 1412 { 1413 /* Create 'Add' action: */ 1414 m_pActionAdd = new QAction(this); 1415 AssertPtrReturnVoid(m_pActionAdd); 1416 { 1417 /* Configure add-action: */ 1418 m_pActionAdd->setShortcut(QKeySequence("Ctrl+A")); 1419 connect(m_pActionAdd, &QAction::triggered, this, &UIMediumManagerWidget::sltAddMedium); 1420 } 1421 /* Create 'Copy' action: */ 1422 m_pActionCopy = new QAction(this); 1423 AssertPtrReturnVoid(m_pActionCopy); 1424 { 1425 /* Configure copy-action: */ 1426 m_pActionCopy->setShortcut(QKeySequence("Ctrl+C")); 1427 connect(m_pActionCopy, &QAction::triggered, this, &UIMediumManagerWidget::sltCopyMedium); 1428 } 1429 1430 /* Create 'Move' action: */ 1431 m_pActionMove = new QAction(this); 1432 AssertPtrReturnVoid(m_pActionMove); 1433 { 1434 /* Configure move-action: */ 1435 m_pActionMove->setShortcut(QKeySequence("Ctrl+M")); 1436 connect(m_pActionMove, &QAction::triggered, this, &UIMediumManagerWidget::sltMoveMedium); 1437 } 1438 1439 /* Create 'Remove' action: */ 1440 m_pActionRemove = new QAction(this); 1441 AssertPtrReturnVoid(m_pActionRemove); 1442 { 1443 /* Configure remove-action: */ 1444 m_pActionRemove->setShortcut(QKeySequence("Ctrl+R")); 1445 connect(m_pActionRemove, &QAction::triggered, this, &UIMediumManagerWidget::sltRemoveMedium); 1446 } 1447 1448 /* Create 'Release' action: */ 1449 m_pActionRelease = new QAction(this); 1450 AssertPtrReturnVoid(m_pActionRelease); 1451 { 1452 /* Configure release-action: */ 1453 m_pActionRelease->setShortcut(QKeySequence("Ctrl+L")); 1454 connect(m_pActionRelease, &QAction::triggered, this, &UIMediumManagerWidget::sltReleaseMedium); 1455 } 1456 1457 /* Create 'Details' action: */ 1458 m_pActionDetails = new QAction(this); 1459 AssertPtrReturnVoid(m_pActionDetails); 1460 { 1461 /* Configure modify-action: */ 1462 m_pActionDetails->setCheckable(true); 1463 m_pActionDetails->setShortcut(QKeySequence("Ctrl+Space")); 1464 connect(m_pActionDetails, &QAction::toggled, this, &UIMediumManagerWidget::sltToggleMediumDetailsVisibility); 1465 } 1466 1467 /* Create 'Refresh' action: */ 1468 m_pActionRefresh = new QAction(this); 1469 AssertPtrReturnVoid(m_pActionRefresh); 1470 { 1471 /* Configure refresh-action: */ 1472 m_pActionRefresh->setShortcut(QKeySequence(QKeySequence::Refresh)); 1473 connect(m_pActionRefresh, &QAction::triggered, this, &UIMediumManagerWidget::sltRefreshAll); 1474 } 1475 1476 /* Update action icons: */ 1477 updateActionIcons(); 1478 1479 /* Prepare menu: */ 1480 prepareMenu(); 1481 /* Prepare context-menu: */ 1482 prepareContextMenu(); 1483 } 1484 1485 void UIMediumManagerWidget::prepareMenu() 1486 { 1487 /* Create 'Medium' menu: */ 1488 m_pMenu = new QMenu(this); 1489 AssertPtrReturnVoid(m_pMenu); 1490 { 1491 /* Configure 'Medium' menu: */ 1492 if (m_pActionAdd) 1493 m_pMenu->addAction(m_pActionAdd); 1494 if (m_pActionCopy) 1495 m_pMenu->addAction(m_pActionCopy); 1496 if (m_pActionMove) 1497 m_pMenu->addAction(m_pActionMove); 1498 if (m_pActionRemove) 1499 m_pMenu->addAction(m_pActionRemove); 1500 if ( (m_pActionCopy || m_pActionMove || m_pActionRemove) 1501 && (m_pActionRelease || m_pActionDetails)) 1502 m_pMenu->addSeparator(); 1503 if (m_pActionRelease) 1504 m_pMenu->addAction(m_pActionRelease); 1505 if (m_pActionDetails) 1506 m_pMenu->addAction(m_pActionDetails); 1507 if ( (m_pActionRelease || m_pActionDetails) 1508 && (m_pActionRefresh)) 1509 m_pMenu->addSeparator(); 1510 if (m_pActionRefresh) 1511 m_pMenu->addAction(m_pActionRefresh); 1512 } 1513 } 1514 1515 void UIMediumManagerWidget::prepareContextMenu() 1516 { 1517 /* Create context-menu: */ 1518 m_pContextMenu = new QMenu(this); 1519 AssertPtrReturnVoid(m_pContextMenu); 1520 { 1521 /* Configure contex-menu: */ 1522 if (m_pActionAdd) 1523 m_pContextMenu->addAction(m_pActionAdd); 1524 if (m_pActionCopy) 1525 m_pContextMenu->addAction(m_pActionCopy); 1526 if (m_pActionMove) 1527 m_pContextMenu->addAction(m_pActionMove); 1528 if (m_pActionRemove) 1529 m_pContextMenu->addAction(m_pActionRemove); 1530 if ( (m_pActionCopy || m_pActionMove || m_pActionRemove) 1531 && (m_pActionRelease || m_pActionDetails)) 1532 m_pContextMenu->addSeparator(); 1533 if (m_pActionRelease) 1534 m_pContextMenu->addAction(m_pActionRelease); 1535 if (m_pActionDetails) 1536 m_pContextMenu->addAction(m_pActionDetails); 1537 } 1538 } 1539 1540 void UIMediumManagerWidget::prepareWidgets() 1541 { 1542 /* Create main-layout: */ 1543 new QVBoxLayout(this); 1544 AssertPtrReturnVoid(layout()); 1545 { 1546 /* Configure layout: */ 1547 layout()->setContentsMargins(0, 0, 0, 0); 1548 #ifdef VBOX_WS_MAC 1549 layout()->setSpacing(10); 1550 #else 1551 layout()->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) / 2); 1552 #endif 1553 1554 /* Prepare toolbar: */ 1555 prepareToolBar(); 1556 /* Prepare tab-widget: */ 1557 prepareTabWidget(); 1558 /* Prepare details-widget: */ 1559 prepareDetailsWidget(); 1560 } 1561 } 1562 1563 void UIMediumManagerWidget::prepareToolBar() 1564 { 1565 /* Create toolbar: */ 1566 m_pToolBar = new UIToolBar(parentWidget()); 1567 AssertPtrReturnVoid(m_pToolBar); 1568 { 1569 /* Configure toolbar: */ 1570 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) * 1.375); 1571 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric)); 1572 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 1573 /* Add toolbar actions: */ 1574 if (m_pActionAdd) 1575 m_pToolBar->addAction(m_pActionAdd); 1576 if (m_pActionCopy) 1577 m_pToolBar->addAction(m_pActionCopy); 1578 if (m_pActionMove) 1579 m_pToolBar->addAction(m_pActionMove); 1580 if (m_pActionRemove) 1581 m_pToolBar->addAction(m_pActionRemove); 1582 if ( (m_pActionCopy || m_pActionMove || m_pActionRemove) 1583 && (m_pActionRelease || m_pActionDetails)) 1584 m_pToolBar->addSeparator(); 1585 if (m_pActionRelease) 1586 m_pToolBar->addAction(m_pActionRelease); 1587 if (m_pActionDetails) 1588 m_pToolBar->addAction(m_pActionDetails); 1589 if ( (m_pActionRelease || m_pActionDetails) 1590 && (m_pActionRefresh)) 1591 m_pToolBar->addSeparator(); 1592 if (m_pActionRefresh) 1593 m_pToolBar->addAction(m_pActionRefresh); 1594 1595 #ifdef VBOX_WS_MAC 1596 /* Check whether we are embedded into a stack: */ 1597 if (m_enmEmbedding == EmbedTo_Stack) 1598 { 1599 /* Add into layout: */ 1600 layout()->addWidget(m_pToolBar); 1601 } 1602 #else 1603 /* Add into layout: */ 1604 layout()->addWidget(m_pToolBar); 1605 #endif 1606 } 1607 } 1608 1609 void UIMediumManagerWidget::prepareTabWidget() 1610 { 1611 /* Create tab-widget: */ 1612 m_pTabWidget = new QITabWidget; 1613 AssertPtrReturnVoid(m_pTabWidget); 1614 { 1615 /* Create tabs: */ 1616 for (int i = 0; i < m_iTabCount; ++i) 1617 prepareTab((UIMediumType)i); 1618 /* Configure tab-widget: */ 1619 m_pTabWidget->setFocusPolicy(Qt::TabFocus); 1620 m_pTabWidget->setTabIcon(tabIndex(UIMediumType_HardDisk), m_iconHD); 1621 m_pTabWidget->setTabIcon(tabIndex(UIMediumType_DVD), m_iconCD); 1622 m_pTabWidget->setTabIcon(tabIndex(UIMediumType_Floppy), m_iconFD); 1623 connect(m_pTabWidget, &QITabWidget::currentChanged, this, &UIMediumManagerWidget::sltHandleCurrentTabChanged); 1624 1625 /* Add tab-widget into central layout: */ 1626 layout()->addWidget(m_pTabWidget); 1627 1628 /* Update other widgets according chosen tab: */ 1629 sltHandleCurrentTabChanged(); 1630 } 1631 } 1632 1633 void UIMediumManagerWidget::prepareTab(UIMediumType type) 1634 { 1635 /* Create tab: */ 1636 m_pTabWidget->addTab(new QWidget, QString()); 1637 QWidget *pTab = tab(type); 1638 AssertPtrReturnVoid(pTab); 1639 { 1640 /* Create tab layout: */ 1641 QVBoxLayout *pLayout = new QVBoxLayout(pTab); 1642 AssertPtrReturnVoid(pLayout); 1643 { 1644 #ifdef VBOX_WS_MAC 1645 /* Configure layout: */ 1646 pLayout->setContentsMargins(10, 10, 10, 10); 1647 #endif 1648 1649 /* Prepare tree-widget: */ 1650 prepareTreeWidget(type, type == UIMediumType_HardDisk ? 3 : 2); 1651 } 1652 } 1653 } 1654 1655 void UIMediumManagerWidget::prepareTreeWidget(UIMediumType type, int iColumns) 1656 { 1657 /* Create tree-widget: */ 1658 m_trees.insert(tabIndex(type), new QITreeWidget); 1659 QITreeWidget *pTreeWidget = treeWidget(type); 1660 AssertPtrReturnVoid(pTreeWidget); 1661 { 1662 /* Configure tree-widget: */ 1663 pTreeWidget->setExpandsOnDoubleClick(false); 1664 pTreeWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 1665 pTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); 1666 pTreeWidget->setAlternatingRowColors(true); 1667 pTreeWidget->setAllColumnsShowFocus(true); 1668 pTreeWidget->setAcceptDrops(true); 1669 pTreeWidget->setColumnCount(iColumns); 1670 pTreeWidget->sortItems(0, Qt::AscendingOrder); 1671 if (iColumns > 0) 1672 pTreeWidget->header()->setSectionResizeMode(0, QHeaderView::Fixed); 1673 if (iColumns > 1) 1674 pTreeWidget->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); 1675 if (iColumns > 2) 1676 pTreeWidget->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); 1677 pTreeWidget->header()->setStretchLastSection(false); 1678 pTreeWidget->setSortingEnabled(true); 1679 connect(pTreeWidget, &QITreeWidget::currentItemChanged, 1680 this, &UIMediumManagerWidget::sltHandleCurrentItemChanged); 1681 if (m_pActionDetails) 1682 connect(pTreeWidget, &QITreeWidget::itemDoubleClicked, 1683 m_pActionDetails, &QAction::setChecked); 1684 connect(pTreeWidget, &QITreeWidget::customContextMenuRequested, 1685 this, &UIMediumManagerWidget::sltHandleContextMenuCall); 1686 connect(pTreeWidget, &QITreeWidget::resized, 1687 this, &UIMediumManagerWidget::sltPerformTablesAdjustment, Qt::QueuedConnection); 1688 connect(pTreeWidget->header(), &QHeaderView::sectionResized, 1689 this, &UIMediumManagerWidget::sltPerformTablesAdjustment, Qt::QueuedConnection); 1690 /* Add tree-widget into tab layout: */ 1691 tab(type)->layout()->addWidget(pTreeWidget); 1692 } 1693 } 1694 1695 void UIMediumManagerWidget::prepareDetailsWidget() 1696 { 1697 /* Create details-widget: */ 1698 m_pDetailsWidget = new UIMediumDetailsWidget(this, m_enmEmbedding); 1699 AssertPtrReturnVoid(m_pDetailsWidget); 1700 { 1701 /* Configure details-widget: */ 1702 m_pDetailsWidget->setVisible(false); 1703 m_pDetailsWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); 1704 connect(m_pDetailsWidget, &UIMediumDetailsWidget::sigAcceptAllowed, 1705 this, &UIMediumManagerWidget::sigAcceptAllowed); 1706 connect(m_pDetailsWidget, &UIMediumDetailsWidget::sigRejectAllowed, 1707 this, &UIMediumManagerWidget::sigRejectAllowed); 1708 connect(m_pDetailsWidget, &UIMediumDetailsWidget::sigDataChangeRejected, 1709 this, &UIMediumManagerWidget::sltResetMediumDetailsChanges); 1710 connect(m_pDetailsWidget, &UIMediumDetailsWidget::sigDataChangeAccepted, 1711 this, &UIMediumManagerWidget::sltApplyMediumDetailsChanges); 1712 1713 /* Add into layout: */ 1714 layout()->addWidget(m_pDetailsWidget); 1715 } 1716 } 1717 1718 void UIMediumManagerWidget::loadSettings() 1719 { 1720 /* Details action/widget: */ 1721 m_pActionDetails->setChecked(gEDataManager->virtualMediaManagerDetailsExpanded()); 1722 } 1723 1724 void UIMediumManagerWidget::repopulateTreeWidgets() 1725 { 1726 /* Remember current medium-items: */ 1727 if (UIMediumItem *pMediumItem = mediumItem(UIMediumType_HardDisk)) 1728 m_strCurrentIdHD = pMediumItem->id(); 1729 if (UIMediumItem *pMediumItem = mediumItem(UIMediumType_DVD)) 1730 m_strCurrentIdCD = pMediumItem->id(); 1731 if (UIMediumItem *pMediumItem = mediumItem(UIMediumType_Floppy)) 1732 m_strCurrentIdFD = pMediumItem->id(); 1733 1734 /* Clear tree-widgets: */ 1735 QITreeWidget *pTreeWidgetHD = treeWidget(UIMediumType_HardDisk); 1736 if (pTreeWidgetHD) 1737 { 1738 setCurrentItem(pTreeWidgetHD, 0); 1739 pTreeWidgetHD->clear(); 1740 } 1741 QITreeWidget *pTreeWidgetCD = treeWidget(UIMediumType_DVD); 1742 if (pTreeWidgetCD) 1743 { 1744 setCurrentItem(pTreeWidgetCD, 0); 1745 pTreeWidgetCD->clear(); 1746 } 1747 QITreeWidget *pTreeWidgetFD = treeWidget(UIMediumType_Floppy); 1748 if (pTreeWidgetFD) 1749 { 1750 setCurrentItem(pTreeWidgetFD, 0); 1751 pTreeWidgetFD->clear(); 1752 } 1753 1754 /* Create medium-items (do not change current one): */ 1755 m_fPreventChangeCurrentItem = true; 1756 foreach (const QString &strMediumID, vboxGlobal().mediumIDs()) 1757 sltHandleMediumCreated(strMediumID); 1758 m_fPreventChangeCurrentItem = false; 1759 1760 /* Select first item as current one if nothing selected: */ 1761 if (pTreeWidgetHD && !mediumItem(UIMediumType_HardDisk)) 1762 if (QTreeWidgetItem *pItem = pTreeWidgetHD->topLevelItem(0)) 1763 setCurrentItem(pTreeWidgetHD, pItem); 1764 if (pTreeWidgetCD && !mediumItem(UIMediumType_DVD)) 1765 if (QTreeWidgetItem *pItem = pTreeWidgetCD->topLevelItem(0)) 1766 setCurrentItem(pTreeWidgetCD, pItem); 1767 if (pTreeWidgetFD && !mediumItem(UIMediumType_Floppy)) 1768 if (QTreeWidgetItem *pItem = pTreeWidgetFD->topLevelItem(0)) 1769 setCurrentItem(pTreeWidgetFD, pItem); 1770 } 1771 1772 void UIMediumManagerWidget::refetchCurrentMediumItem(UIMediumType type) 1773 { 1774 /* Get corresponding medium-item: */ 1775 UIMediumItem *pMediumItem = mediumItem(type); 1776 1777 #ifdef VBOX_WS_MAC 1778 /* Set the file for the proxy icon: */ 1779 if (pMediumItem == currentMediumItem()) 1780 setWindowFilePath(pMediumItem ? pMediumItem->location() : QString()); 1781 #endif /* VBOX_WS_MAC */ 1782 1783 /* Make sure current medium-item visible: */ 1784 if (pMediumItem) 1785 treeWidget(type)->scrollToItem(pMediumItem, QAbstractItemView::EnsureVisible); 1786 1787 /* Update actions: */ 1788 updateActions(); 1789 1790 /* Update details-widget: */ 1791 if (m_pDetailsWidget) 1792 m_pDetailsWidget->setData(pMediumItem ? *pMediumItem : UIDataMedium(type)); 1793 } 1794 1795 void UIMediumManagerWidget::refetchCurrentChosenMediumItem() 1796 { 1797 refetchCurrentMediumItem(currentMediumType()); 1798 } 1799 1800 void UIMediumManagerWidget::refetchCurrentMediumItems() 1801 { 1802 refetchCurrentMediumItem(UIMediumType_HardDisk); 1803 refetchCurrentMediumItem(UIMediumType_DVD); 1804 refetchCurrentMediumItem(UIMediumType_Floppy); 1805 } 1806 1807 void UIMediumManagerWidget::updateActions() 1808 { 1809 /* Get current medium-item: */ 1810 UIMediumItem *pMediumItem = currentMediumItem(); 1811 1812 /* Calculate actions accessibility: */ 1813 bool fNotInEnumeration = !vboxGlobal().isMediumEnumerationInProgress(); 1814 1815 /* Apply actions accessibility: */ 1816 if (m_pActionCopy) 1817 { 1818 bool fActionEnabledCopy = fNotInEnumeration && pMediumItem && checkMediumFor(pMediumItem, Action_Copy); 1819 m_pActionCopy->setEnabled(fActionEnabledCopy); 1820 } 1821 if (m_pActionMove) 1822 { 1823 bool fActionEnabledMove = fNotInEnumeration && pMediumItem && checkMediumFor(pMediumItem, Action_Edit); 1824 m_pActionMove->setEnabled(fActionEnabledMove); 1825 } 1826 if (m_pActionRemove) 1827 { 1828 bool fActionEnabledRemove = fNotInEnumeration && pMediumItem && checkMediumFor(pMediumItem, Action_Remove); 1829 m_pActionRemove->setEnabled(fActionEnabledRemove); 1830 } 1831 if (m_pActionRelease) 1832 { 1833 bool fActionEnabledRelease = fNotInEnumeration && pMediumItem && checkMediumFor(pMediumItem, Action_Release); 1834 m_pActionRelease->setEnabled(fActionEnabledRelease); 1835 } 1836 if (m_pActionDetails) 1837 { 1838 bool fActionEnabledDetails = true; 1839 m_pActionDetails->setEnabled(fActionEnabledDetails); 1840 } 1841 } 1842 1843 void UIMediumManagerWidget::updateActionIcons() 1844 { 1845 QString strPrefix = "hd"; 1846 if (m_pTabWidget) 1847 { 1848 switch (currentMediumType()) 1849 { 1850 case UIMediumType_HardDisk: strPrefix = "hd"; break; 1851 case UIMediumType_DVD: strPrefix = "cd"; break; 1852 case UIMediumType_Floppy: strPrefix = "fd"; break; 1853 default: break; 1854 } 1855 } 1856 1857 if (m_pActionAdd) 1858 m_pActionAdd->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_22px.png").arg(strPrefix), 1859 QString(":/%1_add_16px.png").arg(strPrefix), 1860 QString(":/%1_add_disabled_22px.png").arg(strPrefix), 1861 QString(":/%1_add_disabled_16px.png").arg(strPrefix))); 1862 1863 if (m_pActionCopy) 1864 m_pActionCopy->setIcon(UIIconPool::iconSetFull(QString(":/%1_copy_22px.png").arg(strPrefix), 1865 QString(":/%1_copy_16px.png").arg(strPrefix), 1866 QString(":/%1_copy_disabled_22px.png").arg(strPrefix), 1867 QString(":/%1_copy_disabled_16px.png").arg(strPrefix))); 1868 if (m_pActionMove) 1869 m_pActionMove->setIcon(UIIconPool::iconSetFull(QString(":/%1_move_22px.png").arg(strPrefix), 1870 QString(":/%1_move_16px.png").arg(strPrefix), 1871 QString(":/%1_move_disabled_22px.png").arg(strPrefix), 1872 QString(":/%1_move_disabled_16px.png").arg(strPrefix))); 1873 if (m_pActionRemove) 1874 m_pActionRemove->setIcon(UIIconPool::iconSetFull(QString(":/%1_remove_22px.png").arg(strPrefix), 1875 QString(":/%1_remove_16px.png").arg(strPrefix), 1876 QString(":/%1_remove_disabled_22px.png").arg(strPrefix), 1877 QString(":/%1_remove_disabled_16px.png").arg(strPrefix))); 1878 if (m_pActionRelease) 1879 m_pActionRelease->setIcon(UIIconPool::iconSetFull(QString(":/%1_release_22px.png").arg(strPrefix), 1880 QString(":/%1_release_16px.png").arg(strPrefix), 1881 QString(":/%1_release_disabled_22px.png").arg(strPrefix), 1882 QString(":/%1_release_disabled_16px.png").arg(strPrefix))); 1883 if (m_pActionDetails) 1884 m_pActionDetails->setIcon(UIIconPool::iconSetFull(QString(":/%1_modify_22px.png").arg(strPrefix), 1885 QString(":/%1_modify_16px.png").arg(strPrefix), 1886 QString(":/%1_modify_disabled_22px.png").arg(strPrefix), 1887 QString(":/%1_modify_disabled_16px.png").arg(strPrefix))); 1888 if (m_pActionRefresh && m_pActionRefresh->icon().isNull()) 1889 m_pActionRefresh->setIcon(UIIconPool::iconSetFull(":/refresh_22px.png", ":/refresh_16px.png", 1890 ":/refresh_disabled_22px.png", ":/refresh_disabled_16px.png")); 1891 } 1892 1893 void UIMediumManagerWidget::updateTabIcons(UIMediumItem *pMediumItem, Action action) 1894 { 1895 /* Make sure medium-item is valid: */ 1896 AssertReturnVoid(pMediumItem); 1897 1898 /* Prepare data for tab: */ 1899 const QIcon *pIcon = 0; 1900 bool *pfInaccessible = 0; 1901 const UIMediumType mediumType = pMediumItem->mediumType(); 1902 switch (mediumType) 1903 { 1904 case UIMediumType_HardDisk: 1905 pIcon = &m_iconHD; 1906 pfInaccessible = &m_fInaccessibleHD; 1907 break; 1908 case UIMediumType_DVD: 1909 pIcon = &m_iconCD; 1910 pfInaccessible = &m_fInaccessibleCD; 1911 break; 1912 case UIMediumType_Floppy: 1913 pIcon = &m_iconFD; 1914 pfInaccessible = &m_fInaccessibleFD; 1915 break; 1916 default: 1917 AssertFailed(); 1918 } 1919 AssertReturnVoid(pIcon && pfInaccessible); 1920 1921 switch (action) 1922 { 1923 case Action_Add: 1924 { 1925 /* Does it change the overall state? */ 1926 if (*pfInaccessible || pMediumItem->state() != KMediumState_Inaccessible) 1927 break; /* no */ 1928 1929 *pfInaccessible = true; 1930 1931 if (m_pTabWidget) 1932 m_pTabWidget->setTabIcon(tabIndex(mediumType), vboxGlobal().warningIcon()); 1933 1934 break; 1935 } 1936 case Action_Edit: 1937 case Action_Remove: 1938 { 1939 bool fCheckRest = false; 1940 1941 if (action == Action_Edit) 1942 { 1943 /* Does it change the overall state? */ 1944 if ((*pfInaccessible && pMediumItem->state() == KMediumState_Inaccessible) || 1945 (!*pfInaccessible && pMediumItem->state() != KMediumState_Inaccessible)) 1946 break; /* no */ 1947 1948 /* Is the given item in charge? */ 1949 if (!*pfInaccessible && pMediumItem->state() == KMediumState_Inaccessible) 1950 *pfInaccessible = true; /* yes */ 1951 else 1952 fCheckRest = true; /* no */ 1953 } 1954 else 1955 fCheckRest = true; 1956 1957 if (fCheckRest) 1958 { 1959 /* Find the first KMediumState_Inaccessible item to be in charge: */ 1960 CheckIfSuitableByState lookForState(KMediumState_Inaccessible); 1961 CheckIfSuitableByID ignoreID(pMediumItem->id()); 1962 UIMediumItem *pInaccessibleMediumItem = searchItem(pMediumItem->parentTree(), lookForState, &ignoreID); 1963 *pfInaccessible = !!pInaccessibleMediumItem; 1964 } 1965 1966 if (m_pTabWidget) 1967 { 1968 if (*pfInaccessible) 1969 m_pTabWidget->setTabIcon(tabIndex(mediumType), vboxGlobal().warningIcon()); 1970 else 1971 m_pTabWidget->setTabIcon(tabIndex(mediumType), *pIcon); 1972 } 1973 1974 break; 1975 } 1976 1977 default: 1978 break; 1979 } 1980 } 1981 1982 UIMediumItem* UIMediumManagerWidget::createMediumItem(const UIMedium &medium) 1983 { 1984 /* Get medium type: */ 1985 UIMediumType type = medium.type(); 1986 1987 /* Create medium-item: */ 1988 UIMediumItem *pMediumItem = 0; 1989 switch (type) 1990 { 1991 /* Of hard-drive type: */ 1992 case UIMediumType_HardDisk: 1993 { 1994 /* Make sure corresponding tree-widget exists: */ 1995 QITreeWidget *pTreeWidget = treeWidget(UIMediumType_HardDisk); 1996 if (pTreeWidget) 1997 { 1998 /* Recursively create hard-drive item: */ 1999 pMediumItem = createHardDiskItem(medium); 2000 /* Make sure item was created: */ 2001 if (!pMediumItem) 2002 break; 2003 if (pMediumItem->id() == m_strCurrentIdHD) 2004 { 2005 setCurrentItem(pTreeWidget, pMediumItem); 2006 m_strCurrentIdHD = QString(); 2007 } 2008 } 2009 break; 2010 } 2011 /* Of optical-image type: */ 2012 case UIMediumType_DVD: 2013 { 2014 /* Make sure corresponding tree-widget exists: */ 2015 QITreeWidget *pTreeWidget = treeWidget(UIMediumType_DVD); 2016 if (pTreeWidget) 2017 { 2018 /* Create optical-disk item: */ 2019 pMediumItem = new UIMediumItemCD(medium, pTreeWidget); 2020 /* Make sure item was created: */ 2021 if (!pMediumItem) 2022 break; 2023 LogRel2(("UIMediumManager: Optical medium-item with ID={%s} created.\n", medium.id().toUtf8().constData())); 2024 if (pMediumItem->id() == m_strCurrentIdCD) 2025 { 2026 setCurrentItem(pTreeWidget, pMediumItem); 2027 m_strCurrentIdCD = QString(); 2028 } 2029 } 2030 break; 2031 } 2032 /* Of floppy-image type: */ 2033 case UIMediumType_Floppy: 2034 { 2035 /* Make sure corresponding tree-widget exists: */ 2036 QITreeWidget *pTreeWidget = treeWidget(UIMediumType_Floppy); 2037 if (pTreeWidget) 2038 { 2039 /* Create floppy-disk item: */ 2040 pMediumItem = new UIMediumItemFD(medium, pTreeWidget); 2041 /* Make sure item was created: */ 2042 if (!pMediumItem) 2043 break; 2044 LogRel2(("UIMediumManager: Floppy medium-item with ID={%s} created.\n", medium.id().toUtf8().constData())); 2045 if (pMediumItem->id() == m_strCurrentIdFD) 2046 { 2047 setCurrentItem(pTreeWidget, pMediumItem); 2048 m_strCurrentIdFD = QString(); 2049 } 2050 } 2051 break; 2052 } 2053 default: AssertMsgFailed(("Medium-type unknown: %d\n", type)); break; 2054 } 2055 2056 /* Make sure item was created: */ 2057 if (!pMediumItem) 2058 return 0; 2059 2060 /* Update tab-icons: */ 2061 updateTabIcons(pMediumItem, Action_Add); 2062 2063 /* Re-fetch medium-item if it is current one created: */ 2064 if (pMediumItem == mediumItem(type)) 2065 refetchCurrentMediumItem(type); 2066 2067 /* Return created medium-item: */ 2068 return pMediumItem; 2069 } 2070 2071 UIMediumItem* UIMediumManagerWidget::createHardDiskItem(const UIMedium &medium) 2072 { 2073 /* Make sure passed medium is valid: */ 2074 AssertReturn(!medium.medium().isNull(), 0); 2075 2076 /* Make sure corresponding tree-widget exists: */ 2077 QITreeWidget *pTreeWidget = treeWidget(UIMediumType_HardDisk); 2078 if (pTreeWidget) 2079 { 2080 /* Search for existing medium-item: */ 2081 UIMediumItem *pMediumItem = searchItem(pTreeWidget, CheckIfSuitableByID(medium.id())); 2082 2083 /* If medium-item do not exists: */ 2084 if (!pMediumItem) 2085 { 2086 /* If medium have a parent: */ 2087 if (medium.parentID() != UIMedium::nullID()) 2088 { 2089 /* Try to find parent medium-item: */ 2090 UIMediumItem *pParentMediumItem = searchItem(pTreeWidget, CheckIfSuitableByID(medium.parentID())); 2091 /* If parent medium-item was not found: */ 2092 if (!pParentMediumItem) 2093 { 2094 /* Make sure corresponding parent medium is already cached! */ 2095 UIMedium parentMedium = vboxGlobal().medium(medium.parentID()); 2096 if (parentMedium.isNull()) 2097 AssertMsgFailed(("Parent medium with ID={%s} was not found!\n", medium.parentID().toUtf8().constData())); 2098 /* Try to create parent medium-item: */ 2099 else 2100 pParentMediumItem = createHardDiskItem(parentMedium); 2101 } 2102 /* If parent medium-item was found: */ 2103 if (pParentMediumItem) 2104 { 2105 pMediumItem = new UIMediumItemHD(medium, pParentMediumItem); 2106 LogRel2(("UIMediumManager: Child hard-disk medium-item with ID={%s} created.\n", medium.id().toUtf8().constData())); 2107 } 2108 } 2109 /* Else just create item as top-level one: */ 2110 if (!pMediumItem) 2111 { 2112 pMediumItem = new UIMediumItemHD(medium, pTreeWidget); 2113 LogRel2(("UIMediumManager: Root hard-disk medium-item with ID={%s} created.\n", medium.id().toUtf8().constData())); 2114 } 2115 } 2116 2117 /* Return created medium-item: */ 2118 return pMediumItem; 2119 } 2120 2121 /* Return null by default: */ 2122 return 0; 2123 } 2124 2125 void UIMediumManagerWidget::updateMediumItem(const UIMedium &medium) 2126 { 2127 /* Get medium type: */ 2128 UIMediumType type = medium.type(); 2129 2130 /* Search for existing medium-item: */ 2131 UIMediumItem *pMediumItem = searchItem(treeWidget(type), CheckIfSuitableByID(medium.id())); 2132 2133 /* Create item if doesn't exists: */ 2134 if (!pMediumItem) 2135 pMediumItem = createMediumItem(medium); 2136 2137 /* Make sure item was created: */ 2138 if (!pMediumItem) 2139 return; 2140 2141 /* Update medium-item: */ 2142 pMediumItem->setMedium(medium); 2143 LogRel2(("UIMediumManager: Medium-item with ID={%s} updated.\n", medium.id().toUtf8().constData())); 2144 2145 /* Update tab-icons: */ 2146 updateTabIcons(pMediumItem, Action_Edit); 2147 2148 /* Re-fetch medium-item if it is current one updated: */ 2149 if (pMediumItem == mediumItem(type)) 2150 refetchCurrentMediumItem(type); 2151 } 2152 2153 void UIMediumManagerWidget::deleteMediumItem(const QString &strMediumID) 2154 { 2155 /* Search for corresponding tree-widget: */ 2156 QList<UIMediumType> types; 2157 types << UIMediumType_HardDisk << UIMediumType_DVD << UIMediumType_Floppy; 2158 QITreeWidget *pTreeWidget = 0; 2159 UIMediumItem *pMediumItem = 0; 2160 foreach (UIMediumType type, types) 2161 { 2162 /* Get iterated tree-widget: */ 2163 pTreeWidget = treeWidget(type); 2164 /* Search for existing medium-item: */ 2165 pMediumItem = searchItem(pTreeWidget, CheckIfSuitableByID(strMediumID)); 2166 if (pMediumItem) 2167 break; 2168 } 2169 2170 /* Make sure item was found: */ 2171 if (!pMediumItem) 2172 return; 2173 2174 /* Update tab-icons: */ 2175 updateTabIcons(pMediumItem, Action_Remove); 2176 2177 /* Delete medium-item: */ 2178 delete pMediumItem; 2179 LogRel2(("UIMediumManager: Medium-item with ID={%s} deleted.\n", strMediumID.toUtf8().constData())); 2180 2181 /* If there is no current medium-item now selected 2182 * we have to choose first-available medium-item as current one: */ 2183 if (!pTreeWidget->currentItem()) 2184 setCurrentItem(pTreeWidget, pTreeWidget->topLevelItem(0)); 2185 } 2186 2187 QWidget* UIMediumManagerWidget::tab(UIMediumType type) const 2188 { 2189 /* Determine tab index for passed medium type: */ 2190 int iIndex = tabIndex(type); 2191 2192 /* Return tab for known tab index: */ 2193 if (iIndex >= 0 && iIndex < m_iTabCount) 2194 return iIndex < m_pTabWidget->count() ? m_pTabWidget->widget(iIndex) : 0; 2195 2196 /* Null by default: */ 2197 return 0; 2198 } 2199 2200 QITreeWidget* UIMediumManagerWidget::treeWidget(UIMediumType type) const 2201 { 2202 /* Determine tab index for passed medium type: */ 2203 int iIndex = tabIndex(type); 2204 2205 /* Return tree-widget for known tab index: */ 2206 if (iIndex >= 0 && iIndex < m_iTabCount) 2207 return m_trees.value(iIndex, 0); 2208 2209 /* Null by default: */ 2210 return 0; 2211 } 2212 2213 UIMediumItem* UIMediumManagerWidget::mediumItem(UIMediumType type) const 2214 { 2215 /* Get corresponding tree-widget: */ 2216 QITreeWidget *pTreeWidget = treeWidget(type); 2217 /* Return corresponding medium-item: */ 2218 return pTreeWidget ? toMediumItem(pTreeWidget->currentItem()) : 0; 2219 } 2220 2221 UIMediumType UIMediumManagerWidget::mediumType(QITreeWidget *pTreeWidget) const 2222 { 2223 /* Determine tab index of passed tree-widget: */ 2224 int iIndex = m_trees.key(pTreeWidget, -1); 2225 2226 /* Return medium type for known tab index: */ 2227 if (iIndex >= 0 && iIndex < m_iTabCount) 2228 return (UIMediumType)iIndex; 2229 2230 /* Invalid by default: */ 2231 AssertFailedReturn(UIMediumType_Invalid); 2232 } 2233 2234 UIMediumType UIMediumManagerWidget::currentMediumType() const 2235 { 2236 /* Invalid if tab-widget doesn't exists: */ 2237 if (!m_pTabWidget) 2238 return UIMediumType_Invalid; 2239 2240 /* Return current medium type: */ 2241 return (UIMediumType)m_pTabWidget->currentIndex(); 2242 } 2243 2244 QITreeWidget* UIMediumManagerWidget::currentTreeWidget() const 2245 { 2246 /* Return current tree-widget: */ 2247 return treeWidget(currentMediumType()); 2248 } 2249 2250 UIMediumItem* UIMediumManagerWidget::currentMediumItem() const 2251 { 2252 /* Return current medium-item: */ 2253 return mediumItem(currentMediumType()); 2254 } 2255 2256 void UIMediumManagerWidget::setCurrentItem(QITreeWidget *pTreeWidget, QTreeWidgetItem *pItem) 2257 { 2258 /* Make sure passed tree-widget is valid: */ 2259 AssertPtrReturnVoid(pTreeWidget); 2260 2261 /* Make passed item current for passed tree-widget: */ 2262 pTreeWidget->setCurrentItem(pItem); 2263 2264 /* If non NULL item was passed: */ 2265 if (pItem) 2266 { 2267 /* Make sure it's also selected, and visible: */ 2268 pItem->setSelected(true); 2269 pTreeWidget->scrollToItem(pItem, QAbstractItemView::EnsureVisible); 2270 } 2271 2272 /* Re-fetch currently chosen medium-item: */ 2273 refetchCurrentChosenMediumItem(); 2274 } 2275 2276 /* static */ 2277 int UIMediumManagerWidget::tabIndex(UIMediumType type) 2278 { 2279 /* Return tab index corresponding to known medium type: */ 2280 switch (type) 2281 { 2282 case UIMediumType_HardDisk: return 0; 2283 case UIMediumType_DVD: return 1; 2284 case UIMediumType_Floppy: return 2; 2285 default: break; 2286 } 2287 2288 /* -1 by default: */ 2289 return -1; 2290 } 2291 2292 /* static */ 2293 UIMediumItem* UIMediumManagerWidget::searchItem(QITreeWidget *pTreeWidget, const CheckIfSuitableBy &condition, CheckIfSuitableBy *pException) 2294 { 2295 /* Make sure argument is valid: */ 2296 if (!pTreeWidget) 2297 return 0; 2298 2299 /* Return wrapper: */ 2300 return searchItem(pTreeWidget->invisibleRootItem(), condition, pException); 2301 } 2302 2303 /* static */ 2304 UIMediumItem* UIMediumManagerWidget::searchItem(QTreeWidgetItem *pParentItem, const CheckIfSuitableBy &condition, CheckIfSuitableBy *pException) 2305 { 2306 /* Make sure argument is valid: */ 2307 if (!pParentItem) 2308 return 0; 2309 2310 /* Verify passed item if it is of 'medium' type too: */ 2311 if (UIMediumItem *pMediumParentItem = toMediumItem(pParentItem)) 2312 if ( condition.isItSuitable(pMediumParentItem) 2313 && (!pException || !pException->isItSuitable(pMediumParentItem))) 2314 return pMediumParentItem; 2315 2316 /* Iterate other all the children: */ 2317 for (int iChildIndex = 0; iChildIndex < pParentItem->childCount(); ++iChildIndex) 2318 if (UIMediumItem *pMediumChildItem = toMediumItem(pParentItem->child(iChildIndex))) 2319 if (UIMediumItem *pRequiredMediumChildItem = searchItem(pMediumChildItem, condition, pException)) 2320 return pRequiredMediumChildItem; 2321 2322 /* Null by default: */ 2323 return 0; 2324 } 2325 2326 /* static */ 2327 bool UIMediumManagerWidget::checkMediumFor(UIMediumItem *pItem, Action action) 2328 { 2329 /* Make sure passed ID is valid: */ 2330 AssertReturn(pItem, false); 2331 2332 switch (action) 2333 { 2334 case Action_Edit: 2335 { 2336 /* Edit means changing the description and alike; any media that is 2337 * not being read to or written from can be altered in these terms. */ 2338 switch (pItem->state()) 2339 { 2340 case KMediumState_NotCreated: 2341 case KMediumState_Inaccessible: 2342 case KMediumState_LockedRead: 2343 case KMediumState_LockedWrite: 2344 return false; 2345 default: 2346 break; 2347 } 2348 return true; 2349 } 2350 case Action_Copy: 2351 { 2352 /* False for children: */ 2353 return pItem->medium().parentID() == UIMedium::nullID(); 2354 } 2355 case Action_Remove: 2356 { 2357 /* Removable if not attached to anything: */ 2358 return !pItem->isUsed(); 2359 } 2360 case Action_Release: 2361 { 2362 /* Releasable if attached but not in snapshots: */ 2363 return pItem->isUsed() && !pItem->isUsedInSnapshots(); 2364 } 2365 2366 default: 2367 break; 2368 } 2369 2370 AssertFailedReturn(false); 2371 } 2372 2373 /* static */ 2374 UIMediumItem* UIMediumManagerWidget::toMediumItem(QTreeWidgetItem *pItem) 2375 { 2376 /* Cast passed QTreeWidgetItem to UIMediumItem if possible: */ 2377 return pItem && pItem->type() == QITreeWidgetItem::ItemType ? static_cast<UIMediumItem*>(pItem) : 0; 2378 } 2379 2380 2381 /********************************************************************************************************************************* 2382 * Class UIMediumManagerFactory implementation. * 2383 *********************************************************************************************************************************/ 2384 2385 void UIMediumManagerFactory::create(QIManagerDialog *&pDialog, QWidget *pCenterWidget) 2386 { 2387 pDialog = new UIMediumManager(pCenterWidget); 2388 } 2389 2390 2391 /********************************************************************************************************************************* 2392 * Class UIMediumManagerFactory implementation. * 2393 *********************************************************************************************************************************/ 2394 2395 UIMediumManager::UIMediumManager(QWidget *pCenterWidget) 2396 : QIWithRetranslateUI<QIManagerDialog>(pCenterWidget) 2397 , m_pProgressBar(0) 2398 { 2399 } 2400 2401 void UIMediumManager::sltHandleButtonBoxClick(QAbstractButton *pButton) 2402 { 2403 /* Disable buttons first of all: */ 2404 button(ButtonType_Reset)->setEnabled(false); 2405 button(ButtonType_Apply)->setEnabled(false); 2406 2407 /* Compare with known buttons: */ 2408 if (pButton == button(ButtonType_Reset)) 2409 emit sigDataChangeRejected(); 2410 else 2411 if (pButton == button(ButtonType_Apply)) 2412 emit sigDataChangeAccepted(); 2413 } 2414 2415 void UIMediumManager::retranslateUi() 2416 { 2417 /* Translate window title: */ 2418 setWindowTitle(tr("Virtual Media Manager")); 2419 2420 /* Translate buttons: */ 2421 button(ButtonType_Reset)->setText(tr("Reset")); 2422 button(ButtonType_Apply)->setText(tr("Apply")); 2423 button(ButtonType_Close)->setText(tr("Close")); 2424 button(ButtonType_Reset)->setStatusTip(tr("Reset changes in current medium details")); 2425 button(ButtonType_Apply)->setStatusTip(tr("Apply changes in current medium details")); 2426 button(ButtonType_Close)->setStatusTip(tr("Close dialog without saving")); 2427 button(ButtonType_Reset)->setShortcut(QString("Ctrl+Backspace")); 2428 button(ButtonType_Apply)->setShortcut(QString("Ctrl+Return")); 2429 button(ButtonType_Close)->setShortcut(Qt::Key_Escape); 2430 button(ButtonType_Reset)->setToolTip(tr("Reset Changes (%1)").arg(button(ButtonType_Reset)->shortcut().toString())); 2431 button(ButtonType_Apply)->setToolTip(tr("Apply Changes (%1)").arg(button(ButtonType_Apply)->shortcut().toString())); 2432 button(ButtonType_Close)->setToolTip(tr("Close Window (%1)").arg(button(ButtonType_Close)->shortcut().toString())); 2433 } 2434 2435 void UIMediumManager::configure() 2436 { 2437 /* Apply window icons: */ 2438 setWindowIcon(UIIconPool::iconSetFull(":/diskimage_32px.png", ":/diskimage_16px.png")); 2439 } 2440 2441 void UIMediumManager::configureCentralWidget() 2442 { 2443 /* Create widget: */ 2444 UIMediumManagerWidget *pWidget = new UIMediumManagerWidget(EmbedTo_Dialog, this); 2445 AssertPtrReturnVoid(pWidget); 2446 { 2447 /* Configure widget: */ 2448 setWidget(pWidget); 2449 setWidgetMenu(pWidget->menu()); 2450 #ifdef VBOX_WS_MAC 2451 setWidgetToolbar(pWidget->toolbar()); 2452 #endif 2453 connect(this, &UIMediumManager::sigDataChangeRejected, 2454 pWidget, &UIMediumManagerWidget::sltResetMediumDetailsChanges); 2455 connect(this, &UIMediumManager::sigDataChangeAccepted, 2456 pWidget, &UIMediumManagerWidget::sltApplyMediumDetailsChanges); 2457 2458 /* Add into layout: */ 2459 centralWidget()->layout()->addWidget(pWidget); 2460 } 2461 } 2462 2463 void UIMediumManager::configureButtonBox() 2464 { 2465 /* Configure button-box: */ 2466 connect(widget(), &UIMediumManagerWidget::sigMediumDetailsVisibilityChanged, 2467 button(ButtonType_Apply), &QPushButton::setVisible); 2468 connect(widget(), &UIMediumManagerWidget::sigMediumDetailsVisibilityChanged, 2469 button(ButtonType_Reset), &QPushButton::setVisible); 2470 connect(widget(), &UIMediumManagerWidget::sigAcceptAllowed, 2471 button(ButtonType_Apply), &QPushButton::setEnabled); 2472 connect(widget(), &UIMediumManagerWidget::sigRejectAllowed, 2473 button(ButtonType_Reset), &QPushButton::setEnabled); 2474 connect(buttonBox(), &QIDialogButtonBox::clicked, 2475 this, &UIMediumManager::sltHandleButtonBoxClick); 2476 // WORKAROUND: 2477 // Since we connected signals later than extra-data loaded 2478 // for signals above, we should handle that stuff here again: 2479 button(ButtonType_Apply)->setVisible(gEDataManager->virtualMediaManagerDetailsExpanded()); 2480 button(ButtonType_Reset)->setVisible(gEDataManager->virtualMediaManagerDetailsExpanded()); 2481 2482 /* Create progress-bar: */ 2483 m_pProgressBar = new UIEnumerationProgressBar; 2484 AssertPtrReturnVoid(m_pProgressBar); 2485 { 2486 /* Configure progress-bar: */ 2487 m_pProgressBar->hide(); 2488 /* Add progress-bar into button-box layout: */ 2489 buttonBox()->addExtraWidget(m_pProgressBar); 2490 /* Notify widget it has progress-bar: */ 2491 widget()->setProgressBar(m_pProgressBar); 2492 } 2493 } 2494 2495 void UIMediumManager::finalize() 99 void UIMediumSelector::finalize() 2496 100 { 2497 101 /* Apply language settings: */ 2498 102 retranslateUi(); 2499 103 } 2500 2501 UIMediumManagerWidget *UIMediumManager::widget()2502 {2503 return qobject_cast<UIMediumManagerWidget*>(QIManagerDialog::widget());2504 } -
trunk/src/VBox/Frontends/VirtualBox/src/medium/UIMediumSelector.h
r72344 r72357 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIMedium Manager class declaration.3 * VBox Qt GUI - UIMediumSelector class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef ___UIMedium Manager_h___19 #define ___UIMedium Manager_h___18 #ifndef ___UIMediumSelector_h___ 19 #define ___UIMediumSelector_h___ 20 20 21 21 /* GUI includes: */ 22 #include "QI ManagerDialog.h"22 #include "QIDialog.h" 23 23 #include "QIWithRetranslateUI.h" 24 #include "UIMedium.h" 24 25 #include "UIMediumDefs.h" 26 #include "UIMediumDetailsWidget.h" 25 27 26 28 /* Forward declarations: */ 29 class CheckIfSuitableBy; 27 30 class QAbstractButton; 28 31 class QLabel; 29 32 class QProgressBar; 30 33 class QTabWidget; 31 class QTreeWidgetItem; 34 class QITreeWidget; 35 class QVBoxLayout; 32 36 class QIDialogButtonBox; 33 37 class QILabel; 34 class QITreeWidget;35 class UIMedium;36 class UIMediumDetailsWidget;37 38 class UIMediumItem; 38 39 class UIToolBar; 39 40 40 41 41 /** Functor interface allowing to check if passed UIMediumItem is suitable. */42 class CheckIfSuitableBy42 /** QIDialog extension providing GUI with the dialog to select an existing media. */ 43 class UIMediumSelector : public QIWithRetranslateUI<QIDialog> 43 44 { 44 public:45 45 46 /** Destructs functor. */47 virtual ~CheckIfSuitableBy() { /* Makes MSC happy. */ }48 49 /** Determines whether passed @a pItem is suitable. */50 virtual bool isItSuitable(UIMediumItem *pItem) const = 0;51 };52 53 54 /** Medium manager progress-bar.55 * Reflects medium-enumeration progress, stays hidden otherwise. */56 class UIEnumerationProgressBar : public QWidget57 {58 Q_OBJECT;59 60 public:61 62 /** Constructor on the basis of passed @a pParent. */63 UIEnumerationProgressBar(QWidget *pParent = 0);64 65 /** Defines progress-bar label-text. */66 void setText(const QString &strText);67 68 /** Returns progress-bar current-value. */69 int value() const;70 /** Defines progress-bar current-value. */71 void setValue(int iValue);72 /** Defines progress-bar maximum-value. */73 void setMaximum(int iValue);74 75 private:76 77 /** Prepares progress-bar content. */78 void prepare();79 80 /** Progress-bar label. */81 QLabel *m_pLabel;82 /** Progress-bar itself. */83 QProgressBar *m_pProgressBar;84 };85 86 87 /** QWidget extension providing GUI with the pane to control media related functionality. */88 class UIMediumManagerWidget : public QIWithRetranslateUI<QWidget>89 {90 Q_OBJECT;91 92 /** Item action types. */93 enum Action { Action_Add, Action_Edit, Action_Copy, Action_Remove, Action_Release };94 95 signals:96 97 /** Notifies listeners about medium details-widget @a fVisible. */98 void sigMediumDetailsVisibilityChanged(bool fVisible);99 /** Notifies listeners about accept is @a fAllowed. */100 void sigAcceptAllowed(bool fAllowed);101 /** Notifies listeners about reject is @a fAllowed. */102 void sigRejectAllowed(bool fAllowed);103 104 public:105 106 /** Constructs Virtual Media Manager widget. */107 UIMediumManagerWidget(EmbedTo enmEmbedding, QWidget *pParent = 0);108 109 /** Returns the menu. */110 QMenu *menu() const { return m_pMenu; }111 112 #ifdef VBOX_WS_MAC113 /** Returns the toolbar. */114 UIToolBar *toolbar() const { return m_pToolBar; }115 #endif116 117 /** Defines @a pProgressBar reference. */118 void setProgressBar(UIEnumerationProgressBar *pProgressBar);119 120 protected:121 122 /** @name Event-handling stuff.123 * @{ */124 /** Handles translation event. */125 virtual void retranslateUi() /* override */;126 127 /** Handles @a pShow event. */128 virtual void showEvent(QShowEvent *pEvent) /* override */;129 /** @} */130 131 public slots:132 133 /** @name Details-widget stuff.134 * @{ */135 /** Handles command to reset medium details changes. */136 void sltResetMediumDetailsChanges();137 /** Handles command to apply medium details changes. */138 void sltApplyMediumDetailsChanges();139 /** @} */140 141 private slots:142 143 /** @name Medium operation stuff.144 * @{ */145 /** Handles VBoxGlobal::sigMediumCreated signal. */146 void sltHandleMediumCreated(const QString &strMediumID);147 /** Handles VBoxGlobal::sigMediumDeleted signal. */148 void sltHandleMediumDeleted(const QString &strMediumID);149 /** @} */150 151 /** @name Medium enumeration stuff.152 * @{ */153 /** Handles VBoxGlobal::sigMediumEnumerationStarted signal. */154 void sltHandleMediumEnumerationStart();155 /** Handles VBoxGlobal::sigMediumEnumerated signal. */156 void sltHandleMediumEnumerated(const QString &strMediumID);157 /** Handles VBoxGlobal::sigMediumEnumerationFinished signal. */158 void sltHandleMediumEnumerationFinish();159 /** @} */160 161 /** @name Menu/action stuff.162 * @{ */163 /** Handles command to add medium. */164 void sltAddMedium();165 /** Handles command to copy medium. */166 void sltCopyMedium();167 /** Handles command to move medium. */168 void sltMoveMedium();169 /** Handles command to remove medium. */170 void sltRemoveMedium();171 /** Handles command to release medium. */172 void sltReleaseMedium();173 /** Handles command to make medium details @a fVisible. */174 void sltToggleMediumDetailsVisibility(bool fVisible);175 /** Handles command to refresh medium. */176 void sltRefreshAll();177 /** @} */178 179 /** @name Tab-widget stuff.180 * @{ */181 /** Handles tab change case. */182 void sltHandleCurrentTabChanged();183 /** Handles item change case. */184 void sltHandleCurrentItemChanged();185 /** Handles item context-menu-call case. */186 void sltHandleContextMenuCall(const QPoint &position);187 /** @} */188 189 /** @name Tree-widget stuff.190 * @{ */191 /** Adjusts tree-widgets according content. */192 void sltPerformTablesAdjustment();193 /** @} */194 195 private:196 197 /** @name Prepare/cleanup cascade.198 * @{ */199 /** Prepares all. */200 void prepare();201 /** Prepares this. */202 void prepareThis();203 /** Prepares connections. */204 void prepareConnections();205 /** Prepares actions. */206 void prepareActions();207 /** Prepares menu. */208 void prepareMenu();209 /** Prepares context-menu. */210 void prepareContextMenu();211 /** Prepares widgets. */212 void prepareWidgets();213 /** Prepares toolbar. */214 void prepareToolBar();215 /** Prepares tab-widget. */216 void prepareTabWidget();217 /** Prepares tab-widget's tab. */218 void prepareTab(UIMediumType type);219 /** Prepares tab-widget's tree-widget. */220 void prepareTreeWidget(UIMediumType type, int iColumns);221 /** Prepares details-widget. */222 void prepareDetailsWidget();223 /** Load settings: */224 void loadSettings();225 226 /** Repopulates tree-widgets content. */227 void repopulateTreeWidgets();228 229 /** Updates details according latest changes in current item of passed @a type. */230 void refetchCurrentMediumItem(UIMediumType type);231 /** Updates details according latest changes in current item of chosen type. */232 void refetchCurrentChosenMediumItem();233 /** Updates details according latest changes in all current items. */234 void refetchCurrentMediumItems();235 236 /** Updates actions according currently chosen item. */237 void updateActions();238 /** Updates action icons according currently chosen tab. */239 void updateActionIcons();240 /** Updates tab icons according last @a action happened with @a pItem. */241 void updateTabIcons(UIMediumItem *pItem, Action action);242 /** @} */243 244 /** @name Widget operation stuff.245 * @{ */246 /** Creates UIMediumItem for corresponding @a medium. */247 UIMediumItem *createMediumItem(const UIMedium &medium);248 /** Creates UIMediumItemHD for corresponding @a medium. */249 UIMediumItem *createHardDiskItem(const UIMedium &medium);250 /** Updates UIMediumItem for corresponding @a medium. */251 void updateMediumItem(const UIMedium &medium);252 /** Deletes UIMediumItem for corresponding @a strMediumID. */253 void deleteMediumItem(const QString &strMediumID);254 255 /** Returns tab for passed medium @a type. */256 QWidget *tab(UIMediumType type) const;257 /** Returns tree-widget for passed medium @a type. */258 QITreeWidget *treeWidget(UIMediumType type) const;259 /** Returns item for passed medium @a type. */260 UIMediumItem *mediumItem(UIMediumType type) const;261 262 /** Returns medium type for passed @a pTreeWidget. */263 UIMediumType mediumType(QITreeWidget *pTreeWidget) const;264 265 /** Returns current medium type. */266 UIMediumType currentMediumType() const;267 /** Returns current tree-widget. */268 QITreeWidget *currentTreeWidget() const;269 /** Returns current item. */270 UIMediumItem *currentMediumItem() const;271 272 /** Defines current item for passed @a pTreeWidget as @a pItem. */273 void setCurrentItem(QITreeWidget *pTreeWidget, QTreeWidgetItem *pItem);274 /** @} */275 276 /** @name Helper stuff.277 * @{ */278 /** Returns tab index for passed UIMediumType. */279 static int tabIndex(UIMediumType type);280 281 /** Performs search for the @a pTree child which corresponds to the @a condition but not @a pException. */282 static UIMediumItem *searchItem(QITreeWidget *pTree,283 const CheckIfSuitableBy &condition,284 CheckIfSuitableBy *pException = 0);285 /** Performs search for the @a pParentItem child which corresponds to the @a condition but not @a pException. */286 static UIMediumItem *searchItem(QTreeWidgetItem *pParentItem,287 const CheckIfSuitableBy &condition,288 CheckIfSuitableBy *pException = 0);289 290 /** Checks if @a action can be used for @a pItem. */291 static bool checkMediumFor(UIMediumItem *pItem, Action action);292 293 /** Casts passed QTreeWidgetItem @a pItem to UIMediumItem if possible. */294 static UIMediumItem *toMediumItem(QTreeWidgetItem *pItem);295 /** @} */296 297 /** @name General variables.298 * @{ */299 /** Holds the widget embedding type. */300 const EmbedTo m_enmEmbedding;301 302 /** Holds whether Virtual Media Manager should preserve current item change. */303 bool m_fPreventChangeCurrentItem;304 /** @} */305 306 /** @name Tab-widget variables.307 * @{ */308 /** Holds the tab-widget instance. */309 QTabWidget *m_pTabWidget;310 /** Holds the tab-widget tab-count. */311 const int m_iTabCount;312 /** Holds the map of tree-widget instances. */313 QMap<int, QITreeWidget*> m_trees;314 /** Holds whether hard-drive tab-widget have inaccessible item. */315 bool m_fInaccessibleHD;316 /** Holds whether optical-disk tab-widget have inaccessible item. */317 bool m_fInaccessibleCD;318 /** Holds whether floppy-disk tab-widget have inaccessible item. */319 bool m_fInaccessibleFD;320 /** Holds cached hard-drive tab-widget icon. */321 const QIcon m_iconHD;322 /** Holds cached optical-disk tab-widget icon. */323 const QIcon m_iconCD;324 /** Holds cached floppy-disk tab-widget icon. */325 const QIcon m_iconFD;326 /** Holds current hard-drive tree-view item ID. */327 QString m_strCurrentIdHD;328 /** Holds current optical-disk tree-view item ID. */329 QString m_strCurrentIdCD;330 /** Holds current floppy-disk tree-view item ID. */331 QString m_strCurrentIdFD;332 /** @} */333 334 /** @name Details-widget variables.335 * @{ */336 /** Holds the medium details-widget instance. */337 UIMediumDetailsWidget *m_pDetailsWidget;338 /** @} */339 340 /** @name Toolbar and menu variables.341 * @{ */342 /** Holds the toolbar widget instance. */343 UIToolBar *m_pToolBar;344 /** Holds the context-menu object instance. */345 QMenu *m_pContextMenu;346 /** Holds the menu object instance. */347 QMenu *m_pMenu;348 /** Holds the Add action instance. */349 QAction *m_pActionAdd;350 /** Holds the Copy action instance. */351 QAction *m_pActionCopy;352 /** Holds the Move action instance. */353 QAction *m_pActionMove;354 /** Holds the Remove action instance. */355 QAction *m_pActionRemove;356 /** Holds the Release action instance. */357 QAction *m_pActionRelease;358 /** Holds the Details action instance. */359 QAction *m_pActionDetails;360 /** Holds the Refresh action instance. */361 QAction *m_pActionRefresh;362 /** @} */363 364 /** @name Progress-bar variables.365 * @{ */366 /** Holds the progress-bar widget reference. */367 UIEnumerationProgressBar *m_pProgressBar;368 /** @} */369 };370 371 372 /** QIManagerDialogFactory extension used as a factory for Virtual Media Manager dialog. */373 class UIMediumManagerFactory : public QIManagerDialogFactory374 {375 protected:376 377 /** Creates derived @a pDialog instance.378 * @param pCenterWidget Brings the widget reference to center according to. */379 virtual void create(QIManagerDialog *&pDialog, QWidget *pCenterWidget) /* override */;380 };381 382 383 /** QIManagerDialog extension providing GUI with the dialog to control media related functionality. */384 class UIMediumManager : public QIWithRetranslateUI<QIManagerDialog>385 {386 46 Q_OBJECT; 387 47 388 48 signals: 389 49 390 /** Notifies listeners about data change rejected and should be reseted. */ 391 void sigDataChangeRejected(); 392 /** Notifies listeners about data change accepted and should be applied. */ 393 void sigDataChangeAccepted(); 50 public: 51 52 UIMediumSelector(KDeviceType deviceType, QWidget *pParent = 0, Qt::WindowFlags enmFlags = 0); 394 53 395 54 private slots: 396 55 397 /** @name Button-box stuff.398 * @{ */399 /** Handles button-box button click. */400 void sltHandleButtonBoxClick(QAbstractButton *pButton);401 /** @} */402 403 56 private: 404 57 405 /** Constructs Host Network Manager dialog.406 * @param pCenterWidget Brings the widget reference to center according to. */407 UIMediumManager(QWidget *pCenterWidget);408 58 409 59 /** @name Event-handling stuff. … … 416 66 * @{ */ 417 67 /** Configures all. */ 418 virtual void configure() /* override */; 419 /** Configures central-widget. */ 420 virtual void configureCentralWidget() /* override */; 421 /** Configures button-box. */ 422 virtual void configureButtonBox() /* override */; 68 void configure(); 69 void prepareWidgets(); 423 70 /** Perform final preparations. */ 424 v irtual void finalize() /* override */;71 void finalize(); 425 72 /** @} */ 426 73 427 /** @name Widget stuff.428 * @{ */429 /** Returns the widget. */430 virtual UIMediumManagerWidget *widget() /* override */;431 /** @} */432 74 433 /** @name Progress-bar variables. 434 * @{ */ 435 /** Holds the progress-bar widget instance. */ 436 UIEnumerationProgressBar *m_pProgressBar; 437 /** @} */ 438 439 /** Allow factory access to private/protected members: */ 440 friend class UIMediumManagerFactory; 75 QVBoxLayout *m_pMainLayout; 76 QITreeWidget *m_pTreeWidget; 441 77 }; 442 78 443 #endif /* !___UIMedium Manager_h___ */79 #endif /* !___UIMediumSelector_h___ */
Note:
See TracChangeset
for help on using the changeset viewer.