VirtualBox

Changeset 86124 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 14, 2020 5:16:23 PM (4 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9827: Global properties / Input page: Heavy rework, replacing widgets with corresponding editor classes and performing overall cleanup.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
3 edited
4 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r86097 r86124  
    837837        src/settings/editors/UIAudioControllerEditor.h \
    838838        src/settings/editors/UIAudioHostDriverEditor.h \
     839        src/settings/editors/UIAutoCaptureKeyboardEditor.h \
    839840        src/settings/editors/UIBaseMemoryEditor.h \
    840841        src/settings/editors/UIBootOrderEditor.h \
     
    846847        src/settings/editors/UINetworkAttachmentEditor.h \
    847848        src/settings/editors/UIScaleFactorEditor.h \
     849        src/settings/editors/UIShortcutConfigurationEditor.h \
    848850        src/settings/editors/UIVideoMemoryEditor.h \
    849851        src/settings/editors/UIVirtualCPUEditor.h \
     
    993995        src/settings/editors/UIBootOrderEditor.cpp \
    994996        src/settings/editors/UIHotKeyEditor.cpp \
     997        src/settings/editors/UIShortcutConfigurationEditor.cpp \
    995998        src/settings/global/UIGlobalSettingsExtension.cpp \
    996         src/settings/global/UIGlobalSettingsInput.cpp \
    997999        src/settings/global/UIGlobalSettingsLanguage.cpp \
    9981000        src/settings/global/UIGlobalSettingsNetwork.cpp \
     
    13521354        src/settings/editors/UIAudioControllerEditor.cpp \
    13531355        src/settings/editors/UIAudioHostDriverEditor.cpp \
     1356        src/settings/editors/UIAutoCaptureKeyboardEditor.cpp \
    13541357        src/settings/editors/UIBaseMemoryEditor.cpp \
    13551358        src/settings/editors/UIBootOrderEditor.cpp \
     
    13611364        src/settings/editors/UINetworkAttachmentEditor.cpp \
    13621365        src/settings/editors/UIScaleFactorEditor.cpp \
     1366        src/settings/editors/UIShortcutConfigurationEditor.cpp \
    13631367        src/settings/editors/UIVideoMemoryEditor.cpp \
    13641368        src/settings/editors/UIVirtualCPUEditor.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UIAutoCaptureKeyboardEditor.cpp

    r86120 r86124  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIGlobalSettingsInput class implementation.
     3 * VBox Qt GUI - UIAutoCaptureKeyboardEditor class implementation.
    44 */
    55
     
    1717
    1818/* Qt includes: */
    19 #include <QAbstractItemDelegate>
    2019#include <QCheckBox>
    2120#include <QGridLayout>
    22 #include <QHeaderView>
    23 #include <QItemEditorFactory>
    24 #include <QTabWidget>
     21#include <QLabel>
    2522
    2623/* GUI includes: */
    27 #include "QIStyledItemDelegate.h"
    28 #include "QITableView.h"
    29 #include "QIWidgetValidator.h"
    30 #include "UICommon.h"
    31 #include "UIActionPool.h"
    32 #include "UIGlobalSettingsInput.h"
    33 #include "UIHostComboEditor.h"
    34 #include "UIHotKeyEditor.h"
    35 #include "UIShortcutPool.h"
    36 #include "UIExtraDataManager.h"
    37 #include "UIMessageCenter.h"
    38 
    39 /* Qt includes: */
    40 #include <QShortcut>
     24#include "UIAutoCaptureKeyboardEditor.h"
    4125
    4226
    43 /* Namespaces: */
    44 using namespace UIExtraDataDefs;
    45 
    46 
    47 /** Column index enumerator. */
    48 enum UIHotKeyColumnIndex
     27UIAutoCaptureKeyboardEditor::UIAutoCaptureKeyboardEditor(QWidget *pParent /* = 0 */, bool fWithLabel /* = false */)
     28    : QIWithRetranslateUI<QWidget>(pParent)
     29    , m_fWithLabel(fWithLabel)
     30    , m_fValue(false)
     31    , m_pLabel(0)
     32    , m_pCheckBox(0)
    4933{
    50     UIHotKeyColumnIndex_Description,
    51     UIHotKeyColumnIndex_Sequence,
    52     UIHotKeyColumnIndex_Max
    53 };
    54 
    55 
    56 /** Global settings: Input page: Shortcut cell data structure. */
    57 class UIDataShortcutCell : public QITableViewCell
    58 {
    59     Q_OBJECT;
    60 
    61 public:
    62 
    63     /** Constructs table cell.
    64       * @param  pParent  Brings the row this cell belongs too.
    65       * @param  strText  Brings the text describing this cell. */
    66     UIDataShortcutCell(QITableViewRow *pParent, const QString &strText)
    67         : QITableViewCell(pParent)
    68         , m_strText(strText)
    69     {}
    70 
    71     /** Returns the cell text. */
    72     virtual QString text() const /* override */ { return m_strText; }
    73 
    74 private:
    75 
    76     /** Holds the cell text. */
    77     QString m_strText;
    78 };
    79 
    80 
    81 /** Global settings: Input page: Shortcut data structure. */
    82 class UIDataShortcutRow : public QITableViewRow
    83 {
    84     Q_OBJECT;
    85 
    86 public:
    87 
    88     /** Constructs table row on the basis of passed arguments.
    89       * @param  pParent             Brings the row this cell belongs too.
    90       * @param  strKey              Brings the unique key identifying held sequence.
    91       * @param  strScope            Brings the scope of the held sequence.
    92       * @param  strDescription      Brings the deescription for the held sequence.
    93       * @param  strCurrentSequence  Brings the current held sequence.
    94       * @param  strDefaultSequence  Brings the default held sequence. */
    95     UIDataShortcutRow(QITableView *pParent,
    96                       const QString &strKey,
    97                       const QString &strScope,
    98                       const QString &strDescription,
    99                       const QString &strCurrentSequence,
    100                       const QString &strDefaultSequence)
    101         : QITableViewRow(pParent)
    102         , m_strKey(strKey)
    103         , m_strScope(strScope)
    104         , m_strDescription(strDescription)
    105         , m_strCurrentSequence(strCurrentSequence)
    106         , m_strDefaultSequence(strDefaultSequence)
    107     {
    108         /* Create cells: */
    109         createCells();
    110     }
    111 
    112     /** Constructs table row on the basis of @a other one. */
    113     UIDataShortcutRow(const UIDataShortcutRow &other)
    114         : QITableViewRow(other.table())
    115         , m_strKey(other.key())
    116         , m_strScope(other.scope())
    117         , m_strDescription(other.description())
    118         , m_strCurrentSequence(other.currentSequence())
    119         , m_strDefaultSequence(other.defaultSequence())
    120     {
    121         /* Create cells: */
    122         createCells();
    123     }
    124 
    125     /** Destructs table row. */
    126     ~UIDataShortcutRow()
    127     {
    128         /* Destroy cells: */
    129         destroyCells();
    130     }
    131 
    132     /** Copies a table row from @a other one. */
    133     UIDataShortcutRow &operator=(const UIDataShortcutRow &other)
    134     {
    135         /* Reassign variables: */
    136         setTable(other.table());
    137         m_strKey = other.key();
    138         m_strScope = other.scope();
    139         m_strDescription = other.description();
    140         m_strCurrentSequence = other.currentSequence();
    141         m_strDefaultSequence = other.defaultSequence();
    142 
    143         /* Recreate cells: */
    144         destroyCells();
    145         createCells();
    146 
    147         /* Return this: */
    148         return *this;
    149     }
    150 
    151     /** Returns whether this row equals to @a other. */
    152     bool operator==(const UIDataShortcutRow &other) const
    153     {
    154         /* Compare by the key and the current sequence: */
    155         return true
    156                && (m_strKey == other.key())
    157                && (m_strScope == other.scope())
    158                && (m_strCurrentSequence == other.currentSequence())
    159                ;
    160     }
    161 
    162     /** Returns the key. */
    163     QString key() const { return m_strKey; }
    164     /** Returns the scope. */
    165     QString scope() const { return m_strScope; }
    166     /** Returns the description. */
    167     QString description() const { return m_strDescription; }
    168     /** Returns the current sequence. */
    169     QString currentSequence() const { return m_strCurrentSequence; }
    170     /** Returns the default sequence. */
    171     QString defaultSequence() const { return m_strDefaultSequence; }
    172 
    173     /** Defines @a strCurrentSequence. */
    174     void setCurrentSequence(const QString &strCurrentSequence) { m_strCurrentSequence = strCurrentSequence; }
    175 
    176 protected:
    177 
    178     /** Returns the number of children. */
    179     virtual int childCount() const /* override */
    180     {
    181         return UIHotKeyColumnIndex_Max;
    182     }
    183 
    184     /** Returns the child item with @a iIndex. */
    185     virtual QITableViewCell *childItem(int iIndex) const /* override */
    186     {
    187         switch (iIndex)
    188         {
    189             case UIHotKeyColumnIndex_Description: return m_cells.first;
    190             case UIHotKeyColumnIndex_Sequence: return m_cells.second;
    191             default: break;
    192         }
    193         return 0;
    194     }
    195 
    196 private:
    197 
    198     /** Creates cells. */
    199     void createCells()
    200     {
    201         /* Create cells on the basis of description and current sequence: */
    202         m_cells = qMakePair(new UIDataShortcutCell(this, m_strDescription),
    203                             new UIDataShortcutCell(this, m_strCurrentSequence));
    204     }
    205 
    206     /** Destroys cells. */
    207     void destroyCells()
    208     {
    209         /* Destroy cells: */
    210         delete m_cells.first;
    211         delete m_cells.second;
    212         m_cells.first = 0;
    213         m_cells.second = 0;
    214     }
    215 
    216     /** Holds the key. */
    217     QString m_strKey;
    218     /** Holds the scope. */
    219     QString m_strScope;
    220     /** Holds the description. */
    221     QString m_strDescription;
    222     /** Holds the current sequence. */
    223     QString m_strCurrentSequence;
    224     /** Holds the default sequence. */
    225     QString m_strDefaultSequence;
    226 
    227     /** Holds the cell instances. */
    228     QPair<UIDataShortcutCell*, UIDataShortcutCell*> m_cells;
    229 };
    230 typedef QList<UIDataShortcutRow> UIShortcutCache;
    231 
    232 
    233 /** Global settings: Input page data structure. */
    234 class UIDataSettingsGlobalInput
    235 {
    236 public:
    237 
    238     /** Constructs cache. */
    239     UIDataSettingsGlobalInput()
    240         : m_fAutoCapture(false)
    241     {}
    242 
    243     /** Returns the shortcuts cache [full access]. */
    244     UIShortcutCache &shortcuts() { return m_shortcuts; }
    245     /** Returns the shortcuts cache [read-only access]. */
    246     const UIShortcutCache &shortcuts() const { return m_shortcuts; }
    247 
    248     /** Defines whether the keyboard auto-capture is @a fEnabled. */
    249     void setAutoCapture(bool fEnabled) { m_fAutoCapture = fEnabled; }
    250     /** Returns whether the keyboard auto-capture is enabled. */
    251     bool autoCapture() const { return m_fAutoCapture; }
    252 
    253     /** Returns whether the @a other passed data is equal to this one. */
    254     bool equal(const UIDataSettingsGlobalInput &other) const
    255     {
    256         return (m_shortcuts == other.m_shortcuts) &&
    257                (m_fAutoCapture == other.m_fAutoCapture);
    258     }
    259 
    260     /** Returns whether the @a other passed data is equal to this one. */
    261     bool operator==(const UIDataSettingsGlobalInput &other) const { return equal(other); }
    262     /** Returns whether the @a other passed data is different from this one. */
    263     bool operator!=(const UIDataSettingsGlobalInput &other) const { return !equal(other); }
    264 
    265 private:
    266 
    267     /** Holds the shortcut cache. */
    268     UIShortcutCache m_shortcuts;
    269 
    270     /** Holds whether the keyboard auto-capture is enabled. */
    271     bool m_fAutoCapture;
    272 };
    273 
    274 
    275 /** Global settings: Input page: Shortcut cache sort functor. */
    276 class UIShortcutCacheItemFunctor
    277 {
    278 public:
    279 
    280     /** Constructs cache sorting functor.
    281       * @param  iColumn  Brings the column sorting should be done according to.
    282       * @param  m_order  Brings the sorting order to be applied. */
    283     UIShortcutCacheItemFunctor(int iColumn, Qt::SortOrder order)
    284         : m_iColumn(iColumn)
    285         , m_order(order)
    286     {}
    287 
    288     /** Returns whether the @a item1 is more/less than the @a item2.
    289       * @note  Order depends on the one set through constructor, stored in m_order. */
    290     bool operator()(const UIDataShortcutRow &item1, const UIDataShortcutRow &item2)
    291     {
    292         switch (m_iColumn)
    293         {
    294             case UIHotKeyColumnIndex_Description:
    295                 return m_order == Qt::AscendingOrder ? item1.description() < item2.description() : item1.description() > item2.description();
    296             case UIHotKeyColumnIndex_Sequence:
    297                 return m_order == Qt::AscendingOrder ? item1.currentSequence() < item2.currentSequence() : item1.currentSequence() > item2.currentSequence();
    298             default: break;
    299         }
    300         return m_order == Qt::AscendingOrder ? item1.key() < item2.key() : item1.key() > item2.key();
    301     }
    302 
    303 private:
    304 
    305     /** Holds the column sorting should be done according to. */
    306     int m_iColumn;
    307     /** Holds the sorting order to be applied. */
    308     Qt::SortOrder m_order;
    309 };
    310 
    311 
    312 /** Global settings: Input page: Shortcut search functor. */
    313 class UIFunctorFindShortcut
    314 {
    315 public:
    316 
    317     /** Search match level enumerator. */
    318     enum UIMatchLevel { Base, Full };
    319 
    320     /** Constructs shortcut search functor.
    321       * @param  matchLevel  Brings the search match level. */
    322     UIFunctorFindShortcut(UIMatchLevel enmMatchLevel)
    323         : m_enmMatchLevel(enmMatchLevel)
    324     {}
    325 
    326     /** Returns the position of the 1st occurrence of the
    327       * @a shortcut in the @a shortcuts list, or -1 otherwise. */
    328     int operator()(const UIShortcutCache &shortcuts, const UIDataShortcutRow &shortcut)
    329     {
    330         for (int i = 0; i < shortcuts.size(); ++i)
    331         {
    332             const UIDataShortcutRow &iteratedShortcut = shortcuts.at(i);
    333             switch (m_enmMatchLevel)
    334             {
    335                 case Base:
    336                 {
    337                     if (iteratedShortcut.key() == shortcut.key())
    338                         return i;
    339                     break;
    340                 }
    341                 case Full:
    342                 {
    343                     if (   iteratedShortcut.key() == shortcut.key()
    344                         && iteratedShortcut.currentSequence() == shortcut.currentSequence())
    345                         return i;
    346                     break;
    347                 }
    348             }
    349         }
    350         return -1;
    351     }
    352 
    353 private:
    354 
    355     /** Holds the search match level. */
    356     const UIMatchLevel m_enmMatchLevel;
    357 };
    358 
    359 
    360 /* A model representing hot-key combination table: */
    361 class UIHotKeyTableModel : public QAbstractTableModel
    362 {
    363     Q_OBJECT;
    364 
    365 signals:
    366 
    367     /* Notifier: Readiness stuff: */
    368     void sigShortcutsLoaded();
    369 
    370     /* Notifier: Validation stuff: */
    371     void sigRevalidationRequired();
    372 
    373 public:
    374 
    375     /* Constructor: */
    376     UIHotKeyTableModel(QObject *pParent, UIActionPoolType type);
    377 
    378     /** Returns the number of children. */
    379     int childCount() const;
    380     /** Returns the child item with @a iIndex. */
    381     QITableViewRow *childItem(int iIndex);
    382 
    383     /* API: Loading/saving stuff: */
    384     void load(const UIShortcutCache &shortcuts);
    385     void save(UIShortcutCache &shortcuts);
    386 
    387     /* API: Validation stuff: */
    388     bool isAllShortcutsUnique();
    389 
    390 public slots:
    391 
    392     /* Handler: Filtering stuff: */
    393     void sltHandleFilterTextChange(const QString &strText);
    394 
    395 private:
    396 
    397     /* Internal API: Size stuff: */
    398     int rowCount(const QModelIndex &parent = QModelIndex()) const;
    399     int columnCount(const QModelIndex &parent = QModelIndex()) const;
    400 
    401     /* Internal API: Data stuff: */
    402     Qt::ItemFlags flags(const QModelIndex &index) const;
    403     QVariant headerData(int iSection, Qt::Orientation orientation, int iRole = Qt::DisplayRole) const;
    404     QVariant data(const QModelIndex &index, int iRole = Qt::DisplayRole) const;
    405     bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole);
    406 
    407     /* Internal API: Sorting stuff: */
    408     void sort(int iColumn, Qt::SortOrder order = Qt::AscendingOrder);
    409 
    410     /* Helper: Filtering stuff: */
    411     void applyFilter();
    412 
    413     /* Variables: */
    414     UIActionPoolType m_type;
    415     QString m_strFilter;
    416     UIShortcutCache m_shortcuts;
    417     UIShortcutCache m_filteredShortcuts;
    418     QSet<QString> m_duplicatedSequences;
    419 };
    420 
    421 
    422 /* A table reflecting hot-key combinations: */
    423 class UIHotKeyTable : public QITableView
    424 {
    425     Q_OBJECT;
    426 
    427 public:
    428 
    429     /* Constructor: */
    430     UIHotKeyTable(QWidget *pParent, UIHotKeyTableModel *pModel, const QString &strObjectName);
    431 
    432 protected:
    433 
    434     /** Returns the number of children. */
    435     virtual int childCount() const /* override */;
    436     /** Returns the child item with @a iIndex. */
    437     virtual QITableViewRow *childItem(int iIndex) const /* override */;
    438 
    439 private slots:
    440 
    441     /* Handler: Readiness stuff: */
    442     void sltHandleShortcutsLoaded();
    443 
    444 private:
    445 
    446     /** Prepares all. */
    447     void prepare();
    448 };
    449 
    450 
    451 /*********************************************************************************************************************************
    452 *   Class UIHotKeyTableModel implementation.                                                                                     *
    453 *********************************************************************************************************************************/
    454 
    455 UIHotKeyTableModel::UIHotKeyTableModel(QObject *pParent, UIActionPoolType type)
    456     : QAbstractTableModel(pParent)
    457     , m_type(type)
    458 {
    459 }
    460 
    461 int UIHotKeyTableModel::childCount() const
    462 {
    463     /* Return row count: */
    464     return rowCount();
    465 }
    466 
    467 QITableViewRow *UIHotKeyTableModel::childItem(int iIndex)
    468 {
    469     /* Make sure index within the bounds: */
    470     AssertReturn(iIndex >= 0 && iIndex < m_filteredShortcuts.size(), 0);
    471     /* Return corresponding filtered row: */
    472     return &m_filteredShortcuts[iIndex];
    473 }
    474 
    475 void UIHotKeyTableModel::load(const UIShortcutCache &shortcuts)
    476 {
    477     /* Load shortcuts: */
    478     foreach (const UIDataShortcutRow &item, shortcuts)
    479     {
    480         /* Filter out unnecessary shortcuts: */
    481         if ((m_type == UIActionPoolType_Manager && item.key().startsWith(GUI_Input_MachineShortcuts)) ||
    482             (m_type == UIActionPoolType_Runtime && item.key().startsWith(GUI_Input_SelectorShortcuts)))
    483             continue;
    484         /* Load shortcut cache item into model: */
    485         m_shortcuts << item;
    486     }
    487     /* Apply filter: */
    488     applyFilter();
    489     /* Notify table: */
    490     emit sigShortcutsLoaded();
    491 }
    492 
    493 void UIHotKeyTableModel::save(UIShortcutCache &shortcuts)
    494 {
    495     /* Save model items: */
    496     foreach (const UIDataShortcutRow &item, m_shortcuts)
    497     {
    498         /* Search for corresponding cache item index: */
    499         int iIndexOfCacheItem = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(shortcuts, item);
    500         /* Make sure index is valid: */
    501         if (iIndexOfCacheItem == -1)
    502             continue;
    503         /* Save model item into the cache: */
    504         shortcuts[iIndexOfCacheItem] = item;
    505     }
    506 }
    507 
    508 bool UIHotKeyTableModel::isAllShortcutsUnique()
    509 {
    510     /* Enumerate all the sequences: */
    511     QMap<QString, QString> usedSequences;
    512     foreach (const UIDataShortcutRow &item, m_shortcuts)
    513     {
    514         QString strKey = item.currentSequence();
    515         if (!strKey.isEmpty())
    516         {
    517             const QString strScope = item.scope();
    518             strKey = strScope.isNull() ? strKey : QString("%1: %2").arg(strScope, strKey);
    519             usedSequences.insertMulti(strKey, item.key());
    520         }
    521     }
    522     /* Enumerate all the duplicated sequences: */
    523     QSet<QString> duplicatedSequences;
    524     foreach (const QString &strKey, usedSequences.keys())
    525         if (usedSequences.count(strKey) > 1)
    526             duplicatedSequences.unite(usedSequences.values(strKey).toSet());
    527     /* Is there something changed? */
    528     if (m_duplicatedSequences != duplicatedSequences)
    529     {
    530         m_duplicatedSequences = duplicatedSequences;
    531         emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
    532     }
    533     /* Are there duplicated shortcuts? */
    534     if (!m_duplicatedSequences.isEmpty())
    535         return false;
    536     /* True by default: */
    537     return true;
    538 }
    539 
    540 void UIHotKeyTableModel::sltHandleFilterTextChange(const QString &strText)
    541 {
    542     m_strFilter = strText;
    543     applyFilter();
    544 }
    545 
    546 int UIHotKeyTableModel::rowCount(const QModelIndex& /*parent = QModelIndex()*/) const
    547 {
    548     return m_filteredShortcuts.size();
    549 }
    550 
    551 int UIHotKeyTableModel::columnCount(const QModelIndex& /*parent = QModelIndex()*/) const
    552 {
    553     return 2;
    554 }
    555 
    556 Qt::ItemFlags UIHotKeyTableModel::flags(const QModelIndex &index) const
    557 {
    558     /* No flags for invalid index: */
    559     if (!index.isValid()) return Qt::NoItemFlags;
    560     /* Switch for different columns: */
    561     switch (index.column())
    562     {
    563         case UIHotKeyColumnIndex_Description: return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    564         case UIHotKeyColumnIndex_Sequence: return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
    565         default: break;
    566     }
    567     /* No flags by default: */
    568     return Qt::NoItemFlags;
    569 }
    570 
    571 QVariant UIHotKeyTableModel::headerData(int iSection, Qt::Orientation orientation, int iRole /* = Qt::DisplayRole*/) const
    572 {
    573     /* Switch for different roles: */
    574     switch (iRole)
    575     {
    576         case Qt::DisplayRole:
    577         {
    578             /* Invalid for vertical header: */
    579             if (orientation == Qt::Vertical) return QString();
    580             /* Switch for different columns: */
    581             switch (iSection)
    582             {
    583                 case UIHotKeyColumnIndex_Description: return tr("Name");
    584                 case UIHotKeyColumnIndex_Sequence: return tr("Shortcut");
    585                 default: break;
    586             }
    587             /* Invalid for other cases: */
    588             return QString();
    589         }
    590         default: break;
    591     }
    592     /* Invalid by default: */
    593     return QVariant();
    594 }
    595 
    596 QVariant UIHotKeyTableModel::data(const QModelIndex &index, int iRole /* = Qt::DisplayRole*/) const
    597 {
    598     /* No data for invalid index: */
    599     if (!index.isValid()) return QVariant();
    600     int iIndex = index.row();
    601     /* Switch for different roles: */
    602     switch (iRole)
    603     {
    604         case Qt::DisplayRole:
    605         {
    606             /* Switch for different columns: */
    607             switch (index.column())
    608             {
    609                 case UIHotKeyColumnIndex_Description:
    610                 {
    611                     /* Return shortcut scope and description: */
    612                     const QString strScope = m_filteredShortcuts[iIndex].scope();
    613                     const QString strDescription = m_filteredShortcuts[iIndex].description();
    614                     return strScope.isNull() ? strDescription : tr("%1: %2", "scope: description").arg(strScope, strDescription);
    615                 }
    616                 case UIHotKeyColumnIndex_Sequence:
    617                 {
    618                     /* If that is host-combo cell: */
    619                     if (m_filteredShortcuts[iIndex].key() == UIHostCombo::hostComboCacheKey())
    620                         /* We should return host-combo: */
    621                         return UIHostCombo::toReadableString(m_filteredShortcuts[iIndex].currentSequence());
    622                     /* In other cases we should return hot-combo: */
    623                     QString strHotCombo = m_filteredShortcuts[iIndex].currentSequence();
    624                     /* But if that is machine table and hot-combo is not empty: */
    625                     if (m_type == UIActionPoolType_Runtime && !strHotCombo.isEmpty())
    626                         /* We should prepend it with Host+ prefix: */
    627                         strHotCombo.prepend(UIHostCombo::hostComboModifierName());
    628                     /* Return what we've got: */
    629                     return strHotCombo;
    630                 }
    631                 default: break;
    632             }
    633             /* Invalid for other cases: */
    634             return QString();
    635         }
    636         case Qt::EditRole:
    637         {
    638             /* Switch for different columns: */
    639             switch (index.column())
    640             {
    641                 case UIHotKeyColumnIndex_Sequence: return m_filteredShortcuts[iIndex].key() == UIHostCombo::hostComboCacheKey() ?
    642                                                           QVariant::fromValue(UIHostComboWrapper(m_filteredShortcuts[iIndex].currentSequence())) :
    643                                                           QVariant::fromValue(UIHotKey(m_type == UIActionPoolType_Runtime ?
    644                                                                                        UIHotKeyType_Simple : UIHotKeyType_WithModifiers,
    645                                                                                        m_filteredShortcuts[iIndex].currentSequence(),
    646                                                                                        m_filteredShortcuts[iIndex].defaultSequence()));
    647                 default: break;
    648             }
    649             /* Invalid for other cases: */
    650             return QString();
    651         }
    652         case Qt::FontRole:
    653         {
    654             /* Do we have a default font? */
    655             QFont font(QApplication::font());
    656             /* Switch for different columns: */
    657             switch (index.column())
    658             {
    659                 case UIHotKeyColumnIndex_Sequence:
    660                 {
    661                     if (m_filteredShortcuts[iIndex].key() != UIHostCombo::hostComboCacheKey() &&
    662                         m_filteredShortcuts[iIndex].currentSequence() != m_filteredShortcuts[iIndex].defaultSequence())
    663                         font.setBold(true);
    664                     break;
    665                 }
    666                 default: break;
    667             }
    668             /* Return resulting font: */
    669             return font;
    670         }
    671         case Qt::ForegroundRole:
    672         {
    673             /* Switch for different columns: */
    674             switch (index.column())
    675             {
    676                 case UIHotKeyColumnIndex_Sequence:
    677                 {
    678                     if (m_duplicatedSequences.contains(m_filteredShortcuts[iIndex].key()))
    679                         return QBrush(Qt::red);
    680                     break;
    681                 }
    682                 default: break;
    683             }
    684             /* Default for other cases: */
    685             return QString();
    686         }
    687         default: break;
    688     }
    689     /* Invalid by default: */
    690     return QVariant();
    691 }
    692 
    693 bool UIHotKeyTableModel::setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole*/)
    694 {
    695     /* Nothing to set for invalid index: */
    696     if (!index.isValid()) return false;
    697     /* Switch for different roles: */
    698     switch (iRole)
    699     {
    700         case Qt::EditRole:
    701         {
    702             /* Switch for different columns: */
    703             switch (index.column())
    704             {
    705                 case UIHotKeyColumnIndex_Sequence:
    706                 {
    707                     /* Get index: */
    708                     int iIndex = index.row();
    709                     /* Set sequence to shortcut: */
    710                     UIDataShortcutRow &filteredShortcut = m_filteredShortcuts[iIndex];
    711                     int iShortcutIndex = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(m_shortcuts, filteredShortcut);
    712                     if (iShortcutIndex != -1)
    713                     {
    714                         filteredShortcut.setCurrentSequence(filteredShortcut.key() == UIHostCombo::hostComboCacheKey() ?
    715                                                             value.value<UIHostComboWrapper>().toString() :
    716                                                             value.value<UIHotKey>().sequence());
    717                         m_shortcuts[iShortcutIndex] = filteredShortcut;
    718                         emit sigRevalidationRequired();
    719                         return true;
    720                     }
    721                     break;
    722                 }
    723                 default: break;
    724             }
    725             break;
    726         }
    727         default: break;
    728     }
    729     /* Nothing to set by default: */
    730     return false;
    731 }
    732 
    733 void UIHotKeyTableModel::sort(int iColumn, Qt::SortOrder order /* = Qt::AscendingOrder*/)
    734 {
    735     /* Sort whole the list: */
    736     qStableSort(m_shortcuts.begin(), m_shortcuts.end(), UIShortcutCacheItemFunctor(iColumn, order));
    737     /* Make sure host-combo item is always the first one: */
    738     UIDataShortcutRow fakeHostComboItem(0, UIHostCombo::hostComboCacheKey(), QString(), QString(), QString(), QString());
    739     int iIndexOfHostComboItem = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(m_shortcuts, fakeHostComboItem);
    740     if (iIndexOfHostComboItem != -1)
    741     {
    742         UIDataShortcutRow hostComboItem = m_shortcuts.takeAt(iIndexOfHostComboItem);
    743         m_shortcuts.prepend(hostComboItem);
    744     }
    745     /* Apply the filter: */
    746     applyFilter();
    747     /* Notify the model: */
    748     emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
    749 }
    750 
    751 void UIHotKeyTableModel::applyFilter()
    752 {
    753     /* Erase items first if necessary: */
    754     if (!m_filteredShortcuts.isEmpty())
    755     {
    756         beginRemoveRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1);
    757         m_filteredShortcuts.clear();
    758         endRemoveRows();
    759     }
    760 
    761     /* If filter is empty: */
    762     if (m_strFilter.isEmpty())
    763     {
    764         /* Just add all the items: */
    765         m_filteredShortcuts = m_shortcuts;
    766     }
    767     else
    768     {
    769         /* Check if the description matches the filter: */
    770         foreach (const UIDataShortcutRow &item, m_shortcuts)
    771         {
    772             /* If neither scope nor description or sequence matches the filter, skip item: */
    773             if (!item.scope().contains(m_strFilter, Qt::CaseInsensitive) &&
    774                 !item.description().contains(m_strFilter, Qt::CaseInsensitive) &&
    775                 !item.currentSequence().contains(m_strFilter, Qt::CaseInsensitive))
    776                 continue;
    777             /* Add that item: */
    778             m_filteredShortcuts << item;
    779         }
    780     }
    781 
    782     /* Add items finally if necessary: */
    783     if (!m_filteredShortcuts.isEmpty())
    784     {
    785         beginInsertRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1);
    786         endInsertRows();
    787     }
    788 }
    789 
    790 
    791 /*********************************************************************************************************************************
    792 *   Class UIHotKeyTable implementation.                                                                                          *
    793 *********************************************************************************************************************************/
    794 
    795 UIHotKeyTable::UIHotKeyTable(QWidget *pParent, UIHotKeyTableModel *pModel, const QString &strObjectName)
    796     : QITableView(pParent)
    797 {
    798     /* Set object name: */
    799     setObjectName(strObjectName);
    800     /* Set model: */
    801     setModel(pModel);
    802 
    803     /* Prepare all: */
    80434    prepare();
    80535}
    80636
    807 int UIHotKeyTable::childCount() const
     37void UIAutoCaptureKeyboardEditor::setValue(bool fValue)
    80838{
    809     /* Redirect request to table model: */
    810     return qobject_cast<UIHotKeyTableModel*>(model())->childCount();
    811 }
    812 
    813 QITableViewRow *UIHotKeyTable::childItem(int iIndex) const
    814 {
    815     /* Redirect request to table model: */
    816     return qobject_cast<UIHotKeyTableModel*>(model())->childItem(iIndex);
    817 }
    818 
    819 void UIHotKeyTable::sltHandleShortcutsLoaded()
    820 {
    821     /* Resize columns to feat contents: */
    822     resizeColumnsToContents();
    823 
    824     /* Configure sorting: */
    825     sortByColumn(UIHotKeyColumnIndex_Description, Qt::AscendingOrder);
    826     setSortingEnabled(true);
    827 }
    828 
    829 void UIHotKeyTable::prepare()
    830 {
    831     /* Configure self: */
    832     setTabKeyNavigation(false);
    833     setContextMenuPolicy(Qt::CustomContextMenu);
    834     setSelectionBehavior(QAbstractItemView::SelectRows);
    835     setSelectionMode(QAbstractItemView::SingleSelection);
    836     setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked);
    837 
    838     /* Configure headers: */
    839     verticalHeader()->hide();
    840     verticalHeader()->setDefaultSectionSize((int)(verticalHeader()->minimumSectionSize() * 1.33));
    841     horizontalHeader()->setStretchLastSection(false);
    842     horizontalHeader()->setSectionResizeMode(UIHotKeyColumnIndex_Description, QHeaderView::Interactive);
    843     horizontalHeader()->setSectionResizeMode(UIHotKeyColumnIndex_Sequence, QHeaderView::Stretch);
    844 
    845     /* Connect model: */
    846     UIHotKeyTableModel *pHotKeyTableModel = qobject_cast<UIHotKeyTableModel*>(model());
    847     AssertPtrReturnVoid(pHotKeyTableModel);
     39    if (m_pCheckBox)
    84840    {
    849         connect(pHotKeyTableModel, &UIHotKeyTableModel::sigShortcutsLoaded,
    850                 this, &UIHotKeyTable::sltHandleShortcutsLoaded);
    851     }
    852 
    853     /* Check if we do have proper item delegate: */
    854     QIStyledItemDelegate *pStyledItemDelegate = qobject_cast<QIStyledItemDelegate*>(itemDelegate());
    855     AssertPtrReturnVoid(pStyledItemDelegate);
    856     {
    857         /* Configure item delegate: */
    858         pStyledItemDelegate->setWatchForEditorDataCommits(true);
    859 
    860         /* Create new item editor factory: */
    861         QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;
    862         AssertPtrReturnVoid(pNewItemEditorFactory);
     41        /* Update cached value and
     42         * check-box if value has changed: */
     43        if (m_fValue != fValue)
    86344        {
    864             /* Register UIHotKeyEditor as the UIHotKey editor: */
    865             int iHotKeyTypeId = qRegisterMetaType<UIHotKey>();
    866             QStandardItemEditorCreator<UIHotKeyEditor> *pHotKeyItemEditorCreator = new QStandardItemEditorCreator<UIHotKeyEditor>();
    867             pNewItemEditorFactory->registerEditor((QVariant::Type)iHotKeyTypeId, pHotKeyItemEditorCreator);
    868 
    869             /* Register UIHostComboEditor as the UIHostComboWrapper editor: */
    870             int iHostComboTypeId = qRegisterMetaType<UIHostComboWrapper>();
    871             QStandardItemEditorCreator<UIHostComboEditor> *pHostComboItemEditorCreator = new QStandardItemEditorCreator<UIHostComboEditor>();
    872             pNewItemEditorFactory->registerEditor((QVariant::Type)iHostComboTypeId, pHostComboItemEditorCreator);
    873 
    874             /* Assign configured item editor factory to item delegate: */
    875             pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory);
     45            m_fValue = fValue;
     46            m_pCheckBox->setCheckState(fValue ? Qt::Checked : Qt::Unchecked);
    87647        }
    87748    }
    87849}
    87950
    880 
    881 /*********************************************************************************************************************************
    882 *   Class UIGlobalSettingsInput implementation.                                                                                  *
    883 *********************************************************************************************************************************/
    884 
    885 UIGlobalSettingsInput::UIGlobalSettingsInput()
    886     : m_pModelManager(0)
    887     , m_pModelRuntime(0)
    888     , m_pCache(0)
    889     , m_pTabWidget(0)
    890     , m_pEditorManagerFilter(0), m_pTableManager(0)
    891     , m_pEditorRuntimeFilter(0), m_pTableRuntime(0)
    892     , m_pCheckBoxEnableAutoGrab(0)
     51bool UIAutoCaptureKeyboardEditor::value() const
    89352{
    894     /* Prepare: */
    895     prepare();
     53    return m_pCheckBox ? m_pCheckBox->checkState() == Qt::Checked : m_fValue;
    89654}
    89755
    898 UIGlobalSettingsInput::~UIGlobalSettingsInput()
     56void UIAutoCaptureKeyboardEditor::retranslateUi()
    89957{
    900     /* Cleanup: */
    901     cleanup();
     58    if (m_pLabel)
     59        m_pLabel->setText(tr("Extended Features:"));
     60    if (m_pCheckBox)
     61    {
     62        m_pCheckBox->setWhatsThis(tr("When checked, the keyboard is automatically captured every time the VM window is "
     63                                     "activated. When the keyboard is captured, all keystrokes (including system ones like "
     64                                     "Alt-Tab) are directed to the VM."));
     65        m_pCheckBox->setText(tr("&Auto Capture Keyboard"));
     66    }
    90267}
    90368
    904 void UIGlobalSettingsInput::loadToCacheFrom(QVariant &data)
     69void UIAutoCaptureKeyboardEditor::prepare()
    90570{
    906     /* Fetch data to properties: */
    907     UISettingsPageGlobal::fetchData(data);
     71    /* Prepare main layout: */
     72    QGridLayout *pLayoutMain = new QGridLayout(this);
     73    if (pLayoutMain)
     74    {
     75        pLayoutMain->setContentsMargins(0, 0, 0, 0);
     76        pLayoutMain->setColumnStretch(1, 1);
     77        int iColumn = 0;
    90878
    909     /* Clear cache initially: */
    910     m_pCache->clear();
    911 
    912     /* Prepare old input data: */
    913     UIDataSettingsGlobalInput oldInputData;
    914 
    915     /* Gather old input data: */
    916     oldInputData.shortcuts() << UIDataShortcutRow(m_pTableRuntime,
    917                                                   UIHostCombo::hostComboCacheKey(),
    918                                                   QString(),
    919                                                   tr("Host Key Combination"),
    920                                                   gEDataManager->hostKeyCombination(),
    921                                                   QString());
    922     const QMap<QString, UIShortcut> &shortcuts = gShortcutPool->shortcuts();
    923     const QList<QString> shortcutKeys = shortcuts.keys();
    924     foreach (const QString &strShortcutKey, shortcutKeys)
    925     {
    926         const UIShortcut &shortcut = shortcuts[strShortcutKey];
    927         QITableView *pParent = strShortcutKey.startsWith(GUI_Input_MachineShortcuts) ? m_pTableRuntime :
    928                                strShortcutKey.startsWith(GUI_Input_SelectorShortcuts) ? m_pTableManager : 0;
    929         AssertPtr(pParent);
    930         oldInputData.shortcuts() << UIDataShortcutRow(pParent,
    931                                                       strShortcutKey,
    932                                                       shortcut.scope(),
    933                                                       UICommon::removeAccelMark(shortcut.description()),
    934                                                       shortcut.primaryToNativeText(),
    935                                                       shortcut.defaultSequence().toString(QKeySequence::NativeText));
     79        /* Prepare label: */
     80        if (m_fWithLabel)
     81        {
     82            m_pLabel = new QLabel(this);
     83            if (m_pLabel)
     84                pLayoutMain->addWidget(m_pLabel, 0, iColumn++);
     85        }
     86        /* Prepare check-box: */
     87        m_pCheckBox = new QCheckBox(this);
     88        if (m_pCheckBox)
     89            pLayoutMain->addWidget(m_pCheckBox, 0, iColumn++);
    93690    }
    937     oldInputData.setAutoCapture(gEDataManager->autoCaptureEnabled());
    938 
    939     /* Cache old input data: */
    940     m_pCache->cacheInitialData(oldInputData);
    941 
    942     /* Upload properties to data: */
    943     UISettingsPageGlobal::uploadData(data);
    944 }
    945 
    946 void UIGlobalSettingsInput::getFromCache()
    947 {
    948     /* Get old input data from the cache: */
    949     const UIDataSettingsGlobalInput &oldInputData = m_pCache->base();
    950 
    951     /* Load old input data from the cache: */
    952     m_pModelManager->load(oldInputData.shortcuts());
    953     m_pModelRuntime->load(oldInputData.shortcuts());
    954     m_pCheckBoxEnableAutoGrab->setChecked(oldInputData.autoCapture());
    955 
    956     /* Revalidate: */
    957     revalidate();
    958 }
    959 
    960 void UIGlobalSettingsInput::putToCache()
    961 {
    962     /* Prepare new input data: */
    963     UIDataSettingsGlobalInput newInputData = m_pCache->base();
    964 
    965     /* Gather new input data: */
    966     m_pModelManager->save(newInputData.shortcuts());
    967     m_pModelRuntime->save(newInputData.shortcuts());
    968     newInputData.setAutoCapture(m_pCheckBoxEnableAutoGrab->isChecked());
    969 
    970     /* Cache new input data: */
    971     m_pCache->cacheCurrentData(newInputData);
    972 }
    973 
    974 void UIGlobalSettingsInput::saveFromCacheTo(QVariant &data)
    975 {
    976     /* Fetch data to properties: */
    977     UISettingsPageGlobal::fetchData(data);
    978 
    979     /* Update input data and failing state: */
    980     setFailed(!saveInputData());
    981 
    982     /* Upload properties to data: */
    983     UISettingsPageGlobal::uploadData(data);
    984 }
    985 
    986 bool UIGlobalSettingsInput::validate(QList<UIValidationMessage> &messages)
    987 {
    988     /* Pass by default: */
    989     bool fPass = true;
    990 
    991     /* Check VirtualBox Manager page for unique shortcuts: */
    992     if (!m_pModelManager->isAllShortcutsUnique())
    993     {
    994         UIValidationMessage message;
    995         message.first = UICommon::removeAccelMark(m_pTabWidget->tabText(UIHotKeyTableIndex_Selector));
    996         message.second << tr("Some items have the same shortcuts assigned.");
    997         messages << message;
    998         fPass = false;
    999     }
    1000 
    1001     /* Check Virtual Machine page for unique shortcuts: */
    1002     if (!m_pModelRuntime->isAllShortcutsUnique())
    1003     {
    1004         UIValidationMessage message;
    1005         message.first = UICommon::removeAccelMark(m_pTabWidget->tabText(UIHotKeyTableIndex_Machine));
    1006         message.second << tr("Some items have the same shortcuts assigned.");
    1007         messages << message;
    1008         fPass = false;
    1009     }
    1010 
    1011     /* Return result: */
    1012     return fPass;
    1013 }
    1014 
    1015 void UIGlobalSettingsInput::setOrderAfter(QWidget *pWidget)
    1016 {
    1017     setTabOrder(pWidget, m_pTabWidget);
    1018     setTabOrder(m_pTabWidget, m_pEditorManagerFilter);
    1019     setTabOrder(m_pEditorManagerFilter, m_pTableManager);
    1020     setTabOrder(m_pTableManager, m_pEditorRuntimeFilter);
    1021     setTabOrder(m_pEditorRuntimeFilter, m_pTableRuntime);
    1022     setTabOrder(m_pTableRuntime, m_pCheckBoxEnableAutoGrab);
    1023 }
    1024 
    1025 void UIGlobalSettingsInput::retranslateUi()
    1026 {
    1027     m_pCheckBoxEnableAutoGrab->setWhatsThis(tr("When checked, the keyboard is automatically captured every time the VM window "
    1028                                                "is activated. When the keyboard is captured, all keystrokes (including system ones "
    1029                                                "like Alt-Tab) are directed to the VM."));
    1030     m_pCheckBoxEnableAutoGrab->setText(tr("&Auto Capture Keyboard"));
    1031 
    1032 
    1033     /* Translate tab-widget labels: */
    1034     m_pTabWidget->setTabText(UIHotKeyTableIndex_Selector, tr("&VirtualBox Manager"));
    1035     m_pTabWidget->setTabText(UIHotKeyTableIndex_Machine, tr("Virtual &Machine"));
    1036     m_pTableManager->setWhatsThis(tr("Lists all available shortcuts which can be configured."));
    1037     m_pTableRuntime->setWhatsThis(tr("Lists all available shortcuts which can be configured."));
    1038     m_pEditorManagerFilter->setWhatsThis(tr("Holds a sequence to filter the shortcut list."));
    1039     m_pEditorRuntimeFilter->setWhatsThis(tr("Holds a sequence to filter the shortcut list."));
    1040 }
    1041 
    1042 void UIGlobalSettingsInput::prepare()
    1043 {
    1044     /* Prepare cache: */
    1045     m_pCache = new UISettingsCacheGlobalInput;
    1046     AssertPtrReturnVoid(m_pCache);
    1047 
    1048     /* Prepare everything: */
    1049     prepareWidgets();
    1050     prepareConnections();
    105191
    105292    /* Apply language settings: */
    105393    retranslateUi();
    105494}
    1055 
    1056 void UIGlobalSettingsInput::prepareWidgets()
    1057 {
    1058     /* Prepare main layout: */
    1059     QGridLayout *pMainLayout = new QGridLayout(this);
    1060     if (pMainLayout)
    1061     {
    1062         /* Prepare tab-widget: */
    1063         m_pTabWidget = new QTabWidget(this);
    1064         if (m_pTabWidget)
    1065         {
    1066             /* Prepare 'Manager UI' tab: */
    1067             prepareTabManager();
    1068             /* Prepare 'Runtime UI' tab: */
    1069             prepareTabMachine();
    1070 
    1071             /* Add tab-widget into layout: */
    1072             pMainLayout->addWidget(m_pTabWidget, 0, 0, 1, 2);
    1073         }
    1074 
    1075         /* Prepare 'enable auto-grab' check-box: */
    1076         m_pCheckBoxEnableAutoGrab = new QCheckBox(this);
    1077         if (m_pCheckBoxEnableAutoGrab)
    1078             pMainLayout->addWidget(m_pCheckBoxEnableAutoGrab, 1, 0);
    1079     }
    1080 }
    1081 
    1082 void UIGlobalSettingsInput::prepareTabManager()
    1083 {
    1084     /* Prepare Manager UI tab: */
    1085     QWidget *pTabManager = new QWidget;
    1086     if (pTabManager)
    1087     {
    1088         /* Prepare Manager UI layout: */
    1089         QVBoxLayout *pLayoutManager = new QVBoxLayout(pTabManager);
    1090         if (pLayoutManager)
    1091         {
    1092             pLayoutManager->setSpacing(1);
    1093 #ifdef VBOX_WS_MAC
    1094             /* On Mac OS X and X11 we can do a bit of smoothness: */
    1095             pLayoutManager->setContentsMargins(0, 0, 0, 0);
    1096 #endif
    1097 
    1098             /* Prepare Manager UI filter editor: */
    1099             m_pEditorManagerFilter = new QLineEdit(pTabManager);
    1100             if (m_pEditorManagerFilter)
    1101                 pLayoutManager->addWidget(m_pEditorManagerFilter);
    1102 
    1103             /* Prepare Manager UI model: */
    1104             m_pModelManager = new UIHotKeyTableModel(this, UIActionPoolType_Manager);
    1105 
    1106             /* Prepare Manager UI table: */
    1107             m_pTableManager = new UIHotKeyTable(pTabManager, m_pModelManager, "m_pTableManager");
    1108             if (m_pTableManager)
    1109                 pLayoutManager->addWidget(m_pTableManager);
    1110         }
    1111 
    1112         m_pTabWidget->insertTab(UIHotKeyTableIndex_Selector, pTabManager, QString());
    1113     }
    1114 }
    1115 
    1116 void UIGlobalSettingsInput::prepareTabMachine()
    1117 {
    1118     /* Create Runtime UI tab: */
    1119     QWidget *pTabMachine = new QWidget;
    1120     if (pTabMachine)
    1121     {
    1122         /* Prepare Runtime UI layout: */
    1123         QVBoxLayout *pLayoutMachine = new QVBoxLayout(pTabMachine);
    1124         if (pLayoutMachine)
    1125         {
    1126             pLayoutMachine->setSpacing(1);
    1127 #ifdef VBOX_WS_MAC
    1128             /* On Mac OS X and X11 we can do a bit of smoothness: */
    1129             pLayoutMachine->setContentsMargins(0, 0, 0, 0);
    1130 #endif
    1131 
    1132             /* Prepare Runtime UI filter editor: */
    1133             m_pEditorRuntimeFilter = new QLineEdit(pTabMachine);
    1134             if (m_pEditorRuntimeFilter)
    1135                 pLayoutMachine->addWidget(m_pEditorRuntimeFilter);
    1136 
    1137             /* Prepare Runtime UI model: */
    1138             m_pModelRuntime = new UIHotKeyTableModel(this, UIActionPoolType_Runtime);
    1139 
    1140             /* Create Runtime UI table: */
    1141             m_pTableRuntime = new UIHotKeyTable(pTabMachine, m_pModelRuntime, "m_pTableRuntime");
    1142             if (m_pTableRuntime)
    1143                 pLayoutMachine->addWidget(m_pTableRuntime);
    1144         }
    1145 
    1146         m_pTabWidget->insertTab(UIHotKeyTableIndex_Machine, pTabMachine, QString());
    1147 
    1148         /* In the VM process we start by displaying the Runtime UI tab: */
    1149         if (uiCommon().uiType() == UICommon::UIType_RuntimeUI)
    1150             m_pTabWidget->setCurrentWidget(pTabMachine);
    1151     }
    1152 }
    1153 
    1154 void UIGlobalSettingsInput::prepareConnections()
    1155 {
    1156     /* Configure 'Manager UI' connections: */
    1157     connect(m_pEditorManagerFilter, &QLineEdit::textChanged, m_pModelManager, &UIHotKeyTableModel::sltHandleFilterTextChange);
    1158     connect(m_pModelManager, &UIHotKeyTableModel::sigRevalidationRequired, this, &UIGlobalSettingsInput::revalidate);
    1159 
    1160     /* Configure 'Runtime UI' connections: */
    1161     connect(m_pEditorRuntimeFilter, &QLineEdit::textChanged, m_pModelRuntime, &UIHotKeyTableModel::sltHandleFilterTextChange);
    1162     connect(m_pModelRuntime, &UIHotKeyTableModel::sigRevalidationRequired, this, &UIGlobalSettingsInput::revalidate);
    1163 }
    1164 
    1165 void UIGlobalSettingsInput::cleanup()
    1166 {
    1167     /* Cleanup cache: */
    1168     delete m_pCache;
    1169     m_pCache = 0;
    1170 }
    1171 
    1172 bool UIGlobalSettingsInput::saveInputData()
    1173 {
    1174     /* Prepare result: */
    1175     bool fSuccess = true;
    1176     /* Save input settings from the cache: */
    1177     if (fSuccess && m_pCache->wasChanged())
    1178     {
    1179         /* Get old input data from the cache: */
    1180         const UIDataSettingsGlobalInput &oldInputData = m_pCache->base();
    1181         /* Get new input data from the cache: */
    1182         const UIDataSettingsGlobalInput &newInputData = m_pCache->data();
    1183 
    1184         /* Save new host-combo shortcut from the cache: */
    1185         const UIDataShortcutRow fakeHostComboItem(0, UIHostCombo::hostComboCacheKey(), QString(), QString(), QString(), QString());
    1186         const int iHostComboItemBase = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(oldInputData.shortcuts(), fakeHostComboItem);
    1187         const int iHostComboItemData = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(newInputData.shortcuts(), fakeHostComboItem);
    1188         const QString strHostComboBase = iHostComboItemBase != -1 ? oldInputData.shortcuts().at(iHostComboItemBase).currentSequence() : QString();
    1189         const QString strHostComboData = iHostComboItemData != -1 ? newInputData.shortcuts().at(iHostComboItemData).currentSequence() : QString();
    1190         if (strHostComboData != strHostComboBase)
    1191             gEDataManager->setHostKeyCombination(strHostComboData);
    1192 
    1193         /* Save other new shortcuts from the cache: */
    1194         QMap<QString, QString> sequencesBase;
    1195         QMap<QString, QString> sequencesData;
    1196         foreach (const UIDataShortcutRow &item, oldInputData.shortcuts())
    1197             sequencesBase.insert(item.key(), item.currentSequence());
    1198         foreach (const UIDataShortcutRow &item, newInputData.shortcuts())
    1199             sequencesData.insert(item.key(), item.currentSequence());
    1200         if (sequencesData != sequencesBase)
    1201             gShortcutPool->setOverrides(sequencesData);
    1202 
    1203         /* Save other new things from the cache: */
    1204         if (newInputData.autoCapture() != oldInputData.autoCapture())
    1205             gEDataManager->setAutoCaptureEnabled(newInputData.autoCapture());
    1206     }
    1207     /* Return result: */
    1208     return fSuccess;
    1209 }
    1210 
    1211 # include "UIGlobalSettingsInput.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UIAutoCaptureKeyboardEditor.h

    r86120 r86124  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIGlobalSettingsInput class declaration.
     3 * VBox Qt GUI - UIAutoCaptureKeyboardEditor class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_settings_global_UIGlobalSettingsInput_h
    19 #define FEQT_INCLUDED_SRC_settings_global_UIGlobalSettingsInput_h
     18#ifndef FEQT_INCLUDED_SRC_settings_editors_UIAutoCaptureKeyboardEditor_h
     19#define FEQT_INCLUDED_SRC_settings_editors_UIAutoCaptureKeyboardEditor_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
     
    2323
    2424/* GUI includes: */
    25 #include "UISettingsPage.h"
     25#include "QIWithRetranslateUI.h"
    2626
    27 /* Forward declartions: */
     27/* Forward declarations: */
    2828class QCheckBox;
    29 class QLineEdit;
    30 class QTabWidget;
    31 class UIDataSettingsGlobalInput;
    32 class UIHotKeyTable;
    33 class UIHotKeyTableModel;
    34 typedef UISettingsCache<UIDataSettingsGlobalInput> UISettingsCacheGlobalInput;
     29class QLabel;
    3530
    36 /** Global settings: Input page. */
    37 class SHARED_LIBRARY_STUFF UIGlobalSettingsInput : public UISettingsPageGlobal
     31/** QWidget subclass used as an auto capture keyboard editor. */
     32class SHARED_LIBRARY_STUFF UIAutoCaptureKeyboardEditor : public QIWithRetranslateUI<QWidget>
    3833{
    3934    Q_OBJECT;
    4035
    41     /** Hot-key table indexes. */
    42     enum { UIHotKeyTableIndex_Selector, UIHotKeyTableIndex_Machine };
    43 
    4436public:
    4537
    46     /** Constructs Input settings page. */
    47     UIGlobalSettingsInput();
    48     /** Destructs Input settings page. */
    49     ~UIGlobalSettingsInput();
     38    /** Constructs auto capture keyboard editor passing @a pParent to the base-class.
     39      * @param  fWithLabel  Brings whether we should add label ourselves. */
     40    UIAutoCaptureKeyboardEditor(QWidget *pParent = 0, bool fWithLabel = false);
     41
     42    /** Defines editor @a fValue. */
     43    void setValue(bool fValue);
     44    /** Returns editor value. */
     45    bool value() const;
    5046
    5147protected:
    52 
    53     /** Loads settings from external object(s) packed inside @a data to cache.
    54       * @note  This task WILL be performed in other than the GUI thread, no widget interactions! */
    55     virtual void loadToCacheFrom(QVariant &data) /* override */;
    56     /** Loads data from cache to corresponding widgets.
    57       * @note  This task WILL be performed in the GUI thread only, all widget interactions here! */
    58     virtual void getFromCache() /* override */;
    59 
    60     /** Saves data from corresponding widgets to cache.
    61       * @note  This task WILL be performed in the GUI thread only, all widget interactions here! */
    62     virtual void putToCache() /* override */;
    63     /** Saves settings from cache to external object(s) packed inside @a data.
    64       * @note  This task WILL be performed in other than the GUI thread, no widget interactions! */
    65     virtual void saveFromCacheTo(QVariant &data) /* overrride */;
    66 
    67     /** Performs validation, updates @a messages list if something is wrong. */
    68     virtual bool validate(QList<UIValidationMessage> &messages) /* override */;
    69 
    70     /** Defines TAB order for passed @a pWidget. */
    71     virtual void setOrderAfter(QWidget *pWidget) /* override */;
    7248
    7349    /** Handles translation event. */
     
    7854    /** Prepares all. */
    7955    void prepare();
    80     /** Prepares widgets. */
    81     void prepareWidgets();
    82     /** Prepares Manager UI tab. */
    83     void prepareTabManager();
    84     /** Prepares Runtime UI tab. */
    85     void prepareTabMachine();
    86     /** Prepares connections. */
    87     void prepareConnections();
    88     /** Cleanups all. */
    89     void cleanup();
    9056
    91     /** Saves existing input data from the cache. */
    92     bool saveInputData();
     57    /** Holds whether descriptive label should be created. */
     58    bool  m_fWithLabel;
    9359
    94     /** Holds the Manager UI shortcuts model instance. */
    95     UIHotKeyTableModel *m_pModelManager;
    96     /** Holds the Runtime UI shortcuts model instance. */
    97     UIHotKeyTableModel *m_pModelRuntime;
     60    /** Holds the value to be set. */
     61    bool  m_fValue;
    9862
    99     /** Holds the page data cache instance. */
    100     UISettingsCacheGlobalInput *m_pCache;
    101 
    102     /** @name Widgets
    103      * @{ */
    104         /** Holds the tab-widget instance. */
    105         QTabWidget    *m_pTabWidget;
    106         /** Holds the Manager UI shortcuts filter instance. */
    107         QLineEdit     *m_pEditorManagerFilter;
    108         /** Holds the Manager UI shortcuts table instance. */
    109         UIHotKeyTable *m_pTableManager;
    110         /** Holds the Runtime UI shortcuts filter instance. */
    111         QLineEdit     *m_pEditorRuntimeFilter;
    112         /** Holds the Runtime UI shortcuts table instance. */
    113         UIHotKeyTable *m_pTableRuntime;
    114         /** Holds the 'enable auto-grab' checkbox instance. */
    115         QCheckBox     *m_pCheckBoxEnableAutoGrab;
    116     /** @} */
     63    /** Holds the label instance. */
     64    QLabel    *m_pLabel;
     65    /** Holds the check-box instance. */
     66    QCheckBox *m_pCheckBox;
    11767};
    11868
    119 #endif /* !FEQT_INCLUDED_SRC_settings_global_UIGlobalSettingsInput_h */
     69#endif /* !FEQT_INCLUDED_SRC_settings_editors_UIAutoCaptureKeyboardEditor_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UIShortcutConfigurationEditor.cpp

    r86120 r86124  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIGlobalSettingsInput class implementation.
     3 * VBox Qt GUI - UIShortcutConfigurationEditor class implementation.
    44 */
    55
     
    1717
    1818/* Qt includes: */
    19 #include <QAbstractItemDelegate>
    20 #include <QCheckBox>
    21 #include <QGridLayout>
    2219#include <QHeaderView>
    2320#include <QItemEditorFactory>
    2421#include <QTabWidget>
     22#include <QVBoxLayout>
    2523
    2624/* GUI includes: */
    2725#include "QIStyledItemDelegate.h"
    2826#include "QITableView.h"
    29 #include "QIWidgetValidator.h"
     27#include "UIActionPool.h"
    3028#include "UICommon.h"
    31 #include "UIActionPool.h"
    32 #include "UIGlobalSettingsInput.h"
     29#include "UIExtraDataManager.h"
    3330#include "UIHostComboEditor.h"
    3431#include "UIHotKeyEditor.h"
     32#include "UIMessageCenter.h"
     33#include "UIShortcutConfigurationEditor.h"
    3534#include "UIShortcutPool.h"
    36 #include "UIExtraDataManager.h"
    37 #include "UIMessageCenter.h"
    38 
    39 /* Qt includes: */
    40 #include <QShortcut>
    41 
    4235
    4336/* Namespaces: */
     
    4538
    4639
    47 /** Column index enumerator. */
    48 enum UIHotKeyColumnIndex
    49 {
    50     UIHotKeyColumnIndex_Description,
    51     UIHotKeyColumnIndex_Sequence,
    52     UIHotKeyColumnIndex_Max
     40/** Table column indexes. */
     41enum TableColumnIndex
     42{
     43    TableColumnIndex_Description,
     44    TableColumnIndex_Sequence,
     45    TableColumnIndex_Max
    5346};
    5447
    5548
    56 /** Global settings: Input page: Shortcut cell data structure. */
    57 class UIDataShortcutCell : public QITableViewCell
     49/** QITableViewCell subclass for shortcut configuration editor. */
     50class UIShortcutTableViewCell : public QITableViewCell
    5851{
    5952    Q_OBJECT;
     
    6154public:
    6255
    63     /** Constructs table cell.
     56    /** Constructs table cell on the basis of passed arguments.
    6457      * @param  pParent  Brings the row this cell belongs too.
    6558      * @param  strText  Brings the text describing this cell. */
    66     UIDataShortcutCell(QITableViewRow *pParent, const QString &strText)
     59    UIShortcutTableViewCell(QITableViewRow *pParent, const QString &strText)
    6760        : QITableViewCell(pParent)
    6861        , m_strText(strText)
     
    7972
    8073
    81 /** Global settings: Input page: Shortcut data structure. */
    82 class UIDataShortcutRow : public QITableViewRow
     74/** QITableViewRow subclass for shortcut configuration editor. */
     75class UIShortcutTableViewRow : public QITableViewRow, public UIShortcutConfigurationItem
    8376{
    8477    Q_OBJECT;
     
    8780
    8881    /** Constructs table row on the basis of passed arguments.
    89       * @param  pParent             Brings the row this cell belongs too.
    90       * @param  strKey              Brings the unique key identifying held sequence.
    91       * @param  strScope            Brings the scope of the held sequence.
    92       * @param  strDescription      Brings the deescription for the held sequence.
    93       * @param  strCurrentSequence  Brings the current held sequence.
    94       * @param  strDefaultSequence  Brings the default held sequence. */
    95     UIDataShortcutRow(QITableView *pParent,
    96                       const QString &strKey,
    97                       const QString &strScope,
    98                       const QString &strDescription,
    99                       const QString &strCurrentSequence,
    100                       const QString &strDefaultSequence)
     82      * @param  pParent  Brings the table this row belongs too.
     83      * @param  item     Brings the item this row is based on. */
     84    UIShortcutTableViewRow(QITableView *pParent = 0, const UIShortcutConfigurationItem &item = UIShortcutConfigurationItem())
    10185        : QITableViewRow(pParent)
    102         , m_strKey(strKey)
    103         , m_strScope(strScope)
    104         , m_strDescription(strDescription)
    105         , m_strCurrentSequence(strCurrentSequence)
    106         , m_strDefaultSequence(strDefaultSequence)
    107     {
    108         /* Create cells: */
     86        , UIShortcutConfigurationItem(item)
     87    {
    10988        createCells();
    11089    }
    11190
    112     /** Constructs table row on the basis of @a other one. */
    113     UIDataShortcutRow(const UIDataShortcutRow &other)
    114         : QITableViewRow(other.table())
    115         , m_strKey(other.key())
    116         , m_strScope(other.scope())
    117         , m_strDescription(other.description())
    118         , m_strCurrentSequence(other.currentSequence())
    119         , m_strDefaultSequence(other.defaultSequence())
    120     {
    121         /* Create cells: */
     91    /** Constructs table row on the basis of @a another one. */
     92    UIShortcutTableViewRow(const UIShortcutTableViewRow &another)
     93        : QITableViewRow(another.table())
     94        , UIShortcutConfigurationItem(another)
     95    {
    12296        createCells();
    12397    }
    12498
    12599    /** Destructs table row. */
    126     ~UIDataShortcutRow()
    127     {
    128         /* Destroy cells: */
     100    virtual ~UIShortcutTableViewRow() /* override */
     101    {
    129102        destroyCells();
    130103    }
    131104
    132     /** Copies a table row from @a other one. */
    133     UIDataShortcutRow &operator=(const UIDataShortcutRow &other)
     105    /** Copies a table row from @a another one. */
     106    UIShortcutTableViewRow &operator=(const UIShortcutTableViewRow &another)
    134107    {
    135108        /* Reassign variables: */
    136         setTable(other.table());
    137         m_strKey = other.key();
    138         m_strScope = other.scope();
    139         m_strDescription = other.description();
    140         m_strCurrentSequence = other.currentSequence();
    141         m_strDefaultSequence = other.defaultSequence();
     109        setTable(another.table());
     110        UIShortcutConfigurationItem::operator=(another);
    142111
    143112        /* Recreate cells: */
     
    149118    }
    150119
    151     /** Returns whether this row equals to @a other. */
    152     bool operator==(const UIDataShortcutRow &other) const
    153     {
    154         /* Compare by the key and the current sequence: */
    155         return true
    156                && (m_strKey == other.key())
    157                && (m_strScope == other.scope())
    158                && (m_strCurrentSequence == other.currentSequence())
    159                ;
    160     }
    161 
    162     /** Returns the key. */
    163     QString key() const { return m_strKey; }
    164     /** Returns the scope. */
    165     QString scope() const { return m_strScope; }
    166     /** Returns the description. */
    167     QString description() const { return m_strDescription; }
    168     /** Returns the current sequence. */
    169     QString currentSequence() const { return m_strCurrentSequence; }
    170     /** Returns the default sequence. */
    171     QString defaultSequence() const { return m_strDefaultSequence; }
    172 
    173     /** Defines @a strCurrentSequence. */
    174     void setCurrentSequence(const QString &strCurrentSequence) { m_strCurrentSequence = strCurrentSequence; }
     120    /** Returns whether this row equals to @a another one. */
     121    bool operator==(const UIShortcutTableViewRow &another) const
     122    {
     123        /* Compare variables: */
     124        return UIShortcutConfigurationItem::operator==(another);
     125    }
    175126
    176127protected:
     
    179130    virtual int childCount() const /* override */
    180131    {
    181         return UIHotKeyColumnIndex_Max;
     132        return TableColumnIndex_Max;
    182133    }
    183134
     
    187138        switch (iIndex)
    188139        {
    189             case UIHotKeyColumnIndex_Description: return m_cells.first;
    190             case UIHotKeyColumnIndex_Sequence: return m_cells.second;
     140            case TableColumnIndex_Description: return m_cells.first;
     141            case TableColumnIndex_Sequence: return m_cells.second;
    191142            default: break;
    192143        }
     
    200151    {
    201152        /* Create cells on the basis of description and current sequence: */
    202         m_cells = qMakePair(new UIDataShortcutCell(this, m_strDescription),
    203                             new UIDataShortcutCell(this, m_strCurrentSequence));
     153        m_cells = qMakePair(new UIShortcutTableViewCell(this, description()),
     154                            new UIShortcutTableViewCell(this, currentSequence()));
    204155    }
    205156
     
    214165    }
    215166
    216     /** Holds the key. */
    217     QString m_strKey;
    218     /** Holds the scope. */
    219     QString m_strScope;
    220     /** Holds the description. */
    221     QString m_strDescription;
    222     /** Holds the current sequence. */
    223     QString m_strCurrentSequence;
    224     /** Holds the default sequence. */
    225     QString m_strDefaultSequence;
    226 
    227167    /** Holds the cell instances. */
    228     QPair<UIDataShortcutCell*, UIDataShortcutCell*> m_cells;
     168    QPair<UIShortcutTableViewCell*, UIShortcutTableViewCell*> m_cells;
    229169};
    230 typedef QList<UIDataShortcutRow> UIShortcutCache;
    231 
    232 
    233 /** Global settings: Input page data structure. */
    234 class UIDataSettingsGlobalInput
     170
     171/** Shortcut configuration editor row list. */
     172typedef QList<UIShortcutTableViewRow> UIShortcutTableViewContent;
     173
     174
     175/** Shortcut item sorting functor. */
     176class UIShortcutItemSortingFunctor
    235177{
    236178public:
    237179
    238     /** Constructs cache. */
    239     UIDataSettingsGlobalInput()
    240         : m_fAutoCapture(false)
     180    /** Constructs shortcut item sorting functor.
     181      * @param  iColumn     Brings the column sorting should be done according to.
     182      * @param  m_enmOrder  Brings the sorting order to be applied. */
     183    UIShortcutItemSortingFunctor(int iColumn, Qt::SortOrder enmOrder)
     184        : m_iColumn(iColumn)
     185        , m_enmOrder(enmOrder)
    241186    {}
    242187
    243     /** Returns the shortcuts cache [full access]. */
    244     UIShortcutCache &shortcuts() { return m_shortcuts; }
    245     /** Returns the shortcuts cache [read-only access]. */
    246     const UIShortcutCache &shortcuts() const { return m_shortcuts; }
    247 
    248     /** Defines whether the keyboard auto-capture is @a fEnabled. */
    249     void setAutoCapture(bool fEnabled) { m_fAutoCapture = fEnabled; }
    250     /** Returns whether the keyboard auto-capture is enabled. */
    251     bool autoCapture() const { return m_fAutoCapture; }
    252 
    253     /** Returns whether the @a other passed data is equal to this one. */
    254     bool equal(const UIDataSettingsGlobalInput &other) const
    255     {
    256         return (m_shortcuts == other.m_shortcuts) &&
    257                (m_fAutoCapture == other.m_fAutoCapture);
    258     }
    259 
    260     /** Returns whether the @a other passed data is equal to this one. */
    261     bool operator==(const UIDataSettingsGlobalInput &other) const { return equal(other); }
    262     /** Returns whether the @a other passed data is different from this one. */
    263     bool operator!=(const UIDataSettingsGlobalInput &other) const { return !equal(other); }
     188    /** Returns whether the @a item1 is more/less than the @a item2.
     189      * @note  Order depends on the one set through constructor, stored in m_enmOrder. */
     190    bool operator()(const UIShortcutTableViewRow &item1, const UIShortcutTableViewRow &item2)
     191    {
     192        switch (m_iColumn)
     193        {
     194            case TableColumnIndex_Description:
     195                return   m_enmOrder == Qt::AscendingOrder
     196                       ? item1.description() < item2.description()
     197                       : item1.description() > item2.description();
     198            case TableColumnIndex_Sequence:
     199                return   m_enmOrder == Qt::AscendingOrder
     200                       ? item1.currentSequence() < item2.currentSequence()
     201                       : item1.currentSequence() > item2.currentSequence();
     202            default:
     203                break;
     204        }
     205        return   m_enmOrder == Qt::AscendingOrder
     206               ? item1.key() < item2.key()
     207               : item1.key() > item2.key();
     208    }
    264209
    265210private:
    266211
    267     /** Holds the shortcut cache. */
    268     UIShortcutCache m_shortcuts;
    269 
    270     /** Holds whether the keyboard auto-capture is enabled. */
    271     bool m_fAutoCapture;
     212    /** Holds the column sorting should be done according to. */
     213    int            m_iColumn;
     214    /** Holds the sorting order to be applied. */
     215    Qt::SortOrder  m_enmOrder;
    272216};
    273217
    274218
    275 /** Global settings: Input page: Shortcut cache sort functor. */
    276 class UIShortcutCacheItemFunctor
    277 {
     219/** QAbstractTableModel subclass representing shortcut configuration model. */
     220class UIShortcutConfigurationModel : public QAbstractTableModel
     221{
     222    Q_OBJECT;
     223
     224signals:
     225
     226    /** Notifies about shortcuts loaded. */
     227    void sigShortcutsLoaded();
     228    /** Notifies about data changed. */
     229    void sigDataChanged();
     230
    278231public:
    279232
    280     /** Constructs cache sorting functor.
    281       * @param  iColumn  Brings the column sorting should be done according to.
    282       * @param  m_order  Brings the sorting order to be applied. */
    283     UIShortcutCacheItemFunctor(int iColumn, Qt::SortOrder order)
    284         : m_iColumn(iColumn)
    285         , m_order(order)
    286     {}
    287 
    288     /** Returns whether the @a item1 is more/less than the @a item2.
    289       * @note  Order depends on the one set through constructor, stored in m_order. */
    290     bool operator()(const UIDataShortcutRow &item1, const UIDataShortcutRow &item2)
    291     {
    292         switch (m_iColumn)
    293         {
    294             case UIHotKeyColumnIndex_Description:
    295                 return m_order == Qt::AscendingOrder ? item1.description() < item2.description() : item1.description() > item2.description();
    296             case UIHotKeyColumnIndex_Sequence:
    297                 return m_order == Qt::AscendingOrder ? item1.currentSequence() < item2.currentSequence() : item1.currentSequence() > item2.currentSequence();
    298             default: break;
    299         }
    300         return m_order == Qt::AscendingOrder ? item1.key() < item2.key() : item1.key() > item2.key();
    301     }
    302 
    303 private:
    304 
    305     /** Holds the column sorting should be done according to. */
    306     int m_iColumn;
    307     /** Holds the sorting order to be applied. */
    308     Qt::SortOrder m_order;
    309 };
    310 
    311 
    312 /** Global settings: Input page: Shortcut search functor. */
    313 class UIFunctorFindShortcut
    314 {
    315 public:
    316 
    317     /** Search match level enumerator. */
    318     enum UIMatchLevel { Base, Full };
    319 
    320     /** Constructs shortcut search functor.
    321       * @param  matchLevel  Brings the search match level. */
    322     UIFunctorFindShortcut(UIMatchLevel enmMatchLevel)
    323         : m_enmMatchLevel(enmMatchLevel)
    324     {}
    325 
    326     /** Returns the position of the 1st occurrence of the
    327       * @a shortcut in the @a shortcuts list, or -1 otherwise. */
    328     int operator()(const UIShortcutCache &shortcuts, const UIDataShortcutRow &shortcut)
    329     {
    330         for (int i = 0; i < shortcuts.size(); ++i)
    331         {
    332             const UIDataShortcutRow &iteratedShortcut = shortcuts.at(i);
    333             switch (m_enmMatchLevel)
    334             {
    335                 case Base:
    336                 {
    337                     if (iteratedShortcut.key() == shortcut.key())
    338                         return i;
    339                     break;
    340                 }
    341                 case Full:
    342                 {
    343                     if (   iteratedShortcut.key() == shortcut.key()
    344                         && iteratedShortcut.currentSequence() == shortcut.currentSequence())
    345                         return i;
    346                     break;
    347                 }
    348             }
    349         }
    350         return -1;
    351     }
    352 
    353 private:
    354 
    355     /** Holds the search match level. */
    356     const UIMatchLevel m_enmMatchLevel;
    357 };
    358 
    359 
    360 /* A model representing hot-key combination table: */
    361 class UIHotKeyTableModel : public QAbstractTableModel
    362 {
    363     Q_OBJECT;
    364 
    365 signals:
    366 
    367     /* Notifier: Readiness stuff: */
    368     void sigShortcutsLoaded();
    369 
    370     /* Notifier: Validation stuff: */
    371     void sigRevalidationRequired();
    372 
    373 public:
    374 
    375     /* Constructor: */
    376     UIHotKeyTableModel(QObject *pParent, UIActionPoolType type);
     233    /** Constructs model passing @a pParent to the base-class.
     234      * @param  enmType  Brings the action-pool type this model is related to. */
     235    UIShortcutConfigurationModel(QObject *pParent, UIActionPoolType enmType);
     236
     237    /** Defines the parent @a pTable reference. */
     238    void setTable(UIShortcutConfigurationTable *pTable);
    377239
    378240    /** Returns the number of children. */
     
    381243    QITableViewRow *childItem(int iIndex);
    382244
    383     /* API: Loading/saving stuff: */
    384     void load(const UIShortcutCache &shortcuts);
    385     void save(UIShortcutCache &shortcuts);
    386 
    387     /* API: Validation stuff: */
     245    /** Loads a @a list of shortcuts to the model. */
     246    void load(const UIShortcutConfigurationList &list);
     247    /** Saves the model shortcuts to a @a list. */
     248    void save(UIShortcutConfigurationList &list);
     249
     250    /** Returns whether all shortcuts unique. */
    388251    bool isAllShortcutsUnique();
    389252
    390253public slots:
    391254
    392     /* Handler: Filtering stuff: */
     255    /** Handle filtering @a strText change. */
    393256    void sltHandleFilterTextChange(const QString &strText);
    394257
     258protected:
     259
     260    /** Returns the number of rows under the given @a parent. */
     261    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const /* override */;
     262    /** Returns the number of columns under the given @a parent. */
     263    virtual int columnCount(const QModelIndex &parent = QModelIndex()) const /* override */;
     264
     265    /** Returns the item flags for the given @a index. */
     266    virtual Qt::ItemFlags flags(const QModelIndex &index) const /* override */;
     267    /** Returns the data for the given @a iRole and @a iSection in the header with the specified @a enmOrientation. */
     268    virtual QVariant headerData(int iSection, Qt::Orientation enmOrientation, int iRole = Qt::DisplayRole) const /* override */;
     269    /** Returns the data stored under the given @a iRole for the item referred to by the @a index. */
     270    virtual QVariant data(const QModelIndex &index, int iRole = Qt::DisplayRole) const /* override */;
     271    /** Sets the @a iRole data for the item at @a index to @a value. */
     272    virtual bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole) /* override */;
     273
     274    /** Sorts the model by @a iColumn in the given @a enmOrder. */
     275    virtual void sort(int iColumn, Qt::SortOrder enmOrder = Qt::AscendingOrder) /* override */;
     276
    395277private:
    396278
    397     /* Internal API: Size stuff: */
    398     int rowCount(const QModelIndex &parent = QModelIndex()) const;
    399     int columnCount(const QModelIndex &parent = QModelIndex()) const;
    400 
    401     /* Internal API: Data stuff: */
    402     Qt::ItemFlags flags(const QModelIndex &index) const;
    403     QVariant headerData(int iSection, Qt::Orientation orientation, int iRole = Qt::DisplayRole) const;
    404     QVariant data(const QModelIndex &index, int iRole = Qt::DisplayRole) const;
    405     bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole);
    406 
    407     /* Internal API: Sorting stuff: */
    408     void sort(int iColumn, Qt::SortOrder order = Qt::AscendingOrder);
    409 
    410     /* Helper: Filtering stuff: */
     279    /** Applies filter. */
    411280    void applyFilter();
    412281
    413     /* Variables: */
    414     UIActionPoolType m_type;
    415     QString m_strFilter;
    416     UIShortcutCache m_shortcuts;
    417     UIShortcutCache m_filteredShortcuts;
    418     QSet<QString> m_duplicatedSequences;
     282    /** Holds the action-pool type this model is related to. */
     283    UIActionPoolType  m_enmType;
     284
     285    /** Holds the parent table reference. */
     286    UIShortcutConfigurationTable *m_pTable;
     287
     288    /** Holds current filter. */
     289    QString  m_strFilter;
     290
     291    /** Holds current shortcut list. */
     292    UIShortcutTableViewContent  m_shortcuts;
     293    /** Holds current filtered shortcut list. */
     294    UIShortcutTableViewContent  m_filteredShortcuts;
     295
     296    /** Holds a set of currently duplicated sequences. */
     297    QSet<QString>  m_duplicatedSequences;
    419298};
    420299
    421300
    422 /* A table reflecting hot-key combinations: */
    423 class UIHotKeyTable : public QITableView
     301/** QITableView subclass representing shortcut configuration table. */
     302class UIShortcutConfigurationTable : public QITableView
    424303{
    425304    Q_OBJECT;
     
    427306public:
    428307
    429     /* Constructor: */
    430     UIHotKeyTable(QWidget *pParent, UIHotKeyTableModel *pModel, const QString &strObjectName);
     308    /** Constructs table passing @a pParent to the base-class.
     309      * @param  pModel         Brings the model this table is bound to.
     310      * @param  strObjectName  Brings the object name this table has, required for fast referencing. */
     311    UIShortcutConfigurationTable(QWidget *pParent, UIShortcutConfigurationModel *pModel, const QString &strObjectName);
    431312
    432313protected:
     
    439320private slots:
    440321
    441     /* Handler: Readiness stuff: */
     322    /** Handles shortcuts loaded signal. */
    442323    void sltHandleShortcutsLoaded();
    443324
     
    450331
    451332/*********************************************************************************************************************************
    452 *   Class UIHotKeyTableModel implementation.                                                                                     *
     333*   Class UIShortcutConfigurationModel implementation.                                                                           *
    453334*********************************************************************************************************************************/
    454335
    455 UIHotKeyTableModel::UIHotKeyTableModel(QObject *pParent, UIActionPoolType type)
     336UIShortcutConfigurationModel::UIShortcutConfigurationModel(QObject *pParent, UIActionPoolType enmType)
    456337    : QAbstractTableModel(pParent)
    457     , m_type(type)
    458 {
    459 }
    460 
    461 int UIHotKeyTableModel::childCount() const
     338    , m_enmType(enmType)
     339    , m_pTable(0)
     340{
     341}
     342
     343void UIShortcutConfigurationModel::setTable(UIShortcutConfigurationTable *pTable)
     344{
     345    m_pTable = pTable;
     346}
     347
     348int UIShortcutConfigurationModel::childCount() const
    462349{
    463350    /* Return row count: */
     
    465352}
    466353
    467 QITableViewRow *UIHotKeyTableModel::childItem(int iIndex)
    468 {
    469     /* Make sure index within the bounds: */
     354QITableViewRow *UIShortcutConfigurationModel::childItem(int iIndex)
     355{
     356    /* Make sure index is within the bounds: */
    470357    AssertReturn(iIndex >= 0 && iIndex < m_filteredShortcuts.size(), 0);
    471358    /* Return corresponding filtered row: */
     
    473360}
    474361
    475 void UIHotKeyTableModel::load(const UIShortcutCache &shortcuts)
    476 {
    477     /* Load shortcuts: */
    478     foreach (const UIDataShortcutRow &item, shortcuts)
    479     {
    480         /* Filter out unnecessary shortcuts: */
    481         if ((m_type == UIActionPoolType_Manager && item.key().startsWith(GUI_Input_MachineShortcuts)) ||
    482             (m_type == UIActionPoolType_Runtime && item.key().startsWith(GUI_Input_SelectorShortcuts)))
     362void UIShortcutConfigurationModel::load(const UIShortcutConfigurationList &list)
     363{
     364    /* Load a list of passed shortcuts: */
     365    foreach (const UIShortcutConfigurationItem &item, list)
     366    {
     367        /* Filter out unnecessary items: */
     368        if (   (m_enmType == UIActionPoolType_Manager && item.key().startsWith(GUI_Input_MachineShortcuts))
     369            || (m_enmType == UIActionPoolType_Runtime && item.key().startsWith(GUI_Input_SelectorShortcuts)))
    483370            continue;
    484         /* Load shortcut cache item into model: */
    485         m_shortcuts << item;
     371        /* Add suitable item to the model as a new shortcut: */
     372        m_shortcuts << UIShortcutTableViewRow(m_pTable, item);
    486373    }
    487374    /* Apply filter: */
     
    491378}
    492379
    493 void UIHotKeyTableModel::save(UIShortcutCache &shortcuts)
    494 {
    495     /* Save model items: */
    496     foreach (const UIDataShortcutRow &item, m_shortcuts)
    497     {
    498         /* Search for corresponding cache item index: */
    499         int iIndexOfCacheItem = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(shortcuts, item);
    500         /* Make sure index is valid: */
    501         if (iIndexOfCacheItem == -1)
     380void UIShortcutConfigurationModel::save(UIShortcutConfigurationList &list)
     381{
     382    /* Save cached model shortcuts: */
     383    foreach (const UIShortcutTableViewRow &row, m_shortcuts)
     384    {
     385        const UIShortcutConfigurationItem &item = row;
     386
     387        /* Search for corresponding item position: */
     388        const int iShortcutItemPosition = UIShortcutSearchFunctor<UIShortcutConfigurationItem>()(list, item);
     389        /* Make sure position is valid: */
     390        if (iShortcutItemPosition == -1)
    502391            continue;
    503         /* Save model item into the cache: */
    504         shortcuts[iIndexOfCacheItem] = item;
    505     }
    506 }
    507 
    508 bool UIHotKeyTableModel::isAllShortcutsUnique()
     392        /* Save cached model shortcut to a list: */
     393        list[iShortcutItemPosition] = item;
     394    }
     395}
     396
     397bool UIShortcutConfigurationModel::isAllShortcutsUnique()
    509398{
    510399    /* Enumerate all the sequences: */
    511400    QMap<QString, QString> usedSequences;
    512     foreach (const UIDataShortcutRow &item, m_shortcuts)
     401    foreach (const UIShortcutTableViewRow &item, m_shortcuts)
    513402    {
    514403        QString strKey = item.currentSequence();
     
    538427}
    539428
    540 void UIHotKeyTableModel::sltHandleFilterTextChange(const QString &strText)
     429void UIShortcutConfigurationModel::sltHandleFilterTextChange(const QString &strText)
    541430{
    542431    m_strFilter = strText;
     
    544433}
    545434
    546 int UIHotKeyTableModel::rowCount(const QModelIndex& /*parent = QModelIndex()*/) const
     435int UIShortcutConfigurationModel::rowCount(const QModelIndex& /* parent = QModelIndex() */) const
    547436{
    548437    return m_filteredShortcuts.size();
    549438}
    550439
    551 int UIHotKeyTableModel::columnCount(const QModelIndex& /*parent = QModelIndex()*/) const
    552 {
    553     return 2;
    554 }
    555 
    556 Qt::ItemFlags UIHotKeyTableModel::flags(const QModelIndex &index) const
     440int UIShortcutConfigurationModel::columnCount(const QModelIndex& /* parent = QModelIndex() */) const
     441{
     442    return TableColumnIndex_Max;
     443}
     444
     445Qt::ItemFlags UIShortcutConfigurationModel::flags(const QModelIndex &index) const
    557446{
    558447    /* No flags for invalid index: */
    559     if (!index.isValid()) return Qt::NoItemFlags;
     448    if (!index.isValid())
     449        return Qt::NoItemFlags;
    560450    /* Switch for different columns: */
    561451    switch (index.column())
    562452    {
    563         case UIHotKeyColumnIndex_Description: return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    564         case UIHotKeyColumnIndex_Sequence: return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
     453        case TableColumnIndex_Description: return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
     454        case TableColumnIndex_Sequence: return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
    565455        default: break;
    566456    }
     
    569459}
    570460
    571 QVariant UIHotKeyTableModel::headerData(int iSection, Qt::Orientation orientation, int iRole /* = Qt::DisplayRole*/) const
     461QVariant UIShortcutConfigurationModel::headerData(int iSection,
     462                                                  Qt::Orientation enmOrientation,
     463                                                  int iRole /* = Qt::DisplayRole */) const
    572464{
    573465    /* Switch for different roles: */
     
    577469        {
    578470            /* Invalid for vertical header: */
    579             if (orientation == Qt::Vertical) return QString();
     471            if (enmOrientation == Qt::Vertical)
     472                return QString();
    580473            /* Switch for different columns: */
    581474            switch (iSection)
    582475            {
    583                 case UIHotKeyColumnIndex_Description: return tr("Name");
    584                 case UIHotKeyColumnIndex_Sequence: return tr("Shortcut");
     476                case TableColumnIndex_Description: return tr("Name");
     477                case TableColumnIndex_Sequence: return tr("Shortcut");
    585478                default: break;
    586479            }
     
    588481            return QString();
    589482        }
    590         default: break;
     483        default:
     484            break;
    591485    }
    592486    /* Invalid by default: */
     
    594488}
    595489
    596 QVariant UIHotKeyTableModel::data(const QModelIndex &index, int iRole /* = Qt::DisplayRole*/) const
     490QVariant UIShortcutConfigurationModel::data(const QModelIndex &index, int iRole /* = Qt::DisplayRole */) const
    597491{
    598492    /* No data for invalid index: */
    599     if (!index.isValid()) return QVariant();
    600     int iIndex = index.row();
     493    if (!index.isValid())
     494        return QVariant();
     495    const int iIndex = index.row();
    601496    /* Switch for different roles: */
    602497    switch (iRole)
     
    607502            switch (index.column())
    608503            {
    609                 case UIHotKeyColumnIndex_Description:
     504                case TableColumnIndex_Description:
    610505                {
    611506                    /* Return shortcut scope and description: */
     
    614509                    return strScope.isNull() ? strDescription : tr("%1: %2", "scope: description").arg(strScope, strDescription);
    615510                }
    616                 case UIHotKeyColumnIndex_Sequence:
     511                case TableColumnIndex_Sequence:
    617512                {
    618513                    /* If that is host-combo cell: */
     
    623518                    QString strHotCombo = m_filteredShortcuts[iIndex].currentSequence();
    624519                    /* But if that is machine table and hot-combo is not empty: */
    625                     if (m_type == UIActionPoolType_Runtime && !strHotCombo.isEmpty())
     520                    if (m_enmType == UIActionPoolType_Runtime && !strHotCombo.isEmpty())
    626521                        /* We should prepend it with Host+ prefix: */
    627522                        strHotCombo.prepend(UIHostCombo::hostComboModifierName());
     
    639534            switch (index.column())
    640535            {
    641                 case UIHotKeyColumnIndex_Sequence: return m_filteredShortcuts[iIndex].key() == UIHostCombo::hostComboCacheKey() ?
    642                                                           QVariant::fromValue(UIHostComboWrapper(m_filteredShortcuts[iIndex].currentSequence())) :
    643                                                           QVariant::fromValue(UIHotKey(m_type == UIActionPoolType_Runtime ?
    644                                                                                        UIHotKeyType_Simple : UIHotKeyType_WithModifiers,
    645                                                                                        m_filteredShortcuts[iIndex].currentSequence(),
    646                                                                                        m_filteredShortcuts[iIndex].defaultSequence()));
    647                 default: break;
     536                case TableColumnIndex_Sequence:
     537                    return   m_filteredShortcuts[iIndex].key() == UIHostCombo::hostComboCacheKey()
     538                           ? QVariant::fromValue(UIHostComboWrapper(m_filteredShortcuts[iIndex].currentSequence()))
     539                           : QVariant::fromValue(UIHotKey(  m_enmType == UIActionPoolType_Runtime
     540                                                          ? UIHotKeyType_Simple
     541                                                          : UIHotKeyType_WithModifiers,
     542                                                          m_filteredShortcuts[iIndex].currentSequence(),
     543                                                          m_filteredShortcuts[iIndex].defaultSequence()));
     544                default:
     545                    break;
    648546            }
    649547            /* Invalid for other cases: */
     
    657555            switch (index.column())
    658556            {
    659                 case UIHotKeyColumnIndex_Sequence:
     557                case TableColumnIndex_Sequence:
    660558                {
    661                     if (m_filteredShortcuts[iIndex].key() != UIHostCombo::hostComboCacheKey() &&
    662                         m_filteredShortcuts[iIndex].currentSequence() != m_filteredShortcuts[iIndex].defaultSequence())
     559                    if (   m_filteredShortcuts[iIndex].key() != UIHostCombo::hostComboCacheKey()
     560                        && m_filteredShortcuts[iIndex].currentSequence() != m_filteredShortcuts[iIndex].defaultSequence())
    663561                        font.setBold(true);
    664562                    break;
     
    674572            switch (index.column())
    675573            {
    676                 case UIHotKeyColumnIndex_Sequence:
     574                case TableColumnIndex_Sequence:
    677575                {
    678576                    if (m_duplicatedSequences.contains(m_filteredShortcuts[iIndex].key()))
     
    691589}
    692590
    693 bool UIHotKeyTableModel::setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole*/)
     591bool UIShortcutConfigurationModel::setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole */)
    694592{
    695593    /* Nothing to set for invalid index: */
    696     if (!index.isValid()) return false;
     594    if (!index.isValid())
     595        return false;
    697596    /* Switch for different roles: */
    698597    switch (iRole)
     
    703602            switch (index.column())
    704603            {
    705                 case UIHotKeyColumnIndex_Sequence:
     604                case TableColumnIndex_Sequence:
    706605                {
    707606                    /* Get index: */
    708                     int iIndex = index.row();
     607                    const int iIndex = index.row();
    709608                    /* Set sequence to shortcut: */
    710                     UIDataShortcutRow &filteredShortcut = m_filteredShortcuts[iIndex];
    711                     int iShortcutIndex = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(m_shortcuts, filteredShortcut);
     609                    UIShortcutTableViewRow &filteredShortcut = m_filteredShortcuts[iIndex];
     610                    const int iShortcutIndex = UIShortcutSearchFunctor<UIShortcutTableViewRow>()(m_shortcuts, filteredShortcut);
    712611                    if (iShortcutIndex != -1)
    713612                    {
    714                         filteredShortcut.setCurrentSequence(filteredShortcut.key() == UIHostCombo::hostComboCacheKey() ?
    715                                                             value.value<UIHostComboWrapper>().toString() :
    716                                                             value.value<UIHotKey>().sequence());
     613                        filteredShortcut.setCurrentSequence(  filteredShortcut.key() == UIHostCombo::hostComboCacheKey()
     614                                                            ? value.value<UIHostComboWrapper>().toString()
     615                                                            : value.value<UIHotKey>().sequence());
    717616                        m_shortcuts[iShortcutIndex] = filteredShortcut;
    718                         emit sigRevalidationRequired();
     617                        emit sigDataChanged();
    719618                        return true;
    720619                    }
    721620                    break;
    722621                }
    723                 default: break;
     622                default:
     623                    break;
    724624            }
    725625            break;
    726626        }
    727         default: break;
     627        default:
     628            break;
    728629    }
    729630    /* Nothing to set by default: */
     
    731632}
    732633
    733 void UIHotKeyTableModel::sort(int iColumn, Qt::SortOrder order /* = Qt::AscendingOrder*/)
     634void UIShortcutConfigurationModel::sort(int iColumn, Qt::SortOrder order /* = Qt::AscendingOrder */)
    734635{
    735636    /* Sort whole the list: */
    736     qStableSort(m_shortcuts.begin(), m_shortcuts.end(), UIShortcutCacheItemFunctor(iColumn, order));
     637    qStableSort(m_shortcuts.begin(), m_shortcuts.end(), UIShortcutItemSortingFunctor(iColumn, order));
    737638    /* Make sure host-combo item is always the first one: */
    738     UIDataShortcutRow fakeHostComboItem(0, UIHostCombo::hostComboCacheKey(), QString(), QString(), QString(), QString());
    739     int iIndexOfHostComboItem = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(m_shortcuts, fakeHostComboItem);
     639    UIShortcutConfigurationItem fakeHostComboItem(UIHostCombo::hostComboCacheKey(), QString(), QString(), QString(), QString());
     640    UIShortcutTableViewRow fakeHostComboTableViewRow(0, fakeHostComboItem);
     641    const int iIndexOfHostComboItem = UIShortcutSearchFunctor<UIShortcutTableViewRow>()(m_shortcuts, fakeHostComboTableViewRow);
    740642    if (iIndexOfHostComboItem != -1)
    741643    {
    742         UIDataShortcutRow hostComboItem = m_shortcuts.takeAt(iIndexOfHostComboItem);
     644        UIShortcutTableViewRow hostComboItem = m_shortcuts.takeAt(iIndexOfHostComboItem);
    743645        m_shortcuts.prepend(hostComboItem);
    744646    }
     
    749651}
    750652
    751 void UIHotKeyTableModel::applyFilter()
     653void UIShortcutConfigurationModel::applyFilter()
    752654{
    753655    /* Erase items first if necessary: */
     
    768670    {
    769671        /* Check if the description matches the filter: */
    770         foreach (const UIDataShortcutRow &item, m_shortcuts)
     672        foreach (const UIShortcutTableViewRow &item, m_shortcuts)
    771673        {
    772674            /* If neither scope nor description or sequence matches the filter, skip item: */
    773             if (!item.scope().contains(m_strFilter, Qt::CaseInsensitive) &&
    774                 !item.description().contains(m_strFilter, Qt::CaseInsensitive) &&
    775                 !item.currentSequence().contains(m_strFilter, Qt::CaseInsensitive))
     675            if (   !item.scope().contains(m_strFilter, Qt::CaseInsensitive)
     676                && !item.description().contains(m_strFilter, Qt::CaseInsensitive)
     677                && !item.currentSequence().contains(m_strFilter, Qt::CaseInsensitive))
    776678                continue;
    777679            /* Add that item: */
     
    790692
    791693/*********************************************************************************************************************************
    792 *   Class UIHotKeyTable implementation.                                                                                          *
     694*   Class UIShortcutConfigurationTable implementation.                                                                           *
    793695*********************************************************************************************************************************/
    794696
    795 UIHotKeyTable::UIHotKeyTable(QWidget *pParent, UIHotKeyTableModel *pModel, const QString &strObjectName)
     697UIShortcutConfigurationTable::UIShortcutConfigurationTable(QWidget *pParent,
     698                                                           UIShortcutConfigurationModel *pModel,
     699                                                           const QString &strObjectName)
    796700    : QITableView(pParent)
    797701{
     
    805709}
    806710
    807 int UIHotKeyTable::childCount() const
     711int UIShortcutConfigurationTable::childCount() const
    808712{
    809713    /* Redirect request to table model: */
    810     return qobject_cast<UIHotKeyTableModel*>(model())->childCount();
    811 }
    812 
    813 QITableViewRow *UIHotKeyTable::childItem(int iIndex) const
     714    return qobject_cast<UIShortcutConfigurationModel*>(model())->childCount();
     715}
     716
     717QITableViewRow *UIShortcutConfigurationTable::childItem(int iIndex) const
    814718{
    815719    /* Redirect request to table model: */
    816     return qobject_cast<UIHotKeyTableModel*>(model())->childItem(iIndex);
    817 }
    818 
    819 void UIHotKeyTable::sltHandleShortcutsLoaded()
     720    return qobject_cast<UIShortcutConfigurationModel*>(model())->childItem(iIndex);
     721}
     722
     723void UIShortcutConfigurationTable::sltHandleShortcutsLoaded()
    820724{
    821725    /* Resize columns to feat contents: */
     
    823727
    824728    /* Configure sorting: */
    825     sortByColumn(UIHotKeyColumnIndex_Description, Qt::AscendingOrder);
     729    sortByColumn(TableColumnIndex_Description, Qt::AscendingOrder);
    826730    setSortingEnabled(true);
    827731}
    828732
    829 void UIHotKeyTable::prepare()
     733void UIShortcutConfigurationTable::prepare()
    830734{
    831735    /* Configure self: */
     
    840744    verticalHeader()->setDefaultSectionSize((int)(verticalHeader()->minimumSectionSize() * 1.33));
    841745    horizontalHeader()->setStretchLastSection(false);
    842     horizontalHeader()->setSectionResizeMode(UIHotKeyColumnIndex_Description, QHeaderView::Interactive);
    843     horizontalHeader()->setSectionResizeMode(UIHotKeyColumnIndex_Sequence, QHeaderView::Stretch);
     746    horizontalHeader()->setSectionResizeMode(TableColumnIndex_Description, QHeaderView::Interactive);
     747    horizontalHeader()->setSectionResizeMode(TableColumnIndex_Sequence, QHeaderView::Stretch);
    844748
    845749    /* Connect model: */
    846     UIHotKeyTableModel *pHotKeyTableModel = qobject_cast<UIHotKeyTableModel*>(model());
    847     AssertPtrReturnVoid(pHotKeyTableModel);
    848     {
    849         connect(pHotKeyTableModel, &UIHotKeyTableModel::sigShortcutsLoaded,
    850                 this, &UIHotKeyTable::sltHandleShortcutsLoaded);
    851     }
     750    UIShortcutConfigurationModel *pHotKeyTableModel = qobject_cast<UIShortcutConfigurationModel*>(model());
     751    if (pHotKeyTableModel)
     752        connect(pHotKeyTableModel, &UIShortcutConfigurationModel::sigShortcutsLoaded,
     753                this, &UIShortcutConfigurationTable::sltHandleShortcutsLoaded);
    852754
    853755    /* Check if we do have proper item delegate: */
    854756    QIStyledItemDelegate *pStyledItemDelegate = qobject_cast<QIStyledItemDelegate*>(itemDelegate());
    855     AssertPtrReturnVoid(pStyledItemDelegate);
     757    if (pStyledItemDelegate)
    856758    {
    857759        /* Configure item delegate: */
     
    860762        /* Create new item editor factory: */
    861763        QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;
    862         AssertPtrReturnVoid(pNewItemEditorFactory);
     764        if (pNewItemEditorFactory)
    863765        {
    864766            /* Register UIHotKeyEditor as the UIHotKey editor: */
     
    880782
    881783/*********************************************************************************************************************************
    882 *   Class UIGlobalSettingsInput implementation.                                                                                  *
     784*   Class UIShortcutConfigurationEditor implementation.                                                                          *
    883785*********************************************************************************************************************************/
    884786
    885 UIGlobalSettingsInput::UIGlobalSettingsInput()
    886     : m_pModelManager(0)
     787UIShortcutConfigurationEditor::UIShortcutConfigurationEditor(QWidget *pParent /* = 0 */)
     788    : QIWithRetranslateUI<QWidget>(pParent)
     789    , m_pModelManager(0)
    887790    , m_pModelRuntime(0)
    888     , m_pCache(0)
    889791    , m_pTabWidget(0)
    890     , m_pEditorManagerFilter(0), m_pTableManager(0)
    891     , m_pEditorRuntimeFilter(0), m_pTableRuntime(0)
    892     , m_pCheckBoxEnableAutoGrab(0)
    893 {
    894     /* Prepare: */
     792    , m_pEditorFilterManager(0), m_pTableManager(0)
     793    , m_pEditorFilterRuntime(0), m_pTableRuntime(0)
     794{
    895795    prepare();
    896796}
    897797
    898 UIGlobalSettingsInput::~UIGlobalSettingsInput()
    899 {
    900     /* Cleanup: */
    901     cleanup();
    902 }
    903 
    904 void UIGlobalSettingsInput::loadToCacheFrom(QVariant &data)
    905 {
    906     /* Fetch data to properties: */
    907     UISettingsPageGlobal::fetchData(data);
    908 
    909     /* Clear cache initially: */
    910     m_pCache->clear();
    911 
    912     /* Prepare old input data: */
    913     UIDataSettingsGlobalInput oldInputData;
    914 
    915     /* Gather old input data: */
    916     oldInputData.shortcuts() << UIDataShortcutRow(m_pTableRuntime,
    917                                                   UIHostCombo::hostComboCacheKey(),
    918                                                   QString(),
    919                                                   tr("Host Key Combination"),
    920                                                   gEDataManager->hostKeyCombination(),
    921                                                   QString());
    922     const QMap<QString, UIShortcut> &shortcuts = gShortcutPool->shortcuts();
    923     const QList<QString> shortcutKeys = shortcuts.keys();
    924     foreach (const QString &strShortcutKey, shortcutKeys)
    925     {
    926         const UIShortcut &shortcut = shortcuts[strShortcutKey];
    927         QITableView *pParent = strShortcutKey.startsWith(GUI_Input_MachineShortcuts) ? m_pTableRuntime :
    928                                strShortcutKey.startsWith(GUI_Input_SelectorShortcuts) ? m_pTableManager : 0;
    929         AssertPtr(pParent);
    930         oldInputData.shortcuts() << UIDataShortcutRow(pParent,
    931                                                       strShortcutKey,
    932                                                       shortcut.scope(),
    933                                                       UICommon::removeAccelMark(shortcut.description()),
    934                                                       shortcut.primaryToNativeText(),
    935                                                       shortcut.defaultSequence().toString(QKeySequence::NativeText));
    936     }
    937     oldInputData.setAutoCapture(gEDataManager->autoCaptureEnabled());
    938 
    939     /* Cache old input data: */
    940     m_pCache->cacheInitialData(oldInputData);
    941 
    942     /* Upload properties to data: */
    943     UISettingsPageGlobal::uploadData(data);
    944 }
    945 
    946 void UIGlobalSettingsInput::getFromCache()
    947 {
    948     /* Get old input data from the cache: */
    949     const UIDataSettingsGlobalInput &oldInputData = m_pCache->base();
    950 
    951     /* Load old input data from the cache: */
    952     m_pModelManager->load(oldInputData.shortcuts());
    953     m_pModelRuntime->load(oldInputData.shortcuts());
    954     m_pCheckBoxEnableAutoGrab->setChecked(oldInputData.autoCapture());
    955 
    956     /* Revalidate: */
    957     revalidate();
    958 }
    959 
    960 void UIGlobalSettingsInput::putToCache()
    961 {
    962     /* Prepare new input data: */
    963     UIDataSettingsGlobalInput newInputData = m_pCache->base();
    964 
    965     /* Gather new input data: */
    966     m_pModelManager->save(newInputData.shortcuts());
    967     m_pModelRuntime->save(newInputData.shortcuts());
    968     newInputData.setAutoCapture(m_pCheckBoxEnableAutoGrab->isChecked());
    969 
    970     /* Cache new input data: */
    971     m_pCache->cacheCurrentData(newInputData);
    972 }
    973 
    974 void UIGlobalSettingsInput::saveFromCacheTo(QVariant &data)
    975 {
    976     /* Fetch data to properties: */
    977     UISettingsPageGlobal::fetchData(data);
    978 
    979     /* Update input data and failing state: */
    980     setFailed(!saveInputData());
    981 
    982     /* Upload properties to data: */
    983     UISettingsPageGlobal::uploadData(data);
    984 }
    985 
    986 bool UIGlobalSettingsInput::validate(QList<UIValidationMessage> &messages)
    987 {
    988     /* Pass by default: */
    989     bool fPass = true;
    990 
    991     /* Check VirtualBox Manager page for unique shortcuts: */
    992     if (!m_pModelManager->isAllShortcutsUnique())
    993     {
    994         UIValidationMessage message;
    995         message.first = UICommon::removeAccelMark(m_pTabWidget->tabText(UIHotKeyTableIndex_Selector));
    996         message.second << tr("Some items have the same shortcuts assigned.");
    997         messages << message;
    998         fPass = false;
    999     }
    1000 
    1001     /* Check Virtual Machine page for unique shortcuts: */
    1002     if (!m_pModelRuntime->isAllShortcutsUnique())
    1003     {
    1004         UIValidationMessage message;
    1005         message.first = UICommon::removeAccelMark(m_pTabWidget->tabText(UIHotKeyTableIndex_Machine));
    1006         message.second << tr("Some items have the same shortcuts assigned.");
    1007         messages << message;
    1008         fPass = false;
    1009     }
    1010 
    1011     /* Return result: */
    1012     return fPass;
    1013 }
    1014 
    1015 void UIGlobalSettingsInput::setOrderAfter(QWidget *pWidget)
    1016 {
    1017     setTabOrder(pWidget, m_pTabWidget);
    1018     setTabOrder(m_pTabWidget, m_pEditorManagerFilter);
    1019     setTabOrder(m_pEditorManagerFilter, m_pTableManager);
    1020     setTabOrder(m_pTableManager, m_pEditorRuntimeFilter);
    1021     setTabOrder(m_pEditorRuntimeFilter, m_pTableRuntime);
    1022     setTabOrder(m_pTableRuntime, m_pCheckBoxEnableAutoGrab);
    1023 }
    1024 
    1025 void UIGlobalSettingsInput::retranslateUi()
    1026 {
    1027     m_pCheckBoxEnableAutoGrab->setWhatsThis(tr("When checked, the keyboard is automatically captured every time the VM window "
    1028                                                "is activated. When the keyboard is captured, all keystrokes (including system ones "
    1029                                                "like Alt-Tab) are directed to the VM."));
    1030     m_pCheckBoxEnableAutoGrab->setText(tr("&Auto Capture Keyboard"));
    1031 
    1032 
    1033     /* Translate tab-widget labels: */
    1034     m_pTabWidget->setTabText(UIHotKeyTableIndex_Selector, tr("&VirtualBox Manager"));
    1035     m_pTabWidget->setTabText(UIHotKeyTableIndex_Machine, tr("Virtual &Machine"));
     798void UIShortcutConfigurationEditor::load(const UIShortcutConfigurationList &value)
     799{
     800    m_pModelManager->load(value);
     801    m_pModelRuntime->load(value);
     802}
     803
     804void UIShortcutConfigurationEditor::save(UIShortcutConfigurationList &value) const
     805{
     806    m_pModelManager->save(value);
     807    m_pModelRuntime->save(value);
     808}
     809
     810bool UIShortcutConfigurationEditor::isShortcutsUniqueManager() const
     811{
     812    return m_pModelManager->isAllShortcutsUnique();
     813}
     814
     815bool UIShortcutConfigurationEditor::isShortcutsUniqueRuntime() const
     816{
     817    return m_pModelRuntime->isAllShortcutsUnique();
     818}
     819
     820QString UIShortcutConfigurationEditor::tabNameManager() const
     821{
     822    return m_pTabWidget->tabText(TableIndex_Manager);
     823}
     824
     825QString UIShortcutConfigurationEditor::tabNameRuntime() const
     826{
     827    return m_pTabWidget->tabText(TableIndex_Runtime);
     828}
     829
     830void UIShortcutConfigurationEditor::retranslateUi()
     831{
     832    m_pTabWidget->setTabText(TableIndex_Manager, tr("&VirtualBox Manager"));
     833    m_pTabWidget->setTabText(TableIndex_Runtime, tr("Virtual &Machine"));
    1036834    m_pTableManager->setWhatsThis(tr("Lists all available shortcuts which can be configured."));
    1037835    m_pTableRuntime->setWhatsThis(tr("Lists all available shortcuts which can be configured."));
    1038     m_pEditorManagerFilter->setWhatsThis(tr("Holds a sequence to filter the shortcut list."));
    1039     m_pEditorRuntimeFilter->setWhatsThis(tr("Holds a sequence to filter the shortcut list."));
    1040 }
    1041 
    1042 void UIGlobalSettingsInput::prepare()
    1043 {
    1044     /* Prepare cache: */
    1045     m_pCache = new UISettingsCacheGlobalInput;
    1046     AssertPtrReturnVoid(m_pCache);
    1047 
     836    m_pEditorFilterManager->setWhatsThis(tr("Holds a sequence to filter the shortcut list."));
     837    m_pEditorFilterRuntime->setWhatsThis(tr("Holds a sequence to filter the shortcut list."));
     838}
     839
     840void UIShortcutConfigurationEditor::prepare()
     841{
    1048842    /* Prepare everything: */
    1049843    prepareWidgets();
     
    1054848}
    1055849
    1056 void UIGlobalSettingsInput::prepareWidgets()
     850void UIShortcutConfigurationEditor::prepareWidgets()
    1057851{
    1058852    /* Prepare main layout: */
    1059     QGridLayout *pMainLayout = new QGridLayout(this);
     853    QVBoxLayout *pMainLayout = new QVBoxLayout(this);
    1060854    if (pMainLayout)
    1061855    {
     856        pMainLayout->setContentsMargins(0, 0, 0, 0);
     857
    1062858        /* Prepare tab-widget: */
    1063859        m_pTabWidget = new QTabWidget(this);
     
    1067863            prepareTabManager();
    1068864            /* Prepare 'Runtime UI' tab: */
    1069             prepareTabMachine();
     865            prepareTabRuntime();
    1070866
    1071867            /* Add tab-widget into layout: */
    1072             pMainLayout->addWidget(m_pTabWidget, 0, 0, 1, 2);
    1073         }
    1074 
    1075         /* Prepare 'enable auto-grab' check-box: */
    1076         m_pCheckBoxEnableAutoGrab = new QCheckBox(this);
    1077         if (m_pCheckBoxEnableAutoGrab)
    1078             pMainLayout->addWidget(m_pCheckBoxEnableAutoGrab, 1, 0);
    1079     }
    1080 }
    1081 
    1082 void UIGlobalSettingsInput::prepareTabManager()
     868            pMainLayout->addWidget(m_pTabWidget);
     869        }
     870    }
     871}
     872
     873void UIShortcutConfigurationEditor::prepareTabManager()
    1083874{
    1084875    /* Prepare Manager UI tab: */
     
    1097888
    1098889            /* Prepare Manager UI filter editor: */
    1099             m_pEditorManagerFilter = new QLineEdit(pTabManager);
    1100             if (m_pEditorManagerFilter)
    1101                 pLayoutManager->addWidget(m_pEditorManagerFilter);
     890            m_pEditorFilterManager = new QLineEdit(pTabManager);
     891            if (m_pEditorFilterManager)
     892                pLayoutManager->addWidget(m_pEditorFilterManager);
    1102893
    1103894            /* Prepare Manager UI model: */
    1104             m_pModelManager = new UIHotKeyTableModel(this, UIActionPoolType_Manager);
     895            m_pModelManager = new UIShortcutConfigurationModel(this, UIActionPoolType_Manager);
    1105896
    1106897            /* Prepare Manager UI table: */
    1107             m_pTableManager = new UIHotKeyTable(pTabManager, m_pModelManager, "m_pTableManager");
     898            m_pTableManager = new UIShortcutConfigurationTable(pTabManager, m_pModelManager, "m_pTableManager");
    1108899            if (m_pTableManager)
     900            {
     901                m_pModelManager->setTable(m_pTableManager);
    1109902                pLayoutManager->addWidget(m_pTableManager);
    1110         }
    1111 
    1112         m_pTabWidget->insertTab(UIHotKeyTableIndex_Selector, pTabManager, QString());
    1113     }
    1114 }
    1115 
    1116 void UIGlobalSettingsInput::prepareTabMachine()
     903            }
     904        }
     905
     906        m_pTabWidget->insertTab(TableIndex_Manager, pTabManager, QString());
     907    }
     908}
     909
     910void UIShortcutConfigurationEditor::prepareTabRuntime()
    1117911{
    1118912    /* Create Runtime UI tab: */
     
    1131925
    1132926            /* Prepare Runtime UI filter editor: */
    1133             m_pEditorRuntimeFilter = new QLineEdit(pTabMachine);
    1134             if (m_pEditorRuntimeFilter)
    1135                 pLayoutMachine->addWidget(m_pEditorRuntimeFilter);
     927            m_pEditorFilterRuntime = new QLineEdit(pTabMachine);
     928            if (m_pEditorFilterRuntime)
     929                pLayoutMachine->addWidget(m_pEditorFilterRuntime);
    1136930
    1137931            /* Prepare Runtime UI model: */
    1138             m_pModelRuntime = new UIHotKeyTableModel(this, UIActionPoolType_Runtime);
     932            m_pModelRuntime = new UIShortcutConfigurationModel(this, UIActionPoolType_Runtime);
    1139933
    1140934            /* Create Runtime UI table: */
    1141             m_pTableRuntime = new UIHotKeyTable(pTabMachine, m_pModelRuntime, "m_pTableRuntime");
     935            m_pTableRuntime = new UIShortcutConfigurationTable(pTabMachine, m_pModelRuntime, "m_pTableRuntime");
    1142936            if (m_pTableRuntime)
     937            {
     938                m_pModelRuntime->setTable(m_pTableRuntime);
    1143939                pLayoutMachine->addWidget(m_pTableRuntime);
    1144         }
    1145 
    1146         m_pTabWidget->insertTab(UIHotKeyTableIndex_Machine, pTabMachine, QString());
     940            }
     941        }
     942
     943        m_pTabWidget->insertTab(TableIndex_Runtime, pTabMachine, QString());
    1147944
    1148945        /* In the VM process we start by displaying the Runtime UI tab: */
     
    1152949}
    1153950
    1154 void UIGlobalSettingsInput::prepareConnections()
     951void UIShortcutConfigurationEditor::prepareConnections()
    1155952{
    1156953    /* Configure 'Manager UI' connections: */
    1157     connect(m_pEditorManagerFilter, &QLineEdit::textChanged, m_pModelManager, &UIHotKeyTableModel::sltHandleFilterTextChange);
    1158     connect(m_pModelManager, &UIHotKeyTableModel::sigRevalidationRequired, this, &UIGlobalSettingsInput::revalidate);
     954    connect(m_pEditorFilterManager, &QLineEdit::textChanged,
     955            m_pModelManager, &UIShortcutConfigurationModel::sltHandleFilterTextChange);
     956    connect(m_pModelManager, &UIShortcutConfigurationModel::sigDataChanged,
     957            this, &UIShortcutConfigurationEditor::sigValueChanged);
    1159958
    1160959    /* Configure 'Runtime UI' connections: */
    1161     connect(m_pEditorRuntimeFilter, &QLineEdit::textChanged, m_pModelRuntime, &UIHotKeyTableModel::sltHandleFilterTextChange);
    1162     connect(m_pModelRuntime, &UIHotKeyTableModel::sigRevalidationRequired, this, &UIGlobalSettingsInput::revalidate);
    1163 }
    1164 
    1165 void UIGlobalSettingsInput::cleanup()
    1166 {
    1167     /* Cleanup cache: */
    1168     delete m_pCache;
    1169     m_pCache = 0;
    1170 }
    1171 
    1172 bool UIGlobalSettingsInput::saveInputData()
    1173 {
    1174     /* Prepare result: */
    1175     bool fSuccess = true;
    1176     /* Save input settings from the cache: */
    1177     if (fSuccess && m_pCache->wasChanged())
    1178     {
    1179         /* Get old input data from the cache: */
    1180         const UIDataSettingsGlobalInput &oldInputData = m_pCache->base();
    1181         /* Get new input data from the cache: */
    1182         const UIDataSettingsGlobalInput &newInputData = m_pCache->data();
    1183 
    1184         /* Save new host-combo shortcut from the cache: */
    1185         const UIDataShortcutRow fakeHostComboItem(0, UIHostCombo::hostComboCacheKey(), QString(), QString(), QString(), QString());
    1186         const int iHostComboItemBase = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(oldInputData.shortcuts(), fakeHostComboItem);
    1187         const int iHostComboItemData = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(newInputData.shortcuts(), fakeHostComboItem);
    1188         const QString strHostComboBase = iHostComboItemBase != -1 ? oldInputData.shortcuts().at(iHostComboItemBase).currentSequence() : QString();
    1189         const QString strHostComboData = iHostComboItemData != -1 ? newInputData.shortcuts().at(iHostComboItemData).currentSequence() : QString();
    1190         if (strHostComboData != strHostComboBase)
    1191             gEDataManager->setHostKeyCombination(strHostComboData);
    1192 
    1193         /* Save other new shortcuts from the cache: */
    1194         QMap<QString, QString> sequencesBase;
    1195         QMap<QString, QString> sequencesData;
    1196         foreach (const UIDataShortcutRow &item, oldInputData.shortcuts())
    1197             sequencesBase.insert(item.key(), item.currentSequence());
    1198         foreach (const UIDataShortcutRow &item, newInputData.shortcuts())
    1199             sequencesData.insert(item.key(), item.currentSequence());
    1200         if (sequencesData != sequencesBase)
    1201             gShortcutPool->setOverrides(sequencesData);
    1202 
    1203         /* Save other new things from the cache: */
    1204         if (newInputData.autoCapture() != oldInputData.autoCapture())
    1205             gEDataManager->setAutoCaptureEnabled(newInputData.autoCapture());
    1206     }
    1207     /* Return result: */
    1208     return fSuccess;
    1209 }
    1210 
    1211 # include "UIGlobalSettingsInput.moc"
     960    connect(m_pEditorFilterRuntime, &QLineEdit::textChanged,
     961            m_pModelRuntime, &UIShortcutConfigurationModel::sltHandleFilterTextChange);
     962    connect(m_pModelRuntime, &UIShortcutConfigurationModel::sigDataChanged,
     963            this, &UIShortcutConfigurationEditor::sigValueChanged);
     964}
     965
     966# include "UIShortcutConfigurationEditor.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UIShortcutConfigurationEditor.h

    r86120 r86124  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIGlobalSettingsInput class declaration.
     3 * VBox Qt GUI - UIShortcutConfigurationEditor class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_settings_global_UIGlobalSettingsInput_h
    19 #define FEQT_INCLUDED_SRC_settings_global_UIGlobalSettingsInput_h
     18#ifndef FEQT_INCLUDED_SRC_settings_editors_UIShortcutConfigurationEditor_h
     19#define FEQT_INCLUDED_SRC_settings_editors_UIShortcutConfigurationEditor_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
     
    2323
    2424/* GUI includes: */
    25 #include "UISettingsPage.h"
     25#include "QIWithRetranslateUI.h"
    2626
    2727/* Forward declartions: */
    28 class QCheckBox;
    2928class QLineEdit;
    3029class QTabWidget;
    31 class UIDataSettingsGlobalInput;
    32 class UIHotKeyTable;
    33 class UIHotKeyTableModel;
    34 typedef UISettingsCache<UIDataSettingsGlobalInput> UISettingsCacheGlobalInput;
    35 
    36 /** Global settings: Input page. */
    37 class SHARED_LIBRARY_STUFF UIGlobalSettingsInput : public UISettingsPageGlobal
     30class UIShortcutConfigurationModel;
     31class UIShortcutConfigurationTable;
     32
     33/** Shortcut search functor template. */
     34template <class BaseClass>
     35class UIShortcutSearchFunctor : public BaseClass
     36{
     37public:
     38
     39    /** Constructs shortcut search functor. */
     40    UIShortcutSearchFunctor() {}
     41
     42    /** Returns the position of the 1st occurrence of the
     43      * @a shortcut in the @a shortcuts list, or -1 otherwise. */
     44    int operator()(const QList<BaseClass> &shortcuts, const BaseClass &shortcut)
     45    {
     46        for (int i = 0; i < shortcuts.size(); ++i)
     47        {
     48            const BaseClass &iteratedShortcut = shortcuts.at(i);
     49            if (iteratedShortcut.key() == shortcut.key())
     50                return i;
     51        }
     52        return -1;
     53    }
     54};
     55
     56/** Shortcut configuration item. */
     57class SHARED_LIBRARY_STUFF UIShortcutConfigurationItem
     58{
     59public:
     60
     61    /** Constructs shortcut configuration item on the basis of passed arguments.
     62      * @param  strKey              Brings the unique key identifying held sequence.
     63      * @param  strScope            Brings the scope of the held sequence.
     64      * @param  strDescription      Brings the deescription for the held sequence.
     65      * @param  strCurrentSequence  Brings the current held sequence.
     66      * @param  strDefaultSequence  Brings the default held sequence. */
     67    UIShortcutConfigurationItem(const QString &strKey = QString(),
     68                                const QString &strScope = QString(),
     69                                const QString &strDescription = QString(),
     70                                const QString &strCurrentSequence = QString(),
     71                                const QString &strDefaultSequence = QString())
     72        : m_strKey(strKey)
     73        , m_strScope(strScope)
     74        , m_strDescription(strDescription)
     75        , m_strCurrentSequence(strCurrentSequence)
     76        , m_strDefaultSequence(strDefaultSequence)
     77    {}
     78
     79    /** Constructs shortcut configuration item on the basis of @a another one. */
     80    UIShortcutConfigurationItem(const UIShortcutConfigurationItem &another)
     81        : m_strKey(another.key())
     82        , m_strScope(another.scope())
     83        , m_strDescription(another.description())
     84        , m_strCurrentSequence(another.currentSequence())
     85        , m_strDefaultSequence(another.defaultSequence())
     86    {}
     87
     88    /** Returns the key. */
     89    QString key() const { return m_strKey; }
     90    /** Returns the scope. */
     91    QString scope() const { return m_strScope; }
     92    /** Returns the description. */
     93    QString description() const { return m_strDescription; }
     94    /** Returns the current sequence. */
     95    QString currentSequence() const { return m_strCurrentSequence; }
     96    /** Returns the default sequence. */
     97    QString defaultSequence() const { return m_strDefaultSequence; }
     98
     99    /** Defines @a strCurrentSequence. */
     100    void setCurrentSequence(const QString &strCurrentSequence) { m_strCurrentSequence = strCurrentSequence; }
     101
     102    /** Copies an item from @a another one. */
     103    UIShortcutConfigurationItem &operator=(const UIShortcutConfigurationItem &another)
     104    {
     105        /* Reassign variables: */
     106        m_strKey = another.key();
     107        m_strScope = another.scope();
     108        m_strDescription = another.description();
     109        m_strCurrentSequence = another.currentSequence();
     110        m_strDefaultSequence = another.defaultSequence();
     111
     112        /* Return this: */
     113        return *this;
     114    }
     115
     116    /** Returns whether this item equals to @a another one. */
     117    bool operator==(const UIShortcutConfigurationItem &another) const
     118    {
     119        /* Compare by key, scope and current sequence: */
     120        return    true
     121               && (key() == another.key())
     122               && (scope() == another.scope())
     123               && (currentSequence() == another.currentSequence())
     124                  ;
     125    }
     126
     127private:
     128
     129    /** Holds the key. */
     130    QString m_strKey;
     131    /** Holds the scope. */
     132    QString m_strScope;
     133    /** Holds the description. */
     134    QString m_strDescription;
     135    /** Holds the current sequence. */
     136    QString m_strCurrentSequence;
     137    /** Holds the default sequence. */
     138    QString m_strDefaultSequence;
     139};
     140
     141/** Shortcut configuration list. */
     142typedef QList<UIShortcutConfigurationItem> UIShortcutConfigurationList;
     143
     144/** QWidget subclass used as a shortcut configuration editor. */
     145class SHARED_LIBRARY_STUFF UIShortcutConfigurationEditor : public QIWithRetranslateUI<QWidget>
    38146{
    39147    Q_OBJECT;
    40148
    41     /** Hot-key table indexes. */
    42     enum { UIHotKeyTableIndex_Selector, UIHotKeyTableIndex_Machine };
     149    /** Table indexes. */
     150    enum { TableIndex_Manager, TableIndex_Runtime };
     151
     152signals:
     153
     154    /** Notifies listeners about value change. */
     155    void sigValueChanged();
    43156
    44157public:
    45158
    46     /** Constructs Input settings page. */
    47     UIGlobalSettingsInput();
    48     /** Destructs Input settings page. */
    49     ~UIGlobalSettingsInput();
     159    /** Constructs shortcut configuration editor passing @a pParent to the base-class. */
     160    UIShortcutConfigurationEditor(QWidget *pParent = 0);
     161
     162    /** Loads shortcut configuration list from passed @a value. */
     163    void load(const UIShortcutConfigurationList &value);
     164    /** Saves shortcut configuration list to passed @a value. */
     165    void save(UIShortcutConfigurationList &value) const;
     166
     167    /** Returns whether manager shortcuts are unique. */
     168    bool isShortcutsUniqueManager() const;
     169    /** Returns whether runtime shortcuts are unique. */
     170    bool isShortcutsUniqueRuntime() const;
     171
     172    /** Returns manager tab name. */
     173    QString tabNameManager() const;
     174    /** Returns runtime tab name. */
     175    QString tabNameRuntime() const;
    50176
    51177protected:
    52 
    53     /** Loads settings from external object(s) packed inside @a data to cache.
    54       * @note  This task WILL be performed in other than the GUI thread, no widget interactions! */
    55     virtual void loadToCacheFrom(QVariant &data) /* override */;
    56     /** Loads data from cache to corresponding widgets.
    57       * @note  This task WILL be performed in the GUI thread only, all widget interactions here! */
    58     virtual void getFromCache() /* override */;
    59 
    60     /** Saves data from corresponding widgets to cache.
    61       * @note  This task WILL be performed in the GUI thread only, all widget interactions here! */
    62     virtual void putToCache() /* override */;
    63     /** Saves settings from cache to external object(s) packed inside @a data.
    64       * @note  This task WILL be performed in other than the GUI thread, no widget interactions! */
    65     virtual void saveFromCacheTo(QVariant &data) /* overrride */;
    66 
    67     /** Performs validation, updates @a messages list if something is wrong. */
    68     virtual bool validate(QList<UIValidationMessage> &messages) /* override */;
    69 
    70     /** Defines TAB order for passed @a pWidget. */
    71     virtual void setOrderAfter(QWidget *pWidget) /* override */;
    72178
    73179    /** Handles translation event. */
     
    83189    void prepareTabManager();
    84190    /** Prepares Runtime UI tab. */
    85     void prepareTabMachine();
     191    void prepareTabRuntime();
    86192    /** Prepares connections. */
    87193    void prepareConnections();
    88     /** Cleanups all. */
    89     void cleanup();
    90 
    91     /** Saves existing input data from the cache. */
    92     bool saveInputData();
    93 
    94     /** Holds the Manager UI shortcuts model instance. */
    95     UIHotKeyTableModel *m_pModelManager;
    96     /** Holds the Runtime UI shortcuts model instance. */
    97     UIHotKeyTableModel *m_pModelRuntime;
    98 
    99     /** Holds the page data cache instance. */
    100     UISettingsCacheGlobalInput *m_pCache;
    101 
    102     /** @name Widgets
    103      * @{ */
    104         /** Holds the tab-widget instance. */
    105         QTabWidget    *m_pTabWidget;
    106         /** Holds the Manager UI shortcuts filter instance. */
    107         QLineEdit     *m_pEditorManagerFilter;
    108         /** Holds the Manager UI shortcuts table instance. */
    109         UIHotKeyTable *m_pTableManager;
    110         /** Holds the Runtime UI shortcuts filter instance. */
    111         QLineEdit     *m_pEditorRuntimeFilter;
    112         /** Holds the Runtime UI shortcuts table instance. */
    113         UIHotKeyTable *m_pTableRuntime;
    114         /** Holds the 'enable auto-grab' checkbox instance. */
    115         QCheckBox     *m_pCheckBoxEnableAutoGrab;
    116     /** @} */
     194
     195    /** Holds the Manager UI shortcut configuration model instance. */
     196    UIShortcutConfigurationModel *m_pModelManager;
     197    /** Holds the Runtime UI shortcut configuration model instance. */
     198    UIShortcutConfigurationModel *m_pModelRuntime;
     199
     200    /** Holds the tab-widget instance. */
     201    QTabWidget                   *m_pTabWidget;
     202    /** Holds the Manager UI shortcuts filter instance. */
     203    QLineEdit                    *m_pEditorFilterManager;
     204    /** Holds the Manager UI shortcuts table instance. */
     205    UIShortcutConfigurationTable *m_pTableManager;
     206    /** Holds the Runtime UI shortcuts filter instance. */
     207    QLineEdit                    *m_pEditorFilterRuntime;
     208    /** Holds the Runtime UI shortcuts table instance. */
     209    UIShortcutConfigurationTable *m_pTableRuntime;
    117210};
    118211
    119 #endif /* !FEQT_INCLUDED_SRC_settings_global_UIGlobalSettingsInput_h */
     212#endif /* !FEQT_INCLUDED_SRC_settings_editors_UIShortcutConfigurationEditor_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp

    r86020 r86124  
    1717
    1818/* Qt includes: */
    19 #include <QAbstractItemDelegate>
    2019#include <QCheckBox>
    2120#include <QGridLayout>
    22 #include <QHeaderView>
    23 #include <QItemEditorFactory>
    24 #include <QTabWidget>
     21#include <QLabel>
    2522
    2623/* GUI includes: */
    27 #include "QIStyledItemDelegate.h"
    28 #include "QITableView.h"
    29 #include "QIWidgetValidator.h"
     24#include "UIAutoCaptureKeyboardEditor.h"
    3025#include "UICommon.h"
    31 #include "UIActionPool.h"
    3226#include "UIGlobalSettingsInput.h"
    3327#include "UIHostComboEditor.h"
    34 #include "UIHotKeyEditor.h"
     28#include "UIShortcutConfigurationEditor.h"
    3529#include "UIShortcutPool.h"
    3630#include "UIExtraDataManager.h"
    37 #include "UIMessageCenter.h"
    38 
    39 /* Qt includes: */
    40 #include <QShortcut>
    41 
    42 
    43 /* Namespaces: */
    44 using namespace UIExtraDataDefs;
    45 
    46 
    47 /** Column index enumerator. */
    48 enum UIHotKeyColumnIndex
    49 {
    50     UIHotKeyColumnIndex_Description,
    51     UIHotKeyColumnIndex_Sequence,
    52     UIHotKeyColumnIndex_Max
    53 };
    54 
    55 
    56 /** Global settings: Input page: Shortcut cell data structure. */
    57 class UIDataShortcutCell : public QITableViewCell
    58 {
    59     Q_OBJECT;
    60 
    61 public:
    62 
    63     /** Constructs table cell.
    64       * @param  pParent  Brings the row this cell belongs too.
    65       * @param  strText  Brings the text describing this cell. */
    66     UIDataShortcutCell(QITableViewRow *pParent, const QString &strText)
    67         : QITableViewCell(pParent)
    68         , m_strText(strText)
    69     {}
    70 
    71     /** Returns the cell text. */
    72     virtual QString text() const /* override */ { return m_strText; }
    73 
    74 private:
    75 
    76     /** Holds the cell text. */
    77     QString m_strText;
    78 };
    79 
    80 
    81 /** Global settings: Input page: Shortcut data structure. */
    82 class UIDataShortcutRow : public QITableViewRow
    83 {
    84     Q_OBJECT;
    85 
    86 public:
    87 
    88     /** Constructs table row on the basis of passed arguments.
    89       * @param  pParent             Brings the row this cell belongs too.
    90       * @param  strKey              Brings the unique key identifying held sequence.
    91       * @param  strScope            Brings the scope of the held sequence.
    92       * @param  strDescription      Brings the deescription for the held sequence.
    93       * @param  strCurrentSequence  Brings the current held sequence.
    94       * @param  strDefaultSequence  Brings the default held sequence. */
    95     UIDataShortcutRow(QITableView *pParent,
    96                       const QString &strKey,
    97                       const QString &strScope,
    98                       const QString &strDescription,
    99                       const QString &strCurrentSequence,
    100                       const QString &strDefaultSequence)
    101         : QITableViewRow(pParent)
    102         , m_strKey(strKey)
    103         , m_strScope(strScope)
    104         , m_strDescription(strDescription)
    105         , m_strCurrentSequence(strCurrentSequence)
    106         , m_strDefaultSequence(strDefaultSequence)
    107     {
    108         /* Create cells: */
    109         createCells();
    110     }
    111 
    112     /** Constructs table row on the basis of @a other one. */
    113     UIDataShortcutRow(const UIDataShortcutRow &other)
    114         : QITableViewRow(other.table())
    115         , m_strKey(other.key())
    116         , m_strScope(other.scope())
    117         , m_strDescription(other.description())
    118         , m_strCurrentSequence(other.currentSequence())
    119         , m_strDefaultSequence(other.defaultSequence())
    120     {
    121         /* Create cells: */
    122         createCells();
    123     }
    124 
    125     /** Destructs table row. */
    126     ~UIDataShortcutRow()
    127     {
    128         /* Destroy cells: */
    129         destroyCells();
    130     }
    131 
    132     /** Copies a table row from @a other one. */
    133     UIDataShortcutRow &operator=(const UIDataShortcutRow &other)
    134     {
    135         /* Reassign variables: */
    136         setTable(other.table());
    137         m_strKey = other.key();
    138         m_strScope = other.scope();
    139         m_strDescription = other.description();
    140         m_strCurrentSequence = other.currentSequence();
    141         m_strDefaultSequence = other.defaultSequence();
    142 
    143         /* Recreate cells: */
    144         destroyCells();
    145         createCells();
    146 
    147         /* Return this: */
    148         return *this;
    149     }
    150 
    151     /** Returns whether this row equals to @a other. */
    152     bool operator==(const UIDataShortcutRow &other) const
    153     {
    154         /* Compare by the key and the current sequence: */
    155         return true
    156                && (m_strKey == other.key())
    157                && (m_strScope == other.scope())
    158                && (m_strCurrentSequence == other.currentSequence())
    159                ;
    160     }
    161 
    162     /** Returns the key. */
    163     QString key() const { return m_strKey; }
    164     /** Returns the scope. */
    165     QString scope() const { return m_strScope; }
    166     /** Returns the description. */
    167     QString description() const { return m_strDescription; }
    168     /** Returns the current sequence. */
    169     QString currentSequence() const { return m_strCurrentSequence; }
    170     /** Returns the default sequence. */
    171     QString defaultSequence() const { return m_strDefaultSequence; }
    172 
    173     /** Defines @a strCurrentSequence. */
    174     void setCurrentSequence(const QString &strCurrentSequence) { m_strCurrentSequence = strCurrentSequence; }
    175 
    176 protected:
    177 
    178     /** Returns the number of children. */
    179     virtual int childCount() const /* override */
    180     {
    181         return UIHotKeyColumnIndex_Max;
    182     }
    183 
    184     /** Returns the child item with @a iIndex. */
    185     virtual QITableViewCell *childItem(int iIndex) const /* override */
    186     {
    187         switch (iIndex)
    188         {
    189             case UIHotKeyColumnIndex_Description: return m_cells.first;
    190             case UIHotKeyColumnIndex_Sequence: return m_cells.second;
    191             default: break;
    192         }
    193         return 0;
    194     }
    195 
    196 private:
    197 
    198     /** Creates cells. */
    199     void createCells()
    200     {
    201         /* Create cells on the basis of description and current sequence: */
    202         m_cells = qMakePair(new UIDataShortcutCell(this, m_strDescription),
    203                             new UIDataShortcutCell(this, m_strCurrentSequence));
    204     }
    205 
    206     /** Destroys cells. */
    207     void destroyCells()
    208     {
    209         /* Destroy cells: */
    210         delete m_cells.first;
    211         delete m_cells.second;
    212         m_cells.first = 0;
    213         m_cells.second = 0;
    214     }
    215 
    216     /** Holds the key. */
    217     QString m_strKey;
    218     /** Holds the scope. */
    219     QString m_strScope;
    220     /** Holds the description. */
    221     QString m_strDescription;
    222     /** Holds the current sequence. */
    223     QString m_strCurrentSequence;
    224     /** Holds the default sequence. */
    225     QString m_strDefaultSequence;
    226 
    227     /** Holds the cell instances. */
    228     QPair<UIDataShortcutCell*, UIDataShortcutCell*> m_cells;
    229 };
    230 typedef QList<UIDataShortcutRow> UIShortcutCache;
    23131
    23232
    23333/** Global settings: Input page data structure. */
    234 class UIDataSettingsGlobalInput
    235 {
    236 public:
    237 
     34struct UIDataSettingsGlobalInput
     35{
    23836    /** Constructs cache. */
    23937    UIDataSettingsGlobalInput()
     
    24139    {}
    24240
    243     /** Returns the shortcuts cache [full access]. */
    244     UIShortcutCache &shortcuts() { return m_shortcuts; }
    245     /** Returns the shortcuts cache [read-only access]. */
    246     const UIShortcutCache &shortcuts() const { return m_shortcuts; }
    247 
    248     /** Defines whether the keyboard auto-capture is @a fEnabled. */
    249     void setAutoCapture(bool fEnabled) { m_fAutoCapture = fEnabled; }
    250     /** Returns whether the keyboard auto-capture is enabled. */
    251     bool autoCapture() const { return m_fAutoCapture; }
    252 
    25341    /** Returns whether the @a other passed data is equal to this one. */
    25442    bool equal(const UIDataSettingsGlobalInput &other) const
    25543    {
    256         return (m_shortcuts == other.m_shortcuts) &&
    257                (m_fAutoCapture == other.m_fAutoCapture);
     44        return    true
     45               && (m_shortcuts == other.m_shortcuts)
     46               && (m_fAutoCapture == other.m_fAutoCapture)
     47                  ;
    25848    }
    25949
     
    26353    bool operator!=(const UIDataSettingsGlobalInput &other) const { return !equal(other); }
    26454
    265 private:
    266 
    267     /** Holds the shortcut cache. */
    268     UIShortcutCache m_shortcuts;
    269 
     55    /** Holds the shortcut configuration list. */
     56    UIShortcutConfigurationList  m_shortcuts;
    27057    /** Holds whether the keyboard auto-capture is enabled. */
    271     bool m_fAutoCapture;
     58    bool                         m_fAutoCapture;
    27259};
    27360
    27461
    275 /** Global settings: Input page: Shortcut cache sort functor. */
    276 class UIShortcutCacheItemFunctor
    277 {
    278 public:
    279 
    280     /** Constructs cache sorting functor.
    281       * @param  iColumn  Brings the column sorting should be done according to.
    282       * @param  m_order  Brings the sorting order to be applied. */
    283     UIShortcutCacheItemFunctor(int iColumn, Qt::SortOrder order)
    284         : m_iColumn(iColumn)
    285         , m_order(order)
    286     {}
    287 
    288     /** Returns whether the @a item1 is more/less than the @a item2.
    289       * @note  Order depends on the one set through constructor, stored in m_order. */
    290     bool operator()(const UIDataShortcutRow &item1, const UIDataShortcutRow &item2)
    291     {
    292         switch (m_iColumn)
    293         {
    294             case UIHotKeyColumnIndex_Description:
    295                 return m_order == Qt::AscendingOrder ? item1.description() < item2.description() : item1.description() > item2.description();
    296             case UIHotKeyColumnIndex_Sequence:
    297                 return m_order == Qt::AscendingOrder ? item1.currentSequence() < item2.currentSequence() : item1.currentSequence() > item2.currentSequence();
    298             default: break;
    299         }
    300         return m_order == Qt::AscendingOrder ? item1.key() < item2.key() : item1.key() > item2.key();
    301     }
    302 
    303 private:
    304 
    305     /** Holds the column sorting should be done according to. */
    306     int m_iColumn;
    307     /** Holds the sorting order to be applied. */
    308     Qt::SortOrder m_order;
    309 };
    310 
    311 
    312 /** Global settings: Input page: Shortcut search functor. */
    313 class UIFunctorFindShortcut
    314 {
    315 public:
    316 
    317     /** Search match level enumerator. */
    318     enum UIMatchLevel { Base, Full };
    319 
    320     /** Constructs shortcut search functor.
    321       * @param  matchLevel  Brings the search match level. */
    322     UIFunctorFindShortcut(UIMatchLevel enmMatchLevel)
    323         : m_enmMatchLevel(enmMatchLevel)
    324     {}
    325 
    326     /** Returns the position of the 1st occurrence of the
    327       * @a shortcut in the @a shortcuts list, or -1 otherwise. */
    328     int operator()(const UIShortcutCache &shortcuts, const UIDataShortcutRow &shortcut)
    329     {
    330         for (int i = 0; i < shortcuts.size(); ++i)
    331         {
    332             const UIDataShortcutRow &iteratedShortcut = shortcuts.at(i);
    333             switch (m_enmMatchLevel)
    334             {
    335                 case Base:
    336                 {
    337                     if (iteratedShortcut.key() == shortcut.key())
    338                         return i;
    339                     break;
    340                 }
    341                 case Full:
    342                 {
    343                     if (   iteratedShortcut.key() == shortcut.key()
    344                         && iteratedShortcut.currentSequence() == shortcut.currentSequence())
    345                         return i;
    346                     break;
    347                 }
    348             }
    349         }
    350         return -1;
    351     }
    352 
    353 private:
    354 
    355     /** Holds the search match level. */
    356     const UIMatchLevel m_enmMatchLevel;
    357 };
    358 
    359 
    360 /* A model representing hot-key combination table: */
    361 class UIHotKeyTableModel : public QAbstractTableModel
    362 {
    363     Q_OBJECT;
    364 
    365 signals:
    366 
    367     /* Notifier: Readiness stuff: */
    368     void sigShortcutsLoaded();
    369 
    370     /* Notifier: Validation stuff: */
    371     void sigRevalidationRequired();
    372 
    373 public:
    374 
    375     /* Constructor: */
    376     UIHotKeyTableModel(QObject *pParent, UIActionPoolType type);
    377 
    378     /** Returns the number of children. */
    379     int childCount() const;
    380     /** Returns the child item with @a iIndex. */
    381     QITableViewRow *childItem(int iIndex);
    382 
    383     /* API: Loading/saving stuff: */
    384     void load(const UIShortcutCache &shortcuts);
    385     void save(UIShortcutCache &shortcuts);
    386 
    387     /* API: Validation stuff: */
    388     bool isAllShortcutsUnique();
    389 
    390 public slots:
    391 
    392     /* Handler: Filtering stuff: */
    393     void sltHandleFilterTextChange(const QString &strText);
    394 
    395 private:
    396 
    397     /* Internal API: Size stuff: */
    398     int rowCount(const QModelIndex &parent = QModelIndex()) const;
    399     int columnCount(const QModelIndex &parent = QModelIndex()) const;
    400 
    401     /* Internal API: Data stuff: */
    402     Qt::ItemFlags flags(const QModelIndex &index) const;
    403     QVariant headerData(int iSection, Qt::Orientation orientation, int iRole = Qt::DisplayRole) const;
    404     QVariant data(const QModelIndex &index, int iRole = Qt::DisplayRole) const;
    405     bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole);
    406 
    407     /* Internal API: Sorting stuff: */
    408     void sort(int iColumn, Qt::SortOrder order = Qt::AscendingOrder);
    409 
    410     /* Helper: Filtering stuff: */
    411     void applyFilter();
    412 
    413     /* Variables: */
    414     UIActionPoolType m_type;
    415     QString m_strFilter;
    416     UIShortcutCache m_shortcuts;
    417     UIShortcutCache m_filteredShortcuts;
    418     QSet<QString> m_duplicatedSequences;
    419 };
    420 
    421 
    422 /* A table reflecting hot-key combinations: */
    423 class UIHotKeyTable : public QITableView
    424 {
    425     Q_OBJECT;
    426 
    427 public:
    428 
    429     /* Constructor: */
    430     UIHotKeyTable(QWidget *pParent, UIHotKeyTableModel *pModel, const QString &strObjectName);
    431 
    432 protected:
    433 
    434     /** Returns the number of children. */
    435     virtual int childCount() const /* override */;
    436     /** Returns the child item with @a iIndex. */
    437     virtual QITableViewRow *childItem(int iIndex) const /* override */;
    438 
    439 private slots:
    440 
    441     /* Handler: Readiness stuff: */
    442     void sltHandleShortcutsLoaded();
    443 
    444 private:
    445 
    446     /** Prepares all. */
    447     void prepare();
    448 };
    449 
    450 
    451 /*********************************************************************************************************************************
    452 *   Class UIHotKeyTableModel implementation.                                                                                     *
    453 *********************************************************************************************************************************/
    454 
    455 UIHotKeyTableModel::UIHotKeyTableModel(QObject *pParent, UIActionPoolType type)
    456     : QAbstractTableModel(pParent)
    457     , m_type(type)
    458 {
    459 }
    460 
    461 int UIHotKeyTableModel::childCount() const
    462 {
    463     /* Return row count: */
    464     return rowCount();
    465 }
    466 
    467 QITableViewRow *UIHotKeyTableModel::childItem(int iIndex)
    468 {
    469     /* Make sure index within the bounds: */
    470     AssertReturn(iIndex >= 0 && iIndex < m_filteredShortcuts.size(), 0);
    471     /* Return corresponding filtered row: */
    472     return &m_filteredShortcuts[iIndex];
    473 }
    474 
    475 void UIHotKeyTableModel::load(const UIShortcutCache &shortcuts)
    476 {
    477     /* Load shortcuts: */
    478     foreach (const UIDataShortcutRow &item, shortcuts)
    479     {
    480         /* Filter out unnecessary shortcuts: */
    481         if ((m_type == UIActionPoolType_Manager && item.key().startsWith(GUI_Input_MachineShortcuts)) ||
    482             (m_type == UIActionPoolType_Runtime && item.key().startsWith(GUI_Input_SelectorShortcuts)))
    483             continue;
    484         /* Load shortcut cache item into model: */
    485         m_shortcuts << item;
    486     }
    487     /* Apply filter: */
    488     applyFilter();
    489     /* Notify table: */
    490     emit sigShortcutsLoaded();
    491 }
    492 
    493 void UIHotKeyTableModel::save(UIShortcutCache &shortcuts)
    494 {
    495     /* Save model items: */
    496     foreach (const UIDataShortcutRow &item, m_shortcuts)
    497     {
    498         /* Search for corresponding cache item index: */
    499         int iIndexOfCacheItem = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(shortcuts, item);
    500         /* Make sure index is valid: */
    501         if (iIndexOfCacheItem == -1)
    502             continue;
    503         /* Save model item into the cache: */
    504         shortcuts[iIndexOfCacheItem] = item;
    505     }
    506 }
    507 
    508 bool UIHotKeyTableModel::isAllShortcutsUnique()
    509 {
    510     /* Enumerate all the sequences: */
    511     QMap<QString, QString> usedSequences;
    512     foreach (const UIDataShortcutRow &item, m_shortcuts)
    513     {
    514         QString strKey = item.currentSequence();
    515         if (!strKey.isEmpty())
    516         {
    517             const QString strScope = item.scope();
    518             strKey = strScope.isNull() ? strKey : QString("%1: %2").arg(strScope, strKey);
    519             usedSequences.insertMulti(strKey, item.key());
    520         }
    521     }
    522     /* Enumerate all the duplicated sequences: */
    523     QSet<QString> duplicatedSequences;
    524     foreach (const QString &strKey, usedSequences.keys())
    525         if (usedSequences.count(strKey) > 1)
    526             duplicatedSequences.unite(usedSequences.values(strKey).toSet());
    527     /* Is there something changed? */
    528     if (m_duplicatedSequences != duplicatedSequences)
    529     {
    530         m_duplicatedSequences = duplicatedSequences;
    531         emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
    532     }
    533     /* Are there duplicated shortcuts? */
    534     if (!m_duplicatedSequences.isEmpty())
    535         return false;
    536     /* True by default: */
    537     return true;
    538 }
    539 
    540 void UIHotKeyTableModel::sltHandleFilterTextChange(const QString &strText)
    541 {
    542     m_strFilter = strText;
    543     applyFilter();
    544 }
    545 
    546 int UIHotKeyTableModel::rowCount(const QModelIndex& /*parent = QModelIndex()*/) const
    547 {
    548     return m_filteredShortcuts.size();
    549 }
    550 
    551 int UIHotKeyTableModel::columnCount(const QModelIndex& /*parent = QModelIndex()*/) const
    552 {
    553     return 2;
    554 }
    555 
    556 Qt::ItemFlags UIHotKeyTableModel::flags(const QModelIndex &index) const
    557 {
    558     /* No flags for invalid index: */
    559     if (!index.isValid()) return Qt::NoItemFlags;
    560     /* Switch for different columns: */
    561     switch (index.column())
    562     {
    563         case UIHotKeyColumnIndex_Description: return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    564         case UIHotKeyColumnIndex_Sequence: return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
    565         default: break;
    566     }
    567     /* No flags by default: */
    568     return Qt::NoItemFlags;
    569 }
    570 
    571 QVariant UIHotKeyTableModel::headerData(int iSection, Qt::Orientation orientation, int iRole /* = Qt::DisplayRole*/) const
    572 {
    573     /* Switch for different roles: */
    574     switch (iRole)
    575     {
    576         case Qt::DisplayRole:
    577         {
    578             /* Invalid for vertical header: */
    579             if (orientation == Qt::Vertical) return QString();
    580             /* Switch for different columns: */
    581             switch (iSection)
    582             {
    583                 case UIHotKeyColumnIndex_Description: return tr("Name");
    584                 case UIHotKeyColumnIndex_Sequence: return tr("Shortcut");
    585                 default: break;
    586             }
    587             /* Invalid for other cases: */
    588             return QString();
    589         }
    590         default: break;
    591     }
    592     /* Invalid by default: */
    593     return QVariant();
    594 }
    595 
    596 QVariant UIHotKeyTableModel::data(const QModelIndex &index, int iRole /* = Qt::DisplayRole*/) const
    597 {
    598     /* No data for invalid index: */
    599     if (!index.isValid()) return QVariant();
    600     int iIndex = index.row();
    601     /* Switch for different roles: */
    602     switch (iRole)
    603     {
    604         case Qt::DisplayRole:
    605         {
    606             /* Switch for different columns: */
    607             switch (index.column())
    608             {
    609                 case UIHotKeyColumnIndex_Description:
    610                 {
    611                     /* Return shortcut scope and description: */
    612                     const QString strScope = m_filteredShortcuts[iIndex].scope();
    613                     const QString strDescription = m_filteredShortcuts[iIndex].description();
    614                     return strScope.isNull() ? strDescription : tr("%1: %2", "scope: description").arg(strScope, strDescription);
    615                 }
    616                 case UIHotKeyColumnIndex_Sequence:
    617                 {
    618                     /* If that is host-combo cell: */
    619                     if (m_filteredShortcuts[iIndex].key() == UIHostCombo::hostComboCacheKey())
    620                         /* We should return host-combo: */
    621                         return UIHostCombo::toReadableString(m_filteredShortcuts[iIndex].currentSequence());
    622                     /* In other cases we should return hot-combo: */
    623                     QString strHotCombo = m_filteredShortcuts[iIndex].currentSequence();
    624                     /* But if that is machine table and hot-combo is not empty: */
    625                     if (m_type == UIActionPoolType_Runtime && !strHotCombo.isEmpty())
    626                         /* We should prepend it with Host+ prefix: */
    627                         strHotCombo.prepend(UIHostCombo::hostComboModifierName());
    628                     /* Return what we've got: */
    629                     return strHotCombo;
    630                 }
    631                 default: break;
    632             }
    633             /* Invalid for other cases: */
    634             return QString();
    635         }
    636         case Qt::EditRole:
    637         {
    638             /* Switch for different columns: */
    639             switch (index.column())
    640             {
    641                 case UIHotKeyColumnIndex_Sequence: return m_filteredShortcuts[iIndex].key() == UIHostCombo::hostComboCacheKey() ?
    642                                                           QVariant::fromValue(UIHostComboWrapper(m_filteredShortcuts[iIndex].currentSequence())) :
    643                                                           QVariant::fromValue(UIHotKey(m_type == UIActionPoolType_Runtime ?
    644                                                                                        UIHotKeyType_Simple : UIHotKeyType_WithModifiers,
    645                                                                                        m_filteredShortcuts[iIndex].currentSequence(),
    646                                                                                        m_filteredShortcuts[iIndex].defaultSequence()));
    647                 default: break;
    648             }
    649             /* Invalid for other cases: */
    650             return QString();
    651         }
    652         case Qt::FontRole:
    653         {
    654             /* Do we have a default font? */
    655             QFont font(QApplication::font());
    656             /* Switch for different columns: */
    657             switch (index.column())
    658             {
    659                 case UIHotKeyColumnIndex_Sequence:
    660                 {
    661                     if (m_filteredShortcuts[iIndex].key() != UIHostCombo::hostComboCacheKey() &&
    662                         m_filteredShortcuts[iIndex].currentSequence() != m_filteredShortcuts[iIndex].defaultSequence())
    663                         font.setBold(true);
    664                     break;
    665                 }
    666                 default: break;
    667             }
    668             /* Return resulting font: */
    669             return font;
    670         }
    671         case Qt::ForegroundRole:
    672         {
    673             /* Switch for different columns: */
    674             switch (index.column())
    675             {
    676                 case UIHotKeyColumnIndex_Sequence:
    677                 {
    678                     if (m_duplicatedSequences.contains(m_filteredShortcuts[iIndex].key()))
    679                         return QBrush(Qt::red);
    680                     break;
    681                 }
    682                 default: break;
    683             }
    684             /* Default for other cases: */
    685             return QString();
    686         }
    687         default: break;
    688     }
    689     /* Invalid by default: */
    690     return QVariant();
    691 }
    692 
    693 bool UIHotKeyTableModel::setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole*/)
    694 {
    695     /* Nothing to set for invalid index: */
    696     if (!index.isValid()) return false;
    697     /* Switch for different roles: */
    698     switch (iRole)
    699     {
    700         case Qt::EditRole:
    701         {
    702             /* Switch for different columns: */
    703             switch (index.column())
    704             {
    705                 case UIHotKeyColumnIndex_Sequence:
    706                 {
    707                     /* Get index: */
    708                     int iIndex = index.row();
    709                     /* Set sequence to shortcut: */
    710                     UIDataShortcutRow &filteredShortcut = m_filteredShortcuts[iIndex];
    711                     int iShortcutIndex = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(m_shortcuts, filteredShortcut);
    712                     if (iShortcutIndex != -1)
    713                     {
    714                         filteredShortcut.setCurrentSequence(filteredShortcut.key() == UIHostCombo::hostComboCacheKey() ?
    715                                                             value.value<UIHostComboWrapper>().toString() :
    716                                                             value.value<UIHotKey>().sequence());
    717                         m_shortcuts[iShortcutIndex] = filteredShortcut;
    718                         emit sigRevalidationRequired();
    719                         return true;
    720                     }
    721                     break;
    722                 }
    723                 default: break;
    724             }
    725             break;
    726         }
    727         default: break;
    728     }
    729     /* Nothing to set by default: */
    730     return false;
    731 }
    732 
    733 void UIHotKeyTableModel::sort(int iColumn, Qt::SortOrder order /* = Qt::AscendingOrder*/)
    734 {
    735     /* Sort whole the list: */
    736     qStableSort(m_shortcuts.begin(), m_shortcuts.end(), UIShortcutCacheItemFunctor(iColumn, order));
    737     /* Make sure host-combo item is always the first one: */
    738     UIDataShortcutRow fakeHostComboItem(0, UIHostCombo::hostComboCacheKey(), QString(), QString(), QString(), QString());
    739     int iIndexOfHostComboItem = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(m_shortcuts, fakeHostComboItem);
    740     if (iIndexOfHostComboItem != -1)
    741     {
    742         UIDataShortcutRow hostComboItem = m_shortcuts.takeAt(iIndexOfHostComboItem);
    743         m_shortcuts.prepend(hostComboItem);
    744     }
    745     /* Apply the filter: */
    746     applyFilter();
    747     /* Notify the model: */
    748     emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
    749 }
    750 
    751 void UIHotKeyTableModel::applyFilter()
    752 {
    753     /* Erase items first if necessary: */
    754     if (!m_filteredShortcuts.isEmpty())
    755     {
    756         beginRemoveRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1);
    757         m_filteredShortcuts.clear();
    758         endRemoveRows();
    759     }
    760 
    761     /* If filter is empty: */
    762     if (m_strFilter.isEmpty())
    763     {
    764         /* Just add all the items: */
    765         m_filteredShortcuts = m_shortcuts;
    766     }
    767     else
    768     {
    769         /* Check if the description matches the filter: */
    770         foreach (const UIDataShortcutRow &item, m_shortcuts)
    771         {
    772             /* If neither scope nor description or sequence matches the filter, skip item: */
    773             if (!item.scope().contains(m_strFilter, Qt::CaseInsensitive) &&
    774                 !item.description().contains(m_strFilter, Qt::CaseInsensitive) &&
    775                 !item.currentSequence().contains(m_strFilter, Qt::CaseInsensitive))
    776                 continue;
    777             /* Add that item: */
    778             m_filteredShortcuts << item;
    779         }
    780     }
    781 
    782     /* Add items finally if necessary: */
    783     if (!m_filteredShortcuts.isEmpty())
    784     {
    785         beginInsertRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1);
    786         endInsertRows();
    787     }
    788 }
    789 
    790 
    791 /*********************************************************************************************************************************
    792 *   Class UIHotKeyTable implementation.                                                                                          *
    793 *********************************************************************************************************************************/
    794 
    795 UIHotKeyTable::UIHotKeyTable(QWidget *pParent, UIHotKeyTableModel *pModel, const QString &strObjectName)
    796     : QITableView(pParent)
    797 {
    798     /* Set object name: */
    799     setObjectName(strObjectName);
    800     /* Set model: */
    801     setModel(pModel);
    802 
    803     /* Prepare all: */
     62UIGlobalSettingsInput::UIGlobalSettingsInput()
     63    : m_pCache(0)
     64    , m_pEditorShortcutConfiguration(0)
     65    , m_pLabelInputExtended(0)
     66    , m_pEditorAutoCaptureKeyboard(0)
     67{
    80468    prepare();
    80569}
    80670
    807 int UIHotKeyTable::childCount() const
    808 {
    809     /* Redirect request to table model: */
    810     return qobject_cast<UIHotKeyTableModel*>(model())->childCount();
    811 }
    812 
    813 QITableViewRow *UIHotKeyTable::childItem(int iIndex) const
    814 {
    815     /* Redirect request to table model: */
    816     return qobject_cast<UIHotKeyTableModel*>(model())->childItem(iIndex);
    817 }
    818 
    819 void UIHotKeyTable::sltHandleShortcutsLoaded()
    820 {
    821     /* Resize columns to feat contents: */
    822     resizeColumnsToContents();
    823 
    824     /* Configure sorting: */
    825     sortByColumn(UIHotKeyColumnIndex_Description, Qt::AscendingOrder);
    826     setSortingEnabled(true);
    827 }
    828 
    829 void UIHotKeyTable::prepare()
    830 {
    831     /* Configure self: */
    832     setTabKeyNavigation(false);
    833     setContextMenuPolicy(Qt::CustomContextMenu);
    834     setSelectionBehavior(QAbstractItemView::SelectRows);
    835     setSelectionMode(QAbstractItemView::SingleSelection);
    836     setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked);
    837 
    838     /* Configure headers: */
    839     verticalHeader()->hide();
    840     verticalHeader()->setDefaultSectionSize((int)(verticalHeader()->minimumSectionSize() * 1.33));
    841     horizontalHeader()->setStretchLastSection(false);
    842     horizontalHeader()->setSectionResizeMode(UIHotKeyColumnIndex_Description, QHeaderView::Interactive);
    843     horizontalHeader()->setSectionResizeMode(UIHotKeyColumnIndex_Sequence, QHeaderView::Stretch);
    844 
    845     /* Connect model: */
    846     UIHotKeyTableModel *pHotKeyTableModel = qobject_cast<UIHotKeyTableModel*>(model());
    847     AssertPtrReturnVoid(pHotKeyTableModel);
    848     {
    849         connect(pHotKeyTableModel, &UIHotKeyTableModel::sigShortcutsLoaded,
    850                 this, &UIHotKeyTable::sltHandleShortcutsLoaded);
    851     }
    852 
    853     /* Check if we do have proper item delegate: */
    854     QIStyledItemDelegate *pStyledItemDelegate = qobject_cast<QIStyledItemDelegate*>(itemDelegate());
    855     AssertPtrReturnVoid(pStyledItemDelegate);
    856     {
    857         /* Configure item delegate: */
    858         pStyledItemDelegate->setWatchForEditorDataCommits(true);
    859 
    860         /* Create new item editor factory: */
    861         QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;
    862         AssertPtrReturnVoid(pNewItemEditorFactory);
    863         {
    864             /* Register UIHotKeyEditor as the UIHotKey editor: */
    865             int iHotKeyTypeId = qRegisterMetaType<UIHotKey>();
    866             QStandardItemEditorCreator<UIHotKeyEditor> *pHotKeyItemEditorCreator = new QStandardItemEditorCreator<UIHotKeyEditor>();
    867             pNewItemEditorFactory->registerEditor((QVariant::Type)iHotKeyTypeId, pHotKeyItemEditorCreator);
    868 
    869             /* Register UIHostComboEditor as the UIHostComboWrapper editor: */
    870             int iHostComboTypeId = qRegisterMetaType<UIHostComboWrapper>();
    871             QStandardItemEditorCreator<UIHostComboEditor> *pHostComboItemEditorCreator = new QStandardItemEditorCreator<UIHostComboEditor>();
    872             pNewItemEditorFactory->registerEditor((QVariant::Type)iHostComboTypeId, pHostComboItemEditorCreator);
    873 
    874             /* Assign configured item editor factory to item delegate: */
    875             pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory);
    876         }
    877     }
    878 }
    879 
    880 
    881 /*********************************************************************************************************************************
    882 *   Class UIGlobalSettingsInput implementation.                                                                                  *
    883 *********************************************************************************************************************************/
    884 
    885 UIGlobalSettingsInput::UIGlobalSettingsInput()
    886     : m_pModelManager(0)
    887     , m_pModelRuntime(0)
    888     , m_pCache(0)
    889     , m_pTabWidget(0)
    890     , m_pEditorManagerFilter(0), m_pTableManager(0)
    891     , m_pEditorRuntimeFilter(0), m_pTableRuntime(0)
    892     , m_pCheckBoxEnableAutoGrab(0)
    893 {
    894     /* Prepare: */
    895     prepare();
    896 }
    897 
    89871UIGlobalSettingsInput::~UIGlobalSettingsInput()
    89972{
    900     /* Cleanup: */
    90173    cleanup();
    90274}
     
    91082    m_pCache->clear();
    91183
    912     /* Prepare old input data: */
    913     UIDataSettingsGlobalInput oldInputData;
    914 
    915     /* Gather old input data: */
    916     oldInputData.shortcuts() << UIDataShortcutRow(m_pTableRuntime,
    917                                                   UIHostCombo::hostComboCacheKey(),
    918                                                   QString(),
    919                                                   tr("Host Key Combination"),
    920                                                   gEDataManager->hostKeyCombination(),
    921                                                   QString());
     84    /* Cache old data: */
     85    UIDataSettingsGlobalInput oldData;
     86    UIShortcutConfigurationList list;
     87    list << UIShortcutConfigurationItem(UIHostCombo::hostComboCacheKey(),
     88                                        QString(),
     89                                        tr("Host Key Combination"),
     90                                        gEDataManager->hostKeyCombination(),
     91                                        QString());
    92292    const QMap<QString, UIShortcut> &shortcuts = gShortcutPool->shortcuts();
    92393    const QList<QString> shortcutKeys = shortcuts.keys();
    92494    foreach (const QString &strShortcutKey, shortcutKeys)
    92595    {
    926         const UIShortcut &shortcut = shortcuts[strShortcutKey];
    927         QITableView *pParent = strShortcutKey.startsWith(GUI_Input_MachineShortcuts) ? m_pTableRuntime :
    928                                strShortcutKey.startsWith(GUI_Input_SelectorShortcuts) ? m_pTableManager : 0;
    929         AssertPtr(pParent);
    930         oldInputData.shortcuts() << UIDataShortcutRow(pParent,
    931                                                       strShortcutKey,
    932                                                       shortcut.scope(),
    933                                                       UICommon::removeAccelMark(shortcut.description()),
    934                                                       shortcut.primaryToNativeText(),
    935                                                       shortcut.defaultSequence().toString(QKeySequence::NativeText));
    936     }
    937     oldInputData.setAutoCapture(gEDataManager->autoCaptureEnabled());
    938 
    939     /* Cache old input data: */
    940     m_pCache->cacheInitialData(oldInputData);
     96        const UIShortcut &shortcut = shortcuts.value(strShortcutKey);
     97        list << UIShortcutConfigurationItem(strShortcutKey,
     98                                            shortcut.scope(),
     99                                            UICommon::removeAccelMark(shortcut.description()),
     100                                            shortcut.primaryToNativeText(),
     101                                            shortcut.defaultSequence().toString(QKeySequence::NativeText));
     102    }
     103    oldData.m_shortcuts = list;
     104    oldData.m_fAutoCapture = gEDataManager->autoCaptureEnabled();
     105    m_pCache->cacheInitialData(oldData);
    941106
    942107    /* Upload properties to data: */
     
    946111void UIGlobalSettingsInput::getFromCache()
    947112{
    948     /* Get old input data from the cache: */
    949     const UIDataSettingsGlobalInput &oldInputData = m_pCache->base();
    950 
    951     /* Load old input data from the cache: */
    952     m_pModelManager->load(oldInputData.shortcuts());
    953     m_pModelRuntime->load(oldInputData.shortcuts());
    954     m_pCheckBoxEnableAutoGrab->setChecked(oldInputData.autoCapture());
     113    /* Load old data from cache: */
     114    const UIDataSettingsGlobalInput &oldData = m_pCache->base();
     115    m_pEditorShortcutConfiguration->load(oldData.m_shortcuts);
     116    m_pEditorAutoCaptureKeyboard->setValue(oldData.m_fAutoCapture);
    955117
    956118    /* Revalidate: */
     
    960122void UIGlobalSettingsInput::putToCache()
    961123{
    962     /* Prepare new input data: */
    963     UIDataSettingsGlobalInput newInputData = m_pCache->base();
    964 
    965     /* Gather new input data: */
    966     m_pModelManager->save(newInputData.shortcuts());
    967     m_pModelRuntime->save(newInputData.shortcuts());
    968     newInputData.setAutoCapture(m_pCheckBoxEnableAutoGrab->isChecked());
    969 
    970     /* Cache new input data: */
    971     m_pCache->cacheCurrentData(newInputData);
     124    /* Prepare new data: */
     125    UIDataSettingsGlobalInput newData = m_pCache->base();
     126
     127    /* Cache new data: */
     128    m_pEditorShortcutConfiguration->save(newData.m_shortcuts);
     129    newData.m_fAutoCapture = m_pEditorAutoCaptureKeyboard->value();
     130    m_pCache->cacheCurrentData(newData);
    972131}
    973132
     
    977136    UISettingsPageGlobal::fetchData(data);
    978137
    979     /* Update input data and failing state: */
    980     setFailed(!saveInputData());
     138    /* Update data and failing state: */
     139    setFailed(!saveData());
    981140
    982141    /* Upload properties to data: */
     
    990149
    991150    /* Check VirtualBox Manager page for unique shortcuts: */
    992     if (!m_pModelManager->isAllShortcutsUnique())
     151    if (!m_pEditorShortcutConfiguration->isShortcutsUniqueManager())
    993152    {
    994153        UIValidationMessage message;
    995         message.first = UICommon::removeAccelMark(m_pTabWidget->tabText(UIHotKeyTableIndex_Selector));
     154        message.first = UICommon::removeAccelMark(m_pEditorShortcutConfiguration->tabNameManager());
    996155        message.second << tr("Some items have the same shortcuts assigned.");
    997156        messages << message;
     
    999158    }
    1000159
    1001     /* Check Virtual Machine page for unique shortcuts: */
    1002     if (!m_pModelRuntime->isAllShortcutsUnique())
     160    /* Check Virtual Runtime page for unique shortcuts: */
     161    if (!m_pEditorShortcutConfiguration->isShortcutsUniqueRuntime())
    1003162    {
    1004163        UIValidationMessage message;
    1005         message.first = UICommon::removeAccelMark(m_pTabWidget->tabText(UIHotKeyTableIndex_Machine));
     164        message.first = UICommon::removeAccelMark(m_pEditorShortcutConfiguration->tabNameRuntime());
    1006165        message.second << tr("Some items have the same shortcuts assigned.");
    1007166        messages << message;
     
    1013172}
    1014173
    1015 void UIGlobalSettingsInput::setOrderAfter(QWidget *pWidget)
    1016 {
    1017     setTabOrder(pWidget, m_pTabWidget);
    1018     setTabOrder(m_pTabWidget, m_pEditorManagerFilter);
    1019     setTabOrder(m_pEditorManagerFilter, m_pTableManager);
    1020     setTabOrder(m_pTableManager, m_pEditorRuntimeFilter);
    1021     setTabOrder(m_pEditorRuntimeFilter, m_pTableRuntime);
    1022     setTabOrder(m_pTableRuntime, m_pCheckBoxEnableAutoGrab);
    1023 }
    1024 
    1025174void UIGlobalSettingsInput::retranslateUi()
    1026175{
    1027     m_pCheckBoxEnableAutoGrab->setWhatsThis(tr("When checked, the keyboard is automatically captured every time the VM window "
    1028                                                "is activated. When the keyboard is captured, all keystrokes (including system ones "
    1029                                                "like Alt-Tab) are directed to the VM."));
    1030     m_pCheckBoxEnableAutoGrab->setText(tr("&Auto Capture Keyboard"));
    1031 
    1032 
    1033     /* Translate tab-widget labels: */
    1034     m_pTabWidget->setTabText(UIHotKeyTableIndex_Selector, tr("&VirtualBox Manager"));
    1035     m_pTabWidget->setTabText(UIHotKeyTableIndex_Machine, tr("Virtual &Machine"));
    1036     m_pTableManager->setWhatsThis(tr("Lists all available shortcuts which can be configured."));
    1037     m_pTableRuntime->setWhatsThis(tr("Lists all available shortcuts which can be configured."));
    1038     m_pEditorManagerFilter->setWhatsThis(tr("Holds a sequence to filter the shortcut list."));
    1039     m_pEditorRuntimeFilter->setWhatsThis(tr("Holds a sequence to filter the shortcut list."));
     176    m_pLabelInputExtended->setText(tr("Extended Features:"));
    1040177}
    1041178
     
    1057194{
    1058195    /* Prepare main layout: */
    1059     QGridLayout *pMainLayout = new QGridLayout(this);
    1060     if (pMainLayout)
    1061     {
    1062         /* Prepare tab-widget: */
    1063         m_pTabWidget = new QTabWidget(this);
    1064         if (m_pTabWidget)
     196    QGridLayout *pLayoutMain = new QGridLayout(this);
     197    if (pLayoutMain)
     198    {
     199        /* Prepare 'shortcut configuration' editor: */
     200        m_pEditorShortcutConfiguration = new UIShortcutConfigurationEditor(this);
     201        if (m_pEditorShortcutConfiguration)
     202            pLayoutMain->addWidget(m_pEditorShortcutConfiguration, 0, 0, 1, 2);
     203
     204        /* Prepare input extended label: */
     205        m_pLabelInputExtended = new QLabel(this);
     206        if (m_pLabelInputExtended)
    1065207        {
    1066             /* Prepare 'Manager UI' tab: */
    1067             prepareTabManager();
    1068             /* Prepare 'Runtime UI' tab: */
    1069             prepareTabMachine();
    1070 
    1071             /* Add tab-widget into layout: */
    1072             pMainLayout->addWidget(m_pTabWidget, 0, 0, 1, 2);
     208            m_pLabelInputExtended->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
     209            pLayoutMain->addWidget(m_pLabelInputExtended, 1, 0);
    1073210        }
    1074 
    1075         /* Prepare 'enable auto-grab' check-box: */
    1076         m_pCheckBoxEnableAutoGrab = new QCheckBox(this);
    1077         if (m_pCheckBoxEnableAutoGrab)
    1078             pMainLayout->addWidget(m_pCheckBoxEnableAutoGrab, 1, 0);
    1079     }
    1080 }
    1081 
    1082 void UIGlobalSettingsInput::prepareTabManager()
    1083 {
    1084     /* Prepare Manager UI tab: */
    1085     QWidget *pTabManager = new QWidget;
    1086     if (pTabManager)
    1087     {
    1088         /* Prepare Manager UI layout: */
    1089         QVBoxLayout *pLayoutManager = new QVBoxLayout(pTabManager);
    1090         if (pLayoutManager)
    1091         {
    1092             pLayoutManager->setSpacing(1);
    1093 #ifdef VBOX_WS_MAC
    1094             /* On Mac OS X and X11 we can do a bit of smoothness: */
    1095             pLayoutManager->setContentsMargins(0, 0, 0, 0);
    1096 #endif
    1097 
    1098             /* Prepare Manager UI filter editor: */
    1099             m_pEditorManagerFilter = new QLineEdit(pTabManager);
    1100             if (m_pEditorManagerFilter)
    1101                 pLayoutManager->addWidget(m_pEditorManagerFilter);
    1102 
    1103             /* Prepare Manager UI model: */
    1104             m_pModelManager = new UIHotKeyTableModel(this, UIActionPoolType_Manager);
    1105 
    1106             /* Prepare Manager UI table: */
    1107             m_pTableManager = new UIHotKeyTable(pTabManager, m_pModelManager, "m_pTableManager");
    1108             if (m_pTableManager)
    1109                 pLayoutManager->addWidget(m_pTableManager);
    1110         }
    1111 
    1112         m_pTabWidget->insertTab(UIHotKeyTableIndex_Selector, pTabManager, QString());
    1113     }
    1114 }
    1115 
    1116 void UIGlobalSettingsInput::prepareTabMachine()
    1117 {
    1118     /* Create Runtime UI tab: */
    1119     QWidget *pTabMachine = new QWidget;
    1120     if (pTabMachine)
    1121     {
    1122         /* Prepare Runtime UI layout: */
    1123         QVBoxLayout *pLayoutMachine = new QVBoxLayout(pTabMachine);
    1124         if (pLayoutMachine)
    1125         {
    1126             pLayoutMachine->setSpacing(1);
    1127 #ifdef VBOX_WS_MAC
    1128             /* On Mac OS X and X11 we can do a bit of smoothness: */
    1129             pLayoutMachine->setContentsMargins(0, 0, 0, 0);
    1130 #endif
    1131 
    1132             /* Prepare Runtime UI filter editor: */
    1133             m_pEditorRuntimeFilter = new QLineEdit(pTabMachine);
    1134             if (m_pEditorRuntimeFilter)
    1135                 pLayoutMachine->addWidget(m_pEditorRuntimeFilter);
    1136 
    1137             /* Prepare Runtime UI model: */
    1138             m_pModelRuntime = new UIHotKeyTableModel(this, UIActionPoolType_Runtime);
    1139 
    1140             /* Create Runtime UI table: */
    1141             m_pTableRuntime = new UIHotKeyTable(pTabMachine, m_pModelRuntime, "m_pTableRuntime");
    1142             if (m_pTableRuntime)
    1143                 pLayoutMachine->addWidget(m_pTableRuntime);
    1144         }
    1145 
    1146         m_pTabWidget->insertTab(UIHotKeyTableIndex_Machine, pTabMachine, QString());
    1147 
    1148         /* In the VM process we start by displaying the Runtime UI tab: */
    1149         if (uiCommon().uiType() == UICommon::UIType_RuntimeUI)
    1150             m_pTabWidget->setCurrentWidget(pTabMachine);
     211        /* Prepare 'auto capture keyboard' editor: */
     212        m_pEditorAutoCaptureKeyboard = new UIAutoCaptureKeyboardEditor(this);
     213        if (m_pEditorAutoCaptureKeyboard)
     214            pLayoutMain->addWidget(m_pEditorAutoCaptureKeyboard, 1, 1);
    1151215    }
    1152216}
     
    1154218void UIGlobalSettingsInput::prepareConnections()
    1155219{
    1156     /* Configure 'Manager UI' connections: */
    1157     connect(m_pEditorManagerFilter, &QLineEdit::textChanged, m_pModelManager, &UIHotKeyTableModel::sltHandleFilterTextChange);
    1158     connect(m_pModelManager, &UIHotKeyTableModel::sigRevalidationRequired, this, &UIGlobalSettingsInput::revalidate);
    1159 
    1160     /* Configure 'Runtime UI' connections: */
    1161     connect(m_pEditorRuntimeFilter, &QLineEdit::textChanged, m_pModelRuntime, &UIHotKeyTableModel::sltHandleFilterTextChange);
    1162     connect(m_pModelRuntime, &UIHotKeyTableModel::sigRevalidationRequired, this, &UIGlobalSettingsInput::revalidate);
     220    connect(m_pEditorShortcutConfiguration, &UIShortcutConfigurationEditor::sigValueChanged,
     221            this, &UIGlobalSettingsInput::revalidate);
    1163222}
    1164223
     
    1170229}
    1171230
    1172 bool UIGlobalSettingsInput::saveInputData()
     231bool UIGlobalSettingsInput::saveData()
    1173232{
    1174233    /* Prepare result: */
    1175234    bool fSuccess = true;
    1176     /* Save input settings from the cache: */
     235    /* Save settings from cache: */
    1177236    if (fSuccess && m_pCache->wasChanged())
    1178237    {
    1179         /* Get old input data from the cache: */
    1180         const UIDataSettingsGlobalInput &oldInputData = m_pCache->base();
    1181         /* Get new input data from the cache: */
    1182         const UIDataSettingsGlobalInput &newInputData = m_pCache->data();
    1183 
    1184         /* Save new host-combo shortcut from the cache: */
    1185         const UIDataShortcutRow fakeHostComboItem(0, UIHostCombo::hostComboCacheKey(), QString(), QString(), QString(), QString());
    1186         const int iHostComboItemBase = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(oldInputData.shortcuts(), fakeHostComboItem);
    1187         const int iHostComboItemData = UIFunctorFindShortcut(UIFunctorFindShortcut::Base)(newInputData.shortcuts(), fakeHostComboItem);
    1188         const QString strHostComboBase = iHostComboItemBase != -1 ? oldInputData.shortcuts().at(iHostComboItemBase).currentSequence() : QString();
    1189         const QString strHostComboData = iHostComboItemData != -1 ? newInputData.shortcuts().at(iHostComboItemData).currentSequence() : QString();
     238        /* Get old data from cache: */
     239        const UIDataSettingsGlobalInput &oldData = m_pCache->base();
     240        /* Get new data from cache: */
     241        const UIDataSettingsGlobalInput &newData = m_pCache->data();
     242
     243        /* Save new host-combo shortcut from cache: */
     244        const UIShortcutConfigurationItem fakeHostComboItem(UIHostCombo::hostComboCacheKey(), QString(), QString(), QString(), QString());
     245        const int iHostComboItemBase = UIShortcutSearchFunctor<UIShortcutConfigurationItem>()(oldData.m_shortcuts, fakeHostComboItem);
     246        const int iHostComboItemData = UIShortcutSearchFunctor<UIShortcutConfigurationItem>()(newData.m_shortcuts, fakeHostComboItem);
     247        const QString strHostComboBase = iHostComboItemBase != -1 ? oldData.m_shortcuts.at(iHostComboItemBase).currentSequence() : QString();
     248        const QString strHostComboData = iHostComboItemData != -1 ? newData.m_shortcuts.at(iHostComboItemData).currentSequence() : QString();
    1190249        if (strHostComboData != strHostComboBase)
    1191250            gEDataManager->setHostKeyCombination(strHostComboData);
    1192251
    1193         /* Save other new shortcuts from the cache: */
     252        /* Save other new shortcuts from cache: */
    1194253        QMap<QString, QString> sequencesBase;
    1195254        QMap<QString, QString> sequencesData;
    1196         foreach (const UIDataShortcutRow &item, oldInputData.shortcuts())
     255        foreach (const UIShortcutConfigurationItem &item, oldData.m_shortcuts)
    1197256            sequencesBase.insert(item.key(), item.currentSequence());
    1198         foreach (const UIDataShortcutRow &item, newInputData.shortcuts())
     257        foreach (const UIShortcutConfigurationItem &item, newData.m_shortcuts)
    1199258            sequencesData.insert(item.key(), item.currentSequence());
    1200259        if (sequencesData != sequencesBase)
    1201260            gShortcutPool->setOverrides(sequencesData);
    1202261
    1203         /* Save other new things from the cache: */
    1204         if (newInputData.autoCapture() != oldInputData.autoCapture())
    1205             gEDataManager->setAutoCaptureEnabled(newInputData.autoCapture());
     262        /* Save other new things from cache: */
     263        if (newData.m_fAutoCapture != oldData.m_fAutoCapture)
     264            gEDataManager->setAutoCaptureEnabled(newData.m_fAutoCapture);
    1206265    }
    1207266    /* Return result: */
    1208267    return fSuccess;
    1209268}
    1210 
    1211 # include "UIGlobalSettingsInput.moc"
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.h

    r86095 r86124  
    2525#include "UISettingsPage.h"
    2626
    27 /* Forward declartions: */
    28 class QCheckBox;
    29 class QLineEdit;
    30 class QTabWidget;
    31 class UIDataSettingsGlobalInput;
    32 class UIHotKeyTable;
    33 class UIHotKeyTableModel;
     27/* Forward declarations: */
     28class QLabel;
     29class UIAutoCaptureKeyboardEditor;
     30class UIShortcutConfigurationEditor;
     31struct UIDataSettingsGlobalInput;
    3432typedef UISettingsCache<UIDataSettingsGlobalInput> UISettingsCacheGlobalInput;
    3533
     
    3937    Q_OBJECT;
    4038
    41     /** Hot-key table indexes. */
    42     enum { UIHotKeyTableIndex_Selector, UIHotKeyTableIndex_Machine };
    43 
    4439public:
    4540
    46     /** Constructs Input settings page. */
     41    /** Constructs settings page. */
    4742    UIGlobalSettingsInput();
    48     /** Destructs Input settings page. */
    49     ~UIGlobalSettingsInput();
     43    /** Destructs settings page. */
     44    virtual ~UIGlobalSettingsInput() /* override */;
    5045
    5146protected:
     
    6863    virtual bool validate(QList<UIValidationMessage> &messages) /* override */;
    6964
    70     /** Defines TAB order for passed @a pWidget. */
    71     virtual void setOrderAfter(QWidget *pWidget) /* override */;
    72 
    7365    /** Handles translation event. */
    7466    virtual void retranslateUi() /* override */;
     
    8072    /** Prepares widgets. */
    8173    void prepareWidgets();
    82     /** Prepares Manager UI tab. */
    83     void prepareTabManager();
    84     /** Prepares Runtime UI tab. */
    85     void prepareTabMachine();
    8674    /** Prepares connections. */
    8775    void prepareConnections();
     
    8977    void cleanup();
    9078
    91     /** Saves existing input data from the cache. */
    92     bool saveInputData();
    93 
    94     /** Holds the Manager UI shortcuts model instance. */
    95     UIHotKeyTableModel *m_pModelManager;
    96     /** Holds the Runtime UI shortcuts model instance. */
    97     UIHotKeyTableModel *m_pModelRuntime;
     79    /** Saves existing data from the cache. */
     80    bool saveData();
    9881
    9982    /** Holds the page data cache instance. */
     
    10285    /** @name Widgets
    10386     * @{ */
    104         /** Holds the tab-widget instance. */
    105         QTabWidget    *m_pTabWidget;
    106         /** Holds the Manager UI shortcuts filter instance. */
    107         QLineEdit     *m_pEditorManagerFilter;
    108         /** Holds the Manager UI shortcuts table instance. */
    109         UIHotKeyTable *m_pTableManager;
    110         /** Holds the Runtime UI shortcuts filter instance. */
    111         QLineEdit     *m_pEditorRuntimeFilter;
    112         /** Holds the Runtime UI shortcuts table instance. */
    113         UIHotKeyTable *m_pTableRuntime;
    114         /** Holds the 'enable auto-grab' checkbox instance. */
    115         QCheckBox     *m_pCheckBoxEnableAutoGrab;
     87        /** Holds the 'shortcut configuration' editor instance. */
     88        UIShortcutConfigurationEditor *m_pEditorShortcutConfiguration;
     89        /** Holds the input extended label instance. */
     90        QLabel                        *m_pLabelInputExtended;
     91        /** Holds the 'auto capture keyboard' editor instance. */
     92        UIAutoCaptureKeyboardEditor   *m_pEditorAutoCaptureKeyboard;
    11693    /** @} */
    11794};
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