python_debugger.py :  » IDE » PIDA » pida-0.6beta3 » pida-plugins » python_debugger » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » IDE » PIDA 
PIDA » pida 0.6beta3 » pida plugins » python_debugger » python_debugger.py
# -*- coding: utf-8 -*- 

# Copyright (c) 2007 The PIDA Project

#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:

#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.

#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#SOFTWARE.


# Standard library imports
import os, sys, time, Queue, cgi

# GTK imports
import gtk, gobject

# kiwi imports
from kiwi.ui.objectlist import ObjectList,ObjectTree,Column
from kiwi.ui.dialogs import open

# PIDA Imports
from pida.core.service import Service
from pida.core.features import FeaturesConfig
from pida.core.commands import CommandsConfig
from pida.core.events import EventsConfig
from pida.core.actions import ActionsConfig
from pida.core.options import OptionsConfig
from pida.core.actions import (TYPE_NORMAL,TYPE_MENUTOOL,TYPE_RADIO
                               TYPE_TOGGLE, TYPE_REMEMBER_TOGGLE)
from pida.core.environment import get_uidef_path,get_pixmap_path

from pida.ui.views import PidaView
from pida.ui.terminal import PidaTerminal
from pida.utils.gthreads import AsyncTask

#from pida.utils import rpdb2
import rpdb2

# locale
from pida.core.locale import Locale
locale = Locale('python_debugger')
_ = locale.gettext


# rpdb2 overrides to force PIDA terminal use


class SessionManagerInternal(rpdb2.CSessionManagerInternal):


    

    def _spawn_server(self, fchdir, ExpandedFilename, args, rid):
        """
        Start an OS console to act as server.
        What it does is to start rpdb again in a new console in server only mode.
        """
        debugger = os.path.abspath(rpdb2.__file__)
        if debugger[-1] == 'c':
            debugger = debugger[:-1]
        baseargs = ['python', debugger, '--debugee', '--rid=%s' % rid]
        if fchdir:
            baseargs.append('--chdir')
        if not self.m_fAllowUnencrypted:
            baseargs.append('--encrypted')
        #if self.m_fRemote:
        #    baseargs.append('--remote')
        if os.name == 'nt':
            baseargs.append('--pwd=%s' % self.m_pwd)
        if 'PGD_DEBUG' in os.environ:
            baseargs.append('--debug')
        baseargs.append(ExpandedFilename)
        cmdargs = baseargs + args.split()
        python_exec = sys.executable
        self.terminal.fork_command(python_exec, cmdargs)



class SessionManager(rpdb2.CSessionManager):

    def __init__(self, manager, pwd, fAllowUnencrypted, fAllowRemote, host):
        self.manager = manager
        smi = self._CSessionManager__smi = SessionManagerInternal(
                            pwd, 
                            fAllowUnencrypted, 
                            fAllowRemote, 
                            host
                            )
        smi.terminal = self

    def _create_view(self):
        view = Terminal(self.app)
        self.main_window.attach_slave('outterm_holder', view)
        return view

    def fork_command(self, *args, **kw):
        def _launch(commandargs=args[1]):
            self.manager.svc.boss.cmd('commander', 'execute',
                commandargs=commandargs)
        gobject.idle_add(_launch)


class DebuggerManager(object):
    """Control the debugging process and views"""
    
    def __init__(self, svc):
        self.svc = svc
        rpdb2.main(self.start_client, argv=[])
        self.last_step = None
        self.connect_events()
        sm = self.session_manager
        self.locals_view = LocalsViewer(sm)
        self.globals_view = GlobalsViewer(sm)
        self.stack_view = StackViewer(sm)
        self.threads_view = ThreadsViewer(sm)
        self.breaks_view = BreakpointViewer(sm)
        self.breaks_view.manager = self
        self.console_view = DebuggerConsole(sm)
        self.terminal_view = PidaTerminal()

    def start_client(self, command_line, fAttach, fchdir, pwd, fAllowUnencrypted, fRemote, host):
        self.session_manager = SessionManager(self, pwd, fAllowUnencrypted, fRemote, host)

    def launch(self, commandline, change_directory=False):
        t = AsyncTask(self.session_manager.launch)
        t.start(change_directory, commandline)

    def connect_events(self):
        event_type_dict = {rpdb2.CEventState: {}}
        self.session_manager.register_callback(self.on_update_state, event_type_dict, fSingleUse = False)
        event_type_dict = {rpdb2.CEventStackFrameChange: {}}
        self.session_manager.register_callback(self.on_update_frame, event_type_dict, fSingleUse = False)
        event_type_dict = {rpdb2.CEventThreads: {}}
        self.session_manager.register_callback(self.on_update_threads, event_type_dict, fSingleUse = False)
        event_type_dict = {rpdb2.CEventNoThreads: {}}
        self.session_manager.register_callback(self.on_update_no_threads, event_type_dict, fSingleUse = False)
        event_type_dict = {rpdb2.CEventNamespace: {}}
        self.session_manager.register_callback(self.on_update_namespace, event_type_dict, fSingleUse = False)
        event_type_dict = {rpdb2.CEventThreadBroken: {}}
        self.session_manager.register_callback(self.on_update_thread_broken, event_type_dict, fSingleUse = False)
        event_type_dict = {rpdb2.CEventStack: {}}
        self.session_manager.register_callback(self.on_update_stack, event_type_dict, fSingleUse = False)
        event_type_dict = {rpdb2.CEventBreakpoint: {}}
        self.session_manager.register_callback(self.on_update_bp, event_type_dict, fSingleUse = False)

    def on_update_state(self, event):
        def update():
            self.console_view.write_info(event.m_state + '\n')
            self.svc.update_state(event.m_state)
        gobject.idle_add(update)

    def on_update_frame(self, event):
        print 'uf', dir(event)
        gobject.idle_add(self.stack_view.select_frame, event.m_frame_index)
        self.on_update_source(event.m_frame_index)

    def on_update_namespace(self, *args):
        gobject.idle_add(self.locals_view.update_namespace)
        gobject.idle_add(self.globals_view.update_namespace)

    def on_update_stack(self, event):
        self.last_stack = event.m_stack
        gobject.idle_add(self.stack_view.update_stack, event.m_stack)
        self.on_update_source(-1)

    def on_update_source(self, frame_index):
        def update():
            self.remove_last_step_mark()
            stack_item = self.last_stack['stack'][frame_index]
            filename, linenumber, level, code = stack_item
            self.svc.boss.cmd('buffer', 'open_file', file_name=filename)
            self.svc.boss.editor.cmd('goto_line', line=linenumber)
            self.svc.boss.editor.cmd('show_sign', type='step', 
                                                    file_name=filename,
                                                    line=linenumber)
            self.last_step = filename, linenumber
        stack_item = self.last_stack['stack'][frame_index]
        if 'rpdb2.py' not in stack_item[0]:
            gobject.idle_add(update)

    def remove_last_step_mark(self):
        if self.last_step is not None:
            lfile, lline = self.last_step
            self.svc.boss.editor.cmd('hide_sign', type='step', file_name=lfile, line=lline) 
            self.last_step = None
            

    def on_update_bp(self, event):
        def _u(event):
            act = event.m_action
            if event.m_bp is not None:
                filename = event.m_bp.m_filename
                linenumber = event.m_bp.m_lineno
                index = event.m_bp.m_id
                indices = None
            else:
                filename = None
                linenumber = None
                index = None
                indices = event.m_id_list
            self.breaks_view.update_bp(act, index, indices, filename, linenumber)
            #self.master.update_bp(act, index, indices, filename, linenumber)
        gobject.idle_add(_u, event)

    def on_update_no_threads(self, *args):
        print 'unt', args

    def on_update_threads(self, event):
        gobject.idle_add(self.threads_view.update_threads, event.m_thread_list, event.m_current_thread)

    def on_update_thread_broken(self, *args):
        print 'utb', args

    def set_breakpoint(self, index, filename, linenumber):
        print 'set', index, filename, linenumber
        self.svc.boss.editor.cmd('show_sign', type='breakpoint', 
                                          file_name=filename,
                                          line=linenumber)

    def remove_breakpoint(self, index, filename, linenumber):
        print 'remove', index, filename, linenumber
        self.svc.boss.editor.cmd('hide_sign', type='breakpoint', 
                                          file_name=filename,
                                          line=linenumber)


