Exemple #1
0
 def _get_current_theme():
     theme = app.settings.get('emoticons_theme')
     themes = helpers.get_available_emoticon_themes()
     if theme not in themes:
         app.settings.set('emoticons_theme', 'noto')
         theme = 'noto'
     return theme
Exemple #2
0
 def _get_current_theme(self):
     theme = app.config.get('emoticons_theme')
     themes = helpers.get_available_emoticon_themes()
     if theme not in themes:
         if sys.platform not in ('win32', 'darwin'):
             app.config.set('emoticons_theme', 'font')
             theme = 'font'
         else:
             # Win/Mac fallback to noto
             app.config.set('emoticons_theme', 'noto')
             theme = 'noto'
     return theme
Exemple #3
0
    def __init__(self, *args):
        if sys.platform not in ('win32', 'darwin'):
            PreferenceBox.__init__(self, [])
            return

        emoji_themes_items = []
        for theme in helpers.get_available_emoticon_themes():
            emoji_themes_items.append(theme)

        settings = [
            Setting(SettingKind.POPOVER,
                    _('Emoji Theme'),
                    SettingType.CONFIG,
                    'emoticons_theme',
                    desc=_('Choose from various emoji styles'),
                    props={'entries': emoji_themes_items},
                    callback=self._on_emoticons_theme)
        ]

        PreferenceBox.__init__(self, settings)
Exemple #4
0
 def _check_emoji_theme():
     # Ensure selected emoji theme is valid
     emoji_themes = helpers.get_available_emoticon_themes()
     settings_theme = app.settings.get('emoticons_theme')
     if settings_theme not in emoji_themes:
         app.settings.set('emoticons_theme', 'font')
