Merge lp:~jordy-provost/terminator/custom_commands_submenus into lp:terminator/gtk3
- custom_commands_submenus
- Merge into gtk3
Status: | Needs review |
---|---|
Proposed branch: | lp:~jordy-provost/terminator/custom_commands_submenus |
Merge into: | lp:terminator/gtk3 |
Diff against target: |
896 lines (+436/-394) 1 file modified
terminatorlib/plugins/custom_commands.py (+436/-394) |
To merge this branch: | bzr merge lp:~jordy-provost/terminator/custom_commands_submenus |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alexander van Teijlingen (community) | Approve | ||
Jordy PROVOST (community) | Approve | ||
Terminator | Pending | ||
Review via email: mp+351362@code.launchpad.net |
Commit message
- Permit to create submenus in a more graphical way (instead of using '/' in command names)
- Fixes for indentation coherence (first level is 4 spaces, second is 8, third is 12, etc...)
- Clean some trailing spaces, and spaces only lines
Description of the change
Alexander van Teijlingen (a.vant) wrote : | # |
Also tested on Debian [9] Stretch and working
x86_64 & python2
Good feature imo
Bryce Harrington (bryce) wrote : | # |
Unfortunately the whitespace changes make it hard to spot the actual code changes, but conceptually this sounds interesting.
Jordy PROVOST (jordy-provost) wrote : | # |
Ok, since the review is still pending, i suppose that the merge will not be accepted ?
Unfortunately, i will be forced to maintain a confidential/
Unmerged revisions
- 1804. By Jordy PROVOST
-
Add graphical way to create submenus and fixes for identation coherence (4spaces)
Preview Diff
1 | === modified file 'terminatorlib/plugins/custom_commands.py' |
2 | --- terminatorlib/plugins/custom_commands.py 2017-02-06 11:09:36 +0000 |
3 | +++ terminatorlib/plugins/custom_commands.py 2018-07-26 15:00:50 +0000 |
4 | @@ -7,7 +7,7 @@ |
5 | |
6 | # Fix imports when testing this file directly |
7 | if __name__ == '__main__': |
8 | - sys.path.append( os.path.join(os.path.dirname(__file__), "../..")) |
9 | + sys.path.append( os.path.join(os.path.dirname(__file__), "../..")) |
10 | |
11 | from gi.repository import Gtk |
12 | from gi.repository import GObject |
13 | @@ -16,7 +16,7 @@ |
14 | from terminatorlib.translation import _ |
15 | from terminatorlib.util import get_config_dir, err, dbg, gerr |
16 | |
17 | -(CC_COL_ENABLED, CC_COL_NAME, CC_COL_COMMAND) = range(0,3) |
18 | +(CC_COL_ENABLED, CC_COL_NAME, CC_COL_COMMAND, CC_COL_CUSTOMSUBMENU) = range(0,4) |
19 | |
20 | # Every plugin you want Terminator to load *must* be listed in 'AVAILABLE' |
21 | AVAILABLE = ['CustomCommandsMenu'] |
22 | @@ -28,217 +28,233 @@ |
23 | conf_file = os.path.join(get_config_dir(),"custom_commands") |
24 | |
25 | def __init__( self): |
26 | - config = Config() |
27 | - sections = config.plugin_get_config(self.__class__.__name__) |
28 | - if not isinstance(sections, dict): |
29 | - return |
30 | - noord_cmds = [] |
31 | - for part in sections: |
32 | - s = sections[part] |
33 | - if not (s.has_key("name") and s.has_key("command")): |
34 | - print "CustomCommandsMenu: Ignoring section %s" % s |
35 | - continue |
36 | - name = s["name"] |
37 | - command = s["command"] |
38 | - enabled = s["enabled"] and s["enabled"] or False |
39 | - if s.has_key("position"): |
40 | - self.cmd_list[int(s["position"])] = {'enabled' : enabled, |
41 | - 'name' : name, |
42 | - 'command' : command |
43 | - } |
44 | - else: |
45 | - noord_cmds.append( |
46 | - {'enabled' : enabled, |
47 | + config = Config() |
48 | + sections = config.plugin_get_config(self.__class__.__name__) |
49 | + if not isinstance(sections, dict): |
50 | + return |
51 | + noord_cmds = [] |
52 | + for part in sections: |
53 | + s = sections[part] |
54 | + if not (s.has_key("name") and s.has_key("command")): |
55 | + print "CustomCommandsMenu: Ignoring section %s" % s |
56 | + continue |
57 | + name = s["name"] |
58 | + command = s["command"] |
59 | + enabled = s["enabled"] and s["enabled"] or False |
60 | + try: |
61 | + customsubmenu = s["submenu"] |
62 | + except: |
63 | + customsubmenu = '' |
64 | + if s.has_key("position"): |
65 | + self.cmd_list[int(s["position"])] = {'enabled' : enabled, |
66 | 'name' : name, |
67 | - 'command' : command |
68 | - } |
69 | - ) |
70 | + 'command' : command, |
71 | + 'submenu' : customsubmenu |
72 | + } |
73 | + else: |
74 | + noord_cmds.append( |
75 | + {'enabled' : enabled, |
76 | + 'name' : name, |
77 | + 'command' : command, |
78 | + 'submenu' : customsubmenu |
79 | + } |
80 | + ) |
81 | + |
82 | for cmd in noord_cmds: |
83 | self.cmd_list[len(self.cmd_list)] = cmd |
84 | |
85 | + |
86 | def callback(self, menuitems, menu, terminal): |
87 | """Add our menu items to the menu""" |
88 | - submenus = {} |
89 | item = Gtk.MenuItem.new_with_mnemonic(_('_Custom Commands')) |
90 | menuitems.append(item) |
91 | - |
92 | - submenu = Gtk.Menu() |
93 | - item.set_submenu(submenu) |
94 | - |
95 | + pluginsubmenu = Gtk.Menu() |
96 | + item.set_submenu(pluginsubmenu) |
97 | menuitem = Gtk.MenuItem.new_with_mnemonic(_('_Preferences')) |
98 | menuitem.connect("activate", self.configure) |
99 | - submenu.append(menuitem) |
100 | - |
101 | + pluginsubmenu.append(menuitem) |
102 | menuitem = Gtk.SeparatorMenuItem() |
103 | - submenu.append(menuitem) |
104 | + pluginsubmenu.append(menuitem) |
105 | + try: |
106 | + customsubmenus = sorted(set(self.cmd_list[key]['submenu'] for key in sorted(self.cmd_list.keys()))) |
107 | + except: |
108 | + customsubmenus = [] |
109 | + |
110 | + submenus_dict = {} |
111 | + for customsubmenustr in customsubmenus: |
112 | + if customsubmenustr != '': |
113 | + menuitem = Gtk.MenuItem(_(customsubmenustr)) |
114 | + pluginsubmenu.append(menuitem) |
115 | + customsubmenu = Gtk.Menu() |
116 | + menuitem.set_submenu(customsubmenu) |
117 | + submenus_dict[customsubmenustr] = customsubmenu |
118 | |
119 | theme = Gtk.IconTheme.get_default() |
120 | + |
121 | for command in [ self.cmd_list[key] for key in sorted(self.cmd_list.keys()) ] : |
122 | - if not command['enabled']: |
123 | - continue |
124 | - exe = command['command'].split(' ')[0] |
125 | - iconinfo = theme.choose_icon([exe], Gtk.IconSize.MENU, Gtk.IconLookupFlags.USE_BUILTIN) |
126 | - leaf_name = command['name'].split('/')[-1] |
127 | - branch_names = command['name'].split('/')[:-1] |
128 | - target_submenu = submenu |
129 | - parent_submenu = submenu |
130 | - for idx in range(len(branch_names)): |
131 | - lookup_name = '/'.join(branch_names[0:idx+1]) |
132 | - target_submenu = submenus.get(lookup_name, None) |
133 | - if not target_submenu: |
134 | - item = Gtk.MenuItem(_(branch_names[idx])) |
135 | - parent_submenu.append(item) |
136 | - target_submenu = Gtk.Menu() |
137 | - item.set_submenu(target_submenu) |
138 | - submenus[lookup_name] = target_submenu |
139 | - parent_submenu = target_submenu |
140 | - if iconinfo: |
141 | - image = Gtk.Image() |
142 | - image.set_from_icon_name(exe, Gtk.IconSize.MENU) |
143 | - menuitem = Gtk.ImageMenuItem(leaf_name) |
144 | - menuitem.set_image(image) |
145 | - else: |
146 | - menuitem = Gtk.MenuItem(leaf_name) |
147 | - terminals = terminal.terminator.get_target_terms(terminal) |
148 | - menuitem.connect("activate", self._execute, {'terminals' : terminals, 'command' : command['command'] }) |
149 | - target_submenu.append(menuitem) |
150 | - |
151 | + if not command['enabled']: |
152 | + continue |
153 | + exe = command['command'].split(' ')[0] |
154 | + iconinfo = theme.choose_icon([exe], Gtk.IconSize.MENU, Gtk.IconLookupFlags.USE_BUILTIN) |
155 | + if iconinfo: |
156 | + image = Gtk.Image() |
157 | + image.set_from_icon_name(exe, Gtk.IconSize.MENU) |
158 | + menuitem = Gtk.ImageMenuItem(command['name']) |
159 | + menuitem.set_image(image) |
160 | + else: |
161 | + menuitem = Gtk.MenuItem(command["name"]) |
162 | + terminals = terminal.terminator.get_target_terms(terminal) |
163 | + menuitem.connect("activate", self._execute, {'terminals' : terminals, 'command' : command['command'] }) |
164 | + if command['submenu'] and command['submenu'] != '': |
165 | + customsubmenustr = command['submenu'] |
166 | + customsubmenu = submenus_dict[customsubmenustr] |
167 | + customsubmenu.append(menuitem) |
168 | + else: |
169 | + pluginsubmenu.append(menuitem) |
170 | + |
171 | + |
172 | def _save_config(self): |
173 | - config = Config() |
174 | - config.plugin_del_config(self.__class__.__name__) |
175 | - i = 0 |
176 | - for command in [ self.cmd_list[key] for key in sorted(self.cmd_list.keys()) ] : |
177 | - enabled = command['enabled'] |
178 | - name = command['name'] |
179 | - command = command['command'] |
180 | - |
181 | - item = {} |
182 | - item['enabled'] = enabled |
183 | - item['name'] = name |
184 | - item['command'] = command |
185 | - item['position'] = i |
186 | - |
187 | - config.plugin_set(self.__class__.__name__, name, item) |
188 | - i = i + 1 |
189 | - config.save() |
190 | + config = Config() |
191 | + config.plugin_del_config(self.__class__.__name__) |
192 | + i = 0 |
193 | + for command in [ self.cmd_list[key] for key in sorted(self.cmd_list.keys()) ] : |
194 | + enabled = command['enabled'] |
195 | + name = command['name'] |
196 | + try: |
197 | + submenu = command['submenu'] |
198 | + except: |
199 | + submenu = '' |
200 | + command = command['command'] |
201 | + |
202 | + item = {} |
203 | + item['enabled'] = enabled |
204 | + item['name'] = name |
205 | + item['command'] = command |
206 | + item['position'] = i |
207 | + item['submenu'] = submenu |
208 | + |
209 | + config.plugin_set(self.__class__.__name__, name, item) |
210 | + i = i + 1 |
211 | + config.save() |
212 | |
213 | def _execute(self, widget, data): |
214 | - command = data['command'] |
215 | - if command[-1] != '\n': |
216 | - command = command + '\n' |
217 | - for terminal in data['terminals']: |
218 | - terminal.vte.feed_child(command, len(command)) |
219 | + command = data['command'] |
220 | + if command[-1] != '\n': |
221 | + command = command + '\n' |
222 | + for terminal in data['terminals']: |
223 | + terminal.vte.feed_child(command, len(command)) |
224 | |
225 | def configure(self, widget, data = None): |
226 | - ui = {} |
227 | - dbox = Gtk.Dialog( |
228 | - _("Custom Commands Configuration"), |
229 | - None, |
230 | - Gtk.DialogFlags.MODAL, |
231 | - ( |
232 | - _("_Cancel"), Gtk.ResponseType.REJECT, |
233 | - _("_OK"), Gtk.ResponseType.ACCEPT |
234 | - ) |
235 | - ) |
236 | - dbox.set_transient_for(widget.get_toplevel()) |
237 | - |
238 | - icon_theme = Gtk.IconTheme.get_default() |
239 | - if icon_theme.lookup_icon('terminator-custom-commands', 48, 0): |
240 | - dbox.set_icon_name('terminator-custom-commands') |
241 | - else: |
242 | - dbg('Unable to load Terminator custom command icon') |
243 | - icon = dbox.render_icon(Gtk.STOCK_DIALOG_INFO, Gtk.IconSize.BUTTON) |
244 | - dbox.set_icon(icon) |
245 | - |
246 | - store = Gtk.ListStore(bool, str, str) |
247 | - |
248 | - for command in [ self.cmd_list[key] for key in sorted(self.cmd_list.keys()) ]: |
249 | - store.append([command['enabled'], command['name'], command['command']]) |
250 | - |
251 | - treeview = Gtk.TreeView(store) |
252 | - #treeview.connect("cursor-changed", self.on_cursor_changed, ui) |
253 | - selection = treeview.get_selection() |
254 | - selection.set_mode(Gtk.SelectionMode.SINGLE) |
255 | - selection.connect("changed", self.on_selection_changed, ui) |
256 | - ui['treeview'] = treeview |
257 | - |
258 | - renderer = Gtk.CellRendererToggle() |
259 | - renderer.connect('toggled', self.on_toggled, ui) |
260 | - column = Gtk.TreeViewColumn(_("Enabled"), renderer, active=CC_COL_ENABLED) |
261 | - treeview.append_column(column) |
262 | - |
263 | - renderer = Gtk.CellRendererText() |
264 | - column = Gtk.TreeViewColumn(_("Name"), renderer, text=CC_COL_NAME) |
265 | - treeview.append_column(column) |
266 | - |
267 | - renderer = Gtk.CellRendererText() |
268 | - column = Gtk.TreeViewColumn(_("Command"), renderer, text=CC_COL_COMMAND) |
269 | - treeview.append_column(column) |
270 | - |
271 | - scroll_window = Gtk.ScrolledWindow() |
272 | - scroll_window.set_size_request(500, 250) |
273 | - scroll_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) |
274 | - scroll_window.add_with_viewport(treeview) |
275 | - |
276 | - hbox = Gtk.HBox() |
277 | - hbox.pack_start(scroll_window, True, True, 0) |
278 | - dbox.vbox.pack_start(hbox, True, True, 0) |
279 | - |
280 | - button_box = Gtk.VBox() |
281 | - |
282 | - button = Gtk.Button(_("Top")) |
283 | - button_box.pack_start(button, False, True, 0) |
284 | - button.connect("clicked", self.on_goto_top, ui) |
285 | - button.set_sensitive(False) |
286 | - ui['button_top'] = button |
287 | - |
288 | - button = Gtk.Button(_("Up")) |
289 | - button_box.pack_start(button, False, True, 0) |
290 | - button.connect("clicked", self.on_go_up, ui) |
291 | - button.set_sensitive(False) |
292 | - ui['button_up'] = button |
293 | - |
294 | - button = Gtk.Button(_("Down")) |
295 | - button_box.pack_start(button, False, True, 0) |
296 | - button.connect("clicked", self.on_go_down, ui) |
297 | - button.set_sensitive(False) |
298 | - ui['button_down'] = button |
299 | - |
300 | - button = Gtk.Button(_("Last")) |
301 | - button_box.pack_start(button, False, True, 0) |
302 | - button.connect("clicked", self.on_goto_last, ui) |
303 | - button.set_sensitive(False) |
304 | - ui['button_last'] = button |
305 | - |
306 | - button = Gtk.Button(_("New")) |
307 | - button_box.pack_start(button, False, True, 0) |
308 | - button.connect("clicked", self.on_new, ui) |
309 | - ui['button_new'] = button |
310 | - |
311 | - button = Gtk.Button(_("Edit")) |
312 | - button_box.pack_start(button, False, True, 0) |
313 | - button.set_sensitive(False) |
314 | - button.connect("clicked", self.on_edit, ui) |
315 | - ui['button_edit'] = button |
316 | - |
317 | - button = Gtk.Button(_("Delete")) |
318 | - button_box.pack_start(button, False, True, 0) |
319 | - button.connect("clicked", self.on_delete, ui) |
320 | - button.set_sensitive(False) |
321 | - ui['button_delete'] = button |
322 | - |
323 | - |
324 | - |
325 | - hbox.pack_start(button_box, False, True, 0) |
326 | - self.dbox = dbox |
327 | - dbox.show_all() |
328 | - res = dbox.run() |
329 | - if res == Gtk.ResponseType.ACCEPT: |
330 | - self.update_cmd_list(store) |
331 | - self._save_config() |
332 | - del(self.dbox) |
333 | - dbox.destroy() |
334 | - return |
335 | + ui = {} |
336 | + dbox = Gtk.Dialog( |
337 | + _("Custom Commands Configuration"), |
338 | + None, |
339 | + Gtk.DialogFlags.MODAL, |
340 | + ( |
341 | + _("_Cancel"), Gtk.ResponseType.REJECT, |
342 | + _("_OK"), Gtk.ResponseType.ACCEPT |
343 | + ) |
344 | + ) |
345 | + dbox.set_transient_for(widget.get_toplevel()) |
346 | + |
347 | + icon_theme = Gtk.IconTheme.get_default() |
348 | + if icon_theme.lookup_icon('terminator-custom-commands', 48, 0): |
349 | + dbox.set_icon_name('terminator-custom-commands') |
350 | + else: |
351 | + dbg('Unable to load Terminator custom command icon') |
352 | + icon = dbox.render_icon(Gtk.STOCK_DIALOG_INFO, Gtk.IconSize.BUTTON) |
353 | + dbox.set_icon(icon) |
354 | + |
355 | + store = Gtk.ListStore(bool, str, str, str) |
356 | + |
357 | + for command in [ self.cmd_list[key] for key in sorted(self.cmd_list.keys()) ]: |
358 | + store.append([command['enabled'], command['name'], command['command'], command['submenu']]) |
359 | + treeview = Gtk.TreeView(store) |
360 | + |
361 | + selection = treeview.get_selection() |
362 | + selection.set_mode(Gtk.SelectionMode.SINGLE) |
363 | + selection.connect("changed", self.on_selection_changed, ui) |
364 | + ui['treeview'] = treeview |
365 | + |
366 | + renderer = Gtk.CellRendererToggle() |
367 | + renderer.connect('toggled', self.on_toggled, ui) |
368 | + column = Gtk.TreeViewColumn(_("Enabled"), renderer, active=CC_COL_ENABLED) |
369 | + treeview.append_column(column) |
370 | + |
371 | + renderer = Gtk.CellRendererText() |
372 | + column = Gtk.TreeViewColumn(_("Name"), renderer, text=CC_COL_NAME) |
373 | + treeview.append_column(column) |
374 | + |
375 | + renderer = Gtk.CellRendererText() |
376 | + column = Gtk.TreeViewColumn(_("Submenu"), renderer, text=CC_COL_CUSTOMSUBMENU) |
377 | + treeview.append_column(column) |
378 | + |
379 | + renderer = Gtk.CellRendererText() |
380 | + column = Gtk.TreeViewColumn(_("Command"), renderer, text=CC_COL_COMMAND) |
381 | + treeview.append_column(column) |
382 | + |
383 | + scroll_window = Gtk.ScrolledWindow() |
384 | + scroll_window.set_size_request(500, 250) |
385 | + scroll_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) |
386 | + scroll_window.add_with_viewport(treeview) |
387 | + |
388 | + hbox = Gtk.HBox() |
389 | + hbox.pack_start(scroll_window, True, True, 0) |
390 | + dbox.vbox.pack_start(hbox, True, True, 0) |
391 | + |
392 | + button_box = Gtk.VBox() |
393 | + |
394 | + button = Gtk.Button(_("Top")) |
395 | + button_box.pack_start(button, False, True, 0) |
396 | + button.connect("clicked", self.on_goto_top, ui) |
397 | + button.set_sensitive(False) |
398 | + ui['button_top'] = button |
399 | + |
400 | + button = Gtk.Button(_("Up")) |
401 | + button_box.pack_start(button, False, True, 0) |
402 | + button.connect("clicked", self.on_go_up, ui) |
403 | + button.set_sensitive(False) |
404 | + ui['button_up'] = button |
405 | + |
406 | + button = Gtk.Button(_("Down")) |
407 | + button_box.pack_start(button, False, True, 0) |
408 | + button.connect("clicked", self.on_go_down, ui) |
409 | + button.set_sensitive(False) |
410 | + ui['button_down'] = button |
411 | + |
412 | + button = Gtk.Button(_("Last")) |
413 | + button_box.pack_start(button, False, True, 0) |
414 | + button.connect("clicked", self.on_goto_last, ui) |
415 | + button.set_sensitive(False) |
416 | + ui['button_last'] = button |
417 | + |
418 | + button = Gtk.Button(_("New")) |
419 | + button_box.pack_start(button, False, True, 0) |
420 | + button.connect("clicked", self.on_new, ui) |
421 | + ui['button_new'] = button |
422 | + |
423 | + button = Gtk.Button(_("Edit")) |
424 | + button_box.pack_start(button, False, True, 0) |
425 | + button.set_sensitive(False) |
426 | + button.connect("clicked", self.on_edit, ui) |
427 | + ui['button_edit'] = button |
428 | + |
429 | + button = Gtk.Button(_("Delete")) |
430 | + button_box.pack_start(button, False, True, 0) |
431 | + button.connect("clicked", self.on_delete, ui) |
432 | + button.set_sensitive(False) |
433 | + ui['button_delete'] = button |
434 | + |
435 | + hbox.pack_start(button_box, False, True, 0) |
436 | + self.dbox = dbox |
437 | + dbox.show_all() |
438 | + res = dbox.run() |
439 | + if res == Gtk.ResponseType.ACCEPT: |
440 | + self.update_cmd_list(store) |
441 | + self._save_config() |
442 | + del(self.dbox) |
443 | + dbox.destroy() |
444 | + return |
445 | |
446 | |
447 | def update_cmd_list(self, store): |
448 | @@ -246,223 +262,249 @@ |
449 | self.cmd_list = {} |
450 | i=0 |
451 | while iter: |
452 | - (enabled, name, command) = store.get(iter, |
453 | - CC_COL_ENABLED, |
454 | - CC_COL_NAME, |
455 | - CC_COL_COMMAND) |
456 | - self.cmd_list[i] = {'enabled' : enabled, |
457 | - 'name': name, |
458 | - 'command' : command} |
459 | - iter = store.iter_next(iter) |
460 | - i = i + 1 |
461 | - |
462 | + (enabled, name, command, submenu) = store.get(iter, |
463 | + CC_COL_ENABLED, |
464 | + CC_COL_NAME, |
465 | + CC_COL_COMMAND, |
466 | + CC_COL_CUSTOMSUBMENU) |
467 | + self.cmd_list[i] = {'enabled' : enabled, |
468 | + 'name': name, |
469 | + 'command' : command, |
470 | + 'submenu' : submenu} |
471 | + iter = store.iter_next(iter) |
472 | + i = i + 1 |
473 | + |
474 | |
475 | def on_toggled(self, widget, path, data): |
476 | - treeview = data['treeview'] |
477 | - store = treeview.get_model() |
478 | - iter = store.get_iter(path) |
479 | - (enabled, name, command) = store.get(iter, |
480 | - CC_COL_ENABLED, |
481 | - CC_COL_NAME, |
482 | - CC_COL_COMMAND |
483 | - ) |
484 | - store.set_value(iter, CC_COL_ENABLED, not enabled) |
485 | + treeview = data['treeview'] |
486 | + store = treeview.get_model() |
487 | + iter = store.get_iter(path) |
488 | + (enabled, name, command, submenu) = store.get(iter, |
489 | + CC_COL_ENABLED, |
490 | + CC_COL_NAME, |
491 | + CC_COL_COMMAND, |
492 | + CC_COL_CUSTOMSUBMENU) |
493 | + store.set_value(iter, CC_COL_ENABLED, not enabled) |
494 | |
495 | |
496 | def on_selection_changed(self,selection, data=None): |
497 | - treeview = selection.get_tree_view() |
498 | - (model, iter) = selection.get_selected() |
499 | - data['button_top'].set_sensitive(iter is not None) |
500 | - data['button_up'].set_sensitive(iter is not None) |
501 | - data['button_down'].set_sensitive(iter is not None) |
502 | - data['button_last'].set_sensitive(iter is not None) |
503 | - data['button_edit'].set_sensitive(iter is not None) |
504 | - data['button_delete'].set_sensitive(iter is not None) |
505 | - |
506 | - def _create_command_dialog(self, enabled_var = False, name_var = "", command_var = ""): |
507 | - dialog = Gtk.Dialog( |
508 | - _("New Command"), |
509 | - None, |
510 | - Gtk.DialogFlags.MODAL, |
511 | - ( |
512 | - _("_Cancel"), Gtk.ResponseType.REJECT, |
513 | - _("_OK"), Gtk.ResponseType.ACCEPT |
514 | - ) |
515 | - ) |
516 | - dialog.set_transient_for(self.dbox) |
517 | - table = Gtk.Table(3, 2) |
518 | - |
519 | - label = Gtk.Label(label=_("Enabled:")) |
520 | - table.attach(label, 0, 1, 0, 1) |
521 | - enabled = Gtk.CheckButton() |
522 | - enabled.set_active(enabled_var) |
523 | - table.attach(enabled, 1, 2, 0, 1) |
524 | - |
525 | - label = Gtk.Label(label=_("Name:")) |
526 | - table.attach(label, 0, 1, 1, 2) |
527 | - name = Gtk.Entry() |
528 | - name.set_text(name_var) |
529 | - table.attach(name, 1, 2, 1, 2) |
530 | - |
531 | - label = Gtk.Label(label=_("Command:")) |
532 | - table.attach(label, 0, 1, 2, 3) |
533 | - command = Gtk.Entry() |
534 | - command.set_text(command_var) |
535 | - table.attach(command, 1, 2, 2, 3) |
536 | - |
537 | - dialog.vbox.pack_start(table, True, True, 0) |
538 | - dialog.show_all() |
539 | - return (dialog,enabled,name,command) |
540 | + treeview = selection.get_tree_view() |
541 | + (model, iter) = selection.get_selected() |
542 | + data['button_top'].set_sensitive(iter is not None) |
543 | + data['button_up'].set_sensitive(iter is not None) |
544 | + data['button_down'].set_sensitive(iter is not None) |
545 | + data['button_last'].set_sensitive(iter is not None) |
546 | + data['button_edit'].set_sensitive(iter is not None) |
547 | + data['button_delete'].set_sensitive(iter is not None) |
548 | + |
549 | + def _create_command_dialog(self, enabled_var = False, name_var = "", command_var = "", submenu_var = ""): |
550 | + dialog = Gtk.Dialog( |
551 | + _("New Command"), |
552 | + None, |
553 | + Gtk.DialogFlags.MODAL, |
554 | + ( |
555 | + Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT, |
556 | + Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT |
557 | + ) |
558 | + ) |
559 | + dialog.set_transient_for(self.dbox) |
560 | + table = Gtk.Table(3, 2) |
561 | + |
562 | + label = Gtk.Label(label=_("Enabled:")) |
563 | + table.attach(label, 0, 1, 0, 1) |
564 | + enabled = Gtk.CheckButton() |
565 | + enabled.set_active(enabled_var) |
566 | + table.attach(enabled, 1, 2, 0, 1) |
567 | + |
568 | + label = Gtk.Label(label=_("Name:")) |
569 | + table.attach(label, 0, 1, 1, 2) |
570 | + name = Gtk.Entry() |
571 | + name.set_text(name_var) |
572 | + table.attach(name, 1, 2, 1, 2) |
573 | + |
574 | + label = Gtk.Label(label=_("Submenu:")) |
575 | + table.attach(label, 0, 1, 2, 3) |
576 | + submenu = Gtk.Entry() |
577 | + submenu.set_text(submenu_var) |
578 | + table.attach(submenu, 1, 2, 2, 3) |
579 | + |
580 | + label = Gtk.Label(label=_("Command:")) |
581 | + table.attach(label, 0, 1, 3, 4) |
582 | + command = Gtk.Entry() |
583 | + command.set_text(command_var) |
584 | + table.attach(command, 1, 2, 3, 4) |
585 | + |
586 | + dialog.vbox.pack_start(table, True, True, 0) |
587 | + dialog.show_all() |
588 | + return (dialog,enabled,name,command,submenu) |
589 | |
590 | def on_new(self, button, data): |
591 | - (dialog,enabled,name,command) = self._create_command_dialog() |
592 | - res = dialog.run() |
593 | - item = {} |
594 | - if res == Gtk.ResponseType.ACCEPT: |
595 | - item['enabled'] = enabled.get_active() |
596 | - item['name'] = name.get_text() |
597 | - item['command'] = command.get_text() |
598 | - if item['name'] == '' or item['command'] == '': |
599 | - err = Gtk.MessageDialog(dialog, |
600 | - Gtk.DialogFlags.MODAL, |
601 | - Gtk.MessageType.ERROR, |
602 | - Gtk.ButtonsType.CLOSE, |
603 | - _("You need to define a name and command") |
604 | - ) |
605 | - err.run() |
606 | - err.destroy() |
607 | - else: |
608 | - # we have a new command |
609 | - store = data['treeview'].get_model() |
610 | - iter = store.get_iter_first() |
611 | - name_exist = False |
612 | - while iter != None: |
613 | - if store.get_value(iter,CC_COL_NAME) == item['name']: |
614 | - name_exist = True |
615 | - break |
616 | - iter = store.iter_next(iter) |
617 | - if not name_exist: |
618 | - store.append((item['enabled'], item['name'], item['command'])) |
619 | - else: |
620 | - gerr(_("Name *%s* already exist") % item['name']) |
621 | - dialog.destroy() |
622 | + (dialog,enabled,name,command,submenu) = self._create_command_dialog() |
623 | + res = dialog.run() |
624 | + item = {} |
625 | + if res == Gtk.ResponseType.ACCEPT: |
626 | + item['enabled'] = enabled.get_active() |
627 | + item['name'] = name.get_text() |
628 | + item['submenu'] = submenu.get_text() |
629 | + item['command'] = command.get_text() |
630 | + if item['name'] == '' or item['command'] == '': |
631 | + err = Gtk.MessageDialog(dialog, |
632 | + Gtk.DialogFlags.MODAL, |
633 | + Gtk.MessageType.ERROR, |
634 | + Gtk.ButtonsType.CLOSE, |
635 | + _("You need to define a name and command") |
636 | + ) |
637 | + err.run() |
638 | + err.destroy() |
639 | + else: |
640 | + # we have a new command |
641 | + store = data['treeview'].get_model() |
642 | + iter = store.get_iter_first() |
643 | + name_exist = False |
644 | + while iter != None: |
645 | + if store.get_value(iter,CC_COL_NAME) == item['name']: |
646 | + name_exist = True |
647 | + break |
648 | + iter = store.iter_next(iter) |
649 | + if not name_exist: |
650 | + store.append((item['enabled'], item['name'], item['command'], item['submenu'])) |
651 | + else: |
652 | + gerr(_("Name *%s* already exist") % item['name']) |
653 | + dialog.destroy() |
654 | + |
655 | |
656 | def on_goto_top(self, button, data): |
657 | - treeview = data['treeview'] |
658 | - selection = treeview.get_selection() |
659 | - (store, iter) = selection.get_selected() |
660 | - |
661 | - if not iter: |
662 | - return |
663 | - firstiter = store.get_iter_first() |
664 | - store.move_before(iter, firstiter) |
665 | + treeview = data['treeview'] |
666 | + selection = treeview.get_selection() |
667 | + (store, iter) = selection.get_selected() |
668 | + |
669 | + if not iter: |
670 | + return |
671 | + |
672 | + firstiter = store.get_iter_first() |
673 | + store.move_before(iter, firstiter) |
674 | + |
675 | |
676 | def on_go_up(self, button, data): |
677 | - treeview = data['treeview'] |
678 | - selection = treeview.get_selection() |
679 | - (store, iter) = selection.get_selected() |
680 | - |
681 | - if not iter: |
682 | - return |
683 | - |
684 | - tmpiter = store.get_iter_first() |
685 | - |
686 | - if(store.get_path(tmpiter) == store.get_path(iter)): |
687 | - return |
688 | - |
689 | - while tmpiter: |
690 | - next = store.iter_next(tmpiter) |
691 | - if(store.get_path(next) == store.get_path(iter)): |
692 | - store.swap(iter, tmpiter) |
693 | - break |
694 | + treeview = data['treeview'] |
695 | + selection = treeview.get_selection() |
696 | + (store, iter) = selection.get_selected() |
697 | + |
698 | + if not iter: |
699 | + return |
700 | + |
701 | + tmpiter = store.get_iter_first() |
702 | + |
703 | + if(store.get_path(tmpiter) == store.get_path(iter)): |
704 | + return |
705 | + |
706 | + while tmpiter: |
707 | + next = store.iter_next(tmpiter) |
708 | + |
709 | + if(store.get_path(next) == store.get_path(iter)): |
710 | + store.swap(iter, tmpiter) |
711 | + break |
712 | + |
713 | tmpiter = next |
714 | |
715 | + |
716 | def on_go_down(self, button, data): |
717 | - treeview = data['treeview'] |
718 | - selection = treeview.get_selection() |
719 | - (store, iter) = selection.get_selected() |
720 | - |
721 | - if not iter: |
722 | - return |
723 | - next = store.iter_next(iter) |
724 | - if next: |
725 | - store.swap(iter, next) |
726 | + treeview = data['treeview'] |
727 | + selection = treeview.get_selection() |
728 | + (store, iter) = selection.get_selected() |
729 | + |
730 | + if not iter: |
731 | + return |
732 | + next = store.iter_next(iter) |
733 | + if next: |
734 | + store.swap(iter, next) |
735 | + |
736 | |
737 | def on_goto_last(self, button, data): |
738 | - treeview = data['treeview'] |
739 | - selection = treeview.get_selection() |
740 | - (store, iter) = selection.get_selected() |
741 | - |
742 | - if not iter: |
743 | - return |
744 | - lastiter = iter |
745 | - tmpiter = store.get_iter_first() |
746 | - while tmpiter: |
747 | - lastiter = tmpiter |
748 | - tmpiter = store.iter_next(tmpiter) |
749 | - |
750 | - store.move_after(iter, lastiter) |
751 | - |
752 | - |
753 | + treeview = data['treeview'] |
754 | + selection = treeview.get_selection() |
755 | + (store, iter) = selection.get_selected() |
756 | + |
757 | + if not iter: |
758 | + return |
759 | + |
760 | + lastiter = iter |
761 | + tmpiter = store.get_iter_first() |
762 | + |
763 | + while tmpiter: |
764 | + lastiter = tmpiter |
765 | + tmpiter = store.iter_next(tmpiter) |
766 | + |
767 | + store.move_after(iter, lastiter) |
768 | + |
769 | + |
770 | def on_delete(self, button, data): |
771 | - treeview = data['treeview'] |
772 | - selection = treeview.get_selection() |
773 | - (store, iter) = selection.get_selected() |
774 | - if iter: |
775 | - store.remove(iter) |
776 | - |
777 | - return |
778 | - |
779 | + treeview = data['treeview'] |
780 | + selection = treeview.get_selection() |
781 | + (store, iter) = selection.get_selected() |
782 | + |
783 | + if iter: |
784 | + store.remove(iter) |
785 | + |
786 | + return |
787 | + |
788 | + |
789 | def on_edit(self, button, data): |
790 | - treeview = data['treeview'] |
791 | - selection = treeview.get_selection() |
792 | - (store, iter) = selection.get_selected() |
793 | - |
794 | - if not iter: |
795 | - return |
796 | - |
797 | - (dialog,enabled,name,command) = self._create_command_dialog( |
798 | - enabled_var = store.get_value(iter, CC_COL_ENABLED), |
799 | - name_var = store.get_value(iter, CC_COL_NAME), |
800 | - command_var = store.get_value(iter, CC_COL_COMMAND) |
801 | - ) |
802 | - res = dialog.run() |
803 | - item = {} |
804 | - if res == Gtk.ResponseType.ACCEPT: |
805 | - item['enabled'] = enabled.get_active() |
806 | - item['name'] = name.get_text() |
807 | - item['command'] = command.get_text() |
808 | - if item['name'] == '' or item['command'] == '': |
809 | - err = Gtk.MessageDialog(dialog, |
810 | - Gtk.DialogFlags.MODAL, |
811 | - Gtk.MessageType.ERROR, |
812 | - Gtk.ButtonsType.CLOSE, |
813 | - _("You need to define a name and command") |
814 | - ) |
815 | - err.run() |
816 | - err.destroy() |
817 | - else: |
818 | - tmpiter = store.get_iter_first() |
819 | - name_exist = False |
820 | - while tmpiter != None: |
821 | - if store.get_path(tmpiter) != store.get_path(iter) and store.get_value(tmpiter,CC_COL_NAME) == item['name']: |
822 | - name_exist = True |
823 | - break |
824 | - tmpiter = store.iter_next(tmpiter) |
825 | - if not name_exist: |
826 | - store.set(iter, |
827 | - CC_COL_ENABLED,item['enabled'], |
828 | - CC_COL_NAME, item['name'], |
829 | - CC_COL_COMMAND, item['command'] |
830 | - ) |
831 | - else: |
832 | - gerr(_("Name *%s* already exist") % item['name']) |
833 | - |
834 | - dialog.destroy() |
835 | - |
836 | - |
837 | + treeview = data['treeview'] |
838 | + selection = treeview.get_selection() |
839 | + (store, iter) = selection.get_selected() |
840 | + |
841 | + if not iter: |
842 | + return |
843 | + |
844 | + (dialog,enabled,name,command,submenu) = self._create_command_dialog( |
845 | + enabled_var = store.get_value(iter, CC_COL_ENABLED), |
846 | + name_var = store.get_value(iter, CC_COL_NAME), |
847 | + command_var = store.get_value(iter, CC_COL_COMMAND), |
848 | + submenu_var=store.get_value(iter, CC_COL_CUSTOMSUBMENU) |
849 | + ) |
850 | + |
851 | + res = dialog.run() |
852 | + item = {} |
853 | + |
854 | + if res == Gtk.ResponseType.ACCEPT: |
855 | + item['enabled'] = enabled.get_active() |
856 | + item['name'] = name.get_text() |
857 | + item['command'] = command.get_text() |
858 | + item['submenu'] = submenu.get_text() |
859 | + |
860 | + if item['name'] == '' or item['command'] == '': |
861 | + err = Gtk.MessageDialog(dialog, |
862 | + Gtk.DialogFlags.MODAL, |
863 | + Gtk.MessageType.ERROR, |
864 | + Gtk.ButtonsType.CLOSE, |
865 | + _("You need to define a name and command") |
866 | + ) |
867 | + err.run() |
868 | + err.destroy() |
869 | + else: |
870 | + tmpiter = store.get_iter_first() |
871 | + name_exist = False |
872 | + while tmpiter != None: |
873 | + if store.get_path(tmpiter) != store.get_path(iter) and store.get_value(tmpiter,CC_COL_NAME) == item['name']: |
874 | + name_exist = True |
875 | + break |
876 | + tmpiter = store.iter_next(tmpiter) |
877 | + if not name_exist: |
878 | + store.set(iter, |
879 | + CC_COL_ENABLED,item['enabled'], |
880 | + CC_COL_NAME, item['name'], |
881 | + CC_COL_COMMAND, item['command'], |
882 | + CC_COL_CUSTOMSUBMENU, item['submenu'] |
883 | + ) |
884 | + else: |
885 | + gerr(_("Name *%s* already exist") % item['name']) |
886 | + |
887 | + dialog.destroy() |
888 | + |
889 | + |
890 | if __name__ == '__main__': |
891 | - c = CustomCommandsMenu() |
892 | - c.configure(None, None) |
893 | - Gtk.main() |
894 | + c = CustomCommandsMenu() |
895 | + c.configure(None, None) |
896 | + Gtk.main() |
897 |
Tested on Debian Stretch and Buster without any problem.
Indentation fix does not change the behaviour but improve readability for further changes.