def _create_traits_ui_view(self): """ Create the traits UI view used by the editor. fixme: We create the view dynamically to allow the key bindings to be created dynamically (we don't use this just yet, but obviously plugins need to be able to contribute new bindings). """ view = View( Group( Item("text", editor=CodeEditor(key_bindings=self.key_bindings)), show_labels=False, ), id="envisage.editor.text_editor", handler=TextEditorHandler(), kind="live", resizable=True, width=1.0, height=1.0, buttons=NoButtons, ) return view
class TextView(HasTraits): text = Str save = Button() def __init__(self, text, title): self.text = text self.trait_view().title = title traits_view = View( Item('text', style="readonly", show_label=False, editor=CodeEditor()), HGroup(Item('save'), show_labels=False), resizable=True, width=1024, height=600, ) def _save_changed(self): from window import save_dialog fn = save_dialog() if fn: try: f = open(fn, "w") f.write(self.text) f.close() except: print("unable to write file...")
def default_traits_view(self): view = View( HSplit(VSplit( Item("object_class", editor=self.tree_editor, show_label=False, visible_when="object.show_tree"), Group(Item("search", label=u"搜索"), Item("search_result_str", show_label=False, editor=ListStrEditor( editable=False, selected_index="search_result_index")), label="Search"), ), Item("current_document", style="custom", show_label=False, editor=CodeEditor(lexer="text", search="top", line="current_line", mark_lines="mark_lines", mark_color=0xff7777)), id="tvtkdoc.hsplit"), width=700, height=500, resizable=True, title=u"TVTK文档浏览器", id="tvtkdoc", handler=TVTKDocumentHandler(), ) return view
class RecorderWithUI(Recorder): """ This class represents a Recorder but with a simple user interface. """ # The code to display code = Code(editor=CodeEditor(line='current_line')) # Button to save script to file. save_script = Button('Save Script') # The current line to show, used by the editor. current_line = Int # The root object which is being recorded. root = Any ######################################## # Traits View. view = View(Group( HGroup( Item('recording', show_label=True), spring, Item('save_script', show_label=False), ), Group(Item('code', show_label=False)), ), width=600, height=360, id='apptools.scripting.recorder_with_ui', buttons=['Cancel'], resizable=True, handler=CloseHandler()) ###################################################################### # RecorderWithUI interface. ###################################################################### def on_ui_close(self): """Called from the CloseHandler when the UI is closed. This method basically stops the recording. """ from util import stop_recording from package_globals import get_recorder if get_recorder() is self: stop_recording(self.root, save=False) else: self.recording = False self.unregister(self.root) ###################################################################### # Non-public interface. ###################################################################### @on_trait_change('lines[]') def _update_code(self): self.code = self.get_code() self.current_line = len(self.lines) + 1 def _save_script_fired(self): self.ui_save()
class TextInfo(MFileDialogModel): """ Defines a file dialog extension that displays a file's contents as text. """ # The file's text content: text = Property(depends_on='file_name') #-- Traits View Definitions ------------------------------------------------ view = View( Item('text', style='readonly', show_label=False, editor=CodeEditor())) #-- Property Implementations ----------------------------------------------- @cached_property def _get_text(self): try: if getsize(self.file_name) > MAX_SIZE: return 'File too big...' fh = file(self.file_name, 'rb') data = fh.read() fh.close() except: return '' if (data.find('\x00') >= 0) or (data.find('\xFF') >= 0): return 'File contains binary data...' return data
def code_editor(): """ Factory function that returns an editor that treats a multi-line string as source code. """ global SourceCodeEditor if SourceCodeEditor is None: from traitsui.api import CodeEditor SourceCodeEditor = CodeEditor() return SourceCodeEditor
def _view_default(self): """ This view uses a ModelView to translate the view into ContextVariableList """ view = View( Item('object.exec_model.code', label='Code', id='code', editor=CodeEditor(dim_lines='dim_lines', dim_color='dim_color', squiggle_lines='squiggle_lines'), dock='horizontal', show_label=False), ) return view
class TextItem(ADescriptionItem): """ Defines a class used for displaying a text file within the tutor. """ view = View( Item('content', style='readonly', show_label=False, editor=CodeEditor(show_line_numbers=False, selected_color=0xFFFFFF))) @cached_property def _get_content(self): """ Returns the item content. """ return read_file(self.path)
class TestCode(HasPrivateTraits): code = Code status = Str view = View([ Item('code', style='custom', resizable=True, editor=CodeEditor(key_bindings=key_bindings)), 'status~', '|<>' ], id='traitsui.tests.test_code_editor.TestCode', title='Sample Code Editor', width=0.4, height=0.4, resizable=True, handler=CodeHandler())
class CodeItem(ATutorialItem): """ Defines a class used for displaying a Python source code fragment within the tutor. """ # The displayable content for the item (override): content = Str # The starting line of the code snippet within the original file: start_line = Int # The currently selected line: selected_line = Int # Should this section normally be hidden? hidden = Bool view = View( Item('content', style='custom', show_label=False, editor=CodeEditor(selected_line='selected_line')))
def trait_view(self, name='default'): rest_editor = CodeEditor(lexer='rest', selected_line='selected_line', auto_scroll=True, squiggle_lines='warning_lines', selected_text='selected_text', selected_start_pos='selected_start_pos', selected_end_pos='selected_end_pos') warning_editor = TabularEditor(editable=False, adapter=DocUtilsWarningAdapter(), dclicked='dclicked_warning') html_editor = HTMLEditor(open_externally=True, base_url_name='base_url') return View(Group(Group(Item('object.model.rest', style='custom', editor=rest_editor), Item('html', editor=html_editor), id='rest_editor_view.PairView.HorzGroup', show_labels=False, orientation='horizontal', layout='split'), Item('object.model.warnings', height=0.2, editor=warning_editor), id='rest_editor_view.PairView.VertGroup', show_labels=False, orientation='vertical', layout='split'), id='rest_editor_view.PairView', handler=ReSTHTMLPairHandler(), width=800, height=600, resizable=True)
class PythonEditor(TraitsEditor): """ Tasks Editor that provides a code editor via TraitsUI """ #: The Python code being edited. code = Str() #: Whether or not undo operation is possible. can_undo = Property(Bool, observe="ui.history.undoable") #: Whether or not redo operation is possible. can_redo = Property(Bool, observe="ui.history.redoable") #: The current cursor line. line = Int(1) #: The current cursor column. column = Int(1) #: The currently selected text, if any. selection = Str() #: The length of the currently selected text. selection_length = Property(Int, observe="selection") #: The start of the currently selected text, if any. selection_start = Int() #: The end of the currently selected text, if any. selection_end = Int() #: The position of the last save in the history. _last_save = Int() # IEditor traits --------------------------------------------------------- #: The file being edited. obj = File() #: The editor's user-visible name. name = Property(Str, observe="obj") #: The tooltip for the editor. tooltip = Property(Str, observe="obj") dirty = Property(Bool, observe=["obj", "_last_save", "ui.history.now"]) # ------------------------------------------------------------------------- # PythonTextEditor interface # ------------------------------------------------------------------------- def load(self, path=None): """ Load text from a path, or set text empty if no path. This method uses the default encoding for io.open, which may or may not make sense; a real, robust editor should use tokenize.open or equivalent to detect file encodings. Parameters ---------- path : path or '' or None The path of the file to load. If the path is None, use the path providied via self.obj. """ if path is None: path = self.obj if path: with open(path) as fp: self.code = fp.read() self.obj = path else: self.code = "" if self.ui is not None: # reset history self.ui.history = UndoHistory() self._last_save = 0 def save(self, path=None): """ Load text from a path, or set text empty if no path. This method uses the default encoding for io.open, which may or may not make sense; a real, robust editor should detect the encoding using the mechanisms described in `PEP 263 <https://www.python.org/dev/peps/pep-0263/>`_. Parameters ---------- path : path or '' or None The path of the file to load. If the path is None, use the path providied via self.obj. """ if path is None: path = self.obj with open(path) as fp: fp.write(self.code) if self.ui is not None: # update save marker self._last_save = self.ui.history.now def go_to_line(self): """ Ask the use for a line number and jump to that line. """ max_line = len(self.code.splitlines()) + 1 dialog = LineNumberDialog(max_line=max_line, line=self.line) ui = dialog.edit_traits(kind="livemodal") if ui.result: self.column = 1 self.line = dialog.line def undo(self): """ Undo an operation. """ if self.ui is not None and self.ui.history is not None: self.ui.history.undo() def redo(self): """ Redo an operation. """ if self.ui is not None and self.ui.history is not None: self.ui.history.redo() def create(self, parent): """ Create and set the toolkit-specific contents of the editor. """ super(PythonEditor, self).create(parent) self.ui.history = UndoHistory() self._last_save = 0 # ------------------------------------------------------------------------- # HasTraits interface # ------------------------------------------------------------------------- def _get_dirty(self): """ Whether or not the editor is matches saved data. This is True if there is no file path, or history is not at last save point. """ return self.obj == "" or self._last_save != self.ui.history.now def _get_can_undo(self): """ Whether or not undo operations can be performed. """ if self.ui is not None and self.ui.history is not None: return self.ui.history.can_undo return False def _get_can_redo(self): """ Whether or not redo operations can be performed. """ if self.ui is not None and self.ui.history is not None: return self.ui.history.can_redo return False @cached_property def _get_selection_length(self): return len(self.selection) @cached_property def _get_name(self): """ The current name for the editor. Either the last component of the path """ if self.obj: return os.path.basename(self.obj) else: return "untitled.py" @cached_property def _get_tooltip(self): """ The tooltip for the editor tab. The full path name or "untitiled.py". """ if self.obj: return self.obj else: return "untitled.py" traits_view = View( Item( "code", show_label=False, editor=CodeEditor( selected_text="selection", selected_start_pos="selection_start", selected_end_pos="selection_end", line="line", column="column", ), ))
def trait_view(self, name=None, view_elements=None): if name is None or name=='full': return View( VGroup( HSplit( VSplit( Item('function_search', editor = InstanceEditor(view=function_search_view), label = 'Search', id = 'search', style = 'custom', dock = 'horizontal', show_label = False, ), Item('html_window', style='custom', show_label=False, springy= True, resizable=True, ), id='search_help_view' ), VSplit( Item( 'object.project.active_experiment.canvas', label = 'Canvas', id = 'canvas', # FIXME: need a new way to control the canvas # not using BlockEditor editor = BlockEditor(), dock = 'horizontal', show_label = False ), Item( 'object.project.active_experiment.exec_model.code', label = 'Code', id = 'code', editor = CodeEditor(dim_lines = 'dim_lines', dim_color = 'dim_color', squiggle_lines = 'squiggle_lines'), dock = 'horizontal', show_label = False ), ), Item( 'context_viewer', label = 'Context', id = 'context_table', editor = InstanceEditor(), style = 'custom', dock = 'horizontal', show_label = False, ), id='panel_split', ), Item( 'status', style = 'readonly', show_label = False, resizable = False ), ), title = 'Block Canvas', menubar = BlockApplicationMenuBar, width = 1024, height = 768, id = 'blockcanvas.app.application', resizable = True, handler = BlockApplicationViewHandler(model=self), key_bindings = KeyBindings( KeyBinding(binding1='F5', method_name='_on_execute'), ), ) elif name == 'simple': return View( HSplit( VSplit( Item('function_search', editor = InstanceEditor(view=function_search_view), label = 'Search', id = 'search', style = 'custom', dock = 'horizontal', show_label = False), Item('html_window', style='custom', show_label=False, springy= True, resizable=True), id='search_help_view' ), Item( 'object.project.active_experiment.canvas', label = 'Canvas', id = 'canvas', # FIXME: need a new way to control the canvas # not using BlockEditor editor = BlockEditor(), dock = 'horizontal', show_label = False), id='panel_split'), title = 'Block Canvas - Simple View', menubar = BlockApplicationMenuBar, width = 800, height = 600, id = 'blockcanvas.app.application.simple', resizable = True, handler = BlockApplicationViewHandler(model=self), key_bindings = KeyBindings( KeyBinding(binding1='F5', method_name='_on_execute'), ) )
class MainWindow(HasTraits): title = String() date = String() category = Enum(['nus', 'travel', 'pics', 'food']) dirpath = Directory() codedir = Directory() html_text = String('') status = String('no connection') ftp_url = String('files.000webhost.com') ftp_user = String('maxinsingapore') ftp_dir = String('public_html/pictures') ftp_pw = String() upload_btn = Button('Upload') html_preview = HTML() preview_btn = Button('HTML preview') uploadthread = Instance(UploadThread) notuploading = Bool(True) html_intro_1 = '''<!DOCTYPE html><html><head><link href="main.css" rel="stylesheet"/> <title>Max in Singapore</title> </head> <body> <?php require("ground.php"); ?> <div class = "title"> <a href="''' html_intro_2 = '''.php"><figure><p>back</p</figure></a> </div> <div class="center">''' html_end = ''' </div> </div> </div> </body> </html>''' traits_view = View( HGroup('ftp_url', 'ftp_user', 'ftp_pw', 'ftp_dir'), HGroup('title', 'date', 'category'), HGroup(Item('html_text', editor=CodeEditor()), Item('html_preview', editor=HTMLEditor())), 'preview_btn', Item('dirpath', label='Photo Directory'), Item('codedir', label='Code Directory'), Item('status', style='readonly'), Item('upload_btn', enabled_when='notuploading')) def _preview_btn_fired(self): html_intro = self.html_intro_1 + self.category + self.html_intro_2 self.html_preview = html_intro + self.html_text + self.html_end def _upload_btn_fired(self): if self.dirpath != '' and self.codedir != '': self.notuploading = False self.uploadthread = UploadThread() self.uploadthread.wants_abort = False self.uploadthread.master = self self.uploadthread.start() else: self.status = "choose directories"
class Yasso(HasTraits): """ The Yasso model """ # Parameters p_sets = _get_parameter_files() parameter_set = Enum(p_sets) leaching = Float() # Initial condition initial_mode = Enum(['non zero', 'zero', 'steady state']) initial_litter = List(trait=LitterComponent) steady_state = List(trait=LitterComponent) # Litter input at each timestep in the simulation litter_mode = Enum(['zero', 'yearly', 'constant yearly', 'monthly']) constant_litter = List(trait=LitterComponent) monthly_litter = List(trait=TimedLitterComponent) yearly_litter = List(trait=TimedLitterComponent) zero_litter = List(trait=LitterComponent) # Assumes that this defaults to 0 woody_size_limit = Float(default_value=3.0) area_change = List(trait=AreaChange) # Climate definition for the simulation climate_mode = Enum(['yearly', 'constant yearly', 'monthly']) constant_climate = YearlyClimate() monthly_climate = List(trait=MonthlyClimate, value=[MonthlyClimate(month=1), MonthlyClimate(month=2), MonthlyClimate(month=3), MonthlyClimate(month=4), MonthlyClimate(month=5), MonthlyClimate(month=6), MonthlyClimate(month=7), MonthlyClimate(month=8), MonthlyClimate(month=9), MonthlyClimate(month=10), MonthlyClimate(month=11), MonthlyClimate(month=12)] ) yearly_climate = List(trait=YearlyClimate) # All data as text all_data = Str() data_file = Str() # How the model will be run sample_size = Int() duration_unit = Enum(['year', 'month']) timestep_length = Range(low=1) simulation_length = Range(low=1) result_type = Enum(['C stock', 'C change', 'CO2 production']) presentation_type = Enum(['chart', 'array']) chart_type = Enum(['common scale', 'autofit']) # Buttons new_data_file_event = Button('New...') open_data_file_event = Button('Open...') save_data_file_event = Button('Save') save_as_file_event = Button('Save as...') modelrun_event = Button('Run model') save_result_event = Button('Save raw results...') save_moment_event = Button('Save moment results...') # and the results stored # Individual model calls # iteration,time, total, woody, acid, water, ethanol, non_soluble, humus c_stock = Array(dtype=float32, shape=(None, 10)) # iteration,time, total, woody, acid, water, ethanol, non_soluble, humus c_change = Array(dtype=float32, shape=(None, 10)) # time, iteration, CO2 production co2_yield = Array(dtype=float32, shape=(None, 3)) # time, mean, mode, var, skewness, kurtosis, 95% conf-, 95% conf+ stock_tom = Array(dtype=float32, shape=(None, 8)) stock_woody = Array(dtype=float32, shape=(None, 8)) stock_non_woody = Array(dtype=float32, shape=(None, 8)) stock_acid = Array(dtype=float32, shape=(None, 8)) stock_water = Array(dtype=float32, shape=(None, 8)) stock_ethanol = Array(dtype=float32, shape=(None, 8)) stock_non_soluble = Array(dtype=float32, shape=(None, 8)) stock_humus = Array(dtype=float32, shape=(None, 8)) change_tom = Array(dtype=float32, shape=(None, 8)) change_woody = Array(dtype=float32, shape=(None, 8)) change_non_woody = Array(dtype=float32, shape=(None, 8)) change_acid = Array(dtype=float32, shape=(None, 8)) change_water = Array(dtype=float32, shape=(None, 8)) change_ethanol = Array(dtype=float32, shape=(None, 8)) change_non_soluble = Array(dtype=float32, shape=(None, 8)) change_humus = Array(dtype=float32, shape=(None, 8)) co2 = Array(dtype=float32, shape=(None, 8)) # plot variables stock_plots = Instance(GridContainer) change_plots = Instance(GridContainer) co2_plot = Instance(GridContainer) p_timestep = Array() ps_tom = Array() ps_woody = Array() ps_non_woody = Array() ps_acid = Array() ps_water = Array() ps_ethanol = Array() ps_non_soluble = Array() ps_humus = Array() pc_tom = Array() pc_non_woody = Array() pc_acid = Array() pc_water = Array() pc_ethanol = Array() pc_non_soluble = Array() pc_humus = Array() ############################################################# # UI view ############################################################# view = View( VGroup( HGroup( Item('new_data_file_event', show_label=False,), Item('open_data_file_event', show_label=False,), Item('save_data_file_event', show_label=False,), Item('save_as_file_event', show_label=False,), Item('data_file', style='readonly', show_label=False,), ), HGroup( Item('all_data', show_label=False, editor=CodeEditor(), has_focus=True, width=300, height=400, ), ), label='All data', ), VGroup( HGroup( Item('parameter_set', width=-145), Item('leaching', width=-45, label='Leaching parameter', visible_when='initial_mode!="steady state"'), show_border=True, ), VGroup( HGroup( Item(name='initial_mode', style='custom', label='Initial state:', emphasized=True, ), ), Item('initial_litter', visible_when='initial_mode=="non zero"', show_label=False, editor=litter_te, width=790, height=75, ), ), VGroup( HGroup( Item('litter_mode', style='custom', label='Soil carbon input:', emphasized=True ) ), HGroup( Item('constant_litter', visible_when='litter_mode=="constant yearly"', show_label=False, editor=litter_te, full_size=False, springy=False, #width=-790, height=-75 ), Item('monthly_litter', visible_when='litter_mode=="monthly"', show_label=False, editor=timed_litter_te, full_size=False, springy=False, #width=-790, height=-75 ), Item('yearly_litter', visible_when='litter_mode=="yearly"', show_label=False, editor=timed_litter_te, full_size=False, springy=False, #width=-790,height=-75 ), ), HGroup( Item('area_change', visible_when='litter_mode=="yearly" or '\ 'litter_mode=="monthly"', show_label=False, editor=change_te, full_size=False, springy=False, width=-150,height=-75 ), spring, ), ), VGroup( HGroup( Item('climate_mode', style='custom', label='Climate:', emphasized=True, ), ), HGroup( Item('monthly_climate', show_label=False, visible_when='climate_mode=="monthly"', editor=monthly_climate_te, width=200, height=75 ), Item('yearly_climate', show_label=False, visible_when='climate_mode=="yearly"', editor=yearly_climate_te, width=200, height=75 ), VGroup( Item('object.constant_climate.mean_temperature', style='readonly',), Item('object.constant_climate.annual_rainfall', style='readonly',), Item('object.constant_climate.variation_amplitude', style='readonly',), show_border=True, visible_when='climate_mode=="constant yearly"' ), ), ), label='Data to use', ), VGroup( Group( HGroup( Item('sample_size', width=-45, ), Item('simulation_length', width=-45, label='Number of timesteps', ), Item('timestep_length', width=-45, ), Item('duration_unit', style='custom', show_label=False,), ), HGroup( Item('woody_size_limit', width=-45, ), Item('modelrun_event', show_label=False), ), show_border=True ), HGroup( Item('result_type', style='custom', label='Show', emphasized=True, ), Item('save_result_event', show_label=False,), Item('save_moment_event', show_label=False,), ), HGroup( Item('presentation_type', style='custom', label='As', emphasized=True, ), Item('chart_type', style='custom', label='Chart type', visible_when='presentation_type=="chart"'), ), HGroup( Item('c_stock', visible_when='result_type=="C stock" and \ presentation_type=="array"', show_label=False, editor=c_stock_te, #width=600 ), Item('c_change', visible_when='result_type=="C change" and \ presentation_type=="array"', show_label=False, editor=c_stock_te,), Item('co2_yield', visible_when='result_type=="CO2 production" '\ 'and presentation_type=="array"', show_label=False, editor=co2_yield_te,), Item('stock_plots', editor=ComponentEditor(), show_label=False, visible_when='result_type=="C stock" and \ presentation_type=="chart"',), Item('change_plots', editor=ComponentEditor(), show_label=False, visible_when='result_type=="C change" and \ presentation_type=="chart"',), Item('co2_plot', editor=ComponentEditor(), show_label=False, visible_when='result_type=="CO2 production" and \ presentation_type=="chart"',), ), label='Model run', ), VGroup( Label(label='Yasso15 soil carbon model', emphasized=True), Label(label="<placeholder>", id="about_text"), label='About', ), title = 'Yasso 15', id = 'simosol.yasso15', dock = 'horizontal', width = 800, height = 600, resizable = True, scrollable= True, buttons=NoButtons, icon=app_ir, menubar = MenuBar( Menu(CloseAction, name = 'File'), Menu(UndoAction, RedoAction, RevertAction, name = 'Edit'), ), help=False, ) ############################################################################### # Initialisation ############################################################################### def __init__(self): self.sample_size = 10 self.simulation_length = 10 fn = os.path.split(sys.executable) if fn[1].lower().startswith('python'): exedir = os.path.abspath(os.path.split(sys.argv[0])[0]) self.data_file = self._get_data_file_path(exedir) else: self.data_file = self._get_data_file_path(fn[0]) try: f = codecs.open(self.data_file, 'r', 'utf8') self._load_all_data(f) f.close() except: self.all_data = DATA_STRING self.data_file = '' try: cfg = ConfigParser.ConfigParser() fn = os.path.split(sys.executable) if fn[1].lower().startswith('python'): exedir = os.path.abspath(os.path.split(sys.argv[0])[0]) else: exedir = fn[0] inipath = os.path.join(exedir, 'yasso.ini') cfg.readfp(codecs.open(inipath, "r", "utf8")) about_text = cfg.get("about", "text") about_text = about_text.replace("\\n", "\n") default_param = cfg.get("data", "default_param") if default_param in self.p_sets: self.parameter_set = default_param self.trait_view('about_text').label = about_text except Exception as error: print "Error reading yasso.ini. See the error log for details." raise error def _get_data_file_path(self, exedir): join = os.path.join self.state_file = join(exedir, 'yasso.state') if os.path.exists(self.state_file): f = codecs.open(self.state_file, 'r', 'utf8') datafile = f.read() if len(datafile)>0 and datafile[-1]=='\n': datafile = datafile[:-1] f.close() if not os.path.exists(datafile): os.remove(self.state_file) datafile = join(exedir, 'demo_data.txt') else: datafile = join(exedir, 'demo_data.txt') return datafile def _write_state(self, filename): f = codecs.open(self.state_file, 'w', 'utf8') f.write(filename) f.close() ############################################################################### # Custom derived properties ############################################################################### @property def leach_parameter(self): """Leach parameter can only be 0 when the initialization mode is by steady state. In other cases, the leaching parameter is the trait "leaching". This is to be called from the YassoModel instead of the traits themselves.""" if self.initial_mode=='steady state': return 0 else: return self.leaching ############################################################################### # Event handlers ############################################################################### ######################### # for plot data ######################### def _create_stock_plots(self, common_scale=False): max = None min = 0 stom, max, min = self._create_plot(max, min, self.stock_tom, 'Total organic matter') swoody, max, min = self._create_plot(max, min, self.stock_woody, 'Woody matter') snonwoody, max, min = self._create_plot(max, min, self.stock_non_woody, 'Non-woody matter') sa, max, min = self._create_plot(max, min, self.stock_acid, 'A') sw, max, min = self._create_plot(max, min, self.stock_water, 'W') se, max, min = self._create_plot(max, min, self.stock_ethanol, 'E') sn, max, min = self._create_plot(max, min, self.stock_non_soluble, 'N') sh, max, min = self._create_plot(max, min, self.stock_humus, 'H') if common_scale: for pl in (stom, swoody, snonwoody, sa, sw, se, sn, sh): pl.value_range.set_bounds(min, max) container = GridContainer(stom, swoody, snonwoody, sa, sw, se, sn, sh) container.shape = (3,3) container.spacing = (-8,-8) self.stock_plots = container def _create_change_plots(self, common_scale=False): max = None min = 0 ctom, max, min = self._create_plot(max, min, self.change_tom, 'Total organic matter') cwoody, max, min = self._create_plot(max, min, self.change_woody, 'Woody matter') cnonwoody, max, min = self._create_plot(max, min, self.change_non_woody, 'Non-woody matter') ca, max, min = self._create_plot(max, min, self.change_acid, 'A') cw, max, min = self._create_plot(max, min, self.change_water, 'W') ce, max, min = self._create_plot(max, min, self.change_ethanol, 'E') cn, max, min = self._create_plot(max, min, self.change_non_soluble, 'N') ch, max, min = self._create_plot(max, min, self.change_humus, 'H') if common_scale: for pl in (ctom, cwoody, cnonwoody, ca, cw, ce, cn, ch): pl.value_range.set_bounds(min, max) container = GridContainer(ctom, cwoody, cnonwoody, ca, cw, ce, cn, ch) container.shape = (3,3) container.spacing = (-15,-15) self.change_plots = container def _create_co2_plot(self): max = None min = 0 co2, max, min = self._create_plot(max, min, self.co2, 'CO2 production (in carbon)') container = GridContainer(co2, Plot(), Plot(), Plot()) container.shape= (2,2) self.co2_plot = container def _create_plot(self, max, min, dataobj, title): x = dataobj[:,0] y = dataobj[:,1] if y.max()>max: max = y.max() if y.min()<min: min = y.min() if self.sample_size>1: y2 = dataobj[:,6] y3 = dataobj[:,7] if y3.max()>max: max = y3.max() if y2.min()<min: min = y2.min() plotdata = ArrayPlotData(x=x, y=y, y2=y2, y3=y3) else: plotdata = ArrayPlotData(x=x, y=y) plot = Plot(plotdata) plot.plot(("x", "y"), type="line", color="blue") if self.sample_size>1: plot.plot(("x", "y2"), type="line", color="red") plot.plot(("x", "y3"), type="line", color="red") plot.title = title plot.title_font = 'Arial 10' return plot, max, min ######################## # for running the model ######################## def _modelrun_event_fired(self): # set the parameter set to use fn = os.path.split(sys.executable) if fn[1].lower().startswith('python'): exedir = os.path.abspath(os.path.split(sys.argv[0])[0]) else: exedir = fn[0] pdir = os.path.join(exedir, 'param') parfile = os.path.join(pdir, '%s.dat' % self.parameter_set) if self.initial_mode=='zero' and self.litter_mode=='zero': errmsg = ("Both soil carbon input and initial state may not be " "zero simultaneously.") error(errmsg, title='Invalid model parameters', buttons=['OK']) return if self.climate_mode=='yearly' and not self.yearly_climate: errmsg = ("Climate mode may not be 'yearly' if there are no " "yearly climate entries in the data file.") error(errmsg, title='Invalid model parameters', buttons=['OK']) return if self.leaching>0: errmsg = ("Leaching parameter may not be larger than 0.") error(errmsg, title='Invalid model parameters', buttons=['OK']) return if self.climate_mode=='monthly' and not self.monthly_climate: errmsg = ("Climate mode may not be 'monthly' if there are no " "monthly climate entries in the data file.") error(errmsg, title='Invalid model parameters', buttons=['OK']) return yassorunner = ModelRunner(parfile) if not yassorunner.is_usable_parameter_file(): errmsg = ("The selected parameter file has wrong number of columns " "and cannot be used.") error(errmsg, title='Invalid model parameters', buttons=['OK']) return self.yassorunner = yassorunner if self.initial_mode=='steady state': steady_state = self.yassorunner.compute_steady_state(self) self._set_steady_state(steady_state) self._init_results() self.c_stock, self.c_change, self.co2_yield = \ self.yassorunner.run_model(self) self._create_co2_plot() self._chart_type_changed() ######################## # for chart type ######################## def _chart_type_changed(self): if self.chart_type=='autofit': self._create_stock_plots() self._create_change_plots() elif self.chart_type=='common scale': self._create_stock_plots(common_scale=True) self._create_change_plots(common_scale=True) ######################## # for buttons ######################## def _new_data_file_event_fired(self): filename = save_file() if filename != '': try: self._reset_data() f=codecs.open(filename, 'w', 'utf8') f.close() self.data_file = filename self._write_state(filename) self.all_data=DATA_STRING except: pass def _open_data_file_event_fired(self): filename = open_file() if filename != '': try: f=codecs.open(filename, 'r', 'utf8') self.data_file = filename self._write_state(filename) self._load_all_data(f) f.close() except: pass def _save_data_file_event_fired(self): if self.data_file=='': filename = save_file() if filename=='': return self.data_file = filename self._write_state(filename) self._save_all_data() def _save_as_file_event_fired(self): filename = save_file() if filename=='': return self.data_file = filename self._write_state(filename) self._save_all_data() def _load_all_data(self, datafile): """ Loads all data from a single file. Data in sections defined by [name], data in whitespace delimited rows """ self._reset_data() sectionp = re.compile('\[([\w+\s*]+)\]') datap = re.compile('[+-Ee\d+\.\d*\s*]+') active = None data = defaultdict(list) alldata = '' linecount = 0 for line in datafile: linecount += 1 alldata += line m = re.match(sectionp, line) if m is not None: active = m.group(1) d = re.match(datap, line) if d is not None: try: vals = [float(val) for val in d.group(0).split()] data[active].append(vals) except ValueError: errmsg="There's an error on line %s\n %s"\ "for section %s\n"\ "Values must be space separated and . is the decimal"\ " separator" % (linecount, d.group(0), active) error(errmsg, title='Error saving data', buttons=['OK']) self.all_data = alldata for section, vallist in data.items(): if section=='Initial state': self._set_initial_state(vallist) elif section=='Constant soil carbon input': self._set_constant_litter(vallist) elif section=='Monthly soil carbon input': self._set_monthly_litter(vallist) elif section=='Yearly soil carbon input': self._set_yearly_litter(vallist) elif section=='Relative area change': self._set_area_change(vallist) elif section=='Constant climate': self._set_constant_climate(vallist) elif section=='Monthly climate': self._set_monthly_climate(vallist) elif section=='Yearly climate': self._set_yearly_climate(vallist) def _save_all_data(self): f = codecs.open(self.data_file, 'w', 'utf8') f.write(self.all_data) f.close() f = codecs.open(self.data_file, 'r', 'utf8') self._load_all_data(f) f.close() def _reset_data(self): """ Empties all input data structures """ self.initial_litter = [] self.steady_state = [] self.constant_litter = [] self.monthly_litter = [] self.yearly_litter = [] self.area_change = [] self.constant_climate.mean_temperature = 0 self.constant_climate.annual_rainfall = 0 self.constant_climate.variation_amplitude = 0 self.yearly_climate = [] self.monthly_climate = [] def _set_initial_state(self, data): errmsg = 'Soil carbon components should contain: \n'\ ' mass, mass std, acid, acid std, water, water std,\n'\ ' ethanol, ethanol std, non soluble, non soluble std,'\ '\n humus, humus std, size class' for vals in data: ok, obj = self._load_litter_object(vals, errmsg) if not ok: break self.initial_litter.append(obj) def _set_steady_state(self, data): errmsg = 'Soil carbon components should contain: \n'\ ' mass, mass std, acid, acid std, water, water std,\n'\ ' ethanol, ethanol std, non soluble, non soluble std,'\ '\n humus, humus std, size class' self.steady_state = [] for vals in data: ok, obj = self._load_litter_object(vals, errmsg) if not ok: break self.steady_state.append(obj) def _set_constant_litter(self, data): errmsg = 'Soil carbon components should contain: \n'\ ' mass, mass std, acid, acid std, water, water std,\n'\ ' ethanol, ethanol std, non soluble, non soluble std,'\ '\n humus, humus std, size class' for vals in data: ok, obj = self._load_litter_object(vals, errmsg) if not ok: break self.constant_litter.append(obj) def _set_monthly_litter(self, data): errmsg = 'timed soil carbon components should contain: \n'\ ' timestep, mass, mass std, acid, acid std, water, '\ 'water std,\n'\ ' ethanol, ethanol std, non soluble, non soluble std,'\ '\n humus, humus std, size class' for vals in data: ok, obj = self._load_litter_object(vals, errmsg, True) if not ok: break self.monthly_litter.append(obj) def _set_yearly_litter(self, data): errmsg = 'timed soil carbon components should contain: \n'\ ' timestep, mass, mass std, acid, acid std, water, '\ 'water std,\n'\ ' ethanol, ethanol std, non soluble, non soluble std,'\ '\n humus, humus std, size class' for vals in data: ok, obj = self._load_litter_object(vals, errmsg, True) if not ok: break self.yearly_litter.append(obj) def _set_area_change(self, data): errmsg = 'Area change should contain:\n timestep, relative area change' for vals in data: if len(vals)==2: obj = AreaChange(timestep=int(vals[0]), rel_change=vals[1]) self.area_change.append(obj) elif vals!=[]: errmsg = errmsg + '\n%s data values found, 2 needed' % (len(data)) error(errmsg, title='error reading data', buttons=['OK']) break def _set_yearly_climate(self, data): errmsg = 'Yearly climate should contain: timestep, mean temperature,\n'\ 'annual rainfall and temperature variation amplitude' for vals in data: if len(vals)==4: obj = YearlyClimate(timestep=int(vals[0]), mean_temperature=vals[1], annual_rainfall=vals[2], variation_amplitude=vals[3]) self.yearly_climate.append(obj) elif vals!=[]: errmsg = errmsg + '\n%s data values found, 4 needed' % (len(data)) error(errmsg, title='error reading data', buttons=['OK']) break def _set_constant_climate(self, data): errmsg = 'Constant climate should contain: mean temperature,\n'\ 'annual rainfall and temperature variation amplitude' if len(data[0])==3: self.constant_climate.mean_temperature = data[0][0] self.constant_climate.annual_rainfall = data[0][1] self.constant_climate.variation_amplitude = data[0][2] elif data[0]!=[]: errmsg = errmsg + '\n%s data values found, 3 needed' % (len(data)) error(errmsg, title='error reading data', buttons=['OK']) def _set_monthly_climate(self, data): errmsg = 'Monthly climate data should contain: month,\n'\ 'temperature and rainfall' for vals in data: if len(vals)==3: obj = MonthlyClimate(month=int(vals[0]), temperature=vals[1], rainfall=vals[2]) self.monthly_climate.append(obj) elif vals!=[]: errmsg = errmsg + '\n%s data values found, 3 needed' % (len(data)) error(errmsg, title='Error reading data', buttons=['OK']) break def _load_litter_object(self, data, errmsg, hastime=False): obj = None loaded = True if hastime: if len(data)==14: obj = TimedLitterComponent(timestep=int(data[0]), mass=data[1], mass_std=data[2], acid=data[3], acid_std=data[4], water=data[5], water_std=data[6], ethanol=data[7], ethanol_std=data[8], non_soluble=data[9], non_soluble_std=data[10], humus=data[11], humus_std=data[12], size_class=data[13]) elif data!=[]: errmsg = errmsg + '\n%s data values found, 14 needed' % (len(data)) error(errmsg, title='Error reading data', buttons=['OK']) loaded = False elif data==[]: loaded = False else: if len(data)==13: obj = LitterComponent(mass=data[0], mass_std=data[1], acid=data[2], acid_std=data[3], water=data[4], water_std=data[5], ethanol=data[6], ethanol_std=data[7], non_soluble=data[8], non_soluble_std=data[9], humus=data[10], humus_std=data[11], size_class=data[12]) elif data!=[]: errmsg = errmsg + '\n%s data values found, 13 needed' % (len(data)) error(errmsg, title='Error reading data', buttons=['OK']) loaded = False elif data==[]: loaded = False return loaded, obj def _save_moment_event_fired(self): filename = save_file() if filename != '': f=codecs.open(filename, 'w', 'utf8') if self.result_type=='C stock': comps = (('tom', self.stock_tom), ('woody', self.stock_woody), ('non-woody', self.stock_non_woody), ('acid', self.stock_acid), ('water', self.stock_water), ('ethanol', self.stock_ethanol), ('non-soluble', self.stock_non_soluble), ('humus', self.stock_humus)) elif self.result_type=='C change': comps = (('tom', self.change_tom), ('woody', self.change_woody), ('non-woody', self.change_non_woody), ('acid', self.change_acid), ('water', self.change_water), ('ethanol', self.change_ethanol), ('non-soluble', self.change_non_soluble), ('humus', self.change_humus)) elif self.result_type=='CO2 production': comps = (('CO2', self.co2),) header = '# component, time step, mean, mode, var, skewness, '\ 'kurtosis, 95% confidence lower limit, 95% upper limit' header = self._make_result_header(header) f.write(header+'\n') for comp, res in comps: for row in res: resrow = '' for num in row: resrow = ' '.join([resrow, str(num)]) resrow = ' '.join((comp, resrow)) f.write(resrow+'\n') f.close() def _save_result_event_fired(self): filename = save_file() if filename != '': f=codecs.open(filename, 'w', 'utf8') if self.result_type=='C stock': res = self.c_stock header = '# sample, time step, total om, woody om, non-woody om,'\ ' acid, water, ethanol, non-soluble, humus' elif self.result_type=='C change': res = self.c_change header = '# sample, time step, total om, woody om, non-woody om,'\ ' acid, water, ethanol, non soluble, humus' elif self.result_type=='CO2 production': res = self.co2_yield header = '# sample, time step, CO2 production (in carbon)' header = self._make_result_header(header) f.write(header+'\n') for row in res: resrow = '' for num in row: resrow = ' '.join([resrow, str(num)]) f.write(resrow+'\n') f.close() def _make_result_header(self, header): '''Adds metadata about the results into the header''' hstr = '#########################################################\n' hstr += '# ' + self.result_type + '\n' hstr += '#########################################################\n' hstr += '# Datafile used: ' + self.data_file + '\n' hstr += '# Settings:\n' hstr += '# initial state: ' + self.initial_mode + '\n' hstr += '# soil carbon input: ' + self.litter_mode + '\n' hstr += '# climate: ' + self.climate_mode + '\n' hstr += '# sample size: ' + str(self.sample_size) + '\n' hstr += ''.join(['# timestep length: ', str(self.timestep_length), ' (', self.duration_unit, ')\n']) hstr += '# woody litter size limit: ' + str(self.woody_size_limit)+'\n' hstr += '#\n' return hstr + header def _init_results(self): """ model results: stock & change sample, timestep, tom, woody, non-woody, acid, water, ethanol, non soluble humus model results: CO2 sample, timestep, CO2 production summary results common format: time, mean, mode, var, skewness, kurtosis, 95% confidence-, 95% confidence+ """ self.c_stock = empty(dtype=float32, shape=(0, 10)) self.c_change = empty(dtype=float32, shape=(0, 10)) self.co2_yield = empty(dtype=float32, shape=(0, 3)) self.stock_tom = empty(dtype=float32, shape=(0, 8)) self.stock_woody = empty(dtype=float32, shape=(0, 8)) self.stock_non_woody = empty(dtype=float32, shape=(0, 8)) self.stock_acid = empty(dtype=float32, shape=(0, 8)) self.stock_water = empty(dtype=float32, shape=(0, 8)) self.stock_ethanol = empty(dtype=float32, shape=(0, 8)) self.stock_non_soluble = empty(dtype=float32, shape=(0, 8)) self.stock_humus = empty(dtype=float32, shape=(0, 8)) self.change_tom = empty(dtype=float32, shape=(0, 8)) self.change_woody = empty(dtype=float32, shape=(0, 8)) self.change_non_woody = empty(dtype=float32, shape=(0, 8)) self.change_acid = empty(dtype=float32, shape=(0, 8)) self.change_water = empty(dtype=float32, shape=(0, 8)) self.change_ethanol = empty(dtype=float32, shape=(0, 8)) self.change_non_soluble = empty(dtype=float32, shape=(0, 8)) self.change_humus = empty(dtype=float32, shape=(0, 8)) self.co2 = empty(dtype=float32, shape=(0, 8))
def code_editor(): """ Factory function that returns an editor that treats a multi-line string as source code. """ from traitsui.api import CodeEditor return CodeEditor()
base_url_name='base_url', ), ), VSplit( VGroup( UItem("source", style="custom"), HGroup( spring, UItem("handler.run_button", ), visible_when="source is not None", ), ), Tabbed( Item("log", style="readonly", editor=CodeEditor(show_line_numbers=False, selected_color=0xFFFFFF), label="Output", show_label=False), Item("locals", editor=ShellEditor(share=True), label="Shell", show_label=False), UItem( "demo", style="custom", resizable=True, ), ), dock="horizontal", ), ),
class SyntaxChecker ( Saveable ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # The name of the plugin: name = Str( 'Syntax Checker' ) # The persistence id for this object: id = Str( 'etsdevtools.developer.tools.syntax_checker.state', save_state_id = True ) # Should the syntax checker automatically go to the current syntax error? auto_goto = Bool( False, save_state = True ) # Should a changed file be automatically reloaded: auto_load = Bool( True, save_state = True ) # The name of the file currently being syntax checked: file_name = File( drop_file = DropFile( extensions = [ '.py' ], draggable = True, tooltip = 'Drop a Python source file to ' 'syntax check it.\nDrag this file.' ), connect = 'to' ) # The current source code being syntax checked: source = Str # The current syntax error message: error = Str # Current error line: error_line = Int # Current error column: error_column = Int # Current editor line: line = Int # Current editor column: column = Int # 'Go to' button: go_to = Button( 'Go To' ) # Can the current file be saved? can_save = false #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- traits_view = View( VGroup( TTitle( 'file_name' ), Item( 'source@', editor = CodeEditor( selected_line = 'line' ) ), TTitle( 'error' ), HGroup( spring, Item( 'go_to', show_label = False, enabled_when = '(error_line > 0) and (not auto_goto)' ), ), show_labels = False ), title = 'Syntax Checker' ) options = View( VGroup( Item( 'auto_goto', label = 'Automatically move cursor to syntax error' ), Item( 'auto_load', label = 'Automatically reload externally changed files' ), show_left = False ), title = 'Syntax Checker Options', id = 'etsdevtools.developer.tools.syntax_checker.options', buttons = [ 'OK', 'Cancel' ] ) #--------------------------------------------------------------------------- # Handles the 'auto_goto' trait being changed: #--------------------------------------------------------------------------- def _auto_goto_changed ( self, auto_goto ): """ Handles the 'auto_goto' trait being changed. """ if auto_goto and (self.error_line > 0): self._go_to_changed() #--------------------------------------------------------------------------- # Handles the 'Go To' button being clicked: #--------------------------------------------------------------------------- def _go_to_changed ( self ): """ Handles the 'Go To' button being clicked. """ self.line = self.error_line self.column = self.error_column #--------------------------------------------------------------------------- # Handles the 'file_name' trait being changed: #--------------------------------------------------------------------------- def _file_name_changed ( self, old_name, new_name ): """ Handles the 'file_name' trait being changed. """ self._set_listener( old_name, True ) self._set_listener( new_name, False ) self._load_file_name( new_name ) #--------------------------------------------------------------------------- # Handles the 'source' trait being changed: #--------------------------------------------------------------------------- def _source_changed ( self, source ): """ Handles the 'source' trait being changed. """ if self.can_save: if not self._dont_update: self.needs_save = True do_after( 750, self._syntax_check ) else: self._syntax_check() #--------------------------------------------------------------------------- # Handles the current file being updated: #--------------------------------------------------------------------------- def _file_changed ( self, file_name ): """ Handles the current file being updated. """ if self.auto_load: self._load_file_name( file_name ) #--------------------------------------------------------------------------- # Sets up/Removes a file watch on a specified file: #--------------------------------------------------------------------------- def _set_listener ( self, file_name, remove ): """ Sets up/Removes a file watch on a specified file. """ if exists( file_name ): file_watch.watch( self._file_changed, file_name, remove = remove ) #--------------------------------------------------------------------------- # Loads a specified source file: #--------------------------------------------------------------------------- def _load_file_name ( self, file_name ): """ Loads a specified source file. """ self._dont_update = True self.can_save = True source = read_file( file_name ) if source is None: self.error = 'Error reading file' self.can_save = False source = '' self.source = source self._dont_update = False self.needs_save = False #--------------------------------------------------------------------------- # Checks the current source for syntax errors: #--------------------------------------------------------------------------- def _syntax_check ( self ): """ Checks the current source for syntax errors. """ try: compile( self.source.replace( '\r\n', '\n' ), self.file_name, 'exec' ) self.error = 'Syntactically correct' self.error_line = 0 except SyntaxError, excp: self.error_line = excp.lineno self.error_column = excp.offset + 1 self.error = '%s on line %d, column %d' % ( excp.msg, excp.lineno, self.error_column ) if self.auto_goto: self._go_to_changed()
class Sike(HasTraits): """ Tie several profile-related widgets together. Sike is like Gotcha, only less mature. """ # The main pstats.Stats() object providing the data. stats = Any() # The main results and the subcalls. main_results = Instance(ProfileResults, args=()) caller_results = Instance(ProfileResults, args=()) callee_results = Instance(ProfileResults, args=()) # The records have list of callers. Invert this to give a map from function # to callee. callee_map = Dict() # Map from the (file, lineno, name) tuple to the record. record_map = Dict() # GUI traits ############################################################ basenames = Bool(True) percentages = Bool(True) filename = Str() line = Int(1) code = Str() traits_view = View( VGroup( HGroup(Item("basenames"), Item("percentages")), HGroup( UItem("main_results"), VGroup( Label("Callees"), UItem("callee_results"), Label("Callers"), UItem("caller_results"), UItem("filename", style="readonly"), UItem("code", editor=CodeEditor(line="line")), ), style="custom", ), ), width=1024, height=768, resizable=True, title="Profiling results", ) @classmethod def fromstats(cls, stats, **traits): """ Instantiate an Sike from a Stats object, Stats.stats dictionary, or Profile object, or a filename of the saved Stats data. """ stats = SillyStatsWrapper.getstats(stats) self = cls(stats=stats, **traits) self._refresh_stats() return self def add_stats(self, stats): """ Add new statistics. """ stats = SillyStatsWrapper.getstats(stats) self.stats.add(stats) self._refresh_stats() def records_from_stats(self, stats): """ Create a list of records from a stats dictionary. """ records = [] for ( file_line_name, (ncalls, nonrec_calls, inline_time, cum_time, calls), ) in stats.items(): newcalls = [] for sub_file_line_name, sub_call in calls.items(): newcalls.append(Subrecord((sub_file_line_name,) + sub_call)) records.append( Record( ( file_line_name, ncalls, nonrec_calls, inline_time, cum_time, newcalls, ) ) ) return records def get_callee_map(self, records): """ Create a callee map. """ callees = defaultdict(list) for record in records: for caller in record.callers: callees[caller.file_line_name].append( Subrecord((record.file_line_name,) + caller[1:]) ) return callees @observe("percentages,basenames") def _adapter_traits_changed(self, event): for obj in [ self.main_results, self.callee_results, self.caller_results, ]: setattr(obj, event.name, event.new) @observe("main_results:selected_record") def update_sub_results(self, event): new = event.new if new is None: return self.caller_results.total_time = new.cum_time self.caller_results.records = new.callers self.callee_results._resort() self.caller_results.selected_record = ( self.caller_results.activated_record ) = None self.callee_results.total_time = new.cum_time self.callee_results.records = self.callee_map.get( new.file_line_name, [] ) self.callee_results._resort() self.callee_results.selected_record = ( self.callee_results.activated_record ) = None filename, line, name = new.file_line_name if os.path.exists(filename): with open(filename, "ru") as f: code = f.read() self.code = code self.filename = filename self.line = line else: self.trait_set(code="", filename="", line=1) @observe("caller_results:dclicked," "callee_results:dclicked") def goto_record(self, event): new = event.new if new is None: return if new.item.file_line_name in self.record_map: record = self.record_map[new.item.file_line_name] self.main_results.selected_record = record @observe("stats") def _refresh_stats(self, event=None): """ Refresh the records from the stored Stats object. """ self.main_results.records = self.main_results.sort_records( self.records_from_stats(self.stats.stats) ) self.callee_map = self.get_callee_map(self.main_results.records) self.record_map = {} total_time = 0.0 for record in self.main_results.records: self.record_map[record.file_line_name] = record total_time += record.inline_time self.main_results.total_time = total_time
class Demo(HasTraits): canvas = Instance(ConstraintsContainer) child_canvas = Instance(ConstraintsContainer) constraints_def = Str child_constraints_def = Str share_layout = Bool(False) traits_view = View( HGroup( VGroup( Item( "constraints_def", editor=CodeEditor(), height=100, show_label=False, ), Item("share_layout"), Item( "child_constraints_def", editor=CodeEditor(), height=100, show_label=False, ), ), Item("canvas", editor=ComponentEditor(), show_label=False), ), resizable=True, title="Constraints Demo", width=1000, height=500, ) def _canvas_default(self): parent = ConstraintsContainer(bounds=(500, 500), padding=20) one = Component(id="r", bgcolor=0xFF0000) two = Component(id="g", bgcolor=0x00FF00) three = Component(id="b", bgcolor=0x0000FF) parent.add(one, two, three, self.child_canvas) return parent def _child_canvas_default(self): parent = ConstraintsContainer(id="child", share_layout=self.share_layout) one = Component(id="c", bgcolor=0x00FFFF) two = Component(id="m", bgcolor=0xFF00FF) three = Component(id="y", bgcolor=0xFFFF00) four = Component(id="k", bgcolor=0x000000) parent.add(one, two, three, four) return parent def _constraints_def_changed(self): if self.canvas is None: return canvas = self.canvas components = canvas._components r = components[0] g = components[1] b = components[2] child = components[3] components = child._components c = components[0] m = components[1] y = components[2] k = components[3] try: new_cns = eval(self.constraints_def) except Exception: return canvas.layout_constraints = new_cns canvas.request_redraw() def _child_constraints_def_changed(self): if self.child_canvas is None: return canvas = self.child_canvas components = canvas._components c = components[0] m = components[1] y = components[2] k = components[3] try: new_cns = eval(self.child_constraints_def) except Exception: return canvas.layout_constraints = new_cns canvas.request_redraw() def _share_layout_changed(self): self.child_canvas.share_layout = self.share_layout self.canvas.relayout() self.canvas.request_redraw() def _constraints_def_default(self): return """[ hbox(r, g, b, child), align('layout_height', r,g,b,child), align('layout_width', r,g,b,child), ]""" def _child_constraints_def_default(self): return """[
def traits_view(self): col_pattern_editor = build_col_name_editor(self.all_col_names) filename = basename(self.akta_filepath) spinner_editor = RangeEditor(low=5, high=9999, mode='spinner') time_orig = 'AKTA time from which to import AKTA data and name' \ ' of the corresponding step (typically the load).' search_instructions = 'Hit {}-f to search for a word' search_instructions = search_instructions.format(get_ctrl()) view = KromView( Tabbed( VGroup( VGroup( Label(time_orig), HGroup( Item('time_of_origin', editor=UnitScalarEditor(), show_label=False), Item("akta_start_method_step", label="Method step @ t=0"), ), Item('origin_error_msg', emphasized=True, visible_when='origin_error_msg', style='readonly', label="Note"), show_border=True, label="Time of origin" ), VGroup( Item('patterns_as_list', editor=col_pattern_editor, show_label=False, height=200), Item('pattern_error_msg', emphasized=True, visible_when='pattern_error_msg', style='readonly', label="Error"), show_border=True, label="AKTA Column Types" ), label="AKTA File Settings" ), VGroup( Item('file_preview', editor=CodeEditor(), show_label=False, tooltip=search_instructions), VGroup(Item('length_of_preview', editor=spinner_editor)), show_border=True, label="AKTA File Preview".format(filename), ), VGroup( # Information used to evaluate the loaded product mass Item("mass_bal_analyzer", editor=InstanceEditor(), style="custom", show_label=False), VGroup( HGroup( Item("mass_bal_msg", emphasized=True, style='readonly', show_label=False), ), Item("mass_bal_strategy", label="Adjustment strategy", enabled_when="not mass_balanced"), HGroup( Item("mass_bal_strategy_msg", emphasized=True, style='readonly', show_label=False, enabled_when="not mass_balanced"), ), visible_when="target_experiment and pure_protein_exp" ), label="UV and Mass Balance", ), ), buttons=OKCancelButtons, title="Experiment Importer: {}".format(self.experiment_name), width=900, ) return view
class AnFBIViewer ( HasPrivateTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # The viewer page name: name = Str # The name of the file being viewed: file_name = Str( draggable = 'Drag the file name.' ) # The starting line number: line = Int # The number of lines (start at 'line'): lines = Int( -1 ) # The number of lines of text in the view: nlines = Int # The object associated with this view: object = Any # The title of this view: title = Str # Should the break point trigger only for the specified object: object_only = Bool( False ) # Type of breakpoint to set: bp_type = BPType # The condition the break point should trigger on: condition = Str # The currently selected line: selected_line = Int # The current cursor position: cursor = Int( -1 ) # The list of lines with break points: bp_lines = List( Int ) # The logical starting line (used to adjust lines passed to the FBI): starting_line = Int # Fired when a breakpoint is to be set: bp_set = Button( 'Set' ) # Fired when a breakpoint is to be reset: bp_reset = Button( 'Reset' ) # Does the current line have any breakpoints set on it: has_bp = Bool( False ) # The source code being viewed: source = Code # The FBI module this file corresponds to: module = Any #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- view = View( VGroup( TTitle( 'title' ), HGroup( Item( 'object_only', label = 'For this object only', enabled_when = 'object.object is not None' ), Item( 'bp_type', label = 'Type' ), Item( 'condition', width = 200 ), TButton( 'bp_set', label = 'Set', enabled_when = "(bp_type != 'Trace') or " "(condition.strip() != '')" ), TButton( 'bp_reset', label = 'Reset', enabled_when = 'has_bp' ), show_border = True, label = 'Breakpoint Modifiers' ), Item( 'source', editor = CodeEditor( selected_line = 'selected_line', line = 'cursor', mark_lines = 'bp_lines', mark_color = SelectionColor, auto_scroll = False ) ), show_labels = False ) ) #--------------------------------------------------------------------------- # Initializes the object: #--------------------------------------------------------------------------- def __init__ ( self, **traits ): """ Initializes the object. """ super( AnFBIViewer, self ).__init__( **traits ) source = read_file( self.file_name ) if source is not None: text = source.split( '\n' ) nlines = self.lines if nlines >= 0: self.nlines = nlines line = self.line - 1 source = '\n'.join( text[ line: line + nlines ] ) self.line = 1 self.starting_line = line else: self.nlines = len( text ) self.selected_line = self.cursor = self.line self.source = source self.module = fbi_object.get_module( self.file_name ) self.module.on_trait_change( self.update_viewer, 'bp_lines' ) self.module.on_trait_change( self.update_viewer, 'bp_lines_items' ) title = self.file_name object = self.object if object is not None: title += ' Object: %s(0x%08X)' % ( object.__class__.__name__, id( object ) ) self.title = title self.update_viewer() #--------------------------------------------------------------------------- # Updates the viewer when the current set of breakpoint lines changes: #--------------------------------------------------------------------------- def update_viewer ( self ): """ Updates the viewer when the current set of breakpoint lines changes. """ n = self.nlines sline = self.starting_line bp_lines = [ i - sline for i in fbi_object.break_point_lines( self.file_name ) ] self.bp_lines = [ i for i in bp_lines if 0 <= i <= n ] self._cursor_changed() #--------------------------------------------------------------------------- # Handles the user selecting a new line: #--------------------------------------------------------------------------- def _cursor_changed ( self ): """ Handles the user selecting a new line. """ self.has_bp = (self.cursor in self.bp_lines) self.selected_line = self.cursor #--------------------------------------------------------------------------- # Handles the 'Set' breakpoint button being clicked: #--------------------------------------------------------------------------- def _bp_set_changed ( self ): """ Handles the 'Set' breakpoint button being clicked. """ condition = self.condition.strip() if self.object_only: self_check = ('id(self) == %d' % id( self.object )) if condition != '': condition = '(%s) and (%s)' % ( condition, self_check ) else: condition = self_check fbi_object.add_break_point( self.file_name, self.cursor + self.starting_line, self.bp_type, condition ) #--------------------------------------------------------------------------- # Handles the 'Reset' breakpoint button being clicked: #--------------------------------------------------------------------------- def _bp_reset_changed ( self ): """ Handles the 'Reset' breakpoint button being clicked. """ fbi_object.remove_break_point( self.file_name, self.cursor + self.starting_line )
def create_view(model_view, readonly=False, show_units=True): if show_units: columns = [ ObjectColumn(name='name', label='Name', editable=False, width=0.3), ObjectColumn(name='units', label='Units', editable=False, width=0.3), ObjectColumn(name='binding', label='Value', editable=True, width=0.4), ] else: columns = [ ObjectColumn(name='name', label='Name', editable=False, width=0.4), ObjectColumn(name='binding', label='Value', editable=True, width=0.6), ] if readonly: code_editor_style = 'readonly' else: code_editor_style = 'simple' view = View( VSplit( HGroup( VGroup( Label("Inputs"), Item( 'object.model.inputs', # minimum settings to get rid of # toolbar at top of table. editor=TableEditor( columns=columns, editable=True, configurable=False, sortable=False, sort_model=True, selection_bg_color='white', selection_color='black', label_bg_color=WindowColor, cell_bg_color='white', ), show_label=False, ), ), VGroup( Label("Outputs"), Item( 'object.model.outputs', # minimum settings to get rid of # toolbar at top of table. editor=TableEditor( columns=columns, editable=True, configurable=False, sortable=False, sort_model=True, selection_bg_color='white', selection_color='black', label_bg_color=WindowColor, cell_bg_color='white', ), show_label=False, ), ), ), Group( Item('object.model.code', editor=CodeEditor(), style=code_editor_style, show_label=False), ), ), model_view=model_view, width=720, # about 80 columns wide on code view. height=700, resizable=True, buttons=menu.OKCancelButtons, close_result=False, ) return view
table_editor = TableEditor( columns=[ MatchesColumn1( name='matches', label='#', editable=False, width=0.05, horizontal_alignment='center'), MatchesColumn2( name='matches', width=0.35, format_func=lambda x: ( x + [''])[0].strip(), editor=CodeEditor( line='object.live_search.selected_match', selected_line='object.live_search.selected_match'), style='readonly', edit_width=0.95, edit_height=0.33), FileColumn( name='base_name', label='Name', width=0.30, editable=False), ObjectColumn( name='ext_path', label='Path', width=0.30, editable=False), ],
class FileInspector ( HasPrivateTraits ): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # The inspector page name: name = Property # The name of the file being inspected: file_name = Title( draggable = 'Drag the file name.' ) # The starting line number: line = Int # The number of lines (start at 'line'): lines = Int( -1 ) # The text being inspected: text = Code #--------------------------------------------------------------------------- # Traits view definitions: #--------------------------------------------------------------------------- view = View( VGroup( Item( 'file_name' ), Item( 'text~', editor = CodeEditor( selected_line = 'line' ) ), show_labels = False ) ) #--------------------------------------------------------------------------- # Handles the 'file_name' trait being changed: #--------------------------------------------------------------------------- def _file_name_changed ( self, old_file_name, new_file_name ): """ Handles the 'file_name' trait being changed. """ if old_file_name != '': file_watch.watch( self._update, old_file_name, remove = True ) if new_file_name != '': file_watch.watch( self._update, new_file_name ) self._update( new_file_name ) #--------------------------------------------------------------------------- # Updates the view with the contents of the specified file: #--------------------------------------------------------------------------- def _update ( self, file_name ): """ Updates the view with the contents of the specified file. """ data = read_file( file_name ) if data is not None: if self.is_text( data ): if self.lines > 0: self.text = '\n'.join( data.split( '\n' ) [ max( 0, self.line - 1 ): self.line + self.lines - 1 ] ) else: self.text = data else: format = self.format self.text = '\n'.join( [ format( i, data[ i: i + 16 ] ) for i in range( 0, len( data ), 16 ) ] ) #--------------------------------------------------------------------------- # Implementation of the 'name' property: #--------------------------------------------------------------------------- def _get_name ( self ): if self._name != '': return self._name return basename( self.file_name ) def _set_name ( self, name ): self._name = name #--------------------------------------------------------------------------- # Returns whether a specified buffer contains only valid text characters: #--------------------------------------------------------------------------- def is_text ( self, buffer ): """ Returns whether a specified buffer contains only valid text characters. """ for i in range( min( 256, len( buffer ) ) ): if not buffer[i] in text_characters: return False return True #--------------------------------------------------------------------------- # Formats a binary string of data as a hex encoded string: #--------------------------------------------------------------------------- def format ( self, offset, data ): """ Formats a binary string of data as a hex encoded string. """ hb = [ self.hex_bytes( data[ i: i + 4 ] ) for i in range( 0, 16, 4 ) ] return ('#%08X %s %s %s %s |%s|' % ( offset, hb[0], hb[1], hb[2], hb[3], self.ascii_bytes( data ) )) #--------------------------------------------------------------------------- # Returns the hex encoding of a string of up to 4 bytes of data: #--------------------------------------------------------------------------- def hex_bytes ( self, data ): return ''.join( [ self.hex_byte( data[ i: i + 1 ] ) for i in range( 0, 4 ) ] ) #--------------------------------------------------------------------------- # Returns the hex encoding of a 0 or 1 length string of data: #--------------------------------------------------------------------------- def hex_byte ( self, byte ): """ Returns the hex encoding of a 0 or 1 length string of data. """ if len( byte ) == 0: return ' ' return ('%02X' % ord( byte )) #--------------------------------------------------------------------------- # Returns the ascii encoding of up to 16 bytes of data: #--------------------------------------------------------------------------- def ascii_bytes ( self, data ): return ''.join( [ self.ascii_byte( data[ i: i + 1 ] ) for i in range( 0, 16 ) ] ) #--------------------------------------------------------------------------- # Returns the ascii encoding of a 0 or 1 length string of data: #--------------------------------------------------------------------------- def ascii_byte ( self, byte ): """ Returns the hex encoding of a 0 or 1 length string of data. """ if len( byte ) == 0: return ' ' n = ord( byte ) if 32 <= n <= 127: return byte return '.'
class LiveSearch(HasTraits): # The currenty root directory being searched: root = Directory(getcwd(), entries=10) # Should sub directories be included in the search: recursive = Bool(True) # The file types to include in the search: file_type = Enum('Python', 'C', 'C++', 'Java', 'Ruby') # The current search string: search = Str() # Is the search case sensitive? case_sensitive = Bool(False) # The live search table filter: filter = Property # Instance( TableFilter ) # The current list of source files being searched: source_files = Property # List( SourceFile ) # The currently selected source file: selected = Any # Instance( SourceFile ) # The contents of the currently selected source file: selected_contents = Property # List( Str ) # The currently selected match: selected_match = Int() # The text line corresponding to the selected match: selected_line = Property # Int # The full name of the currently selected source file: selected_full_name = Property # File # The list of marked lines for the currently selected file: mark_lines = Property # List( Int ) # Summary of current number of files and matches: summary = Property # Str #-- Traits UI Views ------------------------------------------------------ view = View( VGroup( HGroup( Item('root', id='root', label='Path', width=0.5 ), Item('recursive'), Item('file_type', label='Type'), Item('search', id='search', width=0.5, editor=HistoryEditor(auto_set=True) ), Item('case_sensitive') ), VSplit( VGroup( Item('summary', editor=TitleEditor() ), Item('source_files', id='source_files', editor=table_editor ), dock='horizontal', show_labels=False ), VGroup( HGroup( Item('selected_full_name', editor=TitleEditor(), springy=True ), Item('selected_full_name', editor=DNDEditor(), tooltip='Drag this file' ), show_labels=False ), Item('selected_contents', style='readonly', editor=CodeEditor(mark_lines='mark_lines', line='selected_line', selected_line='selected_line') ), dock='horizontal', show_labels=False ), id='splitter' ) ), title='Live File Search', id='enthought.examples.demo.Advanced.' 'Table_editor_with_live_search_and_cell_editor.LiveSearch', width=0.75, height=0.67, resizable=True ) #-- Property Implementations --------------------------------------------- @property_depends_on('search, case_sensitive') def _get_filter(self): if len(self.search) == 0: return lambda x: True return lambda x: len(x.matches) > 0 @property_depends_on('root, recursive, file_type') def _get_source_files(self): root = self.root if root == '': root = getcwd() file_types = FileTypes[self.file_type] if self.recursive: result = [] for dir_path, dir_names, file_names in walk(root): for file_name in file_names: if splitext(file_name)[1] in file_types: result.append(SourceFile( live_search=self, full_name=join(dir_path, file_name))) return result return [SourceFile(live_search=self, full_name=join(root, file_name)) for file_name in listdir(root) if splitext(file_name)[1] in file_types] @property_depends_on('selected') def _get_selected_contents(self): if self.selected is None: return '' return ''.join(self.selected.contents) @property_depends_on('selected') def _get_mark_lines(self): if self.selected is None: return [] return [int(match.split(':', 1)[0]) for match in self.selected.matches] @property_depends_on('selected, selected_match') def _get_selected_line(self): selected = self.selected if (selected is None) or (len(selected.matches) == 0): return 1 return int(selected.matches[self.selected_match - 1 ].split(':', 1)[0]) @property_depends_on('selected') def _get_selected_full_name(self): if self.selected is None: return '' return self.selected.full_name @property_depends_on('source_files, search, case_sensitive') def _get_summary(self): source_files = self.source_files search = self.search if search == '': return 'A total of %d files.' % len(source_files) files = 0 matches = 0 for source_file in source_files: n = len(source_file.matches) if n > 0: files += 1 matches += n return 'A total of %d files with %d files containing %d matches.' % ( len(source_files), files, matches) #-- Traits Event Handlers ------------------------------------------------ def _selected_changed(self): self.selected_match = 1 def _source_files_changed(self): if len(self.source_files) > 0: self.selected = self.source_files[0] else: self.selected = None
class Lab(ASection): """ Defines a lab, which is a section of a tutorial with only Python code. This type of section might typically follow a lecture which introduced the code being worked on in the lab. """ # The set-up code (if any) for the lab: setup = Instance(CodeItem) # The list of code items for the lab: snippets = List(CodeItem) # The list of visible code items for the lab: visible_snippets = Property(depends_on='visible', cached=True) # The currently selected snippet: snippet = Instance(CodeItem) # Should normally hidden code items be shown? visible = Bool(False) # The dictionary containing the items from the Python code execution: values = Dict # The run Python code button: run = Button(image=ImageResource('run'), height_padding=1) # User error message: message = Str # The output produced while the program is running: output = Str # The current demo pane (if any): demo = Instance(DemoPane, ()) view = View(VSplit( VGroup( Item('visible_snippets', style='custom', show_label=False, editor=snippet_editor), HGroup( Item('run', style='custom', show_label=False, tooltip='Run the Python code'), '_', Item('message', springy=True, show_label=False, editor=TitleEditor()), '_', Item('visible', label='View hidden sections'), ), ), Tabbed( Item( 'values', id='values_1', label='Shell', editor=ShellEditor(share=True), dock='tab', export='DockWindowShell', ), Item( 'values', id='values_2', editor=ValueEditor(), dock='tab', export='DockWindowShell', ), Item( 'output', style='readonly', editor=CodeEditor(show_line_numbers=False, selected_color=0xFFFFFF), dock='tab', export='DockWindowShell', ), Item( 'demo', id='demo', style='custom', resizable=True, dock='tab', export='DockWindowShell', ), show_labels=False, ), id='splitter', ), id='enthought.tutor.lab', handler=LabHandler) def _run_changed(self): """ Runs the current set of snippet code. """ self.run_code() @cached_property def _get_visible_snippets(self): """ Returns the list of code items that are currently visible. """ if self.visible: return self.snippets return [snippet for snippet in self.snippets if (not snippet.hidden)] def run_code(self): """ Runs all of the code snippets associated with the section. """ # Reconstruct the lab code from the current set of code snippets: start_line = 1 module = '' for snippet in self.snippets: snippet.start_line = start_line module = '%s\n\n%s' % (module, snippet.content) start_line += (snippet.content.count('\n') + 2) # Reset any syntax error and message log values: self.message = self.output = '' # Redirect standard out and error to the message log: stdout, stderr = sys.stdout, sys.stderr sys.stdout = sys.stderr = StdOut(self) try: try: # Get the execution context dictionary: values = self.values # Clear out any special variables defined by the last run: for name in ('demo', 'popup'): if isinstance(values.get(name), HasTraits): del values[name] # Execute the current lab code: exec module[2:] in values, values # fixme: Hack trying to update the Traits UI view of the dict. self.values = {} self.values = values # Handle a 'demo' value being defined: demo = values.get('demo') if not isinstance(demo, HasTraits): demo = NoDemo() self.demo.demo = demo # Handle a 'popup' value being defined: popup = values.get('popup') if isinstance(popup, HasTraits): popup.edit_traits(kind='livemodal') except SyntaxError, excp: # Convert the line number of the syntax error from one in the # composite module to one in the appropriate code snippet: line = excp.lineno if line is not None: snippet = self.snippets[0] for s in self.snippets: if s.start_line > line: break snippet = s line -= (snippet.start_line - 1) # Highlight the line in error: snippet.selected_line = line # Select the correct code snippet: self.snippet = snippet # Display the syntax error message: self.message = '%s in column %s of line %s' % ( excp.msg.capitalize(), excp.offset, line) else: # Display the syntax error message without line # info: self.message = excp.msg.capitalize() except: import traceback traceback.print_exc() finally:
class LoggerView(TraitsUIView): """The Workbench View showing the list of log items.""" id = Str("apptools.logger.plugin.view.logger_view.LoggerView") name = Str("Logger") service = Instance(LoggerService) log_records = List(Instance(logging.LogRecord)) formatted_records = Property(Str, depends_on="log_records") activated = Instance(logging.LogRecord) activated_text = Property(Str, depends_on="activated") reset_button = Button("Reset Logs") show_button = Button("Complete Text Log") copy_button = Button("Copy Log to Clipboard") code_editor = CodeEditor(lexer="null", show_line_numbers=False) log_records_editor = TabularEditor(adapter=LogRecordAdapter(), editable=False, activated="activated") trait_view = View( Group( Item("log_records", editor=log_records_editor), Group( Item("reset_button"), spring, Item("show_button"), Item("copy_button"), orientation="horizontal", show_labels=False, ), show_labels=False, )) ########################################################################### # LogQueueHandler view interface ########################################################################### def update(self, force=False): """Update 'log_records' if our handler has new records or 'force' is set. """ service = self.service if service.handler.has_new_records() or force: log_records = [ rec for rec in service.handler.get() if rec.levelno >= service.preferences.level_ ] log_records.reverse() self.log_records = log_records ########################################################################### # Private interface ########################################################################### @on_trait_change("service.preferences.level_") def _update_log_records(self): self.service.handler._view = self self.update(force=True) def _reset_button_fired(self): self.service.handler.reset() self.log_records = [] def _show_button_fired(self): self.edit_traits(view=View( Item( "formatted_records", editor=self.code_editor, style="readonly", show_label=False, ), width=800, height=600, resizable=True, buttons=["OK"], title="Complete Text Log", )) def _copy_button_fired(self): clipboard.text_data = self.formatted_records @cached_property def _get_formatted_records(self): return "\n".join([ self.service.handler.formatter.format(record) for record in self.log_records ]) def _activated_changed(self): if self.activated is None: return msg = self.activated.getMessage() if self.service.preferences.enable_agent: dialog = QualityAgentView(msg=msg, service=self.service) dialog.open() else: self.edit_traits(view=View( Item( "activated_text", editor=self.code_editor, style="readonly", show_label=False, ), width=800, height=600, resizable=True, buttons=["OK"], title="Log Message Detail", )) @cached_property def _get_activated_text(self): if self.activated is None: return "" else: return self.activated.getMessage()
class Lesson(Lab): """ Defines a lesson, which is a section of a tutorial with both descriptive information and associated Python code. """ # The list of descriptive items for the lesson: descriptions = List(ATutorialItem) view = View( HSplit( Item( 'descriptions', label='Lesson', style='custom', show_label=False, dock='horizontal', editor=list_editor, ), VSplit( VGroup( Item( 'visible_snippets', style='custom', show_label=False, editor=snippet_editor, ), HGroup( Item( 'run', style='custom', show_label=False, tooltip='Run the Python code', ), '_', Item( 'message', springy=True, show_label=False, editor=TitleEditor(), ), '_', Item( 'visible', label='View hidden sections', ), ), label='Lab', dock='horizontal', ), Tabbed( Item( 'values', id='values_1', label='Shell', editor=ShellEditor(share=True), dock='tab', export='DockWindowShell', ), Item( 'values', id='values_2', editor=ValueEditor(), dock='tab', export='DockWindowShell', ), Item( 'output', style='readonly', editor=CodeEditor(show_line_numbers=False, selected_color=0xFFFFFF), dock='tab', export='DockWindowShell', ), Item( 'demo', id='demo', style='custom', resizable=True, dock='tab', export='DockWindowShell', ), show_labels=False, ), label='Lab', dock='horizontal', ), id='splitter', ), id='enthought.tutor.lesson', handler=LabHandler, )
editable=True, configurable=False, sortable=False, sort_model = True, selection_bg_color = 'white', selection_color = 'black', label_bg_color = WindowColor, cell_bg_color = 'white', ), show_label=False, ), ), ), Group( Item('code', editor=CodeEditor(), show_label=False), Item('load_error', show_label=False), ), ), width=720, # about 80 columns wide on code view. height=700, resizable=True, buttons=menu.OKCancelButtons, close_result=False, ) if __name__ == "__main__": from blockcanvas.function_tools.local_python_function import \