VirtualBox

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

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

AHCI: if no hard disk is attached we have to at least report one available port

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.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 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (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
19/****************************************************************************
20** ui.h extension file, included from the uic-generated form implementation.
21**
22** If you wish to add, delete or rename functions or slots use
23** Qt Designer which will update this file, preserving your code. Create an
24** init() function in place of a constructor, and a destroy() function in
25** place of a destructor.
26*****************************************************************************/
27
28/** SATA Ports count */
29static const ULONG SATAPortsCount = 30;
30
31class HDSlotItem;
32
33/** Combines the string and the numeric representation of the hard disk slot. */
34struct HDSlot
35{
36 HDSlot() : bus (KStorageBus_Null), channel (0), device (0) {}
37 HDSlot (const QString &aStr, KStorageBus aBus, LONG aChannel, LONG aDevice)
38 : str (aStr), bus (aBus), channel (aChannel), device (aDevice) {}
39
40 QString str;
41 KStorageBus bus;
42 LONG channel;
43 LONG device;
44};
45
46/**
47 * QObject class reimplementation to use for making selected IDE & SATA
48 * slots unique.
49 */
50class HDSlotUniquizer : public QObject
51{
52 Q_OBJECT
53
54public:
55
56 HDSlotUniquizer (QWidget *aParent, int aSataPortsCount = 0)
57 : QObject (aParent)
58 , mSataPortsCount (aSataPortsCount)
59 {
60 /* Compose Lists */
61 makeIDEList();
62 makeSATAList();
63 }
64
65 QValueList<HDSlot> list (HDSlotItem *aForSubscriber, bool aFilter = true);
66
67 int totalCount() { return mIDEList.size() + mSATAList.size(); }
68
69 int getSATAPortsCount()
70 {
71 return mSataPortsCount;
72 }
73
74 void setSATAPortsCount (int aSataPortsCount)
75 {
76 mSataPortsCount = aSataPortsCount;
77 makeSATAList();
78 }
79
80 void subscribe (HDSlotItem *aSubscriber)
81 {
82 bool result = mSubscribersList.resize (mSubscribersList.size() + 1);
83 if (!result)
84 return;
85
86 mSubscribersList.insert (mSubscribersList.size() - 1, aSubscriber);
87 mSubscribersList.sort();
88
89 emit listChanged();
90 }
91
92 void unsubscribe (HDSlotItem *aSubscriber)
93 {
94 int index = mSubscribersList.findRef (aSubscriber);
95 if (index == -1)
96 return;
97
98 mSubscribersList.remove (index);
99 mSubscribersList.sort();
100 mSubscribersList.resize (mSubscribersList.size() - 1);
101
102 emit listChanged();
103 }
104
105signals:
106
107 void listChanged();
108
109private:
110
111 void makeIDEList()
112 {
113 mIDEList.clear();
114
115 /* IDE Primary Master */
116 mIDEList << HDSlot (vboxGlobal().toFullString (KStorageBus_IDE, 0, 0),
117 KStorageBus_IDE, 0, 0);
118 /* IDE Primary Slave */
119 mIDEList << HDSlot (vboxGlobal().toFullString (KStorageBus_IDE, 0, 1),
120 KStorageBus_IDE, 0, 1);
121 /* IDE Secondary Slave */
122 mIDEList << HDSlot (vboxGlobal().toFullString (KStorageBus_IDE, 1, 1),
123 KStorageBus_IDE, 1, 1);
124
125 emit listChanged();
126 }
127
128 void makeSATAList()
129 {
130 mSATAList.clear();
131
132 for (int i = 0; i < mSataPortsCount; ++ i)
133 mSATAList << HDSlot (vboxGlobal().toFullString (KStorageBus_SATA, 0, i),
134 KStorageBus_SATA, 0, i);
135
136 emit listChanged();
137 }
138
139 int mSataPortsCount;
140 QValueList<HDSlot> mIDEList;
141 QValueList<HDSlot> mSATAList;
142 QPtrVector<HDSlotItem> mSubscribersList;
143};
144
145/**
146 * QComboBox class reimplementation to use as selector for IDE & SATA
147 * slots.
148 */
149class HDSlotItem : public QComboBox
150{
151 Q_OBJECT
152
153public:
154
155 HDSlotItem (QWidget *aParent, HDSlotUniquizer *aUniq)
156 : QComboBox (aParent)
157 , mUniq (aUniq)
158 {
159 /* In some qt themes embedded list-box is not used by default */
160 if (!listBox())
161 setListBox (new QListBox (this));
162
163 refresh();
164 mUniq->subscribe (this);
165 qApp->installEventFilter (this);
166 connect (mUniq, SIGNAL (listChanged()), this, SLOT (refresh()));
167 connect (this, SIGNAL (activated (int)), mUniq, SIGNAL (listChanged()));
168 connect (this, SIGNAL (textChanged()), mUniq, SIGNAL (listChanged()));
169 }
170
171 ~HDSlotItem()
172 {
173 mUniq->unsubscribe (this);
174 }
175
176 void setText (const QString &aText)
177 {
178 QComboBox::setCurrentText (aText);
179 emit textChanged();
180 }
181
182 KStorageBus currentBus() const
183 {
184 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
185 KStorageBus_Null);
186 return mHDSlots [currentItem()].bus;
187 }
188
189 LONG currentChannel() const
190 {
191 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
192 0);
193 return mHDSlots [currentItem()].channel;
194 }
195
196 LONG currentDevice() const
197 {
198 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
199 0);
200 return mHDSlots [currentItem()].device;
201 }
202
203private slots:
204
205 void refresh()
206 {
207 QString current = currentText();
208 mHDSlots = mUniq->list (this);
209 clear();
210
211 bool setCurrent = false;
212
213 for (QValueList<HDSlot>::const_iterator it = mHDSlots.begin();
214 it != mHDSlots.end(); ++ it)
215 {
216 insertItem ((*it).str);
217 if (!setCurrent)
218 setCurrent = (*it).str == current;
219 }
220
221 if (setCurrent)
222 setCurrentText (current);
223 }
224
225signals:
226
227 void textChanged();
228
229private:
230
231 bool eventFilter (QObject *aObject, QEvent *aEvent)
232 {
233 if (aObject != listBox())
234 return false;
235
236 if (aEvent->type() == QEvent::Hide)
237 hide();
238
239 return QComboBox::eventFilter (aObject, aEvent);
240 }
241
242 HDSlotUniquizer *mUniq;
243
244 QValueList<HDSlot> mHDSlots;
245};
246
247/**
248 * VBoxMediaComboBox class reimplementation to use as selector for VDI
249 * image.
250 */
251class HDVdiItem : public VBoxMediaComboBox
252{
253 Q_OBJECT
254
255public:
256
257 HDVdiItem (QWidget *aParent, int aType, QListViewItem *aItem)
258 : VBoxMediaComboBox (aParent, "HDVdiItem", aType)
259 , mItem (aItem)
260 {
261 qApp->installEventFilter (this);
262 connect (&vboxGlobal(),
263 SIGNAL (mediaRemoved (VBoxDefs::DiskType, const QUuid &)),
264 this, SLOT (repaintHandler()));
265 }
266
267private slots:
268
269 void repaintHandler()
270 {
271 mItem->repaint();
272 }
273
274private:
275
276 bool eventFilter (QObject *aObject, QEvent *aEvent)
277 {
278 if (aObject != listBox())
279 return false;
280
281 if (aEvent->type() == QEvent::Hide)
282 hide();
283
284 return VBoxMediaComboBox::eventFilter (aObject, aEvent);
285 }
286
287 QListViewItem *mItem;
288};
289
290QValueList<HDSlot> HDSlotUniquizer::list (HDSlotItem *aSubscriber, bool aFilter)
291{
292 QValueList<HDSlot> list = mIDEList + mSATAList;
293
294 if (!aFilter)
295 return list;
296
297 /* Compose exclude list */
298 QStringList excludeList;
299 for (uint i = 0; i < mSubscribersList.size(); ++ i)
300 if (mSubscribersList [i] != aSubscriber)
301 excludeList << mSubscribersList [i]->currentText();
302
303 /* Filter the list */
304 QValueList<HDSlot>::Iterator it = list.begin();
305 while (it != list.end())
306 {
307 if (excludeList.contains ((*it).str))
308 it = list.remove (it);
309 else
310 ++ it;
311 }
312
313 return list;
314}
315
316class HDListItem : public QListViewItem
317{
318public:
319
320 enum { HDListItemType = 1010 };
321
322 HDListItem (VBoxHardDiskSettings *aWidget, QListView *aParent,
323 QListViewItem *aAfter,
324 HDSlotUniquizer *aUniq, const CMachine &aMachine)
325 : QListViewItem (aParent, aAfter)
326 , mWidget (aWidget)
327 , mUniq (aUniq)
328 , mMachine (aMachine)
329 , mFocusColumn (-1)
330 {
331 init();
332 }
333
334 HDListItem (VBoxHardDiskSettings *aWidget, QListView *aParent,
335 HDSlotUniquizer *aUniq, const CMachine &aMachine)
336 : QListViewItem (aParent)
337 , mWidget (aWidget)
338 , mUniq (aUniq)
339 , mMachine (aMachine)
340 , mFocusColumn (-1)
341 {
342 init();
343 }
344
345 int rtti() const { return HDListItemType; }
346
347 HDListItem* nextSibling() const
348 {
349 QListViewItem *item = QListViewItem::nextSibling();
350 return item && item->rtti() == HDListItemType ?
351 static_cast<HDListItem*> (item) : 0;
352 }
353
354 void setId (const QUuid &aId) const
355 {
356 static_cast<VBoxMediaComboBox*> (mVector [1])->setCurrentItem (aId);
357 }
358
359 QUuid getId() const
360 {
361 return static_cast<VBoxMediaComboBox*> (mVector [1])->getId();
362 }
363
364 KStorageBus bus() const
365 {
366 return static_cast<HDSlotItem*> (mVector [0])->currentBus();
367 }
368
369 LONG channel() const
370 {
371 return static_cast<HDSlotItem*> (mVector [0])->currentChannel();
372 }
373
374 LONG device() const
375 {
376 return static_cast<HDSlotItem*> (mVector [0])->currentDevice();
377 }
378
379 QString text (int aColumn) const
380 {
381 return mVector [aColumn]->currentText();
382 }
383
384 void moveFocusToColumn (int aCol)
385 {
386 mFocusColumn = aCol;
387 repaint();
388 }
389
390 void showEditor()
391 {
392 if (mVector [mFocusColumn]->count())
393 {
394 mVector [mFocusColumn]->show();
395 mVector [mFocusColumn]->popup();
396 }
397 }
398
399 int focusColumn() const
400 {
401 return mFocusColumn;
402 }
403
404 void setAttachment (const CHardDiskAttachment &aHda)
405 {
406 QString device = vboxGlobal()
407 .toFullString (aHda.GetBus(), aHda.GetChannel(), aHda.GetDevice());
408
409 if (mVector [0]->listBox()->findItem (device, Qt::ExactMatch))
410 static_cast<HDSlotItem*> (mVector [0])->setText (device);
411
412 static_cast<VBoxMediaComboBox*> (mVector [1])->
413 setCurrentItem (aHda.GetHardDisk().GetId());
414
415 mVector [0]->setHidden (true);
416 mVector [1]->setHidden (true);
417 }
418
419private:
420
421 void init()
422 {
423 setSelectable (false);
424 mVector.setAutoDelete (true);
425 mVector.resize (listView()->columns());
426
427 QComboBox *cbslot = new HDSlotItem (listView()->viewport(), mUniq);
428 QObject::connect (cbslot, SIGNAL (activated (int)),
429 mWidget, SIGNAL (hddListChanged()));
430 mVector.insert (0, cbslot);
431
432 VBoxMediaComboBox *cbvdi = new HDVdiItem (listView()->viewport(),
433 VBoxDefs::HD, this);
434 QObject::connect (cbvdi, SIGNAL (activated (int)),
435 mWidget, SIGNAL (hddListChanged()));
436 mVector.insert (1, cbvdi);
437 cbvdi->setBelongsTo (mMachine.GetId());
438 cbvdi->refresh();
439 }
440
441 void paintCell (QPainter *aPainter, const QColorGroup &aColorGroup,
442 int aColumn, int aWidth, int aAlign)
443 {
444 QComboBox *cb = mVector [aColumn];
445
446 int indent = 0;
447 for (int i = 0; i < aColumn; ++ i)
448 indent = listView()->columnWidth (i);
449
450 QRect rect = listView()->itemRect (this);
451
452 int xc = rect.x() + indent;
453 int yc = rect.y();
454 int wc = listView()->columnWidth (aColumn);
455 int hc = rect.height();
456
457 cb->move (xc, yc);
458 cb->resize (wc, hc);
459
460 QColorGroup cg (aColorGroup);
461 if (aColumn == mFocusColumn)
462 {
463 cg.setColor (QColorGroup::Base, aColorGroup.highlight());
464 cg.setColor (QColorGroup::Text, aColorGroup.highlightedText());
465 }
466 QListViewItem::paintCell (aPainter, cg, aColumn, aWidth, aAlign);
467 }
468
469 void paintFocus (QPainter *aPainter, const QColorGroup &aColorGroup,
470 const QRect &aRect)
471 {
472 if (mFocusColumn != -1)
473 {
474 int indent = 0;
475 for (int i = 0; i < mFocusColumn; ++ i)
476 indent = listView()->columnWidth (i);
477
478 QRect newFocus (QPoint (aRect.x() + indent, aRect.y()),
479 QSize (listView()->columnWidth (mFocusColumn),
480 aRect.height()));
481
482 QListViewItem::paintFocus (aPainter, aColorGroup, newFocus);
483 }
484 }
485
486 void setup()
487 {
488 QListViewItem::setup();
489 /* Increasing item's height by 30% */
490 setHeight ((int) (height() * 1.3));
491 }
492
493 VBoxHardDiskSettings *mWidget;
494 HDSlotUniquizer *mUniq;
495 CMachine mMachine;
496 QPtrVector<QComboBox> mVector;
497 int mFocusColumn;
498};
499
500class OnItemChangedEvent : public QEvent
501{
502public:
503 enum { Type = QEvent::User + 10 };
504 OnItemChangedEvent (QListViewItem *aItem)
505 : QEvent ((QEvent::Type) Type), mItem (aItem) {}
506
507 QListViewItem *mItem;
508};
509
510void VBoxHardDiskSettings::init()
511{
512 mPrevItem = 0;
513
514 mBtnAdd->setIconSet (VBoxGlobal::iconSet ("vdm_add_16px.png",
515 "vdm_add_disabled_16px.png"));
516 mBtnDel->setIconSet (VBoxGlobal::iconSet ("vdm_remove_16px.png",
517 "vdm_remove_disabled_16px.png"));
518 mBtnOpn->setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
519 "select_file_dis_16px.png"));
520
521 mSlotUniquizer = new HDSlotUniquizer (this);
522
523 connect (mCbSATA, SIGNAL (toggled (bool)),
524 this, SLOT (onToggleSATAController (bool)));
525 connect (mBtnAdd, SIGNAL (clicked()), this, SLOT (addHDItem()));
526 connect (mBtnDel, SIGNAL (clicked()), this, SLOT (delHDItem()));
527 connect (mBtnOpn, SIGNAL (clicked()), this, SLOT (showVDM()));
528 connect (mLvHD, SIGNAL (pressed (QListViewItem*, const QPoint&, int)),
529 this, SLOT (moveFocus (QListViewItem*, const QPoint&, int)));
530 connect (mLvHD, SIGNAL (currentChanged (QListViewItem*)),
531 this, SLOT (onCurrentChanged (QListViewItem*)));
532 connect (mLvHD, SIGNAL (contextMenuRequested (QListViewItem*, const QPoint&, int)),
533 this, SLOT (onContextMenuRequested (QListViewItem*, const QPoint&, int)));
534
535 qApp->installEventFilter (this);
536}
537
538void VBoxHardDiskSettings::getFromMachine (const CMachine &aMachine)
539{
540 mMachine = aMachine;
541
542 mCbSATA->setChecked (mMachine.GetSATAController().GetEnabled());
543
544 CHardDiskAttachmentEnumerator en =
545 mMachine.GetHardDiskAttachments().Enumerate();
546 while (en.HasMore())
547 {
548 CHardDiskAttachment hda = en.GetNext();
549 HDListItem *item = createItem (mSlotUniquizer, mMachine);
550 item->setAttachment (hda);
551 }
552 mLvHD->setSortColumn (0);
553 mLvHD->sort();
554 mLvHD->setSorting (-1);
555 mLvHD->setCurrentItem (mLvHD->firstChild());
556 onAfterCurrentChanged (0);
557}
558
559void VBoxHardDiskSettings::putBackToMachine()
560{
561 mMachine.GetSATAController().SetEnabled (mCbSATA->isChecked());
562
563 /* Detach all attached Hard Disks */
564 CHardDiskAttachmentEnumerator en =
565 mMachine.GetHardDiskAttachments().Enumerate();
566 while (en.HasMore())
567 {
568 CHardDiskAttachment hda = en.GetNext();
569 mMachine.DetachHardDisk (hda.GetBus(), hda.GetChannel(), hda.GetDevice());
570 if (!mMachine.isOk())
571 vboxProblem().cannotDetachHardDisk (this, mMachine,
572 hda.GetBus(), hda.GetChannel(), hda.GetDevice());
573 }
574
575 /* Sort&Attach all listed Hard Disks */
576 mLvHD->setSortColumn (0);
577 mLvHD->sort();
578 LONG maxSATAPort = 1;
579 HDListItem *item = mLvHD->firstChild() &&
580 mLvHD->firstChild()->rtti() == HDListItem::HDListItemType ?
581 static_cast<HDListItem*> (mLvHD->firstChild()) : 0;
582 while (item)
583 {
584 if (item->bus() == KStorageBus_SATA)
585 maxSATAPort = maxSATAPort < item->device() ?
586 item->device() : maxSATAPort;
587 mMachine.AttachHardDisk (item->getId(),
588 item->bus(), item->channel(), item->device());
589 if (!mMachine.isOk())
590 vboxProblem().cannotAttachHardDisk (this, mMachine, item->getId(),
591 item->bus(), item->channel(), item->device());
592 item = item->nextSibling();
593 }
594
595 mMachine.GetSATAController().SetPortCount (maxSATAPort);
596}
597
598QString VBoxHardDiskSettings::checkValidity()
599{
600 QString result;
601 QStringList slList;
602 QStringList idList;
603
604 /* Search for coincidences through all the media-id */
605 HDListItem *item = mLvHD->firstChild() &&
606 mLvHD->firstChild()->rtti() == HDListItem::HDListItemType ?
607 static_cast<HDListItem*> (mLvHD->firstChild()) : 0;
608 while (item)
609 {
610 QString id = item->getId().toString();
611 if (idList.contains (id))
612 {
613 result = tr ("<i>%1</i> uses the hard disk that is already "
614 "attached to <i>%2</i>")
615 .arg (item->text (0)).arg (slList [idList.findIndex (id)]);
616 break;
617 }
618 else
619 {
620 slList << item->text (0);
621 idList << id;
622 }
623 item = item->nextSibling();
624 }
625
626 return result;
627}
628
629void VBoxHardDiskSettings::addHDItem()
630{
631 HDListItem *item = createItem (mSlotUniquizer, mMachine);
632 item->moveFocusToColumn (0);
633 mLvHD->setCurrentItem (item);
634 if (!mLvHD->hasFocus())
635 mLvHD->setFocus();
636 /* Qt3 isn't emits currentChanged() signal if first list-view item added */
637 if (mLvHD->childCount() == 1)
638 onCurrentChanged (item);
639
640 emit hddListChanged();
641}
642
643void VBoxHardDiskSettings::delHDItem()
644{
645 if (mLvHD->currentItem())
646 {
647 QListViewItem *item = mLvHD->currentItem();
648 Assert (item == mPrevItem);
649 if (item == mPrevItem)
650 {
651 delete item;
652 mPrevItem = 0;
653 }
654 }
655
656 emit hddListChanged();
657}
658
659void VBoxHardDiskSettings::showVDM()
660{
661 HDListItem *item = mLvHD->currentItem() &&
662 mLvHD->currentItem()->rtti() == HDListItem::HDListItemType ?
663 static_cast<HDListItem*> (mLvHD->currentItem()) : 0;
664
665 VBoxDiskImageManagerDlg dlg (this, "VBoxDiskImageManagerDlg",
666 WType_Dialog | WShowModal);
667
668 QUuid machineId = mMachine.GetId();
669 QUuid hdId = item->getId();
670
671 dlg.setup (VBoxDefs::HD, true, &machineId, true /* aRefresh */,
672 mMachine, hdId, QUuid(), QUuid());
673
674 if (dlg.exec() == VBoxDiskImageManagerDlg::Accepted)
675 item->setId (dlg.getSelectedUuid());
676}
677
678void VBoxHardDiskSettings::moveFocus (QListViewItem *aItem, const QPoint&, int aCol)
679{
680 if (aItem && aItem->rtti() == HDListItem::HDListItemType)
681 static_cast<HDListItem*> (aItem)->moveFocusToColumn (aCol);
682}
683
684void VBoxHardDiskSettings::onCurrentChanged (QListViewItem *aItem)
685{
686 /* Postpone onCurrentChanged signal to be post-processed after all others */
687 QApplication::postEvent (this, new OnItemChangedEvent (aItem));
688}
689
690void VBoxHardDiskSettings::onToggleSATAController (bool aOn)
691{
692 if (!aOn)
693 {
694 HDListItem *firstItem = mLvHD->firstChild() &&
695 mLvHD->firstChild()->rtti() == HDListItem::HDListItemType ?
696 static_cast<HDListItem*> (mLvHD->firstChild()) : 0;
697
698 /* Search the list for the SATA ports in */
699 HDListItem *sataItem = firstItem;
700 while (sataItem)
701 {
702 if (sataItem->bus() == KStorageBus_SATA)
703 break;
704 sataItem = sataItem->nextSibling();
705 }
706
707 /* If list contains at least one SATA port */
708 if (sataItem)
709 {
710 int rc = vboxProblem().confirmDetachSATASlots (this);
711 if (rc != QIMessageBox::Ok)
712 {
713 /* Switch check-box back to "on" */
714 mCbSATA->blockSignals (true);
715 mCbSATA->setChecked (true);
716 mCbSATA->blockSignals (false);
717 return;
718 }
719 else
720 {
721 /* Delete SATA items */
722 HDListItem *it = firstItem;
723 mLvHD->blockSignals (true);
724 while (it)
725 {
726 HDListItem *curIt = it;
727 it = it->nextSibling();
728 if (curIt->bus() == KStorageBus_SATA)
729 {
730 if (curIt == mLvHD->currentItem())
731 mPrevItem = 0;
732 delete curIt;
733 }
734 }
735 mLvHD->blockSignals (false);
736 emit hddListChanged();
737 }
738 }
739 }
740
741 int newSATAPortsCount = aOn && !mMachine.isNull() ? SATAPortsCount : 0;
742 if (mSlotUniquizer->getSATAPortsCount() != newSATAPortsCount)
743 {
744 mSlotUniquizer->setSATAPortsCount (newSATAPortsCount);
745 onAfterCurrentChanged (mLvHD->currentItem());
746 }
747}
748
749void VBoxHardDiskSettings::onAfterCurrentChanged (QListViewItem *aItem)
750{
751 /* Process postponed onCurrentChanged event */
752 mBtnAdd->setEnabled (mLvHD->childCount() < mSlotUniquizer->totalCount());
753 mBtnDel->setEnabled (aItem);
754 mBtnOpn->setEnabled (aItem);
755
756 if (aItem == mPrevItem)
757 return;
758
759 if (aItem && aItem->rtti() == HDListItem::HDListItemType &&
760 static_cast<HDListItem*> (aItem)->focusColumn() == -1)
761 {
762 int prevFocusColumn = 0;
763 if (mPrevItem && mPrevItem->rtti() == HDListItem::HDListItemType)
764 prevFocusColumn = static_cast<HDListItem*> (mPrevItem)->focusColumn();
765 static_cast<HDListItem*> (aItem)->moveFocusToColumn (prevFocusColumn);
766 }
767
768 if (mPrevItem && mPrevItem->rtti() == HDListItem::HDListItemType)
769 static_cast<HDListItem*> (mPrevItem)->moveFocusToColumn (-1);
770
771 mPrevItem = aItem;
772}
773
774void VBoxHardDiskSettings::onContextMenuRequested (QListViewItem*,
775 const QPoint &aPoint, int)
776{
777 QAction opnAction (tr ("Open Virtual Disk Manager"), QKeySequence (tr ("Ctrl+Space")), this);
778 QAction delAction (tr ("Delete Attachment"), QKeySequence (tr ("Delete")), this);
779 delAction.setIconSet (VBoxGlobal::iconSet ("vdm_remove_16px.png",
780 "vdm_remove_disabled_16px.png"));
781 opnAction.setIconSet (VBoxGlobal::iconSet ("select_file_16px.png",
782 "select_file_dis_16px.png"));
783 QPopupMenu menu (this);
784 opnAction.addTo (&menu);
785 delAction.addTo (&menu);
786 int id = menu.exec (aPoint);
787 int index = id == -1 ? id : menu.indexOf (id);
788 if (index == 0)
789 showVDM();
790 else if (index == 1)
791 delHDItem();
792}
793
794HDListItem* VBoxHardDiskSettings::createItem (HDSlotUniquizer *aUniq,
795 const CMachine &aMachine)
796{
797 return mLvHD->lastItem() ?
798 new HDListItem (this, mLvHD, mLvHD->lastItem(), aUniq, aMachine) :
799 new HDListItem (this, mLvHD, aUniq, aMachine);
800}
801
802bool VBoxHardDiskSettings::event (QEvent *aEvent)
803{
804 switch (aEvent->type())
805 {
806 /* Redirect postponed onCurrentChanged event */
807 case OnItemChangedEvent::Type:
808 {
809 OnItemChangedEvent *e = static_cast<OnItemChangedEvent*> (aEvent);
810 onAfterCurrentChanged (e->mItem);
811 break;
812 }
813 default:
814 break;
815 }
816
817 return QWidget::event (aEvent);
818}
819
820void VBoxHardDiskSettings::showEvent (QShowEvent *aEvent)
821{
822 QWidget::showEvent (aEvent);
823 adjustList();
824}
825
826bool VBoxHardDiskSettings::eventFilter (QObject *aObject, QEvent *aEvent)
827{
828 if (!aObject->isWidgetType())
829 return QWidget::eventFilter (aObject, aEvent);
830
831 if (static_cast<QWidget*> (aObject)->topLevelWidget() != topLevelWidget())
832 return QWidget::eventFilter (aObject, aEvent);
833
834 switch (aEvent->type())
835 {
836 /* Process double-click as "open combo-box" action */
837 case QEvent::MouseButtonDblClick:
838 {
839 if (aObject != mLvHD->viewport())
840 break;
841
842 HDListItem *item = mLvHD->currentItem() &&
843 mLvHD->currentItem()->rtti() == HDListItem::HDListItemType ?
844 static_cast<HDListItem*> (mLvHD->currentItem()) : 0;
845 if (item)
846 item->showEditor();
847 break;
848 }
849 case QEvent::KeyPress:
850 {
851 if (aObject != mLvHD)
852 break;
853
854 HDListItem *item = mLvHD->currentItem() &&
855 mLvHD->currentItem()->rtti() == HDListItem::HDListItemType ?
856 static_cast<HDListItem*> (mLvHD->currentItem()) : 0;
857
858 QKeyEvent *e = static_cast<QKeyEvent*> (aEvent);
859 /* Process cursor-left as "move focus left" action */
860 if (e->key() == Qt::Key_Left && !e->state())
861 {
862 if (item && item->focusColumn() != -1 &&
863 item->focusColumn() > 0)
864 item->moveFocusToColumn (item->focusColumn() - 1);
865 } else
866 /* Process cursor-right as "move focus right" action */
867 if (e->key() == Qt::Key_Right && !e->state())
868 {
869 if (item && item->focusColumn() != -1 &&
870 item->focusColumn() < mLvHD->columns() - 1)
871 item->moveFocusToColumn (item->focusColumn() + 1);
872 } else
873 /* Process F2/Space as "open combo-box" actions */
874 if (!e->state() &&
875 (e->key() == Qt::Key_F2 || e->key() == Qt::Key_Space))
876 {
877 if (item)
878 item->showEditor();
879 }
880 /* Process Ctrl/Alt+Up/Down as "open combo-box" actions */
881 if ((e->state() == Qt::AltButton || e->state() == Qt::ControlButton) &&
882 (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))
883 {
884 if (item)
885 {
886 item->showEditor();
887 return true;
888 }
889 }
890 break;
891 }
892 /* Process focus event to toggle the current selection state */
893 case QEvent::FocusIn:
894 {
895 if (aObject == mLvHD)
896 onAfterCurrentChanged (mLvHD->currentItem());
897 else if (!mGbHDList->queryList (0, 0, false, true)->contains (aObject))
898 onAfterCurrentChanged (0);
899 break;
900 }
901 default:
902 break;
903 }
904
905 return QWidget::eventFilter (aObject, aEvent);
906}
907
908void VBoxHardDiskSettings::adjustList()
909{
910 /* Search through the slots list for maximum element width */
911 int minLength = 0;
912 QFontMetrics fm = mLvHD->fontMetrics();
913 QValueList<HDSlot> list = mSlotUniquizer->list (0, false);
914 for (uint i = 0; i < list.size(); ++ i)
915 {
916 int length = fm.width (list [i].str);
917 minLength = minLength < length ? length : minLength;
918 }
919 minLength = minLength > mLvHD->viewport()->width() * 0.4 ?
920 (int) (mLvHD->viewport()->width() * 0.4) : minLength;
921
922 mLvHD->setColumnWidth (0, minLength + 10 /* little spacing */);
923 mLvHD->setColumnWidth (1, mLvHD->viewport()->width() - mLvHD->columnWidth (0));
924}
925
926#include "VBoxHardDiskSettings.ui.moc"
927
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