/*************************************************************************** * Copyright (C) 1999-2001 by John Birch * * jbb@kdevelop.org * * Copyright (C) 2001 by Bernd Gehrmann * * bernd@kdevelop.org * * * * Adapted for ruby debugging * * -------------------------- * * begin : Mon Nov 1 2004 * * copyright : (C) 2004 by Richard Dale * * email : Richard_Dale@tipitina.demon.co.uk * * * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tdevcore.h" #include "tdevproject.h" #include "tdevmainwindow.h" #include "tdevappfrontend.h" #include "tdevpartcontroller.h" #include "tdevdebugger.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 #include #include namespace RDBDebugger { static const TDevPluginInfo data("tdevrbdebugger"); typedef TDevGenericFactory RubyDebuggerFactory; K_EXPORT_COMPONENT_FACTORY( libtdevrbdebugger, RubyDebuggerFactory( data ) ) RubyDebuggerPart::RubyDebuggerPart( TQObject *parent, const char *name, const TQStringList & ) : TDevPlugin( &data, parent, name ? name : "RubyDebuggerPart" ), controller(0) { // setObjId("RubyDebuggerInterface"); setInstance(RubyDebuggerFactory::instance()); setXMLFile("tdevrbdebugger.rc"); m_debugger = new Debugger( partController() ); statusBarIndicator = new TQLabel(" ", 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")); TQWhatsThis::add (variableWidget, i18n("Variable tree

" "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")); TQWhatsThis::add (rdbBreakpointWidget, i18n("Breakpoint list

" "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")); TQWhatsThis::add (framestackWidget, i18n("Frame stack

" "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")); TQWhatsThis::add (rdbOutputWidget, i18n("RDB output

" "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, TQT_SIGNAL(refreshBPState(const Breakpoint&)), this, TQT_SLOT(slotRefreshBPState(const Breakpoint&))); connect( rdbBreakpointWidget, TQT_SIGNAL(publishBPState(const Breakpoint&)), this, TQT_SLOT(slotRefreshBPState(const Breakpoint&))); connect( rdbBreakpointWidget, TQT_SIGNAL(gotoSourcePosition(const TQString&, int)), this, TQT_SLOT(slotGotoSource(const TQString&, int)) ); // Now setup the actions TDEAction *action; // action = new TDEAction(i18n("&Start"), "1rightarrow", CTRL+SHIFT+Key_F9, action = new TDEAction(i18n("&Start"), "dbgrun", CTRL+SHIFT+Key_F9, this, TQT_SLOT(slotRun()), actionCollection(), "debug_run"); action->setToolTip( i18n("Start in debugger") ); action->setWhatsThis( i18n("Start in debugger

" "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 TDEAction(i18n("Sto&p"), "stop", 0, this, TQT_SLOT(slotStop()), actionCollection(), "debug_stop"); action->setToolTip( i18n("Stop debugger") ); action->setWhatsThis(i18n("Stop debugger

Kills the executable and exits the debugger.")); action = new TDEAction(i18n("Interrupt"), "player_pause", 0, this, TQT_SLOT(slotPause()), actionCollection(), "debug_pause"); action->setToolTip( i18n("Interrupt application") ); action->setWhatsThis(i18n("Interrupt application

Interrupts the debugged process or current RDB command.")); action = new TDEAction(i18n("Run to &Cursor"), "dbgrunto", 0, this, TQT_SLOT(slotRunToCursor()), actionCollection(), "debug_runtocursor"); action->setToolTip( i18n("Run to cursor") ); action->setWhatsThis(i18n("Run to cursor

Continues execution until the cursor position is reached.")); action = new TDEAction(i18n("Step &Over"), "dbgnext", 0, this, TQT_SLOT(slotStepOver()), actionCollection(), "debug_stepover"); action->setToolTip( i18n("Step over the next line") ); action->setWhatsThis( i18n("Step over

" "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 TDEAction(i18n("Step &Into"), "dbgstep", 0, this, TQT_SLOT(slotStepInto()), actionCollection(), "debug_stepinto"); action->setToolTip( i18n("Step into the next statement") ); action->setWhatsThis( i18n("Step into

" "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 TDEAction(i18n("Step O&ut"), "dbgstepout", 0, this, TQT_SLOT(slotStepOut()), actionCollection(), "debug_stepout"); action->setToolTip( i18n("Steps out of the current method") ); action->setWhatsThis( i18n("Step out

" "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 TDEAction(i18n("Toggle Breakpoint"), 0, 0, this, TQT_SLOT(toggleBreakpoint()), actionCollection(), "debug_toggle_breakpoint"); action->setToolTip(i18n("Toggle breakpoint")); action->setWhatsThis(i18n("Toggle breakpoint

Toggles the breakpoint at the current line in editor.")); connect( mainWindow()->main()->guiFactory(), TQT_SIGNAL(clientAdded(KXMLGUIClient*)), this, TQT_SLOT(guiClientAdded(KXMLGUIClient*)) ); connect( partController(), TQT_SIGNAL(loadedFile(const KURL &)), rdbBreakpointWidget, TQT_SLOT(slotRefreshBP(const KURL &)) ); connect( debugger(), TQT_SIGNAL(toggledBreakpoint(const TQString &, int)), rdbBreakpointWidget, TQT_SLOT(slotToggleBreakpoint(const TQString &, int)) ); connect( debugger(), TQT_SIGNAL(editedBreakpoint(const TQString &, int)), rdbBreakpointWidget, TQT_SLOT(slotEditBreakpoint(const TQString &, int)) ); connect( debugger(), TQT_SIGNAL(toggledBreakpointEnabled(const TQString &, int)), rdbBreakpointWidget, TQT_SLOT(slotToggleBreakpointEnabled(const TQString &, int)) ); connect( core(), TQT_SIGNAL(contextMenu(TQPopupMenu *, const Context *)), this, TQT_SLOT(contextMenu(TQPopupMenu *, const Context *)) ); connect( core(), TQT_SIGNAL(stopButtonClicked(TDevPlugin*)), this, TQT_SLOT(slotStop(TDevPlugin*)) ); connect( core(), TQT_SIGNAL(projectClosed()), this, TQT_SLOT(projectClosed()) ); connect( partController(), TQT_SIGNAL(activePartChanged(KParts::Part*)), this, TQT_SLOT(slotActivePartChanged(KParts::Part*)) ); procLineMaker = new ProcessLineMaker(); connect( procLineMaker, TQT_SIGNAL(receivedStdoutLine(const TQCString&)), appFrontend(), TQT_SLOT(insertStdoutLine(const TQCString&)) ); connect( procLineMaker, TQT_SIGNAL(receivedStderrLine(const TQCString&)), appFrontend(), TQT_SLOT(insertStderrLine(const TQCString&)) ); connect( procLineMaker, TQT_SIGNAL(receivedPartialStdoutLine(const TQCString&)), appFrontend(), TQT_SLOT(addPartialStdoutLine(const TQCString&)) ); connect( procLineMaker, TQT_SIGNAL(receivedPartialStderrLine(const TQCString&)), appFrontend(), TQT_SLOT(addPartialStderrLine(const TQCString&)) ); setupController(); TQTimer::singleShot(0, this, TQT_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( TQString("stopped") ); } void RubyDebuggerPart::contextMenu(TQPopupMenu *popup, const Context *context) { if (!context->hasType( Context::EditorContext )) return; const EditorContext *econtext = static_cast(context); m_contextIdent = econtext->currentWord(); popup->insertSeparator(); if (econtext->url().isLocalFile()) { int id = popup->insertItem( i18n("Toggle Breakpoint"), this, TQT_SLOT(toggleBreakpoint()) ); popup->setWhatsThis(id, i18n("Toggle breakpoint

Toggles breakpoint at the current line.")); } if (!m_contextIdent.isEmpty()) { TQString squeezed = KStringHandler::csqueeze(m_contextIdent, 30); int id = popup->insertItem( i18n("Watch: %1").arg(squeezed), this, TQT_SLOT(contextWatch()) ); popup->setWhatsThis(id, i18n("Watch

Adds an expression under the cursor to the Variables/Watch list.")); id = popup->insertItem( i18n("Inspect: %1").arg(squeezed), this, TQT_SLOT(contextRubyInspect()) ); popup->setWhatsThis(id, i18n("Inspect

Evaluates an expression under the cursor.")); } } void RubyDebuggerPart::toggleBreakpoint() { KParts::ReadWritePart *rwpart = dynamic_cast(partController()->activePart()); KTextEditor::ViewCursorInterface *cursorIface = dynamic_cast(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, TQT_SIGNAL(rubyInspect(const TQString&)), controller, TQT_SLOT(slotRubyInspect(const TQString&))); // variableTree -> framestackWidget connect( variableTree, TQT_SIGNAL(selectFrame(int, int)), framestackWidget, TQT_SLOT(slotSelectFrame(int, int))); // framestackWidget -> variableTree connect( framestackWidget, TQT_SIGNAL(frameActive(int, int, const TQString&)), variableTree, TQT_SLOT(slotFrameActive(int, int, const TQString&))); // variableTree -> controller connect( variableTree, TQT_SIGNAL(expandItem(VarItem*, const TQCString&)), controller, TQT_SLOT(slotExpandItem(VarItem*, const TQCString&))); connect( variableTree, TQT_SIGNAL(fetchGlobals(bool)), controller, TQT_SLOT(slotFetchGlobals(bool))); connect( variableTree, TQT_SIGNAL(addWatchExpression(const TQString&, bool)), controller, TQT_SLOT(slotAddWatchExpression(const TQString&, bool))); connect( variableTree, TQT_SIGNAL(removeWatchExpression(int)), controller, TQT_SLOT(slotRemoveWatchExpression(int))); // framestackWidget -> controller connect( framestackWidget, TQT_SIGNAL(selectFrame(int,int,const TQString&)), controller, TQT_SLOT(slotSelectFrame(int,int,const TQString&))); // rdbBreakpointWidget -> controller connect( rdbBreakpointWidget, TQT_SIGNAL(clearAllBreakpoints()), controller, TQT_SLOT(slotClearAllBreakpoints())); connect( rdbBreakpointWidget, TQT_SIGNAL(publishBPState(const Breakpoint&)), controller, TQT_SLOT(slotBPState(const Breakpoint &))); // rdbOutputWidget -> controller connect( rdbOutputWidget, TQT_SIGNAL(userRDBCmd(const TQString &)), controller, TQT_SLOT(slotUserRDBCmd(const TQString&))); connect( rdbOutputWidget, TQT_SIGNAL(breakInto()), controller, TQT_SLOT(slotBreakInto())); // controller -> rdbBreakpointWidget connect( controller, TQT_SIGNAL(acceptPendingBPs()), rdbBreakpointWidget, TQT_SLOT(slotSetPendingBPs())); connect( controller, TQT_SIGNAL(unableToSetBPNow(int)), rdbBreakpointWidget, TQT_SLOT(slotUnableToSetBPNow(int))); connect( controller, TQT_SIGNAL(rawRDBBreakpointList (char*)), rdbBreakpointWidget, TQT_SLOT(slotParseRDBBrkptList(char*))); connect( controller, TQT_SIGNAL(rawRDBBreakpointSet(char*, int)), rdbBreakpointWidget, TQT_SLOT(slotParseRDBBreakpointSet(char*, int))); // controller -> this connect( controller, TQT_SIGNAL(dbgStatus(const TQString&, int)), this, TQT_SLOT(slotStatus(const TQString&, int))); connect( controller, TQT_SIGNAL(showStepInSource(const TQString&, int, const TQString&)), this, TQT_SLOT(slotShowStep(const TQString&, int))); // controller -> procLineMaker connect( controller, TQT_SIGNAL(ttyStdout(const char*)), procLineMaker, TQT_SLOT(slotReceivedStdout(const char*))); connect( controller, TQT_SIGNAL(ttyStderr(const char*)), procLineMaker, TQT_SLOT(slotReceivedStderr(const char*))); // controller -> rdbOutputWidget connect( controller, TQT_SIGNAL(rdbStdout(const char*)), rdbOutputWidget, TQT_SLOT(slotReceivedStdout(const char*)) ); connect( controller, TQT_SIGNAL(rdbStderr(const char*)), rdbOutputWidget, TQT_SLOT(slotReceivedStderr(const char*)) ); connect( controller, TQT_SIGNAL(dbgStatus(const TQString&, int)), rdbOutputWidget, TQT_SLOT(slotDbgStatus(const TQString&, int))); } bool RubyDebuggerPart::startDebugger() { TQString build_dir; // Currently selected build directory TQString run_directory; // Directory from where the program should be run TQString program; // Absolute path to application TQString run_arguments; // Command line arguments to be passed to the application TQString ruby_interpreter; // Absolute path to the ruby interpreter TQString 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(partController()->activePart()); if (ro_part != 0) { program = ro_part->url().path(); } } run_arguments = DomUtil::readEntry(*projectDom(), "/kdevrubysupport/run/programargs"); TQString shell = DomUtil::readEntry(*projectDom(), "/kdevrbdebugger/general/dbgshell"); if( !shell.isEmpty() ) { TQFileInfo 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( TQString("active") ); TDEActionCollection *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"); TQString 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(TQString(" -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); TDEActionCollection *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( TQString("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 { TDEActionCollection *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(TDevPlugin* 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(partController()->activePart()); KTextEditor::ViewCursorInterface *cursorIface = dynamic_cast(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(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 TQString &msg, int state) { TQString stateIndicator; if (state & s_dbgNotStarted) { stateIndicator = " "; } else if (state & s_appBusy) { stateIndicator = "A"; debugger()->clearExecutionPoint(); stateChanged( TQString("active") ); } else if (state & s_programExited) { stateIndicator = "E"; stateChanged( TQString("stopped") ); TDEActionCollection *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( TQString("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 TQString &fileName, int lineNum) { if ( ! fileName.isEmpty() ) { // Debugger counts lines from 1 debugger()->gotoExecutionPoint(KURL( fileName ), lineNum-1); } } void RubyDebuggerPart::slotGotoSource(const TQString &fileName, int lineNum) { if ( ! fileName.isEmpty() ) partController()->editDocument(KURL( fileName ), lineNum); } void RubyDebuggerPart::slotActivePartChanged( KParts::Part* part ) { TDEAction* action = actionCollection()->action("debug_toggle_breakpoint"); if(!action) return; if(!part) { action->setEnabled(false); return; } KTextEditor::ViewCursorInterface *iface = dynamic_cast(part->widget()); action->setEnabled( iface != 0 ); } void RubyDebuggerPart::restorePartialProjectSession(const TQDomElement* el) { rdbBreakpointWidget->restorePartialProjectSession(el); variableWidget->restorePartialProjectSession(el); } void RubyDebuggerPart::savePartialProjectSession(TQDomElement* el) { rdbBreakpointWidget->savePartialProjectSession(el); variableWidget->savePartialProjectSession(el); } } TDevAppFrontend * RDBDebugger::RubyDebuggerPart::appFrontend( ) { return extension("TDevelop/AppFrontend"); } TDevDebugger * RDBDebugger::RubyDebuggerPart::debugger() { return m_debugger; } #include "debuggerpart.moc"