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/>.
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
,
45 dlg
.set_title(_("Cannot communicate JACK D-Bus"))
49 def on_menu_command(self
, widget
, function
):
53 error
= Gtk
.MessageDialog(None,
54 Gtk
.DialogFlags
.MODAL
,
55 Gtk
.MessageType
.ERROR
,
57 _("Error executing ") +
59 _("Unexpected error\n\n") + repr(e
))
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
)
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()
78 jack
= self
.get_jack_configure()
80 item
= Gtk
.MenuItem(_("JACK engine"))
83 item
.connect("button-release-event", function
, "engine")
85 item
= Gtk
.MenuItem(_('JACK "%s" driver') % jack
.get_selected_driver())
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
)
94 item
.connect("button-release-event", function
, module
)
95 except Exception, err
:
96 sys
.stderr
.write(str(err
))
98 if not menu
.get_children():
99 item
= Gtk
.MenuItem(_("Empty config list"))
100 item
.set_sensitive(False)
104 def studio_list_fill(self
, widget
, function
):
105 menu
= widget
.get_submenu()
106 self
.menu_clear(menu
)
108 for studio
in self
.studio_list():
109 item
= Gtk
.MenuItem(studio
)
112 item
.connect("button-release-event", function
, studio
) # "activate" is not used because of focus bug in pygtk
114 self
.menu_clear(menu
)
115 item
= Gtk
.MenuItem(_("Error obtaining studio list"))
116 item
.set_sensitive(False)
119 if not menu
.get_children():
120 item
= Gtk
.MenuItem(_("Empty studio list"))
121 item
.set_sensitive(False)
125 def create_menu(self
):
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))
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
))
142 menu_items
.append((Gtk
.SeparatorMenuItem
.new(),))
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
))
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
))
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))
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
))
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))
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
))
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
:
187 if len(menu_tuple
) > 1:
188 callback
= menu_tuple
[1]
189 exec_path
= menu_tuple
[2]
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
)
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,