1/****************************************************************************
2**
3** Copyright (C) 2018 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtSCriptTools module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qscriptdebuggerscriptsmodel_p.h"
41#include "qscriptscriptdata_p.h"
42
43#include "private/qabstractitemmodel_p.h"
44
45#include <QtCore/qfileinfo.h>
46#include <QtCore/qpair.h>
47#include <QtCore/qdebug.h>
48
49QT_BEGIN_NAMESPACE
50
51class QScriptDebuggerScriptsModelPrivate
52 : public QAbstractItemModelPrivate
53{
54 Q_DECLARE_PUBLIC(QScriptDebuggerScriptsModel)
55public:
56 struct Node {
57 Node(qint64 sid, const QScriptScriptData &dt)
58 : scriptId(sid), data(dt) {}
59
60 qint64 scriptId;
61 QScriptScriptData data;
62 QList<QPair<QString, int> > functionsInfo;
63 QSet<int> executableLineNumbers;
64 };
65
66 QScriptDebuggerScriptsModelPrivate();
67 ~QScriptDebuggerScriptsModelPrivate();
68
69 Node *findScriptNode(qint64 scriptId) const;
70
71 int nextNodeId;
72 QMap<int, Node*> nodes;
73};
74
75QScriptDebuggerScriptsModelPrivate::QScriptDebuggerScriptsModelPrivate()
76{
77 nextNodeId = 0;
78}
79
80QScriptDebuggerScriptsModelPrivate::~QScriptDebuggerScriptsModelPrivate()
81{
82 qDeleteAll(c: nodes);
83}
84
85QScriptDebuggerScriptsModelPrivate::Node *QScriptDebuggerScriptsModelPrivate::findScriptNode(qint64 scriptId) const
86{
87 QMap<int, Node*>::const_iterator it;
88 for (it = nodes.constBegin(); it != nodes.constEnd(); ++it) {
89 Node *n = it.value();
90 if (n->scriptId == scriptId)
91 return n;
92 }
93 return 0;
94}
95
96QScriptDebuggerScriptsModel::QScriptDebuggerScriptsModel(QObject *parent)
97 : QAbstractItemModel(*new QScriptDebuggerScriptsModelPrivate, parent)
98{
99}
100
101QScriptDebuggerScriptsModel::~QScriptDebuggerScriptsModel()
102{
103}
104
105void QScriptDebuggerScriptsModel::removeScript(qint64 id)
106{
107 Q_D(QScriptDebuggerScriptsModel);
108 QMap<int, QScriptDebuggerScriptsModelPrivate::Node*>::iterator it;
109 for (it = d->nodes.begin(); it != d->nodes.end(); ++it) {
110 QScriptDebuggerScriptsModelPrivate::Node *n = it.value();
111 if (n->scriptId == id) {
112 d->nodes.erase(it);
113 delete n;
114 break;
115 }
116 }
117}
118
119void QScriptDebuggerScriptsModel::addScript(qint64 sid, const QScriptScriptData &data)
120{
121 Q_D(QScriptDebuggerScriptsModel);
122 int id = d->nextNodeId;
123 ++d->nextNodeId;
124 d->nodes.insert(akey: id, avalue: new QScriptDebuggerScriptsModelPrivate::Node(sid, data));
125}
126
127void QScriptDebuggerScriptsModel::addExtraScriptInfo(
128 qint64 sid, const QMap<QString, int> &functionsInfo,
129 const QSet<int> &executableLineNumbers)
130{
131 Q_D(QScriptDebuggerScriptsModel);
132 QScriptDebuggerScriptsModelPrivate::Node *node = d->findScriptNode(scriptId: sid);
133 if (!node)
134 return;
135 QList<QPair<QString, int> > lst;
136 QMap<QString, int>::const_iterator it;
137 for (it = functionsInfo.constBegin(); it != functionsInfo.constEnd(); ++it)
138 lst.append(t: qMakePair(x: it.key(), y: it.value()));
139 node->functionsInfo = lst;
140 node->executableLineNumbers = executableLineNumbers;
141}
142
143void QScriptDebuggerScriptsModel::commit()
144{
145 layoutAboutToBeChanged();
146 layoutChanged();
147}
148
149QScriptScriptData QScriptDebuggerScriptsModel::scriptData(qint64 sid) const
150{
151 Q_D(const QScriptDebuggerScriptsModel);
152 QScriptDebuggerScriptsModelPrivate::Node *node = d->findScriptNode(scriptId: sid);
153 if (!node)
154 return QScriptScriptData();
155 return node->data;
156}
157
158QScriptScriptMap QScriptDebuggerScriptsModel::scripts() const
159{
160 Q_D(const QScriptDebuggerScriptsModel);
161 QScriptScriptMap result;
162 QMap<int, QScriptDebuggerScriptsModelPrivate::Node*>::const_iterator it;
163 for (it = d->nodes.constBegin(); it != d->nodes.constEnd(); ++it) {
164 QScriptDebuggerScriptsModelPrivate::Node *n = it.value();
165 result.insert(akey: n->scriptId, avalue: n->data);
166 }
167 return result;
168}
169
170qint64 QScriptDebuggerScriptsModel::resolveScript(const QString &fileName) const
171{
172 Q_D(const QScriptDebuggerScriptsModel);
173 QMap<int, QScriptDebuggerScriptsModelPrivate::Node*>::const_iterator it;
174 for (it = d->nodes.constBegin(); it != d->nodes.constEnd(); ++it) {
175 QScriptDebuggerScriptsModelPrivate::Node *n = it.value();
176 if (n->data.fileName() == fileName)
177 return n->scriptId;
178 }
179 return -1;
180}
181
182QSet<int> QScriptDebuggerScriptsModel::executableLineNumbers(qint64 scriptId) const
183{
184 Q_D(const QScriptDebuggerScriptsModel);
185 QScriptDebuggerScriptsModelPrivate::Node *node = d->findScriptNode(scriptId);
186 if (!node)
187 return QSet<int>();
188 return node->executableLineNumbers;
189}
190
191QModelIndex QScriptDebuggerScriptsModel::indexFromScriptId(qint64 sid) const
192{
193 Q_D(const QScriptDebuggerScriptsModel);
194 int row = 0;
195 QMap<int, QScriptDebuggerScriptsModelPrivate::Node*>::const_iterator it;
196 for (it = d->nodes.constBegin(); it != d->nodes.constEnd(); ++it, ++row) {
197 QScriptDebuggerScriptsModelPrivate::Node *n = it.value();
198 if (n->scriptId == sid)
199 return createIndex(arow: row, acolumn: 0, aid: it.key() << 12);
200 }
201 return QModelIndex();
202}
203
204qint64 QScriptDebuggerScriptsModel::scriptIdFromIndex(const QModelIndex &index) const
205{
206 Q_D(const QScriptDebuggerScriptsModel);
207 if (!index.isValid())
208 return -1;
209 int id = index.internalId();
210 if (id & 1)
211 return -1;
212 QScriptDebuggerScriptsModelPrivate::Node *n = d->nodes.value(akey: id >> 12);
213 if (!n)
214 return -1;
215 return n->scriptId;
216}
217
218QPair<QString, int> QScriptDebuggerScriptsModel::scriptFunctionInfoFromIndex(const QModelIndex &index) const
219{
220 Q_D(const QScriptDebuggerScriptsModel);
221 QPair<QString, int> result;
222 if (!index.isValid())
223 return result;
224 int id = index.internalId();
225 if (!(id & 1))
226 return result;
227 QScriptDebuggerScriptsModelPrivate::Node *node = d->nodes.value(akey: id >> 12);
228 if (!node)
229 return result;
230 int functionIndex = (id >> 1) & ((1 << 11) - 1);
231 result = node->functionsInfo.at(i: functionIndex);
232 return result;
233}
234
235/*!
236 \reimp
237*/
238QModelIndex QScriptDebuggerScriptsModel::index(int row, int column, const QModelIndex &parent) const
239{
240 Q_D(const QScriptDebuggerScriptsModel);
241 if (!parent.isValid()) {
242 if ((row < 0) || (row >= d->nodes.size()))
243 return QModelIndex();
244 if (column != 0)
245 return QModelIndex();
246 return createIndex(arow: row, acolumn: column, aid: d->nodes.keys().at(i: row) << 12);
247 }
248 int id = parent.internalId();
249 if (id & 1)
250 return QModelIndex();
251 return createIndex(arow: row, acolumn: column, aid: id | (row << 1) | 1);
252}
253
254/*!
255 \reimp
256*/
257QModelIndex QScriptDebuggerScriptsModel::parent(const QModelIndex &index) const
258{
259 Q_D(const QScriptDebuggerScriptsModel);
260 if (!index.isValid())
261 return QModelIndex();
262 int id = index.internalId();
263 if (!(id & 1))
264 return QModelIndex();
265 QScriptDebuggerScriptsModelPrivate::Node *n = d->nodes.value(akey: id >> 12);
266 if (!n)
267 return QModelIndex();
268 return indexFromScriptId(sid: n->scriptId);
269}
270
271/*!
272 \reimp
273*/
274int QScriptDebuggerScriptsModel::columnCount(const QModelIndex &) const
275{
276 return 1;
277}
278
279/*!
280 \reimp
281*/
282int QScriptDebuggerScriptsModel::rowCount(const QModelIndex &parent) const
283{
284 Q_D(const QScriptDebuggerScriptsModel);
285 if (!parent.isValid())
286 return d->nodes.size();
287 int id = parent.internalId();
288 if (id & 1)
289 return 0;
290 QScriptDebuggerScriptsModelPrivate::Node *n = d->nodes.value(akey: id >> 12);
291 if (!n)
292 return 0;
293 return n->functionsInfo.size();
294}
295
296/*!
297 \reimp
298*/
299QVariant QScriptDebuggerScriptsModel::data(const QModelIndex &index, int role) const
300{
301 Q_D(const QScriptDebuggerScriptsModel);
302 if (!index.isValid())
303 return QVariant();
304 int id = index.internalId();
305 QScriptDebuggerScriptsModelPrivate::Node *node = d->nodes.value(akey: id >> 12);
306 if (!node)
307 return QVariant();
308 if (!(id & 1)) {
309 if (role == Qt::DisplayRole) {
310 QString fn = node->data.fileName();
311 if (fn.isEmpty())
312 fn = QString::fromLatin1(str: "<anonymous script, id=%0>").arg(a: node->scriptId);
313 return fn;
314 } else if (role == Qt::ToolTipRole) {
315 QString fn = node->data.fileName();
316 if (QFileInfo(fn).fileName() != fn)
317 return fn;
318 } else if (role == Qt::UserRole) {
319 return node->scriptId;
320 } else if (role == Qt::UserRole+1) {
321 return node->data.baseLineNumber();
322 } else if (role == Qt::UserRole+2) {
323 return node->data.contents();
324 }
325 } else {
326 int functionIndex = (id >> 1) & ((1 << 11) - 1);
327 if (role == Qt::DisplayRole)
328 return node->functionsInfo[functionIndex].first;
329 }
330 return QVariant();
331}
332
333QT_END_NAMESPACE
334

source code of qtscript/src/scripttools/debugging/qscriptdebuggerscriptsmodel.cpp