Exemplo n.º 1
0
    def __init__(self):
        """Creates an AbsoluteLayout with full size."""
        super(AbsoluteLayout, self).__init__()

        #: The components in the layout
        self._components = OrderedSet()

        #: Maps each component to a position
        self._componentToCoordinates = dict()

        self.setSizeFull()
Exemplo n.º 2
0
    def addListener(self, eventType, obj, method, arguments=None,
                eventArgIdx=None):
        # Registers a new listener with the specified activation method
        # to listen events generated by this component.

        if self._listenerList is None:
            self._listenerList = OrderedSet()

        lm = ListenerMethod(eventType, obj, method, arguments, eventArgIdx)

        self._listenerList.add(lm)
    def updateHierarchicalWrapper(self):
        """Updates the wrapper's internal hierarchy data to include all Items
        in the underlying container. If the contents of the wrapped container
        change without the wrapper's knowledge, this method needs to be called
        to update the hierarchy information of the Items.
        """
        if not self._hierarchical:

            # Recreate hierarchy and data structures if missing
            if (self._noChildrenAllowed is None or self._parent is None
                    or self._children is None or self._roots is None):
                # Check that the hierarchy is up-to-date
                self._noChildrenAllowed = set()
                self._parent = dict()
                self._children = dict()
                self._roots = OrderedSet(self._container.getItemIds())

            else:

                # ensure order of root and child lists is same as in wrapped
                # container
                itemIds = self._container.getItemIds()
                basedOnOrderFromWrappedContainer = \
                        ListedItemsFirstComparator(itemIds)

                # Calculate the set of all items in the hierarchy
                s = set()
                s = s.union(self._parent.keys())
                s = s.union(self._children.keys())
                s = s.union(self._roots)

                # Remove unnecessary items
                for idd in s:
                    if not self._container.containsId(idd):
                        self.removeFromHierarchyWrapper(idd)

                # Add all the missing items
                ids = self._container.getItemIds()
                for idd in ids:
                    if not (idd in s):
                        self.addToHierarchyWrapper(idd)
                        s.add(idd)

                arry = list(self._roots)
                arry.sort(cmp=basedOnOrderFromWrappedContainer)
                self._roots = OrderedSet()
                for a in arry:
                    self._roots.add(a)

                for obj in self._children.keys():
                    object2 = self._children[obj]
                    object2.sort(cmp=basedOnOrderFromWrappedContainer)
    def updateHierarchicalWrapper(self):
        """Updates the wrapper's internal hierarchy data to include all Items
        in the underlying container. If the contents of the wrapped container
        change without the wrapper's knowledge, this method needs to be called
        to update the hierarchy information of the Items.
        """
        if not self._hierarchical:

            # Recreate hierarchy and data structures if missing
            if (self._noChildrenAllowed is None or self._parent is None
                    or self._children is None or self._roots is None):
                # Check that the hierarchy is up-to-date
                self._noChildrenAllowed = set()
                self._parent = dict()
                self._children = dict()
                self._roots = OrderedSet(self._container.getItemIds())

            else:

                # ensure order of root and child lists is same as in wrapped
                # container
                itemIds = self._container.getItemIds()
                basedOnOrderFromWrappedContainer = \
                        ListedItemsFirstComparator(itemIds)

                # Calculate the set of all items in the hierarchy
                s = set()
                s = s.union(self._parent.keys())
                s = s.union(self._children.keys())
                s = s.union(self._roots)

                # Remove unnecessary items
                for idd in s:
                    if not self._container.containsId(idd):
                        self.removeFromHierarchyWrapper(idd)

                # Add all the missing items
                ids = self._container.getItemIds()
                for idd in ids:
                    if not (idd in s):
                        self.addToHierarchyWrapper(idd)
                        s.add(idd)

                arry = list(self._roots)
                arry.sort(cmp=basedOnOrderFromWrappedContainer)
                self._roots = OrderedSet()
                for a in arry:
                    self._roots.add(a)

                for obj in self._children.keys():
                    object2 = self._children[obj]
                    object2.sort(cmp=basedOnOrderFromWrappedContainer)
Exemplo n.º 5
0
    def __init__(self, caption=None, uploadReceiver=None):
        """Creates a new instance of Upload.

        The receiver must be set before performing an upload.
        """
        super(Upload, self).__init__()

        #: Should the field be focused on next repaint?
        self._focus = False

        #: The tab order number of this field.
        self._tabIndex = 0

        #: The output of the upload is redirected to this receiver.
        self._receiver = None

        self._isUploading = False

        self._contentLength = -1

        self._totalBytes = None

        self._buttonCaption = 'Upload'

        #: ProgressListeners to which information about progress
        #  is sent during upload
        self._progressListeners = OrderedSet()

        self._progressCallbacks = dict()

        self._interrupted = False

        self._notStarted = None

        self._nextid = 0

        #: Flag to indicate that submitting file has been requested.
        self._forceSubmit = None

        if caption:
            self.setCaption(caption)

        if uploadReceiver is not None:
            self._receiver = uploadReceiver

        self._streamVariable = None
    def __init__(self, toBeWrapped):
        """Constructs a new hierarchical wrapper for an existing Container.
        Works even if the to-be-wrapped container already implements the
        C{IHierarchical} interface.

        @param toBeWrapped:
                   the container that needs to be accessed hierarchically
        @see: L{updateHierarchicalWrapper}
        """
        super(ContainerHierarchicalWrapper, self).__init__()

        #: The wrapped container
        self._container = None

        #: Set of IDs of those contained Items that can't have children.
        self._noChildrenAllowed = None

        #: Mapping from Item ID to parent Item ID
        self._parent = None

        #: Mapping from Item ID to a list of child IDs
        self._children = None

        #: List that contains all root elements of the container.
        self._roots = None

        #: Is the wrapped container hierarchical by itself ?
        self._hierarchical = None

        self._container = toBeWrapped
        self._hierarchical = isinstance(self._container, IHierarchical)

        # Check arguments
        if self._container is None:
            raise ValueError, 'Null can not be wrapped'

        # Create initial order if needed
        if not self._hierarchical:
            self._noChildrenAllowed = OrderedSet()
            self._parent = dict()
            self._children = dict()
            self._roots = set(self._container.getItemIds())

        self.updateHierarchicalWrapper()
Exemplo n.º 7
0
    def __init__(self):
        """Creates an AbsoluteLayout with full size."""
        super(AbsoluteLayout, self).__init__()

        #: The components in the layout
        self._components = OrderedSet()

        #: Maps each component to a position
        self._componentToCoordinates = dict()

        self.setSizeFull()
Exemplo n.º 8
0
    def doFilterContainer(self, hasFilters):
        if not hasFilters:
            # All filters removed
            self._filteredRoots = None
            self._filteredChildren = None
            self._filteredParent = None

            return super(HierarchicalContainer,
                         self).doFilterContainer(hasFilters)

        # Reset data structures
        self._filteredRoots = list()
        self._filteredChildren = dict()
        self._filteredParent = dict()

        if self._includeParentsWhenFiltering:
            # Filter so that parents for items that match the filter are also
            # included
            includedItems = set()
            for rootId in self._roots:
                if self.filterIncludingParents(rootId, includedItems):
                    self._filteredRoots.append(rootId)
                    self.addFilteredChildrenRecursively(rootId, includedItems)

            # includedItemIds now contains all the item ids that should be
            # included. Filter IndexedContainer based on this
            self._filterOverride = includedItems
            super(HierarchicalContainer, self).doFilterContainer(hasFilters)
            self._filterOverride = None

            return True
        else:
            # Filter by including all items that pass the filter and make items
            # with no parent new root items

            # Filter IndexedContainer first so getItemIds return the items that
            # match
            super(HierarchicalContainer, self).doFilterContainer(hasFilters)

            filteredItemIds = OrderedSet(self.getItemIds())
            for itemId in filteredItemIds:
                itemParent = self._parent.get(itemId)
                if (itemParent is None or itemParent not in filteredItemIds):
                    # Parent is not included or this was a root, in both cases
                    # this should be a filtered root
                    self._filteredRoots.append(itemId)
                else:
                    # Parent is included. Add this to the children list (create
                    # it first if necessary)
                    self.addFilteredChild(itemParent, itemId)

            return True
