示例#1
0
    def get_tab_image(self, count_unread=True):
        jid = self.gc_contact.get_full_jid()
        if app.config.get('show_avatar_in_tabs'):
            scale = self.parent_win.window.get_scale_factor()
            surface = app.contacts.get_avatar(
                self.account, jid, AvatarSize.TAB, scale)
            if surface is not None:
                return surface

        if count_unread:
            num_unread = len(app.events.get_events(
                self.account, jid, ['printed_' + self.type_id, self.type_id]))
        else:
            num_unread = 0

        transport = None
        if app.jid_is_transport(jid):
            transport = app.get_transport_name_from_jid(jid)

        if self.gc_contact.presence.is_unavailable:
            show = 'offline'
        else:
            show = self.gc_contact.show.value

        if num_unread and app.config.get('show_unread_tab_icon'):
            icon_name = get_icon_name('event', transport=transport)
        else:
            icon_name = get_icon_name(show, transport=transport)

        return icon_name
示例#2
0
 def _update_banner_state_image(self):
     # Set banner image
     if self.gc_contact.presence.is_unavailable:
         icon = get_icon_name('offline')
     else:
         icon = get_icon_name(self.gc_contact.show.value)
     banner_status_img = self.xml.get_object('banner_status_image')
     banner_status_img.set_from_icon_name(icon, Gtk.IconSize.DND)
示例#3
0
 def show_icon(self):
     window_mode = app.interface.msg_win_mgr.mode
     if window_mode in (MessageWindowMgr.ONE_MSG_WINDOW_PERTYPE,
                        MessageWindowMgr.ONE_MSG_WINDOW_NEVER):
         if self.type_ == 'gc':
             icon = get_icon_name('muc-active')
             self.window.set_icon_name(icon)
示例#4
0
文件: tooltips.py 项目: bj-h/gajim
 def add_status_row(self, show, str_status, show_lock=False,
                    indent=True, transport=None):
     """
     Append a new row with status icon to the table
     """
     self.table.insert_row(self.current_row)
     image = Gtk.Image()
     icon_name = get_icon_name(show, transport=transport)
     image.set_from_icon_name(icon_name, Gtk.IconSize.MENU)
     spacer = Gtk.Label(label=self.spacer_label)
     image.set_halign(Gtk.Align.START)
     image.set_valign(Gtk.Align.CENTER)
     if indent:
         self.table.attach(spacer, 1, self.current_row, 1, 1)
     self.table.attach(image, 2, self.current_row, 1, 1)
     status_label = Gtk.Label()
     status_label.set_markup(str_status)
     status_label.set_halign(Gtk.Align.START)
     status_label.set_valign(Gtk.Align.START)
     status_label.set_line_wrap(True)
     self.table.attach(status_label, 3, self.current_row, 1, 1)
     if show_lock:
         lock_image = Gtk.Image()
         lock_image.set_from_icon_name('dialog-password', Gtk.IconSize.MENU)
         self.table.attach(lock_image, 4, self.current_row, 1, 1)
     self.current_row += 1
示例#5
0
    def _get_icon_name(obj):
        if obj.notif_type == 'msg':
            if obj.base_event.properties.is_muc_pm:
                return 'gajim-priv_msg_recv'

        elif obj.notif_type == 'pres':
            if obj.transport_name is not None:
                return '%s-%s' % (obj.transport_name, obj.show)
            return get_icon_name(obj.show)
        return None
示例#6
0
    def _get_icon_name(obj):
        if obj.notif_type == 'msg':
            if obj.base_event.mtype == 'pm':
                return 'gajim-priv_msg_recv'
            if obj.base_event.mtype == 'normal':
                return 'gajim-single_msg_recv'

        elif obj.notif_type == 'pres':
            if obj.transport_name is not None:
                return '%s-%s' % (obj.transport_name, obj.show)
            return get_icon_name(obj.show)
示例#7
0
    def set_img(self, *args):
        """
        Apart from image, we also update tooltip text here
        """
        if not app.interface.systray_enabled:
            return
        if app.config.get('trayicon') == 'always':
            self.status_icon.set_visible(True)
        if app.events.get_nb_systray_events():
            self.status_icon.set_visible(True)

            icon_name = get_icon_name('event')
            self.status_icon.set_from_icon_name(icon_name)
            return

        if app.config.get('trayicon') == 'on_event':
            self.status_icon.set_visible(False)

        icon_name = get_icon_name(self.status)
        self.status_icon.set_from_icon_name(icon_name)
示例#8
0
    def _get_avatar_image(self, account, jid, show):
        if self.new:
            icon_name = 'avatar-default'
            if self.groupchat:
                icon_name = get_icon_name('muc-inactive')
            return Gtk.Image.new_from_icon_name(icon_name, Gtk.IconSize.DND)

        scale = self.get_scale_factor()
        if self.groupchat:
            surface = app.interface.avatar_storage.get_muc_surface(
                account, jid, AvatarSize.CHAT, scale)
            return Gtk.Image.new_from_surface(surface)

        avatar = app.contacts.get_avatar(account, jid, AvatarSize.CHAT, scale,
                                         show)
        return Gtk.Image.new_from_surface(avatar)
