VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/ui/VBoxSharedFoldersSettings.ui.h@ 6942

Last change on this file since 6942 was 6942, checked in by vboxsync, 17 years ago

FE/Qt: Shared Folders: Better solution for painting root items on focus gain (no expensive repants and flickers).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.4 KB
Line 
1/**
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * "Shared Folders" settings dialog UI include (Qt Designer)
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19/****************************************************************************
20** ui.h extension file, included from the uic-generated form implementation.
21**
22** If you want to add, delete, or rename functions or slots, use
23** Qt Designer to update this file, preserving your code.
24**
25** You should not define a constructor or destructor in this file.
26** Instead, write your code in functions called init() and destroy().
27** These will automatically be called by the form's constructor and
28** destructor.
29*****************************************************************************/
30
31
32typedef QPair<QString, VBoxSharedFoldersSettings::SFDialogType> SFolderName;
33typedef QValueList<SFolderName> SFoldersNameList;
34
35
36class VBoxRichListItem : public QListViewItem
37{
38public:
39
40 enum { QIRichListItemId = 1010 };
41
42 enum FormatType
43 {
44 IncorrectFormat = 0,
45 EllipsisStart = 1,
46 EllipsisMiddle = 2,
47 EllipsisEnd = 3,
48 EllipsisFile = 4
49 };
50
51 VBoxRichListItem (FormatType aFormat, QListView *aParent,
52 const QString& aName, const QString& aNull1,
53 const QString& aNull2, const QString& aKey) :
54 QListViewItem (aParent, aName, aNull1, aNull2, aKey), mFormat (aFormat)
55 {
56 }
57
58 VBoxRichListItem (FormatType aFormat, QListViewItem *aParent,
59 const QString& aName, const QString& aPath,
60 const QString& aAccess, const QString& aEdited) :
61 QListViewItem (aParent, aName, aPath, aAccess, aEdited), mFormat (aFormat)
62 {
63 mTextList << aName << aPath << aAccess << aEdited;
64 }
65
66 int rtti() const { return QIRichListItemId; }
67
68 int compare (QListViewItem *aItem, int aColumn, bool aAscending) const
69 {
70 /* Sorting the children always by name: */
71 if (parent() && aItem->parent())
72 return QListViewItem::compare (aItem, 0, aAscending);
73 /* Sorting the root items always by key: */
74 else if (!parent() && !aItem->parent())
75 return QListViewItem::compare (aItem, 3, aAscending);
76 else
77 return QListViewItem::compare (aItem, aColumn, aAscending);
78 }
79
80 VBoxRichListItem* nextSibling() const
81 {
82 QListViewItem *item = QListViewItem::nextSibling();
83 return item && item->rtti() == QIRichListItemId ?
84 static_cast<VBoxRichListItem*> (item) : 0;
85 }
86
87 QString getText (int aIndex) const
88 {
89 return aIndex >= 0 && aIndex < (int)mTextList.size() ?
90 mTextList [aIndex] : QString::null;
91 }
92
93 void updateText (int aColumn, const QString &aText)
94 {
95 if (aColumn >= 0 && aColumn < (int)mTextList.size())
96 mTextList [aColumn] = aText;
97 }
98
99protected:
100
101 void paintCell (QPainter *aPainter, const QColorGroup &aColorGroup,
102 int aColumn, int aWidth, int aAlign)
103 {
104 if (!parent())
105 {
106 /* Make root items occupy the whole width */
107 aWidth = listView()->viewport()->width();
108
109 if (aColumn > 0)
110 {
111 /* For columns other than the first one, paint the overlapping
112 * portion of the first column after correcting the window */
113 aPainter->save();
114 QRect wnd = aPainter->window();
115 int dx = -listView()->treeStepSize();
116 for (int i = 0; i < aColumn; ++ i)
117 dx += listView()->columnWidth (i);
118 wnd.moveBy (dx, 0);
119 aPainter->setWindow (wnd);
120 QListViewItem::paintCell (aPainter, aColorGroup, 0, aWidth, aAlign);
121 aPainter->restore();
122 return;
123 }
124
125 QListViewItem::paintCell (aPainter, aColorGroup, aColumn, aWidth, aAlign);
126 }
127 else
128 {
129 processColumn (aColumn, aWidth);
130 QListViewItem::paintCell (aPainter, aColorGroup, aColumn, aWidth, aAlign);
131 }
132 }
133
134 int width (const QFontMetrics &aFontMetrics, const QListView *, int aColumn) const
135 {
136 return parent() ?
137 aFontMetrics.boundingRect (getText (aColumn)).width() +
138 aFontMetrics.width ("...x") /* indent size */ : 0;
139 }
140
141 void processColumn (int aColumn, int aWidth)
142 {
143 QString oneString = aColumn >= 0 && aColumn < (int)mTextList.size() ?
144 mTextList [aColumn] : QString::null;
145 if (oneString.isNull())
146 return;
147 int oldSize = listView()->fontMetrics().width (oneString);
148 int indentSize = listView()->fontMetrics().width ("...x");
149
150 /* compress text */
151 int start = 0;
152 int finish = 0;
153 int position = 0;
154 int textWidth = 0;
155 do {
156 textWidth = listView()->fontMetrics().width (oneString);
157 if (textWidth + indentSize > aWidth)
158 {
159 start = 0;
160 finish = oneString.length();
161
162 /* selecting remove position */
163 switch (mFormat)
164 {
165 case EllipsisStart:
166 position = start;
167 break;
168 case EllipsisMiddle:
169 position = (finish - start) / 2;
170 break;
171 case EllipsisEnd:
172 position = finish - 1;
173 break;
174 case EllipsisFile:
175 {
176 QRegExp regExp ("([\\\\/][^\\\\^/]+[\\\\/]?$)");
177 int newFinish = regExp.search (oneString);
178 if (newFinish != -1)
179 finish = newFinish;
180 position = (finish - start) / 2;
181 break;
182 }
183 default:
184 AssertMsgFailed (("Invalid format type\n"));
185 }
186
187 if (position == finish)
188 break;
189 oneString.remove (position, 1);
190 }
191 } while (textWidth + indentSize > aWidth);
192 if (position || mFormat == EllipsisFile) oneString.insert (position, "...");
193
194 int newSize = listView()->fontMetrics().width (oneString);
195 setText (aColumn, newSize < oldSize ? oneString : mTextList [aColumn]);
196 }
197
198 FormatType mFormat;
199 QStringList mTextList;
200};
201
202
203class VBoxAddSFDialog : public QDialog
204{
205 Q_OBJECT
206
207public:
208
209 enum DialogType { AddDialogType, EditDialogType };
210
211 VBoxAddSFDialog (VBoxSharedFoldersSettings *aParent,
212 VBoxAddSFDialog::DialogType aType,
213 bool aEnableSelector /* for "permanent" checkbox */,
214 const SFoldersNameList &aUsedNames)
215 : QDialog (aParent, "VBoxAddSFDialog", true /* modal */)
216 , mLePath (0), mLeName (0), mCbPermanent (0), mCbReadonly (0)
217 , mUsedNames (aUsedNames)
218 {
219 switch (aType)
220 {
221 case AddDialogType:
222 setCaption (tr ("Add Share"));
223 break;
224 case EditDialogType:
225 setCaption (tr ("Edit Share"));
226 break;
227 default:
228 AssertMsgFailed (("Incorrect SF Dialog type\n"));
229 }
230 QVBoxLayout *mainLayout = new QVBoxLayout (this, 10, 10, "mainLayout");
231
232 /* Setup Input layout */
233 QGridLayout *inputLayout = new QGridLayout (mainLayout, 3, 3, 10, "inputLayout");
234 QLabel *lbPath = new QLabel (tr ("Folder Path"), this);
235 mLePath = new QLineEdit (this);
236 QToolButton *tbPath = new QToolButton (this);
237 QLabel *lbName = new QLabel (tr ("Folder Name"), this);
238 mLeName = new QLineEdit (this);
239 tbPath->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
240 "select_file_dis_16px.png"));
241 tbPath->setFocusPolicy (QWidget::TabFocus);
242 connect (mLePath, SIGNAL (textChanged (const QString &)),
243 this, SLOT (validate()));
244 connect (mLeName, SIGNAL (textChanged (const QString &)),
245 this, SLOT (validate()));
246 connect (tbPath, SIGNAL (clicked()), this, SLOT (showFileDialog()));
247 QWhatsThis::add (mLePath, tr ("Displays the path to an existing folder on the host PC."));
248 QWhatsThis::add (mLeName, tr ("Displays the name of the shared folder "
249 "(as it will be seen by the guest OS)."));
250 QWhatsThis::add (tbPath, tr ("Opens the dialog to select a folder."));
251
252 inputLayout->addWidget (lbPath, 0, 0);
253 inputLayout->addWidget (mLePath, 0, 1);
254 inputLayout->addWidget (tbPath, 0, 2);
255 inputLayout->addWidget (lbName, 1, 0);
256 inputLayout->addMultiCellWidget (mLeName, 1, 1, 1, 2);
257
258 mCbReadonly = new QCheckBox (tr ("&Read-only"), this);
259 QWhatsThis::add (mCbReadonly,
260 tr ("When checked, the guest OS will not be able to write to the "
261 "specified shared folder."));
262 mCbReadonly->setChecked (false);
263 inputLayout->addMultiCellWidget (mCbReadonly, 2, 2, 0, 2);
264
265 if (aEnableSelector)
266 {
267 mCbPermanent = new QCheckBox (tr ("&Make Permanent"), this);
268 mCbPermanent->setChecked (true);
269 inputLayout->addMultiCellWidget (mCbPermanent, 3, 3, 0, 2);
270 connect (mCbPermanent, SIGNAL (toggled (bool)),
271 this, SLOT (validate()));
272 }
273
274 /* Setup Button layout */
275 QHBoxLayout *buttonLayout = new QHBoxLayout (mainLayout, 10, "buttonLayout");
276 mBtOk = new QPushButton (tr ("&OK"), this, "btOk");
277 QSpacerItem *spacer = new QSpacerItem (0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
278 QPushButton *btCancel = new QPushButton (tr ("Cancel"), this, "btCancel");
279 connect (mBtOk, SIGNAL (clicked()), this, SLOT (accept()));
280 connect (btCancel, SIGNAL (clicked()), this, SLOT (reject()));
281
282 buttonLayout->addWidget (mBtOk);
283 buttonLayout->addItem (spacer);
284 buttonLayout->addWidget (btCancel);
285
286 /* Validate fields */
287 validate();
288 }
289
290 ~VBoxAddSFDialog() {}
291
292 QString getPath() { return mLePath->text(); }
293 QString getName() { return mLeName->text(); }
294 bool getPermanent()
295 {
296 return mCbPermanent ? mCbPermanent->isChecked() : true;
297 }
298 bool getWritable() { return !mCbReadonly->isChecked(); }
299
300 void setPath (const QString &aPath) { mLePath->setText (aPath); }
301 void setName (const QString &aName) { mLeName->setText (aName); }
302 void setPermanent (bool aPermanent)
303 {
304 if (mCbPermanent)
305 {
306 mCbPermanent->setChecked (aPermanent);
307 mCbPermanent->setEnabled (!aPermanent);
308 }
309 }
310 void setWritable (bool aWritable) { mCbReadonly->setChecked (!aWritable); }
311
312private slots:
313
314 void validate()
315 {
316 VBoxSharedFoldersSettings::SFDialogType dlgType =
317 (VBoxSharedFoldersSettings::SFDialogType)
318 static_cast<VBoxSharedFoldersSettings*> (parent())->dialogType();
319 VBoxSharedFoldersSettings::SFDialogType resultType =
320 mCbPermanent && !mCbPermanent->isChecked() ?
321 VBoxSharedFoldersSettings::ConsoleType :
322 dlgType & VBoxSharedFoldersSettings::MachineType ?
323 VBoxSharedFoldersSettings::MachineType :
324 VBoxSharedFoldersSettings::GlobalType;
325 SFolderName pair = qMakePair (mLeName->text(), resultType);
326
327 mBtOk->setEnabled (!mLePath->text().isEmpty() &&
328 !mLeName->text().isEmpty() &&
329 !mUsedNames.contains (pair));
330 }
331
332 void showFileDialog()
333 {
334 QString folder = vboxGlobal()
335 .getExistingDirectory (QDir::rootDirPath(),
336 this, "addSharedFolderDialog",
337 tr ("Select a folder to share"));
338 if (folder.isNull())
339 return;
340
341 QString folderName = QDir::convertSeparators (folder);
342 QRegExp commonRule ("[\\\\/]([^\\\\^/]+)[\\\\/]?$");
343 QRegExp rootRule ("(([a-zA-Z])[^\\\\^/])?[\\\\/]$");
344 if (commonRule.search (folderName) != -1)
345 {
346 /* processing non-root folder */
347 mLePath->setText (folderName.remove (QRegExp ("[\\\\/]$")));
348 mLeName->setText (commonRule.cap (1));
349 }
350 else if (rootRule.search (folderName) != -1)
351 {
352 /* processing root folder */
353 mLePath->setText (folderName);
354#if defined (Q_OS_WIN) || defined (Q_OS_OS2)
355 mLeName->setText (rootRule.cap (2) + "_DRIVE");
356#elif defined (Q_OS_UNIX)
357 mLeName->setText ("ROOT");
358#endif
359 }
360 else
361 return; /* hm, what type of folder it was? */
362 }
363
364private:
365
366 void showEvent (QShowEvent *aEvent)
367 {
368 setFixedHeight (height());
369 QDialog::showEvent (aEvent);
370 }
371
372 QPushButton *mBtOk;
373 QLineEdit *mLePath;
374 QLineEdit *mLeName;
375 QCheckBox *mCbPermanent;
376 QCheckBox *mCbReadonly;
377 SFoldersNameList mUsedNames;
378};
379
380
381void VBoxSharedFoldersSettings::init()
382{
383 mDialogType = WrongType;
384 listView->setSorting (0);
385 new QIListViewSelectionPreserver (this, listView);
386 listView->setShowToolTips (false);
387 listView->setRootIsDecorated (true);
388 listView->header()->setMovingEnabled (false);
389 tbAdd->setIconSet (VBoxGlobal::iconSet ("add_shared_folder_16px.png",
390 "add_shared_folder_disabled_16px.png"));
391 tbEdit->setIconSet (VBoxGlobal::iconSet ("edit_shared_folder_16px.png",
392 "edit_shared_folder_disabled_16px.png"));
393 tbRemove->setIconSet (VBoxGlobal::iconSet ("revome_shared_folder_16px.png",
394 "revome_shared_folder_disabled_16px.png"));
395 connect (tbAdd, SIGNAL (clicked()), this, SLOT (tbAddPressed()));
396 connect (tbEdit, SIGNAL (clicked()), this, SLOT (tbEditPressed()));
397 connect (tbRemove, SIGNAL (clicked()), this, SLOT (tbRemovePressed()));
398 connect (listView, SIGNAL (currentChanged (QListViewItem *)),
399 this, SLOT (processCurrentChanged (QListViewItem *)));
400
401 /* Make after-paining list update to ensure all columns repainted correctly. */
402 connect (listView->header(), SIGNAL (sizeChange (int, int, int)),
403 this, SLOT (updateList()));
404
405 mIsListViewChanged = false;
406
407 listView->viewport()->installEventFilter (this);
408
409 mTrFull = tr ("Full");
410 mTrReadOnly = tr ("Read-only");
411}
412
413void VBoxSharedFoldersSettings::showEvent (QShowEvent *aEvent)
414{
415 QWidget::showEvent (aEvent);
416
417 /* Adjusting size after all pending show events are processed. */
418 QTimer::singleShot (0, this, SLOT (adjustList()));
419}
420
421
422void VBoxSharedFoldersSettings::updateList()
423{
424 /* Updating list after all pending cell-repaint enevts. */
425 QTimer::singleShot (0, listView, SLOT (updateContents()));
426}
427
428void VBoxSharedFoldersSettings::adjustList()
429{
430 /* Adjust two columns size.
431 * Watching columns 0&2 to feat 1/3 of total width. */
432 int total = listView->viewport()->width();
433
434 listView->adjustColumn (0);
435 int w0 = listView->columnWidth (0) < total / 3 ?
436 listView->columnWidth (0) : total / 3;
437
438 listView->adjustColumn (2);
439 int w2 = listView->columnWidth (2) < total / 3 ?
440 listView->columnWidth (2) : total / 3;
441
442 /* We are adjusting columns 0 and 2 and resizing column 1 to feat
443 * visible listView' width according two adjusted columns. Due to
444 * adjusting column 2 influent column 0 restoring all widths. */
445 listView->setColumnWidth (0, w0);
446 listView->setColumnWidth (1, total - w0 - w2);
447 listView->setColumnWidth (2, w2);
448}
449
450bool VBoxSharedFoldersSettings::eventFilter (QObject *aObject, QEvent *aEvent)
451{
452 /* Process & show auto Tool-Tip for partially hidden listview items. */
453 if (aObject == listView->viewport() && aEvent->type() == QEvent::MouseMove)
454 {
455 QMouseEvent *e = static_cast<QMouseEvent*> (aEvent);
456 QListViewItem *i = listView->itemAt (e->pos());
457 VBoxRichListItem *item = i && i->rtti() == VBoxRichListItem::QIRichListItemId ?
458 static_cast<VBoxRichListItem*> (i) : 0;
459 if (item)
460 {
461 int delta = e->pos().x();
462 int id = 0;
463 for (; id < listView->columns(); ++ id)
464 {
465 if (delta < listView->columnWidth (id))
466 break;
467 delta -= listView->columnWidth (id);
468 }
469
470 QString curText = QToolTip::textFor (listView->viewport());
471 QString newText = item->text (id) != item->getText (id) ?
472 item->getText (id) : QString::null;
473
474 if (newText != curText)
475 {
476 QToolTip::remove (listView->viewport());
477 QToolTip::add (listView->viewport(), newText);
478 }
479 }
480 else
481 QToolTip::remove (listView->viewport());
482 }
483
484 return QWidget::eventFilter (aObject, aEvent);
485}
486
487void VBoxSharedFoldersSettings::setDialogType (int aType)
488{
489 mDialogType = aType;
490}
491
492
493void VBoxSharedFoldersSettings::removeSharedFolder (const QString & aName,
494 const QString & aPath,
495 SFDialogType aType)
496{
497 switch (aType)
498 {
499 case GlobalType:
500 {
501 /* This feature is not implemented yet */
502 AssertMsgFailed (("Global shared folders are not implemented yet\n"));
503 break;
504 }
505 case MachineType:
506 {
507 Assert (!mMachine.isNull());
508 mMachine.RemoveSharedFolder (aName);
509 if (!mMachine.isOk())
510 vboxProblem().cannotRemoveSharedFolder (this, mMachine,
511 aName, aPath);
512 break;
513 }
514 case ConsoleType:
515 {
516 Assert (!mConsole.isNull());
517 mConsole.RemoveSharedFolder (aName);
518 if (!mConsole.isOk())
519 vboxProblem().cannotRemoveSharedFolder (this, mConsole,
520 aName, aPath);
521 break;
522 }
523 default:
524 {
525 AssertMsgFailed (("Incorrect shared folder type\n"));
526 }
527 }
528}
529
530void VBoxSharedFoldersSettings::createSharedFolder (const QString & aName,
531 const QString & aPath,
532 bool aWritable,
533 SFDialogType aType)
534{
535 switch (aType)
536 {
537 case GlobalType:
538 {
539 /* This feature is not implemented yet */
540 AssertMsgFailed (("Global shared folders are not implemented yet\n"));
541 break;
542 }
543 case MachineType:
544 {
545 Assert (!mMachine.isNull());
546 mMachine.CreateSharedFolder (aName, aPath, aWritable);
547 if (!mMachine.isOk())
548 vboxProblem().cannotCreateSharedFolder (this, mMachine,
549 aName, aPath);
550 break;
551 }
552 case ConsoleType:
553 {
554 Assert (!mConsole.isNull());
555 mConsole.CreateSharedFolder (aName, aPath, aWritable);
556 if (!mConsole.isOk())
557 vboxProblem().cannotCreateSharedFolder (this, mConsole,
558 aName, aPath);
559 break;
560 }
561 default:
562 {
563 AssertMsgFailed (("Incorrect shared folder type\n"));
564 }
565 }
566}
567
568
569void VBoxSharedFoldersSettings::getFromGlobal()
570{
571 /* This feature is not implemented yet */
572 AssertMsgFailed (("Global shared folders are not implemented yet\n"));
573
574 /*
575 QString name = tr (" Global Folders");
576 QString key (QString::number (GlobalType));
577 VBoxRichListItem *root = new VBoxRichListItem (VBoxRichListItem::EllipsisEnd,
578 listView, name, QString::null, QString::null, key);
579 getFrom (vboxGlobal().virtualBox().GetSharedFolders().Enumerate(), root);
580 */
581}
582
583void VBoxSharedFoldersSettings::getFromMachine (const CMachine &aMachine)
584{
585 mMachine = aMachine;
586 QString name = tr (" Machine Folders");
587 QString key (QString::number (MachineType));
588 VBoxRichListItem *root = new VBoxRichListItem (VBoxRichListItem::EllipsisEnd,
589 listView, name, QString::null, QString::null, key);
590 getFrom (mMachine.GetSharedFolders().Enumerate(), root);
591}
592
593void VBoxSharedFoldersSettings::getFromConsole (const CConsole &aConsole)
594{
595 mConsole = aConsole;
596 QString name = tr (" Transient Folders");
597 QString key (QString::number (ConsoleType));
598 VBoxRichListItem *root = new VBoxRichListItem (VBoxRichListItem::EllipsisEnd,
599 listView, name, QString::null, QString::null, key);
600 getFrom (mConsole.GetSharedFolders().Enumerate(), root);
601}
602
603void VBoxSharedFoldersSettings::getFrom (const CSharedFolderEnumerator &aEn,
604 QListViewItem *aRoot)
605{
606 aRoot->setSelectable (false);
607 while (aEn.HasMore())
608 {
609 CSharedFolder sf = aEn.GetNext();
610 new VBoxRichListItem (VBoxRichListItem::EllipsisFile, aRoot,
611 sf.GetName(), sf.GetHostPath(),
612 sf.GetWritable() ? mTrFull : mTrReadOnly,
613 "not edited");
614 }
615 listView->setOpen (aRoot, true);
616 listView->setCurrentItem (aRoot->firstChild() ? aRoot->firstChild() : aRoot);
617 processCurrentChanged (aRoot->firstChild() ? aRoot->firstChild() : aRoot);
618}
619
620
621void VBoxSharedFoldersSettings::putBackToGlobal()
622{
623 /* This feature is not implemented yet */
624 AssertMsgFailed (("Global shared folders are not implemented yet\n"));
625
626 /*
627 if (!mIsListViewChanged) return;
628 // This function is only available for GlobalType dialog
629 Assert (mDialogType == GlobalType);
630 // Searching for GlobalType item's root
631 QListViewItem *root = listView->findItem (QString::number (GlobalType), 3);
632 Assert (root);
633 CSharedFolderEnumerator en = vboxGlobal().virtualBox().GetSharedFolders().Enumerate();
634 putBackTo (en, root);
635 */
636}
637
638void VBoxSharedFoldersSettings::putBackToMachine()
639{
640 if (!mIsListViewChanged)
641 return;
642
643 /* This function is only available for MachineType dialog */
644 Assert (mDialogType & MachineType);
645 /* Searching for MachineType item's root */
646 QListViewItem *root = listView->findItem (QString::number (MachineType), 3);
647 Assert (root);
648 CSharedFolderEnumerator en = mMachine.GetSharedFolders().Enumerate();
649 putBackTo (en, root);
650}
651
652void VBoxSharedFoldersSettings::putBackToConsole()
653{
654 if (!mIsListViewChanged)
655 return;
656
657 /* This function is only available for ConsoleType dialog */
658 Assert (mDialogType & ConsoleType);
659 /* Searching for ConsoleType item's root */
660 QListViewItem *root = listView->findItem (QString::number (ConsoleType), 3);
661 Assert (root);
662 CSharedFolderEnumerator en = mConsole.GetSharedFolders().Enumerate();
663 putBackTo (en, root);
664}
665
666void VBoxSharedFoldersSettings::putBackTo (CSharedFolderEnumerator &aEn,
667 QListViewItem *aRoot)
668{
669 Assert (!aRoot->text (3).isNull());
670 SFDialogType type = (SFDialogType)aRoot->text (3).toInt();
671
672 /* deleting all changed folders of the list */
673 while (aEn.HasMore())
674 {
675 CSharedFolder sf = aEn.GetNext();
676
677 /* Search for this root's items */
678 QListViewItem *firstItem = aRoot->firstChild();
679 VBoxRichListItem *item = firstItem &&
680 firstItem->rtti() == VBoxRichListItem::QIRichListItemId ?
681 static_cast<VBoxRichListItem*> (firstItem) : 0;
682 while (item)
683 {
684 if (item->getText (0) == sf.GetName() &&
685 item->getText (1) == sf.GetHostPath() &&
686 item->getText (3) == "not edited")
687 break;
688 item = item->nextSibling();
689 }
690 if (item)
691 continue;
692 removeSharedFolder (sf.GetName(), sf.GetHostPath(), type);
693 }
694
695 /* saving all machine related list view items */
696 QListViewItem *iterator = aRoot->firstChild();
697 while (iterator)
698 {
699 VBoxRichListItem *item = 0;
700 if (iterator->rtti() == VBoxRichListItem::QIRichListItemId)
701 item = static_cast<VBoxRichListItem*> (iterator);
702 if (item && !item->getText (0).isNull() && !item->getText (1).isNull()
703 && item->getText (3) == "edited")
704 createSharedFolder (item->getText (0), item->getText (1),
705 item->getText (2) == mTrFull ? true : false, type);
706 iterator = iterator->nextSibling();
707 }
708}
709
710
711QListViewItem* VBoxSharedFoldersSettings::searchRoot (bool aIsPermanent)
712{
713 if (!aIsPermanent)
714 return listView->findItem (QString::number (ConsoleType), 3);
715 else if (mDialogType & MachineType)
716 return listView->findItem (QString::number (MachineType), 3);
717 else
718 return listView->findItem (QString::number (GlobalType), 3);
719}
720
721void VBoxSharedFoldersSettings::tbAddPressed()
722{
723 /* Make the used names list: */
724 SFoldersNameList usedList;
725 QListViewItemIterator it (listView);
726 while (*it)
727 {
728 if ((*it)->parent() && (*it)->rtti() == VBoxRichListItem::QIRichListItemId)
729 {
730 VBoxRichListItem *item = static_cast<VBoxRichListItem*> (*it);
731 SFDialogType type = (SFDialogType)item->parent()->text (3).toInt();
732 usedList << qMakePair (item->getText (0), type);
733 }
734 ++ it;
735 }
736
737 /* Invoke Add-Box Dialog */
738 VBoxAddSFDialog dlg (this, VBoxAddSFDialog::AddDialogType,
739 mDialogType & ConsoleType, usedList);
740 if (dlg.exec() != QDialog::Accepted)
741 return;
742 QString name = dlg.getName();
743 QString path = dlg.getPath();
744 bool isPermanent = dlg.getPermanent();
745 /* Shared folder's name & path could not be empty */
746 Assert (!name.isEmpty() && !path.isEmpty());
747 /* Searching root for the new listview item */
748 QListViewItem *root = searchRoot (isPermanent);
749 Assert (root);
750 /* Appending a new listview item to the root */
751 VBoxRichListItem *item = new VBoxRichListItem (
752 VBoxRichListItem::EllipsisFile, root, name, path,
753 dlg.getWritable() ? mTrFull : mTrReadOnly, "edited");
754 /* Make the created item selected */
755 listView->ensureItemVisible (item);
756 listView->setCurrentItem (item);
757 processCurrentChanged (item);
758 listView->setFocus();
759
760 mIsListViewChanged = true;
761}
762
763void VBoxSharedFoldersSettings::tbEditPressed()
764{
765 /* Make the used names list: */
766 SFoldersNameList usedList;
767 QListViewItemIterator it (listView);
768 while (*it)
769 {
770 if ((*it)->parent() && !(*it)->isSelected() &&
771 (*it)->rtti() == VBoxRichListItem::QIRichListItemId)
772 {
773 VBoxRichListItem *item = static_cast<VBoxRichListItem*> (*it);
774 SFDialogType type = (SFDialogType)item->parent()->text (3).toInt();
775 usedList << qMakePair (item->getText (0), type);
776 }
777 ++ it;
778 }
779
780 /* Check selected item */
781 QListViewItem *selectedItem = listView->selectedItem();
782 VBoxRichListItem *item =
783 selectedItem->rtti() == VBoxRichListItem::QIRichListItemId ?
784 static_cast<VBoxRichListItem*> (selectedItem) : 0;
785 Assert (item);
786 Assert (item->parent());
787 /* Invoke Edit-Box Dialog */
788 VBoxAddSFDialog dlg (this, VBoxAddSFDialog::EditDialogType,
789 mDialogType & ConsoleType, usedList);
790 dlg.setPath (item->getText (1));
791 dlg.setName (item->getText (0));
792 dlg.setPermanent ((SFDialogType)item->parent()->text (3).toInt()
793 != ConsoleType);
794 dlg.setWritable (item->getText (2) == mTrFull);
795 if (dlg.exec() != QDialog::Accepted)
796 return;
797 QString name = dlg.getName();
798 QString path = dlg.getPath();
799 bool isPermanent = dlg.getPermanent();
800 /* Shared folder's name & path could not be empty */
801 Assert (!name.isEmpty() && !path.isEmpty());
802 /* Searching new root for the selected listview item */
803 QListViewItem *root = searchRoot (isPermanent);
804 Assert (root);
805 /* Updating an edited listview item */
806 item->updateText (3, "edited");
807 item->updateText (2, dlg.getWritable() ? mTrFull : mTrReadOnly);
808 item->updateText (1, path);
809 item->updateText (0, name);
810 if (item->parent() != root)
811 {
812 /* Move the selected item into new location */
813 item->parent()->takeItem (item);
814 root->insertItem (item);
815
816 /* Make the created item selected */
817 listView->ensureItemVisible (item);
818 listView->setCurrentItem (item);
819 processCurrentChanged (item);
820 listView->setFocus();
821 }
822 item->repaint();
823
824 mIsListViewChanged = true;
825}
826
827void VBoxSharedFoldersSettings::tbRemovePressed()
828{
829 Assert (listView->selectedItem());
830 delete listView->selectedItem();
831 mIsListViewChanged = true;
832}
833
834
835void VBoxSharedFoldersSettings::processCurrentChanged (QListViewItem *aItem)
836{
837 if (aItem && aItem->isSelectable() && listView->selectedItem() != aItem)
838 listView->setSelected (aItem, true);
839 bool addEnabled = aItem &&
840 (isEditable (aItem->text (3)) ||
841 (aItem->parent() && isEditable (aItem->parent()->text (3))));
842 bool removeEnabled = aItem && aItem->parent() &&
843 isEditable (aItem->parent()->text (3));
844 tbAdd->setEnabled (addEnabled);
845 tbEdit->setEnabled (removeEnabled);
846 tbRemove->setEnabled (removeEnabled);
847}
848
849void VBoxSharedFoldersSettings::processDoubleClick (QListViewItem *aItem)
850{
851 bool editEnabled = aItem && aItem->parent() &&
852 isEditable (aItem->parent()->text (3));
853 if (editEnabled)
854 tbEditPressed();
855}
856
857bool VBoxSharedFoldersSettings::isEditable (const QString &aKey)
858{
859 /* mDialogType should be setup already */
860 Assert (mDialogType);
861
862 SFDialogType type = (SFDialogType)aKey.toInt();
863 if (!type) return false;
864 return mDialogType & type;
865}
866
867
868#include "VBoxSharedFoldersSettings.ui.moc"
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette