1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
""" A view showing a summary of the running application. """
# Standard library imports.
import inspect
# Enthought library imports.
from enthought.envisage.api import IApplication, IPlugin
from enthought.envisage.developer.code_browser.api import CodeBrowser
from enthought.io.api import File
from enthought.traits.api import Any, HasTraits, Instance
from enthought.traits.ui.api import Item, TreeEditor, View
# fixme: non-api import.
from enthought.plugins.text_editor.editor.text_editor import TextEditor
# Local imports.
from application_browser_tree import application_browser_tree_nodes
application_browser_view = View(
Item(
name = 'application',
show_label = False,
editor = TreeEditor(
nodes = application_browser_tree_nodes,
editable = False,
orientation = 'vertical',
hide_root = True,
show_icons = True,
selected = 'selection',
on_dclick = 'object.dclick'
)
),
resizable = True,
style = 'custom',
title = 'Application',
width = .1,
height = .1
)
class ApplicationBrowser(HasTraits):
""" An application browser.
Actually, this class exists just because to use a trait editor we have
to have a trait to edit!
"""
# The application that we are browsing.
application = Instance(IApplication)
# The code browser that we use to parse plugin source code.
code_browser = Instance(CodeBrowser)
# The workbench service.
workbench = Instance('enthought.envisage.ui.workbench.api.Workbench')
# The object that is currently selected in the tree.
selection = Any
# The default traits UI view.
traits_view = application_browser_view
###########################################################################
# 'ApplicationBrowser' interface.
###########################################################################
#### Trait initializers ###################################################
def _code_browser_default(self):
""" Trait initializer. """
return self.application.get_service(CodeBrowser)
def _workbench_default(self):
""" Trait initializer. """
from enthought.envisage.ui.workbench.api import Workbench
return self.application.get_service(Workbench)
#### Trait change handlers ################################################
def _selection_changed(self, trait_name, old, new):
""" Static trait change handler. """
#print 'Selection changed', trait_name, old, new
return
#### Methods ##############################################################
def dclick(self, obj):
""" Called when an object in the tree is double-clicked. """
if IPlugin(obj, None) is not None:
# Parse the plugin source code.
module = self._parse_plugin(obj)
# Get the plugin klass.
klass = self._get_plugin_klass(module, obj)
# Edit the plugin.
editor = self.workbench.edit(
self._get_file_object(obj), kind=TextEditor
)
# Move to the class definition.
editor.select_line(klass.lineno)
return
###########################################################################
# Private interface.
###########################################################################
def _get_file_object(self, obj):
""" Return a 'File' object for an object's source file. """
return File(path=inspect.getsourcefile(type(obj)))
def _get_plugin_klass(self, module, plugin):
""" Get the klass that defines the plugin. """
for name, klass in module.klasses.items():
if name == type(plugin).__name__:
break
else:
klass = None
return klass
def _parse_plugin(self, plugin):
""" Parse the plugin source code. """
filename = self._get_file_object(plugin).path
return self.code_browser.read_file(filename)
#### EOF ######################################################################
|