diff --git a/krusader/Filter/generalfilter.h b/krusader/Filter/generalfilter.h --- a/krusader/Filter/generalfilter.h +++ b/krusader/Filter/generalfilter.h @@ -37,6 +37,7 @@ #include "../Dialogs/kurllistrequester.h" #include "../GUI/profilemanager.h" #include "../GUI/krlistwidget.h" +#include "../GUI/krhistorcombobox.h" class GeneralFilter : public QWidget, public FilterBase { @@ -85,7 +86,7 @@ KURLListRequester *dontSearchIn; QLayout *middleLayout; - KHistoryComboBox* searchFor; + KrHistorComboBox* searchFor; KHistoryComboBox* containsText; KHistoryComboBox* excludeFolderNames; QToolButton* containsRegExp; diff --git a/krusader/Filter/generalfilter.cpp b/krusader/Filter/generalfilter.cpp --- a/krusader/Filter/generalfilter.cpp +++ b/krusader/Filter/generalfilter.cpp @@ -113,7 +113,7 @@ searchForLabel->setText(i18n("Search &for:")); nameGroupLayout->addWidget(searchForLabel, 0, 0); - searchFor = new KHistoryComboBox(false, nameGroup/*, "searchFor"*/); + searchFor = new KrHistorComboBox(false, nameGroup/*, "searchFor"*/); QSizePolicy searchForPolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); searchForPolicy.setHeightForWidth(searchFor->sizePolicy().hasHeightForWidth()); searchFor->setSizePolicy(searchForPolicy); diff --git a/krusader/GUI/CMakeLists.txt b/krusader/GUI/CMakeLists.txt --- a/krusader/GUI/CMakeLists.txt +++ b/krusader/GUI/CMakeLists.txt @@ -6,6 +6,7 @@ kfnkeys.cpp kcmdline.cpp profilemanager.cpp + krhistorcombobox.cpp krremoteencodingmenu.cpp krtreewidget.cpp krstyleproxy.cpp diff --git a/krusader/GUI/krhistorcombobox.h b/krusader/GUI/krhistorcombobox.h new file mode 100644 --- /dev/null +++ b/krusader/GUI/krhistorcombobox.h @@ -0,0 +1,69 @@ +/***************************************************************************** + * Copyright (C) 2018 Shie Erlich * + * Copyright (C) 2018 Rafi Yanai * + * Copyright (C) 2018 Krusader Krew [https://krusader.org] * + * * + * This file is part of Krusader [https://krusader.org]. * + * * + * Krusader is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * Krusader is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with Krusader. If not, see [http://www.gnu.org/licenses/]. * + *****************************************************************************/ + +#ifndef KRHISTORCOMBOBOX_H +#define KRHISTORCOMBOBOX_H + +#include + +/*! A KrHistorComboBox event filter that e.g. deletes the current item when the user presses Shift+Del + + There was more information in https://doc.qt.io/qt-5/qobject.html#installEventFilter, https://forum.qt.io/post/160618 + and https://stackoverflow.com/questions/17820947/remove-items-from-qcombobox-from-ui/52459337#52459337 +*/ +class KHBoxEventFilter : public QObject +{ + Q_OBJECT + +public: + explicit KHBoxEventFilter(QObject *parent = nullptr) : QObject(parent) {} + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; +}; + +//! An event filter for the popup list of a KrHistorComboBox, e.g. it deletes the current item when the user presses Shift+Del +class KHBoxListEventFilter : public QObject +{ + Q_OBJECT + +public: + explicit KHBoxListEventFilter(QObject *parent = nullptr) : QObject(parent) {} + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; +}; + + +//! A specialized version of a KHistoryComboBox, e.g. it deletes the current item when the user presses Shift+Del +class KrHistorComboBox : public KHistoryComboBox +{ + Q_OBJECT + +public: + explicit KrHistorComboBox(bool useCompletion, QWidget *parent = nullptr); + +protected: + KHBoxEventFilter boxEF; + KHBoxListEventFilter listEF; +}; + +#endif // KRHISTORCOMBOBOX_H diff --git a/krusader/GUI/krhistorcombobox.cpp b/krusader/GUI/krhistorcombobox.cpp new file mode 100644 --- /dev/null +++ b/krusader/GUI/krhistorcombobox.cpp @@ -0,0 +1,83 @@ +/***************************************************************************** + * Copyright (C) 2018 Shie Erlich * + * Copyright (C) 2018 Rafi Yanai * + * Copyright (C) 2018 Krusader Krew [https://krusader.org] * + * * + * This file is part of Krusader [https://krusader.org]. * + * * + * Krusader is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 2 of the License, or * + * (at your option) any later version. * + * * + * Krusader is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with Krusader. If not, see [http://www.gnu.org/licenses/]. * + *****************************************************************************/ + +#include "krhistorcombobox.h" + +// QtCore +#include +// QtGui +#include +// QtWidgets +#include + +bool KHBoxEventFilter::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + auto keyEvent = static_cast(event); + if (keyEvent->modifiers() == Qt::ShiftModifier && keyEvent->key() == Qt::Key::Key_Delete) { + auto box = dynamic_cast(obj); + if (box != nullptr) { + QString optionToDelete = box->currentText(); + // Delete the current item + box->removeItem(box->currentIndex()); + // The item has to be deleted also from the completion list + box->completionObject()->removeItem(optionToDelete); + return true; + } + } + } + // Perform the usual event processing + return QObject::eventFilter(obj, event); +} + +bool KHBoxListEventFilter::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + auto keyEvent = static_cast(event); + if (keyEvent->modifiers() == Qt::ShiftModifier && keyEvent->key() == Qt::Key::Key_Delete) { + auto iv = dynamic_cast(obj); + if (iv->model() != nullptr) { + QString entryToDelete = iv->currentIndex().data().toString(); + // Delete the current item from the popup list + iv->model()->removeRow(iv->currentIndex().row()); + // The item has to be deleted also from the completion list of the KHistoryComboBox + if (obj->parent() != nullptr) { + auto box = static_cast(obj->parent()->parent()); + if (box != nullptr) { + box->completionObject()->removeItem(entryToDelete); + return true; + } + } + } + } + } + // Perform the usual event processing + return QObject::eventFilter(obj, event); +} + +KrHistorComboBox::KrHistorComboBox(bool useCompletion, QWidget *parent) : KHistoryComboBox(useCompletion, parent) +{ + installEventFilter(&boxEF); + + QAbstractItemView* iv = view(); + if (iv != nullptr) + iv->installEventFilter(&listEF); +} diff --git a/krusader/Search/krsearchdialog.cpp b/krusader/Search/krsearchdialog.cpp --- a/krusader/Search/krsearchdialog.cpp +++ b/krusader/Search/krsearchdialog.cpp @@ -286,7 +286,7 @@ generalFilter->searchFor->setFocus(); - // finaly, load a profile of apply defaults: + // finally, load a profile of apply defaults: if (profile.isEmpty()) { // load the last used values @@ -426,9 +426,9 @@ qApp->processEvents(); // start the search. - if (searcher != 0) + if (searcher != nullptr) abort(); - searcher = new KRSearchMod(query); + searcher = new KRSearchMod(query); connect(searcher, &KRSearchMod::searching, searchingLabel, &KSqueezedTextLabel::setText); connect(searcher, &KRSearchMod::found, this, &KrSearchDialog::slotFound); connect(searcher, &KRSearchMod::finished, this, &KrSearchDialog::stopSearch);