class Attachments(HasTraits): application = Any() message = Any() def __init__(self, message, **traits): traits = traits.copy() traits['message'] = message super(Attachments, self).__init__(**traits) # FIXME: all of the package_*() methods refer to deprecated project plugins. def package_workspace(self): if self.application is None: pass workspace = self.application.get_service('enthought.envisage.project.IWorkspace') if workspace is not None: dir = workspace.path self._attach_directory(dir) return def package_single_project(self): if self.application is None: pass single_project = self.application.get_service('enthought.envisage.single_project.ModelService') if single_project is not None: dir = single_project.location self._attach_directory(dir) def package_any_relevant_files(self): self.package_workspace() self.package_single_project() return def _attach_directory(self, dir): relpath = os.path.basename(dir) import zipfile from cStringIO import StringIO ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) msg = MIMEBase(maintype, subtype) file_object = StringIO() zip = zipfile.ZipFile(file_object, 'w') _append_to_zip_archive(zip, dir, relpath) zip.close() msg.set_payload(file_object.getvalue()) Encoders.encode_base64(msg) # Encode the payload using Base64 msg.add_header('Content-Disposition', 'attachment', filename='project.zip') self.message.attach(msg) file_object.close()
class ShowVolumes(Action): """ Open a new file in the text editor """ tooltip = "Create a volume" description = "Create a volume" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): from cvolume_action import VolumeParameter from scripts import volslice cfile = self.window.application.get_service( 'cviewer.plugins.cff2.cfile.CFile') so = VolumeParameter(cfile) so.edit_traits(kind='livemodal') if True: #not so.pointset_da[so.pointset]['name'] == "None": # if cancel, not create surface # create a temporary file import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') f.write(volslice % so.volumes[so.myvolume]['name']) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class SimpleConnectionMatrix(Action): tooltip = "Show simple connection matrix" description = "Show simple connection matrix" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): from cnetwork_action import MatrixEdgeNetworkParameter from scripts import conmatrixpyplot cfile = self.window.application.get_service( 'cviewer.plugins.cff2.cfile.CFile') no = MatrixEdgeNetworkParameter(cfile) no.edit_traits(kind='livemodal') if not no.netw[no.graph]['name'] == "None": # if cancel, not create surface # create a temporary file import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') f.write(conmatrixpyplot % (no.netw[no.graph]['name'], no.edge_label)) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class DataBase ( HasTraits ): # The name of the data base file: file_name = File # The open file handle used to access the data base: file = Any( transient = True )
class ExpressionColumn(ObjectColumn): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- # The Python expression used to return the value of the column expression = Expression # Is this column editable? editable = Constant(False) # The globals dictionary that should be passed to the expression evaluation: globals = Any({}) #--------------------------------------------------------------------------- # Gets the value of the column for a specified object: #--------------------------------------------------------------------------- def get_raw_value(self, object): """ Gets the unformatted value of the column for a specified object. """ try: return eval(self.expression_, self.globals, {'object': object}) except: logger.exception('Error evaluating table column expression: %s' % self.expression) return None
class ImageIndexTool(BaseTool): """ A tool to set the slice of a cube based on the user's mouse movements or clicks. """ # This callback will be called with the index into self.component's # index and value: # callback(tool, x_index, y_index) # where *tool* is a reference to this tool instance. The callback # can then use tool.token. callback = Any() # This callback (if it exists) will be called with the integer number # of mousewheel clicks wheel_cb = Any() # This token can be used by the callback to decide how to process # the event. token = Any() # Whether or not to update the slice info; we enter select mode when # the left mouse button is pressed and exit it when the mouse button # is released # FIXME: This is not used right now. select_mode = Bool(False) def normal_left_down(self, event): self._update_slices(event) def normal_right_down(self, event): self._update_slices(event) def normal_mouse_move(self, event): if event.left_down or event.right_down: self._update_slices(event) def _update_slices(self, event): plot = self.component ndx = plot.map_index((event.x, event.y), threshold=5.0, index_only=True) if ndx: self.callback(self, *ndx) def normal_mouse_wheel(self, event): if self.wheel_cb is not None: self.wheel_cb(self, event.mouse_wheel)
class ComputeNBS(Action): tooltip = "Compute NBS" description = "Compute NBS" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): # from cnetwork_nbs_action import NBSNetworkParameter, NBSMoreParameter from scripts import nbsscript # cfile = self.window.application.get_service('cviewer.plugins.cff2.cfile.CFile') # # no = NBSNetworkParameter(cfile) # no.edit_traits(kind='livemodal') # # if (len(no.selected1) == 0 or len(no.selected2) == 0): # return # # mo = NBSMoreParameter(cfile, no.selected1[0], no.selected2[0]) # mo.edit_traits(kind='livemodal') # # import datetime as dt # a=dt.datetime.now() # ostr = '%s%s%s' % (a.hour, a.minute, a.second) # if not (len(no.selected1) == 0 or len(no.selected2) == 0): # # if cancel, not create surface # # create a temporary file # import tempfile # myf = tempfile.mktemp(suffix='.py', prefix='my') # f=open(myf, 'w') # f.write(nbsscript % (str(no.selected1), # mo.first_edge_value, # str(no.selected2), # mo.second_edge_value, # mo.THRES, # mo.K, # mo.TAIL, # ostr)) # f.close() # # self.window.workbench.edit(File(myf), kind=TextEditor,use_existing=False) import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') f.write(nbsscript) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class OpenFile(Action): """ Open a file in the text editor """ tooltip = "Create a surface" description = "Create a surface" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, file, event=None): print "event", event print "app", self.application print "window", self.window
class NewFileAction(Action): """ Open a new file in the text editor. """ tooltip = "Create a new file for editing" description = "Create a new file for editing" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): logger.info('NewFileAction.perform()') self.window.workbench.edit(File(''), kind=TextEditor, use_existing=False)
class Points3d(Pipeline): """ Plots glyphs (like points) at the position of the supplied data. **Function signatures**:: points3d(x, y, z...) points3d(x, y, z, s, ...) points3d(x, y, z, f, ...) x, y and z are numpy arrays, or lists, all of the same shape, giving the positions of the points. If only 3 arrays x, y, z are given, all the points are drawn with the same size and color. In addition, you can pass a fourth array s of the same shape as x, y, and z giving an associated scalar value for each point, or a function f(x, y, z) returning the scalar value. This scalar value can be used to modulate the color and the size of the points.""" _source_function = Callable(scalar_scatter) _pipeline = [ GlyphFactory, ] scale_factor = Any('auto', help='The scaling applied to the glyphs. ' 'the size of the glyph is by default calculated ' 'from the inter-glyph spacing. Specify a float to ' 'give the maximum glyph size in drawing units') def __call_internal__(self, *args, **kwargs): """ Override the call to be able to scale automatically the glyphs. """ scale_factor = kwargs.get('scale_factor', 'auto') if scale_factor == 'auto': kwargs['scale_factor'] = 1 g = Pipeline.__call_internal__(self, *args, **kwargs) if scale_factor == 'auto': g.glyph.glyph.scale_factor = \ tools._typical_distance(g.mlab_source.dataset) g.glyph.glyph.clamping = True else: g.glyph.glyph.clamping = False return g
class MainWindow(ApplicationWindow): """ The main application window. """ # The pyface Timer. my_timer = Any() # Count each time the timer task executes. counter = Int def __init__(self, **traits): """ Creates a new application window. """ # Base class constructor. super(MainWindow, self).__init__(**traits) # Add a menu bar. self.menu_bar_manager = MenuBarManager( MenuManager( Action(name='Start Timer', on_perform=self._start_timer), Action(name='Stop Timer', on_perform=self._stop_timer), Action(name='E&xit', on_perform=self.close), name='&File', )) return def _start_timer(self): """Called when the user selects "Start Timer" from the menu.""" if self.my_timer is None: # First call, so create a Timer. It starts automatically. self.my_timer = Timer(500, self._timer_task) else: self.my_timer.Start() def _stop_timer(self): """Called when the user selecte "Stop Timer" from the menu.""" if self.my_timer is not None: self.my_timer.Stop() def _timer_task(self): """The method run periodically by the timer.""" self.counter += 1 print "counter = %d" % self.counter
class _AutomaticFilterFactory(PipeFactory): """The base class for any auto-generated factory classes. NOTE: This class requires that the `_metadata` trait be set to the metadata object for the object for which this is a factory. """ # The target. _target = Property # The saved target that is created once and then always returned. _saved_target = Any(None) def _get__target(self): """Getter for the _target trait.""" if self._saved_target is None: self._saved_target = self._metadata.get_callable()() return self._saved_target
class ILoadMiniDriver(IODriver): """ Input driver for the iLoad Mini from Loadstar. """ name = Str('iLoad Mini Driver') view = View(Item(name='serial_port', label='Serial port'), Item(name='connect', label='Connect'), Item(name='disconnect', label='Disconnect'), Item(name='tare', label='Tare'), title='iLoad Mini input driver') serial_port = Str() connect = Button() disconnect = Button() tare = Button() _sp = Any() @on_trait_change('serial_port') @on_trait_change('connect') def do_connect(self): print 'iLoad Mini Connecting' self.close() try: self._sp = serial.Serial(self.serial_port, 9600, timeout=1) self._sp.write('O0W0\r') except IOError: self._sp = None @on_trait_change('disconnect') def do_disconnect(self): print 'iLoad Mini Disconnecting' if self._sp: self._sp.close() self._sp = None def receive(self): if self._sp: return self._sp.readline() else: return None
class NetworkReport(Action): tooltip = "Network Report" description = "Network Report" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): from scripts import reportlab import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') f.write(reportlab) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class XNATPushPull(Action): tooltip = "Push and pull files from and to XNAT Server" description = "Push and pull files from and to XNAT Server" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): from scripts import pushpull import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') f.write(pushpull) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class WriteGEXF(Action): tooltip = "Write Gephi GEXF file" description = "Write Gephi GEXF file" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): from scripts import writegexf import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') f.write(writegexf) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class NipypeBet(Action): tooltip = "Brain extraction using BET" description = "Brain extraction using BET" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): from scripts import nipypebet import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') f.write(nipypebet) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class CorticoCortico(Action): tooltip = "Extract cortico-cortico fibers" description = "Extract cortico-cortico fibers" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): from scripts import corticocortico import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') f.write(corticocortico) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class ToolkitEditorFactory(EditorFactory): #--------------------------------------------------------------------------- # Trait definitions: #--------------------------------------------------------------------------- value = Any(0) # Value to set when button is clicked label = Str # Optional label for button #--------------------------------------------------------------------------- # 'Editor' factory methods: #--------------------------------------------------------------------------- def simple_editor(self, ui, object, name, description, parent): return SimpleEditor(parent, factory=self, ui=ui, object=object, name=name, description=description)
class ShowTracks(Action): tooltip = "Show tracks between two regions" description = "Show tracks between two regions" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): from scripts import ctrackedge import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') f.write(ctrackedge) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class NetworkVizTubes(Action): tooltip = "Show 3D Network with Tubes" description = "Show 3D Network with Tubes and colorcoded Nodes" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): from scripts import threedviz2 import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') f.write(threedviz2) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class TrimCase(HasTraits): # Instance(RunCase) runcase = Any() type = Trait('horizontal flight', {'horizontal flight':'c1', 'looping flight':'c2'}) parameters = Dict(String, Instance(Parameter)) parameter_view = List(Parameter, []) traits_view = View(Group(Item('type')), Group(Item('parameter_view', editor=Parameter.editor, show_label=False), label='Parameters'), Item(), # so that groups are not tabbed kind='livemodal', buttons=['OK'] ) #@on_trait_change('type,parameters.value') def update_parameters_from_avl(self): #print 'in update_parameters_from_avl' avl = self.runcase.avl avl.sendline('oper') avl.expect(AVL.patterns['/oper']) avl.sendline(self.type_) avl.expect(AVL.patterns['/oper/m']) constraint_lines = [line.strip() for line in avl.before.splitlines()] i1 = constraint_lines.index('=================================================') constraint_lines = constraint_lines[i1:] #print constraint_lines groups = [re.search(RunCase.patterns['parameter'], line) for line in constraint_lines] params = {} for group in groups: if group is not None: group = group.groupdict() pattern = group['pattern'] name = pattern unit = group.get('unit', '') unit = unit if unit is not None else '' params[name] = Parameter(name=name, pattern=pattern, cmd=group['cmd'], unit=unit, value=float(group['val'])) AVL.goto_state(avl) self.parameters = params self.parameter_view = sorted(params.values(), key=lambda x:x.name.upper()) return self
class ShowSurfaces(Action): """ Open a new file in the text editor """ tooltip = "Create a surface" description = "Create a surface" # The WorkbenchWindow the action is attached to. window = Any() def perform(self, event=None): from csurface_action import SurfaceParameter from scripts import surfscript cfile = self.window.application.get_service( 'cviewer.plugins.cff2.cfile.CFile') so = SurfaceParameter(cfile) so.edit_traits(kind='livemodal') if not so.pointset_da[so.pointset]['name'] == "None": # if cancel, not create surface # create a temporary file import tempfile myf = tempfile.mktemp(suffix='.py', prefix='my') f = open(myf, 'w') if so.labels_da[so.labels].has_key('da_idx'): labels = so.labels_da[so.labels]['da_idx'] else: labels = 0 f.write(surfscript % (so.pointset_da[so.pointset]['name'], so.pointset_da[so.pointset]['da_idx'], so.faces_da[so.faces]['name'], so.faces_da[so.faces]['da_idx'], so.labels_da[so.labels]['name'], labels)) f.close() self.window.workbench.edit(File(myf), kind=TextEditor, use_existing=False)
class SimpleFileDriver(IODriver): """ Simple file input driver. Reads lines from a file periodically. """ name = Str('Simple File Driver') view = View(Item(name='data_file', label='Input file'), Item(name='period_ms', label='Period / ms'), title='Simple file input driver') data_file = File() period_ms = Range(10, 10000, 200) _fp = Any() def open(self): try: self._fp = open(self.data_file, 'r') except IOError: self._fp = None def close(self): if self._fp: self._fp.close() def receive(self): if self._fp: time.sleep(self.period_ms / 1000.0) return self._fp.readline() else: return None @on_trait_change('data_file') def reopen_file(self): self.close() self.open()
class LoggerService(HasTraits): """ The persistent service exposing the Logger plugin's API. """ # The Envisage application. application = Any() # The logging Handler we use. handler = Any() # Our associated LoggerPreferences. preferences = Any() # The view we use. plugin_view = Instance(WorkbenchView) # Contributions from other plugins. mail_files = Property(List(Callable)) def save_preferences(self): """ Save the preferences. """ self.preferences.preferences.save() def whole_log_text(self): """ Return all of the logged data as formatted text. """ lines = [self.handler.format(rec) for rec in self.handler.get()] # Ensure that we end with a newline. lines.append('') text = '\n'.join(lines) return text def create_email_message(self, fromaddr, toaddrs, ccaddrs, subject, priority, include_userdata=False, stack_trace="", comments="", include_environment=True): """ Format a bug report email from the log files. """ from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText message = MIMEMultipart() message['Subject'] = "%s [priority=%s]" % (subject, priority) message['To'] = ', '.join(toaddrs) message['Cc'] = ', '.join(ccaddrs) message['From'] = fromaddr message.preamble = 'You will not see this in a MIME-aware mail ' \ 'reader.\n' message.epilogue = ' ' # To guarantee the message ends with a newline # First section is simple ASCII data ... m = [] m.append("Bug Report") m.append("==============================") m.append("") if len(comments) > 0: m.append("Comments:") m.append("========") m.append(comments) m.append("") if len(stack_trace) > 0: m.append("Stack Trace:") m.append("===========") m.append(stack_trace) m.append("") msg = MIMEText('\n'.join(m)) message.attach(msg) # Include the log file ... logtext = self.whole_log_text() msg = MIMEText(logtext) msg.add_header('Content-Disposition', 'attachment', filename='logfile.txt') message.attach(msg) # Include the environment variables ... # FIXME: ask the user, maybe? if include_environment: # Transmit the user's environment settings as well. Main purpose is # to work out the user name to help with following up on bug reports # and in future we should probably send less data. entries = [] for key, value in sorted(os.environ.items()): entries.append('%30s : %s\n' % (key, value)) msg = MIMEText(''.join(entries)) msg.add_header('Content-Disposition', 'attachment', filename='environment.txt') message.attach(msg) if include_userdata and len(self.mail_files) != 0: f = StringIO() zf = zipfile.ZipFile(f, 'w') for mf in self.mail_files: mf(zf) zf.close() msg = MIMEApplication(f.getvalue()) msg.add_header('Content-Disposition', 'attachment', filename='userdata.zip') message.attach(msg) return message def send_bug_report(self, smtp_server, fromaddr, toaddrs, ccaddrs, message): """ Send a bug report email. """ try: import smtplib logger.debug("Connecting to: %s" % smtp_server) server = smtplib.SMTP(host=smtp_server) logger.debug("Connected: %s" % server) #server.set_debuglevel(1) server.sendmail(fromaddr, toaddrs + ccaddrs, message.as_string()) server.quit() except Exception, e: logger.exception("Problem sending error report")
class AcmeUIPreferencesHelper(PreferencesHelper): width = Any(is_str=True)
class _SceneEditor(Editor): """ An editor for SceneModels. """ # The editor is scrollable, so override the default. scrollable = Bool(True) # Internal GUI traits. _sizer = Any() _scene = Any() #### Public 'Editor' interface ############################################# def init(self, parent): """ Finishes initializing the editor by creating the underlying toolkit widget. """ factory = self.factory self.control = wx.Panel(parent, -1) self._sizer = wx.BoxSizer(wx.VERTICAL) self.control.SetSizer(self._sizer) assert self.value.scene_editor is None, \ "The SceneModel may only have one active editor!" self._create_scene() self.value.activated = True def update_editor(self): """ Updates the editor when the object trait changes external to the editor. """ # Everything should really be handled elsewhere in trait notifications. # Just pass here. pass def dispose(self): """ Disposes of the contents of an editor. """ # Remove notifications. self.value.closing = True self.value.scene_editor = None self._setup_scene_notifications(remove=True) # Remove the current scene. if self._scene is not None: self._scene.close() self._scene = None self._sizer = None # This will destroy self.control and all of its children, including the # scene's control. super(_SceneEditor, self).dispose() #### Private '_SceneEditor' interface ################################## def _create_scene(self): """ Create the TVTK scene widget. """ factory = self.factory self._scene = factory.scene_class(self.control) scene = self._scene self.value.scene_editor = scene # Disable rendering on the scene until we're finished. scene.disable_render = True # Add all of the actors in the current actor map. for obj, actors in self.value.actor_map.items(): self._add_actors_widgets(actors) # Add all of the actors in the current actor map. self._add_actors_widgets(self.value.actor_list) # Set up Traits notifications. self._setup_scene_notifications() # Re-enable rendering. scene.disable_render = False # Ensure the scene's wx control is sized to fill our view's area. Note # that the sizer doesn't automatically layout its contents upon adding # a new child so we have to force it to do a layout. self._sizer.Add(scene.control, 1, wx.EXPAND) self._sizer.Layout() wx.EVT_IDLE(scene.control, None) # Force a render. scene.render() def _setup_scene_notifications(self, remove=False): """ Set up or remove all of the Trait notifications that control the scene widget. """ traits_to_sync = [ 'foreground', 'anti_aliasing_frames', 'stereo', 'background', 'off_screen_rendering', 'polygon_smoothing', 'jpeg_progressive', 'point_smoothing', 'busy', 'disable_render', 'magnification', 'jpeg_quality', 'parallel_projection', 'line_smoothing' ] model = self.value scene = self._scene if not remove: scene.set(**model.get(traits_to_sync)) for trait in traits_to_sync: scene.sync_trait(trait, model, mutual=True, remove=remove) model.on_trait_change( scene.render, name='do_render', remove=remove, ) model.on_trait_change( self._actors_changed, name='actor_map_items', remove=remove, ) model.on_trait_change( self._actor_map_changed, name='actor_map', remove=remove, ) model.on_trait_change( self._actor_list_items_changed, name='actor_list_items', remove=remove, ) model.on_trait_change( self._actor_list_changed, name='actor_list', remove=remove, ) def _actors_changed(self, event): """ Handle the event of the actors in the actor map changing. """ scene = self._scene # Temporarily turn off rendering. We (re)store the old value of # disable_render because it may already be True. old_disable_render = scene.disable_render scene.disable_render = True try: for obj, actors in event.removed.items(): self._remove_actors_widgets(actors) for obj, actors in event.added.items(): self._add_actors_widgets(actors) for obj, actors in event.changed.items(): # The actors in the event are the old ones. Grab the new ones # from the actor map itself. self._remove_actors_widgets(actors) self._add_actors_widgets(self.value.actor_map[obj]) finally: scene.disable_render = old_disable_render scene.render() def _actor_map_changed(self, object, name, old, new): """ Handle the case when the entire actor map is set to something else. """ scene = self._scene # Temporarily turn off rendering. We (re)store the old value of # disable_render because it may already be True. old_disable_render = scene.disable_render scene.disable_render = True try: for obj, actors in old.items(): self._remove_actors_widgets(actors) for obj, actors in new.items(): self._add_actors_widgets(actors) finally: scene.disable_render = old_disable_render scene.render() def _actor_list_items_changed(self, event): self._actor_list_changed(self.value, 'actor_list', event.removed, event.added) def _actor_list_changed(self, object, name, old, new): """ Handle the event of the actors in the actor map changing. """ scene = self._scene # Temporarily turn off rendering. We (re)store the old value of # disable_render because it may already be True. old_disable_render = scene.disable_render scene.disable_render = True try: self._remove_actors_widgets(old) self._add_actors_widgets(new) finally: scene.disable_render = old_disable_render scene.render() def _separate_actors_widgets(self, actors_widgets): """Given a sequence (or single) of actors or widgets, this returns a list of just the actors and another of just the widgets. """ if not hasattr(actors_widgets, '__getitem__'): actors_widgets = [actors_widgets] actors = [] widgets = [] for actor in actors_widgets: if actor.is_a('vtk3DWidget') or actor.is_a( 'vtkInteractorObserver'): widgets.append(actor) else: actors.append(actor) return actors, widgets def _add_actors_widgets(self, actors_widgets): """Add actors and widgets to scene.""" scene = self._scene actors, widgets = self._separate_actors_widgets(actors_widgets) scene.add_actors(actors) enabled_info = self.value.enabled_info for widget in widgets: scene.add_widgets(widget, enabled_info.get(widget, True)) def _remove_actors_widgets(self, actors_widgets): """Remove actors and widgets from scene.""" scene = self._scene actors, widgets = self._separate_actors_widgets(actors_widgets) scene.remove_actors(actors) scene.remove_widgets(widgets)
class MyTextBoxOverlay(TextBoxOverlay): token = Any()
class MyLineInspector(DragTool): # The axis that this tool is parallel to. axis = Enum("index", "value", "index_x", "index_y") # The possible inspection modes of the tool. # # space: # The tool maps from screen space into the data space of the plot. # indexed: # The tool maps from screen space to an index into the plot's index array. inspect_mode = Enum("space", "indexed") # Respond to user mouse events? is_interactive = Bool(True) # Does the tool respond to updates in the metadata on the data source # and update its own position? is_listener = Bool(False) # If interactive, does the line inspector write the current data space point # to the appropriate data source's metadata? write_metadata = Bool(False) # The name of the metadata field to listen or write to. metadata_name = Str("selections") callback = Any() token = Any() handle_size = Float(5) #------------------------------------------------------------------------ # Override default values of inherited traits in BaseTool #------------------------------------------------------------------------ # This tool is visible (overrides BaseTool). visible = True # This tool is drawn as an overlay (overrides BaseTool). draw_mode = "overlay" # TODO:STYLE # Color of the line. color = ColorTrait("grey") # Width in pixels of the line. line_width = Float(1.0) # Dash style of the line. line_style = LineStyle("dash") index_position = Float(-1) # Last recorded position of the mouse _last_position = Trait(None, Any) def draw(self, gc, view_bounds=None): """ Draws this tool on a graphics context. Overrides BaseTool. """ # We draw at different points depending on whether or not we are # interactive. If both listener and interactive are true, then the # selection metadata on the plot component takes precendence. plot = self.component if plot is None: return # if self.is_listener: # tmp = self._get_screen_pts() # elif self.is_interactive: # tmp = self._last_position # # if tmp: # sx, sy = tmp # else: # return if self.axis == "index" or self.axis == "index_x": if self.index_position == -1: self.index_position = int((plot.x + plot.x2) / 2) self.index_changed() self._draw_vertical_line(gc, self.index_position) else: if self.index_position == -1: self.index_position = int((plot.y + plot.y2) / 2) self.index_changed() self._draw_horizontal_line(gc, self.index_position) return def do_layout(self, *args, **kw): pass def overlay(self, component, gc, view_bounds=None, mode="normal"): """ Draws this component overlaid on a graphics context. """ self.draw(gc, view_bounds) return def is_draggable(self, x, y): """ Returns whether the (x,y) position is in a region that is OK to drag. Used by the tool to determine when to start a drag. """ if self.axis == "index" or self.axis == "index_x": if x > self.index_position - self.handle_size and \ x < self.index_position + self.handle_size and \ y > self.component.y2 - 2*self.handle_size and \ y < self.component.y2: return True else: if y > self.index_position - self.handle_size and \ y < self.index_position + self.handle_size and \ x > self.component.x2 - 2*self.handle_size and \ x < self.component.x2: return True return False def dragging(self, event): """ This method is called for every mouse_move event that the tool receives while the user is dragging the mouse. It is recommended that subclasses do most of their work in this method. """ if event.x < self.component.x or event.x > self.component.x2 or \ event.y < self.component.y or event.y > self.component.y2: return if self.axis == "index" or self.axis == "index_x": self.index_position = event.x else: self.index_position = event.y self.index_changed() # index = self.component.map_index((event.x,event.y),index_only=True) # if self.axis == "index" or self.axis == "index_x": # self.index_position = event.x ## self.component.request_redraw() # self.callback(self, self.axis, index[0]) # else: # self.index_position = event.y ## self.component.request_redraw() # self.callback(self, self.axis, index[1]) def index_changed(self): plot = self.component if self.axis == "index" or self.axis == "index_x": index = plot.map_index((self.index_position, plot.y), index_only=True) value = plot.map_data([(self.index_position, plot.y)]) self.callback(self, self.axis, index[0], value[0][0]) else: index = plot.map_index((plot.x, self.index_position), index_only=True) value = plot.map_data([(plot.x, self.index_position)]) self.callback(self, self.axis, index[1], value[0][1]) def update_index(self, token, axis, index): if token == self.token and axis == self.axis: plot = self.component if self.axis == "index" or self.axis == "index_x": dx = plot.index.get_data()[0].get_data()[index] dy = plot.index.get_data()[1].get_data()[0] sx = plot.map_screen([(dx, dy)])[0][0] self.index_position = sx self.component.request_redraw() else: dx = plot.index.get_data()[0].get_data()[0] dy = plot.index.get_data()[1].get_data()[index] sy = plot.map_screen([(dx, dy)])[0][1] self.index_position = sy self.component.request_redraw() # if self.index_position != index: # self.index_position = index pass def _draw_vertical_line(self, gc, sx): """ Draws a vertical line through screen point (sx,sy) having the height of the tool's component. """ if sx < self.component.x or sx > self.component.x2: return gc.save_state() try: gc.set_stroke_color(self.color_) gc.set_line_width(self.line_width) gc.set_line_dash(self.line_style_) gc.move_to(sx, self.component.y) gc.line_to(sx, self.component.y2) gc.stroke_path() gc.rect(sx - self.handle_size, self.component.y2 - 2 * self.handle_size, 2 * self.handle_size, 2 * self.handle_size) gc.fill_path() finally: gc.restore_state() return def _draw_horizontal_line(self, gc, sy): """ Draws a horizontal line through screen point (sx,sy) having the width of the tool's component. """ if sy < self.component.y or sy > self.component.y2: return gc.save_state() try: gc.set_stroke_color(self.color_) gc.set_line_width(self.line_width) gc.set_line_dash(self.line_style_) gc.move_to(self.component.x, sy) gc.line_to(self.component.x2, sy) gc.stroke_path() gc.rect(self.component.x2 - 2 * self.handle_size, sy - self.handle_size, 2 * self.handle_size, 2 * self.handle_size) gc.fill_path() finally: gc.restore_state() return
class DataSourceWizardView(DataSourceWizard): #---------------------------------------------------------------------- # Private traits #---------------------------------------------------------------------- _top_label = Str('Describe your data') _info_text = Str('Array size do not match') _array_label = Str('Available arrays') _data_type_text = Str("What does your data represents?" ) _lines_text = Str("Connect the points with lines" ) _scalar_data_text = Str("Array giving the value of the scalars") _optional_scalar_data_text = Str("Associate scalars with the data points") _connectivity_text = Str("Array giving the triangles") _vector_data_text = Str("Associate vector components") _position_text = Property(depends_on="position_type_") _position_text_dict = {'explicit': 'Coordinnates of the data points:', 'orthogonal grid': 'Position of the layers along each axis:', } def _get__position_text(self): return self._position_text_dict.get(self.position_type_, "") _shown_help_text = Str _data_sources_wrappers = Property(depends_on='data_sources') def _get__data_sources_wrappers(self): return [ ArrayColumnWrapper(name=name, shape=repr(self.data_sources[name].shape)) for name in self._data_sources_names ] # A traits pointing to the object, to play well with traitsUI _self = Instance(DataSourceWizard) _suitable_traits_view = Property(depends_on="data_type_") def _get__suitable_traits_view(self): return "_%s_data_view" % self.data_type_ ui = Any(False) _preview_button = Button(label='Preview structure') def __preview_button_fired(self): if self.ui: self.build_data_source() self.preview() _ok_button = Button(label='OK') def __ok_button_fired(self): if self.ui: self.ui.dispose() self.build_data_source() _cancel_button = Button(label='Cancel') def __cancel_button_fired(self): if self.ui: self.ui.dispose() _is_ok = Bool _is_not_ok = Bool def _anytrait_changed(self): """ Validates if the OK button is enabled. """ if self.ui: self._is_ok = self.check_arrays() self._is_not_ok = not self._is_ok _preview_window = Instance(PreviewWindow, ()) _info_image = Instance(ImageResource, ImageLibrary.image_resource('@std:alert16',)) #---------------------------------------------------------------------- # TraitsUI views #---------------------------------------------------------------------- _coordinates_group = \ HGroup( Item('position_x', label='x', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('position_y', label='y', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('position_z', label='z', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), ) _position_group = \ Group( Item('position_type'), Group( Item('_position_text', style='readonly', resizable=False, show_label=False), _coordinates_group, visible_when='not position_type_=="image data"', ), Group( Item('grid_shape_source_', label='Grid shape', editor=EnumEditor( name='_grid_shape_source_labels', invalid='_is_not_ok')), HGroup( spring, Item('grid_shape', style='custom', editor=ArrayEditor(width=-60), show_label=False), enabled_when='grid_shape_source==""', ), visible_when='position_type_=="image data"', ), label='Position of the data points', show_border=True, show_labels=False, ), _connectivity_group = \ Group( HGroup( Item('_connectivity_text', style='readonly', resizable=False), spring, Item('connectivity_triangles', editor=EnumEditor(name='_data_sources_names'), show_label=False, ), show_labels=False, ), label='Connectivity information', show_border=True, show_labels=False, enabled_when='position_type_=="explicit"', ), _scalar_data_group = \ Group( Item('_scalar_data_text', style='readonly', resizable=False, show_label=False), HGroup( spring, Item('scalar_data', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), show_labels=False, ), label='Scalar value', show_border=True, show_labels=False, ) _optional_scalar_data_group = \ Group( HGroup( 'has_scalar_data', Item('_optional_scalar_data_text', resizable=False, style='readonly'), show_labels=False, ), Item('_scalar_data_text', style='readonly', resizable=False, enabled_when='has_scalar_data', show_label=False), HGroup( spring, Item('scalar_data', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok'), enabled_when='has_scalar_data'), show_labels=False, ), label='Scalar data', show_border=True, show_labels=False, ), _vector_data_group = \ VGroup( HGroup( Item('vector_u', label='u', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('vector_v', label='v', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('vector_w', label='w', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), ), label='Vector data', show_border=True, ), _optional_vector_data_group = \ VGroup( HGroup( Item('has_vector_data', show_label=False), Item('_vector_data_text', style='readonly', resizable=False, show_label=False), ), HGroup( Item('vector_u', label='u', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('vector_v', label='v', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), Item('vector_w', label='w', editor=EnumEditor(name='_data_sources_names', invalid='_is_not_ok')), enabled_when='has_vector_data', ), label='Vector data', show_border=True, ), _array_view = \ View( Item('_array_label', editor=TitleEditor(), show_label=False), Group( Item('_data_sources_wrappers', editor=TabularEditor( adapter = ArrayColumnAdapter(), ), ), show_border=True, show_labels=False )) _questions_view = View( Item('_top_label', editor=TitleEditor(), show_label=False), HGroup( Item('_data_type_text', style='readonly', resizable=False), spring, 'data_type', spring, show_border=True, show_labels=False, ), HGroup( Item('_self', style='custom', editor=InstanceEditor( view_name='_suitable_traits_view'), ), Group( # FIXME: Giving up on context sensitive help # because of lack of time. #Group( # Item('_shown_help_text', editor=HTMLEditor(), # width=300, # label='Help', # ), # show_labels=False, # label='Help', #), #Group( Item('_preview_button', enabled_when='_is_ok'), Item('_preview_window', style='custom', label='Preview structure'), show_labels=False, #label='Preview structure', #), #layout='tabbed', #dock='tab', ), show_labels=False, show_border=True, ), ) _point_data_view = \ View(Group( Group(_coordinates_group, label='Position of the data points', show_border=True, ), HGroup( 'lines', Item('_lines_text', style='readonly', resizable=False), label='Lines', show_labels=False, show_border=True, ), _optional_scalar_data_group, _optional_vector_data_group, # XXX: hack to have more vertical space Label('\n'), Label('\n'), Label('\n'), )) _surface_data_view = \ View(Group( _position_group, _connectivity_group, _optional_scalar_data_group, _optional_vector_data_group, )) _vector_data_view = \ View(Group( _vector_data_group, _position_group, _optional_scalar_data_group, )) _volumetric_data_view = \ View(Group( _scalar_data_group, _position_group, _optional_vector_data_group, )) _wizard_view = View( Group( HGroup( Item('_self', style='custom', show_label=False, editor=InstanceEditor(view='_array_view'), width=0.17, ), '_', Item('_self', style='custom', show_label=False, editor=InstanceEditor(view='_questions_view'), ), ), HGroup( Item('_info_image', editor=ImageEditor(), visible_when="_is_not_ok"), Item('_info_text', style='readonly', resizable=False, visible_when="_is_not_ok"), spring, '_cancel_button', Item('_ok_button', enabled_when='_is_ok'), show_labels=False, ), ), title='Import arrays', resizable=True, ) #---------------------------------------------------------------------- # Public interface #---------------------------------------------------------------------- def __init__(self, **traits): DataSourceFactory.__init__(self, **traits) self._self = self def view_wizard(self): """ Pops up the view of the wizard, and keeps the reference it to be able to close it. """ # FIXME: Workaround for traits bug in enabled_when self.position_type_ self.data_type_ self._suitable_traits_view self.grid_shape_source self._is_ok self.ui = self.edit_traits(view='_wizard_view') def preview(self): """ Display a preview of the data structure in the preview window. """ self._preview_window.clear() self._preview_window.add_source(self.data_source) data = lambda name: self.data_sources[name] g = Glyph() g.glyph.glyph_source.glyph_source = \ g.glyph.glyph_source.glyph_list[0] g.glyph.scale_mode = 'data_scaling_off' if not (self.has_vector_data or self.data_type_ == 'vector'): g.glyph.glyph_source.glyph_source.glyph_type = 'cross' g.actor.property.representation = 'points' g.actor.property.point_size = 3. self._preview_window.add_module(g) if not self.data_type_ in ('point', 'vector') or self.lines: s = Surface() s.actor.property.opacity = 0.3 self._preview_window.add_module(s) if not self.data_type_ == 'point': self._preview_window.add_filter(ExtractEdges()) s = Surface() s.actor.property.opacity = 0.2 self._preview_window.add_module(s)