File indexing completed on 2025-04-27 03:58:21
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-03-14 0007 * Description : User interface for searches 0008 * 0009 * SPDX-FileCopyrightText: 2008-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #ifndef DIGIKAM_COMBOBOX_UTILITIES_H 0016 #define DIGIKAM_COMBOBOX_UTILITIES_H 0017 0018 // Qt includes 0019 0020 #include <QLabel> 0021 #include <QListView> 0022 #include <QComboBox> 0023 #include <QPersistentModelIndex> 0024 #include <QLineEdit> 0025 0026 // Local includes 0027 0028 #include "digikam_export.h" 0029 0030 class QVBoxLayout; 0031 class QTreeView; 0032 0033 namespace Digikam 0034 { 0035 0036 class DIGIKAM_EXPORT ProxyLineEdit : public QLineEdit 0037 { 0038 Q_OBJECT 0039 0040 public: 0041 0042 /** 0043 * This class will not act as a QLineEdit at all, 0044 * but present another widget (any kind of widget) 0045 * instead in the space assigned to the QLineEdit. 0046 * Use this class if you need to pass a QLineEdit but 0047 * want actually to use a different widget. 0048 */ 0049 explicit ProxyLineEdit(QWidget* const parent = nullptr); 0050 0051 /** 0052 * After constructing, set the actual widget here 0053 */ 0054 virtual void setWidget(QWidget* widget); 0055 0056 void setClearButtonShown(bool show); 0057 0058 Q_SIGNALS: 0059 0060 void signalClearButtonPressed(); 0061 0062 private Q_SLOTS: 0063 0064 void slotTextChanged(const QString& text); 0065 0066 protected: 0067 0068 QSize minimumSizeHint() const override; 0069 QSize sizeHint() const override; 0070 0071 void mousePressEvent(QMouseEvent* event) override; 0072 void mouseMoveEvent(QMouseEvent* event) override; 0073 void mouseReleaseEvent(QMouseEvent* event) override; 0074 void mouseDoubleClickEvent(QMouseEvent* event) override; 0075 void keyPressEvent(QKeyEvent* event) override; 0076 void focusInEvent(QFocusEvent* event) override; 0077 void focusOutEvent(QFocusEvent* event) override; 0078 void paintEvent(QPaintEvent* event) override; 0079 void dragEnterEvent(QDragEnterEvent* event) override; 0080 void dragMoveEvent(QDragMoveEvent* e) override; 0081 void dragLeaveEvent(QDragLeaveEvent* e) override; 0082 void dropEvent(QDropEvent* event) override; 0083 void changeEvent(QEvent* event) override; 0084 void contextMenuEvent(QContextMenuEvent* event) override; 0085 void inputMethodEvent(QInputMethodEvent* event) override; 0086 0087 protected: 0088 0089 QWidget* m_widget; 0090 QVBoxLayout* m_layout; 0091 }; 0092 0093 // ------------------------------------------------------------------------- 0094 0095 class DIGIKAM_EXPORT ProxyClickLineEdit : public ProxyLineEdit 0096 { 0097 Q_OBJECT 0098 0099 public: 0100 0101 /** 0102 * A ProxyLineEdit that emits leftClicked() on 0103 * mouse press event. 0104 * Press on the held widget will result in the signal 0105 * if the widget does not accept() them. 0106 */ 0107 explicit ProxyClickLineEdit(QWidget* const parent = nullptr); 0108 0109 Q_SIGNALS: 0110 0111 void leftClicked(); 0112 0113 protected: 0114 0115 void mouseReleaseEvent(QMouseEvent* event) override; 0116 }; 0117 0118 // ------------------------------------------------------------------------- 0119 0120 class DIGIKAM_EXPORT ModelIndexBasedComboBox : public QComboBox 0121 { 0122 Q_OBJECT 0123 0124 public: 0125 0126 /** 0127 * QComboBox has a current index based on a single integer. 0128 * This is not sufficient for more complex models. 0129 * This class is a combo box that stores a current index 0130 * based on QModelIndex. 0131 */ 0132 explicit ModelIndexBasedComboBox(QWidget* const parent = nullptr); 0133 0134 QModelIndex currentIndex() const; 0135 void setCurrentIndex(const QModelIndex& index); 0136 0137 void hidePopup() override; 0138 void showPopup() override; 0139 0140 protected: 0141 0142 QPersistentModelIndex m_currentIndex; 0143 }; 0144 0145 // ------------------------------------------------------------------------- 0146 0147 class DIGIKAM_EXPORT StayPoppedUpComboBox : public ModelIndexBasedComboBox 0148 { 0149 Q_OBJECT 0150 0151 public: 0152 0153 /** 0154 * This class provides an abstract QComboBox with a custom view 0155 * (which is created by implementing subclasses) 0156 * instead of the usual QListView. 0157 * The Pop-up of the combo box will stay open after selecting an item; 0158 * it will be closed by clicking outside, but not inside the widget. 0159 * You need three steps: 0160 * Construct the object, call setModel() with an appropriate 0161 * QAbstractItemModel, then call installView() to replace 0162 * the standard combo box view with a view. 0163 */ 0164 explicit StayPoppedUpComboBox(QWidget* const parent = nullptr); 0165 0166 protected: 0167 0168 /** 0169 * Replace the standard combo box list view with the given view. 0170 * The view will be set as the view of the combo box 0171 * (including re-parenting) and be stored in the m_view variable. 0172 */ 0173 void installView(QAbstractItemView* view); 0174 0175 /** 0176 * Implement in subclass: 0177 * Send the given event to the viewportEvent() method of m_view. 0178 * This method is protected for a usual QAbstractItemView. 0179 * You can override, pass a view, and call parent implementation. 0180 * The existing view will be used. You must then also 0181 * reimplement sendViewportEventToView. 0182 */ 0183 virtual void sendViewportEventToView(QEvent* e) = 0; 0184 0185 bool eventFilter(QObject* watched, QEvent* event) override; 0186 0187 protected: 0188 0189 QAbstractItemView* m_view; 0190 }; 0191 0192 // ------------------------------------------------------------------------- 0193 0194 class DIGIKAM_EXPORT TreeViewComboBox : public StayPoppedUpComboBox 0195 { 0196 Q_OBJECT 0197 0198 public: 0199 0200 /** 0201 * This class provides a QComboBox with a QTreeView 0202 * instead of the usual QListView. 0203 * You need three steps: 0204 * Construct the object, call setModel() with an appropriate 0205 * QAbstractItemModel, then call installView() to replace 0206 * the standard combo box view with a QTreeView. 0207 */ 0208 explicit TreeViewComboBox(QWidget* parent = nullptr); 0209 0210 /** 0211 * Replace the standard combo box list view with a QTreeView. 0212 * Call this after installing an appropriate model. 0213 */ 0214 virtual void installView(QAbstractItemView* view = nullptr); 0215 0216 /** 0217 * Returns the QTreeView of this class. Valid after installView() has been called 0218 */ 0219 QTreeView* view() const; 0220 0221 protected: 0222 0223 void sendViewportEventToView(QEvent* e) override; 0224 }; 0225 0226 // ------------------------------------------------------------------------- 0227 0228 class DIGIKAM_EXPORT ListViewComboBox : public StayPoppedUpComboBox 0229 { 0230 Q_OBJECT 0231 0232 public: 0233 0234 /** 0235 * This class provides an implementation of a StayPoppedUpComboBox 0236 * with a QListView. This is the standard view of a QComboBox, 0237 * but in conjunction with StayPoppedUpComboBox some extra steps are needed. 0238 * You need three steps: 0239 * Construct the object, call setModel() with an appropriate 0240 * QAbstractItemModel, then call installView(). 0241 */ 0242 explicit ListViewComboBox(QWidget* parent = nullptr); 0243 0244 /** 0245 * Returns the QTreeView of this class. Valid after installView() has been called. 0246 */ 0247 QListView* view() const; 0248 0249 /** 0250 * Replace the standard combo box list view with a QTreeView. 0251 * Call this after installing an appropriate model. 0252 */ 0253 virtual void installView(QAbstractItemView* view = nullptr); 0254 0255 protected: 0256 0257 void sendViewportEventToView(QEvent* e) override; 0258 }; 0259 0260 // ------------------------------------------------------------------------- 0261 0262 class DIGIKAM_EXPORT TreeViewLineEditComboBox : public TreeViewComboBox 0263 { 0264 Q_OBJECT 0265 0266 public: 0267 0268 /** 0269 * This class provides a TreeViewComboBox 0270 * with a read-only line edit. 0271 * The text in the line edit can be adjusted. The combo box will 0272 * open on a click on the line edit. 0273 * You need three steps: 0274 * Construct the object, call setModel() with an appropriate 0275 * QAbstractItemModel, then call installView() to replace 0276 * the standard combo box view with a QTreeView. 0277 */ 0278 explicit TreeViewLineEditComboBox(QWidget* const parent = nullptr); 0279 0280 /** 0281 * Set the text of the line edit (the text that is visible 0282 * if the popup is not opened). 0283 * Applicable only for default installLineEdit() implementation. 0284 */ 0285 void setLineEditText(const QString& text); 0286 0287 void setLineEdit(QLineEdit* edit); 0288 0289 /** 0290 * Replace the standard combo box list view with a QTreeView. 0291 * Call this after installing an appropriate model. 0292 */ 0293 void installView(QAbstractItemView* view = nullptr) override; 0294 0295 protected: 0296 0297 /** 0298 * Sets a line edit. Called by installView(). 0299 * The default implementation is described above. 0300 * An empty implementation will keep the default QComboBox line edit. 0301 */ 0302 virtual void installLineEdit(); 0303 0304 protected: 0305 0306 QLineEdit* m_comboLineEdit; 0307 }; 0308 0309 } // namespace Digikam 0310 0311 #endif // DIGIKAM_COMBOBOX_UTILITIES_H