diff options
Diffstat (limited to 'khtml/ecma/kjs_debugwin.h')
-rw-r--r-- | khtml/ecma/kjs_debugwin.h | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/khtml/ecma/kjs_debugwin.h b/khtml/ecma/kjs_debugwin.h new file mode 100644 index 000000000..5a2ce2f1f --- /dev/null +++ b/khtml/ecma/kjs_debugwin.h @@ -0,0 +1,285 @@ +/* + * This file is part of the KDE libraries + * Copyright (C) 2000-2001 Harri Porten (porten@kde.org) + * Copyright (C) 2001,2003 Peter Kelly (pmk@post.com) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _KJS_DEBUGGER_H_ +#define _KJS_DEBUGGER_H_ + +#include <qglobal.h> + +#define KJS_DEBUGGER + +#ifdef KJS_DEBUGGER + +#include <qwidget.h> +#include <qmultilineedit.h> +#include <qpixmap.h> +#include <qptrlist.h> +#include <qptrstack.h> +#include <qcheckbox.h> +#include <kdialogbase.h> +#include <kmainwindow.h> +#include <qscrollview.h> + +#include <kjs/debugger.h> + +#include "dom/dom_misc.h" + +class QListBox; +class QComboBox; +class KActionCollection; +class KAction; + +namespace KJS { + class FunctionImp; + class List; + class Interpreter; + class KJSDebugWin; + + class SourceFile : public DOM::DomShared + { + public: + SourceFile(QString u, QString c, Interpreter *interp) + : url(u), code(c), interpreter(interp) {} + QString getCode(); + QString url; + QString code; + Interpreter *interpreter; + }; + + /** + * @internal + * + * When kjs parses some code, it generates a source code fragment (or just "source"). + * This is referenced by its source id in future calls to functions such as atLine() + * and callEvent(). We keep a record of all source fragments parsed in order to display + * then to the user. + * + * For .js files, the source fragment will be the entire file. For js code included + * in html files, however, there may be multiple source fragments within the one file + * (e.g. multiple SCRIPT tags or onclick="..." attributes) + * + * In the case where a single file has multiple source fragments, the source objects + * for these fragments will all point to the same SourceFile for their code. + */ + class SourceFragment + { + public: + SourceFragment(int sid, int bl, int el, SourceFile *sf); + ~SourceFragment(); + + int sourceId; + int baseLine; + int errorLine; + SourceFile *sourceFile; + private: + SourceFragment(const SourceFragment& other); + SourceFragment& operator = (const SourceFragment& other); + }; + + class KJSErrorDialog : public KDialogBase { + Q_OBJECT + public: + KJSErrorDialog(QWidget *parent, const QString& errorMessage, bool showDebug); + virtual ~KJSErrorDialog(); + + bool debugSelected() const { return m_debugSelected; } + bool dontShowAgain() const { return m_dontShowAgainCb->isChecked(); } + + protected slots: + virtual void slotUser1(); + + private: + QCheckBox *m_dontShowAgainCb; + bool m_debugSelected; + }; + + class EvalMultiLineEdit : public QMultiLineEdit { + Q_OBJECT + public: + EvalMultiLineEdit(QWidget *parent); + const QString & code() const { return m_code; } + protected: + void keyPressEvent(QKeyEvent * e); + private: + QString m_code; + }; + + class SourceDisplay : public QScrollView { + Q_OBJECT + public: + SourceDisplay(KJSDebugWin *debugWin, QWidget *parent, const char *name = 0); + ~SourceDisplay(); + + void setSource(SourceFile *sourceFile); + void setCurrentLine(int lineno, bool doCenter = true); + + signals: + void lineDoubleClicked(int lineno); + + protected: + virtual void contentsMousePressEvent(QMouseEvent *e); + virtual void showEvent(QShowEvent *); + virtual void drawContents(QPainter *p, int clipx, int clipy, int clipw, int cliph); + + QString m_source; + int m_currentLine; + SourceFile *m_sourceFile; + QStringList m_lines; + + KJSDebugWin *m_debugWin; + QFont m_font; + QPixmap m_breakpointIcon; + }; + + /** + * @internal + * + * KJSDebugWin represents the debugger window that is visible to the user. It contains + * a stack frame list, a code viewer and a source fragment selector, plus buttons + * to control execution including next, step and continue. + * + * There is only one debug window per program. This can be obtained by calling #instance + */ + class KJSDebugWin : public KMainWindow, public Debugger, public KInstance + { + Q_OBJECT + friend class SourceDisplay; + public: + KJSDebugWin(QWidget *parent=0, const char *name=0); + virtual ~KJSDebugWin(); + + static KJSDebugWin *createInstance(); + static void destroyInstance(); + static KJSDebugWin *debugWindow() { return kjs_html_debugger; } + + enum Mode { Disabled = 0, // No break on any statements + Next = 1, // Will break on next statement in current context + Step = 2, // Will break on next statement in current or deeper context + Continue = 3, // Will continue until next breakpoint + Stop = 4 // The script will stop execution completely, + // as soon as possible + }; + + void setSourceLine(int sourceId, int lineno); + void setNextSourceInfo(QString url, int baseLine); + void sourceChanged(Interpreter *interpreter, QString url); + bool inSession() const { return !m_execStates.isEmpty(); } + void setMode(Mode m) { m_mode = m; } + void clearInterpreter(Interpreter *interpreter); + ExecState *getExecState() const { return m_execStates.top(); } + + // functions overridden from KJS:Debugger + bool sourceParsed(ExecState *exec, int sourceId, + const UString &source, int errorLine); + bool sourceUnused(ExecState * exec, int sourceId); + bool exception(ExecState *exec, const Value &value, bool inTryCatch); + bool atStatement(ExecState *exec); + bool enterContext(ExecState *exec); + bool exitContext(ExecState *exec, const Completion &completion); + + public slots: + void slotNext(); + void slotStep(); + void slotContinue(); + void slotStop(); + void slotBreakNext(); + void slotToggleBreakpoint(int lineno); + void slotShowFrame(int frameno); + void slotSourceSelected(int sourceSelIndex); + void slotEval(); + + protected: + + void closeEvent(QCloseEvent *e); + bool eventFilter(QObject *obj, QEvent *evt); + void disableOtherWindows(); + void enableOtherWindows(); + + private: + + SourceFile *getSourceFile(Interpreter *interpreter, QString url); + void setSourceFile(Interpreter *interpreter, QString url, SourceFile *sourceFile); + void removeSourceFile(Interpreter *interpreter, QString url); + + void checkBreak(ExecState *exec); + void enterSession(ExecState *exec); + void leaveSession(); + void displaySourceFile(SourceFile *sourceFile, bool forceRefresh); + void updateContextList(); + + QString contextStr(const Context &ctx); + + struct Breakpoint { + int sourceId; + int lineno; + }; + Breakpoint *m_breakpoints; + int m_breakpointCount; + bool setBreakpoint(int sourceId, int lineno); + bool deleteBreakpoint(int sourceId, int lineno); + bool haveBreakpoint(SourceFile *sourceFile, int line0, int line1); + bool haveBreakpoint(int sourceId, int line0, int line1) const { + for (int i = 0; i < m_breakpointCount; i++) { + if (m_breakpoints[i].sourceId == sourceId && + m_breakpoints[i].lineno >= line0 && + m_breakpoints[i].lineno <= line1) + return true; + } + return false; + } + + SourceFile *m_curSourceFile; + Mode m_mode; + QString m_nextSourceUrl; + int m_nextSourceBaseLine; + QPtrStack<ExecState> m_execStates; + ExecState **m_execs; + int m_execsCount; + int m_execsAlloc; + int m_steppingDepth; + + QMap<QString,SourceFile*> m_sourceFiles; /* maps url->SourceFile */ + QMap<int,SourceFragment*> m_sourceFragments; /* maps SourceId->SourceFragment */ + QPtrList<SourceFile> m_sourceSelFiles; /* maps combobox index->SourceFile */ + + KActionCollection *m_actionCollection; + QPixmap m_stopIcon; + QPixmap m_emptyIcon; + SourceDisplay *m_sourceDisplay; + QListBox *m_contextList; + + KAction *m_stepAction; + KAction *m_nextAction; + KAction *m_continueAction; + KAction *m_stopAction; + KAction *m_breakAction; + + QComboBox *m_sourceSel; + EvalMultiLineEdit *m_evalEdit; + int m_evalDepth; + + static KJSDebugWin *kjs_html_debugger; + }; + +} // namespace + +#endif // KJS_DEBUGGER + +#endif // _KJS_DEBUGGER_H_ |