コード例 #1
0
class SecondTask(ExampleTask):
    """ A simple task for opening a blank editor.
    """

    #### Task interface #######################################################

    id = 'example.second_task'
    name = 'Second Multi-Tab Editor'

    menu_bar = SMenuBar(
        SMenu(TaskAction(name='New', method='new', accelerator='Ctrl+N'),
              id='File',
              name='&File'),
        SMenu(DockPaneToggleGroup(),
              TaskToggleGroup(),
              id='View',
              name='&View'))

    tool_bars = [
        SToolBar(TaskAction(method='new',
                            tooltip='New file',
                            image=ImageResource('document_new')),
                 image_size=(32, 32)),
    ]

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def _default_layout_default(self):
        return TaskLayout(left=Tabbed(PaneItem('steps.first_pane'),
                                      PaneItem('steps.second_pane'),
                                      PaneItem('steps.third_pane')))
コード例 #2
0
ファイル: osx_plugin.py プロジェクト: jomason/omnivore
    def set_common_menu_29(self):
        menubar = SMenuBar(
            SMenu(Separator(id="NewGroup", separator=False),
                  Separator(id="NewGroupEnd", separator=False),
                  Group(OpenAction(), id="OpenGroup"),
                  Separator(id="OpenGroupEnd", separator=False),
                  Separator(id="SaveGroupEnd", separator=False),
                  Group(ExitAction(), id="ExitGroup"),
                  id='File',
                  name='&File'),
            SMenu(PreferencesAction(), id='Edit', name='&Edit'),
            SMenu(AboutAction(), id='Help', name='&Help'),
        )
        app = wx.GetApp()
        # Create a fake task so we can use the menu creation routines
        window = TaskWindow(application=self.application)
        log.debug("OSXMenuBarPlugin: minimal menu extra items: %s" %
                  str(self.minimal_menu_actions))
        task = OSXMinimalTask(menu_bar=menubar,
                              window=window,
                              extra_actions=self.minimal_menu_actions)

        t = TaskActionManagerBuilder(task=task)
        mgr = t.create_menu_bar_manager()
        control = mgr.create_menu_bar(app)
        wx.MenuBar.MacSetCommonMenuBar(control)

        # Prevent wx from exiting when the last window is closed
        app.SetExitOnFrameDelete(False)
コード例 #3
0
 def _menu_bar_default(self):
     return SMenuBar(SMenu(TaskAction(name='New', method='new',
                                      accelerator='Ctrl+N'),
                           id='File', name='&File'),
                     SMenu(DockPaneToggleGroup(),
                           TaskToggleGroup(),
                           id='View', name='&View'))
コード例 #4
0
    def _menu_bar_default(self):
        menu_bar = SMenuBar(
            SMenu(SGroup(group_factory=DockPaneToggleGroup,
                         id='tests.bogus_task.DockPaneToggleGroup'),
                  id='View',
                  name='&View'))

        return menu_bar
コード例 #5
0
    def _menu_bar_default(self):
        """A menu bar with functions relevant to the Setup task.
        """
        menu_bar = SMenuBar(SMenu(TaskToggleGroup(), id='File', name='&File'),
                            SMenu(id='Edit', name='&Edit'),
                            SMenu(TaskToggleGroup(), id='View', name='&View'))

        return menu_bar
コード例 #6
0
class PythonShellTask(Task):
    """
    A task which provides a simple Python Shell to the user.
    """

    # Task Interface

    id = "pyface.tasks.contrib.python_shell"
    name = "Python Shell"

    # The list of bindings for the shell
    bindings = List(Dict)

    # The list of commands to run on shell startup
    commands = List(Str)

    # the IPythonShell instance that we are interacting with
    pane = Instance(PythonShellPane)

    # Task Interface

    menu_bar = SMenuBar(
        SMenu(
            TaskAction(name="Open...", method="open", accelerator="Ctrl+O"),
            id="File",
            name="&File",
        ),
        SMenu(id="View", name="&View"),
    )

    def create_central_pane(self):
        """ Create a view pane with a Python shell
        """
        logger.debug("Creating Python shell pane in central pane")
        self.pane = PythonShellPane(bindings=self.bindings,
                                    commands=self.commands)
        return self.pane

    # PythonShellTask API

    def open(self):
        """ Shows a dialog to open a file.
        """
        logger.debug("PythonShellTask: opening file")
        dialog = FileDialog(parent=self.window.control, wildcard="*.py")
        if dialog.open() == OK:
            self._open_file(dialog.path)

    # Private API

    def _open_file(self, path):
        """ Execute the selected file in the editor's interpreter
        """
        logger.debug('PythonShellTask: executing file "%s"' % path)
        self.pane.editor.execute_file(path)
コード例 #7
0
ファイル: step2.py プロジェクト: zyex1108/pyface
class ExampleTask(Task):
    """ A simple task for opening a blank editor.
    """

    #### Task interface #######################################################

    id = 'example.example_task'
    name = 'Multi-Tab Editor'

    active_editor = Property(Instance(IEditor),
                             depends_on='editor_area.active_editor')

    editor_area = Instance(IEditorAreaPane)

    menu_bar = SMenuBar(
        SMenu(TaskAction(name='New', method='new', accelerator='Ctrl+N'),
              id='File',
              name='&File'),
        SMenu(DockPaneToggleGroup(), id='View', name='&View'))

    tool_bars = [
        SToolBar(TaskAction(method='new',
                            tooltip='New file',
                            image=ImageResource('document_new')),
                 image_size=(32, 32)),
    ]

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def create_central_pane(self):
        """ Create the central pane: the script editor.
        """
        self.editor_area = EditorAreaPane()
        return self.editor_area

    ###########################################################################
    # 'ExampleTask' interface.
    ###########################################################################

    def new(self):
        """ Opens a new empty window
        """
        editor = Editor()
        self.editor_area.add_editor(editor)
        self.editor_area.activate_editor(editor)
        self.activated()

    #### Trait property getter/setters ########################################

    def _get_active_editor(self):
        if self.editor_area is not None:
            return self.editor_area.active_editor
        return None
コード例 #8
0
    def _menu_bar_default(self):
        menu_bar = SMenuBar(
            SMenu(
                SGroup(
                    group_factory=DockPaneToggleGroup,
                    id="tests.bogus_task.DockPaneToggleGroup",
                ),
                id="View",
                name="&View",
            ))

        return menu_bar
コード例 #9
0
 def _menu_bar_default(self):
     return SMenuBar(
         SMenu(
             TaskAction(name="New", method="new", accelerator="Ctrl+N"),
             id="File",
             name="&File",
         ),
         SMenu(
             DockPaneToggleGroup(),
             TaskToggleGroup(),
             id="View",
             name="&View",
         ),
     )
コード例 #10
0
ファイル: step6a.py プロジェクト: pbrod/pyface
class SecondTask(ExampleTask):
    """ A simple task for opening a blank editor.
    """

    # Task interface -------------------------------------------------------

    id = "example.second_task"
    name = "Second Multi-Tab Editor"

    menu_bar = SMenuBar(
        SMenu(
            TaskAction(name="New", method="new", accelerator="Ctrl+N"),
            id="File",
            name="&File",
        ),
        SMenu(DockPaneToggleGroup(),
              TaskToggleGroup(),
              id="View",
              name="&View"),
    )

    tool_bars = [
        SToolBar(
            TaskAction(
                method="new",
                tooltip="New file",
                image=ImageResource("document_new"),
            ),
            image_size=(32, 32),
        )
    ]

    # ------------------------------------------------------------------------
    # 'Task' interface.
    # ------------------------------------------------------------------------

    def _default_layout_default(self):
        return TaskLayout(left=VSplitter(
            HSplitter(
                PaneItem("steps.pane1"),
                PaneItem("steps.pane2"),
                PaneItem("steps.pane3"),
            ),
            HSplitter(
                PaneItem("steps.pane4"),
                PaneItem("steps.pane5"),
                PaneItem("steps.pane6"),
            ),
        ))
コード例 #11
0
class PikosTask(Task):

    #### 'Task' interface #####################################################

    id = 'pikos.live.pikos_task'
    name = 'Pikos Live Plotting'

    menu_bar = SMenuBar(SMenu(id='File', name='&File'),
                        SMenu(id='Edit', name='&Edit'),
                        SMenu(TaskToggleGroup(),
                              id='View', name='&View'))

    #### 'PikosTask' interface ################################################

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def create_central_pane(self):
        """ Create a plot pane with a list of models. Keep track of which model
            is active so that dock panes can introspect it.
        """
        pane = PikosTaskPane()
        return pane
コード例 #12
0
class ExampleTask(Task):
    """ A simple task for editing Python code.
    """

    #### Task interface #######################################################

    id = 'example.example_task'
    name = 'Python Script Editor'

    #default_layout = TaskLayout(
    #    left=PaneItem('example.python_script_browser_pane'))

    menu_bar = SMenuBar(
        SMenu(
            TaskAction(
                name='Open...', method='open', accelerator='Ctrl+O'),
            TaskAction(
                name='Save', method='save', accelerator='Ctrl+S'),
            id='File',
            name='&File'),
        SMenu(
            DockPaneToggleGroup(), id='View', name='&View'))

    tool_bars = [
        SToolBar(
            TaskAction(
                method='open',
                tooltip='Open a file',
                image=ImageResource('document_open')),
            TaskAction(
                method='save',
                tooltip='Save the current file',
                image=ImageResource('document_save')))
    ]

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def _default_layout_default(self):
        return TaskLayout(left=PaneItem('example.python_script_browser_pane'))

    def activated(self):
        """ Overriden to set the window's title.
        """
        filename = self.window.central_pane.editor.path
        self.window.title = filename if filename else 'Untitled'

    def create_central_pane(self):
        """ Create the central pane: the script editor.
        """
        return PythonEditorPane()

    def create_dock_panes(self):
        """ Create the file browser and connect to its double click event.
        """
        browser = PythonScriptBrowserPane()
        handler = lambda: self._open_file(browser.selected_file)
        browser.on_trait_change(handler, 'activated')
        return [browser]

    ###########################################################################
    # 'ExampleTask' interface.
    ###########################################################################

    def open(self):
        """ Shows a dialog to open a file.
        """
        dialog = FileDialog(parent=self.window.control, wildcard='*.py')
        if dialog.open() == OK:
            self._open_file(dialog.path)

    def save(self):
        """ Attempts to save the current file, prompting for a path if
            necessary. Returns whether the file was saved.
        """
        editor = self.window.central_pane.editor
        try:
            editor.save()
        except IOError:
            # If you are trying to save to a file that doesn't exist, open up a
            # FileDialog with a 'save as' action.
            dialog = FileDialog(
                parent=self.window.control, action='save as', wildcard='*.py')
            if dialog.open() == OK:
                editor.save(dialog.path)
            else:
                return False
        return True

    ###########################################################################
    # Protected interface.
    ###########################################################################

    def _open_file(self, filename):
        """ Opens the file at the specified path in the editor.
        """
        if self._prompt_for_save():
            self.window.central_pane.editor.path = filename
            self.activated()

    def _prompt_for_save(self):
        """ Prompts the user to save if necessary. Returns whether the dialog
            was cancelled.
        """
        if self.window.central_pane.editor.dirty:
            message = 'The current file has unsaved changes. ' \
                      'Do you want to save your changes?'
            dialog = ConfirmationDialog(
                parent=self.window.control,
                message=message,
                cancel=True,
                default=CANCEL,
                title='Save Changes?')
            result = dialog.open()
            if result == CANCEL:
                return False
            elif result == YES:
                if not self.save():
                    return self._prompt_for_save()
        return True

    @on_trait_change('window:closing')
    def _prompt_on_close(self, event):
        """ Prompt the user to save when exiting.
        """
        if not self._prompt_for_save():
            event.veto = True
