1# -*- coding: utf-8 -*-
2#
3#  Copyrignt (C) 2017 Jordi Mas <jmas@softcatala.org>
4#
5#  This program is free software; you can redistribute it and/or modify
6#  it under the terms of the GNU General Public License as published by
7#  the Free Software Foundation; either version 2 of the License, or
8#  (at your option) any later version.
9#
10#  This program is distributed in the hope that it will be useful,
11#  but WITHOUT ANY WARRANTY; without even the implied warranty of
12#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#  GNU General Public License for more details.
14#
15#  You should have received a copy of the GNU General Public License
16#  along with this program; if not, write to the Free Software
17#  Foundation, Inc., 51 Franklin Street, Fifth Floor,
18#  Boston, MA 02110-1301, USA.
19
20import gi
21gi.require_version('Gtk', '3.0')
22gi.require_version('GtkSource', '4')
23gi.require_version('PeasGtk', '1.0')
24
25from gi.repository import GObject, Gio, Gtk, Gedit, PeasGtk
26from .services.services import Services
27from .services.apertium import Apertium
28from .translateview import TranslateView
29from .preferences import Preferences
30from .settings import Settings
31
32try:
33    import gettext
34    gettext.bindtextdomain('gedit-plugins')
35    gettext.textdomain('gedit-plugins')
36    _ = gettext.gettext
37except:
38    _ = lambda s: s
39
40def _get_translation_service_shared(service_id):
41    settings = Settings()
42    service = Services.get(service_id)
43    if service.has_api_key() is True:
44        key = settings.get_apikey()
45        service.set_api_key(key)
46
47    if service_id == Services.APERTIUM_ID:
48        server = settings.get_apertium_server()
49        service.set_server(server)
50
51    service.init()
52    return service
53
54
55
56class TranslateAppActivatable(GObject.Object, Gedit.AppActivatable):
57
58    app = GObject.Property(type=Gedit.App)
59
60    def __init__(self):
61        GObject.Object.__init__(self)
62
63    def do_activate(self):
64        self.app.add_accelerator("<Primary>K", "win.translate", None)
65
66    def do_deactivate(self):
67        self.app.remove_accelerator("win.translate", None)
68
69class TranslateWindowActivatable(GObject.Object, Gedit.WindowActivatable, PeasGtk.Configurable):
70
71    __gtype_name__ = "TranslateWindowActivatable"
72    window = GObject.Property(type=Gedit.Window)
73
74    def __init__(self):
75        GObject.Object.__init__(self)
76
77    def do_activate(self):
78        action = Gio.SimpleAction(name="translate")
79        action.connect('activate', lambda a, p: self.do_translate())
80        self.window.add_action(action)
81
82        global g_console
83        g_console = TranslateView(namespace = {'__builtins__' : __builtins__,
84                                                   'gedit' : Gedit,
85                                                   'window' : self.window})
86
87        name = self._get_translation_service_name()
88        g_console.write(_('Translations powered by {0}').format(name))
89        bottom = self.window.get_bottom_panel()
90        g_console.show_all()
91        bottom.add_titled(g_console, "GeditTranslateConsolePanel", _('Translate Console'))
92
93    def do_deactivate(self):
94        bottom = self.window.get_bottom_panel()
95        bottom.remove(g_console)
96        self.window.remove_action("translate")
97
98    def do_update_state(self):
99        sensitive = False
100        view = self.window.get_active_view()
101        if view and hasattr(view, "translate_view_activatable"):
102            sensitive = True
103
104        self.window.lookup_action('translate').set_enabled(sensitive)
105
106    def _get_translation_service_name(self):
107        settings = Settings()
108        service_id = settings.get_service()
109        return Services.get_name(service_id)
110
111    def _get_translation_service(self, service_id):
112        return _get_translation_service_shared(service_id)
113
114    def get_languages_names_codes(self, service_id):
115        service = self._get_translation_service(service_id)
116        return service.get_language_names(), service.get_language_codes()
117
118    def do_create_configure_widget(self):
119        config_widget = Preferences(self.plugin_info.get_data_dir(),
120                                    self.get_languages_names_codes)
121        widget = config_widget.configure_widget()
122        return widget
123
124    '''Entry point when user uses keyboard shortcut'''
125    def do_translate(self, unindent=False):
126        view = self.window.get_active_view()
127        if view and view.translate_view_activatable:
128            view.translate_view_activatable.do_translate(view.get_buffer(), unindent)
129
130
131class TranslateViewActivatable(GObject.Object, Gedit.ViewActivatable):
132
133    view = GObject.Property(type=Gedit.View)
134
135    def __init__(self):
136        self.popup_handler_id = 0
137        GObject.Object.__init__(self)
138        self._settings = Settings()
139
140    def do_activate(self):
141        self.view.translate_view_activatable = self
142        self.popup_handler_id = self.view.connect('populate-popup', self.populate_popup)
143
144    def do_deactivate(self):
145        if self.popup_handler_id != 0:
146            self.view.disconnect(self.popup_handler_id)
147            self.popup_handler_id = 0
148        delattr(self.view, "translate_view_activatable")
149
150    def _get_language_pair_name(self):
151        language_pair = self._settings.get_language_pair()
152        languages = language_pair.split('|')
153
154        service = self._get_translation_service()
155        return service.get_language_pair_name(languages[0], languages[1])
156
157    def populate_popup(self, view, popup):
158        if not isinstance(popup, Gtk.MenuShell):
159            return
160
161        item = Gtk.SeparatorMenuItem()
162        item.show()
163        popup.append(item)
164
165        language_pair_name = self._get_language_pair_name()
166        text = _("Translate selected text [{0}]").format(language_pair_name)
167
168        item = Gtk.MenuItem.new_with_mnemonic(text)
169        item.set_sensitive(self.is_enabled())
170        item.show()
171        item.connect('activate', lambda i: self.do_translate(view.get_buffer()))
172        popup.append(item)
173
174    def is_enabled(self):
175        document = self.view.get_buffer()
176        if document is None:
177            return False
178
179        start = None
180        end = None
181
182        try:
183            start, end = document.get_selection_bounds()
184
185        except:
186            pass
187
188        return start is not None and end is not None
189
190    def _get_translation_service(self):
191        service_id = self._settings.get_service()
192        return _get_translation_service_shared(service_id)
193
194    def translate_text(self, document, start, end):
195        doc = self.view.get_buffer()
196        text = doc.get_text(start, end, False)
197        language_pair = self._settings.get_language_pair()
198
199        service = self._get_translation_service()
200        translated = service.translate_text(text, language_pair)
201
202        if self._settings.get_output_document():
203            doc.insert(start, translated)
204        else:
205            g_console.write(translated)
206
207    def do_translate(self, document, unindent=False):
208        start, end = document.get_selection_bounds()
209        self.translate_text(document, start, end)
210
211
212