def forceQuit(self): try: # This part is needed to quit on OS X from osaf.framework.blocks.Block import Block Block.postEventByNameWithSender ("Quit", {}) finally: sys.exit()
def forceQuit(self): try: # This part is needed to quit on OS X from osaf.framework.blocks.Block import Block Block.postEventByNameWithSender("Quit", {}) finally: sys.exit()
def getSidebarSelectedCollection (self): """ Return the sidebar's selected item collection. """ item = Block.findBlockByName ("Sidebar").selectedItemToView if not isinstance (item, ItemCollection): item = None return item return Block.findBlockByName ("Sidebar").selectedItemToView
def getSidebarSelectedCollection(self): """ Return the sidebar's selected item collection. """ item = Block.findBlockByName("Sidebar").selectedItemToView if not isinstance(item, ItemCollection): item = None return item return Block.findBlockByName("Sidebar").selectedItemToView
def onGenerateContentItemsEvent(self, event): # triggered from "Test | Generate Some Content Items" and # "Test | Generate Many Content Items" menu items count = event.arguments['sender'].blockName == 'GenerateMuchDataItem' and 100 or 4 sidebarCollection = Block.findBlockByName ("Sidebar").contents mainView = Globals.views[0] return GenerateItems.GenerateAllItems(self.itsView, count, mainView, sidebarCollection)
def onGenerateContentItemsEvent(self, event): # triggered from "Test | Generate Some Content Items" and # "Test | Generate Many Content Items" menu items count = event.arguments["sender"].blockName == "GenerateMuchDataItem" and 100 or 4 sidebarCollection = Block.findBlockByName("Sidebar").contents mainView = Globals.views[0] return GenerateItems.GenerateAllItems(self.itsView, count, mainView, sidebarCollection)
def importEmail(text, view, coll=None, selectedCollection=False): status, msg = osaf.mail.message.messageTextToKind(view, text) if selectedCollection or coll is None: coll = Block.findBlockByName("MainView").getSidebarSelectedCollection() if msg is not None: coll.add(msg.itsItem) return msg.itsItem
def compact(self, manual=False): view = self.itsView # view is MainThread view view.refresh() toVersion = sharing.getOldestVersion(view) versions = toVersion - self.lastVersion from osaf.framework.blocks.Block import Block setStatusMessage = Block.findBlockByName('StatusBar').setStatusMessage if versions < CompactTask.MIN_VERSIONS: # nothing much to do view.logger.info("Only %d versions to compact, skipping", versions) setStatusMessage(_(u"No data to purge...")) if manual: self.lastRun = self.lastCompact else: self.reschedule(CompactTask.REGULAR_INTERVAL) view.commit() return self.compacted = None def compact(progress): try: counts = view.repository.compact(toVersion, progressFn=progress) except: view.logger.exception("while compacting repository") setStatusMessage(_(u"Purging failed. Go to the Tools>>Logging>>Log Window... menu for details.")) self.compacted = False else: setStatusMessage(_(u'Reclaimed %(numItems)d items, %(numValues)d values, %(numRefs)d refs, %(numIndex)d index entries, %(numNames)d names, %(numLobs)d lobs, %(numBlocks)d blocks, %(numLucene)d lucene documents.') % {"numItems": counts[0], "numValues": counts[1], "numRefs": counts[2], "numIndex": counts[3], "numNames": counts[4], "numLobs": counts[5], "numBlocks": counts[6], "numLucene": counts[7]}) self.compacted = True dialog = CompactDialog(compact, self.lastCompact, versions) dialog.CenterOnScreen() cmd = dialog.ShowModal() dialog.Destroy() if cmd == wx.ID_OK: if self.compacted is True: self.lastVersion = int(toVersion) self.lastCompact = datetime.now() self.reschedule(CompactTask.REGULAR_INTERVAL) elif self.compacted is False: if manual: self.lastRun = self.lastCompact else: self.reschedule(CompactTask.RETRY_INTERVAL) elif manual: self.lastRun = self.lastCompact else: self.reschedule(CompactTask.RETRY_INTERVAL) view.commit()
def createCollections(collectionNames, view): sidebarCollections = [] for collName in collectionNames: if inTest: # create collections differently for unit tests col = pim.ListCollection("testCollection", itsView=view, displayName=collName.strip('\n')) else: col = Block.postEventByNameWithSender("NewCollection", {}) col.displayName = collName.strip('\n') sidebarCollections.append(col) return sidebarCollections
def execute_frame(option_value): logger.info(option_value) result = "PASSED" if option_value == 'all': testNames = test_modules.keys() else: testNames = [option_value] for name in testNames: if not run_test_by_name(name): result = "FAILED" # Process the Quit message, which will check and cleanup the repository # and do the normal close down of Chandler. Wrap this work in an except # block so we can log failures try: Block.postEventByNameWithSender ("Quit", {}) except Exception, e: logger.exception('Chandler "%s" has failed due to traceback' % name) result = "FAILED"
def on_p2p_SendMailEventUpdateUI(self, event): sidebar = Block.findBlockByName("Sidebar") collection = sidebar.contents.getFirstSelectedItem() if collection is not None: menuTitle = '&Send "%s" via p2p email' % (collection.displayName) event.arguments['Enable'] = True else: event.arguments['Enable'] = False menuTitle = '&Send ... via p2p email' event.arguments['Text'] = menuTitle
def on_p2p_SendMailEventUpdateUI(self, event): sidebar = Block.findBlockByName("Sidebar") collection = sidebar.contents.getFirstSelectedItem() if collection is not None: menuTitle = '&Send "%s" via p2p email' %(collection.displayName) event.arguments['Enable'] = True else: event.arguments['Enable'] = False menuTitle = '&Send ... via p2p email' event.arguments['Text'] = menuTitle
def getSidebarSelectedCollection(self, private=False): """ Return the sidebar's selected item collection. Will not return private collections (whose "private" attribute is True) unless you pass private=True. """ sidebar = Block.findBlockByName("Sidebar") item = sidebar.contents.getFirstSelectedItem() if (getattr(item, 'private', None) is not None and private == False and item.private): return None return item
def _SelectedItemScript(self): """ Return the poosible script item: the item shown in the Detail View, unless its body is empty. Otherwise return None. """ item = None try: item = Block.findBlockByName("DetailRoot").selectedItem() body = item.bodyString except AttributeError: pass else: if len(body) == 0: item = None return item
def on_p2p_AccessEvent(self, event): sidebar = Block.findBlockByName("Sidebar") collection = sidebar.contents.getFirstSelectedItem() view = self.itsView acl = collection.getACL('p2p', None) if acl is None: # for now, grant READ to everyone acl = ACL() acl.append(ACE(schema.ns('p2p', view).all.itsUUID, Permissions.READ)) collection.setACL(acl, 'p2p') else: collection.removeACL('p2p') view.commit()
def on_p2p_AccessEvent(self, event): sidebar = Block.findBlockByName("Sidebar") collection = sidebar.contents.getFirstSelectedItem() view = self.itsView acl = collection.getACL('p2p', None) if acl is None: # for now, grant READ to everyone acl = ACL() acl.append( ACE(schema.ns('p2p', view).all.itsUUID, Permissions.READ)) collection.setACL(acl, 'p2p') else: collection.removeACL('p2p') view.commit()
def on_p2p_AccessEventUpdateUI(self, event): sidebar = Block.findBlockByName("Sidebar") collection = sidebar.contents.getFirstSelectedItem() if collection is not None: acl = collection.getACL('p2p', None) if acl is None: op = 'Grant' else: op = 'Revoke' menuTitle = '%s peer &access to "%s"' %(op, collection.displayName) event.arguments['Enable'] = True else: event.arguments['Enable'] = False menuTitle = 'Grant peer &access to ...' event.arguments['Text'] = menuTitle
def __init__(self, parent, id, title=u'', position=wx.DefaultPosition, size=wx.DefaultSize, maxLineCount=1, style=0, staticControlDelegate=None, *args, **keys): super(AETypeOverTextCtrl, self).__init__(parent, id) staticSize = keys['staticSize'] del keys['staticSize'] self.hideLoc = (-100,-100) self.showLoc = (0,0) self.modelData = title self.staticControlDelegate = staticControlDelegate assert maxLineCount > 0 size.height *= maxLineCount editStyle = style | wx.WANTS_CHARS if maxLineCount > 1: editStyle |= wx.TE_MULTILINE|wx.TE_AUTO_SCROLL editControl = DragAndDropTextCtrl(self, -1, pos=position, size=size, style=editStyle, *args, **keys) blockName = Block.findBlockById(id, parent.blockItem).blockName editControl.SetName (blockName + "AEEditControl") self.editControl = editControl editControl.Bind(wx.EVT_KILL_FOCUS, self.OnEditLoseFocus) editControl.Bind(wx.EVT_SET_FOCUS, self.OnEditGainFocus) editControl.Bind(wx.EVT_LEFT_DOWN, self.OnEditClick) editControl.Bind(wx.EVT_LEFT_DCLICK, self.OnEditClick) editControl.Bind(wx.EVT_KEY_UP, self.OnEditKeyUp) # don't automatically resize the static control to snugly fit the text, # since any manipulation by the staticControlDelegate could cause it to # shrink down to nothing style |= wx.ST_NO_AUTORESIZE staticControl = AEStaticText(self, -1, pos=position, size=staticSize, style=style, *args, **keys) staticControl.SetName (blockName + "AEStaticControl") self.staticControl = staticControl staticControl.Bind(wx.EVT_LEFT_UP, self.OnStaticClick) self.Bind(wx.EVT_LEFT_UP, self.OnStaticClick) staticControl.Bind(wx.EVT_SIZE, self.OnSize) self.shownControl = staticControl self.otherControl = editControl self.shownControl.Move(self.showLoc) self.otherControl.Move(self.hideLoc) self._resize()
def on_p2p_AccessEventUpdateUI(self, event): sidebar = Block.findBlockByName("Sidebar") collection = sidebar.contents.getFirstSelectedItem() if collection is not None: acl = collection.getACL('p2p', None) if acl is None: op = 'Grant' else: op = 'Revoke' menuTitle = '%s peer &access to "%s"' % (op, collection.displayName) event.arguments['Enable'] = True else: event.arguments['Enable'] = False menuTitle = 'Grant peer &access to ...' event.arguments['Text'] = menuTitle
def nameToWidget (name): id = {"__wxID_OK__": wx.ID_OK, "__wxID_CANCEL__": wx.ID_CANCEL, "__wxID_YES__": wx.ID_YES, "__wxID_NO__": wx.ID_NO}.get (name, None) if id is not None: widget = wx.FindWindowById (id) assert isinstance (widget, wx.Button), \ "event %d -- Expected widget with id %s to be a button. Instead it is %s" \ % (eventNumber, name, sentTo, str(widget)) return widget elif name == "__none__": return None elif name.startswith ("__block__"): block = Block.findBlockByName (name [len ("__block__"):]) return block.widget else: return wx.FindWindowByName (name)
def _onShareOrManageSidebarCollectionEvent(self, event): """ Share the collection selected in the Sidebar. If the current collection is already shared, then manage the collection. In either case, the real work here is to tell the summary view to deselect, and the detail view that the selection has changed to the entire summary view's collection. The "Collection | Share collection " menu item """ collection = self.getSidebarSelectedCollection() if collection is not None: collection = self.getSidebarSelectedCollection() sidebar = Block.findBlockByName("Sidebar") if sidebar.filterKind is None: filterKindPath = None else: filterKindPath = str(sidebar.filterKind.itsPath) PublishCollection.ShowPublishDialog( wx.GetApp().mainFrame, view=self.itsView, collection=collection, filterKindPath=filterKindPath )
def onShareSidebarCollectionEventUpdateUI(self, event): """ Update the menu to reflect the selected collection name """ collection = self.getSidebarSelectedCollection() if collection is not None: sidebar = Block.findBlockByName("Sidebar") if sidebar.filterKind is None: filterKindPath = [] else: filterKindPath = [str(sidebar.filterKind.itsPath)] collName = Sharing.getFilteredCollectionDisplayName(collection, filterKindPath) menuTitle = _('Share "%s"...') % collName else: menuTitle = _("Share a collection...") event.arguments["Text"] = menuTitle event.arguments["Enable"] = collection is not None and (not Sharing.isShared(collection))
def onNewEvent (self, event): # Create a new Content Item # Triggered from "File | New Item" menu, for any of the item kinds. try: kindParam = event.kindParameter except AttributeError: kindParam = pim.Note.getKind(self.itsView) # default kind for "New" newItem = kindParam.newItem (None, None) newItem.InitOutgoingAttributes () self.RepositoryCommitWithStatus () # Tell the sidebar we want to go to the All collection self.postEventByName ('RequestSelectSidebarItem', {'itemName':u"All"}) # If the event cannot be displayed in this viewer, we need to switch to the all view viewFilter = Block.findBlockByName ("Sidebar").filterKind if not kindParam.isKindOf(viewFilter): self.postEventByName ('ApplicationBarAll', { }) # Tell the ActiveView to select our new item self.postEventByName ('SelectItemBroadcastInsideActiveView', {'item':newItem}) return [newItem]
def _onShareOrManageSidebarCollectionEvent(self, event): """ Share the collection selected in the Sidebar. If the current collection is already shared, then manage the collection. In either case, the real work here is to tell the summary view to deselect, and the detail view that the selection has changed to the entire summary view's collection. The "Collection | Share collection " menu item """ collection = self.getSidebarSelectedCollection () if collection is not None: collection = self.getSidebarSelectedCollection() sidebar = Block.findBlockByName("Sidebar") if sidebar.filterKind is None: filterKindPath = None else: filterKindPath = str(sidebar.filterKind.itsPath) PublishCollection.ShowPublishDialog(wx.GetApp().mainFrame, view=self.itsView, collection=collection, filterKindPath=filterKindPath)
def onNewEvent(self, event): # Create a new Content Item # Triggered from "File | New Item" menu, for any of the item kinds. try: kindParam = event.kindParameter except AttributeError: kindParam = pim.Note.getKind(self.itsView) # default kind for "New" newItem = kindParam.newItem(None, None) newItem.InitOutgoingAttributes() self.RepositoryCommitWithStatus() # Tell the sidebar we want to go to the All collection self.postEventByName("RequestSelectSidebarItem", {"itemName": u"All"}) # If the event cannot be displayed in this viewer, we need to switch to the all view viewFilter = Block.findBlockByName("Sidebar").filterKind if not kindParam.isKindOf(viewFilter): self.postEventByName("ApplicationBarAll", {}) # Tell the ActiveView to select our new item self.postEventByName("SelectItemBroadcastInsideActiveView", {"item": newItem}) return [newItem]
def onShareSidebarCollectionEventUpdateUI (self, event): """ Update the menu to reflect the selected collection name """ collection = self.getSidebarSelectedCollection () if collection is not None: sidebar = Block.findBlockByName("Sidebar") if sidebar.filterKind is None: filterKindPath = [] else: filterKindPath = [str(sidebar.filterKind.itsPath)] collName = Sharing.getFilteredCollectionDisplayName(collection, filterKindPath) menuTitle = _('Share "%s"...') % collName else: menuTitle = _('Share a collection...') event.arguments ['Text'] = menuTitle event.arguments['Enable'] = collection is not None and (not Sharing.isShared(collection))
def run_tests(tests, debug=testDebug, mask=testMask, logName=logFileName): """Method to execute cats tests, must be in Functional directory.""" logger = TestOutput(stdout=True, debug=debug, mask=mask, logName=logName) testList = tests.split(',') statusBar = Block.findBlockByName("StatusBar") totalTests = len(tests.split(',')) curTest = 0 if len(testList) < 2: logger.startSuite(name=testList[0].split(':')[0]) else: logger.startSuite(name='ChandlerFunctionalTestSuite') # We'll normally run individual tests with an exception wrapper; # --catch=never will turn it off, so that a debugger can stop on # uncaught exceptions. runner = Globals.options.catch != 'never' and run_test_wrapped or run_test for paramSet in testList: curTest += 1 statusBar.setStatusMessage( "Test %d of %d %s" % (curTest, totalTests, paramSet.split(":")[0])) runner(logger, paramSet) if haltOnFailure and logger.testHasFailed: logger.report(False, 'Suite halted on test failure') logger.testsSkipped = len( tests.split(',')) - (tests.split(',').index(paramSet) + 1) break if logger.debug < 2: checkRepo(logger) logger.endSuite() if logger.debug == 0: logger.easyReadSummary() else: logger.summary() logger.simpleSummary() logger.tinderOutput() scripting.app_ns().root.Quit()
def onSyncCollectionEventUpdateUI(self, event): """ Update the menu to reflect the selected collection name """ collection = self.getSidebarSelectedCollection() if collection is not None: sidebar = Block.findBlockByName("Sidebar") if sidebar.filterKind is None: filterKindPath = [] else: filterKindPath = [str(sidebar.filterKind.itsPath)] collName = Sharing.getFilteredCollectionDisplayName(collection, filterKindPath) menuTitle = _('Sync "%s"') % collName if Sharing.isShared(collection): event.arguments["Enable"] = True else: event.arguments["Enable"] = False else: event.arguments["Enable"] = False menuTitle = _("Sync a collection") event.arguments["Text"] = menuTitle
def run_tests(tests, debug=testDebug, mask=testMask, logName=logFileName): """Method to execute cats tests, must be in Functional directory.""" logger = TestOutput(stdout=True, debug=debug, mask=mask, logName=logName) testList = tests.split(',') statusBar = Block.findBlockByName("StatusBar") totalTests = len(tests.split(',')) curTest = 0 if len(testList) < 2: logger.startSuite(name = testList[0].split(':')[0]) else: logger.startSuite(name='ChandlerFunctionalTestSuite') # We'll normally run individual tests with an exception wrapper; # --catch=never will turn it off, so that a debugger can stop on # uncaught exceptions. runner = Globals.options.catch != 'never' and run_test_wrapped or run_test for paramSet in testList: curTest += 1 statusBar.setStatusMessage("Test %d of %d %s" % (curTest, totalTests, paramSet.split(":")[0])) runner(logger, paramSet) if haltOnFailure and logger.testHasFailed: logger.report(False, 'Suite halted on test failure') logger.testsSkipped = len(tests.split(',')) - (tests.split(',').index(paramSet) + 1) break if logger.debug < 2: checkRepo(logger) logger.endSuite() if logger.debug == 0: logger.easyReadSummary() else: logger.summary() logger.simpleSummary() logger.tinderOutput() scripting.app_ns().root.Quit()
def onPluginEvent(self, event): msg = '' statusBar = Block.findBlockByName('StatusBar') statusBar.setStatusMessage(msg) subMenu = self.widget.GetSubMenu() menuItem = subMenu.FindItemById(event.arguments["wxEvent"].GetId()) name = menuItem.GetText() plugin_env = pkg_resources.Environment(Globals.options.pluginPath) pluginPrefs = subMenu.pluginPrefs if pluginPrefs.get(name, 'active') == 'active': for egg in plugin_env[name]: break else: return for ep in pkg_resources.iter_entry_points('chandler.parcels'): if plugin_env[ep.dist.key]: # only handle plugin entrypoints requires = ep.dist.requires(ep.extras) if egg in pkg_resources.working_set.resolve(requires): if pluginPrefs.get(ep.dist.key, 'inactive') == 'active': dlg = wx.MessageDialog( None, _(u"%(pluginName)s is required by %(eggName)s.\n\n%(eggName)s must be deactivated first." ) % { 'eggName': ep.dist.egg_name(), 'pluginName': egg.egg_name() }, _(u"Error"), wx.OK | wx.ICON_ERROR) cmd = dlg.ShowModal() dlg.Destroy() return dlg = wx.MessageDialog( None, _(u"All items created by plugin %(pluginName)s will be deleted." ) % {'pluginName': egg.egg_name()}, _(u"Confirm Deactivation"), (wx.YES_NO | wx.YES_DEFAULT | wx.ICON_EXCLAMATION)) cmd = dlg.ShowModal() dlg.Destroy() if cmd == wx.ID_YES: egg = self.deactivatePlugin(name, plugin_env) if egg is not None: msg = _(u"%(pluginName)s was deactivated.") % { 'pluginName': egg.egg_name() } else: return else: return else: egg, dependencies = self.activatePlugin(name, plugin_env) if egg is not None: if not dependencies: msg = _(u"%(pluginName)s was activated.") % { 'pluginName': egg.egg_name() } else: msg = _( u"%(pluginName)s and %(pluginNames)s were activated." ) % { 'pluginName': egg.egg_name(), 'pluginNames': ', '.join([dist.egg_name() for dist in dependencies]) } else: return # Update the menus self.synchronizeWidget() self.refreshMenus(self.itsView) statusBar.setStatusMessage(msg)
def __init__(self, parent, id, title=u'', position=wx.DefaultPosition, size=wx.DefaultSize, maxLineCount=1, style=0, staticControlDelegate=None, *args, **keys): super(AETypeOverTextCtrl, self).__init__(parent, id) staticSize = keys['staticSize'] del keys['staticSize'] self.hideLoc = (-100, -100) self.showLoc = (0, 0) self.modelData = title self.staticControlDelegate = staticControlDelegate assert maxLineCount > 0 size.height *= maxLineCount editStyle = style | wx.WANTS_CHARS if maxLineCount > 1: editStyle |= wx.TE_MULTILINE | wx.TE_AUTO_SCROLL editControl = DragAndDropTextCtrl(self, -1, pos=position, size=size, style=editStyle, *args, **keys) blockName = Block.findBlockById(id, parent.blockItem).blockName editControl.SetName(blockName + "AEEditControl") self.editControl = editControl editControl.Bind(wx.EVT_KILL_FOCUS, self.OnEditLoseFocus) editControl.Bind(wx.EVT_SET_FOCUS, self.OnEditGainFocus) editControl.Bind(wx.EVT_LEFT_DOWN, self.OnEditClick) editControl.Bind(wx.EVT_LEFT_DCLICK, self.OnEditClick) editControl.Bind(wx.EVT_KEY_UP, self.OnEditKeyUp) # don't automatically resize the static control to snugly fit the text, # since any manipulation by the staticControlDelegate could cause it to # shrink down to nothing style |= wx.ST_NO_AUTORESIZE staticControl = AEStaticText(self, -1, pos=position, size=staticSize, style=style, *args, **keys) staticControl.SetName(blockName + "AEStaticControl") self.staticControl = staticControl staticControl.Bind(wx.EVT_LEFT_UP, self.OnStaticClick) self.Bind(wx.EVT_LEFT_UP, self.OnStaticClick) staticControl.Bind(wx.EVT_SIZE, self.OnSize) self.shownControl = staticControl self.otherControl = editControl self.shownControl.Move(self.showLoc) self.otherControl.Move(self.hideLoc) self._resize()
def OnDestroyWindow(self, event): from osaf.framework.blocks.Block import Block Block.wxOnDestroyWidget (event.GetWindow()) event.Skip()
def addItemToAllCollection(self, item): for coll in Block.findBlockByName("Sidebar").contents: if coll.displayName == "All": coll.add(item) return
def ProcessEvent (line, theClass, properties, attributes): def nameToWidget (name): id = {"__wxID_OK__": wx.ID_OK, "__wxID_CANCEL__": wx.ID_CANCEL, "__wxID_YES__": wx.ID_YES, "__wxID_NO__": wx.ID_NO}.get (name, None) if id is not None: widget = wx.FindWindowById (id) assert isinstance (widget, wx.Button), \ "event %d -- Expected widget with id %s to be a button. Instead it is %s" \ % (eventNumber, name, sentTo, str(widget)) return widget elif name == "__none__": return None elif name.startswith ("__block__"): block = Block.findBlockByName (name [len ("__block__"):]) return block.widget else: return wx.FindWindowByName (name) application = wx.GetApp() eventNumber = application.eventsIndex - 1 if wx.Platform == "__WXMAC__": window = wx.Window_FindFocus() if isinstance (window, wx.Window): windowName = window.GetName() else: windowName = "" application.ProcessIdle() application.Yield (True) application.mainFrame.Update() if wx.Platform == "__WXMAC__": window = wx.Window_FindFocus() if isinstance (window, wx.Window): windowName = window.GetName() else: windowName = "" sentTo = properties ["sentTo"] sentToWidget = nameToWidget (sentTo) assert (isinstance (sentToWidget, wx.Window) or isinstance (sentToWidget, wx.Menu) or isinstance (sentToWidget, wx.MenuItem) or isinstance (sentToWidget, wx.ToolBarTool), \ "event %d -- Unexpected type of widget: sentTo is %s; sendToWidget is %s" % (eventNumber, sentTo, str(sentToWidget))) if isinstance (sentToWidget, wx.ToolBarTool): assert sentToWidget.IsControl() sentToWidget = sentToWidget.GetControl() elif isinstance (sentToWidget, wx.MenuItem): assert sentToWidget.IsSubMenu() sentToWidget = sentToWidget.GetSubMenu() eventType = properties["eventType"] if theClass is not wx.grid.GridEvent: event = theClass() for (attribute, value) in attributes.iteritems(): setattr (event, attribute, value) else: # Unfortunately, wx.grid.GridEvent doesn't have setters and getters. Eventually # I will add this to wxWidgets and remove this special case code -- DJA position = attributes ["Position"] event = wx.grid.GridEvent (-1, eventType.evtType[0], Block.findBlockByName (sentTo).widget, row = attributes ["Row"], col = attributes ["Col"], x = position [0], y = position [1]) event.SetEventObject (sentToWidget) event.SetEventType (eventType.evtType[0]) # Use the associated block if present to set the Id of the event associatedBlock = properties.get ("associatedBlock", None) if associatedBlock is not None: id = Block.findBlockByName (associatedBlock).widget.GetId() else: GetIdMethod = getattr (sentToWidget, "GetId", None) assert GetIdMethod is not None, "event %d -- Unexpected widget, doesn't have GetId: sentTo is %s; sendToWidget is %s" % (eventNumber, sentTo, str(sentToWidget)) id = GetIdMethod() event.SetId (id) # Special case clicks on checkboxes to toggle the widget's value # And special case wx.Choice to set the selection. Both of these # are necessary before the event is processed so the GetValue # validation passes if eventType is wx.EVT_CHECKBOX: sentToWidget.SetValue (not sentToWidget.GetValue()) # andSpecial case wx,Choice to set the selection elif eventType is wx.EVT_CHOICE or eventType is wx.EVT_LISTBOX: selectedItem = properties ["selectedItem"] event.SetInt (selectedItem) sentToWidget.SetSelection (selectedItem) # A bug in wxWidgets on Windows stores the wrong value for m_rawCode in wx.EVT_CHAR # Since the correct valus is stored in wx.EVT_KEY_DOWN and wx.EVT_KEY_DOWN # precedes wx.EVT_KEY_DOWN, we'll cache it for the next wx.EVT_KEY_DOWN # Raw key codes are only used on Windows. There they correspond to virtual # keycodes. For this reason we record scripts on Windows to play back on the # other platforms. if eventType is wx.EVT_KEY_DOWN: ProcessEvent.last_rawCode = event.m_rawCode # Track contents of clipboard in events with the clipboard property contents = properties.get ("clipboard", None) if contents is not None: # Work around for bug # success = wx.TheClipboard.Open() assert success, "event %d -- The clipboard can't be opened" % eventNumber success = wx.TheClipboard.SetData (wx.TextDataObject (contents)) assert success, "event %d -- Clipboard SetData failed" % eventNumber data = wx.TextDataObject() success = wx.TheClipboard.GetData (data) assert success, "event %d -- Clipboard GetData failed. This is often caused by a bug in Parallels, try turning off Clipboard Synchronization" % eventNumber value = data.GetText() # Work around for bug #11699 if wx.Platform != "__WXMAC__": assert value == contents, 'event %d -- Clipboard broken: set: "%s"; got: "%s"' % (eventNumber, contents, value) wx.TheClipboard.Close() # Verify script if necessary if schema.ns('osaf.framework.script_recording', application.UIRepositoryView).RecordingController.verifyScripts: lastSentToWidget = ProcessEvent.lastSentToWidget # Make sure the menu or button is enabled if eventType is wx.EVT_MENU: updateUIEvent = wx.UpdateUIEvent (event.GetId()) updateUIEvent.SetEventObject (sentToWidget) sentToWidget.ProcessEvent (updateUIEvent) assert updateUIEvent.GetEnabled() is True,\ "event %d -- You're sending a command to a disable menu" % eventNumber # Check to makee sure we're focused to the right window recordedFocusWindow = properties.get ("recordedFocusWindow", None) if recordedFocusWindow is not None: recordedFocusWindowClass = properties["recordedFocusWindowClass"] focusWindow = wx.Window_FindFocus() # On Macintosh there is a setting under SystemPreferences>Keyboar&Mouse>KeyboardShortcuts # neare the bottom of the page titled "Full Keyboard Access" that defaults to # not letting you set the focus to certain controls, e.g. CheckBoxes. So we # don't verify the focus in those cases. # # On Linux events sent to toolbar cause the focus window to become None # # Also, when lastSentToWidget is None the focus window may not be accurate. if not ( (wx.Platform == "__WXMAC__" and issubclass (recordedFocusWindowClass, wx.CheckBox)) or (wx.Platform == "__WXGTK__" and isinstance (sentToWidget, wx.ToolBar)) or lastSentToWidget is None): if focusWindow is None: focusWindowName = "None" else: focusWindowName = focusWindow.GetName() assert focusWindow is nameToWidget (recordedFocusWindow),\ "event %d -- Focus is: %s; expecting: %s" % (eventNumber, focusWindowName, recordedFocusWindow) # Check to make sure last event caused expected change if lastSentToWidget is not None and not isinstance (lastSentToWidget, wx._core._wxPyDeadObject): GetValueMethod = getattr (lastSentToWidget, "GetValue", None) else: GetValueMethod = None if GetValueMethod is not None: lastWidgetValue = properties.get ("lastWidgetValue", None) if lastWidgetValue is not None: value = GetValueMethod() assert value == lastWidgetValue,\ 'event %d -- widget %s value, "%s" doesn\'t match the value when the script was recorded: "%s"; application.IsActive() is %s'\ % (eventNumber, ProcessEvent.lastSentTo, value, lastWidgetValue, str(application.IsActive())) # Keep track of the last widget. Use Id because widget can be deleted # Return characters with wx.EVT_CHAR events cause problems with verification so we won't verify # this case. I think that the reason verification is a problem her is because our emulation of # these events is slighty from different from the way they are handled by the OS when we record the script. if attributes.get ("UnicodeKey", 0) == 13 and (eventType is wx.EVT_CHAR or eventType is wx.EVT_KEY_DOWN): ProcessEvent.lastSentToWidget = None else: ProcessEvent.lastSentToWidget = sentToWidget ProcessEvent.lastSentTo = sentTo processed = False if eventType is wx.EVT_SET_FOCUS: if wx.Window_FindFocus() is not sentToWidget: # Setting your focus to the window that has the focus causes the # window to lose focus on Windows sentToWidget.SetFocus() # On Linux we occasionally need to Yield for the Focus to be properly set if wx.Window_FindFocus() is not sentToWidget: application.Yield (True) focusWindow = wx.Window.FindFocus() if focusWindow is not sentToWidget: if isinstance (focusWindow, wx.Window): focusWindowName = focusWindow.GetName() else: focusWindowName = "" assert False, \ "event %d -- SetFocus failed; Focus is: %s; expecting: %s; application.IsActive() is %s" \ % (eventNumber, focusWindowName, sentTo, str(application.IsActive())) else: if wx.Platform != "__WXMSW__" or eventType not in ignoreMSWEvents: # On windows we ignore certain events that are generated as a side effect of other events if not sentToWidget.ProcessEvent (event): processed = True if (eventType is wx.EVT_KEY_DOWN and event.m_keyCode in set ((wx.WXK_ESCAPE, wx.WXK_TAB, wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER))): # Special case key downs that end edits in the grid gridWindow = sentToWidget.GetParent() if (gridWindow is not None and isinstance (gridWindow.GetParent(), wx.grid.Grid)): event.SetEventObject (gridWindow) gridWindow.ProcessEvent (event) elif eventType is wx.EVT_CHAR and not event.m_controlDown: # Make sure the selection is valid if __debug__: GetSelectionMethod = getattr (sentToWidget, "GetSelection", None) if GetSelectionMethod is not None: (start, end) = GetSelectionMethod() assert start >= 0 and end >= 0 and start <= end # Try EmulateKeyPress EmulateKeyPress = getattr(sentToWidget, 'EmulateKeyPress', None) if EmulateKeyPress is not None: # On Linx if we call EmulateKeyPress with a return character in a # single line textCtrl it will insert a return character. UnicodeKey = event.UnicodeKey if (UnicodeKey != 13 or sentToWidget.IsMultiLine()): # A bug in wxWidgets on Windows stores the wrong value for m_rawCode in wx.EVT_CHAR # Since the correct valus is stored in wx.EVT_KEY_DOWN and wx.EVT_KEY_DOWN # precedes wx.EVT_KEY_DOWN, we'll cache it for the next wx.EVT_KEY_DOWN event.m_rawCode = ProcessEvent.last_rawCode # Also on Linux we need to translate returns to line feeds. if wx.Platform == "__WXGTK__" and UnicodeKey == 13: event.UnicodeKey = 10 EmulateKeyPress (event) selectionRange = properties.get ("selectionRange", None) if selectionRange is not None: (start, end) = selectionRange # On windows GetValue uses "\n" for end of lines, but the widget stores # "\n\r" for end of lines and SetSelection uses offsets that include # the extra "\r" characters if wx.Platform == "__WXMSW__": value = sentToWidget.GetValue() start = start + value.count ('\n', 0, start) end = end + value.count ('\n', 0, end) sentToWidget.SetSelection (start, end) window = wx.Window_FindFocus() if isinstance (window, wx.Window): windowName = window.GetName() else: windowName = "" # On windows when we propagate notifications while editing a text control # it will end up calling wxSynchronizeWidget in wxTable, which will end the # editing of the table if not isinstance (sentToWidget, wx.TextCtrl): application.propagateAsynchronousNotifications() # Since scrips don't actually move the cursor and cause wxMouseCaptureLostEvents # to be generated we'll periodically release the capture from all the windows. # Alternatively, it might be better to record and playback wxMouseCaptureLostEvents. while True: capturedWindow = wx.Window.GetCapture() if capturedWindow is not None: capturedWindow.ReleaseMouse() else: break
def importICalendarFile(fullpath, view, targetCollection = None, filterAttributes = None, activity=None, tzinfo = None, logger=None, selectedCollection = False): """Import ics file at fullpath into targetCollection. If selectedCollection is True, ignored targetCollection and import into the currently selected sidebar collection. If Trash is chosen as the target collection, a new collection will be created instead. """ from osaf.framework.blocks.Block import Block import translator, ics from osaf import sharing if selectedCollection: targetCollection = Block.findBlockByName("MainView").getSidebarSelectedCollection() trash = schema.ns("osaf.pim", view).trashCollection if targetCollection == trash: targetCollection = None view.commit(sharing.mergeFunction) # to make target collection available # Note: if everyone is following the commit rules that says a commit # happens after every user action, this commit is not required. rv = sharing.getView(view.repository) if targetCollection is not None: targetCollection = rv.findUUID(targetCollection.itsUUID) if not os.path.isfile(fullpath): raise ICalendarImportError(_(u"File does not exist, import cancelled.")) before = epoch_time() (dir, filename) = os.path.split(fullpath) try: # TODO: coerceTzinfo? import stateless try: collection = stateless.importFile(rv , fullpath, collection=targetCollection, filters=filterAttributes, activity=activity) except: if logger: logger.exception("Failed importFile %s" % fullpath) raise ICalendarImportError(_(u"Problem with the file, import cancelled.")) if targetCollection is None: collectionName = getattr(collection, 'displayName', 'Untitled') if collectionName == 'Untitled': name = "".join(filename.split('.')[0:-1]) or filename collection.displayName = name rv.commit(sharing.mergeFunction) # makes new collection available view.refresh(sharing.mergeFunction) # main ui repo view finally: sharing.releaseView(rv) collection = view.findUUID(collection.itsUUID) if targetCollection is None: schema.ns("osaf.app", view).sidebarCollection.add(collection) sideBarBlock = Block.findBlockByName('Sidebar') sideBarBlock.postEventByName ("SelectItemsBroadcast", {'items':[collection]}) if logger: logger.info("Imported collection in %s seconds" % (epoch_time()-before)) return collection
def setStatusMessage(self, msg): Block.findBlockByName('StatusBar').setStatusMessage(msg)
# See the License for the specific language governing permissions and # limitations under the License. import wx import tools.QAUITestAppLib as QAUITestAppLib from osaf.framework.blocks.Block import Block from osaf.framework.scripting import User from application import schema # Test Phase: Initialization logger = QAUITestAppLib.QALogger("PerfLargeDataQuickEntry.log", "QuickEntry") try: testView = QAUITestAppLib.UITestView(logger) block = Block.findBlockByName("ApplicationBarQuickEntry") quickEntryWidget = block.widget quickEntryWidget.SetFocus() User.emulate_typing("Dinner at 7 pm tomorrow night") # XXX I'd really just like to be able to call User.emulate_return() in the # XXX timed part below, but for some reason it does not work. keyEvent = wx.KeyEvent() keyEvent.m_keyCode = wx.WXK_RETURN keyEvent.arguments = {'sender': block} mainView = schema.ns("osaf.views.main", wx.GetApp().UIRepositoryView).MainView # Time how long it takes to create the event starting from pressing ENTER logger.Start("Quick entry")
# limitations under the License. import wx import tools.QAUITestAppLib as QAUITestAppLib from osaf.framework.blocks.Block import Block from osaf.framework.scripting import User from application import schema # Test Phase: Initialization logger = QAUITestAppLib.QALogger("PerfLargeDataQuickEntry.log", "QuickEntry") try: testView = QAUITestAppLib.UITestView(logger) block = Block.findBlockByName("ApplicationBarQuickEntry") quickEntryWidget = block.widget quickEntryWidget.SetFocus() User.emulate_typing("Dinner at 7 pm tomorrow night") # XXX I'd really just like to be able to call User.emulate_return() in the # XXX timed part below, but for some reason it does not work. keyEvent = wx.KeyEvent() keyEvent.m_keyCode = wx.WXK_RETURN keyEvent.arguments = {'sender': block} mainView = schema.ns("osaf.views.main", wx.GetApp().UIRepositoryView).MainView # Time how long it takes to create the event starting from pressing ENTER logger.Start("Quick entry")
def __init__(self, dialogTitle, view): options = [ dict(name='cid:[email protected]', checked=True, label=_(u"Import &reminders")), dict(name='cid:[email protected]', checked=True, label=_(u"Import event &status")) ] FileChooserWithOptions.__init__( self, dialogTitle, schema.ns("osaf.sharing", view).prefs.import_dir, _(u"iCalendar files|*.ics|All files (*.*)|*.*"), wx.OPEN, options) self.Bind(wx.EVT_BUTTON, self.onOK, id=wx.ID_OK) self.Bind(wx.EVT_BUTTON, self.onCancel, id=wx.ID_CANCEL) sidebarCollection = schema.ns("osaf.app", view).sidebarCollection trash = schema.ns("osaf.pim", view).trashCollection selected = Block.findBlockByName( "MainView").getSidebarSelectedCollection() # create a collection chooser gs = wx.FlexGridSizer(2, 2, 2, 2) # rows, cols, hgap, vgap self.chooserLabel = wx.StaticText(self, -1, _(u"Import e&vents into:")) gs.Add(self.chooserLabel, 0, wx.ALL, 3) self.choices = [ col for col in sidebarCollection if (col is not selected) and not isReadOnly(col) and not UserCollection(col).outOfTheBoxCollection ] selectNew = schema.ns("osaf.sharing", view).prefs.import_as_new if selected == trash or isReadOnly(selected): selectNew = True else: self.choices.insert(0, selected) displayChoices = [_(u"New collection")] displayChoices.extend(col.displayName for col in self.choices) self.choices.insert(0, None) # make choice indices match displayChoice self.chooser = wx.Choice(self, -1, choices=displayChoices) self.chooser.Bind(wx.EVT_CHOICE, self.OnCollChoice) if selectNew: self.chooser.SetSelection(0) else: self.chooser.SetSelection(1) gs.Add(self.chooser, 0, wx.ALIGN_LEFT, 0) self.box.Insert(1, gs, 0, wx.LEFT, 16) self.mine = wx.CheckBox(self, -1, _(u"Keep out of Dashboard")) self.mine.SetValue(False) self.box.Insert(2, self.mine, 0, wx.ALL, 3) self.feedbackBox = wx.BoxSizer(wx.VERTICAL) self.gauge = wx.Gauge(self, size=(360, 15)) self.feedbackBox.Add(self.gauge, 0, wx.ALL | wx.ALIGN_CENTER, 10) self.progressText = wx.StaticText(self, -1, _(u"Starting import...")) self.feedbackBox.Add(self.progressText, wx.ALIGN_LEFT) self.box.Insert(3, self.feedbackBox, 0, wx.ALL | wx.ALIGN_CENTER, 10) self.box.Hide(self.feedbackBox) self.box.Fit(self) self.cancelling = False self.view = view
def OnDestroyWindow(self, event): from osaf.framework.blocks.Block import Block Block.wxOnDestroyWidget(event.GetWindow()) event.Skip()
def OnCommand(self, event): """ Catch commands and pass them along to the blocks. 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() if wxID > wx.ID_HIGHEST: block = Block.widgetIDToBlock(wxID) updateUIEvent = event.GetEventType() == wx.EVT_UPDATE_UI.evtType[0] try: blockEvent = block.event except AttributeError: """ Ignore blocks that don't have events. """ assert updateUIEvent else: arguments = {} if updateUIEvent: arguments['UpdateUI'] = True else: try: arguments['buttonState'] = event.GetEventObject( ).GetToolState(wxID) except AttributeError: pass block.post(blockEvent, arguments) if updateUIEvent: try: event.Check(arguments['Check']) except KeyError: pass try: enable = arguments['Enable'] except KeyError: enable = True event.Enable(enable) try: text = arguments['Text'] except KeyError: pass else: event.SetText(text) widget = block.widget """ Some widgets, e.g. wxToolbarItems don't properly handle setting the text of buttons, so we'll handle it here by looking for the method OnSetTextEvent to handle it """ try: method = widget.OnSetTextEvent except AttributeError: pass else: method(event) else: event.Skip()
def on_p2p_SendMailEvent(self, event): sidebar = Block.findBlockByName("Sidebar") collection = sidebar.contents.getFirstSelectedItem() sendmail(collection)
def OnInit(self): util.timing.begin("wxApplication OnInit") #@@@Temporary testing tool written by Morgen -- DJA """ Main application initialization. """ self.needsUpdateUI = True self.ignoreSynchronizeWidget = True self.focus = None wx.InitAllImageHandlers() """ Disable automatic calling of UpdateUIEvents. We will call them manually when blocks get rendered, change visibility, etc. """ wx.UpdateUIEvent.SetUpdateInterval (-1) """ Install a custom displayhook to keep Python from setting the global _ (underscore) to the value of the last evaluated expression. If we don't do this, our mapping of _ to gettext can get overwritten. This is useful in interactive debugging with PyShell. """ def _displayHook(obj): if obj is not None: print repr(obj) sys.displayhook = _displayHook assert Globals.wxApplication == None, "We can have only one application" Globals.wxApplication = self """ Initialize PARCELPATH and sys.path """ parcelPath = Utility.initParcelEnv(Globals.chandlerDirectory, Globals.options.parcelPath) """ Splash Screen. We don't show the splash screen when nosplash is set """ splash = None if not Globals.options.nosplash: splashBitmap = self.GetImage ("splash.png") splash=StartupSplash(None, splashBitmap) splash.Show() wx.Yield() #let the splash screen render itself """ Setup internationalization To experiment with a different locale, try 'fr' and wx.LANGUAGE_FRENCH """ os.environ['LANGUAGE'] = 'en' # self.locale = wx.Locale(wx.LANGUAGE_ENGLISH) """ @@@ Sets the python locale, used by wx.CalendarCtrl for month and weekday names. When running on Linux, 'en' is not understood as a locale, nor is 'fr'. On Windows, you can try 'fr'. locale.setlocale(locale.LC_ALL, 'en') """ # wx.Locale_AddCatalogLookupPathPrefix('locale') # self.locale.AddCatalog('Chandler.mo') gettext.install('chandler', 'locale') """ Crypto initialization """ if splash: splash.updateGauge('crypto') Utility.initCrypto(Globals.options.profileDir) if splash: splash.updateGauge('repository') # The repository opening code was moved to a method so that it can # be called again if there is a schema mismatch and the user chooses # to reopen the repository in create mode. repoDir = Utility.locateRepositoryDirectory(Globals.options.profileDir) try: view = Utility.initRepository(repoDir, Globals.options) except RepositoryVersionError: if self.ShowSchemaMismatchWindow(): Globals.options.create = True view = Utility.initRepository(repoDir, Globals.options) else: raise Utility.SchemaMismatchError self.repository = view.repository """ Verify Schema Version """ if not Utility.verifySchema(view): if self.ShowSchemaMismatchWindow(): # Blow away the repository self.repository.close() Globals.options.create = True view = Utility.initRepository(repoDir, Globals.options) self.repository = view.repository else: raise Utility.SchemaMismatchError self.UIRepositoryView = view # make our view be the default for schema API # so when we say myClass.iterItems() and leave off the view # we get the UI repository view. schema.reset(self.UIRepositoryView) """ Load Parcels """ if splash: splash.updateGauge('parcels') wx.Yield() Utility.initParcels(view, parcelPath) EVT_MAIN_THREAD_CALLBACK(self, self.OnMainThreadCallbackEvent) """ The Twisted Reactor should be started before other Managers and stopped last. """ if splash: splash.updateGauge('twisted') Utility.initTwisted() mainViewRoot = self.LoadMainViewRoot(delete=Globals.options.refreshui) if (mainViewRoot.position.x == -1 and mainViewRoot.position.y == -1): position = wx.DefaultPosition else: position = (mainViewRoot.position.x, mainViewRoot.position.y) # arel: fix for bug involving window size and toolbar on MacOS (bug 3411). # The problem is that mainFrame gets resized when it is rendered # (particularly when the toolbar gets rendered), increasing the window's # height by the height of the toolbar. We fix by remembering the # (correct) size before rendering and resizing. rememberSize = (mainViewRoot.size.width, mainViewRoot.size.height) self.mainFrame = MainFrame(None, -1, "Chandler", pos=position, size=(mainViewRoot.size.width, mainViewRoot.size.height), style=wx.DEFAULT_FRAME_STYLE) mainViewRoot.frame = self.mainFrame """ Register to some global events for name lookup. """ if splash: 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) self.ignoreSynchronizeWidget = False if splash: splash.updateGauge('mainview') self.RenderMainView () if Globals.options.profile: import hotshot, hotshot.stats prof = hotshot.Profile(os.path.join(Globals.options.profileDir, 'commit.log')) prof.runcall(self.UIRepositoryView.commit) prof.close() stats = hotshot.stats.load(os.path.join(Globals.options.profileDir, 'commit.log')) stats.strip_dirs() stats.sort_stats('time', 'calls') stats.print_stats(125) else: wx.Yield() self.UIRepositoryView.commit() if splash: splash.Destroy() #OnDestroyWindow Binding has to appear after splash.Destroy self.Bind(wx.EVT_IDLE, self.OnIdle) self.Bind(wx.EVT_MENU, self.OnCommand, id=-1) self.Bind(wx.EVT_TOOL, self.OnCommand, id=-1) self.Bind(wx.EVT_UPDATE_UI, self.OnCommand, id=-1) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroyWindow, id=-1) self.Bind(wx.EVT_SHOW, self.OnShow, id=-1) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) # resize to intended size. (bug 3411) self.mainFrame.SetSize(rememberSize) self.mainFrame.Show() """Start the WakeupCaller Service""" Utility.initWakeup(self.UIRepositoryView.repository) """Start the Chandler Mail Service""" from osaf.mail.mailservice import MailService Globals.mailService = MailService(self.UIRepositoryView.repository) Globals.mailService.startup() util.timing.end("wxApplication OnInit") #@@@Temporary testing tool written by Morgen -- DJA # data loading script execution if Globals.options.createData: import tools.GenerateItemsFromFile as GenerateItemsFromFile GenerateItemsFromFile.RunScript(Globals.mainViewRoot.itsView, Globals.views[0]) return True #indicates we succeeded with initialization
def OnCommand(self, event): """ Catch commands and pass them along to the blocks. 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() if wxID > wx.ID_HIGHEST: block = Block.widgetIDToBlock (wxID) updateUIEvent = event.GetEventType() == wx.EVT_UPDATE_UI.evtType[0] try: blockEvent = block.event except AttributeError: """ Ignore blocks that don't have events. """ assert updateUIEvent else: arguments = {} if updateUIEvent: arguments ['UpdateUI'] = True else: try: arguments ['buttonState'] = event.GetEventObject().GetToolState (wxID) except AttributeError: pass block.post (blockEvent, arguments) if updateUIEvent: try: event.Check (arguments ['Check']) except KeyError: pass try: enable = arguments ['Enable'] except KeyError: enable = True event.Enable (enable) try: text = arguments ['Text'] except KeyError: pass else: event.SetText (text) widget = block.widget """ Some widgets, e.g. wxToolbarItems don't properly handle setting the text of buttons, so we'll handle it here by looking for the method OnSetTextEvent to handle it """ try: method = widget.OnSetTextEvent except AttributeError: pass else: method (event) else: event.Skip()
def __init__(self, dialogTitle, view): options = [dict(name='cid:[email protected]', checked = True, label = _(u"Import &reminders")), dict(name='cid:[email protected]', checked = True, label = _(u"Import event &status"))] FileChooserWithOptions.__init__( self, dialogTitle, schema.ns("osaf.sharing", view).prefs.import_dir, _(u"iCalendar files|*.ics|All files (*.*)|*.*"), wx.OPEN, options ) self.Bind(wx.EVT_BUTTON, self.onOK, id=wx.ID_OK) self.Bind(wx.EVT_BUTTON, self.onCancel, id=wx.ID_CANCEL) sidebarCollection = schema.ns("osaf.app", view).sidebarCollection trash = schema.ns("osaf.pim", view).trashCollection selected = Block.findBlockByName("MainView").getSidebarSelectedCollection() # create a collection chooser gs = wx.FlexGridSizer(2, 2, 2, 2) # rows, cols, hgap, vgap self.chooserLabel = wx.StaticText(self, -1, _(u"Import e&vents into:")) gs.Add(self.chooserLabel, 0, wx.ALL, 3) self.choices = [col for col in sidebarCollection if (col is not selected) and not isReadOnly(col) and not UserCollection(col).outOfTheBoxCollection] selectNew = schema.ns("osaf.sharing", view).prefs.import_as_new if selected == trash or isReadOnly(selected): selectNew = True else: self.choices.insert(0, selected) displayChoices = [_(u"New collection")] displayChoices.extend(col.displayName for col in self.choices) self.choices.insert(0, None) # make choice indices match displayChoice self.chooser = wx.Choice(self, -1, choices = displayChoices) self.chooser.Bind(wx.EVT_CHOICE, self.OnCollChoice) if selectNew: self.chooser.SetSelection(0) else: self.chooser.SetSelection(1) gs.Add(self.chooser, 0, wx.ALIGN_LEFT, 0) self.box.Insert(1, gs, 0, wx.LEFT, 16) self.mine = wx.CheckBox(self, -1, _(u"Keep out of Dashboard")) self.mine.SetValue(False) self.box.Insert(2, self.mine, 0, wx.ALL, 3) self.feedbackBox = wx.BoxSizer(wx.VERTICAL) self.gauge = wx.Gauge(self, size=(360, 15)) self.feedbackBox.Add(self.gauge, 0, wx.ALL | wx.ALIGN_CENTER, 10) self.progressText = wx.StaticText(self, -1, _(u"Starting import...")) self.feedbackBox.Add(self.progressText, wx.ALIGN_LEFT) self.box.Insert(3, self.feedbackBox, 0, wx.ALL | wx.ALIGN_CENTER, 10) self.box.Hide(self.feedbackBox) self.box.Fit(self) self.cancelling = False self.view = view
def onPluginEvent(self, event): msg = '' statusBar = Block.findBlockByName('StatusBar') statusBar.setStatusMessage(msg) subMenu = self.widget.GetSubMenu() menuItem = subMenu.FindItemById(event.arguments["wxEvent"].GetId()) name = menuItem.GetText() plugin_env = pkg_resources.Environment(Globals.options.pluginPath) pluginPrefs = subMenu.pluginPrefs if pluginPrefs.get(name, 'active') == 'active': for egg in plugin_env[name]: break else: return for ep in pkg_resources.iter_entry_points('chandler.parcels'): if plugin_env[ep.dist.key]: # only handle plugin entrypoints requires = ep.dist.requires(ep.extras) if egg in pkg_resources.working_set.resolve(requires): if pluginPrefs.get(ep.dist.key, 'inactive') == 'active': dlg = wx.MessageDialog(None, _(u"%(pluginName)s is required by %(eggName)s.\n\n%(eggName)s must be deactivated first.") %{'eggName': ep.dist.egg_name(), 'pluginName': egg.egg_name()}, _(u"Error"), wx.OK | wx.ICON_ERROR) cmd = dlg.ShowModal() dlg.Destroy() return dlg = wx.MessageDialog(None, _(u"All items created by plugin %(pluginName)s will be deleted.") %{'pluginName': egg.egg_name()}, _(u"Confirm Deactivation"), (wx.YES_NO | wx.YES_DEFAULT | wx.ICON_EXCLAMATION)) cmd = dlg.ShowModal() dlg.Destroy() if cmd == wx.ID_YES: egg = self.deactivatePlugin(name, plugin_env) if egg is not None: msg = _(u"%(pluginName)s was deactivated.") %{'pluginName': egg.egg_name()} else: return else: return else: egg, dependencies = self.activatePlugin(name, plugin_env) if egg is not None: if not dependencies: msg = _(u"%(pluginName)s was activated.") %{'pluginName': egg.egg_name()} else: msg = _(u"%(pluginName)s and %(pluginNames)s were activated.") %{'pluginName': egg.egg_name(), 'pluginNames': ', '.join([dist.egg_name() for dist in dependencies])} else: return # Update the menus self.synchronizeWidget() self.refreshMenus(self.itsView); statusBar.setStatusMessage(msg)
def compact(self, manual=False): view = self.itsView # view is MainThread view view.refresh() toVersion = sharing.getOldestVersion(view) versions = toVersion - self.lastVersion from osaf.framework.blocks.Block import Block setStatusMessage = Block.findBlockByName('StatusBar').setStatusMessage if versions < CompactTask.MIN_VERSIONS: # nothing much to do view.logger.info("Only %d versions to compact, skipping", versions) setStatusMessage(_(u"No data to purge...")) if manual: self.lastRun = self.lastCompact else: self.reschedule(CompactTask.REGULAR_INTERVAL) view.commit() return self.compacted = None def compact(progress): try: counts = view.repository.compact(toVersion, progressFn=progress) except: view.logger.exception("while compacting repository") setStatusMessage( _(u"Purging failed. Go to the Tools>>Logging>>Log Window... menu for details." )) self.compacted = False else: setStatusMessage( _(u'Reclaimed %(numItems)d items, %(numValues)d values, %(numRefs)d refs, %(numIndex)d index entries, %(numNames)d names, %(numLobs)d lobs, %(numBlocks)d blocks, %(numLucene)d lucene documents.' ) % { "numItems": counts[0], "numValues": counts[1], "numRefs": counts[2], "numIndex": counts[3], "numNames": counts[4], "numLobs": counts[5], "numBlocks": counts[6], "numLucene": counts[7] }) self.compacted = True dialog = CompactDialog(compact, self.lastCompact, versions) dialog.CenterOnScreen() cmd = dialog.ShowModal() dialog.Destroy() if cmd == wx.ID_OK: if self.compacted is True: self.lastVersion = int(toVersion) self.lastCompact = datetime.now() self.reschedule(CompactTask.REGULAR_INTERVAL) elif self.compacted is False: if manual: self.lastRun = self.lastCompact else: self.reschedule(CompactTask.RETRY_INTERVAL) elif manual: self.lastRun = self.lastCompact else: self.reschedule(CompactTask.RETRY_INTERVAL) view.commit()
def importICalendarFile( fullpath, view, targetCollection=None, filterAttributes=None, activity=None, tzinfo=None, logger=None, selectedCollection=False, ): """Import ics file at fullpath into targetCollection. If selectedCollection is True, ignored targetCollection and import into the currently selected sidebar collection. If Trash is chosen as the target collection, a new collection will be created instead. """ from osaf.framework.blocks.Block import Block import translator, ics from osaf import sharing if selectedCollection: targetCollection = Block.findBlockByName("MainView").getSidebarSelectedCollection() trash = schema.ns("osaf.pim", view).trashCollection if targetCollection == trash: targetCollection = None view.commit(sharing.mergeFunction) # to make target collection available # Note: if everyone is following the commit rules that says a commit # happens after every user action, this commit is not required. rv = sharing.getView(view.repository) if targetCollection is not None: targetCollection = rv.findUUID(targetCollection.itsUUID) if not os.path.isfile(fullpath): raise ICalendarImportError(_(u"File does not exist, import cancelled.")) before = epoch_time() (dir, filename) = os.path.split(fullpath) try: # TODO: coerceTzinfo? import stateless try: collection = stateless.importFile( rv, fullpath, collection=targetCollection, filters=filterAttributes, activity=activity ) except: if logger: logger.exception("Failed importFile %s" % fullpath) raise ICalendarImportError(_(u"Problem with the file, import cancelled.")) if targetCollection is None: collectionName = getattr(collection, "displayName", "Untitled") if collectionName == "Untitled": name = "".join(filename.split(".")[0:-1]) or filename collection.displayName = name rv.commit(sharing.mergeFunction) # makes new collection available view.refresh(sharing.mergeFunction) # main ui repo view finally: sharing.releaseView(rv) collection = view.findUUID(collection.itsUUID) if targetCollection is None: schema.ns("osaf.app", view).sidebarCollection.add(collection) sideBarBlock = Block.findBlockByName("Sidebar") sideBarBlock.postEventByName("SelectItemsBroadcast", {"items": [collection]}) if logger: logger.info("Imported collection in %s seconds" % (epoch_time() - before)) return collection
def OnInit(self): util.timing.begin( "wxApplication OnInit" ) #@@@Temporary testing tool written by Morgen -- DJA """ Main application initialization. """ self.needsUpdateUI = True self.ignoreSynchronizeWidget = True self.focus = None wx.InitAllImageHandlers() """ Disable automatic calling of UpdateUIEvents. We will call them manually when blocks get rendered, change visibility, etc. """ wx.UpdateUIEvent.SetUpdateInterval(-1) """ Install a custom displayhook to keep Python from setting the global _ (underscore) to the value of the last evaluated expression. If we don't do this, our mapping of _ to gettext can get overwritten. This is useful in interactive debugging with PyShell. """ def _displayHook(obj): if obj is not None: print repr(obj) sys.displayhook = _displayHook assert Globals.wxApplication == None, "We can have only one application" Globals.wxApplication = self """ Initialize PARCELPATH and sys.path """ parcelPath = Utility.initParcelEnv(Globals.chandlerDirectory, Globals.options.parcelPath) """ Splash Screen. We don't show the splash screen when nosplash is set """ splash = None if not Globals.options.nosplash: splashBitmap = self.GetImage("splash.png") splash = StartupSplash(None, splashBitmap) splash.Show() wx.Yield() #let the splash screen render itself """ Setup internationalization To experiment with a different locale, try 'fr' and wx.LANGUAGE_FRENCH """ os.environ['LANGUAGE'] = 'en' # self.locale = wx.Locale(wx.LANGUAGE_ENGLISH) """ @@@ Sets the python locale, used by wx.CalendarCtrl for month and weekday names. When running on Linux, 'en' is not understood as a locale, nor is 'fr'. On Windows, you can try 'fr'. locale.setlocale(locale.LC_ALL, 'en') """ # wx.Locale_AddCatalogLookupPathPrefix('locale') # self.locale.AddCatalog('Chandler.mo') gettext.install('chandler', 'locale') """ Crypto initialization """ if splash: splash.updateGauge('crypto') Utility.initCrypto(Globals.options.profileDir) if splash: splash.updateGauge('repository') # The repository opening code was moved to a method so that it can # be called again if there is a schema mismatch and the user chooses # to reopen the repository in create mode. repoDir = Utility.locateRepositoryDirectory(Globals.options.profileDir) try: view = Utility.initRepository(repoDir, Globals.options) except RepositoryVersionError: if self.ShowSchemaMismatchWindow(): Globals.options.create = True view = Utility.initRepository(repoDir, Globals.options) else: raise Utility.SchemaMismatchError self.repository = view.repository """ Verify Schema Version """ if not Utility.verifySchema(view): if self.ShowSchemaMismatchWindow(): # Blow away the repository self.repository.close() Globals.options.create = True view = Utility.initRepository(repoDir, Globals.options) self.repository = view.repository else: raise Utility.SchemaMismatchError self.UIRepositoryView = view # make our view be the default for schema API # so when we say myClass.iterItems() and leave off the view # we get the UI repository view. schema.reset(self.UIRepositoryView) """ Load Parcels """ if splash: splash.updateGauge('parcels') wx.Yield() Utility.initParcels(view, parcelPath) EVT_MAIN_THREAD_CALLBACK(self, self.OnMainThreadCallbackEvent) """ The Twisted Reactor should be started before other Managers and stopped last. """ if splash: splash.updateGauge('twisted') Utility.initTwisted() mainViewRoot = self.LoadMainViewRoot(delete=Globals.options.refreshui) if (mainViewRoot.position.x == -1 and mainViewRoot.position.y == -1): position = wx.DefaultPosition else: position = (mainViewRoot.position.x, mainViewRoot.position.y) # arel: fix for bug involving window size and toolbar on MacOS (bug 3411). # The problem is that mainFrame gets resized when it is rendered # (particularly when the toolbar gets rendered), increasing the window's # height by the height of the toolbar. We fix by remembering the # (correct) size before rendering and resizing. rememberSize = (mainViewRoot.size.width, mainViewRoot.size.height) self.mainFrame = MainFrame(None, -1, "Chandler", pos=position, size=(mainViewRoot.size.width, mainViewRoot.size.height), style=wx.DEFAULT_FRAME_STYLE) mainViewRoot.frame = self.mainFrame """ Register to some global events for name lookup. """ if splash: 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) self.ignoreSynchronizeWidget = False if splash: splash.updateGauge('mainview') self.RenderMainView() if Globals.options.profile: import hotshot, hotshot.stats prof = hotshot.Profile( os.path.join(Globals.options.profileDir, 'commit.log')) prof.runcall(self.UIRepositoryView.commit) prof.close() stats = hotshot.stats.load( os.path.join(Globals.options.profileDir, 'commit.log')) stats.strip_dirs() stats.sort_stats('time', 'calls') stats.print_stats(125) else: wx.Yield() self.UIRepositoryView.commit() if splash: splash.Destroy() #OnDestroyWindow Binding has to appear after splash.Destroy self.Bind(wx.EVT_IDLE, self.OnIdle) self.Bind(wx.EVT_MENU, self.OnCommand, id=-1) self.Bind(wx.EVT_TOOL, self.OnCommand, id=-1) self.Bind(wx.EVT_UPDATE_UI, self.OnCommand, id=-1) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroyWindow, id=-1) self.Bind(wx.EVT_SHOW, self.OnShow, id=-1) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) # resize to intended size. (bug 3411) self.mainFrame.SetSize(rememberSize) self.mainFrame.Show() """Start the WakeupCaller Service""" Utility.initWakeup(self.UIRepositoryView.repository) """Start the Chandler Mail Service""" from osaf.mail.mailservice import MailService Globals.mailService = MailService(self.UIRepositoryView.repository) Globals.mailService.startup() util.timing.end("wxApplication OnInit" ) #@@@Temporary testing tool written by Morgen -- DJA # data loading script execution if Globals.options.createData: import tools.GenerateItemsFromFile as GenerateItemsFromFile GenerateItemsFromFile.RunScript(Globals.mainViewRoot.itsView, Globals.views[0]) return True #indicates we succeeded with initialization