コード例 #13
0
class ExampleTask(Task):
    """ A simple task for opening a blank editor.
    """

    #### Task interface #######################################################

    id = 'example.example_task'
    name = 'Multi-Tab Editor'

    active_editor = Property(Instance(IEditor),
                             depends_on='editor_area.active_editor')

    editor_area = Instance(IEditorAreaPane)

    menu_bar = SMenuBar(
        SMenu(TaskAction(name='New', method='new', accelerator='Ctrl+N'),
              id='File',
              name='&File'),
        SMenu(DockPaneToggleGroup(),
              TaskToggleGroup(),
              id='View',
              name='&View'))

    tool_bars = [
        SToolBar(TaskAction(method='new',
                            tooltip='New file',
                            image=ImageResource('document_new')),
                 image_size=(32, 32)),
    ]

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def _default_layout_default(self):
        return TaskLayout(top=Tabbed(PaneItem('steps.first_pane'),
                                     PaneItem('steps.second_pane'),
                                     PaneItem('steps.third_pane')))

    def create_central_pane(self):
        """ Create the central pane: the script editor.
        """
        self.editor_area = EditorAreaPane()
        return self.editor_area

    def create_dock_panes(self):
        """ Create the file browser and connect to its double click event.
        """
        return [FirstPane(), SecondPane(), ThirdPane()]

    ###########################################################################
    # 'ExampleTask' interface.
    ###########################################################################

    def new(self):
        """ Opens a new empty window
        """
        editor = Editor()
        self.editor_area.add_editor(editor)
        self.editor_area.activate_editor(editor)
        self.activated()

    #### Trait property getter/setters ########################################

    def _get_active_editor(self):
        if self.editor_area is not None:
            return self.editor_area.active_editor
        return None
コード例 #14
0
class ExampleTask(Task):
    """ A simple task for opening a blank editor.
    """

    # Task interface -------------------------------------------------------

    id = "example.example_task"
    name = "Multi-Tab Editor"

    active_editor = Property(
        Instance(IEditor), depends_on="editor_area.active_editor"
    )

    editor_area = Instance(IEditorAreaPane)

    menu_bar = SMenuBar(
        SMenu(
            TaskAction(name="New", method="new", accelerator="Ctrl+N"),
            id="File",
            name="&File",
        ),
        SMenu(DockPaneToggleGroup(), id="View", name="&View"),
    )

    tool_bars = [
        SToolBar(
            TaskAction(
                method="new",
                tooltip="New file",
                image=ImageResource("document_new"),
            ),
            image_size=(32, 32),
        )
    ]

    # ------------------------------------------------------------------------
    # 'Task' interface.
    # ------------------------------------------------------------------------

    def create_central_pane(self):
        """ Create the central pane: the script editor.
        """
        self.editor_area = EditorAreaPane()
        return self.editor_area

    # ------------------------------------------------------------------------
    # 'ExampleTask' interface.
    # ------------------------------------------------------------------------

    def new(self):
        """ Opens a new empty window
        """
        editor = Editor()
        self.editor_area.add_editor(editor)
        self.editor_area.activate_editor(editor)
        self.activated()

    # Trait property getter/setters ----------------------------------------

    def _get_active_editor(self):
        if self.editor_area is not None:
            return self.editor_area.active_editor
        return None
コード例 #15
0
class ImageViewerTask(Task):
    """ A simple task for viewing images.
    """
    #### Task interface #######################################################

    id = 'example.image_viewer_task'
    name = 'Image Viewer'

    #default_layout = TaskLayout(
    #    left=PaneItem('example.python_script_browser_pane'))

    menu_bar = SMenuBar(
        SMenu(TaskAction(name='Open...', method='open', accelerator='Ctrl+O'),
              id='File',
              name='&File'),
        SMenu(DockPaneToggleGroup(), id='View', name='&View'))

    tool_bars = [
        SToolBar(
            TaskAction(method='open',
                       tooltip='Open a file',
                       image=ImageResource('document_open')))
    ]

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def _default_layout_default(self):
        return TaskLayout(left=PaneItem('image_viewer.file_browser_pane'))

    def activated(self):
        """ Overriden to set the window's title.
        """
        filename = self.window.central_pane.model.path
        self.window.title = filename if filename else 'Untitled'

    def create_central_pane(self):
        """ Create the central pane: the image viewer.
        """
        return ImageViewerPane()

    def create_dock_panes(self):
        """ Create the file browser and connect to its double click event.
        """
        browser = FileBrowserPane(filters=["*.jpg"])
        handler = lambda: self._open_file(browser.selected_file)
        browser.on_trait_change(handler, 'activated')
        return [browser]

    ###########################################################################
    # 'ExampleTask' interface.
    ###########################################################################

    def open(self):
        """ Shows a dialog to open a file.
        """
        dialog = FileDialog(parent=self.window.control, wildcard='*.jpg')
        if dialog.open() == OK:
            self._open_file(dialog.path)

    ###########################################################################
    # Protected interface.
    ###########################################################################

    def _open_file(self, filename):
        """ Opens the file at the specified path in the editor.
        """
        self.window.central_pane.model.path = filename
        self.activated()
コード例 #16
0
ファイル: step3.py プロジェクト: ovevans/pyface
class ExampleTask(Task):
    """ A simple task for opening a blank editor.
    """

    # Task interface -------------------------------------------------------

    id = "example.example_task"
    name = "Multi-Tab Editor"

    active_editor = Property(Instance(IEditor),
                             observe="editor_area.active_editor")

    editor_area = Instance(IEditorAreaPane)

    menu_bar = SMenuBar(
        SMenu(
            TaskAction(name="New", method="new", accelerator="Ctrl+N"),
            id="File",
            name="&File",
        ),
        SMenu(DockPaneToggleGroup(), id="View", name="&View"),
    )

    tool_bars = [
        SToolBar(
            TaskAction(
                method="new",
                tooltip="New file",
                image=ImageResource("document_new"),
            ),
            image_size=(32, 32),
        )
    ]

    # ------------------------------------------------------------------------
    # 'Task' interface.
    # ------------------------------------------------------------------------

    def _default_layout_default(self):
        return TaskLayout(top=PaneItem("steps.example_pane"))

    def create_central_pane(self):
        """ Create the central pane: the script editor.
        """
        self.editor_area = EditorAreaPane()
        return self.editor_area

    def create_dock_panes(self):
        """ Create the file browser and connect to its double click event.
        """
        pane = ExamplePane()
        return [pane]

    # ------------------------------------------------------------------------
    # 'ExampleTask' interface.
    # ------------------------------------------------------------------------

    def new(self):
        """ Opens a new empty window
        """
        editor = Editor()
        self.editor_area.add_editor(editor)
        self.editor_area.activate_editor(editor)
        self.activated()

    # Trait property getter/setters ----------------------------------------

    def _get_active_editor(self):
        if self.editor_area is not None:
            return self.editor_area.active_editor
        return None
コード例 #17
0
class Visualize2dTask(Task):
    """ A task for visualizing attractors in 2D.
    """

    #### 'Task' interface #####################################################

    id = 'example.attractors.task_2d'
    name = '2D Visualization'

    menu_bar = SMenuBar(SMenu(id='File', name='&File'),
                        SMenu(id='Edit', name='&Edit'),
                        SMenu(TaskToggleGroup(), id='View', name='&View'))

    #### 'Visualize2dTask' interface ##########################################

    # The attractor model that is currently active (visible in the center pane).
    active_model = Any

    # The list of available attractor models.
    models = List

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def create_central_pane(self):
        """ Create a plot pane with a list of models. Keep track of which model
            is active so that dock panes can introspect it.
        """
        pane = Plot2dPane(models=self.models)

        self.active_model = pane.active_model
        pane.on_trait_change(self._update_active_model, 'active_model')

        return pane

    def create_dock_panes(self):
        return [
            ModelConfigPane(model=self.active_model),
            ModelHelpPane(model=self.active_model)
        ]

    ###########################################################################
    # Protected interface.
    ###########################################################################

    #### Trait initializers ###################################################

    def _default_layout_default(self):
        return TaskLayout(
            left=Tabbed(PaneItem('example.attractors.model_config_pane'),
                        PaneItem('example.attractors.model_help_pane')))

    def _models_default(self):
        from model.henon import Henon
        from model.lorenz import Lorenz
        from model.rossler import Rossler
        return [Henon(), Lorenz(), Rossler()]

    #### Trait change handlers ################################################

    def _update_active_model(self):
        self.active_model = self.window.central_pane.active_model
        for dock_pane in self.window.dock_panes:
            dock_pane.model = self.active_model
コード例 #18
0
class Visualize3dTask(Task):
    """ A task for visualizing attractors in 3D.
    """

    #### 'Task' interface #####################################################

    id = "example.attractors.task_3d"
    name = "3D Visualization"

    menu_bar = SMenuBar(
        SMenu(id="File", name="&File"),
        SMenu(id="Edit", name="&Edit"),
        SMenu(TaskToggleGroup(), id="View", name="&View"),
    )

    #### 'Visualize3dTask' interface ##########################################

    # The attractor model that is currently active (visible in the center
    # pane).
    active_model = Any

    # The list of available attractor models.
    models = List

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def create_central_pane(self):
        """ Create a plot pane with a list of models. Keep track of which model
            is active so that dock panes can introspect it.
        """
        pane = Plot3dPane(models=self.models)

        self.active_model = pane.active_model
        pane.on_trait_change(self._update_active_model, "active_model")

        return pane

    def create_dock_panes(self):
        return [
            ModelConfigPane(model=self.active_model),
            ModelHelpPane(model=self.active_model),
        ]

    ###########################################################################
    # Protected interface.
    ###########################################################################

    #### Trait initializers ###################################################

    def _default_layout_default(self):
        return TaskLayout(left=Tabbed(
            PaneItem("example.attractors.model_config_pane"),
            PaneItem("example.attractors.model_help_pane"),
        ))

    def _models_default(self):
        from attractors.model.lorenz import Lorenz
        from attractors.model.rossler import Rossler

        return [Lorenz(), Rossler()]

    #### Trait change handlers ################################################

    def _update_active_model(self):
        self.active_model = self.window.central_pane.active_model
        for dock_pane in self.window.dock_panes:
            dock_pane.model = self.active_model