# Views
class DebuggerConsole(gtk.VBox):

    def __init__(self, sm):
        gtk.VBox.__init__(self)
        self.sm = sm
        self.console = rpdb2.CConsole(sm, self, self, True)
        self.console.start()
        self._queue = Queue.Queue()
        self._text = gtk.TextView()
        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        sw.add(self._text)
        self._buffer = self._text.get_buffer()
        self._buffer.create_tag('mono', family='Monospace')
        self._buffer.create_tag('bold', weight=800)
        self.pack_start(sw)
        self._entry = gtk.Entry()
        self.pack_start(self._entry, expand=False)
        self._entry.connect('activate', self.on_entry__activate)

    def write_text(self, data, *tags):
        self._buffer.insert_with_tags_by_name(
            self._buffer.get_end_iter(), data, 'mono', *tags)
        self._text.scroll_to_iter(self._buffer.get_end_iter(), 0.1)

    def write_info(self, data):
        gobject.idle_add(self.write_text, '[S] ' + data, 'bold')

    def write_from(self, data):
        gobject.idle_add(self.write_text, data)

    def write_to(self, data):
        if len(data) > 1:
            data = '>>> ' + data
            
        gobject.idle_add(self.write_text, data, 'bold')

    def write(self, data):
        self.write_from(data)

    def flush(self):
        pass

    def readline(self):
        return self._queue.get()

    def on_entry__activate(self, entry):
        data = self._entry.get_text() + '\n'
        self._entry.set_text('')
        self.write_to(data)
        self._queue.put(data)


nochildren = ['NoneType', 'str', 'int', 'float', 'long', 'bool']

reprable = nochildren + ['dict', 'list', 'tuple']


class NamespaceItem(object):

    def __init__(self, nsdict):
        self.name = nsdict['name']
        self.stype = nsdict['type']
        self.srepr = nsdict['repr']
        self.expr = nsdict['expr']
        self.n_subnodes = nsdict['n_subnodes']
        self.key = self.name
        self.is_value = False
        self.expanded = False
    
    def get_markup(self):
        if self.is_value:
            self.name = '.'
            mu = cgi.escape(self.srepr)
        else:
            n = cgi.escape(self.name)
            t = cgi.escape(self.stype)
            mu = ('<tt><b>%s</b>  </tt>'
                  '<span color="#903030"><i><small>%s</small></i></span>'
                  % (n, t))
            if self.stype in reprable:
                v = '<tt> %s</tt>' % cgi.escape(self.srepr)
                mu = ''.join([mu, v])
        return mu
    markup = property(get_markup)

    def get_pixbuf(self):
        if self.is_value:
            return None
        return get_pixbuf(self.stype)
    pixbuf = property(get_pixbuf)


class NamespaceViewer(gtk.VBox):

    def __init__(self, sm):
        gtk.VBox.__init__(self)
        self.session_manager = sm
        self._tree = ObjectTree(
            [
                Column('markup', use_markup=True)
            ]
        )
        self._tree.set_headers_visible(False)
        self.pack_start(self._tree)
        self._tree.connect('row-expanded', self.on_tree__row_expanded)
        
    def update_namespace(self, expr=None, parent=None):
        if expr is None:
            expr = self.get_root_expr()
            parent = None
            self._tree.clear()
        el = [(expr, True)]
        filt = 0
        ns = self.session_manager.get_namespace(el, filt)
        for sn in ns[0]['subnodes']:
            item = NamespaceItem(sn)
            piter = self._tree.append(parent, item)
            if item.stype not in nochildren:
                valitem = NamespaceItem(sn)
                valitem.is_value = True
                self._tree.append(item, valitem)

    def on_tree__row_expanded(self, tv, item):
        if not item.expanded:
            item.expanded = True
            self.update_namespace(item.expr, item)

    def get_root_expr(self):
        raise NotImplementedError


class GlobalsViewer(NamespaceViewer):

    def get_root_expr(self):
        return 'globals()'


class LocalsViewer(NamespaceViewer):

    def get_root_expr(self):
        return 'locals()'




