labplot  2.8.2
About: LabPlot is an application for plotting and analysis of 2D and 3D functions and data. It is a complete rewrite of LabPlot1 and lacks in the first release a lot of features available in the predecessor. On the other hand, the GUI and the usability is more superior.
  Fossies Dox: labplot-2.8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

TreeModel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 File : TreeModel.cpp
3 Project : LabPlot
4 Description : This is an abstract treemodel which can be used by a treeview
5 --------------------------------------------------------------------
6 Copyright : (C) 2019 Martin Marmsoler (martin.marmsoler@gmail.com)
7 
8 ***************************************************************************/
9 
10 /***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 * This program is distributed in the hope that it will be useful, *
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20 * GNU General Public License for more details. *
21 * *
22 * You should have received a copy of the GNU General Public License *
23 * along with this program; if not, write to the Free Software *
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
25 * Boston, MA 02110-1301 USA *
26 * *
27 ***************************************************************************/
28 
29 #include "TreeModel.h"
30 
31 //##########################################################
32 // TreeItem ###############################################
33 //##########################################################
34 
36  itemData(data),
37  parentItem(parent) {
38 }
39 
41  qDeleteAll(childItems);
42 }
43 
44 TreeItem *TreeItem::child(int number) {
45  return childItems.value(number);
46 }
47 
48 int TreeItem::childCount() const {
49  return childItems.count();
50 }
51 
52 int TreeItem::childNumber() const {
53  if (parentItem)
54  return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
55 
56  return 0;
57 }
58 
59 int TreeItem::columnCount() const {
60  return itemData.count();
61 }
62 
63 QVariant TreeItem::data(int column) const {
64  return itemData.value(column);
65 }
66 
67 QVariant TreeItem::backgroundColor() const {
68  return m_backgroundColor;
69 }
70 
71 bool TreeItem::insertChildren(int position, int count, int columns) {
72  if (position < 0 || position > childItems.size())
73  return false;
74 
75  for (int row = 0; row < count; ++row) {
76  QVector<QVariant> data(columns);
77  TreeItem *item = new TreeItem(data, this);
78  childItems.insert(position, item);
79  }
80 
81  return true;
82 }
83 
84 bool TreeItem::insertColumns(int position, int columns) {
85  if (position < 0 || position > itemData.size())
86  return false;
87 
88  for (int column = 0; column < columns; ++column)
89  itemData.insert(position, QVariant());
90 
91  foreach (TreeItem *child, childItems)
92  child->insertColumns(position, columns);
93 
94  return true;
95 }
96 
98  return parentItem;
99 }
100 
101 bool TreeItem::removeChildren(int position, int count) {
102  if (position < 0 || position + count > childItems.size())
103  return false;
104 
105  for (int row = 0; row < count; ++row)
106  delete childItems.takeAt(position);
107 
108  return true;
109 }
110 
111 bool TreeItem::removeColumns(int position, int columns) {
112  if (position < 0 || position + columns > itemData.size())
113  return false;
114 
115  for (int column = 0; column < columns; ++column)
116  itemData.remove(position);
117 
118  foreach (TreeItem *child, childItems)
119  child->removeColumns(position, columns);
120 
121  return true;
122 }
123 
124 bool TreeItem::setData(int column, const QVariant& value) {
125  if (column < 0 || column >= itemData.size())
126  return false;
127 
128  itemData[column] = value;
129  return true;
130 }
131 
132 bool TreeItem::setBackgroundColor(int column, const QVariant& value) {
133  if (column < 0 || column >= itemData.size())
134  return false;
135 
136  m_backgroundColor = value.value<QColor>();
137  return true;
138 }
139 
140 //##########################################################
141 // TreeModel ###############################################
142 //##########################################################
143 
144 TreeModel::TreeModel(const QStringList& headers, QObject* parent)
145  : QAbstractItemModel(parent) {
146  QVector<QVariant> rootData;
147  for (auto header : headers)
148  rootData << header;
149 
150  rootItem = new TreeItem(rootData);
151 }
152 
154  delete rootItem;
155 }
156 
157 int TreeModel::columnCount(const QModelIndex& /* parent */) const {
158  return rootItem->columnCount();
159 }
160 
161 QVariant TreeModel::treeData(const int row, const int column, const QModelIndex& parent, const int role) {
162  QModelIndex currentIndex = index(row, column, parent);
163  return data(currentIndex, role);
164 }
165 
166 QVariant TreeModel::data(const QModelIndex& index, int role) const {
167  if (!index.isValid())
168  return QVariant();
169 
170  if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::BackgroundRole)
171  return QVariant();
172 
173  TreeItem *item = getItem(index);
174 
175  if (role != Qt::BackgroundRole)
176  return item->data(index.column());
177 
178  return item->backgroundColor();
179 }
180 
181 Qt::ItemFlags TreeModel::flags(const QModelIndex& index) const {
182  if (!index.isValid())
183  return Qt::NoItemFlags;
184 
185  return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
186 }
187 
188 TreeItem *TreeModel::getItem(const QModelIndex& index) const {
189  if (index.isValid()) {
190  TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
191  if (item)
192  return item;
193  }
194  return rootItem;
195 }
196 
197 QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const {
198  if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
199  return rootItem->data(section);
200 
201  return QVariant();
202 }
203 
204 QModelIndex TreeModel::index(int row, int column, const QModelIndex& parent) const {
205  if (parent.isValid() && parent.column() != 0)
206  return QModelIndex();
207 
208  TreeItem *parentItem = getItem(parent);
209 
210  TreeItem *childItem = parentItem->child(row);
211  if (childItem)
212  return createIndex(row, column, childItem);
213  else
214  return QModelIndex();
215 }
216 
217 bool TreeModel::insertColumns(int position, int columns, const QModelIndex& parent) {
218  bool success;
219 
220  beginInsertColumns(parent, position, position + columns - 1);
221  success = rootItem->insertColumns(position, columns);
222  endInsertColumns();
223 
224  return success;
225 }
226 
227 bool TreeModel::insertRows(int position, int rows, const QModelIndex& parent) {
228  TreeItem *parentItem = getItem(parent);
229  bool success;
230 
231  beginInsertRows(parent, position, position + rows - 1);
232  success = parentItem->insertChildren(position, rows, rootItem->columnCount());
233  endInsertRows();
234 
235  return success;
236 }
237 
238 QModelIndex TreeModel::parent(const QModelIndex &index) const {
239  if (!index.isValid())
240  return {};
241 
242  TreeItem *childItem = getItem(index);
243  TreeItem *parentItem = childItem->parent();
244 
245  if (parentItem == rootItem)
246  return {};
247 
248  return createIndex(parentItem->childNumber(), 0, parentItem);
249 }
250 
251 bool TreeModel::removeColumns(int position, int columns, const QModelIndex& parent) {
252  bool success;
253 
254  beginRemoveColumns(parent, position, position + columns - 1);
255  success = rootItem->removeColumns(position, columns);
256  endRemoveColumns();
257 
258  if (rootItem->columnCount() == 0)
259  removeRows(0, rowCount());
260 
261  return success;
262 }
263 
264 bool TreeModel::removeRows(int position, int rows, const QModelIndex& parent) {
265  TreeItem *parentItem = getItem(parent);
266 
267  beginRemoveRows(parent, position, position + rows - 1);
268  bool success = parentItem->removeChildren(position, rows);
269  endRemoveRows();
270 
271  return success;
272 }
273 
274 int TreeModel::rowCount(const QModelIndex &parent) const {
275  TreeItem *parentItem = getItem(parent);
276 
277  return parentItem->childCount();
278 }
279 
280 bool TreeModel::setTreeData(const QVariant& data, const int row, const int column, const QModelIndex& parent, int role) {
281  QModelIndex curveIndex = index(row, column, parent);
282  return setData(curveIndex, data, role);
283 }
284 
285 bool TreeModel::setData(const QModelIndex& index, const QVariant& value, int role) {
286 
287  if (role == Qt::EditRole || role == Qt::DisplayRole) {
288  TreeItem *item = getItem(index);
289  bool result = item->setData(index.column(), value);
290 
291  if (result)
292  emit dataChanged(index, index);
293 
294  return result;
295  } else if (role == Qt::BackgroundRole) {
296  TreeItem *item = getItem(index);
297  bool result = item->setBackgroundColor(index.column(), value);
298 
299  if (result)
300  emit dataChanged(index, index);
301  }
302 
303  return false;
304 }
305 
306 bool TreeModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role) {
307  if (role != Qt::EditRole && role != Qt::DisplayRole && orientation != Qt::Horizontal)
308  return false;
309 
310  bool result = rootItem->setData(section, value);
311 
312  if (result)
313  emit headerDataChanged(orientation, section, section);
314 
315  return result;
316 }
317 
318 int TreeModel::compareStrings(const QString& value, const int row, const int column, const QModelIndex& parent) {
319  QModelIndex plotIndex = index(row, column, parent);
320  return plotIndex.data().toString().compare(value);
321 }
The TreeItem class Item in the treemodel.
Definition: TreeModel.h:39
int childCount() const
Definition: TreeModel.cpp:48
TreeItem(const QVector< QVariant > &data, TreeItem *parent=0)
Definition: TreeModel.cpp:35
TreeItem * parentItem
Definition: TreeModel.h:62
int columnCount() const
Definition: TreeModel.cpp:59
TreeItem * parent()
Definition: TreeModel.cpp:97
QVariant backgroundColor() const
Definition: TreeModel.cpp:67
bool removeColumns(int position, int columns)
Definition: TreeModel.cpp:111
QList< TreeItem * > childItems
Definition: TreeModel.h:59
int childNumber() const
Definition: TreeModel.cpp:52
TreeItem * child(int number)
Definition: TreeModel.cpp:44
bool removeChildren(int position, int count)
Definition: TreeModel.cpp:101
bool insertColumns(int position, int columns)
Definition: TreeModel.cpp:84
bool setData(int column, const QVariant &value)
Definition: TreeModel.cpp:124
bool insertChildren(int position, int count, int columns)
Definition: TreeModel.cpp:71
QVariant data(int column) const
Definition: TreeModel.cpp:63
QColor m_backgroundColor
Definition: TreeModel.h:61
QVector< QVariant > itemData
Definition: TreeModel.h:60
bool setBackgroundColor(int column, const QVariant &value)
Definition: TreeModel.cpp:132
bool insertColumns(int position, int columns, const QModelIndex &parent=QModelIndex()) override
Definition: TreeModel.cpp:217
QModelIndex parent(const QModelIndex &) const override
Definition: TreeModel.cpp:238
bool setTreeData(const QVariant &data, const int row, const int column, const QModelIndex &parent=QModelIndex(), int role=Qt::EditRole)
Definition: TreeModel.cpp:280
bool removeRows(int position, int rows, const QModelIndex &parent=QModelIndex()) override
Definition: TreeModel.cpp:264
bool setData(const QModelIndex &, const QVariant &value, int role=Qt::EditRole) override
Definition: TreeModel.cpp:285
TreeItem * getItem(const QModelIndex &) const
Definition: TreeModel.cpp:188
TreeModel(const QStringList &headers, QObject *parent=nullptr)
Definition: TreeModel.cpp:144
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: TreeModel.cpp:274
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: TreeModel.cpp:204
TreeItem * rootItem
Definition: TreeModel.h:106
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role=Qt::EditRole) override
Definition: TreeModel.cpp:306
bool insertRows(int position, int rows, const QModelIndex &parent=QModelIndex()) override
Definition: TreeModel.cpp:227
QVariant treeData(const int row, const int column, const QModelIndex &parent=QModelIndex(), const int role=Qt::EditRole)
Definition: TreeModel.cpp:161
QVariant data(const QModelIndex &, int role) const override
Definition: TreeModel.cpp:166
Qt::ItemFlags flags(const QModelIndex &) const override
Definition: TreeModel.cpp:181
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Definition: TreeModel.cpp:157
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Definition: TreeModel.cpp:197
bool removeColumns(int position, int columns, const QModelIndex &parent=QModelIndex()) override
Definition: TreeModel.cpp:251
int compareStrings(const QString &value, const int row, const int column, const QModelIndex &parent=QModelIndex())
Definition: TreeModel.cpp:318