VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/ui/VBoxHardDiskSettings.ui.h@ 14707

Last change on this file since 14707 was 13836, checked in by vboxsync, 16 years ago

s/ELEMENTS/RT_ELEMENTS/g - retiring ELEMENTS (finally).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 34.0 KB
Line 
1/**
2 *
3 * VBox frontends: Qt GUI ("VirtualBox"):
4 * VBoxHardDiskSettings widget UI include (Qt Designer)
5 */
6
7/*
8 * Copyright (C) 2008 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23/****************************************************************************
24** ui.h extension file, included from the uic-generated form implementation.
25**
26** If you wish to add, delete or rename functions or slots use
27** Qt Designer which will update this file, preserving your code. Create an
28** init() function in place of a constructor, and a destroy() function in
29** place of a destructor.
30*****************************************************************************/
31
32/** SATA Ports count */
33static const ULONG SATAPortsCount = 30;
34
35class HDSlotItem;
36
37/** Combines the string and the numeric representation of the hard disk slot. */
38struct HDSlot
39{
40 HDSlot() : bus (KStorageBus_Null), channel (0), device (0) {}
41 HDSlot (const QString &aStr, KStorageBus aBus, LONG aChannel, LONG aDevice)
42 : str (aStr), bus (aBus), channel (aChannel), device (aDevice) {}
43
44 QString str;
45 KStorageBus bus;
46 LONG channel;
47 LONG device;
48};
49
50/**
51 * QObject class reimplementation to use for making selected IDE & SATA
52 * slots unique.
53 */
54class HDSlotUniquizer : public QObject
55{
56 Q_OBJECT
57
58public:
59
60 HDSlotUniquizer (QWidget *aParent, int aSataPortsCount = 0)
61 : QObject (aParent)
62 , mSataPortsCount (aSataPortsCount)
63 {
64 /* Compose Lists */
65 makeIDEList();
66 makeSATAList();
67 }
68
69 QValueList<HDSlot> list (HDSlotItem *aForSubscriber, bool aFilter = true);
70
71 int totalCount() { return mIDEList.size() + mSATAList.size(); }
72
73 int getSATAPortsCount()
74 {
75 return mSataPortsCount;
76 }
77
78 void setSATAPortsCount (int aSataPortsCount)
79 {
80 mSataPortsCount = aSataPortsCount;
81 makeSATAList();
82 }
83
84 void subscribe (HDSlotItem *aSubscriber)
85 {
86 bool result = mSubscribersList.resize (mSubscribersList.size() + 1);
87 if (!result)
88 return;
89
90 mSubscribersList.insert (mSubscribersList.size() - 1, aSubscriber);
91 mSubscribersList.sort();
92
93 emit listChanged();
94 }
95
96 void unsubscribe (HDSlotItem *aSubscriber)
97 {
98 int index = mSubscribersList.findRef (aSubscriber);
99 if (index == -1)
100 return;
101
102 mSubscribersList.remove (index);
103 mSubscribersList.sort();
104 mSubscribersList.resize (mSubscribersList.size() - 1);
105
106 emit listChanged();
107 }
108
109signals:
110
111 void listChanged();
112
113private:
114
115 void makeIDEList()
116 {
117 mIDEList.clear();
118
119 /* IDE Primary Master */
120 mIDEList << HDSlot (vboxGlobal().toFullString (KStorageBus_IDE, 0, 0),
121 KStorageBus_IDE, 0, 0);
122 /* IDE Primary Slave */
123 mIDEList << HDSlot (vboxGlobal().toFullString (KStorageBus_IDE, 0, 1),
124 KStorageBus_IDE, 0, 1);
125 /* IDE Secondary Slave */
126 mIDEList << HDSlot (vboxGlobal().toFullString (KStorageBus_IDE, 1, 1),
127 KStorageBus_IDE, 1, 1);
128
129 emit listChanged();
130 }
131
132 void makeSATAList()
133 {
134 mSATAList.clear();
135
136 for (int i = 0; i < mSataPortsCount; ++ i)
137 mSATAList << HDSlot (vboxGlobal().toFullString (KStorageBus_SATA, i, 0),
138 KStorageBus_SATA, i, 0);
139
140 emit listChanged();
141 }
142
143 int mSataPortsCount;
144 QValueList<HDSlot> mIDEList;
145 QValueList<HDSlot> mSATAList;
146 QPtrVector<HDSlotItem> mSubscribersList;
147};
148
149/**
150 * QComboBox class reimplementation to use as an editor for the device slot
151 * column.
152 */
153class HDSlotItem : public QComboBox
154{
155 Q_OBJECT
156
157public:
158
159 HDSlotItem (QWidget *aParent, HDSlotUniquizer *aUniq)
160 : QComboBox (aParent)
161 , mUniq (aUniq)
162 {
163 /* In some qt themes embedded list-box is not used by default */
164 if (!listBox())
165 setListBox (new QListBox (this));
166
167 setFocusPolicy (QWidget::NoFocus);
168 refresh();
169 mUniq->subscribe (this);
170 connect (mUniq, SIGNAL (listChanged()), this, SLOT (refresh()));
171 connect (mUniq, SIGNAL (listChanged()), this, SLOT (updateToolTip()));
172 connect (this, SIGNAL (activated (int)), mUniq, SIGNAL (listChanged()));
173 connect (this, SIGNAL (textChanged()), mUniq, SIGNAL (listChanged()));
174 }
175
176 ~HDSlotItem()
177 {
178 mUniq->unsubscribe (this);
179 }
180
181 static int scrollBarWidth()
182 {
183 QListBox lb;
184 lb.setVScrollBarMode (QScrollView::AlwaysOn);
185 return lb.verticalScrollBar()->width();
186 }
187
188 void setText (const QString &aText)
189 {
190 QComboBox::setCurrentText (aText);
191 emit textChanged();
192 }
193
194 KStorageBus currentBus() const
195 {
196 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
197 KStorageBus_Null);
198 return mHDSlots [currentItem()].bus;
199 }
200
201 LONG currentChannel() const
202 {
203 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
204 0);
205 return mHDSlots [currentItem()].channel;
206 }
207
208 LONG currentDevice() const
209 {
210 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
211 0);
212 return mHDSlots [currentItem()].device;
213 }
214
215private slots:
216
217 void refresh()
218 {
219 QString current = currentText();
220 mHDSlots = mUniq->list (this);
221 clear();
222
223 bool setCurrent = false;
224
225 for (QValueList<HDSlot>::const_iterator it = mHDSlots.begin();
226 it != mHDSlots.end(); ++ it)
227 {
228 insertItem ((*it).str);
229 if (!setCurrent)
230 setCurrent = (*it).str == current;
231 }
232
233 if (setCurrent)
234 setCurrentText (current);
235 }
236
237 void updateToolTip()
238 {
239 QString oldTip = QToolTip::textFor (this);
240 QString newTip = currentText();
241
242 if (newTip != oldTip)
243 {
244 QToolTip::remove (this);
245 QToolTip::add (this, newTip);
246 }
247 }
248
249signals:
250
251 void textChanged();
252
253private:
254
255 HDSlotUniquizer *mUniq;
256
257 QValueList<HDSlot> mHDSlots;
258};
259
260QValueList <HDSlot> HDSlotUniquizer::list (HDSlotItem *aSubscriber, bool aFilter)
261{
262 QValueList<HDSlot> list = mIDEList + mSATAList;
263
264 if (!aFilter)
265 return list;
266
267 /* Compose exclude list */
268 QStringList excludeList;
269 for (uint i = 0; i < mSubscribersList.size(); ++ i)
270 if (mSubscribersList [i] != aSubscriber)
271 excludeList << mSubscribersList [i]->currentText();
272
273 /* Filter the list */
274 QValueList<HDSlot>::Iterator it = list.begin();
275 while (it != list.end())
276 {
277 if (excludeList.contains ((*it).str))
278 it = list.remove (it);
279 else
280 ++ it;
281 }
282
283 return list;
284}
285
286/**
287 * VBoxMediaComboBox class reimplementation to use as an editor for the hard
288 * disk column.
289 */
290class HDItem : public VBoxMediaComboBox
291{
292 Q_OBJECT
293
294public:
295
296 HDItem (QWidget *aParent, const char *aName, QUuid aMachineID,
297 QListViewItem *aItem)
298 : VBoxMediaComboBox (aParent, aName, VBoxDefs::MediaType_HardDisk,
299 aMachineID)
300 , mItem (aItem)
301 {
302 setFocusPolicy (QWidget::NoFocus);
303
304 connect (this, SIGNAL (activated (int)),
305 this, SLOT (onThisActivated (int)));
306 }
307
308private slots:
309
310 void onThisActivated (int)
311 {
312 mItem->repaint();
313 }
314
315private:
316
317 QListViewItem *mItem;
318};
319
320class HDSpaceItem : public QListViewItem
321{
322public:
323
324 enum { HDSpaceItemType = 1011 };
325
326 HDSpaceItem (QListView *aParent)
327 : QListViewItem (aParent)
328 {
329 setSelectable (false);
330 }
331
332 int rtti() const { return HDSpaceItemType; }
333};
334
335class HDListItem : public QListViewItem
336{
337public:
338
339 enum { HDListItemType = 1010 };
340
341 HDListItem (QListView *aParent, QListViewItem *aAfter,
342 VBoxHardDiskSettings *aSettings, HDSlotUniquizer *aUniq,
343 const QUuid &aMachineId)
344 : QListViewItem (aParent, aAfter)
345 , mFocusColumn (-1)
346 , mAutoFocus (false)
347 {
348 init (aSettings, aUniq, aMachineId);
349 }
350
351 HDListItem (QListView *aParent,
352 VBoxHardDiskSettings *aSettings, HDSlotUniquizer *aUniq,
353 const QUuid &aMachineId)
354 : QListViewItem (aParent)
355 , mFocusColumn (-1)
356 , mAutoFocus (false)
357 {
358 init (aSettings, aUniq, aMachineId);
359 }
360
361 virtual ~HDListItem()
362 {
363 mHDCombo->deleteLater();
364 mSlotCombo->deleteLater();
365 }
366
367 int rtti() const { return HDListItemType; }
368
369 QString toolTip() { return QToolTip::textFor (mHDCombo); }
370
371 void setId (const QUuid &aId) { mHDCombo->setCurrentItem (aId); }
372
373 QUuid id() const { return mHDCombo->id(); }
374 QString location() const { return mHDCombo->location(); }
375
376 KStorageBus bus() { return mSlotCombo->currentBus(); }
377
378 LONG channel() const { return mSlotCombo->currentChannel(); }
379
380 LONG device() const { return mSlotCombo->currentDevice(); }
381
382 QString text (int aColumn) const
383 {
384 AssertReturn (aColumn >= 0 && (size_t) aColumn < RT_ELEMENTS (mCombos),
385 QString::null);
386
387 return mCombos [aColumn]->currentText();
388 }
389
390 const QPixmap *pixmap (int aColumn) const
391 {
392 AssertReturn (aColumn >= 0 && (size_t) aColumn < RT_ELEMENTS (mCombos),
393 NULL);
394
395 return mCombos [aColumn]->pixmap (mCombos [aColumn]->currentItem());
396 }
397
398 void moveFocusToColumn (int aCol)
399 {
400 mFocusColumn = aCol;
401 mAutoFocus = mFocusColumn != -1;
402 repaint();
403 }
404
405 void setAutoFocus (bool aOn)
406 {
407 mAutoFocus = aOn;
408 }
409
410 void showEditor()
411 {
412 if (mFocusColumn >= 0)
413 {
414 AssertReturnVoid ((size_t) mFocusColumn < RT_ELEMENTS (mCombos));
415
416 if (mCombos [mFocusColumn]->count())
417 mCombos [mFocusColumn]->popup();
418 }
419 }
420
421 int focusColumn() const
422 {
423 return mFocusColumn;
424 }
425
426 void setAttachment (const CHardDisk2Attachment &aHda)
427 {
428 QString device = vboxGlobal()
429 .toFullString (aHda.GetBus(), aHda.GetChannel(), aHda.GetDevice());
430
431 if (mSlotCombo->listBox()->findItem (device, Qt::ExactMatch))
432 mSlotCombo->setText (device);
433
434 mHDCombo->setCurrentItem (aHda.GetHardDisk().GetId());
435 }
436
437 int hardDiskCount()
438 {
439 int count = mHDCombo->count();
440 if (count == 1 && mHDCombo-> id (0).isNull())
441 return 0; /* ignore the "no media" item */
442 return count;
443 }
444
445 void tryToSelectNotOneOf (const QValueList <QUuid> &aUsedList)
446 {
447 for (int i = 0; i < mHDCombo->count(); ++ i)
448 {
449 if (!aUsedList.contains (mHDCombo->id (i)))
450 {
451 mHDCombo->setCurrentItem (mHDCombo->id (i));
452 break;
453 }
454 }
455 }
456
457 void setShowDiffs (bool aOn)
458 {
459 if (mHDCombo->showDiffs() != aOn)
460 {
461 mHDCombo->setShowDiffs (aOn);
462 mHDCombo->refresh();
463 }
464 }
465
466private:
467
468 void init (VBoxHardDiskSettings *aSettings, HDSlotUniquizer *aUniq,
469 const QUuid &aMachineId)
470 {
471 AssertReturnVoid (listView()->columns() == RT_ELEMENTS (mCombos));
472
473 setSelectable (false);
474
475 mSlotCombo = new HDSlotItem (listView()->viewport(), aUniq);
476 QObject::connect (mSlotCombo, SIGNAL (activated (int)),
477 aSettings, SIGNAL (hardDiskListChanged()));
478 mCombos [0] = mSlotCombo;
479
480 mHDCombo = new HDItem (listView()->viewport(), "mHDCombo",
481 aMachineId, this);
482 QObject::connect (mHDCombo, SIGNAL (activated (int)),
483 aSettings, SIGNAL (hardDiskListChanged()));
484 mCombos [1] = mHDCombo;
485
486 /* populate the media combobox */
487 mHDCombo->refresh();
488
489#ifdef Q_WS_MAC
490 /* White background on Mac OS X */
491 mSlotCombo->setPaletteBackgroundColor (mSlotCombo->parentWidget()->
492 paletteBackgroundColor());
493 mHDCombo->setPaletteBackgroundColor (mHDCombo->parentWidget()->
494 paletteBackgroundColor());
495#endif /* Q_WS_MAC */
496
497 mSlotCombo->setHidden (true);
498 mHDCombo->setHidden (true);
499 }
500
501 void paintCell (QPainter *aPainter, const QColorGroup &aColorGroup,
502 int aColumn, int aWidth, int aAlign)
503 {
504 AssertReturnVoid (aColumn >= 0 && (size_t) aColumn < RT_ELEMENTS (mCombos));
505
506 QComboBox *cb = mCombos [aColumn];
507
508 /// @todo (r=dmik) show/hide functionality should be removed from here
509 /// to the appropriate places like focus handling routines
510
511 if (aColumn == mFocusColumn)
512 {
513 int indent = 0;
514 for (int i = 0; i < aColumn; ++ i)
515 indent = listView()->columnWidth (i);
516
517 QRect rect = listView()->itemRect (this);
518
519 int xc = rect.x() + indent;
520 int yc = rect.y();
521 int wc = listView()->columnWidth (aColumn);
522 int hc = rect.height();
523
524 cb->move (xc, yc);
525 cb->resize (wc, hc);
526
527 if (cb->isHidden())
528 cb->show();
529 if (mAutoFocus && !cb->hasFocus())
530 QTimer::singleShot (0, cb, SLOT (setFocus()));
531
532 return;
533
534 }
535
536 if (aColumn != mFocusColumn && !cb->isHidden())
537 cb->hide();
538
539 QListViewItem::paintCell (aPainter, aColorGroup, aColumn, aWidth, aAlign);
540 }
541
542 void paintFocus (QPainter *, const QColorGroup &, const QRect &)
543 {
544 /* Do not paint focus, because it presented by combo-box */
545 }
546
547 void setup()
548 {
549 QListViewItem::setup();
550 /* Increasing item's height by 30% */
551 setHeight ((int) (height() * 1.3));
552 }
553
554 HDSlotItem *mSlotCombo;
555 VBoxMediaComboBox *mHDCombo;
556 QComboBox *mCombos [2];
557 int mFocusColumn;
558 bool mAutoFocus;
559};
560
561class OnItemChangedEvent : public QEvent
562{
563public:
564 enum { Type = QEvent::User + 10 };
565 OnItemChangedEvent (QListViewItem *aItem)
566 : QEvent ((QEvent::Type) Type), mItem (aItem) {}
567
568 QListViewItem *mItem;
569};
570
571void VBoxHardDiskSettings::init()
572{
573 mPrevItem = 0;
574
575 /* toolbar */
576
577 VBoxToolBar *toolBar = new VBoxToolBar (0, mGbHDList, "snapshotToolBar");
578
579 mAddAttachmentAct->addTo (toolBar);
580 mRemoveAttachmentAct->addTo (toolBar);
581 mSelectHardDiskAct->addTo (toolBar);
582
583 toolBar->setUsesTextLabel (false);
584 toolBar->setUsesBigPixmaps (false);
585 toolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
586 toolBar->setOrientation (Qt::Vertical);
587#ifdef Q_WS_MAC
588 toolBar->setMacStyle();
589#endif
590 mToolBarLayout->insertWidget (0, toolBar);
591
592 /* context menu */
593 mContextMenu = new QPopupMenu (this);
594 mAddAttachmentAct->addTo (mContextMenu);
595 mRemoveAttachmentAct->addTo (mContextMenu);
596 mSelectHardDiskAct->addTo (mContextMenu);
597
598 /* icons */
599 mAddAttachmentAct->setIconSet
600 (VBoxGlobal::iconSet ("vdm_add_16px.png", "vdm_add_disabled_16px.png"));
601 mRemoveAttachmentAct->setIconSet
602 (VBoxGlobal::iconSet ("vdm_remove_16px.png", "vdm_remove_disabled_16px.png"));
603 mSelectHardDiskAct->setIconSet
604 (VBoxGlobal::iconSet ("select_file_16px.png", "select_file_dis_16px.png"));
605
606 /* rest */
607
608 new HDSpaceItem (mLvHD);
609
610 mSlotUniquizer = new HDSlotUniquizer (this);
611
612 qApp->installEventFilter (this);
613}
614
615void VBoxHardDiskSettings::getFromMachine (const CMachine &aMachine)
616{
617 AssertReturnVoid (mMachine.isNull());
618 AssertReturnVoid (!aMachine.isNull());
619
620 mMachine = aMachine;
621
622 {
623 CSATAController ctl = mMachine.GetSATAController();
624 if (ctl.isNull())
625 {
626 /* hide the SATA check box if the SATA controller is not available
627 * (i.e. in VirtualBox OSE) */
628 mSATACheck->setHidden (true);
629 }
630 else
631 {
632 mSATACheck->setChecked (ctl.GetEnabled());
633 }
634 }
635
636 CHardDisk2AttachmentVector vec = mMachine.GetHardDisk2Attachments();
637 for (size_t i = 0; i < vec.size(); ++ i)
638 {
639 CHardDisk2Attachment hda = vec [i];
640 HDListItem *item = createItem();
641 item->setAttachment (hda);
642 }
643
644 mLvHD->setSortColumn (0);
645 mLvHD->sort();
646 mLvHD->setSorting (-1);
647 mLvHD->setCurrentItem (mLvHD->firstChild());
648 onAfterCurrentChanged (0);
649}
650
651void VBoxHardDiskSettings::putBackToMachine()
652{
653 CSATAController ctl = mMachine.GetSATAController();
654 if (!ctl.isNull())
655 {
656 ctl.SetEnabled (mSATACheck->isChecked());
657 }
658
659 /* Detach all attached Hard Disks */
660 CHardDisk2AttachmentVector vec = mMachine.GetHardDisk2Attachments();
661 for (size_t i = 0; i < vec.size(); ++ i)
662 {
663 CHardDisk2Attachment hda = vec [i];
664 mMachine.DetachHardDisk2 (hda.GetBus(), hda.GetChannel(), hda.GetDevice());
665 if (!mMachine.isOk())
666 vboxProblem().cannotDetachHardDisk (this, mMachine,
667 vboxGlobal().getMedium (CMedium (hda.GetHardDisk())).location(),
668 hda.GetBus(), hda.GetChannel(), hda.GetDevice());
669 }
670
671 /* Sort & attach all listed Hard Disks */
672
673 mLvHD->setSortColumn (0);
674 mLvHD->sort();
675 LONG maxSATAPort = 1;
676
677 for (QListViewItem *item = mLvHD->firstChild(); item;
678 item = item->nextSibling())
679 {
680 if (item->rtti() != HDListItem::HDListItemType)
681 continue;
682
683 HDListItem *hdi = static_cast <HDListItem *> (item);
684
685 if (hdi->bus() == KStorageBus_SATA)
686 maxSATAPort = QMAX (hdi->channel() + 1, maxSATAPort);
687 mMachine.AttachHardDisk2 (hdi->id(),
688 hdi->bus(), hdi->channel(), hdi->device());
689 if (!mMachine.isOk())
690 vboxProblem().cannotAttachHardDisk (this, mMachine,
691 hdi->location(), hdi->bus(), hdi->channel(), hdi->device());
692 }
693
694 if (!ctl.isNull())
695 {
696 ctl.SetPortCount (maxSATAPort);
697 }
698}
699
700QString VBoxHardDiskSettings::checkValidity()
701{
702 QString result;
703 QStringList slList;
704 QValueList <QUuid> idList;
705
706 /* Search for coincidences through all the media-id */
707 for (QListViewItem *item = mLvHD->firstChild(); item;
708 item = item->nextSibling())
709 {
710 if (item->rtti() != HDListItem::HDListItemType)
711 continue;
712
713 HDListItem *hdi = static_cast <HDListItem *> (item);
714
715 QUuid id = hdi->id();
716 if (id.isNull())
717 {
718 result = tr ("No hard disk is selected for <i>%1</i>")
719 .arg (hdi->text (0));
720 break;
721 }
722 else if (idList.contains (id))
723 {
724 result = tr ("<i>%1</i> uses the hard disk that is already "
725 "attached to <i>%2</i>")
726 .arg (item->text (0)).arg (slList [idList.findIndex (id)]);
727 break;
728 }
729 else
730 {
731 slList << item->text (0);
732 idList << id;
733 }
734 }
735
736 return result;
737}
738
739void VBoxHardDiskSettings::addHDItem()
740{
741 /* Create a new item */
742 HDListItem *item = createItem();
743 item->moveFocusToColumn (1);
744 mLvHD->setCurrentItem (item);
745 if (!mLvHD->hasFocus())
746 mLvHD->setFocus();
747
748 /* Qt3 doesn't emit currentChanged() signal when the first item is added */
749 if (mLvHD->childCount() == 1)
750 onCurrentChanged (item);
751
752 /* Search through the attachments for the used hard disks */
753 QValueList <QUuid> usedList;
754 for (QListViewItem *it = mLvHD->firstChild(); it;
755 it = it->nextSibling())
756 {
757 if (it->rtti() != HDListItem::HDListItemType)
758 continue;
759
760 HDListItem *hdi = static_cast <HDListItem *> (it);
761
762 usedList << hdi->id();
763 }
764
765 item->tryToSelectNotOneOf (usedList);
766
767 /* Ask the user for a method to add a new hard disk */
768 int result = mLvHD->childCount() - 1 > item->hardDiskCount() ?
769 vboxProblem().confirmRunNewHDWzdOrVDM (this) :
770 QIMessageBox::Cancel;
771 if (result == QIMessageBox::Yes)
772 {
773 VBoxNewHDWzd dlg (this, "VBoxNewHDWzd");
774 if (dlg.exec() == QDialog::Accepted)
775 {
776 CHardDisk2 hd = dlg.hardDisk();
777 item->setId (dlg.hardDisk().GetId());
778 }
779 }
780 else if (result == QIMessageBox::No)
781 showMediaManager();
782
783 emit hardDiskListChanged();
784}
785
786void VBoxHardDiskSettings::delHDItem()
787{
788 if (mLvHD->currentItem())
789 {
790 QListViewItem *item = mLvHD->currentItem();
791 Assert (item == mPrevItem);
792 if (item == mPrevItem)
793 {
794 delete item;
795 mPrevItem = 0;
796
797 if (mLvHD->currentItem() &&
798 mLvHD->currentItem()->rtti() == HDSpaceItem::HDSpaceItemType &&
799 mLvHD->currentItem()->itemAbove() &&
800 mLvHD->currentItem()->itemAbove()->rtti() == HDListItem::HDListItemType)
801 mLvHD->setCurrentItem (mLvHD->currentItem()->itemAbove());
802 }
803 }
804
805 emit hardDiskListChanged();
806}
807
808void VBoxHardDiskSettings::showMediaManager()
809{
810 HDListItem *item = mLvHD->currentItem() &&
811 mLvHD->currentItem()->rtti() == HDListItem::HDListItemType ?
812 static_cast <HDListItem *> (mLvHD->currentItem()) : 0;
813
814 VBoxMediaManagerDlg dlg (this, "VBoxMediaManagerDlg",
815 WType_Dialog | WShowModal);
816
817 dlg.setup (VBoxDefs::MediaType_HardDisk, true /* aDoSelect */,
818 true /* aRefresh */, mMachine, item->id(),
819 mShowDiffsCheck->isOn());
820
821 if (dlg.exec() == VBoxMediaManagerDlg::Accepted)
822 item->setId (dlg.selectedId());
823}
824
825void VBoxHardDiskSettings::moveFocus (QListViewItem *aItem, const QPoint&, int aCol)
826{
827 if (aItem && aItem->rtti() == HDListItem::HDListItemType)
828 {
829 static_cast <HDListItem *> (aItem)->moveFocusToColumn (aCol);
830 onAfterCurrentChanged (aItem);
831 }
832}
833
834void VBoxHardDiskSettings::onCurrentChanged (QListViewItem *aItem)
835{
836 /* Postpone onCurrentChanged signal to be post-processed after all others */
837 QApplication::postEvent (this, new OnItemChangedEvent (aItem));
838}
839
840void VBoxHardDiskSettings::onSATACheckToggled (bool aOn)
841{
842 if (!aOn)
843 {
844 /* Search the list for the SATA ports */
845 HDListItem *sataItem = NULL;
846 for (QListViewItem *item = mLvHD->firstChild(); item;
847 item = item->nextSibling())
848 {
849 if (item->rtti() != HDListItem::HDListItemType)
850 continue;
851
852 HDListItem *hdi = static_cast <HDListItem *> (item);
853
854 if (hdi->bus() == KStorageBus_SATA)
855 {
856 sataItem = hdi;
857 break;
858 }
859 }
860
861 /* If list contains at least one SATA port */
862 if (sataItem)
863 {
864 int rc = vboxProblem().confirmDetachSATASlots (this);
865 if (rc != QIMessageBox::Ok)
866 {
867 /* Switch check-box back to "on" */
868 mSATACheck->blockSignals (true);
869 mSATACheck->setChecked (true);
870 mSATACheck->blockSignals (false);
871 return;
872 }
873 else
874 {
875 /* Delete SATA items */
876 mLvHD->blockSignals (true);
877 for (QListViewItem *item = mLvHD->firstChild(); item;)
878 {
879 if (item->rtti() == HDListItem::HDListItemType)
880 {
881 HDListItem *hdi = static_cast <HDListItem *> (item);
882 if (hdi->bus() == KStorageBus_SATA)
883 {
884 if (hdi == mLvHD->currentItem())
885 mPrevItem = NULL;
886
887 item = hdi->nextSibling();
888 delete hdi;
889 continue;
890 }
891 }
892
893 item = item->nextSibling();
894 }
895
896 mLvHD->blockSignals (false);
897 emit hardDiskListChanged();
898 }
899 }
900 }
901
902 int newSATAPortsCount = aOn && !mMachine.isNull() ? SATAPortsCount : 0;
903 if (mSlotUniquizer->getSATAPortsCount() != newSATAPortsCount)
904 {
905 mSlotUniquizer->setSATAPortsCount (newSATAPortsCount);
906 onAfterCurrentChanged (mPrevItem);
907 }
908}
909
910void VBoxHardDiskSettings::onShowDiffsCheckToggled (bool aOn)
911{
912 for (QListViewItem *item = mLvHD->firstChild(); item;
913 item = item->nextSibling())
914 {
915 if (item->rtti() != HDListItem::HDListItemType)
916 continue;
917
918 HDListItem *hdi = static_cast <HDListItem *> (item);
919
920 hdi->setShowDiffs (aOn);
921 }
922}
923
924void VBoxHardDiskSettings::onAfterCurrentChanged (QListViewItem *aItem)
925{
926 /* Process postponed onCurrentChanged event */
927 if (aItem != mPrevItem)
928 {
929 int prevFocusColumn =
930 mPrevItem && mPrevItem->rtti() == HDListItem::HDListItemType ?
931 static_cast<HDListItem*> (mPrevItem)->focusColumn() : 1;
932
933 if (mPrevItem && mPrevItem->rtti() == HDListItem::HDListItemType)
934 static_cast<HDListItem*> (mPrevItem)->moveFocusToColumn (-1);
935
936 if (aItem && aItem->rtti() == HDListItem::HDListItemType &&
937 static_cast<HDListItem*> (aItem)->focusColumn() == -1)
938 static_cast<HDListItem*> (aItem)->moveFocusToColumn (prevFocusColumn);
939
940 mPrevItem = aItem;
941 }
942
943 mAddAttachmentAct->setEnabled (mLvHD->childCount() <=
944 mSlotUniquizer->totalCount());
945 mRemoveAttachmentAct->setEnabled (aItem &&
946 aItem->rtti() == HDListItem::HDListItemType);
947 mSelectHardDiskAct->setEnabled (aItem &&
948 aItem->rtti() == HDListItem::HDListItemType &&
949 static_cast<HDListItem*> (aItem)->focusColumn() == 1);
950}
951
952void VBoxHardDiskSettings::onContextMenuRequested (QListViewItem * /*aItem*/,
953 const QPoint &aPoint, int)
954{
955 mContextMenu->exec (aPoint);
956}
957
958HDListItem *VBoxHardDiskSettings::createItem()
959{
960 QListViewItem *item = mLvHD->lastItem();
961 Assert (item->rtti() == HDSpaceItem::HDSpaceItemType);
962 HDListItem *last = item->itemAbove() &&
963 item->itemAbove()->rtti() == HDListItem::HDListItemType ?
964 static_cast <HDListItem *> (item->itemAbove()) : 0;
965
966 QUuid machineId = mMachine.GetId();
967
968 HDListItem *newItem = last ?
969 new HDListItem (mLvHD, last, this, mSlotUniquizer, machineId) :
970 new HDListItem (mLvHD, this, mSlotUniquizer, machineId);
971
972 AssertReturn (newItem != NULL, NULL);
973
974 newItem->setShowDiffs (mShowDiffsCheck->isOn());
975
976 return newItem;
977}
978
979bool VBoxHardDiskSettings::event (QEvent *aEvent)
980{
981 switch (aEvent->type())
982 {
983 /* Redirect postponed onCurrentChanged event */
984 case OnItemChangedEvent::Type:
985 {
986 OnItemChangedEvent *e = static_cast <OnItemChangedEvent *> (aEvent);
987 onAfterCurrentChanged (e->mItem);
988 break;
989 }
990 default:
991 break;
992 }
993
994 return QWidget::event (aEvent);
995}
996
997void VBoxHardDiskSettings::showEvent (QShowEvent *aEvent)
998{
999 QWidget::showEvent (aEvent);
1000 QTimer::singleShot (0, this, SLOT (adjustList()));
1001}
1002
1003bool VBoxHardDiskSettings::eventFilter (QObject *aObject, QEvent *aEvent)
1004{
1005 if (!aObject->isWidgetType())
1006 return QWidget::eventFilter (aObject, aEvent);
1007
1008 if (static_cast<QWidget*> (aObject)->topLevelWidget() != topLevelWidget())
1009 return QWidget::eventFilter (aObject, aEvent);
1010
1011 switch (aEvent->type())
1012 {
1013 /* Process double-click as "open combo-box" action */
1014 case QEvent::MouseButtonDblClick:
1015 {
1016 if (aObject != mLvHD->viewport())
1017 break;
1018
1019 QMouseEvent *e = static_cast<QMouseEvent*> (aEvent);
1020 QListViewItem *clickedItem = mLvHD->itemAt (e->pos());
1021 HDListItem *item = clickedItem &&
1022 clickedItem->rtti() == HDListItem::HDListItemType ?
1023 static_cast <HDListItem *> (clickedItem) : 0;
1024
1025 if (!item && mAddAttachmentAct->isEnabled())
1026 addHDItem();
1027 break;
1028 }
1029 /* Process mouse-move as "make tool-tip" action */
1030 case QEvent::MouseMove:
1031 {
1032 if (aObject != mLvHD->viewport())
1033 {
1034 if (!QToolTip::textFor (mLvHD->viewport()).isNull())
1035 QToolTip::remove (mLvHD->viewport());
1036 break;
1037 }
1038
1039 QMouseEvent *e = static_cast <QMouseEvent *> (aEvent);
1040 QListViewItem *hoveredItem = mLvHD->itemAt (e->pos());
1041 HDListItem *item = hoveredItem &&
1042 hoveredItem->rtti() == HDListItem::HDListItemType ?
1043 static_cast <HDListItem *> (hoveredItem) : 0;
1044
1045 QString oldTip = QToolTip::textFor (mLvHD->viewport());
1046 QString newTip = item ? item->toolTip() :
1047 tr ("Double-click to add a new attachment");
1048
1049 if (newTip != oldTip)
1050 {
1051 QToolTip::remove (mLvHD->viewport());
1052 QToolTip::add (mLvHD->viewport(), newTip);
1053 }
1054 break;
1055 }
1056 case QEvent::KeyPress:
1057 {
1058 if (!mLvHD->queryList (0, 0, false, true)->contains (aObject))
1059 break;
1060
1061 HDListItem *item = mLvHD->currentItem() &&
1062 mLvHD->currentItem()->rtti() == HDListItem::HDListItemType ?
1063 static_cast <HDListItem *> (mLvHD->currentItem()) : 0;
1064
1065 QKeyEvent *e = static_cast<QKeyEvent*> (aEvent);
1066 /* Process cursor-left as "move focus left" action */
1067 if (e->key() == Qt::Key_Left && !e->state())
1068 {
1069 if (item && item->focusColumn() != -1 &&
1070 item->focusColumn() > 0)
1071 {
1072 item->setAutoFocus (false);
1073 mLvHD->setFocus();
1074 item->moveFocusToColumn (item->focusColumn() - 1);
1075 onAfterCurrentChanged (item);
1076 }
1077 return true;
1078 } else
1079 /* Process cursor-right as "move focus right" action */
1080 if (e->key() == Qt::Key_Right && !e->state())
1081 {
1082 if (item && item->focusColumn() != -1 &&
1083 item->focusColumn() < mLvHD->columns() - 1)
1084 {
1085 item->setAutoFocus (false);
1086 mLvHD->setFocus();
1087 item->moveFocusToColumn (item->focusColumn() + 1);
1088 onAfterCurrentChanged (item);
1089 }
1090 return true;
1091 } else
1092 /* Process cursor-up as "move focus up" action */
1093 if (e->key() == Qt::Key_Up && !e->state())
1094 {
1095 if (item && item->focusColumn() != -1 &&
1096 item->itemAbove())
1097 {
1098 item->setAutoFocus (false);
1099 mLvHD->setFocus();
1100 mLvHD->setCurrentItem (item->itemAbove());
1101 }
1102 return true;
1103 } else
1104 /* Process cursor-down as "move focus down" action */
1105 if (e->key() == Qt::Key_Down && !e->state())
1106 {
1107 if (item && item->focusColumn() != -1 &&
1108 item->itemBelow())
1109 {
1110 item->setAutoFocus (false);
1111 mLvHD->setFocus();
1112 mLvHD->setCurrentItem (item->itemBelow());
1113 }
1114 return true;
1115 } else
1116 /* Process F2/Space as "open combo-box" actions */
1117 if (!e->state() &&
1118 (e->key() == Qt::Key_F2 || e->key() == Qt::Key_Space))
1119 {
1120 if (item)
1121 item->showEditor();
1122 return true;
1123 }
1124 /* Process Ctrl/Alt+Up/Down as "open combo-box" actions */
1125 if ((e->state() == Qt::AltButton || e->state() == Qt::ControlButton) &&
1126 (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))
1127 {
1128 if (item)
1129 item->showEditor();
1130 return true;
1131 } else
1132 if ((e->key() == Qt::Key_Tab && !e->state()) ||
1133 e->key() == Qt::Key_Backtab)
1134 {
1135 item->setAutoFocus (false);
1136 mLvHD->setFocus();
1137 }
1138 break;
1139 }
1140 /* Process focus event to toggle the current selection state */
1141 case QEvent::FocusIn:
1142 {
1143 if (aObject == mLvHD)
1144 onAfterCurrentChanged (mLvHD->currentItem());
1145 else if (!mGbHDList->queryList (0, 0, false, true)->contains (aObject))
1146 onAfterCurrentChanged (0);
1147
1148 break;
1149 }
1150 default:
1151 break;
1152 }
1153
1154 return QWidget::eventFilter (aObject, aEvent);
1155}
1156
1157void VBoxHardDiskSettings::adjustList()
1158{
1159 /* Search through the slots list for maximum element width */
1160 int minLength = 0;
1161 QFontMetrics fm = mLvHD->fontMetrics();
1162 QValueList<HDSlot> list = mSlotUniquizer->list (0, false);
1163 for (uint i = 0; i < list.size(); ++ i)
1164 {
1165 int length = fm.width (list [i].str);
1166 minLength = minLength < length ? length : minLength;
1167 }
1168 minLength = minLength > mLvHD->viewport()->width() * 0.4 ?
1169 (int) (mLvHD->viewport()->width() * 0.4) : minLength;
1170
1171 mLvHD->setColumnWidth (0,
1172 minLength /* maximum string width */ +
1173 6 * 2 /* 2 combo-box margin */ +
1174 HDSlotItem::scrollBarWidth() /* scrollbar */);
1175 mLvHD->setColumnWidth (1, mLvHD->viewport()->width() - mLvHD->columnWidth (0));
1176}
1177
1178#include "VBoxHardDiskSettings.ui.moc"
1179
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