Exemple #1
0
class HistoryDemo(HasTraits):

    name = Str()
    file = File()
    directory = Directory()

    view = View(
        Item('name',
             id='name',
             editor=HistoryEditor(entries=5)
             ),
        Item('file',
             id='file1',
             editor=FileEditor(entries=10)
             ),
        Item('file',
             id='file2',
             editor=FileEditor(entries=10,
                               filter=['All files (*.*)|*.*',
                                       'Python files (*.py)|*.py'])
             ),
        Item('directory',
             id='directory',
             editor=DirectoryEditor(entries=10)
             ),
        title='History Editor Demo',
        id='enthought.test.history_demo.HistoryDemo',
        width=0.33,
        resizable=True
    )
Exemple #2
0
    def open_file_view(self):
        item = Item('file_name',
                    id='file_tree',
                    style='custom',
                    show_label=False,
                    width=0.5,
                    editor=DirectoryEditor(
                        filter=self.filter,
                        allow_dir=True,
                        reload_name='reload',
                        dclick_name='dclick',
                    ))
        width = height = 0.20

        if len(self.extensions) > 0:
            raise Exception('extensions are not supported')

        return View(VGroup(
            VGroup(item),
            HGroup(
                Item('create',
                     id='create',
                     show_label=False,
                     style='custom',
                     defined_when='is_save_file',
                     enabled_when='can_create_dir',
                     tooltip='Create a new directory'),
                Item('file_name',
                     id='history',
                     editor=HistoryEditor(entries=self.entries, auto_set=True),
                     springy=True),
                Item('ok',
                     id='ok',
                     show_label=False,
                     enabled_when='is_valid_file'),
                Item('cancel', show_label=False))),
                    title=self.title,
                    id=self.id,
                    kind='livemodal',
                    width=width,
                    height=height,
                    close_result=False,
                    resizable=True)
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
Exemple #4
0
    def open_file_view(self):
        """ Returns the file dialog view to use.
        """
        # Set up the default file dialog view and size information:
        item = Item('file_name',
                    id='file_tree',
                    style='custom',
                    show_label=False,
                    width=0.5,
                    editor=FileEditor(filter=self.filter,
                                      allow_dir=True,
                                      reload_name='reload',
                                      dclick_name='dclick'))
        width = height = 0.20

        # Check to see if we have any extensions being added:
        if len(self.extensions) > 0:

            # fixme: We should use the actual values of the view's Width and
            # height traits here to adjust the overall width and height...
            width *= 2.0

            # Assume we can used a fixed width Group:
            klass = HGroup

            # Set up to build a list of view Item objects:
            items = []

            # Add each extension to the dialog:
            for i, extension in enumerate(self.extensions):

                # Save the extension in a new trait (for use by the View):
                name = 'extension_%d' % i
                setattr(self, name, extension)

                extension_view = extension

                # Sync up the 'file_name' trait with the extension:
                self.sync_trait('file_name', extension, mutual=True)

                # Check to see if it also defines the optional IFileDialogView
                # interface, and if not, use the default view information:
                if not extension.has_traits_interface(IFileDialogView):
                    extension_view = default_view

                # Get the view that the extension wants to use:
                view = extension.trait_view(extension_view.view)

                # Determine if we should use a splitter for the dialog:
                if not extension_view.is_fixed:
                    klass = HSplit

                # Add the extension as a new view item:
                items.append(
                    Item(name,
                         label=user_name_for(extension.__class__.__name__),
                         show_label=False,
                         style='custom',
                         width=0.5,
                         height=0.5,
                         dock='horizontal',
                         resizable=True,
                         editor=InstanceEditor(view=view, id=name)))

            # Finally, combine the normal view element with the extensions:
            item = klass(item,
                         VSplit(id='splitter2', springy=True, *items),
                         id='splitter')
        # Return the resulting view:
        return View(VGroup(
            VGroup(item),
            HGroup(
                Item('create',
                     id='create',
                     show_label=False,
                     style='custom',
                     defined_when='is_save_file',
                     enabled_when='can_create_dir',
                     tooltip='Create a new directory'),
                Item('file_name',
                     id='history',
                     editor=HistoryEditor(entries=self.entries, auto_set=True),
                     springy=True),
                Item('ok',
                     id='ok',
                     show_label=False,
                     enabled_when='is_valid_file'),
                Item('cancel', show_label=False))),
                    title=self.title,
                    id=self.id,
                    kind='livemodal',
                    width=width,
                    height=height,
                    close_result=False,
                    resizable=True)
