Esempio n. 1
0
class Tools(HasPrivateTraits):

    #-- Trait Definitions ------------------------------------------------------

    # Our traits UI object:
    ui = Instance(UI)

    # Optional test arguments when starting the test object's UI:
    test_args = Tuple
    test_traits = Dict

    # The optional object being developed/tested:
    test_object = Instance(HasTraits)

    # The Traits UI object for the object being developed:
    test_ui = Instance(UI)

    # Mode in which to create a test object:
    create_as = Enum('Child', 'Independent', 'Tab')

    # Can the test object be started now?
    can_start = Property(depends_on='test_ui.control')

    # The 'start' test object button:
    start_ui = Button('Start UI')

    # List of active tools pages:
    pages = List(ToolsPage)

    # The current selected page:
    selected_page = Instance(ToolsPage)

    # The name of the current page:
    name = Str('Page')

    # The list of available tools:
    tool_names = Property

    # The current selected tool name:
    selected_tool = Str('FBI Viewer')

    # The 'add tool to active page' button:
    add_tool = Button('Add Tool')

    # The 'create new page' button:
    new_page = Button('New Page')

    # The 'Save active page' page button:
    save_page = Button('Save Page')

    # The 'delete active page' button:
    delete_page = Button('Delete Page')

    # Has the FBI been enabled yet?
    fbi_enabled = Bool(False)

    #-- Traits UI Views --------------------------------------------------------

    view = View(
        VGroup(
            HGroup(
                Item('create_as', defined_when='test_object is not None'),
                TButton(
                    'start_ui',
                    label='Start UI',
                    #enabled_when = 'can_start',
                    defined_when='test_object is not None'),
                '_',
                Item('test_object',
                     style='readonly',
                     show_label=False,
                     defined_when='test_object is not None',
                     tooltip='Drag the application object',
                     editor=DNDEditor(image=ImageResource('object'))),
                Item('test_ui',
                     style='readonly',
                     show_label=False,
                     defined_when='test_object is not None',
                     enabled_when='test_ui is not None',
                     tooltip="Drag the application's Traits UI object",
                     editor=DNDEditor(
                         image=ImageResource('ui'),
                         disabled_image=ImageResource('disabled_ui'))),
                '_',
                spring,
                Item('selected_tool',
                     show_label=False,
                     editor=EnumEditor(name='tool_names'),
                     enabled_when='selected_page is not None'),
                TButton('add_tool',
                        label='Add Tool',
                        enabled_when='selected_page is not None'),
                '_',
                Item('name'),
                TButton('new_page',
                        label='New Page',
                        enabled_when="name.strip() != ''"),
                TButton('save_page',
                        label='Save Page',
                        enabled_when='selected_page is not None'),
                TButton('delete_page',
                        label='Delete Page',
                        enabled_when='selected_page is not None'),
            ),
            '_',
            VGroup(Item('pages',
                        style='custom',
                        editor=ListEditor(use_notebook=True,
                                          deletable=True,
                                          dock_style='tab',
                                          export='DockWindowShell',
                                          page_name='.name',
                                          selected='selected_page')),
                   show_labels=False)),
        title='Enthought Developer Tools: Traits UI Edition',
        id='etsdevtools.developer.tools.Tools',
        width=0.75,
        height=0.75,
        resizable=True,
        handler=ToolsHandler,
        key_bindings=pages_key_bindings)

    #-- Property Implementations -----------------------------------------------

    @cached_property
    def _get_tool_names(self):
        names = StdTools.keys()
        names.sort()

        return names

    def _get_can_start(self):
        return ((self.test_ui is None) or (self.test_ui.control is None))

    #-- Trait Event Handlers ---------------------------------------------------

    def _start_ui_changed(self):
        """ Handles the 'Start UI' button being clicked.
        """
        if self.create_as == 'Tab':
            if self.selected_page is None:
                self._create_new_page()
            self.selected_page.tools.append(self.test_object)
        else:
            parent = None
            if self.create_as == 'Child':
                parent = self.ui.control
            self.test_traits['parent'] = parent
            self.test_ui = self.test_object.edit_traits(
                *self.test_args, **self.test_traits)

    def _selected_tool_changed(self, tool):
        """ Handles the selected tool being changed.
        """
        self._add_selected_tool()

    def _add_tool_changed(self):
        """ Handles the 'Add Tool' button being clicked.
        """
        self._add_selected_tool()

    def _new_page_changed(self):
        """ Handles the 'New Page' button being clicked.
        """
        self._create_new_page()

    def _save_page_changed(self):
        """ Handles the 'Save Page' button being clicked.
        """
        print 'Not implemented yet'

    def _delete_page(self):
        """ Handles the 'Delete Page' button being clicked.
        """
        self.pages.remove(self.selected_page)

    def _name_changed(self, name):
        """ Handles the selected page name being changed.
        """
        if self.selected_page is not None:
            name = name.strip()
            if name != '':
                self.selected_page.name = name

    #-- Commands ---------------------------------------------------------------

    def _select_next_page(self, info=None):
        """ Selects the next page tab.
        """
        self._select_tab(1)

    def _select_previous_page(self, info=None):
        """ Selects the previous page tab.
        """
        self._select_tab(-1)

    def _enable_fbi(self, info=None):
        """ Enables the FBI debugger.
        """
        if not self.fbi_enabled:
            self.fbi_enabled = True

            from etsdevtools.developer.helper.fbi import use_fbi
            use_fbi()

            print 'FBI Enabled'

    #-- Private Methods --------------------------------------------------------

    def _select_tab(self, delta):
        """ Selects the next/previous tool tab.
        """
        pages = self.pages
        if len(pages) > 1:
            try:
                index = pages.index(self.selected_page) + delta
            except:
                index = 0

            self.selected_page = pages[index % len(pages)]

    def _create_new_page(self):
        """ Creates a new tools page.
        """
        page = ToolsPage(name=self.name)
        self.pages.append(page)
        self.selected_page = page

    def _add_selected_tool(self):
        """ Adds the currently selected tool as a new tool to the current page.
        """
        self.selected_page.tools.append(make_tool(self.selected_tool))
