source: trunk/src/scripttools/debugging/qscriptdebuggercodewidget.cpp@ 561

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

trunk: Merged in qt 4.6.1 sources.

File size: 11.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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 "qscriptdebuggercodewidget_p.h"
43#include "qscriptdebuggercodewidgetinterface_p_p.h"
44#include "qscriptdebuggercodeview_p.h"
45#include "qscriptdebuggerscriptsmodel_p.h"
46#include "qscriptbreakpointsmodel_p.h"
47#include "qscripttooltipproviderinterface_p.h"
48
49#include <QtCore/qdebug.h>
50#include <QtGui/qboxlayout.h>
51#include <QtGui/qstackedwidget.h>
52
53QT_BEGIN_NAMESPACE
54
55class QScriptDebuggerCodeWidgetPrivate
56 : public QScriptDebuggerCodeWidgetInterfacePrivate
57{
58 Q_DECLARE_PUBLIC(QScriptDebuggerCodeWidget)
59public:
60 QScriptDebuggerCodeWidgetPrivate();
61 ~QScriptDebuggerCodeWidgetPrivate();
62
63 qint64 scriptId(QScriptDebuggerCodeViewInterface *view) const;
64
65 // private slots
66 void _q_onBreakpointToggleRequest(int lineNumber, bool on);
67 void _q_onBreakpointEnableRequest(int lineNumber, bool enable);
68 void _q_onBreakpointsAboutToBeRemoved(const QModelIndex&, int, int);
69 void _q_onBreakpointsInserted(const QModelIndex&, int, int);
70 void _q_onBreakpointsDataChanged(const QModelIndex &, const QModelIndex &);
71 void _q_onScriptsChanged();
72 void _q_onToolTipRequest(const QPoint &pos, int lineNumber, const QStringList &path);
73
74 QScriptDebuggerScriptsModel *scriptsModel;
75 QStackedWidget *viewStack;
76 QHash<qint64, QScriptDebuggerCodeViewInterface*> viewHash;
77 QScriptBreakpointsModel *breakpointsModel;
78 QScriptToolTipProviderInterface *toolTipProvider;
79};
80
81QScriptDebuggerCodeWidgetPrivate::QScriptDebuggerCodeWidgetPrivate()
82{
83 scriptsModel = 0;
84 breakpointsModel = 0;
85 toolTipProvider = 0;
86}
87
88QScriptDebuggerCodeWidgetPrivate::~QScriptDebuggerCodeWidgetPrivate()
89{
90}
91
92qint64 QScriptDebuggerCodeWidgetPrivate::scriptId(QScriptDebuggerCodeViewInterface *view) const
93{
94 if (!view)
95 return -1;
96 return viewHash.key(view);
97}
98
99void QScriptDebuggerCodeWidgetPrivate::_q_onBreakpointToggleRequest(int lineNumber, bool on)
100{
101 QScriptDebuggerCodeViewInterface *view = qobject_cast<QScriptDebuggerCodeViewInterface*>(q_func()->sender());
102 qint64 sid = scriptId(view);
103 Q_ASSERT(sid != -1);
104 if (on) {
105 QScriptBreakpointData data(sid, lineNumber);
106 data.setFileName(scriptsModel->scriptData(sid).fileName());
107 breakpointsModel->setBreakpoint(data);
108 } else {
109 int bpid = breakpointsModel->resolveBreakpoint(sid, lineNumber);
110 if (bpid == -1)
111 bpid = breakpointsModel->resolveBreakpoint(scriptsModel->scriptData(sid).fileName(), lineNumber);
112 Q_ASSERT(bpid != -1);
113 breakpointsModel->deleteBreakpoint(bpid);
114 }
115}
116
117void QScriptDebuggerCodeWidgetPrivate::_q_onBreakpointEnableRequest(int lineNumber, bool enable)
118{
119 QScriptDebuggerCodeViewInterface *view = qobject_cast<QScriptDebuggerCodeViewInterface*>(q_func()->sender());
120 qint64 sid = scriptId(view);
121 int bpid = breakpointsModel->resolveBreakpoint(sid, lineNumber);
122 if (bpid == -1)
123 bpid = breakpointsModel->resolveBreakpoint(scriptsModel->scriptData(sid).fileName(), lineNumber);
124 Q_ASSERT(bpid != -1);
125 QScriptBreakpointData data = breakpointsModel->breakpointData(bpid);
126 data.setEnabled(enable);
127 breakpointsModel->setBreakpointData(bpid, data);
128}
129
130void QScriptDebuggerCodeWidgetPrivate::_q_onBreakpointsAboutToBeRemoved(
131 const QModelIndex &, int first, int last)
132{
133 for (int i = first; i <= last; ++i) {
134 QScriptBreakpointData data = breakpointsModel->breakpointDataAt(i);
135 qint64 scriptId = data.scriptId();
136 if (scriptId == -1) {
137 scriptId = scriptsModel->resolveScript(data.fileName());
138 if (scriptId == -1)
139 continue;
140 }
141 QScriptDebuggerCodeViewInterface *view = viewHash.value(scriptId);
142 if (!view)
143 continue;
144 view->deleteBreakpoint(data.lineNumber());
145 }
146}
147
148void QScriptDebuggerCodeWidgetPrivate::_q_onBreakpointsInserted(
149 const QModelIndex &, int first, int last)
150{
151 for (int i = first; i <= last; ++i) {
152 QScriptBreakpointData data = breakpointsModel->breakpointDataAt(i);
153 qint64 scriptId = data.scriptId();
154 if (scriptId == -1) {
155 scriptId = scriptsModel->resolveScript(data.fileName());
156 if (scriptId == -1)
157 continue;
158 }
159 QScriptDebuggerCodeViewInterface *view = viewHash.value(scriptId);
160 if (!view)
161 continue;
162 view->setBreakpoint(data.lineNumber());
163 }
164}
165
166void QScriptDebuggerCodeWidgetPrivate::_q_onBreakpointsDataChanged(
167 const QModelIndex &tl, const QModelIndex &br)
168{
169 for (int i = tl.row(); i <= br.row(); ++i) {
170 QScriptBreakpointData data = breakpointsModel->breakpointDataAt(i);
171 qint64 scriptId = data.scriptId();
172 if (scriptId == -1) {
173 scriptId = scriptsModel->resolveScript(data.fileName());
174 if (scriptId == -1)
175 continue;
176 }
177 QScriptDebuggerCodeViewInterface *view = viewHash.value(scriptId);
178 if (!view)
179 continue;
180 view->setBreakpointEnabled(data.lineNumber(), data.isEnabled());
181 }
182}
183
184void QScriptDebuggerCodeWidgetPrivate::_q_onScriptsChanged()
185{
186 // kill editors for scripts that have been removed
187 QHash<qint64, QScriptDebuggerCodeViewInterface*>::iterator it;
188 for (it = viewHash.begin(); it != viewHash.end(); ) {
189 if (!scriptsModel->scriptData(it.key()).isValid()) {
190 it = viewHash.erase(it);
191 } else
192 ++it;
193 }
194}
195
196void QScriptDebuggerCodeWidgetPrivate::_q_onToolTipRequest(
197 const QPoint &pos, int lineNumber, const QStringList &path)
198{
199 toolTipProvider->showToolTip(pos, /*frameIndex=*/-1, lineNumber, path);
200}
201
202QScriptDebuggerCodeWidget::QScriptDebuggerCodeWidget(QWidget *parent)
203 : QScriptDebuggerCodeWidgetInterface(*new QScriptDebuggerCodeWidgetPrivate, parent, 0)
204{
205 Q_D(QScriptDebuggerCodeWidget);
206 QVBoxLayout *vbox = new QVBoxLayout(this);
207 vbox->setMargin(0);
208 d->viewStack = new QStackedWidget();
209 vbox->addWidget(d->viewStack);
210}
211
212QScriptDebuggerCodeWidget::~QScriptDebuggerCodeWidget()
213{
214}
215
216QScriptDebuggerScriptsModel *QScriptDebuggerCodeWidget::scriptsModel() const
217{
218 Q_D(const QScriptDebuggerCodeWidget);
219 return d->scriptsModel;
220}
221
222void QScriptDebuggerCodeWidget::setScriptsModel(QScriptDebuggerScriptsModel *model)
223{
224 Q_D(QScriptDebuggerCodeWidget);
225 d->scriptsModel = model;
226 QObject::connect(model, SIGNAL(layoutChanged()),
227 this, SLOT(_q_onScriptsChanged()));
228}
229
230qint64 QScriptDebuggerCodeWidget::currentScriptId() const
231{
232 Q_D(const QScriptDebuggerCodeWidget);
233 return d->scriptId(currentView());
234}
235
236void QScriptDebuggerCodeWidget::setCurrentScript(qint64 scriptId)
237{
238 Q_D(QScriptDebuggerCodeWidget);
239 if (scriptId == -1) {
240 // ### show "native script"
241 return;
242 }
243 QScriptDebuggerCodeViewInterface *view = d->viewHash.value(scriptId);
244 if (!view) {
245 Q_ASSERT(d->scriptsModel != 0);
246 QScriptScriptData data = d->scriptsModel->scriptData(scriptId);
247 if (!data.isValid())
248 return;
249 view = new QScriptDebuggerCodeView(); // ### use factory, so user can provide his own view
250 view->setBaseLineNumber(data.baseLineNumber());
251 view->setText(data.contents());
252 view->setExecutableLineNumbers(d->scriptsModel->executableLineNumbers(scriptId));
253 QObject::connect(view, SIGNAL(breakpointToggleRequest(int,bool)),
254 this, SLOT(_q_onBreakpointToggleRequest(int,bool)));
255 QObject::connect(view, SIGNAL(breakpointEnableRequest(int,bool)),
256 this, SLOT(_q_onBreakpointEnableRequest(int,bool)));
257 QObject::connect(view, SIGNAL(toolTipRequest(QPoint,int,QStringList)),
258 this, SLOT(_q_onToolTipRequest(QPoint,int,QStringList)));
259 d->viewStack->addWidget(view);
260 d->viewHash.insert(scriptId, view);
261 }
262 d->viewStack->setCurrentWidget(view);
263}
264
265void QScriptDebuggerCodeWidget::invalidateExecutionLineNumbers()
266{
267 Q_D(QScriptDebuggerCodeWidget);
268 QHash<qint64, QScriptDebuggerCodeViewInterface*>::const_iterator it;
269 for (it = d->viewHash.constBegin(); it != d->viewHash.constEnd(); ++it)
270 it.value()->setExecutionLineNumber(-1, /*error=*/false);
271}
272
273QScriptBreakpointsModel *QScriptDebuggerCodeWidget::breakpointsModel() const
274{
275 Q_D(const QScriptDebuggerCodeWidget);
276 return d->breakpointsModel;
277}
278
279void QScriptDebuggerCodeWidget::setBreakpointsModel(QScriptBreakpointsModel *model)
280{
281 Q_D(QScriptDebuggerCodeWidget);
282 d->breakpointsModel = model;
283 QObject::connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
284 this, SLOT(_q_onBreakpointsAboutToBeRemoved(QModelIndex,int,int)));
285 QObject::connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
286 this, SLOT(_q_onBreakpointsInserted(QModelIndex,int,int)));
287 QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
288 this, SLOT(_q_onBreakpointsDataChanged(QModelIndex,QModelIndex)));
289}
290
291void QScriptDebuggerCodeWidget::setToolTipProvider(QScriptToolTipProviderInterface *toolTipProvider)
292{
293 Q_D(QScriptDebuggerCodeWidget);
294 d->toolTipProvider = toolTipProvider;
295}
296
297QScriptDebuggerCodeViewInterface *QScriptDebuggerCodeWidget::currentView() const
298{
299 Q_D(const QScriptDebuggerCodeWidget);
300 return qobject_cast<QScriptDebuggerCodeViewInterface*>(d->viewStack->currentWidget());
301}
302
303QT_END_NAMESPACE
304
305#include "moc_qscriptdebuggercodewidget_p.cpp"
Note: See TracBrowser for help on using the repository browser.