Exemplo n.º 9
0
 def getPoints(cls, series, values):
     if len(values) > 0 and isinstance(values[0], (float, int)):
         points = OrderedSet()
         for value in values:
             points.add(DecimalPoint(series, value))
         return points
     else:
         points = OrderedSet()
         for value in values:
             y = None
             if len(value) == 0:
                 continue
             if len(value) == 2:
                 x = value[0]
                 y = value[1]
             else:
                 x = value[0]
             points.add(DecimalPoint(series, x, y))
         return points
    def __init__(self, toBeWrapped):
        """Constructs a new hierarchical wrapper for an existing Container.
        Works even if the to-be-wrapped container already implements the
        C{IHierarchical} interface.

        @param toBeWrapped:
                   the container that needs to be accessed hierarchically
        @see: L{updateHierarchicalWrapper}
        """
        super(ContainerHierarchicalWrapper, self).__init__()

        #: The wrapped container
        self._container = None

        #: Set of IDs of those contained Items that can't have children.
        self._noChildrenAllowed = None

        #: Mapping from Item ID to parent Item ID
        self._parent = None

        #: Mapping from Item ID to a list of child IDs
        self._children = None

        #: List that contains all root elements of the container.
        self._roots = None

        #: Is the wrapped container hierarchical by itself ?
        self._hierarchical = None

        self._container = toBeWrapped
        self._hierarchical = isinstance(self._container, IHierarchical)

        # Check arguments
        if self._container is None:
            raise ValueError, 'Null can not be wrapped'

        # Create initial order if needed
        if not self._hierarchical:
            self._noChildrenAllowed = OrderedSet()
            self._parent = dict()
            self._children = dict()
            self._roots = set(self._container.getItemIds())

        self.updateHierarchicalWrapper()
Exemplo n.º 11
0
 def getPoints(cls, series, values):
     if len(values) > 0 and isinstance(values[0], (float, int)):
         points = OrderedSet()
         for value in values:
             points.add(DecimalPoint(series, value))
         return points
     else:
         points = OrderedSet()
         for value in values:
             y = None
             if len(value) == 0:
                 continue
             if len(value) == 2:
                 x = value[0]
                 y = value[1]
             else:
                 x = value[0]
             points.add(DecimalPoint(series, x, y))
         return points
Exemplo n.º 12
0
class AbsoluteLayout(AbstractLayout, ILayoutClickNotifier):
    """AbsoluteLayout is a layout implementation that mimics html
    absolute positioning.
    """

    CLIENT_WIDGET = None #ClientWidget(VAbsoluteLayout)

    _CLICK_EVENT = EventId.LAYOUT_CLICK

    def __init__(self):
        """Creates an AbsoluteLayout with full size."""
        super(AbsoluteLayout, self).__init__()

        #: The components in the layout
        self._components = OrderedSet()

        #: Maps each component to a position
        self._componentToCoordinates = dict()

        self.setSizeFull()


    def getComponentIterator(self):
        """Gets an iterator for going through all components enclosed
        in the absolute layout.
        """
        return iter(self._components)


    def getComponentCount(self):
        """Gets the number of contained components. Consistent with
        the iterator returned by L{getComponentIterator}.

        @return: the number of contained components
        """
        return len(self._components)


    def replaceComponent(self, oldComponent, newComponent):
        """Replaces one component with another one. The new component
        inherits the old components position.
        """
        position = self.getPosition(oldComponent)
        self.removeComponent(oldComponent)
        self.addComponent(newComponent)
        self._componentToCoordinates[newComponent] = position


    def addComponent(self, c, cssPosition=None):
        """Adds a component to the layout. The component can be positioned
        by providing a string formatted in CSS-format.

        For example the string "top:10px;left:10px" will position the
        component 10 pixels from the left and 10 pixels from the top. The
        identifiers: "top","left","right" and "bottom" can be used to
        specify the position.

        @param c:
                   The component to add to the layout
        @param cssPosition:
                   The css position string
        """
        # Create position instance and add it to componentToCoordinates
        # map. We need to do this before we call addComponent so the
        # attachListeners can access this position. #6368
        if cssPosition is not None:
            position = ComponentPosition(self)
            position.setCSSString(cssPosition)
            self._componentToCoordinates[c] = position

        self._components.add(c)
        try:
            super(AbsoluteLayout, self).addComponent(c)
            self.requestRepaint()
        except ValueError, e:
            self._components.remove(c)
            if cssPosition is not None:
                # Remove component coordinates if adding fails
                del self._componentToCoordinates[c]
                raise e
Exemplo n.º 13
0
    def paintContent(self, target):
        """Paints any needed component-specific things to the given UIDL
        stream.

        @see: L{AbstractComponent.paintContent}
        """
        self._initialPaint = False

        if self._partialUpdate:
            target.addAttribute('partialUpdate', True)
            target.addAttribute('rootKey',
                                self.itemIdMapper.key(self._expandedItemId))
        else:
            self.getCaptionChangeListener().clear()

            # The tab ordering number
            if self.getTabIndex() > 0:
                target.addAttribute('tabindex', self.getTabIndex())

            # Paint tree attributes
            if self.isSelectable():
                if self.isMultiSelect():
                    target.addAttribute('selectmode', 'multi')
                else:
                    target.addAttribute('selectmode', 'single')

                if self.isMultiSelect():
                    try:
                        idx = MultiSelectMode.values().index(
                            self._multiSelectMode)
                    except ValueError:
                        idx = -1
                    target.addAttribute('multiselectmode', idx)
            else:
                target.addAttribute('selectmode', 'none')

            if self.isNewItemsAllowed():
                target.addAttribute('allownewitem', True)

            if self.isNullSelectionAllowed():
                target.addAttribute('nullselect', True)

            if self._dragMode != TreeDragMode.NONE:
                target.addAttribute('dragMode',
                                    TreeDragMode.ordinal(self._dragMode))

        # Initialize variables
        actionSet = OrderedSet()

        # rendered selectedKeys
        selectedKeys = list()
        expandedKeys = list()

        # Iterates through hierarchical tree using a stack of iterators
        iteratorStack = deque()
        if self._partialUpdate:
            ids = self.getChildren(self._expandedItemId)
        else:
            ids = self.rootItemIds()

        if ids is not None:
            iteratorStack.append(iter(ids))

        # Body actions - Actions which has the target null and can be invoked
        # by right clicking on the Tree body
        if self._actionHandlers is not None:
            keys = list()
            for ah in self._actionHandlers:

                # Getting action for the null item, which in this case
                # means the body item
                aa = ah.getActions(None, self)
                if aa is not None:
                    for ai in range(len(aa)):
                        akey = self._actionMapper.key(aa[ai])
                        actionSet.add(aa[ai])
                        keys.append(akey)

            target.addAttribute('alb', keys)

        while len(iteratorStack) > 0:

            # Gets the iterator for current tree level
            i = iteratorStack[-1]  # peek

            try:
                # Adds the item on current level
                itemId = i.next()

                # Starts the item / node
                isNode = self.areChildrenAllowed(itemId)
                if isNode:
                    target.startTag('node')
                else:
                    target.startTag('leaf')

                if self._itemStyleGenerator is not None:
                    stylename = self._itemStyleGenerator.getStyle(itemId)
                    if stylename is not None:
                        target.addAttribute('style', stylename)

                if self._itemDescriptionGenerator is not None:
                    description = self._itemDescriptionGenerator\
                            .generateDescription(self, itemId, None)
                    if description is not None and description != "":
                        target.addAttribute("descr", description)

                # Adds the attributes
                target.addAttribute('caption', self.getItemCaption(itemId))
                icon = self.getItemIcon(itemId)
                if icon is not None:
                    target.addAttribute('icon', self.getItemIcon(itemId))

                key = self.itemIdMapper.key(itemId)
                target.addAttribute('key', key)
                if self.isSelected(itemId):
                    target.addAttribute('selected', True)
                    selectedKeys.append(key)

                if self.areChildrenAllowed(itemId) and self.isExpanded(itemId):
                    target.addAttribute('expanded', True)
                    expandedKeys.append(key)

                # Add caption change listener
                self.getCaptionChangeListener().addNotifierForItem(itemId)

                # Actions
                if self._actionHandlers is not None:
                    keys = list()
                    ahi = iter(self._actionHandlers)
                    while True:
                        try:
                            aa = ahi.next().getActions(itemId, self)
                            if aa is not None:
                                for ai in range(len(aa)):
                                    akey = self._actionMapper.key(aa[ai])
                                    actionSet.add(aa[ai])
                                    keys.append(akey)
                        except StopIteration:
                            break
                    target.addAttribute('al', keys)

                # Adds the children if expanded, or close the tag
                if (self.isExpanded(itemId) and self.hasChildren(itemId)
                        and self.areChildrenAllowed(itemId)):
                    iteratorStack.append(iter(self.getChildren(itemId)))
                elif isNode:
                    target.endTag('node')
                else:
                    target.endTag('leaf')

            # If the level is finished, back to previous tree level
            except StopIteration:
                # Removes used iterator from the stack
                iteratorStack.pop()

                # Closes node
                if len(iteratorStack) > 0:
                    target.endTag('node')

        # Actions
        if len(actionSet) > 0:
            target.addVariable(self, 'action', '')
            target.startTag('actions')
            i = actionSet
            for a in actionSet:
                target.startTag('action')
                if a.getCaption() is not None:
                    target.addAttribute('caption', a.getCaption())

                if a.getIcon() is not None:
                    target.addAttribute('icon', a.getIcon())

                target.addAttribute('key', self._actionMapper.key(a))
                target.endTag('action')

            target.endTag('actions')

        if self._partialUpdate:
            self._partialUpdate = False
        else:
            # Selected
            target.addVariable(self, 'selected', selectedKeys)

            # Expand and collapse
            target.addVariable(self, 'expand', list())
            target.addVariable(self, 'collapse', list())

            # New items
            target.addVariable(self, 'newitem', list())

            if self._dropHandler is not None:
                self._dropHandler.getAcceptCriterion().paint(target)
