diff options
Diffstat (limited to 'examples/widgets/widgets/shortcuteditor')
14 files changed, 769 insertions, 0 deletions
diff --git a/examples/widgets/widgets/shortcuteditor/CMakeLists.txt b/examples/widgets/widgets/shortcuteditor/CMakeLists.txt new file mode 100644 index 0000000000..d10248fbd7 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +cmake_minimum_required(VERSION 3.16) +project(shortcuteditor LANGUAGES CXX) + +find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets) + +qt_standard_project_setup() + +qt_add_executable(shortcuteditor + actionmanager.cpp actionmanager.h + application.cpp application.h + main.cpp + mainwindow.cpp mainwindow.h + shortcuteditordelegate.cpp shortcuteditordelegate.h + shortcuteditormodel.cpp shortcuteditormodel.h + shortcuteditorwidget.cpp shortcuteditorwidget.h +) + +set_target_properties(shortcuteditor PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(shortcuteditor PRIVATE + Qt6::Core + Qt6::Gui + Qt6::Widgets +) + +install(TARGETS shortcuteditor + BUNDLE DESTINATION . + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + +qt_generate_deploy_app_script( + TARGET shortcuteditor + OUTPUT_SCRIPT deploy_script + NO_UNSUPPORTED_PLATFORM_ERROR +) +install(SCRIPT ${deploy_script}) diff --git a/examples/widgets/widgets/shortcuteditor/actionmanager.cpp b/examples/widgets/widgets/shortcuteditor/actionmanager.cpp new file mode 100644 index 0000000000..cfe5f42674 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/actionmanager.cpp @@ -0,0 +1,57 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "actionmanager.h" + +#include <QAction> +#include <QApplication> +#include <QString> +#include <QVariant> + +static const char *kDefaultShortcutPropertyName = "defaultShortcuts"; +static const char *kIdPropertyName = "id"; +static const char *kAuthorName = "qt"; + +struct ActionIdentifier { + QString author; + QString context; + QString category; + QString name; +}; + +QList<QAction *> ActionManager::registeredActions() const +{ + return m_actions; +} + +void ActionManager::registerAction(QAction *action) +{ + action->setProperty(kDefaultShortcutPropertyName, QVariant::fromValue(action->shortcut())); + m_actions.append(action); +} + +void ActionManager::registerAction(QAction *action, const QString &context, const QString &category) +{ + action->setProperty(kIdPropertyName, QVariant::fromValue(ActionIdentifier{ + kAuthorName, context, category, action->text() + })); + registerAction(action); +} + +QAction *ActionManager::registerAction(const QString &name, const QString &shortcut, const QString &context, const QString &category) +{ + QAction *action = new QAction(name, qApp); + action->setShortcut(QKeySequence(shortcut)); + registerAction(action, context, category); + return action; +} + +QString ActionManager::contextForAction(QAction *action) +{ + return action->property(kIdPropertyName).value<ActionIdentifier>().context; +} + +QString ActionManager::categoryForAction(QAction *action) +{ + return action->property(kIdPropertyName).value<ActionIdentifier>().category; +} diff --git a/examples/widgets/widgets/shortcuteditor/actionmanager.h b/examples/widgets/widgets/shortcuteditor/actionmanager.h new file mode 100644 index 0000000000..da20cd8840 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/actionmanager.h @@ -0,0 +1,33 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef ACTIONMANAGER_H +#define ACTIONMANAGER_H + +#include <QList> +#include <QString> + +QT_BEGIN_NAMESPACE +class QAction; +QT_END_NAMESPACE + +class ActionManager +{ +public: + ActionManager() = default; + ~ActionManager() = default; + + QList<QAction*> registeredActions() const; + + void registerAction(QAction *action); + void registerAction(QAction *action, const QString &context, const QString &category); + QAction *registerAction(const QString &name, const QString &shortcut, const QString &context, const QString &category); + + QString contextForAction(QAction *action); + QString categoryForAction(QAction *action); + +private: + QList<QAction *> m_actions; +}; + +#endif diff --git a/examples/widgets/widgets/shortcuteditor/application.cpp b/examples/widgets/widgets/shortcuteditor/application.cpp new file mode 100644 index 0000000000..4ac76682d0 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/application.cpp @@ -0,0 +1,15 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "application.h" + +Application::Application(int &argc, char **argv) + : QApplication(argc, argv) +{ + m_actionManager = std::make_unique<ActionManager>(); +} + +ActionManager *Application::actionManager() const +{ + return m_actionManager.get(); +} diff --git a/examples/widgets/widgets/shortcuteditor/application.h b/examples/widgets/widgets/shortcuteditor/application.h new file mode 100644 index 0000000000..38808c3ad2 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/application.h @@ -0,0 +1,27 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef APPLICATION_H +#define APPLICATION_H + +#include "actionmanager.h" + +#include <QApplication> + +#include <memory> + +class Application : public QApplication +{ + Q_OBJECT + +public: + Application(int &argc, char **argv); + ~Application() override = default; + + ActionManager *actionManager() const; + +private: + std::unique_ptr<ActionManager> m_actionManager; +}; + +#endif diff --git a/examples/widgets/widgets/shortcuteditor/main.cpp b/examples/widgets/widgets/shortcuteditor/main.cpp new file mode 100644 index 0000000000..029f7a351a --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/main.cpp @@ -0,0 +1,13 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "application.h" +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + Application app(argc, argv); + MainWindow window; + window.show(); + return app.exec(); +} diff --git a/examples/widgets/widgets/shortcuteditor/mainwindow.cpp b/examples/widgets/widgets/shortcuteditor/mainwindow.cpp new file mode 100644 index 0000000000..587dbbc5b5 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/mainwindow.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "mainwindow.h" + +#include "actionmanager.h" +#include "application.h" +#include "shortcuteditorwidget.h" + +#include <QAction> +#include <QHBoxLayout> +#include <QPushButton> +#include <QVBoxLayout> + +MainWindow::MainWindow() +{ + QPushButton *topPushButton = new QPushButton("Left"); + QPushButton *bottomPushButton = new QPushButton("Right"); + for (auto nameShortcut : std::vector<std::vector<const char *>>{{"red", "r", "shift+r"}, {"green", "g", "shift+g"}, {"blue", "b", "shift+b"}}) { + Application *application = static_cast<Application *>(QCoreApplication::instance()); + ActionManager *actionManager = application->actionManager(); + QAction *action = actionManager->registerAction(nameShortcut[0], nameShortcut[1], "top", "color"); + topPushButton->addAction(action); + connect(action, &QAction::triggered, this, [topPushButton, nameShortcut]() { + topPushButton->setText(nameShortcut[0]); + }); + + action = actionManager->registerAction(nameShortcut[0], nameShortcut[2], "bottom", "color"); + bottomPushButton->addAction(action); + connect(action, &QAction::triggered, this, [bottomPushButton, nameShortcut]() { + bottomPushButton->setText(nameShortcut[0]); + }); + } + + QVBoxLayout *vBoxLayout = new QVBoxLayout; + vBoxLayout->addWidget(topPushButton); + vBoxLayout->addWidget(bottomPushButton); + + QHBoxLayout *hBoxLayout = new QHBoxLayout; + hBoxLayout->addWidget(new ShortcutEditorWidget); + hBoxLayout->addLayout(vBoxLayout); + + QWidget *centralWidget = new QWidget; + centralWidget->setLayout(hBoxLayout); + setCentralWidget(centralWidget); +} diff --git a/examples/widgets/widgets/shortcuteditor/mainwindow.h b/examples/widgets/widgets/shortcuteditor/mainwindow.h new file mode 100644 index 0000000000..702b3f2d87 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/mainwindow.h @@ -0,0 +1,22 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> + +QT_BEGIN_NAMESPACE +class QPushButton; +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + ~MainWindow() override = default; +}; + +#endif diff --git a/examples/widgets/widgets/shortcuteditor/shortcuteditordelegate.cpp b/examples/widgets/widgets/shortcuteditor/shortcuteditordelegate.cpp new file mode 100644 index 0000000000..a8b32bc06a --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/shortcuteditordelegate.cpp @@ -0,0 +1,71 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "shortcuteditordelegate.h" + +#include <QAbstractItemModel> +#include <QKeySequenceEdit> + +//! [0] +ShortcutEditorDelegate::ShortcutEditorDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ +} +//! [0] + +//! [1] +QWidget *ShortcutEditorDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &/*option*/, + const QModelIndex &/*index*/) const +{ + QKeySequenceEdit *editor = new QKeySequenceEdit(parent); + connect(editor, &QKeySequenceEdit::editingFinished, this, &ShortcutEditorDelegate::commitAndCloseEditor); + return editor; +} +//! [1] + +//! [2] +void ShortcutEditorDelegate::commitAndCloseEditor() +{ + QKeySequenceEdit *editor = static_cast<QKeySequenceEdit *>(sender()); + Q_EMIT commitData(editor); + Q_EMIT closeEditor(editor); +} +//! [2] + +//! [3] +void ShortcutEditorDelegate::setEditorData(QWidget *editor, + const QModelIndex &index) const +{ + if (!editor || !index.isValid()) + return; + + QString value = index.model()->data(index, Qt::EditRole).toString(); + + QKeySequenceEdit *keySequenceEdit = static_cast<QKeySequenceEdit *>(editor); + keySequenceEdit->setKeySequence(value); +} +//! [3] + +//! [4] +void ShortcutEditorDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ + if (!editor || !model || !index.isValid()) + return; + + const QKeySequenceEdit *keySequenceEdit = static_cast<QKeySequenceEdit *>(editor); + const QKeySequence keySequence = keySequenceEdit->keySequence(); + QString keySequenceString = keySequence.toString(QKeySequence::NativeText); + model->setData(index, keySequenceString); +} +//! [4] + +//! [5] +void ShortcutEditorDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &/*index*/) const +{ + editor->setGeometry(option.rect); +} +//! [5] diff --git a/examples/widgets/widgets/shortcuteditor/shortcuteditordelegate.h b/examples/widgets/widgets/shortcuteditor/shortcuteditordelegate.h new file mode 100644 index 0000000000..2818438db3 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/shortcuteditordelegate.h @@ -0,0 +1,34 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef SHORTCUTEDITORDELEGATE_H +#define SHORTCUTEDITORDELEGATE_H + +#include <QStyledItemDelegate> + +//! [0] +class ShortcutEditorDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + explicit ShortcutEditorDelegate(QObject *parent = nullptr); + ~ShortcutEditorDelegate() override = default; + +protected: + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + void setEditorData(QWidget *editor, const QModelIndex &index) const override; + void setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const override; + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + +private: + void commitAndCloseEditor(); +}; +//! [0] + +#endif diff --git a/examples/widgets/widgets/shortcuteditor/shortcuteditormodel.cpp b/examples/widgets/widgets/shortcuteditor/shortcuteditormodel.cpp new file mode 100644 index 0000000000..612f1fb726 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/shortcuteditormodel.cpp @@ -0,0 +1,273 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "shortcuteditormodel.h" + +#include "actionmanager.h" +#include "application.h" + +#include <QAction> +#include <QModelIndex> + +// List of actions for all categories +using CategoryActionsMap = QMap<QString, QList<QAction *>>; + +// List of categories for all contexts +using ActionsMap = QMap<QString, CategoryActionsMap>; + + +ShortcutEditorModel::ShortcutEditorModelItem::ShortcutEditorModelItem(const QList<QVariant> &data, ShortcutEditorModelItem *parent) + : m_itemData(data) + , m_parentItem(parent) +{ +} + +ShortcutEditorModel::ShortcutEditorModelItem::~ShortcutEditorModelItem() +{ + qDeleteAll(m_childItems); +} + +void ShortcutEditorModel::ShortcutEditorModelItem::appendChild(ShortcutEditorModelItem *item) +{ + m_childItems.push_back(item); +} + +ShortcutEditorModel::ShortcutEditorModelItem *ShortcutEditorModel::ShortcutEditorModelItem::child(int row) const +{ + if (row < 0 || row >= m_childItems.size()) + return nullptr; + + return m_childItems.at(row); +} + +int ShortcutEditorModel::ShortcutEditorModelItem::childCount() const +{ + return m_childItems.count(); +} + +int ShortcutEditorModel::ShortcutEditorModelItem::columnCount() const +{ + return m_itemData.count(); +} + +QVariant ShortcutEditorModel::ShortcutEditorModelItem::data(int column) const +{ + if (column < 0 || column >= m_itemData.size()) + return QVariant(); + + QVariant columnVariant = m_itemData.at(column); + if (column != static_cast<int>(Column::Shortcut) || columnVariant.canConvert<QString>()) + return columnVariant; + + QAction *action = static_cast<QAction *>(columnVariant.value<void *>()); + if (!action) + return QVariant(); + + QKeySequence keySequence = action->shortcut(); + QString keySequenceString = keySequence.toString(QKeySequence::NativeText); + return keySequenceString; +} + +ShortcutEditorModel::ShortcutEditorModelItem *ShortcutEditorModel::ShortcutEditorModelItem::parentItem() const +{ + return m_parentItem; +} + +int ShortcutEditorModel::ShortcutEditorModelItem::row() const +{ + if (m_parentItem) + return m_parentItem->m_childItems.indexOf(const_cast<ShortcutEditorModelItem*>(this)); + + return 0; +} + +QAction *ShortcutEditorModel::ShortcutEditorModelItem::action() const +{ + QVariant actionVariant = m_itemData.at(static_cast<int>(Column::Shortcut)); + return static_cast<QAction*>(actionVariant.value<void *>()); +} + + +//! [0] +ShortcutEditorModel::ShortcutEditorModel(QObject *parent) + : QAbstractItemModel(parent) +{ + m_rootItem = new ShortcutEditorModelItem({tr("Name"), tr("Shortcut")}); +} +//! [0] + +//! [1] +ShortcutEditorModel::~ShortcutEditorModel() +{ + delete m_rootItem; +} +//! [1] + +//! [2] +void ShortcutEditorModel::setActions() +{ + beginResetModel(); + setupModelData(m_rootItem); + endResetModel(); +} +//! [2] + +//! [3] +QModelIndex ShortcutEditorModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + ShortcutEditorModelItem *parentItem; + if (!parent.isValid()) + parentItem = m_rootItem; + else + parentItem = static_cast<ShortcutEditorModelItem*>(parent.internalPointer()); + + ShortcutEditorModelItem *childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + + return QModelIndex(); +} +//! [3] + +//! [4] +QModelIndex ShortcutEditorModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + ShortcutEditorModelItem *childItem = static_cast<ShortcutEditorModelItem*>(index.internalPointer()); + ShortcutEditorModelItem *parentItem = childItem->parentItem(); + + if (parentItem == m_rootItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} +//! [4] + +//! [5] +int ShortcutEditorModel::rowCount(const QModelIndex &parent) const +{ + ShortcutEditorModelItem *parentItem; + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + parentItem = m_rootItem; + else + parentItem = static_cast<ShortcutEditorModelItem*>(parent.internalPointer()); + + return parentItem->childCount(); +} +//! [5] + +//! [6] +int ShortcutEditorModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return static_cast<ShortcutEditorModelItem*>(parent.internalPointer())->columnCount(); + + return m_rootItem->columnCount(); +} +//! [6] + +//! [7] +QVariant ShortcutEditorModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role != Qt::DisplayRole && role != Qt::EditRole) + return QVariant(); + + ShortcutEditorModelItem *item = static_cast<ShortcutEditorModelItem*>(index.internalPointer()); + return item->data(index.column()); +} +//! [7] + +//! [8] +Qt::ItemFlags ShortcutEditorModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + Qt::ItemFlags modelFlags = QAbstractItemModel::flags(index); + if (index.column() == static_cast<int>(Column::Shortcut)) + modelFlags |= Qt::ItemIsEditable; + + return modelFlags; +} +//! [8] + +//! [9] +QVariant ShortcutEditorModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + return m_rootItem->data(section); + } + + return QVariant(); +} +//! [9] + +//! [10] +void ShortcutEditorModel::setupModelData(ShortcutEditorModelItem *parent) +{ + ActionsMap actionsMap; + Application *application = static_cast<Application *>(QCoreApplication::instance()); + ActionManager *actionManager = application->actionManager(); + const QList<QAction *> registeredActions = actionManager->registeredActions(); + for (QAction *action : registeredActions) { + QString context = actionManager->contextForAction(action); + QString category = actionManager->categoryForAction(action); + actionsMap[context][category].append(action); + } + + QAction *nullAction = nullptr; + const QString contextIdPrefix = "root"; + // Go through each context, one context - many categories each iteration + for (const auto &contextLevel : actionsMap.keys()) { + ShortcutEditorModelItem *contextLevelItem = new ShortcutEditorModelItem({contextLevel, QVariant::fromValue(nullAction)}, parent); + parent->appendChild(contextLevelItem); + + // Go through each category, one category - many actions each iteration + for (const auto &categoryLevel : actionsMap[contextLevel].keys()) { + ShortcutEditorModelItem *categoryLevelItem = new ShortcutEditorModelItem({categoryLevel, QVariant::fromValue(nullAction)}, contextLevelItem); + contextLevelItem->appendChild(categoryLevelItem); + for (QAction *action : actionsMap[contextLevel][categoryLevel]) { + QString name = action->text(); + if (name.isEmpty() || !action) + continue; + + ShortcutEditorModelItem *actionLevelItem = new ShortcutEditorModelItem({name, QVariant::fromValue(reinterpret_cast<void *>(action))}, categoryLevelItem); + categoryLevelItem->appendChild(actionLevelItem); + } + } + } +} +//! [10] + +//! [11] +bool ShortcutEditorModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (role == Qt::EditRole && index.column() == static_cast<int>(Column::Shortcut)) { + QString keySequenceString = value.toString(); + ShortcutEditorModelItem *item = static_cast<ShortcutEditorModelItem *>(index.internalPointer()); + QAction *itemAction = item->action(); + if (itemAction) { + if (keySequenceString == itemAction->shortcut().toString(QKeySequence::NativeText)) + return true; + itemAction->setShortcut(keySequenceString); + } + Q_EMIT dataChanged(index, index); + + if (keySequenceString.isEmpty()) + return true; + } + + return QAbstractItemModel::setData(index, value, role); +} +//! [11] diff --git a/examples/widgets/widgets/shortcuteditor/shortcuteditormodel.h b/examples/widgets/widgets/shortcuteditor/shortcuteditormodel.h new file mode 100644 index 0000000000..c687bb4129 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/shortcuteditormodel.h @@ -0,0 +1,71 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef SHORTCUTEDITORMODEL_H +#define SHORTCUTEDITORMODEL_H + +#include <QAbstractItemModel> +#include <QList> +#include <QVariant> + +QT_BEGIN_NAMESPACE +class QAction; +QT_END_NAMESPACE + +enum class Column : uint8_t { + Name, + Shortcut +}; + +//! [0] +class ShortcutEditorModel : public QAbstractItemModel +{ + Q_OBJECT + + class ShortcutEditorModelItem + { + public: + explicit ShortcutEditorModelItem(const QList<QVariant> &data, + ShortcutEditorModelItem *parentItem = nullptr); + ~ShortcutEditorModelItem(); + + void appendChild(ShortcutEditorModelItem *child); + + ShortcutEditorModelItem *child(int row) const; + int childCount() const; + int columnCount() const; + QVariant data(int column) const; + int row() const; + ShortcutEditorModelItem *parentItem() const; + QAction *action() const; + + private: + QList<ShortcutEditorModelItem *> m_childItems; + QList<QVariant> m_itemData; + ShortcutEditorModelItem *m_parentItem; + }; + +public: + explicit ShortcutEditorModel(QObject *parent = nullptr); + ~ShortcutEditorModel() override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &index) const override; + int rowCount(const QModelIndex &index = QModelIndex()) const override; + int columnCount(const QModelIndex &index = QModelIndex()) const override; + + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + void setActions(); + +private: + void setupModelData(ShortcutEditorModelItem *parent); + + ShortcutEditorModelItem *m_rootItem; +}; +//! [0] + +#endif diff --git a/examples/widgets/widgets/shortcuteditor/shortcuteditorwidget.cpp b/examples/widgets/widgets/shortcuteditor/shortcuteditorwidget.cpp new file mode 100644 index 0000000000..3e8a027f38 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/shortcuteditorwidget.cpp @@ -0,0 +1,33 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "shortcuteditorwidget.h" + +#include "shortcuteditordelegate.h" +#include "shortcuteditormodel.h" + +#include <QHeaderView> +#include <QTreeView> +#include <QVBoxLayout> + +//! [0] +ShortcutEditorWidget::ShortcutEditorWidget(QWidget *parent) + : QWidget(parent) +{ + m_model = new ShortcutEditorModel(this); + m_delegate = new ShortcutEditorDelegate(this); + m_view = new QTreeView(this); + m_view->setModel(m_model); + m_view->setItemDelegateForColumn(static_cast<int>(Column::Shortcut), m_delegate); + m_view->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); + m_view->setAllColumnsShowFocus(true); + m_view->header()->resizeSection(0, 250); + + QVBoxLayout *layout = new QVBoxLayout; + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(m_view); + setLayout(layout); + + m_model->setActions(); +} +//! [0] diff --git a/examples/widgets/widgets/shortcuteditor/shortcuteditorwidget.h b/examples/widgets/widgets/shortcuteditor/shortcuteditorwidget.h new file mode 100644 index 0000000000..44735e65e2 --- /dev/null +++ b/examples/widgets/widgets/shortcuteditor/shortcuteditorwidget.h @@ -0,0 +1,32 @@ +// Copyright (C) 2022 Laszlo Papp <lpapp@kde.org> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef SHORTCUTEDITORWIDGET_H +#define SHORTCUTEDITORWIDGET_H + +#include <QWidget> + +class ShortcutEditorDelegate; +class ShortcutEditorModel; + +QT_BEGIN_NAMESPACE +class QTreeView; +QT_END_NAMESPACE + +//! [0] +class ShortcutEditorWidget : public QWidget +{ + Q_OBJECT + +public: + explicit ShortcutEditorWidget(QWidget *parent = nullptr); + ~ShortcutEditorWidget() override = default; + +private: + ShortcutEditorDelegate *m_delegate; + ShortcutEditorModel *m_model; + QTreeView *m_view; +}; +//! [0] + +#endif |