13 # FIXME: How do we make this portable to windows ?
14 ORBit.load_typelib ("./MediaControl.so")
18 """Abstract class defining helper functions to interconnect
19 glade XML files and methods of a python class."""
20 def create_dictionary (self):
21 """Create a (name, function) dictionnary for the current class"""
23 self.create_dictionary_for_class (self.__class__, dict)
26 def create_dictionary_for_class (self, a_class, dict):
27 """Create a (name, function) dictionnary for the specified class"""
28 bases = a_class.__bases__
29 for iteration in bases:
30 self.create_dictionary_for_class (iteration, dict)
31 for iteration in dir(a_class):
32 dict[iteration] = getattr(self, iteration)
35 """Connects the class methods with the UI"""
36 self.gui.signal_autoconnect(self.create_dictionary ())
38 def gtk_widget_hide (self, widget):
42 def on_exit(self, source=None, event=None):
43 """Generic exit callback"""
46 class DVDControl (Connect):
47 def __init__ (self, gladefile):
48 """Initializes the GUI and other attributes"""
50 self.gui = gtk.glade.XML(gladefile)
52 # Frequently used GUI widgets
53 self.gui.logmessages = self.gui.get_widget("logmessages")
54 self.gui.position_label = self.gui.get_widget("position_label")
55 self.gui.fs = gtk.FileSelection ("Select a file")
56 self.gui.fs.ok_button.connect_after ("clicked", lambda win: self.gui.fs.hide ())
57 self.gui.fs.cancel_button.connect ("clicked", lambda win: self.gui.fs.destroy ())
61 self.currentpos = None
64 self.iorfile = "/tmp/vlc-ior.ref"
67 # Default FF/RW time : 5 seconds
68 self.default_time_increment = 5
70 def update_title (self, title):
71 # Update the title of the main window
72 self.gui.get_widget ("win").set_title (title)
74 def launch_player (self):
75 """Launch the VLC corba plugin"""
76 #print "Launching vlc server..."
77 # FIXME: spawn is portable, but how can we make sure that
78 # launch-vlc-corba launches the application in the background ?
80 import distutils.spawn
81 distutils.spawn.spawn (["launch-vlc-corba"], True, True)
82 # Wait a little for the server to initialize. We could instead test
83 # on the existence and validity of self.iorfile
88 """Mainloop : CORBA initalization and Gtk mainloop setup"""
89 self.orb = CORBA.ORB_init(sys.argv)
91 errormessage = """Unable to get a MediaControl object
92 Please try to run the following command:
96 ior = open(self.iorfile).readline()
98 # The iorfile does not existe : the player is maybe not active
101 ior = open(self.iorfile).readline()
106 self.mc = self.orb.string_to_object(ior)
108 if self.mc._non_existent ():
109 # The remote object is not available. Let's run the
111 self.launch_player ()
113 ior = open(self.iorfile).readline()
117 self.mc = self.orb.string_to_object(ior)
118 if self.mc._non_existent ():
122 self.currentpos = VLC.Position ()
123 self.currentpos.value = 0
124 self.currentpos.key = VLC.MediaTime
125 self.currentpos.origin = VLC.RelativePosition
127 gtk.timeout_add (20, self.update_display, self.orb)
131 """Adds a new log message to the logmessage window"""
132 buf = self.gui.logmessages.get_buffer ()
133 mes = str(msg) + "\n"
134 buf.insert_at_cursor (mes, len(mes))
136 endmark = buf.create_mark ("end",
139 self.gui.logmessages.scroll_mark_onscreen (endmark)
142 def on_exit (self, source=None, event=None):
143 """General exit callback"""
145 # Terminate the VLC server
152 def file_selector (self, callback=None, label="Select a file",
154 """Display the file selector"""
155 self.gui.fs.set_property ("title", label)
156 self.gui.fs.set_property ("filename", default)
157 self.gui.fs.set_property ("select-multiple", False)
158 self.gui.fs.set_property ("show-fileops", False)
161 # Disconnecting the old callback
163 self.gui.fs.ok_button.disconnect (self.gui.fs.connect_id)
166 # Connecting the new one
167 self.gui.fs.connect_id = self.gui.fs.ok_button.connect ("clicked", callback, self.gui.fs)
171 def file_selected_cb (self, button, fs):
172 """Open and play the selected movie file"""
173 file = self.gui.fs.get_property ("filename")
174 self.mc.add_to_playlist (file)
178 def move_position (self, value):
179 """Helper function : fast forward or rewind by value seconds"""
180 print "Moving by %d seconds" % value
181 pos = VLC.Position ()
183 pos.key = VLC.MediaTime
184 pos.origin = VLC.RelativePosition
185 self.mc.set_media_position (pos)
188 def update_display (self, orb):
189 """Update the interface"""
190 if self.status == "Play":
191 pos = self.mc.get_media_position (VLC.AbsolutePosition,
193 self.gui.position_label.set_text (str(pos.value))
194 elif self.status == "Stop":
195 self.gui.position_label.set_text ("N/C")
198 # Callbacks function. Skeletons can be generated by glade2py
199 def on_win_key_press_event (self, win=None, event=None):
201 if event.keyval == gtk.keysyms.Tab:
202 self.on_b_pause_clicked (win, event)
204 elif event.keyval == gtk.keysyms.Right:
205 self.on_b_forward_clicked (win, event)
207 elif event.keyval == gtk.keysyms.Left:
208 self.on_b_rewind_clicked (win, event)
210 elif event.keyval == gtk.keysyms.Home:
211 pos = VLC.Position ()
213 pos.key = VLC.MediaTime
214 pos.origin = VLC.AbsolutePosition
215 self.mc.set_media_position (pos)
217 elif event.keyval == gtk.keysyms.End:
218 pos = VLC.Position ()
219 pos.value = -self.default_time_increment
220 pos.key = VLC.MediaTime
221 pos.origin = VLC.ModuloPosition
222 self.mc.set_media_position (pos)
224 elif event.keyval == gtk.keysyms.Page_Down:
225 # FIXME: Next chapter
227 elif event.keyval == gtk.keysyms.Page_Up:
228 # FIXME: Previous chapter
232 def on_quit1_activate (self, button=None, data=None):
233 """Gtk callback to quit"""
234 self.on_exit (button, data)
237 def on_about1_activate (self, button=None, data=None):
238 self.gui.get_widget("about").show ()
241 def about_hide (self, button=None, data=None):
242 self.gui.get_widget("about").hide ()
245 def on_b_rewind_clicked (self, button=None, data=None):
246 if self.status == "Play":
247 self.move_position (-self.default_time_increment)
250 def on_b_play_clicked (self, button=None, data=None):
251 if self.status != "Play":
252 self.mc.start (self.currentpos)
256 def on_b_pause_clicked (self, button=None, data=None):
257 if self.status == "Play":
258 self.mc.pause (self.currentpos)
259 self.status = "Pause"
260 elif self.status == "Pause":
261 self.mc.pause (self.currentpos)
265 def on_b_stop_clicked (self, button=None, data=None):
266 self.mc.stop (self.currentpos)
270 def on_b_forward_clicked (self, button=None, data=None):
271 if self.status == "Play":
272 self.move_position (self.default_time_increment)
275 def on_b_addfile_clicked (self, button=None, data=None):
276 self.file_selector (callback=self.file_selected_cb,
277 label="Play a movie file")
280 def on_b_selectdvd_clicked (self, button=None, data=None):
282 self.mc.add_to_playlist ("dvd:///dev/dvd at 1,1")
283 self.mc.start (self.currentpos)
287 def on_b_exit_clicked (self, button=None, data=None):
288 self.on_exit (button, data)
291 def on_logmessages_insert_at_cursor (self, button=None, data=None):
292 print "on_logmessages_insert_at_cursor activated (%s, %s, %s)" % (self, button, data)
293 # FIXME: faire défiler la scrollmark (cf gtkshell)
296 if __name__ == '__main__':
297 v = DVDControl ("simpleplayer.glade")