Exemplo n.º 14
0
    def paintContent(self, target):
        """Paints any needed component-specific things to the given UIDL
        stream.

        @see: L{AbstractComponent.paintContent}
        """
        self._initialPaint = False

        if self._partialUpdate:
            target.addAttribute('partialUpdate', True)
            target.addAttribute('rootKey',
                    self.itemIdMapper.key(self._expandedItemId))
        else:
            self.getCaptionChangeListener().clear()

            # The tab ordering number
            if self.getTabIndex() > 0:
                target.addAttribute('tabindex', self.getTabIndex())

            # Paint tree attributes
            if self.isSelectable():
                if self.isMultiSelect():
                    target.addAttribute('selectmode', 'multi')
                else:
                    target.addAttribute('selectmode', 'single')

                if self.isMultiSelect():
                    try:
                        idx = MultiSelectMode.values().index(
                                self._multiSelectMode)
                    except ValueError:
                        idx = -1
                    target.addAttribute('multiselectmode', idx)
            else:
                target.addAttribute('selectmode', 'none')

            if self.isNewItemsAllowed():
                target.addAttribute('allownewitem', True)

            if self.isNullSelectionAllowed():
                target.addAttribute('nullselect', True)

            if self._dragMode != TreeDragMode.NONE:
                target.addAttribute('dragMode',
                        TreeDragMode.ordinal(self._dragMode))

        # Initialize variables
        actionSet = OrderedSet()

        # rendered selectedKeys
        selectedKeys = list()
        expandedKeys = list()

        # Iterates through hierarchical tree using a stack of iterators
        iteratorStack = deque()
        if self._partialUpdate:
            ids = self.getChildren(self._expandedItemId)
        else:
            ids = self.rootItemIds()

        if ids is not None:
            iteratorStack.append( iter(ids) )

        # Body actions - Actions which has the target null and can be invoked
        # by right clicking on the Tree body
        if self._actionHandlers is not None:
            keys = list()
            for ah in self._actionHandlers:

                # Getting action for the null item, which in this case
                # means the body item
                aa = ah.getActions(None, self)
                if aa is not None:
                    for ai in range(len(aa)):
                        akey = self._actionMapper.key(aa[ai])
                        actionSet.add(aa[ai])
                        keys.append(akey)

            target.addAttribute('alb', keys)

        while len(iteratorStack) > 0:

            # Gets the iterator for current tree level
            i = iteratorStack[-1]  # peek

            try:
                # Adds the item on current level
                itemId = i.next()

                # Starts the item / node
                isNode = self.areChildrenAllowed(itemId)
                if isNode:
                    target.startTag('node')
                else:
                    target.startTag('leaf')

                if self._itemStyleGenerator is not None:
                    stylename = self._itemStyleGenerator.getStyle(itemId)
                    if stylename is not None:
                        target.addAttribute('style', stylename)

                if self._itemDescriptionGenerator is not None:
                    description = self._itemDescriptionGenerator\
                            .generateDescription(self, itemId, None)
                    if description is not None and description != "":
                        target.addAttribute("descr", description)

                # Adds the attributes
                target.addAttribute('caption', self.getItemCaption(itemId))
                icon = self.getItemIcon(itemId)
                if icon is not None:
                    target.addAttribute('icon', self.getItemIcon(itemId))

                key = self.itemIdMapper.key(itemId)
                target.addAttribute('key', key)
                if self.isSelected(itemId):
                    target.addAttribute('selected', True)
                    selectedKeys.append(key)

                if self.areChildrenAllowed(itemId) and self.isExpanded(itemId):
                    target.addAttribute('expanded', True)
                    expandedKeys.append(key)

                # Add caption change listener
                self.getCaptionChangeListener().addNotifierForItem(itemId)

                # Actions
                if self._actionHandlers is not None:
                    keys = list()
                    ahi = iter(self._actionHandlers)
                    while True:
                        try:
                            aa = ahi.next().getActions(itemId, self)
                            if aa is not None:
                                for ai in range(len(aa)):
                                    akey = self._actionMapper.key(aa[ai])
                                    actionSet.add(aa[ai])
                                    keys.append(akey)
                        except StopIteration:
                            break
                    target.addAttribute('al', keys)

                # Adds the children if expanded, or close the tag
                if (self.isExpanded(itemId)
                        and self.hasChildren(itemId)
                        and self.areChildrenAllowed(itemId)):
                    iteratorStack.append( iter(self.getChildren(itemId)) )
                elif isNode:
                    target.endTag('node')
                else:
                    target.endTag('leaf')

            # If the level is finished, back to previous tree level
            except StopIteration:
                # Removes used iterator from the stack
                iteratorStack.pop()

                # Closes node
                if len(iteratorStack) > 0:
                    target.endTag('node')

        # Actions
        if len(actionSet) > 0:
            target.addVariable(self, 'action', '')
            target.startTag('actions')
            i = actionSet
            for a in actionSet:
                target.startTag('action')
                if a.getCaption() is not None:
                    target.addAttribute('caption', a.getCaption())

                if a.getIcon() is not None:
                    target.addAttribute('icon', a.getIcon())

                target.addAttribute('key', self._actionMapper.key(a))
                target.endTag('action')

            target.endTag('actions')

        if self._partialUpdate:
            self._partialUpdate = False
        else:
            # Selected
            target.addVariable(self, 'selected', selectedKeys)

            # Expand and collapse
            target.addVariable(self, 'expand', list())
            target.addVariable(self, 'collapse', list())

            # New items
            target.addVariable(self, 'newitem', list())

            if self._dropHandler is not None:
                self._dropHandler.getAcceptCriterion().paint(target)
