1 /* SearchableView.h */
2 
3 /* Copyright (C) 2011-2020 Michael Lugmair (Lucio Carreras)
4  *
5  * This file is part of sayonara player
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11 
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16 
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #ifndef SEARCHABLEVIEW_H
22 #define SEARCHABLEVIEW_H
23 
24 #include "Gui/Utils/Widgets/WidgetTemplate.h"
25 #include "Gui/Utils/SearchableWidget/SelectionView.h"
26 #include "Gui/Utils/SearchableWidget/SearchableModel.h"
27 #include "Utils/Pimpl.h"
28 
29 #include <QKeyEvent>
30 #include <QTableView>
31 #include <QListView>
32 #include <QTreeView>
33 
34 class QAbstractItemView;
35 class QItemSelectionModel;
36 class ExtraTriggerMap;
37 class SearchableViewInterface;
38 
39 /**
40  * @brief The MiniSearcherViewConnector class
41  * @ingrou Searchable
42  */
43 class MiniSearcherViewConnector : public QObject
44 {
45 	Q_OBJECT
46 	PIMPL(MiniSearcherViewConnector)
47 
48 	public:
49 		MiniSearcherViewConnector(SearchableViewInterface* parent);
50 		~MiniSearcherViewConnector();
51 
52 		void init();
53 		bool isActive() const;
54 		void setExtraTriggers(const QMap<QChar, QString>& map);
55 		bool handleKeyPress(QKeyEvent* e);
56 
57 	private slots:
58 		void lineEditChanged(const QString& str);
59 		void selectNext();
60 		void selectPrevious();
61 };
62 
63 
64 /**
65  * @brief The SearchViewInterface class
66  * @ingroup Searchable
67  */
68 class SearchableViewInterface :
69 		public SelectionViewInterface
70 {
71 	PIMPL(SearchableViewInterface)
72 
73 protected:
74 	enum class SearchDirection : unsigned char
75 	{
76 		First,
77 		Next,
78 		Prev
79 	};
80 
81 	public:
82 		explicit SearchableViewInterface(QAbstractItemView* view);
83 		virtual ~SearchableViewInterface() override;
84 
85 		QAbstractItemView* view() const;
86 		virtual int	viewportHeight() const;
87 		virtual int	viewportWidth() const;
88 
89 		int setSearchstring(const QString& str);
90 		void selectNextMatch(const QString& str);
91 		void selectPreviousMatch(const QString& str);
92 		bool isMinisearcherActive() const;
93 
94 	protected:
95 		virtual void setSearchModel(SearchableModelInterface* model);
96 		virtual QModelIndex matchIndex(const QString& str, SearchDirection direction) const;
97 		virtual void selectMatch(const QString& str, SearchDirection direction);
98 		bool handleKeyPress(QKeyEvent* e) override;
99 };
100 
101 
102 template<typename View, typename Model>
103 class SearchableView :
104 		public View,
105 		public SearchableViewInterface
106 {
107 	private:
108 		using View::setModel;
109 		using SearchableViewInterface::setSearchModel;
110 
111 	public:
112 		SearchableView(QWidget* parent=nullptr) :
View(parent)113 			View(parent),
114 			SearchableViewInterface(this)
115 		{}
116 
117 		virtual ~SearchableView() = default;
118 
setSearchableModel(Model * model)119 		virtual void setSearchableModel(Model* model)
120 		{
121 			View::setModel(model);
122 			SearchableViewInterface::setSearchModel(model);
123 		}
124 
rowCount()125 		int rowCount() const
126 		{
127 			return (View::model() == nullptr) ? 0 : View::model()->rowCount();
128 		}
129 
130 	protected:
keyPressEvent(QKeyEvent * e)131 		void keyPressEvent(QKeyEvent* e) override
132 		{
133 			bool processed = handleKeyPress(e);
134 			if(processed){
135 				return;
136 			}
137 
138 			View::keyPressEvent(e);
139 		}
140 };
141 
142 using SearchableTableView=Gui::WidgetTemplate<SearchableView<QTableView, SearchableTableModel>>;
143 using SearchableListView=Gui::WidgetTemplate<SearchableView<QListView, SearchableListModel>>;
144 
145 
146 #endif // SEARCHABLEVIEW_H
147