class StackItem(object):

    def __init__(self, index, filename, linenumber, function, line):
        self.key = index
        self.filename = filename
        self.basename = os.path.basename(filename)
        self.dirname = os.path.dirname(filename)
        self.linenumber = linenumber
        self.function = function
        self.line = line
        self.active=False


    def get_markup(self):
        return ('<span color="%(color)s">'
                '<b>%(basename)s:%(linenumber)s</b> '
                '<i><small>%(dirname)s</small></i>\n'
                '<tt>%(line)s</tt></span>' % dict(color=self.color,
                basename=self.basename, linenumber=self.linenumber,
                dirname=self.dirname, line=self.line))
    markup = property(get_markup)

    def get_color(self):
        if self.active:
            return '#000000'
        else:
            return '#909090'
    color = property(get_color)

    def get_icon(self):
        if self.active:
            return None#icons.get(gtk.STOCK_EXECUTE, 16)
        else:
            return None

    pixbuf = property(get_icon)


class StackViewer(gtk.VBox):

    def __init__(self, sm):
        self.session_manager = sm
        gtk.VBox.__init__(self)
        self.tree = ObjectList(
            [
                Column('markup', use_markup=True)
            ]
        )
        self.tree.set_headers_visible(False)
        self.pack_start(self.tree)
        self.tree.connect('double-click', self.on_tree__double_clicked)


    def update_stack(self, stack):
        self._current_tid = stack['current tid']
        self.tree.clear()
        stack_item = None
        for i, row in enumerate(stack['stack'][3:]):
            fn, ln, fc, tl = row
            stack_item = StackItem(i, fn, ln, fc, tl)
            self.tree.insert(0, stack_item)
        if stack_item is not None:
            stack_item.active = True
            self.tree.update(stack_item)
    
    def select_frame(self, index):
        for item in self.tree:
            item.active = (item.key == index)
            self.tree.update(item)

    def on_tree__double_clicked(self, tv, item):
        index = item.key
        self.session_manager.set_frame_index(index)


class ThreadItem(object):

    def __init__(self, tdict):
        self.tid = tdict[rpdb2.DICT_KEY_TID]
        self.broken = tdict[rpdb2.DICT_KEY_BROKEN]
        self.is_current = False
        self.key = self.tid

    def get_broken_text(self):
        if self.broken:
            return 'broken'
        else:
            return 'running'
    state = property(get_broken_text)

    def get_pixbuf(self):
        return None
    pixbuf = property(get_pixbuf)

    def get_markup(self):
        return  ('<tt>%(tid)s</tt> <span color="#909090"><i>%(state)s</i></span>'
           % dict(tid=self.tid, state=self.state) 
        )

    markup = property(get_markup)


class ThreadsViewer(gtk.VBox):

    def __init__(self, sm):
        gtk.VBox.__init__(self)
        self.sesion_manager = sm
        self.tree = ObjectList(
            [
                Column('markup', use_markup=True),
            ]
        )
        self.pack_start(self.tree)
        self.tree.set_headers_visible(False)

    def update_threads(self, threads_list, current_thread):
        self.tree.clear()
        for tdict in threads_list:
            item = ThreadItem(tdict)
            if item.tid == current_thread:
                item.is_current = True
            self.tree.append(item)

    def broken_thread(self, tid):
        for item in self.tree:
            if item.tid == tid:
                item.broken = True
                self.tree.update(item)

class Breakpoint(object):

    def __init__(self, index, filename, linenumber):
        self.key = index
        self.filename = filename
        self.linenumber = linenumber
        self.enabled = True

    def get_color(self):
        if self.enabled:
            return '#000000'
        else:
            return '#a0a0a0'

    def get_disabled_text(self):
        if self.enabled:
            return ''
        else:
            return '(disabled)'

    disabled_text = property(get_disabled_text)
    
    color = property(get_color)

    def get_markup(self):
        return ('<b>[%(key)s]</b>'
                '<span color="%(color)s">'
                '<tt> %(filename)s:%(linenumber)s </tt>'
                '</span><i>%(disabled_text)s</i>') % dict(
                    key=self.key, filename=self.filename,
                    disabled_text=self.disabled_text, color=self.color,
                    linenumber=self.linenumber,
                )

    markup = property(get_markup)


