예제 #1
0
    def setParent(self, itemId, newParentId):
        """Sets the parent of an Item. The new parent item must exist and be
        able to have children. (C{canHaveChildren(newParentId) == True}). It
        is also possible to detach a node from the hierarchy (and thus make
        it root) by setting the parent C{None}.

        @param itemId:
                   the ID of the item to be set as the child of the Item
                   identified with newParentId.
        @param newParentId:
                   the ID of the Item that's to be the new parent of the Item
                   identified with itemId.
        @return: C{True} if the operation succeeded, C{False} if not
        """
        # Checks that the item is in the container
        if not self.containsId(itemId):
            return False

        # Gets the old parent
        oldParentId = self._parent.get(itemId)

        # Checks if no change is necessary
        if ((newParentId is None and oldParentId is None)
                or (newParentId is not None)
                and (newParentId == oldParentId)):
            return True

        # Making root?
        if newParentId is None:
            # The itemId should become a root so we need to
            # - Remove it from the old parent's children list
            # - Add it as a root
            # - Remove it from the item -> parent list (parent is null for
            # roots)

            # Removes from old parents children list
            l = self._children.get(oldParentId)
            if l is not None:
                l.remove(itemId)
                if len(l) > 0:
                    del self._children[oldParentId]

            # Add to be a root
            self._roots.append(itemId)

            # Updates parent
            del self._parent[itemId]

            if self.hasFilters():
                # Refilter the container if setParent is called when filters
                # are applied. Changing parent can change what is included in
                # the filtered version (if includeParentsWhenFiltering==true).
                self.doFilterContainer(self.hasFilters())

            self.fireItemSetChange()

            return True

        # We get here when the item should not become a root and we need to
        # - Verify the new parent exists and can have children
        # - Check that the new parent is not a child of the selected itemId
        # - Updated the item -> parent mapping to point to the new parent
        # - Remove the item from the roots list if it was a root
        # - Remove the item from the old parent's children list if it was not a
        # root

        # Checks that the new parent exists in container and can have
        # children
        if ((not self.containsId(newParentId))
                or (newParentId in self._noChildrenAllowed)):
            return False

        # Checks that setting parent doesn't result to a loop
        o = newParentId
        while o is not None and not (o == itemId):
            o = self._parent.get(o)

        if o is not None:
            return False

        # Updates parent
        self._parent[itemId] = newParentId
        pcl = self._children.get(newParentId)
        if pcl is None:
            # Create an empty list for holding children if one were not
            # previously created
            pcl = list()
            self._children[newParentId] = pcl
        pcl.append(itemId)

        # Removes from old parent or root
        if oldParentId is None:
            self._roots.remove(itemId)
        else:
            l = self._children.get(oldParentId)
            if l is not None:
                l.remove(itemId)
                if len(l) == 0:
                    del self._children[oldParentId]

        if self.hasFilters():
            # Refilter the container if setParent is called when filters
            # are applied. Changing parent can change what is included in
            # the filtered version (if includeParentsWhenFiltering==true).
            self.doFilterContainer(self.hasFilters())

        AbstractContainer.fireItemSetChange(self)

        return True
예제 #2
0
 def fireItemAdded(self, position, itemId, item):
     if position >= 0:
         event = ItemSetChangeEvent(self, position)
         AbstractContainer.fireItemSetChange(self, event)
예제 #3
0
 def fireItemAdded(self, position, itemId, item):
     if position >= 0:
         AbstractContainer.fireItemSetChange(self,
                 ItemSetChangeEvent(self, position))