roster_tweaks.py 9.68 KB
Newer Older
1 2 3
from gi.repository import Pango
from gi.repository import Gtk
from gi.repository import Gdk
4
from gi.repository import GLib
5

6
from gajim.common import app, ged, helpers
7 8 9 10
from gajim.plugins import GajimPlugin
from gajim.plugins.gui import GajimPluginConfigDialog
from gajim.dialogs import ChangeActivityDialog, ChangeMoodDialog
from gajim import gtkgui_helpers
Dicson's avatar
Dicson committed
11

12 13 14 15 16 17
# Since Gajim 1.1.0 _() has to be imported
try:
    from gajim.common.i18n import _
except ImportError:
    pass

Dicson's avatar
Dicson committed
18

Dicson's avatar
Dicson committed
19 20
class RosterTweaksPlugin(GajimPlugin):
    def init(self):
21 22 23
        self.description = _(
            'Allows user to tweak roster window appearance '
            '(eg. make it compact).')
Dicson's avatar
Dicson committed
24 25 26
        self.config_default_values = {'hide_status_combo': (False, ''),
                                      'use_ctr_m': (False, ''),
                                      'menu_visible': (True, ''),
27
                                      'quick_status': (False, ''),
28
                                      'contact_status_subs': (False, ''), }
29 30
        self.events_handlers = {'our-show': (ged.GUI2, self.our_show),
                                'pep-received': (ged.GUI2, self.pep_received)}
31
        self.gui_extension_points = {
32 33
            'roster_draw_contact': (self.roster_draw_contact,
                                    self.disconnect_roster_draw_contact), }
34
        self.roster = app.interface.roster
35
        self.config_dialog = RosterTweaksPluginConfigDialog(self)
Dicson's avatar
Dicson committed
36

37
    def roster_draw_contact(self, roster, jid, account, contact):
38
        self.connected = True
39 40 41 42
        if not self.active:
            return
        if not self.config['contact_status_subs']:
            return
43 44
        child_iters = roster._get_contact_iter(
            jid, account, contact, roster.model)
45 46 47
        if not child_iters:
            return
        name = roster.model[child_iters[0]][1]
48 49
        if '\n<span ' not in name:
            roster.model[child_iters[0]][1] = name + '\n'
50

51
    def disconnect_roster_draw_contact(self, *args):
52 53 54
        if self.connected:
            self.roster.setup_and_draw_roster()
            self.connected = False
55 56

    def pep_received(self, obj):
57
        if obj.jid != app.get_jid_from_account(obj.conn.name):
58 59
            return

60
        pep_dict = app.connections[obj.conn.name].pep
61
        if obj.pep_type == 'mood':
62 63
            img = self.xml.get_object('mood_image')
            if 'mood' in pep_dict:
64 65
                pixbuf = gtkgui_helpers.get_pep_as_pixbuf(pep_dict['mood'])
                img.set_from_pixbuf(pixbuf)
66
            else:
67
                img.set_from_stock('gtk-stop', Gtk.IconSize.MENU)
68
        if obj.pep_type == 'activity':
69 70
            img = self.xml.get_object('activity_image')
            if 'activity' in pep_dict:
71 72
                pb = gtkgui_helpers.get_pep_as_pixbuf(pep_dict['activity'])
                img.set_from_pixbuf(pb)
73
            else:
74
                img.set_from_stock('gtk-stop', Gtk.IconSize.MENU)
75

76
    def our_show(self, *args):
77
        if self.active:
78
            if helpers.get_global_show() != app.SHOW_LIST[0]:
79 80 81 82
                self.status_widget.set_text(helpers.get_global_status())
            else:
                self.status_widget.set_text('')

Dicson's avatar
Dicson committed
83
    def activate(self):
84
        self.pep_dict = {}
Dicson's avatar
Dicson committed
85 86 87
        self.roster.status_combobox.set_property('visible', not self.config[
            'hide_status_combo'])
        self.roster.status_combobox.set_no_show_all(True)
