VirtualBox

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

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

FE/Qt-OSX: Fixed gray background of comboboxes on Mac OS X.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.5 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, 0, i),
138 KStorageBus_SATA, 0, i);
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 selector for IDE & SATA
151 * slots.
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 void setText (const QString &aText)
182 {
183 QComboBox::setCurrentText (aText);
184 emit textChanged();
185 }
186
187 KStorageBus currentBus() const
188 {
189 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
190 KStorageBus_Null);
191 return mHDSlots [currentItem()].bus;
192 }
193
194 LONG currentChannel() const
195 {
196 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
197 0);
198 return mHDSlots [currentItem()].channel;
199 }
200
201 LONG currentDevice() const
202 {
203 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
204 0);
205 return mHDSlots [currentItem()].device;
206 }
207
208private slots:
209
210 void refresh()
211 {
212 QString current = currentText();
213 mHDSlots = mUniq->list (this);
214 clear();
215
216 bool setCurrent = false;
217
218 for (QValueList<HDSlot>::const_iterator it = mHDSlots.begin();
219 it != mHDSlots.end(); ++ it)
220 {
221 insertItem ((*it).str);
222 if (!setCurrent)
223 setCurrent = (*it).str == current;
224 }
225
226 if (setCurrent)
227 setCurrentText (current);
228 }
229
230 void updateToolTip()
231 {
232 QString oldTip = QToolTip::textFor (this);
233 QString newTip = currentText();
234
235 if (newTip != oldTip)
236 {
237 QToolTip::remove (this);
238 QToolTip::add (this, newTip);
239 }
240 }
241
242signals:
243
244 void textChanged();
245
246private:
247
248 HDSlotUniquizer *mUniq;
249
250 QValueList<HDSlot> mHDSlots;
251};
252
253/**
254 * VBoxMediaComboBox class reimplementation to use as selector for VDI
255 * image.
256 */
257class HDVdiItem : public VBoxMediaComboBox
258{
259 Q_OBJECT
260
261public:
262
263 HDVdiItem (QWidget *aParent, int aType, QListViewItem *aItem)
264 : VBoxMediaComboBox (aParent, "HDVdiItem", aType)
265 , mItem (aItem)
266 {
267 setFocusPolicy (QWidget::NoFocus);
268 connect (&vboxGlobal(),
269 SIGNAL (mediaRemoved (VBoxDefs::DiskType, const QUuid &)),
270 this, SLOT (repaintHandler()));
271 }
272
273private slots:
274
275 void repaintHandler()
276 {
277 mItem->repaint();
278 }
279
280private:
281
282 QListViewItem *mItem;
283};
284
285QValueList<HDSlot> HDSlotUniquizer::list (HDSlotItem *aSubscriber, bool aFilter)
286{
287 QValueList<HDSlot> list = mIDEList + mSATAList;
288
289 if (!aFilter)
290 return list;
291
292 /* Compose exclude list */
293 QStringList excludeList;
294 for (uint i = 0; i < mSubscribersList.size(); ++ i)
295 if (mSubscribersList [i] != aSubscriber)
296 excludeList << mSubscribersList [i]->currentText();
297
298 /* Filter the list */
299 QValueList<HDSlot>::Iterator it = list.begin();
300 while (it != list.end())
301 {
302 if (excludeList.contains ((*it).str))
303 it = list.remove (it);
304 else
305 ++ it;
306 }
307
308 return list;
309}
310
311class HDSpaceItem : public QListViewItem
312{
313public:
314
315 enum { HDSpaceItemType = 1011 };
316
317 HDSpaceItem (QListView *aParent)
318 : QListViewItem (aParent)
319 {
320 setSelectable (false);
321 }
322
323 int rtti() const { return HDSpaceItemType; }
324};
325
326class HDListItem : public QListViewItem
327{
328public:
329
330 enum { HDListItemType = 1010 };
331
332 HDListItem (VBoxHardDiskSettings *aWidget, QListView *aParent,
333 QListViewItem *aAfter,
334 HDSlotUniquizer *aUniq, const CMachine &aMachine)
335 : QListViewItem (aParent, aAfter)
336 , mWidget (aWidget)
337 , mUniq (aUniq)
338 , mMachine (aMachine)
339 , mFocusColumn (-1)
340 {
341 init();
342 }
343
344 HDListItem (VBoxHardDiskSettings *aWidget, QListView *aParent,
345 HDSlotUniquizer *aUniq, const CMachine &aMachine)
346 : QListViewItem (aParent)
347 , mWidget (aWidget)
348 , mUniq (aUniq)
349 , mMachine (aMachine)
350 , mFocusColumn (-1)
351 {
352 init();
353 }
354
355 int rtti() const { return HDListItemType; }
356
357 QString toolTip()
358 {
359 return QToolTip::textFor (mVector [1]);
360 }
361
362 HDListItem* nextSibling() const
363 {
364 QListViewItem *item = QListViewItem::nextSibling();
365 return item && item->rtti() == HDListItemType ?
366 static_cast<HDListItem*> (item) : 0;
367 }
368
369 void setId (const QUuid &aId) const
370 {
371 static_cast<VBoxMediaComboBox*> (mVector [1])->setCurrentItem (aId);
372 }
373
374 QUuid getId() const
375 {
376 return static_cast<VBoxMediaComboBox*> (mVector [1])->getId();
377 }
378
379 KStorageBus bus() const
380 {
381 return static_cast<HDSlotItem*> (mVector [0])->currentBus();
382 }
383
384 LONG channel() const
385 {
386 return static_cast<HDSlotItem*> (mVector [0])->currentChannel();
387 }
388
389 LONG device() const
390 {
391 return static_cast<HDSlotItem*> (mVector [0])->currentDevice();
392 }
393
394 QString text (int aColumn) const
395 {
396 return mVector [aColumn]->currentText();
397 }
398
399 void moveFocusToColumn (int aCol)
400 {
401 mFocusColumn = aCol;
402 repaint();
403 }
404
405 void showEditor()
406 {
407 if (mVector [mFocusColumn]->count())
408 mVector [mFocusColumn]->popup();
409 }
410
411 int focusColumn() const
412 {
413 return mFocusColumn;
414 }
415
416 void setAttachment (const CHardDiskAttachment &aHda)
417 {
418 QString device = vboxGlobal()
419 .toFullString (aHda.GetBus(), aHda.GetChannel(), aHda.GetDevice());
420
421 if (mVector [0]->listBox()->findItem (device, Qt::ExactMatch))
422 static_cast<HDSlotItem*> (mVector [0])->setText (device);
423
424 static_cast<VBoxMediaComboBox*> (mVector [1])->
425 setCurrentItem (aHda.GetHardDisk().GetId());
426
427 mVector [0]->setHidden (true);
428 mVector [1]->setHidden (true);
429 }
430
431private:
432
433 void init()
434 {
435 setSelectable (false);
436 mVector.setAutoDelete (true);
437 mVector.resize (listView()->columns());
438
439 QComboBox *cbslot = new HDSlotItem (listView()->viewport(), mUniq);
440 QObject::connect (cbslot, SIGNAL (activated (int)),
441 mWidget, SIGNAL (hddListChanged()));
442 mVector.insert (0, cbslot);
443
444 VBoxMediaComboBox *cbvdi = new HDVdiItem (listView()->viewport(),
445 VBoxDefs::HD, this);
446 QObject::connect (cbvdi, SIGNAL (activated (int)),
447 mWidget, SIGNAL (hddListChanged()));
448 mVector.insert (1, cbvdi);
449 cbvdi->setBelongsTo (mMachine.GetId());
450 cbvdi->refresh();
451#ifdef Q_WS_MAC
452 /* White background on Mac OS X */
453 cbslot->setPaletteBackgroundColor (cbslot->parentWidget()->paletteBackgroundColor());
454 cbvdi->setPaletteBackgroundColor (cbvdi->parentWidget()->paletteBackgroundColor());
455#endif /* Q_WS_MAC */
456 }
457
458 void paintCell (QPainter *aPainter, const QColorGroup &aColorGroup,
459 int aColumn, int aWidth, int aAlign)
460 {
461 QComboBox *cb = mVector [aColumn];
462
463 int indent = 0;
464 for (int i = 0; i < aColumn; ++ i)
465 indent = listView()->columnWidth (i);
466
467 QRect rect = listView()->itemRect (this);
468
469 int xc = rect.x() + indent;
470 int yc = rect.y();
471 int wc = listView()->columnWidth (aColumn);
472 int hc = rect.height();
473
474 cb->move (xc, yc);
475 cb->resize (wc, hc);
476
477 if (aColumn == mFocusColumn && cb->isHidden())
478 cb->show();
479 else if (aColumn != mFocusColumn && !cb->isHidden())
480 cb->hide();
481
482 QListViewItem::paintCell (aPainter, aColorGroup, aColumn, aWidth, aAlign);
483 }
484
485 void paintFocus (QPainter *, const QColorGroup &, const QRect &)
486 {
487 /* Do not paint focus, because it presented by combo-box */
488 }
489
490 void setup()
491 {
492 QListViewItem::setup();
493 /* Increasing item's height by 30% */
494 setHeight ((int) (height() * 1.3));
495 }
496
497 VBoxHardDiskSettings *mWidget;
498 HDSlotUniquizer *mUniq;
499 CMachine mMachine;
500 QPtrVector<QComboBox> mVector;
501 int mFocusColumn;
502};
503
504class OnItemChangedEvent : public QEvent
505{
506public:
507 enum { Type = QEvent::User + 10 };
508 OnItemChangedEvent (QListViewItem *aItem)
509 : QEvent ((QEvent::Type) Type), mItem (aItem) {}
510
511 QListViewItem *mItem;
512};
513
514void VBoxHardDiskSettings::init()
515{
516 mPrevItem = 0;
517
518 /* toolbar */
519
520 VBoxToolBar *toolBar = new VBoxToolBar (0, mGbHDList, "snapshotToolBar");
521
522 mAddAttachmentAct->addTo (toolBar);
523 mRemoveAttachmentAct->addTo (toolBar);
524 mSelectHardDiskAct->addTo (toolBar);
525
526 toolBar->setUsesTextLabel (false);
527 toolBar->setUsesBigPixmaps (false);
528 toolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
529 toolBar->setOrientation (Qt::Vertical);
530#ifdef Q_WS_MAC
531 toolBar->setMacStyle();
532#endif
533 mToolBarLayout->insertWidget (0, toolBar);
534
535 /* context menu */
536 mContextMenu = new QPopupMenu (this);
537 mAddAttachmentAct->addTo (mContextMenu);
538 mRemoveAttachmentAct->addTo (mContextMenu);
539 mSelectHardDiskAct->addTo (mContextMenu);
540
541 /* icons */
542 mAddAttachmentAct->setIconSet
543 (VBoxGlobal::iconSet ("vdm_add_16px.png", "vdm_add_disabled_16px.png"));
544 mRemoveAttachmentAct->setIconSet
545 (VBoxGlobal::iconSet ("vdm_remove_16px.png", "vdm_remove_disabled_16px.png"));
546 mSelectHardDiskAct->setIconSet
547 (VBoxGlobal::iconSet ("select_file_16px.png", "select_file_dis_16px.png"));
548
549 /* connections */
550 connect (mCbSATA, SIGNAL (toggled (bool)),
551 this, SLOT (onToggleSATAController (bool)));
552 connect (mLvHD, SIGNAL (pressed (QListViewItem*, const QPoint&, int)),
553 this, SLOT (moveFocus (QListViewItem*, const QPoint&, int)));
554 connect (mLvHD, SIGNAL (currentChanged (QListViewItem*)),
555 this, SLOT (onCurrentChanged (QListViewItem*)));
556 connect (mLvHD, SIGNAL (contextMenuRequested (QListViewItem*, const QPoint&, int)),
557 this, SLOT (onContextMenuRequested (QListViewItem*, const QPoint&, int)));
558
559 /* rest */
560
561 new HDSpaceItem (mLvHD);
562
563 mSlotUniquizer = new HDSlotUniquizer (this);
564
565 qApp->installEventFilter (this);
566}
567
568void VBoxHardDiskSettings::getFromMachine (const CMachine &aMachine)
569{
570 mMachine = aMachine;
571
572 {
573 CSATAController ctl = mMachine.GetSATAController();
574 if (ctl.isNull())
575 {
576 /* hide the SATA check box if the SATA controller is not available
577 * (i.e. in VirtualBox OSE) */
578 mCbSATA->setHidden (true);
579 }
580 else
581 {
582 mCbSATA->setChecked (ctl.GetEnabled());
583 }
584 }
585
586 CHardDiskAttachmentEnumerator en =
587 mMachine.GetHardDiskAttachments().Enumerate();
588 while (en.HasMore())
589 {
590 CHardDiskAttachment hda = en.GetNext();
591 HDListItem *item = createItem (mSlotUniquizer, mMachine);
592 item->setAttachment (hda);
593 }
594 mLvHD->setSortColumn (0);
595 mLvHD->sort();
596 mLvHD->setSorting (-1);
597 mLvHD->setCurrentItem (mLvHD->firstChild());
598 onAfterCurrentChanged (0);
599}
600
601void VBoxHardDiskSettings::putBackToMachine()
602{
603 CSATAController ctl = mMachine.GetSATAController();
604 if (!ctl.isNull())
605 {
606 ctl.SetEnabled (mCbSATA->isChecked());
607 }
608
609 /* Detach all attached Hard Disks */
610 CHardDiskAttachmentEnumerator en =
611 mMachine.GetHardDiskAttachments().Enumerate();
612 while (en.HasMore())
613 {
614 CHardDiskAttachment hda = en.GetNext();
615 mMachine.DetachHardDisk (hda.GetBus(), hda.GetChannel(), hda.GetDevice());
616 if (!mMachine.isOk())
617 vboxProblem().cannotDetachHardDisk (this, mMachine,
618 hda.GetBus(), hda.GetChannel(), hda.GetDevice());
619 }
620
621 /* Sort&Attach all listed Hard Disks */
622 mLvHD->setSortColumn (0);
623 mLvHD->sort();
624 LONG maxSATAPort = 1;
625 HDListItem *item = mLvHD->firstChild() &&
626 mLvHD->firstChild()->rtti() == HDListItem::HDListItemType ?
627 static_cast<HDListItem*> (mLvHD->firstChild()) : 0;
628 while (item)
629 {
630 if (item->bus() == KStorageBus_SATA)
631 maxSATAPort = maxSATAPort < item->device() ?
632 item->device() : maxSATAPort;
633 mMachine.AttachHardDisk (item->getId(),
634 item->bus(), item->channel(), item->device());
635 if (!mMachine.isOk())
636 vboxProblem().cannotAttachHardDisk (this, mMachine, item->getId(),
637 item->bus(), item->channel(), item->device());
638 item = item->nextSibling();
639 }
640
641 if (!ctl.isNull())
642 {
643 mMachine.GetSATAController().SetPortCount (maxSATAPort);
644 }
645}
646
647QString VBoxHardDiskSettings::checkValidity()
648{
649 QString result;
650 QStringList slList;
651 QStringList idList;
652
653 /* Search for coincidences through all the media-id */
654 HDListItem *item = mLvHD->firstChild() &&
655 mLvHD->firstChild()->rtti() == HDListItem::HDListItemType ?
656 static_cast<HDListItem*> (mLvHD->firstChild()) : 0;
657 while (item)
658 {
659 QString id = item->getId().toString();
660 if (idList.contains (id))
661 {
662 result = tr ("<i>%1</i> uses the hard disk that is already "
663 "attached to <i>%2</i>")
664 .arg (item->text (0)).arg (slList [idList.findIndex (id)]);
665 break;
666 }
667 else
668 {
669 slList << item->text (0);
670 idList << id;
671 }
672 item = item->nextSibling();
673 }
674
675 return result;
676}
677
678void VBoxHardDiskSettings::addHDItem()
679{
680 HDListItem *item = createItem (mSlotUniquizer, mMachine);
681 item->moveFocusToColumn (0);
682 mLvHD->setCurrentItem (item);
683 if (!mLvHD->hasFocus())
684 mLvHD->setFocus();
685 /* Qt3 isn't emits currentChanged() signal if first list-view item added */
686 if (mLvHD->childCount() == 1)
687 onCurrentChanged (item);
688
689 emit hddListChanged();
690}
691
692void VBoxHardDiskSettings::delHDItem()
693{
694 if (mLvHD->currentItem())
695 {
696 QListViewItem *item = mLvHD->currentItem();
697 Assert (item == mPrevItem);
698 if (item == mPrevItem)
699 {
700 delete item;
701 mPrevItem = 0;
702
703 if (mLvHD->currentItem() &&
704 mLvHD->currentItem()->rtti() == HDSpaceItem::HDSpaceItemType &&
705 mLvHD->currentItem()->itemAbove() &&
706 mLvHD->currentItem()->itemAbove()->rtti() == HDListItem::HDListItemType)
707 mLvHD->setCurrentItem (mLvHD->currentItem()->itemAbove());
708 }
709 }
710
711 emit hddListChanged();
712}
713
714void VBoxHardDiskSettings::showVDM()
715{
716 HDListItem *item = mLvHD->currentItem() &&
717 mLvHD->currentItem()->rtti() == HDListItem::HDListItemType ?
718 static_cast<HDListItem*> (mLvHD->currentItem()) : 0;
719
720 VBoxDiskImageManagerDlg dlg (this, "VBoxDiskImageManagerDlg",
721 WType_Dialog | WShowModal);
722
723 QUuid machineId = mMachine.GetId();
724 QUuid hdId = item->getId();
725
726 dlg.setup (VBoxDefs::HD, true, &machineId, true /* aRefresh */,
727 mMachine, hdId, QUuid(), QUuid());
728
729 if (dlg.exec() == VBoxDiskImageManagerDlg::Accepted)
730 item->setId (dlg.getSelectedUuid());
731}
732
733void VBoxHardDiskSettings::moveFocus (QListViewItem *aItem, const QPoint&, int aCol)
734{
735 if (aItem && aItem->rtti() == HDListItem::HDListItemType)
736 {
737 static_cast<HDListItem*> (aItem)->moveFocusToColumn (aCol);
738 onAfterCurrentChanged (aItem);
739 }
740}
741
742void VBoxHardDiskSettings::onCurrentChanged (QListViewItem *aItem)
743{
744 /* Postpone onCurrentChanged signal to be post-processed after all others */
745 QApplication::postEvent (this, new OnItemChangedEvent (aItem));
746}
747
748void VBoxHardDiskSettings::onToggleSATAController (bool aOn)
749{
750 if (!aOn)
751 {
752 HDListItem *firstItem = mLvHD->firstChild() &&
753 mLvHD->firstChild()->rtti() == HDListItem::HDListItemType ?
754 static_cast<HDListItem*> (mLvHD->firstChild()) : 0;
755
756 /* Search the list for the SATA ports in */
757 HDListItem *sataItem = firstItem;
758 while (sataItem)
759 {
760 if (sataItem->bus() == KStorageBus_SATA)
761 break;
762 sataItem = sataItem->nextSibling();
763 }
764
765 /* If list contains at least one SATA port */
766 if (sataItem)
767 {
768 int rc = vboxProblem().confirmDetachSATASlots (this);
769 if (rc != QIMessageBox::Ok)
770 {
771 /* Switch check-box back to "on" */
772 mCbSATA->blockSignals (true);
773 mCbSATA->setChecked (true);
774 mCbSATA->blockSignals (false);
775 return;
776 }
777 else
778 {
779 /* Delete SATA items */
780 HDListItem *it = firstItem;
781 mLvHD->blockSignals (true);
782 while (it)
783 {
784 HDListItem *curIt = it;
785 it = it->nextSibling();
786 if (curIt->bus() == KStorageBus_SATA)
787 {
788 if (curIt == mLvHD->currentItem())
789 mPrevItem = 0;
790 delete curIt;
791 }
792 }
793 mLvHD->blockSignals (false);
794 emit hddListChanged();
795 }
796 }
797 }
798
799 int newSATAPortsCount = aOn && !mMachine.isNull() ? SATAPortsCount : 0;
800 if (mSlotUniquizer->getSATAPortsCount() != newSATAPortsCount)
801 {
802 mSlotUniquizer->setSATAPortsCount (newSATAPortsCount);
803 onAfterCurrentChanged (mLvHD->currentItem());
804 }
805}
806
807void VBoxHardDiskSettings::onAfterCurrentChanged (QListViewItem *aItem)
808{
809 /* Process postponed onCurrentChanged event */
810 if (aItem != mPrevItem)
811 {
812 if (aItem && aItem->rtti() == HDListItem::HDListItemType &&
813 static_cast<HDListItem*> (aItem)->focusColumn() == -1)
814 {
815 int prevFocusColumn = 0;
816 if (mPrevItem && mPrevItem->rtti() == HDListItem::HDListItemType)
817 prevFocusColumn = static_cast<HDListItem*> (mPrevItem)->focusColumn();
818 static_cast<HDListItem*> (aItem)->moveFocusToColumn (prevFocusColumn);
819 }
820
821 if (mPrevItem && mPrevItem->rtti() == HDListItem::HDListItemType)
822 static_cast<HDListItem*> (mPrevItem)->moveFocusToColumn (-1);
823
824 mPrevItem = aItem;
825 }
826
827 mAddAttachmentAct->setEnabled (mLvHD->childCount() <=
828 mSlotUniquizer->totalCount());
829 mRemoveAttachmentAct->setEnabled (aItem &&
830 aItem->rtti() == HDListItem::HDListItemType);
831 mSelectHardDiskAct->setEnabled (aItem &&
832 aItem->rtti() == HDListItem::HDListItemType &&
833 static_cast<HDListItem*> (aItem)->focusColumn() == 1);
834}
835
836void VBoxHardDiskSettings::onContextMenuRequested (QListViewItem * /*aItem*/,
837 const QPoint &aPoint, int)
838{
839 mContextMenu->exec (aPoint);
840}
841
842HDListItem* VBoxHardDiskSettings::createItem (HDSlotUniquizer *aUniq,
843 const CMachine &aMachine)
844{
845 QListViewItem *item = mLvHD->lastItem();
846 Assert (item->rtti() == HDSpaceItem::HDSpaceItemType);
847 HDListItem *last = item->itemAbove() &&
848 item->itemAbove()->rtti() == HDListItem::HDListItemType ?
849 static_cast<HDListItem*> (item->itemAbove()) : 0;
850
851 return last ?
852 new HDListItem (this, mLvHD, last, aUniq, aMachine) :
853 new HDListItem (this, mLvHD, aUniq, aMachine);
854}
855
856bool VBoxHardDiskSettings::event (QEvent *aEvent)
857{
858 switch (aEvent->type())
859 {
860 /* Redirect postponed onCurrentChanged event */
861 case OnItemChangedEvent::Type:
862 {
863 OnItemChangedEvent *e = static_cast<OnItemChangedEvent*> (aEvent);
864 onAfterCurrentChanged (e->mItem);
865 break;
866 }
867 default:
868 break;
869 }
870
871 return QWidget::event (aEvent);
872}
873
874void VBoxHardDiskSettings::showEvent (QShowEvent *aEvent)
875{
876 QWidget::showEvent (aEvent);
877 QTimer::singleShot (0, this, SLOT (adjustList()));
878}
879
880bool VBoxHardDiskSettings::eventFilter (QObject *aObject, QEvent *aEvent)
881{
882 if (!aObject->isWidgetType())
883 return QWidget::eventFilter (aObject, aEvent);
884
885 if (static_cast<QWidget*> (aObject)->topLevelWidget() != topLevelWidget())
886 return QWidget::eventFilter (aObject, aEvent);
887
888 switch (aEvent->type())
889 {
890 /* Process double-click as "open combo-box" action */
891 case QEvent::MouseButtonDblClick:
892 {
893 if (aObject != mLvHD->viewport())
894 break;
895
896 QMouseEvent *e = static_cast<QMouseEvent*> (aEvent);
897 QListViewItem *clickedItem = mLvHD->itemAt (QPoint (e->x(), e->y()));
898 HDListItem *item = clickedItem &&
899 clickedItem->rtti() == HDListItem::HDListItemType ?
900 static_cast<HDListItem*> (clickedItem) : 0;
901
902 if (!item && mAddAttachmentAct->isEnabled())
903 addHDItem();
904 break;
905 }
906 /* Process mouse-move as "make tool-tip" action */
907 case QEvent::MouseMove:
908 {
909 if (aObject != mLvHD->viewport())
910 {
911 if (!QToolTip::textFor (mLvHD->viewport()).isNull())
912 QToolTip::remove (mLvHD->viewport());
913 break;
914 }
915
916 QMouseEvent *e = static_cast<QMouseEvent*> (aEvent);
917 QListViewItem *hoveredItem = mLvHD->itemAt (QPoint (e->x(), e->y()));
918 HDListItem *item = hoveredItem &&
919 hoveredItem->rtti() == HDListItem::HDListItemType ?
920 static_cast<HDListItem*> (hoveredItem) : 0;
921
922 QString oldTip = QToolTip::textFor (mLvHD->viewport());
923 QString newTip = item ? item->toolTip() :
924 tr ("Double-click to add a new attachment");
925
926 if (newTip != oldTip)
927 {
928 QToolTip::remove (mLvHD->viewport());
929 QToolTip::add (mLvHD->viewport(), newTip);
930 }
931 break;
932 }
933 case QEvent::KeyPress:
934 {
935 if (aObject != mLvHD)
936 break;
937
938 HDListItem *item = mLvHD->currentItem() &&
939 mLvHD->currentItem()->rtti() == HDListItem::HDListItemType ?
940 static_cast<HDListItem*> (mLvHD->currentItem()) : 0;
941
942 QKeyEvent *e = static_cast<QKeyEvent*> (aEvent);
943 /* Process cursor-left as "move focus left" action */
944 if (e->key() == Qt::Key_Left && !e->state())
945 {
946 if (item && item->focusColumn() != -1 &&
947 item->focusColumn() > 0)
948 {
949 item->moveFocusToColumn (item->focusColumn() - 1);
950 onAfterCurrentChanged (item);
951 }
952 } else
953 /* Process cursor-right as "move focus right" action */
954 if (e->key() == Qt::Key_Right && !e->state())
955 {
956 if (item && item->focusColumn() != -1 &&
957 item->focusColumn() < mLvHD->columns() - 1)
958 {
959 item->moveFocusToColumn (item->focusColumn() + 1);
960 onAfterCurrentChanged (item);
961 }
962 } else
963 /* Process F2/Space as "open combo-box" actions */
964 if (!e->state() &&
965 (e->key() == Qt::Key_F2 || e->key() == Qt::Key_Space))
966 {
967 if (item)
968 item->showEditor();
969 }
970 /* Process Ctrl/Alt+Up/Down as "open combo-box" actions */
971 if ((e->state() == Qt::AltButton || e->state() == Qt::ControlButton) &&
972 (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))
973 {
974 if (item)
975 {
976 item->showEditor();
977 return true;
978 }
979 }
980 break;
981 }
982 /* Process focus event to toggle the current selection state */
983 case QEvent::FocusIn:
984 {
985 if (aObject == mLvHD)
986 onAfterCurrentChanged (mLvHD->currentItem());
987 else if (!mGbHDList->queryList (0, 0, false, true)->contains (aObject))
988 onAfterCurrentChanged (0);
989 break;
990 }
991 default:
992 break;
993 }
994
995 return QWidget::eventFilter (aObject, aEvent);
996}
997
998void VBoxHardDiskSettings::adjustList()
999{
1000 /* Search through the slots list for maximum element width */
1001 int minLength = 0;
1002 QFontMetrics fm = mLvHD->fontMetrics();
1003 QValueList<HDSlot> list = mSlotUniquizer->list (0, false);
1004 for (uint i = 0; i < list.size(); ++ i)
1005 {
1006 int length = fm.width (list [i].str);
1007 minLength = minLength < length ? length : minLength;
1008 }
1009 minLength = minLength > mLvHD->viewport()->width() * 0.4 ?
1010 (int) (mLvHD->viewport()->width() * 0.4) : minLength;
1011
1012 mLvHD->setColumnWidth (0, minLength + 10 /* little spacing */);
1013 mLvHD->setColumnWidth (1, mLvHD->viewport()->width() - mLvHD->columnWidth (0));
1014}
1015
1016#include "VBoxHardDiskSettings.ui.moc"
1017
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