class ContainerHierarchicalWrapper(IHierarchical, IContainer,
                                   IItemSetChangeNotifier,
                                   IPropertySetChangeNotifier):
    """A wrapper class for adding external hierarchy to containers not
    implementing the L{IHierarchical} interface.

    If the wrapped container is changed directly (that is, not through the
    wrapper), and does not implement IItemSetChangeNotifier and/or
    IPropertySetChangeNotifier the hierarchy information must be updated
    with the L{updateHierarchicalWrapper} method.

    @author: Vaadin Ltd.
    @author: Richard Lincoln
    """
    def __init__(self, toBeWrapped):
        """Constructs a new hierarchical wrapper for an existing Container.
        Works even if the to-be-wrapped container already implements the
        C{IHierarchical} interface.

        @param toBeWrapped:
                   the container that needs to be accessed hierarchically
        @see: L{updateHierarchicalWrapper}
        """
        super(ContainerHierarchicalWrapper, self).__init__()

        #: The wrapped container
        self._container = None

        #: Set of IDs of those contained Items that can't have children.
        self._noChildrenAllowed = None

        #: Mapping from Item ID to parent Item ID
        self._parent = None

        #: Mapping from Item ID to a list of child IDs
        self._children = None

        #: List that contains all root elements of the container.
        self._roots = None

        #: Is the wrapped container hierarchical by itself ?
        self._hierarchical = None

        self._container = toBeWrapped
        self._hierarchical = isinstance(self._container, IHierarchical)

        # Check arguments
        if self._container is None:
            raise ValueError, 'Null can not be wrapped'

        # Create initial order if needed
        if not self._hierarchical:
            self._noChildrenAllowed = OrderedSet()
            self._parent = dict()
            self._children = dict()
            self._roots = set(self._container.getItemIds())

        self.updateHierarchicalWrapper()

    def updateHierarchicalWrapper(self):
        """Updates the wrapper's internal hierarchy data to include all Items
        in the underlying container. If the contents of the wrapped container
        change without the wrapper's knowledge, this method needs to be called
        to update the hierarchy information of the Items.
        """
        if not self._hierarchical:

            # Recreate hierarchy and data structures if missing
            if (self._noChildrenAllowed is None or self._parent is None
                    or self._children is None or self._roots is None):
                # Check that the hierarchy is up-to-date
                self._noChildrenAllowed = set()
                self._parent = dict()
                self._children = dict()
                self._roots = OrderedSet(self._container.getItemIds())

            else:

                # ensure order of root and child lists is same as in wrapped
                # container
                itemIds = self._container.getItemIds()
                basedOnOrderFromWrappedContainer = \
                        ListedItemsFirstComparator(itemIds)

                # Calculate the set of all items in the hierarchy
                s = set()
                s = s.union(self._parent.keys())
                s = s.union(self._children.keys())
                s = s.union(self._roots)

                # Remove unnecessary items
                for idd in s:
                    if not self._container.containsId(idd):
                        self.removeFromHierarchyWrapper(idd)

                # Add all the missing items
                ids = self._container.getItemIds()
                for idd in ids:
                    if not (idd in s):
                        self.addToHierarchyWrapper(idd)
                        s.add(idd)

                arry = list(self._roots)
                arry.sort(cmp=basedOnOrderFromWrappedContainer)
                self._roots = OrderedSet()
                for a in arry:
                    self._roots.add(a)

                for obj in self._children.keys():
                    object2 = self._children[obj]
                    object2.sort(cmp=basedOnOrderFromWrappedContainer)

    def removeFromHierarchyWrapper(self, itemId):
        """Removes the specified Item from the wrapper's internal hierarchy
        structure.

        Note : The Item is not removed from the underlying Container.

        @param itemId:
                   the ID of the item to remove from the hierarchy.
        """
        oprhanedChildren = self._children.pop(itemId, None)
        if oprhanedChildren is not None:
            for obj in oprhanedChildren:
                # make orphaned children root nodes
                self.setParent(obj, None)

        if itemId in self._roots:
            self._roots.remove(itemId)

        p = self._parent.get(itemId)
        if p is not None:
            c = self._children.get(p)
            if c is not None:
                c.remove(itemId)

        if itemId in self._parent:
            del self._parent[itemId]

        if itemId in self._noChildrenAllowed:
            self._noChildrenAllowed.remove(itemId)

    def addToHierarchyWrapper(self, itemId):
        """Adds the specified Item specified to the internal hierarchy
        structure. The new item is added as a root Item. The underlying
        container is not modified.

        @param itemId:
                   the ID of the item to add to the hierarchy.
        """
        self._roots.add(itemId)

    def areChildrenAllowed(self, itemId):
        # Can the specified Item have any children?

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.areChildrenAllowed(itemId)

        if itemId in self._noChildrenAllowed:
            return False

        return self.containsId(itemId)

    def getChildren(self, itemId):
        # Gets the IDs of the children of the specified Item.

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.getChildren(itemId)

        c = self._children.get(itemId)
        if c is None:
            return None

        return list(c)

    def getParent(self, itemId):
        # Gets the ID of the parent of the specified Item.

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.getParent(itemId)

        return self._parent.get(itemId)

    def hasChildren(self, itemId):
        # Is the Item corresponding to the given ID a leaf node?

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.hasChildren(itemId)

        return self._children.get(itemId) is not None

    def isRoot(self, itemId):
        # Is the Item corresponding to the given ID a root node?

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.isRoot(itemId)

        if itemId in self._parent:
            return False

        return self.containsId(itemId)

    def rootItemIds(self):
        # Gets the IDs of the root elements in the container.

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.rootItemIds()

        return list(self._roots)

    def setChildrenAllowed(self, itemId, childrenAllowed):
        """Sets the given Item's capability to have children. If the Item
        identified with the itemId already has children and the
        areChildrenAllowed is false this method fails and C{False}
        is returned; the children must be first explicitly removed with
        L{setParent} or L{IContainer.removeItem}.

        @param itemId:
                   the ID of the Item in the container whose child capability
                   is to be set.
        @param childrenAllowed:
                   the boolean value specifying if the Item can have children
                   or not.
        @return: C{True} if the operation succeeded, C{False} if not
        """
        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.setChildrenAllowed(itemId, childrenAllowed)

        # Check that the item is in the container
        if not self.containsId(itemId):
            return False

        # Update status
        if childrenAllowed:
            if itemId in self._noChildrenAllowed:
                self._noChildrenAllowed.remove(itemId)
        else:
            self._noChildrenAllowed.add(itemId)

        return True

    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
        """
        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.setParent(itemId, newParentId)

        # Check that the item is in the container
        if not self.containsId(itemId):
            return False

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

        # Check 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:

            # Remove 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[itemId]

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

            # Update parent
            self._parent.remove(itemId)

            return True

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

        # Check 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

        # Update parent
        self._parent[itemId] = newParentId
        pcl = self._children.get(newParentId)
        if pcl is None:
            pcl = list()
            self._children[newParentId] = pcl
        pcl.append(itemId)

        # Remove 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:
                    self._children.remove(oldParentId)

        return True

    def addItem(self, itemId=None):
        """Adds a new Item by its ID to the underlying container and to the
        hierarchy. Creates a new Item into the Container, assigns it an
        automatic ID, and adds it to the hierarchy if C{itemId} is C{None}.

        @param itemId:
                   the ID of the Item to be created.
        @return: the added Item or C{None} if the operation failed.
        @raise NotImplementedError:
                    if the addItem is not supported.
        """
        if itemId is None:
            idd = self._container.addItem()
            if not self._hierarchical and idd is not None:
                self.addToHierarchyWrapper(idd)
            return idd
        else:
            item = self._container.addItem(itemId)
            if not self._hierarchical and item is not None:
                self.addToHierarchyWrapper(itemId)
            return item

    def removeAllItems(self):
        """Removes all items from the underlying container and from the
        hierarchy.

        @return: C{True} if the operation succeeded, C{False} if not
        @raise NotImplementedError:
                    if the removeAllItems is not supported.
        """
        success = self._container.removeAllItems()

        if not self._hierarchical and success:
            self._roots.clear()
            self._parent.clear()
            self._children.clear()
            self._noChildrenAllowed.clear()

        return success

    def removeItem(self, itemId):
        """Removes an Item specified by the itemId from the underlying
        container and from the hierarchy.

        @param itemId:
                   the ID of the Item to be removed.
        @return: C{True} if the operation succeeded, C{False} if not
        @raise NotImplementedError:
                    if the removeItem is not supported.
        """
        success = self._container.removeItem(itemId)

        if not self._hierarchical and success:
            self.removeFromHierarchyWrapper(itemId)

        return success

    def removeItemRecursively(self, itemId):
        """Removes the Item identified by given itemId and all its children.

        @see: L{removeItem}
        @param itemId:
                   the identifier of the Item to be removed
        @return: true if the operation succeeded
        """
        dummy = HierarchicalContainer()
        return HierarchicalContainer.removeItemRecursively(dummy, self, itemId)

    def addContainerProperty(self, propertyId, typ, defaultValue):
        """Adds a new Property to all Items in the Container.

        @param propertyId:
                   the ID of the new Property.
        @param typ:
                   the Data type of the new Property.
        @param defaultValue:
                   the value all created Properties are initialized to.
        @return: C{True} if the operation succeeded, C{False} if not
        @raise NotImplementedError:
                    if the addContainerProperty is not supported.
        """
        return self._container.addContainerProperty(propertyId, typ,
                                                    defaultValue)

    def removeContainerProperty(self, propertyId):
        """Removes the specified Property from the underlying container and
        from the hierarchy.

        Note: The Property will be removed from all Items in the Container.

        @param propertyId:
                   the ID of the Property to remove.
        @return: C{True} if the operation succeeded, C{False} if not
        @raise NotImplementedError:
                    if the removeContainerProperty is not supported.
        """
        return self._container.removeContainerProperty(propertyId)

    def containsId(self, itemId):
        # Does the container contain the specified Item?
        return self._container.containsId(itemId)

    def getItem(self, itemId):
        # Gets the specified Item from the container.
        return self._container.getItem(itemId)

    def getItemIds(self):
        # Gets the ID's of all Items stored in the Container
        return self._container.getItemIds()

    def getContainerProperty(self, itemId, propertyId):
        # Gets the Property identified by the given itemId and propertyId
        # from the Container
        return self._container.getContainerProperty(itemId, propertyId)

    def getContainerPropertyIds(self):
        # Gets the ID's of all Properties stored in the Container
        return self._container.getContainerPropertyIds()

    def getType(self, propertyId):
        # Gets the data type of all Properties identified by the given
        # Property ID.
        return self._container.getType(propertyId)

    def size(self):
        # Gets the number of Items in the Container.
        return len(self._container)

    def __len__(self):
        return self.size()

    def addListener(self, listener, iface=None):
        if (isinstance(listener, IItemSetChangeListener) and
            (iface is None or issubclass(iface, IItemSetChangeListener))):
            # Registers a new Item set change listener for this Container.
            if isinstance(self._container, IItemSetChangeNotifier):
                pl = PiggybackListener(listener, self)
                self._container.addListener(pl, IItemSetChangeListener)

        if (isinstance(listener, IPropertySetChangeListener) and
            (iface is None or issubclass(iface, IPropertySetChangeListener))):
            # Registers a new Property set change listener for this Container.
            if isinstance(self._container, IPropertySetChangeNotifier):
                pl = PiggybackListener(listener, self)
                self._container.addListener(pl, IPropertySetChangeListener)

    def addCallback(self, callback, eventType=None, *args):
        if eventType is None:
            eventType = callback._eventType

        if issubclass(eventType, IItemSetChangeEvent):
            # Registers a new Item set change listener for this Container.
            if isinstance(self._container, IItemSetChangeNotifier):
                pl = PiggybackListener(callback, self, *args)
                self._container.addListener(pl, IItemSetChangeListener)

        elif issubclass(eventType, IPropertySetChangeEvent):
            # Registers a new Property set change listener for this Container.
            if isinstance(self._container, IPropertySetChangeNotifier):
                pl = PiggybackListener(callback, self, *args)
                self._container.addListener(pl, IPropertySetChangeListener)

        else:
            super(ContainerHierarchicalWrapper,
                  self).addCallback(callback, eventType, *args)

    def removeListener(self, listener, iface=None):
        if (isinstance(listener, IItemSetChangeListener) and
            (iface is None or issubclass(iface, IItemSetChangeListener))):
            # Removes a Item set change listener from the object.
            if isinstance(self._container, IItemSetChangeNotifier):
                pl = PiggybackListener(listener, self)
                self._container.removeListener(pl, IItemSetChangeListener)

        if (isinstance(listener, IPropertySetChangeListener) and
            (iface is None or issubclass(iface, IPropertySetChangeListener))):
            # Removes a Property set change listener from the object.
            if isinstance(self._container, IPropertySetChangeNotifier):
                pl = PiggybackListener(listener, self)
                self._container.removeListener(pl, IPropertySetChangeListener)

    def removeCallback(self, callback, eventType=None):
        if eventType is None:
            eventType = callback._eventType

        if issubclass(eventType, IItemSetChangeEvent):
            # Removes a Item set change listener from the object.
            if isinstance(self._container, IItemSetChangeNotifier):
                pl = PiggybackListener(callback, self)
                self._container.removeListener(pl, IItemSetChangeListener)

        elif issubclass(eventType, IPropertySetChangeEvent):
            # Removes a Property set change listener from the object.
            if isinstance(self._container, IPropertySetChangeNotifier):
                pl = PiggybackListener(callback, self)
                self._container.removeListener(pl, IPropertySetChangeListener)

        else:
            super(ContainerHierarchicalWrapper,
                  self).removeCallback(callback, eventType)
class ContainerHierarchicalWrapper(IHierarchical, IContainer,
            IItemSetChangeNotifier, IPropertySetChangeNotifier):
    """A wrapper class for adding external hierarchy to containers not
    implementing the L{IHierarchical} interface.

    If the wrapped container is changed directly (that is, not through the
    wrapper), and does not implement IItemSetChangeNotifier and/or
    IPropertySetChangeNotifier the hierarchy information must be updated
    with the L{updateHierarchicalWrapper} method.

    @author: Vaadin Ltd.
    @author: Richard Lincoln
    """

    def __init__(self, toBeWrapped):
        """Constructs a new hierarchical wrapper for an existing Container.
        Works even if the to-be-wrapped container already implements the
        C{IHierarchical} interface.

        @param toBeWrapped:
                   the container that needs to be accessed hierarchically
        @see: L{updateHierarchicalWrapper}
        """
        super(ContainerHierarchicalWrapper, self).__init__()

        #: The wrapped container
        self._container = None

        #: Set of IDs of those contained Items that can't have children.
        self._noChildrenAllowed = None

        #: Mapping from Item ID to parent Item ID
        self._parent = None

        #: Mapping from Item ID to a list of child IDs
        self._children = None

        #: List that contains all root elements of the container.
        self._roots = None

        #: Is the wrapped container hierarchical by itself ?
        self._hierarchical = None

        self._container = toBeWrapped
        self._hierarchical = isinstance(self._container, IHierarchical)

        # Check arguments
        if self._container is None:
            raise ValueError, 'Null can not be wrapped'

        # Create initial order if needed
        if not self._hierarchical:
            self._noChildrenAllowed = OrderedSet()
            self._parent = dict()
            self._children = dict()
            self._roots = set(self._container.getItemIds())

        self.updateHierarchicalWrapper()


    def updateHierarchicalWrapper(self):
        """Updates the wrapper's internal hierarchy data to include all Items
        in the underlying container. If the contents of the wrapped container
        change without the wrapper's knowledge, this method needs to be called
        to update the hierarchy information of the Items.
        """
        if not self._hierarchical:

            # Recreate hierarchy and data structures if missing
            if (self._noChildrenAllowed is None or self._parent is None
                    or self._children is None or self._roots is None):
                # Check that the hierarchy is up-to-date
                self._noChildrenAllowed = set()
                self._parent = dict()
                self._children = dict()
                self._roots = OrderedSet(self._container.getItemIds())

            else:

                # ensure order of root and child lists is same as in wrapped
                # container
                itemIds = self._container.getItemIds()
                basedOnOrderFromWrappedContainer = \
                        ListedItemsFirstComparator(itemIds)

                # Calculate the set of all items in the hierarchy
                s = set()
                s = s.union(self._parent.keys())
                s = s.union(self._children.keys())
                s = s.union(self._roots)

                # Remove unnecessary items
                for idd in s:
                    if not self._container.containsId(idd):
                        self.removeFromHierarchyWrapper(idd)

                # Add all the missing items
                ids = self._container.getItemIds()
                for idd in ids:
                    if not (idd in s):
                        self.addToHierarchyWrapper(idd)
                        s.add(idd)

                arry = list(self._roots)
                arry.sort(cmp=basedOnOrderFromWrappedContainer)
                self._roots = OrderedSet()
                for a in arry:
                    self._roots.add(a)

                for obj in self._children.keys():
                    object2 = self._children[obj]
                    object2.sort(cmp=basedOnOrderFromWrappedContainer)


    def removeFromHierarchyWrapper(self, itemId):
        """Removes the specified Item from the wrapper's internal hierarchy
        structure.

        Note : The Item is not removed from the underlying Container.

        @param itemId:
                   the ID of the item to remove from the hierarchy.
        """
        oprhanedChildren = self._children.pop(itemId, None)
        if oprhanedChildren is not None:
            for obj in oprhanedChildren:
                # make orphaned children root nodes
                self.setParent(obj, None)

        if itemId in self._roots:
            self._roots.remove(itemId)

        p = self._parent.get(itemId)
        if p is not None:
            c = self._children.get(p)
            if c is not None:
                c.remove(itemId)

        if itemId in self._parent:
            del self._parent[itemId]

        if itemId in self._noChildrenAllowed:
            self._noChildrenAllowed.remove(itemId)


    def addToHierarchyWrapper(self, itemId):
        """Adds the specified Item specified to the internal hierarchy
        structure. The new item is added as a root Item. The underlying
        container is not modified.

        @param itemId:
                   the ID of the item to add to the hierarchy.
        """
        self._roots.add(itemId)


    def areChildrenAllowed(self, itemId):
        # Can the specified Item have any children?

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.areChildrenAllowed(itemId)

        if itemId in self._noChildrenAllowed:
            return False

        return self.containsId(itemId)


    def getChildren(self, itemId):
        # Gets the IDs of the children of the specified Item.

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.getChildren(itemId)

        c = self._children.get(itemId)
        if c is None:
            return None

        return list(c)


    def getParent(self, itemId):
        # Gets the ID of the parent of the specified Item.

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.getParent(itemId)

        return self._parent.get(itemId)


    def hasChildren(self, itemId):
        # Is the Item corresponding to the given ID a leaf node?

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.hasChildren(itemId)

        return self._children.get(itemId) is not None


    def isRoot(self, itemId):
        # Is the Item corresponding to the given ID a root node?

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.isRoot(itemId)

        if itemId in self._parent:
            return False

        return self.containsId(itemId)


    def rootItemIds(self):
        # Gets the IDs of the root elements in the container.

        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.rootItemIds()

        return list(self._roots)


    def setChildrenAllowed(self, itemId, childrenAllowed):
        """Sets the given Item's capability to have children. If the Item
        identified with the itemId already has children and the
        areChildrenAllowed is false this method fails and C{False}
        is returned; the children must be first explicitly removed with
        L{setParent} or L{IContainer.removeItem}.

        @param itemId:
                   the ID of the Item in the container whose child capability
                   is to be set.
        @param childrenAllowed:
                   the boolean value specifying if the Item can have children
                   or not.
        @return: C{True} if the operation succeeded, C{False} if not
        """
        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.setChildrenAllowed(itemId, childrenAllowed)

        # Check that the item is in the container
        if not self.containsId(itemId):
            return False

        # Update status
        if childrenAllowed:
            if itemId in self._noChildrenAllowed:
                self._noChildrenAllowed.remove(itemId)
        else:
            self._noChildrenAllowed.add(itemId)

        return True


    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
        """
        # If the wrapped container implements the method directly, use it
        if self._hierarchical:
            return self._container.setParent(itemId, newParentId)

        # Check that the item is in the container
        if not self.containsId(itemId):
            return False

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

        # Check 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:

            # Remove 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[itemId]

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

            # Update parent
            self._parent.remove(itemId)

            return True

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

        # Check 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

        # Update parent
        self._parent[itemId] = newParentId
        pcl = self._children.get(newParentId)
        if pcl is None:
            pcl = list()
            self._children[newParentId] = pcl
        pcl.append(itemId)

        # Remove 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:
                    self._children.remove(oldParentId)

        return True


    def addItem(self, itemId=None):
        """Adds a new Item by its ID to the underlying container and to the
        hierarchy. Creates a new Item into the Container, assigns it an
        automatic ID, and adds it to the hierarchy if C{itemId} is C{None}.

        @param itemId:
                   the ID of the Item to be created.
        @return: the added Item or C{None} if the operation failed.
        @raise NotImplementedError:
                    if the addItem is not supported.
        """
        if itemId is None:
            idd = self._container.addItem()
            if not self._hierarchical and idd is not None:
                self.addToHierarchyWrapper(idd)
            return idd
        else:
            item = self._container.addItem(itemId)
            if not self._hierarchical and item is not None:
                self.addToHierarchyWrapper(itemId)
            return item


    def removeAllItems(self):
        """Removes all items from the underlying container and from the
        hierarchy.

        @return: C{True} if the operation succeeded, C{False} if not
        @raise NotImplementedError:
                    if the removeAllItems is not supported.
        """
        success = self._container.removeAllItems()

        if not self._hierarchical and success:
            self._roots.clear()
            self._parent.clear()
            self._children.clear()
            self._noChildrenAllowed.clear()

        return success


    def removeItem(self, itemId):
        """Removes an Item specified by the itemId from the underlying
        container and from the hierarchy.

        @param itemId:
                   the ID of the Item to be removed.
        @return: C{True} if the operation succeeded, C{False} if not
        @raise NotImplementedError:
                    if the removeItem is not supported.
        """
        success = self._container.removeItem(itemId)

        if not self._hierarchical and success:
            self.removeFromHierarchyWrapper(itemId)

        return success


    def removeItemRecursively(self, itemId):
        """Removes the Item identified by given itemId and all its children.

        @see: L{removeItem}
        @param itemId:
                   the identifier of the Item to be removed
        @return: true if the operation succeeded
        """
        dummy = HierarchicalContainer()
        return HierarchicalContainer.removeItemRecursively(dummy, self, itemId)


    def addContainerProperty(self, propertyId, typ, defaultValue):
        """Adds a new Property to all Items in the Container.

        @param propertyId:
                   the ID of the new Property.
        @param typ:
                   the Data type of the new Property.
        @param defaultValue:
                   the value all created Properties are initialized to.
        @return: C{True} if the operation succeeded, C{False} if not
        @raise NotImplementedError:
                    if the addContainerProperty is not supported.
        """
        return self._container.addContainerProperty(propertyId, typ,
                defaultValue)


    def removeContainerProperty(self, propertyId):
        """Removes the specified Property from the underlying container and
        from the hierarchy.

        Note: The Property will be removed from all Items in the Container.

        @param propertyId:
                   the ID of the Property to remove.
        @return: C{True} if the operation succeeded, C{False} if not
        @raise NotImplementedError:
                    if the removeContainerProperty is not supported.
        """
        return self._container.removeContainerProperty(propertyId)


    def containsId(self, itemId):
        # Does the container contain the specified Item?
        return self._container.containsId(itemId)


    def getItem(self, itemId):
        # Gets the specified Item from the container.
        return self._container.getItem(itemId)


    def getItemIds(self):
        # Gets the ID's of all Items stored in the Container
        return self._container.getItemIds()


    def getContainerProperty(self, itemId, propertyId):
        # Gets the Property identified by the given itemId and propertyId
        # from the Container
        return self._container.getContainerProperty(itemId, propertyId)


    def getContainerPropertyIds(self):
        # Gets the ID's of all Properties stored in the Container
        return self._container.getContainerPropertyIds()


    def getType(self, propertyId):
        # Gets the data type of all Properties identified by the given
        # Property ID.
        return self._container.getType(propertyId)


    def size(self):
        # Gets the number of Items in the Container.
        return len(self._container)


    def __len__(self):
        return self.size()


    def addListener(self, listener, iface=None):
        if (isinstance(listener, IItemSetChangeListener) and
                (iface is None or issubclass(iface, IItemSetChangeListener))):
            # Registers a new Item set change listener for this Container.
            if isinstance(self._container, IItemSetChangeNotifier):
                pl = PiggybackListener(listener, self)
                self._container.addListener(pl, IItemSetChangeListener)

        if (isinstance(listener, IPropertySetChangeListener) and
                (iface is None or
                        issubclass(iface, IPropertySetChangeListener))):
            # Registers a new Property set change listener for this Container.
            if isinstance(self._container, IPropertySetChangeNotifier):
                pl = PiggybackListener(listener, self)
                self._container.addListener(pl, IPropertySetChangeListener)


    def addCallback(self, callback, eventType=None, *args):
        if eventType is None:
            eventType = callback._eventType

        if issubclass(eventType, IItemSetChangeEvent):
            # Registers a new Item set change listener for this Container.
            if isinstance(self._container, IItemSetChangeNotifier):
                pl = PiggybackListener(callback, self, *args)
                self._container.addListener(pl, IItemSetChangeListener)

        elif issubclass(eventType, IPropertySetChangeEvent):
            # Registers a new Property set change listener for this Container.
            if isinstance(self._container, IPropertySetChangeNotifier):
                pl = PiggybackListener(callback, self, *args)
                self._container.addListener(pl, IPropertySetChangeListener)

        else:
            super(ContainerHierarchicalWrapper, self).addCallback(callback,
                    eventType, *args)


    def removeListener(self, listener, iface=None):
        if (isinstance(listener, IItemSetChangeListener) and
                (iface is None or issubclass(iface, IItemSetChangeListener))):
            # Removes a Item set change listener from the object.
            if isinstance(self._container, IItemSetChangeNotifier):
                pl = PiggybackListener(listener, self)
                self._container.removeListener(pl, IItemSetChangeListener)


        if (isinstance(listener, IPropertySetChangeListener) and
            (iface is None or issubclass(iface, IPropertySetChangeListener))):
            # Removes a Property set change listener from the object.
            if isinstance(self._container, IPropertySetChangeNotifier):
                pl = PiggybackListener(listener, self)
                self._container.removeListener(pl, IPropertySetChangeListener)


    def removeCallback(self, callback, eventType=None):
        if eventType is None:
            eventType = callback._eventType

        if issubclass(eventType, IItemSetChangeEvent):
            # Removes a Item set change listener from the object.
            if isinstance(self._container, IItemSetChangeNotifier):
                pl = PiggybackListener(callback, self)
                self._container.removeListener(pl, IItemSetChangeListener)

        elif issubclass(eventType, IPropertySetChangeEvent):
            # Removes a Property set change listener from the object.
            if isinstance(self._container, IPropertySetChangeNotifier):
                pl = PiggybackListener(callback, self)
                self._container.removeListener(pl, IPropertySetChangeListener)

        else:
            super(ContainerHierarchicalWrapper, self).removeCallback(callback,
                    eventType)