class BreakpointViewer(gtk.VBox):

    def __init__(self, sm):
        self.session_manager = sm
        gtk.VBox.__init__(self)
        self.tree = ObjectList(
            [
                Column('markup', use_markup=True),
            ]
        )
        self.tree.set_headers_visible(False)
        self.pack_start(self.tree)
        #self._create_actions()

    def update_bp(self, action, index, indices, filename, linenumber):
        if action == 'set':
            gen = self._get_all_bps([index])
            try:
                val = gen.next()
                val.filename = filename
                val.linenumber = linenumber
                self.tree.update(val)
            except StopIteration:
                bp = Breakpoint(index, filename, linenumber)
                self.tree.append(bp)
                self.manager.set_breakpoint(index, filename, linenumber)
        elif action == 'remove':
            for item in self._get_all_index_rows(indices):
                filename = item.filename
                self.manager.remove_breakpoint(item.key, item.filename, item.linenumber)
                self.tree.remove(item)
        elif action == 'disable':
            for item in self._get_all_bps(indices):
                item.enabled = False
                self.tree.update(item)
        elif action == 'enable':
            for item in self._get_all_bps(indices):
                item.enabled = True
                self.tree.update(item)


    def _create_actions(self):
        self._current = None
        self.add_widget('dis_act', gtk.Action('Disable', 'Disable',
            'Disable this breakpoint', gtk.STOCK_NO))
        self.add_widget('en_act', gtk.Action('Enable', 'Enable',
            'Enable this breakpoint', gtk.STOCK_YES))

    def _create_popup(self, bp, event):
        self._current = bp
        if not bp: return
        menu = gtk.Menu()
        mi = self.dis_act.create_menu_item()
        menu.add(mi)
        self.dis_act.set_sensitive(bp.enabled)
        mi = self.en_act.create_menu_item()
        menu.add(mi)
        self.en_act.set_sensitive(not bp.enabled)
        menu.show_all()
        menu.popup(None, None, None, event.button, event.time)

    def _get_all_index_rows(self, indices):
        for index in indices:
            for item in self.tree:
                if item.key == index:
                    yield item
        
    def _get_all_bps(self, indices):
        for item in self._get_all_index_rows(indices):
            yield item

    def _set_breakpoint_enabled_status(self, bp, enabled):
        if not enabled:
            func = self.session_manager.disable_breakpoint
        else:
            func = self.session_manager.enable_breakpoint
        gobject.idle_add(func, [bp.key], False)

    def on_tree__double_clicked(self, tv, item):
        if item:
            val = item.value
            self._set_breakpoint_enabled_status(val, not val.enabled)

    def on_tree__right_clicked(self, tv, item, event):
        if item is None:
            val = item
        else:
            val = item.value
        self._create_popup(val, event)
        
    def on_dis_act__activate(self, action):
        print 'disabled'
        self._set_breakpoint_enabled_status(self._current, False)

    def on_en_act__activate(self, action):
        self._set_breakpoint_enabled_status(self._current, True)

# PIDA View

class PythonDebuggerView(PidaView):
    key = 'pythondebugger.shell'

    icon_name = 'python-icon'
    label_text = _('Python Debugger')

    def create_ui(self):
        self.manager = self.svc.debugger_manager
        self.create_toolbar()
        nb1 = gtk.Notebook()
        nb1.append_page(self.manager.console_view, gtk.Label('Console'))
        #nb1.append_page(self.manager.terminal_view, gtk.Label('Execution Output'))
        nb1.append_page(self.manager.breaks_view, gtk.Label('Break Points'))
        hb = gtk.HBox()
        hb.pack_start(nb1)
        hb.pack_start(self._toolbar, expand=False)
        self.add_main_widget(hb)
        hb.show_all()

    def create_toolbar(self):
        self._uim = gtk.UIManager()
        self._uim.insert_action_group(self.svc.get_action_group(), 0)
        self._uim.add_ui_from_file(get_uidef_path('python-debugger-toolbar.xml'))
        self._uim.ensure_update()
        self._toolbar = self._uim.get_toplevels('toolbar')[0]
        self._toolbar.set_style(gtk.TOOLBAR_ICONS)
        self._toolbar.set_icon_size(gtk.ICON_SIZE_SMALL_TOOLBAR)
        self._toolbar.set_orientation(gtk.ORIENTATION_VERTICAL)
        self._toolbar.show_all()

