Let customize menu's quit handler
[laditools.git] / laditools / gtk / menu.py
blob94e0c228a23596d3cf1afbd24a3041d181035ab2
1 #!/usr/bin/python
2 # LADITools - Linux Audio Desktop Integration Tools
3 # Copyright (C) 2011-2012 Alessio Treglia <quadrispro@ubuntu.com>
4 # Copyright (C) 2007-2010:
5 # * Marc-Olivier Barre <marco@marcochapeau.org>
6 # * Nedko Arnaudov <nedko@arnaudov.name>
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 import os
22 import sys
23 import subprocess
24 from gi.repository import Gtk
25 from gi.repository import GObject
26 from .. import _gettext_domain
27 from .manager import LadiManagerGtk
29 class LadiMenu(LadiManagerGtk):
31 def __init__(self, jack_autostart, **kwargs):
33 LadiManagerGtk.__init__(self, jack_autostart)
35 self.handler = { 'quit' : Gtk.main_quit, }
36 if 'quit_handler' in kwargs:
37 self.handler['quit'] = kwargs['quit']
39 def on_menu_show_diagnose(self, widget, data=None):
40 dlg = Gtk.MessageDialog(None,
41 Gtk.DialogFlags.MODAL,
42 Gtk.MessageType.ERROR,
43 Gtk.ButtonsType.CLOSE,
44 self.diagnose_text)
45 dlg.set_title(_("Cannot communicate JACK D-Bus"))
46 dlg.run()
47 dlg.destroy()
49 def on_menu_command(self, widget, function):
50 try:
51 function()
52 except Exception, e:
53 error = Gtk.MessageDialog(None,
54 Gtk.DialogFlags.MODAL,
55 Gtk.MessageType.ERROR,
56 Gtk.ButtonsType.OK,
57 _("Error executing ") +
58 repr(function) +
59 _("Unexpected error\n\n") + repr(e))
60 error.run()
61 error.destroy()
63 def on_menu_launch_handler(self, widget, command):
64 commandline = command.split()
65 commandline[0] = command = self._launcher_which(commandline[0])
66 if not command in self.proc_list:
67 LadiManagerGtk.launcher_exec(self, command=commandline)
68 else:
69 LadiManagerGtk.launcher_kill(self, command=commandline)
71 def menu_clear(self, menu):
72 menu.foreach(lambda item,none: menu.remove(item), None)
74 def configure_list_fill(self, widget, function):
75 menu = widget.get_submenu()
76 self.menu_clear(menu)
77 try:
78 jack = self.get_jack_configure()
79 # 'engine' item
80 item = Gtk.MenuItem(_("JACK engine"))
81 item.show()
82 menu.append(item)
83 item.connect("button-release-event", function, "engine")
84 # 'params' item
85 item = Gtk.MenuItem(_('JACK "%s" driver') % jack.get_selected_driver())
86 item.show()
87 menu.append(item)
88 item.connect("button-release-event", function, "params")
89 for internal in jack.read_container(['internals']):
90 module = str(internal)
91 item = Gtk.MenuItem(_('JACK "%s"') % module)
92 item.show()
93 menu.append(item)
94 item.connect("button-release-event", function, module)
95 except Exception, err:
96 sys.stderr.write(str(err))
97 sys.stderr.flush()
98 if not menu.get_children():
99 item = Gtk.MenuItem(_("Empty config list"))
100 item.set_sensitive(False)
101 item.show()
102 menu.append(item)
104 def studio_list_fill(self, widget, function):
105 menu = widget.get_submenu()
106 self.menu_clear(menu)
107 try:
108 for studio in self.studio_list():
109 item = Gtk.MenuItem(studio)
110 item.show()
111 menu.append(item)
112 item.connect("button-release-event", function, studio) # "activate" is not used because of focus bug in pygtk
113 except Exception, e:
114 self.menu_clear(menu)
115 item = Gtk.MenuItem(_("Error obtaining studio list"))
116 item.set_sensitive(False)
117 item.show()
118 menu.append(item)
119 if not menu.get_children():
120 item = Gtk.MenuItem(_("Empty studio list"))
121 item.set_sensitive(False)
122 item.show()
123 menu.append(item)
125 def create_menu(self):
126 menu_items = []
128 ladish_available = self.ladish_is_available()
129 jack_available = self.jack_is_available()
130 a2j_available = self.a2j_is_available()
132 if self.diagnose_text:
133 menu_items.append((Gtk.ImageMenuItem(_("Diagnose")), self.on_menu_show_diagnose, None))
134 menu_items.append((Gtk.SeparatorMenuItem.new(), None, None))
136 if ladish_available:
137 menu_items.append((Gtk.ImageMenuItem(_("Start gladish")), self.on_menu_launch_handler, "gladish"))
139 menu_items.append((Gtk.ImageMenuItem("Configure ..."), self.configure_list_fill, self.studio_configure))
141 menu = Gtk.Menu()
142 menu_items.append((Gtk.SeparatorMenuItem.new(),))
143 if ladish_available:
144 menu_items.append((Gtk.ImageMenuItem(_("New studio...")), self.on_menu_command, self.studio_new))
145 menu_items.append((Gtk.ImageMenuItem(_("Load studio")), self.studio_list_fill, self.studio_load))
146 menu_items.append((Gtk.SeparatorMenuItem.new(), None, None))
147 if self.studio_is_loaded():
148 if self.studio_is_started():
149 menu_items.append((Gtk.ImageMenuItem(_("Stop studio")), self.on_menu_command, self.studio_stop))
150 menu_items.append((Gtk.ImageMenuItem(_("Save studio")), self.on_menu_command, self.studio_save))
151 else:
152 menu_items.append((Gtk.ImageMenuItem(_("Start studio")), self.on_menu_command, self.studio_start))
153 menu_items.append((Gtk.ImageMenuItem(_("Rename studio")), self.on_menu_command, self.studio_rename))
154 menu_items.append((Gtk.ImageMenuItem(_("Unload studio")), self.on_menu_command, self.studio_unload))
155 else:
156 menu_items.append((Gtk.ImageMenuItem(_("Start automatic studio")), self.on_menu_command, self.jack_start))
157 menu_items.append((Gtk.SeparatorMenuItem.new(), None, None))
158 menu_items.append((Gtk.ImageMenuItem(_("Delete studio")), self.studio_list_fill, self.studio_delete))
159 menu_items.append((Gtk.ImageMenuItem(_("Reactivate ladishd")), self.on_menu_command, self.ladish_reactivate))
160 menu_items.append((Gtk.SeparatorMenuItem.new(), None, None))
161 if jack_available:
162 if not self.jack_is_started():
163 if not ladish_available:
164 menu_items.append((Gtk.ImageMenuItem(_("Start JACK server")), self.on_menu_command, self.jack_start))
165 else:
166 menu_items.append((Gtk.ImageMenuItem(_("Reset Xruns")), self.on_menu_command, self.jack_reset_xruns))
167 if not ladish_available:
168 menu_items.append((Gtk.ImageMenuItem(_("Stop JACK server")), self.on_menu_command, self.jack_stop))
169 menu_items.append((Gtk.ImageMenuItem(_("Reactivate JACK")), self.on_menu_command, self.jack_reactivate))
170 menu_items.append((Gtk.SeparatorMenuItem.new(), None, None))
171 if a2j_available:
172 # when a2jmidid is used in used with ladish, a2j script should be used
173 # for managing bridge "active" lifetime
174 if not ladish_available:
175 if not self.a2j_is_started():
176 menu_items.append((Gtk.ImageMenuItem(_("Start A2J bridge")), self.on_menu_command, self.a2j_start))
177 else:
178 menu_items.append((Gtk.ImageMenuItem(_("Stop A2J bridge")), self.on_menu_command, self.a2j_stop))
179 menu_items.append((Gtk.ImageMenuItem(_("Reactivate A2J")), self.on_menu_command, self.a2j_reactivate))
180 menu_items.append((Gtk.SeparatorMenuItem.new(), None, None))
181 if hasattr(self, 'on_about'):
182 menu_items.append((Gtk.ImageMenuItem(_("About")), self.on_about, None))
183 menu_items.append((Gtk.ImageMenuItem(_("Quit")), self.on_menu_command, self.handler['quit']))
185 for menu_tuple in menu_items:
186 item = menu_tuple[0]
187 if len(menu_tuple) > 1:
188 callback = menu_tuple[1]
189 exec_path = menu_tuple[2]
190 menu.append(item)
191 if type(item) is not Gtk.SeparatorMenuItem:
192 if callback in (self.studio_list_fill, self.configure_list_fill):
193 item.set_submenu(Gtk.Menu())
194 item.connect("activate", callback, exec_path)
195 menu.show_all()
196 return menu
198 def studio_load(self, item, event, studio):
199 LadiManagerGtk.studio_load(self, item=item, event=event, studio=studio)
201 def studio_delete(self, item, event, studio):
202 LadiManagerGtk.studio_delete(self, item=item, event=event, studio=studio)
204 def menu_activate(self):
205 menu = self.create_menu()
206 menu.popup(parent_menu_shell=None,
207 parent_menu_item=None,
208 func=None,
209 data=None,
210 button=3,
211 activate_time=0)
212 menu.reposition()