Example #1
0
    def _resize_items(self):
        """ Size the splitter based on the 'width' or 'height' attributes
            of the Traits UI view elements.
        """
        use_widths = (self.orientation() == QtCore.Qt.Horizontal)

        # Get the requested size for the items.
        sizes = []
        for item in self._group.content:
            if use_widths:
                sizes.append(item.width)
            else:
                sizes.append(item.height)

        # Find out how much space is available.
        if use_widths:
            total = self.width()
        else:
            total = self.height()

        # Allocate requested space.
        avail = total
        remain = 0
        for i, sz in enumerate(sizes):
            if avail <= 0:
                break

            if sz >= 0:
                if sz >= 1:
                    sz = min(sz, avail)
                else:
                    sz *= total

                sz = int(sz)
                sizes[i] = sz
                avail -= sz
            else:
                remain += 1

        # Allocate the remainder to those parts that didn't request a width.
        if remain > 0:
            remain = int(avail / remain)

            for i, sz in enumerate(sizes):
                if sz < 0:
                    sizes[i] = remain

        # If all requested a width, allocate the remainder to the last item.
        else:
            sizes[-1] += avail

        self.setSizes(sizes)
Example #2
0
 def find ( self, name, stack = None ):
     """ Finds a specified ViewElement within the specified (optional) search
         context.
     """
     # Assume search starts from the beginning the of the search order:
     i = 0
     
     # If a stack was specified, see if there is a matching entry in the 
     # stack already:
     if stack is not None:
         for ssi in stack:
             if name == ssi.id:
                 # Match found, resume search at next ViewElements object
                 # in the search order:
                 i = ssi.context + 1
                 break
                 
     # Search for a matching name starting at the specified ViewElements
     # object in the search order:
     for j, ves in enumerate( self._get_search_order()[i:] ):
         result = ves.content.get( name )
         if result is not None:
             # Match found. If there is a stack, push matching name and
             # ViewElements context onto it:
             if stack is not None:
                 stack[0:0] = [ SearchStackItem( id      = name, 
                                                 context = i + j ) ]
                 
             # Return the ViewElement object that matched the name:
             return result
             
     # Indicate no match was found:
     return None
Example #3
0
def _fill_panel(panel, content, ui, item_handler=None):
    """Fill a page based container panel with content.
    """
    active = 0

    for index, item in enumerate(content):
        page_name = item.get_label(ui)
        if page_name == "":
           page_name = "Page %d" % index

        if isinstance(item, Group):
            if item.selected:
                active = index

            gp = _GroupPanel(item, ui, suppress_label=True)
            page = gp.control
            sub_page = gp.sub_control

            # If the result is the same type with only one page, collapse it
            # down into just the page.
            if type(sub_page) is type(panel) and sub_page.count() == 1:
                new = sub_page.widget(0)
                if isinstance(panel, QtGui.QTabWidget):
                    sub_page.removeTab(0)
                else:
                    sub_page.removeItem(0)
            elif isinstance(page, QtGui.QWidget):
                new = page
            else:
                new = QtGui.QWidget()
                new.setLayout(page)

            layout = new.layout()
            if layout is not None:
                layout.setAlignment(QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)

        else:
            new = QtGui.QWidget()
            layout = QtGui.QVBoxLayout(new)
            layout.setMargin(0)
            item_handler(item, layout)

        # Add the content.
        if isinstance(panel, QtGui.QTabWidget):
            panel.addTab(new, page_name)
        else:
            panel.addItem(new, page_name)

    panel.setCurrentIndex(active)
Example #4
0
 def merge_undo(self, undo_item):
     """ Merges two undo items if possible.
     """
     # Discard undo items that are identical to us. This is to eliminate
     # the same undo item being created by multiple listeners monitoring the
     # same list for changes:
     if (isinstance(undo_item, self.__class__)
             and (self.object is undo_item.object)
             and (self.name == undo_item.name)
             and (self.index == undo_item.index)):
         added = undo_item.added
         removed = undo_item.removed
         if ((len(self.added) == len(added))
                 and (len(self.removed) == len(removed))):
             for i, item in enumerate(self.added):
                 if item is not added[i]:
                     break
             else:
                 for i, item in enumerate(self.removed):
                     if item is not removed[i]:
                         break
                 else:
                     return True
     return False
Example #5
0
 def merge_undo ( self, undo_item ):
     """ Merges two undo items if possible.
     """
     # Discard undo items that are identical to us. This is to eliminate
     # the same undo item being created by multiple listeners monitoring the
     # same list for changes:
     if (isinstance( undo_item, self.__class__ )        and
        (self.object is undo_item.object)               and
        (self.name  == undo_item.name)                  and
        (self.index == undo_item.index)):
         added   = undo_item.added
         removed = undo_item.removed
         if ((len( self.added )   == len( added )) and
             (len( self.removed ) == len( removed ))):
             for i, item in enumerate( self.added ):
                 if item is not added[i]:
                     break
             else:
                 for i, item in enumerate( self.removed ):
                     if item is not removed[i]:
                         break
                 else:
                     return True
     return False
