r2 - 23 Aug 2004 - 11:01:09 - DuckySherwoodYou are here: OSAF >  Journal Web  >  ContributorNotes > MorgenSagenNotes > MorgenSagen20040820

Sidebar

Just what is the sidebar?

The sidebar is a Table whose "contents" is sidebarItemCollection, which is a NamedCollection whose "inclusions" contains AllTableView, InTableView, etc. AllTableView is a SplitterWindow whose "contents" is allItemCollection, and "childrenBlocks" contains AllSummary and a cloud-copy of DetailRootTemplate. allItemCollection is a NamedCollection (displayName = "All") whose "rule" is mixedQuery (which matches all Notes and Contacts). AllSummary is a BoxContainer whose "childrenBlocks" contains a cloud-copy of LayoutSelector, and AllTable. AllTable is a Table whose "contents" is allItemCollection (hmmm, this is also in AllTableView's contents). LayoutSelector is a Toolbar whose "childrenBlocks" contain ListViewButton, MonthViewButton, etc.

  • Sidebar (Table)
    • .contents = sidebarItemCollection

  • sidebarItemCollection (NamedCollection)
    • .inclusions = AllTableView, InTableView, etc.

  • AllTableView (SplitterWindow)
    • .contents = allItemCollection
    • .childrenBlocks:
      • AllSummary (BoxContainer)
        • .childrenBlocks:
          • (Copy of) LayoutSelector (Toolbar)
          • AllTable (Table)
            • .contents = allItemCollection
      • (Copy of) DetailRootTemplate (SelectionContainer)

  • allItemCollection (NamedCollection)
    • .rule = mixedQuery matching Notes and Contacts

Looking at UntitledView, which is the view I want to use as a template:

  • UntitledView
    • .contents = untitledItemCollection
    • .childrenBlocks:
      • UntitledSummary (BoxContainer)
        • .childrenBlocks:
          • (Copy of) LayoutSelector (Toolbar)
          • UntitledTable (Table)
            • .contents = untitledItemCollection
      • (Copy of) DetailRootTemplate

Adding a new view to the sidebar

When I get a collection from Stuart (via webdav) to add to the sidebar, I'm trying to use the NewItemCollectionItem event (parcels/osaf/framework/blocks/Events/parcel.xml) which gets handed by onModifyContentsEvent (parcels/osaf/framework/blocks/Block.py). onModifyContentsEvent now takes a "collection" argument passed in via notification.data -- this collection is the NamedCollection I got from Stuart. That method makes a cloud copy of UntitledView (since that what the parcel.xml defines for event.items), sets that copy's contents to be the collection, and adds the copy (a view) to the sidebar's contents.

NewItemCollectionItem is defined in parcels/osaf/framework/blocks/Events/parcel.xml as:

  <ModifyContentsEvent itsName="NewItemCollectionItem">
    <dispatchEnum>SendToBlock</dispatchEnum>
    <dispatchToBlock itemref="doc:Sidebar"/>
    <methodName>onModifyContentsEvent</methodName>
    <items itemref="content:UntitledView"/>
    <copyItems>True</copyItems>
  </ModifyContentsEvent>

The code that posts this event (Main.py):

            collection = osaf.framework.webdav.Dav.DAV(url).get( )
            event = Globals.parcelManager.lookup(EVENTS,
             "NewItemCollectionItem")
            event.Post({'collection':collection})
            Globals.repository.commit()

The only remaining hack is that I need to set the new collection as contents for both the copied view and that view's table.

    def onModifyContentsEvent(self, notification):
        event = notification.event 
        operation = event.operation

        # 'collection' is an item collection that we want our new view
        # to contain
        collection = notification.data.get('collection', None)
        
        # we'll put the copies in //userdata
        userdata = Globals.repository.findPath('//userdata')
        
        for item in event.items:
            if event.copyItems:
                copies = { } # This will contain all the copied items
                item = item.copy(parent=userdata, cloudAlias='default',
                 copies=copies)
                Globals.notificationManager.PrepareSubscribers()
                if collection is not None:
                    print "I am setting collection to", collection
                    item.contents = collection
        
                    # @@@ Hack to also set the table's contents:
                    tableKind = Globals.repository.findPath("//parcels/osaf/framework/blocks/Table")
                    for copy in copies.values():
                        if copy.isItemOf(tableKind):
                            copy.contents = collection
                            """
                            Hack to work around Stuarts bug #1568 -- DJA
                            """
                            item.contents._ItemCollection__refresh()
            if operation == 'toggle':
                try:
                    index = self.contents.index (item)
                except ValueError:
                    operation = 'add'
                else:
                    operation = 'remove'
            method = getattr (self.contents, operation)
            method (item)


Remaining work:

  • Move Heikki's invite handling code into framework/sharing
  • Hook up the IMAP/SMTP dialog useSSL checkboxes
  • Make sure that subscribing to the same collection twice is handled properly


All Issues below have been fixed:

Debugging adding things to the sidebar

So I checked in the code that lets you try to subscribe to a collection from the Test menu. If you put in for the url:

It will begin downloading items, return me a namedcollection, and I use the onModifyContentsEvent on line 200 of Block.py to create a copy of untitledView to add to the sidebar. The new view does get into the sidebar, but if I click on it I get:

[THIS HAS BEEN FIXED -- it was because I need to let the NotificationManager know that there are new events, which I did with PrepareSubscribers() ]


Traceback (most recent call last):
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/ControlBlocks.py", line 471, in OnWXSelectionChanged
    {'item':item})
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Block.py", line 24, in Post
    event.Post (args)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/notifications/schema/Event.py", line 27, in Post
    Globals.notificationManager.PostNotification(notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/notifications/NotificationManager.py", line 157, in PostNotification
    sub.post(notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/notifications/NotificationManager.py", line 184, in post
    self.callback(notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 77, in dispatchEvent
    broadcast (block, methodName, notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 51, in broadcast
    broadcast (child, methodName, notification, stopAtEventBoundary)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 51, in broadcast
    broadcast (child, methodName, notification, stopAtEventBoundary)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 51, in broadcast
    broadcast (child, methodName, notification, stopAtEventBoundary)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 48, in broadcast
    callMethod (block, methodName, notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 29, in callMethod
    member (notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/views/main/TabbedView.py", line 14, in onSelectionChangedEvent
    self.ChangeCurrentTab(item)
  File "/Users/morgen/dev/chandler/parcels/osaf/views/main/TabbedView.py", line 34, in ChangeCurrentTab
    item.render()                
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Block.py", line 97, in render
    child.render()
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Block.py", line 97, in render
    child.render()
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Block.py", line 80, in render
    Globals.mainView.dispatchEvent)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/notifications/NotificationManager.py", line 88, in Subscribe
    decls.append(self.declarations[e.itsUUID])
KeyError: <UUID: 6355967e-f2b0-11d8-9cc4-000a95bb2738>

What does it mean that at line 88, self.declarations[ ] doesn't contain e.itsUUID?

[TURNS OUT my event wasn't yet known to NotificationManager, so I now call PrepareSubscribers() after the cloud copy]

Once I get the above error, from then on clicking on the sidebar results in:


Traceback (most recent call last):
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/ControlBlocks.py", line 471, in OnWXSelectionChanged
    {'item':item})
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Block.py", line 24, in Post
    event.Post (args)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/notifications/schema/Event.py", line 27, in Post
    Globals.notificationManager.PostNotification(notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/notifications/NotificationManager.py", line 157, in PostNotification
    sub.post(notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/notifications/NotificationManager.py", line 184, in post
    self.callback(notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 77, in dispatchEvent
    broadcast (block, methodName, notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 51, in broadcast
    broadcast (child, methodName, notification, stopAtEventBoundary)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 51, in broadcast
    broadcast (child, methodName, notification, stopAtEventBoundary)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 51, in broadcast
    broadcast (child, methodName, notification, stopAtEventBoundary)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 48, in broadcast
    callMethod (block, methodName, notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/framework/blocks/Views.py", line 29, in callMethod
    member (notification)
  File "/Users/morgen/dev/chandler/parcels/osaf/views/main/TabbedView.py", line 14, in onSelectionChangedEvent
    self.ChangeCurrentTab(item)
  File "/Users/morgen/dev/chandler/parcels/osaf/views/main/TabbedView.py", line 29, in ChangeCurrentTab
    previousChild = self.childrenBlocks.previous(page.blockItem)
  File "/Users/morgen/dev/chandler/repository/item/ItemRef.py", line 1207, in previous
    previousKey = self.previousKey(key)
  File "/Users/morgen/dev/chandler/repository/util/LinkedMap.py", line 226, in previousKey
    return self._get(key)._previousKey
  File "/Users/morgen/dev/chandler/repository/util/LinkedMap.py", line 83, in _get
    return super(LinkedMap, self).__getitem__(key)
KeyError: <UUID: 120feea8-f2c5-11d8-f496-000a95bb2738>

[STUART FIXED THIS] Also, Stuart, the collection I get from dav.get() appears to be empty (I copied the following from the repo viewer):


NamedCollection: XYZZY    (I am setting displayName to XYZZY for testing, so there is something there)
Path: //userdata/contentitems/cLoAm3OI17ofSG00GlKOsU
UUID: cbd89160-f2b0-11d8-fdaa-000a95bb2738
collectionOwner:
SplitterWindow: dYTWpHOI17ofSG00GlKOsU
displayName: XYZZY
etag: "47641-f-412552d4"
exclusions: []
importance: normal
inclusions: []
lastModified: Fri, 20 Aug 2004 01:24:36 GMT
rule: (None)
sharedURL: http://code-bear.com/dav/test_item_collection
sharedVersion: 0

-- MorgenSagen - 20 Aug 2004

Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r2 < r1 | More topic actions
 
Open Source Applications Foundation
Except where otherwise noted, this site and its content are licensed by OSAF under an Creative Commons License, Attribution Only 3.0.
See list of page contributors for attributions.