Exemplo n.º 17
0
class EventRouter(IMethodEventSource):
    """C{EventRouter} class implementing the inheritable event
    listening model. For more information on the event model see the
    L{muntjac.event package documentation<muntjac.event>}.

    @author: Vaadin Ltd.
    @author: Richard Lincoln
    @version: @VERSION@
    """

    def __init__(self):
        #: List of registered listeners.
        self._listenerList = None


    def addListener(self, eventType, obj, method, arguments=None,
                eventArgIdx=None):
        # Registers a new listener with the specified activation method
        # to listen events generated by this component.

        if self._listenerList is None:
            self._listenerList = OrderedSet()

        lm = ListenerMethod(eventType, obj, method, arguments, eventArgIdx)

        self._listenerList.add(lm)


    def removeListener(self, eventType, target, method=None):
        # Removes the event listener methods matching
        # the given given paramaters.
        if method is None:
            if self._listenerList is not None:
                for lm in self._listenerList:
                    if lm.matches(eventType, target):
                        self._listenerList.remove(lm)
                        return
        else:
            if isinstance(method, basestring):
                methodName = method

                method = getattr(target, methodName)

                if method is None:
                    raise ValueError()

                # Remove the listeners
                if self._listenerList is not None:
                    for lm in self._listenerList:
                        if lm.matches(eventType, target, method):
                            self._listenerList.remove(lm)
                            return
            else:
                if self._listenerList is not None:
                    for lm in self._listenerList:
                        if lm.matches(eventType, target, method):
                            self._listenerList.remove(lm)
                            return


    def removeAllListeners(self):
        """Removes all listeners from event router."""
        self._listenerList = None


    def fireEvent(self, event):
        """Sends an event to all registered listeners. The listeners will
        decide if the activation method should be called or not.

        @param event:
                   the Event to be sent to all listeners.
        """
        # It is not necessary to send any events if there are no listeners
        if self._listenerList is not None:
            # Make a copy of the listener list to allow listeners to be added
            # inside listener methods. Fixes #3605.

            # Send the event to all listeners. The listeners themselves
            # will filter out unwanted events.
            listeners = list(self._listenerList)
            for listener in listeners:
                listener.receiveEvent(event)


    def hasListeners(self, eventType):
        """Checks if the given Event type is listened by a listener registered
        to this router.

        @param eventType:
                   the event type to be checked
        @return: true if a listener is registered for the given event type
        """
        if self._listenerList is not None:
            for lm in self._listenerList:
                if lm.isType(eventType):
                    return True
        return False


    def getListeners(self, eventType):
        """Returns all listeners that match or extend the given event type.

        @param eventType:
                   The type of event to return listeners for.
        @return: A collection with all registered listeners. Empty if no
                listeners are found.
        """
        listeners = list()
        if self._listenerList is not None:
            for lm in self._listenerList:
                if lm.isOrExtendsType(eventType):
                    listeners.append(lm.getTarget())
        return listeners