Exemple #5
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()
Exemple #6
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.set_default_size(-1, 400)

        self.xml = get_builder('preferences_window.ui')
        self.notebook = self.xml.get_object('preferences_notebook')
        self.add(self.notebook)

        self.one_window_type_combobox = self.xml.get_object(
            'one_window_type_combobox')
        self.iconset_combobox = self.xml.get_object('iconset_combobox')
        self.notify_on_signin_checkbutton = self.xml.get_object(
            'notify_on_signin_checkbutton')
        self.notify_on_signout_checkbutton = self.xml.get_object(
            'notify_on_signout_checkbutton')
        self.auto_popup_away_checkbutton = self.xml.get_object(
            'auto_popup_away_checkbutton')
        self.auto_popup_chat_opened_checkbutton = self.xml.get_object(
            'auto_popup_chat_opened_checkbutton')
        self.sound_dnd_checkbutton = self.xml.get_object(
            'sound_dnd_checkbutton')
        self.auto_away_checkbutton = self.xml.get_object(
            'auto_away_checkbutton')
        self.auto_away_time_spinbutton = self.xml.get_object(
            'auto_away_time_spinbutton')
        self.auto_away_message_entry = self.xml.get_object(
            'auto_away_message_entry')
        self.auto_xa_checkbutton = self.xml.get_object('auto_xa_checkbutton')
        self.auto_xa_time_spinbutton = self.xml.get_object(
            'auto_xa_time_spinbutton')
        self.auto_xa_message_entry = self.xml.get_object(
            'auto_xa_message_entry')

        ### General tab ###
        # Display avatars in roster
        st = app.config.get('show_avatars_in_roster')
        self.xml.get_object('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.xml.get_object('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')
        w = self.xml.get_object('show_pep_in_roster_checkbutton')
        if st1 == st2 == st3 == st4:
            w.set_active(st1)
        else:
            w.set_inconsistent(True)

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

        # emoticons
        emoticons_combobox = self.xml.get_object('emoticons_combobox')
        emoticon_themes = helpers.get_available_emoticon_themes()

        emoticons_combobox.append_text(_('Disabled'))
        for theme in emoticon_themes:
            emoticons_combobox.append_text(theme)

        config_theme = app.config.get('emoticons_theme')
        if config_theme not in emoticon_themes:
            config_theme = _('Disabled')
        emoticons_combobox.set_id_column(0)
        emoticons_combobox.set_active_id(config_theme)

        # 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.one_window_type_combobox.set_active(choices.index(type_))
        else:
            self.one_window_type_combobox.set_active(0)

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

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

        # use speller
        if app.is_installed('GSPELL'):
            st = app.config.get('use_speller')
            self.xml.get_object('speller_checkbutton').set_active(st)
        else:
            self.xml.get_object('speller_checkbutton').set_sensitive(False)

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

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

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

        # iconset
        iconsets_list = os.listdir(
            os.path.join(configpaths.get('DATA'), 'iconsets'))
        if os.path.isdir(configpaths.get('MY_ICONSETS')):
            iconsets_list += os.listdir(configpaths.get('MY_ICONSETS'))
        # new model, image in 0, string in 1
        model = Gtk.ListStore(Gtk.Image, str)
        renderer_image = cell_renderer_image.CellRendererImage(0, 0)
        renderer_text = Gtk.CellRendererText()
        renderer_text.set_property('xpad', 5)
        self.iconset_combobox.pack_start(renderer_image, False)
        self.iconset_combobox.pack_start(renderer_text, True)
        self.iconset_combobox.add_attribute(renderer_text, 'text', 1)
        self.iconset_combobox.add_attribute(renderer_image, 'image', 0)
        self.iconset_combobox.set_model(model)
        l = []
        for dir in iconsets_list:
            if not os.path.isdir(os.path.join(configpaths.get('DATA'), 'iconsets', dir)) \
            and not os.path.isdir(os.path.join(configpaths.get('MY_ICONSETS'), dir)):
                continue
            if dir != '.svn' and dir != 'transports':
                l.append(dir)
        if l.count == 0:
            l.append(' ')
        for i in range(len(l)):
            preview = Gtk.Image()
            files = []
            files.append(
                os.path.join(helpers.get_iconset_path(l[i]), '16x16',
                             'online.png'))
            files.append(
                os.path.join(helpers.get_iconset_path(l[i]), '16x16',
                             'online.gif'))
            for file_ in files:
                if os.path.exists(file_):
                    preview.set_from_file(file_)
            model.append([preview, l[i]])
            if app.config.get('iconset') == l[i]:
                self.iconset_combobox.set_active(i)

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

        ### Personal Events tab ###
        # outgoing send chat state notifications
        st = app.config.get('outgoing_chat_state_notifications')
        combo = self.xml.get_object('outgoing_chat_states_combobox')
        if st == 'all':
            combo.set_active(0)
        elif st == 'composing_only':
            combo.set_active(1)
        else:  # disabled
            combo.set_active(2)

        # displayed send chat state notifications
        st = app.config.get('displayed_chat_state_notifications')
        combo = self.xml.get_object('displayed_chat_states_combobox')
        if st == 'all':
            combo.set_active(0)
        elif st == 'composing_only':
            combo.set_active(1)
        else:  # disabled
            combo.set_active(2)

        ### Notifications tab ###
        # On new event
        on_event_combobox = self.xml.get_object('on_event_combobox')
        if app.config.get('autopopup'):
            on_event_combobox.set_active(0)
        elif app.config.get('notify_on_new_message'):
            on_event_combobox.set_active(1)
        else:
            on_event_combobox.set_active(2)

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

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

        # autopopupaway
        st = app.config.get('autopopupaway')
        self.auto_popup_away_checkbutton.set_active(st)

        # autopopup_chat_opened
        st = app.config.get('autopopup_chat_opened')
        self.auto_popup_chat_opened_checkbutton.set_active(st)

        # sounddnd
        st = app.config.get('sounddnd')
        self.sound_dnd_checkbutton.set_active(st)

        # Systray
        systray_combobox = self.xml.get_object('systray_combobox')
        if app.config.get('trayicon') == 'never':
            systray_combobox.set_active(0)
        elif app.config.get('trayicon') == 'on_event':
            systray_combobox.set_active(1)
        else:
            systray_combobox.set_active(2)

        # sounds
        if app.config.get('sounds_on'):
            self.xml.get_object('play_sounds_checkbutton').set_active(True)
        else:
            self.xml.get_object('manage_sounds_button').set_sensitive(False)

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

        # Autoawaytime
        st = app.config.get('autoawaytime')
        self.auto_away_time_spinbutton.set_value(st)
        self.auto_away_time_spinbutton.set_sensitive(
            app.config.get('autoaway'))

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

        # Autoxa
        st = app.config.get('autoxa')
        self.auto_xa_checkbutton.set_active(st)

        # Autoxatime
        st = app.config.get('autoxatime')
        self.auto_xa_time_spinbutton.set_value(st)
        self.auto_xa_time_spinbutton.set_sensitive(app.config.get('autoxa'))

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

        if not idle.Monitor.is_available():
            self.xml.get_object('autoaway_table').set_sensitive(False)

        # ask_status when online / offline
        st = app.config.get('ask_online_status')
        self.xml.get_object('prompt_online_status_message_checkbutton').\
                set_active(st)
        st = app.config.get('ask_offline_status')
        self.xml.get_object('prompt_offline_status_message_checkbutton').\
                set_active(st)

        # Default Status messages
        self.default_msg_tree = self.xml.get_object('default_msg_treeview')
        self.fill_default_msg_treeview()

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

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

        ### Audio / Video tab ###
        def create_av_combobox(opt_name,
                               device_dict,
                               config_name=None,
                               key=None):
            combobox = self.xml.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.xml.get_object('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.xml.get_object(opt_name + '_combobox')
                combobox.set_sensitive(False)

        # STUN
        cb = self.xml.get_object('stun_checkbutton')
        st = app.config.get('use_stun_server')
        cb.set_active(st)

        entry = self.xml.get_object('stun_server_entry')
        entry.set_text(app.config.get('stun_server'))
        if not st:
            entry.set_sensitive(False)

        ### Advanced tab ###
        # open links with
        if os.name == 'nt':
            applications_frame = self.xml.get_object('applications_frame')
            applications_frame.set_no_show_all(True)
            applications_frame.hide()
        else:
            self.applications_combobox = self.xml.get_object(
                'applications_combobox')
            self.xml.get_object('custom_apps_frame').hide()
            self.xml.get_object('custom_apps_frame').set_no_show_all(True)

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

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

        # log status changes of contacts
        st = app.config.get('log_contact_status_changes')
        self.xml.get_object('log_show_changes_checkbutton').set_active(st)

        # send os info
        w = self.xml.get_object('send_os_info_checkbutton')
        st = self.get_per_account_option('send_os_info')
        if st == 'mixed':
            w.set_inconsistent(True)
        else:
            w.set_active(st)

        # send absolute time info
        w = self.xml.get_object('send_time_info_checkbutton')
        st = self.get_per_account_option('send_time_info')
        if st == 'mixed':
            w.set_inconsistent(True)
        else:
            w.set_active(st)

        # send idle time
        w = self.xml.get_object('send_idle_time_checkbutton')
        st = self.get_per_account_option('send_idle_time')
        if st == 'mixed':
            w.set_inconsistent(True)
        else:
            w.set_active(st)

        self.update_proxy_list()

        # Ignore messages from unknown contacts
        w = self.xml.get_object(
            'ignore_events_from_unknown_contacts_checkbutton')
        st = self.get_per_account_option('ignore_unknown_contacts')
        if st == 'mixed':
            w.set_inconsistent(True)
        else:
            w.set_active(st)

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

        self.msg_tree.get_model().connect('row-changed',
                                          self.on_msg_treemodel_row_changed)
        self.msg_tree.get_model().connect('row-deleted',
                                          self.on_msg_treemodel_row_deleted)
        self.default_msg_tree.get_model().connect(
            'row-changed', self.on_default_msg_treemodel_row_changed)

        self.sounds_preferences = None
        self.theme_preferences = None

        self.notebook.set_current_page(0)

        self.show_all()
Exemple #7
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()