示例#9
0
    def __init__(self,
                 account,
                 to='',
                 action='',
                 from_whom='',
                 subject='',
                 message='',
                 resource='',
                 session=None,
                 form_node=None):
        Gtk.ApplicationWindow.__init__(self)
        self.set_application(app.app)
        self.set_title(_('Send Single Message'))
        self.set_name('SendSingleMessageWindow')
        self.account = account
        self.action = action

        self.subject = subject
        self.message = message
        self.to = to
        self.from_whom = from_whom
        self.resource = resource
        self.session = session

        self._ui = get_builder('single_message_window.ui')
        self.message_tv_buffer = self._ui.message_textview.get_buffer()
        self.conversation_textview = ConversationTextview(
            account, used_in_history_window=True)
        self.conversation_textview.tv.show()
        self.conversation_textview.tv.set_left_margin(6)
        self.conversation_textview.tv.set_right_margin(6)
        self.conversation_textview.tv.set_top_margin(6)
        self.conversation_textview.tv.set_bottom_margin(6)
        self.conversation_tv_buffer = self.conversation_textview.tv.get_buffer(
        )
        self._ui.conversation_scrolledwindow.add(self.conversation_textview.tv)

        self.form_widget = None
        parent_box = self._ui.conversation_scrolledwindow.get_parent()
        if form_node:
            self.form_widget = DataFormWidget(form_node)
            self.form_widget.show_all()
            self._ui.conversation_scrolledwindow.hide()
            self._ui.message_label_received.hide()
            parent_box.add(self.form_widget)
            parent_box.child_set_property(self.form_widget, 'top-attach', 2)
            parent_box.child_set_property(self.form_widget, 'left-attach', 0)
            parent_box.child_set_property(self.form_widget, 'width', 2)
            self.action = 'form'

        self.message_tv_buffer.connect('changed', self.update_char_counter)
        if isinstance(to, list):
            jid = ', '.join([i[0].get_full_jid() for i in to])
            self._ui.to_entry.set_text(jid)
        else:
            self._ui.to_entry.set_text(to)

        if app.config.get('use_speller') and app.is_installed(
                'GSPELL') and action == 'send':
            lang = app.config.get('speller_language')
            gspell_lang = Gspell.language_lookup(lang)
            if gspell_lang is None:
                AspellDictError(lang)
            else:
                spell_buffer = Gspell.TextBuffer.get_from_gtk_text_buffer(
                    self._ui.message_textview.get_buffer())
                spell_buffer.set_spell_checker(Gspell.Checker.new(gspell_lang))
                spell_view = Gspell.TextView.get_from_gtk_text_view(
                    self._ui.message_textview)
                spell_view.set_inline_spell_checking(True)
                spell_view.set_enable_language_menu(True)

        self.prepare_widgets_for(self.action)

        # set_text(None) raises TypeError exception
        if self.subject is None:
            self.subject = _('(No subject)')
        self._ui.subject_entry.set_text(self.subject)
        self._ui.subject_from_entry_label.set_text(self.subject)

        if to == '':
            liststore = get_completion_liststore(self._ui.to_entry)
            self.completion_dict = helpers.get_contact_dict_for_account(
                account)
            keys = sorted(self.completion_dict.keys())
            for jid in keys:
                contact = self.completion_dict[jid]
                status_icon = get_icon_name(contact.show)
                liststore.append((status_icon, jid))
        else:
            self.completion_dict = {}

        self._ui.to_entry.connect('changed', self.on_to_entry_changed)
        self._ui.connect_signals(self)

        # get window position and size from config
        resize_window(self._ui.single_message_window,
                      app.config.get('single-msg-width'),
                      app.config.get('single-msg-height'))
        move_window(self._ui.single_message_window,
                    app.config.get('single-msg-x-position'),
                    app.config.get('single-msg-y-position'))

        self._ui.single_message_window.show_all()
示例#10
0
    def _fill_completion_dict(self):
        """
        Fill completion_dict for key auto completion. Then load history for
        current jid (by calling another function)

        Key will be either jid or full_completion_name (contact name or long
        description like "pm-contact from groupchat....").

        {key : (jid, account, nick_name, full_completion_name}
        This is a generator and does pseudo-threading via idle_add().
        """
        liststore = get_completion_liststore(
            self._ui.query_entry.get_child())
        liststore.set_sort_column_id(1, Gtk.SortType.ASCENDING)
        self._ui.query_entry.get_child().get_completion().connect(
            'match-selected', self.on_jid_entry_match_selected)

        self._ui.query_entry.set_model(liststore)

        # Add all jids in logs.db:
        db_jids = app.logger.get_jids_in_db()
        completion_dict = dict.fromkeys(db_jids)

        self.accounts_seen_online = list(app.contacts.get_accounts())

        # Enhance contacts of online accounts with contact.
        # Needed for mapping below
        for account in self.accounts_seen_online:
            completion_dict.update(
                helpers.get_contact_dict_for_account(account))

        muc_active_icon = get_icon_name('muc-active')
        online_icon = get_icon_name('online')

        keys = list(completion_dict.keys())
        # Move the actual jid at first so we load history faster
        actual_jid = self._ui.query_entry.get_child().get_text()
        if actual_jid in keys:
            keys.remove(actual_jid)
            keys.insert(0, actual_jid)
        if '' in keys:
            keys.remove('')
        if None in keys:
            keys.remove(None)
        # Map jid to info tuple
        # Warning : This for is time critical with big DB
        for key in keys:
            completed = key
            completed2 = None
            contact = completion_dict[completed]
            if contact:
                info_name = contact.get_shown_name()
                info_completion = info_name
                info_jid = contact.jid
            else:
                # Corresponding account is offline, we know nothing
                info_name = completed.split('@')[0]
                info_completion = completed
                info_jid = completed

            info_acc = self._get_account_for_jid(info_jid)

            if (app.logger.jid_is_room_jid(completed) or
                    app.logger.jid_is_from_pm(completed)):
                icon = muc_active_icon
                if app.logger.jid_is_from_pm(completed):
                    # It's PM. Make it easier to find
                    room, nick = app.get_room_and_nick_from_fjid(completed)
                    info_completion = '%s from %s' % (nick, room)
                    completed = info_completion
                    info_completion2 = '%s/%s' % (room, nick)
                    completed2 = info_completion2
                    info_name = nick
            else:
                icon = online_icon

            if len(completed) > 70:
                completed = completed[:70] + '[\u2026]'
            liststore.append((icon, completed))
            self.completion_dict[key] = (
                info_jid, info_acc, info_name, info_completion)
            self.completion_dict[completed] = (
                info_jid, info_acc, info_name, info_completion)
            if completed2:
                if len(completed2) > 70:
                    completed2 = completed2[:70] + '[\u2026]'
                liststore.append((icon, completed2))
                self.completion_dict[completed2] = (
                    info_jid, info_acc, info_name, info_completion2)
            if key == actual_jid:
                self._load_history(info_jid, self.account or info_acc)
            yield True
        keys.sort()
        yield False
