File indexing completed on 2024-05-05 05:37:09
0001 /* 0002 SPDX-FileCopyrightText: 2003 Scott Wheeler <wheeler@kde.org> 0003 SPDX-FileCopyrightText: 2005 Rafal Rzepecki <divide@users.sourceforge.net> 0004 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org> 0005 SPDX-FileCopyrightText: 2007 Pino Toscano <pino@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-only 0008 */ 0009 0010 #ifndef KTREEVIEWSEARCHLINE_H 0011 #define KTREEVIEWSEARCHLINE_H 0012 0013 #include <klineedit.h> 0014 0015 class QModelIndex; 0016 class QTreeView; 0017 0018 class KTreeViewSearchLinePrivate; 0019 class KTreeViewSearchLineWidgetPrivate; 0020 0021 /** 0022 * This class makes it easy to add a search line for filtering the items in 0023 * listviews based on a simple text search. 0024 * 0025 * No changes to the application other than instantiating this class with 0026 * appropriate QTreeViews should be needed. 0027 */ 0028 0029 class KTreeViewSearchLine : public KLineEdit 0030 { 0031 Q_OBJECT 0032 0033 Q_PROPERTY(Qt::CaseSensitivity caseSensitity READ caseSensitivity WRITE setCaseSensitivity) 0034 Q_PROPERTY(bool keepParentsVisible READ keepParentsVisible WRITE setKeepParentsVisible) 0035 0036 public: 0037 /** 0038 * Constructs a KTreeViewSearchLine with \a treeView being the QTreeView to 0039 * be filtered. 0040 * 0041 * If \a treeView is null then the widget will be disabled until listviews 0042 * are set with setTreeView(), setTreeViews() or added with addTreeView(). 0043 */ 0044 explicit KTreeViewSearchLine(QWidget *parent = nullptr, QTreeView *treeView = nullptr); 0045 0046 /** 0047 * Constructs a KTreeViewSearchLine with \a treeViews being the list of 0048 * pointers to QTreeViews to be filtered. 0049 * 0050 * If \a treeViews is empty then the widget will be disabled until listviews 0051 * are set with setTreeView(), setTreeViews() or added with addTreeView(). 0052 */ 0053 KTreeViewSearchLine(QWidget *parent, const QList<QTreeView *> &treeViews); 0054 0055 /** 0056 * Destroys the KTreeViewSearchLine. 0057 */ 0058 ~KTreeViewSearchLine() override; 0059 0060 /** 0061 * Returns true if the search is case sensitive. This defaults to false. 0062 * 0063 * @see setCaseSensitive() 0064 */ 0065 Qt::CaseSensitivity caseSensitivity() const; 0066 0067 /** 0068 * Returns the current list of columns that will be searched. If the 0069 * returned list is empty all visible columns will be searched. 0070 * 0071 * @see setSearchColumns 0072 */ 0073 QList<int> searchColumns() const; 0074 0075 /** 0076 * If this is true (the default) then the parents of matched items will also 0077 * be shown. 0078 * 0079 * @see setKeepParentsVisible() 0080 */ 0081 bool keepParentsVisible() const; 0082 0083 /** 0084 * Returns the listview that is currently filtered by the search. 0085 * If there are multiple listviews filtered, it returns 0. 0086 * 0087 * @see setTreeView(), treeView() 0088 */ 0089 QTreeView *treeView() const; 0090 0091 /** 0092 * Returns the list of pointers to listviews that are currently filtered by 0093 * the search. 0094 * 0095 * @see setTreeViews(), addTreeView(), treeView() 0096 */ 0097 QList<QTreeView *> treeViews() const; 0098 0099 public Q_SLOTS: 0100 /** 0101 * Adds a QTreeView to the list of listviews filtered by this search line. 0102 * If \a treeView is null then the widget will be disabled. 0103 * 0104 * @see treeView(), setTreeViews(), removeTreeView() 0105 */ 0106 void addTreeView(QTreeView *treeView); 0107 0108 /** 0109 * Removes a QTreeView from the list of listviews filtered by this search 0110 * line. Does nothing if \a treeView is 0 or is not filtered by the quick search 0111 * line. 0112 * 0113 * @see listVew(), setTreeView(), addTreeView() 0114 */ 0115 void removeTreeView(QTreeView *treeView); 0116 0117 /** 0118 * Updates search to only make visible the items that match \a pattern. If 0119 * \a s is null then the line edit's text will be used. 0120 */ 0121 virtual void updateSearch(const QString &pattern = QString()); 0122 0123 /** 0124 * Make the search case sensitive or case insensitive. 0125 * 0126 * @see caseSenstivity() 0127 */ 0128 void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity); 0129 0130 /** 0131 * When a search is active on a list that's organized into a tree view if 0132 * a parent or ancestor of an item is does not match the search then it 0133 * will be hidden and as such so too will any children that match. 0134 * 0135 * If this is set to true (the default) then the parents of matching items 0136 * will be shown. 0137 * 0138 * @see keepParentsVisible 0139 */ 0140 void setKeepParentsVisible(bool value); 0141 0142 /** 0143 * Sets the list of columns to be searched. The default is to search all, 0144 * visible columns which can be restored by passing \a columns as an empty 0145 * list. 0146 * If listviews to be filtered have different numbers or labels of columns 0147 * this method has no effect. 0148 * 0149 * @see searchColumns 0150 */ 0151 void setSearchColumns(const QList<int> &columns); 0152 0153 /** 0154 * Sets the QTreeView that is filtered by this search line, replacing any 0155 * previously filtered listviews. If \a treeView is null then the widget will be 0156 * disabled. 0157 * 0158 * @see treeView(), setTreeViews() 0159 */ 0160 void setTreeView(QTreeView *treeView); 0161 0162 /** 0163 * Sets QTreeViews that are filtered by this search line, replacing any 0164 * previously filtered listviews. If \a treeViews is empty then the widget will 0165 * be disabled. 0166 * 0167 * @see treeViews(), addTreeView(), setTreeView() 0168 */ 0169 void setTreeViews(const QList<QTreeView *> &treeViews); 0170 0171 /** 0172 * Returns true if \a item matches the search \a pattern. This will be evaluated 0173 * based on the value of caseSensitive(). This can be overridden in 0174 * subclasses to implement more complicated matching schemes. 0175 */ 0176 virtual bool itemMatches(const QModelIndex &item, int row, const QString &pattern) const; 0177 0178 /** 0179 * Checks columns in all listviews and decides whether choosing columns to 0180 * filter on makes any sense. 0181 * 0182 * Returns false if either of the following is true: 0183 * * there are no listviews connected, 0184 * * the listviews have different numbers of columns, 0185 * * the listviews have only one column, 0186 * * the listviews differ in column labels. 0187 * 0188 * Otherwise it returns true. 0189 * 0190 * @see setSearchColumns() 0191 */ 0192 virtual bool canChooseColumnsCheck(); 0193 0194 protected: 0195 /** 0196 * Re-implemented for internal reasons. API not affected. 0197 */ 0198 void contextMenuEvent(QContextMenuEvent *) override; 0199 0200 /** 0201 * Updates search to only make visible appropriate items in \a treeView. If 0202 * \a treeView is null then nothing is done. 0203 */ 0204 virtual void updateSearch(QTreeView *treeView); 0205 0206 /** 0207 * Connects signals of this listview to the appropriate Q_SLOTS of the search 0208 * line. 0209 */ 0210 virtual void connectTreeView(QTreeView *); 0211 0212 /** 0213 * Disconnects signals of a listviews from the search line. 0214 */ 0215 virtual void disconnectTreeView(QTreeView *); 0216 0217 protected Q_SLOTS: 0218 /** 0219 * When keys are pressed a new search string is created and a timer is 0220 * activated. The most recent search is activated when this timer runs out 0221 * if another key has not yet been pressed. 0222 * 0223 * This method makes @param search the most recent search and starts the 0224 * timer. 0225 * 0226 * Together with activateSearch() this makes it such that searches are not 0227 * started until there is a short break in the users typing. 0228 * 0229 * @see activateSearch() 0230 */ 0231 void queueSearch(const QString &search); 0232 0233 /** 0234 * When the timer started with queueSearch() expires this slot is called. 0235 * If there has been another timer started then this slot does nothing. 0236 * However if there are no other pending searches this starts the list view 0237 * search. 0238 * 0239 * @see queueSearch() 0240 */ 0241 void activateSearch(); 0242 0243 private: 0244 KTreeViewSearchLinePrivate *const d; 0245 0246 // Q_PRIVATE_SLOT( d, void rowsInserted( const QModelIndex&, int, int ) const ) 0247 Q_PRIVATE_SLOT(d, void treeViewDeleted(QObject *)) 0248 Q_PRIVATE_SLOT(d, void slotColumnActivated(QAction *)) 0249 Q_PRIVATE_SLOT(d, void slotAllVisibleColumns()) 0250 0251 private Q_SLOTS: 0252 void rowsInserted(const QModelIndex &parent, int start, int end) const; 0253 }; 0254 0255 /** 0256 * Creates a widget featuring a KTreeViewSearchLine, a label with the text 0257 * "Search" and a button to clear the search. 0258 */ 0259 class KTreeViewSearchLineWidget : public QWidget 0260 { 0261 Q_OBJECT 0262 0263 public: 0264 /** 0265 * Creates a KTreeViewSearchLineWidget for \a treeView with \a parent as the 0266 * parent. 0267 */ 0268 explicit KTreeViewSearchLineWidget(QWidget *parent = nullptr, QTreeView *treeView = nullptr); 0269 0270 /** 0271 * Destroys the KTreeViewSearchLineWidget 0272 */ 0273 ~KTreeViewSearchLineWidget() override; 0274 0275 /** 0276 * Returns a pointer to the search line. 0277 */ 0278 KTreeViewSearchLine *searchLine() const; 0279 0280 protected Q_SLOTS: 0281 /** 0282 * Creates the widgets inside of the widget. This is called from the 0283 * constructor via a single shot timer so that it it guaranteed to run 0284 * after construction is complete. This makes it suitable for overriding in 0285 * subclasses. 0286 */ 0287 virtual void createWidgets(); 0288 0289 protected: 0290 /** 0291 * Creates the search line. This can be useful to reimplement in cases where 0292 * a KTreeViewSearchLine subclass is used. 0293 * 0294 * It is const because it is be called from searchLine(), which to the user 0295 * doesn't conceptually alter the widget. 0296 */ 0297 virtual KTreeViewSearchLine *createSearchLine(QTreeView *treeView) const; 0298 0299 private: 0300 KTreeViewSearchLineWidgetPrivate *const d; 0301 }; 0302 0303 #endif