コード例 #19
0
class FlowTask(Task):
    """
    classdocs
    """

    id = "edu.mit.synbio.cytoflow.flow_task"
    name = "Cytometry analysis"

    # the main workflow instance.
    # THIS IS WHERE IT'S INITIALLY INSTANTIATED (note the args=())
    model = Instance(Workflow, args=())

    # the center pane
    view = Instance(FlowTaskPane)

    # plugin lists, to setup the interface
    op_plugins = List(IOperationPlugin)
    view_plugins = List(IViewPlugin)

    menu_bar = SMenuBar(
        SMenu(
            TaskAction(name='Open...', method='on_open', accelerator='Ctrl+O'),
            TaskAction(
                name='Save',
                #image='save',
                method='on_save',
                accelerator='Ctrl+S'),
            TaskAction(name='Save As...',
                       method='on_save_as',
                       accelerator='Ctrl+e'),
            TaskAction(name='Export image...',
                       method='on_export',
                       accelerator='Ctrl+x'),
            TaskAction(name='Export IPython notebook...',
                       method='on_ipython',
                       accelerator='Ctrl+I'),
            TaskAction(name='Preferences...',
                       method='on_prefs',
                       accelerator='Ctrl+P'),
            id='File',
            name='&File'),
        SMenu(TaskAction(name='About...',
                         method='on_about',
                         accelerator="Ctrl+A"),
              id="Help",
              name="&Help"))

    tool_bars = [
        SToolBar(TaskAction(method='on_new',
                            name="New",
                            tooltip='New workflow',
                            image=ImageResource('new')),
                 TaskAction(method='on_open',
                            name="Open",
                            tooltip='Open a file',
                            image=ImageResource('open')),
                 TaskAction(method='on_save',
                            name="Save",
                            tooltip='Save the current file',
                            image=ImageResource('save')),
                 TaskAction(method='on_export',
                            name="Export",
                            tooltip='Export the current plot',
                            image=ImageResource('export')),
                 TaskAction(method='on_ipython',
                            name='IPython',
                            tooltip="Export to an IPython notebook...",
                            image=ImageResource('ipython')),
                 TaskAction(method='on_prefs',
                            name="Prefs",
                            tooltip='Preferences',
                            image=ImageResource('prefs')),
                 image_size=(32, 32))
    ]

    # are we debugging?  ie, do we need a default setup?
    debug = Bool

    worker = Instance(threading.Thread)
    to_update = Instance(UniquePriorityQueue, ())
    worker_flag = Instance(threading.Event, args=())
    worker_lock = Instance(threading.Lock, args=())

    def initialized(self):

        # make sure that when the result changes we get notified
        # can't use a static notifier because selected.result gets updated
        # on the worker thread, but we need to dispatch on the UI thread
        self.model.on_trait_change(self._result_updated,
                                   "selected:result",
                                   dispatch='ui')

    def activated(self):
        # add an import plugin
        plugin = ImportPlugin()
        wi = WorkflowItem(task=self)
        wi.operation = plugin.get_operation()

        self.model.workflow.append(wi)
        self.model.selected = wi

        # if we're debugging, add a few data bits
        if self.debug:
            from cytoflow import Tube

            wi.operation.conditions["Dox"] = "log"

            tube1 = Tube(file="../cytoflow/tests/data/Plate01/CFP_Well_A4.fcs",
                         conditions={"Dox": 0.1})

            tube2 = Tube(file="../cytoflow/tests/data/Plate01/RFP_Well_A3.fcs",
                         conditions={"Dox": 1.0})

            wi.operation.tubes.append(tube1)
            wi.operation.tubes.append(tube2)

            self.add_operation(
                'edu.mit.synbio.cytoflowgui.op_plugins.threshold')
            self.model.selected.operation.channel = "Y2-A"
            self.model.selected.operation.threshold = 2000
            self.model.selected.operation.name = "T"

    def prepare_destroy(self):
        self.model = None

    def _default_layout_default(self):
        return TaskLayout(left=PaneItem("edu.mit.synbio.workflow_pane"),
                          right=PaneItem("edu.mit.synbio.view_traits_pane"))

    def create_central_pane(self):
        self.view = FlowTaskPane(model=self.model)
        return self.view

    def create_dock_panes(self):
        return [
            WorkflowDockPane(model=self.model,
                             plugins=self.op_plugins,
                             task=self),
            ViewDockPane(model=self.model,
                         plugins=self.view_plugins,
                         task=self)
        ]

    def on_new(self):
        self.model.workflow = []

        # add an import plugin
        plugin = ImportPlugin()
        wi = WorkflowItem(task=self)
        wi.operation = plugin.get_operation()

        self.model.workflow.append(wi)
        self.model.selected = wi

    def on_open(self):
        """ Shows a dialog to open a file.
        """
        dialog = FileDialog(parent=self.window.control,
                            action='open',
                            wildcard='*.flow')
        if dialog.open() == OK:
            self.open_file(dialog.path)

    def open_file(self, path):
        f = open(path, 'r')
        unpickler = pickle.Unpickler(f)
        new_model = unpickler.load()

        # update the link back to the controller (ie, self)
        for wi in new_model.workflow:
            wi.task = self

            # and set up the view handlers
            for view in wi.views:
                view.handler = view.handler_factory(model=view, wi=wi)

        # replace the current workflow with the one we just loaded

        if False:
            from event_tracer import record_events

            with record_events() as container:
                self.model.workflow[:] = new_model.workflow
                self.model.selected = new_model.selected

            container.save_to_directory(os.getcwd())
        else:
            self.model.workflow[:] = new_model.workflow
            self.model.selected = new_model.selected

        wi = self.model.workflow[0]
        while True:
            wi.status = "invalid"
            with self.worker_lock:
                self.to_update.put_nowait((self.model.workflow.index(wi), wi))
            if wi.next:
                wi = wi.next
            else:
                break

        # check to see if we have a worker thread around
        if not self.worker or not self.worker.is_alive():
            self.worker = threading.Thread(target=update_model,
                                           args=(self.worker_flag,
                                                 self.worker_lock,
                                                 self.to_update))
            self.worker.daemon = True
            self.worker.start()

        # start the worker thread processing
        with self.worker_lock:
            if not self.to_update.empty():
                self.worker_flag.set()

    def on_save(self):
        """ Shows a dialog to open a file.
        """
        dialog = FileDialog(parent=self.window.control,
                            action='save as',
                            wildcard='*.flow')
        if dialog.open() == OK:
            self.save_file(dialog.path)

    def on_save_as(self):
        pass

    def save_file(self, path):
        # TODO - error handling
        f = open(path, 'w')
        pickler = pickle.Pickler(f, 0)  # text protocol for now
        pickler.dump(self.model)

    def on_export(self):
        """
        Shows a dialog to export a file
        """
        dialog = FileDialog(parent=self.window.control, action='save as')
        if dialog.open() == OK:
            self.view.export(dialog.path)

    def on_ipython(self):
        """
        Shows a dialog to export the workflow to an IPython notebook
        """

        dialog = FileDialog(parent=self.window.control,
                            action='save as',
                            wildcard='*.ipynb')
        if dialog.open() == OK:
            writer = IPythonNotebookWriter(file=dialog.path)
            writer.export(self.workflow)

    def on_prefs(self):
        pass

    def on_about(self):
        from cytoflow import __version__ as cf_version
        from fcsparser import __version__ as fcs_version
        from pandas.version import __version__ as pd_version
        from numpy.version import version as np_version
        from numexpr import __version__ as numexp_version
        from seaborn import __version__ as sns_version
        from matplotlib import __version__ as mpl_version
        from pyface import __version__ as py_version
        from envisage import __version__ as env_version
        from traits import __version__ as trt_version
        from traitsui import __version__ as trt_ui_version

        text = [
            "<b>Cytoflow {0}</b>".format(cf_version), "<p>",
            "fcsversion {0}".format(fcs_version),
            "pandas {0}".format(pd_version), "numpy {0}".format(np_version),
            "numexpr {0}".format(numexp_version),
            "seaborn {0}".format(sns_version),
            "matplotlib {0}".format(mpl_version),
            "pyface {0}".format(py_version),
            "envisage {0}".format(env_version),
            "traits {0}".format(trt_version),
            "traitsui {0}".format(trt_ui_version),
            "Icons from the <a href=http://tango.freedesktop.org>Tango Desktop Project</a>",
            "<a href=https://thenounproject.com/search/?q=setup&i=14287>Settings icon</a> by Paulo Sa Ferreira from <a href=https://thenounproject.com>The Noun Project</a>",
            "Cuvette image from Wikimedia Commons user <a href=http://commons.wikimedia.org/wiki/File:Hellma_Large_cone_cytometry_cell.JPG>HellmaUSA</a>"
        ]
        dialog = AboutDialog(parent=self.window.control,
                             title="About",
                             image=ImageResource('cuvette'),
                             additions=text)
        dialog.open()

    def add_operation(self, op_id):
        # first, find the matching plugin
        plugin = next((x for x in self.op_plugins if x.id == op_id))

        # default to inserting at the end of the list if none selected
        after = self.model.selected
        if after is None:
            after = self.model.workflow[-1]

        idx = self.model.workflow.index(after)

        wi = WorkflowItem(task=self)
        wi.operation = plugin.get_operation()

        wi.next = after.next
        after.next = wi
        wi.previous = after
        if wi.next:
            wi.next.previous = wi
        self.model.workflow.insert(idx + 1, wi)

        # set up the default view
        wi.default_view = plugin.get_default_view()
        if wi.default_view is not None:
            wi.default_view.op = wi.operation
            wi.default_view.handler = \
                wi.default_view.handler_factory(model = wi.default_view, wi = wi.previous)
            wi.views.append(wi.default_view)

        # select (open) the new workflow item
        self.model.selected = wi
        if wi.default_view:
            wi.current_view = wi.default_view

        # invalidate everything following
        self.operation_parameters_updated()

    @on_trait_change("model:workflow[]")
    def _on_remove_operation(self, obj, name, old, new):
        if name == "workflow_items" and len(new) == 0 and len(old) > 0:
            assert len(old) == 1
            wi = old[0]

            if self.model.selected == wi:
                self.model.selected = wi.previous

            wi.previous.next = wi.next
            if wi.next:
                wi.next.previous = wi.previous

            del wi.default_view
            del wi.views
            del wi

            self.operation_parameters_updated()

    @on_trait_change("model:selected:operation:+")
    def operation_parameters_updated(self):

        # invalidate this workflow item and all the ones following it
        wi = self.model.selected
        while True:
            wi.status = "invalid"
            with self.worker_lock:
                self.to_update.put_nowait((self.model.workflow.index(wi), wi))
            if wi.next:
                wi = wi.next
            else:
                break

        # check to see if we have a worker thread around
        if not self.worker or not self.worker.is_alive():
            self.worker = threading.Thread(target=update_model,
                                           args=(self.worker_flag,
                                                 self.worker_lock,
                                                 self.to_update))
            self.worker.daemon = True
            self.worker.start()

        # start the worker thread processing
        with self.worker_lock:
            if not self.to_update.empty():
                self.worker_flag.set()

    def set_current_view(self, view_id):
        """
        called by the view pane 
        """
        wi = self.model.selected

        if view_id == "default":
            view_id = self.model.selected.default_view.id

        view = next((x for x in wi.views if x.id == view_id), None)

        if not view:
            plugin = next(
                (x for x in self.view_plugins if x.view_id == view_id))
            view = plugin.get_view()
            view.handler = view.handler_factory(model=view, wi=wi)
            wi.views.append(view)

        wi.current_view = view

    @on_trait_change("model:selected.current_view")
    def _current_view_changed(self, obj, name, old, new):

        # we get notified if *either* the currently selected workflowitem
        # *or* the current view changes.

        if name == 'selected':
            new = new.current_view if new else None
            old = old.current_view if old else None

        # remove the notifications from the old view
        if old:
            old.on_trait_change(self.view_parameters_updated, remove=True)

            # and if the old view was interactive, turn off its interactivity
            # to remove the matplotlib event handlers
            if "interactive" in old.traits():
                old.interactive = False

        # whenever the view parameters change, we need to know so we can
        # update the plot(s)
        if new:
            new.on_trait_change(self.view_parameters_updated)

            if self.model.selected:
                self.view.plot(self.model.selected)
            else:
                self.view.clear_plot()
        else:
            self.view.clear_plot()

    def _result_updated(self, obj, name, old, new):
        print "result updated"
        if self.model.selected:
            self.view.plot(self.model.selected)
        else:
            self.view.clear_plot()

    def view_parameters_updated(self, obj, name, new):

        # i should be able to specify the metadata i want in the listener,
        # but there's an odd interaction (bug) between metadata, dynamic
        # trait listeners and instance traits.  so, check for 'transient'
        # here instead,

        if obj.trait(name).transient:
            return

        print "view parameters updated: {0}".format(name)
        wi = self.model.selected
        if wi is None:
            wi = self.model.workflow[-1]

        self.view.plot(wi)
