Example #1
0
    def __init__(self,
                 parent,
                 buddy_callback,
                 showCapabilities=True,
                 infoboxmode=False):
        SimplePanel.__init__(self, parent)

        self.buddy_callback = buddy_callback

        self.Bind(wx.EVT_PAINT, lambda e: wx.PaintDC(self))

        self.infoboxmode = infoboxmode
        self._lastcaps = None

        self.UpdateSkin()
        self.Sizer = wx.BoxSizer(wx.VERTICAL)

        # create delegates for callbacks
        for action in ('OnSendFiles', 'OnSendFolder', 'OnViewPastChats',
                       'OnAlert', 'OnBlock', 'OnAddContact'):
            setattr(self, action, Delegate())

        # Create the uberbar for the capabilities.
        self.cbar = bar = UberBar(self,
                                  skinkey=self.capabilitiesskin,
                                  overflowmode=True)
        # FIXME: we should simply not allow the capabilities bar to be created for native mode
        if not showCapabilities or nativeIMWindow:
            self.cbar.Hide()

        if not infoboxmode:
            self.cbar.Bind(wx.EVT_CONTEXT_MENU,
                           lambda e: self.ActionsBarMenu.PopupMenu(event=e))

        # Create all the buttons for the capabilities bar.

        iconsize = skin.get('ActionsBar.IconSize')
        icons = skin.get('ActionsBar.Icons')

        for attr, title, tooltip in buttons:
            icon = getattr(icons, attr).Resized(iconsize)
            if attr == 'files':
                # "files" has a dropdown menu
                button = UberButton(bar,
                                    -1,
                                    title,
                                    icon=icon,
                                    type='menu',
                                    menu=self.FileMenu)

                # Change the label and action of the files button when it's overflowed into
                # the menu on the right.
                button.overflow_label = _('Send File')
                button.overflow_callback = self.OnSendFiles
            else:
                # hack until I fix this :[ -kevin
                if attr == 'video' and infoboxmode: continue

                button = UberButton(bar, -1, title, icon=icon)
                button.overflow_label = title

            button.SetToolTipString(tooltip)

            setattr(self, 'b' + attr, button)
            bar.Add(button, calcSize=False)

        bar.OnUBSize()

        #TODO Add button logics

        #        if not self.infoboxmode:
        #            self.badd = UberButton(bar,-1,'',icon = getattr(icons, 'add').Resized(iconsize))
        #            bar.AddStatic(self.badd)
        #            self.badd.Bind(wx.EVT_BUTTON,lambda e: self.OnAddContact())

        # Create multichat icon for the roomlist
        if pref('messaging.groupchat.enabled', False) and not self.infoboxmode:
            self.bmultichat = UberButton(
                bar,
                -1,
                icon=skin.get('actionsbar.icons.roomlist').Resized(16),
                type='toggle')
            self.bmultichat.SetToolTipString(_('Group Chat'))
            bar.AddStatic(self.bmultichat)

        self.ihistory = SimpleMenuItem(_('View Past Chats'),
                                       method=self.OnViewPastChats)

        def show_prefs_notifications(a):
            import gui.pref.prefsdialog as prefsdialog
            prefsdialog.show('notifications')

        self.ialert = SimpleMenuItem(_("Alert Me When..."),
                                     method=show_prefs_notifications)
        self.iblock = SimpleMenuItem(_("Block"), method=self.OnBlock)

        if not self.infoboxmode:
            self.iadd = SimpleMenuItem(_("Add Contact"),
                                       method=self.OnAddContact)
            bar.AddMenuItem(self.iadd)
        bar.AddMenuItem(self.ihistory)
        bar.AddMenuItem(self.ialert)

        if not self.infoboxmode:
            bar.AddMenuItem(SimpleMenuItem(id=-1))
            bar.AddMenuItem(self.iblock)

        self.Sizer.Add(bar, 0, wx.EXPAND)

        # create the To/From bar
        self.tfbar = tfbar = UberBar(self, skinkey=self.tofromskin)
        self.tfbar.Hide()

        tofrom_font = skin.get('tofrombar.font', default_font)
        tofrom_color = skin.get('tofrombar.fontcolor', wx.BLACK)

        talign = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT

        self.to_label = ClearText(tfbar, _('To:'), alignment=talign)
        self.to_label.Font = tofrom_font
        self.to_label.FontColor = tofrom_color
        self.from_label = ClearText(tfbar, _('From:'), alignment=talign)
        self.from_label.Font = tofrom_font
        self.from_label.FontColor = tofrom_color

        self.cto = UberCombo(tfbar,
                             skinkey=self.tofromcomboskin,
                             typeable=False,
                             size=(100, 20),
                             minmenuwidth=200)
        self.cfrom = UberCombo(tfbar,
                               skinkey=self.tofromcomboskin,
                               typeable=False,
                               size=(100, 20),
                               minmenuwidth=200)

        tfbar.Add(self.to_label, calcSize=False)
        tfbar.Add(self.cto, True, calcSize=False)
        tfbar.Add(self.from_label, calcSize=False)
        tfbar.Add(self.cfrom, True)

        self.Sizer.Add(tfbar, 0, wx.EXPAND)

        profile.prefs.link(action_icons_key, self.UpdateIcons)

        self.cbar.overflowmenu.BeforeDisplay += self.ApplyCaps
