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