コード例 #20
0
class PythonEditorTask(Task):
    """ A simple task for editing Python code.
    """

    # 'Task' traits -----------------------------------------------------------

    #: The unique id of the task.
    id = 'example.python_editor_task'

    #: The human-readable name of the task.
    name = u"Python Editor"

    #: The currently active editor in the editor area, if any.
    active_editor = Property(Instance(IEditor),
                             depends_on='editor_area.active_editor')

    #: The editor area for this task.
    editor_area = Instance(IEditorAreaPane)

    #: The menu bar for the task.
    menu_bar = SMenuBar(
        SMenu(
            SGroup(
                TaskAction(name='New', method='new', accelerator='Ctrl+N'),
                id='new_group',
            ),
            SGroup(
                TaskAction(name='Open...', method='open',
                           accelerator='Ctrl+O'),
                id='open_group',
            ),
            SGroup(
                TaskAction(name='Save',
                           method='save',
                           accelerator='Ctrl+S',
                           enabled_name='active_editor.dirty'),
                TaskAction(name='Save As...',
                           method='save_as',
                           accelerator='Ctrl+Shift+S'),
                id='save_group',
            ),
            SGroup(
                TaskAction(
                    name='Close Editor',
                    method='close_editor',
                    accelerator='Ctrl+W',
                ),
                id='close_group',
            ),
            id='File',
            name='&File',
        ),
        SMenu(
            SGroup(
                EditorAction(
                    name='Undo',
                    method='undo',
                    enabled_name='can_undo',
                    accelerator='Ctrl+Z',
                ),
                EditorAction(
                    name='Redo',
                    method='redo',
                    enabled_name='can_redo',
                    accelerator='Ctrl+Shift+Z',
                ),
                id='undo_group',
            ),
            SGroup(
                EditorAction(
                    name='Go to Line...',
                    method='go_to_line',
                    accelerator='Ctrl+G',
                ),
                id='search_group',
            ),
            id='Edit',
            name='&Edit',
        ), SMenu(
            DockPaneToggleGroup(),
            id='View',
            name='&View',
        ),
        SMenu(
            SGroup(
                OpenURLAction(
                    name='Python Documentation',
                    id='python_docs',
                    url=PYTHON_DOCS,
                ),
                id="documentation_group",
            ),
            id='Help',
            name='&Help',
        ))

    #: The tool bars for the task.
    tool_bars = [
        SToolBar(TaskAction(
            method='new',
            tooltip='New file',
            image=ImageResource('document_new'),
        ),
                 TaskAction(method='open',
                            tooltip='Open a file',
                            image=ImageResource('document_open')),
                 TaskAction(method='save',
                            tooltip='Save the current file',
                            image=ImageResource('document_save'),
                            enabled_name='active_editor.dirty'),
                 image_size=(16, 16),
                 show_tool_names=False),
    ]

    #: The status bar for the window when this task is active.
    status_bar = Instance(StatusBarManager, ())

    # -------------------------------------------------------------------------
    # 'PythonEditorTask' interface.
    # -------------------------------------------------------------------------

    def create_editor(self, path=''):
        """ Create a new editor in the editor pane.

        Parameters
        ----------
        path : path or ''
            The path to the file to edit, or '' for an empty editor.
        """
        if path:
            path = os.path.abspath(path)
        use_existing = (path != '')
        self.editor_area.edit(
            path,
            factory=PythonEditor,
            use_existing=use_existing,
        )
        if path:
            self.active_editor.load()

    def close_editor(self):
        """ Close the active editor, or if no editors, close the Task window.
        """
        if self.editor_area.active_editor is not None:
            self.editor_area.remove_editor(self.editor_area.active_editor)
        else:
            self.window.close()

    def new(self):
        """ Open a new empty window
        """
        self.create_editor()

    def open(self):
        """ Shows a dialog to open a Python file.
        """
        dialog = FileDialog(parent=self.window.control, wildcard='*.py')
        if dialog.open() == OK:
            self.create_editor(dialog.path)

    def save(self):
        """ Save the current file.
        
        If needed, this code prompts for a path.
        
        Returns
        -------
        saved : bool
            Whether or not the file was saved.
        """
        editor = self.active_editor
        try:
            editor.save()
        except IOError:
            # If you are trying to save to a file that doesn't exist, open up a
            # FileDialog with a 'save as' action.
            dialog = FileDialog(
                parent=self.window.control,
                action='save as',
                wildcard='*.py',
            )
            if dialog.open() == OK:
                editor.save(dialog.path)
            else:
                return False
        return True

    # -------------------------------------------------------------------------
    # 'Task' interface.
    # -------------------------------------------------------------------------

    def _default_layout_default(self):
        """ The default layout with the browser pane on the left.
        """
        return TaskLayout(
            left=PaneItem('example.python_browser_pane', width=200))

    def create_central_pane(self):
        """ Create the central pane: the script editor.
        """
        self.editor_area = EditorAreaPane()
        return self.editor_area

    def create_dock_panes(self):
        """ Create the file browser and connect to its double click event.
        """
        browser = PythonBrowserPane()

        def handler():
            return self.create_editor(browser.selected_file)

        browser.on_trait_change(handler, 'activated')
        return [browser]

    # -------------------------------------------------------------------------
    # Protected interface.
    # -------------------------------------------------------------------------

    def _prompt_for_save(self):
        """ Prompts the user to save if necessary. Returns whether the dialog
            was cancelled.
        """
        dirty_editors = {
            editor.name: editor
            for editor in self.editor_area.editors
            if editor.dirty and (editor.obj or editor.code)
        }
        if not dirty_editors:
            return True

        message = 'You have unsaved files. Would you like to save them?'
        dialog = ConfirmationDialog(parent=self.window.control,
                                    message=message,
                                    cancel=True,
                                    default=CANCEL,
                                    title='Save Changes?')
        result = dialog.open()
        if result == CANCEL:
            return False
        elif result == YES:
            for name, editor in dirty_editors.items():
                editor.save(editor.path)
        return True

    # Trait change handlers --------------------------------------------------

    @on_trait_change('window:closing')
    def _prompt_on_close(self, event):
        """ Prompt the user to save when exiting.
        """
        close = self._prompt_for_save()
        event.veto = not close

    @on_trait_change('active_editor.name')
    def _change_title(self):
        """ Update the window title when the active editor changes.
        """
        if self.window.active_task == self:
            if self.active_editor is not None:
                self.window.title = self.active_editor.name
            else:
                self.window.title = self.name

    @on_trait_change('active_editor.[line,column,selection_length]')
    def _update_status(self):
        if self.active_editor is not None:
            editor = self.active_editor
            if editor.selection_length:
                self.status_bar.messages = [
                    "Ln {}, Col {} ({} selected)".format(
                        editor.line, editor.column, editor.selection_length)
                ]
            else:
                self.status_bar.messages = [
                    "Ln {}, Col {}".format(editor.line, editor.column)
                ]
        else:
            self.status_bar.messages = []

    # Trait property getter/setters ------------------------------------------

    @cached_property
    def _get_active_editor(self):
        if self.editor_area is not None:
            return self.editor_area.active_editor
        return None
コード例 #21
0
class ExampleTask(Task):
    """ A simple task for editing Python code.
    """

    # Task interface -------------------------------------------------------

    id = "example.example_task"
    name = "Python Script Editor"

    # default_layout = TaskLayout(
    #    left=PaneItem('example.python_script_browser_pane'))

    menu_bar = SMenuBar(
        SMenu(
            TaskAction(name="Open...", method="open", accelerator="Ctrl+O"),
            TaskAction(name="Save", method="save", accelerator="Ctrl+S"),
            id="File",
            name="&File",
        ),
        SMenu(DockPaneToggleGroup(), id="View", name="&View"),
    )

    tool_bars = [
        SToolBar(
            TaskAction(
                method="open",
                tooltip="Open a file",
                image=ImageResource("document_open"),
            ),
            TaskAction(
                method="save",
                tooltip="Save the current file",
                image=ImageResource("document_save"),
            ),
        )
    ]

    # ------------------------------------------------------------------------
    # 'Task' interface.
    # ------------------------------------------------------------------------

    def _default_layout_default(self):
        return TaskLayout(left=PaneItem("example.python_script_browser_pane"))

    def activated(self):
        """ Overriden to set the window's title.
        """
        filename = self.window.central_pane.editor.path
        self.window.title = filename if filename else "Untitled"

    def create_central_pane(self):
        """ Create the central pane: the script editor.
        """
        return PythonEditorPane()

    def create_dock_panes(self):
        """ Create the file browser and connect to its double click event.
        """
        browser = PythonScriptBrowserPane()
        handler = lambda _: self._open_file(browser.selected_file)
        browser.observe(handler, "activated")
        return [browser]

    # ------------------------------------------------------------------------
    # 'ExampleTask' interface.
    # ------------------------------------------------------------------------

    def open(self):
        """ Shows a dialog to open a file.
        """
        dialog = FileDialog(parent=self.window.control, wildcard="*.py")
        if dialog.open() == OK:
            self._open_file(dialog.path)

    def save(self):
        """ Attempts to save the current file, prompting for a path if
            necessary. Returns whether the file was saved.
        """
        editor = self.window.central_pane.editor
        try:
            editor.save()
        except IOError:
            # If you are trying to save to a file that doesn't exist, open up a
            # FileDialog with a 'save as' action.
            dialog = FileDialog(parent=self.window.control,
                                action="save as",
                                wildcard="*.py")
            if dialog.open() == OK:
                editor.save(dialog.path)
            else:
                return False
        return True

    # ------------------------------------------------------------------------
    # Protected interface.
    # ------------------------------------------------------------------------

    def _open_file(self, filename):
        """ Opens the file at the specified path in the editor.
        """
        if self._prompt_for_save():
            self.window.central_pane.editor.path = filename
            self.activated()

    def _prompt_for_save(self):
        """ Prompts the user to save if necessary. Returns whether the dialog
            was cancelled.
        """
        if self.window.central_pane.editor.dirty:
            message = ("The current file has unsaved changes. "
                       "Do you want to save your changes?")
            dialog = ConfirmationDialog(
                parent=self.window.control,
                message=message,
                cancel=True,
                default=CANCEL,
                title="Save Changes?",
            )
            result = dialog.open()
            if result == CANCEL:
                return False
            elif result == YES:
                if not self.save():
                    return self._prompt_for_save()
        return True

    @observe("window:closing")
    def _prompt_on_close(self, event):
        """ Prompt the user to save when exiting.
        """
        window = event.new
        if not self._prompt_for_save():
            window.veto = True
