def metacontact_buddy_menu(menu, mc): lenmc = len(mc) for contact in mc: # add a service specific menu for each contact in the metacontact contact_menu = Menu(menu.Window) # search_bases = False means we'll get the actions specific to the buddy's service actions.menu(menu.Window, contact, contact_menu, search_bases=False) if contact_menu[0].IsSeparator(): contact_menu.RemoveItem(contact_menu[0]) if lenmc > 2: contact_menu.AddSep() contact_menu.AddItem(_('&Remove from Merged Contact'), callback=lambda contact=contact: mc.manager. remove(mc, contact)) # use the contact's service icon for the submenu (greyed out if offline) icon = contact.serviceicon if not contact.online: icon = icon.Greyed menu.AddSubMenu(contact_menu, contact.name, bitmap=icon)
def on_fbar_context_menu(self, e): # TODO: why isn't the IM window's formatting bar its own subclass!? from gui.uberwidgets.umenu import UMenu m = UMenu(self) m.AddItem(_('Hide Formatting Bar'), callback = lambda: wx.CallAfter(setpref, 'messaging.show_formatting_bar', False)) m.PopupMenu()
def popup(self): if hasattr(self, '_menu') and self._menu: self._menu.Destroy() from gui.uberwidgets.umenu import UMenu menu = UMenu(self) if not self.data.type == 'fb': menu.AddItem(_('&Edit'), callback=lambda: self.on_edit()) menu.AddItem(_('&Delete'), callback=lambda: self.on_delete()) menu.AddSep() common.actions.menu(self, self.data, menu) self._menu = menu return menu
def popup(self): if hasattr(self, '_menu') and self._menu: self._menu.Destroy() menu = UMenu(self) menu.AddItem(_('&Edit'), callback = lambda: self.on_edit()) menu.AddItem(_('&Remove'), callback = lambda: self.on_delete()) menu.AddSep() actions.menu(self, self.data, menu) self._menu = menu return menu
def yahoo_buddy_menu(menu, contact): ''' Appends a Yahoo-specific "Stealth Settings" submenu to "menu". account - YahooProtocol object menu - a UMenu selection - the selected Contact object or None ''' menu_title = _('&Stealth Settings') stealth_menu = Menu(menu.Window) enable = stealth_menu.Enable a = stealth_menu.AddCheckItem name = getattr(contact, 'name', _('Selection')) # append an item for each stealth option items = [ a(_('Appear Online to {name}').format(name=name), callback=lambda: contact.set_stealth_session(False)), a(_('Appear Offline to {name}').format(name=name), callback=lambda: contact.set_stealth_session(True)), a(_('Appear Permanently Offline to {name}').format(name=name), callback=lambda: contact.set_stealth_perm(True)) ] # append a separator and a link to the webpage explaining stealth mode stealth_menu.AddSep() a(_('Learn More (URL)'), callback=lambda: wx.LaunchDefaultBrowser( 'http://messenger.yahoo.com/stealth.php')) online, offline, perm = items # items are disabled unless a yahoo buddy is selected if contact is None or contact.service != 'yahoo': for item in items: enable(item.Id, False) item.Check(False) else: invisible = profile.status.invisible enable(online.Id, True) enable(offline.Id, invisible) enable(perm.Id, True) if contact.stealth_perm: perm.Check(True) elif invisible and contact.stealth_session: offline.Check(True) elif not invisible or not contact.stealth_session: online.Check(True) menu.AddSubMenu(stealth_menu, menu_title)
def __OnContextMenu(self, e): from gui.uberwidgets.umenu import UMenu from gui.toolbox import std_textctrl_menu with UMenu.Reuse(self) as menu: self.AddSuggestionsToMenu(menu) std_textctrl_menu(self, menu)
def __init__(self, parent): super(ConnectionList, self).__init__(parent) #set here so that when a profile change occurs the reference updates correctly global accounts accounts = profile.account_manager.accounts self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) self.Sizer = wx.BoxSizer(wx.VERTICAL) self.SetScrollRate(0, 1) self.SetSkinKey('accountpanels', True) self.ShowAll = False self.oldaccounts = [] self.panels = {} accounts.add_observer(self.WhenListChanges) profile.account_manager.add_observer(self.InitShow, 'accounts_loaded') self.menu = UMenu(self) Bind = self.Bind Bind(wx.EVT_PAINT, self.OnPaint) Bind(wx.EVT_ERASE_BACKGROUND, lambda e: None) Bind(wx.EVT_SIZE, self.OnSize) self.BindWheel(self) Bind(wx.EVT_SCROLLWIN_LINEDOWN, lambda e: self.Scroll(0, self.ViewStart[1] + SCROLLCONST)) Bind(wx.EVT_SCROLLWIN_LINEUP, lambda e: self.Scroll(0, self.ViewStart[1] - SCROLLCONST)) Bind(wx.EVT_SCROLLWIN, lambda e: (e.Skip(), wx.CallAfter(self.Refresh))) Bind(wx.EVT_KEY_DOWN, self.OnKey)
def default_umenu(tc): from gui.uberwidgets.umenu import UMenu m = UMenu(tc) # spelling suggestions and options if isinstance(tc, SpellCheckTextCtrlMixin): tc.AddSuggestionsToMenu(m) m.AddItem(_('Copy'), id = wx.ID_COPY, callback = tc.Copy) m.AddItem(_('Paste'), id = wx.ID_PASTE, callback = tc.Paste) m.AddSep() from gui.toolbox import add_rtl_checkbox add_rtl_checkbox(tc, m) return m
def __init__( self, parent, accts, infobox, skinkey, prefkey=None, onDoubleClick=None, # a callable taking an acct labelCallback=None, # a callable: acct -> unicode ): wx.VListBox.__init__(self, parent) self.SetSkinKey(skinkey) self.prefkey = prefkey self.unlocked = pref(self.prefkey + '.unlocked', True) self._obs_link = None self.infobox = infobox infobox.Befriend(self) self.accts = accts self.willreconaccts = set() self.itemheight = 0 self.UpdateSkin() Bind = self.Bind Bind(wx.EVT_MOTION, self.OnMouseMotion) Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseOut) Bind(wx.EVT_RIGHT_UP, self.OnRightUp) Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDblClick) Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) Bind(wx.EVT_LEFT_UP, self.OnLeftUp) Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.OnMouseLost) self.BuildList() self.menu = UMenu(self) self.OnDoubleClick = Delegate( [onDoubleClick] if onDoubleClick is not None else []) self.labelCallback = labelCallback self.BindObservers()
def popup(self): try: return self._popupmenu except AttributeError: self._popupmenu = menu = UMenu(self) menu.AddItem(_('&Edit'), callback=self.on_edit) menu.AddItem(_('&Remove'), callback=self.on_delete) return menu
def CreatePopupMenu(self): buddy_frame = wx.FindWindowByName('Buddy List') # TODO: fix skinned menus so that they don't need to be told they are in the system tray! umenu = UMenu(buddy_frame, onshow=None, windowless=True) add_hidden_convo_menu_items(umenu) statuscombo.add_global_to_menu(umenu, _('Set &Global Status...')) statmenu = UMenu( buddy_frame, onshow=None) #statuscombo.create_status_menu(add_custom = True) statuscombo.status_menu(statmenu, add_custom=True, add_promote=True) umenu.AddSubMenu(statmenu, _('Set IM &Status')) umenu.AddSep() show_hide = umenu.AddItem(_('Show &Buddy List'), id=actionIDs.ShowBuddyList) if buddy_frame: docker = getattr(buddy_frame, 'docker', None) if docker: disable_hide = docker.Enabled and docker.docked and docker.AutoHide show_hide.label = _( 'Hide &Buddy List') if buddy_frame.Shown else _( 'Show &Buddy List') show_hide.Enable(not disable_hide) # The menubar is the "app" menubar on Mac and thus cannot be hidden. if platformName != 'mac': umenu.AddPrefCheck('buddylist.show_menubar', _('Show Menu Bar')) umenu.AddItem(_('&Preferences...'), id=wx.ID_PREFERENCES) # Mac gets this menu item standard on the Dock, don't duplicate it. if platformName != 'mac': umenu.AddSep() umenu.AddItem(_('E&xit Digsby'), id=wx.ID_EXIT) # since status items are created dynamically, we must bind to them on the fly. self.SetupStatusHandlers() return umenu
def build_actionsbar_menu(self): m = UMenu(self, onshow=self.update_actionsbar_menu) c = self._actionsbar_checks = {} for name, label in [('icons', _('Icons Only')), ('text', _('Text Only')), ('next', _('Icons Next to Text')), ('above', _('Icons Above Text'))]: def cb(name=name): with self.Frozen(): setpref(action_icons_key, name) c[name] = m.AddCheckItem(label, callback=cb) m.AddSep() m.AddItem( _('Hide Actions Bar'), callback=lambda: setpref('messaging.show_actions_bar', False)) return m
def addmenu(self): try: return self.add_popup except AttributeError: self.add_popup = menu = UMenu(self) protocols = common.protocolmeta.protocols emailprotocols = common.protocolmeta.emailprotocols for p in emailprotocols.keys(): menu.AddItem(protocols[p].name, callback=lambda p=p: self.add_account(p), bitmap=skin.get('serviceicons.' + p, None)) return menu
def ShowMenu(self, e): self._menutab = e.EventObject try: menu = self._tabmenu except AttributeError: from gui.uberwidgets.umenu import UMenu menu = self._tabmenu = UMenu(self) menu.AddItem('Close &Other Tabs', id = CLOSE_OTHER_TABS) menu.AddSep() menu.AddItem('&Close Tab', id = CLOSE_TAB) menu.PopupMenu()
def GenMenu(self): m = UMenu(self) # spelling suggestions and options if isinstance(self, SpellCheckTextCtrlMixin): if self.AddSuggestionsToMenu(m): m.AddSep() m.AddItem(_('Cut'), id = wx.ID_CUT, callback = self.Cut) m.AddItem(_('Copy'), id = wx.ID_COPY, callback = self.Copy) m.AddItem(_('Paste'), id = wx.ID_PASTE, callback = self.Paste) m.AddSep() m.AddItem(_('Select All'), id = wx.ID_SELECTALL, callback = lambda: self.SetSelection(0, self.GetLastPosition())) m.AddSep() from gui.toolbox import add_rtl_checkbox add_rtl_checkbox(self, m) return m
def GetTextCtrlMenu(self): from gui.uberwidgets.umenu import UMenu m, tc = UMenu(self), self.input_area.tc # spelling suggestions and options from gui.spellchecktextctrlmixin import add_spelling_suggestions if add_spelling_suggestions(tc, m): m.AddSep() m.AddItem( _('Copy'), id=wx.ID_COPY, callback=tc.Copy) # todo: disable if "not tc.CanCopy()" when shown. m.AddItem(_('Paste'), id=wx.ID_PASTE, callback=tc.Paste) m.AddSep() m.AddPrefCheck('messaging.show_actions_bar', _('Show &Actions Bar')) m.AddPrefCheck('messaging.show_formatting_bar', _('Show &Formatting Bar')) m.AddPrefCheck('messaging.show_send_button', _('Show Send Button')) m.AddSep() gui.toolbox.add_rtl_checkbox(tc, m) return m
def popup(self): if not hasattr(self, '_menu') or not self._menu: self._menu = menu = UMenu(self) else: menu = self._menu menu.RemoveAllItems() menu.AddItem(_('&Edit'), callback=lambda: self.on_edit()) menu.AddItem(_('&Remove'), callback=lambda: self.on_delete()) if self.data.enabled: menu.AddSep() common.actions.menu(self, self.data, menu) return menu
def __init__(self, acct, infobox=None): # This method doesn't run for PyObjC icons (see initWithAccount instead), so it's okay # to put wx and Observable code in here. self.acct = acct self.infobox = infobox from gui.uberwidgets.umenu import UMenu self._menu = UMenu(wx.FindWindowByName('Buddy List'), onshow=self.update_menu) # generate unique tray icon IDs for each account that are persistent # across program runs (specifically, for Windows' tray icon hiding options) trayid = hash('accounttrayicon_' + acct.protocol + '_' + acct.name) super(AccountTrayIcon, self).__init__(acct.icon, menu=self._menu, id=trayid) self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_click) self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.on_double_click) self.register_observers(acct, self.on_account_updated) self.on_account_updated()
def refresh_wx_tree(): ''' Calls "UpdateSkin" on every GUI control that has it, descending from top level windows down through their children. ''' # UMenus aren't necessarily wx Children accessible # through the widget tree--skip them on the tree descent from gui.uberwidgets.umenu import UMenu skip = (UMenu, ) for window in GetTopLevelWindows(): with window.FrozenQuick(): _updateskin(window, skip) # now update menus UMenu.CallAll(UMenu.UpdateSkin)
def xfer_popup(self): list = self try: return list._popupmenu except AttributeError: pass list._popupmenu = menu = UMenu(self, onshow=self.on_rightclick_show) menu.open = menu.AddItem(_('&Open'), callback=lambda: list._menurow.on_open()) menu.openfolder = menu.AddItem( _('Open &Containing Folder'), callback=lambda: list._menurow.on_open_folder()) menu.AddSep() menu.remove = menu.AddItem(_('&Remove'), callback=lambda: list._menurow.on_remove()) return menu
def initWithAccount(self, acct, infobox): with nspool(): self.acct = acct self.infobox = infobox from gui.uberwidgets.umenu import UMenu self._menu = UMenu(wx.FindWindowByName('Buddy List'), onshow=self.update_menu) statusbar = NSStatusBar.systemStatusBar() self.statusitem = statusbar.statusItemWithLength_( NSVariableStatusItemLength) self.statusitem.setTarget_(self) self.statusitem.setAction_("itemClicked:") # set up our observer self.observer = Notifier(self) acct.add_observer(self.observer.on_account_updated, 'count', 'state', obj=self.observer) self.on_account_updated()
def __init__(self,parent): SimplePanel.__init__(self, parent, wx.FULL_REPAINT_ON_RESIZE) self.BackgroundColour = wx.WHITE self.Sizer = wx.BoxSizer(HORIZONTAL) sz = wx.BoxSizer(HORIZONTAL) self.Sizer.Add(sz,1,EXPAND|ALL,3) leftcol = wx.BoxSizer(VERTICAL) acctcombo = self.acctcombo = UberCombo(self, value='',skinkey='AppDefaults.PrefCombo') acctcont = PrefPanel(self,acctcombo,_('Account')) leftcol.Add(acctcont,0,EXPAND|ALL,3) buddylist = self.buddylist = ListOBuddies(self) self.buddies_panel = buddycont = PrefPanel(self, buddylist, _('Buddy')) leftcol.Add(buddycont, 1, EXPAND | TOPLESS, 3) style = wx.NO_BORDER | CAL_SUNDAY_FIRST | CAL_SEQUENTIAL_MONTH_SELECTION | CAL_SHOW_HOLIDAYS cal = self.cal = CalendarCtrl(self, -1, wx.DateTime.Now(), wx.DefaultPosition, wx.DefaultSize, style) cal.SetForegroundColour(wx.Color(160, 160, 160)) cal.SetHolidayColours(wx.BLACK, wx.WHITE) cal.SetHeaderColours(Color(160, 160, 160), Color(239, 239, 239)) calcont = PrefPanel(self,cal,_('Date')) leftcol.Add(calcont, 0, EXPAND | TOPLESS, 3) sz.Add(leftcol, 0, EXPAND) viewpanel = wx.Panel(self) viewer = self.viewer = PastBrowserWebkitWindow(viewpanel) # viewer.SetMouseWheelZooms(True) finder = self.finder = FindBar(viewpanel,viewer) menu = UMenu(viewer) menu.AddItem(_('Copy'), id = wx.ID_COPY, callback = lambda *a: viewer.Copy()) viewer.BindWheel(self) viewer.BindScrollWin(self) viewer.Bind(wx.EVT_CONTEXT_MENU, lambda e: (menu.GetItemById(wx.ID_COPY).Enable(viewer.CanCopy()), menu.PopupMenu(event = e))) viewer.Bind(wx.EVT_KEY_DOWN,self.OnKeyDown) finder.TextControl.Bind(wx.EVT_KEY_DOWN,self.OnKeyDown) nav = BoxSizer(wx.HORIZONTAL) prev = self.prev = UberButton(viewpanel, label = '<-', skin = BUTTON_SKIN) next = self.next = UberButton(viewpanel, label = '->', skin = BUTTON_SKIN) datelabel = wx.StaticText(viewpanel, -1, style = wx.ALIGN_CENTER| wx.ST_NO_AUTORESIZE) datelabel.SetMinSize((140, -1)) prev.Bind(wx.EVT_BUTTON, lambda e: self.Flip(-1)) next.Bind(wx.EVT_BUTTON, lambda e: self.Flip( 1)) nav.AddStretchSpacer(1) nav.AddMany([(prev, 0, wx.EXPAND | wx.ALIGN_CENTER), (datelabel, 0, wx.EXPAND | wx.ALIGN_CENTER), (next, 0, wx.EXPAND | wx.ALIGN_CENTER)]) nav.AddStretchSpacer(1) viewpanel.Sizer = wx.BoxSizer(wx.VERTICAL) viewpanel.Sizer.AddMany([ (nav, 0, EXPAND), (viewer, 1, EXPAND), (finder, 0, EXPAND) ]) sz.Add(PrefPanel(self, viewpanel, _('Conversation Log')), 1, EXPAND | ALL, 3) Bind = self.Bind Bind(wx.EVT_PAINT, self.OnPaint) def OnAcct(*a): ''' Handle selection of a new account from the Account drop down ''' if self.GroupChatsSelected(): from collections import defaultdict self.groupchats = defaultdict(list) for g in GetGroupChats(): d = g['time'] key = DateTimeFromDMY(d.day, d.month-1, d.year) self.groupchats[key].append(g) #dates = sorted((g['date'], g) for g in self.dates = sorted(self.groupchats.keys()) UpdateCal() self.buddies_panel.SetTitle(_('Chats')) else: buddylist.SetList(GetBuddies(acctcombo.Value.id), BuddyRenderer()) OnBuddy() self.buddies_panel.SetTitle(_('Buddy')) def OnBuddy(*a): ''' Handels selection of a buddy from the buddy pannel ''' if not self.GroupChatsSelected(): self.dates = GetDates(buddylist.SelectedBuddy.dir) UpdateCal() else: ViewLogForFile(buddylist.SelectedItem['file'], do_aliases=False) def UpdateCal(): ''' Switches the date to the last date conversed with the selected budy ''' self.next.Enable(True) self.prev.Enable(True) if self.dates: self.cal.Date = self.dates[-1] self.cal.Enable(True) OnCalChange() def OnCalChange(*a): ''' Update the Calendar UI to a new date ''' caldate = cal.Date currentyear = caldate.GetYear() currentmonth = caldate.GetMonth() relevantdates = frozenset(date.GetDay() for date in self.dates if date.GetYear() == currentyear and date.GetMonth() == currentmonth and date.GetDay()) SetHoliday, SetAttr = cal.SetHoliday, cal.SetAttr for i in xrange(1, 32): if i in relevantdates: SetHoliday(i) else: SetAttr(i, CalendarDateAttr(Color(160,160,160))) OnDayChange() self.OnCalChange = OnCalChange def ViewLogForDay(date): ''' Load the log file for the specified date for the currently selected buddy ''' logpath = logpath_for_date(buddylist.SelectedBuddy, date) ViewLogForFile(logpath) def ViewLogForFile(logpath, do_aliases=True): ''' Update the log viewer with the file specified ''' with viewer.Frozen(): viewer.SetPageSource(logpath.text('utf-8', 'replace'), logpath.url()) viewer.RunScript('window.scroll(0, 0);') if do_aliases: substitue_aliases() import hooks hooks.notify('digsby.statistics.logviewer.log_viewed') def substitue_aliases(): ''' Swap out buddy names with their allies ''' import gui with open(gui.skin.resourcedir() / 'html' / 'jquery-1.3.2.js', 'rb') as f: viewer.RunScript(f.read()) buddy = buddylist.SelectedBuddy aliases = IAliasProvider(profile()) import simplejson as json names = set(json.loads(viewer.RunScript("var foo = []; $('.buddy').each(function(){foo.push($(this).html())}); JSON.stringify(foo);"))) for name in names: alias = aliases.get_alias(name, buddy.service, buddy.protocol) or name viewer.RunScript(SUBHTML % (json.dumps(name), json.dumps(alias))) def OnDayChange(*a): ''' Show the log for the day selected in the clander ''' date = cal.Date self.date = date datelabel.SetLabel(date.FormatDate()) if cal.GetAttr(date.GetDay()).IsHoliday(): if self.GroupChatsSelected(): chats = sorted(self.groupchats[date], key=lambda g: g['time'], reverse=True) buddylist.SetList(chats, GroupChatRenderer()) if chats: ViewLogForFile(chats[0]['file'], do_aliases=False) else: ViewLogForDay(date) else: year = str(date.GetYear()) month = date.GetMonth() month = wx.DateTime.GetMonthName(int(month)) day = str(date.GetDay()) specific_day_string = _('{month}, {day}, {year}').format(month=month, day=day, year=year) if self.GroupChatsSelected(): msg = _("There are no chat logs for {specific_day_string}.").format(specific_day_string=specific_day_string) else: msg = _("There are no chat logs for {specific_day_string} with {name}.").format(specific_day_string=specific_day_string, name=buddylist.SelectedBuddy.name) viewer.SetPageSource(msg, 'file:///C:/') viewer.SetFocus() wx.CallAfter(cal.Refresh) self.OnDayChange = OnDayChange acctcombo.SetCallbacks(value = OnAcct) buddylist.Bind(wx.EVT_LISTBOX, OnBuddy) cBind = cal.Bind cBind(EVT_CALENDAR_YEAR, OnCalChange) cBind(EVT_CALENDAR_MONTH, OnCalChange) cBind(EVT_CALENDAR_SEL_CHANGED, OnDayChange) acctcombo.SetItems(MakeAccountItems(), 0)
def create_main_menu(parent): 'Returns the main menu object.' menu = MenuBar(parent, skinkey='menubar') digsby = Menu(parent) view = Menu(parent) tools = Menu(parent) help = Menu(parent) def makeadd(m): return (lambda title, callback=None, id=-1: m.AddItem( title, callback=callback, id=id)) # # My Status # mystatus = Menu(parent, onshow=update_statuses) add = makeadd(mystatus) add(_('&New Status Message...'), new_status_message) add(_('&Edit Status Messages...'), lambda: prefsdialog_show('status')) mystatus.AddSep() from gui.protocols import add_group def add_chat(): import gui.chatgui gui.chatgui.join_chat() # # Digsby # digsby.AddSubMenu(mystatus, _('My Status')) add = makeadd(digsby) add(_('My &Accounts...'), lambda: prefsdialog_show('accounts')) digsby.AddSep() sendimitem = add(_('&New IM...\tCtrl+N'), ShowNewIMDialog) if pref('messaging.groupchat.enabled', False): groupchatitem = add(_('New Group C&hat...\tCtrl+Shift+N'), add_chat) else: groupchatitem = None digsby.AddSep() addcontactitem = add(_('Add &Contact...\tCtrl+A'), lambda: AddContactDialog.MakeOrShow()) addgroupitem = add(_('Add &Group...\tCtrl+Shift+A'), lambda: add_group()) renameitem = add(_('&Rename Selection'), lambda: parent.blist.rename_selected()) deleteitem = add( _('&Delete Selection...'), lambda: parent.blist.delete_blist_item(parent.blist.SelectedItem)) digsby.AddSep() add(_('Sign &Off Digsby (%s)') % profile.name, lambda: profile.signoff()) # wx.App handles this for proper shutdown. add(_('E&xit Digsby'), id=wx.ID_EXIT) def on_digsby_show(_m): b = parent.blist.SelectedItem allow_add = any(x.allow_contact_add for x in profile.account_manager.connected_accounts) for item in (sendimitem, groupchatitem, addcontactitem, addgroupitem): if item is not None: item.Enable(allow_add) if not allow_rename(b): renameitem.SetItemLabel(_('&Rename Selection')) deleteitem.SetItemLabel(_('&Delete Selection')) renameitem.Enable(False) deleteitem.Enable(False) else: renameitem.SetItemLabel( _('&Rename {name}').format(name=getattr(b, 'alias', b.name))) deleteitem.SetItemLabel( _('&Delete {name}').format(name=getattr(b, 'alias', b.name))) renameitem.Enable(True) deleteitem.Enable(True) # # View # add = makeadd(view) view.AddPrefCheck('buddylist.always_on_top', _('&Always On Top')) add(_('Skins...\tCtrl+S'), lambda: prefsdialog_show('appearance')) view.AddSep() view.AddPrefCheck('buddylist.show_menubar', _('&Menu Bar')) def on_menubar(val): if not val: wx.MessageBox( _('You can bring back the menubar by right clicking ' 'on the digsby icon in the task tray.'), _('Hide Menu Bar')) profile.prefs.link('buddylist.show_menubar', lambda val: wx.CallAfter(on_menubar, val), False, menu) view.AddPrefCheck('buddylist.show_status', _('Status Panel')) add(_('Arrange &Panels...'), callback=lambda *_a: edit_buddylist_order(parent)) view.AddSep() view.AddPrefCheck('buddylist.show_mobile', _('Show &Mobile Contacts\tCtrl+M')) view.AddPrefCheck('buddylist.show_offline', _('Show &Offline Contacts\tCtrl+O')) groupoffline = view.AddPrefCheck('buddylist.group_offline', _('&Group Offline Contacts\tCtrl+G')) hideoffline = view.AddPrefCheck('buddylist.hide_offline_groups', _('&Hide Offline Groups')) groupby = Menu(parent) add = makeadd(groupby) groupby.sorttypes = [] # sort by sortby = Menu(parent) add = makeadd(sortby) sortby.sorttypes = [] sort_models = profile.blist.sort_models group_by = sort_models[0] sort_by = sort_models[1] then_by = sort_models[2] def addsort(model, view, sortstr, title): def set(model=model, view=view, sortstr=sortstr): model.selection = [v[0] for v in model.values].index(sortstr) view[model.selection].Check(True) mi = view.AddCheckItem(title, set) view.sorttypes.append(sortstr) return mi sort_names = dict( (('none', _('&None')), ('status', _('&Status')), ('name', _('N&ame')), ('log', _('&Log Size')), ('service', _('Ser&vice')))) def addsorts(model, view, names): for name in names: addsort(model=model, view=view, sortstr=name, title=sort_names[name]) addsorts(model=group_by, view=groupby, names=[k for k, _v in GROUP_BY_CHOICES]) groupby.AddSep() groupby.AddItem(_('Advan&ced...'), callback=lambda: prefsdialog_show('contact_list')) addsorts(model=sort_by, view=sortby, names=[k for k, _v in SORT_BY_CHOICES]) sortby.AddSep() def sortby_adv_click(): sortby[-1].Check(then_by.selection > 0) prefsdialog_show('contact_list') sortby.AddCheckItem(_('Advan&ced...'), callback=sortby_adv_click) sortby_adv = sortby[-1] groupby.reset_watcher = reset_checks_SortOptionWatcher( model=group_by, view=groupby, names=GROUP_BY_CHOICES) sortby.reset_watcher = reset_checks_SortOptionWatcher( model=sort_by, view=sortby, names=SORT_BY_CHOICES) sortby.adv_watcher = reset_check_AdvWatcher(model=then_by, view=sortby_adv) view.AddSep() view.AddSubMenu(groupby, _('&Group By')) view.AddSubMenu(sortby, _('&Sort By')) # # Tools # add = makeadd(tools) add(_('&Preferences...\tCtrl+P'), id=wx.ID_PREFERENCES, callback=lambda: prefsdialog_show('accounts')) add(_('Buddy List &Search\tCtrl+F'), parent.start_search) add(_('&File Transfer History\tCtrl+J'), FileTransferDialog.Display) def pb_show(): from gui.pastbrowser import PastBrowser PastBrowser.MakeOrShow() add(_('&Chat History\tCtrl+H'), pb_show) # # Help # add = makeadd(help) add(_('&Documentation'), lambda: wx.LaunchDefaultBrowser('http://wiki.digsby.com')) add(_('Support &Forums'), lambda: wx.LaunchDefaultBrowser('http://forum.digsby.com')) help.AddSep() add(_('&Submit Bug Report'), do_diagnostic) add(_('Su&ggest a Feature'), send_features_email) help.AddSep() if getattr(sys, 'DEV', False) or pref('debug.console', False): add(_('Show Debug Console'), wx.GetApp().toggle_crust) help.AddSep() add(_('Su&pport Digsby'), lambda: support.SupportFrame.MakeOrShow(parent)) for hook in Hook("digsby.help.actions"): help_menu_items = hook() for item in help_menu_items: add(*item) def on_view_show(_m): sortstatus = pref('buddylist.sortby').startswith('*status') showoffline = pref('buddylist.show_offline') hidegroups = pref('buddylist.hide_offline_groups') groupoff = pref('buddylist.group_offline') groupoffline.Enable(not sortstatus and showoffline) groupoffline.Check(groupoff and (not sortstatus and showoffline)) hideoffline.Enable(not sortstatus) hideoffline.Check((sortstatus and not showoffline) or (not sortstatus and hidegroups)) digsbyMenuName = _('&Digsby') if config.platformName == "mac": digsbyMenuName = _("&File") menu.Append(digsby, digsbyMenuName, onshow=on_digsby_show) menu.Append(view, _('&View'), onshow=on_view_show) menu.Append(tools, _('&Tools'), onshow=lambda m: on_accounts_entries(parent, m)) menu.Append(help, _('&Help')) return menu
def GetMenu(self): try: self._menu.Destroy() except AttributeError: pass from gui.uberwidgets.umenu import UMenu m = UMenu(self, onshow=self._onpopupshown) self._menu = m self._topid = id(self.Top) self.keep_on_top = m.AddCheckItem(_('&Keep on Top'), callback=self.Top.ToggleOnTop) self.view_past_chats_item = m.AddItem(_('&View Past Chats'), callback=self._on_view_past_chats) m.AddSep() add, addcheck, setmode = m.AddItem, m.AddCheckItem, self.set_mode c = self.capsbuttons = {} buddy = self.Buddy for bname, caption in buttons: if bname == 'files': c[bname] = add(caption, callback=lambda: self.Buddy.send_file()) else: if buddy is None or (bname == 'sms' and 'SMS' not in buddy.caps): continue c[bname] = addcheck( caption, callback=lambda b=bname: setmode(b, toggle_tofrom=b == 'im')) m.AddSep() self.edit_items = {} self.edit_items['Copy'] = add(_('Copy\tCtrl+C'), id=wx.ID_COPY) # add a "Copy Link" item if the mouse is hovering over a link message_area = getattr(self, 'message_area', None) if message_area is not None: # may not be created yet. ctrl = wx.FindWindowAtPointer() if ctrl is message_area: info = ctrl.HitTest(ctrl.ScreenToClient(wx.GetMousePosition())) if info.Link: add(_('Copy &Link'), callback=lambda: clipboard.copy(info.Link)) self.paste_item = self.edit_items['Paste'] = add(_('Paste\tCtrl+V'), id=wx.ID_PASTE) self.paste_index = len(self._menu) - 1 if pref('debug.message_area.show_edit_source', False): add(_('Edit Source'), callback=lambda: self.message_area.EditSource()) if pref('debug.message_area.show_jsconsole', False): from gui.browser import jsconsole add(_('&Javascript Console'), callback=lambda: jsconsole.show_console()) # text size menu if message_area is not None and message_area.IsShownOnScreen(): textsize_menu = UMenu(self) self.textbigger = textsize_menu.AddItem( _('&Increase Text Size\tCtrl+='), callback=message_area.IncreaseTextSize) self.textsmaller = textsize_menu.AddItem( _('&Decrease Text Size\tCtrl+-'), callback=message_area.DecreaseTextSize) textsize_menu.AddSep() textsize_menu.AddItem(_('&Reset Text Size\tCtrl+0'), callback=message_area.ResetTextSize) m.AddSubMenu(textsize_menu, _('&Text Size')) m.AddSep() # these checkboxes affect a global preference that immediately takes effect in # all open ImWins self.roomlist_item = m.AddCheckItem(_('Show &Room List'), callback=self.toggle_roomlist) self.actions_item = m.AddPrefCheck('messaging.show_actions_bar', _('Show &Actions Bar')) self.formatting_item = m.AddPrefCheck('messaging.show_formatting_bar', _('Show &Formatting Bar')) return self._menu
def context_menu(self): try: return self._context_menu except AttributeError: self._context_menu = UMenu(self, _('BuddyList Popup')) return self._context_menu
def OnContextMenu(self, event): from gui.uberwidgets.umenu import UMenu m = UMenu(self) m.AddItem(_('Hide Formatting Bar'), callback = lambda: wx.CallAfter(setpref, 'messaging.show_formatting_bar', False)) m.PopupMenu()
def menu(parent, obj, menu=None, cls=None, search_bases=True, filter=lambda func: True): 'Builds or adds to an existing menu with actions for the specified object.' from gui.uberwidgets.umenu import UMenu actions = forclass(cls if cls is not None else obj, search_bases) menu = menu if menu is not None else UMenu(parent) # For each action defined in the YAML names = set() for action in actions: # # ---- means separator # if isinstance(action, basestring) and action.startswith('--'): menu.AddSep() continue # # method: a function to call # elif 'method' in action: introspect.import_function(action['method'])(menu, obj) continue name = action['call'] if name in names: continue else: names.add(name) # the actual function func = getattr(obj, name, None) if func is None: continue gui_name = action['name'] try: # read precondition lambda and "needs" from the @action annotations precondition, needslist = getattr(obj, '_actions')[name] except KeyError, _e: # ...if there is no @action annotating the method, just call it precondition, needslist = lambda v: True, [] if needslist: import gui.userform as userform callback = partial(userform.getinput, obj, parent, needslist, func, title=gui_name.replace('&', '')) elif 'gui' in action: gui = introspect.import_function(action['gui']) if not hasattr(gui, 'Prompt'): callback = lambda gui=gui, func=func: gui(obj, func) else: def callback(gui=gui, func=func): gui(None, obj).Prompt(func) else: callback = func # Preconditions # - None: Don't show menu item # - False: Show disabled menu item # - True: Show menu item result = precondition(obj) if precondition is not None else True if filter(func) and (precondition is None or result is not None): name = action_name(obj, gui_name) menu.AddItem(name, callback=callback).Enable(bool(result))
class AccountList(wx.VListBox, UberWidget): 'Shows a list of active accounts with counts of new items' def __init__( self, parent, accts, infobox, skinkey, prefkey=None, onDoubleClick=None, # a callable taking an acct labelCallback=None, # a callable: acct -> unicode ): wx.VListBox.__init__(self, parent) self.SetSkinKey(skinkey) self.prefkey = prefkey self.unlocked = pref(self.prefkey + '.unlocked', True) self._obs_link = None self.infobox = infobox infobox.Befriend(self) self.accts = accts self.willreconaccts = set() self.itemheight = 0 self.UpdateSkin() Bind = self.Bind Bind(wx.EVT_MOTION, self.OnMouseMotion) Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseOut) Bind(wx.EVT_RIGHT_UP, self.OnRightUp) Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDblClick) Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) Bind(wx.EVT_LEFT_UP, self.OnLeftUp) Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.OnMouseLost) self.BuildList() self.menu = UMenu(self) self.OnDoubleClick = Delegate( [onDoubleClick] if onDoubleClick is not None else []) self.labelCallback = labelCallback self.BindObservers() def OnClose(self, e=None): """ Unbinds observer when this widget closes """ log.info('OnClose: %r', self) self.UnbindObservers() def WhenOrderPrefChanged(self, sortorder): if self.order != sortorder: self.order = sortorder active = dict([(acct.id, acct) for acct in self.active]) self.active = [active[id] for id in sortorder if id in active] self.Refresh() def WhenUnlockedPrefChanged(self, unlcoked): self.unlocked = pref(self.prefkey + '.unlocked', True) def BindObservers(self): """ Sets up observers on a list of accounts """ self._obs_link = self.accts.add_list_observer( self.BuildList, self.WhenStateChanged, 'state', 'enabled', 'count', 'offline_reason', 'alerts', 'alias') profile.prefs.link(self.prefkey + '.order', self.WhenOrderPrefChanged, False) profile.prefs.link(self.prefkey + '.unlocked', self.WhenUnlockedPrefChanged, False) def UnbindObservers(self): 'Removes observers on a list of accounts' if self._obs_link is not None: self._obs_link.disconnect() self._obs_link = None def CalledAfterRefreshLine(self, acct): try: self.RefreshLine(self.active.index(acct)) except ValueError: self.Refresh() def WhenStateChanged(self, acct, attr, old, new): 'This handles all changes on an account level.' #update new item count if attr in ('count', 'alerts', 'alias'): wx.CallAfter(self.CalledAfterRefreshLine, acct) #rebuild list when account is disabled or enabled elif attr == 'enabled': wx.CallAfter(self.BuildList) #Offline reason has changed, set up message elif attr == 'state' or attr == 'offline_reason': if acct.offline_reason == acct.Reasons.WILL_RECONNECT: self.willreconaccts.add(acct) else: self.willreconaccts.discard(acct) if len(self.willreconaccts): refreshtimer().Register(self) else: refreshtimer().UnRegister(self) self.Refresh() def OnMouseOut(self, event=None): """ Make sure selection gets updated on mouse out """ i = self.Selection if i != -1: self.RefreshLine(i) self.Selection = -1 def OnMouseWheel(self, e): # foward mouse wheel events to the infobox. if self.infobox.IsShown(): self.infobox.on_mousewheel(e) def OnMouseMotion(self, event): """ Selection gets update and infobox gets requested on mouse over item """ mp = event.Position hit = self.HitTest(mp) dragging = event.Dragging() selection = self.Selection active = self.active if self.unlocked and event.LeftIsDown( ) and dragging and self.HasCapture() and -1 not in ( selection, hit) and hit != selection: item = active[selection] active.pop(selection) active.insert(hit, item) sortorder = self.order sortorder.remove(item.id) i = sortorder.index(active[hit - 1].id) + 1 if hit > 0 else 0 sortorder.insert(i, item.id) setpref(self.prefkey + '.order', sortorder) self.Refresh() self.Selection = hit self.TryShowInfobox(hit) def OnLeftUp(self, event): while self.HasCapture(): self.ReleaseMouse() if not self.ClientRect.Contains(event.Position): self.OnMouseOut(event) def OnMouseLost(self, event): if not self.ClientRect.Contains( self.ScreenToClient(wx.GetMousePosition())): self.OnMouseOut() def OnLeftDown(self, event): self.infobox.quickshow = True self.TryShowInfobox(self.Selection) if not self.HasCapture(): self.CaptureMouse() def TryShowInfobox(self, i): if pref('infobox.show', True) and i >= 0: p = self.Parent pl = p.ClientToScreen( (0, self.Position.y + self.OnMeasureItem(0) * i)) pr = pl + (p.Size.width, 0) self.infobox.Display(pl, pr, self.active[i]) def OnLeftDblClick(self, event): """ performs the action associated with the list on DOuble Click """ self.OnDoubleClick(self.active[self.Selection]) self.infobox.Hide() def ToggleOrderLock(self): self.unlocked = not self.unlocked setpref(self.prefkey + '.unlocked', self.unlocked) def OnRightUp(self, event): """ Generate and open menu on right click """ if self.Selection >= 0: # populate the popup menu with actions self.menu.RemoveAllItems() acct = self.active[self.Selection] if hasattr(getattr(acct, 'menu_actions', None), '__call__'): acct.menu_actions(self.menu) elif isinstance(acct, EmailAccount): #HAX: an ugly hack until Email-specific actions are removed from EmailAccount. actions.menu(wx.FindWindowByName('Buddy List'), acct, menu=self.menu, search_bases=False, cls=EmailAccount) else: actions.menu(wx.FindWindowByName('Buddy List'), acct, menu=self.menu) self.menu.AddSep() # if self.prefkey is not None: # unlockitem = self.menu.AddCheckItem(_('Allow Rearrange'), callback = self.ToggleOrderLock) # unlockitem.Check(self.unlocked) self.menu.PopupMenu() def BuildList(self, *__): """ When the account list changes rebuild the list of items to display. Then it recalculates size needs. """ try: self.__i += 1 except: self.__i = 1 accts = self.accts sortorder = pref(self.prefkey + '.order') self.order = sortorder[:] if not len(sortorder): sortorder = [acct.id for acct in accts] elif len(sortorder) != len(accts) or set( acct.id for acct in accts) != set(sortorder): for acct in accts: if acct.id not in sortorder: i = accts.index(acct) i = sortorder.index(self.accts[i - 1].id) + 1 if i > 0 else 0 sortorder.insert(i, acct.id) sortset = set(sortorder) if len(sortorder) != len(sortset): cleansortorder = [] for i in sortorder: if i in sortset: cleansortorder.append(i) sortset.remove(i) sortorder = cleansortorder if self.order != sortorder: setpref(self.prefkey + '.order', sortorder) active = dict([(acct.id, acct) for acct in accts if acct.enabled]) self.active = [active[id] for id in sortorder if id in active] with self.Frozen(): self.ItemCount = len(self.active) self.Size = self.MinSize = wx.Size( -1, self.ItemCount * self.itemheight) self.Top.Layout() self.Top.Refresh() self.Refresh() def UpdateSkin(self): """ The usual """ skinget = lambda s, default: skin('%s.%s' % (self.skinkey, s), default) self.padding = skinget('padding', lambda: wx.Point(3, 3)) self.Font = skinget('font', default_font) self.iconsize = skinget('iconsize', 16) self.itemheight = max(self.iconsize, self.Font.LineHeight) + self.padding.y * 2 default_color = SkinColor(wx.Color(225, 255, 225)) self.bg = skinget('backgrounds.normal', default_color) self.selbg = skinget('backgrounds.hover', default_color) self.fontcolor = skinget('fontcolors.normal', wx.BLACK) self.selfontcolor = skinget('fontcolors.hover', wx.BLACK) self.MinSize = wx.Size(-1, self.itemheight * self.ItemCount) def OnMeasureItem(self, n): "Returns the predetermined item height" return self.itemheight def OnDrawBackground(self, dc, rect, n): getattr(self, 'selbg' if self.Selection == n else 'bg').Draw(dc, rect, n) def OnDrawItem(self, dc, rect, n): 'Draw the foreground content of the item.' dc.Font = self.Font dc.TextForeground = self.selfontcolor if n == self.Selection else self.fontcolor acct = self.active[n] iconsize = self.iconsize if (hasattr(acct, 'count') and acct.count > 0) or not should_grey(acct): icon = acct.icon.Resized(iconsize) else: icon = acct.icon.Greyed.Resized(iconsize) pad = self.padding.x dc.DrawBitmap(icon, rect.x + pad, rect.y + self.itemheight / 2 - icon.Height / 2, True) xoff = iconsize + 2 * pad textRect = wx.Rect( rect.x + xoff, rect.y + self.itemheight / 2 - dc.Font.LineHeight / 2, rect.width - xoff, dc.Font.LineHeight) dc.DrawTruncatedText(self.labelCallback(acct), textRect)
class AccountTrayIcon(baseAccountTrayClass): @classmethod def create(cls, acct, infobox): ### ### TODO: this is less awful, but still awful ### trayClass = ITrayIconProvider(acct).tray_icon_class() if config.platform == 'mac': object = trayClass.alloc().init() object.initWithAccount(acct, infobox) return object else: return trayClass(acct, infobox) def __init__(self, acct, infobox=None): # This method doesn't run for PyObjC icons (see initWithAccount instead), so it's okay # to put wx and Observable code in here. self.acct = acct self.infobox = infobox from gui.uberwidgets.umenu import UMenu self._menu = UMenu(wx.FindWindowByName('Buddy List'), onshow=self.update_menu) # generate unique tray icon IDs for each account that are persistent # across program runs (specifically, for Windows' tray icon hiding options) trayid = hash('accounttrayicon_' + acct.protocol + '_' + acct.name) super(AccountTrayIcon, self).__init__(acct.icon, menu=self._menu, id=trayid) self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_click) self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.on_double_click) self.register_observers(acct, self.on_account_updated) self.on_account_updated() def update_menu(self, event=None): self._menu.RemoveAllItems() actions.menu(wx.FindWindowByName('Buddy List'), self.acct, cls=type(self.acct), menu=self._menu) def on_click(self, e=None): try: dclick_timer = self.dclick_timer except AttributeError: dclick_timer = self.dclick_timer = wx.PyTimer(lambda: None) if dclick_timer.IsRunning(): self.on_double_click() dclick_timer.Stop() else: dclick_timer.StartOneShot(GetDoubleClickTime()) self.show_infobox() e.Skip() def on_double_click(self, e=None): if self.infobox.IsShown(): self.infobox.Hide() url = self.acct.DefaultAction() if url is not None: wx.LaunchDefaultBrowser(url) def show_infobox(self): if not self.infobox: return info = self.infobox if info.IsShown() and getattr(info, 'account', None) is self.acct: info.Hide() else: pt = self.get_infobox_tray_position() info.ShowFromTray(pt, self.acct) # info.Show() # tell the infobox to gain focus, so the mousewheel works wx.CallAfter(info.do_focus) def get_infobox_tray_position(self): #TODO: find taskbar position from the correct HWND. this code assumes the mouse # is on the same display as the tray, and that the tray is on the bottom of the # "client area" rectangle returned by wxDisplay try: import cgui r = cgui.GetTrayRect() pt = Point(r.Right - r.Width / 2, r.Bottom - r.Height / 2) display = Monitor.GetFromPoint(pt, find_near=True) rect = display.GetClientArea() distances = [] for p in ('TopLeft', 'TopRight', 'BottomLeft', 'BottomRight'): corner = getattr(rect, p) distances.append((corner, corner.DistanceTo(pt), p)) distances.sort(key=itemgetter(1)) corner, distance, name = distances[0] return corner except Exception: print_exc() return Monitor.GetFromPointer().ClientArea.BottomRight def Destroy(self): self._destroyed = True if not config.platform == 'mac': self.unregister_observers(self.acct, self.on_account_updated) return super(AccountTrayIcon, self).Destroy() @property def count_string(self): acct = self.acct if acct.offline_reason != acct.Reasons.NONE: count = 'X' else: count = getattr(acct, 'count', 0) return count def on_account_updated(self, obj=None, attr=None, old=None, new=None): obj_or_event = obj if not self or getattr(self, '_destroyed', False): return acct = self.acct count = self.count_string if acct.enabled: # todo: remove this lame way figure out icon size icon = acct.icon.PIL.Resized(self._IconSize) if self.should_show_count() and count: # place text in the corner icon = draw_tiny_text(icon, str(count)).WX if pref('trayicons.email.gray_on_empty', True) and count in (0, 'X') and should_grey(acct): icon = icon.WXB.Greyed self.SetIcon(icon, self.Tooltip) def should_show_count(self): return pref('trayicons.email.show_count', True) @property def Tooltip(self): return ''
f.Bind(wx.EVT_MENU, lambda e: msg('%s %s %s' % (e, e.EventType, e.Id))) f.Bind(wx.EVT_CLOSE, lambda e: app.ExitMainLoop()) p = wx.Panel(f) f.CenterOnScreen() p.Sizer = wx.BoxSizer(wx.VERTICAL) bar = UMenuBar(p, p.Sizer) bmps = [ wx.Bitmap('..\\..\\..\\res\\%s.png' % aa) for aa in ('online', 'away', 'offline') ] m = UMenu(f) m.AddItem('&Preferences\tCtrl+P', callback=lambda: msg('prefs'), bitmap=skin.get('serviceicons.aim')) accounts_item = m.AddItem('&Accounts\tCtrl+A', callback=lambda: msg('show accounts!')) m.AddSep() sub = UMenu(f) g = sub.AddItem('one', callback=lambda: msg('one!')) sub.AddItem('two\tCtrl+T', bitmap=bmps[1]) three = sub.AddItem('three', bitmap=bmps[2]) sub4 = UMenu(f) sub4.AddItem('foo1')
def create_main_menu(parent): 'Returns the main menu object.' menu = MenuBar(parent, skinkey = 'menubar') digsby = Menu(parent) view = Menu(parent) tools = Menu(parent) help = Menu(parent) def makeadd(m): return (lambda title, callback = None, id = -1: m.AddItem(title, callback = callback, id = id)) # # My Status # mystatus = Menu(parent, onshow = update_statuses); add = makeadd(mystatus) add(_('&New Status Message...'), new_status_message) add(_('&Edit Status Messages...'), lambda: prefsdialog_show('status')) mystatus.AddSep() from gui.protocols import add_group def add_chat(): import gui.chatgui gui.chatgui.join_chat() # # Digsby # digsby.AddSubMenu(mystatus, _('My Status')); add = makeadd(digsby) add(_('My &Accounts...'), lambda: prefsdialog_show('accounts')) digsby.AddSep() sendimitem = add(_('&New IM...\tCtrl+N'), ShowNewIMDialog) if pref('messaging.groupchat.enabled', False): groupchatitem = add(_('New Group C&hat...\tCtrl+Shift+N'), add_chat) else: groupchatitem = None digsby.AddSep() addcontactitem = add(_('Add &Contact...\tCtrl+A'),lambda : AddContactDialog.MakeOrShow()) addgroupitem = add(_('Add &Group...\tCtrl+Shift+A'), lambda: add_group()) renameitem = add(_('&Rename Selection'), lambda: parent.blist.rename_selected()) deleteitem = add(_('&Delete Selection...'), lambda: parent.blist.delete_blist_item(parent.blist.SelectedItem)) digsby.AddSep() add(_('Sign &Off Digsby (%s)') % profile.name, lambda: profile.signoff()) # wx.App handles this for proper shutdown. add(_('E&xit Digsby'), id = wx.ID_EXIT) def on_digsby_show(_m): b = parent.blist.SelectedItem allow_add = any(x.allow_contact_add for x in profile.account_manager.connected_accounts) for item in (sendimitem, groupchatitem, addcontactitem, addgroupitem): if item is not None: item.Enable(allow_add) if not allow_rename(b): renameitem.SetItemLabel(_('&Rename Selection')) deleteitem.SetItemLabel(_('&Delete Selection')) renameitem.Enable(False) deleteitem.Enable(False) else: renameitem.SetItemLabel(_('&Rename {name}').format(name=getattr(b, 'alias', b.name))) deleteitem.SetItemLabel(_('&Delete {name}').format(name=getattr(b, 'alias', b.name))) renameitem.Enable(True) deleteitem.Enable(True) # # View # add = makeadd(view) view.AddPrefCheck('buddylist.always_on_top', _('&Always On Top')) add(_('Skins...\tCtrl+S'), lambda: prefsdialog_show('appearance')) view.AddSep() view.AddPrefCheck('buddylist.show_menubar', _('&Menu Bar')) def on_menubar(val): if not val: wx.MessageBox(_('You can bring back the menubar by right clicking ' 'on the digsby icon in the task tray.'), _('Hide Menu Bar')) profile.prefs.link('buddylist.show_menubar', lambda val: wx.CallAfter(on_menubar, val), False, menu) view.AddPrefCheck('buddylist.show_status', _('Status Panel')) add(_('Arrange &Panels...'), callback = lambda *_a: edit_buddylist_order(parent)) view.AddSep() view.AddPrefCheck('buddylist.show_mobile', _('Show &Mobile Contacts\tCtrl+M')) view.AddPrefCheck('buddylist.show_offline', _('Show &Offline Contacts\tCtrl+O')) groupoffline = view.AddPrefCheck('buddylist.group_offline', _('&Group Offline Contacts\tCtrl+G')) hideoffline = view.AddPrefCheck('buddylist.hide_offline_groups', _('&Hide Offline Groups')) groupby = Menu(parent); add = makeadd(groupby) groupby.sorttypes = [] # sort by sortby = Menu(parent); add = makeadd(sortby) sortby.sorttypes = [] sort_models = profile.blist.sort_models group_by = sort_models[0] sort_by = sort_models[1] then_by = sort_models[2] def addsort(model, view, sortstr, title): def set(model = model, view = view, sortstr = sortstr): model.selection = [v[0] for v in model.values].index(sortstr) view[model.selection].Check(True) mi = view.AddCheckItem(title, set) view.sorttypes.append( sortstr ) return mi sort_names = dict((('none', _('&None')), ('status', _('&Status')), ('name', _('N&ame')), ('log', _('&Log Size')), ('service', _('Ser&vice')))) def addsorts(model, view, names): for name in names: addsort(model = model, view = view, sortstr = name, title = sort_names[name]) addsorts(model = group_by, view = groupby, names = [k for k,_v in GROUP_BY_CHOICES]) groupby.AddSep() groupby.AddItem(_('Advan&ced...'), callback = lambda: prefsdialog_show('contact_list')) addsorts(model = sort_by, view = sortby, names = [k for k,_v in SORT_BY_CHOICES]) sortby.AddSep() def sortby_adv_click(): sortby[-1].Check(then_by.selection > 0) prefsdialog_show('contact_list') sortby.AddCheckItem(_('Advan&ced...'), callback = sortby_adv_click) sortby_adv = sortby[-1] groupby.reset_watcher = reset_checks_SortOptionWatcher(model = group_by, view = groupby, names = GROUP_BY_CHOICES) sortby.reset_watcher = reset_checks_SortOptionWatcher(model = sort_by, view = sortby, names = SORT_BY_CHOICES) sortby.adv_watcher = reset_check_AdvWatcher(model = then_by, view = sortby_adv) view.AddSep() view.AddSubMenu(groupby, _('&Group By')) view.AddSubMenu(sortby, _('&Sort By')) # # Tools # add = makeadd(tools) add(_('&Preferences...\tCtrl+P'), id = wx.ID_PREFERENCES, callback = lambda: prefsdialog_show('accounts')) add(_('Buddy List &Search\tCtrl+F'), parent.start_search) add(_('&File Transfer History\tCtrl+J'), FileTransferDialog.Display) def pb_show(): from gui.pastbrowser import PastBrowser PastBrowser.MakeOrShow() add(_('&Chat History\tCtrl+H'), pb_show) # # Help # add = makeadd(help) add(_('&Documentation'), lambda: wx.LaunchDefaultBrowser('http://wiki.digsby.com')) add(_('Support &Forums'), lambda: wx.LaunchDefaultBrowser('http://forum.digsby.com')) help.AddSep() add(_('&Submit Bug Report'), do_diagnostic) add(_('Su&ggest a Feature'), send_features_email) help.AddSep() if getattr(sys, 'DEV', False) or pref('debug.console', False): add(_('Show Debug Console'), wx.GetApp().toggle_crust) help.AddSep() add(_('Su&pport Digsby'), lambda: support.SupportFrame.MakeOrShow(parent)) for hook in Hook("digsby.help.actions"): help_menu_items = hook() for item in help_menu_items: add(*item) def on_view_show(_m): sortstatus = pref('buddylist.sortby').startswith('*status') showoffline = pref('buddylist.show_offline') hidegroups = pref('buddylist.hide_offline_groups') groupoff = pref('buddylist.group_offline') groupoffline.Enable(not sortstatus and showoffline) groupoffline.Check(groupoff and (not sortstatus and showoffline)) hideoffline.Enable(not sortstatus) hideoffline.Check((sortstatus and not showoffline) or (not sortstatus and hidegroups)) digsbyMenuName = _('&Digsby') if config.platformName == "mac": digsbyMenuName = _("&File") menu.Append(digsby, digsbyMenuName, onshow = on_digsby_show) menu.Append(view, _('&View'), onshow = on_view_show) menu.Append(tools, _('&Tools'), onshow = lambda m: on_accounts_entries(parent, m)) menu.Append(help, _('&Help')) return menu