Changeset 105059 in vbox
- Timestamp:
- Jun 27, 2024 12:50:28 PM (5 months ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/settings/editors
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UIShortcutConfigurationEditor.cpp
r105058 r105059 30 30 #include <QHeaderView> 31 31 #include <QItemEditorFactory> 32 #include <QSortFilterProxyModel> 32 33 #include <QTabWidget> 33 34 #include <QVBoxLayout> … … 184 185 185 186 186 /** Shortcut item sorting functor. */187 class UIShortcutItemSortingFunctor188 {189 public:190 191 /** Constructs shortcut item sorting functor.192 * @param iColumn Brings the column sorting should be done according to.193 * @param m_enmOrder Brings the sorting order to be applied. */194 UIShortcutItemSortingFunctor(int iColumn, Qt::SortOrder enmOrder)195 : m_iColumn(iColumn)196 , m_enmOrder(enmOrder)197 {}198 199 /** Returns whether the @a pItem1 is more/less than the @a pItem2.200 * @note Order depends on the one set through constructor, stored in m_enmOrder. */201 bool operator()(UIShortcutTableViewRow *pItem1, UIShortcutTableViewRow *pItem2)202 {203 switch (m_iColumn)204 {205 case TableColumnIndex_Description:206 return m_enmOrder == Qt::AscendingOrder207 ? pItem1->description() < pItem2->description()208 : pItem1->description() > pItem2->description();209 case TableColumnIndex_Sequence:210 return m_enmOrder == Qt::AscendingOrder211 ? pItem1->currentSequence() < pItem2->currentSequence()212 : pItem1->currentSequence() > pItem2->currentSequence();213 default:214 break;215 }216 return m_enmOrder == Qt::AscendingOrder217 ? pItem1->key() < pItem2->key()218 : pItem1->key() > pItem2->key();219 }220 221 private:222 223 /** Holds the column sorting should be done according to. */224 int m_iColumn;225 /** Holds the sorting order to be applied. */226 Qt::SortOrder m_enmOrder;227 };228 229 230 187 /** QAbstractTableModel subclass representing shortcut configuration model. */ 231 188 class UIShortcutConfigurationModel : public QAbstractTableModel … … 239 196 240 197 public: 198 199 /** Holds the data roles. */ 200 enum DataRoles 201 { 202 IsHostCombo = Qt::UserRole + 1, 203 }; 241 204 242 205 /** Constructs model passing @a pParent to the base-class. … … 253 216 /** Returns whether all shortcuts unique. */ 254 217 bool isAllShortcutsUnique(); 255 256 public slots:257 258 /** Handle filtering @a strText change. */259 void sltHandleFilterTextChange(const QString &strText);260 218 261 219 protected: … … 275 233 virtual bool setData(const QModelIndex &index, const QVariant &value, int iRole = Qt::EditRole) RT_OVERRIDE; 276 234 277 /** Sorts the model by @a iColumn in the given @a enmOrder. */278 virtual void sort(int iColumn, Qt::SortOrder enmOrder = Qt::AscendingOrder) RT_OVERRIDE;279 280 235 private: 281 236 … … 283 238 QITableView *view() const; 284 239 285 /** Applies filter. */286 void applyFilter();287 288 240 /** Holds the parent shortcut-configuration editor instance. */ 289 241 UIShortcutConfigurationEditor *m_pShortcutConfigurationEditor; … … 292 244 UIType m_enmType; 293 245 294 /** Holds current filter. */295 QString m_strFilter;296 297 246 /** Holds current shortcut list. */ 298 247 UIShortcutTableViewContent m_shortcuts; 299 /** Holds current filtered shortcut list. */300 UIShortcutTableViewContent m_filteredShortcuts;301 248 302 249 /** Holds a set of currently duplicated sequences. */ 303 250 QSet<QString> m_duplicatedSequences; 251 }; 252 253 254 /** QSortFilterProxyModel subclass representing shortcut configuration proxy-model. */ 255 class UIShortcutConfigurationProxyModel : public QSortFilterProxyModel 256 { 257 Q_OBJECT; 258 259 public: 260 261 /** Constructs the shortcut configuration proxy-model passing @a pParent to the base-class. */ 262 UIShortcutConfigurationProxyModel(QObject *pParent = 0); 263 264 public slots: 265 266 /** Defines model @a strFilter. */ 267 void setFilter(const QString &strFilter); 268 269 protected: 270 271 /** Returns whether item in the row indicated by the given @a iSourceRow and @a srcParentIdx should be included in the model. */ 272 virtual bool filterAcceptsRow(int iSourceRow, const QModelIndex &srcParentIdx) const RT_OVERRIDE; 273 274 /** Returns whether value of the item @a srcIdxLeft is less than the value of the item @a srcIdxRight. */ 275 virtual bool lessThan(const QModelIndex &srcIdxLeft, const QModelIndex &srcIdxRight) const RT_OVERRIDE; 276 277 private: 278 279 /** Holds the model filter. */ 280 QString m_strFilter; 304 281 }; 305 282 … … 360 337 qDeleteAll(m_shortcuts); 361 338 m_shortcuts.clear(); 362 m_filteredShortcuts.clear();363 339 } 364 340 365 341 void UIShortcutConfigurationModel::load(const UIShortcutConfigurationList &list) 366 342 { 343 /* Erase rows first if necessary: */ 344 if (!m_shortcuts.isEmpty()) 345 { 346 beginRemoveRows(QModelIndex(), 0, m_shortcuts.size() - 1); 347 m_shortcuts.clear(); 348 endRemoveRows(); 349 } 350 367 351 /* Load a list of passed shortcuts: */ 368 352 foreach (const UIShortcutConfigurationItem &item, list) … … 376 360 } 377 361 378 /* Apply filter: */ 379 applyFilter(); 362 /* Add rows finally if necessary: */ 363 if (!m_shortcuts.isEmpty()) 364 { 365 beginInsertRows(QModelIndex(), 0, m_shortcuts.size() - 1); 366 endInsertRows(); 367 } 380 368 } 381 369 … … 430 418 } 431 419 432 void UIShortcutConfigurationModel::sltHandleFilterTextChange(const QString &strText)433 {434 m_strFilter = strText;435 applyFilter();436 }437 438 420 int UIShortcutConfigurationModel::rowCount(const QModelIndex& /* parent = QModelIndex() */) const 439 421 { 440 return m_ filteredShortcuts.size();422 return m_shortcuts.size(); 441 423 } 442 424 … … 508 490 { 509 491 /* Return shortcut scope and description: */ 510 const QString strScope = m_ filteredShortcuts.at(iIndex)->scope();511 const QString strDescription = m_ filteredShortcuts.at(iIndex)->description();492 const QString strScope = m_shortcuts.at(iIndex)->scope(); 493 const QString strDescription = m_shortcuts.at(iIndex)->description(); 512 494 return strScope.isNull() ? strDescription : QString("%1: %2").arg(strScope, strDescription); 513 495 } … … 515 497 { 516 498 /* If that is host-combo cell: */ 517 if (m_ filteredShortcuts.at(iIndex)->key() == UIHostCombo::hostComboCacheKey())499 if (m_shortcuts.at(iIndex)->key() == UIHostCombo::hostComboCacheKey()) 518 500 /* We should return host-combo: */ 519 return UIHostCombo::toReadableString(m_ filteredShortcuts.at(iIndex)->currentSequence());501 return UIHostCombo::toReadableString(m_shortcuts.at(iIndex)->currentSequence()); 520 502 /* In other cases we should return hot-combo: */ 521 QString strHotCombo = m_ filteredShortcuts.at(iIndex)->currentSequence();503 QString strHotCombo = m_shortcuts.at(iIndex)->currentSequence(); 522 504 /* But if that is machine table and hot-combo is not empty: */ 523 505 if (m_enmType == UIType_RuntimeUI && !strHotCombo.isEmpty()) … … 538 520 { 539 521 case TableColumnIndex_Sequence: 540 return m_ filteredShortcuts.at(iIndex)->key() == UIHostCombo::hostComboCacheKey()541 ? QVariant::fromValue(UIHostComboWrapper(m_ filteredShortcuts.at(iIndex)->currentSequence()))522 return m_shortcuts.at(iIndex)->key() == UIHostCombo::hostComboCacheKey() 523 ? QVariant::fromValue(UIHostComboWrapper(m_shortcuts.at(iIndex)->currentSequence())) 542 524 : QVariant::fromValue(UIHotKey( m_enmType == UIType_RuntimeUI 543 525 ? UIHotKeyType_Simple 544 526 : UIHotKeyType_WithModifiers, 545 m_ filteredShortcuts.at(iIndex)->currentSequence(),546 m_ filteredShortcuts.at(iIndex)->defaultSequence()));527 m_shortcuts.at(iIndex)->currentSequence(), 528 m_shortcuts.at(iIndex)->defaultSequence())); 547 529 default: 548 530 break; … … 560 542 case TableColumnIndex_Sequence: 561 543 { 562 if ( m_ filteredShortcuts.at(iIndex)->key() != UIHostCombo::hostComboCacheKey()563 && m_ filteredShortcuts.at(iIndex)->currentSequence() != m_filteredShortcuts.at(iIndex)->defaultSequence())544 if ( m_shortcuts.at(iIndex)->key() != UIHostCombo::hostComboCacheKey() 545 && m_shortcuts.at(iIndex)->currentSequence() != m_shortcuts.at(iIndex)->defaultSequence()) 564 546 font.setBold(true); 565 547 break; … … 577 559 case TableColumnIndex_Sequence: 578 560 { 579 if (m_duplicatedSequences.contains(m_ filteredShortcuts.at(iIndex)->key()))561 if (m_duplicatedSequences.contains(m_shortcuts.at(iIndex)->key())) 580 562 return QBrush(Qt::red); 581 563 break; … … 585 567 /* Default for other cases: */ 586 568 return QString(); 569 } 570 case IsHostCombo: 571 { 572 return m_shortcuts.at(iIndex)->key() == UIHostCombo::hostComboCacheKey(); 587 573 } 588 574 default: break; … … 610 596 const int iIndex = index.row(); 611 597 /* Set sequence to shortcut: */ 612 UIShortcutTableViewRow *pFilteredShortcut = m_ filteredShortcuts.at(iIndex);598 UIShortcutTableViewRow *pFilteredShortcut = m_shortcuts.at(iIndex); 613 599 const int iShortcutIndex = UIShortcutSearchFunctor<UIShortcutTableViewRow>()(m_shortcuts, pFilteredShortcut); 614 600 if (iShortcutIndex != -1) … … 634 620 } 635 621 636 void UIShortcutConfigurationModel::sort(int iColumn, Qt::SortOrder order /* = Qt::AscendingOrder */)637 {638 /* Sort whole the list: */639 std::stable_sort(m_filteredShortcuts.begin(), m_filteredShortcuts.end(), UIShortcutItemSortingFunctor(iColumn, order));640 /* Make sure host-combo item is always the first one: */641 UIShortcutConfigurationItem fakeHostComboItem(UIHostCombo::hostComboCacheKey(), QString(), QString(), QString(), QString());642 UIShortcutTableViewRow fakeHostComboTableViewRow(0, fakeHostComboItem);643 const int iIndexOfHostComboItem = UIShortcutSearchFunctor<UIShortcutTableViewRow>()(m_filteredShortcuts, fakeHostComboTableViewRow);644 if (iIndexOfHostComboItem != -1)645 {646 UIShortcutTableViewRow *pHostComboItem = m_filteredShortcuts.takeAt(iIndexOfHostComboItem);647 m_filteredShortcuts.prepend(pHostComboItem);648 }649 /* Notify the model: */650 emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));651 }652 653 622 QITableView *UIShortcutConfigurationModel::view() const 654 623 { … … 661 630 } 662 631 663 void UIShortcutConfigurationModel::applyFilter() 664 { 665 /* Erase rows first if necessary: */ 666 if (!m_filteredShortcuts.isEmpty()) 667 { 668 beginRemoveRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1); 669 m_filteredShortcuts.clear(); 670 endRemoveRows(); 671 } 672 673 /* If filter is empty: */ 674 if (m_strFilter.isEmpty()) 675 { 676 /* Just add all the rows: */ 677 m_filteredShortcuts = m_shortcuts; 678 } 679 else 680 { 681 /* Check if the description matches the filter: */ 682 foreach (UIShortcutTableViewRow *pRow, m_shortcuts) 683 { 684 /* If neither scope nor description or sequence matches the filter, skip the pRow: */ 685 if ( !pRow->scope().contains(m_strFilter, Qt::CaseInsensitive) 686 && !pRow->description().contains(m_strFilter, Qt::CaseInsensitive) 687 && !pRow->currentSequence().contains(m_strFilter, Qt::CaseInsensitive)) 688 continue; 689 /* Add that pRow: */ 690 m_filteredShortcuts << pRow; 691 } 692 } 693 694 /* Add rows finally if necessary: */ 695 if (!m_filteredShortcuts.isEmpty()) 696 { 697 beginInsertRows(QModelIndex(), 0, m_filteredShortcuts.size() - 1); 698 endInsertRows(); 699 } 632 633 /********************************************************************************************************************************* 634 * Class UIShortcutConfigurationProxyModel implementation. * 635 *********************************************************************************************************************************/ 636 637 UIShortcutConfigurationProxyModel::UIShortcutConfigurationProxyModel(QObject *pParent /* = 0 */) 638 : QSortFilterProxyModel(pParent) 639 { 640 } 641 642 void UIShortcutConfigurationProxyModel::setFilter(const QString &strFilter) 643 { 644 m_strFilter = strFilter; 645 invalidate(); 646 } 647 648 bool UIShortcutConfigurationProxyModel::filterAcceptsRow(int iSourceRow, const QModelIndex &srcIdxParent) const 649 { 650 /* Acquire child index of source model: */ 651 QModelIndex srcIdxChild = sourceModel()->index(iSourceRow, 0, srcIdxParent); 652 if (srcIdxChild.isValid()) 653 { 654 /* Perform QString case-insensitive filtering, default Qt::DisplayRole is Ok: */ 655 if (!sourceModel()->data(srcIdxChild).toString().contains(m_strFilter, Qt::CaseInsensitive)) 656 return false; 657 } 658 /* Everything else is allowed: */ 659 return true; 660 } 661 662 bool UIShortcutConfigurationProxyModel::lessThan(const QModelIndex &srcIdxLeft, const QModelIndex &srcIdxRight) const 663 { 664 /* Check if left or right index contains the Host-combo shortcut: */ 665 if (sourceModel()->data(srcIdxLeft, UIShortcutConfigurationModel::IsHostCombo).toBool()) 666 return true; 667 else if (sourceModel()->data(srcIdxRight, UIShortcutConfigurationModel::IsHostCombo).toBool()) 668 return false; 669 670 /* Perform QString case-insensitive comparition otherwise: */ 671 return QString::compare(sourceModel()->data(srcIdxLeft).toString(), 672 sourceModel()->data(srcIdxRight).toString(), 673 Qt::CaseInsensitive) < 0; 700 674 } 701 675 … … 814 788 , m_pModelManager(0) 815 789 , m_pModelRuntime(0) 790 , m_pProxyModelManager(0) 791 , m_pProxyModelRuntime(0) 816 792 , m_pTabWidget(0) 817 793 , m_pEditorFilterManager(0), m_pTableManager(0) … … 930 906 m_pModelManager = new UIShortcutConfigurationModel(this, UIType_ManagerUI); 931 907 908 /* Prepare Manager UI proxy-model: */ 909 m_pProxyModelManager = new UIShortcutConfigurationProxyModel(this); 910 if (m_pProxyModelManager) 911 m_pProxyModelManager->setSourceModel(m_pModelManager); 912 932 913 /* Prepare Manager UI table: */ 933 914 m_pTableManager = new UIShortcutConfigurationView(pTabManager, "m_pTableManager"); 934 915 if (m_pTableManager) 935 916 { 936 m_pTableManager->setModel(m_p ModelManager);917 m_pTableManager->setModel(m_pProxyModelManager); 937 918 pLayoutManager->addWidget(m_pTableManager); 938 919 } … … 967 948 m_pModelRuntime = new UIShortcutConfigurationModel(this, UIType_RuntimeUI); 968 949 950 /* Prepare Runtime UI proxy-model: */ 951 m_pProxyModelRuntime = new UIShortcutConfigurationProxyModel(this); 952 if (m_pProxyModelRuntime) 953 m_pProxyModelRuntime->setSourceModel(m_pModelRuntime); 954 969 955 /* Create Runtime UI table: */ 970 956 m_pTableRuntime = new UIShortcutConfigurationView(pTabMachine, "m_pTableRuntime"); 971 957 if (m_pTableRuntime) 972 958 { 973 m_pTableRuntime->setModel(m_p ModelRuntime);959 m_pTableRuntime->setModel(m_pProxyModelRuntime); 974 960 pLayoutMachine->addWidget(m_pTableRuntime); 975 961 } … … 988 974 /* Configure 'Manager UI' connections: */ 989 975 connect(m_pEditorFilterManager, &QLineEdit::textChanged, 990 m_p ModelManager, &UIShortcutConfigurationModel::sltHandleFilterTextChange);976 m_pProxyModelManager, &UIShortcutConfigurationProxyModel::setFilter); 991 977 connect(m_pModelManager, &UIShortcutConfigurationModel::sigDataChanged, 992 978 this, &UIShortcutConfigurationEditor::sigValueChanged); … … 994 980 /* Configure 'Runtime UI' connections: */ 995 981 connect(m_pEditorFilterRuntime, &QLineEdit::textChanged, 996 m_p ModelRuntime, &UIShortcutConfigurationModel::sltHandleFilterTextChange);982 m_pProxyModelRuntime, &UIShortcutConfigurationProxyModel::setFilter); 997 983 connect(m_pModelRuntime, &UIShortcutConfigurationModel::sigDataChanged, 998 984 this, &UIShortcutConfigurationEditor::sigValueChanged); -
trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UIShortcutConfigurationEditor.h
r105056 r105059 40 40 class QITableView; 41 41 class UIShortcutConfigurationModel; 42 class UIShortcutConfigurationProxyModel; 42 43 43 44 /** Shortcut search functor template. */ … … 252 253 UIShortcutConfigurationModel *m_pModelRuntime; 253 254 255 /** Holds the proxy Manager UI shortcut configuration model instance. */ 256 UIShortcutConfigurationProxyModel *m_pProxyModelManager; 257 /** Holds the proxy Runtime UI shortcut configuration model instance. */ 258 UIShortcutConfigurationProxyModel *m_pProxyModelRuntime; 259 254 260 /** Holds the tab-widget instance. */ 255 261 QTabWidget *m_pTabWidget;
Note:
See TracChangeset
for help on using the changeset viewer.