summaryrefslogtreecommitdiffstats
path: root/languages/ruby/debugger/debuggerpart.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'languages/ruby/debugger/debuggerpart.cpp')
-rw-r--r--languages/ruby/debugger/debuggerpart.cpp785
1 files changed, 785 insertions, 0 deletions
diff --git a/languages/ruby/debugger/debuggerpart.cpp b/languages/ruby/debugger/debuggerpart.cpp
new file mode 100644
index 00000000..95b4dd09
--- /dev/null
+++ b/languages/ruby/debugger/debuggerpart.cpp
@@ -0,0 +1,785 @@
+/***************************************************************************
+ * Copyright (C) 1999-2001 by John Birch *
+ * Copyright (C) 2001 by Bernd Gehrmann *
+ * *
+ * Adapted for ruby debugging *
+ * -------------------------- *
+ * begin : Mon Nov 1 2004 *
+ * copyright : (C) 2004 by Richard Dale *
+ * email : [email protected] *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#include "debuggerpart.h"
+
+#include <qdir.h>
+#include <qvbox.h>
+#include <qwhatsthis.h>
+#include <qpopupmenu.h>
+
+#include <kaction.h>
+#include <kdebug.h>
+#include <kfiledialog.h>
+#include <kdevgenericfactory.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmainwindow.h>
+#include <kstatusbar.h>
+#include <kparts/part.h>
+#include <ktexteditor/viewcursorinterface.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <qtimer.h>
+#include <kstringhandler.h>
+#include <kstandarddirs.h>
+
+#include "kdevcore.h"
+#include "kdevproject.h"
+#include "kdevmainwindow.h"
+#include "kdevappfrontend.h"
+#include "kdevpartcontroller.h"
+#include "kdevdebugger.h"
+#include "domutil.h"
+#include "variablewidget.h"
+#include "rdbbreakpointwidget.h"
+#include "framestackwidget.h"
+#include "processwidget.h"
+#include "rdbcontroller.h"
+#include "breakpoint.h"
+#include "dbgpsdlg.h"
+#include "dbgtoolbar.h"
+#include "rdbparser.h"
+#include "rdboutputwidget.h"
+#include "processlinemaker.h"
+
+#include <iostream>
+
+#include <kdevplugininfo.h>
+#include <debugger.h>
+
+
+namespace RDBDebugger
+{
+static const KDevPluginInfo data("kdevrbdebugger");
+
+typedef KDevGenericFactory<RubyDebuggerPart> RubyDebuggerFactory;
+K_EXPORT_COMPONENT_FACTORY( libkdevrbdebugger, RubyDebuggerFactory( data ) )
+
+RubyDebuggerPart::RubyDebuggerPart( QObject *parent, const char *name, const QStringList & ) :
+ KDevPlugin( &data, parent, name ? name : "RubyDebuggerPart" ),
+ controller(0)
+{
+// setObjId("RubyDebuggerInterface");
+ setInstance(RubyDebuggerFactory::instance());
+
+ setXMLFile("kdevrbdebugger.rc");
+
+ m_debugger = new Debugger( partController() );
+
+ statusBarIndicator = new QLabel(" ", mainWindow()->statusBar());
+ statusBarIndicator->setFixedWidth(15);
+ mainWindow()->statusBar()->addWidget(statusBarIndicator, 0, true);
+ statusBarIndicator->show();
+
+ // Setup widgets and dbgcontroller
+ variableWidget = new VariableWidget( 0, "rdbVariablewidget");
+// /*variableWidget*/->setEnabled(false);
+ variableWidget->setIcon(SmallIcon("math_brace"));
+ variableWidget->setCaption(i18n("Variable Tree"));
+ QWhatsThis::add
+ (variableWidget, i18n("<b>Variable tree</b><p>"
+ "The variable tree allows you to see "
+ "the variable values as you step "
+ "through your program using the internal "
+ "debugger. Click the right mouse button on items in "
+ "this view to get a popup menu.\n"
+ "To speed up stepping through your code "
+ "leave the tree items closed.\n"));
+ mainWindow()->embedSelectView(variableWidget, i18n("Variables"), i18n("Debugger variable-view"));
+
+// mainWindow()->setViewAvailable(variableWidget, false);
+
+ rdbBreakpointWidget = new RDBBreakpointWidget( 0, "rdbBreakpointWidget" );
+ rdbBreakpointWidget->setCaption(i18n("Breakpoint List"));
+ QWhatsThis::add
+ (rdbBreakpointWidget, i18n("<b>Breakpoint list</b><p>"
+ "Displays a list of breakpoints with "
+ "their current status. Clicking on a "
+ "breakpoint item allows you to change "
+ "the breakpoint and will take you "
+ "to the source in the editor window."));
+ rdbBreakpointWidget->setIcon( SmallIcon("stop") );
+ mainWindow()->embedOutputView(rdbBreakpointWidget, i18n("Breakpoints"), i18n("Debugger breakpoints"));
+
+ framestackWidget = new FramestackWidget( 0, "rdbFramestackWidget" );
+ framestackWidget->setEnabled(false);
+ framestackWidget->setCaption(i18n("Frame Stack"));
+ QWhatsThis::add
+ (framestackWidget, i18n("<b>Frame stack</b><p>"
+ "Often referred to as the \"call stack\", "
+ "this is a list showing what method is "
+ "currently active and who called each "
+ "method to get to this point in your "
+ "program. By clicking on an item you "
+ "can see the values in any of the "
+ "previous calling methods."));
+ framestackWidget->setIcon( SmallIcon("table") );
+ mainWindow()->embedOutputView(framestackWidget, i18n("Frame Stack"), i18n("Debugger method call stack"));
+ mainWindow()->setViewAvailable(framestackWidget, false);
+
+
+ rdbOutputWidget = new RDBOutputWidget( 0, "rdbOutputWidget" );
+ rdbOutputWidget->setEnabled(false);
+ rdbOutputWidget->setIcon( SmallIcon("inline_image") );
+ rdbOutputWidget->setCaption(i18n("RDB Output"));
+ QWhatsThis::add
+ (rdbOutputWidget, i18n("<b>RDB output</b><p>"
+ "Shows all rdb commands being executed. "
+ "You can also issue any other rdb command while debugging."));
+ mainWindow()->embedOutputView(rdbOutputWidget, i18n("RDB"),
+ i18n("RDB output"));
+ mainWindow()->setViewAvailable(rdbOutputWidget, false);
+
+ // rdbBreakpointWidget -> this
+ connect( rdbBreakpointWidget, SIGNAL(refreshBPState(const Breakpoint&)),
+ this, SLOT(slotRefreshBPState(const Breakpoint&)));
+ connect( rdbBreakpointWidget, SIGNAL(publishBPState(const Breakpoint&)),
+ this, SLOT(slotRefreshBPState(const Breakpoint&)));
+ connect( rdbBreakpointWidget, SIGNAL(gotoSourcePosition(const QString&, int)),
+ this, SLOT(slotGotoSource(const QString&, int)) );
+
+ // Now setup the actions
+ KAction *action;
+
+// action = new KAction(i18n("&Start"), "1rightarrow", CTRL+SHIFT+Key_F9,
+ action = new KAction(i18n("&Start"), "dbgrun", CTRL+SHIFT+Key_F9,
+ this, SLOT(slotRun()),
+ actionCollection(), "debug_run");
+ action->setToolTip( i18n("Start in debugger") );
+ action->setWhatsThis( i18n("<b>Start in debugger</b><p>"
+ "Starts the debugger with the project's main "
+ "executable. You may set some breakpoints "
+ "before this, or you can interrupt the program "
+ "while it is running, in order to get information "
+ "about variables, frame stack, and so on.") );
+
+ action = new KAction(i18n("Sto&p"), "stop", 0,
+ this, SLOT(slotStop()),
+ actionCollection(), "debug_stop");
+ action->setToolTip( i18n("Stop debugger") );
+ action->setWhatsThis(i18n("<b>Stop debugger</b><p>Kills the executable and exits the debugger."));
+
+ action = new KAction(i18n("Interrupt"), "player_pause", 0,
+ this, SLOT(slotPause()),
+ actionCollection(), "debug_pause");
+ action->setToolTip( i18n("Interrupt application") );
+ action->setWhatsThis(i18n("<b>Interrupt application</b><p>Interrupts the debugged process or current RDB command."));
+
+ action = new KAction(i18n("Run to &Cursor"), "dbgrunto", 0,
+ this, SLOT(slotRunToCursor()),
+ actionCollection(), "debug_runtocursor");
+ action->setToolTip( i18n("Run to cursor") );
+ action->setWhatsThis(i18n("<b>Run to cursor</b><p>Continues execution until the cursor position is reached."));
+
+
+ action = new KAction(i18n("Step &Over"), "dbgnext", 0,
+ this, SLOT(slotStepOver()),
+ actionCollection(), "debug_stepover");
+ action->setToolTip( i18n("Step over the next line") );
+ action->setWhatsThis( i18n("<b>Step over</b><p>"
+ "Executes one line of source in the current source file. "
+ "If the source line is a call to a method the whole "
+ "method is executed and the app will stop at the line "
+ "following the method call.") );
+
+
+ action = new KAction(i18n("Step &Into"), "dbgstep", 0,
+ this, SLOT(slotStepInto()),
+ actionCollection(), "debug_stepinto");
+ action->setToolTip( i18n("Step into the next statement") );
+ action->setWhatsThis( i18n("<b>Step into</b><p>"
+ "Executes exactly one line of source. If the source line "
+ "is a call to a method then execution will stop after "
+ "the method has been entered.") );
+
+
+
+ action = new KAction(i18n("Step O&ut"), "dbgstepout", 0,
+ this, SLOT(slotStepOut()),
+ actionCollection(), "debug_stepout");
+ action->setToolTip( i18n("Steps out of the current method") );
+ action->setWhatsThis( i18n("<b>Step out</b><p>"
+ "Executes the application until the currently executing "
+ "method is completed. The debugger will then display "
+ "the line after the original call to that method. If "
+ "program execution is in the outermost frame (i.e. in "
+ "the topleveltoggleWatchpoint) then this operation has no effect.") );
+
+
+ action = new KAction(i18n("Toggle Breakpoint"), 0, 0,
+ this, SLOT(toggleBreakpoint()),
+ actionCollection(), "debug_toggle_breakpoint");
+ action->setToolTip(i18n("Toggle breakpoint"));
+ action->setWhatsThis(i18n("<b>Toggle breakpoint</b><p>Toggles the breakpoint at the current line in editor."));
+
+ connect( mainWindow()->main()->guiFactory(), SIGNAL(clientAdded(KXMLGUIClient*)),
+ this, SLOT(guiClientAdded(KXMLGUIClient*)) );
+
+
+ connect( partController(), SIGNAL(loadedFile(const KURL &)),
+ rdbBreakpointWidget, SLOT(slotRefreshBP(const KURL &)) );
+ connect( debugger(), SIGNAL(toggledBreakpoint(const QString &, int)),
+ rdbBreakpointWidget, SLOT(slotToggleBreakpoint(const QString &, int)) );
+ connect( debugger(), SIGNAL(editedBreakpoint(const QString &, int)),
+ rdbBreakpointWidget, SLOT(slotEditBreakpoint(const QString &, int)) );
+ connect( debugger(), SIGNAL(toggledBreakpointEnabled(const QString &, int)),
+ rdbBreakpointWidget, SLOT(slotToggleBreakpointEnabled(const QString &, int)) );
+
+ connect( core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)),
+ this, SLOT(contextMenu(QPopupMenu *, const Context *)) );
+
+ connect( core(), SIGNAL(stopButtonClicked(KDevPlugin*)),
+ this, SLOT(slotStop(KDevPlugin*)) );
+ connect( core(), SIGNAL(projectClosed()),
+ this, SLOT(projectClosed()) );
+
+ connect( partController(), SIGNAL(activePartChanged(KParts::Part*)),
+ this, SLOT(slotActivePartChanged(KParts::Part*)) );
+
+ procLineMaker = new ProcessLineMaker();
+
+ connect( procLineMaker, SIGNAL(receivedStdoutLine(const QCString&)),
+ appFrontend(), SLOT(insertStdoutLine(const QCString&)) );
+ connect( procLineMaker, SIGNAL(receivedStderrLine(const QCString&)),
+ appFrontend(), SLOT(insertStderrLine(const QCString&)) );
+ connect( procLineMaker, SIGNAL(receivedPartialStdoutLine(const QCString&)),
+ appFrontend(), SLOT(addPartialStdoutLine(const QCString&)) );
+ connect( procLineMaker, SIGNAL(receivedPartialStderrLine(const QCString&)),
+ appFrontend(), SLOT(addPartialStderrLine(const QCString&)) );
+
+ setupController();
+ QTimer::singleShot(0, this, SLOT(setupDcop()));
+}
+
+RubyDebuggerPart::~RubyDebuggerPart()
+{
+ kapp->dcopClient()->setNotifications(false);
+
+ if (variableWidget)
+ mainWindow()->removeView(variableWidget);
+ if (rdbBreakpointWidget)
+ mainWindow()->removeView(rdbBreakpointWidget);
+ if (framestackWidget)
+ mainWindow()->removeView(framestackWidget);
+ if(rdbOutputWidget)
+ mainWindow()->removeView(rdbOutputWidget);
+
+ delete variableWidget;
+ delete rdbBreakpointWidget;
+ delete framestackWidget;
+ delete rdbOutputWidget;
+ delete controller;
+ delete floatingToolBar;
+ delete statusBarIndicator;
+ delete procLineMaker;
+}
+
+
+void RubyDebuggerPart::guiClientAdded( KXMLGUIClient* client )
+{
+ // Can't change state until after XMLGUI has been loaded...
+ // Anyone know of a better way of doing this?
+ if( client == this )
+ stateChanged( QString("stopped") );
+}
+
+void RubyDebuggerPart::contextMenu(QPopupMenu *popup, const Context *context)
+{
+ if (!context->hasType( Context::EditorContext ))
+ return;
+
+ const EditorContext *econtext = static_cast<const EditorContext*>(context);
+ m_contextIdent = econtext->currentWord();
+
+ popup->insertSeparator();
+ if (econtext->url().isLocalFile())
+ {
+ int id = popup->insertItem( i18n("Toggle Breakpoint"), this, SLOT(toggleBreakpoint()) );
+ popup->setWhatsThis(id, i18n("<b>Toggle breakpoint</b><p>Toggles breakpoint at the current line."));
+ }
+ if (!m_contextIdent.isEmpty())
+ {
+ QString squeezed = KStringHandler::csqueeze(m_contextIdent, 30);
+ int id = popup->insertItem( i18n("Watch: %1").arg(squeezed), this, SLOT(contextWatch()) );
+ popup->setWhatsThis(id, i18n("<b>Watch</b><p>Adds an expression under the cursor to the Variables/Watch list."));
+
+ id = popup->insertItem( i18n("Inspect: %1").arg(squeezed), this, SLOT(contextRubyInspect()) );
+ popup->setWhatsThis(id, i18n("<b>Inspect</b><p>Evaluates an expression under the cursor."));
+ }
+}
+
+
+void RubyDebuggerPart::toggleBreakpoint()
+{
+ KParts::ReadWritePart *rwpart
+ = dynamic_cast<KParts::ReadWritePart*>(partController()->activePart());
+ KTextEditor::ViewCursorInterface *cursorIface
+ = dynamic_cast<KTextEditor::ViewCursorInterface*>(partController()->activeWidget());
+
+ if (!rwpart || !cursorIface)
+ return;
+
+ uint line, col;
+ cursorIface->cursorPositionReal(&line, &col);
+
+ rdbBreakpointWidget->slotToggleBreakpoint(rwpart->url().path(), line);
+}
+
+
+void RubyDebuggerPart::contextWatch()
+{
+ variableWidget->slotAddWatchExpression(m_contextIdent);
+}
+
+// Evaluates the selected text
+void RubyDebuggerPart::contextRubyInspect()
+{
+ emit rubyInspect(m_contextIdent);
+}
+
+
+void RubyDebuggerPart::setupController()
+{
+ VariableTree *variableTree = variableWidget->varTree();
+
+ controller = new RDBController(variableTree, framestackWidget, *projectDom());
+
+ // this -> controller
+ connect( this, SIGNAL(rubyInspect(const QString&)),
+ controller, SLOT(slotRubyInspect(const QString&)));
+
+ // variableTree -> framestackWidget
+ connect( variableTree, SIGNAL(selectFrame(int, int)),
+ framestackWidget, SLOT(slotSelectFrame(int, int)));
+
+ // framestackWidget -> variableTree
+ connect( framestackWidget, SIGNAL(frameActive(int, int, const QString&)),
+ variableTree, SLOT(slotFrameActive(int, int, const QString&)));
+
+ // variableTree -> controller
+ connect( variableTree, SIGNAL(expandItem(VarItem*, const QCString&)),
+ controller, SLOT(slotExpandItem(VarItem*, const QCString&)));
+ connect( variableTree, SIGNAL(fetchGlobals(bool)),
+ controller, SLOT(slotFetchGlobals(bool)));
+ connect( variableTree, SIGNAL(addWatchExpression(const QString&, bool)),
+ controller, SLOT(slotAddWatchExpression(const QString&, bool)));
+ connect( variableTree, SIGNAL(removeWatchExpression(int)),
+ controller, SLOT(slotRemoveWatchExpression(int)));
+
+ // framestackWidget -> controller
+ connect( framestackWidget, SIGNAL(selectFrame(int,int,const QString&)),
+ controller, SLOT(slotSelectFrame(int,int,const QString&)));
+
+ // rdbBreakpointWidget -> controller
+ connect( rdbBreakpointWidget, SIGNAL(clearAllBreakpoints()),
+ controller, SLOT(slotClearAllBreakpoints()));
+ connect( rdbBreakpointWidget, SIGNAL(publishBPState(const Breakpoint&)),
+ controller, SLOT(slotBPState(const Breakpoint &)));
+
+
+ // rdbOutputWidget -> controller
+ connect( rdbOutputWidget, SIGNAL(userRDBCmd(const QString &)),
+ controller, SLOT(slotUserRDBCmd(const QString&)));
+ connect( rdbOutputWidget, SIGNAL(breakInto()),
+ controller, SLOT(slotBreakInto()));
+
+ // controller -> rdbBreakpointWidget
+ connect( controller, SIGNAL(acceptPendingBPs()),
+ rdbBreakpointWidget, SLOT(slotSetPendingBPs()));
+ connect( controller, SIGNAL(unableToSetBPNow(int)),
+ rdbBreakpointWidget, SLOT(slotUnableToSetBPNow(int)));
+ connect( controller, SIGNAL(rawRDBBreakpointList (char*)),
+ rdbBreakpointWidget, SLOT(slotParseRDBBrkptList(char*)));
+ connect( controller, SIGNAL(rawRDBBreakpointSet(char*, int)),
+ rdbBreakpointWidget, SLOT(slotParseRDBBreakpointSet(char*, int)));
+
+
+ // controller -> this
+ connect( controller, SIGNAL(dbgStatus(const QString&, int)),
+ this, SLOT(slotStatus(const QString&, int)));
+ connect( controller, SIGNAL(showStepInSource(const QString&, int, const QString&)),
+ this, SLOT(slotShowStep(const QString&, int)));
+
+ // controller -> procLineMaker
+ connect( controller, SIGNAL(ttyStdout(const char*)),
+ procLineMaker, SLOT(slotReceivedStdout(const char*)));
+ connect( controller, SIGNAL(ttyStderr(const char*)),
+ procLineMaker, SLOT(slotReceivedStderr(const char*)));
+
+ // controller -> rdbOutputWidget
+ connect( controller, SIGNAL(rdbStdout(const char*)),
+ rdbOutputWidget, SLOT(slotReceivedStdout(const char*)) );
+ connect( controller, SIGNAL(rdbStderr(const char*)),
+ rdbOutputWidget, SLOT(slotReceivedStderr(const char*)) );
+ connect( controller, SIGNAL(dbgStatus(const QString&, int)),
+ rdbOutputWidget, SLOT(slotDbgStatus(const QString&, int)));
+
+}
+
+
+bool RubyDebuggerPart::startDebugger()
+{
+ QString build_dir; // Currently selected build directory
+ QString run_directory; // Directory from where the program should be run
+ QString program; // Absolute path to application
+ QString run_arguments; // Command line arguments to be passed to the application
+ QString ruby_interpreter; // Absolute path to the ruby interpreter
+ QString debuggee_path; // Absolute path to debuggee.rb debugger script
+ bool show_constants; // Show constants in the debugger
+ bool trace_into_ruby; // Trace into the ruby code installed under sitedir
+
+ if (project()) {
+ build_dir = project()->buildDirectory();
+ run_directory = DomUtil::readEntry(*projectDom(), "/kdevscriptproject/run/globalcwd");
+ if (run_directory.isEmpty())
+ run_directory = project()->buildDirectory();
+ }
+
+ int runMainProgram = DomUtil::readIntEntry(*projectDom(), "/kdevrubysupport/run/runmainprogram");
+
+ if (runMainProgram == 0) {
+ program = project()->projectDirectory() + "/" + DomUtil::readEntry(*projectDom(), "/kdevrubysupport/run/mainprogram");
+ } else {
+ KParts::ReadOnlyPart *ro_part = dynamic_cast<KParts::ReadOnlyPart*>(partController()->activePart());
+ if (ro_part != 0) {
+ program = ro_part->url().path();
+ }
+ }
+
+ run_arguments = DomUtil::readEntry(*projectDom(), "/kdevrubysupport/run/programargs");
+
+ QString shell = DomUtil::readEntry(*projectDom(), "/kdevrbdebugger/general/dbgshell");
+ if( !shell.isEmpty() )
+ {
+ QFileInfo info( shell );
+ if( info.isRelative() )
+ {
+ shell = build_dir + "/" + shell;
+ info.setFile( shell );
+ }
+ if( !info.exists() )
+ {
+ KMessageBox::error(
+ mainWindow()->main(),
+ i18n("Could not locate the debugging shell '%1'.").arg( shell ),
+ i18n("Debugging Shell Not Found") );
+ return false;
+ }
+ }
+
+ core()->running(this, true);
+
+ stateChanged( QString("active") );
+
+ KActionCollection *ac = actionCollection();
+ ac->action("debug_run")->setText( i18n("&Continue") );
+// ac->action("debug_run")->setIcon( "dbgrun" );
+ ac->action("debug_run")->setToolTip( i18n("Continues the application execution") );
+ ac->action("debug_run")->setWhatsThis( i18n("Continue application execution\n\n"
+ "Continues the execution of your application in the "
+ "debugger. This only takes effect when the application "
+ "has been halted by the debugger (i.e. a breakpoint has "
+ "been activated or the interrupt was pressed).") );
+
+
+// mainWindow()->setViewAvailable(variableWidget, true);
+ mainWindow()->setViewAvailable(framestackWidget, true);
+ mainWindow()->setViewAvailable(rdbOutputWidget, true);
+
+// variableWidget->setEnabled(true);
+ framestackWidget->setEnabled(true);
+
+ rdbOutputWidget->clear();
+ rdbOutputWidget->setEnabled(true);
+
+ if (DomUtil::readBoolEntry(*projectDom(), "/kdevrbdebugger/general/floatingtoolbar", false))
+ {
+ floatingToolBar = new DbgToolBar(this, mainWindow()->main());
+ floatingToolBar->show();
+ }
+
+ ruby_interpreter = DomUtil::readEntry(*projectDom(), "/kdevrubysupport/run/interpreter");
+
+ int coding = DomUtil::readIntEntry(*projectDom(), "/kdevrubysupport/run/charactercoding");
+ QString character_coding("-K");
+
+ switch (coding) {
+ case 0:
+ character_coding.append("A");
+ break;
+ case 1:
+ character_coding.append("E");
+ break;
+ case 2:
+ character_coding.append("S");
+ break;
+ case 3:
+ character_coding.append("U");
+ break;
+ }
+
+// ruby_interpreter.append(QString(" -K") + code);
+
+ debuggee_path = ::locate("data", "kdevrbdebugger/debuggee.rb", instance());
+
+ show_constants = DomUtil::readBoolEntry(*projectDom(), "/kdevrbdebugger/general/showconstants");
+ trace_into_ruby = DomUtil::readBoolEntry(*projectDom(), "/kdevrbdebugger/general/traceintoruby");
+
+ controller->slotStart(ruby_interpreter, character_coding, run_directory, debuggee_path, program, run_arguments, show_constants, trace_into_ruby);
+ return true;
+}
+
+void RubyDebuggerPart::slotStopDebugger()
+{
+ controller->slotStopDebugger();
+ debugger()->clearExecutionPoint();
+
+ delete floatingToolBar;
+ floatingToolBar = 0;
+
+ rdbBreakpointWidget->reset();
+ framestackWidget->clear();
+ variableWidget->varTree()->clear();
+
+// variableWidget->setEnabled(false);
+ framestackWidget->setEnabled(false);
+ rdbOutputWidget->setEnabled(false);
+
+// mainWindow()->setViewAvailable(variableWidget, false);
+ mainWindow()->setViewAvailable(framestackWidget, false);
+ mainWindow()->setViewAvailable(rdbOutputWidget, false);
+
+ KActionCollection *ac = actionCollection();
+ ac->action("debug_run")->setText( i18n("&Start") );
+// ac->action("debug_run")->setIcon( "1rightarrow" );
+ ac->action("debug_run")->setToolTip( i18n("Runs the program in the debugger") );
+ ac->action("debug_run")->setWhatsThis( i18n("Start in debugger\n\n"
+ "Starts the debugger with the project's main "
+ "executable. You may set some breakpoints "
+ "before this, or you can interrupt the program "
+ "while it is running, in order to get information "
+ "about variables, frame stack, and so on.") );
+
+ stateChanged( QString("stopped") );
+
+ core()->running(this, false);
+}
+
+void RubyDebuggerPart::projectClosed()
+{
+ slotStopDebugger();
+}
+
+void RubyDebuggerPart::slotRun()
+{
+ if (controller->stateIsOn(s_programExited)) {
+ rdbBreakpointWidget->reset();
+ }
+
+ if ( controller->stateIsOn( s_dbgNotStarted ) ) {
+ mainWindow()->statusBar()->message(i18n("Debugging program"), 1000);
+ mainWindow()->raiseView(rdbOutputWidget);
+ appFrontend()->clearView();
+ startDebugger();
+ } else {
+ KActionCollection *ac = actionCollection();
+ ac->action("debug_run")->setText( i18n("&Continue") );
+ ac->action("debug_run")->setToolTip( i18n("Continues the application execution") );
+ ac->action("debug_run")->setWhatsThis( i18n("Continue application execution\n\n"
+ "Continues the execution of your application in the "
+ "debugger. This only takes effect when the application "
+ "has been halted by the debugger (i.e. a breakpoint has "
+ "been activated or the interrupt was pressed).") );
+
+ mainWindow()->statusBar()->message(i18n("Continuing program"), 1000);
+ }
+
+ controller->slotRun();
+}
+
+
+
+void RubyDebuggerPart::slotStop(KDevPlugin* which)
+{
+ if( which != 0 && which != this )
+ return;
+
+// if( !controller->stateIsOn( s_dbgNotStarted ) && !controller->stateIsOn( s_shuttingDown ) )
+ slotStopDebugger();
+}
+
+
+void RubyDebuggerPart::slotPause()
+{
+ controller->slotBreakInto();
+}
+
+
+void RubyDebuggerPart::slotRunToCursor()
+{
+ KParts::ReadWritePart *rwpart
+ = dynamic_cast<KParts::ReadWritePart*>(partController()->activePart());
+ KTextEditor::ViewCursorInterface *cursorIface
+ = dynamic_cast<KTextEditor::ViewCursorInterface*>(partController()->activeWidget());
+
+ if (!rwpart || !rwpart->url().isLocalFile() || !cursorIface)
+ return;
+
+ uint line, col;
+ cursorIface->cursorPosition(&line, &col);
+
+ controller->slotRunUntil(rwpart->url().path(), line);
+}
+
+void RubyDebuggerPart::slotStepOver()
+{
+ controller->slotStepOver();
+}
+
+
+
+void RubyDebuggerPart::slotStepInto()
+{
+ controller->slotStepInto();
+}
+
+
+void RubyDebuggerPart::slotStepOut()
+{
+ controller->slotStepOutOff();
+}
+
+
+
+
+void RubyDebuggerPart::slotRefreshBPState( const Breakpoint& BP)
+{
+ if (BP.type() == BP_TYPE_FilePos)
+ {
+ const FilePosBreakpoint& bp = dynamic_cast<const FilePosBreakpoint&>(BP);
+ if (bp.isActionDie())
+ debugger()->setBreakpoint(bp.fileName(), bp.lineNum()-1, -1, true, false);
+ else
+ debugger()->setBreakpoint(bp.fileName(), bp.lineNum()-1,
+ 1/*bp->id()*/, bp.isEnabled(), bp.isPending() );
+ }
+}
+
+
+void RubyDebuggerPart::slotStatus(const QString &msg, int state)
+{
+ QString stateIndicator;
+
+ if (state & s_dbgNotStarted)
+ {
+ stateIndicator = " ";
+ }
+ else if (state & s_appBusy)
+ {
+ stateIndicator = "A";
+ debugger()->clearExecutionPoint();
+ stateChanged( QString("active") );
+ }
+ else if (state & s_programExited)
+ {
+ stateIndicator = "E";
+ stateChanged( QString("stopped") );
+ KActionCollection *ac = actionCollection();
+ ac->action("debug_run")->setText( i18n("Restart") );
+// ac->action("debug_run")->setIcon( "1rightarrow" );
+ ac->action("debug_run")->setToolTip( i18n("Restart the program in the debugger") );
+ ac->action("debug_run")->setWhatsThis( i18n("Restart in debugger\n\n"
+ "Restarts the program in the debugger") );
+// slotStop();
+ }
+ else
+ {
+ stateIndicator = "P";
+ stateChanged( QString("paused") );
+ }
+
+ // And now? :-)
+ kdDebug(9012) << "Debugger state: " << stateIndicator << ": " << endl;
+ kdDebug(9012) << " " << msg << endl;
+
+ statusBarIndicator->setText(stateIndicator);
+ if (!msg.isEmpty())
+ mainWindow()->statusBar()->message(msg, 3000);
+}
+
+
+void RubyDebuggerPart::slotShowStep(const QString &fileName, int lineNum)
+{
+ if ( ! fileName.isEmpty() )
+ {
+ // Debugger counts lines from 1
+ debugger()->gotoExecutionPoint(KURL( fileName ), lineNum-1);
+ }
+}
+
+
+void RubyDebuggerPart::slotGotoSource(const QString &fileName, int lineNum)
+{
+ if ( ! fileName.isEmpty() )
+ partController()->editDocument(KURL( fileName ), lineNum);
+}
+
+
+void RubyDebuggerPart::slotActivePartChanged( KParts::Part* part )
+{
+ KAction* action = actionCollection()->action("debug_toggle_breakpoint");
+ if(!action)
+ return;
+
+ if(!part)
+ {
+ action->setEnabled(false);
+ return;
+ }
+ KTextEditor::ViewCursorInterface *iface
+ = dynamic_cast<KTextEditor::ViewCursorInterface*>(part->widget());
+ action->setEnabled( iface != 0 );
+}
+
+void RubyDebuggerPart::restorePartialProjectSession(const QDomElement* el)
+{
+ rdbBreakpointWidget->restorePartialProjectSession(el);
+ variableWidget->restorePartialProjectSession(el);
+}
+
+void RubyDebuggerPart::savePartialProjectSession(QDomElement* el)
+{
+ rdbBreakpointWidget->savePartialProjectSession(el);
+ variableWidget->savePartialProjectSession(el);
+}
+
+}
+
+KDevAppFrontend * RDBDebugger::RubyDebuggerPart::appFrontend( )
+{
+ return extension<KDevAppFrontend>("KDevelop/AppFrontend");
+}
+
+KDevDebugger * RDBDebugger::RubyDebuggerPart::debugger()
+{
+ return m_debugger;
+}
+
+#include "debuggerpart.moc"