VirtualBox

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

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

SATA UI: Try to fix incorrect column adjustment on some platforms.

  • 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 QTimer::singleShot (0, this, SLOT (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