Merge lp:~sdemchenko/glipper/feature-accelerators into lp:glipper

Proposed by Stanislav Demchenko
Status: Needs review
Proposed branch: lp:~sdemchenko/glipper/feature-accelerators
Merge into: lp:glipper
Diff against target: 165 lines (+95/-4)
4 files modified
glipper/AppIndicator.py (+26/-2)
glipper/__init__.py (+3/-0)
glipper/plugins/autopaste.py (+62/-0)
glipper/plugins/snippets.py (+4/-2)
To merge this branch: bzr merge lp:~sdemchenko/glipper/feature-accelerators
Reviewer Review Type Date Requested Status
Laszlo Pandy Pending
Review via email: mp+118856@code.launchpad.net

Description of the change

I have added accelerators to history items and to snippet menu and its items.
Also, a new plugin "Auto paste" can accelerate Glipper usage even further (it sends Control+V key stroke to the active window right after an item selection). Just like item accelerators, auto-pasting works both for history and snippets.

To post a comment you must log in.
Revision history for this message
Laszlo Pandy (laszlok) wrote :

> reserved_accelerators = "0acpu" # _0. Snippets, _About, _Clear, _Preferences, Pl_ugins

This won't work. For example, in the French translation, the accelorator for Pl_ugins is "_Greffons".

The only way I see to make it work across languages is to only use numbers for the accelorators.

Revision history for this message
Stanislav Demchenko (sdemchenko) wrote :

Hi Laszlo, thank you for the tip, I'll try to amend this ASAP.
And I have one more question, about plugin Auto Paste: in that plugin
I rely on a command "xte", which is in Ubuntu package "xautomation",
and I'm undecided if I shall
1) add a dependency on that package (to spare users from manual
installation), or
2) ask users to install xautomation themselves (as I do now in a
message box), because the plugin is optional and people may not want
to have extra dependencies.
I implemented the second option to be conservative, but honestly I
feel it just unnecessarily adds some headache to users, and I should
add a dependency on xautomation.
What is your preference?

On Wed, Aug 15, 2012 at 9:37 AM, Laszlo Pandy <email address hidden> wrote:
>> reserved_accelerators = "0acpu" # _0. Snippets, _About, _Clear, _Preferences, Pl_ugins
>
> This won't work. For example, in the French translation, the accelorator for Pl_ugins is "_Greffons".
>
> The only way I see to make it work across languages is to only use numbers for the accelorators.
> --
> https://code.launchpad.net/~sdemchenko/glipper/feature-accelerators/+merge/118856
> You are the owner of lp:~sdemchenko/glipper/feature-accelerators.

121. By Stanislav Demchenko

Replaced hard-coded accelerator characters with their respective internationalized counterparts provided by GTK.

Revision history for this message
Joseph Boiteau (josephboiteau) wrote :

so will that be merged?

I'm quite interested by the auto-paste feature myself, it should be an option to set via the Preferences

Unmerged revisions

121. By Stanislav Demchenko

Replaced hard-coded accelerator characters with their respective internationalized counterparts provided by GTK.

120. By Stanislav Demchenko

Added 'Auto paste' plugin to emulate Control+V on a history or snippet item selection.

119. By Stanislav Demchenko

Added a space between the accelerator and the label in menu item "Snippets" (for readability).

118. By Stanislav Demchenko

Restored spaces as in trunk to simplify review.
Added 1 extra space between the accelerator character and menu item label to improve readability.

117. By Stanislav Demchenko

