plugin.py 3.79 KB
Newer Older
1 2 3 4
import json
from pathlib import Path
from functools import partial

Dicson's avatar
Dicson committed
5 6
from gi.repository import Gtk

7
from gajim.common import configpaths
8

9
from gajim.plugins import GajimPlugin
Philipp Hörist's avatar
Philipp Hörist committed
10
from gajim.plugins.plugins_i18n import _
11

12 13
from quick_replies.quick_replies import DEFAULT_DATA
from quick_replies.gtk.config import ConfigDialog
14 15


16 17 18 19
class QuickRepliesPlugin(GajimPlugin):
    def init(self):
        self.description = _('Adds a menu with customizable quick replies')
        self.config_dialog = partial(ConfigDialog, self)
20
        self.gui_extension_points = {
21 22
            'chat_control_base': (self._connect_chat_control,
                                  self._disconnect_chat_control),
23
            }
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
        self._buttons = {}
        self.quick_replies = self._load_quick_replies()

    def _connect_chat_control(self, chat_control):
        button = QuickRepliesButton(chat_control, self.quick_replies)
        self._buttons[chat_control.control_id] = button
        actions_hbox = chat_control.xml.get_object('hbox')
        actions_hbox.pack_start(button, False, False, 0)
        actions_hbox.reorder_child(
            button, len(actions_hbox.get_children()) - 2)
        button.show()

    def _disconnect_chat_control(self, chat_control):
        button = self._buttons.get(chat_control.control_id)
        if button is not None:
            button.destroy()
            self._buttons.pop(chat_control.control_id, None)

    @staticmethod
    def _load_quick_replies():
        try:
            data_path = Path(configpaths.get('PLUGINS_DATA'))
        except KeyError:
            # PLUGINS_DATA was added in 1.0.99.1
            return DEFAULT_DATA

        path = data_path / 'quick_replies' / 'quick_replies'
        if not path.exists():
            return DEFAULT_DATA

        with path.open('r') as file:
            quick_replies = json.load(file)
        return quick_replies

    @staticmethod
    def _save_quick_replies(quick_replies):
        try:
            data_path = Path(configpaths.get('PLUGINS_DATA'))
        except KeyError:
            # PLUGINS_DATA was added in 1.0.99.1
            return

        path = data_path / 'quick_replies'
        if not path.exists():
            path.mkdir(parents=True)

        filepath = path / 'quick_replies'
        with filepath.open('w') as file:
            json.dump(quick_replies, file)

    def set_quick_replies(self, quick_replies):
        self.quick_replies = quick_replies
        self._save_quick_replies(quick_replies)
        self._update_buttons()

    def _update_buttons(self):
        for button in self._buttons.values():
            button.update_menu(self.quick_replies)


class QuickRepliesButton(Gtk.MenuButton):
    def __init__(self, chat_control, replies):
        Gtk.MenuButton.__init__(self)
        self.get_style_context().add_class('chatcontrol-actionbar-button')
        self.set_property('relief', Gtk.ReliefStyle.NONE)
        self.set_can_focus(False)
        plugin_path = Path(__file__).parent
        img_path = plugin_path.resolve() / 'quick_replies.png'
        img = Gtk.Image.new_from_file(str(img_path))
        self.set_image(img)
        self.set_tooltip_text(_('Quick Replies'))

        self._chat_control = chat_control

        self.update_menu(replies)

    def update_menu(self, replies):
        self._menu = Gtk.Menu()
        for reply in replies:
            item = Gtk.MenuItem.new_with_label(label=reply)
            item.connect('activate', self._on_insert, reply)
            self._menu.append(item)
        self._menu.show_all()
        self.set_popup(self._menu)

109
    def _on_insert(self, _widget, text):
110 111 112 113
        message_buffer = self._chat_control.msg_textview.get_buffer()
        self._chat_control.msg_textview.remove_placeholder()
        message_buffer.insert_at_cursor(text.rstrip() + ' ')
        self._chat_control.msg_textview.grab_focus()