VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp@ 37126

Last change on this file since 37126 was 37126, checked in by vboxsync, 13 years ago

FE/Qt: 3887: Make certain settings editable during runtime: Fix availability states for all VM settings pages for switching between online and offline modes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 30.9 KB
Line 
1/* $Id: UIMachineSettingsSF.cpp 37126 2011-05-17 13:56:50Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt4 GUI ("VirtualBox"):
5 * UIMachineSettingsSF class implementation
6 */
7
8/*
9 * Copyright (C) 2008-2011 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* Local includes */
21#include "UIIconPool.h"
22#include "VBoxGlobal.h"
23#include "VBoxProblemReporter.h"
24#include "VBoxUtils.h"
25#include "UIMachineSettingsSF.h"
26#include "UIMachineSettingsSFDetails.h"
27
28/* Global includes */
29#include <QHeaderView>
30#include <QTimer>
31
32class SFTreeViewItem : public QTreeWidgetItem
33{
34public:
35
36 enum { SFTreeViewItemType = QTreeWidgetItem::UserType + 1 };
37
38 enum FormatType
39 {
40 IncorrectFormat = 0,
41 EllipsisStart = 1,
42 EllipsisMiddle = 2,
43 EllipsisEnd = 3,
44 EllipsisFile = 4
45 };
46
47 /* Root Item */
48 SFTreeViewItem (QTreeWidget *aParent, const QStringList &aFields, FormatType aFormat)
49 : QTreeWidgetItem (aParent, aFields, SFTreeViewItemType), mFormat (aFormat)
50 {
51 setFirstColumnSpanned (true);
52 setFlags (flags() ^ Qt::ItemIsSelectable);
53 }
54
55 /* Child Item */
56 SFTreeViewItem (SFTreeViewItem *aParent, const QStringList &aFields, FormatType aFormat)
57 : QTreeWidgetItem (aParent, aFields, SFTreeViewItemType), mFormat (aFormat)
58 {
59 updateText (aFields);
60 }
61
62 bool operator< (const QTreeWidgetItem &aOther) const
63 {
64 /* Root items should always been sorted by id-field. */
65 return parent() ? text (0).toLower() < aOther.text (0).toLower() :
66 text (1).toLower() < aOther.text (1).toLower();
67 }
68
69 SFTreeViewItem* child (int aIndex) const
70 {
71 QTreeWidgetItem *item = QTreeWidgetItem::child (aIndex);
72 return item && item->type() == SFTreeViewItemType ? static_cast <SFTreeViewItem*> (item) : 0;
73 }
74
75 QString getText (int aIndex) const
76 {
77 return aIndex >= 0 && aIndex < (int)mTextList.size() ? mTextList [aIndex] : QString::null;
78 }
79
80 void updateText (const QStringList &aFields)
81 {
82 mTextList.clear();
83 mTextList << aFields;
84 adjustText();
85 }
86
87 void adjustText()
88 {
89 for (int i = 0; i < treeWidget()->columnCount(); ++ i)
90 processColumn (i);
91 }
92
93private:
94
95 void processColumn (int aColumn)
96 {
97 QString oneString = getText (aColumn);
98 if (oneString.isNull())
99 return;
100 QFontMetrics fm = treeWidget()->fontMetrics();
101 int oldSize = fm.width (oneString);
102 int indentSize = fm.width (" ... ");
103 int itemIndent = parent() ? treeWidget()->indentation() * 2 : treeWidget()->indentation();
104 if (aColumn == 0)
105 indentSize += itemIndent;
106 int cWidth = treeWidget()->columnWidth (aColumn);
107
108 /* Compress text */
109 int start = 0;
110 int finish = 0;
111 int position = 0;
112 int textWidth = 0;
113 do
114 {
115 textWidth = fm.width (oneString);
116 if (textWidth + indentSize > cWidth)
117 {
118 start = 0;
119 finish = oneString.length();
120
121 /* Selecting remove position */
122 switch (mFormat)
123 {
124 case EllipsisStart:
125 position = start;
126 break;
127 case EllipsisMiddle:
128 position = (finish - start) / 2;
129 break;
130 case EllipsisEnd:
131 position = finish - 1;
132 break;
133 case EllipsisFile:
134 {
135 QRegExp regExp ("([\\\\/][^\\\\^/]+[\\\\/]?$)");
136 int newFinish = regExp.indexIn (oneString);
137 if (newFinish != -1)
138 finish = newFinish;
139 position = (finish - start) / 2;
140 break;
141 }
142 default:
143 AssertMsgFailed (("Invalid format type\n"));
144 }
145
146 if (position == finish)
147 break;
148
149 oneString.remove (position, 1);
150 }
151 }
152 while (textWidth + indentSize > cWidth);
153
154 if (position || mFormat == EllipsisFile) oneString.insert (position, "...");
155 int newSize = fm.width (oneString);
156 setText (aColumn, newSize < oldSize ? oneString : mTextList [aColumn]);
157 setToolTip (aColumn, text (aColumn) == getText (aColumn) ? QString::null : getText (aColumn));
158
159 /* Calculate item's size-hint */
160 setSizeHint (aColumn, QSize (fm.width (QString (" %1 ").arg (getText (aColumn))), 100));
161 }
162
163 FormatType mFormat;
164 QStringList mTextList;
165};
166
167UIMachineSettingsSF::UIMachineSettingsSF()
168 : mNewAction(0), mEdtAction(0), mDelAction(0)
169{
170 /* Apply UI decorations */
171 Ui::UIMachineSettingsSF::setupUi (this);
172
173 /* Prepare actions */
174 mNewAction = new QAction (this);
175 mEdtAction = new QAction (this);
176 mDelAction = new QAction (this);
177
178 mNewAction->setShortcut (QKeySequence ("Ins"));
179 mEdtAction->setShortcut (QKeySequence ("Ctrl+Space"));
180 mDelAction->setShortcut (QKeySequence ("Del"));
181
182 mNewAction->setIcon(UIIconPool::iconSet(":/add_shared_folder_16px.png",
183 ":/add_shared_folder_disabled_16px.png"));
184 mEdtAction->setIcon(UIIconPool::iconSet(":/edit_shared_folder_16px.png",
185 ":/edit_shared_folder_disabled_16px.png"));
186 mDelAction->setIcon(UIIconPool::iconSet(":/remove_shared_folder_16px.png",
187 ":/remove_shared_folder_disabled_16px.png"));
188
189 /* Prepare toolbar */
190 mTbFolders->setUsesTextLabel (false);
191 mTbFolders->setIconSize (QSize (16, 16));
192 mTbFolders->setOrientation (Qt::Vertical);
193 mTbFolders->addAction (mNewAction);
194 mTbFolders->addAction (mEdtAction);
195 mTbFolders->addAction (mDelAction);
196
197 /* Setup connections */
198 mTwFolders->header()->setMovable (false);
199 connect (mNewAction, SIGNAL (triggered (bool)), this, SLOT (addTriggered()));
200 connect (mEdtAction, SIGNAL (triggered (bool)), this, SLOT (edtTriggered()));
201 connect (mDelAction, SIGNAL (triggered (bool)), this, SLOT (delTriggered()));
202 connect (mTwFolders, SIGNAL (currentItemChanged (QTreeWidgetItem *, QTreeWidgetItem *)),
203 this, SLOT (processCurrentChanged (QTreeWidgetItem *)));
204 connect (mTwFolders, SIGNAL (itemDoubleClicked (QTreeWidgetItem *, int)),
205 this, SLOT (processDoubleClick (QTreeWidgetItem *)));
206 connect (mTwFolders, SIGNAL (customContextMenuRequested (const QPoint &)),
207 this, SLOT (showContextMenu (const QPoint &)));
208
209 retranslateUi();
210}
211
212void UIMachineSettingsSF::resizeEvent (QResizeEvent *aEvent)
213{
214 NOREF(aEvent);
215 adjustList();
216}
217
218/* Load data to cashe from corresponding external object(s),
219 * this task COULD be performed in other than GUI thread: */
220void UIMachineSettingsSF::loadToCacheFrom(QVariant &data)
221{
222 /* Fetch data to machine: */
223 UISettingsPageMachine::fetchData(data);
224
225 /* Clear cache initially: */
226 m_cache.clear();
227
228 /* Load machine (permanent) shared folders into shared folders cache if possible: */
229 if (isSharedFolderTypeSupported(MachineType))
230 loadToCacheFrom(MachineType);
231 /* Load console (temporary) shared folders into shared folders cache if possible: */
232 if (isSharedFolderTypeSupported(ConsoleType))
233 loadToCacheFrom(ConsoleType);
234
235 /* Upload machine to data: */
236 UISettingsPageMachine::uploadData(data);
237}
238
239void UIMachineSettingsSF::loadToCacheFrom(UISharedFolderType sharedFoldersType)
240{
241 /* Get current shared folders: */
242 CSharedFolderVector sharedFolders = getSharedFolders(sharedFoldersType);
243
244 /* For each shared folder: */
245 for (int iFolderIndex = 0; iFolderIndex < sharedFolders.size(); ++iFolderIndex)
246 {
247 /* Prepare cache key & data: */
248 QString strSharedFolderKey = QString::number(iFolderIndex);
249 UIDataSettingsSharedFolder sharedFolderData;
250
251 /* Check if shared folder exists: */
252 const CSharedFolder &folder = sharedFolders[iFolderIndex];
253 if (!folder.isNull())
254 {
255 /* Gather shared folder values: */
256 sharedFolderData.m_type = sharedFoldersType;
257 sharedFolderData.m_strName = folder.GetName();
258 sharedFolderData.m_strHostPath = folder.GetHostPath();
259 sharedFolderData.m_fAutoMount = folder.GetAutoMount();
260 sharedFolderData.m_fWritable = folder.GetWritable();
261 /* Override shared folder cache key: */
262 strSharedFolderKey = sharedFolderData.m_strName;
263 }
264
265 /* Cache shared folder data: */
266 m_cache.child(strSharedFolderKey).cacheInitialData(sharedFolderData);
267 }
268}
269
270/* Load data to corresponding widgets from cache,
271 * this task SHOULD be performed in GUI thread only: */
272void UIMachineSettingsSF::getFromCache()
273{
274 /* Clear list initially: */
275 mTwFolders->clear();
276
277 /* Update root items visibility: */
278 updateRootItemsVisibility();
279
280 /* Load shared folders data: */
281 for (int iFolderIndex = 0; iFolderIndex < m_cache.childCount(); ++iFolderIndex)
282 {
283 /* Get shared folder data: */
284 const UIDataSettingsSharedFolder &sharedFolderData = m_cache.child(iFolderIndex).base();
285 /* Prepare item fields: */
286 QStringList fields;
287 fields << sharedFolderData.m_strName
288 << sharedFolderData.m_strHostPath
289 << (sharedFolderData.m_fAutoMount ? mTrYes : "")
290 << (sharedFolderData.m_fWritable ? mTrFull : mTrReadOnly);
291 /* Create new shared folders item: */
292 new SFTreeViewItem(root(sharedFolderData.m_type), fields, SFTreeViewItem::EllipsisFile);
293 }
294 /* Ensure current item fetched: */
295 mTwFolders->setCurrentItem(mTwFolders->topLevelItem(0));
296 processCurrentChanged(mTwFolders->currentItem());
297
298 /* Polish page finally: */
299 polishPage();
300}
301
302/* Save data from corresponding widgets to cache,
303 * this task SHOULD be performed in GUI thread only: */
304void UIMachineSettingsSF::putToCache()
305{
306 /* For each shared folder type: */
307 QTreeWidgetItem *pMainRootItem = mTwFolders->invisibleRootItem();
308 for (int iFodlersTypeIndex = 0; iFodlersTypeIndex < pMainRootItem->childCount(); ++iFodlersTypeIndex)
309 {
310 /* Get shared folder root item: */
311 SFTreeViewItem *pFolderTypeRoot = static_cast<SFTreeViewItem*>(pMainRootItem->child(iFodlersTypeIndex));
312 UISharedFolderType sharedFolderType = (UISharedFolderType)pFolderTypeRoot->text(1).toInt();
313 /* For each shared folder of current type: */
314 for (int iFoldersIndex = 0; iFoldersIndex < pFolderTypeRoot->childCount(); ++iFoldersIndex)
315 {
316 SFTreeViewItem *pFolderItem = static_cast<SFTreeViewItem*>(pFolderTypeRoot->child(iFoldersIndex));
317 UIDataSettingsSharedFolder sharedFolderData;
318 sharedFolderData.m_type = sharedFolderType;
319 sharedFolderData.m_strName = pFolderItem->getText(0);
320 sharedFolderData.m_strHostPath = pFolderItem->getText(1);
321 sharedFolderData.m_fAutoMount = pFolderItem->getText(2) == mTrYes ? true : false;
322 sharedFolderData.m_fWritable = pFolderItem->getText(3) == mTrFull ? true : false;
323 m_cache.child(sharedFolderData.m_strName).cacheCurrentData(sharedFolderData);
324 }
325 }
326}
327
328/* Save data from cache to corresponding external object(s),
329 * this task COULD be performed in other than GUI thread: */
330void UIMachineSettingsSF::saveFromCacheTo(QVariant &data)
331{
332 /* Fetch data to machine: */
333 UISettingsPageMachine::fetchData(data);
334
335 /* Check if shared folders data was changed at all: */
336 if (m_cache.wasChanged())
337 {
338 /* Save machine (permanent) shared folders if possible: */
339 if (isSharedFolderTypeSupported(MachineType))
340 saveFromCacheTo(MachineType);
341 /* Save console (temporary) shared folders if possible: */
342 if (isSharedFolderTypeSupported(ConsoleType))
343 saveFromCacheTo(ConsoleType);
344 }
345
346 /* Upload machine to data: */
347 UISettingsPageMachine::uploadData(data);
348}
349
350void UIMachineSettingsSF::saveFromCacheTo(UISharedFolderType sharedFoldersType)
351{
352 /* For each shared folder data set: */
353 for (int iSharedFolderIndex = 0; iSharedFolderIndex < m_cache.childCount(); ++iSharedFolderIndex)
354 {
355 /* Check if this shared folder data was actually changed: */
356 const UICacheSettingsSharedFolder &sharedFolderCache = m_cache.child(iSharedFolderIndex);
357 if (sharedFolderCache.wasChanged())
358 {
359 /* If shared folder was removed: */
360 if (sharedFolderCache.wasRemoved())
361 {
362 /* Get shared folder data: */
363 const UIDataSettingsSharedFolder &sharedFolderData = sharedFolderCache.base();
364 /* Check if thats shared folder of required type before removing: */
365 if (sharedFolderData.m_type == sharedFoldersType)
366 removeSharedFolder(sharedFolderCache);
367 }
368
369 /* If shared folder was created: */
370 if (sharedFolderCache.wasCreated())
371 {
372 /* Get shared folder data: */
373 const UIDataSettingsSharedFolder &sharedFolderData = sharedFolderCache.data();
374 /* Check if thats shared folder of required type before creating: */
375 if (sharedFolderData.m_type == sharedFoldersType)
376 createSharedFolder(sharedFolderCache);
377 }
378
379 /* If shared folder was changed: */
380 if (sharedFolderCache.wasUpdated())
381 {
382 /* Get shared folder data: */
383 const UIDataSettingsSharedFolder &sharedFolderData = sharedFolderCache.data();
384 /* Check if thats shared folder of required type before recreating: */
385 if (sharedFolderData.m_type == sharedFoldersType)
386 {
387 removeSharedFolder(sharedFolderCache);
388 createSharedFolder(sharedFolderCache);
389 }
390 }
391 }
392 }
393}
394
395void UIMachineSettingsSF::setOrderAfter (QWidget *aWidget)
396{
397 setTabOrder (aWidget, mTwFolders);
398}
399
400void UIMachineSettingsSF::retranslateUi()
401{
402 /* Translate uic generated strings */
403 Ui::UIMachineSettingsSF::retranslateUi (this);
404
405 mNewAction->setText (tr ("&Add Shared Folder"));
406 mEdtAction->setText (tr ("&Edit Shared Folder"));
407 mDelAction->setText (tr ("&Remove Shared Folder"));
408
409 mNewAction->setToolTip (mNewAction->text().remove ('&') +
410 QString (" (%1)").arg (mNewAction->shortcut().toString()));
411 mEdtAction->setToolTip (mEdtAction->text().remove ('&') +
412 QString (" (%1)").arg (mEdtAction->shortcut().toString()));
413 mDelAction->setToolTip (mDelAction->text().remove ('&') +
414 QString (" (%1)").arg (mDelAction->shortcut().toString()));
415
416 mNewAction->setWhatsThis (tr ("Adds a new shared folder definition."));
417 mEdtAction->setWhatsThis (tr ("Edits the selected shared folder definition."));
418 mDelAction->setWhatsThis (tr ("Removes the selected shared folder definition."));
419
420 mTrFull = tr ("Full");
421 mTrReadOnly = tr ("Read-only");
422 mTrYes = tr ("Yes"); /** @todo Need to figure out if this string is necessary at all! */
423}
424
425void UIMachineSettingsSF::addTriggered()
426{
427 /* Invoke Add-Box Dialog */
428 UIMachineSettingsSFDetails dlg (UIMachineSettingsSFDetails::AddType, isSharedFolderTypeSupported(ConsoleType), usedList (true), this);
429 if (dlg.exec() == QDialog::Accepted)
430 {
431 QString name = dlg.name();
432 QString path = dlg.path();
433 bool isPermanent = dlg.isPermanent();
434 /* Shared folder's name & path could not be empty */
435 Assert (!name.isEmpty() && !path.isEmpty());
436 /* Appending a new listview item to the root */
437 QStringList fields;
438 fields << name /* name */ << path /* path */
439 << (dlg.isAutoMounted() ? mTrYes : "" /* auto mount? */)
440 << (dlg.isWriteable() ? mTrFull : mTrReadOnly /* writable? */);
441 SFTreeViewItem *item = new SFTreeViewItem (root(isPermanent ? MachineType : ConsoleType),
442 fields, SFTreeViewItem::EllipsisFile);
443 mTwFolders->sortItems (0, Qt::AscendingOrder);
444 mTwFolders->scrollToItem (item);
445 mTwFolders->setCurrentItem (item);
446 processCurrentChanged (item);
447 mTwFolders->setFocus();
448 adjustList();
449 }
450}
451
452void UIMachineSettingsSF::edtTriggered()
453{
454 /* Check selected item */
455 QTreeWidgetItem *selectedItem = mTwFolders->selectedItems().size() == 1 ? mTwFolders->selectedItems() [0] : 0;
456 SFTreeViewItem *item = selectedItem && selectedItem->type() == SFTreeViewItem::SFTreeViewItemType ?
457 static_cast <SFTreeViewItem*> (selectedItem) : 0;
458 Assert (item);
459 Assert (item->parent());
460
461 /* Invoke Edit-Box Dialog */
462 UIMachineSettingsSFDetails dlg (UIMachineSettingsSFDetails::EditType, isSharedFolderTypeSupported(ConsoleType), usedList (false), this);
463 dlg.setPath (item->getText (1));
464 dlg.setName (item->getText (0));
465 dlg.setPermanent ((UISharedFolderType)item->parent()->text (1).toInt() != ConsoleType);
466 dlg.setAutoMount (item->getText (2) == mTrYes);
467 dlg.setWriteable (item->getText (3) == mTrFull);
468 if (dlg.exec() == QDialog::Accepted)
469 {
470 QString name = dlg.name();
471 QString path = dlg.path();
472 bool isPermanent = dlg.isPermanent();
473 /* Shared folder's name & path could not be empty */
474 Assert (!name.isEmpty() && !path.isEmpty());
475 /* Searching new root for the selected listview item */
476 SFTreeViewItem *pRoot = root(isPermanent ? MachineType : ConsoleType);
477 /* Updating an edited listview item */
478 QStringList fields;
479 fields << name /* name */ << path /* path */
480 << (dlg.isAutoMounted() ? mTrYes : "" /* auto mount? */)
481 << (dlg.isWriteable() ? mTrFull : mTrReadOnly /* writable? */);
482 item->updateText (fields);
483 mTwFolders->sortItems (0, Qt::AscendingOrder);
484 if (item->parent() != pRoot)
485 {
486 /* Move the selected item into new location */
487 item->parent()->takeChild (item->parent()->indexOfChild (item));
488 pRoot->insertChild (pRoot->childCount(), item);
489 mTwFolders->scrollToItem (item);
490 mTwFolders->setCurrentItem (item);
491 processCurrentChanged (item);
492 mTwFolders->setFocus();
493 }
494 adjustList();
495 }
496}
497
498void UIMachineSettingsSF::delTriggered()
499{
500 QTreeWidgetItem *selectedItem = mTwFolders->selectedItems().size() == 1 ? mTwFolders->selectedItems() [0] : 0;
501 Assert (selectedItem);
502 delete selectedItem;
503 adjustList();
504}
505
506void UIMachineSettingsSF::processCurrentChanged (QTreeWidgetItem *aCurrentItem)
507{
508 if (aCurrentItem && aCurrentItem->parent() && !aCurrentItem->isSelected())
509 aCurrentItem->setSelected (true);
510 QString key = !aCurrentItem ? QString::null : aCurrentItem->parent() ?
511 aCurrentItem->parent()->text (1) : aCurrentItem->text (1);
512 bool addEnabled = aCurrentItem;
513 bool removeEnabled = addEnabled && aCurrentItem->parent();
514 mNewAction->setEnabled (addEnabled);
515 mEdtAction->setEnabled (removeEnabled);
516 mDelAction->setEnabled (removeEnabled);
517}
518
519void UIMachineSettingsSF::processDoubleClick (QTreeWidgetItem *aItem)
520{
521 bool editEnabled = aItem && aItem->parent();
522 if (editEnabled)
523 edtTriggered();
524}
525
526void UIMachineSettingsSF::showContextMenu(const QPoint &pos)
527{
528 QMenu menu;
529 QTreeWidgetItem *pItem = mTwFolders->itemAt(pos);
530 if (mTwFolders->isEnabled() && pItem && pItem->flags() & Qt::ItemIsSelectable)
531 {
532 menu.addAction(mEdtAction);
533 menu.addAction(mDelAction);
534 }
535 else
536 {
537 menu.addAction(mNewAction);
538 }
539 if (!menu.isEmpty())
540 menu.exec(mTwFolders->viewport()->mapToGlobal(pos));
541}
542
543void UIMachineSettingsSF::adjustList()
544{
545 /*
546 * Calculates required columns sizes to max out column 2
547 * and let all other columns stay at their minimum sizes.
548 *
549 * Columns
550 * 0 = Tree view
551 * 1 = Shared Folder name
552 * 2 = Auto-mount flag
553 * 3 = Writable flag
554 */
555 QAbstractItemView *itemView = mTwFolders;
556 QHeaderView *itemHeader = mTwFolders->header();
557 int total = mTwFolders->viewport()->width();
558
559 int mw0 = qMax (itemView->sizeHintForColumn (0), itemHeader->sectionSizeHint (0));
560 int mw2 = qMax (itemView->sizeHintForColumn (2), itemHeader->sectionSizeHint (2));
561 int mw3 = qMax (itemView->sizeHintForColumn (3), itemHeader->sectionSizeHint (3));
562
563 int w0 = mw0 < total / 4 ? mw0 : total / 4;
564 int w2 = mw2 < total / 4 ? mw2 : total / 4;
565 int w3 = mw3 < total / 4 ? mw3 : total / 4;
566
567 /* Giving 1st column all the available space. */
568 mTwFolders->setColumnWidth (0, w0);
569 mTwFolders->setColumnWidth (1, total - w0 - w2 - w3);
570 mTwFolders->setColumnWidth (2, w2);
571 mTwFolders->setColumnWidth (3, w3);
572}
573
574void UIMachineSettingsSF::adjustFields()
575{
576 QTreeWidgetItem *mainRoot = mTwFolders->invisibleRootItem();
577 for (int i = 0; i < mainRoot->childCount(); ++ i)
578 {
579 QTreeWidgetItem *subRoot = mainRoot->child (i);
580 for (int j = 0; j < subRoot->childCount(); ++ j)
581 {
582 SFTreeViewItem *item = subRoot->child (j) &&
583 subRoot->child (j)->type() == SFTreeViewItem::SFTreeViewItemType ?
584 static_cast <SFTreeViewItem*> (subRoot->child (j)) : 0;
585 if (item)
586 item->adjustText();
587 }
588 }
589}
590
591void UIMachineSettingsSF::showEvent (QShowEvent *aEvent)
592{
593 UISettingsPageMachine::showEvent (aEvent);
594
595 /* Connect header-resize signal just before widget is shown after all the items properly loaded and initialized. */
596 connect (mTwFolders->header(), SIGNAL (sectionResized (int, int, int)), this, SLOT (adjustFields()));
597
598 /* Adjusting size after all pending show events are processed. */
599 QTimer::singleShot (0, this, SLOT (adjustList()));
600}
601
602SFTreeViewItem* UIMachineSettingsSF::root(UISharedFolderType sharedFolderType)
603{
604 /* Search for the corresponding root item among all the top-level items: */
605 SFTreeViewItem *pRootItem = 0;
606 QTreeWidgetItem *pMainRootItem = mTwFolders->invisibleRootItem();
607 for (int iFolderTypeIndex = 0; iFolderTypeIndex < pMainRootItem->childCount(); ++iFolderTypeIndex)
608 {
609 /* Get iterated item: */
610 QTreeWidgetItem *pIteratedItem = pMainRootItem->child(iFolderTypeIndex);
611 /* If iterated item type is what we are looking for: */
612 if (pIteratedItem->text(1).toInt() == sharedFolderType)
613 {
614 /* Remember the item: */
615 pRootItem = static_cast<SFTreeViewItem*>(pIteratedItem);
616 /* And break further search: */
617 break;
618 }
619 }
620 /* Return root item: */
621 return pRootItem;
622}
623
624SFoldersNameList UIMachineSettingsSF::usedList (bool aIncludeSelected)
625{
626 /* Make the used names list: */
627 SFoldersNameList list;
628 QTreeWidgetItemIterator it (mTwFolders);
629 while (*it)
630 {
631 if ((*it)->parent() && (aIncludeSelected || !(*it)->isSelected()) &&
632 (*it)->type() == SFTreeViewItem::SFTreeViewItemType)
633 {
634 SFTreeViewItem *item = static_cast <SFTreeViewItem*> (*it);
635 UISharedFolderType type = (UISharedFolderType) item->parent()->text (1).toInt();
636 list << qMakePair (item->getText (0), type);
637 }
638 ++ it;
639 }
640 return list;
641}
642
643bool UIMachineSettingsSF::isSharedFolderTypeSupported(UISharedFolderType sharedFolderType) const
644{
645 bool fIsSharedFolderTypeSupported = false;
646 switch (sharedFolderType)
647 {
648 case MachineType:
649 fIsSharedFolderTypeSupported = isMachineInValidMode();
650 break;
651 case ConsoleType:
652 fIsSharedFolderTypeSupported = isMachineSaved() || isMachineOnline();
653 break;
654 default:
655 break;
656 }
657 return fIsSharedFolderTypeSupported;
658}
659
660void UIMachineSettingsSF::updateRootItemsVisibility()
661{
662 /* Update (show/hide) machine (permanent) root item: */
663 setRootItemVisible(MachineType, isSharedFolderTypeSupported(MachineType));
664 /* Update (show/hide) console (temporary) root item: */
665 setRootItemVisible(ConsoleType, isSharedFolderTypeSupported(ConsoleType));
666}
667
668void UIMachineSettingsSF::setRootItemVisible(UISharedFolderType sharedFolderType, bool fVisible)
669{
670 /* Search for the corresponding root item among all the top-level items: */
671 SFTreeViewItem *pRootItem = root(sharedFolderType);
672 /* If root item, we are looking for, still not found: */
673 if (!pRootItem)
674 {
675 /* Prepare fields for the new root item: */
676 QStringList fields;
677 /* Depending on folder type: */
678 switch (sharedFolderType)
679 {
680 case MachineType:
681 fields << tr(" Machine Folders") << QString::number(MachineType);
682 break;
683 case ConsoleType:
684 fields << tr(" Transient Folders") << QString::number(ConsoleType);
685 break;
686 default:
687 break;
688 }
689 /* And create the new root item: */
690 pRootItem = new SFTreeViewItem(mTwFolders, fields, SFTreeViewItem::EllipsisEnd);
691 }
692 /* Expand/collaps it if necessary: */
693 pRootItem->setExpanded(fVisible);
694 /* And hide/show it if necessary: */
695 pRootItem->setHidden(!fVisible);
696}
697
698void UIMachineSettingsSF::polishPage()
699{
700 /* Update widgets availability: */
701 mNameSeparator->setEnabled(isMachineInValidMode());
702 mTwFolders->setEnabled(isMachineInValidMode());
703 mTbFolders->setEnabled(isMachineInValidMode());
704
705 /* Update root items visibility: */
706 updateRootItemsVisibility();
707}
708
709CSharedFolderVector UIMachineSettingsSF::getSharedFolders(UISharedFolderType sharedFoldersType)
710{
711 CSharedFolderVector sharedFolders;
712 if (isSharedFolderTypeSupported(sharedFoldersType))
713 {
714 switch (sharedFoldersType)
715 {
716 case MachineType:
717 {
718 AssertMsg(!m_machine.isNull(), ("Machine is NOT set!\n"));
719 sharedFolders = m_machine.GetSharedFolders();
720 break;
721 }
722 case ConsoleType:
723 {
724 AssertMsg(!m_console.isNull(), ("Console is NOT set!\n"));
725 sharedFolders = m_console.GetSharedFolders();
726 break;
727 }
728 default:
729 break;
730 }
731 }
732 return sharedFolders;
733}
734
735bool UIMachineSettingsSF::removeSharedFolder(const UICacheSettingsSharedFolder &folderCache)
736{
737 /* Get shared folder data: */
738 const UIDataSettingsSharedFolder &folderData = folderCache.base();
739 QString strName = folderData.m_strName;
740 QString strPath = folderData.m_strHostPath;
741 UISharedFolderType sharedFoldersType = folderData.m_type;
742
743 /* Get current shared folders: */
744 CSharedFolderVector sharedFolders = getSharedFolders(sharedFoldersType);
745 /* Check that such shared folder really exists: */
746 CSharedFolder sharedFolder;
747 for (int iSharedFolderIndex = 0; iSharedFolderIndex < sharedFolders.size(); ++iSharedFolderIndex)
748 if (sharedFolders[iSharedFolderIndex].GetName() == strName)
749 sharedFolder = sharedFolders[iSharedFolderIndex];
750 if (!sharedFolder.isNull())
751 {
752 /* Remove existing shared folder: */
753 switch(sharedFoldersType)
754 {
755 case MachineType:
756 {
757 m_machine.RemoveSharedFolder(strName);
758 if (!m_machine.isOk())
759 {
760 /* Mark the page as failed: */
761 setFailed(true);
762 /* Show error message: */
763 vboxProblem().cannotRemoveSharedFolder(m_machine, strName, strPath);
764 /* Finish early: */
765 return false;
766 }
767 break;
768 }
769 case ConsoleType:
770 {
771 m_console.RemoveSharedFolder(strName);
772 if (!m_console.isOk())
773 {
774 /* Mark the page as failed: */
775 setFailed(true);
776 /* Show error message: */
777 vboxProblem().cannotRemoveSharedFolder(m_console, strName, strPath);
778 /* Finish early: */
779 return false;
780 }
781 break;
782 }
783 default:
784 break;
785 }
786 }
787 return true;
788}
789
790bool UIMachineSettingsSF::createSharedFolder(const UICacheSettingsSharedFolder &folderCache)
791{
792 /* Get shared folder data: */
793 const UIDataSettingsSharedFolder &folderData = folderCache.data();
794 QString strName = folderData.m_strName;
795 QString strPath = folderData.m_strHostPath;
796 bool fIsWritable = folderData.m_fWritable;
797 bool fIsAutoMount = folderData.m_fAutoMount;
798 UISharedFolderType sharedFoldersType = folderData.m_type;
799
800 /* Get current shared folders: */
801 CSharedFolderVector sharedFolders = getSharedFolders(sharedFoldersType);
802 /* Check if such shared folder do not exists: */
803 CSharedFolder sharedFolder;
804 for (int iSharedFolderIndex = 0; iSharedFolderIndex < sharedFolders.size(); ++iSharedFolderIndex)
805 if (sharedFolders[iSharedFolderIndex].GetName() == strName)
806 sharedFolder = sharedFolders[iSharedFolderIndex];
807 if (sharedFolder.isNull())
808 {
809 /* Create new shared folder: */
810 switch(sharedFoldersType)
811 {
812 case MachineType:
813 {
814 m_machine.CreateSharedFolder(strName, strPath, fIsWritable, fIsAutoMount);
815 if (!m_machine.isOk())
816 {
817 /* Mark the page as failed: */
818 setFailed(true);
819 /* Show error message: */
820 vboxProblem().cannotCreateSharedFolder(m_machine, strName, strPath);
821 /* Finish early: */
822 return false;
823 }
824 break;
825 }
826 case ConsoleType:
827 {
828 /* Create new shared folder: */
829 m_console.CreateSharedFolder(strName, strPath, fIsWritable, fIsAutoMount);
830 if (!m_console.isOk())
831 {
832 /* Mark the page as failed: */
833 setFailed(true);
834 /* Show error message: */
835 vboxProblem().cannotCreateSharedFolder(m_console, strName, strPath);
836 /* Finish early: */
837 return false;
838 }
839 break;
840 }
841 default:
842 break;
843 }
844 }
845 return true;
846}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use