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)
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
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)
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
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
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 )
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
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