source: branches/4.5.1/src/scripttools/debugging/qscriptdebuggercodewidget.cpp@ 921

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

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

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