Initial port to GTK4+Adwaita

This commit is contained in:
Rafael Mardojai CM 2021-10-19 20:49:20 -05:00
parent 1a05970e43
commit 2fa1d125ce
15 changed files with 833 additions and 1148 deletions

View file

@ -1,7 +1,7 @@
{
"app-id" : "com.github.gi_lom.dialect",
"runtime" : "org.gnome.Platform",
"runtime-version" : "40",
"runtime-version" : "master",
"sdk" : "org.gnome.Sdk",
"command" : "dialect",
"finish-args" : [

View file

@ -1,18 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkAboutDialog" id="about">
<property name="can_focus">False</property>
<property name="modal">True</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
<property name="program_name" translatable="yes">Dialect</property>
<property name="copyright" translatable="yes">Copyright 20202021 The Dialect Authors</property>
<property name="comments" translatable="yes">A translation app for GNOME.</property>
<property name="website">https://github.com/dialect-app/dialect</property>
<property name="website_label" translatable="yes">GitHub page</property>
<property name="authors">gi-lom
<property name="authors">
Mufeed Ali
Rafael Mardojai CM
</property>

View file

@ -6,7 +6,8 @@
<file>about.ui</file>
<file>preferences.ui</file>
<file>lang-selector.ui</file>
<file>shortcuts-window.ui</file>
<file>lang-row.ui</file>
<file>shortcuts.ui</file>
<file>style.css</file>
</gresource>
</gresources>

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkBox">
<property name="spacing">6</property>
<style>
<class name="langselector"/>
</style>
<child>
<object class="GtkLabel">
<property name="xalign">0</property>
<binding name="label">
<lookup name="name" type="LangObject">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkImage">
<property name="icon-name">object-select-symbolic</property>
<binding name="visible">
<lookup name="selected" type="LangObject">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</property>
</template>
</interface>

View file

@ -3,21 +3,13 @@
<interface>
<requires lib="gtk+" version="3.22"/>
<template class="DialectLangSelector" parent="GtkPopover">
<property name="can_focus">False</property>
<property name="height_request">250</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">8</property>
<child>
<object class="GtkSearchEntry" id="search">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="primary_icon_name">edit-find-symbolic</property>
<property name="primary_icon_activatable">False</property>
<property name="primary_icon_sensitive">False</property>
<property name="margin_top">8</property>
<property name="margin_start">8</property>
<property name="margin_end">8</property>
@ -25,45 +17,31 @@
</child>
<child>
<object class="GtkScrolledWindow" id="scroll">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vexpand">True</property>
<property name="margin_bottom">8</property>
<property name="margin_start">8</property>
<property name="margin_end">8</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkRevealer" id="revealer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="reveal-child">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkListBox" id="recent_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection-mode">none</property>
<style>
<class name="background"/>
</style>
<object class="GtkListView" id="recent_list">
</object>
</child>
<child>
<object class="GtkSeparator" id="separator">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin">8</property>
<property name="margin-top">8</property>
<property name="margin-bottom">8</property>
<property name="margin-start">8</property>
<property name="margin-end">8</property>
</object>
</child>
</object>
@ -71,13 +49,7 @@
</object>
</child>
<child>
<object class="GtkListBox" id="lang_list">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection-mode">none</property>
<style>
<class name="background"/>
</style>
<object class="GtkListView" id="lang_list">
</object>
</child>
</object>
@ -85,9 +57,6 @@
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
</packing>
</child>
</object>
</child>

View file

@ -1,28 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.0"/>
<requires lib="libhandy" version="1.0"/>
<template class="DialectPreferencesWindow" parent="HdyPreferencesWindow">
<template class="DialectPreferencesWindow" parent="AdwPreferencesWindow">
<property name="default_height">420</property>
<property name="default_width">600</property>
<property name="modal">True</property>
<property name="window_position">center-on-parent</property>
<child>
<object class="HdyPreferencesPage">
<property name="visible">True</property>
<object class="AdwPreferencesPage">
<child>
<object class="HdyPreferencesGroup">
<object class="AdwPreferencesGroup" id="appearance">
<property name="title" translatable="yes">Appearance</property>
<property name="visible">True</property>
<property name="visible">False</property>
<child>
<object class="HdyActionRow">
<object class="AdwActionRow">
<property name="title" translatable="yes">Dark Mode</property>
<property name="visible">True</property>
<property name="activatable_widget">dark_mode</property>
<child>
<object class="GtkSwitch" id="dark_mode">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
</object>
</child>
@ -31,155 +24,134 @@
</object>
</child>
<child>
<object class="HdyPreferencesGroup">
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Behavior</property>
<property name="visible">True</property>
<child>
<object class="HdyActionRow">
<object class="AdwActionRow">
<property name="title" translatable="yes">Live Translation</property>
<property name="subtitle" translatable="yes">Warning: Your IP address may get banned for API abuse.</property>
<property name="visible">True</property>
<property name="activatable_widget">live_translation</property>
<child>
<object class="GtkSwitch" id="live_translation">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyComboRow" id="translate_accel">
<object class="AdwComboRow" id="translate_accel">
<property name="title" translatable="yes">Translation Shortcut</property>
<property name="subtitle" translatable="yes">The unselected choice will be used for line break.</property>
<property name="visible">True</property>
<property name="model">
<object class="GtkStringList">
<items>
<item>Ctrl + Enter</item>
<item>Enter</item>
</items>
</object>
</property>
</object>
</child>
<child>
<object class="HdyActionRow">
<object class="AdwActionRow">
<property name="title" translatable="yes">Default to Auto</property>
<property name="subtitle" translatable="yes">Use "Auto" as the default language</property>
<property name="visible">True</property>
<property name="activatable_widget">src_auto</property>
<child>
<object class="GtkSwitch" id="src_auto">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyComboRow" id="backend">
<object class="AdwComboRow" id="backend">
<property name="title" translatable="yes">Translator</property>
<property name="subtitle" translatable="yes">Choose from the available translation services.</property>
<property name="visible">True</property>
<property name="expression">
<lookup name="prettyname" type="BackendObject"></lookup>
</property>
</object>
</child>
<child>
<object class="HdyActionRow" id="backend_instance_row">
<object class="AdwActionRow" id="backend_instance_row">
<property name="title" translatable="yes">Translator Instance</property>
<property name="subtitle" translatable="yes">Enter a translation service URL.</property>
<property name="visible">True</property>
<child>
<object class="GtkStack" id="backend_instance_stack">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="spacing">6</property>
<property name="valign">center</property>
<property name="halign">end</property>
<child>
<object class="GtkLabel" id="backend_instance_label">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="backend_instance_edit">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Edit</property>
<object class="GtkStackPage">
<property name="name">view</property>
<property name="child">
<object class="GtkBox">
<property name="spacing">6</property>
<property name="valign">center</property>
<property name="halign">end</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">document-edit-symbolic</property>
<object class="GtkLabel" id="backend_instance_label">
</object>
</child>
<child>
<object class="GtkButton" id="backend_instance_edit">
<property name="tooltip-text" translatable="yes">Edit</property>
<child>
<object class="GtkImage">
<property name="icon-name">document-edit-symbolic</property>
</object>
</child>
</object>
</child>
</object>
</child>
</property>
</object>
<packing>
<property name="name">view</property>
</packing>
</child>
<child>
<object class="GtkBox" id="backend_instance_edit_box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="valign">center</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkEntry" id="backend_instance">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="backend_instance_reset">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Reset to default</property>
<object class="GtkStackPage">
<property name="name">edit</property>
<property name="child">
<object class="GtkBox" id="backend_instance_edit_box">
<property name="valign">center</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">view-refresh-symbolic</property>
<object class="GtkEntry" id="backend_instance">
</object>
</child>
<child>
<object class="GtkButton" id="backend_instance_reset">
<property name="tooltip-text" translatable="yes">Reset to default</property>
<child>
<object class="GtkImage">
<property name="icon-name">view-refresh-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="backend_instance_save">
<property name="tooltip-text" translatable="yes">Save</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton" id="backend_instance_save">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Save</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
</property>
</object>
<packing>
<property name="name">edit</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow" id="tts_row">
<object class="AdwActionRow" id="tts_row">
<property name="title" translatable="yes">Text-to-Speech</property>
<property name="subtitle" translatable="yes">Use Google for TTS.</property>
<property name="visible">True</property>
<property name="activatable_widget">tts</property>
<child>
<object class="GtkSwitch" id="tts">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
</object>
</child>
@ -188,10 +160,9 @@
</object>
</child>
<child>
<object class="HdyPreferencesGroup" id="search_provider">
<object class="AdwPreferencesGroup" id="search_provider">
<property name="title" translatable="yes">Search Provider</property>
<property name="description" translatable="yes">To reduce API abuse, the GNOME search provider in Dialect is turned off when Live translation is. Ensure the search provider is also turned on in the GNOME Settings.</property>
<property name="visible">True</property>
</object>
</child>
</object>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkShortcutsWindow" id="shortcuts">
<object class="GtkShortcutsWindow" id="help_overlay">
<property name="modal">True</property>
<child>
<object class="GtkShortcutsSection">

View file

@ -1,9 +1,19 @@
.toolbox {
.main-box {
padding: 12px;
}
.translation-box {
background: @theme_base_color;
border: 1px solid @borders;
border-bottom-left-radius: 9px;
border-bottom-right-radius: 9px;
border-top: 0;
border-radius: 9px;
}
.translation-box scrolledwindow {
border-bottom: 1px solid @borders;
}
.tools-box {
padding: 6px;
}
@ -17,30 +27,6 @@
border-top: 0;
}
.translation-frame {
background: @theme_base_color;
border-top-left-radius: 9px;
border-top-right-radius: 9px;
}
.translation-frame:disabled {
background: @insensitive_bg_color;
}
.translation-frame:backdrop {
background: @theme_unfocused_base_color;
}
.translation-frame scrollbar {
padding-top: 3px;
}
.translation-frame scrollbar:dir(ltr) {
border-top-right-radius: 9px;
}
.translation-frame scrollbar:dir(rtl) {
border-top-left-radius: 9px;
}
.langselector {
border-radius: 4px;
}

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
import re
from gi.repository import GObject, Gtk
from gi.repository import Gio, GObject, Gtk
from dialect.define import RES_PATH
from dialect.translators import get_lang_name
@ -31,46 +31,56 @@ class DialectLangSelector(Gtk.Popover):
# Connect popover closed signal
self.connect('closed', self._closed)
# Connect list signals
self.recent_list.connect('row-activated', self._activated)
self.lang_list.connect('row-activated', self._activated)
# Set filter func to lang list
self.lang_list.set_filter_func(self.filter_func, None, False)
self.recent_list.connect('activate', self._activated)
self.lang_list.connect('activate', self._activated)
# Connect search entry changed signal
self.search.connect('changed', self._update_search)
def filter_func(self, row, _data, _notify_destroy):
search = self.search.get_text()
return bool(re.search(search, row.name, re.IGNORECASE))
self.factory = Gtk.BuilderListItemFactory.new_from_resource(
None, f'{RES_PATH}/lang-row.ui'
);
self.recent_model = Gio.ListStore.new(LangObject)
selection_model = Gtk.SingleSelection.new(self.recent_model)
selection_model.set_autoselect(False)
self.recent_list.set_model(selection_model)
self.recent_list.set_factory(self.factory)
self.lang_model = Gio.ListStore.new(LangObject)
self.filter = Gtk.CustomFilter()
self.filter.set_filter_func(self._filter_func)
fitler_model = Gtk.FilterListModel.new(self.lang_model, self.filter)
selection_model = Gtk.SingleSelection.new(fitler_model)
selection_model.set_autoselect(False)
self.lang_list.set_model(selection_model)
self.lang_list.set_factory(self.factory)
def set_languages(self, languages):
# Clear list
children = self.lang_list.get_children()
for child in children:
self.lang_list.remove(child)
self.lang_model.remove_all()
# Load langs list
for code in languages:
row_selected = (code == self.selected)
self.lang_list.insert(LangRow(code, get_lang_name(code), row_selected), -1)
self.lang_model.append(LangObject(code, get_lang_name(code)))
def insert_recent(self, code, name, position=-1):
def insert_recent(self, code, name):
row_selected = (code == self.selected)
self.recent_list.insert(LangRow(code, name, row_selected), position)
self.recent_model.append(LangObject(code, name, row_selected))
def clear_recent(self):
children = self.recent_list.get_children()
for child in children:
self.recent_list.remove(child)
self.recent_model.remove_all()
def refresh_selected(self):
for lang in self.lang_list.get_children():
lang.selected = (lang.code == self.selected)
for item in self.lang_model:
item.set_property('selected', (item.code == self.selected))
def _activated(self, _list, row):
def _activated(self, list_view, index):
# Close popover
self.popdown()
model = list_view.get_model()
lang = model.get_selected_item()
# Set selected property
self.set_property('selected', row.code)
self.set_property('selected', lang.code)
def _closed(self, _popover):
# Reset scroll
@ -79,39 +89,30 @@ class DialectLangSelector(Gtk.Popover):
# Clear search
self.search.set_text('')
def _filter_func(self, item):
search = self.search.get_text()
return bool(re.search(search, item.name, re.IGNORECASE))
def _update_search(self, _entry):
search = self.search.get_text()
if search != '':
self.revealer.set_reveal_child(False)
else:
self.revealer.set_reveal_child(True)
self.lang_list.invalidate_filter()
self.filter.emit('changed', Gtk.FilterChange.DIFFERENT)
class LangRow(Gtk.ListBoxRow):
class LangObject(GObject.Object):
__gtype_name__ = 'LangObject'
def __init__(self, code, name, selected=False, **kwargs):
super().__init__(**kwargs)
code = GObject.Property(type=str)
name = GObject.Property(type=str)
selected = GObject.Property(type=bool, default=False)
self.code = code
self.name = name
def __init__(self, code, name, selected=False):
super().__init__()
row_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12)
label = Gtk.Label(self.name,
halign=Gtk.Align.START,
margin_start=4)
self.get_style_context().add_class('langselector')
row_box.pack_start(label, False, True, 0)
self.selected_icon = Gtk.Image.new_from_icon_name('object-select-symbolic', Gtk.IconSize.BUTTON)
row_box.pack_start(self.selected_icon, False, True, 0)
self.add(row_box)
self.show_all()
self.selected = selected
@property
def selected(self):
return self.selected_icon.get_visible()
@selected.setter
def selected(self, value):
self.selected_icon.set_visible(value)
self.set_property('code', code)
self.set_property('name', name)
self.set_property('selected', selected)

View file

@ -8,12 +8,12 @@ import sys
from gettext import gettext as _
import gi
gi.require_version('Gdk', '3.0')
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '4.0')
gi.require_version('Gtk', '4.0')
gi.require_version('Gst', '1.0')
gi.require_version('Handy', '1')
gi.require_version('Adw', '1')
from gi.repository import Gdk, Gio, GLib, Gst, Gtk, Handy
from gi.repository import Adw, Gdk, Gio, GLib, Gst, Gtk
from dialect.define import APP_ID, RES_PATH
from dialect.preferences import DialectPreferencesWindow
@ -21,9 +21,9 @@ from dialect.settings import Settings
from dialect.window import DialectWindow
class Dialect(Gtk.Application):
class Dialect(Adw.Application):
def __init__(self, version):
Gtk.Application.__init__(
Adw.Application.__init__(
self,
application_id=APP_ID,
flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE
@ -59,7 +59,6 @@ class Dialect(Gtk.Application):
text=self.launch_text,
langs=self.launch_langs
)
self.setup_actions_signals()
self.window.present()
@ -89,95 +88,50 @@ class Dialect(Gtk.Application):
return 0
def do_startup(self):
Gtk.Application.do_startup(self)
GLib.set_application_name(_('Dialect'))
GLib.set_prgname('com.github.gi_lom.dialect')
Adw.Application.do_startup(self)
Handy.init() # Init Handy
Gst.init(None) # Init Gst
# Load CSS
css_provider = Gtk.CssProvider()
css_provider.load_from_resource(f'{RES_PATH}/style.css')
screen = Gdk.Screen.get_default()
style_context = Gtk.StyleContext()
style_context.add_provider_for_screen(screen, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
def setup_actions(self):
""" Setup menu actions """
self.pronunciation_action = Gio.SimpleAction.new_stateful(
pronunciation = Gio.SimpleAction.new_stateful(
'pronunciation', None, Settings.get().show_pronunciation_value
)
pronunciation.connect('change-state', self._on_pronunciation)
self.add_action(pronunciation)
preferences = Gio.SimpleAction.new('preferences', None)
preferences.connect('activate', self._on_preferences)
self.add_action(preferences)
shortcuts = Gio.SimpleAction.new('shortcuts', None)
shortcuts.connect('activate', self._on_shortcuts)
self.add_action(shortcuts)
about = Gio.SimpleAction.new('about', None)
about.connect('activate', self._on_about)
self.add_action(about)
quit_action = Gio.SimpleAction.new('quit', None)
quit_action.connect('activate', self._on_quit)
self.add_action(quit_action)
self.set_accels_for_action('app.pronunciation', ['<Primary>P'])
self.add_action(self.pronunciation_action)
self.preferences_action = Gio.SimpleAction.new('preferences', None)
self.set_accels_for_action('app.preferences', ['<Primary>comma'])
self.add_action(self.preferences_action)
self.shortcuts_action = Gio.SimpleAction.new('shortcuts', None)
self.set_accels_for_action('app.shortcuts', ['<Primary>question'])
self.add_action(self.shortcuts_action)
self.about_action = Gio.SimpleAction.new('about', None)
self.add_action(self.about_action)
self.back_action = Gio.SimpleAction.new('back', None)
self.back_action.set_enabled(False)
self.set_accels_for_action('app.back', ['<Alt>Left'])
self.add_action(self.back_action)
self.forward_action = Gio.SimpleAction.new('forward', None)
self.forward_action.set_enabled(False)
self.set_accels_for_action('app.forward', ['<Alt>Right'])
self.add_action(self.forward_action)
self.switch_action = Gio.SimpleAction.new('switch', None)
self.set_accels_for_action('app.switch', ['<Primary>S'])
self.add_action(self.switch_action)
self.clear_action = Gio.SimpleAction.new('clear', None)
self.clear_action.set_enabled(False)
self.set_accels_for_action('app.clear', ['<Primary>D'])
self.add_action(self.clear_action)
self.paste_action = Gio.SimpleAction.new('paste', None)
self.set_accels_for_action('app.paste', ['<Primary><Shift>V'])
self.add_action(self.paste_action)
self.copy_action = Gio.SimpleAction.new('copy', None)
self.copy_action.set_enabled(False)
self.set_accels_for_action('app.copy', ['<Primary><Shift>C'])
self.add_action(self.copy_action)
self.listen_dest_action = Gio.SimpleAction.new('listen-dest', None)
self.set_accels_for_action('app.listen-dest', ['<Primary>L'])
self.add_action(self.listen_dest_action)
self.listen_src_action = Gio.SimpleAction.new('listen-src', None)
self.set_accels_for_action('app.listen-src', ['<Primary><Shift>L'])
self.add_action(self.listen_src_action)
self.quit_action = Gio.SimpleAction.new('quit', None)
self.set_accels_for_action('app.quit', ['<Primary>Q'])
self.add_action(self.quit_action)
def setup_actions_signals(self):
self.pronunciation_action.connect('change-state', self.on_pronunciation)
self.preferences_action.connect('activate', self.on_preferences)
self.shortcuts_action.connect('activate', self.on_shortcuts)
self.about_action.connect('activate', self.on_about)
self.back_action.connect('activate', self.window.ui_return)
self.forward_action.connect('activate', self.window.ui_forward)
self.switch_action.connect('activate', self.window.ui_switch)
self.clear_action.connect('activate', self.window.ui_clear)
self.paste_action.connect('activate', self.window.ui_paste)
self.copy_action.connect('activate', self.window.ui_copy)
self.listen_dest_action.connect('activate', self.window.ui_dest_voice)
self.listen_src_action.connect('activate', self.window.ui_src_voice)
self.quit_action.connect('activate', self.on_quit)
self.set_accels_for_action('win.back', ['<Alt>Left'])
self.set_accels_for_action('win.forward', ['<Alt>Right'])
self.set_accels_for_action('win.switch', ['<Primary>S'])
self.set_accels_for_action('win.clear', ['<Primary>D'])
self.set_accels_for_action('win.paste', ['<Primary><Shift>V'])
self.set_accels_for_action('win.copy', ['<Primary><Shift>C'])
self.set_accels_for_action('win.listen-dest', ['<Primary>L'])
self.set_accels_for_action('win.listen-src', ['<Primary><Shift>L'])
def on_pronunciation(self, action, value):
def _on_pronunciation(self, action, value):
""" Update show pronunciation setting """
action.set_state(value)
Settings.get().show_pronunciation = value
@ -188,33 +142,32 @@ class Dialect(Gtk.Application):
if self.window.trans_dest_pron is not None:
self.window.dest_pron_revealer.set_reveal_child(value)
def on_preferences(self, _action, _param):
def _on_preferences(self, _action, _param):
""" Show preferences window """
window = DialectPreferencesWindow(self.window)
window.set_transient_for(self.window)
window.present()
def on_shortcuts(self, _action, _param):
def _on_shortcuts(self, _action, _param):
"""Launch the Keyboard Shortcuts window."""
builder = Gtk.Builder.new_from_resource(f'{RES_PATH}/shortcuts-window.ui')
builder = Gtk.Builder.new_from_resource(f'{RES_PATH}/shortcuts.ui')
translate_shortcut = builder.get_object('translate_shortcut')
translate_shortcut.set_visible(not Settings.get().live_translation)
translate_shortcut.set_property('accelerator', Settings.get().translate_accel)
shortcuts_window = builder.get_object('shortcuts')
shortcuts_window = builder.get_object('help_overlay')
shortcuts_window.set_transient_for(self.window)
shortcuts_window.show()
def on_about(self, _action, _param):
def _on_about(self, _action, _param):
""" Show about dialog """
builder = Gtk.Builder.new_from_resource(f'{RES_PATH}/about.ui')
about = builder.get_object('about')
about.set_transient_for(self.window)
about.set_logo_icon_name(APP_ID)
about.set_version(self.version)
about.connect('response', lambda dialog, response: dialog.destroy())
about.present()
def on_quit(self, _action, _param):
def _on_quit(self, _action, _param):
self.quit()

View file

@ -7,7 +7,7 @@ import re
import threading
from gettext import gettext as _
from gi.repository import Gio, GLib, GObject, Gtk, Handy
from gi.repository import Adw, Gio, GLib, GObject, Gtk
from dialect.define import RES_PATH
from dialect.settings import Settings
@ -16,12 +16,13 @@ from dialect.tts import TTS
@Gtk.Template(resource_path=f'{RES_PATH}/preferences.ui')
class DialectPreferencesWindow(Handy.PreferencesWindow):
class DialectPreferencesWindow(Adw.PreferencesWindow):
__gtype_name__ = 'DialectPreferencesWindow'
parent = NotImplemented
# Get preferences widgets
appearance = Gtk.Template.Child()
dark_mode = Gtk.Template.Child()
live_translation = Gtk.Template.Child()
translate_accel = Gtk.Template.Child()
@ -49,17 +50,12 @@ class DialectPreferencesWindow(Handy.PreferencesWindow):
def setup(self):
# Disable search, we have few preferences
self.set_search_enabled(False)
# Temporal fix for crash
self.connect('destroy', self._unbind_settings)
# Setup translate accel combo row
model = Gio.ListStore.new(Handy.ValueObject)
options = ['Ctrl + Enter', 'Enter']
for index, value in enumerate(options):
model.insert(index, Handy.ValueObject.new(value))
self.translate_accel.bind_name_model(model,
Handy.ValueObject.dup_string)
# Show dark mode preference
self.style_manager = self.parent.app.get_style_manager()
if not self.style_manager.get_system_supports_color_schemes():
self.appearance.set_visible(True)
# Setup backends combo row
self.backend_model = Gio.ListStore.new(BackendObject)
backend_options = [
@ -70,8 +66,7 @@ class DialectPreferencesWindow(Handy.PreferencesWindow):
self.backend_model.insert(index, value)
if value.name == Settings.get().backend:
selected_backend_index = index
self.backend.bind_name_model(self.backend_model,
BackendObject.get_name)
self.backend.set_model(self.backend_model)
# Bind preferences with GSettings
Settings.get().bind('dark-mode', self.dark_mode, 'active',
@ -79,7 +74,7 @@ class DialectPreferencesWindow(Handy.PreferencesWindow):
Settings.get().bind('live-translation', self.live_translation, 'active',
Gio.SettingsBindFlags.DEFAULT)
Settings.get().bind('translate-accel', self.translate_accel,
'selected-index', Gio.SettingsBindFlags.DEFAULT)
'selected', Gio.SettingsBindFlags.DEFAULT)
Settings.get().bind('src-auto', self.src_auto, 'active',
Gio.SettingsBindFlags.DEFAULT)
@ -95,8 +90,8 @@ class DialectPreferencesWindow(Handy.PreferencesWindow):
self.live_translation.connect('notify::active', self._toggle_accel_pref)
# Switch backends
self.backend.set_selected_index(selected_backend_index)
self.backend.connect('notify::selected-index', self._switch_backends)
self.backend.set_selected(selected_backend_index)
self.backend.connect('notify::selected', self._switch_backends)
self.parent.connect('notify::backend-loading', self._on_backend_loading)
# Toggle TTS
@ -109,24 +104,30 @@ class DialectPreferencesWindow(Handy.PreferencesWindow):
self.backend_instance_reset.connect('clicked', self._on_reset_backend_instance)
self.__check_instance_support()
self.instance_save_image = Gtk.Image.new_from_icon_name(
'emblem-ok-symbolic', Gtk.IconSize.BUTTON)
self.backend_instance_save.add(self.instance_save_image)
self.instance_save_image = Gtk.Image.new_from_icon_name('emblem-ok-symbolic')
self.backend_instance_save.set_child(self.instance_save_image)
self.instance_save_spinner = Gtk.Spinner()
self.instance_save_image.show()
self.instance_save_spinner.show()
self.error_popover = Gtk.Popover(
relative_to=self.backend_instance, can_focus=False, modal=False)
pointing_to=self.backend_instance.get_allocation(),
can_focus=False,
)
self.error_label = Gtk.Label(label='Not a valid instance')
error_icon = Gtk.Image.new_from_icon_name(
'dialog-error-symbolic', Gtk.IconSize.LARGE_TOOLBAR)
error_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, margin=8, spacing=8)
error_box.pack_start(error_icon, False, False, 0)
error_box.pack_start(self.error_label, False, False, 0)
self.error_popover.add(error_box)
error_icon = Gtk.Image.new_from_icon_name('dialog-error-symbolic')
error_box = Gtk.Box(
orientation=Gtk.Orientation.HORIZONTAL,
margin_start=8,
margin_end=8,
margin_top=8,
margin_bottom=8,
spacing=8
)
error_box.prepend(error_icon)
error_box.prepend(self.error_label)
self.error_popover.set_child(error_box)
self.error_popover.set_position(Gtk.PositionType.BOTTOM)
error_box.show_all()
self.error_popover.hide()
# Search Provider
@ -148,9 +149,12 @@ class DialectPreferencesWindow(Handy.PreferencesWindow):
self.parent.change_backends(backend)
def _toggle_dark_mode(self, switch, _active):
gtk_settings = Gtk.Settings.get_default()
active = switch.get_active()
gtk_settings.set_property('gtk-application-prefer-dark-theme', active)
if not self.style_manager.get_system_supports_color_schemes():
active = switch.get_active()
if active:
self.style_manager.set_color_scheme(Adw.ColorScheme.FORCE_DARK)
else:
self.style_manager.set_color_scheme(Adw.ColorScheme.DEFAULT)
def _toggle_accel_pref(self, switch, _active):
self.translate_accel.set_sensitive(not switch.get_active())
@ -175,7 +179,7 @@ class DialectPreferencesWindow(Handy.PreferencesWindow):
).start()
def _switch_backends(self, row, _value):
backend = self.backend_model[row.get_selected_index()].name
backend = self.backend_model[row.get_selected()].name
Settings.get().backend = backend
self.__check_instance_support()
self.parent.change_backends(backend)
@ -257,13 +261,13 @@ class DialectPreferencesWindow(Handy.PreferencesWindow):
class BackendObject(GObject.Object):
name = None
prettyname = None
__gtype_name__ = 'BackendObject'
name = GObject.Property(type=str)
prettyname = GObject.Property(type=str)
def __init__(self, name, prettyname):
super().__init__()
self.name = name
self.prettyname = prettyname
def get_name(self):
return self.prettyname
self.set_property('name', name)
self.set_property('prettyname', prettyname)

View file

@ -205,7 +205,7 @@ class Settings(Gio.Settings):
if settings is not None and settings.get('src-langs'):
return settings.get('src-langs')
return TRANSLATORS[backend].src_langs
return TRANSLATORS[backend].src_langsP
def set_src_langs(self, backend, langs):
self._delete_arr_key(f'{backend}-src-langs') # Set deprecated key to unused state.

View file

@ -7,7 +7,7 @@ import threading
from gettext import gettext as _
from tempfile import NamedTemporaryFile
from gi.repository import Gdk, GLib, GObject, Gst, Gtk, Handy
from gi.repository import Adw, Gdk, Gio, GLib, GObject, Gst, Gtk
from dialect.define import APP_ID, MAX_LENGTH, RES_PATH, TRANS_NUMBER
from dialect.lang_selector import DialectLangSelector
@ -17,7 +17,7 @@ from dialect.tts import TTS
@Gtk.Template(resource_path=f'{RES_PATH}/window.ui')
class DialectWindow(Handy.ApplicationWindow):
class DialectWindow(Adw.ApplicationWindow):
__gtype_name__ = 'DialectWindow'
# Get widgets
@ -67,8 +67,10 @@ class DialectWindow(Handy.ApplicationWindow):
notification_revealer = Gtk.Template.Child()
notification_label = Gtk.Template.Child()
translator = None # Translator object
src_key_ctrlr = Gtk.Template.Child()
# Translator
translator = None # Translator object
# Text to speech
tts = None
tts_langs = None
@ -112,29 +114,27 @@ class DialectWindow(Handy.ApplicationWindow):
bus.connect('message', self.on_gst_message)
self.player_event = threading.Event() # An event for letting us know when Gst is done playing
# Clipboard
self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) # This is only for the Clipboard button
# Setup window
self.setup_actions()
self.setup()
def setup(self):
self.set_default_icon_name(APP_ID)
# Load saved dark mode
gtk_settings = Gtk.Settings.get_default()
gtk_settings.set_property('gtk-application-prefer-dark-theme',
Settings.get().dark_mode)
style_manager = self.app.get_style_manager()
if not style_manager.get_system_supports_color_schemes() and Settings.get().dark_mode:
style_manager.set_color_scheme(Adw.ColorScheme.FORCE_DARK)
# Connect responsive design function
self.connect('check-resize', self.responsive_listener)
self.connect('notify::default-width', self.responsive_listener)
self.connect('notify::maximized', self.responsive_listener)
# Save settings on close
self.connect('delete-event', self.save_settings)
self.connect('unrealize', self.save_settings)
self.setup_headerbar()
self.setup_actionbar()
self.setup_translation()
self.toggle_mobile_mode()
self.responsive_listener(launch=True)
# Load translator
self.retry_backend_btn.connect('clicked', self.retry_load_translator)
@ -147,6 +147,43 @@ class DialectWindow(Handy.ApplicationWindow):
if Settings.get().tts != '':
threading.Thread(target=self.load_lang_speech, daemon=True).start()
def setup_actions(self):
back = Gio.SimpleAction.new('back', None)
back.set_enabled(False)
back.connect('activate', self.ui_return)
self.add_action(back)
forward_action = Gio.SimpleAction.new('forward', None)
forward_action.set_enabled(False)
forward_action.connect('activate', self.ui_forward)
self.add_action(forward_action)
switch_action = Gio.SimpleAction.new('switch', None)
switch_action.connect('activate', self.ui_switch)
self.add_action(switch_action)
clear_action = Gio.SimpleAction.new('clear', None)
clear_action.set_enabled(False)
clear_action.connect('activate', self.ui_clear)
self.add_action(clear_action)
paste_action = Gio.SimpleAction.new('paste', None)
paste_action.connect('activate', self.ui_paste)
self.add_action(paste_action)
copy_action = Gio.SimpleAction.new('copy', None)
copy_action.set_enabled(False)
copy_action.connect('activate', self.ui_copy)
self.add_action(copy_action)
listen_dest_action = Gio.SimpleAction.new('listen-dest', None)
listen_dest_action.connect('activate', self.ui_dest_voice)
self.add_action(listen_dest_action)
listen_src_action = Gio.SimpleAction.new('listen-src', None)
listen_src_action.connect('activate', self.ui_src_voice)
self.add_action(listen_src_action)
def load_translator(self, backend, launch=False):
def update_ui():
# Supported features
@ -156,9 +193,9 @@ class DialectWindow(Handy.ApplicationWindow):
if not self.translator.supported_features['pronunciation']:
self.src_pron_revealer.set_reveal_child(False)
self.dest_pron_revealer.set_reveal_child(False)
self.app.pronunciation_action.set_enabled(False)
self.app.lookup_action('pronunciation').set_enabled(False)
else:
self.app.pronunciation_action.set_enabled(True)
self.app.lookup_action('pronunciation').set_enabled(True)
self.no_retranslate = True
# Update langs list
@ -225,10 +262,10 @@ class DialectWindow(Handy.ApplicationWindow):
).start()
def on_listen_failed(self):
self.src_voice_btn.set_image(self.src_voice_warning)
self.src_voice_btn.set_child(self.src_voice_warning)
self.src_voice_spinner.stop()
self.dest_voice_btn.set_image(self.dest_voice_warning)
self.dest_voice_btn.set_child(self.dest_voice_warning)
self.dest_voice_spinner.stop()
tooltip_text = _('A network issue has occured. Retry?')
@ -249,17 +286,17 @@ class DialectWindow(Handy.ApplicationWindow):
)
if self.tts_langs:
self.app.listen_src_action.set_enabled(
self.lookup_action('listen-src').set_enabled(
self.src_lang_selector.get_property('selected') in self.tts_langs
and src_text != ''
)
self.app.listen_dest_action.set_enabled(
self.lookup_action('listen-dest').set_enabled(
self.dest_lang_selector.get_property('selected') in self.tts_langs
and dest_text != ''
)
else:
self.app.listen_src_action.set_enabled(src_text != '')
self.app.listen_dest_action.set_enabled(dest_text != '')
self.lookup_action('listen-src').set_enabled(src_text != '')
self.lookup_action('listen-dest').set_enabled(dest_text != '')
def load_lang_speech(self, listen=False, text=None, language=None):
"""
@ -290,7 +327,6 @@ class DialectWindow(Handy.ApplicationWindow):
self.on_src_lang_changed)
# Set popover selector to button
self.src_lang_btn.set_popover(self.src_lang_selector)
self.src_lang_selector.set_relative_to(self.src_lang_btn)
# Right lang selector
self.dest_lang_selector = DialectLangSelector()
@ -298,28 +334,23 @@ class DialectWindow(Handy.ApplicationWindow):
self.on_dest_lang_changed)
# Set popover selector to button
self.dest_lang_btn.set_popover(self.dest_lang_selector)
self.dest_lang_selector.set_relative_to(self.dest_lang_btn)
self.langs_button_box.set_homogeneous(False)
# Add menu to menu button
builder = Gtk.Builder.new_from_resource(f'{RES_PATH}/menu.ui')
menu = builder.get_object('app-menu')
menu_popover = Gtk.Popover.new_from_model(self.menu_btn, menu)
menu_popover = Gtk.PopoverMenu.new_from_model(menu)
self.menu_btn.set_popover(menu_popover)
def setup_actionbar(self):
# Set popovers to lang buttons
self.src_lang_btn2.set_popover(self.src_lang_selector)
self.dest_lang_btn2.set_popover(self.dest_lang_selector)
def setup_translation(self):
# Left buffer
self.src_buffer = self.src_text.get_buffer()
self.src_buffer.set_text(self.launch_text)
self.src_buffer.connect('changed', self.on_src_text_changed)
self.src_buffer.connect('end-user-action', self.user_action_ended)
self.connect('key-press-event', self.update_trans_button)
# Detect typing
self.src_key_ctrlr.connect('key-pressed', self.update_trans_button)
# Translate button
self.translate_btn.connect('clicked', self.translation)
# "Did you mean" links
@ -334,16 +365,12 @@ class DialectWindow(Handy.ApplicationWindow):
self.trans_warning.hide()
# Voice buttons prep-work
self.src_voice_warning = Gtk.Image.new_from_icon_name(
'dialog-warning-symbolic', Gtk.IconSize.BUTTON)
self.src_voice_image = Gtk.Image.new_from_icon_name(
'audio-speakers-symbolic', Gtk.IconSize.BUTTON)
self.src_voice_warning = Gtk.Image.new_from_icon_name('dialog-warning-symbolic')
self.src_voice_image = Gtk.Image.new_from_icon_name('audio-speakers-symbolic')
self.src_voice_spinner = Gtk.Spinner() # For use while audio is running or still loading.
self.dest_voice_warning = Gtk.Image.new_from_icon_name(
'dialog-warning-symbolic', Gtk.IconSize.BUTTON)
self.dest_voice_image = Gtk.Image.new_from_icon_name(
'audio-speakers-symbolic', Gtk.IconSize.BUTTON)
self.dest_voice_warning = Gtk.Image.new_from_icon_name('dialog-warning-symbolic')
self.dest_voice_image = Gtk.Image.new_from_icon_name('audio-speakers-symbolic')
self.dest_voice_spinner = Gtk.Spinner()
self.toggle_voice_spinner(True)
@ -351,10 +378,15 @@ class DialectWindow(Handy.ApplicationWindow):
self.src_voice_btn.set_visible(Settings.get().tts != '')
self.dest_voice_btn.set_visible(Settings.get().tts != '')
def responsive_listener(self, _window):
size = self.get_size()
def responsive_listener(self, _window=None, _param=None, launch=False):
if launch:
width, height = Settings.get().window_size
else:
size = self.get_default_size()
width = size.width
height = size.height
if size.width < 680:
if width < 680 and not self.is_maximized():
if self.mobile_mode is False:
self.mobile_mode = True
self.toggle_mobile_mode()
@ -363,6 +395,9 @@ class DialectWindow(Handy.ApplicationWindow):
self.mobile_mode = False
self.toggle_mobile_mode()
if launch:
self.set_default_size(width, height)
def toggle_mobile_mode(self):
if self.mobile_mode:
# Show actionbar
@ -372,8 +407,10 @@ class DialectWindow(Handy.ApplicationWindow):
# Change translation box orientation
self.translator_box.set_orientation(Gtk.Orientation.VERTICAL)
# Change lang selectors position
self.src_lang_selector.set_relative_to(self.src_lang_btn2)
self.dest_lang_selector.set_relative_to(self.dest_lang_btn2)
self.src_lang_btn.set_popover(None)
self.src_lang_btn2.set_popover(self.src_lang_selector)
self.dest_lang_btn.set_popover(None)
self.dest_lang_btn2.set_popover(self.dest_lang_selector)
else:
# Hide actionbar
self.actionbar.set_reveal_child(False)
@ -382,8 +419,10 @@ class DialectWindow(Handy.ApplicationWindow):
# Reset translation box orientation
self.translator_box.set_orientation(Gtk.Orientation.HORIZONTAL)
# Reset lang selectors position
self.src_lang_selector.set_relative_to(self.src_lang_btn)
self.dest_lang_selector.set_relative_to(self.dest_lang_btn)
self.src_lang_btn2.set_popover(None)
self.src_lang_btn.set_popover(self.src_lang_selector)
self.dest_lang_btn2.set_popover(None)
self.dest_lang_btn.set_popover(self.dest_lang_selector)
def translate(self, text, src_lang, dest_lang):
"""
@ -404,7 +443,7 @@ class DialectWindow(Handy.ApplicationWindow):
def save_settings(self, *args, **kwargs):
if not self.is_maximized():
size = self.get_size()
size = self.get_default_size()
Settings.get().window_size = (size.width, size.height)
if self.translator is not None:
Settings.get().set_src_langs(self.translator.name, self.src_langs)
@ -430,12 +469,12 @@ class DialectWindow(Handy.ApplicationWindow):
def toggle_voice_spinner(self, active=True):
if active:
self.app.listen_src_action.set_enabled(False)
self.src_voice_btn.set_image(self.src_voice_spinner)
self.lookup_action('listen-src').set_enabled(False)
self.src_voice_btn.set_child(self.src_voice_spinner)
self.src_voice_spinner.start()
self.app.listen_dest_action.set_enabled(False)
self.dest_voice_btn.set_image(self.dest_voice_spinner)
self.lookup_action('listen-dest').set_enabled(False)
self.dest_voice_btn.set_child(self.dest_voice_spinner)
self.dest_voice_spinner.start()
else:
src_text = self.src_buffer.get_text(
@ -443,11 +482,11 @@ class DialectWindow(Handy.ApplicationWindow):
self.src_buffer.get_end_iter(),
True
)
self.app.listen_src_action.set_enabled(
self.lookup_action('listen-src').set_enabled(
self.src_lang_selector.get_property('selected') in self.tts_langs
and src_text != ''
)
self.src_voice_btn.set_image(self.src_voice_image)
self.src_voice_btn.set_child(self.src_voice_image)
self.src_voice_spinner.stop()
dest_text = self.dest_buffer.get_text(
@ -455,11 +494,11 @@ class DialectWindow(Handy.ApplicationWindow):
self.dest_buffer.get_end_iter(),
True
)
self.app.listen_dest_action.set_enabled(
self.lookup_action('listen-dest').set_enabled(
self.dest_lang_selector.get_property('selected') in self.tts_langs
and dest_text != ''
)
self.dest_voice_btn.set_image(self.dest_voice_image)
self.dest_voice_btn.set_child(self.dest_voice_image)
self.dest_voice_spinner.stop()
def on_src_lang_changed(self, _obj, _param):
@ -479,8 +518,9 @@ class DialectWindow(Handy.ApplicationWindow):
# Disable or enable listen function.
if self.tts_langs and Settings.get().tts != '':
self.app.listen_src_action.set_enabled(code in self.tts_langs
and src_text != '')
self.lookup_action('listen-src').set_enabled(
code in self.tts_langs and src_text != ''
)
if code in self.translator.languages:
self.src_lang_label.set_label(get_lang_name(code))
@ -526,8 +566,9 @@ class DialectWindow(Handy.ApplicationWindow):
# Disable or enable listen function.
if self.tts_langs and Settings.get().tts != '':
self.app.listen_dest_action.set_enabled(code in self.tts_langs
and dest_text != '')
self.lookup_action('listen-dest').set_enabled(
code in self.tts_langs and dest_text != ''
)
self.dest_lang_label.set_label(get_lang_name(code))
# Update saved dest langs list
@ -642,14 +683,20 @@ class DialectWindow(Handy.ApplicationWindow):
self.dest_buffer.get_end_iter(),
True
)
self.clipboard.set_text(dest_text, -1)
self.clipboard.store()
clipboard = Gdk.Display.get_default().get_clipboard()
clipboard.set(dest_text)
def ui_paste(self, _action, _param):
text = self.clipboard.wait_for_text()
if text is not None:
end_iter = self.src_buffer.get_end_iter()
self.src_buffer.insert(end_iter, text)
clipboard = Gdk.Display.get_default().get_clipboard()
def on_paste(_clipboard, result):
text = clipboard.read_text_finish(result)
if text is not None:
end_iter = self.src_buffer.get_end_iter()
self.src_buffer.insert(end_iter, text)
cancellable = Gio.Cancellable()
clipboard.read_text_async(cancellable, on_paste)
def ui_src_voice(self, _action, _param):
src_text = self.src_buffer.get_text(
@ -713,27 +760,28 @@ class DialectWindow(Handy.ApplicationWindow):
self.voice_loading = False
# This starts the translation if Ctrl+Enter button is pressed
def update_trans_button(self, button, keyboard):
modifiers = keyboard.get_state() & Gtk.accelerator_get_default_mod_mask()
def update_trans_button(self, _button, keyval, _keycode, state):
modifiers = state & Gtk.accelerator_get_default_mod_mask()
control_mask = Gdk.ModifierType.CONTROL_MASK
shift_mask = Gdk.ModifierType.SHIFT_MASK
unicode_key_val = Gdk.keyval_to_unicode(keyboard.keyval)
enter_keys = (Gdk.KEY_Return, Gdk.KEY_KP_Enter)
if (GLib.unichar_isgraph(chr(unicode_key_val)) and
modifiers in (shift_mask, 0) and not self.src_text.is_focus()):
self.src_text.grab_focus()
# Disabled until I find better ways to make it work.
# shift_mask = Gdk.ModifierType.SHIFT_MASK
# unicode_key_val = Gdk.keyval_to_unicode(keyval)
# if (GLib.unichar_isgraph(chr(unicode_key_val)) and
# modifiers in (shift_mask, 0) and not self.src_text.is_focus()):
# self.src_text.grab_focus()
if not Settings.get().live_translation:
if control_mask == modifiers:
if keyboard.keyval in enter_keys:
if keyval in enter_keys:
if not Settings.get().translate_accel_value:
self.translation(button)
self.translation(None)
return Gdk.EVENT_STOP
return Gdk.EVENT_PROPAGATE
elif keyboard.keyval in enter_keys:
elif keyval in enter_keys:
if Settings.get().translate_accel_value:
self.translation(button)
self.translation(None)
return Gdk.EVENT_STOP
return Gdk.EVENT_PROPAGATE
@ -748,25 +796,25 @@ class DialectWindow(Handy.ApplicationWindow):
def on_src_text_changed(self, buffer):
sensitive = buffer.get_char_count() != 0
self.translate_btn.set_sensitive(sensitive)
self.app.clear_action.set_enabled(sensitive)
self.lookup_action('clear').set_enabled(sensitive)
if not self.voice_loading and self.tts_langs:
self.app.listen_src_action.set_enabled(
self.lookup_action('listen-src').set_enabled(
self.src_lang_selector.get_property('selected') in self.tts_langs
and sensitive
)
elif not self.voice_loading and not self.tts_langs:
self.app.listen_src_action.set_enabled(sensitive)
self.lookup_action('listen-src').set_enabled(sensitive)
def on_dest_text_changed(self, buffer):
sensitive = buffer.get_char_count() != 0
self.app.copy_action.set_enabled(sensitive)
self.lookup_action('copy').set_enabled(sensitive)
if not self.voice_loading and self.tts_langs:
self.app.listen_dest_action.set_enabled(
self.lookup_action('listen-dest').set_enabled(
self.dest_lang_selector.get_property('selected') in self.tts_langs
and sensitive
)
elif not self.voice_loading and not self.tts_langs:
self.app.listen_dest_action.set_enabled(sensitive)
self.lookup_action('listen-dest').set_enabled(sensitive)
def user_action_ended(self, buffer):
# If the text is over the highest number of characters allowed, it is truncated.
@ -785,8 +833,8 @@ class DialectWindow(Handy.ApplicationWindow):
# The history part
def reset_return_forward_btns(self):
self.app.back_action.set_enabled(self.current_history < len(self.translator.history) - 1)
self.app.forward_action.set_enabled(self.current_history > 0)
self.lookup_action('back').set_enabled(self.current_history < len(self.translator.history) - 1)
self.lookup_action('forward').set_enabled(self.current_history > 0)
# Retrieve translation history
def history_update(self):
@ -875,9 +923,9 @@ class DialectWindow(Handy.ApplicationWindow):
def on_trans_failed():
self.trans_warning.show()
self.send_notification(_('Translation failed.\nPlease check for network issues.'))
self.app.copy_action.set_enabled(False)
self.app.listen_src_action.set_enabled(False)
self.app.listen_dest_action.set_enabled(False)
self.lookup_action('copy').set_enabled(False)
self.lookup_action('listen-src').set_enabled(False)
self.lookup_action('listen-dest').set_enabled(False)
def on_trans_success():
self.trans_warning.hide()

View file

@ -1,5 +1,5 @@
project('dialect',
version: '1.4.1',
version: '2.0.0',
meson_version: '>= 0.50.0',
default_options: [ 'warning_level=2',
],