class PythonDebuggerView2(PidaView):
    key = 'pythondebugger.stacks'

    icon_name = 'python-icon'
    label_text = _('Python Debugger')


    def create_ui(self):
        self.manager = self.svc.debugger_manager
        nb2 = gtk.Notebook()
        nb2.append_page(self.manager.stack_view, gtk.Label('Stack'))
        nb2.append_page(self.manager.threads_view, gtk.Label('Threads'))
        nb2.append_page(self.manager.locals_view, gtk.Label('Locals'))
        nb2.append_page(self.manager.globals_view, gtk.Label('Globals'))
        self.add_main_widget(nb2)
        nb2.show_all()


class PythondebuggerCommandlineView(PidaView):

    key = 'pythondebugger.launcher'

    gladefile = 'pythondebugger_commandline'

    icon_name = 'gtk-execute'
    label_text = _('Debug Python Script')



    def on_exec_button__clicked(self, button):
        commandline = self.command_line.get_text()
        if commandline:
            self.svc.launch(commandline, self.change_directory.get_active())

    def on_open_button__clicked(self, button):
        fn = open_dlg('Select a script to load.', parent=self.svc.boss.window)
        if fn:
            self.command_line.set_text(fn)



# Service Configuration

# Actions
class DebuggerActionsConfig(ActionsConfig):
    def create_actions(self):
        # Menu
        self.create_action(
            'show_pydebugger_view',
            TYPE_REMEMBER_TOGGLE,
            'Show Python Debugger',
            'Show the Python debugger',
            'accessories-text-editor',
            self.on_show_debugger_view,
            '<Shift><Control>b',
        )

        self.create_action(
            'execute_pythondebugger',
            TYPE_NORMAL,
            'Debug Python Script',
            'Load a python script into the debugger',
            'gtk-execute',
            self.on_exec_commandline,
            '<Shift><Control>6',
        )

        #self.create_action(
        #    'show_stack_view',
        #    TYPE_TOGGLE,
        #    "Debugger's stack view",
        #    'Show the stack of current debugger',
        #    'accessories-text-editor',
        #    self.on_show_stack_view,
        #    '<Shift><Control>s',
        #)
    
        # Toolbar
        self.create_action(
            'debug_start',
            TYPE_NORMAL,
            'Continue',
            'Start debugger or Continue debbuging',
            'gdb-go',
            self.on_start,
            '<F3>',
        )
        #self.create_action(
        #    'debug_stop',
        #    TYPE_NORMAL,
        #    'Break',
        #    'Stop debbuging',
        #    'gdb-break',
        #    self.on_stop,
        #    '<F4>',
        #)
        self.create_action(
            'debug_next',
            TYPE_NORMAL,
            'Next',
            'Step to the next statement',
            'gdb-next',
            self.on_step_over,
            '<F6>',
        )
        self.create_action(
            'debug_step',
            TYPE_NORMAL,
            'Step',
            'Step into highlighted statement',
            'gdb-step',
            self.on_step_in,
            '<F5>',
        )
        self.create_action(
            'debug_return',
            TYPE_NORMAL,
            'Finish function',
            'Step until end of current function',
            'gdb-return',
            self.on_return,
            '<F7>',
        )
        self.create_action(
            'debug_break',
            TYPE_NORMAL,
            'Break',
            'Breakpoint the execution',
            'gdb-break',
            self.on_break,
            '<F3>',
        )

    # Buttonbar
    def on_step_over(self, action):
        self.svc._view.manager.session_manager.request_next()

    def on_step_in(self, action):
        self.svc._view.manager.session_manager.request_step()

    def on_start(self, action):
        self.svc._view.manager.session_manager.request_go()

    def on_stop(self, action):
        self.svc._view.manager.session_manager.stop_debuggee()

    def on_return(self, action):
        self.svc._view.manager.session_manager.request_return()

    # Menu
    def on_show_debugger_view(self, action):
        if action.get_active():
            self.svc.show_debugger_view()
        else:
            self.svc.boss.cmd('window', 'remove_view', view=self.svc._breakpoints_view)

    def on_show_stack_view(self, action):
        if not self.svc._stack_view:
            self.svc._stack_view = DebuggerStackView(self.svc)

        if action.get_active():
            self.svc.boss.cmd('window', 'add_view', paned='Terminal', view=self.svc._stack_view)
        else:
            self.svc.boss.cmd('window', 'remove_view', view=self.svc._stack_view)
        
    #
    def on_break(self, action):
        self.svc._view.manager.session_manager.request_break()

    def on_exec_commandline(self, action):
        self.svc.show_cmdline_dialog()