class HB_HeapBrowser ( HasPrivateTraits ):

    # The name of the plugin:
    name = Str( 'Heap Browser' )

    # The current heap statistics table entries:
    current_counts = List( HB_ClassCount )

    # The list of currently selected counts:
    selected_counts = List( HB_ClassCount )

    # The sting that all class names must contain:
    filter_name = Str( event = 'heap_updated' )

    # The threshold for the number of instances to display:
    filter_instances = Int( event = 'heap_updated' )

    # The threshold for the amount of change to display:
    filter_change = Int( event = 'heap_updated' )

    # Number of items in the current_counts list:
    current_classes = Property( depends_on = 'current_counts' )

    # Total number of instances in the current_counts list:
    current_instances = Property( depends_on = 'current_counts' )

    # Total change in the current_counts list:
    current_change = Property( depends_on = 'current_counts' )

    # Indicates whether or not the selection set is empty or not:
    has_counts = Property

    # The set of all current active object ids:
    current_ids = Any( set() )

    # Current heap statistics:
    current_heap = Any( {} )

    # Previous heap statistics:
    previous_heap = Any( {} )

    # Event fired when anything changes that affects the heap statistics view:
    heap_updated = Event

    # The list of object classes currently being ignored:
    ignored_classes = Any( set() )

    # The list of object classes currently being shown:
    shown_classes = Any( set() )

    # Refresh button:
    refresh = Button( 'Refresh' )

    # Baseline button (to create a new 'baseline' set):
    baseline = Button( 'Baseline' )

    # Hide all selected items button:
    hide_selected = Button( 'Hide Selected' )

    # Show only the selected items button:
    show_selected = Button( 'Show Selected' )

    # Show all items button:
    show_all = Button( 'Show All' )

    # Show the details of the current selected items button:
    show_details = Button( 'Show Details' )

    # Event fired when a 'counts' item is double-clicked:
    counts_dclick = Event

    #-- View 2 Traits ----------------------------------------------------------

    # The list of objects which the user has requested detailed information for:
    details = List( HB_Detail )

    #-- View 3 Traits ----------------------------------------------------------

    # The list of object referrer trees:
    referrers = List( HB_Referrers )

    #-- View 4 Traits ----------------------------------------------------------

    # The list of object baselines:
    baselines = List( HB_Baseline )

    #-- Traits View Definitions ------------------------------------------------

    heap_stats_view = View(
        VSplit(
            VGroup(
                HGroup(
                    Item( 'filter_name',
                          id     = 'filter_name',
                          label  = 'Name',
                          width  = -90,
                          editor = HistoryEditor( auto_set = True ),
                    ),
                    '_',
                    Item( 'filter_instances',
                          label = 'Min Instances',
                          width = -36
                    ),
                    '_',
                    Item( 'filter_change',
                          label = 'Min Change',
                          width = -36
                    ),
                    '_',
                    spring,
                    '_',
                    Item( 'current_classes',
                          label       = 'Classes',
                          style       = 'readonly',
                          format_func = commatize,
                          width       = -35
                    ),
                    '_',
                    Item( 'current_instances',
                          label       = 'Instances',
                          style       = 'readonly',
                          format_func = commatize,
                          width       = -50
                    ),
                    '_',
                    Item( 'current_change',
                          label       = 'Change',
                          style       = 'readonly',
                          format_func = commatize,
                          width       = -50
                    ),
                ),
                Item( 'current_counts',
                      id     = 'current_counts',
                      editor = counts_table_editor
                ),
                '_',
                HGroup(
                    Item( 'refresh',
                          tooltip = 'Refresh the heap statistics' ),
                    Item( 'baseline',
                          tooltip = 'Create a new baseline set' ),
                    spring,
                    Item( 'hide_selected',
                          tooltip = 'Remove all selected items from the view',
                          enabled_when = 'has_counts' ),
                    Item( 'show_selected',
                          tooltip = 'Show only the selected items in the view',
                          enabled_when = 'has_counts' ),
                    Item( 'show_all',
                          tooltip = 'Show all items again',
                          enabled_when = '(len( ignored_classes ) > 0) '
                                      'or (len( shown_classes ) > 0)' ),
                    '_',
                    Item( 'show_details',
                          tooltip = 'Show the instances of the selected '
                                    'classes',
                          enabled_when = 'has_counts' ),
                    show_labels = False,
                ),
                label       = 'Heap',
                show_labels = False,
                dock        = 'tab'
            ),
            Item( 'details',
                  id     = 'details',
                  style  = 'custom',
                  dock   = 'tab',
                  editor = ListEditor( use_notebook = True,
                                       deletable    = True,
                                       dock_style   = 'tab',
                                       export       = 'DockWindowShell',
                                       page_name    = '.short_name' )
            ),
            Item( 'referrers',
                  id     = 'referrers',
                  style  = 'custom',
                  dock   = 'tab',
                  editor = ListEditor( use_notebook = True,
                                       deletable    = True,
                                       dock_style   = 'tab',
                                       export       = 'DockWindowShell',
                                       page_name    = '.name' )
            ),
            Item( 'baselines',
                  id     = 'baselines',
                  style  = 'custom',
                  dock   = 'tab',
                  editor = ListEditor( use_notebook = True,
                                       deletable    = True,
                                       dock_style   = 'tab',
                                       export       = 'DockWindowShell',
                                       page_name    = 'Baseline' )
            ),
            id          = 'splitter',
            show_labels = False
        ),
        title        = 'Heap Browser',
        id           = 'etsdevtools.developer.tools.heap_browser.HB_HeapBrowser',
        width        = 0.5,
        height       = 0.75,
        resizable    = True,
        key_bindings = heap_browser_key_bindings
    )

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

    def _get_has_counts ( self ):
        return (len( self.selected_counts ) > 0)

    def _get_current_classes ( self ):
        return len( self.current_counts )

    @cached_property
    def _get_current_instances ( self ):
        return reduce( lambda l, r: l + r.instances, self.current_counts, 0 )

    @cached_property
    def _get_current_change ( self ):
        return reduce( lambda l, r: l + r.change, self.current_counts, 0 )

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

    def _heap_updated_changed ( self ):
        """ Handles the 'heap_updated' event being fired by rebuilding the
            heap class counts list.
        """
        ignored = ignored_classes
        shown   = self.shown_classes
        no_show = (len( shown ) == 0)
        if no_show:
            ignored = ignored_classes.union( self.ignored_classes )

        old              = self.previous_heap
        filter_name      = self.filter_name.lower()
        filter_instances = self.filter_instances
        filter_change    = self.filter_change
        counts = [ HB_ClassCount( name      = name,
                                  instances = instances,
                                  change    = instances - old.get( name, 0 ) )
                   for name, instances in self.current_heap.iteritems()
                   if (name not in ignored)                   and
                      (no_show or (name in shown))            and
                      (name.lower().find( filter_name ) >= 0) and
                      (instances >= filter_instances)         and
                      (abs( instances - old.get( name, 0 ) ) >= filter_change)
        ]
        counts.sort( lambda l, r: cmp( l.lower_name, r.lower_name ) )
        self.current_counts = counts

    def _refresh_changed ( self, ignore = None ):
        """ Handles the 'Refresh' button being clicked.
        """
        self.update()

    def _baseline_changed ( self, ignore = None ):
        """ Handles the 'Baseline' button being clicked.
        """
        self.baselines.append( self._create_baseline() )

    def _hide_selected_changed ( self, info = None ):
        """ Handles the 'Hide Selected' button being clicked.
        """
        self.ignored_classes.update(
            set( [ item.name for item in self.selected_counts ] )
        )
        self.shown_classes.clear()
        del self.selected_counts[:]
        self.heap_updated = True

    def _show_selected_changed ( self, info = None ):
        """ Handles the 'Show Selected' button being clicked.
        """
        self.shown_classes = set(
            set( [ item.name for item in self.selected_counts ] )
        )
        self.ignored_classes.clear()
        del self.selected_counts[:]
        self.heap_updated = True

    def _show_all_changed ( self, info = None ):
        """ Handles the 'Show All' button being clicked.
        """
        self.ignored_classes.clear()
        self.shown_classes.clear()
        del self.selected_counts[:]
        self.heap_updated = True

    def _show_details_changed ( self, ignore = True ):
        """ Handles the 'Show Details' button being clicked.
        """
        self.details.extend( [ HB_Detail( name = item.name, owner = self )
                               for item in self.selected_counts ] )

    def _counts_dclick_changed ( self, event ):
        """ Handles the user double-clicking a 'counts' table entry in order
            to show its details.
        """
        item, column = event
        self.details.append( HB_Detail( name = item.name, owner = self ) )

    def _set_filter_change_1 ( self, info = None ):
        """ Sets the filter change value to 1.
        """
        self.filter_change = 1

    def _clear_filter ( self, info = None ):
        """ Clears all current filter variable settings back to their defaults.
        """
        self.filter_change = filter_instances = 0
        self.filter_name   = ''

    def _select_all ( self, info = None ):
        """ Selects all current displayed items.
        """
        self.selected_counts = self.current_counts

    def _unselect_all ( self, info = None ):
        """ Unselects all currently selected items.
        """
        self.selected_counts = []

    #-- Public Methods ---------------------------------------------------------

    def update ( self ):
        """ Updates the heap statistics.
        """
        self.previous_heap = old = self.current_heap
        self.current_heap  = new = {}
        self.current_ids   = ids = set()

        gc.collect()

        for object in gc.get_objects():
            name = object_name( object )
            if name not in ignored_classes:
                new[ name ] = new.setdefault( name, 0 ) + 1
                ids.add( id( object ) )

        self.heap_updated = True

        # Indicate that each class detail should update its instance
        # information:
        for detail in self.details:
            detail.update = True

        # Indicate that each referrer should update its instance information:
        for referrer in self.referrers:
            referrer.root.update = True

        # Indicate that each baseline view should update its contents:
        for baseline in self.baselines:
            baseline.update = ids

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

    def _create_baseline ( self ):
        """ Creates a new baseline object.
        """
        current_ids = self.current_ids
        object_ids  = {}

        gc.collect()

        for object in gc.get_objects():
            if id( object ) not in current_ids:
                name = object_name( object )
                if name not in ignored_classes:
                    object_ids[ id( object ) ] = name

        return HB_Baseline( object_ids = object_ids, owner = self )