Exemplo n.º 18
0
class AbsoluteLayout(AbstractLayout, ILayoutClickNotifier):
    """AbsoluteLayout is a layout implementation that mimics html
    absolute positioning.
    """

    CLIENT_WIDGET = None  #ClientWidget(VAbsoluteLayout)

    _CLICK_EVENT = EventId.LAYOUT_CLICK

    def __init__(self):
        """Creates an AbsoluteLayout with full size."""
        super(AbsoluteLayout, self).__init__()

        #: The components in the layout
        self._components = OrderedSet()

        #: Maps each component to a position
        self._componentToCoordinates = dict()

        self.setSizeFull()

    def getComponentIterator(self):
        """Gets an iterator for going through all components enclosed
        in the absolute layout.
        """
        return iter(self._components)

    def getComponentCount(self):
        """Gets the number of contained components. Consistent with
        the iterator returned by L{getComponentIterator}.

        @return: the number of contained components
        """
        return len(self._components)

    def replaceComponent(self, oldComponent, newComponent):
        """Replaces one component with another one. The new component
        inherits the old components position.
        """
        position = self.getPosition(oldComponent)
        self.removeComponent(oldComponent)
        self.addComponent(newComponent)
        self._componentToCoordinates[newComponent] = position

    def addComponent(self, c, cssPosition=None):
        """Adds a component to the layout. The component can be positioned
        by providing a string formatted in CSS-format.

        For example the string "top:10px;left:10px" will position the
        component 10 pixels from the left and 10 pixels from the top. The
        identifiers: "top","left","right" and "bottom" can be used to
        specify the position.

        @param c:
                   The component to add to the layout
        @param cssPosition:
                   The css position string
        """
        # Create position instance and add it to componentToCoordinates
        # map. We need to do this before we call addComponent so the
        # attachListeners can access this position. #6368
        if cssPosition is not None:
            position = ComponentPosition(self)
            position.setCSSString(cssPosition)
            self._componentToCoordinates[c] = position

        self._components.add(c)
        try:
            super(AbsoluteLayout, self).addComponent(c)
            self.requestRepaint()
        except ValueError, e:
            self._components.remove(c)
            if cssPosition is not None:
                # Remove component coordinates if adding fails
                del self._componentToCoordinates[c]
                raise e
