VirtualBox

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

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

SATA ui: Make the order or auto assigned vdi similar to the order of vdi appearance in Media Combo Box combo-box.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 33.3 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 (mFocusColumn >= 0)
422 if (mVector [mFocusColumn]->count())
423 mVector [mFocusColumn]->popup();
424 }
425
426 int focusColumn() const
427 {
428 return mFocusColumn;
429 }
430
431 void setAttachment (const CHardDiskAttachment &aHda)
432 {
433 QString device = vboxGlobal()
434 .toFullString (aHda.GetBus(), aHda.GetChannel(), aHda.GetDevice());
435
436 if (mVector [0]->listBox()->findItem (device, Qt::ExactMatch))
437 static_cast<HDSlotItem*> (mVector [0])->setText (device);
438
439 static_cast<VBoxMediaComboBox*> (mVector [1])->
440 setCurrentItem (aHda.GetHardDisk().GetRoot().GetId());
441
442 mVector [0]->setHidden (true);
443 mVector [1]->setHidden (true);
444 }
445
446 int vdiCount()
447 {
448 return mVector [1]->count();
449 }
450
451 void tryToChooseExcluding (const QStringList &aUsedList)
452 {
453 for (int i = 0; i < mVector [1]->count(); ++ i)
454 {
455 if (!aUsedList.contains (mVector [1]->text (i)))
456 {
457 setId (static_cast<HDVdiItem*> (mVector [1])->getId (i));
458 break;
459 }
460 }
461 }
462
463private:
464
465 void init()
466 {
467 setSelectable (false);
468 mVector.setAutoDelete (true);
469 mVector.resize (listView()->columns());
470
471 QComboBox *cbslot = new HDSlotItem (listView()->viewport(), mUniq);
472 QObject::connect (cbslot, SIGNAL (activated (int)),
473 mWidget, SIGNAL (hddListChanged()));
474 mVector.insert (0, cbslot);
475
476 VBoxMediaComboBox *cbvdi = new HDVdiItem (listView()->viewport(),
477 VBoxDefs::HD, this);
478 QObject::connect (cbvdi, SIGNAL (activated (int)),
479 mWidget, SIGNAL (hddListChanged()));
480 mVector.insert (1, cbvdi);
481 cbvdi->setBelongsTo (mMachine.GetId());
482 cbvdi->refresh();
483#ifdef Q_WS_MAC
484 /* White background on Mac OS X */
485 cbslot->setPaletteBackgroundColor (cbslot->parentWidget()->paletteBackgroundColor());
486 cbvdi->setPaletteBackgroundColor (cbvdi->parentWidget()->paletteBackgroundColor());
487#endif /* Q_WS_MAC */
488 }
489
490 void paintCell (QPainter *aPainter, const QColorGroup &aColorGroup,
491 int aColumn, int aWidth, int aAlign)
492 {
493 QComboBox *cb = mVector [aColumn];
494
495 int indent = 0;
496 for (int i = 0; i < aColumn; ++ i)
497 indent = listView()->columnWidth (i);
498
499 QRect rect = listView()->itemRect (this);
500
501 int xc = rect.x() + indent;
502 int yc = rect.y();
503 int wc = listView()->columnWidth (aColumn);
504 int hc = rect.height();
505
506 cb->move (xc, yc);
507 cb->resize (wc, hc);
508
509 if (aColumn == mFocusColumn)
510 {
511 if (cb->isHidden())
512 cb->show();
513 if (mAutoFocus && !cb->hasFocus())
514 QTimer::singleShot (0, cb, SLOT (setFocus()));
515 }
516 else if (aColumn != mFocusColumn && !cb->isHidden())
517 cb->hide();
518
519 QListViewItem::paintCell (aPainter, aColorGroup, aColumn, aWidth, aAlign);
520 }
521
522 void paintFocus (QPainter *, const QColorGroup &, const QRect &)
523 {
524 /* Do not paint focus, because it presented by combo-box */
525 }
526
527 void setup()
528 {
529 QListViewItem::setup();
530 /* Increasing item's height by 30% */
531 setHeight ((int) (height() * 1.3));
532 }
533
534 VBoxHardDiskSettings *mWidget;
535 HDSlotUniquizer *mUniq;
536 CMachine mMachine;
537 QPtrVector<QComboBox> mVector;
538 int mFocusColumn;
539 bool mAutoFocus;
540};
541
542class OnItemChangedEvent : public QEvent
543{
544public:
545 enum { Type = QEvent::User + 10 };
546 OnItemChangedEvent (QListViewItem *aItem)
547 : QEvent ((QEvent::Type) Type), mItem (aItem) {}
548
549 QListViewItem *mItem;
550};
551
552void VBoxHardDiskSettings::init()
553{
554 mPrevItem = 0;
555
556 /* toolbar */
557
558 VBoxToolBar *toolBar = new VBoxToolBar (0, mGbHDList, "snapshotToolBar");
559
560 mAddAttachmentAct->addTo (toolBar);
561 mRemoveAttachmentAct->addTo (toolBar);
562 mSelectHardDiskAct->addTo (toolBar);
563
564 toolBar->setUsesTextLabel (false);
565 toolBar->setUsesBigPixmaps (false);
566 toolBar->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
567 toolBar->setOrientation (Qt::Vertical);
568#ifdef Q_WS_MAC
569 toolBar->setMacStyle();
570#endif
571 mToolBarLayout->insertWidget (0, toolBar);
572
573 /* context menu */
574 mContextMenu = new QPopupMenu (this);
575 mAddAttachmentAct->addTo (mContextMenu);
576 mRemoveAttachmentAct->addTo (mContextMenu);
577 mSelectHardDiskAct->addTo (mContextMenu);
578
579 /* icons */
580 mAddAttachmentAct->setIconSet
581 (VBoxGlobal::iconSet ("vdm_add_16px.png", "vdm_add_disabled_16px.png"));
582 mRemoveAttachmentAct->setIconSet
583 (VBoxGlobal::iconSet ("vdm_remove_16px.png", "vdm_remove_disabled_16px.png"));
584 mSelectHardDiskAct->setIconSet
585 (VBoxGlobal::iconSet ("select_file_16px.png", "select_file_dis_16px.png"));
586
587 /* connections */
588 connect (mCbSATA, SIGNAL (toggled (bool)),
589 this, SLOT (onToggleSATAController (bool)));
590 connect (mLvHD, SIGNAL (pressed (QListViewItem*, const QPoint&, int)),
591 this, SLOT (moveFocus (QListViewItem*, const QPoint&, int)));
592 connect (mLvHD, SIGNAL (currentChanged (QListViewItem*)),
593 this, SLOT (onCurrentChanged (QListViewItem*)));
594 connect (mLvHD, SIGNAL (contextMenuRequested (QListViewItem*, const QPoint&, int)),
595 this, SLOT (onContextMenuRequested (QListViewItem*, const QPoint&, int)));
596
597 /* rest */
598
599 new HDSpaceItem (mLvHD);
600
601 mSlotUniquizer = new HDSlotUniquizer (this);
602
603 qApp->installEventFilter (this);
604}
605
606void VBoxHardDiskSettings::getFromMachine (const CMachine &aMachine)
607{
608 mMachine = aMachine;
609
610 {
611 CSATAController ctl = mMachine.GetSATAController();
612 if (ctl.isNull())
613 {
614 /* hide the SATA check box if the SATA controller is not available
615 * (i.e. in VirtualBox OSE) */
616 mCbSATA->setHidden (true);
617 }
618 else
619 {
620 mCbSATA->setChecked (ctl.GetEnabled());
621 }
622 }
623
624 CHardDiskAttachmentEnumerator en =
625 mMachine.GetHardDiskAttachments().Enumerate();
626 while (en.HasMore())
627 {
628 CHardDiskAttachment hda = en.GetNext();
629 HDListItem *item = createItem (mSlotUniquizer, mMachine);
630 item->setAttachment (hda);
631 }
632 mLvHD->setSortColumn (0);
633 mLvHD->sort();
634 mLvHD->setSorting (-1);
635 mLvHD->setCurrentItem (mLvHD->firstChild());
636 onAfterCurrentChanged (0);
637}
638
639void VBoxHardDiskSettings::putBackToMachine()
640{
641 CSATAController ctl = mMachine.GetSATAController();
642 if (!ctl.isNull())
643 {
644 ctl.SetEnabled (mCbSATA->isChecked());
645 }
646
647 /* Detach all attached Hard Disks */
648 CHardDiskAttachmentEnumerator en =
649 mMachine.GetHardDiskAttachments().Enumerate();
650 while (en.HasMore())
651 {
652 CHardDiskAttachment hda = en.GetNext();
653 mMachine.DetachHardDisk (hda.GetBus(), hda.GetChannel(), hda.GetDevice());
654 if (!mMachine.isOk())
655 vboxProblem().cannotDetachHardDisk (this, mMachine,
656 hda.GetBus(), hda.GetChannel(), hda.GetDevice());
657 }
658
659 /* Sort&Attach all listed Hard Disks */
660 mLvHD->setSortColumn (0);
661 mLvHD->sort();
662 LONG maxSATAPort = 1;
663 HDListItem *item = mLvHD->firstChild() &&
664 mLvHD->firstChild()->rtti() == HDListItem::HDListItemType ?
665 static_cast<HDListItem*> (mLvHD->firstChild()) : 0;
666 while (item)
667 {
668 if (item->bus() == KStorageBus_SATA)
669 maxSATAPort = maxSATAPort < item->device() ?
670 item->device() : maxSATAPort;
671 mMachine.AttachHardDisk (item->getId(),
672 item->bus(), item->channel(), item->device());
673 if (!mMachine.isOk())
674 vboxProblem().cannotAttachHardDisk (this, mMachine, item->getId(),
675 item->bus(), item->channel(), item->device());
676 item = item->nextSibling();
677 }
678
679 if (!ctl.isNull())
680 {
681 mMachine.GetSATAController().SetPortCount (maxSATAPort);
682 }
683}
684
685QString VBoxHardDiskSettings::checkValidity()
686{
687 QString result;
688 QStringList slList;
689 QStringList idList;
690
691 /* Search for coincidences through all the media-id */
692 HDListItem *item = mLvHD->firstChild() &&
693 mLvHD->firstChild()->rtti() == HDListItem::HDListItemType ?
694 static_cast<HDListItem*> (mLvHD->firstChild()) : 0;
695 while (item)
696 {
697 QString id = item->getId().toString();
698 if (item->getId().isNull())
699 {
700 result = tr ("No hard disk is selected for <i>%1</i>")
701 .arg (item->text (0));
702 break;
703 }
704 else if (idList.contains (id))
705 {
706 result = tr ("<i>%1</i> uses the hard disk that is already "
707 "attached to <i>%2</i>")
708 .arg (item->text (0)).arg (slList [idList.findIndex (id)]);
709 break;
710 }
711 else
712 {
713 slList << item->text (0);
714 idList << id;
715 }
716 item = item->nextSibling();
717 }
718
719 return result;
720}
721
722void VBoxHardDiskSettings::addHDItem()
723{
724 /* Create new item */
725 HDListItem *item = createItem (mSlotUniquizer, mMachine);
726 item->moveFocusToColumn (1);
727 mLvHD->setCurrentItem (item);
728 if (!mLvHD->hasFocus())
729 mLvHD->setFocus();
730 /* Qt3 isn't emits currentChanged() signal if first list-view item added */
731 if (mLvHD->childCount() == 1)
732 onCurrentChanged (item);
733
734 /* Search through the attachments for the used VDIs */
735 QStringList usedList;
736 HDListItem *it = mLvHD->firstChild()->rtti() == HDListItem::HDListItemType ?
737 static_cast<HDListItem*> (mLvHD->firstChild()) : 0;
738 while (it && it != item)
739 {
740 usedList << it->text (1);
741 it = it->nextSibling();
742 }
743 item->tryToChooseExcluding (usedList);
744
745 /* Ask the user for method to add new vdi */
746 int result = mLvHD->childCount() - 1 > item->vdiCount() ?
747 vboxProblem().confirmRunNewHDWzdOrVDM (this) :
748 QIMessageBox::Cancel;
749 if (result == QIMessageBox::Yes)
750 {
751 VBoxNewHDWzd dlg (this, "VBoxNewHDWzd");
752 if (dlg.exec() == QDialog::Accepted)
753 {
754 CHardDisk hd = dlg.hardDisk();
755 VBoxMedia::Status status =
756 hd.GetAccessible() ? VBoxMedia::Ok :
757 hd.isOk() ? VBoxMedia::Inaccessible :
758 VBoxMedia::Error;
759 vboxGlobal().addMedia (VBoxMedia (CUnknown (hd), VBoxDefs::HD, status));
760 item->setId (dlg.hardDisk().GetId());
761 }
762 }
763 else if (result == QIMessageBox::No)
764 showVDM();
765
766 emit hddListChanged();
767}
768
769void VBoxHardDiskSettings::delHDItem()
770{
771 if (mLvHD->currentItem())
772 {
773 QListViewItem *item = mLvHD->currentItem();
774 Assert (item == mPrevItem);
775 if (item == mPrevItem)
776 {
777 delete item;
778 mPrevItem = 0;
779
780 if (mLvHD->currentItem() &&
781 mLvHD->currentItem()->rtti() == HDSpaceItem::HDSpaceItemType &&
782 mLvHD->currentItem()->itemAbove() &&
783 mLvHD->currentItem()->itemAbove()->rtti() == HDListItem::HDListItemType)
784 mLvHD->setCurrentItem (mLvHD->currentItem()->itemAbove());
785 }
786 }
787
788 emit hddListChanged();
789}
790
791void VBoxHardDiskSettings::showVDM()
792{
793 HDListItem *item = mLvHD->currentItem() &&
794 mLvHD->currentItem()->rtti() == HDListItem::HDListItemType ?
795 static_cast<HDListItem*> (mLvHD->currentItem()) : 0;
796
797 VBoxDiskImageManagerDlg dlg (this, "VBoxDiskImageManagerDlg",
798 WType_Dialog | WShowModal);
799
800 QUuid machineId = mMachine.GetId();
801 QUuid hdId = item->getId();
802
803 dlg.setup (VBoxDefs::HD, true, &machineId, true /* aRefresh */,
804 mMachine, hdId, QUuid(), QUuid());
805
806 if (dlg.exec() == VBoxDiskImageManagerDlg::Accepted)
807 item->setId (dlg.getSelectedUuid());
808}
809
810void VBoxHardDiskSettings::moveFocus (QListViewItem *aItem, const QPoint&, int aCol)
811{
812 if (aItem && aItem->rtti() == HDListItem::HDListItemType)
813 {
814 static_cast<HDListItem*> (aItem)->moveFocusToColumn (aCol);
815 onAfterCurrentChanged (aItem);
816 }
817}
818
819void VBoxHardDiskSettings::onCurrentChanged (QListViewItem *aItem)
820{
821 /* Postpone onCurrentChanged signal to be post-processed after all others */
822 QApplication::postEvent (this, new OnItemChangedEvent (aItem));
823}
824
825void VBoxHardDiskSettings::onToggleSATAController (bool aOn)
826{
827 if (!aOn)
828 {
829 HDListItem *firstItem = mLvHD->firstChild() &&
830 mLvHD->firstChild()->rtti() == HDListItem::HDListItemType ?
831 static_cast<HDListItem*> (mLvHD->firstChild()) : 0;
832
833 /* Search the list for the SATA ports in */
834 HDListItem *sataItem = firstItem;
835 while (sataItem)
836 {
837 if (sataItem->bus() == KStorageBus_SATA)
838 break;
839 sataItem = sataItem->nextSibling();
840 }
841
842 /* If list contains at least one SATA port */
843 if (sataItem)
844 {
845 int rc = vboxProblem().confirmDetachSATASlots (this);
846 if (rc != QIMessageBox::Ok)
847 {
848 /* Switch check-box back to "on" */
849 mCbSATA->blockSignals (true);
850 mCbSATA->setChecked (true);
851 mCbSATA->blockSignals (false);
852 return;
853 }
854 else
855 {
856 /* Delete SATA items */
857 HDListItem *it = firstItem;
858 mLvHD->blockSignals (true);
859 while (it)
860 {
861 HDListItem *curIt = it;
862 it = it->nextSibling();
863 if (curIt->bus() == KStorageBus_SATA)
864 {
865 if (curIt == mLvHD->currentItem())
866 mPrevItem = 0;
867 delete curIt;
868 }
869 }
870 mLvHD->blockSignals (false);
871 emit hddListChanged();
872 }
873 }
874 }
875
876 int newSATAPortsCount = aOn && !mMachine.isNull() ? SATAPortsCount : 0;
877 if (mSlotUniquizer->getSATAPortsCount() != newSATAPortsCount)
878 {
879 mSlotUniquizer->setSATAPortsCount (newSATAPortsCount);
880 onAfterCurrentChanged (mLvHD->currentItem());
881 }
882}
883
884void VBoxHardDiskSettings::onAfterCurrentChanged (QListViewItem *aItem)
885{
886 /* Process postponed onCurrentChanged event */
887 if (aItem != mPrevItem)
888 {
889 int prevFocusColumn =
890 mPrevItem && mPrevItem->rtti() == HDListItem::HDListItemType ?
891 static_cast<HDListItem*> (mPrevItem)->focusColumn() : 1;
892
893 if (mPrevItem && mPrevItem->rtti() == HDListItem::HDListItemType)
894 static_cast<HDListItem*> (mPrevItem)->moveFocusToColumn (-1);
895
896 if (aItem && aItem->rtti() == HDListItem::HDListItemType &&
897 static_cast<HDListItem*> (aItem)->focusColumn() == -1)
898 static_cast<HDListItem*> (aItem)->moveFocusToColumn (prevFocusColumn);
899
900 mPrevItem = aItem;
901 }
902
903 mAddAttachmentAct->setEnabled (mLvHD->childCount() <=
904 mSlotUniquizer->totalCount());
905 mRemoveAttachmentAct->setEnabled (aItem &&
906 aItem->rtti() == HDListItem::HDListItemType);
907 mSelectHardDiskAct->setEnabled (aItem &&
908 aItem->rtti() == HDListItem::HDListItemType &&
909 static_cast<HDListItem*> (aItem)->focusColumn() == 1);
910}
911
912void VBoxHardDiskSettings::onContextMenuRequested (QListViewItem * /*aItem*/,
913 const QPoint &aPoint, int)
914{
915 mContextMenu->exec (aPoint);
916}
917
918HDListItem* VBoxHardDiskSettings::createItem (HDSlotUniquizer *aUniq,
919 const CMachine &aMachine)
920{
921 QListViewItem *item = mLvHD->lastItem();
922 Assert (item->rtti() == HDSpaceItem::HDSpaceItemType);
923 HDListItem *last = item->itemAbove() &&
924 item->itemAbove()->rtti() == HDListItem::HDListItemType ?
925 static_cast<HDListItem*> (item->itemAbove()) : 0;
926
927 return last ?
928 new HDListItem (this, mLvHD, last, aUniq, aMachine) :
929 new HDListItem (this, mLvHD, aUniq, aMachine);
930}
931
932bool VBoxHardDiskSettings::event (QEvent *aEvent)
933{
934 switch (aEvent->type())
935 {
936 /* Redirect postponed onCurrentChanged event */
937 case OnItemChangedEvent::Type:
938 {
939 OnItemChangedEvent *e = static_cast<OnItemChangedEvent*> (aEvent);
940 onAfterCurrentChanged (e->mItem);
941 break;
942 }
943 default:
944 break;
945 }
946
947 return QWidget::event (aEvent);
948}
949
950void VBoxHardDiskSettings::showEvent (QShowEvent *aEvent)
951{
952 QWidget::showEvent (aEvent);
953 QTimer::singleShot (0, this, SLOT (adjustList()));
954}
955
956bool VBoxHardDiskSettings::eventFilter (QObject *aObject, QEvent *aEvent)
957{
958 if (!aObject->isWidgetType())
959 return QWidget::eventFilter (aObject, aEvent);
960
961 if (static_cast<QWidget*> (aObject)->topLevelWidget() != topLevelWidget())
962 return QWidget::eventFilter (aObject, aEvent);
963
964 switch (aEvent->type())
965 {
966 /* Process double-click as "open combo-box" action */
967 case QEvent::MouseButtonDblClick:
968 {
969 if (aObject != mLvHD->viewport())
970 break;
971
972 QMouseEvent *e = static_cast<QMouseEvent*> (aEvent);
973 QListViewItem *clickedItem = mLvHD->itemAt (e->pos());
974 HDListItem *item = clickedItem &&
975 clickedItem->rtti() == HDListItem::HDListItemType ?
976 static_cast<HDListItem*> (clickedItem) : 0;
977
978 if (!item && mAddAttachmentAct->isEnabled())
979 addHDItem();
980 break;
981 }
982 /* Process mouse-move as "make tool-tip" action */
983 case QEvent::MouseMove:
984 {
985 if (aObject != mLvHD->viewport())
986 {
987 if (!QToolTip::textFor (mLvHD->viewport()).isNull())
988 QToolTip::remove (mLvHD->viewport());
989 break;
990 }
991
992 QMouseEvent *e = static_cast<QMouseEvent*> (aEvent);
993 QListViewItem *hoveredItem = mLvHD->itemAt (e->pos());
994 HDListItem *item = hoveredItem &&
995 hoveredItem->rtti() == HDListItem::HDListItemType ?
996 static_cast<HDListItem*> (hoveredItem) : 0;
997
998 QString oldTip = QToolTip::textFor (mLvHD->viewport());
999 QString newTip = item ? item->toolTip() :
1000 tr ("Double-click to add a new attachment");
1001
1002 if (newTip != oldTip)
1003 {
1004 QToolTip::remove (mLvHD->viewport());
1005 QToolTip::add (mLvHD->viewport(), newTip);
1006 }
1007 break;
1008 }
1009 case QEvent::KeyPress:
1010 {
1011 if (!mLvHD->queryList (0, 0, false, true)->contains (aObject))
1012 break;
1013
1014 HDListItem *item = mLvHD->currentItem() &&
1015 mLvHD->currentItem()->rtti() == HDListItem::HDListItemType ?
1016 static_cast<HDListItem*> (mLvHD->currentItem()) : 0;
1017
1018 QKeyEvent *e = static_cast<QKeyEvent*> (aEvent);
1019 /* Process cursor-left as "move focus left" action */
1020 if (e->key() == Qt::Key_Left && !e->state())
1021 {
1022 if (item && item->focusColumn() != -1 &&
1023 item->focusColumn() > 0)
1024 {
1025 item->setAutoFocus (false);
1026 mLvHD->setFocus();
1027 item->moveFocusToColumn (item->focusColumn() - 1);
1028 onAfterCurrentChanged (item);
1029 }
1030 return true;
1031 } else
1032 /* Process cursor-right as "move focus right" action */
1033 if (e->key() == Qt::Key_Right && !e->state())
1034 {
1035 if (item && item->focusColumn() != -1 &&
1036 item->focusColumn() < mLvHD->columns() - 1)
1037 {
1038 item->setAutoFocus (false);
1039 mLvHD->setFocus();
1040 item->moveFocusToColumn (item->focusColumn() + 1);
1041 onAfterCurrentChanged (item);
1042 }
1043 return true;
1044 } else
1045 /* Process cursor-up as "move focus up" action */
1046 if (e->key() == Qt::Key_Up && !e->state())
1047 {
1048 if (item && item->focusColumn() != -1 &&
1049 item->itemAbove())
1050 {
1051 item->setAutoFocus (false);
1052 mLvHD->setFocus();
1053 mLvHD->setCurrentItem (item->itemAbove());
1054 }
1055 return true;
1056 } else
1057 /* Process cursor-down as "move focus down" action */
1058 if (e->key() == Qt::Key_Down && !e->state())
1059 {
1060 if (item && item->focusColumn() != -1 &&
1061 item->itemBelow())
1062 {
1063 item->setAutoFocus (false);
1064 mLvHD->setFocus();
1065 mLvHD->setCurrentItem (item->itemBelow());
1066 }
1067 return true;
1068 } else
1069 /* Process F2/Space as "open combo-box" actions */
1070 if (!e->state() &&
1071 (e->key() == Qt::Key_F2 || e->key() == Qt::Key_Space))
1072 {
1073 if (item)
1074 item->showEditor();
1075 return true;
1076 }
1077 /* Process Ctrl/Alt+Up/Down as "open combo-box" actions */
1078 if ((e->state() == Qt::AltButton || e->state() == Qt::ControlButton) &&
1079 (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))
1080 {
1081 if (item)
1082 item->showEditor();
1083 return true;
1084 } else
1085 if ((e->key() == Qt::Key_Tab && !e->state()) ||
1086 e->key() == Qt::Key_Backtab)
1087 {
1088 item->setAutoFocus (false);
1089 mLvHD->setFocus();
1090 }
1091 break;
1092 }
1093 /* Process focus event to toggle the current selection state */
1094 case QEvent::FocusIn:
1095 {
1096 if (aObject == mLvHD)
1097 onAfterCurrentChanged (mLvHD->currentItem());
1098 else if (!mGbHDList->queryList (0, 0, false, true)->contains (aObject))
1099 onAfterCurrentChanged (0);
1100
1101 break;
1102 }
1103 default:
1104 break;
1105 }
1106
1107 return QWidget::eventFilter (aObject, aEvent);
1108}
1109
1110void VBoxHardDiskSettings::adjustList()
1111{
1112 /* Search through the slots list for maximum element width */
1113 int minLength = 0;
1114 QFontMetrics fm = mLvHD->fontMetrics();
1115 QValueList<HDSlot> list = mSlotUniquizer->list (0, false);
1116 for (uint i = 0; i < list.size(); ++ i)
1117 {
1118 int length = fm.width (list [i].str);
1119 minLength = minLength < length ? length : minLength;
1120 }
1121 minLength = minLength > mLvHD->viewport()->width() * 0.4 ?
1122 (int) (mLvHD->viewport()->width() * 0.4) : minLength;
1123
1124 mLvHD->setColumnWidth (0,
1125 minLength /* maximum string width */ +
1126 6 * 2 /* 2 combo-box margin */ +
1127 HDSlotItem::scrollBarWidth() /* scrollbar */);
1128 mLvHD->setColumnWidth (1, mLvHD->viewport()->width() - mLvHD->columnWidth (0));
1129}
1130
1131#include "VBoxHardDiskSettings.ui.moc"
1132
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