88 89
        self.enable_ctrl_m()

Dicson's avatar
Dicson committed
90
        vbox = self.roster.xml.get_object('roster_vbox2')
91 92
        self.GTK_BUILDER_FILE_PATH = self.local_file_path(
            'config_dialog.ui')
93
        self.xml = Gtk.Builder()
94 95
        self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH, ['hbox1'])
        self.status_widget = self.xml.get_object('status_entry')
96
        self.status_widget.set_property('visible', self.config['quick_status'])
97
        self.status_widget.set_property('no-show-all', True)
98 99
        self.font_desc = self.status_widget.get_pango_context(
            ).get_font_description()
100 101
        self.activity_button = self.xml.get_object('activity_button')
        self.activity_button.set_property('no-show-all', True)
Dicson's avatar
Dicson committed
102 103
        self.activity_button.set_property('visible', self.config[
            'quick_status'])
104 105 106 107
        self.mood_button = self.xml.get_object('mood_button')
        self.mood_button.set_property('no-show-all', True)
        self.mood_button.set_property('visible', self.config['quick_status'])
        hbox = self.xml.get_object('hbox1')
108
        vbox.pack_start(hbox, False, True, 0)
109
        self.xml.connect_signals(self)
110
        self.roster.setup_and_draw_roster()
111 112

    def enable_ctrl_m(self):
Dicson's avatar
Dicson committed
113
        if self.config['use_ctr_m']:
Dicson's avatar
Dicson committed
114
            window = self.roster.window
115 116
            self.accel_group = Gtk.accel_groups_from_object(window)[0]
            self.accel_group.connect(Gdk.KEY_m,
117 118 119
                                     Gdk.ModifierType.CONTROL_MASK,
                                     Gtk.AccelFlags.MASK,
                                     self.on_ctrl_m)
120
            self.config['menu_visible'] = not self.config['menu_visible']
121
            self.on_ctrl_m()
Dicson's avatar
Dicson committed
122 123

    def deactivate(self):
Dicson's avatar
Dicson committed
124
        self.roster.status_combobox.show()
Dicson's avatar
Dicson committed
125
        self.status_widget.destroy()
126 127
        self.activity_button.destroy()
        self.mood_button.destroy()
128
        self.roster.window.set_show_menubar(True)
Dicson's avatar
Dicson committed
129

130 131
    def on_ctrl_m(self, *args):
        self.roster.window.set_show_menubar(self.config['menu_visible'])
132
        self.config['menu_visible'] = not self.config['menu_visible']
Dicson's avatar
Dicson committed
133 134
        return True

135
    def status_changed(self, widget, event):
136
        if event.keyval in (Gdk.KEY_Return, Gdk.KEY_KP_Enter):
137
            accounts = app.connections.keys()
138 139
            message = widget.get_text()
            for account in accounts:
140
                if not app.account_is_connected(account):
141
                    continue
142 143
                current_show = app.SHOW_LIST[
                    app.connections[account].connected]
Dicson's avatar
Dicson committed
144
                self.roster.send_status(account, current_show, message)
145
            self.font_desc.set_weight(Pango.Weight.BOLD)
146
            widget.modify_font(self.font_desc)
147 148
            self.font_desc.set_weight(Pango.Weight.NORMAL)
            GLib.timeout_add(1000, widget.modify_font, self.font_desc)
149

150 151 152 153 154
    def on_activity_button_clicked(self, widget):
        def on_response(activity, subactivity, text):
            self.pep_dict['activity'] = activity or ''
            self.pep_dict['subactivity'] = subactivity or ''
            self.pep_dict['activity_text'] = text
Dicson's avatar
Dicson committed
155
            self.send_pep()
156 157 158 159
        ChangeActivityDialog(on_response, 
                             self.pep_dict.get('activity', None),
                             self.pep_dict.get('subactivity', None),
                             self.pep_dict.get('activity_text', None))
