VirtualBox

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

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

Fixed initial attachment selection for differencing Hard Disks.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.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 static int scrollBarWidth()
182 {
183 QListBox lb;
184 lb.setVScrollBarMode (QScrollView::AlwaysOn);
185 return lb.verticalScrollBar()->width();
186 }
187
188 void setText (const QString &aText)
189 {
190 QComboBox::setCurrentText (aText);
191 emit textChanged();
192 }
193
194 KStorageBus currentBus() const
195 {
196 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
197 KStorageBus_Null);
198 return mHDSlots [currentItem()].bus;
199 }
200
201 LONG currentChannel() const
202 {
203 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
204 0);
205 return mHDSlots [currentItem()].channel;
206 }
207
208 LONG currentDevice() const
209 {
210 AssertReturn (currentItem() >= 0 && (size_t) currentItem() < mHDSlots.size(),
211 0);
212 return mHDSlots [currentItem()].device;
213 }
214
215private slots:
216
217 void refresh()
218 {
219 QString current = currentText();
220 mHDSlots = mUniq->list (this);
221 clear();
222
223 bool setCurrent = false;
224
225 for (QValueList<HDSlot>::const_iterator it = mHDSlots.begin();
226 it != mHDSlots.end(); ++ it)
227 {
228 insertItem ((*it).str);
229 if (!setCurrent)
230 setCurrent = (*it).str == current;
231 }
232
233 if (setCurrent)
234 setCurrentText (current);
235 }
236
237 void updateToolTip()
238 {
239 QString oldTip = QToolTip::textFor (this);
240 QString newTip = currentText();
241
242 if (newTip != oldTip)
243 {
244 QToolTip::remove (this);
245 QToolTip::add (this, newTip);
246 }
247 }
248
249signals:
250
251 void textChanged();
252
253private:
254
255 HDSlotUniquizer *mUniq;
256
257 QValueList<HDSlot> mHDSlots;
258};
259
260/**
261 * VBoxMediaComboBox class reimplementation to use as selector for VDI
262 * image.
263 */
264class HDVdiItem : public VBoxMediaComboBox
265{
266 Q_OBJECT
267
268public:
269
270 HDVdiItem (QWidget *aParent, int aType, QListViewItem *aItem)
271 : VBoxMediaComboBox (aParent, "HDVdiItem", aType)
272 , mItem (aItem)
273 {
274 setFocusPolicy (QWidget::NoFocus);
275 connect (&vboxGlobal(),
276 SIGNAL (mediaRemoved (VBoxDefs::DiskType, const QUuid &)),
277 this, SLOT (repaintHandler()));
278 }
279
280private slots:
281
282 void repaintHandler()
283 {
284 mItem->repaint();
285 }
286
287private:
288
289 QListViewItem *mItem;
290};
291
292QValueList<HDSlot> HDSlotUniquizer::list (HDSlotItem *aSubscriber, bool aFilter)
293{
294 QValueList<HDSlot> list = mIDEList + mSATAList;
295
296 if (!aFilter)
297 return list;
298
299 /* Compose exclude list */
300 QStringList excludeList;
301 for (uint i = 0; i < mSubscribersList.size(); ++ i)
302 if (mSubscribersList [i] != aSubscriber)
303 excludeList << mSubscribersList [i]->currentText();
304
305 /* Filter the list */
306 QValueList<HDSlot>::Iterator it = list.begin();
307 while (it != list.end())
308 {
309 if (excludeList.contains ((*it).str))
310 it = list.remove (it);
311 else
312 ++ it;
313 }
314
315 return list;
316}
317
318class HDSpaceItem : public QListViewItem
319{
320public:
321
322 enum { HDSpaceItemType = 1011 };
323
324 HDSpaceItem (QListView *aParent)
325 : QListViewItem (aParent)
326 {
327 setSelectable (false);
328 }
329
330 int rtti() const { return HDSpaceItemType; }
331};
332
333class HDListItem : public QListViewItem
334{
335public:
336
337 enum { HDListItemType = 1010 };
338
339 HDListItem (VBoxHardDiskSettings *aWidget, QListView *aParent,
340 QListViewItem *aAfter,
341 HDSlotUniquizer *aUniq, const CMachine &aMachine)
342 : QListViewItem (aParent, aAfter)
343 , mWidget (aWidget)
344 , mUniq (aUniq)
345 , mMachine (aMachine)
346 , mFocusColumn (-1)
347 , mAutoFocus (false)
348 {
349 init();
350 }
351
352 HDListItem (VBoxHardDiskSettings *aWidget, QListView *aParent,
353 HDSlotUniquizer *aUniq, const CMachine &aMachine)
354 : QListViewItem (aParent)
355 , mWidget (aWidget)
356 , mUniq (aUniq)
357 , mMachine (aMachine)
358 , mFocusColumn (-1)
359 {
360 init();
361 }
362
363 int rtti() const { return HDListItemType; }
364
365 QString toolTip()
366 {
367 return QToolTip::textFor (mVector [1]);
368 }
369
370 HDListItem* nextSibling() const
371 {
372 QListViewItem *item = QListViewItem::nextSibling();
373 return item && item->rtti() == HDListItemType ?
374 static_cast<HDListItem*> (item) : 0;
375 }
376
377 void setId (const QUuid &aId) const
378 {
379 static_cast<VBoxMediaComboBox*> (mVector [1])->setCurrentItem (aId);
380 }
381
382 QUuid getId() const
383 {
384 return static_cast<VBoxMediaComboBox*> (mVector [1])->getId();
385 }
386
387 KStorageBus bus() const
388 {
389 return static_cast<HDSlotItem*> (mVector [0])->currentBus();
390 }
391
392 LONG channel() const
393 {
394 return static_cast<HDSlotItem*> (mVector [0])->currentChannel();
395 }
396
397 LONG device() const
398 {
399 return static_cast<HDSlotItem*> (mVector [0])->currentDevice();
400 }
401
402 QString text (int aColumn) const
403 {
404 return mVector [aColumn]->currentText();
405 }
406
407 void moveFocusToColumn (int aCol)
408 {
409 mFocusColumn = aCol;
410 mAutoFocus = mFocusColumn != -1;
411 repaint();
412 }
413
414 void setAutoFocus (bool aOn)
415 {
416 mAutoFocus = aOn;
417 }
418
419 void showEditor()
420 {
421 if (mVector [mFocusColumn]->count())
422 mVector [mFocusColumn]->popup();
423 }
424
425 int focusColumn() const
426 {
427 return mFocusColumn;
428 }
429
430 void setAttachment (const CHardDiskAttachment &aHda)
431 {
432 QString device = vboxGlobal()
433 .toFullString (aHda.GetBus(), aHda.GetChannel(), aHda.GetDevice());
434
435 if (mVector [0]->listBox()->findItem (device, Qt::ExactMatch))
436 static_cast<HDSlotItem*> (mVector [0])->setText (device);
437
438 static_cast<VBoxMediaComboBox*> (mVector [1])->
439 setCurrentItem (aHda.GetHardDisk().GetRoot().GetId());
440
441 mVector [0]->setHidden (true);
442 mVector [1]->setHidden (true);
443 }
444
445private:
446
447 void init()
448 {
449 setSelectable (false);
450 mVector.setAutoDelete (true);
451 mVector.resize (listView()->columns());
452
453 QComboBox *cbslot = new HDSlotItem (listView()->viewport(), mUniq);
454 QObject::connect (cbslot, SIGNAL (activated (int)),
455 mWidget, SIGNAL (hddListChanged()));
456 mVector.insert (0, cbslot);
457
458 VBoxMediaComboBox *cbvdi = new HDVdiItem (listView()->viewport(),
459 VBoxDefs::HD, this);
460 QObject::connect (cbvdi, SIGNAL (activated (int)),
461 mWidget, SIGNAL (hddListChanged()));
462 mVector.insert (1, cbvdi);
463 cbvdi->setBelongsTo (mMachine.GetId());
464 cbvdi->refresh();
465#ifdef Q_WS_MAC
466 /* White background on Mac OS X */
467 cbslot->setPaletteBackgroundColor (cbslot->parentWidget()->paletteBackgroundColor());
468 cbvdi->setPaletteBackgroundColor (cbvdi->parentWidget()->paletteBackgroundColor());
469#endif /* Q_WS_MAC */
470 }
471
472 void paintCell (QPainter *aPainter, const QColorGroup &aColorGroup,
473 int aColumn, int aWidth, int aAlign)
474 {
475 QComboBox *cb = mVector [aColumn];
476
477 int indent = 0;
478 for (int i = 0; i < aColumn; ++ i)
479 indent = listView()->columnWidth (i);
480
481 QRect rect = listView()->itemRect (this);
482
483 int xc = rect.x() + indent;
484 int yc = rect.y();
485 int wc = listView()->columnWidth (aColumn);
486 int hc = rect.height();
487
488 cb->move (xc, yc);
489 cb->resize (wc, hc);
490
491 if (aColumn == mFocusColumn)
492 {
493 if (cb->isHidden())
494 cb->show();
495 if (mAutoFocus && !cb->hasFocus())
496 QTimer::singleShot (0, cb, SLOT (setFocus()));
497 }
498 else if (aColumn != mFocusColumn && !cb->isHidden())
499 cb->hide();
500
501 QListViewItem::paintCell (aPainter, aColorGroup, aColumn, aWidth, aAlign);
502 }
503
504 void paintFocus (QPainter *, const QColorGroup &, const QRect &)
505 {
506 /* Do not paint focus, because it presented by combo-box */
507 }
508
509 void setup()
510 {
511 QListViewItem::setup();
512 /* Increasing item's height by 30% */
513 setHeight ((int) (height() * 1.3));
514 }
515
516 VBoxHardDiskSettings *mWidget;
517 HDSlotUniquizer *mUniq;
518 CMachine mMachine;
519 QPtrVector<QComboBox> mVector;
520 int mFocusColumn;
521 bool mAutoFocus;
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 int prevFocusColumn =
833 mPrevItem && mPrevItem->rtti() == HDListItem::HDListItemType ?
834 static_cast<HDListItem*> (mPrevItem)->focusColumn() : 0;
835
836 if (mPrevItem && mPrevItem->rtti() == HDListItem::HDListItemType)
837 static_cast<HDListItem*> (mPrevItem)->moveFocusToColumn (-1);
838
839 if (aItem && aItem->rtti() == HDListItem::HDListItemType &&
840 static_cast<HDListItem*> (aItem)->focusColumn() == -1)
841 static_cast<HDListItem*> (aItem)->moveFocusToColumn (prevFocusColumn);
842
843 mPrevItem = aItem;
844 }
845
846 mAddAttachmentAct->setEnabled (mLvHD->childCount() <=
847 mSlotUniquizer->totalCount());
848 mRemoveAttachmentAct->setEnabled (aItem &&
849 aItem->rtti() == HDListItem::HDListItemType);
850 mSelectHardDiskAct->setEnabled (aItem &&
851 aItem->rtti() == HDListItem::HDListItemType &&
852 static_cast<HDListItem*> (aItem)->focusColumn() == 1);
853}
854
855void VBoxHardDiskSettings::onContextMenuRequested (QListViewItem * /*aItem*/,
856 const QPoint &aPoint, int)
857{
858 mContextMenu->exec (aPoint);
859}
860
861HDListItem* VBoxHardDiskSettings::createItem (HDSlotUniquizer *aUniq,
862 const CMachine &aMachine)
863{
864 QListViewItem *item = mLvHD->lastItem();
865 Assert (item->rtti() == HDSpaceItem::HDSpaceItemType);
866 HDListItem *last = item->itemAbove() &&
867 item->itemAbove()->rtti() == HDListItem::HDListItemType ?
868 static_cast<HDListItem*> (item->itemAbove()) : 0;
869
870 return last ?
871 new HDListItem (this, mLvHD, last, aUniq, aMachine) :
872 new HDListItem (this, mLvHD, aUniq, aMachine);
873}
874
875bool VBoxHardDiskSettings::event (QEvent *aEvent)
876{
877 switch (aEvent->type())
878 {
879 /* Redirect postponed onCurrentChanged event */
880 case OnItemChangedEvent::Type:
881 {
882 OnItemChangedEvent *e = static_cast<OnItemChangedEvent*> (aEvent);
883 onAfterCurrentChanged (e->mItem);
884 break;
885 }
886 default:
887 break;
888 }
889
890 return QWidget::event (aEvent);
891}
892
893void VBoxHardDiskSettings::showEvent (QShowEvent *aEvent)
894{
895 QWidget::showEvent (aEvent);
896 QTimer::singleShot (0, this, SLOT (adjustList()));
897}
898
899bool VBoxHardDiskSettings::eventFilter (QObject *aObject, QEvent *aEvent)
900{
901 if (!aObject->isWidgetType())
902 return QWidget::eventFilter (aObject, aEvent);
903
904 if (static_cast<QWidget*> (aObject)->topLevelWidget() != topLevelWidget())
905 return QWidget::eventFilter (aObject, aEvent);
906
907 switch (aEvent->type())
908 {
909 /* Process double-click as "open combo-box" action */
910 case QEvent::MouseButtonDblClick:
911 {
912 if (aObject != mLvHD->viewport())
913 break;
914
915 QMouseEvent *e = static_cast<QMouseEvent*> (aEvent);
916 QListViewItem *clickedItem = mLvHD->itemAt (e->pos());
917 HDListItem *item = clickedItem &&
918 clickedItem->rtti() == HDListItem::HDListItemType ?
919 static_cast<HDListItem*> (clickedItem) : 0;
920
921 if (!item && mAddAttachmentAct->isEnabled())
922 addHDItem();
923 break;
924 }
925 /* Process mouse-move as "make tool-tip" action */
926 case QEvent::MouseMove:
927 {
928 if (aObject != mLvHD->viewport())
929 {
930 if (!QToolTip::textFor (mLvHD->viewport()).isNull())
931 QToolTip::remove (mLvHD->viewport());
932 break;
933 }
934
935 QMouseEvent *e = static_cast<QMouseEvent*> (aEvent);
936 QListViewItem *hoveredItem = mLvHD->itemAt (e->pos());
937 HDListItem *item = hoveredItem &&
938 hoveredItem->rtti() == HDListItem::HDListItemType ?
939 static_cast<HDListItem*> (hoveredItem) : 0;
940
941 QString oldTip = QToolTip::textFor (mLvHD->viewport());
942 QString newTip = item ? item->toolTip() :
943 tr ("Double-click to add a new attachment");
944
945 if (newTip != oldTip)
946 {
947 QToolTip::remove (mLvHD->viewport());
948 QToolTip::add (mLvHD->viewport(), newTip);
949 }
950 break;
951 }
952 case QEvent::KeyPress:
953 {
954 if (!mLvHD->queryList (0, 0, false, true)->contains (aObject))
955 break;
956
957 HDListItem *item = mLvHD->currentItem() &&
958 mLvHD->currentItem()->rtti() == HDListItem::HDListItemType ?
959 static_cast<HDListItem*> (mLvHD->currentItem()) : 0;
960
961 QKeyEvent *e = static_cast<QKeyEvent*> (aEvent);
962 /* Process cursor-left as "move focus left" action */
963 if (e->key() == Qt::Key_Left && !e->state())
964 {
965 if (item && item->focusColumn() != -1 &&
966 item->focusColumn() > 0)
967 {
968 item->setAutoFocus (false);
969 mLvHD->setFocus();
970 item->moveFocusToColumn (item->focusColumn() - 1);
971 onAfterCurrentChanged (item);
972 }
973 return true;
974 } else
975 /* Process cursor-right as "move focus right" action */
976 if (e->key() == Qt::Key_Right && !e->state())
977 {
978 if (item && item->focusColumn() != -1 &&
979 item->focusColumn() < mLvHD->columns() - 1)
980 {
981 item->setAutoFocus (false);
982 mLvHD->setFocus();
983 item->moveFocusToColumn (item->focusColumn() + 1);
984 onAfterCurrentChanged (item);
985 }
986 return true;
987 } else
988 /* Process cursor-up as "move focus up" action */
989 if (e->key() == Qt::Key_Up && !e->state())
990 {
991 if (item && item->focusColumn() != -1 &&
992 item->itemAbove())
993 {
994 item->setAutoFocus (false);
995 mLvHD->setFocus();
996 mLvHD->setCurrentItem (item->itemAbove());
997 }
998 return true;
999 } else
1000 /* Process cursor-down as "move focus down" action */
1001 if (e->key() == Qt::Key_Down && !e->state())
1002 {
1003 if (item && item->focusColumn() != -1 &&
1004 item->itemBelow())
1005 {
1006 item->setAutoFocus (false);
1007 mLvHD->setFocus();
1008 mLvHD->setCurrentItem (item->itemBelow());
1009 }
1010 return true;
1011 } else
1012 /* Process F2/Space as "open combo-box" actions */
1013 if (!e->state() &&
1014 (e->key() == Qt::Key_F2 || e->key() == Qt::Key_Space))
1015 {
1016 if (item)
1017 item->showEditor();
1018 return true;
1019 }
1020 /* Process Ctrl/Alt+Up/Down as "open combo-box" actions */
1021 if ((e->state() == Qt::AltButton || e->state() == Qt::ControlButton) &&
1022 (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))
1023 {
1024 if (item)
1025 item->showEditor();
1026 return true;
1027 } else
1028 if ((e->key() == Qt::Key_Tab && !e->state()) ||
1029 e->key() == Qt::Key_Backtab)
1030 {
1031 item->setAutoFocus (false);
1032 mLvHD->setFocus();
1033 }
1034 break;
1035 }
1036 /* Process focus event to toggle the current selection state */
1037 case QEvent::FocusIn:
1038 {
1039 if (aObject == mLvHD)
1040 onAfterCurrentChanged (mLvHD->currentItem());
1041 else if (!mGbHDList->queryList (0, 0, false, true)->contains (aObject))
1042 onAfterCurrentChanged (0);
1043
1044 break;
1045 }
1046 default:
1047 break;
1048 }
1049
1050 return QWidget::eventFilter (aObject, aEvent);
1051}
1052
1053void VBoxHardDiskSettings::adjustList()
1054{
1055 /* Search through the slots list for maximum element width */
1056 int minLength = 0;
1057 QFontMetrics fm = mLvHD->fontMetrics();
1058 QValueList<HDSlot> list = mSlotUniquizer->list (0, false);
1059 for (uint i = 0; i < list.size(); ++ i)
1060 {
1061 int length = fm.width (list [i].str);
1062 minLength = minLength < length ? length : minLength;
1063 }
1064 minLength = minLength > mLvHD->viewport()->width() * 0.4 ?
1065 (int) (mLvHD->viewport()->width() * 0.4) : minLength;
1066
1067 mLvHD->setColumnWidth (0,
1068 minLength /* maximum string width */ +
1069 6 * 2 /* 2 combo-box margin */ +
1070 HDSlotItem::scrollBarWidth() /* scrollbar */);
1071 mLvHD->setColumnWidth (1, mLvHD->viewport()->width() - mLvHD->columnWidth (0));
1072}
1073
1074#include "VBoxHardDiskSettings.ui.moc"
1075
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