示例#11
0
    def __init__(self):
        Gtk.ApplicationWindow.__init__(self)
        self.set_application(app.app)
        self.set_position(Gtk.WindowPosition.CENTER)
        self.set_show_menubar(False)
        self.set_title(_('Preferences'))

        self._ui = get_builder('preferences_window.ui')
        self.add(self._ui.preferences_window)

        ### General tab ###
        ## Behavior of Windows and Tabs
        # Set default for single window type
        choices = c_config.opt_one_window_types
        type_ = app.config.get('one_message_window')
        if type_ in choices:
            self._ui.one_window_type_combobox.set_active(choices.index(type_))
        else:
            self._ui.one_window_type_combobox.set_active(0)

        # Show roster on startup
        choices = c_config.opt_show_roster_on_startup
        type_ = app.config.get('show_roster_on_startup')
        if type_ in choices:
            self._ui.show_roster_on_startup.set_active(choices.index(type_))
        else:
            self._ui.show_roster_on_startup.set_active(0)

        # Quit on roster x
        st = app.config.get('quit_on_roster_x_button')
        self._ui.quit_on_roster_x_checkbutton.set_active(st)

        # Tab placement
        st = app.config.get('tabs_position')
        if st == 'top':
            self._ui.tabs_placement.set_active(0)
        elif st == 'bottom':
            self._ui.tabs_placement.set_active(1)
        elif st == 'left':
            self._ui.tabs_placement.set_active(2)
        else:  # right
            self._ui.tabs_placement.set_active(3)

        # Show avatar in tabs
        st = app.config.get('show_avatar_in_tabs')
        self._ui.show_avatar_in_tabs_checkbutton.set_active(st)

        ## Contact List Appearance
        # Display avatars in roster
        st = app.config.get('show_avatars_in_roster')
        self._ui.show_avatars_in_roster_checkbutton.set_active(st)

        # Display status msg under contact name in roster
        st = app.config.get('show_status_msgs_in_roster')
        self._ui.show_status_msgs_in_roster_checkbutton.set_active(st)

        # Display PEP in roster
        st1 = app.config.get('show_mood_in_roster')
        st2 = app.config.get('show_activity_in_roster')
        st3 = app.config.get('show_tunes_in_roster')
        st4 = app.config.get('show_location_in_roster')
        if st1 == st2 == st3 == st4:
            self._ui.show_pep_in_roster_checkbutton.set_active(st1)
        else:
            self._ui.show_pep_in_roster_checkbutton.set_inconsistent(True)

        # Sort contacts by show
        st = app.config.get('sort_by_show_in_roster')
        self._ui.sort_by_show_in_roster_checkbutton.set_active(st)
        st = app.config.get('sort_by_show_in_muc')
        self._ui.sort_by_show_in_muc_checkbutton.set_active(st)

        ### Chat tab ###
        ## Chat Settings
        # Use speller
        if app.is_installed('GSPELL'):
            st = app.config.get('use_speller')
            self._ui.speller_checkbutton.set_active(st)
        else:
            self._ui.speller_checkbutton.set_sensitive(False)

        # XEP-0184 positive ack
        st = app.config.get('positive_184_ack')
        self._ui.positive_184_ack_checkbutton.set_active(st)

        # Ignore XHTML
        st = app.config.get('ignore_incoming_xhtml')
        self._ui.xhtml_checkbutton.set_active(st)

        # Print status messages in single chats
        st = app.config.get('print_status_in_chats')
        self._ui.print_status_in_chats_checkbutton.set_active(st)

        # Show subject on join
        st = app.config.get('show_subject_on_join')
        self._ui.subject_on_join_checkbutton.set_active(st)

        # Group chat settings
        threshold_model = self._ui.sync_threshold_combobox.get_model()
        days = app.config.get_options('threshold_options', return_type=int)
        for day in days:
            if day == 0:
                label = _('No threshold')
            else:
                label = ngettext('%i day', '%i days', day, day, day)
            threshold_model.append([str(day), label])
        public_threshold = app.config.get('public_room_sync_threshold')
        self._ui.sync_threshold_combobox.set_id_column(0)
        self._ui.sync_threshold_combobox.set_active_id(str(public_threshold))

        st = app.config.get('print_join_left_default')
        self._ui.join_leave_checkbutton.set_active(st)

        st = app.config.get('print_status_muc_default')
        self._ui.status_change_checkbutton.set_active(st)

        # Displayed chat state notifications
        st = app.config.get('show_chatstate_in_tabs')
        self._ui.show_chatstate_in_tabs.set_active(st)

        st = app.config.get('show_chatstate_in_roster')
        self._ui.show_chatstate_in_roster.set_active(st)

        st = app.config.get('show_chatstate_in_banner')
        self._ui.show_chatstate_in_banner.set_active(st)

        ### Notifications tab ###
        ## Visual Notifications
        # Systray icon
        if app.config.get('trayicon') == 'never':
            self._ui.systray_combobox.set_active(0)
        elif app.config.get('trayicon') == 'on_event':
            self._ui.systray_combobox.set_active(1)
        else:  # always
            self._ui.systray_combobox.set_active(2)

        # Notify on new event
        if app.config.get('autopopup'):
            self._ui.on_event_received_combobox.set_active(0)
        elif app.config.get('notify_on_new_message'):
            self._ui.on_event_received_combobox.set_active(1)
        else:  # only show in roster
            self._ui.on_event_received_combobox.set_active(2)

        # Notify on online statuses
        st = app.config.get('notify_on_signin')
        self._ui.notify_on_signin_checkbutton.set_active(st)

        # Notify on offline statuses
        st = app.config.get('notify_on_signout')
        self._ui.notify_on_signout_checkbutton.set_active(st)

        # Auto popup when away
        st = app.config.get('autopopupaway')
        self._ui.auto_popup_away_checkbutton.set_active(st)

        # Auto popup when chat already open
        st = app.config.get('autopopup_chat_opened')
        self._ui.auto_popup_chat_opened_checkbutton.set_active(st)

        ## Sounds
        # Sounds
        if app.config.get('sounds_on'):
            self._ui.play_sounds_checkbutton.set_active(True)
        else:
            self._ui.manage_sounds_button.set_sensitive(False)

        # Allow sounds when dnd
        st = app.config.get('sounddnd')
        self._ui.sound_dnd_checkbutton.set_active(st)

        #### Status tab ###
        # Auto away
        st = app.config.get('autoaway')
        self._ui.auto_away_checkbutton.set_active(st)

        # Auto away time
        st = app.config.get('autoawaytime')
        self._ui.auto_away_time_spinbutton.set_value(st)
        self._ui.auto_away_time_spinbutton.set_sensitive(
            app.config.get('autoaway'))

        # Auto away message
        st = app.config.get('autoaway_message')
        self._ui.auto_away_message_entry.set_text(st)
        self._ui.auto_away_message_entry.set_sensitive(
            app.config.get('autoaway'))

        # Auto xa
        st = app.config.get('autoxa')
        self._ui.auto_xa_checkbutton.set_active(st)

        # Auto xa time
        st = app.config.get('autoxatime')
        self._ui.auto_xa_time_spinbutton.set_value(st)
        self._ui.auto_xa_time_spinbutton.set_sensitive(
            app.config.get('autoxa'))

        # Auto xa message
        st = app.config.get('autoxa_message')
        self._ui.auto_xa_message_entry.set_text(st)
        self._ui.auto_xa_message_entry.set_sensitive(app.config.get('autoxa'))

        if not idle.Monitor.is_available():
            self._ui.autoaway_table.set_sensitive(False)

        # Restore last status
        st = self.get_per_account_option('restore_last_status')
        if st == 'mixed':
            self._ui.restore_last_status_checkbutton.set_inconsistent(True)
        else:
            self._ui.restore_last_status_checkbutton.set_active(st)

        # Ask for status when online/offline
        st = app.config.get('ask_online_status')
        self._ui.prompt_online_status_message_checkbutton.set_active(st)
        st = app.config.get('ask_offline_status')
        self._ui.prompt_offline_status_message_checkbutton.set_active(st)

        # Default status messages
        self.fill_default_msg_treeview()

        # Status messages
        renderer = Gtk.CellRendererText()
        renderer.connect('edited', self.on_msg_cell_edited)
        renderer.set_property('editable', True)
        col = Gtk.TreeViewColumn('name', renderer, text=0)
        self._ui.msg_treeview.append_column(col)
        self.fill_msg_treeview()

        buf = self._ui.msg_textview.get_buffer()
        buf.connect('end-user-action', self.on_msg_textview_changed)

        ### Style tab ###
        # Themes
        self.changed_id = self._ui.theme_combobox.connect(
            'changed', self.on_theme_combobox_changed)
        self.update_theme_list()

        # Dark theme
        self._ui.dark_theme_combobox.set_active_id(
            str(app.config.get('dark_theme')))

        # Emoticons
        emoticon_themes = helpers.get_available_emoticon_themes()

        for theme in emoticon_themes:
            self._ui.emoticons_combobox.append_text(theme)

        config_theme = app.config.get('emoticons_theme')
        if config_theme not in emoticon_themes:
            config_theme = 'font'
        self._ui.emoticons_combobox.set_id_column(0)
        self._ui.emoticons_combobox.set_active_id(config_theme)

        self._ui.ascii_emoticons.set_active(app.config.get('ascii_emoticons'))

        # Iconset
        model = Gtk.ListStore(str, str)
        renderer_image = Gtk.CellRendererPixbuf()
        renderer_text = Gtk.CellRendererText()
        renderer_text.set_property('xpad', 5)
        self._ui.iconset_combobox.pack_start(renderer_image, False)
        self._ui.iconset_combobox.pack_start(renderer_text, True)
        self._ui.iconset_combobox.add_attribute(renderer_text, 'text', 1)
        self._ui.iconset_combobox.add_attribute(renderer_image, 'icon_name', 0)
        self._ui.iconset_combobox.set_model(model)

        for index, iconset_name in enumerate(get_available_iconsets()):
            icon_name = get_icon_name('online', iconset=iconset_name)
            model.append([icon_name, iconset_name])
            if app.config.get('iconset') == iconset_name:
                self._ui.iconset_combobox.set_active(index)

        # Use transports iconsets
        st = app.config.get('use_transports_iconsets')
        self._ui.transports_iconsets_checkbutton.set_active(st)

        ### Audio/Video tab ###
        def create_av_combobox(opt_name,
                               device_dict,
                               config_name=None,
                               key=None):
            combobox = self._ui.get_object(opt_name + '_combobox')
            cell = Gtk.CellRendererText()
            cell.set_property('ellipsize', Pango.EllipsizeMode.END)
            cell.set_property('ellipsize-set', True)
            combobox.pack_start(cell, True)
            combobox.add_attribute(cell, 'text', 0)
            model = Gtk.ListStore(str, str)
            combobox.set_model(model)
            if config_name:
                config = app.config.get(config_name)
            else:
                config = app.config.get(opt_name + '_device')

            for index, (name, value) in enumerate(
                    sorted(device_dict.items(), key=key)):
                model.append((name, value))
                if config == value:
                    combobox.set_active(index)

        if HAS_GST and app.is_installed('FARSTREAM'):
            create_av_combobox('audio_input',
                               AudioInputManager().get_devices())
            create_av_combobox('audio_output',
                               AudioOutputManager().get_devices())
            create_av_combobox('video_input',
                               VideoInputManager().get_devices())
            create_av_combobox('video_output',
                               VideoOutputManager().get_devices())

            create_av_combobox('video_framerate', {_('Default'): '',
                '15fps': '15/1', '10fps': '10/1', '5fps': '5/1',
                '2.5fps': '5/2'}, 'video_framerate', key=lambda x: -1 if \
                not x[1] else float(x[0][:-3]))
            create_av_combobox('video_size', {_('Default'): '',
                '800x600': '800x600', '640x480': '640x480',
                '320x240': '320x240'}, 'video_size', key=lambda x: -1 if \
                not x[1] else int(x[0][:3]))
            st = app.config.get('video_see_self')
            self._ui.video_see_self_checkbutton.set_active(st)

        else:
            for opt_name in ('audio_input', 'audio_output', 'video_input',
                             'video_output', 'video_framerate', 'video_size'):
                combobox = self._ui.get_object(opt_name + '_combobox')
                combobox.set_sensitive(False)

        # STUN
        st = app.config.get('use_stun_server')
        self._ui.stun_checkbutton.set_active(st)

        self._ui.stun_server_entry.set_text(app.config.get('stun_server'))
        if not st:
            self._ui.stun_server_entry.set_sensitive(False)

        ### Advanced tab ###
        ## Applications (open links with)
        if os.name == 'nt':
            self._ui.custom_apps_frame.set_no_show_all(True)
            self._ui.custom_apps_frame.hide()
        else:
            self._ui.custom_apps_frame.hide()
            self._ui.custom_apps_frame.set_no_show_all(True)

            if app.config.get('autodetect_browser_mailer'):
                self._ui.applications_combobox.set_active(0)
            else:
                self._ui.applications_combobox.set_active(1)
                self._ui.custom_apps_frame.show()

            self._ui.custom_browser_entry.set_text(
                app.config.get('custombrowser'))
            self._ui.custom_mail_client_entry.set_text(
                app.config.get('custommailapp'))
            self._ui.custom_file_manager_entry.set_text(
                app.config.get('custom_file_manager'))

        ## Miscellaneous
        # Proxy
        self.update_proxy_list()

        # Log status changes of contacts
        st = app.config.get('log_contact_status_changes')
        self._ui.log_show_changes_checkbutton.set_active(st)

        # Enable debug logging
        if sys.platform == 'win32':
            self._ui.enable_logging.set_active(app.get_win_debug_mode())
            self._ui.enable_logging.show()

        self._ui.connect_signals(self)
        self.connect('key-press-event', self._on_key_press)

        self._ui.msg_treeview.get_model().connect(
            'row-changed', self.on_msg_treemodel_row_changed)
        self._ui.msg_treeview.get_model().connect(
            'row-deleted', self.on_msg_treemodel_row_deleted)
        self._ui.default_msg_treeview.get_model().connect(
            'row-changed', self.on_default_msg_treemodel_row_changed)

        self.sounds_preferences = None
        self.theme_preferences = None

        self.show_all()
