Skip to content

Commit caa70b9

Browse files
authored
[PanelTranslator@klangman] Fixes and improvements (#6835)
- Fix the output for right-to-left language output by using the -no-bidi translation-shell parameter when translating text - Remove the Hotkey1/2 options and replaced them with 8 unique hotkey options on a new Hotkeys configuration dialog page. This makes the hotkey support more versatile and allows the Cinnamon Keyboard->Shortcuts setting page to properly show Panel Translator Hotkeys in it's user interface - Add support for allowing the popup dialog window to be resized - Save and restore popup window size on window resize events and applet startup - Fix handling of display scaling factors
1 parent 0fe7a0f commit caa70b9

File tree

13 files changed

+632
-673
lines changed

13 files changed

+632
-673
lines changed

PanelTranslator@klangman/CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 1.2.0
4+
5+
* Fixed the output for right-to-left language output by using the -no-bidi translation-shell parameter when translating text
6+
* Removed the Hotkey1/2 options and replaced them with 8 unique hotkey options on a new Hotkeys configuration dialog page. This makes the hotkey support more versatile and allows the Cinnamon Keyboard->Shortcuts setting page to properly show Panel Translator Hotkeys in it's user interface
7+
* Added support for allowing the popup dialog window to be resized
8+
* Save and restore popup window size on window resize events and applet startup
9+
* Fix handling of display scaling factors
10+
311
## 1.1.0
412

513
* Added two hotkey options that can perform any of the 8 translation options
@@ -13,4 +21,3 @@
1321
## 1.0.1
1422

1523
* Show any text-to-speech errors by placing the stderr text at the bottom of the GUI
16-

PanelTranslator@klangman/files/PanelTranslator@klangman/applet.js

Lines changed: 104 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ const TranslateAction = {
6060
TransClipboardCopy: 8
6161
}
6262

63+
const Hotkeys = [
64+
{name: "panelTranslator-trans-selection", setting: "hotkey-trans-selection", action: TranslateAction.PopupSelection, enabled: false},
65+
{name: "panelTranslator-trans-clipboard", setting: "hotkey-trans-clipboard", action: TranslateAction.PopupClipboard, enabled: false},
66+
{name: "panelTranslator-trans-play-selection", setting: "hotkey-trans-play-selection", action: TranslateAction.PopupSelectionPlay, enabled: false},
67+
{name: "panelTranslator-trans-play-clipboard", setting: "hotkey-trans-play-clipboard", action: TranslateAction.PopupClipboardPlay, enabled: false},
68+
{name: "panelTranslator-play-selection", setting: "hotkey-play-selection", action: TranslateAction.PlaySelection, enabled: false},
69+
{name: "panelTranslator-play-clipboard", setting: "hotkey-play-clipboard", action: TranslateAction.PlayClipboard, enabled: false},
70+
{name: "panelTranslator-trans-copy-selection", setting: "hotkey-trans-copy-selection", action: TranslateAction.TransSelectionCopy, enabled: false},
71+
{name: "panelTranslator-trans-copy-clipboard", setting: "hotkey-trans-copy-clipboard", action: TranslateAction.TransClipboardCopy, enabled: false},
72+
]
73+
6374
const Engine = {
6475
Apertium: 0,
6576
Aspell: 1,
@@ -108,13 +119,21 @@ class PanelTranslatorApp extends Applet.IconApplet {
108119
this.getEngine();
109120
this.languages = [];
110121
this.getLanguages();
111-
this.hotkey1Combo = null;
112-
this.hotkey2Combo = null;
122+
this._resizer = new Applet.PopupResizeHandler(this.menu.actor,
123+
() => this._orientation,
124+
(w,h) => this.translatorPopup.onBoxResized(w,h),
125+
() => this.popup_width,
126+
() => this.popup_height);
127+
128+
this.settings.bind("popup-width", "popup_width");
129+
this.settings.bind("popup-height", "popup_height");
130+
113131
}
114132

115133
on_applet_added_to_panel() {
116-
this._signalManager.connect(this.settings, "changed::hotkey-1", this._updateHotkeys, this);
117-
this._signalManager.connect(this.settings, "changed::hotkey-2", this._updateHotkeys, this);
134+
for ( let i=0 ; i < Hotkeys.length ; i++ ) {
135+
this._signalManager.connect(this.settings, "changed::" + Hotkeys[i].setting, this._updateHotkeys, this);
136+
}
118137
this._updateHotkeys()
119138
}
120139

@@ -123,22 +142,20 @@ class PanelTranslatorApp extends Applet.IconApplet {
123142
}
124143

125144
_updateHotkeys(register=true) {
126-
if (this.hotkey1Combo) {
127-
Main.keybindingManager.removeHotKey("panelTranslator-hotkey1");
128-
this.hotkey1Combo = null;
129-
}
130-
if (this.hotkey2Combo) {
131-
Main.keybindingManager.removeHotKey("panelTranslator-hotkey2");
132-
this.hotkey2Combo = null;
133-
}
134-
if (register) {
135-
this.hotkey1Combo = this.getHotkeySequence("hotkey-1");
136-
if (this.hotkey1Combo) {
137-
Main.keybindingManager.addHotKey("panelTranslator-hotkey1", this.hotkey1Combo, () => this.performHotkey("hotkey1-action") );
145+
let i;
146+
for ( i=0 ; i < Hotkeys.length ; i++ ) {
147+
if (Hotkeys[i].enabled) {
148+
Main.keybindingManager.removeHotKey(Hotkeys[i].name);
149+
Hotkeys.enabled = false;
138150
}
139-
this.hotkey2Combo = this.getHotkeySequence("hotkey-2");
140-
if (this.hotkey2Combo) {
141-
Main.keybindingManager.addHotKey("panelTranslator-hotkey2", this.hotkey2Combo, () => this.performHotkey("hotkey2-action") );
151+
152+
if (register) {
153+
let hotkeyCombo = this.getHotkeySequence(Hotkeys[i].setting);
154+
if (hotkeyCombo) {
155+
let action = Hotkeys[i].action;
156+
Main.keybindingManager.addHotKey(Hotkeys[i].name, hotkeyCombo, () => this._performTranslateAction(action));
157+
Hotkeys[i].enabled = true;
158+
}
142159
}
143160
}
144161
}
@@ -151,11 +168,6 @@ class PanelTranslatorApp extends Applet.IconApplet {
151168
return null;
152169
}
153170

154-
performHotkey(name) {
155-
let action = this.settings.getValue(name);
156-
this._performTranslateAction(action);
157-
}
158-
159171
_performTranslateAction(action) {
160172
switch(action) {
161173
case TranslateAction.PopupSelection:
@@ -375,10 +387,15 @@ class TranslatorPopupItem extends PopupMenu.PopupMenuSection {
375387
this.toTextBox.set_text(fromText);
376388
});
377389

378-
this.fromSearchEntry = new St.Entry({ name: 'menu-search-entry', width: 210, track_hover: true, can_focus: true, x_expand: true, x_align: Clutter.ActorAlign.START });
390+
let monitor = this._applet.panel.monitor;
391+
let width = Math.min(monitor.width, this._applet.settings.getValue("popup-width"));
392+
let height = Math.min(monitor.height, this._applet.settings.getValue("popup-height"));
393+
this._applet.settings.setValue("popup-width", width);
394+
this._applet.settings.setValue("popup-height", height);
395+
this.fromSearchEntry = new St.Entry({ name: 'menu-search-entry', width: 210*global.ui_scale, track_hover: true, can_focus: true, x_expand: true, x_align: Clutter.ActorAlign.START });
379396
this.fromSearchEntry.get_clutter_text().connect( 'key-press-event', Lang.bind(this, this._onKeyPressEvent) );
380397
this.fromSearchEntry.get_clutter_text().connect( 'key-release-event', (actor, event) => {this._onKeyReleaseEvent(actor, event, this.fromLanguage); } );
381-
this.toSearchEntry = new St.Entry({ name: 'menu-search-entry', width: 210, track_hover: true, can_focus: true, x_expand: true, x_align: Clutter.ActorAlign.END });
398+
this.toSearchEntry = new St.Entry({ name: 'menu-search-entry', width: 210*global.ui_scale, track_hover: true, can_focus: true, x_expand: true, x_align: Clutter.ActorAlign.END });
382399
this.toSearchEntry.get_clutter_text().connect( 'key-press-event', Lang.bind(this, this._onKeyPressEvent) );
383400
this.toSearchEntry.get_clutter_text().connect( 'key-release-event', (actor, event) => {this._onKeyReleaseEvent(actor, event, this.toLanguage); } );
384401
this._searchFromIcon = new St.Icon({ style_class: 'menu-search-entry-icon', icon_name: 'edit-find', icon_type: St.IconType.SYMBOLIC });
@@ -390,18 +407,18 @@ class TranslatorPopupItem extends PopupMenu.PopupMenuSection {
390407
this.languageBox.add_child(this.toSearchEntry);
391408

392409
// Setup the from/to text boxes
393-
this.fromTextBox = new St.Entry({name: 'menu-search-entry', hint_text: _("{Text to translate}"), width: 250, height: 180, style: 'margin-right:2px;'});
410+
this.fromTextBox = new St.Entry({name: 'menu-search-entry', hint_text: _("{Text to translate}"), width: /*250*/(width/2-45)*global.ui_scale, height: /*180*/(height-90)*global.ui_scale, style: 'margin-right:2px;'});
394411
let text = this.fromTextBox.get_clutter_text();
395412
text.set_line_wrap(true);
396413
text.set_single_line_mode(false);
397414
text.set_max_length(200);
398415
text.connect('text-changed', () => {this.enableTranslateIfPossible();});
399416
text.connect('activate', (actor, event) => {
400-
Util.spawnCommandLineAsyncIO( "trans -b -e " + this._applet.engine + " " + this.fromLanguage.code + ":" + this.toLanguage.code + " \"" + escapeQuotes(this.fromTextBox.get_text()) + "\"", Lang.bind(this, this.readTranslation) );
417+
Util.spawnCommandLineAsyncIO( "trans -no-bidi -b -e " + this._applet.engine + " " + this.fromLanguage.code + ":" + this.toLanguage.code + " \"" + escapeQuotes(this.fromTextBox.get_text()) + "\"", Lang.bind(this, this.readTranslation) );
401418
});
402419
this.textBox.add_child(this.fromTextBox);
403420

404-
this.toTextBox = new St.Entry({name: 'menu-search-entry', hint_text: _("{Translated text}"), width: 250, height: 180, style: 'margin-left:2px;'});
421+
this.toTextBox = new St.Entry({name: 'menu-search-entry', hint_text: _("{Translated text}"), width: /*250*/(width/2-45)*global.ui_scale, height: /*180*/(height-90)*global.ui_scale, style: 'margin-left:2px;'});
405422
text = this.toTextBox.get_clutter_text();
406423
text.set_line_wrap(true);
407424
text.set_single_line_mode(false);
@@ -433,7 +450,7 @@ class TranslatorPopupItem extends PopupMenu.PopupMenuSection {
433450
this.toTextBox.set_text("");
434451
});
435452
this.translate = new ControlButton("media-playback-start-symbolic", _("Translate"), () => {
436-
Util.spawnCommandLineAsyncIO( "trans -b -e " + this._applet.engine + " " + this.fromLanguage.code + ":" + this.toLanguage.code + " \"" + escapeQuotes(this.fromTextBox.get_text()) + "\"", Lang.bind(this, this.readTranslation) );
453+
Util.spawnCommandLineAsyncIO( "trans -no-bidi -b -e " + this._applet.engine + " " + this.fromLanguage.code + ":" + this.toLanguage.code + " \"" + escapeQuotes(this.fromTextBox.get_text()) + "\"", Lang.bind(this, this.readTranslation) );
437454
});
438455
this.translate.setEnabled(false);
439456
let toBtnBox = new St.BoxLayout({x_align: Clutter.ActorAlign.END, x_expand: true});
@@ -460,6 +477,44 @@ class TranslatorPopupItem extends PopupMenu.PopupMenuSection {
460477

461478
this.addActor(this.vertBox, {expand: true});
462479
this._applet._signalManager.connect(this._applet.settings, "changed::translate-engine", this._applet.getEngine, this._applet);
480+
this._applet._signalManager.connect(global, "scale-changed", this._onScaleChanged, this);
481+
}
482+
483+
onBoxResized(w,h) {
484+
w = Math.max(Math.trunc(w), 540);
485+
h = Math.max(Math.trunc(h), 160);
486+
this.fromTextBox.set_width((w/2-45)*global.ui_scale);
487+
this.fromTextBox.set_height((h-90)*global.ui_scale);
488+
489+
this.toTextBox.set_width((w/2-45)*global.ui_scale);
490+
this.toTextBox.set_height((h-90)*global.ui_scale);
491+
this._applet.settings.setValue("popup-width", w);
492+
this._applet.settings.setValue("popup-height", h);
493+
}
494+
495+
_onScaleChanged() {
496+
let monitor = this._applet.panel.monitor;
497+
let width = Math.min(monitor.width, this._applet.settings.getValue("popup-width"));
498+
let height = Math.min(monitor.height, this._applet.settings.getValue("popup-height"));
499+
this._applet.settings.setValue("popup-width", width);
500+
this._applet.settings.setValue("popup-height", height);
501+
502+
this.fromSearchEntry.set_width(210*global.ui_scale);
503+
this.toSearchEntry.set_width(210*global.ui_scale);
504+
this.fromTextBox.set_width((width/2-45)*global.ui_scale);
505+
this.fromTextBox.set_height((height-90)*global.ui_scale);
506+
this.toTextBox.set_width((width/2-45)*global.ui_scale);
507+
this.toTextBox.set_height((height-90)*global.ui_scale);
508+
509+
this.switchButton.updateDisabledIcon();
510+
this.config.updateDisabledIcon();
511+
this.help.updateDisabledIcon();
512+
this.playFrom.updateDisabledIcon();
513+
this.paste.updateDisabledIcon();
514+
this.clear.updateDisabledIcon();
515+
this.translate.updateDisabledIcon();
516+
this.copy.updateDisabledIcon();
517+
this.playTo.updateDisabledIcon();
463518
}
464519

465520
// Handles key press events for the from/to language search entry widgets
@@ -583,11 +638,11 @@ class TranslatorPopupItem extends PopupMenu.PopupMenuSection {
583638
this.fromTextBox.set_text(text.trim());
584639
if (translate) {
585640
if (play) {
586-
Util.spawnCommandLineAsyncIO( "trans -b -e " + this._applet.engine + " " + this.fromLanguage.code + ":" + this.toLanguage.code + " \"" + escapeQuotes(this.fromTextBox.get_text()) + "\"", Lang.bind(this, this.playTranslation) );
641+
Util.spawnCommandLineAsyncIO( "trans -no-bidi -b -e " + this._applet.engine + " " + this.fromLanguage.code + ":" + this.toLanguage.code + " \"" + escapeQuotes(this.fromTextBox.get_text()) + "\"", Lang.bind(this, this.playTranslation) );
587642
} else if (copy) {
588-
Util.spawnCommandLineAsyncIO( "trans -b -e " + this._applet.engine + " " + this.fromLanguage.code + ":" + this.toLanguage.code + " \"" + escapeQuotes(this.fromTextBox.get_text()) + "\"", Lang.bind(this, this.copyTranslation) );
643+
Util.spawnCommandLineAsyncIO( "trans -no-bidi -b -e " + this._applet.engine + " " + this.fromLanguage.code + ":" + this.toLanguage.code + " \"" + escapeQuotes(this.fromTextBox.get_text()) + "\"", Lang.bind(this, this.copyTranslation) );
589644
} else {
590-
Util.spawnCommandLineAsyncIO( "trans -b -e " + this._applet.engine + " " + this.fromLanguage.code + ":" + this.toLanguage.code + " \"" + escapeQuotes(this.fromTextBox.get_text()) + "\"", Lang.bind(this, this.readTranslation) );
645+
Util.spawnCommandLineAsyncIO( "trans -no-bidi -b -e " + this._applet.engine + " " + this.fromLanguage.code + ":" + this.toLanguage.code + " \"" + escapeQuotes(this.fromTextBox.get_text()) + "\"", Lang.bind(this, this.readTranslation) );
591646
}
592647
} else {
593648
this.toTextBox.set_text("");
@@ -615,31 +670,36 @@ class TranslatorPopupItem extends PopupMenu.PopupMenuSection {
615670
class ControlButton {
616671
constructor(icon, tooltip, callback) {
617672
this.actor = new St.Bin();
618-
619673
this.button = new St.Button({style_class: 'menu-favorites-button' /*'panel-translator-button' 'menu-favorites-button' 'keyboard-key'*/});
620674
this.button.connect('clicked', callback);
621-
675+
this.icon_name = icon;
622676
this.icon = new St.Icon({ icon_type: St.IconType.SYMBOLIC, icon_name: icon, icon_size: ICON_SIZE });
677+
this.updateDisabledIcon();
678+
this.button.set_child(this.icon);
679+
this.actor.add_actor(this.button);
680+
this.tooltip = new Tooltips.Tooltip(this.button, tooltip);
681+
}
623682

624-
let themeIcon = ICONTHEME.lookup_icon(icon, ICON_SIZE, 0);
683+
updateDisabledIcon() {
684+
let themeIcon = ICONTHEME.lookup_icon(this.icon_name, ICON_SIZE*global.ui_scale, 0);
625685
if (themeIcon) {
626-
let pixBuf = GdkPixbuf.Pixbuf.new_from_file_at_size(themeIcon.get_filename(), ICON_SIZE, ICON_SIZE);
686+
let pixBuf = GdkPixbuf.Pixbuf.new_from_file_at_size(themeIcon.get_filename(), ICON_SIZE*global.ui_scale, ICON_SIZE*global.ui_scale);
627687
if (pixBuf) {
628688
let image = new Clutter.Image();
629689
pixBuf.saturate_and_pixelate(pixBuf, 1, true);
630690
try {
631691
image.set_data(pixBuf.get_pixels(), pixBuf.get_has_alpha() ? Cogl.PixelFormat.RGBA_8888 : Cogl.PixelFormat.RGBA_888,
632-
ICON_SIZE, ICON_SIZE, pixBuf.get_rowstride() );
633-
this.disabledIcon = new Clutter.Actor({width: ICON_SIZE, height: ICON_SIZE, content: image});
692+
ICON_SIZE*global.ui_scale, ICON_SIZE*global.ui_scale, pixBuf.get_rowstride() );
693+
this.disabledIcon = new Clutter.Actor({width: ICON_SIZE*global.ui_scale, height: ICON_SIZE*global.ui_scale, content: image});
694+
if (this.enabledStatus === false) {
695+
// Since the disabledIcon has changed, we might need to reflect that change in the actual button
696+
this.setEnabled(false);
697+
}
634698
} catch(e) {
635699
// Can't set the image data, so just use the default!
636700
}
637701
}
638702
}
639-
this.button.set_child(this.icon);
640-
this.actor.add_actor(this.button);
641-
642-
this.tooltip = new Tooltips.Tooltip(this.button, tooltip);
643703
}
644704

645705
getActor() {
@@ -656,6 +716,7 @@ class ControlButton {
656716
}
657717

658718
setEnabled(status) {
719+
this.enabledStatus = status;
659720
this.button.change_style_pseudo_class("insensitive", !status);
660721
this.button.can_focus = status;
661722
this.button.reactive = status;

PanelTranslator@klangman/files/PanelTranslator@klangman/metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
"max-instances": -1,
66
"author": "klangman",
77
"hide-configuration": false,
8-
"version": "1.1.0"
8+
"version": "1.2.0"
99
}

0 commit comments

Comments
 (0)