Exemplo n.º 19
0
class Upload(AbstractComponent, IFocusable): #IComponent,
    """IComponent for uploading files from client to server.

    The visible component consists of a file name input box and a browse
    button and an upload submit button to start uploading.

    The Upload component needs a StringIO to write the uploaded
    data. You need to implement the upload.IReceiver interface and return the
    output stream in the receiveUpload() method.

    You can get an event regarding starting (StartedEvent), progress
    (ProgressEvent), and finishing (FinishedEvent) of upload by implementing
    IStartedListener, IProgressListener, and IFinishedListener, respectively.
    The IFinishedListener is called for both failed and succeeded uploads. If
    you wish to separate between these two cases, you can use
    ISucceededListener (SucceededEvenet) and IFailedListener (FailedEvent).

    The upload component does not itself show upload progress, but you can use
    the ProgressIndicator for providing progress feedback by implementing
    IProgressListener and updating the indicator in updateProgress().

    Setting upload component immediate initiates the upload as soon as a file
    is selected, instead of the common pattern of file selection field and
    upload button.

    Note! Because of browser dependent implementations of <input type="file">
    element, setting size for Upload component is not supported. For some
    browsers setting size may work to some extent.

    @author: Vaadin Ltd.
    @author: Richard Lincoln
    @version: @VERSION@
    """

    CLIENT_WIDGET = None #ClientWidget(VUpload, LoadStyle.LAZY)

    def __init__(self, caption=None, uploadReceiver=None):
        """Creates a new instance of Upload.

        The receiver must be set before performing an upload.
        """
        super(Upload, self).__init__()

        #: Should the field be focused on next repaint?
        self._focus = False

        #: The tab order number of this field.
        self._tabIndex = 0

        #: The output of the upload is redirected to this receiver.
        self._receiver = None

        self._isUploading = False

        self._contentLength = -1

        self._totalBytes = None

        self._buttonCaption = 'Upload'

        #: ProgressListeners to which information about progress
        #  is sent during upload
        self._progressListeners = OrderedSet()

        self._progressCallbacks = dict()

        self._interrupted = False

        self._notStarted = None

        self._nextid = 0

        #: Flag to indicate that submitting file has been requested.
        self._forceSubmit = None

        if caption:
            self.setCaption(caption)

        if uploadReceiver is not None:
            self._receiver = uploadReceiver

        self._streamVariable = None


    def changeVariables(self, source, variables):
        """Invoked when the value of a variable has changed.

        @see: L{AbstractComponent.changeVariables}
        """
        if 'pollForStart' in variables:
            idd = variables.get('pollForStart')
            if not self._isUploading and idd == self._nextid:
                self._notStarted = True
                self.requestRepaint()
            else:
                pass


    def paintContent(self, target):
        """Paints the content of this component.

        @param target:
                   Target to paint the content on.
        @raise PaintException:
                    if the paint operation failed.
        """
        if self._notStarted:
            target.addAttribute('notStarted', True)
            self._notStarted = False
            return

        if self._forceSubmit:
            target.addAttribute('forceSubmit', True)
            self._forceSubmit = True
            return

        # The field should be focused
        if self._focus:
            target.addAttribute('focus', True)

        # The tab ordering number
        if self._tabIndex >= 0:
            target.addAttribute('tabindex', self._tabIndex)

        target.addAttribute('state', self._isUploading)

        if self._buttonCaption is not None:
            target.addAttribute('buttoncaption', self._buttonCaption)

        target.addAttribute('nextid', self._nextid)

        # Post file to this strean variable
        target.addVariable(self, 'action', self.getStreamVariable())


    def addListener(self, listener, iface=None):
        """Adds an event listener.

        @param listener:
                   the listener to be added.
        """
        if (isinstance(listener, IFailedListener) and
                (iface is None or issubclass(iface, IFailedListener))):
            self.registerListener(FailedEvent,
                    listener, _UPLOAD_FAILED_METHOD)

        if (isinstance(listener, IFinishedListener) and
                (iface is None or issubclass(iface, IFinishedListener))):
            self.registerListener(FinishedEvent,
                    listener, _UPLOAD_FINISHED_METHOD)

        if (isinstance(listener, IProgressListener) and
                (iface is None or issubclass(iface, IProgressListener))):
            self._progressListeners.add(listener)

        if (isinstance(listener, IStartedListener) and
                (iface is None or issubclass(iface, IStartedListener))):
            self.registerListener(StartedEvent,
                    listener, _UPLOAD_STARTED_METHOD)

        if (isinstance(listener, ISucceededListener) and
                (iface is None or issubclass(iface, ISucceededListener))):
            self.registerListener(SucceededEvent,
                    listener, _UPLOAD_SUCCEEDED_METHOD)

        super(Upload, self).addListener(listener, iface)


    def addCallback(self, callback, eventType=None, *args):
        if eventType is None:
            eventType = callback._eventType

        if issubclass(eventType, FailedEvent):
            self.registerCallback(FailedEvent, callback, None, *args)

        elif issubclass(eventType, FinishedEvent):
            self.registerCallback(FinishedEvent, callback, None, *args)

        elif issubclass(eventType, IProgressListener):  # no progress event
            self._progressCallbacks[callback] = args

        elif issubclass(eventType, StartedEvent):
            self.registerCallback(StartedEvent, callback, None, *args)

        elif issubclass(eventType, SucceededEvent):
            self.registerCallback(SucceededEvent, callback, None, *args)

        else:
            super(Upload, self).addCallback(callback, eventType, *args)


    def removeListener(self, listener, iface=None):
        """Removes an event listener.

        @param listener:
                   the listener to be removed.
        """
        if (isinstance(listener, IFailedListener) and
                (iface is None or issubclass(iface, IFailedListener))):
            self.withdrawListener(FailedEvent,
                    listener, _UPLOAD_FAILED_METHOD)

        if (isinstance(listener, IFinishedListener) and
                (iface is None or issubclass(iface, IFinishedListener))):
            self.withdrawListener(FinishedEvent,
                    listener, _UPLOAD_FINISHED_METHOD)

        if (isinstance(listener, IProgressListener) and
                (iface is None or issubclass(iface, IProgressListener))):
            if listener in self._progressListeners:
                self._progressListeners.remove(listener)

        if (isinstance(listener, IStartedListener) and
                (iface is None or issubclass(iface, IStartedListener))):
            self.withdrawListener(StartedEvent,
                    listener, _UPLOAD_STARTED_METHOD)

        if (isinstance(listener, ISucceededListener) and
                (iface is None or issubclass(iface, ISucceededListener))):
            self.withdrawListener(SucceededEvent,
                    listener, _UPLOAD_SUCCEEDED_METHOD)

        super(Upload, self).removeListener(listener, iface)


    def removeCallback(self, callback, eventType=None):
        if eventType is None:
            eventType = callback._eventType

        if issubclass(eventType, FailedEvent):
            self.withdrawCallback(FailedEvent, callback)

        elif issubclass(eventType, FinishedEvent):
            self.withdrawCallback(FinishedEvent, callback)

        elif issubclass(eventType, IProgressListener):  # no progress event
            if callback in self._progressCallbacks:
                del self._progressListeners[callback]

        elif issubclass(eventType, StartedEvent):
            self.withdrawCallback(StartedEvent, callback)

        elif issubclass(eventType, SucceededEvent):
            self.withdrawCallback(SucceededEvent, callback)

        else:
            super(Upload, self).removeCallback(callback, eventType)


    def fireStarted(self, filename, MIMEType):
        """Emit upload received event.
        """
        evt = StartedEvent(self, filename, MIMEType, self._contentLength)
        self.fireEvent(evt)


    def fireUploadInterrupted(self, filename, MIMEType, length, e=None):
        """Emits the upload failed event.
        """
        if e is None:
            evt = FailedEvent(self, filename, MIMEType, length)
        else:
            evt = FailedEvent(self, filename, MIMEType, length, e)

        self.fireEvent(evt)


    def fireNoInputStream(self, filename, MIMEType, length):
        evt = NoInputStreamEvent(self, filename, MIMEType, length)
        self.fireEvent(evt)


    def fireNoOutputStream(self, filename, MIMEType, length):
        evt = NoOutputStreamEvent(self, filename, MIMEType, length)
        self.fireEvent(evt)


    def fireUploadSuccess(self, filename, MIMEType, length):
        """Emits the upload success event.
        """
        evt = SucceededEvent(self, filename, MIMEType, length)
        self.fireEvent(evt)


    def fireUpdateProgress(self, totalBytes, contentLength):
        """Emits the progress event.

        @param totalBytes:
                   bytes received so far
        @param contentLength:
                   actual size of the file being uploaded, if known
        """
        # this is implemented differently than other listeners to
        # maintain backwards compatibility
        for l in self._progressListeners:
            l.updateProgress(totalBytes, contentLength)

        for callback, args in self._progressCallbacks.iteritems():
            callback(totalBytes, contentLength, *args)


    def getReceiver(self):
        """Returns the current receiver.

        @return: the IStreamVariable.
        """
        return self._receiver


    def setReceiver(self, receiver):
        """Sets the receiver.

        @param receiver:
                   the receiver to set.
        """
        self._receiver = receiver


    def focus(self):
        super(Upload, self).focus()


    def getTabIndex(self):
        """Gets the Tabulator index of this IFocusable component.

        @see: L{IFocusable.getTabIndex}
        """
        return self._tabIndex


    def setTabIndex(self, tabIndex):
        """Sets the Tabulator index of this IFocusable component.

        @see: L{IFocusable.setTabIndex}
        """
        self._tabIndex = tabIndex


    def startUpload(self):
        """Go into upload state. This is to prevent double uploading on same
        component.

        Warning: this is an internal method used by the framework and should
        not be used by user of the Upload component. Using it results in the
        Upload component going in wrong state and not working. It is currently
        public because it is used by another class.
        """
        if self._isUploading:
            raise ValueError, 'uploading already started'

        self._isUploading = True
        self._nextid += 1


    def interruptUpload(self):
        """Interrupts the upload currently being received. The interruption
        will be done by the receiving tread so this method will return
        immediately and the actual interrupt will happen a bit later.
        """
        if self._isUploading:
            self._interrupted = True


    def endUpload(self):
        """Go into state where new uploading can begin.

        Warning: this is an internal method used by the framework and should
        not be used by user of the Upload component.
        """
        self._isUploading = False
        self._contentLength = -1
        self._interrupted = False
        self.requestRepaint()


    def isUploading(self):
        return self._isUploading


    def getBytesRead(self):
        """Gets read bytes of the file currently being uploaded.

        @return: bytes
        """
        return self._totalBytes


    def getUploadSize(self):
        """Returns size of file currently being uploaded. Value sane only
        during upload.

        @return: size in bytes
        """
        return self._contentLength


    def setProgressListener(self, progressListener):
        """This method is deprecated, use addListener(IProgressListener)
        instead.

        @deprecated: Use addListener(IProgressListener) instead.
        """
        warn('use addListener() instead', DeprecationWarning)

        self.addListener(progressListener, IProgressListener)


    def getProgressListener(self):
        """This method is deprecated.

        @deprecated: Replaced with addListener/removeListener
        @return: listener
        """
        warn('replaced with addListener/removeListener', DeprecationWarning)

        if len(self._progressListeners) == 0:
            return None
        else:
            return iter(self._progressListeners).next()


    def getButtonCaption(self):
        """@return: String to be rendered into button that fires uploading"""
        return self._buttonCaption


    def setButtonCaption(self, buttonCaption):
        """In addition to the actual file chooser, upload components have
        button that starts actual upload progress. This method is used to set
        text in that button.

        In case the button text is set to null, the button is hidden. In this
        case developer must explicitly initiate the upload process with
        L{submitUpload}.

        In case the Upload is used in immediate mode using
        L{setImmediate}, the file choose (html input with type
        "file") is hidden and only the button with this text is shown.

        B{Note} the string given is set as is to the button.
        HTML formatting is not stripped. Be sure to properly validate your
        value according to your needs.

        @param buttonCaption:
                   text for upload components button.
        """
        self._buttonCaption = buttonCaption
        self.requestRepaint()


    def submitUpload(self):
        """Forces the upload the send selected file to the server.

        In case developer wants to use this feature, he/she will most probably
        want to hide the uploads internal submit button by setting its caption
        to null with L{setButtonCaption} method.

        Note, that the upload runs asynchronous. Developer should use normal
        upload listeners to trac the process of upload. If the field is empty
        uploaded the file name will be empty string and file length 0 in the
        upload finished event.

        Also note, that the developer should not remove or modify the upload
        in the same user transaction where the upload submit is requested. The
        upload may safely be hidden or removed once the upload started event
        is fired.
        """
        self.requestRepaint()
        self._forceSubmit = True


    def requestRepaint(self):
        self._forceSubmit = False
        super(Upload, self).requestRepaint()


    def getStreamVariable(self):
        # Handle to terminal via Upload monitors and controls the upload
        # during it is being streamed.
        if self._streamVariable is None:
            self._streamVariable = InnerStreamVariable(self)

        return self._streamVariable


    def getListeners(self, eventType):
        if issubclass(eventType, IStreamingEvent):
            return list(self._progressListeners)

        return super(Upload, self).getListeners(eventType)


    def getCallbacks(self, eventType):
        if issubclass(eventType, IStreamingEvent):
            return dict(self._progressCallbacks)

        return super(Upload, self).getCallbacks(eventType)