示例#12
0
文件: start_chat.py 项目: bj-h/gajim
    def __init__(self,
                 account,
                 contact,
                 jid,
                 name,
                 show_account,
                 groupchat=False):
        Gtk.ListBoxRow.__init__(self)
        self.get_style_context().add_class('start-chat-row')
        self.account = account
        self.account_label = app.get_account_label(account)
        self.show_account = show_account
        self.jid = jid
        self.contact = contact
        self.name = name
        self.groupchat = groupchat
        self.new = jid == ''

        grid = Gtk.Grid()
        grid.set_column_spacing(12)
        grid.set_size_request(260, -1)

        if self.groupchat:
            muc_icon = get_icon_name(
                'muc-inactive' if self.new else 'muc-active')
            image = Gtk.Image.new_from_icon_name(muc_icon, Gtk.IconSize.DND)
        else:
            scale = self.get_scale_factor()
            avatar = app.contacts.get_avatar(account, jid, AvatarSize.CHAT,
                                             scale)
            if avatar is None:
                image = Gtk.Image.new_from_icon_name('avatar-default',
                                                     Gtk.IconSize.DND)
            else:
                image = Gtk.Image.new_from_surface(avatar)

        image.set_size_request(AvatarSize.CHAT, AvatarSize.CHAT)
        grid.add(image)

        middle_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        middle_box.set_hexpand(True)

        if self.name is None:
            if self.groupchat:
                self.name = _('Join Group Chat')
            else:
                self.name = _('Add Contact')

        self.name_label = Gtk.Label(label=self.name)
        self.name_label.set_ellipsize(Pango.EllipsizeMode.END)
        self.name_label.set_xalign(0)
        self.name_label.set_width_chars(25)
        self.name_label.set_halign(Gtk.Align.START)
        self.name_label.get_style_context().add_class('bold16')

        status = contact.show if contact else 'offline'
        css_class = helpers.get_css_show_color(status)
        if css_class is not None:
            self.name_label.get_style_context().add_class(css_class)
        middle_box.add(self.name_label)

        self.jid_label = Gtk.Label(label=jid)
        self.jid_label.set_ellipsize(Pango.EllipsizeMode.END)
        self.jid_label.set_xalign(0)
        self.jid_label.set_width_chars(25)
        self.jid_label.set_halign(Gtk.Align.START)
        self.jid_label.get_style_context().add_class('dim-label')
        middle_box.add(self.jid_label)

        grid.add(middle_box)

        if show_account:
            account_label = Gtk.Label(label=self.account_label)
            account_label.set_halign(Gtk.Align.START)
            account_label.set_valign(Gtk.Align.START)

            right_box = Gtk.Box()
            right_box.set_vexpand(True)
            right_box.add(account_label)
            grid.add(right_box)

        self.add(grid)
        self.show_all()