コード例 #22
0
ファイル: example_task.py プロジェクト: ovevans/pyface
class ExampleTask(Task):
    """ A simple task for editing Python code.
    """

    # Task interface -------------------------------------------------------

    id = "example.example_task"
    name = "Multi-Tab Editor"

    active_editor = Property(Instance(IEditor),
                             observe="editor_area.active_editor")

    editor_area = Instance(IEditorAreaPane)

    menu_bar = SMenuBar(
        SMenu(
            TaskAction(name="New", method="new", accelerator="Ctrl+N"),
            TaskAction(name="Open...", method="open", accelerator="Ctrl+O"),
            TaskAction(name="Save", method="save", accelerator="Ctrl+S"),
            id="File",
            name="&File",
        ),
        SMenu(DockPaneToggleGroup(), id="View", name="&View"),
    )

    tool_bars = [
        SToolBar(
            TaskAction(
                method="new",
                tooltip="New file",
                image=ImageResource("document_new"),
            ),
            TaskAction(
                method="open",
                tooltip="Open a file",
                image=ImageResource("document_open"),
            ),
            TaskAction(
                method="save",
                tooltip="Save the current file",
                image=ImageResource("document_save"),
            ),
            image_size=(32, 32),
            show_tool_names=False,
        )
    ]

    # ------------------------------------------------------------------------
    # 'Task' interface.
    # ------------------------------------------------------------------------

    def _default_layout_default(self):
        return TaskLayout(left=PaneItem("example.python_script_browser_pane"))

    def activated(self):
        """ Overriden to set the window's title.
        """
        return
        filename = self.active_editor.path if self.active_editor else ""
        self.window.title = filename if filename else "Untitled"

    def create_central_pane(self):
        """ Create the central pane: the script editor.
        """
        self.editor_area = EditorAreaPane()
        return self.editor_area

    def create_dock_panes(self):
        """ Create the file browser and connect to its double click event.
        """
        browser = PythonScriptBrowserPane()
        handler = lambda _: self._open_file(browser.selected_file)
        browser.observe(handler, "activated")
        return [browser]

    # ------------------------------------------------------------------------
    # 'ExampleTask' interface.
    # ------------------------------------------------------------------------

    def new(self):
        """ Opens a new empty window
        """
        editor = PythonEditor()
        self.editor_area.add_editor(editor)
        self.editor_area.activate_editor(editor)
        self.activated()

    def open(self):
        """ Shows a dialog to open a file.
        """
        dialog = FileDialog(parent=self.window.control, wildcard="*.py")
        if dialog.open() == OK:
            self._open_file(dialog.path)

    def save(self):
        """ Attempts to save the current file, prompting for a path if
            necessary. Returns whether the file was saved.
        """
        editor = self.active_editor
        try:
            editor.save()
        except IOError:
            # If you are trying to save to a file that doesn't exist, open up a
            # FileDialog with a 'save as' action.
            dialog = FileDialog(parent=self.window.control,
                                action="save as",
                                wildcard="*.py")
            if dialog.open() == OK:
                editor.save(dialog.path)
            else:
                return False
        return True

    # ------------------------------------------------------------------------
    # Protected interface.
    # ------------------------------------------------------------------------

    def _open_file(self, filename):
        """ Opens the file at the specified path in the editor.
        """
        editor = PythonEditor(path=filename)
        self.editor_area.add_editor(editor)
        self.editor_area.activate_editor(editor)
        self.activated()

    def _prompt_for_save(self):
        """ Prompts the user to save if necessary. Returns whether the dialog
            was cancelled.
        """
        dirty_editors = dict([(editor.name, editor)
                              for editor in self.editor_area.editors
                              if editor.dirty])
        if not dirty_editors.keys():
            return True
        message = "You have unsaved files. Would you like to save them?"
        dialog = ConfirmationDialog(
            parent=self.window.control,
            message=message,
            cancel=True,
            default=CANCEL,
            title="Save Changes?",
        )
        result = dialog.open()
        if result == CANCEL:
            return False
        elif result == YES:
            for name, editor in dirty_editors.items():
                editor.save(editor.path)
        return True

    # Trait change handlers ------------------------------------------------

    @observe("window:closing")
    def _prompt_on_close(self, event):
        """ Prompt the user to save when exiting.
        """
        close = self._prompt_for_save()
        window = event.new
        window.veto = not close

    # Trait property getter/setters ----------------------------------------

    def _get_active_editor(self):
        if self.editor_area is not None:
            return self.editor_area.active_editor
        return None
コード例 #23
0
class FlowTask(Task):
    """
    classdocs
    """

    id = "edu.mit.synbio.cytoflow.flow_task"
    name = "Cytometry analysis"

    # the main workflow instance.
    model = Instance(Workflow)

    # the center pane
    plot_pane = Instance(FlowTaskPane)
    workflow_pane = Instance(WorkflowDockPane)
    view_pane = Instance(ViewDockPane)

    # plugin lists, to setup the interface
    op_plugins = List(IOperationPlugin)
    view_plugins = List(IViewPlugin)

    menu_bar = SMenuBar(
        SMenu(
            TaskAction(name='Open...', method='on_open', accelerator='Ctrl+O'),
            TaskAction(
                name='Save',
                #image='save',
                method='on_save',
                accelerator='Ctrl+S'),
            TaskAction(name='Save As...',
                       method='on_save_as',
                       accelerator='Ctrl+e'),
            TaskAction(name='Save Plot...',
                       method='on_export',
                       accelerator='Ctrl+x'),
            #                               TaskAction(name='Export Jupyter notebook...',
            #                                          method='on_notebook',
            #                                          accelerator='Ctrl+I'),
            #                               TaskAction(name='Preferences...',
            #                                          method='on_prefs',
            #                                          accelerator='Ctrl+P'),
            id='File',
            name='&File'),
        SMenu(id='View', name='&View'),
        SMenu(TaskAction(name='Report a problem....', method='on_problem'),
              TaskAction(name='About...', method='on_about'),
              id="Help",
              name="&Help"))

    tool_bars = [
        SToolBar(
            TaskAction(method='on_new',
                       name="New",
                       tooltip='New workflow',
                       image=ImageResource('new')),
            TaskAction(method='on_open',
                       name="Open",
                       tooltip='Open a file',
                       image=ImageResource('open')),
            TaskAction(method='on_save',
                       name="Save",
                       tooltip='Save the current file',
                       image=ImageResource('save')),
            TaskAction(method='on_export',
                       name="Save Plot",
                       tooltip='Save the current plot',
                       image=ImageResource('export')),
            #                            TaskAction(method='on_notebook',
            #                                       name='Notebook',
            #                                       tooltip="Export to an Jupyter notebook...",
            #                                       image=ImageResource('ipython')),
            #                            TaskAction(method='on_prefs',
            #                                       name = "Prefs",
            #                                       tooltip='Preferences',
            #                                       image=ImageResource('prefs')),
            image_size=(32, 32))
    ]

    # the file to save to if the user clicks "save" and has already clicked
    # "open" or "save as".
    filename = Unicode

    def prepare_destroy(self):
        self.model.shutdown_remote_process()

    def activated(self):
        # add the import op
        self.add_operation(ImportPlugin().id)
        self.model.selected = self.model.workflow[0]

        # if we're debugging, add a few data bits
        if self.model.debug:
            from cytoflow import Tube

            import_op = self.model.workflow[0].operation
            import_op.conditions = {"Dox": "float", "Well": "category"}
            #             import_op.conditions["Dox"] = "float"
            #             import_op.conditions["Well"] = "category"

            tube1 = Tube(file="../cytoflow/tests/data/Plate01/CFP_Well_A4.fcs",
                         conditions={
                             "Dox": 0.0,
                             "Well": 'A'
                         })

            tube2 = Tube(file="../cytoflow/tests/data/Plate01/RFP_Well_A3.fcs",
                         conditions={
                             "Dox": 10.0,
                             "Well": 'A'
                         })

            tube3 = Tube(file="../cytoflow/tests/data/Plate01/CFP_Well_B4.fcs",
                         conditions={
                             "Dox": 0.0,
                             "Well": 'B'
                         })

            tube4 = Tube(file="../cytoflow/tests/data/Plate01/RFP_Well_A6.fcs",
                         conditions={
                             "Dox": 10.0,
                             "Well": 'B'
                         })

            import_op.tubes = [tube1, tube2, tube3, tube4]

#             self.add_operation(ChannelStatisticPlugin().id)
#             stat_op = self.model.workflow[1].operation
#             stat_op.name = "Test"
#             stat_op.channel = "Y2-A"
#             stat_op.statistic_name = "Geom.Mean"
#             stat_op.by = ["Dox", "Well"]
#             self.model.selected = self.model.workflow[1]

        self.model.modified = False

    def _default_layout_default(self):
        return TaskLayout(left=PaneItem("edu.mit.synbio.workflow_pane"),
                          right=PaneItem("edu.mit.synbio.view_traits_pane"))

    def create_central_pane(self):
        self.plot_pane = FlowTaskPane(model=self.model)
        return self.plot_pane

    def create_dock_panes(self):
        self.workflow_pane = WorkflowDockPane(model=self.model,
                                              plugins=self.op_plugins,
                                              task=self)

        self.view_pane = ViewDockPane(model=self.model,
                                      plugins=self.view_plugins,
                                      task=self)

        return [self.workflow_pane, self.view_pane]

    def on_new(self):
        if self.model.modified:
            ret = confirm(
                parent=None,
                message=
                "Are you sure you want to discard the current workflow?",
                title="Clear workflow?")

            if ret != YES:
                return

        self.filename = ""
        self.window.title = "Cytoflow"

        # clear the workflow
        self.model.workflow = []

        # add the import op
        self.add_operation(ImportPlugin().id)

        # and select the operation
        self.model.selected = self.model.workflow[0]

        self.model.modified = False

    def on_open(self):
        """ 
        Shows a dialog to open a file.
        """

        if self.model.modified:
            ret = confirm(
                parent=None,
                message=
                "Are you sure you want to discard the current workflow?",
                title="Clear workflow?")

            if ret != YES:
                return

        dialog = FileDialog(
            parent=self.window.control,
            action='open',
            wildcard=(
                FileDialog.create_wildcard("Cytoflow workflow", "*.flow") +
                ';' +  #@UndefinedVariable  
                FileDialog.create_wildcard("All files",
                                           "*")))  #@UndefinedVariable
        if dialog.open() == OK:
            self.open_file(dialog.path)
            self.filename = dialog.path
            self.window.title = "Cytoflow - " + self.filename

    def open_file(self, path):
        f = open(path, 'r')
        unpickler = pickle.Unpickler(f)

        try:
            version = unpickler.load()
        except TraitError:
            error(parent=None,
                  message="This doesn't look like a Cytoflow file. Or maybe "
                  "you tried to load a workflow older than version "
                  "0.5?")
            return

        if version != self.model.version:
            ret = confirm(
                parent=None,
                message="This is Cytoflow {}, but you're trying "
                "to load a workflow from version {}. This may or "
                "may not work!  Are you sure you want to proceed?".format(
                    self.model.version, version),
                title="Load workflow?")
            if ret != YES:
                return

        try:
            new_workflow = unpickler.load()
        except TraitError as e:
            error(parent=None, message="Error trying to load the workflow.")
            return

        # a few things to take care of when reloading
        for wi_idx, wi in enumerate(new_workflow):

            # get wi lock
            wi.lock.acquire()

            # clear the wi status
            wi.status = "loading"

            # re-link the linked list.  i thought this would get taken care
            # of in deserialization, but i guess not...
            if wi_idx > 0:
                wi.previous_wi = new_workflow[wi_idx - 1]

        # replace the current workflow with the one we just loaded

        if False:  # for debugging the loading of things
            from .event_tracer import record_events

            with record_events() as container:
                self.model.workflow = new_workflow

            container.save_to_directory(os.getcwd())
        else:
            self.model.workflow = new_workflow
            self.model.modified = False

        for wi in self.model.workflow:
            wi.lock.release()

    def on_save(self):
        """ Save the file to the previous filename  """
        if self.filename:
            self.save_file(self.filename)
        else:
            self.on_save_as()

    def on_save_as(self):
        dialog = DefaultFileDialog(
            parent=self.window.control,
            action='save as',
            default_suffix="flow",
            wildcard=(
                FileDialog.create_wildcard("Cytoflow workflow", "*.flow") +
                ';' +  #@UndefinedVariable  
                FileDialog.create_wildcard("All files",
                                           "*")))  #@UndefinedVariable

        if dialog.open() == OK:
            self.save_file(dialog.path)
            self.filename = dialog.path
            self.window.title = "Cytoflow - " + self.filename
        pass

    def save_file(self, path):
        # TODO - error handling
        f = open(path, 'w')
        pickler = pickle.Pickler(f, 0)  # text protocol for now
        pickler.dump(self.model.version)
        pickler.dump(self.model.workflow)
        self.model.modified = False

    @on_trait_change('model.modified', post_init=True)
    def _on_model_modified(self, val):
        if val:
            if not self.window.title.endswith("*"):
                self.window.title += "*"
        else:
            if self.window.title.endswith("*"):
                self.window.title = self.window.title[:-1]

    def on_export(self):
        """
        Shows a dialog to export a file
        """

        information(
            None, "This will save exactly what you see on the screen "
            "to a file.", "Export")

        f = ""
        filetypes_groups = self.plot_pane.canvas.get_supported_filetypes_grouped(
        )
        filename_exts = []
        for name, ext in filetypes_groups.items():
            if f:
                f += ";"
            f += FileDialog.create_wildcard(name,
                                            " ".join(["*." + e for e in ext
                                                      ]))  #@UndefinedVariable
            filename_exts.append(ext)

        dialog = FileDialog(parent=self.window.control,
                            action='save as',
                            wildcard=f)

        if dialog.open() == OK:
            filetypes = list(
                self.plot_pane.canvas.get_supported_filetypes().keys())
            if not [
                    ext for ext in ["." + ext for ext in filetypes]
                    if dialog.path.endswith(ext)
            ]:
                selected_exts = filename_exts[dialog.wildcard_index]
                ext = sorted(selected_exts, key=len)[0]
                dialog.path += "."
                dialog.path += ext

            self.plot_pane.export(dialog.path)

    def on_notebook(self):
        """
        Shows a dialog to export the workflow to an Jupyter notebook
        """

        return

        dialog = FileDialog(parent=self.window.control,
                            action='save as',
                            wildcard='*.ipynb')
        if dialog.open() == OK:
            writer = JupyterNotebookWriter(file=dialog.path)
            writer.export(self.model.workflow)

    def on_prefs(self):
        pass

    def on_problem(self):

        information(
            None, "Your email client will now create a new message to the "
            "developer.  Debugging logs are attached.  Please fill "
            "out the template bug report and send -- thank you for "
            "reporting a bug!")

        log = self.application.application_log.getvalue()

        versions = [
            "{0} {1}".format(key, value)
            for key, value in self._get_package_versions().items()
        ]

        body = """
Thank you for your bug report!  Please fill out the following template.

PLATFORM (Mac, PC, Linux, other):

OPERATING SYSTEM (eg OSX 10.7, Windows 8.1):

SEVERITY (Critical? Major? Minor? Enhancement?):

DESCRIPTION:
  - What were you trying to do?
  - What happened?
  - What did you expect to happen?
  

PACKAGE VERSIONS: {0}

DEBUG LOG: {1}
""".format(versions, log)


