File indexing completed on 2024-06-16 04:15:39
0001 /* This file is part of the KDE libraries SPDX-FileCopyrightText: 1998 Mark Donohoe <donohoe@kde.org> 0002 SPDX-FileCopyrightText: 1997 Nicolas Hadacek <hadacek@kde.org> 0003 SPDX-FileCopyrightText: 1998 Matthias Ettrich <ettrich@kde.org> 0004 SPDX-FileCopyrightText: 2001 Ellis Whitehead <ellis@kde.org> 0005 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org> 0006 SPDX-FileCopyrightText: 2007 Roberto Raggi <roberto@kdevelop.org> 0007 SPDX-FileCopyrightText: 2007 Andreas Hartmetz <ahartmetz@gmail.com> 0008 SPDX-FileCopyrightText: 2008 Michael Jansen <kde@michael-jansen.biz> 0009 0010 SPDX-License-Identifier: LGPL-2.0-or-later 0011 */ 0012 0013 #include "KisShortcutsDialog_p.h" 0014 #include "KisShortcutsEditor_p.h" 0015 0016 #include <QAction> 0017 #include <QTreeWidgetItem> 0018 #include <kis_debug.h> 0019 0020 0021 KisShortcutsEditorItem::KisShortcutsEditorItem(QTreeWidgetItem *parent, QAction *action) 0022 : QTreeWidgetItem(parent, ActionItem) 0023 , m_action(action) 0024 { 0025 // Filtering message requested by translators (scripting). 0026 m_id = m_action->objectName(); 0027 m_actionNameInTable = i18nc("@item:intable Action name in shortcuts configuration", 0028 "%1", KLocalizedString::removeAcceleratorMarker(m_action->text())); 0029 if (m_actionNameInTable.isEmpty()) { 0030 warnKrita << "Action without text!" << m_action->objectName(); 0031 m_actionNameInTable = m_id; 0032 } 0033 0034 m_collator.setNumericMode(true); 0035 m_collator.setCaseSensitivity(Qt::CaseSensitive); 0036 0037 // qDebug() << "Adding new action" << m_id << "with shortcut" << keySequence(LocalPrimary).toString(); 0038 } 0039 0040 KisShortcutsEditorItem::~KisShortcutsEditorItem() 0041 { 0042 delete m_oldLocalShortcut; 0043 } 0044 0045 bool KisShortcutsEditorItem::isModified() const 0046 { 0047 return m_oldLocalShortcut; 0048 } 0049 0050 QVariant KisShortcutsEditorItem::data(int column, int role) const 0051 { 0052 switch (role) { 0053 case Qt::DisplayRole: 0054 switch (column) { 0055 case Name: 0056 return m_actionNameInTable; 0057 case Id: 0058 return m_id; 0059 case LocalPrimary: 0060 case LocalAlternate: 0061 return QVariant::fromValue(keySequence(column)); 0062 default: 0063 break; 0064 } 0065 break; 0066 case Qt::DecorationRole: 0067 if (column == Name) { 0068 return m_action->icon(); 0069 } else { 0070 return QIcon(); 0071 } 0072 break; 0073 case Qt::WhatsThisRole: 0074 return m_action->whatsThis(); 0075 case Qt::ToolTipRole: 0076 // TODO: show command descriptions/tooltips in the shortcut editor 0077 return QVariant(); 0078 case Qt::FontRole: 0079 if (column == Name && m_isNameBold) { 0080 QFont modifiedFont = treeWidget()->font(); 0081 modifiedFont.setBold(true); 0082 return modifiedFont; 0083 } 0084 break; 0085 case KExtendableItemDelegate::ShowExtensionIndicatorRole: 0086 switch (column) { 0087 case Name: 0088 return false; 0089 case LocalPrimary: 0090 case LocalAlternate: 0091 return !m_action->property("isShortcutConfigurable").isValid() 0092 || m_action->property("isShortcutConfigurable").toBool(); 0093 default: 0094 return false; 0095 } 0096 //the following are custom roles, defined in this source file only 0097 case ShortcutRole: 0098 switch (column) { 0099 case LocalPrimary: 0100 case LocalAlternate: 0101 return QVariant::fromValue(keySequence(column)); 0102 default: 0103 // Column not valid for this role 0104 Q_ASSERT(false); 0105 return QVariant(); 0106 } 0107 0108 case DefaultShortcutRole: { 0109 0110 // Note: we are using the QMetaObject system to store this property. 0111 QList<QKeySequence> defaultShortcuts = m_action->property("defaultShortcuts").value<QList<QKeySequence> >(); 0112 0113 switch (column) { 0114 case LocalPrimary: 0115 return QVariant::fromValue(primarySequence(defaultShortcuts)); 0116 case LocalAlternate: 0117 return QVariant::fromValue(alternateSequence(defaultShortcuts)); 0118 default: 0119 // Column not valid for this role 0120 Q_ASSERT(false); 0121 return QVariant(); 0122 } 0123 } 0124 case ObjectRole: 0125 return QVariant::fromValue((QObject *)m_action); 0126 0127 default: 0128 break; 0129 } 0130 0131 return QVariant(); 0132 } 0133 0134 bool KisShortcutsEditorItem::operator<(const QTreeWidgetItem &other) const 0135 { 0136 const int column = treeWidget() ? treeWidget()->sortColumn() : 0; 0137 return m_collator.compare(text(column), other.text(column)) < 0; 0138 } 0139 0140 QKeySequence KisShortcutsEditorItem::keySequence(uint column) const 0141 { 0142 QList<QKeySequence> shortcuts = m_action->shortcuts(); 0143 0144 switch (column) { 0145 case LocalPrimary: 0146 return primarySequence(shortcuts); 0147 case LocalAlternate: 0148 return alternateSequence(shortcuts); 0149 default: 0150 return QKeySequence(); 0151 } 0152 } 0153 0154 void KisShortcutsEditorItem::setKeySequence(uint column, const QKeySequence &seq) 0155 { 0156 QList<QKeySequence> ks; 0157 ks = m_action->shortcuts(); 0158 if (!m_oldLocalShortcut) { 0159 m_oldLocalShortcut = new QList<QKeySequence>(ks); 0160 } 0161 0162 if (column == LocalAlternate) { 0163 if (ks.isEmpty()) { 0164 ks << QKeySequence(); 0165 } 0166 0167 if (ks.size() <= 1) { 0168 ks << seq; 0169 } else { 0170 ks[1] = seq; 0171 } 0172 } else { 0173 if (ks.isEmpty()) { 0174 ks << seq; 0175 } else { 0176 ks[0] = seq; 0177 } 0178 } 0179 0180 m_action->setShortcuts(ks); 0181 0182 updateModified(); 0183 } 0184 0185 //our definition of modified is "modified since the chooser was shown". 0186 void KisShortcutsEditorItem::updateModified() 0187 { 0188 if (m_oldLocalShortcut && *m_oldLocalShortcut == m_action->shortcuts()) { 0189 delete m_oldLocalShortcut; 0190 m_oldLocalShortcut = 0; 0191 } 0192 } 0193 0194 bool KisShortcutsEditorItem::isModified(uint column) const 0195 { 0196 switch (column) { 0197 case Name: 0198 return false; 0199 case LocalPrimary: 0200 case LocalAlternate: 0201 if (!m_oldLocalShortcut) { 0202 return false; 0203 } 0204 if (column == LocalPrimary) { 0205 return primarySequence(*m_oldLocalShortcut) != primarySequence(m_action->shortcuts()); 0206 } else { 0207 return alternateSequence(*m_oldLocalShortcut) != alternateSequence(m_action->shortcuts()); 0208 } 0209 default: 0210 return false; 0211 } 0212 } 0213 0214 void KisShortcutsEditorItem::undo() 0215 { 0216 //dbgKrita << "Undoing changes for " << data(Name, Qt::DisplayRole).toString(); 0217 0218 if (m_oldLocalShortcut) { 0219 // We only ever reset the active Shortcut 0220 m_action->setShortcuts(*m_oldLocalShortcut); 0221 } 0222 0223 updateModified(); 0224 } 0225 0226 void KisShortcutsEditorItem::commit() 0227 { 0228 if (m_oldLocalShortcut) { // || m_oldShapeGesture || m_oldRockerGesture) { 0229 dbgUI << "Committing changes for " << data(Name, Qt::DisplayRole).toString(); 0230 } 0231 0232 delete m_oldLocalShortcut; 0233 m_oldLocalShortcut = 0; 0234 }