示例#13
0
文件: dialogs.py 项目: bj-h/gajim
    def __init__(self, account, jids, preselected=None):
        """
        This window is used to trasform a one-to-one chat to a MUC. We do 2
        things: first select the server and then make a guests list
        """

        self.instances.append(self)
        self.account = account
        self.auto_jids = jids
        self.preselected_jids = preselected

        self.xml = get_builder('chat_to_muc_window.ui')
        self.window = self.xml.get_object('chat_to_muc_window')

        for widget_to_add in ('invite_button', 'cancel_button',
                              'server_list_comboboxentry', 'guests_treeview',
                              'guests_store', 'server_and_guests_hseparator',
                              'server_select_label'):
            self.__dict__[widget_to_add] = self.xml.get_object(widget_to_add)

        server_list = []
        self.servers = Gtk.ListStore(str)
        self.server_list_comboboxentry.set_model(self.servers)
        cell = Gtk.CellRendererText()
        self.server_list_comboboxentry.pack_start(cell, True)
        self.server_list_comboboxentry.add_attribute(cell, 'text', 0)

        # get the muc server of our server
        if 'jabber' in app.connections[account].muc_jid:
            server_list.append(app.connections[account].muc_jid['jabber'])
        # add servers or recently joined groupchats
        recently_groupchat = app.config.get_per('accounts', account,
                                                'recent_groupchats').split()
        for g in recently_groupchat:
            server = app.get_server_from_jid(g)
            if server not in server_list and not server.startswith('irc'):
                server_list.append(server)
        # add a default server
        if not server_list:
            server_list.append('conference.jabber.org')

        for s in server_list:
            self.servers.append([s])

        self.server_list_comboboxentry.set_active(0)

        # set treeview
        # name, jid

        self.guests_store.set_sort_column_id(1, Gtk.SortType.ASCENDING)
        self.guests_treeview.get_selection().set_mode(
            Gtk.SelectionMode.MULTIPLE)

        # All contacts beside the following can be invited:
        #       transports, zeroconf contacts, minimized groupchats
        def invitable(contact, contact_transport=None):
            return (contact.jid not in self.auto_jids
                    and contact.jid != app.get_jid_from_account(account)
                    and contact.jid
                    not in app.interface.minimized_controls[account]
                    and not contact.is_transport()
                    and contact_transport in ('jabber', None))

        # set jabber id and pseudos
        for account_ in app.contacts.get_accounts():
            if app.connections[account_].is_zeroconf:
                continue
            for jid in app.contacts.get_jid_list(account_):
                contact = app.contacts.get_contact_with_highest_priority(
                    account_, jid)
                contact_transport = app.get_transport_name_from_jid(jid)
                # Add contact if it can be invited
                if invitable(contact, contact_transport) and \
                contact.show not in ('offline', 'error'):
                    icon_name = get_icon_name(contact.show)
                    name = contact.name
                    if name == '':
                        name = jid.split('@')[0]
                    iter_ = self.guests_store.append([icon_name, name, jid])
                    # preselect treeview rows
                    if self.preselected_jids and jid in self.preselected_jids:
                        path = self.guests_store.get_path(iter_)
                        self.guests_treeview.get_selection().select_path(path)

        # show all
        self.window.show_all()

        self.xml.connect_signals(self)