Example #2
0
class CapabilitiesBar(SimplePanel):
    '''
    A specialized UberBar used used in the infobox and the IM window
    has a subbar with to/from combos.
    '''
    def __init__(self,
                 parent,
                 buddy_callback,
                 showCapabilities=True,
                 infoboxmode=False):
        SimplePanel.__init__(self, parent)

        self.buddy_callback = buddy_callback

        self.Bind(wx.EVT_PAINT, lambda e: wx.PaintDC(self))

        self.infoboxmode = infoboxmode
        self._lastcaps = None

        self.UpdateSkin()
        self.Sizer = wx.BoxSizer(wx.VERTICAL)

        # create delegates for callbacks
        for action in ('OnSendFiles', 'OnSendFolder', 'OnViewPastChats',
                       'OnAlert', 'OnBlock', 'OnAddContact'):
            setattr(self, action, Delegate())

        # Create the uberbar for the capabilities.
        self.cbar = bar = UberBar(self,
                                  skinkey=self.capabilitiesskin,
                                  overflowmode=True)
        # FIXME: we should simply not allow the capabilities bar to be created for native mode
        if not showCapabilities or nativeIMWindow:
            self.cbar.Hide()

        if not infoboxmode:
            self.cbar.Bind(wx.EVT_CONTEXT_MENU,
                           lambda e: self.ActionsBarMenu.PopupMenu(event=e))

        # Create all the buttons for the capabilities bar.

        iconsize = skin.get('ActionsBar.IconSize')
        icons = skin.get('ActionsBar.Icons')

        for attr, title, tooltip in buttons:
            icon = getattr(icons, attr).Resized(iconsize)
            if attr == 'files':
                # "files" has a dropdown menu
                button = UberButton(bar,
                                    -1,
                                    title,
                                    icon=icon,
                                    type='menu',
                                    menu=self.FileMenu)

                # Change the label and action of the files button when it's overflowed into
                # the menu on the right.
                button.overflow_label = _('Send File')
                button.overflow_callback = self.OnSendFiles
            else:
                # hack until I fix this :[ -kevin
                if attr == 'video' and infoboxmode: continue

                button = UberButton(bar, -1, title, icon=icon)
                button.overflow_label = title

            button.SetToolTipString(tooltip)

            setattr(self, 'b' + attr, button)
            bar.Add(button, calcSize=False)

        bar.OnUBSize()

        #TODO Add button logics

        #        if not self.infoboxmode:
        #            self.badd = UberButton(bar,-1,'',icon = getattr(icons, 'add').Resized(iconsize))
        #            bar.AddStatic(self.badd)
        #            self.badd.Bind(wx.EVT_BUTTON,lambda e: self.OnAddContact())

        # Create multichat icon for the roomlist
        if pref('messaging.groupchat.enabled', False) and not self.infoboxmode:
            self.bmultichat = UberButton(
                bar,
                -1,
                icon=skin.get('actionsbar.icons.roomlist').Resized(16),
                type='toggle')
            self.bmultichat.SetToolTipString(_('Group Chat'))
            bar.AddStatic(self.bmultichat)

        self.ihistory = SimpleMenuItem(_('View Past Chats'),
                                       method=self.OnViewPastChats)

        def show_prefs_notifications(a):
            import gui.pref.prefsdialog as prefsdialog
            prefsdialog.show('notifications')

        self.ialert = SimpleMenuItem(_("Alert Me When..."),
                                     method=show_prefs_notifications)
        self.iblock = SimpleMenuItem(_("Block"), method=self.OnBlock)

        if not self.infoboxmode:
            self.iadd = SimpleMenuItem(_("Add Contact"),
                                       method=self.OnAddContact)
            bar.AddMenuItem(self.iadd)
        bar.AddMenuItem(self.ihistory)
        bar.AddMenuItem(self.ialert)

        if not self.infoboxmode:
            bar.AddMenuItem(SimpleMenuItem(id=-1))
            bar.AddMenuItem(self.iblock)

        self.Sizer.Add(bar, 0, wx.EXPAND)

        # create the To/From bar
        self.tfbar = tfbar = UberBar(self, skinkey=self.tofromskin)
        self.tfbar.Hide()

        tofrom_font = skin.get('tofrombar.font', default_font)
        tofrom_color = skin.get('tofrombar.fontcolor', wx.BLACK)

        talign = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT

        self.to_label = ClearText(tfbar, _('To:'), alignment=talign)
        self.to_label.Font = tofrom_font
        self.to_label.FontColor = tofrom_color
        self.from_label = ClearText(tfbar, _('From:'), alignment=talign)
        self.from_label.Font = tofrom_font
        self.from_label.FontColor = tofrom_color

        self.cto = UberCombo(tfbar,
                             skinkey=self.tofromcomboskin,
                             typeable=False,
                             size=(100, 20),
                             minmenuwidth=200)
        self.cfrom = UberCombo(tfbar,
                               skinkey=self.tofromcomboskin,
                               typeable=False,
                               size=(100, 20),
                               minmenuwidth=200)

        tfbar.Add(self.to_label, calcSize=False)
        tfbar.Add(self.cto, True, calcSize=False)
        tfbar.Add(self.from_label, calcSize=False)
        tfbar.Add(self.cfrom, True)

        self.Sizer.Add(tfbar, 0, wx.EXPAND)

        profile.prefs.link(action_icons_key, self.UpdateIcons)

        self.cbar.overflowmenu.BeforeDisplay += self.ApplyCaps

    ToCombo = property(lambda self: self.cto)
    FromCombo = property(lambda self: self.cfrom)

    def UpdateSkin(self):
        'Tells the subbars what skins they should load.'

        sget = skin.get
        self.capabilitiesskin = sget('actionsbar.toolbarskin', None)
        self.tofromskin = sget('tofrombar.toolbarskin', None)

        self.menuskin = sget('%s.menuskin' % self.capabilitiesskin, None)

        self.tofromcomboskin = sget("tofrombar.comboboxskin", None)

        self.iconsize = sget('ActionsBar.IconSize')
        self.icons = sget('ActionsBar.Icons')

        if hasattr(self, 'to_label'):
            tofrom_font = sget('tofrombar.font', lambda: default_font())
            tofrom_color = sget('tofrombar.fontcolor', lambda: wx.BLACK)

            self.to_label.Font = self.from_label.Font = tofrom_font
            self.to_label.FontColor = self.from_label.FontColor = tofrom_color

        if hasattr(self, 'cbar'): self.cbar.SetSkinKey(self.capabilitiesskin)
        if hasattr(self, 'tfbar'): self.tfbar.SetSkinKey(self.tofromskin)
        if hasattr(self, 'cto'): self.cto.SetSkinKey(self.tofromcomboskin)
        if hasattr(self, 'cfrom'): self.cfrom.SetSkinKey(self.tofromcomboskin)

        self.UpdateIcons()

    def UpdateIcons(self, *a):
        'Updates icon sizes for buttons.'

        icons_pref = pref(action_icons_key)
        textonly = icons_pref == 'text'

        icons = self.icons
        size = self.iconsize
        #TODO: Add Button logics
        #        allbuttons = list(buttons)
        #        allbuttons.append(('add',''))

        with self.Frozen():
            for attr, title, tooltip in buttons:
                icon = None if textonly else getattr(icons, attr).Resized(size)
                button = getattr(self, 'b' + attr, None)
                if button is not None:
                    button.SetIcon(icon)
                    button.SetAlignment(wx.VERTICAL if icons_pref ==
                                        'above' else wx.HORIZONTAL)
                    button.SetLabel('' if icons_pref == 'icons' else title)

        self.Parent.Layout()
        self.Refresh()

    def ShowToFrom(self, show=True):
        'Show or hide the to/from bar.'

        return self.tfbar.Show(show)

    @property
    def RoomListButtonShown(self):
        bmultichat = getattr(self, 'bmultichat', None)
        return bmultichat is not None and bmultichat.IsShown()

    @property
    def ToFromShown(self):
        'Returns True if the To/From bar is shown.'

        return self.tfbar.IsShown()

    def ShowCapabilities(self, show=True):
        'Show/Hide the capabilities bar.'

        return self.cbar.Show(show)
        #self.Layout()

    def CapabilitiesIsShown(self):
        'Returns True if the capabilities bar is shown.'

        return self.cbar.IsShown()

    def GetButton(self, button):
        'Returns one of the butons by name.'

        return getattr(self, 'b' + button, None)

    def ApplyCaps(self, contact=None, convo=None):
        'Those shows and hides options depending on the capabilities the Contact reports.'

        if contact is None and convo is None:
            convo = self.buddy_callback()
            from common.Conversation import Conversation
            if not isinstance(convo, Conversation):
                contact = convo
                convo = None

        c = None
        if convo is not None:
            if convo.ischat:
                c = set([caps.IM])
            elif contact is None:
                contact = convo.buddy

        if c is None:
            c = set(contact.caps)

        if contact is not None:
            c.add(('blocked', contact.blocked))

        # early exit if capabilities are the same.
        if c == self._lastcaps: return

        buttons_caps = [('binfo', contact is not None and not any(
            (contact.sms and contact.mobile, self.infoboxmode))),
                        ('bim', caps.IM in c), ('bfiles', caps.FILES in c),
                        ('bemail', caps.EMAIL in c), ('bsms', caps.SMS in c),
                        ('bvideo', caps.VIDEO in c)]

        for name, val in buttons_caps:
            ctrl = getattr(self, name, None)
            if ctrl is not None:
                ctrl.Show(ctrl, val, False)

        cbar = self.cbar
        menu = cbar.overflowmenu
        count = menu.spine.items.count
        iblock = self.iblock

        if caps.BLOCKABLE in c and not count(iblock):
            cbar.AddMenuItem(SimpleMenuItem(id=-1))
            cbar.AddMenuItem(iblock)
        elif not caps.BLOCKABLE in c and count(iblock):
            cbar.overflowmenu.RemoveItem(iblock)

        if contact is not None:
            if contact.blocked:
                content = _('Unblock {name}')
            else:
                content = _('Block {name}')

            iblock.content = [content.format(name=contact.name)]

        self.set_groupchat_visibility(contact, convo)

        i = len(menu.spine.items) - 1
        if menu.GetItem(i).id == -1:
            menu.RemoveItem(i)

        # don't show the dropdown on the right for widgets.
        self.cbar.overflowbutton.Show(not getattr(contact, 'iswidget', False))

        self._lastcaps = c

        cbar.GenWidthRestriction(True)

        self.update_add_contact_shown(convo)

        self.Parent.Layout()

    def update_add_contact_shown(self, convo):
        if not hasattr(self, 'iadd'):
            return

        ischat = convo is not None and convo.ischat
        overflow = self.cbar.overflowmenu

        if ischat:
            if overflow.GetIndex(self.iadd) != -1:
                overflow.RemoveItem(self.iadd)
        else:
            if overflow.GetIndex(self.iadd) == -1:
                overflow.InsertItem(overflow.GetIndex(self.ihistory),
                                    self.iadd)

    def set_groupchat_visibility(self, contact, convo):
        if not hasattr(self, 'bmultichat'):
            return

        proto = getattr(contact, 'protocol', getattr(convo, 'protocol', None))
        groupchat = False
        if proto is not None:
            groupchat = getattr(proto,
                                'supports_group_chat', False) and getattr(
                                    contact, 'supports_group_chat', False)
            self.bmultichat.Show(groupchat)

    @property
    def FileMenu(self):

        self._filemenu = SimpleMenu(self, self.menuskin)
        self.send_file_item = SimpleMenuItem(_('Send File'),
                                             lambda *a: self.OnSendFiles())
        #            if b and b.online:
        self._filemenu.AppendItem(self.send_file_item)
        self._filemenu.AppendItem(
            SimpleMenuItem(_('Transfer History'),
                           lambda *a: FileTransferDialog.Display()))

        return self._filemenu

#        try:
#            return self._filemenu
#        except AttributeError:
#            self._filemenu = self.build_file_menu()
#            return self._filemenu

    @property
    def ActionsBarMenu(self):
        try:
            return self._actionsbarmenu
        except AttributeError:
            self._actionsbarmenu = self.build_actionsbar_menu()
            return self._actionsbarmenu

    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 update_actionsbar_menu(self, menu):
        p = pref(action_icons_key)
        for name, item in self._actionsbar_checks.iteritems():
            item.Check(p == name)