Kirigami-addons

shortcutsmodel.cpp
1// SPDX-FileCopyrightText: 2024 Carl Schwan <carlschwan@kde.org>
2// SPDX-License-Identifier: LGPL-2.1-or-later
3
4#include "shortcutsmodel_p.h"
5
6#include <QAction>
7#include <unordered_set>
8#include <KLocalizedString>
9#include <KConfigGroup>
10#include "kirigamiactioncollection.h"
11
12ShortcutsModel::ShortcutsModel(QObject *parent)
13 : QAbstractListModel(parent)
14{
15}
16
17int ShortcutsModel::rowCount(const QModelIndex &parent) const
18{
19 return parent.isValid() ? 0 : m_items.count();
20}
21
22QVariant ShortcutsModel::data(const QModelIndex &index, int role) const
23{
24 Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid));
25
26 const auto &item = m_items[index.row()];
27
28 switch (role) {
29 case Qt::DisplayRole:
30 return item.action->text();
31 case IconNameRole:
32 return item.action->icon().name();
33 case ShortcutRole:
34 return item.action->shortcut();
35 case ShortcutDisplayRole: {
36 QStringList displayText;
37 const auto shortcuts = item.action->shortcuts();
38 for (const auto &shortcut : shortcuts) {
39 displayText << shortcut.toString(QKeySequence::NativeText);
40 }
41 return displayText.join(i18nc("List separator", ", "));
42 }
43 case DefaultShortcutRole:
44 return item.action->shortcut().toString(QKeySequence::NativeText);
45 case AlternateShortcutsRole:
46 if (item.action->shortcuts().size() <= 1) {
47 return {};
48 } else {
49 return QVariant::fromValue(item.action->shortcuts().mid(1));
50 }
51 case CollectionNameRole:
52 return item.collection->componentDisplayName();
53 default:
54 return {};
55 }
56}
57
58QHash<int, QByteArray> ShortcutsModel::roleNames() const
59{
60 return {
61 { Qt::DisplayRole, "actionName" },
62 { IconNameRole, "iconName" },
63 { DefaultShortcutRole, "defaultShortcut" },
64 { ShortcutRole, "shortcut" },
65 { ShortcutDisplayRole, "shortcutDisplay" },
66 { AlternateShortcutsRole, "alternateShortcuts" },
67 { CollectionNameRole, "collectionName" },
68 };
69}
70
71void ShortcutsModel::refresh(const QList<KirigamiActionCollection *> &actionCollections)
72{
73 m_collections = actionCollections;
74 int totalActions = std::accumulate(actionCollections.begin(), actionCollections.end(), 0, [](int a, KirigamiActionCollection *collection) {
75 return a + collection->actions().count();
76 });
77
78 QList<Item> temp_rows;
79 std::unordered_set<QAction *> uniqueActions;
80 temp_rows.reserve(totalActions);
81 for (const auto &collection : actionCollections) {
82 for (const auto action : collection->actions()) {
83 if (collection->isShortcutsConfigurable(action)) {
84 temp_rows.push_back(ShortcutsModel::Item{collection, action});
85 }
86 }
87 }
88
89 beginResetModel();
90 m_items = std::move(temp_rows);
91 endResetModel();
92}
93
94QList<QKeySequence> ShortcutsModel::updateShortcut(int row, int shortcutIndex, QKeySequence keySequence)
95{
96 Q_ASSERT(row >= 0 && row < rowCount());
97
98 const auto &item = m_items[row];
99 auto oldShortcuts = item.action->shortcuts();
100 if (keySequence.isEmpty()) {
101 if (shortcutIndex != oldShortcuts.count()) {
102 oldShortcuts.remove(shortcutIndex);
103 }
104 } else {
105 if (shortcutIndex == oldShortcuts.count()) {
106 oldShortcuts << keySequence;
107 } else {
108 oldShortcuts[shortcutIndex] = keySequence;
109 }
110 }
111
112 item.action->setShortcuts(oldShortcuts);
113
114 Q_EMIT dataChanged(index(row), index(row));
115
116 if (item.action->shortcuts().size() <= 1) {
117 return {};
118 } else {
119 return item.action->shortcuts().mid(1);
120 }
121}
122
123void ShortcutsModel::resetAll()
124{
125 for (int i = 0, count = rowCount(); i < count; i++) {
126 reset(i);
127 }
128}
129
130void ShortcutsModel::save()
131{
132 for (const auto *collection : std::as_const(m_collections)) {
133 collection->writeSettings(nullptr); // Use default location
134 }
135}
136
137QList<QKeySequence> ShortcutsModel::reset(int row)
138{
139 Q_ASSERT(row >= 0 && row < rowCount());
140
141 const auto &item = m_items[row];
142
143 const QList<QKeySequence> defaultShortcuts = item.action->property("defaultShortcuts").value<QList<QKeySequence>>();
144
145 if (item.action->shortcuts() != defaultShortcuts) {
146 item.action->setShortcuts(defaultShortcuts);
147 }
148
149 Q_EMIT dataChanged(index(row), index(row));
150
151 if (item.action->shortcuts().size() <= 1) {
152 return {};
153 } else {
154 return item.action->shortcuts().mid(1);
155 }
156}
157QKeySequence ShortcutsModel::emptyKeySequence() const
158{
159 return {};
160}
A container for a set of QAction objects.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
KGuiItem reset()
const QList< QKeySequence > & shortcut(StandardShortcut id)
iterator begin()
iterator end()
void push_back(parameter_type value)
void reserve(qsizetype size)
T value(qsizetype i) const const
bool isValid() const const
int row() const const
QString join(QChar separator) const const
DisplayRole
void keySequence(QWidget *widget, const QKeySequence &keySequence)
QVariant fromValue(T &&value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:12:26 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.