Example #6
0
    def replace_include ( self, view_elements ):
        """ Replaces any items that have an **id** attribute with an Include
        object with the same ID value, and puts the object with the ID
        into the specified ViewElements object.

        Parameters
        ----------
        view_elements : ViewElements object
            A set of Group, Item, and Include objects
        """
        for i, item in enumerate( self.content ):
            if item.is_includable():
                id = item.id
                if id in view_elements.content:
                    raise TraitError, \
                          "Duplicate definition for view element '%s'" % id
                self.content[ i ] = Include( id )
                view_elements.content[ id ] = item
            item.replace_include( view_elements )
Example #7
0
    def merge_undo(self, undo_item):
        """ Merges two undo items if possible.
        """
        # Undo items are potentially mergeable only if they are of the same
        # class and refer to the same object trait, so check that first:
        if (isinstance(undo_item, self.__class__)
                and (self.object is undo_item.object)
                and (self.name == undo_item.name)):
            v1 = self.new_value
            v2 = undo_item.new_value
            t1 = type(v1)
            if t1 is type(v2):

                if isinstance(t1, basestring):
                    # Merge two undo items if they have new values which are
                    # strings which only differ by one character (corresponding
                    # to a single character insertion, deletion or replacement
                    # operation in a text editor):
                    n1 = len(v1)
                    n2 = len(v2)
                    n = min(n1, n2)
                    i = 0
                    while (i < n) and (v1[i] == v2[i]):
                        i += 1
                    if v1[i + (n2 <= n1):] == v2[i + (n2 >= n1):]:
                        self.new_value = v2
                        return True

                elif isSequenceType(v1):
                    # Merge sequence types only if a single element has changed
                    # from the 'original' value, and the element type is a
                    # simple Python type:
                    v1 = self.old_value
                    if isSequenceType(v1):
                        # Note: wxColour says it's a sequence type, but it
                        # doesn't support 'len', so we handle the exception
                        # just in case other classes have similar behavior:
                        try:
                            if len(v1) == len(v2):
                                diffs = 0
                                for i, item in enumerate(v1):
                                    titem = type(item)
                                    item2 = v2[i]
                                    if ((titem not in SimpleTypes)
                                            or (titem is not type(item2))
                                            or (item != item2)):
                                        diffs += 1
                                        if diffs >= 2:
                                            return False
                                if diffs == 0:
                                    return False
                                self.new_value = v2
                                return True
                        except:
                            pass

                elif t1 in NumericTypes:
                    # Always merge simple numeric trait changes:
                    self.new_value = v2
                    return True
        return False
Example #8
0
    def merge_undo ( self, undo_item ):
        """ Merges two undo items if possible.
        """
        # Undo items are potentially mergeable only if they are of the same
        # class and refer to the same object trait, so check that first:
        if (isinstance( undo_item, self.__class__ ) and
           (self.object is undo_item.object) and
           (self.name == undo_item.name)):
            v1 = self.new_value
            v2 = undo_item.new_value
            t1 = type( v1 )
            if t1 is type( v2 ):

                if isinstance(t1, basestring):
                    # Merge two undo items if they have new values which are
                    # strings which only differ by one character (corresponding
                    # to a single character insertion, deletion or replacement
                    # operation in a text editor):
                    n1 = len( v1 )
                    n2 = len( v2 )
                    n  = min( n1, n2 )
                    i  = 0
                    while (i < n) and (v1[i] == v2[i]):
                        i += 1
                    if v1[i + (n2 <= n1):] == v2[i + (n2 >= n1):]:
                        self.new_value = v2
                        return True

                elif isSequenceType( v1 ):
                    # Merge sequence types only if a single element has changed
                    # from the 'original' value, and the element type is a
                    # simple Python type:
                    v1 = self.old_value
                    if isSequenceType( v1 ):
                        # Note: wxColour says it's a sequence type, but it
                        # doesn't support 'len', so we handle the exception
                        # just in case other classes have similar behavior:
                        try:
                            if len( v1 ) == len( v2 ):
                                diffs = 0
                                for i, item in enumerate( v1 ):
                                    titem = type( item )
                                    item2 = v2[i]
                                    if ((titem not in SimpleTypes)   or
                                        (titem is not type( item2 )) or
                                        (item != item2)):
                                        diffs += 1
                                        if diffs >= 2:
                                            return False
                                if diffs == 0:
                                    return False
                                self.new_value = v2
                                return True
                        except:
                            pass

                elif t1 in NumericTypes:
                    # Always merge simple numeric trait changes:
                    self.new_value = v2
                    return True
        return False