def test_StringFuncs(self): teststring = "This is a very long string with Unicode chars: Žš”¯ and 1234567890" revstring = "0987654321 dna ¯”šŽ :srahc edocinU htiw gnirts gnol yrev a si sihT" self.assertEqual(utils.reverseText(teststring), revstring) cap = "&File" self.assertEqual(utils.cleanMenuCaption(cap), "File") self.assertEqual(utils.cleanMenuCaption(cap, "e"), "&Fil")
def _setHotKey(self, evt): dlg = HotKeyEditor(self) itm = self._selectedItem origKey = itm.hotkey dlg.setKey(origKey) dlg.show() if dlg.Accepted: hk = dlg.KeyText change = (hk != origKey) dupeItem = None if change: dupeItem = self._hotKeyMap.get(hk) if dupeItem and (dupeItem is not itm): msg = _("This key combination is assigned to the menu command '%s'. " + "Do you wish to re-assign it to the command '%s'?") % (cleanMenuCaption(dupeItem.Caption, "&_"), cleanMenuCaption(itm.Caption, "&_")) change = dabo.ui.areYouSure(msg, title=_("Duplicate Keystroke"), defaultNo=True, cancelButton=False) if change: if dupeItem: # Un-assign that hotkey dupeItem.HotKey = None # Clear it from the tree nd = self.menuKeyAssignmentTree.nodeForObject(dupeItem) if nd: nd.hotkey = None if origKey: self._hotKeyMap.pop(origKey) if hk: # Set the internal key map. self._hotKeyMap[hk] = itm.Object self.txtMenuCurrentHotKey.Value = itm.hotkey = itm.Object.HotKey = hk itm.pref.setValue("hotkey", hk) dlg.release() self.pgMenuKeys.update()
def _addDefaultPages(self): """ Called when no other code exists to fill the dialog, or when the class's IncludeDefaultPages property is True. """ af = self.Application.ActiveForm if not af or af is self: af = self.Parent try: mb = af.MenuBar except AttributeError: mb = None if mb: pm = af.PreferenceManager.menu self.preferenceKeys.append(pm) menuPage = self.pgMenuKeys = self.addCategory(_("Menu Keys")) self._selectedItem = None self._hotKeyMap = {} menuPage.Sizer.Orientation = "H" tree = dabo.ui.dTreeView(menuPage, OnTreeSelection=self._onMenuTreeSelection, RegID="menuKeyAssignmentTree") root = tree.setRootNode(_("Menu")) for mn in mb.Children: cap = cleanMenuCaption(mn.Caption, "&") prefcap = cleanMenuCaption(mn.Caption) nd = root.appendChild(cap) nd.pref = pm nd.hotkey = "n/a" nd.Object = mn menukey = pm.get(prefcap) self._recurseMenu(mn, nd, menukey) menuPage.Sizer.append1x(tree, border=10) root.expand() self._originalHotKeyMap = self._hotKeyMap.copy() sz = dabo.ui.dGridSizer(MaxCols=2, HGap=5, VGap=10) lbl = dabo.ui.dLabel(menuPage, Caption=_("Current Key:")) txt = dabo.ui.dTextBox(menuPage, ReadOnly=True, Alignment="Center", RegID="txtMenuCurrentHotKey") sz.append(lbl, halign="right") sz.append(txt, "x") sz.appendSpacer(1) btn = dabo.ui.dButton(menuPage, Caption=_("Set Key..."), OnHit=self._setHotKey, DynamicEnabled=self._canSetHotKey) sz.append(btn, halign="center") sz.appendSpacer(1) btn = dabo.ui.dButton(menuPage, Caption=_("Clear Key"), OnHit=self._clearHotKey, DynamicEnabled=self._canClearHotKey) sz.append(btn, halign="center") sz.setColExpand(True, 1) menuPage.Sizer.append1x(sz, border=10)
def _restoreMenuPrefs(self): if not self: # Form has already been released return pm = self.PreferenceManager mb = self.MenuBar if mb is None or not pm.hasKey("menu"): return menus = mb.Children pmMenu = pm.menu menuPath = pmMenu.FullPath + "." prefs = pmMenu.getPrefs(returnNested=True) for itmPath, hk in prefs.items(): relPath, setting = itmPath.replace(menuPath, "").rsplit(".", 1) menuItem = mb for pth in relPath.split("."): try: menuItem = [ch for ch in menuItem.Children if hasattr(ch, "Caption") and cleanMenuCaption(ch.Caption) == pth][0] except IndexError: # No such menu; skip it menuItem = None break if menuItem is not None: if setting == "hotkey": menuItem.HotKey = hk
def _itemByCaption(self, cap, returnPos=False): """ Common method for locating a menu item by its caption, ignoring all the 'special' characters for acceleration. If 'returnPos' is True, the position of the found item is returned instead of the item itself. """ cap = cleanMenuCaption(cap, "&_") for pos in xrange(self.GetMenuItemCount()): itm = self.FindItemByPosition(pos) itmCap = cleanMenuCaption(itm.GetLabel(), "&_") if itmCap == cap: if returnPos: return pos else: return self._daboChildren.get(itm.GetId(), None) return None
def _recurseMenu(self, mn, nd, pref): """mn is the menu; nd is the tree node for that menu; pref is the pref key for the menu.""" for itm in mn.Children: native = True try: cap = cleanMenuCaption(itm.Caption, "&") prefcap = cleanMenuCaption(itm.Caption) except AttributeError: # A separator line continue kidnode = nd.appendChild(cap) subpref = pref.get(prefcap) kidnode.pref = subpref kidnode.hotkey = "n/a" if itm.Children: self._recurseMenu(itm, kidnode, subpref) else: try: kidnode.hotkey = itm.HotKey self._hotKeyMap[itm.HotKey] = itm except AttributeError: pass kidnode.Object = itm
def onMenuOpenMRU(self, menu): """ Make sure that the MRU items are there and are in the correct order. """ cap = menu.Caption cleanCap = cleanMenuCaption(cap) topLevel = isinstance(menu.Parent, dabo.ui.dMenuBar) mnPrm = self._mruMenuPrompts.get(cleanCap, []) if not mnPrm: return if topLevel and (menu._mruSeparator is None): menu._mruSeparator = menu.appendSeparator() tmplt = "&%s %s" promptList = [tmplt % (pos+1, txt) for pos, txt in enumerate(mnPrm)] idx = -1 ok = True for prm in promptList: try: newIdx = menu.getItemIndex(prm) if newIdx is None or (newIdx < idx): ok = False break else: idx = newIdx except IndexError: # The menu items aren't in this menu ok = False break if not ok: # Remove all the items lnks = self._mruMenuLinks.get(menu, {}) kids = menu.Children for itm in list(lnks.values())[::-1]: if itm not in kids: continue try: menu.remove(itm) except (IndexError, ValueError) as e: pass # Add them all back lnks = {} fncs = self._mruMenuFuncs.get(cleanCap, {}) for pos, txt in enumerate(mnPrm): itm = menu.append(tmplt % (pos+1, txt), OnHit=fncs.get(txt, None)) lnks[itm.GetId()] = itm self._mruMenuLinks[menu] = lnks
def addToMRU(self, menuOrCaption, prompt, bindfunc=None): """ Adds the specified menu to the top of the list of MRU prompts for that menu. """ if isinstance(menuOrCaption, str): # They passed the menu caption directly cap = menuOrCaption else: cap = menuOrCaption.Caption cleanCap = cleanMenuCaption(cap) mn = self._mruMenuPrompts.get(cleanCap, []) if prompt in mn: mn.remove(prompt) mn.insert(0, prompt) self._mruMenuPrompts[cleanCap] = mn[:self._mruMaxItems] mf = self._mruMenuFuncs.get(cleanCap, {}) mf[prompt] = bindfunc self._mruMenuFuncs[cleanCap] = mf