VirtualBox

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

Last change on this file since 1863 was 1863, checked in by vboxsync, 18 years ago

1902: "Select Directory" dialogs are not native:

Own Win32 API native folders list dialog implemented. Dialog implemented as designed in parallel thread to avoid errors caused by COM initialization.
Change get-existing-directory to native in three places:

  1. Machine & VDI default location selection in Global Settings.
  2. Default snapshot location selection in VM Settings.
  3. Shared folder selection.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.3 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 InnoTek Systemberatung 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 as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23/****************************************************************************
24** ui.h extension file, included from the uic-generated form implementation.
25**
26** If you want to add, delete, or rename functions or slots, use
27** Qt Designer to update this file, preserving your code.
28**
29** You should not define a constructor or destructor in this file.
30** Instead, write your code in functions called init() and destroy().
31** These will automatically be called by the form's constructor and
32** destructor.
33*****************************************************************************/
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& aNull,
53 const QString& aKey) :
54 QListViewItem (aParent, aName, aNull, aKey), mFormat (aFormat)
55 {
56 }
57
58 VBoxRichListItem (FormatType aFormat, QListViewItem *aParent,
59 const QString& aName, const QString& aPath) :
60 QListViewItem (aParent, aName, aPath), mFormat (aFormat)
61 {
62 mTextList << aName << aPath;
63 }
64
65 int rtti() const { return QIRichListItemId; }
66
67 QString getText (int aIndex)
68 {
69 return aIndex >= 0 && aIndex < (int)mTextList.size() ?
70 mTextList [aIndex] : QString::null;
71 }
72
73 void updateText (int aColumn, const QString &aText)
74 {
75 if (aColumn >= 0 && aColumn < (int)mTextList.size())
76 mTextList [aColumn] = aText;
77 }
78
79protected:
80
81 void paintCell (QPainter *aPainter, const QColorGroup &aColorGroup,
82 int aColumn, int aWidth, int aAlign)
83 {
84 processColumn (aColumn, aWidth);
85 QListViewItem::paintCell (aPainter, aColorGroup, aColumn, aWidth, aAlign);
86 }
87
88 void processColumn (int aColumn, int aWidth)
89 {
90 QString oneString = aColumn >= 0 && aColumn < (int)mTextList.size() ?
91 mTextList [aColumn] : QString::null;
92 if (oneString.isNull())
93 return;
94 int oldSize = listView()->fontMetrics().width (oneString);
95 int indentSize = listView()->fontMetrics().width ("...x");
96
97 /* compress text */
98 int start = 0;
99 int finish = 0;
100 int position = 0;
101 int textWidth = 0;
102 do {
103 textWidth = listView()->fontMetrics().width (oneString);
104 if (textWidth + indentSize > aWidth)
105 {
106 start = 0;
107 finish = oneString.length();
108
109 /* selecting remove position */
110 switch (mFormat)
111 {
112 case EllipsisStart:
113 position = start;
114 break;
115 case EllipsisMiddle:
116 position = (finish - start) / 2;
117 break;
118 case EllipsisEnd:
119 position = finish - 1;
120 break;
121 case EllipsisFile:
122 {
123 QRegExp regExp ("([\\\\/][^\\\\^/]+[\\\\/]?$)");
124 int newFinish = regExp.search (oneString);
125 if (newFinish != -1)
126 finish = newFinish;
127 position = (finish - start) / 2;
128 break;
129 }
130 default:
131 AssertMsgFailed (("Invalid format type\n"));
132 }
133
134 if (position == finish)
135 break;
136 oneString.remove (position, 1);
137 }
138 } while (textWidth + indentSize > aWidth);
139 if (position || mFormat == EllipsisFile) oneString.insert (position, "...");
140
141 int newSize = listView()->fontMetrics().width (oneString);
142 setText (aColumn, newSize < oldSize ? oneString : mTextList [aColumn]);
143 }
144
145 FormatType mFormat;
146 QStringList mTextList;
147};
148
149
150class VBoxAddSFDialog : public QDialog
151{
152 Q_OBJECT
153
154public:
155
156 enum DialogType { AddDType, EditDType };
157
158 VBoxAddSFDialog (QWidget *aParent, VBoxAddSFDialog::DialogType aType) :
159 QDialog (aParent, "VBoxAddSFDialog", true /* modal */),
160 mLePath (0), mLeName (0)
161 {
162 switch (aType)
163 {
164 case AddDType:
165 setCaption (tr ("Add Share"));
166 break;
167 case EditDType:
168 setCaption (tr ("Edit Share"));
169 break;
170 default:
171 AssertMsgFailed (("Incorrect SF Dialog type\n"));
172 }
173 QVBoxLayout *mainLayout = new QVBoxLayout (this, 10, 10, "mainLayout");
174
175 /* Setup Input layout */
176 QGridLayout *inputLayout = new QGridLayout (mainLayout, 2, 3, 10, "inputLayout");
177 QLabel *lbPath = new QLabel ("Folder Path", this);
178 mLePath = new QLineEdit (this);
179 QToolButton *tbPath = new QToolButton (this);
180 QLabel *lbName = new QLabel ("Folder Name", this);
181 mLeName = new QLineEdit (this);
182 tbPath->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
183 "select_file_dis_16px.png"));
184 tbPath->setFocusPolicy (QWidget::TabFocus);
185 connect (mLePath, SIGNAL (textChanged (const QString &)),
186 this, SLOT (validate()));
187 connect (mLeName, SIGNAL (textChanged (const QString &)),
188 this, SLOT (validate()));
189 connect (tbPath, SIGNAL (clicked()), this, SLOT (showFileDialog()));
190 connect (&vboxGlobal(), SIGNAL (existingDirectoryResult (const QString&)),
191 this, SLOT (folderSelected (const QString&)));
192 QWhatsThis::add (mLePath, tr ("Enter existing path for the shared folder here"));
193 QWhatsThis::add (mLeName, tr ("Enter name for the shared folder to be created"));
194 QWhatsThis::add (tbPath, tr ("Click to invoke <open folder> dialog"));
195
196 inputLayout->addWidget (lbPath, 0, 0);
197 inputLayout->addWidget (mLePath, 0, 1);
198 inputLayout->addWidget (tbPath, 0, 2);
199 inputLayout->addWidget (lbName, 1, 0);
200 inputLayout->addMultiCellWidget (mLeName, 1, 1, 1, 2);
201
202 /* Setup Button layout */
203 QHBoxLayout *buttonLayout = new QHBoxLayout (mainLayout, 10, "buttonLayout");
204 mBtOk = new QPushButton ("OK", this, "btOk");
205 QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
206 QPushButton *btCancel = new QPushButton ("Cancel", this, "btCancel");
207 connect (mBtOk, SIGNAL (clicked()), this, SLOT (accept()));
208 connect (btCancel, SIGNAL (clicked()), this, SLOT (reject()));
209
210 buttonLayout->addWidget (mBtOk);
211 buttonLayout->addItem (spacer);
212 buttonLayout->addWidget (btCancel);
213
214 /* Validate fields */
215 validate();
216 }
217
218 ~VBoxAddSFDialog() {}
219
220 QString getPath() { return mLePath->text(); }
221 QString getName() { return mLeName->text(); }
222
223 void setPath (const QString &aPath) { mLePath->setText (aPath); }
224 void setName (const QString &aName) { mLeName->setText (aName); }
225
226private slots:
227
228 void validate()
229 {
230 mBtOk->setEnabled (!mLePath->text().isEmpty() && !mLeName->text().isEmpty());
231 }
232
233 void showFileDialog()
234 {
235 vboxGlobal().getExistingDirectory (QDir::convertSeparators (
236 QDir::rootDirPath()),
237 this, "addSharedFolderDialog",
238 tr ("Select a folder to share"));
239 }
240
241 void folderSelected (const QString &aFolder)
242 {
243 if (aFolder.isNull())
244 return;
245
246 QString folderName = QDir::convertSeparators (aFolder);
247 QRegExp commonRule ("[\\\\/]([^\\\\^/]+)[\\\\/]?$");
248 QRegExp rootRule ("(([a-zA-Z])[^\\\\^/])?[\\\\/]$");
249 if (commonRule.search (folderName) != -1)
250 {
251 /* processing non-root folder */
252 mLePath->setText (folderName.remove (QRegExp ("[\\\\/]$")));
253 mLeName->setText (commonRule.cap (1));
254 }
255 else if (rootRule.search (folderName) != -1)
256 {
257 /* processing root folder */
258 mLePath->setText (folderName);
259#if defined(Q_WS_WIN32)
260 mLeName->setText (rootRule.cap (2) + "_DRIVE");
261#elif defined(Q_WS_X11)
262 mLeName->setText ("ROOT");
263#endif
264 }
265 else
266 return; /* hm, what type of folder it was? */
267 }
268
269private:
270
271 void showEvent (QShowEvent *aEvent)
272 {
273 setFixedHeight (height());
274 QDialog::showEvent (aEvent);
275 }
276
277 QPushButton *mBtOk;
278 QLineEdit *mLePath;
279 QLineEdit *mLeName;
280};
281
282
283void VBoxSharedFoldersSettings::init()
284{
285 mDialogType = WrongType;
286 new QIListViewSelectionPreserver (this, listView);
287 listView->setShowToolTips (false);
288 listView->setRootIsDecorated (true);
289 tbAdd->setIconSet (VBoxGlobal::iconSet ("add_shared_folder_16px.png",
290 "add_shared_folder_disabled_16px.png"));
291 tbEdit->setIconSet (VBoxGlobal::iconSet ("edit_shared_folder_16px.png",
292 "edit_shared_folder_disabled_16px.png"));
293 tbRemove->setIconSet (VBoxGlobal::iconSet ("revome_shared_folder_16px.png",
294 "revome_shared_folder_disabled_16px.png"));
295 QToolTip::add (tbAdd, tr ("Add a new shared folder"));
296 QToolTip::add (tbEdit, tr ("Edit the selected shared folder"));
297 QToolTip::add (tbRemove, tr ("Remove the selected shared folder"));
298 connect (tbAdd, SIGNAL (clicked()), this, SLOT (tbAddPressed()));
299 connect (tbEdit, SIGNAL (clicked()), this, SLOT (tbEditPressed()));
300 connect (tbRemove, SIGNAL (clicked()), this, SLOT (tbRemovePressed()));
301 connect (listView, SIGNAL (currentChanged (QListViewItem *)),
302 this, SLOT (processCurrentChanged (QListViewItem *)));
303 connect (listView, SIGNAL (onItem (QListViewItem *)),
304 this, SLOT (processOnItem (QListViewItem *)));
305
306 mIsListViewChanged = false;
307}
308
309void VBoxSharedFoldersSettings::setDialogType (
310 VBoxSharedFoldersSettings::SFDialogType aType)
311{
312 mDialogType = aType;
313}
314
315
316void VBoxSharedFoldersSettings::removeSharedFolder (const QString & aName,
317 const QString & aPath,
318 SFDialogType aType)
319{
320 switch (aType)
321 {
322 case GlobalType:
323 {
324 /* This feature is not implemented yet */
325 AssertMsgFailed (("Global shared folders are not implemented yet\n"));
326 break;
327 }
328 case MachineType:
329 {
330 Assert (!mMachine.isNull());
331 mMachine.RemoveSharedFolder (aName);
332 if (!mMachine.isOk())
333 vboxProblem().cannotRemoveSharedFolder (this, mMachine,
334 aName, aPath);
335 break;
336 }
337 case ConsoleType:
338 {
339 Assert (!mConsole.isNull());
340 mConsole.RemoveSharedFolder (aName);
341 if (!mConsole.isOk())
342 vboxProblem().cannotRemoveSharedFolder (this, mConsole,
343 aName, aPath);
344 break;
345 }
346 default:
347 {
348 AssertMsgFailed (("Incorrect shared folder type\n"));
349 }
350 }
351}
352
353void VBoxSharedFoldersSettings::createSharedFolder (const QString & aName,
354 const QString & aPath,
355 SFDialogType aType)
356{
357 switch (aType)
358 {
359 case GlobalType:
360 {
361 /* This feature is not implemented yet */
362 AssertMsgFailed (("Global shared folders are not implemented yet\n"));
363 break;
364 }
365 case MachineType:
366 {
367 Assert (!mMachine.isNull());
368 mMachine.CreateSharedFolder (aName, aPath);
369 if (!mMachine.isOk())
370 vboxProblem().cannotCreateSharedFolder (this, mMachine,
371 aName, aPath);
372 break;
373 }
374 case ConsoleType:
375 {
376 Assert (!mConsole.isNull());
377 mConsole.CreateSharedFolder (aName, aPath);
378 if (!mConsole.isOk())
379 vboxProblem().cannotCreateSharedFolder (this, mConsole,
380 aName, aPath);
381 break;
382 }
383 default:
384 {
385 AssertMsgFailed (("Incorrect shared folder type\n"));
386 }
387 }
388}
389
390
391void VBoxSharedFoldersSettings::getFromGlobal()
392{
393 /* This feature is not implemented yet */
394 AssertMsgFailed (("Global shared folders are not implemented yet\n"));
395
396 /*
397 QString name = tr (" Global Folders");
398 QString key (QString::number (GlobalType));
399 VBoxRichListItem *root = new VBoxRichListItem (VBoxRichListItem::EllipsisEnd,
400 listView, name, QString::null, key);
401 getFrom (vboxGlobal().virtualBox().GetSharedFolders().Enumerate(), root);
402 */
403}
404
405void VBoxSharedFoldersSettings::getFromMachine (const CMachine &aMachine)
406{
407 mMachine = aMachine;
408 QString name = tr (" Machine Folders");
409 QString key (QString::number (MachineType));
410 VBoxRichListItem *root = new VBoxRichListItem (VBoxRichListItem::EllipsisEnd,
411 listView, name, QString::null, key);
412 getFrom (mMachine.GetSharedFolders().Enumerate(), root);
413}
414
415void VBoxSharedFoldersSettings::getFromConsole (const CConsole &aConsole)
416{
417 mConsole = aConsole;
418 QString name = tr (" Transient Folders");
419 QString key (QString::number (ConsoleType));
420 VBoxRichListItem *root = new VBoxRichListItem (VBoxRichListItem::EllipsisEnd,
421 listView, name, QString::null, key);
422 getFrom (mConsole.GetSharedFolders().Enumerate(), root);
423}
424
425void VBoxSharedFoldersSettings::getFrom (const CSharedFolderEnumerator &aEn,
426 QListViewItem *aRoot)
427{
428 aRoot->setSelectable (false);
429 while (aEn.HasMore())
430 {
431 CSharedFolder sf = aEn.GetNext();
432 new VBoxRichListItem (VBoxRichListItem::EllipsisFile, aRoot,
433 sf.GetName(), sf.GetHostPath());
434 }
435 listView->setOpen (aRoot, true);
436 listView->setCurrentItem (aRoot);
437 processCurrentChanged (aRoot);
438}
439
440
441void VBoxSharedFoldersSettings::putBackToGlobal()
442{
443 /* This feature is not implemented yet */
444 AssertMsgFailed (("Global shared folders are not implemented yet\n"));
445
446 /*
447 if (!mIsListViewChanged) return;
448 // This function is only available for GlobalType dialog
449 Assert (mDialogType == GlobalType);
450 // Searching for GlobalType item's root
451 QListViewItem *root = listView->findItem (QString::number (GlobalType), 2);
452 Assert (root);
453 CSharedFolderEnumerator en = vboxGlobal().virtualBox().GetSharedFolders().Enumerate();
454 putBackTo (en, root);
455 */
456}
457
458void VBoxSharedFoldersSettings::putBackToMachine()
459{
460 if (!mIsListViewChanged)
461 return;
462
463 /* This function is only available for MachineType dialog */
464 Assert (mDialogType == MachineType);
465 /* Searching for MachineType item's root */
466 QListViewItem *root = listView->findItem (QString::number (MachineType), 2);
467 Assert (root);
468 CSharedFolderEnumerator en = mMachine.GetSharedFolders().Enumerate();
469 putBackTo (en, root);
470}
471
472void VBoxSharedFoldersSettings::putBackToConsole()
473{
474 if (!mIsListViewChanged)
475 return;
476
477 /* This function is only available for ConsoleType dialog */
478 Assert (mDialogType == ConsoleType);
479 /* Searching for ConsoleType item's root */
480 QListViewItem *root = listView->findItem (QString::number (ConsoleType), 2);
481 Assert (root);
482 CSharedFolderEnumerator en = mConsole.GetSharedFolders().Enumerate();
483 putBackTo (en, root);
484}
485
486void VBoxSharedFoldersSettings::putBackTo (CSharedFolderEnumerator &aEn,
487 QListViewItem *aRoot)
488{
489 Assert (!aRoot->text (2).isNull());
490 SFDialogType type = (SFDialogType)aRoot->text (2).toInt();
491
492 /* deleting all existing folders if the list */
493 while (aEn.HasMore())
494 {
495 CSharedFolder sf = aEn.GetNext();
496 removeSharedFolder (sf.GetName(), sf.GetHostPath(), type);
497 }
498
499 /* saving all machine related list view items */
500 QListViewItem *iterator = aRoot->firstChild();
501 while (iterator)
502 {
503 VBoxRichListItem *item = 0;
504 if (iterator->rtti() == VBoxRichListItem::QIRichListItemId)
505 item = static_cast<VBoxRichListItem*> (iterator);
506 if (item && !item->getText (0).isNull() && !item->getText (1).isNull())
507 createSharedFolder (item->getText (0), item->getText (1), type);
508 else
509 AssertMsgFailed (("Incorrect listview item type\n"));
510 iterator = iterator->nextSibling();
511 }
512}
513
514
515void VBoxSharedFoldersSettings::tbAddPressed()
516{
517 /* Invoke Add-Box Dialog */
518 VBoxAddSFDialog dlg (this, VBoxAddSFDialog::AddDType);
519 if (dlg.exec() != QDialog::Accepted)
520 return;
521 QString name = dlg.getName();
522 QString path = dlg.getPath();
523 /* Shared folder's name & path could not be empty */
524 Assert (!name.isEmpty() && !path.isEmpty());
525 /* Searching root for the new listview item */
526 QListViewItem *root = listView->findItem (QString::number (mDialogType), 2);
527 Assert (root);
528 /* Appending a new listview item to the root */
529 VBoxRichListItem *item = new VBoxRichListItem (VBoxRichListItem::EllipsisFile,
530 root, name, path);
531 listView->ensureItemVisible (item);
532 listView->setCurrentItem (item);
533 processCurrentChanged (item);
534 listView->setFocus();
535 mIsListViewChanged = true;
536}
537
538void VBoxSharedFoldersSettings::tbEditPressed()
539{
540 /* Check selected item */
541 QListViewItem *selectedItem = listView->selectedItem();
542 VBoxRichListItem *item = 0;
543 if (selectedItem->rtti() == VBoxRichListItem::QIRichListItemId)
544 item = static_cast<VBoxRichListItem*> (selectedItem);
545 Assert (item);
546 /* Invoke Add-Box Dialog */
547 VBoxAddSFDialog dlg (this, VBoxAddSFDialog::EditDType);
548 dlg.setPath (item->getText (1));
549 dlg.setName (item->getText (0));
550 if (dlg.exec() != QDialog::Accepted)
551 return;
552 QString name = dlg.getName();
553 QString path = dlg.getPath();
554 /* Shared folder's name & path could not be empty */
555 Assert (!name.isEmpty() && !path.isEmpty());
556 /* Updating an edited listview item */
557 item->updateText (1, path);
558 item->updateText (0, name);
559 mIsListViewChanged = true;
560}
561
562void VBoxSharedFoldersSettings::tbRemovePressed()
563{
564 Assert (listView->selectedItem());
565 delete listView->selectedItem();
566 mIsListViewChanged = true;
567}
568
569
570void VBoxSharedFoldersSettings::processOnItem (QListViewItem *aItem)
571{
572 VBoxRichListItem *item = 0;
573 if (aItem->rtti() == VBoxRichListItem::QIRichListItemId)
574 item = static_cast<VBoxRichListItem*> (aItem);
575 Assert (item);
576 QString tip = tr ("<nobr>Name:&nbsp;&nbsp;%1</nobr><br>"
577 "<nobr>Path:&nbsp;&nbsp;%2</nobr>")
578 .arg (item->getText (0)).arg (item->getText (1));
579 if (!item->getText (0).isNull() && !item->getText (1).isNull())
580 QToolTip::add (listView->viewport(), listView->itemRect (aItem), tip);
581 else
582 QToolTip::remove (listView->viewport());
583}
584
585void VBoxSharedFoldersSettings::processCurrentChanged (QListViewItem *aItem)
586{
587 if (aItem && aItem->isSelectable() && listView->selectedItem() != aItem)
588 listView->setSelected (aItem, true);
589 bool addEnabled = aItem &&
590 (isEditable (aItem->text (2)) ||
591 aItem->parent() && isEditable (aItem->parent()->text (2)));
592 bool removeEnabled = aItem && aItem->parent() &&
593 isEditable (aItem->parent()->text (2));
594 tbAdd->setEnabled (addEnabled);
595 tbEdit->setEnabled (removeEnabled);
596 tbRemove->setEnabled (removeEnabled);
597}
598
599bool VBoxSharedFoldersSettings::isEditable (const QString &aKey)
600{
601 /* mDialogType should be sutup already */
602 Assert (mDialogType);
603 /* simple item has no key information */
604 if (aKey.isEmpty())
605 return false;
606 SFDialogType type = (SFDialogType)aKey.toInt();
607 if (!type)
608 AssertMsgFailed (("Incorrect listview item key value\n"));
609 return type == mDialogType;
610}
611
612
613#include "VBoxSharedFoldersSettings.ui.moc"
Note: See TracBrowser for help on using the repository browser.

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