Falkon Develop
Cross-platform Qt-based web browser
tabmrumodel.cpp
Go to the documentation of this file.
1/* ============================================================
2* Falkon - Qt web browser
3* Copyright (C) 2018 David Rosca <nowrep@gmail.com>
4*
5* This program is free software: you can redistribute it and/or modify
6* it under the terms of the GNU General Public License as published by
7* the Free Software Foundation, either version 3 of the License, or
8* (at your option) any later version.
9*
10* This program is distributed in the hope that it will be useful,
11* but WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17* ============================================================ */
18#include "tabmrumodel.h"
19#include "tabmodel.h"
20#include "webtab.h"
21#include "tabwidget.h"
22#include "browserwindow.h"
23
25{
26public:
27 explicit TabMruModelItem(WebTab *tab = nullptr, const QModelIndex &index = QModelIndex());
29
30 WebTab *tab = nullptr;
31 QVector<TabMruModelItem*> children;
32 QPersistentModelIndex sourceIndex;
33};
34
35TabMruModelItem::TabMruModelItem(WebTab *tab, const QModelIndex &index)
36 : tab(tab)
37 , sourceIndex(index)
38{
39}
40
42{
43 qDeleteAll(children);
44}
45
46TabMruModel::TabMruModel(BrowserWindow *window, QObject *parent)
47 : QAbstractProxyModel(parent)
48 , m_window(window)
49{
50 connect(this, &QAbstractProxyModel::sourceModelChanged, this, &TabMruModel::init);
51}
52
54{
55 delete m_root;
56}
57
58QModelIndex TabMruModel::tabIndex(WebTab *tab) const
59{
60 TabMruModelItem *item = m_items.value(tab);
61 return item ? createIndex(m_root->children.indexOf(item), 0, item) : QModelIndex();
62}
63
64WebTab *TabMruModel::tab(const QModelIndex &index) const
65{
66 TabMruModelItem *it = item(index);
67 return it ? it->tab : nullptr;
68}
69
70Qt::ItemFlags TabMruModel::flags(const QModelIndex &index) const
71{
72 if (!index.isValid()) {
73 return Qt::NoItemFlags;
74 }
75 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
76}
77
78int TabMruModel::rowCount(const QModelIndex &parent) const
79{
80 if (parent.isValid()) {
81 return 0;
82 }
83 return m_items.count();
84}
85
86int TabMruModel::columnCount(const QModelIndex &parent) const
87{
88 if (parent.column() > 0) {
89 return 0;
90 }
91 return 1;
92}
93
94QModelIndex TabMruModel::parent(const QModelIndex &index) const
95{
96 Q_UNUSED(index)
97 return {};
98}
99
100QModelIndex TabMruModel::index(int row, int column, const QModelIndex &parent) const
101{
102 if (!hasIndex(row, column, parent)) {
103 return {};
104 }
105 return createIndex(row, column, m_root->children.at(row));
106}
107
108QModelIndex TabMruModel::mapFromSource(const QModelIndex &sourceIndex) const
109{
110 return tabIndex(sourceIndex.data(TabModel::WebTabRole).value<WebTab*>());
111}
112
113QModelIndex TabMruModel::mapToSource(const QModelIndex &proxyIndex) const
114{
115 TabMruModelItem *it = item(proxyIndex);
116 if (!it) {
117 return {};
118 }
119 return it->sourceIndex;
120}
121
122void TabMruModel::init()
123{
124 delete m_root;
125 m_items.clear();
126
127 m_root = new TabMruModelItem;
128 sourceRowsInserted(QModelIndex(), 0, sourceModel()->rowCount());
129 currentTabChanged(m_window->tabWidget()->currentIndex());
130
131 connect(m_window->tabWidget(), &TabWidget::currentChanged, this, &TabMruModel::currentTabChanged, Qt::UniqueConnection);
132 connect(sourceModel(), &QAbstractItemModel::dataChanged, this, &TabMruModel::sourceDataChanged, Qt::UniqueConnection);
133 connect(sourceModel(), &QAbstractItemModel::rowsInserted, this, &TabMruModel::sourceRowsInserted, Qt::UniqueConnection);
134 connect(sourceModel(), &QAbstractItemModel::rowsAboutToBeRemoved, this, &TabMruModel::sourceRowsAboutToBeRemoved, Qt::UniqueConnection);
135 connect(sourceModel(), &QAbstractItemModel::modelReset, this, &TabMruModel::sourceReset, Qt::UniqueConnection);
136}
137
138QModelIndex TabMruModel::index(TabMruModelItem *item) const
139{
140 if (!item || item == m_root) {
141 return {};
142 }
143 return createIndex(m_root->children.indexOf(item), 0, item);
144}
145
146TabMruModelItem *TabMruModel::item(const QModelIndex &index) const
147{
148 return static_cast<TabMruModelItem*>(index.internalPointer());
149}
150
151void TabMruModel::currentTabChanged(int index)
152{
153 TabMruModelItem *it = item(mapFromSource(sourceModel()->index(index, 0)));
154 if (!it) {
155 return;
156 }
157 const int from = m_root->children.indexOf(it);
158 if (from == 0) {
159 return;
160 }
161 if (!beginMoveRows(QModelIndex(), from, from, QModelIndex(), 0)) {
162 qWarning() << "Invalid beginMoveRows" << from;
163 return;
164 }
165 m_root->children.removeAt(from);
166 m_root->children.insert(0, it);
167 endMoveRows();
168}
169
170void TabMruModel::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
171{
172 Q_EMIT dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight), roles);
173}
174
175void TabMruModel::sourceRowsInserted(const QModelIndex &parent, int start, int end)
176{
177 for (int i = start; i <= end; ++i) {
178 const QModelIndex index = sourceModel()->index(i, 0, parent);
179 auto *tab = index.data(TabModel::WebTabRole).value<WebTab*>();
180 if (tab) {
181 beginInsertRows(QModelIndex(), m_items.count(), m_items.count());
182 auto *item = new TabMruModelItem(tab, index);
183 m_items[tab] = item;
184 m_root->children.append(item);
185 endInsertRows();
186 }
187 }
188}
189
190void TabMruModel::sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
191{
192 for (int i = start; i <= end; ++i) {
193 const QModelIndex index = sourceModel()->index(i, 0, parent);
195 if (it) {
196 const int idx = m_root->children.indexOf(it);
197 beginRemoveRows(QModelIndex(), idx, idx);
198 m_items.remove(it->tab);
199 m_root->children.removeAt(idx);
200 delete it;
201 endRemoveRows();
202 }
203 }
204}
205
206void TabMruModel::sourceReset()
207{
208 beginResetModel();
209 init();
210 endResetModel();
211}
TabWidget * tabWidget() const
@ WebTabRole
Definition: tabmodel.h:54
~TabMruModel() override
Definition: tabmrumodel.cpp:53
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
TabMruModel(BrowserWindow *window, QObject *parent=nullptr)
Definition: tabmrumodel.cpp:46
QModelIndex tabIndex(WebTab *tab) const
Definition: tabmrumodel.cpp:58
int rowCount(const QModelIndex &parent) const override
Definition: tabmrumodel.cpp:78
WebTab * tab(const QModelIndex &index) const
Definition: tabmrumodel.cpp:64
Qt::ItemFlags flags(const QModelIndex &index) const override
Definition: tabmrumodel.cpp:70
int columnCount(const QModelIndex &parent) const override
Definition: tabmrumodel.cpp:86
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
QModelIndex parent(const QModelIndex &index) const override
Definition: tabmrumodel.cpp:94
TabMruModelItem(WebTab *tab=nullptr, const QModelIndex &index=QModelIndex())
Definition: tabmrumodel.cpp:35
QPersistentModelIndex sourceIndex
Definition: tabmrumodel.cpp:32
QVector< TabMruModelItem * > children
Definition: tabmrumodel.cpp:31
int currentIndex() const
void currentChanged(int index)
Definition: webtab.h:40
i
Definition: i18n.py:23