KHtml

kjs_debugwin.h
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2000-2001 Harri Porten ([email protected])
4  * Copyright (C) 2001,2003 Peter Kelly ([email protected])
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #ifndef _KJS_DEBUGGER_H_
22 #define _KJS_DEBUGGER_H_
23 
24 #ifdef KJS_DEBUGGER
25 
26 #include <qwidget.h>
27 #include <q3multilineedit.h>
28 #include <qpixmap.h>
29 #include <q3ptrlist.h>
30 #include <QStack>
31 #include <qcheckbox.h>
32 #include <kdialog.h>
33 #include <kcomponentdata.h>
34 #include <kmainwindow.h>
35 #include <q3scrollview.h>
36 
37 #include <kjs/debugger.h>
38 #include <kjs/completion.h>
39 #include <kjs/interpreter.h>
40 #include <kjs/value.h>
41 #include "kjs_binding.h"
42 
43 #include "dom/dom_misc.h"
44 
45 class QListWidget;
46 class QComboBox;
47 class QAction;
48 
49 namespace KJS
50 {
51 class List;
52 class KJSDebugWin;
53 
54 class SourceFile : public DOM::DomShared
55 {
56 public:
57  SourceFile(QString u, QString c, Interpreter *interp)
58  : url(u), code(c), interpreter(interp) {}
59  QString getCode();
60  QString url;
61  QString code;
62  Interpreter *interpreter;
63 };
64 
65 /**
66  * @internal
67  *
68  * When kjs parses some code, it generates a source code fragment (or just "source").
69  * This is referenced by its source id in future calls to functions such as atLine()
70  * and callEvent(). We keep a record of all source fragments parsed in order to display
71  * then to the user.
72  *
73  * For .js files, the source fragment will be the entire file. For js code included
74  * in html files, however, there may be multiple source fragments within the one file
75  * (e.g. multiple SCRIPT tags or onclick="..." attributes)
76  *
77  * In the case where a single file has multiple source fragments, the source objects
78  * for these fragments will all point to the same SourceFile for their code.
79  */
80 class SourceFragment
81 {
82 public:
83  SourceFragment(int sid, int bl, int el, SourceFile *sf);
84  ~SourceFragment();
85 
86  int sourceId;
87  int baseLine;
88  int errorLine;
89  SourceFile *sourceFile;
90 private:
91  SourceFragment(const SourceFragment &other);
92  SourceFragment &operator = (const SourceFragment &other);
93 };
94 
95 class KJSErrorDialog : public KDialog
96 {
97  Q_OBJECT
98 public:
99  KJSErrorDialog(QWidget *parent, const QString &errorMessage, bool showDebug);
100  virtual ~KJSErrorDialog();
101 
102  bool debugSelected() const
103  {
104  return m_debugSelected;
105  }
106  bool dontShowAgain() const
107  {
108  return m_dontShowAgainCb->isChecked();
109  }
110 
111 protected Q_SLOTS:
112  virtual void slotUser1();
113 
114 private:
115  QCheckBox *m_dontShowAgainCb;
116  bool m_debugSelected;
117 };
118 
119 class EvalMultiLineEdit : public Q3MultiLineEdit
120 {
121  Q_OBJECT
122 public:
123  EvalMultiLineEdit(QWidget *parent);
124  const QString &code() const
125  {
126  return m_code;
127  }
128 protected:
129  void keyPressEvent(QKeyEvent *e);
130 private:
131  QString m_code;
132 };
133 
134 class SourceDisplay : public Q3ScrollView
135 {
136  Q_OBJECT
137 public:
138  SourceDisplay(KJSDebugWin *debugWin, QWidget *parent, const char *name = 0);
139  ~SourceDisplay();
140 
141  void setSource(SourceFile *sourceFile);
142  void setCurrentLine(int lineno, bool doCenter = true);
143 
144 Q_SIGNALS:
145  void lineDoubleClicked(int lineno);
146 
147 protected:
148  virtual void contentsMousePressEvent(QMouseEvent *e);
149  virtual void showEvent(QShowEvent *);
150  virtual void drawContents(QPainter *p, int clipx, int clipy, int clipw, int cliph);
151 
152  QString m_source;
153  int m_currentLine;
154  SourceFile *m_sourceFile;
155  QStringList m_lines;
156 
157  KJSDebugWin *m_debugWin;
158  QFont m_font;
159  QPixmap m_breakpointIcon;
160 };
161 
162 /**
163  * @internal
164  *
165  * KJSDebugWin represents the debugger window that is visible to the user. It contains
166  * a stack frame list, a code viewer and a source fragment selector, plus buttons
167  * to control execution including next, step and continue.
168  *
169  * There is only one debug window per program. This can be obtained by calling #instance
170  */
171 class KJSDebugWin : public KMainWindow, public Debugger, public KComponentData
172 {
173  Q_OBJECT
174  friend class SourceDisplay;
175 public:
176  KJSDebugWin(QWidget *parent = 0, const char *name = 0);
177  virtual ~KJSDebugWin();
178 
179  static KJSDebugWin *createInstance();
180  static void destroyInstance();
181  static KJSDebugWin *debugWindow()
182  {
183  return kjs_html_debugger;
184  }
185 
186  enum Mode { Disabled = 0, // No break on any statements
187  Next = 1, // Will break on next statement in current context
188  Step = 2, // Will break on next statement in current or deeper context
189  Continue = 3, // Will continue until next breakpoint
190  Stop = 4 // The script will stop execution completely,
191  // as soon as possible
192  };
193 
194  void setSourceLine(int sourceId, int lineno);
195  void setNextSourceInfo(QString url, int baseLine);
196  void sourceChanged(Interpreter *interpreter, QString url);
197  bool inSession() const
198  {
199  return !m_execStates.isEmpty();
200  }
201  void setMode(Mode m)
202  {
203  m_mode = m;
204  }
205  void clearInterpreter(Interpreter *interpreter);
206  ExecState *getExecState() const
207  {
208  return m_execStates.top();
209  }
210 
211  // functions overridden from KJS:Debugger
212  bool sourceParsed(ExecState *exec, int sourceId,
213  const UString &source, int errorLine);
214  bool sourceUnused(ExecState *exec, int sourceId);
215  bool exception(ExecState *exec, JSValue *value, bool inTryCatch);
216  bool atStatement(ExecState *exec);
217  bool enterContext(ExecState *exec);
218  bool exitContext(ExecState *exec, const Completion &completion);
219 
220 public Q_SLOTS:
221  void slotNext();
222  void slotStep();
223  void slotContinue();
224  void slotStop();
225  void slotBreakNext();
226  void slotToggleBreakpoint(int lineno);
227  void slotShowFrame(int frameno);
228  void slotSourceSelected(int sourceSelIndex);
229  void slotEval();
230 
231 protected:
232 
233  void closeEvent(QCloseEvent *e);
234  bool eventFilter(QObject *obj, QEvent *evt);
235  void disableOtherWindows();
236  void enableOtherWindows();
237 
238 private:
239 
240  SourceFile *getSourceFile(Interpreter *interpreter, QString url);
241  void setSourceFile(Interpreter *interpreter, QString url, SourceFile *sourceFile);
242  void removeSourceFile(Interpreter *interpreter, QString url);
243 
244  void checkBreak(ExecState *exec);
245  void enterSession(ExecState *exec);
246  void leaveSession();
247  void displaySourceFile(SourceFile *sourceFile, bool forceRefresh);
248  void updateContextList();
249 
250  QString contextStr(const Context &ctx);
251 
252  struct Breakpoint {
253  int sourceId;
254  int lineno;
255  };
256  Breakpoint *m_breakpoints;
257  int m_breakpointCount;
258  bool setBreakpoint(int sourceId, int lineno);
259  bool deleteBreakpoint(int sourceId, int lineno);
260  bool haveBreakpoint(SourceFile *sourceFile, int line0, int line1);
261  bool haveBreakpoint(int sourceId, int line0, int line1) const
262  {
263  for (int i = 0; i < m_breakpointCount; i++) {
264  if (m_breakpoints[i].sourceId == sourceId &&
265  m_breakpoints[i].lineno >= line0 &&
266  m_breakpoints[i].lineno <= line1) {
267  return true;
268  }
269  }
270  return false;
271  }
272 
273  SourceFile *m_curSourceFile;
274  Mode m_mode;
275  QString m_nextSourceUrl;
276  int m_nextSourceBaseLine;
277  QStack<ExecState *> m_execStates;
278  ExecState **m_execs;
279  int m_execsCount;
280  int m_execsAlloc;
281  int m_steppingDepth;
282 
283  QMap<QString, SourceFile *> m_sourceFiles; /* maps url->SourceFile */
284  QMap<int, SourceFragment *> m_sourceFragments; /* maps SourceId->SourceFragment */
285  Q3PtrList<SourceFile> m_sourceSelFiles; /* maps combobox index->SourceFile */
286 
287  QPixmap m_stopIcon;
288  QPixmap m_emptyIcon;
289  SourceDisplay *m_sourceDisplay;
290  QListWidget *m_contextList;
291 
292  QAction *m_stepAction;
293  QAction *m_nextAction;
294  QAction *m_continueAction;
295  QAction *m_stopAction;
296  QAction *m_breakAction;
297 
298  QComboBox *m_sourceSel;
299  EvalMultiLineEdit *m_evalEdit;
300  int m_evalDepth;
301 
302  static KJSDebugWin *kjs_html_debugger;
303 };
304 
305 } // namespace
306 
307 #endif // KJS_DEBUGGER
308 
309 #endif // _KJS_DEBUGGER_H_
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 16 2021 22:47:57 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.