Added accelerators for menu items in history and in snippets.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'glipper/AppIndicator.py'
2--- glipper/AppIndicator.py 2012-08-11 22:07:48 +0000
3+++ glipper/AppIndicator.py 2012-08-15 20:12:23 +0000
4@@ -7,6 +7,7 @@
5 from glipper.Keybinder import *
6 from glipper.History import *
7 from glipper.PluginsManager import *
8+import string
9
10 class StatusIcon:
11 def __init__(self):
12@@ -76,7 +77,7 @@
13 menu_item.set_sensitive(False)
14 self.menu.append(menu_item)
15 else:
16- for item in history:
17+ for i, item in enumerate(history):
18 menu_item = gtk.CheckMenuItem(format_item(item), False)
19 menu_item.set_property('draw-as-radio', True)
20
21@@ -91,6 +92,7 @@
22
23 menu_item.connect('activate', self.on_menu_item_activate, item)
24 self.menu.append(menu_item)
25+ add_accelerator(i, menu_item)
26
27 self.menu.append(gtk.SeparatorMenuItem())
28
29@@ -186,5 +188,27 @@
30 i = item.replace("\n", " ")
31 i = i.replace("\t", " ")
32 if len(item) > max_item_length:
33- return i[0:max_item_length/2] + u'\u2026' + i[-(max_item_length/2-3):]
34+ return i[0:max_item_length/2] + u'\u2026' + i[-(max_item_length/2-3):]
35 return i
36+
37+def _get_reserved_accelerators():
38+ labels = [_("Pl_ugins"), "_0. " + _("Snippets")]
39+ for menu_item in [gtk.ImageMenuItem(gtk.STOCK_ABOUT),
40+ gtk.ImageMenuItem(gtk.STOCK_HELP),
41+ gtk.ImageMenuItem(gtk.STOCK_PREFERENCES),
42+ gtk.ImageMenuItem(gtk.STOCK_CLEAR)]:
43+ labels.append(menu_item.get_children()[0].get_label())
44+ menu_item.destroy()
45+ accelerators_in_use = set()
46+ for label in labels:
47+ for i, char in enumerate(label):
48+ if char == '_' and i + 1 < len(label):
49+ accelerators_in_use.add(label[i + 1].lower())
50+ return ''.join(accelerators_in_use)
51+
52+def add_accelerator(pos, menu_item):
53+ available_accelerators = (string.digits + string.lowercase).translate(None, _get_reserved_accelerators())
54+ if pos < len(available_accelerators):
55+ label_with_escaped_underscore = menu_item.get_label().replace('_', '__')
56+ menu_item.set_label('_' + available_accelerators[pos] + '. ' + label_with_escaped_underscore)
57+ menu_item.set_use_underline(True)
58
59=== modified file 'glipper/__init__.py'
60--- glipper/__init__.py 2011-04-08 23:06:47 +0000
61+++ glipper/__init__.py 2012-08-15 20:12:23 +0000
62@@ -125,3 +125,6 @@
63
64 def format_item(item):
65 return glipper.AppIndicator.format_item(item)
66+
67+def add_accelerator(order_in_menu, menu_item):
68+ return glipper.AppIndicator.add_accelerator(order_in_menu, menu_item)
69
70=== added file 'glipper/plugins/autopaste.py'
71--- glipper/plugins/autopaste.py 1970-01-01 00:00:00 +0000
72+++ glipper/plugins/autopaste.py 2012-08-15 20:12:23 +0000
73@@ -0,0 +1,62 @@
74+from gettext import gettext as _
75+import os
76+import subprocess
77+import gtk
78+from glipper.AppIndicator import AppIndicator
79+
80+snippets = __import__("snippets")
81+history_original_on_menu_item_activate = AppIndicator.on_menu_item_activate
82+snippet_original_on_menu_item_activate = snippets.on_activate
83+
84+def info():
85+ info = {"Name": _("Auto paste"),
86+ "Description": _("Pastes the selected item into the active window (emulates a '^+V' key press)."),
87+ "Preferences": False}
88+ return info
89+
90+def init():
91+ if not is_xte_installed():
92+ return
93+ enhance_history_on_activate_behavior()
94+ enhance_snippet_on_activate_behavior()
95+
96+def stop():
97+ AppIndicator.on_menu_item_activate = history_original_on_menu_item_activate
98+ snippets.on_activate = snippet_original_on_menu_item_activate
99+
100+def enhance_history_on_activate_behavior():
101+ def on_menu_item_activate_enhanced(self, menu_item, item):
102+ history_original_on_menu_item_activate(self, menu_item, item)
103+ paste()
104+ AppIndicator.on_menu_item_activate = on_menu_item_activate_enhanced
105+
106+
107+def enhance_snippet_on_activate_behavior():
108+ def on_menu_item_activate_enhanced(menu_item, snippet):
109+ snippet_original_on_menu_item_activate(menu_item, snippet)
110+ paste()
111+ snippets.on_activate = on_menu_item_activate_enhanced
112+
113+def paste():
114+ subprocess.call(["xte", "keydown Control_L", "key V", "keyup Control_L"])
115+
116+def is_xte_installed():
117+ devnull = open(os.devnull, 'w')
118+ try:
119+ subprocess.call(["xte", "-h"], stdout=devnull)
120+ except OSError:
121+ devnull.close()
122+ md = gtk.MessageDialog(
123+ None,
124+ gtk.DIALOG_DESTROY_WITH_PARENT,
125+ gtk.MESSAGE_ERROR,
126+ gtk.BUTTONS_CLOSE,
127+ _("Plugin 'Auto paste' for Glipper uses command 'xte' from package 'xautomation'.\n"
128+ "To use the plugin, please install the package, e.g. run:\n"
129+ "'sudo apt-get install xautomation'.\n"
130+ "Then disable and re-enable the plugin to activate it."))
131+ md.run()
132+ md.destroy()
133+ return False
134+ else:
135+ return True
136\ No newline at end of file
137
138=== modified file 'glipper/plugins/snippets.py'
139--- glipper/plugins/snippets.py 2011-04-09 08:17:59 +0000
140+++ glipper/plugins/snippets.py 2012-08-15 20:12:23 +0000
141@@ -107,7 +107,8 @@
142 load_snippets()
143 Manager(parent)
144
145-menu_item = gtk.MenuItem(_("Snippets"))
146+menu_item = gtk.MenuItem("_0. " + _("Snippets"))
147+menu_item.set_use_underline(True)
148 menu = gtk.Menu()
149
150 def init():
151@@ -128,12 +129,13 @@
152 if len(snippets) == 0:
153 menu.append(gtk.MenuItem(_("No snippets available")))
154 else:
155- for snippet in snippets:
156+ for i, snippet in enumerate(snippets):
157 item = gtk.MenuItem(glipper.format_item(snippet))
158 if len(snippet) > max_length:
159 item.set_tooltip_text(snippet)
160 item.connect('activate', on_activate, snippet)
161 menu.append(item)
162+ glipper.add_accelerator(i, item)
163
164 menu.show_all()
165 menu_item.set_submenu(menu)

Subscribers

People subscribed via source and target branches