kjs_debugwin.h

00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (C) 2000-2001 Harri Porten (porten@kde.org)
00004  *  Copyright (C) 2001,2003 Peter Kelly (pmk@post.com)
00005  *
00006  *  This library is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU Library General Public
00008  *  License as published by the Free Software Foundation; either
00009  *  version 2 of the License, or (at your option) any later version.
00010  *
00011  *  This library is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  Library General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU Library General Public
00017  *  License along with this library; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #ifndef _KJS_DEBUGGER_H_
00022 #define _KJS_DEBUGGER_H_
00023 
00024 #include <qglobal.h>
00025 
00026 #define KJS_DEBUGGER
00027 
00028 #ifdef KJS_DEBUGGER
00029 
00030 #include <qwidget.h>
00031 #include <qmultilineedit.h>
00032 #include <qpixmap.h>
00033 #include <qptrlist.h>
00034 #include <qptrstack.h>
00035 #include <qcheckbox.h>
00036 #include <kdialogbase.h>
00037 #include <kmainwindow.h>
00038 #include <qscrollview.h>
00039 
00040 #include <kjs/debugger.h>
00041 
00042 #include "dom/dom_misc.h"
00043 
00044 class QListBox;
00045 class QComboBox;
00046 class KActionCollection;
00047 class KAction;
00048 
00049 namespace KJS {
00050   class FunctionImp;
00051   class List;
00052   class Interpreter;
00053   class KJSDebugWin;
00054 
00055   class SourceFile : public DOM::DomShared
00056   {
00057    public:
00058     SourceFile(QString u, QString c, Interpreter *interp) 
00059     : url(u), code(c), interpreter(interp) {}
00060     QString getCode();
00061     QString url;
00062     QString code;
00063     Interpreter *interpreter;
00064   };
00065 
00081   class SourceFragment
00082   {
00083   public:
00084     SourceFragment(int sid, int bl, int el, SourceFile *sf);
00085     ~SourceFragment();
00086 
00087     int sourceId;
00088     int baseLine;
00089     int errorLine;
00090     SourceFile *sourceFile;
00091   private:
00092     SourceFragment(const SourceFragment& other);
00093     SourceFragment& operator = (const SourceFragment& other);
00094   };
00095 
00096   class KJSErrorDialog : public KDialogBase {
00097     Q_OBJECT
00098   public:
00099     KJSErrorDialog(QWidget *parent, const QString& errorMessage, bool showDebug);
00100     virtual ~KJSErrorDialog();
00101 
00102     bool debugSelected() const { return m_debugSelected; }
00103     bool dontShowAgain() const { return m_dontShowAgainCb->isChecked(); }
00104 
00105   protected slots:
00106     virtual void slotUser1();
00107 
00108   private:
00109     QCheckBox *m_dontShowAgainCb;
00110     bool m_debugSelected;
00111   };
00112 
00113   class EvalMultiLineEdit : public QMultiLineEdit {
00114     Q_OBJECT
00115   public:
00116       EvalMultiLineEdit(QWidget *parent);
00117       const QString & code() const { return m_code; }
00118   protected:
00119       void keyPressEvent(QKeyEvent * e);
00120   private:
00121       QString m_code;
00122   };
00123 
00124   class SourceDisplay : public QScrollView {
00125     Q_OBJECT
00126   public:
00127     SourceDisplay(KJSDebugWin *debugWin, QWidget *parent, const char *name = 0);
00128     ~SourceDisplay();
00129 
00130     void setSource(SourceFile *sourceFile);
00131     void setCurrentLine(int lineno, bool doCenter = true);
00132 
00133   signals:
00134     void lineDoubleClicked(int lineno);
00135 
00136   protected:
00137     virtual void contentsMousePressEvent(QMouseEvent *e);
00138     virtual void showEvent(QShowEvent *);
00139     virtual void drawContents(QPainter *p, int clipx, int clipy, int clipw, int cliph);
00140 
00141     QString m_source;
00142     int m_currentLine;
00143     SourceFile *m_sourceFile;
00144     QStringList m_lines;
00145 
00146     KJSDebugWin *m_debugWin;
00147     QFont m_font;
00148     QPixmap m_breakpointIcon;
00149   };
00150 
00160   class KJSDebugWin : public KMainWindow, public Debugger, public KInstance
00161   {
00162     Q_OBJECT
00163     friend class SourceDisplay;
00164   public:
00165     KJSDebugWin(QWidget *parent=0, const char *name=0);
00166     virtual ~KJSDebugWin();
00167 
00168     static KJSDebugWin *createInstance();
00169     static void destroyInstance();
00170     static KJSDebugWin *debugWindow() { return kjs_html_debugger; }
00171 
00172     enum Mode { Disabled = 0, // No break on any statements
00173         Next     = 1, // Will break on next statement in current context
00174         Step     = 2, // Will break on next statement in current or deeper context
00175         Continue = 3, // Will continue until next breakpoint
00176         Stop     = 4  // The script will stop execution completely,
00177                   // as soon as possible
00178     };
00179 
00180     void setSourceLine(int sourceId, int lineno);
00181     void setNextSourceInfo(QString url, int baseLine);
00182     void sourceChanged(Interpreter *interpreter, QString url);
00183     bool inSession() const { return !m_execStates.isEmpty(); }
00184     void setMode(Mode m) { m_mode = m; }
00185     void clearInterpreter(Interpreter *interpreter);
00186     ExecState *getExecState() const { return m_execStates.top(); }
00187 
00188     // functions overridden from KJS:Debugger
00189     bool sourceParsed(ExecState *exec, int sourceId,
00190               const UString &source, int errorLine);
00191     bool sourceUnused(ExecState * exec, int sourceId);
00192     bool exception(ExecState *exec, const Value &value, bool inTryCatch);
00193     bool atStatement(ExecState *exec);
00194     bool enterContext(ExecState *exec);
00195     bool exitContext(ExecState *exec, const Completion &completion);
00196 
00197   public slots:
00198     void slotNext();
00199     void slotStep();
00200     void slotContinue();
00201     void slotStop();
00202     void slotBreakNext();
00203     void slotToggleBreakpoint(int lineno);
00204     void slotShowFrame(int frameno);
00205     void slotSourceSelected(int sourceSelIndex);
00206     void slotEval();
00207 
00208   protected:
00209 
00210     void closeEvent(QCloseEvent *e);
00211     bool eventFilter(QObject *obj, QEvent *evt);
00212     void disableOtherWindows();
00213     void enableOtherWindows();
00214 
00215   private:
00216 
00217     SourceFile *getSourceFile(Interpreter *interpreter, QString url);
00218     void setSourceFile(Interpreter *interpreter, QString url, SourceFile *sourceFile);
00219     void removeSourceFile(Interpreter *interpreter, QString url);
00220 
00221     void checkBreak(ExecState *exec);
00222     void enterSession(ExecState *exec);
00223     void leaveSession();
00224     void displaySourceFile(SourceFile *sourceFile, bool forceRefresh);
00225     void updateContextList();
00226 
00227     QString contextStr(const Context &ctx);
00228 
00229     struct Breakpoint {
00230       int sourceId;
00231       int lineno;
00232     };
00233     Breakpoint *m_breakpoints;
00234     int m_breakpointCount;
00235     bool setBreakpoint(int sourceId, int lineno);
00236     bool deleteBreakpoint(int sourceId, int lineno);
00237     bool haveBreakpoint(SourceFile *sourceFile, int line0, int line1);
00238     bool haveBreakpoint(int sourceId, int line0, int line1) const {
00239       for (int i = 0; i < m_breakpointCount; i++) {
00240     if (m_breakpoints[i].sourceId == sourceId &&
00241         m_breakpoints[i].lineno >= line0 &&
00242         m_breakpoints[i].lineno <= line1)
00243       return true;
00244       }
00245       return false;
00246     }
00247 
00248     SourceFile *m_curSourceFile;
00249     Mode m_mode;
00250     QString m_nextSourceUrl;
00251     int m_nextSourceBaseLine;
00252     QPtrStack<ExecState> m_execStates;
00253     ExecState **m_execs;
00254     int m_execsCount;
00255     int m_execsAlloc;
00256     int m_steppingDepth;
00257 
00258     QMap<QString,SourceFile*> m_sourceFiles; /* maps url->SourceFile */
00259     QMap<int,SourceFragment*> m_sourceFragments; /* maps SourceId->SourceFragment */
00260     QPtrList<SourceFile> m_sourceSelFiles; /* maps combobox index->SourceFile */
00261 
00262     KActionCollection *m_actionCollection;
00263     QPixmap m_stopIcon;
00264     QPixmap m_emptyIcon;
00265     SourceDisplay *m_sourceDisplay;
00266     QListBox *m_contextList;
00267 
00268     KAction *m_stepAction;
00269     KAction *m_nextAction;
00270     KAction *m_continueAction;
00271     KAction *m_stopAction;
00272     KAction *m_breakAction;
00273 
00274     QComboBox *m_sourceSel;
00275     EvalMultiLineEdit *m_evalEdit;
00276     int m_evalDepth;
00277 
00278     static KJSDebugWin *kjs_html_debugger;
00279   };
00280 
00281 } // namespace
00282 
00283 #endif // KJS_DEBUGGER
00284 
00285 #endif // _KJS_DEBUGGER_H_
KDE Home | KDE Accessibility Home | Description of Access Keys