Changeset 8159 in vbox
- Timestamp:
- Apr 18, 2008 4:01:43 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 29869
- Location:
- trunk/src/VBox/Frontends/VirtualBox4
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox4/include/VBoxDefs.h
r8155 r8159 6 6 7 7 /* 8 * Copyright (C) 2006-200 7Sun Microsystems, Inc.8 * Copyright (C) 2006-2008 Sun Microsystems, Inc. 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 172 172 }; 173 173 174 #define MAC_LEOPARD_STYLE defined(Q_WS_MAC) && (QT_VERSION >= 0x040300) 175 174 176 #endif // __VBoxDefs_h__ 175 177 -
trunk/src/VBox/Frontends/VirtualBox4/include/VBoxSelectorWnd.h
r8155 r8159 6 6 7 7 /* 8 * Copyright (C) 2006-200 7Sun Microsystems, Inc.8 * Copyright (C) 2006-2008 Sun Microsystems, Inc. 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 31 31 #include <QMainWindow> 32 32 33 class VBoxVMListBox;34 33 class VBoxSnapshotsWgt; 35 34 class VBoxVMDetailsView; 36 35 class VBoxVMDescriptionPage; 37 36 class VBoxVMLogViewer; 37 class VBoxVMListView; 38 class VBoxVMModel; 39 class VBoxVMItem; 38 40 39 41 class QTabWidget; 40 class Q 3ListBoxItem;42 class QListView; 41 43 class QEvent; 42 44 class QUuid; 43 45 44 class VBoxSelectorWnd 46 class VBoxSelectorWnd: public QMainWindow 45 47 { 46 48 Q_OBJECT … … 76 78 bool aDescription); 77 79 78 void showContextMenu ( Q3ListBoxItem *, const QPoint &);80 void showContextMenu (VBoxVMItem *aItem, const QPoint &aPoint); 79 81 80 82 protected: … … 91 93 private slots: 92 94 93 void vmList BoxCurrentChanged (bool aRefreshDetails = true,94 bool aRefreshSnapshots = true,95 bool aRefreshDescription = true);95 void vmListViewCurrentChanged (bool aRefreshDetails = true, 96 bool aRefreshSnapshots = true, 97 bool aRefreshDescription = true); 96 98 97 99 void mediaEnumStarted(); … … 133 135 QAction *helpResetMessagesAction; 134 136 135 /* widgets */ 136 VBoxVMListBox *vmListBox; 137 /* The vm list view/model */ 138 VBoxVMListView *mVMListView; 139 VBoxVMModel *mVMModel; 140 141 /* The right information widgets */ 137 142 QTabWidget *vmTabWidget; 138 143 VBoxVMDetailsView *vmDetailsView; -
trunk/src/VBox/Frontends/VirtualBox4/include/VBoxVMListBox.h
r8155 r8159 2 2 * 3 3 * VBox frontends: Qt GUI ("VirtualBox"): 4 * VBoxVM ListBox, VBoxVMListBoxItemclass declarations4 * VBoxVMItem, VBoxVMModel, VBoxVMListView, VBoxVMItemPainter class declarations 5 5 */ 6 6 7 7 /* 8 * Copyright (C) 2006-200 7Sun Microsystems, Inc.8 * Copyright (C) 2006-2008 Sun Microsystems, Inc. 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 24 24 #define __VBoxVMListBox_h__ 25 25 26 #include "COMDefs.h"27 28 #include "VBoxSelectorWnd.h"29 26 #include "VBoxGlobal.h" 30 31 #include <q3listbox.h> 32 #include <qfont.h> 33 #include <qdatetime.h> 34 //Added by qt3to4: 35 #include <QFocusEvent> 36 37 struct QUuid; 38 class QColorGroup; 39 40 class VBoxVMListBoxTip; 41 class VBoxVMListBoxItem; 42 43 /** 44 * 45 * The VBoxVMListBox class is a visual representation of the list of 46 * existing VMs in the VBox GUI. 47 * 48 * Every item in the list box is an instance of the VBoxVMListBoxItem 49 * class. 50 */ 51 class VBoxVMListBox : public Q3ListBox 52 { 53 Q_OBJECT 54 55 public: 56 57 VBoxVMListBox (QWidget *aParent = 0, const char *aName = NULL, 58 Qt::WFlags aFlags = 0); 59 60 virtual ~VBoxVMListBox(); 61 62 QFont nameFont() const { return mNameFont; } 63 64 QFont shotFont() const { return mShotFont; } 65 66 QFont stateFont (KSessionState aS) const 67 { 68 return aS == KSessionState_Closed ? font() : mStateBusyFont; 69 } 70 71 int margin() const { return mMargin; } 72 73 void refresh(); 74 void refresh (const QUuid &aID); 75 76 VBoxVMListBoxItem *item (const QUuid &aID); 77 78 const QColorGroup &activeColorGroup() const; 79 80 protected: 81 82 virtual void focusInEvent (QFocusEvent *aE); 83 virtual void focusOutEvent (QFocusEvent *aE); 84 85 private: 86 87 CVirtualBox mVBox; 88 QFont mNameFont; 89 QFont mShotFont; 90 QFont mStateBusyFont; 91 int mMargin; 92 93 VBoxVMListBoxTip *mToolTip; 94 bool mGaveFocusToPopup; 95 }; 96 97 /** 98 * 99 * The VBoxVMListBoxItem class is a visual representation of the virtual 100 * machine in the VBoxVMListBox widget. 101 * 102 * It holds a CMachine instance (passed to the constructor) to 103 * get an access to various VM data. 104 */ 105 class VBoxVMListBoxItem : public Q3ListBoxItem 106 { 107 public: 108 109 VBoxVMListBoxItem (VBoxVMListBox *aLB, const CMachine &aM); 110 virtual ~VBoxVMListBoxItem(); 111 112 QString text() const { return mName; } 113 114 VBoxVMListBox *vmListBox() const 115 { 116 return static_cast <VBoxVMListBox *> (listBox()); 117 } 27 #include "VBoxDefs.h" 28 29 /* Qt includes */ 30 #include <QAbstractListModel> 31 #include <QListView> 32 #include <QItemDelegate> 33 34 class VBoxVMItem 35 { 36 public: 37 VBoxVMItem (const CMachine &aM); 38 virtual ~VBoxVMItem(); 118 39 119 40 CMachine machine() const { return mMachine; } 120 void setMachine (const CMachine &aM); 121 122 void recache(); 41 42 QString name() const { return mName; } 43 QIcon osIcon() const { return mAccessible ? vboxGlobal().vmGuestOSTypeIcon (mOSTypeId) :QPixmap (":/os_unknown.png"); } 44 QUuid id() const { return mId; } 45 46 QString sessionStateName() const { return mAccessible ? vboxGlobal().toString (mState) : QObject::tr ("Inaccessible"); } 47 QIcon sessionStateIcon() const { return mAccessible ? vboxGlobal().toIcon (mState) : QPixmap (":/state_aborted_16px.png"); } 48 49 QString snapshotName() const { return mSnapshotName; } 50 ULONG snapshotCount() const { return mSnapshotCount; } 123 51 124 52 QString toolTipText() const; 125 53 126 int height (const Q3ListBox *) const;127 int width (const Q3ListBox *) const;128 129 QUuid id() const { return mId; }130 54 bool accessible() const { return mAccessible; } 131 55 const CVirtualBoxErrorInfo &accessError() const { return mAccessError; } 132 QString name() const { return mName; }133 56 KMachineState state() const { return mState; } 134 57 KSessionState sessionState() const { return mSessionState; } 135 ULONG snapshotCount() const { return mSnapshotCount; } 136 137 /// @todo see comments in #switchTo() in VBoxVMListBox.cpp 138 #if 0 139 bool canSwitchTo() const { return mWinId != (WId) ~0; } 140 #endif 58 59 bool recache(); 60 141 61 bool canSwitchTo() const; 142 62 bool switchTo(); 143 63 144 protected:145 146 void paint (QPainter *aP);147 148 64 private: 149 65 66 /* Private member vars */ 150 67 CMachine mMachine; 151 68 152 /* cached machine data (to minimize server requests) */ 153 69 /* Cached machine data (to minimize server requests) */ 154 70 QUuid mId; 155 71 QString mSettingsFile; … … 167 83 168 84 ULONG mPid; 169 /// @todo see comments in #switchTo() in VBoxVMListBox.cpp170 #if 0171 WId mWinId;172 #endif173 85 }; 174 86 87 /* Make the pointer of this class public to the QVariant framework */ 88 Q_DECLARE_METATYPE(VBoxVMItem *); 89 90 class VBoxVMModel: public QAbstractListModel 91 { 92 Q_OBJECT; 93 94 public: 95 enum { SnapShotDisplayRole = Qt::UserRole, 96 SnapShotFontRole, 97 SessionStateDisplayRole, 98 SessionStateDecorationRole, 99 SessionStateFontRole, 100 VBoxVMItemPtrRole }; 101 102 VBoxVMModel(QObject *aParent = 0) 103 :QAbstractListModel (aParent) { refresh(); } 104 105 void addItem (VBoxVMItem *aItem); 106 void removeItem (VBoxVMItem *aItem); 107 void refreshItem (VBoxVMItem *aItem); 108 109 void itemChanged (VBoxVMItem *aItem); 110 111 void refresh(); 112 113 VBoxVMItem *itemById (const QUuid &aId) const; 114 QModelIndex indexById (const QUuid &aId) const; 115 116 int rowById (const QUuid &aId) const;; 117 118 void sort (Qt::SortOrder aOrder = Qt::AscendingOrder) { sort (0, aOrder); } 119 120 /* The following are necessary model implementations */ 121 void sort (int aColumn, Qt::SortOrder aOrder = Qt::AscendingOrder); 122 123 int rowCount (const QModelIndex &aParent = QModelIndex()) const; 124 125 QVariant data (const QModelIndex &aIndex, int aRole) const; 126 QVariant headerData (int aSection, Qt::Orientation aOrientation, 127 int aRole = Qt::DisplayRole) const; 128 129 bool removeRows (int aRow, int aCount, const QModelIndex &aParent = QModelIndex()); 130 131 private: 132 static bool VBoxVMItemNameCompareLessThan (VBoxVMItem* aItem1, VBoxVMItem* aItem2); 133 static bool VBoxVMItemNameCompareGreaterThan (VBoxVMItem* aItem1, VBoxVMItem* aItem2); 134 135 /* Private member vars */ 136 QList<VBoxVMItem *> mVMItemList; 137 }; 138 139 class VBoxVMListView: public QListView 140 { 141 Q_OBJECT; 142 143 public: 144 VBoxVMListView (QWidget *aParent = 0); 145 146 void selectItemByRow (int row); 147 void selectItemById (const QUuid &aID); 148 void ensureSomeRowSelected (int aRowHint); 149 VBoxVMItem * selectedItem() const; 150 151 void ensureCurrentVisible(); 152 153 signals: 154 void currentChanged(); 155 void activated(); 156 void contextMenuRequested (VBoxVMItem *aItem, const QPoint &aPoint); 157 158 protected slots: 159 void selectionChanged (const QItemSelection &aSelected, const QItemSelection &aDeselected); 160 void currentChanged (const QModelIndex &aCurrent, const QModelIndex &aPrevious); 161 void dataChanged (const QModelIndex &aTopLeft, const QModelIndex &aBottomRight); 162 void focusChanged (QWidget *aOld, QWidget *aNow); 163 164 protected: 165 void mousePressEvent (QMouseEvent *aEvent); 166 bool selectCurrent(); 167 }; 168 169 class VBoxVMItemPainter: public QItemDelegate 170 { 171 public: 172 VBoxVMItemPainter (QObject *aParent = 0) 173 : QItemDelegate (aParent), mMargin (8), mSpacing (mMargin * 3 / 2) {} 174 175 QSize sizeHint (const QStyleOptionViewItem &aOption, 176 const QModelIndex &aIndex) const; 177 178 void paint (QPainter *aPainter, const QStyleOptionViewItem &aOption, 179 const QModelIndex &aIndex) const; 180 181 protected: 182 void drawBackground (QPainter *aPainter, const QStyleOptionViewItem &aOption, 183 const QModelIndex &aIndex) const; 184 185 private: 186 inline QFontMetrics fontMetric (const QModelIndex &aIndex, int aRole) const { return QFontMetrics (aIndex.data (aRole).value<QFont>()); } 187 inline QIcon::Mode iconMode (QStyle::State aState) const 188 { 189 if (!(aState & QStyle::State_Enabled)) 190 return QIcon::Disabled; 191 if (aState & QStyle::State_Selected) 192 return QIcon::Selected; 193 return QIcon::Normal; 194 } 195 inline QIcon::State iconState (QStyle::State aState) const { return aState & QStyle::State_Open ? QIcon::On : QIcon::Off; } 196 197 QRect rect (const QStyleOptionViewItem &aOption, 198 const QModelIndex &aIndex, int aRole) const; 199 200 void calcLayout (const QModelIndex &aIndex, 201 QRect *aOSType, QRect *aVMName, QRect *aShot, 202 QRect *aStateIcon, QRect *aState) const; 203 204 /* Private member vars */ 205 int mMargin; 206 int mSpacing; 207 }; 208 175 209 #endif // __VBoxVMListItem_h__ -
trunk/src/VBox/Frontends/VirtualBox4/src/VBoxSelectorWnd.cpp
r8155 r8159 6 6 7 7 /* 8 * Copyright (C) 2006-200 7Sun Microsystems, Inc.8 * Copyright (C) 2006-2008 Sun Microsystems, Inc. 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 219 219 ~VBoxVMDescriptionPage() {} 220 220 221 void setMachineItem (VBoxVM ListBoxItem *aItem);221 void setMachineItem (VBoxVMItem *aItem); 222 222 223 223 void languageChange(); … … 230 230 private: 231 231 232 VBoxVM ListBoxItem *mItem;232 VBoxVMItem *mItem; 233 233 234 234 VBoxSelectorWnd *mParent; … … 298 298 * unnecessary RPC calls. 299 299 */ 300 void VBoxVMDescriptionPage::setMachineItem (VBoxVM ListBoxItem *aItem)300 void VBoxVMDescriptionPage::setMachineItem (VBoxVMItem *aItem) 301 301 { 302 302 mItem = aItem; … … 455 455 QHBoxLayout *centralLayout = 456 456 new QHBoxLayout (centralWidget()); 457 centralLayout->setSpacing (9);458 VBoxGlobal::setLayoutMargin (centralLayout, 5);459 457 460 458 /* left vertical box */ 461 459 QVBoxLayout *leftVLayout = new QVBoxLayout (); 462 leftVLayout->setSpacing (5);463 460 /* right vertical box */ 464 461 QVBoxLayout *rightVLayout = new QVBoxLayout (); 465 rightVLayout->setSpacing (5); 466 centralLayout->addLayout (leftVLayout, 3); 467 centralLayout->addLayout (rightVLayout, 3); 462 centralLayout->addLayout (leftVLayout, 1); 463 centralLayout->addLayout (rightVLayout, 2); 468 464 469 465 /* VM list toolbar */ 470 466 VBoxToolBar *vmTools = new VBoxToolBar (this); 471 #if defined (Q_WS_MAC) && (QT_VERSION >= 0x040300)467 #if MAC_LEOPARD_STYLE 472 468 /* Enable unified toolbars on Mac OS X. Available on Qt >= 4.3 */ 473 469 setUnifiedTitleAndToolBarOnMac (true); 474 470 addToolBar (vmTools); 475 #else 471 /* No spacing/margin on the mac */ 472 VBoxGlobal::setLayoutMargin (centralLayout, 0); 473 leftVLayout->setSpacing (0); 474 rightVLayout->setSpacing (0); 475 #else /* MAC_LEOPARD_STYLE */ 476 476 leftVLayout->addWidget(vmTools); 477 #endif 478 479 /* VM list box */ 480 vmListBox = new VBoxVMListBox (); 481 leftVLayout->addWidget (vmListBox); 477 centralLayout->setSpacing (9); 478 VBoxGlobal::setLayoutMargin (centralLayout, 5); 479 leftVLayout->setSpacing (5); 480 rightVLayout->setSpacing (5); 481 #endif /* MAC_LEOPARD_STYLE */ 482 483 /* VM list view */ 484 mVMListView = new VBoxVMListView(); 485 mVMModel = new VBoxVMModel(); 486 mVMListView->setModel (mVMModel); 487 488 leftVLayout->addWidget (mVMListView); 482 489 483 490 /* VM tab widget containing details and snapshots tabs */ … … 614 621 } 615 622 623 /* Reset to the first item */ 624 mVMListView->selectItemByRow (0); 616 625 /* restore the position of vm selector */ 617 626 { … … 619 628 QString prevVMId = vbox.GetExtraData (VBoxDefs::GUI_LastVMSelected); 620 629 621 VBoxVMListBoxItem *item = vmListBox->item (QUuid (prevVMId)); 622 if (item) 623 vmListBox->setSelected (item, true); 630 mVMListView->selectItemById (QUuid (prevVMId)); 624 631 } 625 632 … … 653 660 &vboxProblem(), SLOT (resetSuppressedMessages())); 654 661 655 connect ( vmListBox, SIGNAL (currentChanged(Q3ListBoxItem *)),656 this, SLOT (vmList BoxCurrentChanged()));657 connect ( vmListBox, SIGNAL (selected (Q3ListBoxItem *)),662 connect (mVMListView, SIGNAL (currentChanged()), 663 this, SLOT (vmListViewCurrentChanged())); 664 connect (mVMListView, SIGNAL (activated ()), 658 665 this, SLOT (vmStart())); 659 connect ( vmListBox, SIGNAL (contextMenuRequested (Q3ListBoxItem *, const QPoint &)),660 this, SLOT (showContextMenu ( Q3ListBoxItem *, const QPoint &)));666 connect (mVMListView, SIGNAL (contextMenuRequested (VBoxVMItem *, const QPoint &)), 667 this, SLOT (showContextMenu (VBoxVMItem *, const QPoint &))); 661 668 662 669 connect (vmDetailsView, SIGNAL (linkClicked (const QString &)), … … 682 689 683 690 /* bring the VM list to the focus */ 684 vmListBox->setFocus();691 mVMListView->setFocus(); 685 692 } 686 693 … … 702 709 /* save vm selector position */ 703 710 { 704 Q3ListBoxItem *item = vmListBox->selectedItem();711 VBoxVMItem *item = mVMListView->selectedItem(); 705 712 QString curVMId = item ? 706 QString ( static_cast<VBoxVMListBoxItem*> (item)->id()) :713 QString (item->id()) : 707 714 QString::null; 708 715 vbox.SetExtraData (VBoxDefs::GUI_LastVMSelected, curVMId); … … 755 762 756 763 /* wait until the list is updated by OnMachineRegistered() */ 757 VBoxVMListBoxItem *item = 0;758 while (!i tem)764 QModelIndex index; 765 while (!index.isValid()) 759 766 { 760 767 qApp->processEvents(); 761 item = vmListBox->item (m.GetId()); 762 } 763 /* 764 * we must use setSelected() instead of setCurrentItem() below because 765 * setCurrentItem() does nothing after the first item has been added 766 * to the list (since it is already the current one), but we still 767 * need currentChanged() to be emitted to sync things (QListBox doesn't 768 * emit currentChanged() when the current item index changes from -1 769 * to 0, i.e. when the first item is being added -- seems to be a Qt 770 * bug). 771 */ 772 vmListBox->setSelected (item, true); 768 index = mVMModel->indexById (m.GetId()); 769 } 770 mVMListView->setCurrentIndex (index); 773 771 } 774 772 } … … 791 789 } 792 790 793 VBoxVM ListBoxItem *item = (VBoxVMListBoxItem *) vmListBox->selectedItem();791 VBoxVMItem *item = mVMListView->selectedItem(); 794 792 795 793 AssertMsgReturnVoid (item, ("Item must be always selected here")); … … 818 816 { 819 817 if (oldName.compare (m.GetName())) 820 vmListBox->sort();818 mVMModel->sort(); 821 819 } 822 820 else … … 831 829 } 832 830 833 vmListBox->setFocus();831 mVMListView->setFocus(); 834 832 835 833 session.Close(); … … 838 836 void VBoxSelectorWnd::vmDelete() 839 837 { 840 VBoxVM ListBoxItem *item = (VBoxVMListBoxItem *) vmListBox->selectedItem();838 VBoxVMItem *item = mVMListView->selectedItem(); 841 839 842 840 AssertMsgReturn (item, ("Item must be always selected here"), (void) 0); … … 884 882 machine.DeleteSettings(); 885 883 /* remove the item shortly: cmachine it refers to is no longer valid! */ 886 vmListBox->removeItem (vmListBox->index (item)); 884 #warning "port me: check this" 885 int row = mVMModel->rowById (item->id()); 886 mVMModel->removeItem (item); 887 mVMListView->ensureSomeRowSelected (row); 887 888 } 888 889 if (!vbox.isOk() || !machine.isOk()) … … 894 895 void VBoxSelectorWnd::vmStart() 895 896 { 896 /* we always get here when vmListBox emits the selected() signal,897 /* we always get here when mVMListView emits the activated() signal, 897 898 * so we must explicitly check if the action is enabled or not. */ 898 899 if (!vmStartAction->isEnabled()) 899 900 return; 900 901 901 VBoxVM ListBoxItem *item = (VBoxVMListBoxItem *) vmListBox->selectedItem();902 VBoxVMItem *item = mVMListView->selectedItem(); 902 903 903 904 AssertMsg (item, ("Item must be always selected here")); … … 971 972 void VBoxSelectorWnd::vmDiscard() 972 973 { 973 VBoxVM ListBoxItem *item = (VBoxVMListBoxItem *) vmListBox->selectedItem();974 VBoxVMItem *item = mVMListView->selectedItem(); 974 975 975 976 AssertMsgReturn (item, ("Item must be always selected here"), (void) 0); … … 1005 1006 void VBoxSelectorWnd::vmPause (bool aPause) 1006 1007 { 1007 VBoxVM ListBoxItem *item = (VBoxVMListBoxItem *) vmListBox->selectedItem();1008 VBoxVMItem *item = mVMListView->selectedItem(); 1008 1009 1009 1010 AssertMsgReturn (item, ("Item must be always selected here"), (void) 0); … … 1036 1037 void VBoxSelectorWnd::vmRefresh() 1037 1038 { 1038 VBoxVM ListBoxItem *item = (VBoxVMListBoxItem *) vmListBox->selectedItem();1039 VBoxVMItem *item = mVMListView->selectedItem(); 1039 1040 1040 1041 AssertMsgReturn (item, ("Item must be always selected here"), (void) 0); … … 1048 1049 void VBoxSelectorWnd::vmShowLogs() 1049 1050 { 1050 VBoxVM ListBoxItem *item = (VBoxVMListBoxItem *) vmListBox->selectedItem();1051 VBoxVMItem *item = mVMListView->selectedItem(); 1051 1052 CMachine machine = item->machine(); 1052 1053 VBoxVMLogViewer::createLogViewer (machine); … … 1055 1056 void VBoxSelectorWnd::refreshVMList() 1056 1057 { 1057 vmListBox->refresh();1058 vmList BoxCurrentChanged();1058 mVMModel->refresh(); 1059 vmListViewCurrentChanged(); 1059 1060 } 1060 1061 … … 1063 1064 bool aDescription) 1064 1065 { 1065 vmListBox->refresh (aID); 1066 VBoxVMListBoxItem *item = (VBoxVMListBoxItem *) vmListBox->selectedItem(); 1067 if (item && item->id() == aID) 1068 vmListBoxCurrentChanged (aDetails, aSnapshots, aDescription); 1069 } 1070 1071 void VBoxSelectorWnd::showContextMenu (Q3ListBoxItem *aItem, const QPoint &aPoint) 1066 VBoxVMItem *item = mVMModel->itemById (aID); 1067 if (item) 1068 { 1069 mVMModel->refreshItem (item); 1070 if (item && item->id() == aID) 1071 vmListViewCurrentChanged (aDetails, aSnapshots, aDescription); 1072 } 1073 } 1074 1075 void VBoxSelectorWnd::showContextMenu (VBoxVMItem *aItem, const QPoint &aPoint) 1072 1076 { 1073 1077 if (aItem) … … 1131 1135 vmTabWidget->setTabText (vmTabWidget->indexOf (vmDetailsView), tr ("&Details")); 1132 1136 /* note: Snapshots and Details tabs are changed dynamically by 1133 * vmList BoxCurrentChanged() */1137 * vmListViewCurrentChanged() */ 1134 1138 1135 1139 /* ensure the details and screenshot view are updated */ 1136 vmList BoxCurrentChanged();1140 vmListViewCurrentChanged(); 1137 1141 1138 1142 fileDiskMgrAction->setText (tr ("Virtual &Disk Manager...")); … … 1178 1182 vmDeleteAction->setStatusTip (tr ("Delete the selected virtual machine")); 1179 1183 1180 /* Note: vmStartAction text is set up in vmList BoxCurrentChanged() */1184 /* Note: vmStartAction text is set up in vmListViewCurrentChanged() */ 1181 1185 1182 1186 vmDiscardAction->setText (tr ("D&iscard")); … … 1225 1229 ///////////////////////////////////////////////////////////////////////////// 1226 1230 1227 void VBoxSelectorWnd::vmList BoxCurrentChanged (bool aRefreshDetails,1231 void VBoxSelectorWnd::vmListViewCurrentChanged (bool aRefreshDetails, 1228 1232 bool aRefreshSnapshots, 1229 1233 bool aRefreshDescription) 1230 1234 { 1231 if (!vmListBox->selectedItem() && vmListBox->currentItem() >= 0) 1232 { 1233 /* selected always follows current */ 1234 vmListBox->setSelected (vmListBox->currentItem(), true); 1235 } 1236 1237 vmListBox->ensureCurrentVisible(); 1238 VBoxVMListBoxItem *item = (VBoxVMListBoxItem *) vmListBox->selectedItem(); 1235 VBoxVMItem *item = mVMListView->selectedItem(); 1239 1236 1240 1237 if (item && item->accessible()) … … 1395 1392 { 1396 1393 /* refresh the current details to pick up hard disk sizes */ 1397 vmList BoxCurrentChanged (true /* aRefreshDetails */);1394 vmListViewCurrentChanged (true /* aRefreshDetails */); 1398 1395 } 1399 1396 … … 1401 1398 { 1402 1399 /* refresh the current details to pick up hard disk sizes */ 1403 vmList BoxCurrentChanged (true /* aRefreshDetails */);1400 vmListViewCurrentChanged (true /* aRefreshDetails */); 1404 1401 1405 1402 /* we warn about inaccessible media only once (after media emumeration … … 1465 1462 if (!m.isNull()) 1466 1463 { 1467 new VBoxVMListBoxItem (vmListBox, m); 1468 vmListBox->sort(); 1464 mVMModel->addItem (new VBoxVMItem (m)); 1465 mVMModel->sort(); 1466 /* Make sure the description, ... pages are properly updated. 1467 * Actualy we haven't call the next method, but unfortunately Qt 1468 * seems buggy if the new item is on the same position as the 1469 * previous one. So go on the safe side and call this by our self. */ 1470 vmListViewCurrentChanged(); 1469 1471 } 1470 1472 /* m.isNull() is ok (theoretically, the machine could have been … … 1473 1475 else 1474 1476 { 1475 VBoxVM ListBoxItem *item = vmListBox->item(e.id);1477 VBoxVMItem *item = mVMModel->itemById (e.id); 1476 1478 if (item) 1477 vmListBox->removeItem (vmListBox->index (item)); 1479 { 1480 int row = mVMModel->rowById (item->id()); 1481 mVMModel->removeItem (item); 1482 mVMListView->ensureSomeRowSelected (row); 1483 } 1484 1478 1485 /* item = 0 is ok (if we originated this event then the item 1479 1486 * has been already removed) */ -
trunk/src/VBox/Frontends/VirtualBox4/src/VBoxVMListBox.cpp
r8155 r8159 2 2 * 3 3 * VBox frontends: Qt GUI ("VirtualBox"): 4 * VBoxVM ListItemclass implementation4 * VBoxVMItem, VBoxVMModel, VBoxVMListView, VBoxVMItemPainter class implementation 5 5 */ 6 6 7 7 /* 8 * Copyright (C) 2006-200 7Sun Microsystems, Inc.8 * Copyright (C) 2006-2008 Sun Microsystems, Inc. 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 22 22 23 23 #include "VBoxVMListBox.h" 24 25 24 #include "VBoxProblemReporter.h" 26 25 27 #include <qpainter.h> 28 #include <qfontmetrics.h> 29 #include <qdrawutil.h> 30 #include <qtooltip.h> 31 #include <qmetaobject.h> 32 #include <qstyle.h> 33 34 #include <qfileinfo.h> 35 //Added by qt3to4: 36 #include <QPixmap> 37 #include <q3mimefactory.h> 38 #include <QFocusEvent> 26 /* Qt includes */ 27 #include <QPainter> 28 #include <QFileInfo> 39 29 40 30 #if defined (Q_WS_MAC) 41 31 # include <Carbon/Carbon.h> 32 # if MAC_LEOPARD_STYLE 33 # include <qmacstyle_mac.h> 34 # endif /* MAC_LEOPARD_STYLE */ 42 35 #endif 43 36 … … 144 137 #endif 145 138 146 //////////////////////////////////////////////////////////////////////////////// 147 // VBoxVMListBoxItem class 148 //////////////////////////////////////////////////////////////////////////////// 149 150 #warning port me 151 //class VBoxVMListBoxTip : public QToolTip 152 //{ 153 //public: 154 // 155 // VBoxVMListBoxTip (VBoxVMListBox *aLB, QToolTipGroup *aTG = 0) 156 // : QToolTip (aLB, aTG) 157 // {} 158 // 159 // virtual ~VBoxVMListBoxTip() 160 // { 161 // remove (parentWidget()); 162 // } 163 // 164 // void maybeTip (const QPoint &aPnt); 165 //}; 166 // 167 //void VBoxVMListBoxTip::maybeTip (const QPoint &aPnt) 168 //{ 169 // const VBoxVMListBox *lb = static_cast <VBoxVMListBox *> (parentWidget()); 170 // 171 // VBoxVMListBoxItem *vmi = static_cast <VBoxVMListBoxItem *> (lb->itemAt (aPnt)); 172 // if (!vmi) 173 // return; 174 // 175 // if (parentWidget()->topLevelWidget()->inherits ("QMainWindow")) 176 // { 177 // /* 178 // * Ensure the main window doesn't show the text from the previous 179 // * tooltip in the status bar. 180 // */ 181 // QToolTipGroup *toolTipGroup = 182 // (::qt_cast <Q3MainWindow *> (parentWidget()->topLevelWidget()))-> 183 // toolTipGroup(); 184 // if (toolTipGroup) 185 // { 186 // int index = toolTipGroup->metaObject()->findSignal("removeTip()", false); 187 // toolTipGroup->qt_emit (index, 0); 188 // } 189 // } 190 // 191 // tip (lb->itemRect (vmi), vmi->toolTipText()); 192 //} 193 194 //////////////////////////////////////////////////////////////////////////////// 195 // VBoxVMListBox class 196 //////////////////////////////////////////////////////////////////////////////// 197 198 /** 199 * Creates a box with the list of all virtual machines in the 200 * VirtualBox installation. 201 */ 202 VBoxVMListBox:: 203 VBoxVMListBox (QWidget *aParent /* = 0 */, const char *aName /* = NULL */, 204 Qt::WFlags aFlags /* = 0 */) 205 : Q3ListBox (aParent, aName, aFlags) 206 { 207 mVBox = vboxGlobal().virtualBox(); 208 209 mNameFont = QFont (font().family(), font().pointSize() + 1, QFont::Bold); 210 mShotFont = QFont (font().family(), font().pointSize() + 1); 211 mStateBusyFont = font(); 212 mStateBusyFont.setItalic (true); 213 214 mMargin = QMAX (fontMetrics().width (' ') * 2, 8); 215 216 #warning port me 217 // mToolTip = new VBoxVMListBoxTip (this); 218 219 mGaveFocusToPopup = false; 220 221 refresh(); 222 } 223 224 VBoxVMListBox::~VBoxVMListBox() 225 { 226 #warning port me 227 // delete mToolTip; 139 VBoxVMItem::VBoxVMItem (const CMachine &aM) 140 : mMachine (aM) 141 { 142 recache(); 143 } 144 145 VBoxVMItem::~VBoxVMItem() 146 { 228 147 } 229 148 … … 231 150 //////////////////////////////////////////////////////////////////////////////// 232 151 233 /** 234 * Refreshes the box contents by rereading the list of VM's using 235 * the IVirtualBox instance. 236 */ 237 void VBoxVMListBox::refresh() 238 { 239 clear(); 240 241 CMachineVector vec = mVBox.GetMachines2(); 242 for (CMachineVector::ConstIterator m = vec.begin(); 243 m != vec.end(); ++ m) 244 new VBoxVMListBoxItem (this, *m); 245 246 sort(); 247 setCurrentItem (0); 248 } 249 250 /** 251 * Refreshes the item corresponding to the given UUID. 252 */ 253 void VBoxVMListBox::refresh (const QUuid &aID) 254 { 255 for (uint i = 0; i < count(); i++) 256 { 257 VBoxVMListBoxItem *vmi = (VBoxVMListBoxItem *) Q3ListBox::item (i); 258 if (vmi->id() == aID) 259 { 260 vmi->recache(); 261 /* we call triggerUpdate() instead of updateItem() to cause the 262 * layout to be redone for the case when the item width changes */ 263 triggerUpdate (true); 264 break; 265 } 266 } 267 } 268 269 /** 270 * Returns the list item with the given UUID. 271 */ 272 VBoxVMListBoxItem *VBoxVMListBox::item (const QUuid &aID) 273 { 274 for (uint i = 0; i < count(); i++) 275 { 276 VBoxVMListBoxItem *vmi = (VBoxVMListBoxItem *) Q3ListBox::item (i); 277 if (vmi->id() == aID) 278 return vmi; 279 } 280 return 0; 281 } 282 283 /** 284 * Returns the color group QListBox uses to prepare a place for painting 285 * a list box item (for example, to draw the highlighted rectangle of the 286 * currently selected item, etc.). Useful in item's QListBoxItem::paint() 287 * reimplementations to select correct colors that will contrast with the 288 * item rectangle. 289 */ 290 const QColorGroup &VBoxVMListBox::activeColorGroup() const 291 { 292 /* Too bad QListBox doesn't allow to determine what color group it uses 293 * to draw the item's rectangle before calling its paint() method. Not 294 * knowing that, we cannot choose correct colors that will contrast with 295 * that rectangle. So, we have to use the logic of QListBox itself. 296 * Here is a modified extract from qlistbox.cpp: */ 297 298 #warning port me 299 // bool drawActiveSelection = 300 // !style().styleHint (QStyle::SH_ItemView_ChangeHighlightOnFocus, this) || 301 // hasFocus() || 302 // mGaveFocusToPopup; 303 // 304 // return (drawActiveSelection ? colorGroup() : palette().inactive()); 305 return colorGroup(); 306 } 307 308 // protected members 309 //////////////////////////////////////////////////////////////////////////////// 310 311 void VBoxVMListBox::focusInEvent (QFocusEvent *aE) 312 { 313 mGaveFocusToPopup = false; 314 Q3ListBox::focusInEvent (aE); 315 } 316 317 void VBoxVMListBox::focusOutEvent (QFocusEvent *aE) 318 { 319 /* A modified extract from qlistbox.cpp (see #activeColorGroup()): */ 320 mGaveFocusToPopup = 321 #warning port me: check this 322 aE->reason() == QFocusEvent::Popup || 323 // QFocusEvent::reason() == QFocusEvent::Popup || 324 (qApp->focusWidget() && qApp->focusWidget()->inherits ("QMenuBar")); 325 Q3ListBox::focusOutEvent (aE); 326 } 327 328 // private members 329 //////////////////////////////////////////////////////////////////////////////// 330 331 //////////////////////////////////////////////////////////////////////////////// 332 // VBoxVMListBoxItem class 333 //////////////////////////////////////////////////////////////////////////////// 334 335 VBoxVMListBoxItem::VBoxVMListBoxItem (VBoxVMListBox *aLB, const CMachine &aM) 336 : Q3ListBoxItem (aLB), mMachine (aM) 337 { 338 recache(); 339 } 340 341 VBoxVMListBoxItem::~VBoxVMListBoxItem() 342 { 343 } 344 345 // public members 346 //////////////////////////////////////////////////////////////////////////////// 347 348 void VBoxVMListBoxItem::setMachine (const CMachine &aM) 349 { 350 Assert (!aM.isNull()); 351 352 mMachine = aM; 353 recache(); 354 vmListBox()->triggerUpdate (true); 355 } 356 357 void VBoxVMListBoxItem::recache() 358 { 359 bool needsResort = true; 360 361 mId = mMachine.GetId(); 362 mSettingsFile = mMachine.GetSettingsFilePath(); 363 364 mAccessible = mMachine.GetAccessible(); 365 if (mAccessible) 366 { 367 QString name = mMachine.GetName(); 368 CSnapshot snp = mMachine.GetCurrentSnapshot(); 369 mSnapshotName = snp.isNull() ? QString::null : snp.GetName(); 370 needsResort = name != mName; 371 mName = name; 372 373 mState = mMachine.GetState(); 374 mLastStateChange.setTime_t (mMachine.GetLastStateChange() / 1000); 375 mSessionState = mMachine.GetSessionState(); 376 mOSTypeId = mMachine.GetOSTypeId(); 377 mSnapshotCount = mMachine.GetSnapshotCount(); 378 379 if (mState >= KMachineState_Running) 380 { 381 mPid = mMachine.GetSessionPid(); 382 /// @todo Remove. See @c todo in #switchTo() below. 383 #if 0 384 mWinId = FindWindowIdFromPid (mPid); 385 #endif 386 } 387 else 388 { 389 mPid = (ULONG) ~0; 390 /// @todo Remove. See @c todo in #switchTo() below. 391 #if 0 392 mWinId = (WId) ~0; 393 #endif 394 } 395 } 396 else 397 { 398 mAccessError = mMachine.GetAccessError(); 399 400 /* this should be in sync with 401 * VBoxProblemReporter::confirmMachineDeletion() */ 402 QFileInfo fi (mSettingsFile); 403 QString name = fi.extension().lower() == "xml" ? 404 fi.baseName (true) : fi.fileName(); 405 needsResort = name != mName; 406 mName = name; 407 mState = KMachineState_Null; 408 mSessionState = KSessionState_Null; 409 mLastStateChange = QDateTime::currentDateTime(); 410 mOSTypeId = QString::null; 411 mSnapshotCount = 0; 412 413 mPid = (ULONG) ~0; 414 /// @todo Remove. See @c todo in #switchTo() below. 415 #if 0 416 mWinId = (WId) ~0; 417 #endif 418 } 419 420 if (needsResort) 421 vmListBox()->sort(); 422 } 423 424 QString VBoxVMListBoxItem::toolTipText() const 152 QString VBoxVMItem::toolTipText() const 425 153 { 426 154 QString dateTime = (mLastStateChange.date() == QDate::currentDate()) ? … … 435 163 if (!mSnapshotName.isNull()) 436 164 toolTip += QString (" (%1)").arg (mSnapshotName); 437 toolTip = QString ( VBoxVMListBox::tr (165 toolTip = QString (QObject::tr ( 438 166 "<nobr>%1<br></nobr>" 439 167 "<nobr>%2 since %3</nobr><br>" … … 447 175 else 448 176 { 449 toolTip = QString ( VBoxVMListBox::tr (177 toolTip = QString (QObject::tr ( 450 178 "<nobr><b>%1</b><br></nobr>" 451 179 "<nobr>Inaccessible since %2</nobr>", … … 458 186 } 459 187 460 int VBoxVMListBoxItem::width (const Q3ListBox *) const 461 { 462 /* see the picture below for dimensions */ 463 464 const VBoxVMListBox *lb = vmListBox(); 465 466 QFontMetrics fmName = QFontMetrics (lb->nameFont()); 467 QFontMetrics fmShot = QFontMetrics (lb->shotFont()); 468 QFontMetrics fmState = QFontMetrics (lb->stateFont (mSessionState)); 469 const int marg = lb->margin(); 470 471 QPixmap pmOSType; 472 QPixmap pmState; 473 QString strState; 474 188 bool VBoxVMItem::recache() 189 { 190 bool needsResort = true; 191 192 mId = mMachine.GetId(); 193 mSettingsFile = mMachine.GetSettingsFilePath(); 194 195 mAccessible = mMachine.GetAccessible(); 475 196 if (mAccessible) 476 197 { 477 pmOSType = vboxGlobal().vmGuestOSTypeIcon (mOSTypeId); 478 pmState = vboxGlobal().toIcon (mState); 479 strState = vboxGlobal().toString (mState); 198 QString name = mMachine.GetName(); 199 CSnapshot snp = mMachine.GetCurrentSnapshot(); 200 mSnapshotName = snp.isNull() ? QString::null : snp.GetName(); 201 needsResort = name != mName; 202 mName = name; 203 204 mState = mMachine.GetState(); 205 mLastStateChange.setTime_t (mMachine.GetLastStateChange() / 1000); 206 mSessionState = mMachine.GetSessionState(); 207 mOSTypeId = mMachine.GetOSTypeId(); 208 mSnapshotCount = mMachine.GetSnapshotCount(); 209 210 if (mState >= KMachineState_Running) 211 { 212 mPid = mMachine.GetSessionPid(); 213 /// @todo Remove. See @c todo in #switchTo() below. 214 #if 0 215 mWinId = FindWindowIdFromPid (mPid); 216 #endif 217 } 218 else 219 { 220 mPid = (ULONG) ~0; 221 /// @todo Remove. See @c todo in #switchTo() below. 222 #if 0 223 mWinId = (WId) ~0; 224 #endif 225 } 480 226 } 481 227 else 482 228 { 483 /// @todo (r=dmik) temporary 484 pmOSType = QPixmap (":/os_unknown.png"); 485 pmState = QPixmap (":/state_aborted_16px.png"); 486 strState = VBoxVMListBox::tr ("Inaccessible"); 487 } 488 489 int nameWidth = fmName.width (mName); 490 if (!mSnapshotName.isNull()) 491 nameWidth += fmShot.width (QString (" (%1)").arg (mSnapshotName)); 492 int stateWidth = pmState.width() + fmState.width (' ') + 493 fmState.width (strState); 494 495 return marg + pmOSType.width() + marg * 3 / 2 + 496 QMAX (nameWidth, stateWidth) + marg; 497 } 498 499 int VBoxVMListBoxItem::height (const Q3ListBox *) const 500 { 501 /* see the picture below for dimensions */ 502 503 const VBoxVMListBox *lb = vmListBox(); 504 505 QFontMetrics fmName = QFontMetrics (lb->nameFont()); 506 QFontMetrics fmState = QFontMetrics (lb->stateFont (mSessionState)); 507 const int marg = lb->margin(); 508 509 QPixmap pmOSType; 510 QPixmap pmState; 511 512 if (mAccessible) 513 { 514 pmOSType = vboxGlobal().vmGuestOSTypeIcon (mOSTypeId); 515 pmState = vboxGlobal().toIcon (mState); 516 } 517 else 518 { 519 /// @todo (r=dmik) temporary 520 pmOSType = QPixmap (":/os_unknown.png"); 521 pmState = QPixmap (":/state_aborted_16px.png"); 522 } 523 524 int strHeight = fmName.lineSpacing() + 525 QMAX (pmState.height(), fmState.height()); 526 527 return marg + QMAX (pmOSType.height(), strHeight) + marg; 229 mAccessError = mMachine.GetAccessError(); 230 231 /* this should be in sync with 232 * VBoxProblemReporter::confirmMachineDeletion() */ 233 QFileInfo fi (mSettingsFile); 234 QString name = fi.completeSuffix().toLower() == "xml" ? 235 fi.completeBaseName() : fi.fileName(); 236 needsResort = name != mName; 237 mName = name; 238 mState = KMachineState_Null; 239 mSessionState = KSessionState_Null; 240 mLastStateChange = QDateTime::currentDateTime(); 241 mOSTypeId = QString::null; 242 mSnapshotCount = 0; 243 244 mPid = (ULONG) ~0; 245 /// @todo Remove. See @c todo in #switchTo() below. 246 #if 0 247 mWinId = (WId) ~0; 248 #endif 249 } 250 251 return needsResort; 528 252 } 529 253 … … 532 256 * foreground, and @a false otherwise. 533 257 */ 534 bool VBoxVM ListBoxItem::canSwitchTo() const258 bool VBoxVMItem::canSwitchTo() const 535 259 { 536 260 return const_cast <CMachine &> (mMachine).CanShowConsoleWindow(); … … 547 271 * @return true if successfully switched and false otherwise. 548 272 */ 549 bool VBoxVM ListBoxItem::switchTo()273 bool VBoxVMItem::switchTo() 550 274 { 551 275 #ifdef Q_WS_MAC … … 659 383 } 660 384 661 // protected members 662 //////////////////////////////////////////////////////////////////////////////// 663 385 /* VBoxVMModel class */ 386 387 void VBoxVMModel::addItem (VBoxVMItem *aItem) 388 { 389 Assert (aItem); 390 int row = mVMItemList.count(); 391 emit layoutAboutToBeChanged(); 392 beginInsertRows (QModelIndex(), row, row); 393 mVMItemList << aItem; 394 endInsertRows(); 395 refreshItem (aItem); 396 } 397 398 void VBoxVMModel::removeItem (VBoxVMItem *aItem) 399 { 400 Assert (aItem); 401 int row = mVMItemList.indexOf (aItem); 402 removeRows (row, 1); 403 } 404 405 bool VBoxVMModel::removeRows (int aRow, int aCount, const QModelIndex &aParent /* = QModelIndex() */) 406 { 407 emit layoutAboutToBeChanged(); 408 beginRemoveRows (aParent, aRow, aRow + aCount); 409 mVMItemList.erase (mVMItemList.begin() + aRow, mVMItemList.begin() + aRow + aCount); 410 endRemoveRows(); 411 emit layoutChanged(); 412 return true; 413 } 414 415 /** 416 * Refreshes the item corresponding to the given UUID. 417 */ 418 void VBoxVMModel::refreshItem (VBoxVMItem *aItem) 419 { 420 Assert (aItem); 421 if (aItem->recache()) 422 sort(); 423 itemChanged (aItem); 424 } 425 426 void VBoxVMModel::itemChanged (VBoxVMItem *aItem) 427 { 428 Assert (aItem); 429 int row = mVMItemList.indexOf (aItem); 430 /* Emit an layout change signal for the case some dimensions of the item 431 * has changed also. */ 432 emit layoutChanged(); 433 /* Emit an data changed signal. */ 434 emit dataChanged (index (row), index (row)); 435 } 436 437 /** 438 * Refreshes the model contents by rereading the list of VM's using the 439 * IVirtualBox instance. 440 */ 441 void VBoxVMModel::refresh() 442 { 443 CVirtualBox vbox = vboxGlobal().virtualBox(); 444 CMachineVector vec = vbox.GetMachines2(); 445 for (CMachineVector::ConstIterator m = vec.begin(); 446 m != vec.end(); ++ m) 447 addItem(new VBoxVMItem (*m)); 448 449 sort(); 450 } 451 452 /** 453 * Returns the list item with the given UUID. 454 */ 455 VBoxVMItem *VBoxVMModel::itemById (const QUuid &aId) const 456 { 457 foreach (VBoxVMItem *item, mVMItemList) 458 if (item->id() == aId) 459 return item; 460 return NULL; 461 } 462 463 QModelIndex VBoxVMModel::indexById (const QUuid &aId) const 464 { 465 int row = rowById (aId); 466 if (row >= 0) 467 return index (row); 468 else 469 return QModelIndex(); 470 } 471 472 int VBoxVMModel::rowById (const QUuid &aId) const 473 { 474 for (int i=0; i < mVMItemList.count(); ++i) 475 { 476 VBoxVMItem *item = mVMItemList.at (i); 477 if (item->id() == aId) 478 return i; 479 } 480 return -1; 481 } 482 483 void VBoxVMModel::sort (int /* aColumn */, Qt::SortOrder aOrder /* = Qt::AscendingOrder */) 484 { 485 emit layoutAboutToBeChanged(); 486 switch (aOrder) 487 { 488 case Qt::AscendingOrder: qSort (mVMItemList.begin(), mVMItemList.end(), VBoxVMItemNameCompareLessThan); break; 489 case Qt::DescendingOrder: qSort (mVMItemList.begin(), mVMItemList.end(), VBoxVMItemNameCompareGreaterThan); break; 490 } 491 emit layoutChanged(); 492 } 493 494 int VBoxVMModel::rowCount(const QModelIndex & /* aParent = QModelIndex() */) const 495 { 496 return mVMItemList.count(); 497 } 498 499 QVariant VBoxVMModel::data(const QModelIndex &aIndex, int aRole) const 500 { 501 if (!aIndex.isValid()) 502 return QVariant(); 503 504 if (aIndex.row() >= mVMItemList.size()) 505 return QVariant(); 506 507 QVariant v; 508 switch (aRole) 509 { 510 case Qt::DisplayRole: 511 { 512 v = mVMItemList.at (aIndex.row())->name(); 513 break; 514 } 515 case Qt::DecorationRole: 516 { 517 v = mVMItemList.at (aIndex.row())->osIcon(); 518 break; 519 } 520 case Qt::ToolTipRole: 521 { 522 v = mVMItemList.at (aIndex.row())->toolTipText(); 523 break; 524 } 525 case Qt::FontRole: 526 { 527 QFont f = qApp->font(); 528 f.setPointSize (f.pointSize() + 1); 529 f.setWeight (QFont::Bold); 530 v = f; 531 break; 532 } 533 case SnapShotDisplayRole: 534 { 535 v = mVMItemList.at (aIndex.row())->snapshotName(); 536 break; 537 } 538 case SnapShotFontRole: 539 { 540 QFont f = qApp->font(); 541 v = f; 542 break; 543 } 544 case SessionStateDisplayRole: 545 { 546 v = mVMItemList.at (aIndex.row())->sessionStateName(); 547 break; 548 } 549 case SessionStateDecorationRole: 550 { 551 v = mVMItemList.at (aIndex.row())->sessionStateIcon(); 552 break; 553 } 554 case SessionStateFontRole: 555 { 556 QFont f = qApp->font(); 557 f.setPointSize (f.pointSize()); 558 if (mVMItemList.at (aIndex.row())->sessionState() != KSessionState_Closed) 559 f.setItalic (true); 560 v = f; 561 break; 562 } 563 case VBoxVMItemPtrRole: 564 { 565 v = qVariantFromValue (mVMItemList.at (aIndex.row())); 566 } 567 } 568 return v; 569 } 570 571 QVariant VBoxVMModel::headerData(int aSection, Qt::Orientation aOrientation, 572 int aRole /* = Qt::DisplayRole */) const 573 { 574 if (aRole != Qt::DisplayRole) 575 return QVariant(); 576 577 if (aOrientation == Qt::Horizontal) 578 return QString (tr ("VM")); 579 else 580 return QString ("%1").arg (aSection); 581 } 582 583 bool VBoxVMModel::VBoxVMItemNameCompareLessThan (VBoxVMItem* aItem1, VBoxVMItem* aItem2) 584 { 585 Assert (aItem1); 586 Assert (aItem2); 587 return aItem1->name().toLower() < aItem2->name().toLower(); 588 } 589 590 bool VBoxVMModel::VBoxVMItemNameCompareGreaterThan (VBoxVMItem* aItem1, VBoxVMItem* aItem2) 591 { 592 Assert (aItem1); 593 Assert (aItem2); 594 return aItem2->name().toLower() < aItem1->name().toLower(); 595 } 596 597 /* VBoxVMListBox class */ 598 599 VBoxVMListView::VBoxVMListView (QWidget *aParent /* = 0 */) 600 :QListView (aParent) 601 { 602 /* Create & set our delegation class */ 603 VBoxVMItemPainter *delegate = new VBoxVMItemPainter(this); 604 setItemDelegate(delegate); 605 /* Default icon size */ 606 setIconSize (QSize (32, 32)); 607 /* Publish the activation of items */ 608 connect (this, SIGNAL (activated (const QModelIndex &)), 609 this, SIGNAL (activated ())); 610 /* Track if the application lost the focus */ 611 #if MAC_LEOPARD_STYLE 612 connect (QCoreApplication::instance(), SIGNAL (focusChanged (QWidget *, QWidget *)), 613 this, SLOT (focusChanged (QWidget *, QWidget *))); 614 /* 1 pixel line frame */ 615 setMidLineWidth (1); 616 setLineWidth (0); 617 setFrameShape (QFrame::Box); 618 focusChanged (NULL, this); 619 /* Nesty hack to disable the focus rect on the list view. This interface 620 * may change at any time! */ 621 static_cast<QMacStyle *> (style())->setFocusRectPolicy (this, QMacStyle::FocusDisabled); 622 #endif /* MAC_LEOPARD_STYLE */ 623 } 624 625 void VBoxVMListView::selectItemByRow (int row) 626 { 627 setCurrentIndex (model()->index (row, 0)); 628 } 629 630 void VBoxVMListView::selectItemById (const QUuid &aID) 631 { 632 if (VBoxVMModel *m = qobject_cast<VBoxVMModel*> (model())) 633 { 634 QModelIndex i = m->indexById (aID); 635 if (i.isValid()) 636 setCurrentIndex (i); 637 } 638 } 639 640 void VBoxVMListView::ensureSomeRowSelected (int aRowHint) 641 { 642 VBoxVMItem *item = selectedItem(); 643 if(!item) 644 { 645 aRowHint = qBound (0, aRowHint, model()->rowCount() - 1); 646 selectItemByRow (aRowHint); 647 item = selectedItem (); 648 if (!item) 649 selectItemByRow (0); 650 } 651 } 652 653 VBoxVMItem * VBoxVMListView::selectedItem() const 654 { 655 QModelIndexList indexes = selectedIndexes(); 656 if (indexes.isEmpty()) 657 return NULL; 658 return model()->data (indexes.first(), VBoxVMModel::VBoxVMItemPtrRole).value<VBoxVMItem *>(); 659 } 660 661 void VBoxVMListView::ensureCurrentVisible() 662 { 663 scrollTo (currentIndex(), QAbstractItemView::EnsureVisible); 664 } 665 666 void VBoxVMListView::selectionChanged (const QItemSelection &aSelected, const QItemSelection &aDeselected) 667 { 668 QListView::selectionChanged (aSelected, aDeselected); 669 selectCurrent(); 670 ensureCurrentVisible(); 671 emit currentChanged(); 672 } 673 674 void VBoxVMListView::currentChanged (const QModelIndex &aCurrent, const QModelIndex &aPrevious) 675 { 676 QListView::currentChanged (aCurrent, aPrevious); 677 selectCurrent(); 678 ensureCurrentVisible(); 679 emit currentChanged(); 680 } 681 682 void VBoxVMListView::dataChanged (const QModelIndex &aTopLeft, const QModelIndex &aBottomRight) 683 { 684 QListView::dataChanged (aTopLeft, aBottomRight); 685 selectCurrent(); 686 ensureCurrentVisible(); 687 emit currentChanged(); 688 } 689 690 void VBoxVMListView::focusChanged (QWidget * /* aOld */, QWidget *aNow) 691 { 692 #if MAC_LEOPARD_STYLE 693 QColor bgColor (212, 221, 229); 694 if (aNow == NULL) 695 bgColor.setRgb (232, 232, 232); 696 QPalette pal = viewport()->palette(); 697 pal.setColor (QPalette::Base, bgColor); 698 viewport()->setPalette (pal); 699 viewport()->setAutoFillBackground (true); 700 #else /* MAC_LEOPARD_STYLE */ 701 NOREF (aNow); 702 #endif /* MAC_LEOPARD_STYLE */ 703 } 704 705 void VBoxVMListView::mousePressEvent (QMouseEvent *aEvent) 706 { 707 /* First process event, in the case the user select a new item */ 708 QListView::mousePressEvent (aEvent); 709 if (aEvent->button() == Qt::RightButton) 710 { 711 /* Send a context menu request if necessary */ 712 const QModelIndex &index = indexAt (aEvent->pos()); 713 if (index.isValid()) 714 { 715 VBoxVMItem *item = model()->data (index, VBoxVMModel::VBoxVMItemPtrRole).value<VBoxVMItem *>(); 716 emit contextMenuRequested (item, aEvent->globalPos()); 717 } 718 } 719 } 720 721 bool VBoxVMListView::selectCurrent() 722 { 723 QModelIndexList indexes = selectionModel()->selectedIndexes(); 724 if (indexes.isEmpty() || 725 indexes.first() != currentIndex()) 726 { 727 /* Make sure that the current is always selected */ 728 selectionModel()->select (currentIndex(), QItemSelectionModel::Current | QItemSelectionModel::ClearAndSelect); 729 return true; 730 } 731 return false; 732 } 733 734 /* VBoxVMItemPainter class */ 664 735 /* 665 736 +----------------------------------------------+ … … 678 749 */ 679 750 680 void VBoxVMListBoxItem::paint (QPainter *aP) 681 { 682 const VBoxVMListBox *lb = vmListBox(); 683 684 QFontMetrics fmName = QFontMetrics (lb->nameFont()); 685 QFontMetrics fmShot = QFontMetrics (lb->shotFont()); 686 QFontMetrics fmState = QFontMetrics (lb->stateFont (mSessionState)); 687 const int marg = lb->margin(); 688 689 QPixmap pmOSType; 690 QPixmap pmState; 691 QString strState; 692 693 if (mAccessible) 694 { 695 pmOSType = vboxGlobal().vmGuestOSTypeIcon (mOSTypeId); 696 pmState = vboxGlobal().toIcon (mState); 697 strState = vboxGlobal().toString (mState); 698 } 699 else 700 { 701 /// @todo (r=dmik) temporary 702 pmOSType = QPixmap (":/os_unknown.png"); 703 pmState = QPixmap (":/state_aborted_16px.png"); 704 strState = VBoxVMListBox::tr ("Inaccessible"); 705 } 706 707 const QPalette &pal = lb->palette(); 708 709 int osTypeY = marg; 710 int strHeight = fmName.lineSpacing() + 711 QMAX (pmState.height(), fmState.height()); 712 if (strHeight > pmOSType.height()) 713 osTypeY += (strHeight - pmOSType.height()) / 2; 714 715 /* draw the OS type icon with border, vertically centered */ 716 aP->drawPixmap (marg, osTypeY, pmOSType); 717 718 aP->setPen (isSelected() ? 719 pal.color (QPalette::Active, QPalette::HighlightedText) : 720 pal.color (QPalette::Active, QPalette::Text)); 721 722 int textX = marg + pmOSType.width() + marg * 3 / 2; 723 724 /* draw the VM name */ 725 aP->setFont (lb->nameFont()); 726 aP->drawText (textX, marg + fmName.ascent(), mName); 727 728 if (!mSnapshotName.isNull()) 729 { 730 int nameWidth = fmName.width (mName); 731 aP->setFont (lb->shotFont()); 732 QString shotName = QString (" (%1)").arg (mSnapshotName); 733 aP->drawText (textX + nameWidth, marg + fmName.ascent(), shotName); 734 } 735 736 int stateY = marg + fmName.lineSpacing(); 737 int stateH = QMAX (pmState.height(), fmState.height()); 738 739 /* draw the VM state icon */ 740 aP->drawPixmap (textX, stateY + (stateH - pmState.height()) / 2, 741 pmState); 742 743 /* draw the VM state text */ 744 aP->setFont (lb->stateFont (mSessionState)); 745 aP->drawText (textX + pmState.width() + fmState.width(' '), 746 stateY + (stateH - fmState.height()) / 2 + fmState.ascent(), 747 strState); 748 } 751 /* Little helper class for layout calculation */ 752 class QRectList: public QList<QRect *> 753 { 754 public: 755 void alignVCenterTo (QRect* aWhich) 756 { 757 QRect b; 758 foreach (QRect *rect, *this) 759 if(rect != aWhich) 760 b |= *rect; 761 if (b.width() > aWhich->width()) 762 aWhich->moveCenter (QPoint (aWhich->center().x(), b.center().y())); 763 else 764 { 765 foreach (QRect *rect, *this) 766 if(rect != aWhich) 767 rect->moveCenter (QPoint (rect->center().x(), aWhich->center().y())); 768 } 769 } 770 }; 771 772 QSize VBoxVMItemPainter::sizeHint (const QStyleOptionViewItem &aOption, 773 const QModelIndex &aIndex) const 774 { 775 /* Get the size of every item */ 776 QRect osTypeRT = rect (aOption, aIndex, Qt::DecorationRole); 777 QRect vmNameRT = rect (aOption, aIndex, Qt::DisplayRole); 778 QRect shotRT = rect (aOption, aIndex, VBoxVMModel::SnapShotDisplayRole); 779 QRect stateIconRT = rect (aOption, aIndex, VBoxVMModel::SessionStateDecorationRole); 780 QRect stateRT = rect (aOption, aIndex, VBoxVMModel::SessionStateDisplayRole); 781 /* Calculate the position for every item */ 782 calcLayout (aIndex, &osTypeRT, &vmNameRT, &shotRT, &stateIconRT, &stateRT); 783 /* Calc the bounding rect */ 784 const QRect boundingRect = osTypeRT | vmNameRT | shotRT | stateIconRT | stateRT; 785 /* Return + left/top/right/bottom margin */ 786 return (boundingRect.size() + QSize (2 * mMargin, 2 * mMargin)); 787 } 788 789 void VBoxVMItemPainter::paint (QPainter *aPainter, const QStyleOptionViewItem &aOption, 790 const QModelIndex &aIndex) const 791 { 792 // Name and decoration 793 const QString vmName = aIndex.data(Qt::DisplayRole).toString(); 794 const QFont nameFont = aIndex.data (Qt::FontRole).value<QFont>(); 795 const QPixmap osType = aIndex.data(Qt::DecorationRole).value<QIcon>().pixmap (aOption.decorationSize, iconMode (aOption.state), iconState (aOption.state)); 796 797 const QString shot = aIndex.data(VBoxVMModel::SnapShotDisplayRole).toString(); 798 const QFont shotFont = aIndex.data (VBoxVMModel::SnapShotFontRole).value<QFont>(); 799 800 const QString state = aIndex.data(VBoxVMModel::SessionStateDisplayRole).toString(); 801 const QFont stateFont = aIndex.data (VBoxVMModel::SessionStateFontRole).value<QFont>(); 802 const QPixmap stateIcon = aIndex.data(VBoxVMModel::SessionStateDecorationRole).value<QIcon>().pixmap (QSize (16, 16), iconMode (aOption.state), iconState (aOption.state)); 803 804 /* Get the sizes for all items */ 805 QRect osTypeRT = rect (aOption, aIndex, Qt::DecorationRole); 806 QRect vmNameRT = rect (aOption, aIndex, Qt::DisplayRole); 807 QRect shotRT = rect (aOption, aIndex, VBoxVMModel::SnapShotDisplayRole); 808 QRect stateIconRT = rect (aOption, aIndex, VBoxVMModel::SessionStateDecorationRole); 809 QRect stateRT = rect (aOption, aIndex, VBoxVMModel::SessionStateDisplayRole); 810 811 /* Calculate the positions for all items */ 812 calcLayout (aIndex, &osTypeRT, &vmNameRT, &shotRT, &stateIconRT, &stateRT); 813 814 /* Get the appropiate pen for the current state */ 815 QPalette pal = aOption.palette; 816 QPen pen = pal.color (QPalette::Active, QPalette::Text); 817 if (aOption.state & QStyle::State_Selected) 818 pen = pal.color (QPalette::Active, QPalette::HighlightedText); 819 /* Start drawing */ 820 drawBackground (aPainter, aOption, aIndex); 821 aPainter->save(); 822 /* Set the current pen */ 823 aPainter->setPen (pen); 824 /* Move the painter to the initial position */ 825 aPainter->translate (aOption.rect.x(), aOption.rect.y()); 826 /* os type icon */ 827 aPainter->drawPixmap (osTypeRT, osType); 828 /* vm name */ 829 aPainter->setFont (nameFont); 830 aPainter->drawText (vmNameRT, vmName); 831 /* current snapshot in braces */ 832 if (!shot.isEmpty()) 833 { 834 aPainter->setFont (shotFont); 835 aPainter->drawText (shotRT, QString ("(%1)").arg (shot)); 836 } 837 /* state icon */ 838 aPainter->drawPixmap (stateIconRT, stateIcon); 839 /* textual state */ 840 aPainter->setFont (stateFont); 841 aPainter->drawText (stateRT, state); 842 /* For debugging */ 843 // QRect boundingRect = osTypeRT | vmNameRT | shotRT | stateIconRT | stateRT; 844 // aPainter->drawRect (boundingRect); 845 aPainter->restore(); 846 drawFocus(aPainter, aOption, aOption.rect); 847 } 848 849 void VBoxVMItemPainter::drawBackground (QPainter *aPainter, const QStyleOptionViewItem &aOption, 850 const QModelIndex &aIndex) const 851 { 852 #if MAC_LEOPARD_STYLE 853 NOREF (aIndex); 854 /* Macify for Leopard */ 855 if (aOption.state & QStyle::State_Selected) 856 { 857 /* Standard color for selected items and focus on the widget */ 858 QColor topLineColor (69, 128, 200); 859 QColor topGradColor (92, 147, 214); 860 QColor bottomGradColor (21, 83, 169); 861 /* Color for selected items and no focus on the widget */ 862 if (QWidget *p = qobject_cast<QWidget *> (parent())) 863 if (!p->hasFocus()) 864 { 865 topLineColor.setRgb (145, 160, 192); 866 topGradColor.setRgb (162, 177, 207); 867 bottomGradColor.setRgb (110, 129, 169); 868 } 869 /* Color for selected items and no focus on the application at all */ 870 if (qApp->focusWidget() == NULL) 871 { 872 topLineColor.setRgb (151, 151, 151); 873 topGradColor.setRgb (180, 180, 180); 874 bottomGradColor.setRgb (137, 137, 137); 875 } 876 /* Paint the background */ 877 QRect r = aOption.rect; 878 r.setTop (r.top() + 1); 879 QLinearGradient linearGrad (QPointF(0, r.top()), QPointF(0, r.bottom())); 880 linearGrad.setColorAt (0, topGradColor); 881 linearGrad.setColorAt (1, bottomGradColor); 882 aPainter->setPen (topLineColor); 883 aPainter->drawLine (r.left(), r.top() - 1, r.right(), r.top() - 1); 884 aPainter->fillRect (r, linearGrad); 885 } 886 #else /* MAC_LEOPARD_STYLE */ 887 QItemDelegate::drawBackground (aPainter, aOption, aIndex); 888 #endif /* MAC_LEOPARD_STYLE */ 889 } 890 891 QRect VBoxVMItemPainter::rect (const QStyleOptionViewItem &aOption, 892 const QModelIndex &aIndex, int aRole) const 893 { 894 switch (aRole) 895 { 896 case Qt::DisplayRole: 897 { 898 QString text = aIndex.data (Qt::DisplayRole).toString(); 899 QFontMetrics fm (fontMetric (aIndex, Qt::FontRole)); 900 return QRect (QPoint (0, 0), fm.size (0, text)); 901 break; 902 } 903 case Qt::DecorationRole: 904 { 905 QIcon icon = aIndex.data (Qt::DecorationRole).value<QIcon>(); 906 return QRect (QPoint (0, 0), icon.actualSize (aOption.decorationSize, iconMode (aOption.state), iconState (aOption.state))); 907 break; 908 } 909 case VBoxVMModel::SnapShotDisplayRole: 910 { 911 QString text = aIndex.data (VBoxVMModel::SnapShotDisplayRole).toString(); 912 if (!text.isEmpty()) 913 { 914 QFontMetrics fm (fontMetric (aIndex, VBoxVMModel::SnapShotFontRole)); 915 return QRect (QPoint (0, 0), fm.size (0, QString ("(%1)").arg (text))); 916 }else 917 return QRect(); 918 break; 919 } 920 case VBoxVMModel::SessionStateDisplayRole: 921 { 922 QString text = aIndex.data (VBoxVMModel::SessionStateDisplayRole).toString(); 923 QFontMetrics fm (fontMetric (aIndex, VBoxVMModel::SessionStateFontRole)); 924 return QRect (QPoint (0, 0), fm.size (0, text)); 925 break; 926 } 927 case VBoxVMModel::SessionStateDecorationRole: 928 { 929 QIcon icon = aIndex.data (VBoxVMModel::SessionStateDecorationRole).value<QIcon>(); 930 return QRect (QPoint (0, 0), icon.actualSize (QSize (16, 16), iconMode (aOption.state), iconState (aOption.state))); 931 break; 932 } 933 } 934 return QRect(); 935 } 936 937 void VBoxVMItemPainter::calcLayout (const QModelIndex &aIndex, 938 QRect *aOSType, QRect *aVMName, QRect *aShot, 939 QRect *aStateIcon, QRect *aState) const 940 { 941 const int nameSpaceWidth = fontMetric (aIndex, Qt::FontRole).width (' '); 942 const int stateSpaceWidth = fontMetric (aIndex, VBoxVMModel::SessionStateFontRole).width (' '); 943 /* Really basic layout managment. 944 * First layout as usual */ 945 aOSType->moveTo (mMargin, mMargin); 946 aVMName->moveTo (mMargin + aOSType->width() + mSpacing, mMargin); 947 aShot->moveTo (aVMName->right() + nameSpaceWidth, aVMName->top()); 948 aStateIcon->moveTo (aVMName->left(), aVMName->bottom()); 949 aState->moveTo (aStateIcon->right() + stateSpaceWidth, aStateIcon->top()); 950 /* Do grouping for the automatic center routine. 951 * First the states group: */ 952 QRectList statesLayout; 953 statesLayout << aStateIcon << aState; 954 /* All items in the layout: */ 955 QRectList allLayout; 956 allLayout << aOSType << aVMName << aShot << statesLayout; 957 /* Now verticaly center the items based on the reference item */ 958 statesLayout.alignVCenterTo (aStateIcon); 959 allLayout.alignVCenterTo (aOSType); 960 } 961
Note:
See TracChangeset
for help on using the changeset viewer.