Index: /home/heikki/workspace/chandler/application/Application.py =================================================================== --- /home/heikki/workspace/chandler/application/Application.py (revision 13027) +++ /home/heikki/workspace/chandler/application/Application.py (working copy) @@ -29,10 +29,28 @@ # SCHEMA_VERSION has moved to Utility.py - #@@@Temporary testing tool written by Morgen -- DJA import util.timing +def delayedImports(): + """ + We must delay importing things from parcels to avoid circular references. + We also don't want to be importing the same things over and over; hence + this function which will save us from that and gain a little performance. + """ + from osaf.framework.blocks.Block import wxRectangularChild, Block + from osaf.framework.blocks.BranchPoint import BranchPointBlock + import osaf.framework.scripting as Scripting + from osaf.pim.structs import SizeType, PositionType + g = globals() + g['Block'] = Block + g['wxRectangularChild'] = wxRectangularChild + g['BranchPointBlock'] = BranchPointBlock + g['Scripting'] = Scripting + g['SizeType'] = SizeType + g['PositionType'] = PositionType + + # Event used to post callbacks on the UI thread wxEVT_MAIN_THREAD_CALLBACK = wx.NewEventType() @@ -88,6 +106,7 @@ self.Bind(wx.EVT_CLOSE, self.OnClose) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_MOVE, self.OnMove) + self.app = wx.GetApp() def ShowTreeOfBlocks (self, treeOfBlocks): if hasattr (self, "treeOfBlocks"): @@ -100,7 +119,6 @@ sizer = wx.BoxSizer (wx.HORIZONTAL) self.SetSizer (sizer) - from osaf.framework.blocks.Block import wxRectangularChild sizer.Add (self.treeOfBlocks.widget, self.treeOfBlocks.stretchFactor, wxRectangularChild.CalculateWXFlag(self.treeOfBlocks), @@ -117,10 +135,10 @@ # Calling Skip causes wxWindows to continue processing the event, # which will cause the parent class to get a crack at the event. - if not wx.GetApp().ignoreSynchronizeWidget: - from osaf.pim.structs import SizeType + if not self.app.ignoreSynchronizeWidget: # Our first child's block is the FrameWindow where we store size and position - self.GetChildren()[0].blockItem.size = SizeType (self.GetSize().x, self.GetSize().y) + size = self.GetSize() + self.GetChildren()[0].blockItem.size = SizeType (size.x, size.y) event.Skip() def OnMove(self, event): @@ -127,10 +145,10 @@ # Calling Skip causes wxWindows to continue processing the event, # which will cause the parent class to get a crack at the event. - if not wx.GetApp().ignoreSynchronizeWidget: - from osaf.pim.structs import PositionType + if not self.app.ignoreSynchronizeWidget: # Our first child's block is the FrameWindow where we store size and position - self.GetChildren()[0].blockItem.position = PositionType(self.GetPosition().x, self.GetPosition().y) + position = self.GetPosition() + self.GetChildren()[0].blockItem.position = PositionType(position.x, position.y) event.Skip() @@ -197,7 +215,6 @@ logger.exception(e) # Finish any edits in progress. - from osaf.framework.blocks.Block import Block Block.finishEdits() # For some strange reason when there's an idle handler on the @@ -209,7 +226,7 @@ app.Bind(wx.EVT_MENU, None, id=-1) if wx.Platform == '__WXMAC__': - wx.GetApp().Bind(wx.EVT_ACTIVATE_APP, None) + app.Bind(wx.EVT_ACTIVATE_APP, None) if __debug__: displayInfoWhileProcessing (_("Checking repository..."), @@ -448,6 +465,8 @@ splash.updateGauge('parcels') Utility.initParcels(view, parcelPath) + delayedImports() + # Now that the parcel world exists, save our locale for next time. self.saveLocale() @@ -490,8 +509,6 @@ splash.updateGauge('globalevents') globalEvents = self.UIRepositoryView.findPath('//parcels/osaf/framework/blocks/GlobalEvents') - from osaf.framework.blocks.Block import Block - Block.addToNameToItemUUIDDictionary (globalEvents.eventsForNamedLookup, Block.eventNameToItemUUID) @@ -623,8 +640,7 @@ def deleteAllBranchCaches (block): for child in block.childrenBlocks: deleteAllBranchCaches (child) - import osaf.framework.blocks.BranchPoint as BranchPoint - if isinstance (block, BranchPoint.BranchPointBlock): + if isinstance (block, BranchPointBlock): block.delegate.deleteCopiesFromCache() self.UIRepositoryView.refresh() @@ -630,10 +646,8 @@ self.UIRepositoryView.refresh() deleteAllBranchCaches(mainViewRoot) - from osaf.framework.blocks import Block - for item in self.UIRepositoryView['userdata'].iterChildren(): - if isinstance (item, Block.Block): + if isinstance (item, Block): item.delete() self.UIRepositoryView.commit() @@ -641,8 +655,6 @@ return mainViewRoot def RenderMainView (self): - from osaf.framework.blocks.Block import Block - mainViewRoot = self.mainFrame.mainViewRoot mainViewRoot.lastDynamicBlock = False mainViewRoot.render() @@ -658,7 +670,6 @@ sizer = wx.BoxSizer (wx.HORIZONTAL) self.mainFrame.SetSizer (sizer) - from osaf.framework.blocks.Block import wxRectangularChild sizer.Add (mainViewRoot.widget, mainViewRoot.stretchFactor, wxRectangularChild.CalculateWXFlag(mainViewRoot), @@ -674,7 +685,6 @@ EVT_MAIN_THREAD_CALLBACK(self, None) mainViewRoot = self.mainFrame.mainViewRoot.unRender() if __debug__: - from osaf.framework.blocks.Block import Block view = self.UIRepositoryView for uWatched, watchers in view._watchers.iteritems(): watchers = watchers.get(view.SUBSCRIBERS) @@ -735,7 +745,6 @@ Our events have ids greater than wx.ID_HIGHEST Delay imports to avoid circular references. """ - from osaf.framework.blocks.Block import Block wxID = event.GetId() block = Block.idToBlock.get (wxID, None) if block is not None: @@ -769,7 +778,7 @@ #wx.GetActiveWindow is implemented only on windows, so wet get the top #level parent of whatever window has the focus - if ((wxID > 0 and wxID < wx.ID_LOWEST) or + if ((0 < wxID < wx.ID_LOWEST) or not isinstance (wx.GetTopLevelParent(wx.Window.FindFocus()), wx.Dialog)): updateUIEvent = event.GetEventType() == wx.EVT_UPDATE_UI.evtType[0] @@ -810,7 +819,6 @@ event.Skip() def OnDestroyWindow(self, event): - from osaf.framework.blocks.Block import Block Block.wxOnDestroyWidget (event.GetWindow()) event.Skip() @@ -819,15 +827,11 @@ # object to get the wrong type because of a "feature" of SWIG. So we need to avoid # OnShows in this case by using ignoreSynchronizeWidget as a flag. - if not wx.GetApp().ignoreSynchronizeWidget: + if not self.ignoreSynchronizeWidget: widget = event.GetEventObject() - try: - block = widget.blockItem - except AttributeError: - pass - else: - if widget.IsShown() != event.GetShow(): - self.needsUpdateUI = True + if getattr(widget, 'blockItem', None) is not None and \ + widget.IsShown() != event.GetShow(): + self.needsUpdateUI = True event.Skip() @@ -851,7 +855,6 @@ self.fireAsynchronousNotifications() # synchronize dirtied blocks to reflect changes to the data - from osaf.framework.blocks.Block import Block # make the list first in case it gets tweaked during synchronizeWidget view = self.UIRepositoryView dirtyBlocks = [view[theUUID] for theUUID in Block.dirtyBlocks] @@ -888,7 +891,6 @@ # Give CPIA Script a chance to execute a script if not self.StartupScriptDone: self.StartupScriptDone = True - import osaf.framework.scripting as Scripting wx.CallAfter(Scripting.run_startup_script, self.UIRepositoryView) event.Skip() @@ -896,7 +898,6 @@ StartupScriptDone = False def OnKeyDown(self, event): - import osaf.framework.scripting as Scripting if Scripting.hotkey_script(event, self.UIRepositoryView): pass # consume the keystroke (the script is now running) else: @@ -1013,9 +1014,7 @@ Do a repository refresh to get the changes across from the other thread. """ - from osaf.framework.blocks.Block import Block - - wx.GetApp().UIRepositoryView.refresh () # bring changes across from the other thread/view + self.UIRepositoryView.refresh () # bring changes across from the other thread/view # unwrap the target item and find the method to call @@ -1074,7 +1073,7 @@ # convert all dictionary items for key,value in keyArgs.items(): keyArgs[key] = TransportWrapper (value) - wx.GetApp().PostAsyncEvent (self._DispatchItemMethod, item, + self.PostAsyncEvent (self._DispatchItemMethod, item, methodName, transportArgs, keyArgs) @@ -1088,7 +1087,6 @@ headless.view = view = self.UIRepositoryView def run(scriptText): - import osaf.framework.scripting as Scripting Scripting.run_script(scriptText, headless.view) # Import helper methods/variables from headless, and also add