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

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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