#         mailto.mailto("*****@*****.**",
#                       subject = "Cytoflow bug report",
#                       body = body)

    def _get_package_versions(self):

        import sys
        from cytoflow import __version__ as cf_version
        from fcsparser import __version__ as fcs_version
        from pandas import __version__ as pd_version
        from numpy import __version__ as np_version
        from numexpr import __version__ as nxp_version
        from bottleneck import __version__ as btl_version
        from seaborn import __version__ as sns_version
        from matplotlib import __version__ as mpl_version
        from scipy import __version__ as scipy_version
        from sklearn import __version__ as skl_version
        from pyface import __version__ as pyf_version
        from envisage import __version__ as env_version
        from traits import __version__ as trt_version
        from traitsui import __version__ as trt_ui_version

        return {
            "python": sys.version,
            "cytoflow": cf_version,
            "fcsparser": fcs_version,
            "pandas": pd_version,
            "numpy": np_version,
            "numexpr": nxp_version,
            "bottleneck": btl_version,
            "seaborn": sns_version,
            "matplotlib": mpl_version,
            "scipy": scipy_version,
            "scikit-learn": skl_version,
            "pyface": pyf_version,
            "envisage": env_version,
            "traits": trt_version,
            "traitsui": trt_ui_version
        }

    def on_about(self):
        versions = self._get_package_versions()
        text = ["<b>Cytoflow {0}</b>".format(versions['cytoflow']), "<p>"]

        ver_text = [
            "{0} {1}".format(key, value) for key, value in versions.items()
        ]

        text.extend(ver_text)

        text.extend([
            "Icons from the <a href=http://tango.freedesktop.org>Tango Desktop Project</a>",
            "<a href=https://thenounproject.com/search/?q=setup&i=14287>Settings icon</a> by Paulo Sa Ferreira from <a href=https://thenounproject.com>The Noun Project</a>",
            "<a href=http://www.freepik.com/free-photos-vectors/background>App icon from Starline - Freepik.com</a>",
            "Cuvette image from Wikimedia Commons user <a href=http://commons.wikimedia.org/wiki/File:Hellma_Large_cone_cytometry_cell.JPG>HellmaUSA</a>"
        ])

        dialog = AboutDialog(text=text,
                             parent=self.window.control,
                             title="About",
                             image=ImageResource('cuvette'),
                             additions=text)
        dialog.open()

    @on_trait_change('model.selected', post_init=True)
    def _on_select_op(self, selected):
        if selected:
            self.view_pane.enabled = (selected is not None)
            self.view_pane.default_view = selected.default_view.id if selected.default_view else ""
            self.view_pane.selected_view = selected.current_view.id if selected.current_view else ""
        else:
            self.view_pane.enabled = False

    @on_trait_change('view_pane.selected_view', post_init=True)
    def _on_select_view(self, view_id):

        if not view_id:
            return

        # if we already have an instantiated view object, find it
        try:
            self.model.selected.current_view = next(
                (x for x in self.model.selected.views if x.id == view_id))
        except StopIteration:
            # else make the new view
            plugin = next(
                (x for x in self.view_plugins if x.view_id == view_id))
            view = plugin.get_view()
            self.model.selected.views.append(view)
            self.model.selected.current_view = view

    def add_operation(self, op_id):
        # first, find the matching plugin
        plugin = next((x for x in self.op_plugins if x.id == op_id))

        # next, get an operation
        op = plugin.get_operation()

        # make a new workflow item
        wi = WorkflowItem(
            operation=op,
            deletable=(op_id !=
                       'edu.mit.synbio.cytoflowgui.op_plugins.import'))

        # if the op has a default view, add it to the wi
        try:
            wi.default_view = op.default_view()
            wi.views.append(wi.default_view)
            wi.current_view = wi.default_view
        except AttributeError:
            pass

        # figure out where to add it
        if self.model.selected:
            idx = self.model.workflow.index(self.model.selected) + 1
        else:
            idx = len(self.model.workflow)

        # the add_remove_items handler takes care of updating the linked list
        self.model.workflow.insert(idx, wi)

        # and make sure to actually select the new wi
        self.model.selected = wi
コード例 #24
0
ファイル: tasbe_task.py プロジェクト: nathan2wong/cytoflow
class TASBETask(Task):
    """
    classdocs
    """
    
    id = "edu.mit.synbio.cytoflowgui.tasbe_task"
    name = "TASBE calibration"
    
    menu_bar = SMenuBar(SMenu(TaskToggleGroup(),
                              id = 'View', name = '&View'))
    
    # the main workflow instance.
    model = Instance(Workflow)
    
    op = Instance(IOperation)
        
    calibration_pane = Instance(CalibrationPane)
    help_pane = Instance(HelpDockPane)
    
    _cached_help = HTML

    
    def activated(self):
        self.model.backup_workflow = self.model.workflow
        self.model.workflow = []
        self.model.modified = False
        
        # add the op
        self.op = TasbeCalibrationOp()
        
        # make a new workflow item
        wi = WorkflowItem(operation = self.op,
                          deletable = False)
       
        wi.default_view = self.op.default_view() 
        wi.views.append(wi.default_view)
        wi.current_view = wi.default_view
             
        self.model.workflow.append(wi)
        self.model.selected = wi
        
        self.help_pane.html = self.op.get_help()
    
    def _default_layout_default(self):
        return TaskLayout(left = PaneItem("edu.mit.synbio.cytoflowgui.calibration_pane", width = 350),
                          right = PaneItem("edu.mit.synbio.cytoflowgui.help_pane", width = 350))
     
    def create_central_pane(self):
        return self.application.plot_pane
     
    def create_dock_panes(self):
        self.calibration_pane = CalibrationPane(model = self.model, 
                                                task = self)
         
        self.help_pane = HelpDockPane(task = self)
        
        return [self.calibration_pane, self.help_pane]
    
    @on_trait_change('op:do_exit', post_init = True)
    def activate_cytoflow_task(self):
        task = next(x for x in self.window.tasks if x.id == 'edu.mit.synbio.cytoflowgui.flow_task')
        self.window.activate_task(task)
コード例 #25
0
class ExampleTask(Task):
    """ A simple task for editing Python code.
    """

    #### Task interface #######################################################

    id = 'example.example_task'
    name = 'Multi-Tab Editor'

    active_editor = Property(Instance(IEditor),
                             depends_on='editor_area.active_editor')

    editor_area = Instance(IEditorAreaPane)

    menu_bar = SMenuBar(
        SMenu(TaskAction(name='New', method='new', accelerator='Ctrl+N'),
              TaskAction(name='Open...', method='open', accelerator='Ctrl+O'),
              TaskAction(name='Save', method='save', accelerator='Ctrl+S'),
              id='File',
              name='&File'),
        SMenu(DockPaneToggleGroup(), id='View', name='&View'))

    tool_bars = [
        SToolBar(TaskAction(method='new',
                            tooltip='New file',
                            image=ImageResource('document_new')),
                 TaskAction(method='open',
                            tooltip='Open a file',
                            image=ImageResource('document_open')),
                 TaskAction(method='save',
                            tooltip='Save the current file',
                            image=ImageResource('document_save')),
                 image_size=(32, 32),
                 show_tool_names=False),
    ]

    ###########################################################################
    # 'Task' interface.
    ###########################################################################

    def _default_layout_default(self):
        return TaskLayout(left=PaneItem('example.python_script_browser_pane'))

    def activated(self):
        """ Overriden to set the window's title.
        """
        return
        filename = self.active_editor.path if self.active_editor else ''
        self.window.title = filename if filename else 'Untitled'

    def create_central_pane(self):
        """ Create the central pane: the script editor.
        """
        self.editor_area = EditorAreaPane()
        return self.editor_area

    def create_dock_panes(self):
        """ Create the file browser and connect to its double click event.
        """
        browser = PythonScriptBrowserPane()
        handler = lambda: self._open_file(browser.selected_file)
        browser.on_trait_change(handler, 'activated')
        return [browser]

    ###########################################################################
    # 'ExampleTask' interface.
    ###########################################################################

    def new(self):
        """ Opens a new empty window
        """
        editor = PythonEditor()
        self.editor_area.add_editor(editor)
        self.editor_area.activate_editor(editor)
        self.activated()

    def open(self):
        """ Shows a dialog to open a file.
        """
        dialog = FileDialog(parent=self.window.control, wildcard='*.py')
        if dialog.open() == OK:
            self._open_file(dialog.path)

    def save(self):
        """ Attempts to save the current file, prompting for a path if
            necessary. Returns whether the file was saved.
        """
        editor = self.active_editor
        try:
            editor.save()
        except IOError:
            # If you are trying to save to a file that doesn't exist, open up a
            # FileDialog with a 'save as' action.
            dialog = FileDialog(parent=self.window.control,
                                action='save as',
                                wildcard='*.py')
            if dialog.open() == OK:
                editor.save(dialog.path)
            else:
                return False
        return True

    ###########################################################################
    # Protected interface.
    ###########################################################################

    def _open_file(self, filename):
        """ Opens the file at the specified path in the editor.
        """
        editor = PythonEditor(path=filename)
        self.editor_area.add_editor(editor)
        self.editor_area.activate_editor(editor)
        self.activated()

    def _prompt_for_save(self):
        """ Prompts the user to save if necessary. Returns whether the dialog
            was cancelled.
        """
        dirty_editors = dict([(editor.name, editor)
                              for editor in self.editor_area.editors
                              if editor.dirty])
        if not list(dirty_editors.keys()):
            return True
        message = 'You have unsaved files. Would you like to save them?'
        dialog = ConfirmationDialog(parent=self.window.control,
                                    message=message,
                                    cancel=True,
                                    default=CANCEL,
                                    title='Save Changes?')
        result = dialog.open()
        if result == CANCEL:
            return False
        elif result == YES:
            for name, editor in list(dirty_editors.items()):
                editor.save(editor.path)
        return True

    #### Trait change handlers ################################################

    @on_trait_change('window:closing')
    def _prompt_on_close(self, event):
        """ Prompt the user to save when exiting.
        """
        close = self._prompt_for_save()
        event.veto = not close

    #### Trait property getter/setters ########################################

    def _get_active_editor(self):
        if self.editor_area is not None:
            return self.editor_area.active_editor
        return None
