1 /*
2     SPDX-FileCopyrightText: 2009 Stephen Kelly <steveire@gmail.com>
3     SPDX-FileCopyrightText: 2009 Nokia Corporation and /or its subsidiary(-ies) <qt-info@nokia.com>
4 
5     This file is part of the test suite of the Qt Toolkit.
6 
7     SPDX-License-Identifier: LGPL-2.1-only WITH Qt-LGPL-exception-1.1
8 */
9 
10 #ifndef DYNAMICTREEMODEL_H
11 #define DYNAMICTREEMODEL_H
12 
13 #include <QAbstractItemModel>
14 
15 #include <QHash>
16 #include <QList>
17 
18 class DynamicTreeModel : public QAbstractItemModel
19 {
20     Q_OBJECT
21 
22 public:
23     DynamicTreeModel(QObject *parent = nullptr);
24 
25     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
26     QModelIndex parent(const QModelIndex &index) const;
27     int rowCount(const QModelIndex &index = QModelIndex()) const;
28     int columnCount(const QModelIndex &index = QModelIndex()) const;
29 
30     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
31 
32     void clear();
33 
34 protected Q_SLOTS:
35 
36     /**
37     Finds the parent id of the string with id @p searchId.
38 
39     Returns -1 if not found.
40     */
41     qint64 findParentId(qint64 searchId) const;
42 
43 private:
44     QHash<qint64, QString> m_items;
45     QHash<qint64, QList<QList<qint64>>> m_childItems;
46     qint64 nextId;
newId()47     qint64 newId()
48     {
49         return nextId++;
50     };
51 
52     QModelIndex m_nextParentIndex;
53     int m_nextRow;
54 
55     int m_depth;
56     int maxDepth;
57 
58     friend class ModelInsertCommand;
59     friend class ModelMoveCommand;
60     friend class ModelResetCommand;
61     friend class ModelResetCommandFixed;
62 };
63 
64 class ModelChangeCommand : public QObject
65 {
66     Q_OBJECT
67 public:
68     explicit ModelChangeCommand(DynamicTreeModel *model, QObject *parent = nullptr);
69 
~ModelChangeCommand()70     virtual ~ModelChangeCommand()
71     {
72     }
73 
setAncestorRowNumbers(QList<int> rowNumbers)74     void setAncestorRowNumbers(QList<int> rowNumbers)
75     {
76         m_rowNumbers = rowNumbers;
77     }
78 
79     QModelIndex findIndex(QList<int> rows);
80 
setStartRow(int row)81     void setStartRow(int row)
82     {
83         m_startRow = row;
84     }
85 
setEndRow(int row)86     void setEndRow(int row)
87     {
88         m_endRow = row;
89     }
90 
setNumCols(int cols)91     void setNumCols(int cols)
92     {
93         m_numCols = cols;
94     }
95 
96     virtual void doCommand() = 0;
97 
98 protected:
99     DynamicTreeModel *m_model;
100     QList<int> m_rowNumbers;
101     int m_numCols;
102     int m_startRow;
103     int m_endRow;
104 };
105 
106 typedef QList<ModelChangeCommand *> ModelChangeCommandList;
107 
108 class ModelInsertCommand : public ModelChangeCommand
109 {
110     Q_OBJECT
111 
112 public:
113     explicit ModelInsertCommand(DynamicTreeModel *model, QObject *parent = nullptr);
~ModelInsertCommand()114     virtual ~ModelInsertCommand()
115     {
116     }
117 
118     virtual void doCommand();
119 };
120 
121 class ModelMoveCommand : public ModelChangeCommand
122 {
123     Q_OBJECT
124 public:
125     ModelMoveCommand(DynamicTreeModel *model, QObject *parent);
126 
~ModelMoveCommand()127     virtual ~ModelMoveCommand()
128     {
129     }
130 
131     virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow);
132 
133     virtual void doCommand();
134 
135     virtual void emitPostSignal();
136 
setDestAncestors(QList<int> rows)137     void setDestAncestors(QList<int> rows)
138     {
139         m_destRowNumbers = rows;
140     }
141 
setDestRow(int row)142     void setDestRow(int row)
143     {
144         m_destRow = row;
145     }
146 
147 protected:
148     QList<int> m_destRowNumbers;
149     int m_destRow;
150 };
151 
152 /**
153   A command which does a move and emits a reset signal.
154 */
155 class ModelResetCommand : public ModelMoveCommand
156 {
157     Q_OBJECT
158 public:
159     explicit ModelResetCommand(DynamicTreeModel *model, QObject *parent = nullptr);
160 
161     virtual ~ModelResetCommand();
162 
163     virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow);
164     virtual void emitPostSignal();
165 };
166 
167 /**
168   A command which does a move and emits a beginResetModel and endResetModel signals.
169 */
170 class ModelResetCommandFixed : public ModelMoveCommand
171 {
172     Q_OBJECT
173 public:
174     explicit ModelResetCommandFixed(DynamicTreeModel *model, QObject *parent = nullptr);
175 
176     virtual ~ModelResetCommandFixed();
177 
178     virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow);
179     virtual void emitPostSignal();
180 };
181 
182 #endif
183