File indexing completed on 2024-04-28 05:50:39

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "ProfileShortcutDelegate.h"
0008 
0009 #include <QApplication>
0010 #include <QKeyEvent>
0011 #include <QPainter>
0012 
0013 using namespace Konsole;
0014 
0015 ShortcutItemDelegate::ShortcutItemDelegate(QObject *parent)
0016     : QStyledItemDelegate(parent)
0017     , _modifiedEditors(QSet<QWidget *>())
0018     , _itemsBeingEdited(QSet<QModelIndex>())
0019 {
0020 }
0021 
0022 void ShortcutItemDelegate::editorModified()
0023 {
0024     auto *editor = qobject_cast<FilteredKeySequenceEdit *>(sender());
0025     Q_ASSERT(editor);
0026     _modifiedEditors.insert(editor);
0027     Q_EMIT commitData(editor);
0028     Q_EMIT closeEditor(editor);
0029 }
0030 void ShortcutItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
0031 {
0032     _itemsBeingEdited.remove(index);
0033 
0034     if (!_modifiedEditors.contains(editor)) {
0035         return;
0036     }
0037 
0038     const auto shortcut = qobject_cast<FilteredKeySequenceEdit *>(editor)->keySequence().toString();
0039     model->setData(index, shortcut, Qt::DisplayRole);
0040 
0041     _modifiedEditors.remove(editor);
0042 }
0043 
0044 QWidget *ShortcutItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const
0045 {
0046     _itemsBeingEdited.insert(index);
0047 
0048     auto editor = new FilteredKeySequenceEdit(parent);
0049     const auto shortcutString = index.data(Qt::DisplayRole).toString();
0050 
0051     editor->setKeySequence(QKeySequence::fromString(shortcutString));
0052     editor->setFocus(Qt::FocusReason::MouseFocusReason);
0053 
0054     connect(editor, &QKeySequenceEdit::editingFinished, this, &Konsole::ShortcutItemDelegate::editorModified);
0055 
0056     return editor;
0057 }
0058 void ShortcutItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0059 {
0060     if (_itemsBeingEdited.contains(index)) {
0061         StyledBackgroundPainter::drawBackground(painter, option, index);
0062     } else {
0063         QStyledItemDelegate::paint(painter, option, index);
0064     }
0065 }
0066 
0067 QSize ShortcutItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
0068 {
0069     const auto shortcutString = index.data(Qt::DisplayRole).toString();
0070     const auto fm = option.fontMetrics;
0071 
0072     static const int editorMargins = 16; // chosen empirically
0073     const int width = fm.boundingRect(shortcutString + QStringLiteral(", ...")).width() + editorMargins;
0074 
0075     return {width, QStyledItemDelegate::sizeHint(option, index).height()};
0076 }
0077 
0078 void ShortcutItemDelegate::destroyEditor(QWidget *editor, const QModelIndex &index) const
0079 {
0080     _itemsBeingEdited.remove(index);
0081     _modifiedEditors.remove(editor);
0082     editor->deleteLater();
0083 }
0084 
0085 void FilteredKeySequenceEdit::keyPressEvent(QKeyEvent *event)
0086 {
0087     if (event->modifiers() == Qt::NoModifier) {
0088         switch (event->key()) {
0089         case Qt::Key_Enter:
0090         case Qt::Key_Return:
0091             Q_EMIT editingFinished();
0092             return;
0093         case Qt::Key_Backspace:
0094         case Qt::Key_Delete:
0095             clear();
0096             Q_EMIT editingFinished();
0097             event->accept();
0098             return;
0099         default:
0100             event->accept();
0101             return;
0102         }
0103     }
0104     QKeySequenceEdit::keyPressEvent(event);
0105 }
0106 
0107 void StyledBackgroundPainter::drawBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &)
0108 {
0109     const auto *opt = qstyleoption_cast<const QStyleOptionViewItem *>(&option);
0110     const QWidget *widget = opt != nullptr ? opt->widget : nullptr;
0111 
0112     QStyle *style = widget != nullptr ? widget->style() : QApplication::style();
0113 
0114     style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget);
0115 }
0116 
0117 #include "moc_ProfileShortcutDelegate.cpp"