source: trunk/src/scripttools/debugging/qscriptbreakpointsmodel.cpp@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 14.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtSCriptTools module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qscriptbreakpointsmodel_p.h"
43#include "qscriptdebuggerjobschedulerinterface_p.h"
44#include "qscriptdebuggercommandschedulerjob_p.h"
45#include "qscriptdebuggercommandschedulerfrontend_p.h"
46
47#include "private/qabstractitemmodel_p.h"
48
49#include <QtCore/qpair.h>
50#include <QtGui/qicon.h>
51#include <QtCore/qdebug.h>
52
53QT_BEGIN_NAMESPACE
54
55/*!
56 \since 4.5
57 \class QScriptBreakpointsModel
58 \internal
59*/
60
61class QScriptBreakpointsModelPrivate
62 : public QAbstractItemModelPrivate
63{
64 Q_DECLARE_PUBLIC(QScriptBreakpointsModel)
65public:
66 QScriptBreakpointsModelPrivate();
67 ~QScriptBreakpointsModelPrivate();
68
69 QScriptDebuggerJobSchedulerInterface *jobScheduler;
70 QScriptDebuggerCommandSchedulerInterface *commandScheduler;
71 QList<QPair<int, QScriptBreakpointData> > breakpoints;
72};
73
74QScriptBreakpointsModelPrivate::QScriptBreakpointsModelPrivate()
75{
76}
77
78QScriptBreakpointsModelPrivate::~QScriptBreakpointsModelPrivate()
79{
80}
81
82QScriptBreakpointsModel::QScriptBreakpointsModel(
83 QScriptDebuggerJobSchedulerInterface *jobScheduler,
84 QScriptDebuggerCommandSchedulerInterface *commandScheduler,
85 QObject *parent)
86 : QAbstractItemModel(*new QScriptBreakpointsModelPrivate, parent)
87{
88 Q_D(QScriptBreakpointsModel);
89 d->jobScheduler = jobScheduler;
90 d->commandScheduler = commandScheduler;
91}
92
93QScriptBreakpointsModel::~QScriptBreakpointsModel()
94{
95}
96
97namespace
98{
99
100class SetBreakpointJob : public QScriptDebuggerCommandSchedulerJob
101{
102public:
103 SetBreakpointJob(const QScriptBreakpointData &data,
104 QScriptDebuggerCommandSchedulerInterface *scheduler)
105 : QScriptDebuggerCommandSchedulerJob(scheduler),
106 m_data(data)
107 { }
108
109 void start()
110 {
111 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
112 frontend.scheduleSetBreakpoint(m_data);
113 }
114
115 void handleResponse(const QScriptDebuggerResponse &, int)
116 {
117 finish();
118 }
119
120private:
121 QScriptBreakpointData m_data;
122};
123
124} // namespace
125
126/*!
127 Sets a breakpoint defined by the given \a data.
128 A new row will be inserted into the model if the breakpoint could be
129 successfully set.
130*/
131void QScriptBreakpointsModel::setBreakpoint(const QScriptBreakpointData &data)
132{
133 Q_D(QScriptBreakpointsModel);
134 QScriptDebuggerJob *job = new SetBreakpointJob(data, d->commandScheduler);
135 d->jobScheduler->scheduleJob(job);
136}
137
138namespace
139{
140
141class SetBreakpointDataJob : public QScriptDebuggerCommandSchedulerJob
142{
143public:
144 SetBreakpointDataJob(int id, const QScriptBreakpointData &data,
145 QScriptDebuggerCommandSchedulerInterface *scheduler)
146 : QScriptDebuggerCommandSchedulerJob(scheduler),
147 m_id(id), m_data(data)
148 { }
149
150 void start()
151 {
152 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
153 frontend.scheduleSetBreakpointData(m_id, m_data);
154 }
155
156 void handleResponse(const QScriptDebuggerResponse &, int)
157 {
158 finish();
159 }
160
161private:
162 int m_id;
163 QScriptBreakpointData m_data;
164};
165
166} // namespace
167
168/*!
169 Sets the \a data associated with the breakpoint identified by \a id.
170 A dataChanged() signal will be emitted if the breakpoint data could
171 be successfully changed.
172*/
173void QScriptBreakpointsModel::setBreakpointData(int id, const QScriptBreakpointData &data)
174{
175 Q_D(QScriptBreakpointsModel);
176 QScriptDebuggerJob *job = new SetBreakpointDataJob(id, data, d->commandScheduler);
177 d->jobScheduler->scheduleJob(job);
178}
179
180namespace
181{
182
183class DeleteBreakpointJob : public QScriptDebuggerCommandSchedulerJob
184{
185public:
186 DeleteBreakpointJob(int id, QScriptDebuggerCommandSchedulerInterface *scheduler)
187 : QScriptDebuggerCommandSchedulerJob(scheduler),
188 m_id(id)
189 { }
190
191 void start()
192 {
193 QScriptDebuggerCommandSchedulerFrontend frontend(commandScheduler(), this);
194 frontend.scheduleDeleteBreakpoint(m_id);
195 }
196
197 void handleResponse(const QScriptDebuggerResponse &, int)
198 {
199 finish();
200 }
201
202private:
203 int m_id;
204};
205
206} // namespace
207
208/*!
209 Deletes the breakpoint with the given \a id.
210 The corresponding row in the model will be removed if the breakpoint
211 was successfully deleted.
212*/
213void QScriptBreakpointsModel::deleteBreakpoint(int id)
214{
215 Q_D(QScriptBreakpointsModel);
216 QScriptDebuggerJob *job = new DeleteBreakpointJob(id, d->commandScheduler);
217 d->jobScheduler->scheduleJob(job);
218}
219
220/*!
221 Adds a breakpoint to the model. This function does not actually set
222 a breakpoint (i.e. it doesn't communicate with the debugger).
223*/
224void QScriptBreakpointsModel::addBreakpoint(int id, const QScriptBreakpointData &data)
225{
226 Q_D(QScriptBreakpointsModel);
227 int rowIndex = d->breakpoints.size();
228 beginInsertRows(QModelIndex(), rowIndex, rowIndex);
229 d->breakpoints.append(qMakePair(id, data));
230 endInsertRows();
231}
232
233/*!
234 Modify the \a data of breakpoint \a id.
235*/
236void QScriptBreakpointsModel::modifyBreakpoint(int id, const QScriptBreakpointData &data)
237{
238 Q_D(QScriptBreakpointsModel);
239 for (int i = 0; i < d->breakpoints.size(); ++i) {
240 if (d->breakpoints.at(i).first == id) {
241 d->breakpoints[i] = qMakePair(id, data);
242 emit dataChanged(createIndex(i, 0), createIndex(i, columnCount()-1));
243 break;
244 }
245 }
246}
247
248/*!
249 Remove the breakpoint identified by \a id from the model. This
250 function does not delete the breakpoint (i.e. it doesn't communicate
251 with the debugger).
252*/
253void QScriptBreakpointsModel::removeBreakpoint(int id)
254{
255 Q_D(QScriptBreakpointsModel);
256 for (int i = 0; i < d->breakpoints.size(); ++i) {
257 if (d->breakpoints.at(i).first == id) {
258 beginRemoveRows(QModelIndex(), i, i);
259 d->breakpoints.removeAt(i);
260 endRemoveRows();
261 break;
262 }
263 }
264}
265
266/*!
267 Returns the id of the breakpoint at the given \a row.
268*/
269int QScriptBreakpointsModel::breakpointIdAt(int row) const
270{
271 Q_D(const QScriptBreakpointsModel);
272 return d->breakpoints.at(row).first;
273}
274
275/*!
276 Returns the data for the breakpoint at the given \a row.
277*/
278QScriptBreakpointData QScriptBreakpointsModel::breakpointDataAt(int row) const
279{
280 Q_D(const QScriptBreakpointsModel);
281 return d->breakpoints.at(row).second;
282}
283
284QScriptBreakpointData QScriptBreakpointsModel::breakpointData(int id) const
285{
286 Q_D(const QScriptBreakpointsModel);
287 for (int i = 0; i < d->breakpoints.size(); ++i) {
288 if (d->breakpoints.at(i).first == id)
289 return d->breakpoints.at(i).second;
290 }
291 return QScriptBreakpointData();
292}
293
294/*!
295 Tries to find a breakpoint with the given \a scriptId and \a
296 lineNumber. Returns the id of the first breakpoint that matches, or
297 -1 if no such breakpoint is found.
298*/
299int QScriptBreakpointsModel::resolveBreakpoint(qint64 scriptId, int lineNumber) const
300{
301 Q_D(const QScriptBreakpointsModel);
302 for (int i = 0; i < d->breakpoints.size(); ++i) {
303 if ((d->breakpoints.at(i).second.scriptId() == scriptId)
304 && (d->breakpoints.at(i).second.lineNumber() == lineNumber)) {
305 return d->breakpoints.at(i).first;
306 }
307 }
308 return -1;
309}
310
311int QScriptBreakpointsModel::resolveBreakpoint(const QString &fileName, int lineNumber) const
312{
313 Q_D(const QScriptBreakpointsModel);
314 for (int i = 0; i < d->breakpoints.size(); ++i) {
315 if ((d->breakpoints.at(i).second.fileName() == fileName)
316 && (d->breakpoints.at(i).second.lineNumber() == lineNumber)) {
317 return d->breakpoints.at(i).first;
318 }
319 }
320 return -1;
321}
322
323/*!
324 \reimp
325*/
326QModelIndex QScriptBreakpointsModel::index(int row, int column, const QModelIndex &parent) const
327{
328 Q_D(const QScriptBreakpointsModel);
329 if (parent.isValid())
330 return QModelIndex();
331 if ((row < 0) || (row >= d->breakpoints.size()))
332 return QModelIndex();
333 if ((column < 0) || (column >= columnCount()))
334 return QModelIndex();
335 return createIndex(row, column);
336}
337
338/*!
339 \reimp
340*/
341QModelIndex QScriptBreakpointsModel::parent(const QModelIndex &) const
342{
343 return QModelIndex();
344}
345
346/*!
347 \reimp
348*/
349int QScriptBreakpointsModel::columnCount(const QModelIndex &parent) const
350{
351 if (!parent.isValid())
352 return 6;
353 return 0;
354}
355
356/*!
357 \reimp
358*/
359int QScriptBreakpointsModel::rowCount(const QModelIndex &parent) const
360{
361 Q_D(const QScriptBreakpointsModel);
362 if (!parent.isValid())
363 return d->breakpoints.size();
364 return 0;
365}
366
367/*!
368 \reimp
369*/
370QVariant QScriptBreakpointsModel::data(const QModelIndex &index, int role) const
371{
372 Q_D(const QScriptBreakpointsModel);
373 if (!index.isValid() || (index.row() >= d->breakpoints.size()))
374 return QVariant();
375 const QPair<int, QScriptBreakpointData> &item = d->breakpoints.at(index.row());
376 if (role == Qt::DisplayRole) {
377 if (index.column() == 0)
378 return item.first;
379 else if (index.column() == 1) {
380 QString loc = item.second.fileName();
381 if (loc.isEmpty())
382 loc = QString::fromLatin1("<anonymous script, id=%0>").arg(item.second.scriptId());
383 loc.append(QString::fromLatin1(":%0").arg(item.second.lineNumber()));
384 return loc;
385 } else if (index.column() == 2) {
386 if (!item.second.condition().isEmpty())
387 return item.second.condition();
388 } else if (index.column() == 3) {
389 if (item.second.ignoreCount() != 0)
390 return item.second.ignoreCount();
391 } else if (index.column() == 5) {
392 return item.second.hitCount();
393 }
394 } else if (role == Qt::CheckStateRole) {
395 if (index.column() == 0) {
396 return item.second.isEnabled() ? Qt::Checked : Qt::Unchecked;
397 } else if (index.column() == 4) {
398 return item.second.isSingleShot() ? Qt::Checked : Qt::Unchecked;
399 }
400 } else if (role == Qt::EditRole) {
401 if (index.column() == 2)
402 return item.second.condition();
403 else if (index.column() == 3)
404 return item.second.ignoreCount();
405 }
406 return QVariant();
407}
408
409/*!
410 \reimp
411*/
412bool QScriptBreakpointsModel::setData(const QModelIndex &index, const QVariant &value, int role)
413{
414 Q_D(QScriptBreakpointsModel);
415 if (!index.isValid() || (index.row() >= d->breakpoints.size()))
416 return false;
417 const QPair<int, QScriptBreakpointData> &item = d->breakpoints.at(index.row());
418 QScriptBreakpointData modifiedData;
419 int col = index.column();
420 if ((col == 0) || (col == 4)) {
421 if (role == Qt::CheckStateRole) {
422 modifiedData = item.second;
423 if (col == 0)
424 modifiedData.setEnabled(value.toInt() == Qt::Checked);
425 else
426 modifiedData.setSingleShot(value.toInt() == Qt::Checked);
427 }
428 } else if (col == 2) {
429 if (role == Qt::EditRole) {
430 modifiedData = item.second;
431 modifiedData.setCondition(value.toString());
432 }
433 } else if (col == 3) {
434 if (role == Qt::EditRole) {
435 modifiedData = item.second;
436 modifiedData.setIgnoreCount(value.toInt());
437 }
438 }
439 if (!modifiedData.isValid())
440 return false;
441 QScriptDebuggerJob *job = new SetBreakpointDataJob(item.first, modifiedData, d->commandScheduler);
442 d->jobScheduler->scheduleJob(job);
443 return true;
444}
445
446/*!
447 \reimp
448*/
449QVariant QScriptBreakpointsModel::headerData(int section, Qt::Orientation orient, int role) const
450{
451 if (orient == Qt::Horizontal) {
452 if (role == Qt::DisplayRole) {
453 if (section == 0)
454 return QObject::tr("ID");
455 else if (section == 1)
456 return QObject::tr("Location");
457 else if (section == 2)
458 return QObject::tr("Condition");
459 else if (section == 3)
460 return QObject::tr("Ignore-count");
461 else if (section == 4)
462 return QObject::tr("Single-shot");
463 else if (section == 5)
464 return QObject::tr("Hit-count");
465 }
466 }
467 return QVariant();
468}
469
470/*!
471 \reimp
472*/
473Qt::ItemFlags QScriptBreakpointsModel::flags(const QModelIndex &index) const
474{
475 if (!index.isValid())
476 return 0;
477 Qt::ItemFlags ret = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
478 switch (index.column()) {
479 case 0:
480 ret |= Qt::ItemIsUserCheckable;
481 break;
482 case 1:
483 break;
484 case 2:
485 ret |= Qt::ItemIsEditable;
486 break;
487 case 3:
488 ret |= Qt::ItemIsEditable;
489 break;
490 case 4:
491 ret |= Qt::ItemIsUserCheckable;
492 break;
493 }
494 return ret;
495}
496
497QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.