VirtualBox

Ignore:
Timestamp:
Mar 13, 2007 8:41:45 PM (18 years ago)
Author:
vboxsync
Message:

Boot items table implemented through QListView class.
This table allows:

  1. to select desired boot devices (by selecting check-boxes near the every device item with mouse or by pressing <space> hot-key).
  2. to select desired boot sequence for selected devices (by mouse clicking on related up/down buttons or by pressing <ctrl-up/ctrl-down> hot-keys).
  3. to navigate through boot-devises list (by mouse or by pressing <up/down> hot-keys).

P.S. Up/Down tool-buttons icons are set to usb up/down (there are no required icons yet).

Location:
trunk/src/VBox/Frontends/VirtualBox/ui
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/ui/VBoxVMSettingsDlg.ui

    r1289 r1455  
    11351135                                            <hsizetype>7</hsizetype>
    11361136                                            <vsizetype>5</vsizetype>
    1137                                             <horstretch>1</horstretch>
     1137                                            <horstretch>0</horstretch>
    11381138                                            <verstretch>0</verstretch>
    11391139                                        </sizepolicy>
     
    26252625    <include location="global" impldecl="in implementation">qtimer.h</include>
    26262626    <include location="global" impldecl="in implementation">qpopupmenu.h</include>
    2627     <include location="global" impldecl="in implementation">qtable.h</include>
     2627    <include location="global" impldecl="in implementation">qlistview.h</include>
    26282628    <include location="local" impldecl="in declaration">COMDefs.h</include>
    26292629    <include location="local" impldecl="in declaration">QIWidgetValidator.h</include>
     
    26432643    <forward>class VBoxSharedFoldersSettings</forward>
    26442644    <forward>class QIRichLabel</forward>
    2645     <forward>class BootItemsTable</forward>
     2645    <forward>class BootItemsList</forward>
    26462646</forwards>
    26472647<variables>
     
    26772677    <variable access="private">VBoxUSBMenu *usbDevicesMenu;</variable>
    26782678    <variable access="private">QIRichLabel *whatsThisLabel;</variable>
    2679     <variable access="private">BootItemsTable *tblBootOrder;</variable>
     2679    <variable access="private">BootItemsList *tblBootOrder;</variable>
    26802680</variables>
    26812681<slots>
  • trunk/src/VBox/Frontends/VirtualBox/ui/VBoxVMSettingsDlg.ui.h

    r1371 r1455  
    5353
    5454/**
    55  *  Class: BootItemsTable.
    56  *  QTable class reimplementation to use as boot items table.
    57  *  It handles "focus-in" situation creating combo-box for focused item.
    58  *  It also presents wrappers for some hidden functionality.
     55 *  QListView class reimplementation to use as boot items table.
     56 *  It has one unsorted column without header with automated width
     57 *  resize management.
     58 *  Keymapping handlers for ctrl-up & ctrl-down are translated into
     59 *  boot-items up/down moving.
    5960 */
    60 class BootItemsTable : public QTable
     61class BootItemsTable : public QListView
    6162{
    6263    Q_OBJECT
     
    6566
    6667    BootItemsTable (QWidget *aParent, const char *aName)
    67         : QTable (aParent, aName) {}
     68        : QListView (aParent, aName)
     69    {
     70        addColumn (QString::null);
     71        header()->hide();
     72        setSorting (-1);
     73        setColumnWidthMode (0, Maximum);
     74        setResizeMode (AllColumns);
     75        QWhatsThis::add (this, tr ("Defines the boot device order. "
     76                                   "Click on the checkbox to select which "
     77                                   "devices will be used. Move desired boot "
     78                                   "devices up/down to define boot sequence."));
     79        setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred);
     80        connect (this, SIGNAL (pressed (QListViewItem*)),
     81                 this, SLOT (processPressed (QListViewItem*)));
     82    }
     83
    6884    ~BootItemsTable() {}
    6985
    70     void endEdit (int aRow, int aCol)
    71     {
    72         QTable::endEdit (aRow, aCol, true, false);
    73     }
    74 
    75 protected:
    76 
    77     void focusInEvent (QFocusEvent *)
    78     {
    79         int row = currentRow() >= 0 ? currentRow() : 0;
    80         setCurrentCell (row, 0);
    81         editCell (row, 0);
     86signals:
     87
     88    void moveItemUp();
     89    void moveItemDown();
     90
     91private slots:
     92
     93    void processPressed (QListViewItem *aItem)
     94    {
     95        if (!aItem)
     96            setSelected (currentItem(), true);
     97    }
     98
     99    void keyPressEvent (QKeyEvent *aEvent)
     100    {
     101        if (aEvent->state() == Qt::ControlButton)
     102        {
     103            switch (aEvent->key())
     104            {
     105                case Qt::Key_Up:
     106                    emit moveItemUp();
     107                    return;
     108                case Qt::Key_Down:
     109                    emit moveItemDown();
     110                    return;
     111                default:
     112                    break;
     113            }
     114        }
     115        QListView::keyPressEvent (aEvent);
    82116    }
    83117};
     
    85119
    86120/**
    87  *  Class: BootComboBox.
    88  *  QComboBox class reimplementation to use as boot item's editor.
    89  *  This class handles tab/backtab keypress events for boot item re-focusing.
    90  *  It also handles "focus-lost" situation for combo-box control destroying
    91  *  it after focus leaving from the combo-box.
     121 *  QWidget class reimplementation to use as boot items widget.
     122 *  It contains BootItemsTable and two tool-buttons for moving
     123 *  boot-items up/down.
     124 *  This widget handles saving/loading CMachine information related
     125 *  to boot sequience.
    92126 */
    93 class BootComboBox : public QComboBox
    94 {
     127class BootItemsList : public QWidget
     128{
     129    Q_OBJECT
     130
    95131public:
    96132
    97     BootComboBox (QWidget *aParent, QTable *aTable)
    98         : QComboBox (aParent), mParent (0)
    99     {
    100         Assert (aTable->inherits ("BootItemsTable"));
    101         mParent = static_cast<BootItemsTable*> (aTable);
    102     }
    103     ~BootComboBox() {}
    104 
    105 protected:
    106 
    107     void focusOutEvent (QFocusEvent *)
    108     {
    109         if (!listBox()->hasFocus())
    110         {
    111             mParent->endEdit (mParent->currentRow(), mParent->currentColumn());
    112             mParent->clearFocus();
    113         }
    114     }
    115 
    116     bool event (QEvent *aEvent)
    117     {
    118         if (aEvent->type() == QEvent::KeyPress)
    119         {
    120             QKeyEvent *event = static_cast<QKeyEvent*> (aEvent);
    121             switch (event->key())
     133    BootItemsList (QWidget *aParent, const char *aName)
     134        : QWidget (aParent, aName), mBootTable (0)
     135    {
     136        /* Setup main widget layout */
     137        QHBoxLayout *mainLayout = new QHBoxLayout (this, 0, 10, "mainLayout");
     138
     139        /* Setup settings layout */
     140        mBootTable = new BootItemsTable (this, "mBootTable");
     141        connect (mBootTable, SIGNAL (currentChanged (QListViewItem*)),
     142                 this, SLOT (processCurrentChanged (QListViewItem*)));
     143        mainLayout->addWidget (mBootTable);
     144
     145        /* Setup button's layout */
     146        QVBoxLayout *buttonLayout = new QVBoxLayout (mainLayout, 0, "buttonLayout");
     147        mBtnUp = new QToolButton (this, "mBtnUp");
     148        mBtnDown = new QToolButton (this, "mBtnDown");
     149        QWhatsThis::add (mBtnUp, tr ("Move the selected boot device up."));
     150        QWhatsThis::add (mBtnDown, tr ("Move the selected boot device down."));
     151        mBtnUp->setAutoRaise (true);
     152        mBtnDown->setAutoRaise (true);
     153        mBtnUp->setFocusPolicy (QWidget::StrongFocus);
     154        mBtnDown->setFocusPolicy (QWidget::StrongFocus);
     155        mBtnUp->setIconSet (VBoxGlobal::iconSet ("usb_moveup_16px.png",
     156                                                 "usb_moveup_disabled_16px.png"));
     157        mBtnDown->setIconSet (VBoxGlobal::iconSet ("usb_movedown_16px.png",
     158                                                   "usb_movedown_disabled_16px.png"));
     159        QSpacerItem *spacer = new QSpacerItem (0, 0, QSizePolicy::Minimum,
     160                                                     QSizePolicy::Expanding);
     161        connect (mBtnUp, SIGNAL (clicked()), this, SLOT (moveItemUp()));
     162        connect (mBtnDown, SIGNAL (clicked()), this, SLOT (moveItemDown()));
     163        connect (mBootTable, SIGNAL (moveItemUp()), this, SLOT (moveItemUp()));
     164        connect (mBootTable, SIGNAL (moveItemDown()), this, SLOT (moveItemDown()));
     165        buttonLayout->addWidget (mBtnUp);
     166        buttonLayout->addWidget (mBtnDown);
     167        buttonLayout->addItem (spacer);
     168
     169        /* Setup focus proxy for BootItemsList */
     170        setFocusProxy (mBootTable);
     171    }
     172
     173    ~BootItemsList() {}
     174
     175    void fixTabStops()
     176    {
     177        /* Fixing focus order for BootItemsList */
     178        setTabOrder (mBootTable, mBtnUp);
     179        setTabOrder (mBtnUp, mBtnDown);
     180    }
     181
     182    void getFromMachine (const CMachine &aMachine)
     183    {
     184        /* Load boot-items of current VM */
     185        QStringList uniqueList;
     186        int minimumWidth = 0;
     187        for (int i = 1; i <= 4; ++ i)
     188        {
     189            CEnums::DeviceType type = aMachine.GetBootOrder (i);
     190            if (type != CEnums::NoDevice)
    122191            {
    123                 case Qt::Key_Backtab:
    124                     /* Going to parent QTable */
    125                     focusData()->home();
    126                     focusData()->next()->setFocus();
    127                     /* Jumps other the parent QTable */
    128                     focusData()->home();
    129                     focusData()->prev()->setFocus();
    130                     return false;
    131                     break;
    132                 case Qt::Key_Tab:
    133                     /* Going to parent QTable */
    134                     focusData()->home();
    135                     focusData()->next()->setFocus();
    136                     /* Jumps other the parent QTable */
    137                     focusData()->home();
    138                     focusData()->next()->setFocus();
    139                     return false;
    140                     break;
    141                 default:
    142                     return QComboBox::event (aEvent);
     192                QString name = vboxGlobal().toString (type);
     193                QCheckListItem *item = new QCheckListItem (mBootTable,
     194                    mBootTable->lastItem(), name, QCheckListItem::CheckBox);
     195                item->setOn (true);
     196                uniqueList << name;
     197                int width = item->width (mBootTable->fontMetrics(), mBootTable, 0);
     198                if (width > minimumWidth) minimumWidth = width;
    143199            }
    144200        }
    145         else
    146             return QComboBox::event (aEvent);
    147     }
    148 
    149     BootItemsTable *mParent;
    150 };
    151 
    152 
    153 /**
    154  *  Class: ComboTableItem.
    155  *  Simple QTableItem subclass to use QComboBox as the cell editor.
    156  *  This subclass (as opposed to QComboTableItem) allows to specify the
    157  *  EditType::WhenCurrent edit type of the cell (to let it look like a normal
    158  *  text cell when not in focus).
    159  *
    160  *  Additionally, this subclass supports unicity of a group of values
    161  *  among a group of ComboTableItem items that refer to the same list of
    162  *  unique values currently being used.
    163  */
    164 class ComboTableItem : public QObject, public QTableItem
    165 {
    166     Q_OBJECT
    167 
    168 public:
    169 
    170     enum { BootItemType = 1001 };
    171 
    172     ComboTableItem (QTable *aTable, EditType aEditType,
    173                     const QStringList &aList, const QStringList &aUnique,
    174                     QStringList *aUniqueInUse)
    175         : QTableItem (aTable, aEditType)
    176         , mList (aList), mUnique (aUnique), mUniqueInUse (aUniqueInUse), mComboBoxSelector(0)
    177     {
    178         setReplaceable (FALSE);
    179     }
    180 
    181     QWidget *createEditor() const
    182     {
    183         mComboBoxSelector = (QComboBox*) new BootComboBox (table()->viewport(), table());
    184         QStringList list = mList;
    185         if (mUniqueInUse)
    186         {
    187             /* remove unique values currently in use */
    188             for (QStringList::Iterator it = mUniqueInUse->begin();
    189                  it != mUniqueInUse->end(); ++ it)
     201        /* Load other unique boot-items */
     202        for (int i = CEnums::FloppyDevice; i < CEnums::USBDevice; ++ i)
     203        {
     204            QString name = vboxGlobal().toString ((CEnums::DeviceType) i);
     205            if (!uniqueList.contains (name))
    190206            {
    191                 if (*it != text())
    192                     list.remove (*it);
     207                QCheckListItem *item = new QCheckListItem (mBootTable,
     208                    mBootTable->lastItem(), name, QCheckListItem::CheckBox);
     209                uniqueList << name;
     210                int width = item->width (mBootTable->fontMetrics(), mBootTable, 0);
     211                if (width > minimumWidth) minimumWidth = width;
    193212            }
    194213        }
    195         mComboBoxSelector->insertStringList (list);
    196         mComboBoxSelector->setCurrentText (text());
    197         QObject::connect (table(), SIGNAL (clicked (int, int, int, const QPoint&)),
    198                           this, SLOT (processClicked (int, int, int, const QPoint&)));
    199 
    200         return mComboBoxSelector;
    201     }
    202 
    203     void setContentFromEditor (QWidget *aWidget)
    204     {
    205         if (aWidget->inherits ("QComboBox"))
    206         {
    207             QString text = ((QComboBox *) aWidget)->currentText();
    208             setText (text);
    209         }
    210         else
    211             QTableItem::setContentFromEditor (aWidget);
    212     }
    213 
    214     void setText (const QString &aText)
    215     {
    216         if (aText != text())
    217         {
    218             /* update the list of unique values currently in use */
    219             if (mUniqueInUse)
     214        processCurrentChanged (mBootTable->firstChild());
     215        mBootTable->setFixedWidth (minimumWidth +
     216                                   4 /* viewport margin */);
     217        mBootTable->setFixedHeight (mBootTable->childCount() *
     218                                    mBootTable->firstChild()->totalHeight() +
     219                                    4 /* viewport margin */);
     220    }
     221
     222    void putBackToMachine (CMachine &aMachine)
     223    {
     224        QCheckListItem *item = 0;
     225        /* Search for checked items */
     226        int index = 1;
     227        item = static_cast<QCheckListItem*> (mBootTable->firstChild());
     228        while (item)
     229        {
     230            if (item->isOn())
    220231            {
    221                 QStringList::Iterator it = mUniqueInUse->find (text());
    222                 if (it != mUniqueInUse->end())
    223                     mUniqueInUse->remove (it);
    224                 if (mUnique.contains (aText))
    225                     (*mUniqueInUse) += aText;
     232                CEnums::DeviceType type =
     233                    vboxGlobal().toDeviceType (item->text (0));
     234                aMachine.SetBootOrder (index++, type);
    226235            }
    227             QTableItem::setText (aText);
    228         }
    229     }
    230 
    231     /*
    232      *  Function: rtti()
    233      *  Required for runtime information about ComboTableItem class
    234      *  used for static_cast from QTableItem
    235      */
    236     int rtti() const { return BootItemType; }
    237 
    238     /*
    239      *  Function: getEditor()
    240      *  Returns pointer to stored combo-box
    241      */
    242     QComboBox* getEditor() { return mComboBoxSelector; }
     236            item = static_cast<QCheckListItem*> (item->nextSibling());
     237        }
     238        /* Search for non-checked items */
     239        item = static_cast<QCheckListItem*> (mBootTable->firstChild());
     240        while (item)
     241        {
     242            if (!item->isOn())
     243                aMachine.SetBootOrder (index++, CEnums::NoDevice);
     244            item = static_cast<QCheckListItem*> (item->nextSibling());
     245        }
     246    }
     247
     248    void processFocusIn (QWidget *aWidget)
     249    {
     250        if (aWidget == mBootTable)
     251        {
     252            mBootTable->setSelected (mBootTable->currentItem(), true);
     253            processCurrentChanged (mBootTable->currentItem());
     254        }
     255        else if (aWidget != mBtnUp && aWidget != mBtnDown)
     256        {
     257            mBootTable->setSelected (mBootTable->currentItem(), false);
     258            processCurrentChanged (mBootTable->currentItem());
     259        }
     260    }
    243261
    244262private slots:
    245263
    246     /*
    247      *  Slot: processClicked(...)
    248      *  Ensures item's combo-box popup in case of it was force-closed
    249      *  with using of endEdit() last time
    250      */
    251     void processClicked (int aRow, int aCol, int, const QPoint &)
    252     {
    253         if (aRow == row() && aCol == col())
    254             mComboBoxSelector->popup();
     264    void moveItemUp()
     265    {
     266        QListViewItem *item = mBootTable->currentItem();
     267        Assert (item);
     268        QListViewItem *itemAbove = item->itemAbove();
     269        if (!itemAbove) return;
     270        itemAbove->moveItem (item);
     271        processCurrentChanged (item);
     272    }
     273
     274    void moveItemDown()
     275    {
     276        QListViewItem *item = mBootTable->currentItem();
     277        Assert (item);
     278        QListViewItem *itemBelow = item->itemBelow();
     279        if (!itemBelow) return;
     280        item->moveItem (itemBelow);
     281        processCurrentChanged (item);
     282    }
     283
     284    void processCurrentChanged (QListViewItem *aItem)
     285    {
     286        bool upEnabled   = aItem && aItem->isSelected() && aItem->itemAbove();
     287        bool downEnabled = aItem && aItem->isSelected() && aItem->itemBelow();
     288        if (mBtnUp->hasFocus() && !upEnabled ||
     289            mBtnDown->hasFocus() && !downEnabled)
     290            mBootTable->setFocus();
     291        mBtnUp->setEnabled (upEnabled);
     292        mBtnDown->setEnabled (downEnabled);
    255293    }
    256294
    257295private:
    258296
    259     const QStringList  mList;
    260     const QStringList  mUnique;
    261     QStringList*       mUniqueInUse;
    262     mutable QComboBox* mComboBoxSelector;
     297    BootItemsTable *mBootTable;
     298    QToolButton *mBtnUp;
     299    QToolButton *mBtnDown;
    263300};
    264301
     
    651688    slVRAM_valueChanged (slVRAM->value());
    652689
    653 
    654     tblBootOrder = new BootItemsTable ( groupBox12, "tblBootOrder" );
    655     QWhatsThis::add (tblBootOrder,
    656                      tr ("Defines the boot device order. Click on the entry and "
    657                          "select a desired boot device from the drop-down list."));
     690    /* Boot-order table */
     691    tblBootOrder = new BootItemsList (groupBox12, "tblBootOrder");
     692    /* Fixing focus order for BootItemsList */
    658693    setTabOrder (tbwGeneral, tblBootOrder);
    659     setTabOrder (tblBootOrder, chbEnableACPI);
    660     tblBootOrder->setSizePolicy (QSizePolicy ((QSizePolicy::SizeType)7,
    661         (QSizePolicy::SizeType)7, 1, 0,
    662         tblBootOrder->sizePolicy().hasHeightForWidth()));
    663     tblBootOrder->setNumRows (0);
    664     tblBootOrder->setNumCols (0);
    665     tblBootOrder->setShowGrid (FALSE);
    666     tblBootOrder->setSelectionMode (QTable::NoSelection);
    667     tblBootOrder->setFocusStyle (QTable::FollowStyle);
     694    setTabOrder (tblBootOrder->focusProxy(), chbEnableACPI);
    668695    groupBox12Layout->addWidget (tblBootOrder);
    669 
    670     tblBootOrder->horizontalHeader()->hide();
    671     tblBootOrder->setTopMargin (0);
    672     tblBootOrder->verticalHeader()->hide();
    673     tblBootOrder->setLeftMargin (0);
    674     tblBootOrder->setNumCols (1);
    675     tblBootOrder->setNumRows (sysProps.GetMaxBootPosition());
    676     {
    677         QStringList list = vboxGlobal().deviceTypeStrings();
    678         QStringList unique;
    679         unique
    680             << vboxGlobal().toString (CEnums::FloppyDevice)
    681             << vboxGlobal().toString (CEnums::DVDDevice)
    682             << vboxGlobal().toString (CEnums::HardDiskDevice)
    683             << vboxGlobal().toString (CEnums::NetworkDevice);
    684         for (int i = 0; i < tblBootOrder->numRows(); i++)
    685         {
    686             ComboTableItem *item = new ComboTableItem (
    687                 tblBootOrder, QTableItem::WhenCurrent,
    688                 list, unique, &bootDevicesInUse);
    689             tblBootOrder->setItem (i, 0, item);
    690         }
    691     }
    692 
    693     tblBootOrder->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred);
    694     tblBootOrder->setMinimumHeight (tblBootOrder->rowHeight(0) * 4 +
    695                                     tblBootOrder->frameWidth() * 2);
    696     tblBootOrder->setColumnStretchable (0, true);
    697     tblBootOrder->verticalHeader()->setResizeEnabled (false);
    698     tblBootOrder->verticalHeader()->setClickEnabled (false);
    699 //    tblBootOrder->setFocusStyle (QTable::FollowStyle);
     696    tblBootOrder->fixTabStops();
    700697
    701698    /* HDD Images page */
     
    762759        {
    763760            updateWhatsThis (true /* gotFocus */);
     761            tblBootOrder->processFocusIn (widget);
    764762            break;
    765763        }
     
    930928 *  from the given category page. In this case, the specified widget
    931929 *  will get focus when the dialog is open.
    932  * 
     930 *
    933931 *  @note Calling this method after the dialog is open has no sense.
    934932 *
     
    11951193    slVRAM->setValue (machine.GetVRAMSize());
    11961194
    1197     /* boot order */
    1198     bootDevicesInUse.clear();
    1199     for (int i = 0; i < tblBootOrder->numRows(); i ++)
    1200     {
    1201         QTableItem *item = tblBootOrder->item (i, 0);
    1202         item->setText (vboxGlobal().toString (machine.GetBootOrder (i + 1)));
    1203     }
     1195    /* Boot-order */
     1196    tblBootOrder->getFromMachine (machine);
    12041197
    12051198    /* ACPI */
     
    15121505
    15131506    /* boot order */
    1514     for (int i = 0; i < tblBootOrder->numRows(); i ++)
    1515     {
    1516         QTableItem *item = tblBootOrder->item (i, 0);
    1517         cmachine.SetBootOrder (i + 1, vboxGlobal().toDeviceType (item->text()));
    1518     }
     1507    tblBootOrder->putBackToMachine (cmachine);
    15191508
    15201509    /* ACPI */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette