- Timestamp:
- Nov 10, 2014 5:11:24 PM (10 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 3 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r53041 r53295 275 275 src/extensions/QIStatusBar.h \ 276 276 src/extensions/QIStatusBarIndicator.h \ 277 src/extensions/QIStyledItemDelegate.h \ 277 278 src/extensions/QITabWidget.h \ 278 279 src/extensions/QITableView.h \ … … 495 496 src/selector/UIVMDesktop.cpp \ 496 497 src/settings/UISettingsDialogSpecific.cpp \ 497 src/settings/global/UIGlobalSettingsInput.cpp \498 498 src/settings/machine/UIMachineSettingsStorage.cpp \ 499 499 src/settings/machine/UIMachineSettingsUSB.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIStyledItemDelegate.h
r53291 r53295 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIGlobalSettingsInput class implementation.3 * VBox Qt GUI - QIStyledItemDelegate class declaration. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2006-201 3Oracle Corporation7 * Copyright (C) 2006-2014 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 19 19 # include <precomp.h> 20 20 #else /* !VBOX_WITH_PRECOMPILED_HEADERS */ 21 22 21 /* Qt includes: */ 23 # include <QHeaderView>24 # include <QAbstractItemDelegate>25 22 # include <QStyledItemDelegate> 26 # include <QItemEditorFactory>27 # include <QTabWidget>28 29 /* GUI includes: */30 # include "QIWidgetValidator.h"31 # include "UIGlobalSettingsInput.h"32 # include "UIShortcutPool.h"33 # include "UIHotKeyEditor.h"34 # include "UIHostComboEditor.h"35 # include "VBoxGlobalSettings.h"36 37 23 #endif /* !VBOX_WITH_PRECOMPILED_HEADERS */ 38 24 39 #include <QShortcut>40 41 42 /* Namespaces: */43 using namespace UIExtraDataDefs;44 45 46 /* Input page constructor: */47 UIGlobalSettingsInput::UIGlobalSettingsInput()48 : m_pTabWidget(0)49 , m_pSelectorFilterEditor(0), m_pSelectorModel(0), m_pSelectorTable(0)50 , m_pMachineFilterEditor(0), m_pMachineModel(0), m_pMachineTable(0)51 {52 /* Apply UI decorations: */53 Ui::UIGlobalSettingsInput::setupUi(this);54 55 /* Create tab widget: */56 m_pTabWidget = new QTabWidget(this);57 m_pTabWidget->setMinimumWidth(400);58 m_pMainLayout->addWidget(m_pTabWidget, 0, 0, 1, 2);59 60 /* Create selector tab: */61 QWidget *pSelectorTab = new QWidget;62 m_pTabWidget->insertTab(UIHotKeyTableIndex_Selector, pSelectorTab, QString());63 m_pSelectorFilterEditor = new QLineEdit(pSelectorTab);64 m_pSelectorModel = new UIHotKeyTableModel(this, UIActionPoolType_Selector);65 m_pSelectorTable = new UIHotKeyTable(pSelectorTab, m_pSelectorModel, "m_pSelectorTable");66 connect(m_pSelectorFilterEditor, SIGNAL(textChanged(const QString &)),67 m_pSelectorModel, SLOT(sltHandleFilterTextChange(const QString &)));68 QVBoxLayout *pSelectorLayout = new QVBoxLayout(pSelectorTab);69 #ifndef Q_WS_WIN70 /* On Windows host that looks ugly, but71 * On Mac OS X and X11 that deserves it's place. */72 pSelectorLayout->setContentsMargins(0, 0, 0, 0);73 #endif /* !Q_WS_WIN */74 pSelectorLayout->setSpacing(1);75 pSelectorLayout->addWidget(m_pSelectorFilterEditor);76 pSelectorLayout->addWidget(m_pSelectorTable);77 setTabOrder(m_pTabWidget, m_pSelectorFilterEditor);78 setTabOrder(m_pSelectorFilterEditor, m_pSelectorTable);79 80 /* Create machine tab: */81 QWidget *pMachineTab = new QWidget;82 m_pTabWidget->insertTab(UIHotKeyTableIndex_Machine, pMachineTab, QString());83 m_pMachineFilterEditor = new QLineEdit(pMachineTab);84 m_pMachineModel = new UIHotKeyTableModel(this, UIActionPoolType_Runtime);85 m_pMachineTable = new UIHotKeyTable(pMachineTab, m_pMachineModel, "m_pMachineTable");86 connect(m_pMachineFilterEditor, SIGNAL(textChanged(const QString &)),87 m_pMachineModel, SLOT(sltHandleFilterTextChange(const QString &)));88 QVBoxLayout *pMachineLayout = new QVBoxLayout(pMachineTab);89 #ifndef Q_WS_WIN90 /* On Windows host that looks ugly, but91 * On Mac OS X and X11 that deserves it's place. */92 pMachineLayout->setContentsMargins(0, 0, 0, 0);93 #endif /* !Q_WS_WIN */94 pMachineLayout->setSpacing(1);95 pMachineLayout->addWidget(m_pMachineFilterEditor);96 pMachineLayout->addWidget(m_pMachineTable);97 setTabOrder(m_pSelectorTable, m_pMachineFilterEditor);98 setTabOrder(m_pMachineFilterEditor, m_pMachineTable);99 100 /* Prepare validation: */101 prepareValidation();102 103 /* Apply language settings: */104 retranslateUi();105 }106 107 /* Load data to cache from corresponding external object(s),108 * this task COULD be performed in other than GUI thread: */109 void UIGlobalSettingsInput::loadToCacheFrom(QVariant &data)110 {111 /* Fetch data to properties & settings: */112 UISettingsPageGlobal::fetchData(data);113 114 /* Load host-combo shortcut to cache: */115 m_cache.m_shortcuts << UIShortcutCacheItem(UIHostCombo::hostComboCacheKey(), tr("Host Key Combination"), m_settings.hostCombo(), QString());116 /* Load all other shortcuts to cache: */117 const QMap<QString, UIShortcut>& shortcuts = gShortcutPool->shortcuts();118 const QList<QString> shortcutKeys = shortcuts.keys();119 foreach (const QString &strShortcutKey, shortcutKeys)120 {121 const UIShortcut &shortcut = shortcuts[strShortcutKey];122 m_cache.m_shortcuts << UIShortcutCacheItem(strShortcutKey, VBoxGlobal::removeAccelMark(shortcut.description()),123 shortcut.sequence().toString(QKeySequence::NativeText),124 shortcut.defaultSequence().toString(QKeySequence::NativeText));125 }126 /* Load other things to cache: */127 m_cache.m_fAutoCapture = m_settings.autoCapture();128 129 /* Upload properties & settings to data: */130 UISettingsPageGlobal::uploadData(data);131 }132 133 /* Load data to corresponding widgets from cache,134 * this task SHOULD be performed in GUI thread only: */135 void UIGlobalSettingsInput::getFromCache()136 {137 /* Fetch from cache: */138 m_pSelectorModel->load(m_cache.m_shortcuts);139 m_pMachineModel->load(m_cache.m_shortcuts);140 m_pEnableAutoGrabCheckbox->setChecked(m_cache.m_fAutoCapture);141 142 /* Revalidate: */143 revalidate();144 }145 146 /* Save data from corresponding widgets to cache,147 * this task SHOULD be performed in GUI thread only: */148 void UIGlobalSettingsInput::putToCache()149 {150 /* Upload to cache: */151 m_pSelectorModel->save(m_cache.m_shortcuts);152 m_pMachineModel->save(m_cache.m_shortcuts);153 m_cache.m_fAutoCapture = m_pEnableAutoGrabCheckbox->isChecked();154 }155 156 /* Save data from cache to corresponding external object(s),157 * this task COULD be performed in other than GUI thread: */158 void UIGlobalSettingsInput::saveFromCacheTo(QVariant &data)159 {160 /* Fetch data to properties & settings: */161 UISettingsPageGlobal::fetchData(data);162 163 /* Save host-combo shortcut from cache: */164 UIShortcutCacheItem fakeHostComboItem(UIHostCombo::hostComboCacheKey(), QString(), QString(), QString());165 int iIndexOfHostComboItem = m_cache.m_shortcuts.indexOf(fakeHostComboItem);166 if (iIndexOfHostComboItem != -1)167 m_settings.setHostCombo(m_cache.m_shortcuts[iIndexOfHostComboItem].currentSequence);168 /* Iterate over cached shortcuts: */169 QMap<QString, QString> sequences;170 foreach (const UIShortcutCacheItem &item, m_cache.m_shortcuts)171 sequences.insert(item.key, item.currentSequence);172 /* Save shortcut sequences from cache: */173 gShortcutPool->setOverrides(sequences);174 /* Save other things from cache: */175 m_settings.setAutoCapture(m_cache.m_fAutoCapture);176 177 /* Upload properties & settings to data: */178 UISettingsPageGlobal::uploadData(data);179 }180 181 bool UIGlobalSettingsInput::validate(QList<UIValidationMessage> &messages)182 {183 /* Pass by default: */184 bool fPass = true;185 186 /* Check VirtualBox Manager page for unique shortcuts: */187 if (!m_pSelectorModel->isAllShortcutsUnique())188 {189 UIValidationMessage message;190 message.first = VBoxGlobal::removeAccelMark(m_pTabWidget->tabText(UIHotKeyTableIndex_Selector));191 message.second << tr("Some items have the same shortcuts assigned.");192 messages << message;193 fPass = false;194 }195 196 /* Check Virtual Machine page for unique shortcuts: */197 if (!m_pMachineModel->isAllShortcutsUnique())198 {199 UIValidationMessage message;200 message.first = VBoxGlobal::removeAccelMark(m_pTabWidget->tabText(UIHotKeyTableIndex_Machine));201 message.second << tr("Some items have the same shortcuts assigned.");202 messages << message;203 fPass = false;204 }205 206 /* Return result: */207 return fPass;208 }209 210 /* Navigation stuff: */211 void UIGlobalSettingsInput::setOrderAfter(QWidget *pWidget)212 {213 setTabOrder(pWidget, m_pTabWidget);214 setTabOrder(m_pMachineTable, m_pEnableAutoGrabCheckbox);215 }216 217 /* Translation stuff: */218 void UIGlobalSettingsInput::retranslateUi()219 {220 /* Translate uic generated strings: */221 Ui::UIGlobalSettingsInput::retranslateUi(this);222 223 /* Translate tab-widget labels: */224 m_pTabWidget->setTabText(UIHotKeyTableIndex_Selector, tr("&VirtualBox Manager"));225 m_pTabWidget->setTabText(UIHotKeyTableIndex_Machine, tr("Virtual &Machine"));226 m_pSelectorTable->setWhatsThis(tr("Lists all the available shortcuts "227 "which can be configured."));228 m_pMachineTable->setWhatsThis(tr("Lists all the available shortcuts "229 "which can be configured."));230 m_pSelectorFilterEditor->setWhatsThis(tr("Enter a sequence to filter the shortcut list."));231 m_pMachineFilterEditor->setWhatsThis(tr("Enter a sequence to filter the shortcut list."));232 }233 234 void UIGlobalSettingsInput::prepareValidation()235 {236 /* Prepare validation: */237 connect(m_pSelectorModel, SIGNAL(sigRevalidationRequired()), this, SLOT(revalidate()));238 connect(m_pMachineModel, SIGNAL(sigRevalidationRequired()), this, SLOT(revalidate()));239 }240 241 242 UIHotKeyTableModel::UIHotKeyTableModel(QObject *pParent, UIActionPoolType type)243 : QAbstractTableModel(pParent)244 , m_type(type)245 {246 }247 248 void UIHotKeyTableModel::load(const UIShortcutCache &shortcuts)249 {250 /* Load shortcuts: */251 foreach (const UIShortcutCacheItem &item, shortcuts)252 {253 /* Filter out unnecessary shortcuts: */254 if ((m_type == UIActionPoolType_Selector && item.key.startsWith(GUI_Input_MachineShortcuts)) ||255 (m_type == UIActionPoolType_Runtime && item.key.startsWith(GUI_Input_SelectorShortcuts)))256 continue;257 /* Load shortcut cache item into model: */258 m_shortcuts << item;259 }260 /* Apply filter: */261 applyFilter();262 /* Notify table: */263 emit sigShortcutsLoaded();264 }265 266 void UIHotKeyTableModel::save(UIShortcutCache &shortcuts)267 {268 /* Save model items: */269 foreach (const UIShortcutCacheItem &item, m_shortcuts)270 {271 /* Search for corresponding cache item index: */272 int iIndexOfCacheItem = shortcuts.indexOf(item);273 /* Make sure index is valid: */274 if (iIndexOfCacheItem == -1)275 continue;276 /* Save model item into the cache: */277 shortcuts[iIndexOfCacheItem] = item;278 }279 }280 281 bool UIHotKeyTableModel::isAllShortcutsUnique()282 {283 /* Enumerate all the sequences: */284 QMap<QString, QString> usedSequences;285 foreach (const UIShortcutCacheItem &item, m_shortcuts)286 if (!item.currentSequence.isEmpty())287 usedSequences.insertMulti(item.currentSequence, item.key);288 /* Enumerate all the duplicated sequences: */289 QSet<QString> duplicatedSequences;290 foreach (const QString &strKey, usedSequences.keys())291 if (usedSequences.count(strKey) > 1)292 duplicatedSequences.unite(usedSequences.values(strKey).toSet());293 /* Is there something changed? */294 if (m_duplicatedSequences != duplicatedSequences)295 {296 m_duplicatedSequences = duplicatedSequences;297 emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));298 }299 /* Are there duplicated shortcuts? */300 if (!m_duplicatedSequences.isEmpty())301 return false;302 /* True by default: */303 return true;304 }305 306 void UIHotKeyTableModel::sltHandleFilterTextChange(const QString &strText)307 {308 m_strFilter = strText;309 applyFilter();310 }311 312 int UIHotKeyTableModel::rowCount(const QModelIndex& /*parent = QModelIndex()*/) const313 {314 return m_filteredShortcuts.size();315 }316 317 int UIHotKeyTableModel::columnCount(const QModelIndex& /*parent = QModelIndex()*/) const318 {319 return 2;320 }321 322 Qt::ItemFlags UIHotKeyTableModel::flags(const QModelIndex &index) const323 {324 /* No flags for invalid index: */325 if (!index.isValid()) return Qt::NoItemFlags;326 /* Switch for different columns: */327 switch (index.column())328 {329 case UIHotKeyTableSection_Name: return Qt::ItemIsEnabled | Qt::ItemIsSelectable;330 case UIHotKeyTableSection_Value: return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;331 default: break;332 }333 /* No flags by default: */334 return Qt::NoItemFlags;335 }336 337 QVariant UIHotKeyTableModel::headerData(int iSection, Qt::Orientation orientation, int iRole /* = Qt::DisplayRole*/) const338 {339 /* Switch for different roles: */340 switch (iRole)341 {342 case Qt::DisplayRole:343 {344 /* Invalid for vertical header: */345 if (orientation == Qt::Vertical) return QString();346 /* Switch for different columns: */347 switch (iSection)348 {349 case UIHotKeyTableSection_Name: return tr("Name");350 case UIHotKeyTableSection_Value: return tr("Shortcut");351 default: break;352 }353 /* Invalid for other cases: */354 return QString();355 }356 default: break;357 }358 /* Invalid by default: */359 return QVariant();360 }361 362 QVariant UIHotKeyTableModel::data(const QModelIndex &index, int iRole /* = Qt::DisplayRole*/) const363 {364 /* No data for invalid index: */365 if (!index.isValid()) return QVariant();366 int iIndex = index.row();367 /* Switch for different roles: */368 switch (iRole)369 {370 case Qt::DisplayRole:371 {372 /* Switch for different columns: */373 switch (index.column())374 {375 case UIHotKeyTableSection_Name:376 {377 /* Return shortcut description: */378 return m_filteredShortcuts[iIndex].description;379 }380 case UIHotKeyTableSection_Value:381 {382 /* If that is host-combo cell: */383 if (m_filteredShortcuts[iIndex].key == UIHostCombo::hostComboCacheKey())384 /* We should return host-combo: */385 return UIHostCombo::toReadableString(m_filteredShortcuts[iIndex].currentSequence);386 /* In other cases we should return hot-combo: */387 QString strHotCombo = m_filteredShortcuts[iIndex].currentSequence;388 /* But if that is machine table and hot-combo is not empty: */389 if (m_type == UIActionPoolType_Runtime && !strHotCombo.isEmpty())390 /* We should prepend it with Host+ prefix: */391 strHotCombo.prepend(UIHostCombo::hostComboModifierName());392 /* Return what we've got: */393 return strHotCombo;394 }395 default: break;396 }397 /* Invalid for other cases: */398 return QString();399 }400 case Qt::EditRole:401 {402 /* Switch for different columns: */403 switch (index.column())404 {405 case UIHotKeyTableSection_Value: return m_filteredShortcuts[iIndex].key == UIHostCombo::hostComboCacheKey() ?406 QVariant::fromValue(UIHostComboWrapper(m_filteredShortcuts[iIndex].currentSequence)) :407 QVariant::fromValue(UIHotKey(m_type == UIActionPoolType_Runtime ?408 UIHotKeyType_Simple : UIHotKeyType_WithModifiers,409 m_filteredShortcuts[iIndex].currentSequence,410 m_filteredShortcuts[iIndex].defaultSequence));411 default: break;412 }413 /* Invalid for other cases: */414 return QString();415 }416 case Qt::FontRole:417 {418 /* Do we have a default font? */419 QFont font(QApplication::font());420 /* Switch for different columns: */421 switch (index.column())422 {423 case UIHotKeyTableSection_Value:424 {425 if (m_filteredShortcuts[iIndex].key != UIHostCombo::hostComboCacheKey() &&426 m_filteredShortcuts[iIndex].currentSequence != m_filteredShortcuts[iIndex].defaultSequence)427 font.setBold(true);428 break;429 }430 default: break;431 }432 /* Return resulting font: */433 return font;434 }435 case Qt::ForegroundRole:436 {437 /* Switch for different columns: */438 switch (index.column())439 {440 case UIHotKeyTableSection_Value:441 {442 if (m_duplicatedSequences.contains(m_filteredShortcuts[iIndex].key))443 return QBrush(Qt::red);444 break;445 }446 default: break;447 }448 /* Default for other cases: */449 return QString();450 }451 default: break;452 }453 /* Invalid by default: */454 return QVariant();455 }456 457 bool UIHotKeyTableModel::setData(const QModelIndex &index, const QVariant &value, int iRole /* = Qt::EditRole*/)458 {459 /* Nothing to set for invalid index: */460 if (!index.isValid()) return false;461 /* Switch for different roles: */462 switch (iRole)463 {464 case Qt::EditRole:465 {466 /* Switch for different columns: */467 switch (index.column())468 {469 case UIHotKeyTableSection_Value:470 {471 /* Get index: */472 int iIndex = index.row();473 /* Set sequence to shortcut: */474 UIShortcutCacheItem &filteredShortcut = m_filteredShortcuts[iIndex];475 int iShortcutIndex = m_shortcuts.indexOf(filteredShortcut);476 if (iShortcutIndex != -1)477 {478 filteredShortcut.currentSequence = filteredShortcut.key == UIHostCombo::hostComboCacheKey() ?479 value.value<UIHostComboWrapper>().toString() :480 value.value<UIHotKey>().sequence();481 m_shortcuts[iShortcutIndex] = filteredShortcut;482 emit sigRevalidationRequired();483 return true;484 }485 break;486 }487 default: break;488 }489 break;490 }491 default: break;492 }493 /* Nothing to set by default: */494 return false;495 }496 497 void UIHotKeyTableModel::sort(int iColumn, Qt::SortOrder order /* = Qt::AscendingOrder*/)498 {499 /* Sort whole the list: */500 qStableSort(m_shortcuts.begin(), m_shortcuts.end(), UIShortcutCacheItemFunctor(iColumn, order));501 /* Make sure host-combo item is always the first one: */502 UIShortcutCacheItem fakeHostComboItem(UIHostCombo::hostComboCacheKey(), QString(), QString(), QString());503 int iIndexOfHostComboItem = m_shortcuts.indexOf(fakeHostComboItem);504 if (iIndexOfHostComboItem != -1)505 {506 UIShortcutCacheItem hostComboItem = m_shortcuts.takeAt(iIndexOfHostComboItem);507 m_shortcuts.prepend(hostComboItem);508 }509 /* Apply the filter: */510 applyFilter();511 /* Notify the model: */512 emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));513 }514 515 void UIHotKeyTableModel::applyFilter()516 {517 /* Erase items first if necessary: */518 if (!m_filteredShortcuts.isEmpty())519 {520 beginRemoveRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1);521 m_filteredShortcuts.clear();522 endRemoveRows();523 }524 525 /* If filter is empty: */526 if (m_strFilter.isEmpty())527 {528 /* Just add all the items: */529 m_filteredShortcuts = m_shortcuts;530 }531 else532 {533 /* Check if the description matches the filter: */534 foreach (const UIShortcutCacheItem &item, m_shortcuts)535 {536 /* If neither description nor sequence matches the filter, skip item: */537 if (!item.description.contains(m_strFilter, Qt::CaseInsensitive) &&538 !item.currentSequence.contains(m_strFilter, Qt::CaseInsensitive))539 continue;540 /* Add that item: */541 m_filteredShortcuts << item;542 }543 }544 545 /* Add items finally if necessary: */546 if (!m_filteredShortcuts.isEmpty())547 {548 beginInsertRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1);549 endInsertRows();550 }551 }552 553 554 25 /** Own QStyledItemDelegate implementation. */ 555 class UIStyledItemDelegate : public QStyledItemDelegate26 class QIStyledItemDelegate : public QStyledItemDelegate 556 27 { 557 28 Q_OBJECT; … … 560 31 561 32 /** Constructor. */ 562 UIStyledItemDelegate(QObject *pParent) : QStyledItemDelegate(pParent) {}33 QIStyledItemDelegate(QObject *pParent) : QStyledItemDelegate(pParent) {} 563 34 564 35 private: … … 567 38 * The @a pParent widget and style @a option are used to control how the editor widget appears. 568 39 * Besides Qt description copy-pasted above we are installing the hook to redirect editor's sigCommitData signal. */ 569 QWidget* createEditor(QWidget *pParent, const QStyleOptionViewItem &option, const QModelIndex &index) const; 40 QWidget* createEditor(QWidget *pParent, const QStyleOptionViewItem &option, const QModelIndex &index) const 41 { 42 /* Call to base-class to get actual editor created: */ 43 QWidget *pEditor = QStyledItemDelegate::createEditor(pParent, option, index); 44 /* All the stuff we actually need from QIStyledItemDelegate is to redirect this one signal: */ 45 connect(pEditor, SIGNAL(sigCommitData(QWidget*)), this, SIGNAL(commitData(QWidget*))); 46 /* Return actual editor: */ 47 return pEditor; 48 } 570 49 }; 571 572 QWidget* UIStyledItemDelegate::createEditor(QWidget *pParent, const QStyleOptionViewItem &option, const QModelIndex &index) const573 {574 /* Call to base-class to get actual editor created: */575 QWidget *pEditor = QStyledItemDelegate::createEditor(pParent, option, index);576 /* All the stuff we actually need from UIStyledItemDelegate is to redirect this one signal: */577 if (qobject_cast<UIHotKeyEditor*>(pEditor) || qobject_cast<UIHostComboEditor*>(pEditor))578 connect(pEditor, SIGNAL(sigCommitData(QWidget*)), this, SIGNAL(commitData(QWidget*)));579 /* Return actual editor: */580 return pEditor;581 }582 583 584 UIHotKeyTable::UIHotKeyTable(QWidget *pParent, UIHotKeyTableModel *pModel, const QString &strObjectName)585 : QTableView(pParent)586 {587 /* Set object name: */588 setObjectName(strObjectName);589 590 /* Connect model: */591 setModel(pModel);592 connect(pModel, SIGNAL(sigShortcutsLoaded()), this, SLOT(sltHandleShortcutsLoaded()));593 594 /* Configure self: */595 setTabKeyNavigation(false);596 setContextMenuPolicy(Qt::CustomContextMenu);597 setSelectionBehavior(QAbstractItemView::SelectRows);598 setSelectionMode(QAbstractItemView::SingleSelection);599 setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked);600 601 /* Configure headers: */602 verticalHeader()->hide();603 verticalHeader()->setDefaultSectionSize((int)(verticalHeader()->minimumSectionSize() * 1.33));604 horizontalHeader()->setStretchLastSection(false);605 horizontalHeader()->setResizeMode(UIHotKeyTableSection_Name, QHeaderView::Interactive);606 horizontalHeader()->setResizeMode(UIHotKeyTableSection_Value, QHeaderView::Stretch);607 608 /* Reinstall delegate: */609 delete itemDelegate();610 UIStyledItemDelegate *pStyledItemDelegate = new UIStyledItemDelegate(this);611 setItemDelegate(pStyledItemDelegate);612 613 /* Create new item editor factory: */614 QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory;615 616 /* Register UIHotKeyEditor as the UIHotKey editor: */617 int iHotKeyTypeId = qRegisterMetaType<UIHotKey>();618 QStandardItemEditorCreator<UIHotKeyEditor> *pHotKeyItemEditorCreator = new QStandardItemEditorCreator<UIHotKeyEditor>();619 pNewItemEditorFactory->registerEditor((QVariant::Type)iHotKeyTypeId, pHotKeyItemEditorCreator);620 621 /* Register UIHostComboEditor as the UIHostComboWrapper: */622 int iHostComboTypeId = qRegisterMetaType<UIHostComboWrapper>();623 QStandardItemEditorCreator<UIHostComboEditor> *pHostComboItemEditorCreator = new QStandardItemEditorCreator<UIHostComboEditor>();624 pNewItemEditorFactory->registerEditor((QVariant::Type)iHostComboTypeId, pHostComboItemEditorCreator);625 626 /* Set configured item editor factory for table delegate: */627 pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory);628 }629 630 void UIHotKeyTable::sltHandleShortcutsLoaded()631 {632 /* Resize columns to feat contents: */633 resizeColumnsToContents();634 635 /* Configure sorting: */636 sortByColumn(UIHotKeyTableSection_Name, Qt::AscendingOrder);637 setSortingEnabled(true);638 }639 640 #include "UIGlobalSettingsInput.moc"641 -
trunk/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsInput.cpp
r53286 r53295 23 23 # include <QHeaderView> 24 24 # include <QAbstractItemDelegate> 25 # include <QStyledItemDelegate>26 25 # include <QItemEditorFactory> 27 26 # include <QTabWidget> … … 29 28 /* GUI includes: */ 30 29 # include "QIWidgetValidator.h" 30 # include "QIStyledItemDelegate.h" 31 31 # include "UIGlobalSettingsInput.h" 32 32 # include "UIShortcutPool.h" … … 552 552 553 553 554 /** Own QStyledItemDelegate implementation. */555 class UIStyledItemDelegate : public QStyledItemDelegate556 {557 Q_OBJECT;558 559 public:560 561 /** Constructor. */562 UIStyledItemDelegate(QObject *pParent) : QStyledItemDelegate(pParent) {}563 564 private:565 566 /** Returns the widget used to edit the item specified by @a index for editing.567 * The @a pParent widget and style @a option are used to control how the editor widget appears.568 * Besides Qt description copy-pasted above we are installing the hook to redirect editor's sigCommitData signal. */569 QWidget* createEditor(QWidget *pParent, const QStyleOptionViewItem &option, const QModelIndex &index) const;570 };571 572 QWidget* UIStyledItemDelegate::createEditor(QWidget *pParent, const QStyleOptionViewItem &option, const QModelIndex &index) const573 {574 /* Call to base-class to get actual editor created: */575 QWidget *pEditor = QStyledItemDelegate::createEditor(pParent, option, index);576 /* All the stuff we actually need from UIStyledItemDelegate is to redirect this one signal: */577 if (qobject_cast<UIHotKeyEditor*>(pEditor) || qobject_cast<UIHostComboEditor*>(pEditor))578 connect(pEditor, SIGNAL(sigCommitData(QWidget*)), this, SIGNAL(commitData(QWidget*)));579 /* Return actual editor: */580 return pEditor;581 }582 583 584 554 UIHotKeyTable::UIHotKeyTable(QWidget *pParent, UIHotKeyTableModel *pModel, const QString &strObjectName) 585 555 : QTableView(pParent) … … 608 578 /* Reinstall delegate: */ 609 579 delete itemDelegate(); 610 UIStyledItemDelegate *pStyledItemDelegate = new UIStyledItemDelegate(this);580 QIStyledItemDelegate *pStyledItemDelegate = new QIStyledItemDelegate(this); 611 581 setItemDelegate(pStyledItemDelegate); 612 582 … … 638 608 } 639 609 640 #include "UIGlobalSettingsInput.moc"641 -
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPortForwardingTable.cpp
r53291 r53295 38 38 # include "UIToolBar.h" 39 39 # include "QITableView.h" 40 # include "QIStyledItemDelegate.h" 40 41 41 42 /* Other VBox includes: */ … … 108 109 Q_PROPERTY(NameData name READ name WRITE setName USER true); 109 110 111 signals: 112 113 /** Notifies listener about data should be committed. */ 114 void sigCommitData(QWidget *pThis); 115 110 116 public: 111 117 … … 116 122 setAlignment(Qt::AlignLeft | Qt::AlignVCenter); 117 123 setValidator(new QRegExpValidator(QRegExp("[^,:]*"), this)); 124 connect(this, SIGNAL(textEdited(const QString&)), this, SLOT(sltTextEdited(const QString&))); 125 } 126 127 private slots: 128 129 /** Drops the changed data to listener. */ 130 void sltTextEdited(const QString&) 131 { 132 emit sigCommitData(this); 118 133 } 119 134 … … 139 154 Q_PROPERTY(KNATProtocol protocol READ protocol WRITE setProtocol USER true); 140 155 156 signals: 157 158 /** Notifies listener about data should be committed. */ 159 void sigCommitData(QWidget *pThis); 160 141 161 public: 142 162 … … 146 166 addItem(gpConverter->toString(KNATProtocol_UDP), QVariant::fromValue(KNATProtocol_UDP)); 147 167 addItem(gpConverter->toString(KNATProtocol_TCP), QVariant::fromValue(KNATProtocol_TCP)); 168 connect(this, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(sltTextEdited(const QString&))); 169 } 170 171 private slots: 172 173 /** Drops the changed data to listener. */ 174 void sltTextEdited(const QString&) 175 { 176 emit sigCommitData(this); 148 177 } 149 178 … … 175 204 Q_OBJECT; 176 205 Q_PROPERTY(IpData ip READ ip WRITE setIp USER true); 206 207 signals: 208 209 /** Notifies listener about data should be committed. */ 210 void sigCommitData(QWidget *pThis); 177 211 178 212 public: … … 208 242 Q_PROPERTY(IpData ip READ ip WRITE setIp USER true); 209 243 244 signals: 245 246 /** Notifies listener about data should be committed. */ 247 void sigCommitData(QWidget *pThis); 248 210 249 public: 211 250 … … 240 279 Q_PROPERTY(PortData port READ port WRITE setPort USER true); 241 280 281 signals: 282 283 /** Notifies listener about data should be committed. */ 284 void sigCommitData(QWidget *pThis); 285 242 286 public: 243 287 … … 247 291 setFrame(false); 248 292 setRange(0, (1 << (8 * sizeof(ushort))) - 1); 293 connect(this, SIGNAL(valueChanged(const QString&)), this, SLOT(sltTextEdited(const QString&))); 294 } 295 296 private slots: 297 298 /** Drops the changed data to listener. */ 299 void sltTextEdited(const QString&) 300 { 301 emit sigCommitData(this); 249 302 } 250 303 … … 575 628 } 576 629 577 /* Register delegates editors: */ 578 if (QAbstractItemDelegate *pAbstractItemDelegate = m_pTableView->itemDelegate()) 579 { 580 if (QStyledItemDelegate *pStyledItemDelegate = qobject_cast<QStyledItemDelegate*>(pAbstractItemDelegate)) 581 { 582 /* Create new item editor factory: */ 583 QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory; 584 585 /* Register name type: */ 586 int iNameId = qRegisterMetaType<NameData>(); 587 /* Register name editor: */ 588 QStandardItemEditorCreator<NameEditor> *pNameEditorItemCreator = new QStandardItemEditorCreator<NameEditor>(); 589 /* Link name type & editor: */ 590 pNewItemEditorFactory->registerEditor((QVariant::Type)iNameId, pNameEditorItemCreator); 591 592 /* Register protocol type: */ 593 int iProtocolId = qRegisterMetaType<KNATProtocol>(); 594 /* Register protocol editor: */ 595 QStandardItemEditorCreator<ProtocolEditor> *pProtocolEditorItemCreator = new QStandardItemEditorCreator<ProtocolEditor>(); 596 /* Link protocol type & editor: */ 597 pNewItemEditorFactory->registerEditor((QVariant::Type)iProtocolId, pProtocolEditorItemCreator); 598 599 /* Register ip type: */ 600 int iIpId = qRegisterMetaType<IpData>(); 601 /* Register ip editor: */ 602 if (!fIPv6) 603 { 604 QStandardItemEditorCreator<IPv4Editor> *pIPv4EditorItemCreator = new QStandardItemEditorCreator<IPv4Editor>(); 605 /* Link ip type & editor: */ 606 pNewItemEditorFactory->registerEditor((QVariant::Type)iIpId, pIPv4EditorItemCreator); 607 } 608 else 609 { 610 QStandardItemEditorCreator<IPv6Editor> *pIPv6EditorItemCreator = new QStandardItemEditorCreator<IPv6Editor>(); 611 /* Link ip type & editor: */ 612 pNewItemEditorFactory->registerEditor((QVariant::Type)iIpId, pIPv6EditorItemCreator); 613 } 614 615 /* Register port type: */ 616 int iPortId = qRegisterMetaType<PortData>(); 617 /* Register port editor: */ 618 QStandardItemEditorCreator<PortEditor> *pPortEditorItemCreator = new QStandardItemEditorCreator<PortEditor>(); 619 /* Link port type & editor: */ 620 pNewItemEditorFactory->registerEditor((QVariant::Type)iPortId, pPortEditorItemCreator); 621 622 /* Set newly created item editor factory for table delegate: */ 623 pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory); 624 } 625 } 630 /* Reinstall delegate: */ 631 delete m_pTableView->itemDelegate(); 632 QIStyledItemDelegate *pStyledItemDelegate = new QIStyledItemDelegate(this); 633 m_pTableView->setItemDelegate(pStyledItemDelegate); 634 635 /* Create new item editor factory: */ 636 QItemEditorFactory *pNewItemEditorFactory = new QItemEditorFactory; 637 638 /* Register name type: */ 639 int iNameId = qRegisterMetaType<NameData>(); 640 /* Register name editor: */ 641 QStandardItemEditorCreator<NameEditor> *pNameEditorItemCreator = new QStandardItemEditorCreator<NameEditor>(); 642 /* Link name type & editor: */ 643 pNewItemEditorFactory->registerEditor((QVariant::Type)iNameId, pNameEditorItemCreator); 644 645 /* Register protocol type: */ 646 int iProtocolId = qRegisterMetaType<KNATProtocol>(); 647 /* Register protocol editor: */ 648 QStandardItemEditorCreator<ProtocolEditor> *pProtocolEditorItemCreator = new QStandardItemEditorCreator<ProtocolEditor>(); 649 /* Link protocol type & editor: */ 650 pNewItemEditorFactory->registerEditor((QVariant::Type)iProtocolId, pProtocolEditorItemCreator); 651 652 /* Register ip type: */ 653 int iIpId = qRegisterMetaType<IpData>(); 654 /* Register ip editor: */ 655 if (!fIPv6) 656 { 657 QStandardItemEditorCreator<IPv4Editor> *pIPv4EditorItemCreator = new QStandardItemEditorCreator<IPv4Editor>(); 658 /* Link ip type & editor: */ 659 pNewItemEditorFactory->registerEditor((QVariant::Type)iIpId, pIPv4EditorItemCreator); 660 } 661 else 662 { 663 QStandardItemEditorCreator<IPv6Editor> *pIPv6EditorItemCreator = new QStandardItemEditorCreator<IPv6Editor>(); 664 /* Link ip type & editor: */ 665 pNewItemEditorFactory->registerEditor((QVariant::Type)iIpId, pIPv6EditorItemCreator); 666 } 667 668 /* Register port type: */ 669 int iPortId = qRegisterMetaType<PortData>(); 670 /* Register port editor: */ 671 QStandardItemEditorCreator<PortEditor> *pPortEditorItemCreator = new QStandardItemEditorCreator<PortEditor>(); 672 /* Link port type & editor: */ 673 pNewItemEditorFactory->registerEditor((QVariant::Type)iPortId, pPortEditorItemCreator); 674 675 /* Set newly created item editor factory for table delegate: */ 676 pStyledItemDelegate->setItemEditorFactory(pNewItemEditorFactory); 626 677 627 678 /* Retranslate dialog: */
Note:
See TracChangeset
for help on using the changeset viewer.