160 161 162 163 164

    def on_mood_button_clicked(self, widget):
        def on_response(mood, text):
            self.pep_dict['mood'] = mood or ''
            self.pep_dict['mood_text'] = text
Dicson's avatar
Dicson committed
165
            self.send_pep()
166 167 168
        ChangeMoodDialog(on_response, 
                         self.pep_dict.get('mood', None),
                         self.pep_dict.get('mood_text', None))
169

Dicson's avatar
Dicson committed
170
    def send_pep(self):
171
        accounts = app.connections.keys()
Dicson's avatar
Dicson committed
172
        for account in accounts:
173
            if app.account_is_connected(account):
Dicson's avatar
Dicson committed
174
                self.roster.send_pep(account, self.pep_dict)
Dicson's avatar
Dicson committed
175

Dicson's avatar
Dicson committed
176

Dicson's avatar
Dicson committed
177 178 179 180
class RosterTweaksPluginConfigDialog(GajimPluginConfigDialog):
    def init(self):
        self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path(
                'config_dialog.ui')
181
        self.xml = Gtk.Builder()
Dicson's avatar
Dicson committed
182
        self.xml.set_translation_domain('gajim_plugins')
183 184
        self.xml.add_objects_from_file(
            self.GTK_BUILDER_FILE_PATH, ['roster_tweaks_config_vbox'])
185

Dicson's avatar
Dicson committed
186
        self.config_vbox = self.xml.get_object('roster_tweaks_config_vbox')
187
        self.get_child().pack_start(self.config_vbox, True, True, 0)
Dicson's avatar
Dicson committed
188 189 190

        self.hide_combo = self.xml.get_object('hide_combo')
        self.use_ctr_m = self.xml.get_object('use_ctr_m')
191 192
        status_widget = self.xml.get_object('contact_status_subs')
        status_widget.set_active(self.plugin.config['contact_status_subs'])
Dicson's avatar
Dicson committed
193 194 195 196 197 198

        self.xml.connect_signals(self)

    def on_run(self):
        self.hide_combo.set_active(self.plugin.config['hide_status_combo'])
        self.use_ctr_m.set_active(self.plugin.config['use_ctr_m'])
199 200
        status_widget = self.xml.get_object('quick_status')
        status_widget.set_active(self.plugin.config['quick_status'])
Dicson's avatar
Dicson committed
201 202 203

    def on_hide_combo_toggled(self, button):
        self.plugin.config['hide_status_combo'] = button.get_active()
204 205
        self.plugin.roster.status_combobox.set_property(
            'visible', not self.plugin.config['hide_status_combo'])
Dicson's avatar
Dicson committed
206

207 208
    def on_quick_status_toggled(self, button):
        self.plugin.config['quick_status'] = button.get_active()
209 210
        if not self.plugin.active:
            return
211
        self.plugin.status_widget.set_property('visible', button.get_active())
212 213
        self.plugin.mood_button.set_property('visible', button.get_active())
        self.plugin.activity_button.set_property('visible', button.get_active())
214
        self.plugin.status_widget.set_text(helpers.get_global_status())
215

Dicson's avatar
Dicson committed
216
    def on_use_ctr_m_toggled(self, button):
217 218 219 220
        is_ctr_m_enabled = button.get_active()
        self.plugin.config['use_ctr_m'] = is_ctr_m_enabled
        if is_ctr_m_enabled:
            self.plugin.enable_ctrl_m()
Dicson's avatar
Dicson committed
221
        else:
222 223
            self.plugin.accel_group.disconnect_key(
                Gdk.KEY_m, Gdk.ModifierType.CONTROL_MASK)
Dicson's avatar
Dicson committed
224
            self.plugin.config['menu_visible'] = True
225
            self.plugin.roster.window.set_show_menubar(True)
226 227 228

    def on_contact_status_subs_toggled(self, button):
        self.plugin.config['contact_status_subs'] = button.get_active()
229 230
        if self.plugin.active:
            self.plugin.roster.setup_and_draw_roster()