1 /**************************************************************************
2 * Otter Browser: Web browser controlled by the user, not vice-versa.
3 * Copyright (C) 2013 - 2018 Michal Dutkiewicz aka Emdek <michal@emdek.pl>
4 * Copyright (C) 2015 - 2016 Jan Bajer aka bajasoft <jbajer@gmail.com>
5 * Copyright (C) 2015 Piotr Wójcik <chocimier@tlen.pl>
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 
22 #ifndef OTTER_ITEMVIEWWIDGET_H
23 #define OTTER_ITEMVIEWWIDGET_H
24 
25 #include <QtCore/QSortFilterProxyModel>
26 #include <QtGui/QContextMenuEvent>
27 #include <QtGui/QStandardItemModel>
28 #include <QtWidgets/QHeaderView>
29 #include <QtWidgets/QTreeView>
30 
31 namespace Otter
32 {
33 
34 class HeaderViewWidget final : public QHeaderView
35 {
36 	Q_OBJECT
37 
38 public:
39 	enum DataRole
40 	{
41 		WidthRole = Qt::UserRole,
42 		UserRole
43 	};
44 
45 	explicit HeaderViewWidget(Qt::Orientation orientation, QWidget *parent = nullptr);
46 
47 protected:
48 	enum SortOrder
49 	{
50 		NoOrder = -3,
51 		AscendingOrder = -2,
52 		DescendingOrder = -1
53 	};
54 
55 	void showEvent(QShowEvent *event) override;
56 	void contextMenuEvent(QContextMenuEvent *event) override;
57 	bool viewportEvent(QEvent *event) override;
58 
59 protected slots:
60 	void toggleColumnVisibility(QAction *action);
61 	void toggleSort(QAction *action);
62 	void handleSectionClicked(int column);
63 	void setSort(int column, Qt::SortOrder order);
64 
65 signals:
66 	void sortChanged(int column, Qt::SortOrder order);
67 	void columnVisibilityChanged(int column, bool hidden);
68 };
69 
70 class ItemViewWidget : public QTreeView
71 {
72 	Q_OBJECT
73 
74 public:
75 	enum ViewMode
76 	{
77 		ListView = 0,
78 		TreeView
79 	};
80 
81 	explicit ItemViewWidget(QWidget *parent = nullptr);
82 
83 	void setData(const QModelIndex &index, const QVariant &value, int role);
84 	void setModel(QAbstractItemModel *model) override;
85 	void setModel(QAbstractItemModel *model, bool useSortProxy);
86 	void setSortRoleMapping(const QMap<int, int> &mapping);
87 	void setViewMode(ViewMode mode);
88 	void setModified(bool isModified);
89 	QStandardItemModel* getSourceModel() const;
90 	QSortFilterProxyModel* getProxyModel() const;
91 	QStandardItem* getItem(const QModelIndex &index) const;
92 	QStandardItem* getItem(int row, int column = 0, const QModelIndex &parent = {}) const;
93 	QModelIndex getCheckedIndex(const QModelIndex &parent = {}) const;
94 	QModelIndex getCurrentIndex(int column = 0) const;
95 	QModelIndex getIndex(int row, int column = 0, const QModelIndex &parent = {}) const;
96 	QSize sizeHint() const override;
97 	ViewMode getViewMode() const;
98 	Qt::SortOrder getSortOrder() const;
99 	int getSortColumn() const;
100 	int getCurrentRow() const;
101 	int getRowCount(const QModelIndex &parent = {}) const;
102 	int getColumnCount(const QModelIndex &parent = {}) const;
103 	bool canMoveRowUp() const;
104 	bool canMoveRowDown() const;
105 	bool isExclusive() const;
106 	bool isModified() const;
107 
108 public slots:
109 	void insertRow(const QList<QStandardItem*> &items = {});
110 	void removeRow();
111 	void moveUpRow();
112 	void moveDownRow();
113 	void markAsModified();
114 	void setSort(int column, Qt::SortOrder order);
115 	void setColumnVisibility(int column, bool hide);
116 	void setExclusive(bool isExclusive);
117 	void setFilterString(const QString &filter);
118 	void setFilterRoles(const QSet<int> &roles);
119 
120 protected:
121 	void showEvent(QShowEvent *event) override;
122 	void resizeEvent(QResizeEvent *event) override;
123 	void keyPressEvent(QKeyEvent *event) override;
124 	void dropEvent(QDropEvent *event) override;
125 	void startDrag(Qt::DropActions supportedActions) override;
126 	void ensureInitialized();
127 	void moveRow(bool moveUp);
128 	void selectRow(const QModelIndex &index);
129 	bool applyFilter(const QModelIndex &index, bool parentHasMatch = false);
130 
131 protected slots:
132 	void currentChanged(const QModelIndex &current, const QModelIndex &previous) override;
133 	void saveState();
134 	void handleOptionChanged(int identifier, const QVariant &value);
135 	void notifySelectionChanged();
136 	void updateFilter();
137 	void updateSize();
138 
139 private:
140 	HeaderViewWidget *m_headerWidget;
141 	QStandardItemModel *m_sourceModel;
142 	QSortFilterProxyModel *m_proxyModel;
143 	QString m_filterString;
144 	QMap<int, int> m_sortRoleMapping;
145 	QSet<QModelIndex> m_expandedBranches;
146 	QSet<int> m_filterRoles;
147 	ViewMode m_viewMode;
148 	Qt::SortOrder m_sortOrder;
149 	int m_sortColumn;
150 	int m_dragRow;
151 	bool m_canGatherExpanded;
152 	bool m_isExclusive;
153 	bool m_isModified;
154 	bool m_isInitialized;
155 
156 signals:
157 	void canMoveRowUpChanged(bool isAllowed);
158 	void canMoveRowDownChanged(bool isAllowed);
159 	void needsActionsUpdate();
160 	void modified();
161 	void sortChanged(int column, Qt::SortOrder order);
162 };
163 
164 }
165 
166 #endif
167