- Timestamp:
- Jan 7, 2019 12:15:00 PM (6 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 1 added
- 6 edited
- 11 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r76668 r76671 350 350 ./src/logviewer \ 351 351 ./src/medium \ 352 ./src/medium/viso \ 352 353 ./src/objects \ 353 354 ./src/platform \ … … 829 830 src/medium/UIMediumItem.h \ 830 831 src/medium/UIMediumSelector.h \ 832 src/medium/viso/UIVisoBrowserBase.h \ 833 src/medium/viso/UIVisoContentBrowser.h \ 834 src/medium/viso/UIVisoCreator.h \ 835 src/medium/viso/UIVisoCreatorOptionsDialog.h \ 836 src/medium/viso/UIVisoHostBrowser.h \ 831 837 src/runtime/UIConsoleEventHandler.h \ 832 838 src/runtime/UIFrameBuffer.h \ … … 1100 1106 src/globals/UIMessageCenter.h \ 1101 1107 src/globals/UIModalWindowManager.h \ 1108 src/globals/UIPathOperations.h \ 1102 1109 src/globals/UIPopupCenter.h \ 1103 1110 src/globals/UIProgressEventHandler.h \ … … 1120 1127 src/medium/UIMediumItem.h \ 1121 1128 src/medium/UIMediumSelector.h \ 1129 src/medium/viso/UIVisoBrowserBase.h \ 1130 src/medium/viso/UIVisoContentBrowser.h \ 1131 src/medium/viso/UIVisoCreator.h \ 1132 src/medium/viso/UIVisoCreatorOptionsDialog.h \ 1133 src/medium/viso/UIVisoHostBrowser.h \ 1122 1134 src/settings/UISettingsDialog.h \ 1123 1135 src/settings/UISettingsDialogSpecific.h \ … … 1239 1251 src/medium/UIMediumEnumerator.cpp \ 1240 1252 src/medium/UIMediumSelector.cpp \ 1253 src/medium/viso/UIVisoContentBrowser.cpp \ 1254 src/medium/viso/UIVisoHostBrowser.cpp \ 1241 1255 src/runtime/UIConsoleEventHandler.cpp \ 1242 1256 src/runtime/UIFrameBuffer.cpp \ … … 1328 1342 src/medium/UIMediumEnumerator.cpp \ 1329 1343 src/medium/UIMediumSelector.cpp \ 1344 src/medium/viso/UIVisoContentBrowser.cpp \ 1345 src/medium/viso/UIVisoHostBrowser.cpp \ 1330 1346 src/settings/global/UIGlobalSettingsExtension.cpp \ 1331 1347 src/settings/global/UIGlobalSettingsInput.cpp \ … … 1558 1574 src/medium/UIMediumItem.cpp \ 1559 1575 src/medium/UIMediumSelector.cpp \ 1576 src/medium/viso/UIVisoBrowserBase.cpp \ 1577 src/medium/viso/UIVisoContentBrowser.cpp \ 1578 src/medium/viso/UIVisoCreator.cpp \ 1579 src/medium/viso/UIVisoCreatorOptionsDialog.cpp \ 1580 src/medium/viso/UIVisoHostBrowser.cpp \ 1560 1581 src/objects/UIRichTextString.cpp \ 1561 1582 src/runtime/UIConsoleEventHandler.cpp \ … … 1902 1923 src/medium/UIMediumItem.cpp \ 1903 1924 src/medium/UIMediumSelector.cpp \ 1925 src/medium/viso/UIVisoBrowserBase.cpp \ 1926 src/medium/viso/UIVisoContentBrowser.cpp \ 1927 src/medium/viso/UIVisoCreator.cpp \ 1928 src/medium/viso/UIVisoCreatorOptionsDialog.cpp \ 1929 src/medium/viso/UIVisoHostBrowser.cpp \ 1904 1930 src/objects/UIRichTextString.cpp \ 1905 1931 src/settings/UISettingsDefs.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/globals/UICustomFileSystemModel.cpp
r76669 r76671 90 90 } 91 91 92 QList<const UICustomFileSystemItem*> UICustomFileSystemItem::children() const 93 { 94 QList<const UICustomFileSystemItem*> childList; 95 foreach (UICustomFileSystemItem *child, m_childItems) 96 childList << child; 97 return childList; 98 } 99 92 100 int UICustomFileSystemItem::columnCount() const 93 101 { 94 102 return m_itemData.count(); 95 96 103 } 97 104 -
trunk/src/VBox/Frontends/VirtualBox/src/globals/UICustomFileSystemModel.h
r76626 r76671 58 58 UICustomFileSystemItem *child(const QString &path) const; 59 59 int childCount() const; 60 QList<const UICustomFileSystemItem*> children() const; 60 61 int columnCount() const; 61 62 QVariant data(int column) const; -
trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
r76606 r76671 78 78 #include "UIVirtualBoxEventHandler.h" 79 79 #include "UIDesktopWidgetWatchdog.h" 80 #include "UIVisoCreator.h" 80 81 #ifdef VBOX_WS_X11 81 82 # include "UIHostComboEditor.h" … … 2711 2712 } 2712 2713 2714 QUuid VBoxGlobal::createVisoMediumWithVisoCreator(QWidget *pParent, const QString &strFolder) 2715 { 2716 2717 QWidget *pDialogParent = windowManager().realParentWindow(pParent); 2718 QPointer<UIVisoCreator> pVisoCreator = new UIVisoCreator(pDialogParent); 2719 2720 if (!pVisoCreator) 2721 return QString(); 2722 windowManager().registerNewParent(pVisoCreator, pDialogParent); 2723 2724 if (pVisoCreator->execute(true, false)) 2725 { 2726 QStringList files = pVisoCreator->pathList(); 2727 if (files.empty() || files[0].isEmpty()) 2728 return QUuid(); 2729 2730 /* Produce the VISO. */ 2731 char szVisoPath[RTPATH_MAX]; 2732 int vrc = RTPathJoin(szVisoPath, sizeof(szVisoPath), strFolder.toUtf8().constData(), "ad-hoc.viso"); 2733 if (RT_SUCCESS(vrc)) 2734 { 2735 PRTSTREAM pStrmViso; 2736 vrc = RTStrmOpen(szVisoPath, "w", &pStrmViso); 2737 if (RT_SUCCESS(vrc)) 2738 { 2739 RTUUID Uuid; 2740 vrc = RTUuidCreate(&Uuid); 2741 if (RT_SUCCESS(vrc)) 2742 { 2743 RTStrmPrintf(pStrmViso, "--iprt-iso-maker-file-marker-bourne-sh %RTuuid\n", &Uuid); 2744 2745 for (int iFile = 0; iFile < files.size(); iFile++) 2746 { 2747 QByteArray const utf8Name = files[iFile].toUtf8(); 2748 const char *apszArgv[2] = { utf8Name.constData(), NULL }; 2749 char *pszQuoted; 2750 vrc = RTGetOptArgvToString(&pszQuoted, apszArgv, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH); 2751 if (RT_SUCCESS(vrc)) 2752 { 2753 RTStrmPrintf(pStrmViso, "%s\n", pszQuoted); 2754 RTStrFree(pszQuoted); 2755 } 2756 else 2757 break; 2758 } 2759 2760 RTStrmFlush(pStrmViso); 2761 if (RT_SUCCESS(vrc)) 2762 vrc = RTStrmError(pStrmViso); 2763 } 2764 2765 RTStrmClose(pStrmViso); 2766 } 2767 } 2768 2769 /* Done. */ 2770 if (RT_SUCCESS(vrc)) 2771 { 2772 delete pVisoCreator; 2773 return openMedium(UIMediumDeviceType_DVD, QString(szVisoPath), pParent); 2774 } 2775 } 2776 delete pVisoCreator; 2777 return QUuid(); 2778 } 2779 2713 2780 QUuid VBoxGlobal::showCreateFloppyDiskDialog(QWidget *pParent, const QString &strMachineName, const QString &strMachineFolder) 2714 2781 { … … 2795 2862 "This is used for optical media")); 2796 2863 } 2864 2797 2865 2798 2866 /* Insert separator: */ … … 2958 3026 uMediumID = openMediumWithFileOpenDialog(target.mediumType, windowManager().mainWindowShown(), strMachineFolder); 2959 3027 else if(target.type == UIMediumTarget::UIMediumTargetType_CreateAdHocVISO) 2960 uMediumID = createVisoMediumWithFileOpenDialog(windowManager().mainWindowShown(), strMachineFolder); 3028 { 3029 //uMediumID = createVisoMediumWithFileOpenDialog(windowManager().mainWindowShown(), strMachineFolder); 3030 uMediumID = createVisoMediumWithVisoCreator(windowManager().mainWindowShown(), strMachineFolder); 3031 } 2961 3032 else if(target.type == UIMediumTarget::UIMediumTargetType_CreateFloppyDisk) 2962 3033 uMediumID = showCreateFloppyDiskDialog(windowManager().mainWindowShown(), comConstMachine.GetName(), strMachineFolder); -
trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.h
r76581 r76671 519 519 QUuid createVisoMediumWithFileOpenDialog(QWidget *pParent, const QString &strFolder); 520 520 521 /** Creates a VISO by using the VISO creator dialog. 522 * @param pParent Brings the dialog parent. 523 * @param strFolder Brings the folder to browse for VISO file contents. */ 524 QUuid createVisoMediumWithVisoCreator(QWidget *pParent, const QString &strFolder); 525 521 526 /** Creates and shows a dialog thru which user can create a new floppy disk a VISO using the file-open dialog. 522 527 * @param parent Passes the parent of the dialog, -
trunk/src/VBox/Frontends/VirtualBox/src/guestctrl/UIFileManagerTable.cpp
r76627 r76671 880 880 } 881 881 } 882 883 882 884 883 void UIFileManagerTable::sltCreateFileViewContextMenu(const QPoint &point) -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoBrowserBase.cpp
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelectorclass implementation.3 * VBox Qt GUI - UIVisoBrowserBase class implementation. 4 4 */ 5 5 … … 17 17 18 18 /* Qt includes: */ 19 #include <QAction>20 19 #include <QHeaderView> 20 #include <QGridLayout> 21 #include <QLabel> 22 #include <QSplitter> 23 #include <QTableView> 24 #include <QTreeView> 21 25 #include <QVBoxLayout> 22 #include <QPushButton>23 26 24 27 /* GUI includes: */ 25 #include "QIComboBox.h"26 #include "QIDialogButtonBox.h"27 #include "QIFileDialog.h"28 #include "QILineEdit.h"29 #include "QIMessageBox.h"30 #include "QITabWidget.h"31 28 #include "QIToolButton.h" 32 #include "VBoxGlobal.h" 33 #include "UIDesktopWidgetWatchdog.h" 34 #include "UIExtraDataManager.h" 35 #include "UIFDCreationDialog.h" 36 #include "UIMediumSelector.h" 37 #include "UIMessageCenter.h" 38 #include "UIIconPool.h" 39 #include "UIMedium.h" 40 #include "UIMediumItem.h" 41 #include "UIToolBar.h" 42 43 /* COM includes: */ 44 #include "COMEnums.h" 45 #include "CMachine.h" 46 #include "CMediumAttachment.h" 47 #include "CMediumFormat.h" 48 #include "CStorageController.h" 49 #include "CSystemProperties.h" 50 51 #ifdef VBOX_WS_MAC 52 # include "UIWindowMenuManager.h" 53 #endif /* VBOX_WS_MAC */ 29 #include "UIVisoBrowserBase.h" 54 30 55 31 56 class UIMediumSearchWidget : public QWidget 32 UIVisoBrowserBase::UIVisoBrowserBase(QWidget *pParent) 33 : QWidget(pParent) 34 , m_pTreeView(0) 35 , m_pTableView(0) 36 , m_pTitleLabel(0) 37 , m_pAddRemoveButton(0) 38 , m_pRightContainerWidget(0) 39 , m_pRightContainerLayout(0) 40 , m_pMainLayout(0) 41 , m_pHorizontalSplitter(0) 57 42 { 58 Q_OBJECT;59 60 public:61 62 enum SearchType63 {64 SearchByName,65 SearchByUUID,66 SearchByMax67 };68 69 signals:70 71 void sigSearchTypeChanged(int newType);72 void sigSearchTermChanged(QString searchTerm);73 74 public:75 76 UIMediumSearchWidget(QWidget *pParent = 0);77 SearchType searchType() const;78 QString searchTerm() const;79 80 private:81 82 void prepareWidgets();83 QIComboBox *m_pSearchComboxBox;84 QLineEdit *m_pSearchTermLineEdit;85 };86 87 88 /*********************************************************************************************************************************89 * UIMediumSearchWidget implementation. *90 *********************************************************************************************************************************/91 92 UIMediumSearchWidget::UIMediumSearchWidget(QWidget *pParent)93 :QWidget(pParent)94 , m_pSearchComboxBox(0)95 , m_pSearchTermLineEdit(0)96 {97 prepareWidgets();98 43 } 99 44 100 void UIMediumSearchWidget::prepareWidgets()45 UIVisoBrowserBase::~UIVisoBrowserBase() 101 46 { 102 QHBoxLayout *pLayout = new QHBoxLayout; 103 setLayout(pLayout); 104 pLayout->setContentsMargins(0, 0, 0, 0); 105 pLayout->setSpacing(0); 47 } 106 48 107 m_pSearchComboxBox = new QIComboBox; 108 if (m_pSearchComboxBox) 49 void UIVisoBrowserBase::prepareObjects() 50 { 51 m_pMainLayout = new QGridLayout; 52 setLayout(m_pMainLayout); 53 54 QWidget *pLeftContainerWidget = new QWidget; 55 m_pRightContainerWidget = new QWidget; 56 57 QVBoxLayout *pLeftContainerLayout = new QVBoxLayout; 58 m_pRightContainerLayout = new QGridLayout; 59 60 pLeftContainerLayout->setSpacing(1); 61 pLeftContainerLayout->setContentsMargins(0, 0, 0, 0); 62 m_pRightContainerLayout->setSpacing(1); 63 m_pRightContainerLayout->setContentsMargins(0, 0, 0, 0); 64 65 if (!m_pMainLayout || !pLeftContainerLayout || !m_pRightContainerLayout) 66 return; 67 if (!pLeftContainerWidget || !m_pRightContainerWidget) 68 return; 69 70 pLeftContainerWidget->setLayout(pLeftContainerLayout); 71 m_pRightContainerWidget->setLayout(m_pRightContainerLayout); 72 73 m_pHorizontalSplitter = new QSplitter; 74 if (!m_pHorizontalSplitter) 75 return; 76 77 m_pMainLayout->addWidget(m_pHorizontalSplitter, 1, 0); 78 m_pHorizontalSplitter->setOrientation(Qt::Horizontal); 79 m_pHorizontalSplitter->setHandleWidth(2); 80 81 m_pTitleLabel = new QLabel; 82 if (m_pTitleLabel) 109 83 { 110 m_pSearchComboxBox->setEditable(false); 111 m_pSearchComboxBox->insertItem(SearchByName, "Search By Name"); 112 m_pSearchComboxBox->insertItem(SearchByUUID, "Search By UUID"); 113 pLayout->addWidget(m_pSearchComboxBox); 114 115 connect(m_pSearchComboxBox, static_cast<void(QIComboBox::*)(int)>(&QIComboBox::currentIndexChanged), 116 this, &UIMediumSearchWidget::sigSearchTypeChanged); 117 84 pLeftContainerLayout->addWidget(m_pTitleLabel); 118 85 } 119 86 120 m_p SearchTermLineEdit = new QLineEdit;121 if (m_p SearchTermLineEdit)87 m_pTreeView = new QTreeView; 88 if (m_pTreeView) 122 89 { 123 m_pSearchTermLineEdit->setClearButtonEnabled(true); 124 pLayout->addWidget(m_pSearchTermLineEdit); 125 connect(m_pSearchTermLineEdit, &QILineEdit::textChanged, 126 this, &UIMediumSearchWidget::sigSearchTermChanged); 90 pLeftContainerLayout->addWidget(m_pTreeView); 91 m_pTreeView->setSelectionMode(QAbstractItemView::SingleSelection); 92 m_pTreeView->setAlternatingRowColors(true); 93 m_pTreeView->header()->hide(); 94 m_pTreeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); 95 } 96 97 m_pTableView = new QTableView; 98 if (m_pTableView) 99 { 100 m_pRightContainerLayout->addWidget(m_pTableView, 0, 0, 4, 4); 101 m_pTableView->setSelectionMode(QAbstractItemView::ContiguousSelection); 102 m_pTableView->setShowGrid(false); 103 m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows); 104 m_pTableView->setEditTriggers(QAbstractItemView::NoEditTriggers); 105 m_pTableView->setAlternatingRowColors(true); 106 QHeaderView *pVerticalHeader = m_pTableView->verticalHeader(); 107 if (pVerticalHeader) 108 { 109 m_pTableView->verticalHeader()->setVisible(false); 110 /* Minimize the row height: */ 111 m_pTableView->verticalHeader()->setDefaultSectionSize(m_pTableView->verticalHeader()->minimumSectionSize()); 112 } 113 QHeaderView *pHorizontalHeader = m_pTableView->horizontalHeader(); 114 if (pHorizontalHeader) 115 { 116 pHorizontalHeader->setHighlightSections(false); 117 pHorizontalHeader->setSectionResizeMode(QHeaderView::Stretch); 118 } 119 } 120 121 m_pAddRemoveButton = new QIToolButton; 122 if (m_pAddRemoveButton) 123 { 124 m_pRightContainerLayout->addWidget(m_pAddRemoveButton, 0, 5, 1, 1); 125 m_pAddRemoveButton->setEnabled(false); 126 } 127 128 m_pHorizontalSplitter->addWidget(pLeftContainerWidget); 129 m_pHorizontalSplitter->addWidget(m_pRightContainerWidget); 130 m_pHorizontalSplitter->setCollapsible(m_pHorizontalSplitter->indexOf(pLeftContainerWidget), false); 131 m_pHorizontalSplitter->setCollapsible(m_pHorizontalSplitter->indexOf(m_pRightContainerWidget), false); 132 m_pHorizontalSplitter->setStretchFactor(0, 1); 133 m_pHorizontalSplitter->setStretchFactor(1, 3); 134 } 135 136 void UIVisoBrowserBase::prepareConnections() 137 { 138 if (m_pTableView) 139 connect(m_pTableView, &QTableView::doubleClicked, 140 this, &UIVisoBrowserBase::sltHandleTableViewItemDoubleClick); 141 if (m_pTreeView) 142 { 143 connect(m_pTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, 144 this, &UIVisoBrowserBase::sltHandleTreeSelectionChanged); 145 connect(m_pTreeView, &QTreeView::clicked, 146 this, &UIVisoBrowserBase::sltHandleTreeItemClicked); 127 147 } 128 148 } 129 149 130 UIMediumSearchWidget::SearchType UIMediumSearchWidget::searchType() const 150 void UIVisoBrowserBase::sltHandleTableViewItemDoubleClick(const QModelIndex &index) 131 151 { 132 if (!m_pSearchComboxBox || m_pSearchComboxBox->currentIndex() >= static_cast<int>(SearchByMax)) 133 return SearchByMax; 134 return static_cast<SearchType>(m_pSearchComboxBox->currentIndex()); 152 tableViewItemDoubleClick(index); 135 153 } 136 154 137 QString UIMediumSearchWidget::searchTerm() const 155 void UIVisoBrowserBase::sltHandleTreeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) 138 156 { 139 if (!m_pSearchTermLineEdit) 140 return QString(); 141 return m_pSearchTermLineEdit->text(); 157 if (!m_pTableView) 158 return; 159 Q_UNUSED(deselected); 160 QModelIndexList indices = selected.indexes(); 161 if (indices.empty()) 162 return; 163 QModelIndex selectedIndex = indices[0]; 164 treeSelectionChanged(selectedIndex); 165 } 166 167 void UIVisoBrowserBase::sltHandleTreeItemClicked(const QModelIndex &modelIndex) 168 { 169 if (!m_pTreeView) 170 return; 171 m_pTreeView->setExpanded(modelIndex, true); 142 172 } 143 173 144 174 145 UIMediumSelector::UIMediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName /* = QString() */, 146 const QString &machineSettigFilePath /* = QString() */, QWidget *pParent /* = 0 */) 147 :QIWithRetranslateUI<QIDialog>(pParent) 148 , m_pMainLayout(0) 149 , m_pTreeWidget(0) 150 , m_enmMediumType(enmMediumType) 151 , m_pButtonBox(0) 152 , m_pToolBar(0) 153 , m_pActionAdd(0) 154 , m_pActionCreate(0) 155 , m_pActionRefresh(0) 156 , m_pAttachedSubTreeRoot(0) 157 , m_pNotAttachedSubTreeRoot(0) 158 , m_pParent(pParent) 159 , m_pSearchWidget(0) 160 , m_strMachineSettingsFilePath(machineSettigFilePath) 161 , m_strMachineName(machineName) 162 { 163 configure(); 164 finalize(); 165 } 166 167 QList<QUuid> UIMediumSelector::selectedMediumIds() const 168 { 169 QList<QUuid> selectedIds; 170 if (!m_pTreeWidget) 171 return selectedIds; 172 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 173 for (int i = 0; i < selectedItems.size(); ++i) 174 { 175 UIMediumItem *item = dynamic_cast<UIMediumItem*>(selectedItems.at(i)); 176 if (item) 177 selectedIds.push_back(item->medium().id()); 178 } 179 return selectedIds; 180 } 181 182 183 void UIMediumSelector::retranslateUi() 184 { 185 if (m_pActionAdd) 186 { 187 m_pActionAdd->setText(tr("&Add...")); 188 m_pActionAdd->setToolTip(tr("Add Disk Image")); 189 m_pActionAdd->setStatusTip(tr("Add existing disk image file")); 190 } 191 192 if (m_pActionCreate) 193 { 194 m_pActionCreate->setText(tr("&Create...")); 195 m_pActionCreate->setToolTip(tr("Create Disk Image")); 196 m_pActionCreate->setStatusTip(tr("Create new disk image file")); 197 } 198 199 if (m_pActionRefresh) 200 { 201 m_pActionRefresh->setText(tr("&Refresh")); 202 m_pActionRefresh->setToolTip(tr("Refresh Disk Image Files (%1)").arg(m_pActionRefresh->shortcut().toString())); 203 m_pActionRefresh->setStatusTip(tr("Refresh the list of disk image files")); 204 } 205 206 if (m_pButtonBox) 207 m_pButtonBox->button(QDialogButtonBox::Ok)->setText(tr("Choose")); 208 209 if (m_pTreeWidget) 210 { 211 m_pTreeWidget->headerItem()->setText(0, tr("Name")); 212 m_pTreeWidget->headerItem()->setText(1, tr("Virtual Size")); 213 m_pTreeWidget->headerItem()->setText(2, tr("Actual Size")); 214 } 215 } 216 217 void UIMediumSelector::configure() 218 { 219 /* Apply window icons: */ 220 setWindowIcon(UIIconPool::iconSetFull(":/media_manager_32px.png", ":/media_manager_16px.png")); 221 prepareActions(); 222 prepareWidgets(); 223 prepareConnections(); 224 } 225 226 void UIMediumSelector::prepareActions() 227 { 228 QString strPrefix("hd"); 229 switch (m_enmMediumType) 230 { 231 case UIMediumDeviceType_DVD: 232 strPrefix = "cd"; 233 break; 234 case UIMediumDeviceType_Floppy: 235 strPrefix = "fd"; 236 break; 237 case UIMediumDeviceType_HardDisk: 238 case UIMediumDeviceType_All: 239 case UIMediumDeviceType_Invalid: 240 default: 241 strPrefix = "hd"; 242 break; 243 } 244 245 m_pActionAdd = new QAction(this); 246 if (m_pActionAdd) 247 { 248 /* Configure add-action: */ 249 m_pActionAdd->setShortcut(QKeySequence("Ctrl+A")); 250 251 m_pActionAdd->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix), 252 QString(":/%1_add_16px.png").arg(strPrefix), 253 QString(":/%1_add_disabled_32px.png").arg(strPrefix), 254 QString(":/%1_add_disabled_16px.png").arg(strPrefix))); 255 } 256 257 /* Currently create is supported only for Floppy: */ 258 if (m_enmMediumType == UIMediumDeviceType_Floppy) 259 { 260 m_pActionCreate = new QAction(this); 261 } 262 if (m_pActionCreate) 263 { 264 265 m_pActionCreate->setShortcut(QKeySequence("Ctrl+C")); 266 m_pActionCreate->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix), 267 QString(":/%1_add_16px.png").arg(strPrefix), 268 QString(":/%1_add_disabled_32px.png").arg(strPrefix), 269 QString(":/%1_add_disabled_16px.png").arg(strPrefix))); 270 } 271 272 273 m_pActionRefresh = new QAction(this); 274 if (m_pActionRefresh) 275 { 276 m_pActionRefresh->setShortcut(QKeySequence(QKeySequence::Refresh)); 277 if (m_pActionRefresh && m_pActionRefresh->icon().isNull()) 278 m_pActionRefresh->setIcon(UIIconPool::iconSetFull(":/refresh_32px.png", ":/refresh_16px.png", 279 ":/refresh_disabled_32px.png", ":/refresh_disabled_16px.png")); 280 } 281 } 282 283 void UIMediumSelector::prepareConnections() 284 { 285 /* Configure medium-enumeration connections: */ 286 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationStarted, 287 this, &UIMediumSelector::sltHandleMediumEnumerationStart); 288 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerated, 289 this, &UIMediumSelector::sltHandleMediumEnumerated); 290 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationFinished, 291 this, &UIMediumSelector::sltHandleMediumEnumerationFinish); 292 if (m_pActionAdd) 293 connect(m_pActionAdd, &QAction::triggered, this, &UIMediumSelector::sltAddMedium); 294 if (m_pActionCreate) 295 connect(m_pActionCreate, &QAction::triggered, this, &UIMediumSelector::sltCreateMedium); 296 if (m_pActionRefresh) 297 connect(m_pActionRefresh, &QAction::triggered, this, &UIMediumSelector::sltHandleRefresh); 298 299 if (m_pTreeWidget) 300 { 301 connect(m_pTreeWidget, &QITreeWidget::itemSelectionChanged, this, &UIMediumSelector::sltHandleItemSelectionChanged); 302 connect(m_pTreeWidget, &QITreeWidget::itemDoubleClicked, this, &UIMediumSelector::sltHandleTreeWidgetDoubleClick); 303 } 304 305 if (m_pButtonBox) 306 { 307 connect(m_pButtonBox, &QIDialogButtonBox::rejected, this, &UIMediumSelector::close); 308 connect(m_pButtonBox, &QIDialogButtonBox::accepted, this, &UIMediumSelector::accept); 309 } 310 311 if (m_pSearchWidget) 312 { 313 connect(m_pSearchWidget, &UIMediumSearchWidget::sigSearchTypeChanged, 314 this, &UIMediumSelector::sltHandleSearchTypeChange); 315 connect(m_pSearchWidget, &UIMediumSearchWidget::sigSearchTermChanged, 316 this, &UIMediumSelector::sltHandleSearchTermChange); 317 } 318 } 319 320 UIMediumItem* UIMediumSelector::addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent) 321 { 322 if (!pParent) 323 return 0; 324 switch (m_enmMediumType) 325 { 326 case UIMediumDeviceType_DVD: 327 return new UIMediumItemCD(medium, pParent); 328 break; 329 case UIMediumDeviceType_Floppy: 330 return new UIMediumItemFD(medium, pParent); 331 break; 332 case UIMediumDeviceType_HardDisk: 333 case UIMediumDeviceType_All: 334 case UIMediumDeviceType_Invalid: 335 default: 336 return createHardDiskItem(medium, pParent); 337 break; 338 } 339 } 340 341 UIMediumItem* UIMediumSelector::createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent) 342 { 343 if (medium.medium().isNull()) 344 return 0; 345 if (!m_pTreeWidget) 346 return 0; 347 /* Search the tree to see if we already have the item: */ 348 UIMediumItem *pMediumItem = searchItem(0, medium.id()); 349 if (pMediumItem) 350 return pMediumItem; 351 /* Check if the corresponding medium has a parent */ 352 if (medium.parentID() != UIMedium::nullID()) 353 { 354 UIMediumItem *pParentMediumItem = searchItem(0, medium.parentID()); 355 /* If parent medium-item was not found we create it: */ 356 if (!pParentMediumItem) 357 { 358 /* Make sure corresponding parent medium is already cached! */ 359 UIMedium parentMedium = vboxGlobal().medium(medium.parentID()); 360 if (parentMedium.isNull()) 361 AssertMsgFailed(("Parent medium with ID={%s} was not found!\n", medium.parentID().toString().toUtf8().constData())); 362 /* Try to create parent medium-item: */ 363 else 364 pParentMediumItem = createHardDiskItem(parentMedium, pParent); 365 } 366 if (pParentMediumItem) 367 { 368 pMediumItem = new UIMediumItemHD(medium, pParentMediumItem); 369 LogRel2(("UIMediumManager: Child hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData())); 370 } 371 else 372 AssertMsgFailed(("Parent medium with ID={%s} could not be created!\n", medium.parentID().toString().toUtf8().constData())); 373 } 374 375 /* No parents, thus just create item as top-level one: */ 376 else 377 { 378 pMediumItem = new UIMediumItemHD(medium, pParent); 379 LogRel2(("UIMediumManager: Root hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData())); 380 } 381 return pMediumItem; 382 } 383 384 void UIMediumSelector::restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList) 385 { 386 if (!m_pTreeWidget) 387 return; 388 if (selectedMediums.isEmpty()) 389 { 390 m_pTreeWidget->setCurrentItem(0); 391 return; 392 } 393 bool selected = false; 394 for (int i = 0; i < mediumList.size(); ++i) 395 { 396 if (!mediumList[i]) 397 continue; 398 if (selectedMediums.contains(mediumList[i]->medium().id())) 399 { 400 mediumList[i]->setSelected(true); 401 selected = true; 402 } 403 } 404 405 if (!selected) 406 m_pTreeWidget->setCurrentItem(0); 407 return; 408 } 409 410 void UIMediumSelector::prepareWidgets() 411 { 412 m_pMainLayout = new QVBoxLayout; 413 if (!m_pMainLayout) 414 return; 415 416 setLayout(m_pMainLayout); 417 418 m_pToolBar = new UIToolBar(parentWidget()); 419 if (m_pToolBar) 420 { 421 /* Configure toolbar: */ 422 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize)); 423 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric)); 424 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 425 /* Add toolbar actions: */ 426 if (m_pActionAdd) 427 m_pToolBar->addAction(m_pActionAdd); 428 if (m_pActionCreate) 429 m_pToolBar->addAction(m_pActionCreate); 430 if (m_pActionRefresh) 431 m_pToolBar->addAction(m_pActionRefresh); 432 433 m_pMainLayout->addWidget(m_pToolBar); 434 } 435 436 m_pTreeWidget = new QITreeWidget; 437 if (m_pTreeWidget) 438 { 439 m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); 440 m_pMainLayout->addWidget(m_pTreeWidget); 441 m_pTreeWidget->setAlternatingRowColors(true); 442 int iColumnCount = (m_enmMediumType == UIMediumDeviceType_HardDisk) ? 3 : 2; 443 m_pTreeWidget->setColumnCount(iColumnCount); 444 m_pTreeWidget->setSortingEnabled(true); 445 m_pTreeWidget->sortItems(0, Qt::AscendingOrder); 446 } 447 448 m_pSearchWidget = new UIMediumSearchWidget; 449 if (m_pSearchWidget) 450 { 451 m_pMainLayout->addWidget(m_pSearchWidget); 452 } 453 454 m_pButtonBox = new QIDialogButtonBox; 455 if (m_pButtonBox) 456 { 457 /* Configure button-box: */ 458 m_pButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); 459 m_pButtonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::Key_Escape); 460 461 /* Add button-box into main layout: */ 462 m_pMainLayout->addWidget(m_pButtonBox); 463 } 464 465 repopulateTreeWidget(); 466 } 467 468 void UIMediumSelector::sltAddMedium() 469 { 470 QString strDefaultMachineFolder = vboxGlobal().virtualBox().GetSystemProperties().GetDefaultMachineFolder(); 471 QUuid uMediumID = vboxGlobal().openMediumWithFileOpenDialog(m_enmMediumType, this, strDefaultMachineFolder); 472 if (uMediumID.isNull()) 473 return; 474 repopulateTreeWidget(); 475 selectMedium(uMediumID); 476 477 } 478 479 void UIMediumSelector::sltCreateMedium() 480 { 481 QString strMachineFolder = QFileInfo(m_strMachineSettingsFilePath).absolutePath(); 482 UIFDCreationDialog *pDialog = new UIFDCreationDialog(this, m_strMachineName, strMachineFolder); 483 if (pDialog->exec()) 484 { 485 repopulateTreeWidget(); 486 selectMedium(pDialog->mediumID()); 487 } 488 delete pDialog; 489 } 490 491 void UIMediumSelector::sltHandleItemSelectionChanged() 492 { 493 updateOkButton(); 494 } 495 496 void UIMediumSelector::sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column) 497 { 498 Q_UNUSED(column); 499 if (!dynamic_cast<UIMediumItem*>(item)) 500 return; 501 accept(); 502 } 503 504 505 void UIMediumSelector::sltHandleMediumEnumerationStart() 506 { 507 /* Disable controls. Left Alone button box 'Ok' button. it is handle by tree population: */ 508 if (m_pActionRefresh) 509 m_pActionRefresh->setEnabled(false); 510 } 511 512 void UIMediumSelector::sltHandleMediumEnumerated() 513 { 514 } 515 516 void UIMediumSelector::sltHandleMediumEnumerationFinish() 517 { 518 repopulateTreeWidget(); 519 if (m_pActionRefresh) 520 m_pActionRefresh->setEnabled(true); 521 } 522 523 void UIMediumSelector::sltHandleRefresh() 524 { 525 /* Initialize media enumation: */ 526 vboxGlobal().startMediumEnumeration(); 527 } 528 529 void UIMediumSelector::sltHandleSearchTypeChange(int type) 530 { 531 Q_UNUSED(type); 532 performMediumSearch(); 533 } 534 535 void UIMediumSelector::sltHandleSearchTermChange(QString searchTerm) 536 { 537 Q_UNUSED(searchTerm); 538 performMediumSearch(); 539 } 540 541 void UIMediumSelector::selectMedium(const QUuid &uMediumID) 542 { 543 if (!m_pTreeWidget) 544 return; 545 UIMediumItem *pMediumItem = searchItem(0, uMediumID); 546 if (pMediumItem) 547 { 548 m_pTreeWidget->setCurrentItem(pMediumItem); 549 550 } 551 } 552 553 void UIMediumSelector::updateOkButton() 554 { 555 556 if (!m_pTreeWidget || !m_pButtonBox || !m_pButtonBox->button(QDialogButtonBox::Ok)) 557 return; 558 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 559 if (selectedItems.isEmpty()) 560 { 561 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); 562 return; 563 } 564 565 /* check if at least one of the selected items is a UIMediumItem */ 566 bool mediumItemSelected = false; 567 for (int i = 0; i < selectedItems.size() && !mediumItemSelected; ++i) 568 { 569 if (dynamic_cast<UIMediumItem*>(selectedItems.at(i))) 570 mediumItemSelected = true; 571 } 572 if (mediumItemSelected) 573 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(true); 574 else 575 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); 576 } 577 578 void UIMediumSelector::finalize() 579 { 580 /* Apply language settings: */ 581 retranslateUi(); 582 } 583 584 void UIMediumSelector::showEvent(QShowEvent *pEvent) 585 { 586 Q_UNUSED(pEvent); 587 588 /* Try to determine the initial size: */ 589 QSize proposedSize; 590 int iHostScreen = 0; 591 if (m_pParent) 592 iHostScreen = gpDesktop->screenNumber(m_pParent); 593 else 594 iHostScreen = gpDesktop->screenNumber(this); 595 if (iHostScreen >= 0 && iHostScreen < gpDesktop->screenCount()) 596 { 597 /* On the basis of current host-screen geometry if possible: */ 598 const QRect screenGeometry = gpDesktop->screenGeometry(iHostScreen); 599 if (screenGeometry.isValid()) 600 proposedSize = screenGeometry.size() * 5 / 15; 601 } 602 /* Fallback to default size if we failed: */ 603 if (proposedSize.isNull()) 604 proposedSize = QSize(800, 600); 605 /* Resize to initial size: */ 606 resize(proposedSize); 607 608 if (m_pParent) 609 VBoxGlobal::centerWidget(this, m_pParent, false); 610 611 } 612 613 void UIMediumSelector::repopulateTreeWidget() 614 { 615 if (!m_pTreeWidget) 616 return; 617 /* Cache the currently selected items: */ 618 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 619 QList<QUuid> selectedMedia = selectedMediumIds(); 620 /* uuid list of selected items: */ 621 /* Reset the related data structure: */ 622 m_mediumItemList.clear(); 623 m_pTreeWidget->clear(); 624 m_pAttachedSubTreeRoot = 0; 625 m_pNotAttachedSubTreeRoot = 0; 626 QVector<UIMediumItem*> menuItemVector; 627 628 foreach (const QUuid &uMediumID, vboxGlobal().mediumIDs()) 629 { 630 UIMedium medium = vboxGlobal().medium(uMediumID); 631 //printf("name %s\n", qPrintable(medium.name())); 632 if (medium.type() == m_enmMediumType) 633 { 634 bool isMediumAttached = !(medium.medium().GetMachineIds().isEmpty()); 635 QITreeWidgetItem *pParent = 0; 636 if (isMediumAttached) 637 { 638 if (!m_pAttachedSubTreeRoot) 639 { 640 QStringList strList; 641 strList << "Attached"; 642 m_pAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList); 643 } 644 pParent = m_pAttachedSubTreeRoot; 645 646 } 647 else 648 { 649 if (!m_pNotAttachedSubTreeRoot) 650 { 651 QStringList strList; 652 strList << "Not Attached"; 653 m_pNotAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList); 654 } 655 pParent = m_pNotAttachedSubTreeRoot; 656 } 657 UIMediumItem *treeItem = addTreeItem(medium, pParent); 658 m_mediumItemList.append(treeItem); 659 menuItemVector.push_back(treeItem); 660 } 661 } 662 restoreSelection(selectedMedia, menuItemVector); 663 saveDefaultForeground(); 664 updateOkButton(); 665 if (m_pAttachedSubTreeRoot) 666 m_pTreeWidget->expandItem(m_pAttachedSubTreeRoot); 667 668 if (m_pNotAttachedSubTreeRoot) 669 m_pTreeWidget->expandItem(m_pNotAttachedSubTreeRoot); 670 671 m_pTreeWidget->resizeColumnToContents(0); 672 performMediumSearch(); 673 } 674 675 void UIMediumSelector::saveDefaultForeground() 676 { 677 if (!m_pTreeWidget) 678 return; 679 if (m_defaultItemForeground == QBrush() && m_pTreeWidget->topLevelItemCount() >= 1) 680 { 681 QTreeWidgetItem *item = m_pTreeWidget->topLevelItem(0); 682 if (item) 683 { 684 QVariant data = item->data(0, Qt::ForegroundRole); 685 if (data.canConvert<QBrush>()) 686 { 687 m_defaultItemForeground = data.value<QBrush>(); 688 } 689 } 690 } 691 } 692 693 UIMediumItem* UIMediumSelector::searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId) 694 { 695 if (!m_pTreeWidget) 696 return 0; 697 if (!pParent) 698 { 699 pParent = m_pTreeWidget->invisibleRootItem(); 700 } 701 if (!pParent) 702 return 0; 703 704 for (int i = 0; i < pParent->childCount(); ++i) 705 { 706 QTreeWidgetItem *pChild = pParent->child(i); 707 if (!pChild) 708 continue; 709 UIMediumItem *mediumItem = dynamic_cast<UIMediumItem*>(pChild); 710 if (mediumItem) 711 { 712 if (mediumItem->id() == mediumId) 713 { 714 return mediumItem; 715 } 716 } 717 UIMediumItem *pResult = searchItem(pChild, mediumId); 718 if (pResult) 719 return pResult; 720 } 721 return 0; 722 } 723 724 void UIMediumSelector::performMediumSearch() 725 { 726 if (!m_pSearchWidget || !m_pTreeWidget) 727 return; 728 /* Unmark all tree items to remove the highltights: */ 729 for (int i = 0; i < m_mediumItemList.size(); ++i) 730 { 731 for (int j = 0; j < m_pTreeWidget->columnCount(); ++j) 732 { 733 if (m_mediumItemList[i]) 734 m_mediumItemList[i]->setData(j, Qt::ForegroundRole, m_defaultItemForeground); 735 } 736 } 737 738 739 UIMediumSearchWidget::SearchType searchType = 740 m_pSearchWidget->searchType(); 741 if (searchType >= UIMediumSearchWidget::SearchByMax) 742 return; 743 QString strTerm = m_pSearchWidget->searchTerm(); 744 if (strTerm.isEmpty()) 745 return; 746 747 for (int i = 0; i < m_mediumItemList.size(); ++i) 748 { 749 if (!m_mediumItemList[i]) 750 continue; 751 QString strMedium; 752 if (searchType == UIMediumSearchWidget::SearchByName) 753 strMedium = m_mediumItemList[i]->medium().name(); 754 else if(searchType == UIMediumSearchWidget::SearchByUUID) 755 strMedium = m_mediumItemList[i]->medium().id().toString(); 756 if (strMedium.isEmpty()) 757 continue; 758 if (strMedium.contains(strTerm, Qt::CaseInsensitive)) 759 { 760 // mark the item 761 for (int j = 0; j < m_pTreeWidget->columnCount(); ++j) 762 m_mediumItemList[i]->setData(j, Qt::ForegroundRole, QBrush(QColor(255, 0, 0))); 763 } 764 } 765 } 766 767 #include "UIMediumSelector.moc" 175 //#include "UIVisoBrowserBase.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoBrowserBase.h
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelectorclass declaration.3 * VBox Qt GUI - UIVisoBrowserBase class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h19 #define FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h18 #ifndef FEQT_INCLUDED_SRC_medium_viso_UIVisoBrowserBase_h 19 #define FEQT_INCLUDED_SRC_medium_viso_UIVisoBrowserBase_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once 22 22 #endif 23 23 24 /* GUI includes: */ 25 #include "QIDialog.h" 26 #include "QIWithRetranslateUI.h" 27 #include "UIMedium.h" 28 #include "UIMediumDefs.h" 29 #include "UIMediumDetailsWidget.h" 24 /* Qt includes: */ 25 #include <QModelIndex> 26 #include <QWidget> 30 27 31 28 /* Forward declarations: */ 32 class Q Action;33 class Q TreeWidgetItem;34 class Q ITreeWidget;35 class Q ITreeWidgetItem;29 class QItemSelection; 30 class QGridLayout; 31 class QLabel; 32 class QSplitter; 36 33 class QVBoxLayout; 37 class QIDialogButtonBox; 38 class UIMediumItem; 39 class UIMediumSearchWidget; 40 class UIToolBar; 34 class QTableView; 35 class QTreeView; 36 class QIToolButton; 41 37 42 43 /** QIDialog extension providing GUI with a dialog to select an existing medium. */ 44 class SHARED_LIBRARY_STUFF UIMediumSelector : public QIWithRetranslateUI<QIDialog> 38 class UIVisoBrowserBase : public QWidget 45 39 { 46 47 40 Q_OBJECT; 48 49 signals:50 41 51 42 public: 52 43 53 UI MediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName = QString(),54 const QString &machineSettigFilePath = QString(), QWidget *pParent = 0);55 QList<QUuid> selectedMediumIds() const;44 UIVisoBrowserBase(QWidget *pParent = 0); 45 ~UIVisoBrowserBase(); 46 virtual void showHideHiddenObjects(bool bShow) = 0; 56 47 57 48 protected: 58 49 59 void showEvent(QShowEvent *pEvent); 50 void prepareObjects(); 51 void prepareConnections(); 52 53 virtual void tableViewItemDoubleClick(const QModelIndex &index) = 0; 54 virtual void treeSelectionChanged(const QModelIndex &selectedTreeIndex) = 0; 55 virtual void setTableRootIndex(QModelIndex index = QModelIndex()) = 0; 56 virtual void setTreeCurrentIndex(QModelIndex index = QModelIndex()) = 0; 57 58 59 QTreeView *m_pTreeView; 60 QTableView *m_pTableView; 61 QLabel *m_pTitleLabel; 62 QIToolButton *m_pAddRemoveButton; 63 QWidget *m_pRightContainerWidget; 64 QGridLayout *m_pRightContainerLayout; 65 66 private: 67 QGridLayout *m_pMainLayout; 68 QSplitter *m_pHorizontalSplitter; 60 69 61 70 private slots: 62 63 void sltAddMedium(); 64 void sltCreateMedium(); 65 void sltHandleItemSelectionChanged(); 66 void sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column); 67 void sltHandleMediumEnumerationStart(); 68 void sltHandleMediumEnumerated(); 69 void sltHandleMediumEnumerationFinish(); 70 void sltHandleRefresh(); 71 void sltHandleSearchTypeChange(int type); 72 void sltHandleSearchTermChange(QString searchTerm); 71 void sltHandleTableViewItemDoubleClick(const QModelIndex &index); 72 void sltHandleTreeSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); 73 void sltHandleTreeItemClicked(const QModelIndex &modelIndex); 73 74 74 75 private: 75 76 76 77 /** @name Event-handling stuff.78 * @{ */79 /** Handles translation event. */80 virtual void retranslateUi() /* override */;81 /** @} */82 83 /** @name Prepare/cleanup cascade.84 * @{ */85 /** Configures all. */86 void configure();87 void prepareWidgets();88 void prepareActions();89 void prepareConnections();90 /** Perform final preparations. */91 void finalize();92 /** @} */93 94 void repopulateTreeWidget();95 /** Disable/enable 'ok' button on the basis of having a selected item */96 void updateOkButton();97 UIMediumItem* addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent);98 void restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList);99 /** Recursively create the hard disk hierarchy under the tree widget */100 UIMediumItem* createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent);101 UIMediumItem* searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId);102 void performMediumSearch();103 /** Remember the default foreground brush of the tree so that we can reset tree items' foreground later */104 void saveDefaultForeground();105 void selectMedium(const QUuid &uMediumID);106 107 QVBoxLayout *m_pMainLayout;108 QITreeWidget *m_pTreeWidget;109 UIMediumDeviceType m_enmMediumType;110 QIDialogButtonBox *m_pButtonBox;111 UIToolBar *m_pToolBar;112 QAction *m_pActionAdd;113 QAction *m_pActionCreate;114 QAction *m_pActionRefresh;115 /** All the known media that are already attached to some vm are added under the following top level tree item */116 QITreeWidgetItem *m_pAttachedSubTreeRoot;117 /** All the known media that are not attached to any vm are added under the following top level tree item */118 QITreeWidgetItem *m_pNotAttachedSubTreeRoot;119 QWidget *m_pParent;120 UIMediumSearchWidget *m_pSearchWidget;121 QList<UIMediumItem*> m_mediumItemList;122 QBrush m_defaultItemForeground;123 QString m_strMachineSettingsFilePath;124 QString m_strMachineName;125 77 }; 126 78 127 #endif /* !FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h */79 #endif /* !FEQT_INCLUDED_SRC_medium_viso_UIVisoBrowserBase_h */ -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoContentBrowser.cpp
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelector class implementation.3 * VBox Qt GUI - UIVisoContentBrowser class implementation. 4 4 */ 5 5 … … 16 16 */ 17 17 18 18 19 /* Qt includes: */ 19 #include <QAction> 20 #include <QAbstractItemModel> 21 #include <QDateTime> 22 #include <QDir> 23 #include <QFileSystemModel> 24 #include <QHBoxLayout> 20 25 #include <QHeaderView> 21 #include <QVBoxLayout> 22 #include <QPushButton> 26 #include <QLabel> 27 #include <QListView> 28 #include <QSplitter> 29 #include <QTableView> 30 #include <QTreeView> 23 31 24 32 /* GUI includes: */ 25 #include "QIComboBox.h"26 #include "QIDialogButtonBox.h"27 #include "QIFileDialog.h"28 #include "QILineEdit.h"29 #include "QIMessageBox.h"30 #include "QITabWidget.h"31 33 #include "QIToolButton.h" 32 #include "VBoxGlobal.h" 33 #include "UIDesktopWidgetWatchdog.h" 34 #include "UIExtraDataManager.h" 35 #include "UIFDCreationDialog.h" 36 #include "UIMediumSelector.h" 37 #include "UIMessageCenter.h" 34 #include "UICustomFileSystemModel.h" 38 35 #include "UIIconPool.h" 39 #include "UIMedium.h" 40 #include "UIMediumItem.h" 41 #include "UIToolBar.h" 42 43 /* COM includes: */ 44 #include "COMEnums.h" 45 #include "CMachine.h" 46 #include "CMediumAttachment.h" 47 #include "CMediumFormat.h" 48 #include "CStorageController.h" 49 #include "CSystemProperties.h" 50 51 #ifdef VBOX_WS_MAC 52 # include "UIWindowMenuManager.h" 53 #endif /* VBOX_WS_MAC */ 54 55 56 class UIMediumSearchWidget : public QWidget 57 { 36 #include "UIPathOperations.h" 37 #include "UIVisoContentBrowser.h" 38 39 40 /********************************************************************************************************************************* 41 * UIVisoContentTreeProxyModel definition. * 42 *********************************************************************************************************************************/ 43 44 class UIVisoContentTreeProxyModel : public UICustomFileSystemProxyModel 45 { 46 58 47 Q_OBJECT; 59 48 60 49 public: 61 50 62 enum SearchType 63 { 64 SearchByName, 65 SearchByUUID, 66 SearchByMax 67 }; 68 69 signals: 70 71 void sigSearchTypeChanged(int newType); 72 void sigSearchTermChanged(QString searchTerm); 73 74 public: 75 76 UIMediumSearchWidget(QWidget *pParent = 0); 77 SearchType searchType() const; 78 QString searchTerm() const; 79 80 private: 81 82 void prepareWidgets(); 83 QIComboBox *m_pSearchComboxBox; 84 QLineEdit *m_pSearchTermLineEdit; 51 UIVisoContentTreeProxyModel(QObject *parent = 0); 52 53 protected: 54 55 /** Used to filter-out files and show only directories. */ 56 virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const /* override */; 57 85 58 }; 86 59 87 60 88 61 /********************************************************************************************************************************* 89 * UI MediumSearchWidget implementation.*62 * UIVisoContentTreeProxyModel implementation. * 90 63 *********************************************************************************************************************************/ 91 64 92 UIMediumSearchWidget::UIMediumSearchWidget(QWidget *pParent) 93 :QWidget(pParent) 94 , m_pSearchComboxBox(0) 95 , m_pSearchTermLineEdit(0) 96 { 97 prepareWidgets(); 98 } 99 100 void UIMediumSearchWidget::prepareWidgets() 101 { 102 QHBoxLayout *pLayout = new QHBoxLayout; 103 setLayout(pLayout); 104 pLayout->setContentsMargins(0, 0, 0, 0); 105 pLayout->setSpacing(0); 106 107 m_pSearchComboxBox = new QIComboBox; 108 if (m_pSearchComboxBox) 109 { 110 m_pSearchComboxBox->setEditable(false); 111 m_pSearchComboxBox->insertItem(SearchByName, "Search By Name"); 112 m_pSearchComboxBox->insertItem(SearchByUUID, "Search By UUID"); 113 pLayout->addWidget(m_pSearchComboxBox); 114 115 connect(m_pSearchComboxBox, static_cast<void(QIComboBox::*)(int)>(&QIComboBox::currentIndexChanged), 116 this, &UIMediumSearchWidget::sigSearchTypeChanged); 117 118 } 119 120 m_pSearchTermLineEdit = new QLineEdit; 121 if (m_pSearchTermLineEdit) 122 { 123 m_pSearchTermLineEdit->setClearButtonEnabled(true); 124 pLayout->addWidget(m_pSearchTermLineEdit); 125 connect(m_pSearchTermLineEdit, &QILineEdit::textChanged, 126 this, &UIMediumSearchWidget::sigSearchTermChanged); 127 } 128 } 129 130 UIMediumSearchWidget::SearchType UIMediumSearchWidget::searchType() const 131 { 132 if (!m_pSearchComboxBox || m_pSearchComboxBox->currentIndex() >= static_cast<int>(SearchByMax)) 133 return SearchByMax; 134 return static_cast<SearchType>(m_pSearchComboxBox->currentIndex()); 135 } 136 137 QString UIMediumSearchWidget::searchTerm() const 138 { 139 if (!m_pSearchTermLineEdit) 140 return QString(); 141 return m_pSearchTermLineEdit->text(); 142 } 143 144 145 UIMediumSelector::UIMediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName /* = QString() */, 146 const QString &machineSettigFilePath /* = QString() */, QWidget *pParent /* = 0 */) 147 :QIWithRetranslateUI<QIDialog>(pParent) 148 , m_pMainLayout(0) 149 , m_pTreeWidget(0) 150 , m_enmMediumType(enmMediumType) 151 , m_pButtonBox(0) 152 , m_pToolBar(0) 153 , m_pActionAdd(0) 154 , m_pActionCreate(0) 155 , m_pActionRefresh(0) 156 , m_pAttachedSubTreeRoot(0) 157 , m_pNotAttachedSubTreeRoot(0) 158 , m_pParent(pParent) 159 , m_pSearchWidget(0) 160 , m_strMachineSettingsFilePath(machineSettigFilePath) 161 , m_strMachineName(machineName) 162 { 163 configure(); 164 finalize(); 165 } 166 167 QList<QUuid> UIMediumSelector::selectedMediumIds() const 168 { 169 QList<QUuid> selectedIds; 170 if (!m_pTreeWidget) 171 return selectedIds; 172 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 173 for (int i = 0; i < selectedItems.size(); ++i) 174 { 175 UIMediumItem *item = dynamic_cast<UIMediumItem*>(selectedItems.at(i)); 176 if (item) 177 selectedIds.push_back(item->medium().id()); 178 } 179 return selectedIds; 180 } 181 182 183 void UIMediumSelector::retranslateUi() 184 { 185 if (m_pActionAdd) 186 { 187 m_pActionAdd->setText(tr("&Add...")); 188 m_pActionAdd->setToolTip(tr("Add Disk Image")); 189 m_pActionAdd->setStatusTip(tr("Add existing disk image file")); 190 } 191 192 if (m_pActionCreate) 193 { 194 m_pActionCreate->setText(tr("&Create...")); 195 m_pActionCreate->setToolTip(tr("Create Disk Image")); 196 m_pActionCreate->setStatusTip(tr("Create new disk image file")); 197 } 198 199 if (m_pActionRefresh) 200 { 201 m_pActionRefresh->setText(tr("&Refresh")); 202 m_pActionRefresh->setToolTip(tr("Refresh Disk Image Files (%1)").arg(m_pActionRefresh->shortcut().toString())); 203 m_pActionRefresh->setStatusTip(tr("Refresh the list of disk image files")); 204 } 205 206 if (m_pButtonBox) 207 m_pButtonBox->button(QDialogButtonBox::Ok)->setText(tr("Choose")); 208 209 if (m_pTreeWidget) 210 { 211 m_pTreeWidget->headerItem()->setText(0, tr("Name")); 212 m_pTreeWidget->headerItem()->setText(1, tr("Virtual Size")); 213 m_pTreeWidget->headerItem()->setText(2, tr("Actual Size")); 214 } 215 } 216 217 void UIMediumSelector::configure() 218 { 219 /* Apply window icons: */ 220 setWindowIcon(UIIconPool::iconSetFull(":/media_manager_32px.png", ":/media_manager_16px.png")); 221 prepareActions(); 222 prepareWidgets(); 65 UIVisoContentTreeProxyModel::UIVisoContentTreeProxyModel(QObject *parent /* = 0 */) 66 :UICustomFileSystemProxyModel(parent) 67 { 68 } 69 70 bool UIVisoContentTreeProxyModel::filterAcceptsRow(int iSourceRow, const QModelIndex &sourceParent) const /* override */ 71 { 72 QModelIndex itemIndex = sourceModel()->index(iSourceRow, 0, sourceParent); 73 if (!itemIndex.isValid()) 74 return false; 75 76 UICustomFileSystemItem *item = static_cast<UICustomFileSystemItem*>(itemIndex.internalPointer()); 77 if (!item) 78 return false; 79 80 if (item->isUpDirectory()) 81 return false; 82 if (item->isDirectory() || item->isSymLinkToADirectory()) 83 return true; 84 85 return false; 86 } 87 88 89 /********************************************************************************************************************************* 90 * UIVisoContentBrowser implementation. * 91 *********************************************************************************************************************************/ 92 93 UIVisoContentBrowser::UIVisoContentBrowser(QWidget *pParent) 94 : QIWithRetranslateUI<UIVisoBrowserBase>(pParent) 95 , m_pModel(0) 96 , m_pTableProxyModel(0) 97 , m_pTreeProxyModel(0) 98 , m_pNewDirectoryButton(0) 99 { 100 prepareObjects(); 223 101 prepareConnections(); 224 102 } 225 103 226 void UIMediumSelector::prepareActions() 227 { 228 QString strPrefix("hd"); 229 switch (m_enmMediumType) 230 { 231 case UIMediumDeviceType_DVD: 232 strPrefix = "cd"; 233 break; 234 case UIMediumDeviceType_Floppy: 235 strPrefix = "fd"; 236 break; 237 case UIMediumDeviceType_HardDisk: 238 case UIMediumDeviceType_All: 239 case UIMediumDeviceType_Invalid: 240 default: 241 strPrefix = "hd"; 242 break; 243 } 244 245 m_pActionAdd = new QAction(this); 246 if (m_pActionAdd) 247 { 248 /* Configure add-action: */ 249 m_pActionAdd->setShortcut(QKeySequence("Ctrl+A")); 250 251 m_pActionAdd->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix), 252 QString(":/%1_add_16px.png").arg(strPrefix), 253 QString(":/%1_add_disabled_32px.png").arg(strPrefix), 254 QString(":/%1_add_disabled_16px.png").arg(strPrefix))); 255 } 256 257 /* Currently create is supported only for Floppy: */ 258 if (m_enmMediumType == UIMediumDeviceType_Floppy) 259 { 260 m_pActionCreate = new QAction(this); 261 } 262 if (m_pActionCreate) 263 { 264 265 m_pActionCreate->setShortcut(QKeySequence("Ctrl+C")); 266 m_pActionCreate->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix), 267 QString(":/%1_add_16px.png").arg(strPrefix), 268 QString(":/%1_add_disabled_32px.png").arg(strPrefix), 269 QString(":/%1_add_disabled_16px.png").arg(strPrefix))); 270 } 271 272 273 m_pActionRefresh = new QAction(this); 274 if (m_pActionRefresh) 275 { 276 m_pActionRefresh->setShortcut(QKeySequence(QKeySequence::Refresh)); 277 if (m_pActionRefresh && m_pActionRefresh->icon().isNull()) 278 m_pActionRefresh->setIcon(UIIconPool::iconSetFull(":/refresh_32px.png", ":/refresh_16px.png", 279 ":/refresh_disabled_32px.png", ":/refresh_disabled_16px.png")); 280 } 281 } 282 283 void UIMediumSelector::prepareConnections() 284 { 285 /* Configure medium-enumeration connections: */ 286 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationStarted, 287 this, &UIMediumSelector::sltHandleMediumEnumerationStart); 288 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerated, 289 this, &UIMediumSelector::sltHandleMediumEnumerated); 290 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationFinished, 291 this, &UIMediumSelector::sltHandleMediumEnumerationFinish); 292 if (m_pActionAdd) 293 connect(m_pActionAdd, &QAction::triggered, this, &UIMediumSelector::sltAddMedium); 294 if (m_pActionCreate) 295 connect(m_pActionCreate, &QAction::triggered, this, &UIMediumSelector::sltCreateMedium); 296 if (m_pActionRefresh) 297 connect(m_pActionRefresh, &QAction::triggered, this, &UIMediumSelector::sltHandleRefresh); 298 299 if (m_pTreeWidget) 300 { 301 connect(m_pTreeWidget, &QITreeWidget::itemSelectionChanged, this, &UIMediumSelector::sltHandleItemSelectionChanged); 302 connect(m_pTreeWidget, &QITreeWidget::itemDoubleClicked, this, &UIMediumSelector::sltHandleTreeWidgetDoubleClick); 303 } 304 305 if (m_pButtonBox) 306 { 307 connect(m_pButtonBox, &QIDialogButtonBox::rejected, this, &UIMediumSelector::close); 308 connect(m_pButtonBox, &QIDialogButtonBox::accepted, this, &UIMediumSelector::accept); 309 } 310 311 if (m_pSearchWidget) 312 { 313 connect(m_pSearchWidget, &UIMediumSearchWidget::sigSearchTypeChanged, 314 this, &UIMediumSelector::sltHandleSearchTypeChange); 315 connect(m_pSearchWidget, &UIMediumSearchWidget::sigSearchTermChanged, 316 this, &UIMediumSelector::sltHandleSearchTermChange); 317 } 318 } 319 320 UIMediumItem* UIMediumSelector::addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent) 321 { 322 if (!pParent) 104 UIVisoContentBrowser::~UIVisoContentBrowser() 105 { 106 } 107 108 void UIVisoContentBrowser::addObjectsToViso(QStringList pathList) 109 { 110 if (!m_pTableView) 111 return; 112 113 QModelIndex parentIndex = m_pTableProxyModel->mapToSource(m_pTableView->rootIndex()); 114 if (!parentIndex.isValid()) 115 return; 116 117 UICustomFileSystemItem *pParentItem = static_cast<UICustomFileSystemItem*>(parentIndex.internalPointer()); 118 if (!pParentItem) 119 return; 120 foreach (const QString &strPath, pathList) 121 { 122 QFileInfo fileInfo(strPath); 123 if (!fileInfo.exists()) 124 continue; 125 if (pParentItem->child(fileInfo.fileName())) 126 continue; 127 128 UICustomFileSystemItem* pAddedItem = new UICustomFileSystemItem(fileInfo.fileName(), pParentItem, 129 fileType(fileInfo)); 130 pAddedItem->setData(strPath, UICustomFileSystemModelColumn_LocalPath); 131 pAddedItem->setData(UIPathOperations::mergePaths(pParentItem->path(), fileInfo.fileName()), 132 UICustomFileSystemModelColumn_Path); 133 pAddedItem->setIsOpened(false); 134 if (fileInfo.isSymLink()) 135 { 136 pAddedItem->setTargetPath(fileInfo.symLinkTarget()); 137 pAddedItem->setIsSymLinkToADirectory(QFileInfo(fileInfo.symLinkTarget()).isDir()); 138 } 139 140 } 141 if (m_pTableProxyModel) 142 m_pTableProxyModel->invalidate(); 143 if (m_pTreeProxyModel) 144 { 145 m_pTreeProxyModel->invalidate(); 146 m_pTreeView->setExpanded(m_pTreeView->currentIndex(), true); 147 } 148 } 149 150 QStringList UIVisoContentBrowser::pathList() 151 { 152 if (!rootItem()) 153 return QStringList(); 154 155 UICustomFileSystemItem *pRoot = rootItem()->child(0); 156 157 if (!pRoot) 158 return QStringList(); 159 160 QStringList pathList; 161 for (int i = 0; i < pRoot->childCount(); ++i) 162 { 163 QString strEntry = QString("%1=%2").arg(pRoot->child(i)->data(UICustomFileSystemModelColumn_Path).toString()). 164 arg(pRoot->child(i)->data(UICustomFileSystemModelColumn_LocalPath).toString()); 165 pathList << strEntry; 166 } 167 return pathList; 168 } 169 170 171 void UIVisoContentBrowser::retranslateUi() 172 { 173 if (m_pTitleLabel) 174 m_pTitleLabel->setText(QApplication::translate("UIVisoCreator", "VISO content")); 175 if (m_pAddRemoveButton) 176 m_pAddRemoveButton->setToolTip(QApplication::translate("UIVisoCreator", "Remove selected file objects from VISO")); 177 if (m_pNewDirectoryButton) 178 m_pNewDirectoryButton->setToolTip(QApplication::translate("UIVisoCreator", "Create a new directory under the current directory")); 179 180 UICustomFileSystemItem *pRootItem = rootItem(); 181 if (pRootItem) 182 { 183 pRootItem->setData(QApplication::translate("UIVisoCreator", "Name"), UICustomFileSystemModelColumn_Name); 184 pRootItem->setData(QApplication::translate("UIVisoCreator", "Size"), UICustomFileSystemModelColumn_Size); 185 pRootItem->setData(QApplication::translate("UIVisoCreator", "Change Time"), UICustomFileSystemModelColumn_ChangeTime); 186 pRootItem->setData(QApplication::translate("UIVisoCreator", "Owner"), UICustomFileSystemModelColumn_Owner); 187 pRootItem->setData(QApplication::translate("UIVisoCreator", "Permissions"), UICustomFileSystemModelColumn_Permissions); 188 pRootItem->setData(QApplication::translate("UIVisoCreator", "Local Path"), UICustomFileSystemModelColumn_LocalPath); 189 pRootItem->setData(QApplication::translate("UIVisoCreator", "ISO Path"), UICustomFileSystemModelColumn_Path); 190 } 191 } 192 193 void UIVisoContentBrowser::tableViewItemDoubleClick(const QModelIndex &index) 194 { 195 if (!index.isValid() || !m_pTableProxyModel) 196 return; 197 UICustomFileSystemItem *pClickedItem = 198 static_cast<UICustomFileSystemItem*>(m_pTableProxyModel->mapToSource(index).internalPointer()); 199 if (pClickedItem->isUpDirectory()) 200 { 201 QModelIndex currentRoot = m_pTableProxyModel->mapToSource(m_pTableView->rootIndex()); 202 /* Go up if we are not already there: */ 203 if (currentRoot != m_pModel->rootIndex()) 204 { 205 setTableRootIndex(currentRoot.parent()); 206 setTreeCurrentIndex(currentRoot.parent()); 207 } 208 } 209 else 210 { 211 scanHostDirectory(pClickedItem); 212 setTableRootIndex(index); 213 setTreeCurrentIndex(index); 214 } 215 } 216 217 void UIVisoContentBrowser::sltHandleCreateNewDirectory() 218 { 219 if (!m_pTableView) 220 return; 221 QString strNewDirectoryName("NewDirectory"); 222 223 QModelIndex parentIndex = m_pTableProxyModel->mapToSource(m_pTableView->rootIndex()); 224 if (!parentIndex.isValid()) 225 return; 226 227 UICustomFileSystemItem *pParentItem = static_cast<UICustomFileSystemItem*>(parentIndex.internalPointer()); 228 if (!pParentItem) 229 return; 230 231 /* Check to see if we already have a directory named strNewDirectoryName: */ 232 QList<const UICustomFileSystemItem*> children = pParentItem->children(); 233 foreach (const UICustomFileSystemItem *item, children) 234 { 235 if (item->name() == strNewDirectoryName) 236 return; 237 } 238 239 240 UICustomFileSystemItem* pAddedItem = new UICustomFileSystemItem(strNewDirectoryName, pParentItem, 241 KFsObjType_Directory); 242 243 pAddedItem->setIsOpened(false); 244 if (m_pTableProxyModel) 245 m_pTableProxyModel->invalidate(); 246 247 renameFileObject(pAddedItem); 248 } 249 250 void UIVisoContentBrowser::prepareObjects() 251 { 252 UIVisoBrowserBase::prepareObjects(); 253 254 m_pModel = new UICustomFileSystemModel(this); 255 m_pTableProxyModel = new UICustomFileSystemProxyModel(this); 256 if (m_pTableProxyModel) 257 { 258 m_pTableProxyModel->setSourceModel(m_pModel); 259 m_pTableProxyModel->setListDirectoriesOnTop(true); 260 } 261 262 m_pTreeProxyModel = new UIVisoContentTreeProxyModel(this); 263 if (m_pTreeProxyModel) 264 { 265 m_pTreeProxyModel->setSourceModel(m_pModel); 266 } 267 268 initializeModel(); 269 270 if (m_pTreeView) 271 { 272 m_pTreeView->setModel(m_pTreeProxyModel); 273 // m_pTreeView->setRootIndex(m_pProxyModel->mapFromSource(m_pModel->rootIndex())); 274 m_pTreeView->setCurrentIndex(m_pTreeProxyModel->mapFromSource(m_pModel->rootIndex())); 275 276 /* Show only the 0th column that is "name': */ 277 m_pTreeView->hideColumn(UICustomFileSystemModelColumn_Owner); 278 m_pTreeView->hideColumn(UICustomFileSystemModelColumn_Permissions); 279 m_pTreeView->hideColumn(UICustomFileSystemModelColumn_Size); 280 m_pTreeView->hideColumn(UICustomFileSystemModelColumn_ChangeTime); 281 m_pTreeView->hideColumn(UICustomFileSystemModelColumn_Path); 282 m_pTreeView->hideColumn(UICustomFileSystemModelColumn_LocalPath); 283 } 284 285 if (m_pTableView) 286 { 287 m_pTableView->setModel(m_pTableProxyModel); 288 setTableRootIndex(); 289 m_pTableView->hideColumn(UICustomFileSystemModelColumn_Owner); 290 m_pTableView->hideColumn(UICustomFileSystemModelColumn_Permissions); 291 m_pTableView->hideColumn(UICustomFileSystemModelColumn_Size); 292 m_pTableView->hideColumn(UICustomFileSystemModelColumn_ChangeTime); 293 294 m_pTableView->setSortingEnabled(true); 295 m_pTableView->sortByColumn(0, Qt::AscendingOrder); 296 } 297 298 if (m_pAddRemoveButton) 299 m_pAddRemoveButton->setIcon(UIIconPool::iconSet(":/attachment_remove_16px.png", ":/attachment_remove_disabled_16px.png")); 300 301 m_pNewDirectoryButton = new QIToolButton; 302 if (m_pNewDirectoryButton) 303 { 304 m_pRightContainerLayout->addWidget(m_pNewDirectoryButton, 1, 5, 1, 1); 305 m_pNewDirectoryButton->setIcon(UIIconPool::iconSet(":/attachment_add_16px.png", ":/attachment_add_disabled_16px.png")); 306 m_pNewDirectoryButton->setEnabled(true); 307 } 308 309 retranslateUi(); 310 } 311 312 void UIVisoContentBrowser::prepareConnections() 313 { 314 UIVisoBrowserBase::prepareConnections(); 315 if (m_pNewDirectoryButton) 316 connect(m_pNewDirectoryButton, &QIToolButton::clicked, 317 this, &UIVisoContentBrowser::sltHandleCreateNewDirectory); 318 if (m_pModel) 319 connect(m_pModel, &UICustomFileSystemModel::sigItemRenamed, 320 this, &UIVisoContentBrowser::sltHandleItemRenameAttempt); 321 } 322 323 UICustomFileSystemItem* UIVisoContentBrowser::rootItem() 324 { 325 if (!m_pModel) 323 326 return 0; 324 switch (m_enmMediumType) 325 { 326 case UIMediumDeviceType_DVD: 327 return new UIMediumItemCD(medium, pParent); 328 break; 329 case UIMediumDeviceType_Floppy: 330 return new UIMediumItemFD(medium, pParent); 331 break; 332 case UIMediumDeviceType_HardDisk: 333 case UIMediumDeviceType_All: 334 case UIMediumDeviceType_Invalid: 335 default: 336 return createHardDiskItem(medium, pParent); 337 break; 338 } 339 } 340 341 UIMediumItem* UIMediumSelector::createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent) 342 { 343 if (medium.medium().isNull()) 344 return 0; 345 if (!m_pTreeWidget) 346 return 0; 347 /* Search the tree to see if we already have the item: */ 348 UIMediumItem *pMediumItem = searchItem(0, medium.id()); 349 if (pMediumItem) 350 return pMediumItem; 351 /* Check if the corresponding medium has a parent */ 352 if (medium.parentID() != UIMedium::nullID()) 353 { 354 UIMediumItem *pParentMediumItem = searchItem(0, medium.parentID()); 355 /* If parent medium-item was not found we create it: */ 356 if (!pParentMediumItem) 327 return m_pModel->rootItem(); 328 } 329 330 331 void UIVisoContentBrowser::initializeModel() 332 { 333 if (m_pModel) 334 m_pModel->reset(); 335 if (!rootItem()) 336 return; 337 338 const QString startPath = QString("/%1").arg(m_strVisoName); 339 340 UICustomFileSystemItem* startItem = new UICustomFileSystemItem(startPath, rootItem(), KFsObjType_Directory); 341 startItem->setPath("/"); 342 startItem->setIsOpened(false); 343 } 344 345 346 void UIVisoContentBrowser::setTableRootIndex(QModelIndex index /* = QModelIndex */) 347 { 348 if (!m_pTableView) 349 return; 350 if (index.isValid()) 351 { 352 QModelIndex tableIndex = convertIndexToTableIndex(index); 353 if (tableIndex.isValid()) 354 m_pTableView->setRootIndex(tableIndex); 355 return; 356 } 357 QItemSelectionModel *selectionModel = m_pTreeView->selectionModel(); 358 if (selectionModel) 359 { 360 if (!selectionModel->selectedIndexes().isEmpty()) 357 361 { 358 /* Make sure corresponding parent medium is already cached! */ 359 UIMedium parentMedium = vboxGlobal().medium(medium.parentID()); 360 if (parentMedium.isNull()) 361 AssertMsgFailed(("Parent medium with ID={%s} was not found!\n", medium.parentID().toString().toUtf8().constData())); 362 /* Try to create parent medium-item: */ 363 else 364 pParentMediumItem = createHardDiskItem(parentMedium, pParent); 362 QModelIndex treeIndex = selectionModel->selectedIndexes().at(0); 363 QModelIndex tableIndex = convertIndexToTableIndex(treeIndex); 364 if (tableIndex.isValid()) 365 m_pTableView->setRootIndex(tableIndex); 365 366 } 366 if (pParentMediumItem) 367 } 368 } 369 370 void UIVisoContentBrowser::setTreeCurrentIndex(QModelIndex index /* = QModelIndex() */) 371 { 372 if (!m_pTreeView) 373 return; 374 QItemSelectionModel *pSelectionModel = m_pTreeView->selectionModel(); 375 if (!pSelectionModel) 376 return; 377 m_pTreeView->blockSignals(true); 378 pSelectionModel->blockSignals(true); 379 QModelIndex treeIndex; 380 if (index.isValid()) 381 { 382 treeIndex = convertIndexToTreeIndex(index); 383 } 384 else 385 { 386 QItemSelectionModel *selectionModel = m_pTableView->selectionModel(); 387 if (selectionModel) 367 388 { 368 pMediumItem = new UIMediumItemHD(medium, pParentMediumItem); 369 LogRel2(("UIMediumManager: Child hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData())); 370 } 371 else 372 AssertMsgFailed(("Parent medium with ID={%s} could not be created!\n", medium.parentID().toString().toUtf8().constData())); 373 } 374 375 /* No parents, thus just create item as top-level one: */ 376 else 377 { 378 pMediumItem = new UIMediumItemHD(medium, pParent); 379 LogRel2(("UIMediumManager: Root hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData())); 380 } 381 return pMediumItem; 382 } 383 384 void UIMediumSelector::restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList) 385 { 386 if (!m_pTreeWidget) 387 return; 388 if (selectedMediums.isEmpty()) 389 { 390 m_pTreeWidget->setCurrentItem(0); 391 return; 392 } 393 bool selected = false; 394 for (int i = 0; i < mediumList.size(); ++i) 395 { 396 if (!mediumList[i]) 397 continue; 398 if (selectedMediums.contains(mediumList[i]->medium().id())) 399 { 400 mediumList[i]->setSelected(true); 401 selected = true; 402 } 403 } 404 405 if (!selected) 406 m_pTreeWidget->setCurrentItem(0); 407 return; 408 } 409 410 void UIMediumSelector::prepareWidgets() 411 { 412 m_pMainLayout = new QVBoxLayout; 413 if (!m_pMainLayout) 414 return; 415 416 setLayout(m_pMainLayout); 417 418 m_pToolBar = new UIToolBar(parentWidget()); 419 if (m_pToolBar) 420 { 421 /* Configure toolbar: */ 422 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize)); 423 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric)); 424 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 425 /* Add toolbar actions: */ 426 if (m_pActionAdd) 427 m_pToolBar->addAction(m_pActionAdd); 428 if (m_pActionCreate) 429 m_pToolBar->addAction(m_pActionCreate); 430 if (m_pActionRefresh) 431 m_pToolBar->addAction(m_pActionRefresh); 432 433 m_pMainLayout->addWidget(m_pToolBar); 434 } 435 436 m_pTreeWidget = new QITreeWidget; 437 if (m_pTreeWidget) 438 { 439 m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); 440 m_pMainLayout->addWidget(m_pTreeWidget); 441 m_pTreeWidget->setAlternatingRowColors(true); 442 int iColumnCount = (m_enmMediumType == UIMediumDeviceType_HardDisk) ? 3 : 2; 443 m_pTreeWidget->setColumnCount(iColumnCount); 444 m_pTreeWidget->setSortingEnabled(true); 445 m_pTreeWidget->sortItems(0, Qt::AscendingOrder); 446 } 447 448 m_pSearchWidget = new UIMediumSearchWidget; 449 if (m_pSearchWidget) 450 { 451 m_pMainLayout->addWidget(m_pSearchWidget); 452 } 453 454 m_pButtonBox = new QIDialogButtonBox; 455 if (m_pButtonBox) 456 { 457 /* Configure button-box: */ 458 m_pButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); 459 m_pButtonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::Key_Escape); 460 461 /* Add button-box into main layout: */ 462 m_pMainLayout->addWidget(m_pButtonBox); 463 } 464 465 repopulateTreeWidget(); 466 } 467 468 void UIMediumSelector::sltAddMedium() 469 { 470 QString strDefaultMachineFolder = vboxGlobal().virtualBox().GetSystemProperties().GetDefaultMachineFolder(); 471 QUuid uMediumID = vboxGlobal().openMediumWithFileOpenDialog(m_enmMediumType, this, strDefaultMachineFolder); 472 if (uMediumID.isNull()) 473 return; 474 repopulateTreeWidget(); 475 selectMedium(uMediumID); 476 477 } 478 479 void UIMediumSelector::sltCreateMedium() 480 { 481 QString strMachineFolder = QFileInfo(m_strMachineSettingsFilePath).absolutePath(); 482 UIFDCreationDialog *pDialog = new UIFDCreationDialog(this, m_strMachineName, strMachineFolder); 483 if (pDialog->exec()) 484 { 485 repopulateTreeWidget(); 486 selectMedium(pDialog->mediumID()); 487 } 488 delete pDialog; 489 } 490 491 void UIMediumSelector::sltHandleItemSelectionChanged() 492 { 493 updateOkButton(); 494 } 495 496 void UIMediumSelector::sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column) 497 { 498 Q_UNUSED(column); 499 if (!dynamic_cast<UIMediumItem*>(item)) 500 return; 501 accept(); 502 } 503 504 505 void UIMediumSelector::sltHandleMediumEnumerationStart() 506 { 507 /* Disable controls. Left Alone button box 'Ok' button. it is handle by tree population: */ 508 if (m_pActionRefresh) 509 m_pActionRefresh->setEnabled(false); 510 } 511 512 void UIMediumSelector::sltHandleMediumEnumerated() 513 { 514 } 515 516 void UIMediumSelector::sltHandleMediumEnumerationFinish() 517 { 518 repopulateTreeWidget(); 519 if (m_pActionRefresh) 520 m_pActionRefresh->setEnabled(true); 521 } 522 523 void UIMediumSelector::sltHandleRefresh() 524 { 525 /* Initialize media enumation: */ 526 vboxGlobal().startMediumEnumeration(); 527 } 528 529 void UIMediumSelector::sltHandleSearchTypeChange(int type) 530 { 531 Q_UNUSED(type); 532 performMediumSearch(); 533 } 534 535 void UIMediumSelector::sltHandleSearchTermChange(QString searchTerm) 536 { 537 Q_UNUSED(searchTerm); 538 performMediumSearch(); 539 } 540 541 void UIMediumSelector::selectMedium(const QUuid &uMediumID) 542 { 543 if (!m_pTreeWidget) 544 return; 545 UIMediumItem *pMediumItem = searchItem(0, uMediumID); 546 if (pMediumItem) 547 { 548 m_pTreeWidget->setCurrentItem(pMediumItem); 549 550 } 551 } 552 553 void UIMediumSelector::updateOkButton() 554 { 555 556 if (!m_pTreeWidget || !m_pButtonBox || !m_pButtonBox->button(QDialogButtonBox::Ok)) 557 return; 558 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 559 if (selectedItems.isEmpty()) 560 { 561 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); 562 return; 563 } 564 565 /* check if at least one of the selected items is a UIMediumItem */ 566 bool mediumItemSelected = false; 567 for (int i = 0; i < selectedItems.size() && !mediumItemSelected; ++i) 568 { 569 if (dynamic_cast<UIMediumItem*>(selectedItems.at(i))) 570 mediumItemSelected = true; 571 } 572 if (mediumItemSelected) 573 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(true); 574 else 575 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); 576 } 577 578 void UIMediumSelector::finalize() 579 { 580 /* Apply language settings: */ 581 retranslateUi(); 582 } 583 584 void UIMediumSelector::showEvent(QShowEvent *pEvent) 585 { 586 Q_UNUSED(pEvent); 587 588 /* Try to determine the initial size: */ 589 QSize proposedSize; 590 int iHostScreen = 0; 591 if (m_pParent) 592 iHostScreen = gpDesktop->screenNumber(m_pParent); 593 else 594 iHostScreen = gpDesktop->screenNumber(this); 595 if (iHostScreen >= 0 && iHostScreen < gpDesktop->screenCount()) 596 { 597 /* On the basis of current host-screen geometry if possible: */ 598 const QRect screenGeometry = gpDesktop->screenGeometry(iHostScreen); 599 if (screenGeometry.isValid()) 600 proposedSize = screenGeometry.size() * 5 / 15; 601 } 602 /* Fallback to default size if we failed: */ 603 if (proposedSize.isNull()) 604 proposedSize = QSize(800, 600); 605 /* Resize to initial size: */ 606 resize(proposedSize); 607 608 if (m_pParent) 609 VBoxGlobal::centerWidget(this, m_pParent, false); 610 611 } 612 613 void UIMediumSelector::repopulateTreeWidget() 614 { 615 if (!m_pTreeWidget) 616 return; 617 /* Cache the currently selected items: */ 618 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 619 QList<QUuid> selectedMedia = selectedMediumIds(); 620 /* uuid list of selected items: */ 621 /* Reset the related data structure: */ 622 m_mediumItemList.clear(); 623 m_pTreeWidget->clear(); 624 m_pAttachedSubTreeRoot = 0; 625 m_pNotAttachedSubTreeRoot = 0; 626 QVector<UIMediumItem*> menuItemVector; 627 628 foreach (const QUuid &uMediumID, vboxGlobal().mediumIDs()) 629 { 630 UIMedium medium = vboxGlobal().medium(uMediumID); 631 //printf("name %s\n", qPrintable(medium.name())); 632 if (medium.type() == m_enmMediumType) 633 { 634 bool isMediumAttached = !(medium.medium().GetMachineIds().isEmpty()); 635 QITreeWidgetItem *pParent = 0; 636 if (isMediumAttached) 389 if (!selectionModel->selectedIndexes().isEmpty()) 637 390 { 638 if (!m_pAttachedSubTreeRoot) 639 { 640 QStringList strList; 641 strList << "Attached"; 642 m_pAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList); 643 } 644 pParent = m_pAttachedSubTreeRoot; 645 646 } 647 else 648 { 649 if (!m_pNotAttachedSubTreeRoot) 650 { 651 QStringList strList; 652 strList << "Not Attached"; 653 m_pNotAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList); 654 } 655 pParent = m_pNotAttachedSubTreeRoot; 656 } 657 UIMediumItem *treeItem = addTreeItem(medium, pParent); 658 m_mediumItemList.append(treeItem); 659 menuItemVector.push_back(treeItem); 660 } 661 } 662 restoreSelection(selectedMedia, menuItemVector); 663 saveDefaultForeground(); 664 updateOkButton(); 665 if (m_pAttachedSubTreeRoot) 666 m_pTreeWidget->expandItem(m_pAttachedSubTreeRoot); 667 668 if (m_pNotAttachedSubTreeRoot) 669 m_pTreeWidget->expandItem(m_pNotAttachedSubTreeRoot); 670 671 m_pTreeWidget->resizeColumnToContents(0); 672 performMediumSearch(); 673 } 674 675 void UIMediumSelector::saveDefaultForeground() 676 { 677 if (!m_pTreeWidget) 678 return; 679 if (m_defaultItemForeground == QBrush() && m_pTreeWidget->topLevelItemCount() >= 1) 680 { 681 QTreeWidgetItem *item = m_pTreeWidget->topLevelItem(0); 682 if (item) 683 { 684 QVariant data = item->data(0, Qt::ForegroundRole); 685 if (data.canConvert<QBrush>()) 686 { 687 m_defaultItemForeground = data.value<QBrush>(); 391 QModelIndex tableIndex = selectionModel->selectedIndexes().at(0); 392 treeIndex = convertIndexToTreeIndex(tableIndex); 688 393 } 689 394 } 690 395 } 691 } 692 693 UIMediumItem* UIMediumSelector::searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId) 694 { 695 if (!m_pTreeWidget) 696 return 0; 697 if (!pParent) 698 { 699 pParent = m_pTreeWidget->invisibleRootItem(); 700 } 701 if (!pParent) 702 return 0; 703 704 for (int i = 0; i < pParent->childCount(); ++i) 705 { 706 QTreeWidgetItem *pChild = pParent->child(i); 707 if (!pChild) 708 continue; 709 UIMediumItem *mediumItem = dynamic_cast<UIMediumItem*>(pChild); 710 if (mediumItem) 396 397 if (treeIndex.isValid()) 398 { 399 m_pTreeView->setCurrentIndex(treeIndex); 400 m_pTreeView->setExpanded(treeIndex, true); 401 m_pTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter); 402 m_pTreeProxyModel->invalidate(); 403 } 404 405 pSelectionModel->blockSignals(false); 406 m_pTreeView->blockSignals(false); 407 } 408 409 410 411 void UIVisoContentBrowser::treeSelectionChanged(const QModelIndex &selectedTreeIndex) 412 { 413 if (!m_pTableProxyModel || !m_pTreeProxyModel) 414 return; 415 416 /* Check if we need to scan the directory in the host system: */ 417 UICustomFileSystemItem *pClickedItem = 418 static_cast<UICustomFileSystemItem*>(m_pTreeProxyModel->mapToSource(selectedTreeIndex).internalPointer()); 419 scanHostDirectory(pClickedItem); 420 setTableRootIndex(selectedTreeIndex); 421 m_pTableProxyModel->invalidate(); 422 m_pTreeProxyModel->invalidate(); 423 } 424 425 void UIVisoContentBrowser::showHideHiddenObjects(bool bShow) 426 { 427 Q_UNUSED(bShow); 428 } 429 430 void UIVisoContentBrowser::setVisoName(const QString &strName) 431 { 432 if (m_strVisoName == strName) 433 return; 434 m_strVisoName = strName; 435 updateStartItemName(); 436 } 437 438 QModelIndex UIVisoContentBrowser::convertIndexToTableIndex(const QModelIndex &index) 439 { 440 if (!index.isValid()) 441 return QModelIndex(); 442 443 if (index.model() == m_pTableProxyModel) 444 return index; 445 else if (index.model() == m_pModel) 446 return m_pTableProxyModel->mapFromSource(index); 447 /* else if (index.model() == m_pTreeProxyModel): */ 448 return m_pTableProxyModel->mapFromSource(m_pTreeProxyModel->mapToSource(index)); 449 } 450 451 QModelIndex UIVisoContentBrowser::convertIndexToTreeIndex(const QModelIndex &index) 452 { 453 if (!index.isValid()) 454 return QModelIndex(); 455 456 if (index.model() == m_pTreeProxyModel) 457 return index; 458 else if (index.model() == m_pModel) 459 return m_pTreeProxyModel->mapFromSource(index); 460 /* else if (index.model() == m_pTableProxyModel): */ 461 return m_pTreeProxyModel->mapFromSource(m_pTableProxyModel->mapToSource(index)); 462 } 463 464 void UIVisoContentBrowser::scanHostDirectory(UICustomFileSystemItem *directoryItem) 465 { 466 if (!directoryItem) 467 return; 468 /* the clicked item can be a directory created with the VISO content. in that case local path data 469 should be empty: */ 470 if (directoryItem->type() != KFsObjType_Directory || 471 directoryItem->data(UICustomFileSystemModelColumn_LocalPath).toString().isEmpty()) 472 return; 473 QDir directory(directoryItem->data(UICustomFileSystemModelColumn_LocalPath).toString()); 474 if (directory.exists() && !directoryItem->isOpened()) 475 { 476 QFileInfoList directoryContent = directory.entryInfoList(); 477 for (int i = 0; i < directoryContent.size(); ++i) 711 478 { 712 if (mediumItem->id() == mediumId) 479 const QFileInfo &fileInfo = directoryContent[i]; 480 if (fileInfo.fileName() == ".") 481 continue; 482 UICustomFileSystemItem *newItem = new UICustomFileSystemItem(fileInfo.fileName(), 483 directoryItem, 484 fileType(fileInfo)); 485 newItem->setData(fileInfo.filePath(), UICustomFileSystemModelColumn_LocalPath); 486 487 newItem->setData(UIPathOperations::mergePaths(directoryItem->path(), fileInfo.fileName()), 488 UICustomFileSystemModelColumn_Path); 489 if (fileInfo.isSymLink()) 713 490 { 714 return mediumItem; 491 newItem->setTargetPath(fileInfo.symLinkTarget()); 492 newItem->setIsSymLinkToADirectory(QFileInfo(fileInfo.symLinkTarget()).isDir()); 715 493 } 716 494 } 717 UIMediumItem *pResult = searchItem(pChild, mediumId); 718 if (pResult) 719 return pResult; 720 } 721 return 0; 722 } 723 724 void UIMediumSelector::performMediumSearch() 725 { 726 if (!m_pSearchWidget || !m_pTreeWidget) 727 return; 728 /* Unmark all tree items to remove the highltights: */ 729 for (int i = 0; i < m_mediumItemList.size(); ++i) 730 { 731 for (int j = 0; j < m_pTreeWidget->columnCount(); ++j) 732 { 733 if (m_mediumItemList[i]) 734 m_mediumItemList[i]->setData(j, Qt::ForegroundRole, m_defaultItemForeground); 735 } 736 } 737 738 739 UIMediumSearchWidget::SearchType searchType = 740 m_pSearchWidget->searchType(); 741 if (searchType >= UIMediumSearchWidget::SearchByMax) 742 return; 743 QString strTerm = m_pSearchWidget->searchTerm(); 744 if (strTerm.isEmpty()) 745 return; 746 747 for (int i = 0; i < m_mediumItemList.size(); ++i) 748 { 749 if (!m_mediumItemList[i]) 750 continue; 751 QString strMedium; 752 if (searchType == UIMediumSearchWidget::SearchByName) 753 strMedium = m_mediumItemList[i]->medium().name(); 754 else if(searchType == UIMediumSearchWidget::SearchByUUID) 755 strMedium = m_mediumItemList[i]->medium().id().toString(); 756 if (strMedium.isEmpty()) 757 continue; 758 if (strMedium.contains(strTerm, Qt::CaseInsensitive)) 759 { 760 // mark the item 761 for (int j = 0; j < m_pTreeWidget->columnCount(); ++j) 762 m_mediumItemList[i]->setData(j, Qt::ForegroundRole, QBrush(QColor(255, 0, 0))); 763 } 764 } 765 } 766 767 #include "UIMediumSelector.moc" 495 directoryItem->setIsOpened(true); 496 } 497 } 498 499 /* static */ KFsObjType UIVisoContentBrowser::fileType(const QFileInfo &fsInfo) 500 { 501 if (!fsInfo.exists()) 502 return KFsObjType_Unknown; 503 /* first check if it is symlink becacuse for Qt 504 being smylin and directory/file is not mutually exclusive: */ 505 if (fsInfo.isSymLink()) 506 return KFsObjType_Symlink; 507 else if (fsInfo.isFile()) 508 return KFsObjType_File; 509 else if (fsInfo.isDir()) 510 return KFsObjType_Directory; 511 512 return KFsObjType_Unknown; 513 } 514 515 void UIVisoContentBrowser::updateStartItemName() 516 { 517 if (!rootItem() || !rootItem()->child(0)) 518 return; 519 const QString strName = QString("/%1").arg(m_strVisoName); 520 521 rootItem()->child(0)->setData(strName, UICustomFileSystemModelColumn_Name); 522 m_pTreeProxyModel->invalidate(); 523 m_pTableProxyModel->invalidate(); 524 } 525 526 void UIVisoContentBrowser::renameFileObject(UICustomFileSystemItem *pItem) 527 { 528 m_pTableView->edit(m_pTableProxyModel->mapFromSource(m_pModel->index(pItem))); 529 } 530 531 void UIVisoContentBrowser::sltHandleItemRenameAttempt(UICustomFileSystemItem *pItem, QString strOldName, QString strNewName) 532 { 533 if (!pItem || !pItem->parentItem()) 534 return; 535 QList<const UICustomFileSystemItem*> children = pItem->parentItem()->children(); 536 bool bDuplicate = false; 537 foreach (const UICustomFileSystemItem *item, children) 538 { 539 if (item->name() == strNewName && item != pItem) 540 bDuplicate = true; 541 } 542 543 if (bDuplicate) 544 { 545 /* Restore the previous name in case the @strNewName is a duplicate: */ 546 pItem->setData(strOldName, static_cast<int>(UICustomFileSystemModelColumn_Name)); 547 } 548 549 if (m_pTableProxyModel) 550 m_pTableProxyModel->invalidate(); 551 } 552 553 #include "UIVisoContentBrowser.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoContentBrowser.h
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelector class declaration.3 * VBox Qt GUI - UIVisoContentBrowser class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h19 #define FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h18 #ifndef FEQT_INCLUDED_SRC_medium_viso_UIVisoContentBrowser_h 19 #define FEQT_INCLUDED_SRC_medium_viso_UIVisoContentBrowser_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once 22 22 #endif 23 23 24 /* Qt includes: */ 25 #include <QWidget> 26 27 /* Qt includes: */ 28 #include <QModelIndex> 29 #include <QFileInfo> 30 24 31 /* GUI includes: */ 25 #include "QIDialog.h"26 32 #include "QIWithRetranslateUI.h" 27 #include "UIMedium.h" 28 #include "UIMediumDefs.h" 29 #include "UIMediumDetailsWidget.h" 33 #include "UIVisoBrowserBase.h" 34 35 /* COM includes: */ 36 #include "COMEnums.h" 37 30 38 31 39 /* Forward declarations: */ 32 class QAction; 33 class QTreeWidgetItem; 34 class QITreeWidget; 35 class QITreeWidgetItem; 36 class QVBoxLayout; 37 class QIDialogButtonBox; 38 class UIMediumItem; 39 class UIMediumSearchWidget; 40 class UIToolBar; 40 class UICustomFileSystemModel; 41 class UICustomFileSystemItem; 42 class UICustomFileSystemProxyModel; 43 class UIVisoContentTreeProxyModel; 41 44 42 43 /** QIDialog extension providing GUI with a dialog to select an existing medium. */ 44 class SHARED_LIBRARY_STUFF UIMediumSelector : public QIWithRetranslateUI<QIDialog> 45 class SHARED_LIBRARY_STUFF UIVisoContentBrowser : public QIWithRetranslateUI<UIVisoBrowserBase> 45 46 { 46 47 47 Q_OBJECT; 48 49 signals:50 48 51 49 public: 52 50 53 UIMediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName = QString(), 54 const QString &machineSettigFilePath = QString(), QWidget *pParent = 0); 55 QList<QUuid> selectedMediumIds() const; 51 UIVisoContentBrowser(QWidget *pParent = 0); 52 ~UIVisoContentBrowser(); 53 /** Adds file objests from the host file system. @p pathList consists of list of paths to there objects. */ 54 void addObjectsToViso(QStringList pathList); 55 QStringList pathList(); 56 virtual void showHideHiddenObjects(bool bShow) /* override */; 57 58 void setVisoName(const QString &strName); 56 59 57 60 protected: 58 61 59 void showEvent(QShowEvent *pEvent); 62 void retranslateUi(); 63 virtual void tableViewItemDoubleClick(const QModelIndex &index) /* override */; 64 /** @name Functions to set view root indices explicitly. They block the related signals. @p is converted 65 to the correct index before setting. 66 * @{ */ 67 virtual void setTableRootIndex(QModelIndex index = QModelIndex()) /* override */; 68 virtual void setTreeCurrentIndex(QModelIndex index = QModelIndex()) /* override */; 69 /** @} */ 70 71 virtual void treeSelectionChanged(const QModelIndex &selectedTreeIndex) /* override */; 60 72 61 73 private slots: 62 74 63 void sltAddMedium(); 64 void sltCreateMedium(); 65 void sltHandleItemSelectionChanged(); 66 void sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column); 67 void sltHandleMediumEnumerationStart(); 68 void sltHandleMediumEnumerated(); 69 void sltHandleMediumEnumerationFinish(); 70 void sltHandleRefresh(); 71 void sltHandleSearchTypeChange(int type); 72 void sltHandleSearchTermChange(QString searchTerm); 75 void sltHandleCreateNewDirectory(); 76 void sltHandleItemRenameAttempt(UICustomFileSystemItem *pItem, QString strOldName, QString strNewName); 77 73 78 74 79 private: 75 80 81 void prepareObjects(); 82 void prepareConnections(); 83 void initializeModel(); 84 UICustomFileSystemItem* rootItem(); 85 QModelIndex convertIndexToTableIndex(const QModelIndex &index); 86 QModelIndex convertIndexToTreeIndex(const QModelIndex &index); 87 void scanHostDirectory(UICustomFileSystemItem *directory); 88 KFsObjType fileType(const QFileInfo &fsInfo); 89 void updateStartItemName(); 90 void renameFileObject(UICustomFileSystemItem *pItem); 76 91 77 /** @name Event-handling stuff. 78 * @{ */ 79 /** Handles translation event. */ 80 virtual void retranslateUi() /* override */; 81 /** @} */ 82 83 /** @name Prepare/cleanup cascade. 84 * @{ */ 85 /** Configures all. */ 86 void configure(); 87 void prepareWidgets(); 88 void prepareActions(); 89 void prepareConnections(); 90 /** Perform final preparations. */ 91 void finalize(); 92 /** @} */ 93 94 void repopulateTreeWidget(); 95 /** Disable/enable 'ok' button on the basis of having a selected item */ 96 void updateOkButton(); 97 UIMediumItem* addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent); 98 void restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList); 99 /** Recursively create the hard disk hierarchy under the tree widget */ 100 UIMediumItem* createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent); 101 UIMediumItem* searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId); 102 void performMediumSearch(); 103 /** Remember the default foreground brush of the tree so that we can reset tree items' foreground later */ 104 void saveDefaultForeground(); 105 void selectMedium(const QUuid &uMediumID); 106 107 QVBoxLayout *m_pMainLayout; 108 QITreeWidget *m_pTreeWidget; 109 UIMediumDeviceType m_enmMediumType; 110 QIDialogButtonBox *m_pButtonBox; 111 UIToolBar *m_pToolBar; 112 QAction *m_pActionAdd; 113 QAction *m_pActionCreate; 114 QAction *m_pActionRefresh; 115 /** All the known media that are already attached to some vm are added under the following top level tree item */ 116 QITreeWidgetItem *m_pAttachedSubTreeRoot; 117 /** All the known media that are not attached to any vm are added under the following top level tree item */ 118 QITreeWidgetItem *m_pNotAttachedSubTreeRoot; 119 QWidget *m_pParent; 120 UIMediumSearchWidget *m_pSearchWidget; 121 QList<UIMediumItem*> m_mediumItemList; 122 QBrush m_defaultItemForeground; 123 QString m_strMachineSettingsFilePath; 124 QString m_strMachineName; 92 UICustomFileSystemModel *m_pModel; 93 UICustomFileSystemProxyModel *m_pTableProxyModel; 94 UIVisoContentTreeProxyModel *m_pTreeProxyModel; 95 QIToolButton *m_pNewDirectoryButton; 96 QString m_strVisoName; 125 97 }; 126 98 127 #endif /* !FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h */99 #endif /* !FEQT_INCLUDED_SRC_medium_viso_UIVisoContentBrowser_h */ -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoCreator.cpp
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelector class implementation.3 * VBox Qt GUI - UIVisoCreator class implementation. 4 4 */ 5 5 … … 17 17 18 18 /* Qt includes: */ 19 #include <QAction>20 #include <QHeaderView>21 19 #include <QVBoxLayout> 22 20 #include <QPushButton> 21 #include <QSplitter> 22 #include <QStyle> 23 23 24 24 /* GUI includes: */ 25 #include "QIComboBox.h"26 25 #include "QIDialogButtonBox.h" 27 #include "QIFileDialog.h"28 #include "QILineEdit.h"29 #include "QIMessageBox.h"30 #include "QITabWidget.h"31 #include "QIToolButton.h"32 #include "VBoxGlobal.h"33 #include "UIDesktopWidgetWatchdog.h"34 #include "UIExtraDataManager.h"35 #include "UIFDCreationDialog.h"36 #include "UIMediumSelector.h"37 #include "UIMessageCenter.h"38 26 #include "UIIconPool.h" 39 #include "UIMedium.h"40 #include "UIMediumItem.h"41 27 #include "UIToolBar.h" 42 43 /* COM includes: */ 44 #include "COMEnums.h" 45 #include "CMachine.h" 46 #include "CMediumAttachment.h" 47 #include "CMediumFormat.h" 48 #include "CStorageController.h" 49 #include "CSystemProperties.h" 50 51 #ifdef VBOX_WS_MAC 52 # include "UIWindowMenuManager.h" 53 #endif /* VBOX_WS_MAC */ 28 #include "UIVisoHostBrowser.h" 29 #include "UIVisoCreator.h" 30 #include "UIVisoCreatorOptionsDialog.h" 31 #include "UIVisoContentBrowser.h" 54 32 55 33 56 class UIMediumSearchWidget : public QWidget 34 UIVisoCreator::UIVisoCreator(QWidget *pParent /* =0 */) 35 : QIWithRetranslateUI<QIDialog>(pParent) 36 , m_pMainLayout(0) 37 , m_pVerticalSplitter(0) 38 , m_pHostBrowser(0) 39 , m_pVisoBrowser(0) 40 , m_pButtonBox(0) 41 , m_pToolBar(0) 42 , m_pActionOptions(0) 57 43 { 58 Q_OBJECT;59 44 60 public: 61 62 enum SearchType 63 { 64 SearchByName, 65 SearchByUUID, 66 SearchByMax 67 }; 68 69 signals: 70 71 void sigSearchTypeChanged(int newType); 72 void sigSearchTermChanged(QString searchTerm); 73 74 public: 75 76 UIMediumSearchWidget(QWidget *pParent = 0); 77 SearchType searchType() const; 78 QString searchTerm() const; 79 80 private: 81 82 void prepareWidgets(); 83 QIComboBox *m_pSearchComboxBox; 84 QLineEdit *m_pSearchTermLineEdit; 85 }; 86 87 88 /********************************************************************************************************************************* 89 * UIMediumSearchWidget implementation. * 90 *********************************************************************************************************************************/ 91 92 UIMediumSearchWidget::UIMediumSearchWidget(QWidget *pParent) 93 :QWidget(pParent) 94 , m_pSearchComboxBox(0) 95 , m_pSearchTermLineEdit(0) 96 { 97 prepareWidgets(); 45 prepareActions(); 46 prepareObjects(); 47 prepareConnections(); 98 48 } 99 49 100 void UIMediumSearchWidget::prepareWidgets()50 UIVisoCreator::~UIVisoCreator() 101 51 { 102 QHBoxLayout *pLayout = new QHBoxLayout; 103 setLayout(pLayout); 104 pLayout->setContentsMargins(0, 0, 0, 0); 105 pLayout->setSpacing(0); 52 } 106 53 107 m_pSearchComboxBox = new QIComboBox; 108 if (m_pSearchComboxBox) 54 QStringList UIVisoCreator::pathList() 55 { 56 if (!m_pVisoBrowser) 57 return QStringList(); 58 return m_pVisoBrowser->pathList(); 59 } 60 61 void UIVisoCreator::retranslateUi() 62 { 63 if (m_pActionOptions) 109 64 { 110 m_pSearchComboxBox->setEditable(false); 111 m_pSearchComboxBox->insertItem(SearchByName, "Search By Name"); 112 m_pSearchComboxBox->insertItem(SearchByUUID, "Search By UUID"); 113 pLayout->addWidget(m_pSearchComboxBox); 114 115 connect(m_pSearchComboxBox, static_cast<void(QIComboBox::*)(int)>(&QIComboBox::currentIndexChanged), 116 this, &UIMediumSearchWidget::sigSearchTypeChanged); 117 118 } 119 120 m_pSearchTermLineEdit = new QLineEdit; 121 if (m_pSearchTermLineEdit) 122 { 123 m_pSearchTermLineEdit->setClearButtonEnabled(true); 124 pLayout->addWidget(m_pSearchTermLineEdit); 125 connect(m_pSearchTermLineEdit, &QILineEdit::textChanged, 126 this, &UIMediumSearchWidget::sigSearchTermChanged); 65 m_pActionOptions->setText(tr("&Options...")); 66 m_pActionOptions->setToolTip(tr("VISO Options")); 67 m_pActionOptions->setStatusTip(tr("Manage VISO Options")); 127 68 } 128 69 } 129 70 130 UIMediumSearchWidget::SearchType UIMediumSearchWidget::searchType() const 71 void UIVisoCreator::sltHandleAddObjectsToViso(QStringList pathList) 131 72 { 132 if (!m_pSearchComboxBox || m_pSearchComboxBox->currentIndex() >= static_cast<int>(SearchByMax)) 133 return SearchByMax; 134 return static_cast<SearchType>(m_pSearchComboxBox->currentIndex()); 73 if (m_pVisoBrowser) 74 m_pVisoBrowser->addObjectsToViso(pathList); 135 75 } 136 76 137 QString UIMediumSearchWidget::searchTerm() const 77 void UIVisoCreator::sltHandleOptionsAction() 138 78 { 139 if (!m_pSearchTermLineEdit) 140 return QString(); 141 return m_pSearchTermLineEdit->text(); 79 UIVisoCreatorOptionsDialog *pDialog = new UIVisoCreatorOptionsDialog(m_visoOptions, m_browserOptions, this); 80 81 if(!pDialog) 82 return; 83 if (pDialog->execute(true, false)) 84 { 85 /** Check if any of the options has been modified: */ 86 checkBrowserOptions(pDialog->browserOptions()); 87 checkVisoOptions(pDialog->visoOptions()); 88 } 89 delete pDialog; 142 90 } 143 91 144 92 145 UIMediumSelector::UIMediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName /* = QString() */, 146 const QString &machineSettigFilePath /* = QString() */, QWidget *pParent /* = 0 */) 147 :QIWithRetranslateUI<QIDialog>(pParent) 148 , m_pMainLayout(0) 149 , m_pTreeWidget(0) 150 , m_enmMediumType(enmMediumType) 151 , m_pButtonBox(0) 152 , m_pToolBar(0) 153 , m_pActionAdd(0) 154 , m_pActionCreate(0) 155 , m_pActionRefresh(0) 156 , m_pAttachedSubTreeRoot(0) 157 , m_pNotAttachedSubTreeRoot(0) 158 , m_pParent(pParent) 159 , m_pSearchWidget(0) 160 , m_strMachineSettingsFilePath(machineSettigFilePath) 161 , m_strMachineName(machineName) 162 { 163 configure(); 164 finalize(); 165 } 166 167 QList<QUuid> UIMediumSelector::selectedMediumIds() const 168 { 169 QList<QUuid> selectedIds; 170 if (!m_pTreeWidget) 171 return selectedIds; 172 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 173 for (int i = 0; i < selectedItems.size(); ++i) 174 { 175 UIMediumItem *item = dynamic_cast<UIMediumItem*>(selectedItems.at(i)); 176 if (item) 177 selectedIds.push_back(item->medium().id()); 178 } 179 return selectedIds; 180 } 181 182 183 void UIMediumSelector::retranslateUi() 184 { 185 if (m_pActionAdd) 186 { 187 m_pActionAdd->setText(tr("&Add...")); 188 m_pActionAdd->setToolTip(tr("Add Disk Image")); 189 m_pActionAdd->setStatusTip(tr("Add existing disk image file")); 190 } 191 192 if (m_pActionCreate) 193 { 194 m_pActionCreate->setText(tr("&Create...")); 195 m_pActionCreate->setToolTip(tr("Create Disk Image")); 196 m_pActionCreate->setStatusTip(tr("Create new disk image file")); 197 } 198 199 if (m_pActionRefresh) 200 { 201 m_pActionRefresh->setText(tr("&Refresh")); 202 m_pActionRefresh->setToolTip(tr("Refresh Disk Image Files (%1)").arg(m_pActionRefresh->shortcut().toString())); 203 m_pActionRefresh->setStatusTip(tr("Refresh the list of disk image files")); 204 } 205 206 if (m_pButtonBox) 207 m_pButtonBox->button(QDialogButtonBox::Ok)->setText(tr("Choose")); 208 209 if (m_pTreeWidget) 210 { 211 m_pTreeWidget->headerItem()->setText(0, tr("Name")); 212 m_pTreeWidget->headerItem()->setText(1, tr("Virtual Size")); 213 m_pTreeWidget->headerItem()->setText(2, tr("Actual Size")); 214 } 215 } 216 217 void UIMediumSelector::configure() 218 { 219 /* Apply window icons: */ 220 setWindowIcon(UIIconPool::iconSetFull(":/media_manager_32px.png", ":/media_manager_16px.png")); 221 prepareActions(); 222 prepareWidgets(); 223 prepareConnections(); 224 } 225 226 void UIMediumSelector::prepareActions() 227 { 228 QString strPrefix("hd"); 229 switch (m_enmMediumType) 230 { 231 case UIMediumDeviceType_DVD: 232 strPrefix = "cd"; 233 break; 234 case UIMediumDeviceType_Floppy: 235 strPrefix = "fd"; 236 break; 237 case UIMediumDeviceType_HardDisk: 238 case UIMediumDeviceType_All: 239 case UIMediumDeviceType_Invalid: 240 default: 241 strPrefix = "hd"; 242 break; 243 } 244 245 m_pActionAdd = new QAction(this); 246 if (m_pActionAdd) 247 { 248 /* Configure add-action: */ 249 m_pActionAdd->setShortcut(QKeySequence("Ctrl+A")); 250 251 m_pActionAdd->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix), 252 QString(":/%1_add_16px.png").arg(strPrefix), 253 QString(":/%1_add_disabled_32px.png").arg(strPrefix), 254 QString(":/%1_add_disabled_16px.png").arg(strPrefix))); 255 } 256 257 /* Currently create is supported only for Floppy: */ 258 if (m_enmMediumType == UIMediumDeviceType_Floppy) 259 { 260 m_pActionCreate = new QAction(this); 261 } 262 if (m_pActionCreate) 263 { 264 265 m_pActionCreate->setShortcut(QKeySequence("Ctrl+C")); 266 m_pActionCreate->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix), 267 QString(":/%1_add_16px.png").arg(strPrefix), 268 QString(":/%1_add_disabled_32px.png").arg(strPrefix), 269 QString(":/%1_add_disabled_16px.png").arg(strPrefix))); 270 } 271 272 273 m_pActionRefresh = new QAction(this); 274 if (m_pActionRefresh) 275 { 276 m_pActionRefresh->setShortcut(QKeySequence(QKeySequence::Refresh)); 277 if (m_pActionRefresh && m_pActionRefresh->icon().isNull()) 278 m_pActionRefresh->setIcon(UIIconPool::iconSetFull(":/refresh_32px.png", ":/refresh_16px.png", 279 ":/refresh_disabled_32px.png", ":/refresh_disabled_16px.png")); 280 } 281 } 282 283 void UIMediumSelector::prepareConnections() 284 { 285 /* Configure medium-enumeration connections: */ 286 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationStarted, 287 this, &UIMediumSelector::sltHandleMediumEnumerationStart); 288 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerated, 289 this, &UIMediumSelector::sltHandleMediumEnumerated); 290 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationFinished, 291 this, &UIMediumSelector::sltHandleMediumEnumerationFinish); 292 if (m_pActionAdd) 293 connect(m_pActionAdd, &QAction::triggered, this, &UIMediumSelector::sltAddMedium); 294 if (m_pActionCreate) 295 connect(m_pActionCreate, &QAction::triggered, this, &UIMediumSelector::sltCreateMedium); 296 if (m_pActionRefresh) 297 connect(m_pActionRefresh, &QAction::triggered, this, &UIMediumSelector::sltHandleRefresh); 298 299 if (m_pTreeWidget) 300 { 301 connect(m_pTreeWidget, &QITreeWidget::itemSelectionChanged, this, &UIMediumSelector::sltHandleItemSelectionChanged); 302 connect(m_pTreeWidget, &QITreeWidget::itemDoubleClicked, this, &UIMediumSelector::sltHandleTreeWidgetDoubleClick); 303 } 304 305 if (m_pButtonBox) 306 { 307 connect(m_pButtonBox, &QIDialogButtonBox::rejected, this, &UIMediumSelector::close); 308 connect(m_pButtonBox, &QIDialogButtonBox::accepted, this, &UIMediumSelector::accept); 309 } 310 311 if (m_pSearchWidget) 312 { 313 connect(m_pSearchWidget, &UIMediumSearchWidget::sigSearchTypeChanged, 314 this, &UIMediumSelector::sltHandleSearchTypeChange); 315 connect(m_pSearchWidget, &UIMediumSearchWidget::sigSearchTermChanged, 316 this, &UIMediumSelector::sltHandleSearchTermChange); 317 } 318 } 319 320 UIMediumItem* UIMediumSelector::addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent) 321 { 322 if (!pParent) 323 return 0; 324 switch (m_enmMediumType) 325 { 326 case UIMediumDeviceType_DVD: 327 return new UIMediumItemCD(medium, pParent); 328 break; 329 case UIMediumDeviceType_Floppy: 330 return new UIMediumItemFD(medium, pParent); 331 break; 332 case UIMediumDeviceType_HardDisk: 333 case UIMediumDeviceType_All: 334 case UIMediumDeviceType_Invalid: 335 default: 336 return createHardDiskItem(medium, pParent); 337 break; 338 } 339 } 340 341 UIMediumItem* UIMediumSelector::createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent) 342 { 343 if (medium.medium().isNull()) 344 return 0; 345 if (!m_pTreeWidget) 346 return 0; 347 /* Search the tree to see if we already have the item: */ 348 UIMediumItem *pMediumItem = searchItem(0, medium.id()); 349 if (pMediumItem) 350 return pMediumItem; 351 /* Check if the corresponding medium has a parent */ 352 if (medium.parentID() != UIMedium::nullID()) 353 { 354 UIMediumItem *pParentMediumItem = searchItem(0, medium.parentID()); 355 /* If parent medium-item was not found we create it: */ 356 if (!pParentMediumItem) 357 { 358 /* Make sure corresponding parent medium is already cached! */ 359 UIMedium parentMedium = vboxGlobal().medium(medium.parentID()); 360 if (parentMedium.isNull()) 361 AssertMsgFailed(("Parent medium with ID={%s} was not found!\n", medium.parentID().toString().toUtf8().constData())); 362 /* Try to create parent medium-item: */ 363 else 364 pParentMediumItem = createHardDiskItem(parentMedium, pParent); 365 } 366 if (pParentMediumItem) 367 { 368 pMediumItem = new UIMediumItemHD(medium, pParentMediumItem); 369 LogRel2(("UIMediumManager: Child hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData())); 370 } 371 else 372 AssertMsgFailed(("Parent medium with ID={%s} could not be created!\n", medium.parentID().toString().toUtf8().constData())); 373 } 374 375 /* No parents, thus just create item as top-level one: */ 376 else 377 { 378 pMediumItem = new UIMediumItemHD(medium, pParent); 379 LogRel2(("UIMediumManager: Root hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData())); 380 } 381 return pMediumItem; 382 } 383 384 void UIMediumSelector::restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList) 385 { 386 if (!m_pTreeWidget) 387 return; 388 if (selectedMediums.isEmpty()) 389 { 390 m_pTreeWidget->setCurrentItem(0); 391 return; 392 } 393 bool selected = false; 394 for (int i = 0; i < mediumList.size(); ++i) 395 { 396 if (!mediumList[i]) 397 continue; 398 if (selectedMediums.contains(mediumList[i]->medium().id())) 399 { 400 mediumList[i]->setSelected(true); 401 selected = true; 402 } 403 } 404 405 if (!selected) 406 m_pTreeWidget->setCurrentItem(0); 407 return; 408 } 409 410 void UIMediumSelector::prepareWidgets() 93 void UIVisoCreator::prepareObjects() 411 94 { 412 95 m_pMainLayout = new QVBoxLayout; 413 96 if (!m_pMainLayout) 414 97 return; 415 416 setLayout(m_pMainLayout);417 98 418 99 m_pToolBar = new UIToolBar(parentWidget()); … … 424 105 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 425 106 /* Add toolbar actions: */ 426 if (m_pActionAdd) 427 m_pToolBar->addAction(m_pActionAdd); 428 if (m_pActionCreate) 429 m_pToolBar->addAction(m_pActionCreate); 430 if (m_pActionRefresh) 431 m_pToolBar->addAction(m_pActionRefresh); 432 107 if (m_pActionOptions) 108 m_pToolBar->addAction(m_pActionOptions); 433 109 m_pMainLayout->addWidget(m_pToolBar); 434 110 } 435 111 436 m_pTreeWidget = new QITreeWidget; 437 if (m_pTreeWidget) 112 m_pVerticalSplitter = new QSplitter; 113 if (!m_pVerticalSplitter) 114 return; 115 116 m_pMainLayout->addWidget(m_pVerticalSplitter); 117 m_pVerticalSplitter->setOrientation(Qt::Vertical); 118 m_pVerticalSplitter->setHandleWidth(1); 119 120 m_pHostBrowser = new UIVisoHostBrowser; 121 if (m_pHostBrowser) 438 122 { 439 m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); 440 m_pMainLayout->addWidget(m_pTreeWidget); 441 m_pTreeWidget->setAlternatingRowColors(true); 442 int iColumnCount = (m_enmMediumType == UIMediumDeviceType_HardDisk) ? 3 : 2; 443 m_pTreeWidget->setColumnCount(iColumnCount); 444 m_pTreeWidget->setSortingEnabled(true); 445 m_pTreeWidget->sortItems(0, Qt::AscendingOrder); 123 m_pVerticalSplitter->addWidget(m_pHostBrowser); 124 connect(m_pHostBrowser, &UIVisoHostBrowser::sigAddObjectsToViso, 125 this, &UIVisoCreator::sltHandleAddObjectsToViso); 446 126 } 447 448 m_pSearchWidget = new UIMediumSearchWidget; 449 if (m_pSearchWidget) 127 m_pVisoBrowser = new UIVisoContentBrowser; 128 if (m_pVisoBrowser) 450 129 { 451 m_pMainLayout->addWidget(m_pSearchWidget); 130 m_pVerticalSplitter->addWidget(m_pVisoBrowser); 131 m_pVisoBrowser->setVisoName(m_visoOptions.m_strVisoName); 452 132 } 453 454 133 m_pButtonBox = new QIDialogButtonBox; 455 134 if (m_pButtonBox) 456 135 { 457 /* Configure button-box: */458 136 m_pButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); 459 137 m_pButtonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::Key_Escape); 460 461 /* Add button-box into main layout: */462 138 m_pMainLayout->addWidget(m_pButtonBox); 463 139 } 464 465 repopulateTreeWidget();140 retranslateUi(); 141 setLayout(m_pMainLayout); 466 142 } 467 143 468 void UI MediumSelector::sltAddMedium()144 void UIVisoCreator::prepareConnections() 469 145 { 470 QString strDefaultMachineFolder = vboxGlobal().virtualBox().GetSystemProperties().GetDefaultMachineFolder(); 471 QUuid uMediumID = vboxGlobal().openMediumWithFileOpenDialog(m_enmMediumType, this, strDefaultMachineFolder); 472 if (uMediumID.isNull()) 473 return; 474 repopulateTreeWidget(); 475 selectMedium(uMediumID); 476 477 } 478 479 void UIMediumSelector::sltCreateMedium() 480 { 481 QString strMachineFolder = QFileInfo(m_strMachineSettingsFilePath).absolutePath(); 482 UIFDCreationDialog *pDialog = new UIFDCreationDialog(this, m_strMachineName, strMachineFolder); 483 if (pDialog->exec()) 146 if (m_pButtonBox) 484 147 { 485 repopulateTreeWidget();486 selectMedium(pDialog->mediumID());148 connect(m_pButtonBox, &QIDialogButtonBox::rejected, this, &UIVisoCreator::close); 149 connect(m_pButtonBox, &QIDialogButtonBox::accepted, this, &UIVisoCreator::accept); 487 150 } 488 delete pDialog; 489 } 490 491 void UIMediumSelector::sltHandleItemSelectionChanged() 492 { 493 updateOkButton(); 494 } 495 496 void UIMediumSelector::sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column) 497 { 498 Q_UNUSED(column); 499 if (!dynamic_cast<UIMediumItem*>(item)) 500 return; 501 accept(); 502 } 503 504 505 void UIMediumSelector::sltHandleMediumEnumerationStart() 506 { 507 /* Disable controls. Left Alone button box 'Ok' button. it is handle by tree population: */ 508 if (m_pActionRefresh) 509 m_pActionRefresh->setEnabled(false); 510 } 511 512 void UIMediumSelector::sltHandleMediumEnumerated() 513 { 514 } 515 516 void UIMediumSelector::sltHandleMediumEnumerationFinish() 517 { 518 repopulateTreeWidget(); 519 if (m_pActionRefresh) 520 m_pActionRefresh->setEnabled(true); 521 } 522 523 void UIMediumSelector::sltHandleRefresh() 524 { 525 /* Initialize media enumation: */ 526 vboxGlobal().startMediumEnumeration(); 527 } 528 529 void UIMediumSelector::sltHandleSearchTypeChange(int type) 530 { 531 Q_UNUSED(type); 532 performMediumSearch(); 533 } 534 535 void UIMediumSelector::sltHandleSearchTermChange(QString searchTerm) 536 { 537 Q_UNUSED(searchTerm); 538 performMediumSearch(); 539 } 540 541 void UIMediumSelector::selectMedium(const QUuid &uMediumID) 542 { 543 if (!m_pTreeWidget) 544 return; 545 UIMediumItem *pMediumItem = searchItem(0, uMediumID); 546 if (pMediumItem) 151 if (m_pActionOptions) 547 152 { 548 m_pTreeWidget->setCurrentItem(pMediumItem);153 connect(m_pActionOptions, &QAction::triggered, this, &UIVisoCreator::sltHandleOptionsAction); 549 154 550 155 } 551 156 } 552 157 553 void UI MediumSelector::updateOkButton()158 void UIVisoCreator::prepareActions() 554 159 { 160 m_pActionOptions = new QAction(this); 161 if (m_pActionOptions) 162 { 163 /* Configure add-action: */ 164 m_pActionOptions->setShortcut(QKeySequence("Ctrl+A")); 555 165 556 if (!m_pTreeWidget || !m_pButtonBox || !m_pButtonBox->button(QDialogButtonBox::Ok)) 557 return; 558 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 559 if (selectedItems.isEmpty()) 560 { 561 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); 562 return; 563 } 564 565 /* check if at least one of the selected items is a UIMediumItem */ 566 bool mediumItemSelected = false; 567 for (int i = 0; i < selectedItems.size() && !mediumItemSelected; ++i) 568 { 569 if (dynamic_cast<UIMediumItem*>(selectedItems.at(i))) 570 mediumItemSelected = true; 571 } 572 if (mediumItemSelected) 573 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(true); 574 else 575 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); 576 } 577 578 void UIMediumSelector::finalize() 579 { 580 /* Apply language settings: */ 581 retranslateUi(); 582 } 583 584 void UIMediumSelector::showEvent(QShowEvent *pEvent) 585 { 586 Q_UNUSED(pEvent); 587 588 /* Try to determine the initial size: */ 589 QSize proposedSize; 590 int iHostScreen = 0; 591 if (m_pParent) 592 iHostScreen = gpDesktop->screenNumber(m_pParent); 593 else 594 iHostScreen = gpDesktop->screenNumber(this); 595 if (iHostScreen >= 0 && iHostScreen < gpDesktop->screenCount()) 596 { 597 /* On the basis of current host-screen geometry if possible: */ 598 const QRect screenGeometry = gpDesktop->screenGeometry(iHostScreen); 599 if (screenGeometry.isValid()) 600 proposedSize = screenGeometry.size() * 5 / 15; 601 } 602 /* Fallback to default size if we failed: */ 603 if (proposedSize.isNull()) 604 proposedSize = QSize(800, 600); 605 /* Resize to initial size: */ 606 resize(proposedSize); 607 608 if (m_pParent) 609 VBoxGlobal::centerWidget(this, m_pParent, false); 610 611 } 612 613 void UIMediumSelector::repopulateTreeWidget() 614 { 615 if (!m_pTreeWidget) 616 return; 617 /* Cache the currently selected items: */ 618 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 619 QList<QUuid> selectedMedia = selectedMediumIds(); 620 /* uuid list of selected items: */ 621 /* Reset the related data structure: */ 622 m_mediumItemList.clear(); 623 m_pTreeWidget->clear(); 624 m_pAttachedSubTreeRoot = 0; 625 m_pNotAttachedSubTreeRoot = 0; 626 QVector<UIMediumItem*> menuItemVector; 627 628 foreach (const QUuid &uMediumID, vboxGlobal().mediumIDs()) 629 { 630 UIMedium medium = vboxGlobal().medium(uMediumID); 631 //printf("name %s\n", qPrintable(medium.name())); 632 if (medium.type() == m_enmMediumType) 633 { 634 bool isMediumAttached = !(medium.medium().GetMachineIds().isEmpty()); 635 QITreeWidgetItem *pParent = 0; 636 if (isMediumAttached) 637 { 638 if (!m_pAttachedSubTreeRoot) 639 { 640 QStringList strList; 641 strList << "Attached"; 642 m_pAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList); 643 } 644 pParent = m_pAttachedSubTreeRoot; 645 646 } 647 else 648 { 649 if (!m_pNotAttachedSubTreeRoot) 650 { 651 QStringList strList; 652 strList << "Not Attached"; 653 m_pNotAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList); 654 } 655 pParent = m_pNotAttachedSubTreeRoot; 656 } 657 UIMediumItem *treeItem = addTreeItem(medium, pParent); 658 m_mediumItemList.append(treeItem); 659 menuItemVector.push_back(treeItem); 660 } 661 } 662 restoreSelection(selectedMedia, menuItemVector); 663 saveDefaultForeground(); 664 updateOkButton(); 665 if (m_pAttachedSubTreeRoot) 666 m_pTreeWidget->expandItem(m_pAttachedSubTreeRoot); 667 668 if (m_pNotAttachedSubTreeRoot) 669 m_pTreeWidget->expandItem(m_pNotAttachedSubTreeRoot); 670 671 m_pTreeWidget->resizeColumnToContents(0); 672 performMediumSearch(); 673 } 674 675 void UIMediumSelector::saveDefaultForeground() 676 { 677 if (!m_pTreeWidget) 678 return; 679 if (m_defaultItemForeground == QBrush() && m_pTreeWidget->topLevelItemCount() >= 1) 680 { 681 QTreeWidgetItem *item = m_pTreeWidget->topLevelItem(0); 682 if (item) 683 { 684 QVariant data = item->data(0, Qt::ForegroundRole); 685 if (data.canConvert<QBrush>()) 686 { 687 m_defaultItemForeground = data.value<QBrush>(); 688 } 689 } 166 m_pActionOptions->setIcon(UIIconPool::iconSetFull(":/file_manager_options_32px.png", 167 ":/%file_manager_options_16px.png", 168 ":/file_manager_options_disabled_32px.png", 169 ":/file_manager_options_disabled_16px.png")); 690 170 } 691 171 } 692 172 693 UIMediumItem* UIMediumSelector::searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId)173 void UIVisoCreator::checkBrowserOptions(const BrowserOptions &browserOptions) 694 174 { 695 if ( !m_pTreeWidget)696 return 0;697 if ( !pParent)175 if (browserOptions == m_browserOptions) 176 return; 177 if (browserOptions.m_bShowHiddenObjects != m_browserOptions.m_bShowHiddenObjects) 698 178 { 699 pParent = m_pTreeWidget->invisibleRootItem(); 179 if (m_pHostBrowser) 180 m_pHostBrowser->showHideHiddenObjects(browserOptions.m_bShowHiddenObjects); 181 if(m_pVisoBrowser) 182 m_pVisoBrowser->showHideHiddenObjects(browserOptions.m_bShowHiddenObjects); 700 183 } 701 if (!pParent) 702 return 0; 703 704 for (int i = 0; i < pParent->childCount(); ++i) 705 { 706 QTreeWidgetItem *pChild = pParent->child(i); 707 if (!pChild) 708 continue; 709 UIMediumItem *mediumItem = dynamic_cast<UIMediumItem*>(pChild); 710 if (mediumItem) 711 { 712 if (mediumItem->id() == mediumId) 713 { 714 return mediumItem; 715 } 716 } 717 UIMediumItem *pResult = searchItem(pChild, mediumId); 718 if (pResult) 719 return pResult; 720 } 721 return 0; 184 m_browserOptions = browserOptions; 722 185 } 723 186 724 void UI MediumSelector::performMediumSearch()187 void UIVisoCreator::checkVisoOptions(const VisoOptions &visoOptions) 725 188 { 726 if ( !m_pSearchWidget || !m_pTreeWidget)189 if (visoOptions == m_visoOptions) 727 190 return; 728 /* Unmark all tree items to remove the highltights: */ 729 for (int i = 0; i < m_mediumItemList.size(); ++i) 191 if (visoOptions.m_strVisoName != m_visoOptions.m_strVisoName) 730 192 { 731 for (int j = 0; j < m_pTreeWidget->columnCount(); ++j) 732 { 733 if (m_mediumItemList[i]) 734 m_mediumItemList[i]->setData(j, Qt::ForegroundRole, m_defaultItemForeground); 735 } 193 if(m_pVisoBrowser) 194 m_pVisoBrowser->setVisoName(visoOptions.m_strVisoName); 736 195 } 196 m_visoOptions = visoOptions; 737 197 738 739 UIMediumSearchWidget::SearchType searchType =740 m_pSearchWidget->searchType();741 if (searchType >= UIMediumSearchWidget::SearchByMax)742 return;743 QString strTerm = m_pSearchWidget->searchTerm();744 if (strTerm.isEmpty())745 return;746 747 for (int i = 0; i < m_mediumItemList.size(); ++i)748 {749 if (!m_mediumItemList[i])750 continue;751 QString strMedium;752 if (searchType == UIMediumSearchWidget::SearchByName)753 strMedium = m_mediumItemList[i]->medium().name();754 else if(searchType == UIMediumSearchWidget::SearchByUUID)755 strMedium = m_mediumItemList[i]->medium().id().toString();756 if (strMedium.isEmpty())757 continue;758 if (strMedium.contains(strTerm, Qt::CaseInsensitive))759 {760 // mark the item761 for (int j = 0; j < m_pTreeWidget->columnCount(); ++j)762 m_mediumItemList[i]->setData(j, Qt::ForegroundRole, QBrush(QColor(255, 0, 0)));763 }764 }765 198 } 766 767 #include "UIMediumSelector.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoCreator.h
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelector class declaration.3 * VBox Qt GUI - UIVisoCreator class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h19 #define FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h18 #ifndef FEQT_INCLUDED_SRC_medium_viso_UIVisoCreator_h 19 #define FEQT_INCLUDED_SRC_medium_viso_UIVisoCreator_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once 22 22 #endif 23 23 24 25 26 /* Qt includes: */ 27 28 29 /* Qt includes: */ 30 #include <QModelIndex> 31 24 32 /* GUI includes: */ 25 33 #include "QIDialog.h" 26 34 #include "QIWithRetranslateUI.h" 27 #include "UIMedium.h" 28 #include "UIMediumDefs.h" 29 #include "UIMediumDetailsWidget.h" 35 #include "UIVisoCreatorDefs.h" 30 36 31 37 /* Forward declarations: */ 32 class QAction; 33 class QTreeWidgetItem; 34 class QITreeWidget; 35 class QITreeWidgetItem; 38 class QItemSelection; 36 39 class QVBoxLayout; 40 class QSplitter; 37 41 class QIDialogButtonBox; 38 class UIMediumItem; 39 class UIMediumSearchWidget; 42 class UIActionPool; 40 43 class UIToolBar; 44 class UIVisoHostBrowser; 45 class UIVisoContentBrowser; 46 class VisoOptions; 47 class BrowserOptions; 41 48 42 43 /** QIDialog extension providing GUI with a dialog to select an existing medium. */ 44 class SHARED_LIBRARY_STUFF UIMediumSelector : public QIWithRetranslateUI<QIDialog> 49 class SHARED_LIBRARY_STUFF UIVisoCreator : public QIWithRetranslateUI<QIDialog> 45 50 { 46 47 51 Q_OBJECT; 48 49 signals:50 52 51 53 public: 52 54 53 UIMediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName = QString(), 54 const QString &machineSettigFilePath = QString(), QWidget *pParent = 0); 55 QList<QUuid> selectedMediumIds() const; 55 UIVisoCreator(QWidget *pParent = 0); 56 ~UIVisoCreator(); 57 QStringList pathList(); 58 59 #ifdef VBOX_WS_MAC 60 /** Returns the toolbar. */ 61 UIToolBar *toolbar() const { return m_pToolBar; } 62 #endif 56 63 57 64 protected: 58 65 59 void showEvent(QShowEvent *pEvent);66 void retranslateUi(); 60 67 61 68 private slots: 62 69 63 void sltAddMedium(); 64 void sltCreateMedium(); 65 void sltHandleItemSelectionChanged(); 66 void sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column); 67 void sltHandleMediumEnumerationStart(); 68 void sltHandleMediumEnumerated(); 69 void sltHandleMediumEnumerationFinish(); 70 void sltHandleRefresh(); 71 void sltHandleSearchTypeChange(int type); 72 void sltHandleSearchTermChange(QString searchTerm); 70 void sltHandleAddObjectsToViso(QStringList pathList); 71 void sltHandleOptionsAction(); 73 72 74 73 private: 75 74 76 77 /** @name Event-handling stuff. 78 * @{ */ 79 /** Handles translation event. */ 80 virtual void retranslateUi() /* override */; 81 /** @} */ 82 83 /** @name Prepare/cleanup cascade. 84 * @{ */ 85 /** Configures all. */ 86 void configure(); 87 void prepareWidgets(); 88 void prepareActions(); 89 void prepareConnections(); 90 /** Perform final preparations. */ 91 void finalize(); 92 /** @} */ 93 94 void repopulateTreeWidget(); 95 /** Disable/enable 'ok' button on the basis of having a selected item */ 96 void updateOkButton(); 97 UIMediumItem* addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent); 98 void restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList); 99 /** Recursively create the hard disk hierarchy under the tree widget */ 100 UIMediumItem* createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent); 101 UIMediumItem* searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId); 102 void performMediumSearch(); 103 /** Remember the default foreground brush of the tree so that we can reset tree items' foreground later */ 104 void saveDefaultForeground(); 105 void selectMedium(const QUuid &uMediumID); 75 void prepareObjects(); 76 void prepareConnections(); 77 void prepareActions(); 78 /** Set the root index of the m_pTableModel to the current index of m_pTreeModel. */ 79 void setTableRootIndex(QModelIndex index = QModelIndex() ); 80 void setTreeCurrentIndex(QModelIndex index = QModelIndex() ); 81 void checkBrowserOptions(const BrowserOptions &browserOptions); 82 void checkVisoOptions(const VisoOptions &visoOptions); 106 83 107 84 QVBoxLayout *m_pMainLayout; 108 QITreeWidget *m_pTreeWidget; 109 UIMediumDeviceType m_enmMediumType; 85 QSplitter *m_pVerticalSplitter; 86 UIVisoHostBrowser *m_pHostBrowser; 87 UIVisoContentBrowser *m_pVisoBrowser; 110 88 QIDialogButtonBox *m_pButtonBox; 111 89 UIToolBar *m_pToolBar; 112 QAction *m_pActionAdd; 113 QAction *m_pActionCreate; 114 QAction *m_pActionRefresh; 115 /** All the known media that are already attached to some vm are added under the following top level tree item */ 116 QITreeWidgetItem *m_pAttachedSubTreeRoot; 117 /** All the known media that are not attached to any vm are added under the following top level tree item */ 118 QITreeWidgetItem *m_pNotAttachedSubTreeRoot; 119 QWidget *m_pParent; 120 UIMediumSearchWidget *m_pSearchWidget; 121 QList<UIMediumItem*> m_mediumItemList; 122 QBrush m_defaultItemForeground; 123 QString m_strMachineSettingsFilePath; 124 QString m_strMachineName; 90 QAction *m_pActionOptions; 91 VisoOptions m_visoOptions; 92 BrowserOptions m_browserOptions; 93 125 94 }; 126 95 127 #endif /* !FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h */96 #endif /* !FEQT_INCLUDED_SRC_medium_viso_UIVisoCreator_h */ -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoCreatorDefs.h
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelectorclass declaration.3 * VBox Qt GUI - UIVisoCreatorDefs class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h19 #define FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h18 #ifndef FEQT_INCLUDED_SRC_medium_viso_UIVisoCreatorDefs_h 19 #define FEQT_INCLUDED_SRC_medium_viso_UIVisoCreatorDefs_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once 22 22 #endif 23 23 24 /* GUI includes: */25 #include "QIDialog.h"26 #include "QIWithRetranslateUI.h"27 #include "UIMedium.h"28 #include "UIMediumDefs.h"29 #include "UIMediumDetailsWidget.h"30 24 31 /* Forward declarations: */ 32 class QAction; 33 class QTreeWidgetItem; 34 class QITreeWidget; 35 class QITreeWidgetItem; 36 class QVBoxLayout; 37 class QIDialogButtonBox; 38 class UIMediumItem; 39 class UIMediumSearchWidget; 40 class UIToolBar; 25 struct VisoOptions 26 { 27 QString m_strVisoName = "ad-hoc-viso"; 28 bool operator==(const VisoOptions &otherOptions) const 29 { 30 return m_strVisoName == otherOptions.m_strVisoName; 31 } 32 }; 33 34 struct BrowserOptions 35 { 36 bool m_bShowHiddenObjects = true; 37 bool operator==(const BrowserOptions &otherOptions) const 38 { 39 return m_bShowHiddenObjects == otherOptions.m_bShowHiddenObjects; 40 } 41 }; 41 42 42 43 43 /** QIDialog extension providing GUI with a dialog to select an existing medium. */44 class SHARED_LIBRARY_STUFF UIMediumSelector : public QIWithRetranslateUI<QIDialog>45 {46 44 47 Q_OBJECT; 48 49 signals: 50 51 public: 52 53 UIMediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName = QString(), 54 const QString &machineSettigFilePath = QString(), QWidget *pParent = 0); 55 QList<QUuid> selectedMediumIds() const; 56 57 protected: 58 59 void showEvent(QShowEvent *pEvent); 60 61 private slots: 62 63 void sltAddMedium(); 64 void sltCreateMedium(); 65 void sltHandleItemSelectionChanged(); 66 void sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column); 67 void sltHandleMediumEnumerationStart(); 68 void sltHandleMediumEnumerated(); 69 void sltHandleMediumEnumerationFinish(); 70 void sltHandleRefresh(); 71 void sltHandleSearchTypeChange(int type); 72 void sltHandleSearchTermChange(QString searchTerm); 73 74 private: 75 76 77 /** @name Event-handling stuff. 78 * @{ */ 79 /** Handles translation event. */ 80 virtual void retranslateUi() /* override */; 81 /** @} */ 82 83 /** @name Prepare/cleanup cascade. 84 * @{ */ 85 /** Configures all. */ 86 void configure(); 87 void prepareWidgets(); 88 void prepareActions(); 89 void prepareConnections(); 90 /** Perform final preparations. */ 91 void finalize(); 92 /** @} */ 93 94 void repopulateTreeWidget(); 95 /** Disable/enable 'ok' button on the basis of having a selected item */ 96 void updateOkButton(); 97 UIMediumItem* addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent); 98 void restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList); 99 /** Recursively create the hard disk hierarchy under the tree widget */ 100 UIMediumItem* createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent); 101 UIMediumItem* searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId); 102 void performMediumSearch(); 103 /** Remember the default foreground brush of the tree so that we can reset tree items' foreground later */ 104 void saveDefaultForeground(); 105 void selectMedium(const QUuid &uMediumID); 106 107 QVBoxLayout *m_pMainLayout; 108 QITreeWidget *m_pTreeWidget; 109 UIMediumDeviceType m_enmMediumType; 110 QIDialogButtonBox *m_pButtonBox; 111 UIToolBar *m_pToolBar; 112 QAction *m_pActionAdd; 113 QAction *m_pActionCreate; 114 QAction *m_pActionRefresh; 115 /** All the known media that are already attached to some vm are added under the following top level tree item */ 116 QITreeWidgetItem *m_pAttachedSubTreeRoot; 117 /** All the known media that are not attached to any vm are added under the following top level tree item */ 118 QITreeWidgetItem *m_pNotAttachedSubTreeRoot; 119 QWidget *m_pParent; 120 UIMediumSearchWidget *m_pSearchWidget; 121 QList<UIMediumItem*> m_mediumItemList; 122 QBrush m_defaultItemForeground; 123 QString m_strMachineSettingsFilePath; 124 QString m_strMachineName; 125 }; 126 127 #endif /* !FEQT_INCLUDED_SRC_medium_UIMediumSelector_h */ 45 #endif /* !FEQT_INCLUDED_SRC_medium_viso_UIVisoCreatorDefs_h */ -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoCreatorOptionsDialog.cpp
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelectorclass implementation.3 * VBox Qt GUI - UIVisoCreatorOptionsDialog class implementation. 4 4 */ 5 5 … … 17 17 18 18 /* Qt includes: */ 19 #include <Q Action>20 #include <Q HeaderView>19 #include <QCheckBox> 20 #include <QGridLayout> 21 21 #include <QVBoxLayout> 22 22 #include <QPushButton> 23 #include <QSplitter> 24 #include <QStyle> 23 25 24 26 /* GUI includes: */ 25 #include "QIComboBox.h"26 27 #include "QIDialogButtonBox.h" 27 #include "QI FileDialog.h"28 #include "QILabel.h" 28 29 #include "QILineEdit.h" 29 #include "QIMessageBox.h"30 30 #include "QITabWidget.h" 31 #include "QIToolButton.h"32 #include "VBoxGlobal.h"33 #include "UIDesktopWidgetWatchdog.h"34 #include "UIExtraDataManager.h"35 #include "UIFDCreationDialog.h"36 #include "UIMediumSelector.h"37 #include "UIMessageCenter.h"38 31 #include "UIIconPool.h" 39 #include "UIMedium.h"40 #include "UIMediumItem.h"41 32 #include "UIToolBar.h" 33 #include "UIVisoHostBrowser.h" 34 #include "UIVisoCreator.h" 35 #include "UIVisoCreatorOptionsDialog.h" 36 #include "UIVisoContentBrowser.h" 42 37 43 /* COM includes: */ 44 #include "COMEnums.h" 45 #include "CMachine.h" 46 #include "CMediumAttachment.h" 47 #include "CMediumFormat.h" 48 #include "CStorageController.h" 49 #include "CSystemProperties.h" 50 51 #ifdef VBOX_WS_MAC 52 # include "UIWindowMenuManager.h" 53 #endif /* VBOX_WS_MAC */ 54 55 56 class UIMediumSearchWidget : public QWidget 38 UIVisoCreatorOptionsDialog::UIVisoCreatorOptionsDialog(const VisoOptions &visoOptions, 39 const BrowserOptions &browserOptions, 40 QWidget *pParent /* =0 */) 41 : QIDialog(pParent) 42 , m_pMainLayout(0) 43 , m_pButtonBox(0) 44 , m_pTab(0) 45 , m_visoOptions(visoOptions) 46 , m_browserOptions(browserOptions) 57 47 { 58 Q_OBJECT; 59 60 public: 61 62 enum SearchType 63 { 64 SearchByName, 65 SearchByUUID, 66 SearchByMax 67 }; 68 69 signals: 70 71 void sigSearchTypeChanged(int newType); 72 void sigSearchTermChanged(QString searchTerm); 73 74 public: 75 76 UIMediumSearchWidget(QWidget *pParent = 0); 77 SearchType searchType() const; 78 QString searchTerm() const; 79 80 private: 81 82 void prepareWidgets(); 83 QIComboBox *m_pSearchComboxBox; 84 QLineEdit *m_pSearchTermLineEdit; 85 }; 86 87 88 /********************************************************************************************************************************* 89 * UIMediumSearchWidget implementation. * 90 *********************************************************************************************************************************/ 91 92 UIMediumSearchWidget::UIMediumSearchWidget(QWidget *pParent) 93 :QWidget(pParent) 94 , m_pSearchComboxBox(0) 95 , m_pSearchTermLineEdit(0) 96 { 97 prepareWidgets(); 98 } 99 100 void UIMediumSearchWidget::prepareWidgets() 101 { 102 QHBoxLayout *pLayout = new QHBoxLayout; 103 setLayout(pLayout); 104 pLayout->setContentsMargins(0, 0, 0, 0); 105 pLayout->setSpacing(0); 106 107 m_pSearchComboxBox = new QIComboBox; 108 if (m_pSearchComboxBox) 109 { 110 m_pSearchComboxBox->setEditable(false); 111 m_pSearchComboxBox->insertItem(SearchByName, "Search By Name"); 112 m_pSearchComboxBox->insertItem(SearchByUUID, "Search By UUID"); 113 pLayout->addWidget(m_pSearchComboxBox); 114 115 connect(m_pSearchComboxBox, static_cast<void(QIComboBox::*)(int)>(&QIComboBox::currentIndexChanged), 116 this, &UIMediumSearchWidget::sigSearchTypeChanged); 117 118 } 119 120 m_pSearchTermLineEdit = new QLineEdit; 121 if (m_pSearchTermLineEdit) 122 { 123 m_pSearchTermLineEdit->setClearButtonEnabled(true); 124 pLayout->addWidget(m_pSearchTermLineEdit); 125 connect(m_pSearchTermLineEdit, &QILineEdit::textChanged, 126 this, &UIMediumSearchWidget::sigSearchTermChanged); 127 } 128 } 129 130 UIMediumSearchWidget::SearchType UIMediumSearchWidget::searchType() const 131 { 132 if (!m_pSearchComboxBox || m_pSearchComboxBox->currentIndex() >= static_cast<int>(SearchByMax)) 133 return SearchByMax; 134 return static_cast<SearchType>(m_pSearchComboxBox->currentIndex()); 135 } 136 137 QString UIMediumSearchWidget::searchTerm() const 138 { 139 if (!m_pSearchTermLineEdit) 140 return QString(); 141 return m_pSearchTermLineEdit->text(); 142 } 143 144 145 UIMediumSelector::UIMediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName /* = QString() */, 146 const QString &machineSettigFilePath /* = QString() */, QWidget *pParent /* = 0 */) 147 :QIWithRetranslateUI<QIDialog>(pParent) 148 , m_pMainLayout(0) 149 , m_pTreeWidget(0) 150 , m_enmMediumType(enmMediumType) 151 , m_pButtonBox(0) 152 , m_pToolBar(0) 153 , m_pActionAdd(0) 154 , m_pActionCreate(0) 155 , m_pActionRefresh(0) 156 , m_pAttachedSubTreeRoot(0) 157 , m_pNotAttachedSubTreeRoot(0) 158 , m_pParent(pParent) 159 , m_pSearchWidget(0) 160 , m_strMachineSettingsFilePath(machineSettigFilePath) 161 , m_strMachineName(machineName) 162 { 163 configure(); 164 finalize(); 165 } 166 167 QList<QUuid> UIMediumSelector::selectedMediumIds() const 168 { 169 QList<QUuid> selectedIds; 170 if (!m_pTreeWidget) 171 return selectedIds; 172 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 173 for (int i = 0; i < selectedItems.size(); ++i) 174 { 175 UIMediumItem *item = dynamic_cast<UIMediumItem*>(selectedItems.at(i)); 176 if (item) 177 selectedIds.push_back(item->medium().id()); 178 } 179 return selectedIds; 180 } 181 182 183 void UIMediumSelector::retranslateUi() 184 { 185 if (m_pActionAdd) 186 { 187 m_pActionAdd->setText(tr("&Add...")); 188 m_pActionAdd->setToolTip(tr("Add Disk Image")); 189 m_pActionAdd->setStatusTip(tr("Add existing disk image file")); 190 } 191 192 if (m_pActionCreate) 193 { 194 m_pActionCreate->setText(tr("&Create...")); 195 m_pActionCreate->setToolTip(tr("Create Disk Image")); 196 m_pActionCreate->setStatusTip(tr("Create new disk image file")); 197 } 198 199 if (m_pActionRefresh) 200 { 201 m_pActionRefresh->setText(tr("&Refresh")); 202 m_pActionRefresh->setToolTip(tr("Refresh Disk Image Files (%1)").arg(m_pActionRefresh->shortcut().toString())); 203 m_pActionRefresh->setStatusTip(tr("Refresh the list of disk image files")); 204 } 205 206 if (m_pButtonBox) 207 m_pButtonBox->button(QDialogButtonBox::Ok)->setText(tr("Choose")); 208 209 if (m_pTreeWidget) 210 { 211 m_pTreeWidget->headerItem()->setText(0, tr("Name")); 212 m_pTreeWidget->headerItem()->setText(1, tr("Virtual Size")); 213 m_pTreeWidget->headerItem()->setText(2, tr("Actual Size")); 214 } 215 } 216 217 void UIMediumSelector::configure() 218 { 219 /* Apply window icons: */ 220 setWindowIcon(UIIconPool::iconSetFull(":/media_manager_32px.png", ":/media_manager_16px.png")); 221 prepareActions(); 222 prepareWidgets(); 48 prepareObjects(); 223 49 prepareConnections(); 224 50 } 225 51 226 void UIMediumSelector::prepareActions()52 UIVisoCreatorOptionsDialog::~UIVisoCreatorOptionsDialog() 227 53 { 228 QString strPrefix("hd");229 switch (m_enmMediumType)230 {231 case UIMediumDeviceType_DVD:232 strPrefix = "cd";233 break;234 case UIMediumDeviceType_Floppy:235 strPrefix = "fd";236 break;237 case UIMediumDeviceType_HardDisk:238 case UIMediumDeviceType_All:239 case UIMediumDeviceType_Invalid:240 default:241 strPrefix = "hd";242 break;243 }244 245 m_pActionAdd = new QAction(this);246 if (m_pActionAdd)247 {248 /* Configure add-action: */249 m_pActionAdd->setShortcut(QKeySequence("Ctrl+A"));250 251 m_pActionAdd->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix),252 QString(":/%1_add_16px.png").arg(strPrefix),253 QString(":/%1_add_disabled_32px.png").arg(strPrefix),254 QString(":/%1_add_disabled_16px.png").arg(strPrefix)));255 }256 257 /* Currently create is supported only for Floppy: */258 if (m_enmMediumType == UIMediumDeviceType_Floppy)259 {260 m_pActionCreate = new QAction(this);261 }262 if (m_pActionCreate)263 {264 265 m_pActionCreate->setShortcut(QKeySequence("Ctrl+C"));266 m_pActionCreate->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix),267 QString(":/%1_add_16px.png").arg(strPrefix),268 QString(":/%1_add_disabled_32px.png").arg(strPrefix),269 QString(":/%1_add_disabled_16px.png").arg(strPrefix)));270 }271 272 273 m_pActionRefresh = new QAction(this);274 if (m_pActionRefresh)275 {276 m_pActionRefresh->setShortcut(QKeySequence(QKeySequence::Refresh));277 if (m_pActionRefresh && m_pActionRefresh->icon().isNull())278 m_pActionRefresh->setIcon(UIIconPool::iconSetFull(":/refresh_32px.png", ":/refresh_16px.png",279 ":/refresh_disabled_32px.png", ":/refresh_disabled_16px.png"));280 }281 54 } 282 55 283 void UIMediumSelector::prepareConnections() 56 const BrowserOptions &UIVisoCreatorOptionsDialog::browserOptions() const 284 57 { 285 /* Configure medium-enumeration connections: */ 286 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationStarted, 287 this, &UIMediumSelector::sltHandleMediumEnumerationStart); 288 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerated, 289 this, &UIMediumSelector::sltHandleMediumEnumerated); 290 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationFinished, 291 this, &UIMediumSelector::sltHandleMediumEnumerationFinish); 292 if (m_pActionAdd) 293 connect(m_pActionAdd, &QAction::triggered, this, &UIMediumSelector::sltAddMedium); 294 if (m_pActionCreate) 295 connect(m_pActionCreate, &QAction::triggered, this, &UIMediumSelector::sltCreateMedium); 296 if (m_pActionRefresh) 297 connect(m_pActionRefresh, &QAction::triggered, this, &UIMediumSelector::sltHandleRefresh); 298 299 if (m_pTreeWidget) 300 { 301 connect(m_pTreeWidget, &QITreeWidget::itemSelectionChanged, this, &UIMediumSelector::sltHandleItemSelectionChanged); 302 connect(m_pTreeWidget, &QITreeWidget::itemDoubleClicked, this, &UIMediumSelector::sltHandleTreeWidgetDoubleClick); 303 } 304 305 if (m_pButtonBox) 306 { 307 connect(m_pButtonBox, &QIDialogButtonBox::rejected, this, &UIMediumSelector::close); 308 connect(m_pButtonBox, &QIDialogButtonBox::accepted, this, &UIMediumSelector::accept); 309 } 310 311 if (m_pSearchWidget) 312 { 313 connect(m_pSearchWidget, &UIMediumSearchWidget::sigSearchTypeChanged, 314 this, &UIMediumSelector::sltHandleSearchTypeChange); 315 connect(m_pSearchWidget, &UIMediumSearchWidget::sigSearchTermChanged, 316 this, &UIMediumSelector::sltHandleSearchTermChange); 317 } 58 return m_browserOptions; 318 59 } 319 60 320 UIMediumItem* UIMediumSelector::addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent) 61 const VisoOptions &UIVisoCreatorOptionsDialog::visoOptions() const 321 62 { 322 if (!pParent) 323 return 0; 324 switch (m_enmMediumType) 325 { 326 case UIMediumDeviceType_DVD: 327 return new UIMediumItemCD(medium, pParent); 328 break; 329 case UIMediumDeviceType_Floppy: 330 return new UIMediumItemFD(medium, pParent); 331 break; 332 case UIMediumDeviceType_HardDisk: 333 case UIMediumDeviceType_All: 334 case UIMediumDeviceType_Invalid: 335 default: 336 return createHardDiskItem(medium, pParent); 337 break; 338 } 63 return m_visoOptions; 339 64 } 340 65 341 UIMediumItem* UIMediumSelector::createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent)66 void UIVisoCreatorOptionsDialog::sltHandlShowHiddenObjectsChange(int iState) 342 67 { 343 if (medium.medium().isNull()) 344 return 0; 345 if (!m_pTreeWidget) 346 return 0; 347 /* Search the tree to see if we already have the item: */ 348 UIMediumItem *pMediumItem = searchItem(0, medium.id()); 349 if (pMediumItem) 350 return pMediumItem; 351 /* Check if the corresponding medium has a parent */ 352 if (medium.parentID() != UIMedium::nullID()) 353 { 354 UIMediumItem *pParentMediumItem = searchItem(0, medium.parentID()); 355 /* If parent medium-item was not found we create it: */ 356 if (!pParentMediumItem) 357 { 358 /* Make sure corresponding parent medium is already cached! */ 359 UIMedium parentMedium = vboxGlobal().medium(medium.parentID()); 360 if (parentMedium.isNull()) 361 AssertMsgFailed(("Parent medium with ID={%s} was not found!\n", medium.parentID().toString().toUtf8().constData())); 362 /* Try to create parent medium-item: */ 363 else 364 pParentMediumItem = createHardDiskItem(parentMedium, pParent); 365 } 366 if (pParentMediumItem) 367 { 368 pMediumItem = new UIMediumItemHD(medium, pParentMediumItem); 369 LogRel2(("UIMediumManager: Child hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData())); 370 } 371 else 372 AssertMsgFailed(("Parent medium with ID={%s} could not be created!\n", medium.parentID().toString().toUtf8().constData())); 373 } 374 375 /* No parents, thus just create item as top-level one: */ 68 if (iState == static_cast<int>(Qt::Checked)) 69 m_browserOptions.m_bShowHiddenObjects = true; 376 70 else 377 { 378 pMediumItem = new UIMediumItemHD(medium, pParent); 379 LogRel2(("UIMediumManager: Root hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData())); 380 } 381 return pMediumItem; 71 m_browserOptions.m_bShowHiddenObjects = false; 382 72 } 383 73 384 void UI MediumSelector::restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList)74 void UIVisoCreatorOptionsDialog::sltHandleVisoNameChange(const QString &strText) 385 75 { 386 if (!m_pTreeWidget) 387 return; 388 if (selectedMediums.isEmpty()) 389 { 390 m_pTreeWidget->setCurrentItem(0); 391 return; 392 } 393 bool selected = false; 394 for (int i = 0; i < mediumList.size(); ++i) 395 { 396 if (!mediumList[i]) 397 continue; 398 if (selectedMediums.contains(mediumList[i]->medium().id())) 399 { 400 mediumList[i]->setSelected(true); 401 selected = true; 402 } 403 } 404 405 if (!selected) 406 m_pTreeWidget->setCurrentItem(0); 407 return; 76 m_visoOptions.m_strVisoName = strText; 408 77 } 409 78 410 void UI MediumSelector::prepareWidgets()79 void UIVisoCreatorOptionsDialog::prepareObjects() 411 80 { 412 81 m_pMainLayout = new QVBoxLayout; … … 414 83 return; 415 84 416 setLayout(m_pMainLayout); 85 m_pTab = new QITabWidget; 86 if (m_pTab) 87 { 88 m_pMainLayout->addWidget(m_pTab); 89 m_pTab->insertTab(static_cast<int>(TabPage_VISO_Options), new QWidget, UIVisoCreator::tr("VISO Options")); 90 m_pTab->insertTab(static_cast<int>(TabPage_Browser_Options), new QWidget, UIVisoCreator::tr("Browser Options")); 417 91 418 m_pToolBar = new UIToolBar(parentWidget()); 419 if (m_pToolBar) 420 { 421 /* Configure toolbar: */ 422 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize)); 423 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric)); 424 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 425 /* Add toolbar actions: */ 426 if (m_pActionAdd) 427 m_pToolBar->addAction(m_pActionAdd); 428 if (m_pActionCreate) 429 m_pToolBar->addAction(m_pActionCreate); 430 if (m_pActionRefresh) 431 m_pToolBar->addAction(m_pActionRefresh); 92 m_pTab->setTabToolTip(static_cast<int>(TabPage_VISO_Options), UIVisoCreator::tr("Change VISO options")); 93 m_pTab->setTabWhatsThis(static_cast<int>(TabPage_VISO_Options), UIVisoCreator::tr("Change VISO options")); 432 94 433 m_pMainLayout->addWidget(m_pToolBar); 95 m_pTab->setTabToolTip(static_cast<int>(TabPage_Browser_Options), UIVisoCreator::tr("Change Browser options")); 96 m_pTab->setTabWhatsThis(static_cast<int>(TabPage_Browser_Options), UIVisoCreator::tr("Change Browser options")); 97 98 434 99 } 435 436 m_pTreeWidget = new QITreeWidget; 437 if (m_pTreeWidget) 438 { 439 m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); 440 m_pMainLayout->addWidget(m_pTreeWidget); 441 m_pTreeWidget->setAlternatingRowColors(true); 442 int iColumnCount = (m_enmMediumType == UIMediumDeviceType_HardDisk) ? 3 : 2; 443 m_pTreeWidget->setColumnCount(iColumnCount); 444 m_pTreeWidget->setSortingEnabled(true); 445 m_pTreeWidget->sortItems(0, Qt::AscendingOrder); 446 } 447 448 m_pSearchWidget = new UIMediumSearchWidget; 449 if (m_pSearchWidget) 450 { 451 m_pMainLayout->addWidget(m_pSearchWidget); 452 } 100 prepareTabWidget(); 453 101 454 102 m_pButtonBox = new QIDialogButtonBox; 455 103 if (m_pButtonBox) 456 104 { 457 /* Configure button-box: */458 105 m_pButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); 459 106 m_pButtonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::Key_Escape); 460 461 /* Add button-box into main layout: */462 107 m_pMainLayout->addWidget(m_pButtonBox); 463 108 } 464 465 repopulateTreeWidget(); 109 setLayout(m_pMainLayout); 466 110 } 467 111 468 void UI MediumSelector::sltAddMedium()112 void UIVisoCreatorOptionsDialog::prepareConnections() 469 113 { 470 QString strDefaultMachineFolder = vboxGlobal().virtualBox().GetSystemProperties().GetDefaultMachineFolder(); 471 QUuid uMediumID = vboxGlobal().openMediumWithFileOpenDialog(m_enmMediumType, this, strDefaultMachineFolder); 472 if (uMediumID.isNull()) 473 return; 474 repopulateTreeWidget(); 475 selectMedium(uMediumID); 476 477 } 478 479 void UIMediumSelector::sltCreateMedium() 480 { 481 QString strMachineFolder = QFileInfo(m_strMachineSettingsFilePath).absolutePath(); 482 UIFDCreationDialog *pDialog = new UIFDCreationDialog(this, m_strMachineName, strMachineFolder); 483 if (pDialog->exec()) 114 if (m_pButtonBox) 484 115 { 485 repopulateTreeWidget(); 486 selectMedium(pDialog->mediumID()); 487 } 488 delete pDialog; 489 } 490 491 void UIMediumSelector::sltHandleItemSelectionChanged() 492 { 493 updateOkButton(); 494 } 495 496 void UIMediumSelector::sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column) 497 { 498 Q_UNUSED(column); 499 if (!dynamic_cast<UIMediumItem*>(item)) 500 return; 501 accept(); 502 } 503 504 505 void UIMediumSelector::sltHandleMediumEnumerationStart() 506 { 507 /* Disable controls. Left Alone button box 'Ok' button. it is handle by tree population: */ 508 if (m_pActionRefresh) 509 m_pActionRefresh->setEnabled(false); 510 } 511 512 void UIMediumSelector::sltHandleMediumEnumerated() 513 { 514 } 515 516 void UIMediumSelector::sltHandleMediumEnumerationFinish() 517 { 518 repopulateTreeWidget(); 519 if (m_pActionRefresh) 520 m_pActionRefresh->setEnabled(true); 521 } 522 523 void UIMediumSelector::sltHandleRefresh() 524 { 525 /* Initialize media enumation: */ 526 vboxGlobal().startMediumEnumeration(); 527 } 528 529 void UIMediumSelector::sltHandleSearchTypeChange(int type) 530 { 531 Q_UNUSED(type); 532 performMediumSearch(); 533 } 534 535 void UIMediumSelector::sltHandleSearchTermChange(QString searchTerm) 536 { 537 Q_UNUSED(searchTerm); 538 performMediumSearch(); 539 } 540 541 void UIMediumSelector::selectMedium(const QUuid &uMediumID) 542 { 543 if (!m_pTreeWidget) 544 return; 545 UIMediumItem *pMediumItem = searchItem(0, uMediumID); 546 if (pMediumItem) 547 { 548 m_pTreeWidget->setCurrentItem(pMediumItem); 549 116 connect(m_pButtonBox, &QIDialogButtonBox::rejected, this, &UIVisoCreatorOptionsDialog::close); 117 connect(m_pButtonBox, &QIDialogButtonBox::accepted, this, &UIVisoCreatorOptionsDialog::accept); 550 118 } 551 119 } 552 120 553 void UI MediumSelector::updateOkButton()121 void UIVisoCreatorOptionsDialog::prepareTabWidget() 554 122 { 123 if (!m_pTab) 124 return; 125 QWidget *pVisoPage = m_pTab->widget(static_cast<int>(TabPage_VISO_Options)); 126 if (pVisoPage) 127 { 128 QGridLayout *pLayout = new QGridLayout; 555 129 556 if (!m_pTreeWidget || !m_pButtonBox || !m_pButtonBox->button(QDialogButtonBox::Ok)) 557 return; 558 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 559 if (selectedItems.isEmpty()) 560 { 561 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); 562 return; 130 QILineEdit *pVisoNameLineEdit = new QILineEdit; 131 connect(pVisoNameLineEdit, &QILineEdit::textChanged, 132 this, &UIVisoCreatorOptionsDialog::sltHandleVisoNameChange); 133 pVisoNameLineEdit->setText(m_visoOptions.m_strVisoName); 134 QILabel *pVisoNameLabel = new QILabel(UIVisoCreator::tr("VISO Name")); 135 pVisoNameLabel->setBuddy(pVisoNameLineEdit); 136 137 pLayout->addWidget(pVisoNameLabel, 0, 0, Qt::AlignTop); 138 pLayout->addWidget(pVisoNameLineEdit, 0, 1, Qt::AlignTop); 139 140 pVisoPage->setLayout(pLayout); 563 141 } 564 142 565 /* check if at least one of the selected items is a UIMediumItem */ 566 bool mediumItemSelected = false; 567 for (int i = 0; i < selectedItems.size() && !mediumItemSelected; ++i) 143 QWidget *pBrowserPage = m_pTab->widget(static_cast<int>(TabPage_Browser_Options)); 144 if (pBrowserPage) 568 145 { 569 if (dynamic_cast<UIMediumItem*>(selectedItems.at(i))) 570 mediumItemSelected = true; 146 QGridLayout *pLayout = new QGridLayout; 147 148 QCheckBox *pShowHiddenObjectsCheckBox = new QCheckBox; 149 pShowHiddenObjectsCheckBox->setChecked(m_browserOptions.m_bShowHiddenObjects); 150 QILabel *pShowHiddenObjectsLabel = new QILabel(UIVisoCreator::tr("Show Hidden Objects")); 151 pShowHiddenObjectsLabel->setBuddy(pShowHiddenObjectsCheckBox); 152 pLayout->addWidget(pShowHiddenObjectsLabel, 0, 0, Qt::AlignTop); 153 pLayout->addWidget(pShowHiddenObjectsCheckBox, 0, 1, Qt::AlignTop); 154 connect(pShowHiddenObjectsCheckBox, &QCheckBox::stateChanged, 155 this, &UIVisoCreatorOptionsDialog::sltHandlShowHiddenObjectsChange); 156 pBrowserPage->setLayout(pLayout); 571 157 } 572 if (mediumItemSelected)573 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(true);574 else575 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false);576 }577 578 void UIMediumSelector::finalize()579 {580 /* Apply language settings: */581 retranslateUi();582 }583 584 void UIMediumSelector::showEvent(QShowEvent *pEvent)585 {586 Q_UNUSED(pEvent);587 588 /* Try to determine the initial size: */589 QSize proposedSize;590 int iHostScreen = 0;591 if (m_pParent)592 iHostScreen = gpDesktop->screenNumber(m_pParent);593 else594 iHostScreen = gpDesktop->screenNumber(this);595 if (iHostScreen >= 0 && iHostScreen < gpDesktop->screenCount())596 {597 /* On the basis of current host-screen geometry if possible: */598 const QRect screenGeometry = gpDesktop->screenGeometry(iHostScreen);599 if (screenGeometry.isValid())600 proposedSize = screenGeometry.size() * 5 / 15;601 }602 /* Fallback to default size if we failed: */603 if (proposedSize.isNull())604 proposedSize = QSize(800, 600);605 /* Resize to initial size: */606 resize(proposedSize);607 608 if (m_pParent)609 VBoxGlobal::centerWidget(this, m_pParent, false);610 158 611 159 } 612 613 void UIMediumSelector::repopulateTreeWidget()614 {615 if (!m_pTreeWidget)616 return;617 /* Cache the currently selected items: */618 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems();619 QList<QUuid> selectedMedia = selectedMediumIds();620 /* uuid list of selected items: */621 /* Reset the related data structure: */622 m_mediumItemList.clear();623 m_pTreeWidget->clear();624 m_pAttachedSubTreeRoot = 0;625 m_pNotAttachedSubTreeRoot = 0;626 QVector<UIMediumItem*> menuItemVector;627 628 foreach (const QUuid &uMediumID, vboxGlobal().mediumIDs())629 {630 UIMedium medium = vboxGlobal().medium(uMediumID);631 //printf("name %s\n", qPrintable(medium.name()));632 if (medium.type() == m_enmMediumType)633 {634 bool isMediumAttached = !(medium.medium().GetMachineIds().isEmpty());635 QITreeWidgetItem *pParent = 0;636 if (isMediumAttached)637 {638 if (!m_pAttachedSubTreeRoot)639 {640 QStringList strList;641 strList << "Attached";642 m_pAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList);643 }644 pParent = m_pAttachedSubTreeRoot;645 646 }647 else648 {649 if (!m_pNotAttachedSubTreeRoot)650 {651 QStringList strList;652 strList << "Not Attached";653 m_pNotAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList);654 }655 pParent = m_pNotAttachedSubTreeRoot;656 }657 UIMediumItem *treeItem = addTreeItem(medium, pParent);658 m_mediumItemList.append(treeItem);659 menuItemVector.push_back(treeItem);660 }661 }662 restoreSelection(selectedMedia, menuItemVector);663 saveDefaultForeground();664 updateOkButton();665 if (m_pAttachedSubTreeRoot)666 m_pTreeWidget->expandItem(m_pAttachedSubTreeRoot);667 668 if (m_pNotAttachedSubTreeRoot)669 m_pTreeWidget->expandItem(m_pNotAttachedSubTreeRoot);670 671 m_pTreeWidget->resizeColumnToContents(0);672 performMediumSearch();673 }674 675 void UIMediumSelector::saveDefaultForeground()676 {677 if (!m_pTreeWidget)678 return;679 if (m_defaultItemForeground == QBrush() && m_pTreeWidget->topLevelItemCount() >= 1)680 {681 QTreeWidgetItem *item = m_pTreeWidget->topLevelItem(0);682 if (item)683 {684 QVariant data = item->data(0, Qt::ForegroundRole);685 if (data.canConvert<QBrush>())686 {687 m_defaultItemForeground = data.value<QBrush>();688 }689 }690 }691 }692 693 UIMediumItem* UIMediumSelector::searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId)694 {695 if (!m_pTreeWidget)696 return 0;697 if (!pParent)698 {699 pParent = m_pTreeWidget->invisibleRootItem();700 }701 if (!pParent)702 return 0;703 704 for (int i = 0; i < pParent->childCount(); ++i)705 {706 QTreeWidgetItem *pChild = pParent->child(i);707 if (!pChild)708 continue;709 UIMediumItem *mediumItem = dynamic_cast<UIMediumItem*>(pChild);710 if (mediumItem)711 {712 if (mediumItem->id() == mediumId)713 {714 return mediumItem;715 }716 }717 UIMediumItem *pResult = searchItem(pChild, mediumId);718 if (pResult)719 return pResult;720 }721 return 0;722 }723 724 void UIMediumSelector::performMediumSearch()725 {726 if (!m_pSearchWidget || !m_pTreeWidget)727 return;728 /* Unmark all tree items to remove the highltights: */729 for (int i = 0; i < m_mediumItemList.size(); ++i)730 {731 for (int j = 0; j < m_pTreeWidget->columnCount(); ++j)732 {733 if (m_mediumItemList[i])734 m_mediumItemList[i]->setData(j, Qt::ForegroundRole, m_defaultItemForeground);735 }736 }737 738 739 UIMediumSearchWidget::SearchType searchType =740 m_pSearchWidget->searchType();741 if (searchType >= UIMediumSearchWidget::SearchByMax)742 return;743 QString strTerm = m_pSearchWidget->searchTerm();744 if (strTerm.isEmpty())745 return;746 747 for (int i = 0; i < m_mediumItemList.size(); ++i)748 {749 if (!m_mediumItemList[i])750 continue;751 QString strMedium;752 if (searchType == UIMediumSearchWidget::SearchByName)753 strMedium = m_mediumItemList[i]->medium().name();754 else if(searchType == UIMediumSearchWidget::SearchByUUID)755 strMedium = m_mediumItemList[i]->medium().id().toString();756 if (strMedium.isEmpty())757 continue;758 if (strMedium.contains(strTerm, Qt::CaseInsensitive))759 {760 // mark the item761 for (int j = 0; j < m_pTreeWidget->columnCount(); ++j)762 m_mediumItemList[i]->setData(j, Qt::ForegroundRole, QBrush(QColor(255, 0, 0)));763 }764 }765 }766 767 #include "UIMediumSelector.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoCreatorOptionsDialog.h
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelectorclass declaration.3 * VBox Qt GUI - UIVisoCreatorOptionsDialog class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h19 #define FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h18 #ifndef FEQT_INCLUDED_SRC_medium_viso_UIVisoCreatorOptionsDialog_h 19 #define FEQT_INCLUDED_SRC_medium_viso_UIVisoCreatorOptionsDialog_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once … … 25 25 #include "QIDialog.h" 26 26 #include "QIWithRetranslateUI.h" 27 #include "UIMedium.h" 28 #include "UIMediumDefs.h" 29 #include "UIMediumDetailsWidget.h" 27 #include "UIVisoCreatorDefs.h" 30 28 31 29 /* Forward declarations: */ 32 class QAction; 33 class QTreeWidgetItem; 34 class QITreeWidget; 35 class QITreeWidgetItem; 30 // class QILabel; 31 // class QILineEdit; 32 class QITabWidget; 36 33 class QVBoxLayout; 37 34 class QIDialogButtonBox; 38 class UIMediumItem; 39 class UIMediumSearchWidget; 40 class UIToolBar; 35 class VisoOptions; 36 class BrowserOptions; 41 37 42 38 43 /** QIDialog extension providing GUI with a dialog to select an existing medium. */ 44 class SHARED_LIBRARY_STUFF UIMediumSelector : public QIWithRetranslateUI<QIDialog> 39 class SHARED_LIBRARY_STUFF UIVisoCreatorOptionsDialog : public QIDialog 45 40 { 46 47 41 Q_OBJECT; 48 49 signals:50 42 51 43 public: 52 44 53 UIMediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName = QString(), 54 const QString &machineSettigFilePath = QString(), QWidget *pParent = 0); 55 QList<QUuid> selectedMediumIds() const; 56 57 protected: 58 59 void showEvent(QShowEvent *pEvent); 45 UIVisoCreatorOptionsDialog(const VisoOptions &visoOptions, 46 const BrowserOptions &browserOptions, 47 QWidget *pParent = 0); 48 ~UIVisoCreatorOptionsDialog(); 49 const BrowserOptions &browserOptions() const; 50 const VisoOptions &visoOptions() const; 60 51 61 52 private slots: 62 63 void sltAddMedium(); 64 void sltCreateMedium(); 65 void sltHandleItemSelectionChanged(); 66 void sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column); 67 void sltHandleMediumEnumerationStart(); 68 void sltHandleMediumEnumerated(); 69 void sltHandleMediumEnumerationFinish(); 70 void sltHandleRefresh(); 71 void sltHandleSearchTypeChange(int type); 72 void sltHandleSearchTermChange(QString searchTerm); 53 void sltHandlShowHiddenObjectsChange(int iState); 54 void sltHandleVisoNameChange(const QString &strText); 73 55 74 56 private: 57 enum TabPage 58 { 59 TabPage_VISO_Options, 60 TabPage_Browser_Options, 61 TabPage_Max 62 }; 75 63 76 77 /** @name Event-handling stuff. 78 * @{ */ 79 /** Handles translation event. */ 80 virtual void retranslateUi() /* override */; 81 /** @} */ 82 83 /** @name Prepare/cleanup cascade. 84 * @{ */ 85 /** Configures all. */ 86 void configure(); 87 void prepareWidgets(); 88 void prepareActions(); 89 void prepareConnections(); 90 /** Perform final preparations. */ 91 void finalize(); 92 /** @} */ 93 94 void repopulateTreeWidget(); 95 /** Disable/enable 'ok' button on the basis of having a selected item */ 96 void updateOkButton(); 97 UIMediumItem* addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent); 98 void restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList); 99 /** Recursively create the hard disk hierarchy under the tree widget */ 100 UIMediumItem* createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent); 101 UIMediumItem* searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId); 102 void performMediumSearch(); 103 /** Remember the default foreground brush of the tree so that we can reset tree items' foreground later */ 104 void saveDefaultForeground(); 105 void selectMedium(const QUuid &uMediumID); 106 64 void prepareObjects(); 65 void prepareConnections(); 66 void prepareTabWidget(); 107 67 QVBoxLayout *m_pMainLayout; 108 QITreeWidget *m_pTreeWidget;109 UIMediumDeviceType m_enmMediumType;110 68 QIDialogButtonBox *m_pButtonBox; 111 UIToolBar *m_pToolBar; 112 QAction *m_pActionAdd; 113 QAction *m_pActionCreate; 114 QAction *m_pActionRefresh; 115 /** All the known media that are already attached to some vm are added under the following top level tree item */ 116 QITreeWidgetItem *m_pAttachedSubTreeRoot; 117 /** All the known media that are not attached to any vm are added under the following top level tree item */ 118 QITreeWidgetItem *m_pNotAttachedSubTreeRoot; 119 QWidget *m_pParent; 120 UIMediumSearchWidget *m_pSearchWidget; 121 QList<UIMediumItem*> m_mediumItemList; 122 QBrush m_defaultItemForeground; 123 QString m_strMachineSettingsFilePath; 124 QString m_strMachineName; 69 QITabWidget *m_pTab; 70 // QILineEdit *m_pVisoNameLineEdit; 71 //QILabel *m_pVISONameLabel; 72 VisoOptions m_visoOptions; 73 BrowserOptions m_browserOptions; 74 friend class UIVisoCreator; 125 75 }; 126 76 127 #endif /* !FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h */77 #endif /* !FEQT_INCLUDED_SRC_medium_viso_UIVisoCreatorOptionsDialog_h */ -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoHostBrowser.cpp
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelector class implementation.3 * VBox Qt GUI - UIVisoHostBrowser class implementation. 4 4 */ 5 5 … … 15 15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 16 16 */ 17 18 17 /* Qt includes: */ 19 #include <QAction> 18 #include <QAbstractItemModel> 19 #include <QDir> 20 #include <QFileSystemModel> 20 21 #include <QHeaderView> 21 #include <QVBoxLayout> 22 #include <QPushButton> 22 #include <QLabel> 23 #include <QListView> 24 #include <QTableView> 25 #include <QTreeView> 23 26 24 27 /* GUI includes: */ 25 #include "QIComboBox.h" 26 #include "QIDialogButtonBox.h" 27 #include "QIFileDialog.h" 28 #include "QILineEdit.h" 29 #include "QIMessageBox.h" 30 #include "QITabWidget.h" 28 #include "UIIconPool.h" 29 #include "UIVisoHostBrowser.h" 31 30 #include "QIToolButton.h" 32 #include "VBoxGlobal.h" 33 #include "UIDesktopWidgetWatchdog.h" 34 #include "UIExtraDataManager.h" 35 #include "UIFDCreationDialog.h" 36 #include "UIMediumSelector.h" 37 #include "UIMessageCenter.h" 38 #include "UIIconPool.h" 39 #include "UIMedium.h" 40 #include "UIMediumItem.h" 41 #include "UIToolBar.h" 42 43 /* COM includes: */ 44 #include "COMEnums.h" 45 #include "CMachine.h" 46 #include "CMediumAttachment.h" 47 #include "CMediumFormat.h" 48 #include "CStorageController.h" 49 #include "CSystemProperties.h" 50 51 #ifdef VBOX_WS_MAC 52 # include "UIWindowMenuManager.h" 53 #endif /* VBOX_WS_MAC */ 54 55 56 class UIMediumSearchWidget : public QWidget 31 32 /********************************************************************************************************************************* 33 * UIVisoHostBrowserModel definition. * 34 *********************************************************************************************************************************/ 35 36 class UIVisoHostBrowserModel : public QFileSystemModel 57 37 { 58 38 Q_OBJECT; 59 39 60 40 public: 61 62 enum SearchType 63 { 64 SearchByName, 65 SearchByUUID, 66 SearchByMax 67 }; 68 69 signals: 70 71 void sigSearchTypeChanged(int newType); 72 void sigSearchTermChanged(QString searchTerm); 73 74 public: 75 76 UIMediumSearchWidget(QWidget *pParent = 0); 77 SearchType searchType() const; 78 QString searchTerm() const; 41 virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const /* override */; 42 UIVisoHostBrowserModel(QObject *pParent); 43 44 protected: 79 45 80 46 private: 81 47 82 void prepareWidgets();83 QIComboBox *m_pSearchComboxBox;84 QLineEdit *m_pSearchTermLineEdit;85 48 }; 86 49 87 88 50 /********************************************************************************************************************************* 89 * UI MediumSearchWidget implementation.*51 * UIVisoHostBrowserModel implementation. * 90 52 *********************************************************************************************************************************/ 91 53 92 UIMediumSearchWidget::UIMediumSearchWidget(QWidget *pParent) 93 :QWidget(pParent) 94 , m_pSearchComboxBox(0) 95 , m_pSearchTermLineEdit(0) 96 { 97 prepareWidgets(); 98 } 99 100 void UIMediumSearchWidget::prepareWidgets() 101 { 102 QHBoxLayout *pLayout = new QHBoxLayout; 103 setLayout(pLayout); 104 pLayout->setContentsMargins(0, 0, 0, 0); 105 pLayout->setSpacing(0); 106 107 m_pSearchComboxBox = new QIComboBox; 108 if (m_pSearchComboxBox) 109 { 110 m_pSearchComboxBox->setEditable(false); 111 m_pSearchComboxBox->insertItem(SearchByName, "Search By Name"); 112 m_pSearchComboxBox->insertItem(SearchByUUID, "Search By UUID"); 113 pLayout->addWidget(m_pSearchComboxBox); 114 115 connect(m_pSearchComboxBox, static_cast<void(QIComboBox::*)(int)>(&QIComboBox::currentIndexChanged), 116 this, &UIMediumSearchWidget::sigSearchTypeChanged); 117 118 } 119 120 m_pSearchTermLineEdit = new QLineEdit; 121 if (m_pSearchTermLineEdit) 122 { 123 m_pSearchTermLineEdit->setClearButtonEnabled(true); 124 pLayout->addWidget(m_pSearchTermLineEdit); 125 connect(m_pSearchTermLineEdit, &QILineEdit::textChanged, 126 this, &UIMediumSearchWidget::sigSearchTermChanged); 127 } 128 } 129 130 UIMediumSearchWidget::SearchType UIMediumSearchWidget::searchType() const 131 { 132 if (!m_pSearchComboxBox || m_pSearchComboxBox->currentIndex() >= static_cast<int>(SearchByMax)) 133 return SearchByMax; 134 return static_cast<SearchType>(m_pSearchComboxBox->currentIndex()); 135 } 136 137 QString UIMediumSearchWidget::searchTerm() const 138 { 139 if (!m_pSearchTermLineEdit) 140 return QString(); 141 return m_pSearchTermLineEdit->text(); 142 } 143 144 145 UIMediumSelector::UIMediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName /* = QString() */, 146 const QString &machineSettigFilePath /* = QString() */, QWidget *pParent /* = 0 */) 147 :QIWithRetranslateUI<QIDialog>(pParent) 148 , m_pMainLayout(0) 149 , m_pTreeWidget(0) 150 , m_enmMediumType(enmMediumType) 151 , m_pButtonBox(0) 152 , m_pToolBar(0) 153 , m_pActionAdd(0) 154 , m_pActionCreate(0) 155 , m_pActionRefresh(0) 156 , m_pAttachedSubTreeRoot(0) 157 , m_pNotAttachedSubTreeRoot(0) 158 , m_pParent(pParent) 159 , m_pSearchWidget(0) 160 , m_strMachineSettingsFilePath(machineSettigFilePath) 161 , m_strMachineName(machineName) 162 { 163 configure(); 164 finalize(); 165 } 166 167 QList<QUuid> UIMediumSelector::selectedMediumIds() const 168 { 169 QList<QUuid> selectedIds; 170 if (!m_pTreeWidget) 171 return selectedIds; 172 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 173 for (int i = 0; i < selectedItems.size(); ++i) 174 { 175 UIMediumItem *item = dynamic_cast<UIMediumItem*>(selectedItems.at(i)); 176 if (item) 177 selectedIds.push_back(item->medium().id()); 178 } 179 return selectedIds; 180 } 181 182 183 void UIMediumSelector::retranslateUi() 184 { 185 if (m_pActionAdd) 186 { 187 m_pActionAdd->setText(tr("&Add...")); 188 m_pActionAdd->setToolTip(tr("Add Disk Image")); 189 m_pActionAdd->setStatusTip(tr("Add existing disk image file")); 190 } 191 192 if (m_pActionCreate) 193 { 194 m_pActionCreate->setText(tr("&Create...")); 195 m_pActionCreate->setToolTip(tr("Create Disk Image")); 196 m_pActionCreate->setStatusTip(tr("Create new disk image file")); 197 } 198 199 if (m_pActionRefresh) 200 { 201 m_pActionRefresh->setText(tr("&Refresh")); 202 m_pActionRefresh->setToolTip(tr("Refresh Disk Image Files (%1)").arg(m_pActionRefresh->shortcut().toString())); 203 m_pActionRefresh->setStatusTip(tr("Refresh the list of disk image files")); 204 } 205 206 if (m_pButtonBox) 207 m_pButtonBox->button(QDialogButtonBox::Ok)->setText(tr("Choose")); 208 209 if (m_pTreeWidget) 210 { 211 m_pTreeWidget->headerItem()->setText(0, tr("Name")); 212 m_pTreeWidget->headerItem()->setText(1, tr("Virtual Size")); 213 m_pTreeWidget->headerItem()->setText(2, tr("Actual Size")); 214 } 215 } 216 217 void UIMediumSelector::configure() 218 { 219 /* Apply window icons: */ 220 setWindowIcon(UIIconPool::iconSetFull(":/media_manager_32px.png", ":/media_manager_16px.png")); 221 prepareActions(); 222 prepareWidgets(); 54 UIVisoHostBrowserModel::UIVisoHostBrowserModel(QObject *pParent /* = 0 */) 55 :QFileSystemModel(pParent) 56 { 57 } 58 59 QVariant UIVisoHostBrowserModel::data(const QModelIndex &index, int enmRole /* = Qt::DisplayRole */) const 60 { 61 if (enmRole == Qt::DecorationRole && index.column() == 0) 62 { 63 QFileInfo info = fileInfo(index); 64 65 if(info.isSymLink() && info.isDir()) 66 return QIcon(":/file_manager_folder_symlink_16px.png"); 67 else if(info.isSymLink() && info.isFile()) 68 return QIcon(":/file_manager_file_symlink_16px.png"); 69 else if(info.isFile()) 70 return QIcon(":/file_manager_file_16px.png"); 71 else if(info.isDir()) 72 return QIcon(":/file_manager_folder_16px.png"); 73 } 74 return QFileSystemModel::data(index, enmRole); 75 } 76 77 /********************************************************************************************************************************* 78 * UIVisoHostBrowser implementation. * 79 *********************************************************************************************************************************/ 80 81 UIVisoHostBrowser::UIVisoHostBrowser(QWidget *pParent) 82 : QIWithRetranslateUI<UIVisoBrowserBase>(pParent) 83 , m_pTreeModel(0) 84 , m_pTableModel(0) 85 { 86 // loadOptions(); 87 // prepareGuestListener(); 88 prepareObjects(); 223 89 prepareConnections(); 224 } 225 226 void UIMediumSelector::prepareActions() 227 { 228 QString strPrefix("hd"); 229 switch (m_enmMediumType) 230 { 231 case UIMediumDeviceType_DVD: 232 strPrefix = "cd"; 233 break; 234 case UIMediumDeviceType_Floppy: 235 strPrefix = "fd"; 236 break; 237 case UIMediumDeviceType_HardDisk: 238 case UIMediumDeviceType_All: 239 case UIMediumDeviceType_Invalid: 240 default: 241 strPrefix = "hd"; 242 break; 243 } 244 245 m_pActionAdd = new QAction(this); 246 if (m_pActionAdd) 247 { 248 /* Configure add-action: */ 249 m_pActionAdd->setShortcut(QKeySequence("Ctrl+A")); 250 251 m_pActionAdd->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix), 252 QString(":/%1_add_16px.png").arg(strPrefix), 253 QString(":/%1_add_disabled_32px.png").arg(strPrefix), 254 QString(":/%1_add_disabled_16px.png").arg(strPrefix))); 255 } 256 257 /* Currently create is supported only for Floppy: */ 258 if (m_enmMediumType == UIMediumDeviceType_Floppy) 259 { 260 m_pActionCreate = new QAction(this); 261 } 262 if (m_pActionCreate) 263 { 264 265 m_pActionCreate->setShortcut(QKeySequence("Ctrl+C")); 266 m_pActionCreate->setIcon(UIIconPool::iconSetFull(QString(":/%1_add_32px.png").arg(strPrefix), 267 QString(":/%1_add_16px.png").arg(strPrefix), 268 QString(":/%1_add_disabled_32px.png").arg(strPrefix), 269 QString(":/%1_add_disabled_16px.png").arg(strPrefix))); 270 } 271 272 273 m_pActionRefresh = new QAction(this); 274 if (m_pActionRefresh) 275 { 276 m_pActionRefresh->setShortcut(QKeySequence(QKeySequence::Refresh)); 277 if (m_pActionRefresh && m_pActionRefresh->icon().isNull()) 278 m_pActionRefresh->setIcon(UIIconPool::iconSetFull(":/refresh_32px.png", ":/refresh_16px.png", 279 ":/refresh_disabled_32px.png", ":/refresh_disabled_16px.png")); 280 } 281 } 282 283 void UIMediumSelector::prepareConnections() 284 { 285 /* Configure medium-enumeration connections: */ 286 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationStarted, 287 this, &UIMediumSelector::sltHandleMediumEnumerationStart); 288 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerated, 289 this, &UIMediumSelector::sltHandleMediumEnumerated); 290 connect(&vboxGlobal(), &VBoxGlobal::sigMediumEnumerationFinished, 291 this, &UIMediumSelector::sltHandleMediumEnumerationFinish); 292 if (m_pActionAdd) 293 connect(m_pActionAdd, &QAction::triggered, this, &UIMediumSelector::sltAddMedium); 294 if (m_pActionCreate) 295 connect(m_pActionCreate, &QAction::triggered, this, &UIMediumSelector::sltCreateMedium); 296 if (m_pActionRefresh) 297 connect(m_pActionRefresh, &QAction::triggered, this, &UIMediumSelector::sltHandleRefresh); 298 299 if (m_pTreeWidget) 300 { 301 connect(m_pTreeWidget, &QITreeWidget::itemSelectionChanged, this, &UIMediumSelector::sltHandleItemSelectionChanged); 302 connect(m_pTreeWidget, &QITreeWidget::itemDoubleClicked, this, &UIMediumSelector::sltHandleTreeWidgetDoubleClick); 303 } 304 305 if (m_pButtonBox) 306 { 307 connect(m_pButtonBox, &QIDialogButtonBox::rejected, this, &UIMediumSelector::close); 308 connect(m_pButtonBox, &QIDialogButtonBox::accepted, this, &UIMediumSelector::accept); 309 } 310 311 if (m_pSearchWidget) 312 { 313 connect(m_pSearchWidget, &UIMediumSearchWidget::sigSearchTypeChanged, 314 this, &UIMediumSelector::sltHandleSearchTypeChange); 315 connect(m_pSearchWidget, &UIMediumSearchWidget::sigSearchTermChanged, 316 this, &UIMediumSelector::sltHandleSearchTermChange); 317 } 318 } 319 320 UIMediumItem* UIMediumSelector::addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent) 321 { 322 if (!pParent) 323 return 0; 324 switch (m_enmMediumType) 325 { 326 case UIMediumDeviceType_DVD: 327 return new UIMediumItemCD(medium, pParent); 328 break; 329 case UIMediumDeviceType_Floppy: 330 return new UIMediumItemFD(medium, pParent); 331 break; 332 case UIMediumDeviceType_HardDisk: 333 case UIMediumDeviceType_All: 334 case UIMediumDeviceType_Invalid: 335 default: 336 return createHardDiskItem(medium, pParent); 337 break; 338 } 339 } 340 341 UIMediumItem* UIMediumSelector::createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent) 342 { 343 if (medium.medium().isNull()) 344 return 0; 345 if (!m_pTreeWidget) 346 return 0; 347 /* Search the tree to see if we already have the item: */ 348 UIMediumItem *pMediumItem = searchItem(0, medium.id()); 349 if (pMediumItem) 350 return pMediumItem; 351 /* Check if the corresponding medium has a parent */ 352 if (medium.parentID() != UIMedium::nullID()) 353 { 354 UIMediumItem *pParentMediumItem = searchItem(0, medium.parentID()); 355 /* If parent medium-item was not found we create it: */ 356 if (!pParentMediumItem) 357 { 358 /* Make sure corresponding parent medium is already cached! */ 359 UIMedium parentMedium = vboxGlobal().medium(medium.parentID()); 360 if (parentMedium.isNull()) 361 AssertMsgFailed(("Parent medium with ID={%s} was not found!\n", medium.parentID().toString().toUtf8().constData())); 362 /* Try to create parent medium-item: */ 363 else 364 pParentMediumItem = createHardDiskItem(parentMedium, pParent); 365 } 366 if (pParentMediumItem) 367 { 368 pMediumItem = new UIMediumItemHD(medium, pParentMediumItem); 369 LogRel2(("UIMediumManager: Child hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData())); 370 } 371 else 372 AssertMsgFailed(("Parent medium with ID={%s} could not be created!\n", medium.parentID().toString().toUtf8().constData())); 373 } 374 375 /* No parents, thus just create item as top-level one: */ 90 // retranslateUi(); 91 // restorePanelVisibility(); 92 // UIVisoHostBrowserOptions::create(); 93 } 94 95 UIVisoHostBrowser::~UIVisoHostBrowser() 96 { 97 } 98 99 void UIVisoHostBrowser::retranslateUi() 100 { 101 if (m_pTitleLabel) 102 m_pTitleLabel->setText(QApplication::translate("UIVisoCreator", "Host file system")); 103 if (m_pAddRemoveButton) 104 m_pAddRemoveButton->setToolTip(QApplication::translate("UIVisoCreator", "Add selected file objects to VISO")); 105 } 106 107 void UIVisoHostBrowser::prepareObjects() 108 { 109 UIVisoBrowserBase::prepareObjects(); 110 111 m_pTreeModel = new UIVisoHostBrowserModel(this); 112 m_pTreeModel->setRootPath(QDir::rootPath()); 113 m_pTreeModel->setReadOnly(true); 114 m_pTreeModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden); 115 m_pTableModel = new UIVisoHostBrowserModel(this); 116 m_pTableModel->setRootPath(QDir::rootPath()); 117 m_pTableModel->setReadOnly(true); 118 m_pTableModel->setFilter(QDir::AllEntries | QDir::NoDot | QDir::Hidden | QDir::System); 119 120 if (m_pTreeView) 121 { 122 m_pTreeView->setModel(m_pTreeModel); 123 m_pTreeView->setRootIndex(m_pTreeModel->index(m_pTreeModel->rootPath()).parent()); 124 m_pTreeView->setCurrentIndex(m_pTreeModel->index(QDir::homePath())); 125 /* Show only the 0th column that is "name': */ 126 m_pTreeView->hideColumn(1); 127 m_pTreeView->hideColumn(2); 128 m_pTreeView->hideColumn(3); 129 } 130 131 132 if (m_pTableView) 133 { 134 m_pTableView->setModel(m_pTableModel); 135 setTableRootIndex(); 136 /* Hide the "type" column: */ 137 m_pTableView->hideColumn(2); 138 } 139 140 if (m_pAddRemoveButton) 141 { 142 m_pAddRemoveButton->setIcon(UIIconPool::iconSet(":/attachment_add_16px.png", ":/attachment_add_disabled_16px.png")); 143 } 144 145 retranslateUi(); 146 } 147 148 void UIVisoHostBrowser::prepareConnections() 149 { 150 UIVisoBrowserBase::prepareConnections(); 151 if (m_pTableView->selectionModel()) 152 connect(m_pTableView->selectionModel(), &QItemSelectionModel::selectionChanged, 153 this, &UIVisoHostBrowser::sltHandleTableSelectionChanged); 154 if (m_pAddRemoveButton) 155 connect(m_pAddRemoveButton, &QIToolButton::clicked, 156 this, &UIVisoHostBrowser::sltHandleAddButtonClicked); 157 } 158 159 void UIVisoHostBrowser::sltHandleTableSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) 160 { 161 Q_UNUSED(deselected); 162 Q_UNUSED(selected); 163 m_pAddRemoveButton->setEnabled(!selected.isEmpty()); 164 } 165 166 void UIVisoHostBrowser::tableViewItemDoubleClick(const QModelIndex &index) 167 { 168 if (!index.isValid()) 169 return; 170 QFileInfo fileInfo = m_pTableModel->fileInfo(index); 171 /* QFileInfo::isDir() returns true if QFileInfo is a folder or a symlink to folder: */ 172 if (!fileInfo.isDir()) 173 return; 174 setTableRootIndex(index); 175 176 m_pTreeView->blockSignals(true); 177 setTreeCurrentIndex(index); 178 m_pTreeView->blockSignals(false); 179 } 180 181 void UIVisoHostBrowser::treeSelectionChanged(const QModelIndex &selectedTreeIndex) 182 { 183 setTableRootIndex(selectedTreeIndex); 184 } 185 186 void UIVisoHostBrowser::showHideHiddenObjects(bool bShow) 187 { 188 if (bShow) 189 { 190 m_pTableModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden); 191 m_pTreeModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden); 192 } 376 193 else 377 194 { 378 pMediumItem = new UIMediumItemHD(medium, pParent); 379 LogRel2(("UIMediumManager: Root hard-disk medium-item with ID={%s} created.\n", medium.id().toString().toUtf8().constData())); 380 } 381 return pMediumItem; 382 } 383 384 void UIMediumSelector::restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList) 385 { 386 if (!m_pTreeWidget) 387 return; 388 if (selectedMediums.isEmpty()) 389 { 390 m_pTreeWidget->setCurrentItem(0); 391 return; 392 } 393 bool selected = false; 394 for (int i = 0; i < mediumList.size(); ++i) 395 { 396 if (!mediumList[i]) 397 continue; 398 if (selectedMediums.contains(mediumList[i]->medium().id())) 399 { 400 mediumList[i]->setSelected(true); 401 selected = true; 402 } 403 } 404 405 if (!selected) 406 m_pTreeWidget->setCurrentItem(0); 407 return; 408 } 409 410 void UIMediumSelector::prepareWidgets() 411 { 412 m_pMainLayout = new QVBoxLayout; 413 if (!m_pMainLayout) 414 return; 415 416 setLayout(m_pMainLayout); 417 418 m_pToolBar = new UIToolBar(parentWidget()); 419 if (m_pToolBar) 420 { 421 /* Configure toolbar: */ 422 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize)); 423 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric)); 424 m_pToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 425 /* Add toolbar actions: */ 426 if (m_pActionAdd) 427 m_pToolBar->addAction(m_pActionAdd); 428 if (m_pActionCreate) 429 m_pToolBar->addAction(m_pActionCreate); 430 if (m_pActionRefresh) 431 m_pToolBar->addAction(m_pActionRefresh); 432 433 m_pMainLayout->addWidget(m_pToolBar); 434 } 435 436 m_pTreeWidget = new QITreeWidget; 437 if (m_pTreeWidget) 438 { 439 m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); 440 m_pMainLayout->addWidget(m_pTreeWidget); 441 m_pTreeWidget->setAlternatingRowColors(true); 442 int iColumnCount = (m_enmMediumType == UIMediumDeviceType_HardDisk) ? 3 : 2; 443 m_pTreeWidget->setColumnCount(iColumnCount); 444 m_pTreeWidget->setSortingEnabled(true); 445 m_pTreeWidget->sortItems(0, Qt::AscendingOrder); 446 } 447 448 m_pSearchWidget = new UIMediumSearchWidget; 449 if (m_pSearchWidget) 450 { 451 m_pMainLayout->addWidget(m_pSearchWidget); 452 } 453 454 m_pButtonBox = new QIDialogButtonBox; 455 if (m_pButtonBox) 456 { 457 /* Configure button-box: */ 458 m_pButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok); 459 m_pButtonBox->button(QDialogButtonBox::Cancel)->setShortcut(Qt::Key_Escape); 460 461 /* Add button-box into main layout: */ 462 m_pMainLayout->addWidget(m_pButtonBox); 463 } 464 465 repopulateTreeWidget(); 466 } 467 468 void UIMediumSelector::sltAddMedium() 469 { 470 QString strDefaultMachineFolder = vboxGlobal().virtualBox().GetSystemProperties().GetDefaultMachineFolder(); 471 QUuid uMediumID = vboxGlobal().openMediumWithFileOpenDialog(m_enmMediumType, this, strDefaultMachineFolder); 472 if (uMediumID.isNull()) 473 return; 474 repopulateTreeWidget(); 475 selectMedium(uMediumID); 476 477 } 478 479 void UIMediumSelector::sltCreateMedium() 480 { 481 QString strMachineFolder = QFileInfo(m_strMachineSettingsFilePath).absolutePath(); 482 UIFDCreationDialog *pDialog = new UIFDCreationDialog(this, m_strMachineName, strMachineFolder); 483 if (pDialog->exec()) 484 { 485 repopulateTreeWidget(); 486 selectMedium(pDialog->mediumID()); 487 } 488 delete pDialog; 489 } 490 491 void UIMediumSelector::sltHandleItemSelectionChanged() 492 { 493 updateOkButton(); 494 } 495 496 void UIMediumSelector::sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column) 497 { 498 Q_UNUSED(column); 499 if (!dynamic_cast<UIMediumItem*>(item)) 500 return; 501 accept(); 502 } 503 504 505 void UIMediumSelector::sltHandleMediumEnumerationStart() 506 { 507 /* Disable controls. Left Alone button box 'Ok' button. it is handle by tree population: */ 508 if (m_pActionRefresh) 509 m_pActionRefresh->setEnabled(false); 510 } 511 512 void UIMediumSelector::sltHandleMediumEnumerated() 513 { 514 } 515 516 void UIMediumSelector::sltHandleMediumEnumerationFinish() 517 { 518 repopulateTreeWidget(); 519 if (m_pActionRefresh) 520 m_pActionRefresh->setEnabled(true); 521 } 522 523 void UIMediumSelector::sltHandleRefresh() 524 { 525 /* Initialize media enumation: */ 526 vboxGlobal().startMediumEnumeration(); 527 } 528 529 void UIMediumSelector::sltHandleSearchTypeChange(int type) 530 { 531 Q_UNUSED(type); 532 performMediumSearch(); 533 } 534 535 void UIMediumSelector::sltHandleSearchTermChange(QString searchTerm) 536 { 537 Q_UNUSED(searchTerm); 538 performMediumSearch(); 539 } 540 541 void UIMediumSelector::selectMedium(const QUuid &uMediumID) 542 { 543 if (!m_pTreeWidget) 544 return; 545 UIMediumItem *pMediumItem = searchItem(0, uMediumID); 546 if (pMediumItem) 547 { 548 m_pTreeWidget->setCurrentItem(pMediumItem); 549 550 } 551 } 552 553 void UIMediumSelector::updateOkButton() 554 { 555 556 if (!m_pTreeWidget || !m_pButtonBox || !m_pButtonBox->button(QDialogButtonBox::Ok)) 557 return; 558 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 559 if (selectedItems.isEmpty()) 560 { 561 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); 562 return; 563 } 564 565 /* check if at least one of the selected items is a UIMediumItem */ 566 bool mediumItemSelected = false; 567 for (int i = 0; i < selectedItems.size() && !mediumItemSelected; ++i) 568 { 569 if (dynamic_cast<UIMediumItem*>(selectedItems.at(i))) 570 mediumItemSelected = true; 571 } 572 if (mediumItemSelected) 573 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(true); 195 m_pTableModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); 196 m_pTreeModel->setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); 197 } 198 } 199 200 void UIVisoHostBrowser::sltHandleAddButtonClicked() 201 { 202 if (!m_pTableView || !m_pTableModel) 203 return; 204 QItemSelectionModel *pSelectionModel = m_pTableView->selectionModel(); 205 if (!pSelectionModel) 206 return; 207 QModelIndexList selectedIndices = pSelectionModel->selectedRows(0); 208 QStringList pathList; 209 for (int i = 0; i < selectedIndices.size(); ++i) 210 { 211 pathList << m_pTableModel->filePath(selectedIndices[i]); 212 } 213 emit sigAddObjectsToViso(pathList); 214 } 215 216 void UIVisoHostBrowser::setTableRootIndex(QModelIndex index /* = QModelIndex */) 217 { 218 if (!m_pTreeView || !m_pTreeView->selectionModel() || !m_pTableView) 219 return; 220 QString strCurrentTreePath; 221 if (!index.isValid()) 222 { 223 QModelIndex currentTreeIndex = m_pTreeView->selectionModel()->currentIndex(); 224 strCurrentTreePath = m_pTreeModel->filePath(currentTreeIndex); 225 } 574 226 else 575 m_pButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); 576 } 577 578 void UIMediumSelector::finalize() 579 { 580 /* Apply language settings: */ 581 retranslateUi(); 582 } 583 584 void UIMediumSelector::showEvent(QShowEvent *pEvent) 585 { 586 Q_UNUSED(pEvent); 587 588 /* Try to determine the initial size: */ 589 QSize proposedSize; 590 int iHostScreen = 0; 591 if (m_pParent) 592 iHostScreen = gpDesktop->screenNumber(m_pParent); 227 strCurrentTreePath = m_pTreeModel->filePath(index); 228 if (!strCurrentTreePath.isEmpty()) 229 m_pTableView->setRootIndex(m_pTableModel->index(strCurrentTreePath)); 230 } 231 232 void UIVisoHostBrowser::setTreeCurrentIndex(QModelIndex index /* = QModelIndex() */) 233 { 234 QString strCurrentTablePath; 235 if (!index.isValid()) 236 { 237 QModelIndex currentTableIndex = m_pTableView->selectionModel()->currentIndex(); 238 strCurrentTablePath = m_pTableModel->filePath(currentTableIndex); 239 } 593 240 else 594 iHostScreen = gpDesktop->screenNumber(this); 595 if (iHostScreen >= 0 && iHostScreen < gpDesktop->screenCount()) 596 { 597 /* On the basis of current host-screen geometry if possible: */ 598 const QRect screenGeometry = gpDesktop->screenGeometry(iHostScreen); 599 if (screenGeometry.isValid()) 600 proposedSize = screenGeometry.size() * 5 / 15; 601 } 602 /* Fallback to default size if we failed: */ 603 if (proposedSize.isNull()) 604 proposedSize = QSize(800, 600); 605 /* Resize to initial size: */ 606 resize(proposedSize); 607 608 if (m_pParent) 609 VBoxGlobal::centerWidget(this, m_pParent, false); 610 611 } 612 613 void UIMediumSelector::repopulateTreeWidget() 614 { 615 if (!m_pTreeWidget) 616 return; 617 /* Cache the currently selected items: */ 618 QList<QTreeWidgetItem*> selectedItems = m_pTreeWidget->selectedItems(); 619 QList<QUuid> selectedMedia = selectedMediumIds(); 620 /* uuid list of selected items: */ 621 /* Reset the related data structure: */ 622 m_mediumItemList.clear(); 623 m_pTreeWidget->clear(); 624 m_pAttachedSubTreeRoot = 0; 625 m_pNotAttachedSubTreeRoot = 0; 626 QVector<UIMediumItem*> menuItemVector; 627 628 foreach (const QUuid &uMediumID, vboxGlobal().mediumIDs()) 629 { 630 UIMedium medium = vboxGlobal().medium(uMediumID); 631 //printf("name %s\n", qPrintable(medium.name())); 632 if (medium.type() == m_enmMediumType) 633 { 634 bool isMediumAttached = !(medium.medium().GetMachineIds().isEmpty()); 635 QITreeWidgetItem *pParent = 0; 636 if (isMediumAttached) 637 { 638 if (!m_pAttachedSubTreeRoot) 639 { 640 QStringList strList; 641 strList << "Attached"; 642 m_pAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList); 643 } 644 pParent = m_pAttachedSubTreeRoot; 645 646 } 647 else 648 { 649 if (!m_pNotAttachedSubTreeRoot) 650 { 651 QStringList strList; 652 strList << "Not Attached"; 653 m_pNotAttachedSubTreeRoot = new QITreeWidgetItem(m_pTreeWidget, strList); 654 } 655 pParent = m_pNotAttachedSubTreeRoot; 656 } 657 UIMediumItem *treeItem = addTreeItem(medium, pParent); 658 m_mediumItemList.append(treeItem); 659 menuItemVector.push_back(treeItem); 660 } 661 } 662 restoreSelection(selectedMedia, menuItemVector); 663 saveDefaultForeground(); 664 updateOkButton(); 665 if (m_pAttachedSubTreeRoot) 666 m_pTreeWidget->expandItem(m_pAttachedSubTreeRoot); 667 668 if (m_pNotAttachedSubTreeRoot) 669 m_pTreeWidget->expandItem(m_pNotAttachedSubTreeRoot); 670 671 m_pTreeWidget->resizeColumnToContents(0); 672 performMediumSearch(); 673 } 674 675 void UIMediumSelector::saveDefaultForeground() 676 { 677 if (!m_pTreeWidget) 678 return; 679 if (m_defaultItemForeground == QBrush() && m_pTreeWidget->topLevelItemCount() >= 1) 680 { 681 QTreeWidgetItem *item = m_pTreeWidget->topLevelItem(0); 682 if (item) 683 { 684 QVariant data = item->data(0, Qt::ForegroundRole); 685 if (data.canConvert<QBrush>()) 686 { 687 m_defaultItemForeground = data.value<QBrush>(); 688 } 689 } 690 } 691 } 692 693 UIMediumItem* UIMediumSelector::searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId) 694 { 695 if (!m_pTreeWidget) 696 return 0; 697 if (!pParent) 698 { 699 pParent = m_pTreeWidget->invisibleRootItem(); 700 } 701 if (!pParent) 702 return 0; 703 704 for (int i = 0; i < pParent->childCount(); ++i) 705 { 706 QTreeWidgetItem *pChild = pParent->child(i); 707 if (!pChild) 708 continue; 709 UIMediumItem *mediumItem = dynamic_cast<UIMediumItem*>(pChild); 710 if (mediumItem) 711 { 712 if (mediumItem->id() == mediumId) 713 { 714 return mediumItem; 715 } 716 } 717 UIMediumItem *pResult = searchItem(pChild, mediumId); 718 if (pResult) 719 return pResult; 720 } 721 return 0; 722 } 723 724 void UIMediumSelector::performMediumSearch() 725 { 726 if (!m_pSearchWidget || !m_pTreeWidget) 727 return; 728 /* Unmark all tree items to remove the highltights: */ 729 for (int i = 0; i < m_mediumItemList.size(); ++i) 730 { 731 for (int j = 0; j < m_pTreeWidget->columnCount(); ++j) 732 { 733 if (m_mediumItemList[i]) 734 m_mediumItemList[i]->setData(j, Qt::ForegroundRole, m_defaultItemForeground); 735 } 736 } 737 738 739 UIMediumSearchWidget::SearchType searchType = 740 m_pSearchWidget->searchType(); 741 if (searchType >= UIMediumSearchWidget::SearchByMax) 742 return; 743 QString strTerm = m_pSearchWidget->searchTerm(); 744 if (strTerm.isEmpty()) 745 return; 746 747 for (int i = 0; i < m_mediumItemList.size(); ++i) 748 { 749 if (!m_mediumItemList[i]) 750 continue; 751 QString strMedium; 752 if (searchType == UIMediumSearchWidget::SearchByName) 753 strMedium = m_mediumItemList[i]->medium().name(); 754 else if(searchType == UIMediumSearchWidget::SearchByUUID) 755 strMedium = m_mediumItemList[i]->medium().id().toString(); 756 if (strMedium.isEmpty()) 757 continue; 758 if (strMedium.contains(strTerm, Qt::CaseInsensitive)) 759 { 760 // mark the item 761 for (int j = 0; j < m_pTreeWidget->columnCount(); ++j) 762 m_mediumItemList[i]->setData(j, Qt::ForegroundRole, QBrush(QColor(255, 0, 0))); 763 } 764 } 765 } 766 767 #include "UIMediumSelector.moc" 241 strCurrentTablePath = m_pTableModel->filePath(index); 242 m_pTreeView->setCurrentIndex(m_pTreeModel->index(strCurrentTablePath)); 243 } 244 245 246 #include "UIVisoHostBrowser.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/medium/viso/UIVisoHostBrowser.h
r76607 r76671 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UI MediumSelector class declaration.3 * VBox Qt GUI - UIVisoHostBrowser class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h19 #define FEQT_INCLUDED_SRC_medium_ UIMediumSelector_h18 #ifndef FEQT_INCLUDED_SRC_medium_viso_UIVisoHostBrowser_h 19 #define FEQT_INCLUDED_SRC_medium_viso_UIVisoHostBrowser_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once 22 22 #endif 23 23 24 25 /* Qt includes: */ 26 # include <QModelIndex> 27 24 28 /* GUI includes: */ 25 #include "QIDialog.h"26 29 #include "QIWithRetranslateUI.h" 27 #include "UIMedium.h" 28 #include "UIMediumDefs.h" 29 #include "UIMediumDetailsWidget.h" 30 #include "UIVisoBrowserBase.h" 30 31 31 32 /* Forward declarations: */ 32 class QAction; 33 class QTreeWidgetItem; 34 class QITreeWidget; 35 class QITreeWidgetItem; 36 class QVBoxLayout; 37 class QIDialogButtonBox; 38 class UIMediumItem; 39 class UIMediumSearchWidget; 40 class UIToolBar; 33 class QItemSelection; 34 class UIVisoHostBrowserModel; 41 35 42 43 /** QIDialog extension providing GUI with a dialog to select an existing medium. */ 44 class SHARED_LIBRARY_STUFF UIMediumSelector : public QIWithRetranslateUI<QIDialog> 36 /** A QWidget extension. */ 37 class SHARED_LIBRARY_STUFF UIVisoHostBrowser : public QIWithRetranslateUI<UIVisoBrowserBase> 45 38 { 46 47 39 Q_OBJECT; 48 40 49 41 signals: 50 42 43 void sigAddObjectsToViso(QStringList pathList); 44 51 45 public: 52 46 53 UI MediumSelector(UIMediumDeviceType enmMediumType, const QString &machineName = QString(),54 const QString &machineSettigFilePath = QString(), QWidget *pParent = 0);55 QList<QUuid> selectedMediumIds() const;47 UIVisoHostBrowser(QWidget *pParent = 0); 48 ~UIVisoHostBrowser(); 49 virtual void showHideHiddenObjects(bool bShow) /* override */; 56 50 57 51 protected: 58 52 59 void showEvent(QShowEvent *pEvent); 53 void retranslateUi(); 54 virtual void tableViewItemDoubleClick(const QModelIndex &index) /* override */; 55 virtual void setTableRootIndex(QModelIndex index = QModelIndex()) /* override */; 56 virtual void setTreeCurrentIndex(QModelIndex index = QModelIndex()) /* override */; 57 58 virtual void treeSelectionChanged(const QModelIndex &selectedTreeIndex) /* override */; 60 59 61 60 private slots: 62 61 63 void sltAddMedium(); 64 void sltCreateMedium(); 65 void sltHandleItemSelectionChanged(); 66 void sltHandleTreeWidgetDoubleClick(QTreeWidgetItem * item, int column); 67 void sltHandleMediumEnumerationStart(); 68 void sltHandleMediumEnumerated(); 69 void sltHandleMediumEnumerationFinish(); 70 void sltHandleRefresh(); 71 void sltHandleSearchTypeChange(int type); 72 void sltHandleSearchTermChange(QString searchTerm); 62 void sltHandleTableSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); 63 void sltHandleAddButtonClicked(); 73 64 74 65 private: 75 66 67 void prepareObjects(); 68 void prepareConnections(); 76 69 77 /** @name Event-handling stuff. 78 * @{ */ 79 /** Handles translation event. */ 80 virtual void retranslateUi() /* override */; 81 /** @} */ 82 83 /** @name Prepare/cleanup cascade. 84 * @{ */ 85 /** Configures all. */ 86 void configure(); 87 void prepareWidgets(); 88 void prepareActions(); 89 void prepareConnections(); 90 /** Perform final preparations. */ 91 void finalize(); 92 /** @} */ 93 94 void repopulateTreeWidget(); 95 /** Disable/enable 'ok' button on the basis of having a selected item */ 96 void updateOkButton(); 97 UIMediumItem* addTreeItem(const UIMedium &medium, QITreeWidgetItem *pParent); 98 void restoreSelection(const QList<QUuid> &selectedMediums, QVector<UIMediumItem*> &mediumList); 99 /** Recursively create the hard disk hierarchy under the tree widget */ 100 UIMediumItem* createHardDiskItem(const UIMedium &medium, QITreeWidgetItem *pParent); 101 UIMediumItem* searchItem(const QTreeWidgetItem *pParent, const QUuid &mediumId); 102 void performMediumSearch(); 103 /** Remember the default foreground brush of the tree so that we can reset tree items' foreground later */ 104 void saveDefaultForeground(); 105 void selectMedium(const QUuid &uMediumID); 106 107 QVBoxLayout *m_pMainLayout; 108 QITreeWidget *m_pTreeWidget; 109 UIMediumDeviceType m_enmMediumType; 110 QIDialogButtonBox *m_pButtonBox; 111 UIToolBar *m_pToolBar; 112 QAction *m_pActionAdd; 113 QAction *m_pActionCreate; 114 QAction *m_pActionRefresh; 115 /** All the known media that are already attached to some vm are added under the following top level tree item */ 116 QITreeWidgetItem *m_pAttachedSubTreeRoot; 117 /** All the known media that are not attached to any vm are added under the following top level tree item */ 118 QITreeWidgetItem *m_pNotAttachedSubTreeRoot; 119 QWidget *m_pParent; 120 UIMediumSearchWidget *m_pSearchWidget; 121 QList<UIMediumItem*> m_mediumItemList; 122 QBrush m_defaultItemForeground; 123 QString m_strMachineSettingsFilePath; 124 QString m_strMachineName; 70 /** We have two file system models (one for each item view) since we set different filter on each of these models. */ 71 UIVisoHostBrowserModel *m_pTreeModel; 72 UIVisoHostBrowserModel *m_pTableModel; 125 73 }; 126 74 127 #endif /* !FEQT_INCLUDED_SRC_medium_UIMediumSelector_h */ 75 76 #endif /* !FEQT_INCLUDED_SRC_medium_viso_UIVisoHostBrowser_h */
Note:
See TracChangeset
for help on using the changeset viewer.