コード例 #26
0
ファイル: flow_task.py プロジェクト: crife-pact/cytoflow
class FlowTask(Task):
    """
    classdocs
    """
    
    id = "edu.mit.synbio.cytoflowgui.flow_task"
    name = "Cytometry analysis"
    
    # the main workflow instance.
    model = Instance(Workflow)
        
    # the center pane
    workflow_pane = Instance(WorkflowDockPane)
    view_pane = Instance(ViewDockPane)
    help_pane = Instance(HelpDockPane)
    plot_params_pane = Instance(PlotParamsPane)
    
    # plugin lists, to setup the interface
    op_plugins = List(IOperationPlugin)
    view_plugins = List(IViewPlugin)
    
    menu_bar = SMenuBar(SMenu(TaskAction(name='Open...',
                                         method='on_open',
                                         accelerator='Ctrl+O'),
                              TaskAction(name='Save',
                                         #image='save', 
                                         method='on_save',
                                         accelerator='Ctrl+S'),
                              TaskAction(name='Save As...',
                                         method='on_save_as',
                                         accelerator='Ctrl+e'),
                              TaskAction(name='Save Plot...',
                                         method='on_export',
                                         accelerator='Ctrl+x'),
                              TaskAction(name='Export Jupyter notebook...',
                                         method='on_notebook',
                                         accelerator='Ctrl+I'),                              
#                               TaskAction(name='Preferences...',
#                                          method='on_prefs',
#                                          accelerator='Ctrl+P'),
                              id='File', name='&File'),
                        SMenu(TaskToggleGroup(),
                              id = 'View', name = '&View'),
                        SMenu(TaskAction(name = 'Online documentation...',
                                         method = 'on_docs'),
                                         TaskAction(name = 'Report a problem....',
                                         method = 'on_problem'),
                              TaskAction(name='About...',
                                         method='on_about'),
                              id="Help", name ="&Help"))
    
    tool_bars = [ SToolBar(TaskAction(method='on_new',
                                      name = "New",
                                      tooltip='New workflow',
                                      image=ImageResource('new')),
                           TaskAction(method='on_open',
                                      name = "Open",
                                      tooltip='Open a file',
                                      image=ImageResource('open')),
                           TaskAction(method='on_save',
                                      name = "Save",
                                      tooltip='Save the current file',
                                      image=ImageResource('save')),
                           TaskAction(method='on_export',
                                      name = "Save Plot",
                                      tooltip='Save the current plot',
                                      image=ImageResource('export')),
                           TaskAction(method='on_notebook',
                                       name='Notebook',
                                       tooltip="Export to an Jupyter notebook...",
                                       image=ImageResource('jupyter')),
                           TaskAction(method = "on_calibrate",
                                      name = "Calibrate FCS...",
                                      tooltip = "Calibrate FCS files",
                                      image = ImageResource('tasbe')),
                           TaskAction(method = 'on_problem',
                                      name = "Report a bug...",
                                      tooltib = "Report a bug",
                                      image = ImageResource('bug')))]