class DebuggerCommands(CommandsConfig):

    def launch(self, command_line, change_directory=False):
        self.svc.launch(command_line, change_directory)


class DebuggerEventsConfig(EventsConfig):

    def subscribe_all_foreign(self):
        #self.subscribe_foreign('buffer', 'document-changed',
        #                             self.on_document_changed)
        self.subscribe_foreign('editor', 'started',
                                     self.on_editor_startup)

    # XXX Well, that's not gonna work
    def on_editor_startup(self):
        """
        Set the highlights in vim
        """
        self.svc.boss.editor.cmd('define_sign_type', type="breakpoint", icon=get_pixmap_path("stop.svg"), 
                                                linehl="", text="X", texthl="Search")
        self.svc.boss.editor.cmd('define_sign_type', type="step", icon=get_pixmap_path("forward.svg"), 
                                                linehl="lCursor", text=">", texthl="lCursor")

    def on_document_changed(self, document):
        if document is not None:
            self.svc.get_action('debug_toggle_breakpoint').set_sensitive(True)
            self.svc.update_editor(document)
        else:
            self.svc.get_action('debug_toggle_breakpoint').set_sensitive(False)

# Service class
class Python_debugger(Service):
    """Describe your Service Here""" 
    actions_config = DebuggerActionsConfig
    commands_config = DebuggerCommands
    events_config = DebuggerEventsConfig

    def start(self):
        self.debugger_manager = DebuggerManager(self)
        self._view = PythonDebuggerView(self)
        self._view2 = PythonDebuggerView2(self)
        self.set_all_actions_insensitive()

    def show_debugger_view(self):
        self.boss.cmd('window', 'add_view', paned='Terminal', view=self._view)
        self.boss.cmd('window', 'add_view', paned='Plugin', view=self._view2)

    def hide_debugger_view(self):
        self.boss.cmd('window', 'remove_view', view=self._view)
        self.boss.cmd('window', 'remove_view', view=self._view2)

    def ensure_view_visible(self):
        if not self.get_action('show_pydebugger_view').get_active():
            self.get_action('show_pydebugger_view').set_active(True)
        self.boss.cmd('window', 'present_view', view=self._view)

    def launch(self, command_line, change_directory):
        self.ensure_view_visible()
        self._view.manager.launch(command_line, change_directory)

    def update_state(self, state):
        if state == 'broken':
            self.set_broken_actions()
        elif state == 'running':
            self.set_running_actions()
        elif state == 'detached':
            self.set_all_actions_insensitive()
            self._view.manager.remove_last_step_mark()

        else:
            self.set_all_actions_insensitive()

    def set_all_actions_insensitive(self):
        for actname in ['debug_start', 'debug_next', 'debug_break',
                        'debug_step', 'debug_return']:
            self.get_action(actname).set_sensitive(False)

    def set_running_actions(self):
        self.set_all_actions_insensitive()
        for actname in ['debug_break']:
            self.get_action(actname).set_sensitive(True)

    def set_broken_actions(self):
        self.set_all_actions_insensitive()
        for actname in ['debug_start', 'debug_next', 'debug_step',
                        'debug_return']:
            self.get_action(actname).set_sensitive(True)

    def stop(self):
        try:
            self._view.manager.session_manager.shutdown()
            self._view.manager.session_manager.stop_debuggee()
        except:
            pass

    def show_cmdline_dialog(self):
        view = PythondebuggerCommandlineView(self)
        self.boss.cmd('window', 'add_view', paned='Terminal', view=view)


# Required Service attribute for service loading
Service = Python_debugger



# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.