class LiveSearch(HasTraits):

    # The currenty root directory being searched:
    root = Directory(getcwd(), entries=10)

    # Should sub directories be included in the search:
    recursive = Bool(True)

    # The file types to include in the search:
    file_type = Enum('Python', 'C', 'C++', 'Java', 'Ruby')

    # The current search string:
    search = Str()

    # Is the search case sensitive?
    case_sensitive = Bool(False)

    # The live search table filter:
    filter = Property  # Instance( TableFilter )

    # The current list of source files being searched:
    source_files = Property  # List( SourceFile )

    # The currently selected source file:
    selected = Any  # Instance( SourceFile )

    # The contents of the currently selected source file:
    selected_contents = Property  # List( Str )

    # The currently selected match:
    selected_match = Int()

    # The text line corresponding to the selected match:
    selected_line = Property  # Int

    # The full name of the currently selected source file:
    selected_full_name = Property  # File

    # The list of marked lines for the currently selected file:
    mark_lines = Property  # List( Int )

    # Summary of current number of files and matches:
    summary = Property  # Str

    #-- Traits UI Views ------------------------------------------------------

    view = View(
        VGroup(
            HGroup(
                Item('root',
                     id='root',
                     label='Path',
                     width=0.5
                     ),
                Item('recursive'),
                Item('file_type', label='Type'),
                Item('search',
                     id='search',
                     width=0.5,
                     editor=HistoryEditor(auto_set=True)
                     ),
                Item('case_sensitive')
            ),
            VSplit(
                VGroup(
                    Item('summary',
                         editor=TitleEditor()
                         ),
                    Item('source_files',
                         id='source_files',
                         editor=table_editor
                         ),
                    dock='horizontal',
                    show_labels=False
                ),
                VGroup(
                    HGroup(
                        Item('selected_full_name',
                             editor=TitleEditor(),
                             springy=True
                             ),
                        Item('selected_full_name',
                             editor=DNDEditor(),
                             tooltip='Drag this file'
                             ),
                        show_labels=False
                    ),
                    Item('selected_contents',
                         style='readonly',
                         editor=CodeEditor(mark_lines='mark_lines',
                                           line='selected_line',
                                           selected_line='selected_line')
                         ),
                    dock='horizontal',
                    show_labels=False
                ),
                id='splitter'
            )
        ),
        title='Live File Search',
        id='enthought.examples.demo.Advanced.'
        'Table_editor_with_live_search_and_cell_editor.LiveSearch',
        width=0.75,
        height=0.67,
        resizable=True
    )

    #-- Property Implementations ---------------------------------------------

    @property_depends_on('search, case_sensitive')
    def _get_filter(self):
        if len(self.search) == 0:
            return lambda x: True

        return lambda x: len(x.matches) > 0

    @property_depends_on('root, recursive, file_type')
    def _get_source_files(self):
        root = self.root
        if root == '':
            root = getcwd()

        file_types = FileTypes[self.file_type]
        if self.recursive:
            result = []
            for dir_path, dir_names, file_names in walk(root):
                for file_name in file_names:
                    if splitext(file_name)[1] in file_types:
                        result.append(SourceFile(
                            live_search=self,
                            full_name=join(dir_path, file_name)))
            return result

        return [SourceFile(live_search=self,
                           full_name=join(root, file_name))
                for file_name in listdir(root)
                if splitext(file_name)[1] in file_types]

    @property_depends_on('selected')
    def _get_selected_contents(self):
        if self.selected is None:
            return ''

        return ''.join(self.selected.contents)

    @property_depends_on('selected')
    def _get_mark_lines(self):
        if self.selected is None:
            return []

        return [int(match.split(':', 1)[0])
                for match in self.selected.matches]

    @property_depends_on('selected, selected_match')
    def _get_selected_line(self):
        selected = self.selected
        if (selected is None) or (len(selected.matches) == 0):
            return 1

        return int(selected.matches[self.selected_match - 1
                                    ].split(':', 1)[0])

    @property_depends_on('selected')
    def _get_selected_full_name(self):
        if self.selected is None:
            return ''

        return self.selected.full_name

    @property_depends_on('source_files, search, case_sensitive')
    def _get_summary(self):
        source_files = self.source_files
        search = self.search
        if search == '':
            return 'A total of %d files.' % len(source_files)

        files = 0
        matches = 0
        for source_file in source_files:
            n = len(source_file.matches)
            if n > 0:
                files += 1
                matches += n

        return 'A total of %d files with %d files containing %d matches.' % (
               len(source_files), files, matches)

    #-- Traits Event Handlers ------------------------------------------------

    def _selected_changed(self):
        self.selected_match = 1

    def _source_files_changed(self):
        if len(self.source_files) > 0:
            self.selected = self.source_files[0]
        else:
            self.selected = None