#                            TaskAction(method='on_prefs',
#                                       name = "Prefs",
#                                       tooltip='Preferences',
#                                       image=ImageResource('prefs')),
    
    # the file to save to if the user clicks "save" and has already clicked
    # "open" or "save as".
    filename = Str
        
    def initialized(self):
        if self.filename:
            self.open_file(self.filename)

        
    def activated(self):
        
        # if we're coming back from the TASBE task, re-load the saved
        # workflow
        if self.model.backup_workflow:
            self.model.workflow = self.model.backup_workflow
            self.model.backup_workflow = []
            return
        
        # else, set up a new workflow
        # add the import op
        if not self.model.workflow:
            self.add_operation(ImportPlugin().id) 
            self.model.selected = self.model.workflow[0]
                    
        self.model.modified = False
    
    def _default_layout_default(self):
        return TaskLayout(left = VSplitter(PaneItem("edu.mit.synbio.cytoflowgui.workflow_pane", width = 350),
                                           PaneItem("edu.mit.synbio.cytoflowgui.help_pane", width = 350, height = 350)),
                          right = VSplitter(PaneItem("edu.mit.synbio.cytoflowgui.view_traits_pane", width = 350),
                                            PaneItem("edu.mit.synbio.cytoflowgui.params_pane", width = 350, height = 350)),
                          top_left_corner = 'left',
                          bottom_left_corner = 'left',
                          top_right_corner = 'right',
                          bottom_right_corner = 'right')
     
    def create_central_pane(self):   
        # set the toolbar image size
        # this isn't really the right place for this, but it's the only
        # place control passes back to user code before the toolbar
        # is created.
        
        dpi = self.window.control.physicalDpiX()
        self.tool_bars[0].image_size = (int(0.4 * dpi), int(0.4 * dpi))
        return self.application.plot_pane
     
    def create_dock_panes(self):
        self.workflow_pane = WorkflowDockPane(model = self.model, 
                                              plugins = self.op_plugins,
                                              task = self)
        
        self.view_pane = ViewDockPane(model = self.model,
                                      plugins = self.view_plugins,
                                      task = self)
        
        self.help_pane = HelpDockPane(view_plugins = self.view_plugins,
                                      op_plugins = self.op_plugins,
                                      task = self)
        
        self.plot_params_pane = PlotParamsPane(model = self.model,
                                               task = self)
        
        return [self.workflow_pane, self.view_pane, self.help_pane, self.plot_params_pane]
        
    def on_new(self):
        if self.model.modified:
            ret = confirm(parent = None,
                          message = "Are you sure you want to discard the current workflow?",
                          title = "Clear workflow?")
            
            if ret != YES:
                return
            
        self.filename = ""
        self.window.title = "Cytoflow"
        
        # clear the workflow
        self.model.workflow = []
        
        # add the import op
        self.add_operation(ImportPlugin().id) 
        
        # and select the operation
        self.model.selected = self.model.workflow[0]
        
        self.model.modified = False
     
        
    def on_open(self):
        """ 
        Shows a dialog to open a file.
        """
        
        if self.model.modified:
            ret = confirm(parent = None,
                          message = "Are you sure you want to discard the current workflow?",
                          title = "Clear workflow?")
            
            if ret != YES:
                return
        
        dialog = FileDialog(parent = self.window.control, 
                            action = 'open',
                            wildcard = (FileDialog.create_wildcard("Cytoflow workflow", "*.flow") + ';' +  #@UndefinedVariable  
                                        FileDialog.create_wildcard("All files", "*"))) #@UndefinedVariable  
        if dialog.open() == OK:
            self.open_file(dialog.path)
            self.filename = dialog.path
            self.window.title = "Cytoflow - " + self.filename
            

    def open_file(self, path):
        
        try:
            new_workflow = load_yaml(path)

            # a few things to take care of when reloading.
            # we do this in the try block to catch people who
            # load valid YAML files that aren't from cytoflow.
            
            for wi_idx, wi in enumerate(new_workflow):
                
                # get wi lock
                wi.lock.acquire()
                
                # clear the wi status
                wi.status = "loading"
    
                # re-link the linked list.
                if wi_idx > 0:
                    wi.previous_wi = new_workflow[wi_idx - 1]
                
                if wi_idx < len(new_workflow) - 1:
                    wi.next_wi = new_workflow[wi_idx + 1]

        except yaml.parser.ParserError as e:
            error(None,
                  "Parser error loading {} -- is it a Cytoflow file?\n\n{}"
                  .format(path, str(e)))
            return
        except Exception as e:
            error(None,
                  "{} loading {} -- is it a Cytoflow file?\n\n{}"
                  .format(e.__class__.__name__, path, str(e)))
            return
        
        # are we just running a smoke test?
        if 'startup_test' in new_workflow[0].metadata:
            def quit_app(app):
                app.exit(force = True)
                
            from pyface.timer.api import do_after
            do_after(5*1000, quit_app, self.application)
            return
            
        # check that the FCS files are all there
        
        wi = new_workflow[0]
        assert(wi.operation.id == "edu.mit.synbio.cytoflow.operations.import")
        missing_tubes = 0
        for tube in wi.operation.tubes:
            file = pathlib.Path(tube.file)
            if not file.exists():
                missing_tubes += 1
                
        if missing_tubes == len(wi.operation.tubes):
            warning(self.window.control,
                    "Cytoflow couldn't find any of the FCS files from that "
                    "workflow.  If they've been moved, please open one FCS "
                    "file to show Cytoflow where they've been moved to.")
            
            dialog = FileDialog(parent = self.window.control, 
                                action = 'open',
                                wildcard = (FileDialog.create_wildcard("FCS files", "*.fcs *.lmd")))  # @UndefinedVariable
            
            if dialog.open() == OK:
                # find the "best" file match -- ie, the one with the longest
                # tail match
                fcs_path = pathlib.Path(dialog.path).parts
                best_path_len = -1
                                
                for tube in wi.operation.tubes:
                    tube_path = pathlib.Path(tube.file).parts
                    
                    for i in range(len(fcs_path)):
                        if list(reversed(fcs_path))[:i] == list(reversed(tube_path))[:i] and i > best_path_len:
                            best_path_len = i
                            
                if best_path_len >= 0:
                    for tube in wi.operation.tubes:
                        tube_path = pathlib.Path(tube.file).parts
                        new_path = fcs_path[:-1 * best_path_len] + tube_path[-1 * best_path_len :]
                        tube.file = str(pathlib.Path(*new_path))
                        
        elif missing_tubes > 0:
            warning(self.window.control,
                    "Cytoflow couldn't find some of the FCS files from that "
                    "workflow.  You'll need to re-load them from the Import "
                    "operation.")

        # replace the current workflow with the one we just loaded
        
        if False:  # for debugging the loading of things
            from .event_tracer import record_events 
            
            with record_events() as container:
                self.model.workflow = new_workflow
                                
            container.save_to_directory(os.getcwd()) 
        else:
            self.model.workflow = new_workflow
            self.model.modified = False
            
        for wi in self.model.workflow:
            wi.lock.release()
            
        if self.model.debug:
            self.model.run_all()
        else:
            ret = confirm(parent = None,
                          message = "Do you want to execute the workflow now?",
                          title = "Run workflow?")
            
            if ret == YES:
                self.model.run_all()

        
    def on_save(self):
        """ Save the file to the previous filename  """
        if self.filename:
            save_yaml(self.model.workflow, self.filename)
            self.model.modified = False
        else:
            self.on_save_as()
            
    def on_save_as(self):
        dialog = DefaultFileDialog(parent = self.window.control,
                                   action = 'save as', 
                                   default_suffix = "flow",
                                   wildcard = (FileDialog.create_wildcard("Cytoflow workflow", "*.flow") + ';' + #@UndefinedVariable  
                                               FileDialog.create_wildcard("All files", "*")))                    #@UndefinedVariable  
        
        if dialog.open() == OK:
            save_yaml(self.model.workflow, dialog.path)
            self.filename = dialog.path
            self.model.modified = False
            self.window.title = "Cytoflow - " + self.filename
            
    @on_trait_change('model.modified', post_init = True)
    def _on_model_modified(self, val):
        if val:
            if not self.window.title.endswith("*"):
                self.window.title += "*"
        else:
            if self.window.title.endswith("*"):
                self.window.title = self.window.title[:-1]
        

    def on_export(self):
        task = next(x for x in self.window.tasks if x.id == 'edu.mit.synbio.cytoflowgui.export_task')
        self.window.activate_task(task)        


    def on_calibrate(self):
        task = next(x for x in self.window.tasks if x.id == 'edu.mit.synbio.cytoflowgui.tasbe_task')
        self.window.activate_task(task)
        
            
    def on_notebook(self):
        """
        Shows a dialog to export the workflow to an Jupyter notebook
        """

        dialog = DefaultFileDialog(parent = self.window.control,
                                   action = 'save as',
                                   default_suffix = "ipynb",
                                   wildcard = (FileDialog.create_wildcard("Jupyter notebook", "*.ipynb") + ';' + #@UndefinedVariable  
                                               FileDialog.create_wildcard("All files", "*")))  # @UndefinedVariable
        if dialog.open() == OK:
            save_notebook(self.model.workflow, dialog.path)

    
    def on_prefs(self):
        pass
    
    def on_docs(self):
        webbrowser.open_new_tab("https://cytoflow.readthedocs.io/en/stable/manual.html")

    
    def on_problem(self):

        log = str(self._get_package_versions()) + "\n" + self.application.application_log.getvalue()
        
        msg = "The best way to report a problem is send an application log to " \
              "the developers.  If you click 'Yes' below, you will be given then " \
              "opportunity to save the log to a file and then file a " \
              "new issue on GitHub at " \
              "https://github.com/cytoflow/cytoflow/issues/new" 
        
        dialog = ConfirmationDialog(message = msg,
                                    informative = "Would you like to report an issue to the developers?")
                
        if dialog.open() == YES:
            dialog = DefaultFileDialog(parent = self.window.control,
                                       action = 'save as', 
                                       default_suffix = "log",
                                       wildcard = (FileDialog.create_wildcard("Log files", "*.log") + ';' + #@UndefinedVariable  
                                                   FileDialog.create_wildcard("All files", "*")))                    #@UndefinedVariable  
            
            if dialog.open() == OK:
                with open(dialog.path, 'w') as f:
                    f.write(log)
                  
                webbrowser.open_new_tab("https://github.com/cytoflow/cytoflow/issues/new")
                  
            return
    
    def _get_package_versions(self):    
        from cytoflow import __version__ as cf_version
        from fcsparser import __version__ as fcs_version
        from pandas import __version__ as pd_version
        from numpy import __version__ as np_version
        from numexpr import __version__ as nxp_version
        from bottleneck import __version__ as btl_version
        from seaborn import __version__ as sns_version
        from matplotlib import __version__ as mpl_version
        from scipy import __version__ as scipy_version
        from sklearn import __version__ as skl_version
        from statsmodels import __version__ as stats_version
        from pyface import __version__ as pyf_version
        from envisage import __version__ as env_version
        from traits import __version__ as trt_version
        from traitsui import __version__ as trt_ui_version
        from yapf import __version__ as yapf_version
        from nbformat import __version__ as nb_version
        from yaml import __version__ as yaml_version
        
        return {"python" : sys.version,
                "cytoflow" : cf_version,
                "fcsparser" : fcs_version,
                "pandas" : pd_version,
                "numpy" : np_version,
                "numexpr" : nxp_version,
                "bottleneck" : btl_version,
                "seaborn" : sns_version,
                "matplotlib" : mpl_version,
                "scipy" : scipy_version,
                "scikit-learn" : skl_version,
                "statsmodels" : stats_version,
                "pyface" : pyf_version,
                "envisage" : env_version,
                "traits" : trt_version,
                "traitsui" : trt_ui_version,
                "nbformat" : nb_version,
                "yapf" : yapf_version,
                "yaml" : yaml_version}
        
        
    def on_about(self):
        versions = self._get_package_versions()
        text = ["<b>Cytoflow {0}</b>".format(versions['cytoflow']),
                "<p>"]
        
        ver_text = ["{0} {1}".format(key, value) for key, value in versions.items()]
        
        text.extend(ver_text)
        
        text.extend(["Icons from the <a href=http://tango.freedesktop.org>Tango Desktop Project</a>",
                "<a href=https://thenounproject.com/search/?q=setup&i=14287>Settings icon</a> by Paulo Sa Ferreira from <a href=https://thenounproject.com>The Noun Project</a>",
                "<a href=https://thenounproject.com/search/?q=processing&i=849831>Processing icon</a> by Gregor Cresnar from <a href=https://thenounproject.com>The Noun Project</a>",
                "<a href=http://www.freepik.com/free-photos-vectors/background>App icon from Starline - Freepik.com</a>",
                "Cuvette image from Wikimedia Commons user <a href=http://commons.wikimedia.org/wiki/File:Hellma_Large_cone_cytometry_cell.JPG>HellmaUSA</a>"])
        
        dialog = AboutDialog(text = text,
                             parent = self.window.control,
                             title = "About",
                             image = ImageResource('cuvette'),
                             additions = text)
        dialog.open()
        
    @on_trait_change('model.selected', post_init = True)
    def _on_select_op(self, selected):
        if selected:
            self.view_pane.enabled = (selected is not None)
            self.view_pane.default_view = selected.default_view.id if selected.default_view else ""
            self.view_pane.selected_view = selected.current_view.id if selected.current_view else ""
            self.help_pane.help_id = selected.operation.id
        else:
            self.view_pane.enabled = False
            
    @on_trait_change('view_pane.selected_view', post_init = True)
    def _on_select_view(self, view_id):
        
        if not view_id:
            return
        
        # if we already have an instantiated view object, find it
        try:
            self.model.selected.current_view = next((x for x in self.model.selected.views if x.id == view_id))
        except StopIteration:
            # else make the new view
            plugin = next((x for x in self.view_plugins if x.view_id == view_id))
            view = plugin.get_view()
            self.model.selected.views.append(view)
            self.model.selected.current_view = view
            
        self.help_pane.help_id = view_id
    
    def add_operation(self, op_id):
        # first, find the matching plugin
        plugin = next((x for x in self.op_plugins if x.id == op_id))
        
        # next, get an operation
        op = plugin.get_operation()
        
        # make a new workflow item
        wi = WorkflowItem(operation = op,
                          deletable = (op_id != 'edu.mit.synbio.cytoflowgui.op_plugins.import'))
        
        # if the op has a default view, add it to the wi
        try:
            wi.default_view = op.default_view()
            wi.views.append(wi.default_view)
            wi.current_view = wi.default_view
        except AttributeError:
            pass
        
        # figure out where to add it
        if self.model.selected:
            idx = self.model.workflow.index(self.model.selected) + 1
        else:
            idx = len(self.model.workflow)
             
        # the add_remove_items handler takes care of updating the linked list
        self.model.workflow.insert(idx, wi)
        
        # and make sure to actually select the new wi
        self.model.selected = wi
コード例 #27
0
 def _menu_bar_default(self):
     menu_bar = SMenuBar(
         SMenu(SMenu(SGroup(
             TaskAction(name='New Simulation',
                        method='new_simulation_from_datasource',
                        image=ImageResource('office-chart-pie')),
             TaskAction(name='New Simulation from Experiment',
                        method='new_simulation_from_experiments',
                        image=ImageResource('kchart'),
                        accelerator='Ctrl+N'),
             id='NewSimulationGroup',
             name='NewSimulationGroup',
         ),
                     id='NewMenu',
                     name='&New Simulation'),
               SGroup(TaskAction(name='Save Project',
                                 accelerator='Ctrl+S',
                                 method='save',
                                 image=ImageResource('document-save')),
                      TaskAction(name='Save Project As...',
                                 accelerator='Ctrl+Shift+S',
                                 method='save_request',
                                 image=ImageResource('document-save-as')),
                      id='SaveGroup',
                      name='SaveGroup'),
               SGroup(
                   TaskAction(name='Save User Data',
                              method='save_user_ds',
                              image=ImageResource('drive-harddisk')),
                   TaskAction(name='Export User Data As...',
                              method='request_export_user_ds',
                              image=ImageResource('document-import')),
                   id='SaveUserDataGroup',
                   name='SaveUserDataGroup',
               ),
               SGroup(
                   TaskWindowAction(
                       name='Close',
                       accelerator='Ctrl+W',
                       method='close',
                   ),
                   id='CloseGroup',
                   name='CloseGroup',
               ),
               id='File',
               name='&File'), SMenu(id='Edit', name='&Edit'),
         SMenu(DockPaneToggleGroup(), id='View', name='&View'),
         SMenu(
             SGroup(
                 TaskAction(name='Parameter Explorer',
                            accelerator='Ctrl+Shift+N',
                            method='new_simulation_grid',
                            enabled_name='simulations_exist'),
                 TaskAction(name='Parameter Optimizer',
                            accelerator='Ctrl+Shift+M',
                            method='new_optimizer',
                            enabled_name='experiments_and_sim_exist'),
                 id='ParamExplorationGroup',
                 name='ParamExplorationGroup',
             ),
             SGroup(
                 TaskAction(name='Run Simulations',
                            method='run_simulations',
                            accelerator='Ctrl+R',
                            enabled_name='simulations_exist',
                            image=ImageResource('arrow-right')),
                 TaskAction(name='Run Simulation Group',
                            method='run_simulation_groups',
                            accelerator='Ctrl+Shift+R',
                            enabled_name='simulation_groups_exist',
                            image=ImageResource('arrow-right-double')),
                 id='RunSimulationGroup',
                 name='RunSimulationGroup',
             ),
             SGroup(
                 TaskAction(name='Plot Chomatogram(s)',
                            method='new_model_calibration_plot',
                            accelerator='Ctrl+P',
                            image=ImageResource('office-chart-line')),
                 TaskAction(name='Particle data animation',
                            method='new_animation_plot'),
                 id='PlotsGroup',
                 name='PlotsGroup',
             ),
             SGroup(
                 TaskAction(name=STRIP_TOOL_NAME,
                            method='open_strip_fraction_editor',
                            enabled_name='_strip_component_exist'),
                 id='ConfigurationGroup',
                 name='ConfigurationGroup',
             ),
             SGroup(TaskAction(name='Custom Python script...',
                               accelerator='Ctrl+I',
                               method='request_run_python_script',
                               tooltip='Modify the current project with '
                               'custom script.',
                               image=ImageResource('text-x-python')),
                    TaskAction(name='Interactive Python console...',
                               accelerator='Ctrl+J',
                               tooltip="(Jupyter) Python console to "
                               "interactively explore Reveal's code "
                               "and develop new tools/scripts.",
                               method='request_launch_python_console',
                               image=ImageResource('ipython_icon')),
                    id='RunPythonGroup',
                    name='RunPythonGroup'),
             id='Tools',
             name='&Tools',
         ), SMenu(id='Help', name='&Help'))
     return menu_bar