示例#14
0
    def __init__(self):
        Gtk.ApplicationWindow.__init__(self)
        self.set_application(app.app)
        self.set_position(Gtk.WindowPosition.CENTER)
        self.set_show_menubar(False)
        self.set_title(_('Preferences'))

        self._ui = get_builder('preferences_window.ui')
        self.add(self._ui.preferences_window)

        ### General tab ###
        ## Behavior of Windows and Tabs
        # Set default for single window type
        choices = c_config.opt_one_window_types
        type_ = app.config.get('one_message_window')
        if type_ in choices:
            self._ui.one_window_type_combobox.set_active(choices.index(type_))
        else:
            self._ui.one_window_type_combobox.set_active(0)

        # Show roster on startup
        choices = c_config.opt_show_roster_on_startup
        type_ = app.config.get('show_roster_on_startup')
        if type_ in choices:
            self._ui.show_roster_on_startup.set_active(choices.index(type_))
        else:
            self._ui.show_roster_on_startup.set_active(0)

        # Quit on roster x
        st = app.config.get('quit_on_roster_x_button')
        self._ui.quit_on_roster_x_checkbutton.set_active(st)

        # Tab placement
        st = app.config.get('tabs_position')
        if st == 'top':
            self._ui.tabs_placement.set_active(0)
        elif st == 'bottom':
            self._ui.tabs_placement.set_active(1)
        elif st == 'left':
            self._ui.tabs_placement.set_active(2)
        else:  # right
            self._ui.tabs_placement.set_active(3)

        # Show avatar in tabs
        st = app.config.get('show_avatar_in_tabs')
        self._ui.show_avatar_in_tabs_checkbutton.set_active(st)

        ## Contact List Appearance
        # Display avatars in roster
        st = app.config.get('show_avatars_in_roster')
        self._ui.show_avatars_in_roster_checkbutton.set_active(st)

        # Display status msg under contact name in roster
        st = app.config.get('show_status_msgs_in_roster')
        self._ui.show_status_msgs_in_roster_checkbutton.set_active(st)

        # Display PEP in roster
        st1 = app.config.get('show_mood_in_roster')
        st2 = app.config.get('show_activity_in_roster')
        st3 = app.config.get('show_tunes_in_roster')
        st4 = app.config.get('show_location_in_roster')
        if st1 == st2 == st3 == st4:
            self._ui.show_pep_in_roster_checkbutton.set_active(st1)
        else:
            self._ui.show_pep_in_roster_checkbutton.set_inconsistent(True)

        # Sort contacts by show
        st = app.config.get('sort_by_show_in_roster')
        self._ui.sort_by_show_in_roster_checkbutton.set_active(st)
        st = app.config.get('sort_by_show_in_muc')
        self._ui.sort_by_show_in_muc_checkbutton.set_active(st)

        ### Chat tab ###
        ## General Settings

        # Enable auto copy
        st = app.config.get('auto_copy')
        self._ui.auto_copy.set_active(st)

        ## Chat Settings
        # Use speller
        if app.is_installed('GSPELL'):
            st = app.config.get('use_speller')
            self._ui.speller_checkbutton.set_active(st)
        else:
            self._ui.speller_checkbutton.set_sensitive(False)

        # XEP-0184 positive ack
        st = app.config.get('positive_184_ack')
        self._ui.positive_184_ack_checkbutton.set_active(st)

        # Ignore XHTML
        st = app.config.get('show_xhtml')
        self._ui.xhtml_checkbutton.set_active(st)

        # Print status messages in single chats
        st = app.config.get('print_status_in_chats')
        self._ui.print_status_in_chats_checkbutton.set_active(st)

        # Show subject on join
        st = app.config.get('show_subject_on_join')
        self._ui.subject_on_join_checkbutton.set_active(st)

        # Group chat settings
        threshold_model = self._ui.sync_threshold_combobox.get_model()
        days = app.config.get_options('threshold_options', return_type=int)
        for day in days:
            if day == 0:
                label = _('No threshold')
            else:
                label = ngettext('%i day', '%i days', day, day, day)
            threshold_model.append([str(day), label])
        public_threshold = app.config.get('public_room_sync_threshold')
        self._ui.sync_threshold_combobox.set_id_column(0)
        self._ui.sync_threshold_combobox.set_active_id(str(public_threshold))

        st = app.config.get('print_join_left_default')
        self._ui.join_leave_checkbutton.set_active(st)

        st = app.config.get('print_status_muc_default')
        self._ui.status_change_checkbutton.set_active(st)

        # Displayed chat state notifications
        st = app.config.get('show_chatstate_in_tabs')
        self._ui.show_chatstate_in_tabs.set_active(st)

        st = app.config.get('show_chatstate_in_roster')
        self._ui.show_chatstate_in_roster.set_active(st)

        st = app.config.get('show_chatstate_in_banner')
        self._ui.show_chatstate_in_banner.set_active(st)

        ### Notifications tab ###
        ## Visual Notifications
        # Systray icon
        if app.config.get('trayicon') == 'never':
            self._ui.systray_combobox.set_active(0)
        elif app.config.get('trayicon') == 'on_event':
            self._ui.systray_combobox.set_active(1)
        else:  # always
            self._ui.systray_combobox.set_active(2)

        # Notify on new event
        if app.config.get('autopopup'):
            self._ui.on_event_received_combobox.set_active(0)
        elif app.config.get('notify_on_new_message'):
            self._ui.on_event_received_combobox.set_active(1)
        else:  # only show in roster
            self._ui.on_event_received_combobox.set_active(2)

        # Notify on online statuses
        st = app.config.get('notify_on_signin')
        self._ui.notify_on_signin_checkbutton.set_active(st)

        # Notify on offline statuses
        st = app.config.get('notify_on_signout')
        self._ui.notify_on_signout_checkbutton.set_active(st)

        # Auto popup when away
        st = app.config.get('autopopupaway')
        self._ui.auto_popup_away_checkbutton.set_active(st)

        # Auto popup when chat already open
        st = app.config.get('autopopup_chat_opened')
        self._ui.auto_popup_chat_opened_checkbutton.set_active(st)

        ## Sounds
        # Sounds
        if app.config.get('sounds_on'):
            self._ui.play_sounds_checkbutton.set_active(True)
        else:
            self._ui.manage_sounds_button.set_sensitive(False)

        # Allow sounds when dnd
        st = app.config.get('sounddnd')
        self._ui.sound_dnd_checkbutton.set_active(st)

        #### Status tab ###
        # Auto away
        st = app.config.get('autoaway')
        self._ui.auto_away_checkbutton.set_active(st)

        # Auto away time
        st = app.config.get('autoawaytime')
        self._ui.auto_away_time_spinbutton.set_value(st)
        self._ui.auto_away_time_spinbutton.set_sensitive(
            app.config.get('autoaway'))

        # Auto away message
        st = app.config.get('autoaway_message')
        self._ui.auto_away_message_entry.set_text(st)
        self._ui.auto_away_message_entry.set_sensitive(
            app.config.get('autoaway'))

        # Auto xa
        st = app.config.get('autoxa')
        self._ui.auto_xa_checkbutton.set_active(st)

        # Auto xa time
        st = app.config.get('autoxatime')
        self._ui.auto_xa_time_spinbutton.set_value(st)
        self._ui.auto_xa_time_spinbutton.set_sensitive(
            app.config.get('autoxa'))

        # Auto xa message
        st = app.config.get('autoxa_message')
        self._ui.auto_xa_message_entry.set_text(st)
        self._ui.auto_xa_message_entry.set_sensitive(app.config.get('autoxa'))

        if not idle.Monitor.is_available():
            self._ui.autoaway_table.set_sensitive(False)

        # Restore last status
        st = self.get_per_account_option('restore_last_status')
        if st == 'mixed':
            self._ui.restore_last_status_checkbutton.set_inconsistent(True)
        else:
            self._ui.restore_last_status_checkbutton.set_active(st)

        # Ask for status when online/offline
        st = app.config.get('ask_online_status')
        self._ui.prompt_online_status_message_checkbutton.set_active(st)
        st = app.config.get('ask_offline_status')
        self._ui.prompt_offline_status_message_checkbutton.set_active(st)

        # Default status messages
        self.fill_default_msg_treeview()

        # Status messages
        renderer = Gtk.CellRendererText()
        renderer.connect('edited', self.on_msg_cell_edited)
        renderer.set_property('editable', True)
        col = Gtk.TreeViewColumn('name', renderer, text=0)
        self._ui.msg_treeview.append_column(col)
        self.fill_msg_treeview()

        buf = self._ui.msg_textview.get_buffer()
        buf.connect('end-user-action', self.on_msg_textview_changed)

        ### Style tab ###
        # Themes
        self.changed_id = self._ui.theme_combobox.connect(
            'changed', self.on_theme_combobox_changed)
        self.update_theme_list()

        # Dark theme
        self._ui.dark_theme_combobox.set_active_id(
            str(app.config.get('dark_theme')))

        # Emoticons
        emoticon_themes = helpers.get_available_emoticon_themes()

        for theme in emoticon_themes:
            self._ui.emoticons_combobox.append_text(theme)

        config_theme = app.config.get('emoticons_theme')
        if config_theme not in emoticon_themes:
            config_theme = 'font'
        self._ui.emoticons_combobox.set_id_column(0)
        self._ui.emoticons_combobox.set_active_id(config_theme)

        self._ui.ascii_emoticons.set_active(app.config.get('ascii_emoticons'))

        # Iconset
        model = Gtk.ListStore(str, str)
        renderer_image = Gtk.CellRendererPixbuf()
        renderer_text = Gtk.CellRendererText()
        renderer_text.set_property('xpad', 5)
        self._ui.iconset_combobox.pack_start(renderer_image, False)
        self._ui.iconset_combobox.pack_start(renderer_text, True)
        self._ui.iconset_combobox.add_attribute(renderer_text, 'text', 1)
        self._ui.iconset_combobox.add_attribute(renderer_image, 'icon_name', 0)
        self._ui.iconset_combobox.set_model(model)

        for index, iconset_name in enumerate(get_available_iconsets()):
            icon_name = get_icon_name('online', iconset=iconset_name)
            model.append([icon_name, iconset_name])
            if app.config.get('iconset') == iconset_name:
                self._ui.iconset_combobox.set_active(index)

        # Use transports iconsets
        st = app.config.get('use_transports_iconsets')
        self._ui.transports_iconsets_checkbutton.set_active(st)

        ### Audio/Video tab ###
        def create_av_combobox(
            opt_name,
            device_dict,
            config_name=None,
            # This key is there to give the first index to autovideosrc and co.
            key=lambda x: '' if x[1].startswith('auto') else x[0].lower()):
            combobox = self._ui.get_object(opt_name + '_combobox')
            cell = Gtk.CellRendererText()
            cell.set_property('ellipsize', Pango.EllipsizeMode.END)
            cell.set_property('ellipsize-set', True)
            combobox.pack_start(cell, True)
            combobox.add_attribute(cell, 'text', 0)
            model = Gtk.ListStore(str, str)
            combobox.set_model(model)
            if config_name:
                config = app.config.get(config_name)
            else:
                config = app.config.get(opt_name + '_device')

            for index, (name, value) in enumerate(
                    sorted(device_dict.items(), key=key)):
                model.append((name, value))
                if config == value:
                    combobox.set_active(index)

        if HAS_GST and app.is_installed('FARSTREAM'):
            create_av_combobox('audio_input',
                               AudioInputManager().get_devices())
            create_av_combobox('audio_output',
                               AudioOutputManager().get_devices())
            create_av_combobox('video_input',
                               VideoInputManager().get_devices())

            create_av_combobox('video_framerate', {
                _('Default'): '',
                '15fps': '15/1',
                '10fps': '10/1',
                '5fps': '5/1',
                '2.5fps': '5/2'
            },
                               'video_framerate',
                               key=lambda x: -1
                               if not x[1] else float(x[0][:-3]))
            create_av_combobox('video_size', {
                _('Default'): '',
                '800x600': '800x600',
                '640x480': '640x480',
                '320x240': '320x240'
            },
                               'video_size',
                               key=lambda x: -1 if not x[1] else int(x[0][:3]))
            st = app.config.get('video_see_self')
            self._ui.video_see_self_checkbutton.set_active(st)

            def on_av_map(tab):
                label = self._ui.selected_video_output
                sink, widget, name = self.setup_video_output()
                if sink is None:
                    log.error(
                        'Failed to obtain a working Gstreamer GTK+ sink, '
                        'video support will be disabled')
                    self._ui.video_input_combobox.set_sensitive(False)
                    label.set_markup(
                        _('<span color="red" font-weight="bold">'
                          'Unavailable</span>, video support will be disabled')
                    )
                    return

                text = ''
                if name == 'gtkglsink':
                    text = _('<span color="green" font-weight="bold">'
                             'OpenGL</span> accelerated')
                elif name == 'gtksink':
                    text = _('<span color="yellow" font-weight="bold">'
                             'Unaccelerated</span>')
                label.set_markup(text)
                if self.av_pipeline is None:
                    self.av_pipeline = Gst.Pipeline.new('preferences-pipeline')
                else:
                    self.av_pipeline.set_state(Gst.State.NULL)
                self.av_pipeline.add(sink)
                self.av_sink = sink
                if self.av_widget is not None:
                    tab.remove(self.av_widget)
                tab.add(widget)
                self.av_widget = widget

                src_name = app.config.get('video_input_device')
                try:
                    self.av_src = Gst.parse_bin_from_description(
                        src_name, True)
                except GLib.Error:
                    log.error(
                        'Failed to parse "%s" as Gstreamer element,'
                        ' falling back to autovideosrc', src_name)
                    self.av_src = None
                if self.av_src is not None:
                    self.av_pipeline.add(self.av_src)
                    self.av_src.link(self.av_sink)
                    self.av_pipeline.set_state(Gst.State.PLAYING)
                else:
                    # Parsing the pipeline stored in video_input_device failed,
                    # let’s try the default one.
                    self.av_src = Gst.ElementFactory.make('autovideosrc', None)
                    if self.av_src is None:
                        log.error(
                            'Failed to obtain a working Gstreamer source,'
                            ' video will be disabled.')
                        self._ui.video_input_combobox.set_sensitive(False)
                        return
                    # Great, this succeeded, let’s store it back into the
                    # config and use it. We’ve made autovideosrc the first
                    # element in the combobox so we can pick index 0 without
                    # worry.
                    combobox = self._ui.video_input_combobox
                    combobox.set_active(0)

            def on_av_unmap(tab):
                if self.av_pipeline is not None:
                    self.av_pipeline.set_state(Gst.State.NULL)
                if self.av_src is not None:
                    self.av_pipeline.remove(self.av_src)
                    self.av_src = None
                if self.av_sink is not None:
                    self.av_pipeline.remove(self.av_sink)
                    self.av_sink = None
                if self.av_widget is not None:
                    tab.remove(self.av_widget)
                    self.av_widget = None
                self.av_pipeline = None

            self.av_pipeline = None
            self.av_src = None
            self.av_sink = None
            self.av_widget = None
            tab = self._ui.audio_video_tab
            tab.connect('map', on_av_map)
            tab.connect('unmap', on_av_unmap)

        else:
            for opt_name in ('audio_input', 'audio_output', 'video_input',
                             'video_framerate', 'video_size'):
                combobox = self._ui.get_object(opt_name + '_combobox')
                combobox.set_sensitive(False)

        # STUN
        st = app.config.get('use_stun_server')
        self._ui.stun_checkbutton.set_active(st)

        self._ui.stun_server_entry.set_text(app.config.get('stun_server'))
        if not st:
            self._ui.stun_server_entry.set_sensitive(False)

        ### Advanced tab ###

        ## Miscellaneous
        # Proxy
        self.update_proxy_list()

        # Log status changes of contacts
        st = app.config.get('log_contact_status_changes')
        self._ui.log_show_changes_checkbutton.set_active(st)

        self._ui.enable_logging.set_active(app.get_debug_mode())
        self._ui.enable_logging.show()

        self._ui.connect_signals(self)
        self.connect('key-press-event', self._on_key_press)

        self._ui.msg_treeview.get_model().connect(
            'row-changed', self.on_msg_treemodel_row_changed)
        self._ui.msg_treeview.get_model().connect(
            'row-deleted', self.on_msg_treemodel_row_deleted)
        self._ui.default_msg_treeview.get_model().connect(
            'row-changed', self.on_default_msg_treemodel_row_changed)

        self.sounds_preferences = None
        self.theme_preferences = None

        self.show_all()