VirtualBox

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

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

"Select..." button made enabled only when the second column (e.g. the hard disk) is in focus in the attachment list.

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