File indexing completed on 2024-04-28 17:06:04

0001 /*
0002     SPDX-FileCopyrightText: 2018-2020 Shie Erlich <krusader@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2018-2020 Rafi Yanai <krusader@users.sourceforge.net>
0004     SPDX-FileCopyrightText: 2018-2022 Krusader Krew <https://krusader.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "krhistorycombobox.h"
0010 
0011 // QtCore
0012 #include <QEvent>
0013 // QtGui
0014 #include <QKeyEvent>
0015 // QtWidgets
0016 #include <QAbstractItemView>
0017 
0018 /**
0019  *  A KrHistoryComboBox event filter that e.g. deletes the current item when Shift+Del is pressed
0020  *  There was more information in https://doc.qt.io/qt-5/qobject.html#installEventFilter,
0021  *  https://forum.qt.io/post/160618 and
0022  *  https://stackoverflow.com/questions/17820947/remove-items-from-qcombobox-from-ui/52459337#52459337
0023  */
0024 class KHBoxEventFilter : public QObject
0025 {
0026     Q_OBJECT
0027 
0028 public:
0029     explicit KHBoxEventFilter(QObject *parent = nullptr)
0030         : QObject(parent)
0031     {
0032     }
0033 
0034 protected:
0035     bool eventFilter(QObject *obj, QEvent *event) override;
0036 };
0037 
0038 bool KHBoxEventFilter::eventFilter(QObject *obj, QEvent *event)
0039 {
0040     if (event->type() == QEvent::KeyPress) {
0041         auto keyEvent = static_cast<QKeyEvent *>(event);
0042         if (keyEvent->modifiers() == Qt::ShiftModifier && keyEvent->key() == Qt::Key::Key_Delete) {
0043             auto comboBox = qobject_cast<KHistoryComboBox *>(obj);
0044             if (comboBox != nullptr) {
0045                 QString entryToDelete = comboBox->currentText();
0046                 // Delete the current item
0047                 comboBox->removeItem(comboBox->currentIndex());
0048                 // The item has to be deleted also from the completion list
0049                 comboBox->completionObject()->removeItem(entryToDelete);
0050                 return true;
0051             }
0052         }
0053     }
0054     // Perform the usual event processing
0055     return QObject::eventFilter(obj, event);
0056 }
0057 
0058 /**
0059  *  An event filter for the popup list of a KrHistoryComboBox, e.g. it deletes the current
0060  *  item when the user presses Shift+Del
0061  */
0062 class KHBoxListEventFilter : public QObject
0063 {
0064     Q_OBJECT
0065 
0066 public:
0067     explicit KHBoxListEventFilter(QObject *parent = nullptr)
0068         : QObject(parent)
0069     {
0070     }
0071 
0072 protected:
0073     bool eventFilter(QObject *obj, QEvent *event) override;
0074 };
0075 
0076 bool KHBoxListEventFilter::eventFilter(QObject *obj, QEvent *event)
0077 {
0078     if (event->type() == QEvent::KeyPress) {
0079         auto keyEvent = static_cast<QKeyEvent *>(event);
0080         if (keyEvent->modifiers() == Qt::ShiftModifier && keyEvent->key() == Qt::Key::Key_Delete) {
0081             auto itemView = qobject_cast<QAbstractItemView *>(obj);
0082             if (itemView->model() != nullptr) {
0083                 QString entryToDelete = itemView->currentIndex().data().toString();
0084                 // Delete the current item from the popup list
0085                 itemView->model()->removeRow(itemView->currentIndex().row());
0086                 // The item has to be deleted also from the completion list of the KHistoryComboBox
0087                 if (itemView->parent() != nullptr) {
0088                     auto comboBox = qobject_cast<KHistoryComboBox *>(itemView->parent()->parent());
0089                     if (comboBox != nullptr) {
0090                         comboBox->completionObject()->removeItem(entryToDelete);
0091                         return true;
0092                     }
0093                 }
0094             }
0095         }
0096     }
0097     // Perform the usual event processing
0098     return QObject::eventFilter(obj, event);
0099 }
0100 
0101 #include "krhistorycombobox.moc" // required for class definitions with Q_OBJECT macro in implementation files
0102 
0103 KrHistoryComboBox::KrHistoryComboBox(bool useCompletion, QWidget *parent)
0104     : KHistoryComboBox(useCompletion, parent)
0105 {
0106     installEventFilter(new KHBoxEventFilter(this));
0107 
0108     QAbstractItemView *itemView = view();
0109     if (itemView != nullptr)
0110         itemView->installEventFilter(new KHBoxListEventFilter(this));
0111 }