[xiph-commits] r14791 - trunk/subtle

jmesquita at svn.xiph.org jmesquita at svn.xiph.org
Wed Apr 23 11:01:02 PDT 2008


Author: jmesquita
Date: 2008-04-23 11:01:02 -0700 (Wed, 23 Apr 2008)
New Revision: 14791

Added:
   trunk/subtle/Subtle.py
Removed:
   trunk/subtle/Souffleur.py
Log:
Continuing to rename project and its files.


Deleted: trunk/subtle/Souffleur.py
===================================================================
--- trunk/subtle/Souffleur.py	2008-04-23 17:54:59 UTC (rev 14790)
+++ trunk/subtle/Souffleur.py	2008-04-23 18:01:02 UTC (rev 14791)
@@ -1,812 +0,0 @@
-#!/usr/bin/env python
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-
-from GPlayer import VideoWidget
-from GPlayer import GstPlayer
-from Subtitles import Subtitles
-import sys
-import os
-
-from MediaInfo import MediaInfo
-from SouffleurXML import ProjectXML
-
-try:
-    import pygtk
-    #tell pyGTK, if possible, that we want GTKv2
-    pygtk.require("2.0")
-except:
-    #Some distributions come with GTK2, but not pyGTK
-    pass
-try:
-    import gtk
-    import gobject
-    import gtk.glade
-except:
-    print "You need to install pyGTK or GTKv2 ",
-    print "or set your PYTHONPATH correctly."
-    print "try: export PYTHONPATH=",
-    print "/usr/local/lib/python2.2/site-packages/"
-    sys.exit(1)
-#now we have both gtk and gtk.glade imported
-#Also, we know we are running GTK v2
-import gst
-
-class Souffleur:
-    def __init__(self):
-        """
-        In this init we are going to display the main
-        Souffleur window
-        """
-        gladefile="souffleur.glade"
-        windowname="MAIN_WINDOW"
-        
-        self.update_id = -1
-        self.p_position = gst.CLOCK_TIME_NONE
-        self.p_duration = gst.CLOCK_TIME_NONE
-        self.UPDATE_INTERVAL=100
-        
-        self.Subtitle = None
-        self.Subtitles = []
-	# Current subtitle being edited
-	self.cur_edit_sub_iter = None
-
-        #self.scroll = 0
-        self.videoWidgetGst = None
-        self.player = None
-        self.t_duration = 0
-        self.media = []
-
-        self.wTree=gtk.glade.XML(gladefile,windowname)
-        self.gladefile = gladefile
-        dic = { "gtk_main_quit" : (gtk.main_quit),\
-            "on_main_file_quit_activate": (gtk.main_quit), \
-            "on_main_file_open_activate": self.mainFileOpen, \
-            "on_TOOL_PLAY_clicked": self.playerPlay,\
-            "on_TOOL_STOP_clicked": self.playerStop,\
-            "on_TOOL_SEEK_FORWARD_clicked": self.playerSeekForward,\
-            "on_TOOL_SEEK_REWIND_clicked": self.playerSeekRewind,\
-            "on_TOOL_HIDE_STREAMS_clicked": self.cb_hideStreamsPane,\
-            "on_TOOL_HIDE_SUBLIST_clicked": self.cb_hideSubPane,\
-            "on_MEDIA_ADJUSTMENT_button_press_event": self.buttonPressAdjustment,\
-            "on_MEDIA_ADJUSTMENT_button_release_event": self.buttonReleaseAdjustment,\
-            "on_MEDIA_ADJUSTMENT_change_value": self.changeValueAdjustment,\
-            "on_VIDEO_OUT_PUT_expose_event": self.exposeEventVideoOut,\
-            "on_main_file_save_activate": self.cb_onSaveMenu,\
-            "on_main_file_save_as_activate": self.cb_onSaveAsMenu,\
-            "on_main_file_new_activate": self.cb_onNewMenu,\
-            "on_MAIN_VIEW_STREAMS_PANE_activate": self.cb_showStreamsPane,\
-            "on_MAIN_VIEW_SUBTITLES_activate": self.cb_showSubtitlePane,\
-            "on_TOOL_DEL_STREAM_clicked": self.cb_delStream,\
-	    "on_TOOL_MOD_STREAM_clicked": self.cb_modStream,\
-	    "on_TOOL_NEW_STREAM_clicked": self.cb_newStream,\
-	    "on_TOOL_ADD_STREAM_clicked": self.cb_addNewStream,\
-	    "on_LIST_SUBS_button_release_event": self.cb_onSubsListSelect,\
-	    "on_LIST_SUBS_button_press_event": self.cb_onSubsListSelect,\
-	    "on_txt_subedit_key_release_event": self.cb_onSubtitleEdit,\
-	    "on_TOOL_SAVE_STREAM_clicked": self.cb_saveStream,\
-	    "on_TOOL_DEL_SUBS_clicked": self.cb_subDel,\
-	    "on_TOOL_OUT_SUB_clicked": self.cb_subOut,\
-	    "on_TOOL_IN_SUB_clicked": self.cb_subIn,\
-	    "on_TOOL_INS_B4_SUB_clicked": self.cb_onSubInsB4,\
-	    "on_TOOL_INS_AFTER_SUB_clicked": self.cb_onSubInsAfter,\
-	    "on_TOOL_IN_SUB_clicked": self.cb_subIn}
-        self.wTree.signal_autoconnect (dic)
-        
-	self.windowMainWindow=self.wTree.get_widget("MAIN_WINDOW")
-        self.windowProjectOpen=None
-        self.windowProjectSO=None
-        self.PFileName=None
-        self.windowMediaOpen=None
-        #self.windowStreams=gtk.glade.XML (self.gladefile,"STREAM_WINDOW")
-        #dic = {"on_TOOL_DEL_STREAM_clicked": self.cb_delStream,\
-        #        "on_TOOL_MOD_STREAM_clicked": self.cb_modStream,\
-        #        "on_TOOL_NEW_STREAM_clicked": self.cb_newStream,\
-        #        "on_TOOL_ADD_STREAM_clicked": self.cb_addNewStream,\
-        #        "on_STREAM_WINDOW_delete_event": self.cb_StreamWindowDelete}
-        #self.windowStreams.signal_autoconnect (dic)
-        ### Setup LIST_STREAMS
-        #LIST = self.windowStreams.get_widget("LIST_STREAMS")
-        LIST = self.wTree.get_widget("LIST_STREAMS")
-        if LIST:
-            self.streamsTreeStore = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_UINT)
-            LIST.set_model(self.streamsTreeStore)
-            cell = gtk.CellRendererText()
-            tvcolumn = gtk.TreeViewColumn('Streams', cell, text = 0)
-            LIST.append_column(tvcolumn)
-        
-        #self.windowSubsList=gtk.glade.XML (self.gladefile,"SUBS_LIST")
-        #dic = {"on_LIST_SUBS_cursor_changed": self.cb_onSubsListSelect,\
-        #        "on_TOOL_SAVE_STREAM_clicked": self.cb_saveStream,\
-        #        "on_TOOL_DEL_SUBS_clicked": self.cb_subDel,\
-        #        "on_TOOL_OUT_SUB_clicked": self.cb_subOut,\
-        #        "on_TOOL_IN_SUB_clicked": self.cb_subIn,\
-        #        "on_TOOL_INS_B4_SUB_clicked": self.cb_onSubInsB4,\
-        #        "on_TOOL_INS_AFTER_SUB_clicked": self.cb_onSubInsAfter,\
-        #        "on_TOOL_IN_SUB_clicked": self.cb_subIn,\
-        #        "on_SUBS_LIST_delete_event": self.cb_onSubsWindowDelete}
-        #self.windowSubsList.signal_autoconnect (dic)
-        #SUBLIST = self.windowSubsList.get_widget("LIST_SUBS")
-        SUBLIST = self.wTree.get_widget("LIST_SUBS")
-	SUBLIST.add_events(gtk.gdk._2BUTTON_PRESS)
-        if SUBLIST:
-            self.subsListStore = gtk.ListStore(gobject.TYPE_UINT,
-                                                gobject.TYPE_UINT,
-						gobject.TYPE_UINT,
-                                                gobject.TYPE_STRING)
-            SUBLIST.set_model(self.subsListStore)
-            cell = gtk.CellRendererText()
-            tvcolumn = gtk.TreeViewColumn('#', cell, text = 0)
-            SUBLIST.append_column(tvcolumn)
-            cell = gtk.CellRendererText()
-            tvcolumn = gtk.TreeViewColumn('Start', cell, text = 1)
-            SUBLIST.append_column(tvcolumn)
-            cell = gtk.CellRendererText()
-            tvcolumn = gtk.TreeViewColumn('End', cell, text = 2)
-            SUBLIST.append_column(tvcolumn)
-            cell = gtk.CellRendererText()
-            tvcolumn = gtk.TreeViewColumn('Text', cell, text = 3)
-	    tvcolumn.set_resizable(True)
-            SUBLIST.append_column(tvcolumn)
-        #WND=self.windowStreams.get_widget("STREAM_WINDOW")
-        #WND.hide()
-        #WND=self.windowSubsList.get_widget("SUBS_LIST")
-        #WND.hide()
-        ### Main window setup
-        self.videoWidget = self.wTree.get_widget("VIDEO_OUT_PUT")
-        self.adjustment = self.wTree.get_widget("MEDIA_ADJUSTMENT")
-        self.labelHour = self.wTree.get_widget("LABEL_HOUR")
-        self.labelMin = self.wTree.get_widget("LABEL_MIN")
-        self.labelSec = self.wTree.get_widget("LABEL_SEC")
-        self.labelMSec = self.wTree.get_widget("LABEL_MSEC")
-        self.playButton = self.wTree.get_widget("TOOL_PLAY")
-	self.lbl_cur_fps = self.wTree.get_widget("lbl_cur_fps")
-	self.streams_pane = self.wTree.get_widget("streams_pane")
-	self.subtitle_pane = self.wTree.get_widget("subtitle_pane")
-	self.txt_subedit = self.wTree.get_widget("txt_subedit")
-	self.subList = SUBLIST
-	#self.windowMainWindow.maximize()
-        return
-#==============================================================================
-    def cb_hideSubPane(self, widget):
-	"""
-	    Hide the subtitles pane
-	"""
-	self.subtitle_pane.hide()
-	return
-#==============================================================================
-    def cb_hideStreamsPane(self, widget):
-	"""
-	    Hide the streams pane
-	"""
-	self.streams_pane.hide()
-	return
-#==============================================================================
-    def cb_showStreamsPane(self, widget):
-	"""
-	    Hide the streams pane
-	"""
-	self.streams_pane.show()
-	return
-#==============================================================================
-    def cb_onSubInsB4(self, widget):
-	"""
-	    Insert new subtitle before current selected
-	"""
-	subsList = self.wTree.get_widget("LIST_SUBS")
-	selection = subsList.get_selection()
-	result = selection.get_selected()
-	if result:
-            model, iter = result
-	    if self.subsListStore.iter_is_valid(iter):
-		cur, sTime, eTime = self.subsListStore.get(iter, 0, 1, 2)
-		self.Subtitle.subAdd(sTime-1,sTime-2,'',None,1)
-		self.subsListStore.insert_before(iter, (cur, sTime-1, sTime-2, 'New subtitle...'))
-		self.reorder_SubsListStore()
-	return
-#==============================================================================
-    def cb_onSubInsAfter(self, widget):
-	"""
-	    Insert new subtitle after current selected
-	"""
-	subsList = self.wTree.get_widget("LIST_SUBS")
-	selection = subsList.get_selection()
-	result = selection.get_selected()
-	if result:
-            model, iter = result
-	    if self.subsListStore.iter_is_valid(iter):
-		cur, sTime, eTime = self.subsListStore.get(iter, 0, 1, 2)
-		self.Subtitle.subAdd(eTime+1,eTime+2,'',None,1)
-		cur += 1
-		self.subsListStore.insert_after(iter, (cur, eTime+1, eTime+2, 'New subtitle...'))
-		self.reorder_SubsListStore()
-	return
-#==============================================================================
-    def reorder_SubsListStore(self):
-	"""
-	    Reorder the subs listStore when added or deleted
-	"""
-	iter = self.subsListStore.get_iter_first()
-	cur = 0
-	while iter is not None:
-	    if iter is not None:
-		self.subsListStore.set_value(iter, 0, cur)
-		cur += 1
-		iter = self.subsListStore.iter_next(iter)
-#==============================================================================
-    def cb_subDel(self, widget):
-	"""
-	    Delete a subtile from the list store and from memory
-	"""
-	subsList = self.wTree.get_widget("LIST_SUBS")
-	selection = subsList.get_selection()
-	result = selection.get_selected()
-	if result:
-            model, iter = result
-	    subKey = self.subsListStore.get(iter, 1)
-            self.Subtitle.subDel(subKey[0])
-	    model.remove(iter)
-	    self.reorder_SubsListStore()
-#==============================================================================
-    def cb_subOut(self, widget):
-	"""
-	    Set subtitle endtime
-	"""
-	if self.player:
-	    subsList = self.windowSubsList.get_widget("LIST_SUBS")
-	    selection = subsList.get_selection()
-	    result = selection.get_selected()
-	    if result:
-		model, iter = result
-		subKey, end_time = self.subsListStore.get(iter, 1, 2)
-		try:
-		    self.Subtitle.getSub(subKey).end_time = self.p_position/1000000
-		    self.Subtitle.subUpdate(subKey)
-		except:
-		    print "Error while setting subtitle timecode"
-		    return
-		self.subsListStore.set(iter,2,self.p_position/1000000)
-	return True
-#==============================================================================
-    def cb_subIn(self, widget):
-	"""
-	    Set subtitle start time
-	"""
-	if self.player:
-	    subsList = self.windowSubsList.get_widget("LIST_SUBS")
-	    selection = subsList.get_selection()
-	    result = selection.get_selected()
-	    if result:
-		model, iter = result
-		subKey = self.subsListStore.get(iter, 1)
-		try:
-		    self.Subtitle.getSub(subKey[0]).start_time = self.p_position/1000000
-		    self.Subtitle.subUpdate(subKey[0])
-		except:
-		    print "Error while setting subtitle timecode"
-		    return
-		self.subsListStore.set(iter,1,self.p_position/1000000)
-	return True
-#==============================================================================
-    def cb_onSubsWindowDelete(self, widget, event):
-        widget.hide()
-        return True
-#==============================================================================
-    def cb_StreamWindowDelete(self, widget, event):
-        widget.hide()
-        return True
-#==============================================================================
-    def cb_onSubtitleWindow(self, menu):
-        if self.windowSubsList:
-            WND=self.windowSubsList.get_widget("SUBS_LIST")
-            WND.show()
-#==============================================================================
-    def cb_showSubtitlePane(self, menu):
-	"""
-	   Show subtitle pane
-	"""
-	self.subtitle_pane.show()
-#==============================================================================
-    def cb_onStreamsWindow(self, menu):
-        if self.windowStreams:
-            WND=self.windowStreams.get_widget("STREAM_WINDOW")
-            WND.show()
-#==============================================================================
-    def getSubtitle(self, source):
-        for i in self.Subtitles:
-            if i.subSource==source:
-                return i
-        return None
-#==============================================================================
-    def cb_saveStream(self, widget):
-        if not self.windowStreams:
-            return
-        if not self.streamsTreeStore:
-            return
-        TView = self.windowStreams.get_widget("LIST_STREAMS")
-        TSelec = TView.get_selection()
-        TModel, TIter = TSelec.get_selected()
-        if not TIter:
-            return
-        N=TModel.get_value(TIter, 1)
-        mInfo = self.media[N]
-        if "subtitle" in mInfo.MIME:
-            tSubtitle = self.getSubtitle(mInfo.Streams[0].ID)
-            tSubtitle.subSave(mInfo.source, 1)
-#==============================================================================
-    def cb_modStream(self, widget):
-	# We have removed the window
-        #if not self.windowStreams:
-        #    return
-        if not self.streamsTreeStore:
-            return
-        #TView = self.windowStreams.get_widget("LIST_STREAMS")
-        TView = self.wTree.get_widget("LIST_STREAMS")
-        TSelec = TView.get_selection()
-        TModel, TIter = TSelec.get_selected()
-        if not TIter:
-            return
-        N=TModel.get_value(TIter, 0)
-	# FIXME: We should actually get the selected subtitle
-	if "Subtitle" in N:
-	    self.setSubtitle()
-#==============================================================================
-    def cb_newStream(self, widget):
-	"""
-	   Create a new subtitle
-	"""
-	print "Create a new stream"
-	#TODO: Lets popup something that will let us choose sub type
-	return
-#==============================================================================
-    def setSubtitle(self):
-        if self.Subtitle:
-	    # We have removed the window for now
-            #if (self.windowStreams):
-            #    WND=self.windowSubsList.get_widget("SUBS_LIST")
-            #    WND.show()
-            self.subsWindowUpdate()
-#==============================================================================
-    def updateStreamWindow(self):
-	#FIXME: This should be more complete and better handled
-	# Maybe all streams must be on the same list/dict
-        if not self.streamsTreeStore:
-            return
-        self.streamsTreeStore.clear()
-	for sub in self.Subtitles:
-            iter = self.streamsTreeStore.append(None)
-	    self.streamsTreeStore.set(iter, 0, "Subtitle: "+ sub.filename, 1, self.Subtitles.index(sub))
-	    child = self.streamsTreeStore.append(iter)
-	    self.streamsTreeStore.set(child, 0, "Type: " + sub.subType, \
-		    1, self.Subtitles.index(sub))
-        for mInfo in self.media:
-            iter = self.streamsTreeStore.append(None)
-            self.streamsTreeStore.set(iter, 0, mInfo.source, 1, self.media.index(mInfo))
-	    if mInfo.has_video:
-                child = self.streamsTreeStore.append(iter)
-		self.streamsTreeStore.set(child, 0, "Mimetype: " + mInfo.MIME.split("/")[1], \
-			1, self.media.index(mInfo))
-                child = self.streamsTreeStore.append(iter)
-		self.streamsTreeStore.set(child, 0, "Resolution: %dx%d "% (mInfo.videoWidth, mInfo.videoHeight), \
-			1, self.media.index(mInfo))
-                child = self.streamsTreeStore.append(iter)
-		self.streamsTreeStore.set(child, 0, ("Framerate: %.2f" % mInfo.framerate), \
-			1, self.media.index(mInfo))
-                child = self.streamsTreeStore.append(iter)
-		self.streamsTreeStore.set(child, 0, ("Length: %s s" % mInfo.videoLengthS), \
-			1, self.media.index(mInfo))
-                child = self.streamsTreeStore.append(iter)
-		self.streamsTreeStore.set(child, 0, ("Frames: %d" % (mInfo.videoLengthS/(1/mInfo.framerate))), \
-			1, self.media.index(mInfo))
-                child = self.streamsTreeStore.append(iter)
-#==============================================================================
-    def cb_delStream(self, widget):
-	"""
-	    Remove a stream from the current project
-	"""
-	#FIXME: We broke this ...
-        if not self.windowStreams:
-            return
-        if not self.streamsTreeStore:
-            return
-        TView = self.windowStreams.get_widget("LIST_STREAMS")
-        TSelec = TView.get_selection()
-        TModel, TIter = TSelec.get_selected()
-        if not TIter:
-            return
-        N=TModel.get_value(TIter, 1)
-        self.updateStreamWindow()
-#==============================================================================
-    def cb_openMediaCancel(self, widget):
-        if self.windowMediaOpen:
-            WND=self.windowMediaOpen.get_widget("OPEN_MEDIA")
-            WND.hide()
-#==============================================================================
-    def cb_openMediaOpen(self, widget):
-        WND=self.windowMediaOpen.get_widget("OPEN_MEDIA")
-        FN=WND.get_filename()
-        URI=WND.get_uri()
-	self.TEST_SUB_URI = URI
-        WND.hide()
-
-	extension = os.path.splitext(FN)[1]
-	tmpSub = Subtitles(FN)
-	if extension in tmpSub.getSupportedTypes():
-	    #TODO: We should improve the way we check subtitles
-	    tmpSub.subLoad(FN)
-	    self.Subtitle = tmpSub
-	    self.Subtitles.append(tmpSub)
-	    self.updateStreamWindow()
-	else:
-	    #TODO: Check if it is media or throw error
-	    MI = MediaInfo(FN, URI)
-	    # Lets poll for information
-	    gobject.timeout_add(30, self.addMedia, MI)
-
-#==============================================================================
-    def cb_addNewStream(self, widget):
-        if(self.windowMediaOpen==None):
-            self.windowMediaOpen=gtk.glade.XML (self.gladefile,"OPEN_MEDIA")
-            dic={"on_OPEN_BUTTON_CANCEL_clicked": self.cb_openMediaCancel,\
-                "on_OPEN_BUTTON_OPEN_clicked": self.cb_openMediaOpen }
-            self.windowMediaOpen.signal_autoconnect(dic)
-        else:
-            WND=self.windowMediaOpen.get_widget("OPEN_MEDIA")
-            if not WND:
-                self.windowMediaOpen=None
-            else:
-                WND.show()
-        return
-#==============================================================================
-    def cb_onNewMenu(self, menu):
-        if self.windowStreams:
-            WND=self.windowStreams.get_widget("STREAM_WINDOW")
-            WND.show()
-#==============================================================================
-    def cb_onSubsListSelect(self, widget, event):
-	"""
-	    Do the proper thing when subtitle is selected
-	    2 clicks seeks de video to its timecode
-	    1 click edits on the TextView
-	"""
-	#FIXME: Something nasty happens on the selection of the subtitle
-	# Only happens the first time and throws an exception
-	Row=None
-	Selection = widget.get_selection()
-	if Selection==None:
-	    return
-	Model, Rows = Selection.get_selected_rows()
-	if Rows != None:
-	    Row = Model[Rows[0][0]]
-	    if self.Subtitle:
-		Sub = self.Subtitle.subs[Row[1]]
-	if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
-	    if self.player:
-		B=0;
-		self.player.set_subtitle_text(Sub.text)
-		if self.player.is_playing():
-		    B=1
-		    self.play_toggled()
-		real = long(Row[1]) # in ns
-		self.player.seek(real*1000000)
-		# allow for a preroll
-		self.player.get_state(timeout=50*gst.MSECOND) # 50 ms
-		if B==1:
-		    self.play_toggled()
-	if event.type == gtk.gdk.BUTTON_RELEASE:
-	    model, self.cur_edit_sub_iter =  Selection.get_selected() 
-	    self.setSubtitleEdit(Sub.text)
-#==============================================================================
-    def cb_onSubTextEdited(self, cell, path, new_text):
-	"""
-	    Callback to change subtitle when subtitle text was changed
-	"""
-	iter = self.subsListStore.get_iter(path)
-	subKey, ETime, Text = self.subsListStore.get(iter, 1, 2, 3)
-	subtitle = self.Subtitle.getSub(subKey)
-	if subtitle.text != new_text:
-	    subAttr = subtitle.Attributes
-	    self.Subtitle.subDel(subKey)
-	    self.Subtitle.subAdd(subKey,ETime,new_text,subAttr,1)
-	    self.subsListStore.set(iter,3,new_text)
-
-        return True
-#==============================================================================
-    def cb_onSubtitleEdit(self, widget, event):
-	"""
-	    Updates the subtile list in realtime
-	"""
-	id, subKey, ETime = self.subsListStore.get(self.cur_edit_sub_iter, 0, 1, 2)
-	#self.Subtitle.subDel(subKey)
-	text = self.txt_subedit.get_buffer().get_property('text')
-	self.Subtitle.updateText(subKey,text)
-	#self.Subtitle.subAdd(subKey,ETime,text,None,0)
-	self.subsListStore.set(self.cur_edit_sub_iter, 3, text) 
-	return
-#==============================================================================
-    def setSubtitleEdit(self,sub):
-	"""
-	    Set the subtitle to be edited
-	"""
-	buf = self.txt_subedit.get_buffer()
-	buf.set_text(sub)
-#==============================================================================
-    def subsWindowUpdate(self):
-        if not self.Subtitle:
-            return
-	# We have removed the window for now
-        #if self.windowSubsList:
-	self.subsListStore.clear()
-	j=0
-	for i in self.Subtitle.subKeys:
-	    S=self.Subtitle.subs[i]
-	    iter = self.subsListStore.append(None)
-	    self.subsListStore.set(iter,0, j, 
-					1, int(S.start_time),
-					2, int(S.end_time),
-					3, str(S.text))
-	    j +=1
-#==============================================================================
-    def saveProject(self):
-        if not self.PFileName:
-            return
-        if self.PFileName[-4:]!=".spf":
-            self.PFileName=self.PFileName+".spf"
-        PXML=ProjectXML()
-        PXML.addHeadInfo("title", "Soufleur development version")
-        PXML.addHeadInfo("desc", "This is version current at development stage.")
-        PXML.addHeadInfo("author", "DarakuTenshi")
-        PXML.addHeadInfo("email", "otaky at ukr.net")
-        PXML.addHeadInfo("info", "Sample of save function")
-        for i in self.media:
-            PXML.addMedia(i)
-        for i in self.Subtitles:
-            PXML.addSubtitle(i)
-        PXML.write(self.PFileName)
-#==============================================================================
-    def cb_projectSaveOpen(self, widget):
-        WND=self.windowProjectSO.get_widget("SAVE_OPEN_PFILE")
-        self.PFileName=WND.get_filename()
-        self.saveProject()
-        WND.hide()
-#==============================================================================
-    def cb_projectSaveCancel(self, widget):
-        if(self.windowProjectSO==None): return
-        WND=self.windowProjectSO.get_widget("SAVE_OPEN_PFILE")
-        WND.hide()
-#==============================================================================
-    def cb_onSaveAsMenu(self, widget):
-        self.PFileName=None
-        self.cb_onSaveMenu(widget)
-#==============================================================================
-    def cb_onSaveMenu(self, widget):
-        if self.PFileName:
-            self.saveProject()
-            return
-        if(self.windowProjectSO==None):
-            self.windowProjectSO=gtk.glade.XML (self.gladefile,"SAVE_OPEN_PFILE")
-            dic={"on_PROJECT_BUTTON_CANCEL_clicked": self.cb_projectSaveCancel,\
-                "on_PROJECT_BUTTON_OK_clicked": self.cb_projectSaveOpen }
-            self.windowProjectSO.signal_autoconnect(dic)
-            WND=self.windowProjectSO.get_widget("SAVE_OPEN_PFILE")
-            WND.set_action(gtk.FILE_CHOOSER_ACTION_SAVE)
-            OKB = self.windowProjectSO.get_widget("PROJECT_BUTTON_OK")
-            OKB.set_label("gtk-save")
-            OKB.set_use_stock(True)
-            Filter=gtk.FileFilter()
-            Filter.set_name("Souffleur project file")
-            Filter.add_pattern("*.spf")
-            WND.add_filter(Filter)
-        else:
-            WND=self.windowProjectSO.get_widget("SAVE_OPEN_PFILE")
-            if(WND==None):
-                self.windowProjectSO=None
-                self.cb_onSaveMenu(widget)
-            else:
-                WND.show()
-#==============================================================================
-    def cb_setSubStartTime(self, widget):
-        self.subStartTime.set_value(self.p_position/1000000)
-#==============================================================================
-    def cb_setSubEndTime(self, widget):
-        self.subEndTime.set_value(self.p_position/1000000)
-#==============================================================================
-    def setSubStartTime(self, time):
-        self.subStartTime.set_value(time)
-#==============================================================================
-    def setSubEndTime(self, time):
-        self.subEndTime.set_value(time)
-#==============================================================================
-    def exposeEventVideoOut(self, widget, event):
-        if self.videoWidgetGst:
-            self.videoWidgetGst.do_expose_event(event)
-#==============================================================================
-    def changeValueAdjustment(self, widget, t1, t2):
-        #if (not self.scroll):
-            real = long(self.adjustment.get_value()) # in ns
-            self.player.seek(real)
-            # allow for a preroll
-            self.player.get_state(timeout=50*gst.MSECOND) # 50 ms
-
-#==============================================================================
-    def buttonReleaseAdjustment(self, widget, event):
-        self.scroll=0
-#==============================================================================
-    def buttonPressAdjustment(self, widget, event):
-        self.scroll=1
-#==============================================================================
-    def playerStop(self, widget):
-        if self.player:
-            if self.player.is_playing():
-                self.play_toggled()
-            self.player.stop()
-#==============================================================================
-    def playerPlay(self, widget):
-        if self.player:
-            self.play_toggled()
-#==============================================================================
-    def playerSlowMotion(self, widget):
-	"""
-	    Put the current playing video in slow motion
-	"""
-	#TODO: Implement it
-	pass
-#==============================================================================
-    def playerFastForward(self, widget):
-	"""
-	    Put the current playing video in FastForward 
-	"""
-	#TODO: Implement it
-	pass
-#==============================================================================
-    def playerSeekForward(self, widget):
-	"""
-	    Jump some time beyond current position
-	"""
-	#TODO: Implement it
-	pass
-#==============================================================================
-    def playerSeekRewind(self, widget):
-	"""
-	    Jump back som time
-	"""
-	#TODO: Implement it
-	pass
-#==============================================================================
-    def mainFileOpen(self, widget):
-        if(self.windowProjectOpen==None):
-            self.windowProjectOpen=gtk.glade.XML (self.gladefile,"SAVE_OPEN_PFILE")
-            dic={"on_PROJECT_BUTTON_CANCEL_clicked": self.openFileCancel,\
-                "on_PROJECT_BUTTON_OK_clicked": self.openFileOpen }
-            self.windowProjectOpen.signal_autoconnect(dic)
-            WND=self.windowProjectOpen.get_widget("SAVE_OPEN_PFILE")
-            WND.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
-            OKB = self.windowProjectOpen.get_widget("PROJECT_BUTTON_OK")
-            OKB.set_label("gtk-open")
-            OKB.set_use_stock(True)
-            Filter=gtk.FileFilter()
-            Filter.set_name("Souffleur project file")
-            Filter.add_pattern("*.spf")
-            WND.add_filter(Filter)
-        else:
-            WND=self.windowProjectOpen.get_widget("SAVE_OPEN_PFILE")
-            if(WND==None):
-                self.windowProjectOpen=None
-                self.mainFileOpen(widget)
-            else:
-                WND.show()
-        return
-#==============================================================================
-    def openFileCancel(self, widget):
-        if(self.windowProjectOpen==None): return
-        WND=self.windowProjectOpen.get_widget("SAVE_OPEN_PFILE")
-        WND.hide()
-        return
-#==============================================================================
-    def openFileOpen(self, widget):
-        WND=self.windowProjectOpen.get_widget("SAVE_OPEN_PFILE")
-        self.PFileName=WND.get_filename()
-        WND.hide()
-        PXML=ProjectXML()
-        PXML.load(self.PFileName)
-        for i in PXML.getMedia():
-            self.addMedia(i)
-        self.Subtitles=[]
-        for i in PXML.getSubtitle():
-            self.Subtitles.append(i)
-        if len(self.media)>0:
-            WND=self.windowStreams.get_widget("STREAM_WINDOW")
-            WND.show()
-        return
-#==============================================================================
-    def addMedia(self, mInfo):
-        if not mInfo:
-            return
-	# Frist, wait for media discovery 
-	if mInfo.poll():
-	    return True 
-	mInfo = mInfo.getMedia()
-        self.media.append(mInfo)
-        self.updateStreamWindow()
-	#Set videoWidget sizes according to media standards
-	self.videoWidget.set_size_request(mInfo.videoWidth, mInfo.videoHeight)
-	self.videoWidgetGst=VideoWidget(self.videoWidget)
-	self.player=GstPlayer(self.videoWidgetGst)
-	self.player.set_location("file://"+mInfo.source)
-	if self.videoWidget.flags() & gtk.REALIZED:
-	    self.play_toggled()
-	else:
-	    self.videoWidget.connect_after('realize',
-				       lambda *x: self.play_toggled())
-        return
-#==============================================================================
-    def play_toggled(self):
-        if self.player.is_playing():
-            self.player.pause()
-            self.playButton.set_stock_id(gtk.STOCK_MEDIA_PLAY)
-            #self.playButton.set_icon_name(gtk.STOCK_MEDIA_PLAY)
-	    if gobject.source_remove(self.update_id):
-		    self.update_id = -1
-        else:
-            self.player.play()
-            if self.update_id == -1:
-                self.update_id = gobject.timeout_add(self.UPDATE_INTERVAL,
-                                                     self.update_scale_cb)
-            self.playButton.set_stock_id(gtk.STOCK_MEDIA_PAUSE)
-#==============================================================================
-    def update_scale_cb(self):
-        had_duration = self.p_duration != gst.CLOCK_TIME_NONE
-        self.p_position, self.p_duration = self.player.query_position()
-        if self.p_duration != self.t_duration:
-            self.t_duration = self.p_duration
-            self.adjustment.set_range(0, self.t_duration)
-        tmSec= self.p_position/1000000
-        MSec = tmSec
-        tmSec = tmSec/1000
-        Sec = tmSec%60
-        tmSec = tmSec/60
-        Min = tmSec%60
-        Hour = tmSec/60
-        if self.Subtitle:
-            TText = self.Subtitle.getSub(MSec)
-            if self.player.is_playing():
-                if TText:
-		    self.player.set_subtitle_text(TText.text)
-		    #TODO: Select the current playing subtitle
-		    # Careful with any processor intesive tasks here
-		    # !!!Critical loop!!!
-                else:
-		    self.player.set_subtitle_text('')
-		    # Unselect what is not being played
-		    Selection = self.subList.get_selection()
-		    if Selection:
-			Selection.unselect_all()
-        if (self.p_position != gst.CLOCK_TIME_NONE):# and (not self.scroll):
-            value = self.p_position
-            self.adjustment.set_value(value)
-        self.labelHour.set_text("%02d"%Hour)
-        self.labelMin.set_text("%02d"%Min)
-        self.labelSec.set_text("%02d"%Sec)
-	#BUG: We are not displaying that correctly
-        self.labelMSec.set_text("%09d"%MSec)
-	#FIXME: We should know which media is playing
-	self.lbl_cur_fps.set_text("%d"%(MSec/1/self.media[0].framerate))
-        return True
-#==============================================================================
-#	MAIN:
-#==============================================================================
-souffleur=Souffleur()
-gtk.main()

Copied: trunk/subtle/Subtle.py (from rev 14790, trunk/subtle/Souffleur.py)
===================================================================
--- trunk/subtle/Subtle.py	                        (rev 0)
+++ trunk/subtle/Subtle.py	2008-04-23 18:01:02 UTC (rev 14791)
@@ -0,0 +1,812 @@
+#!/usr/bin/env python
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+from GPlayer import VideoWidget
+from GPlayer import GstPlayer
+from Subtitles import Subtitles
+import sys
+import os
+
+from MediaInfo import MediaInfo
+from SouffleurXML import ProjectXML
+
+try:
+    import pygtk
+    #tell pyGTK, if possible, that we want GTKv2
+    pygtk.require("2.0")
+except:
+    #Some distributions come with GTK2, but not pyGTK
+    pass
+try:
+    import gtk
+    import gobject
+    import gtk.glade
+except:
+    print "You need to install pyGTK or GTKv2 ",
+    print "or set your PYTHONPATH correctly."
+    print "try: export PYTHONPATH=",
+    print "/usr/local/lib/python2.2/site-packages/"
+    sys.exit(1)
+#now we have both gtk and gtk.glade imported
+#Also, we know we are running GTK v2
+import gst
+
+class Souffleur:
+    def __init__(self):
+        """
+        In this init we are going to display the main
+        Souffleur window
+        """
+        gladefile="souffleur.glade"
+        windowname="MAIN_WINDOW"
+        
+        self.update_id = -1
+        self.p_position = gst.CLOCK_TIME_NONE
+        self.p_duration = gst.CLOCK_TIME_NONE
+        self.UPDATE_INTERVAL=100
+        
+        self.Subtitle = None
+        self.Subtitles = []
+	# Current subtitle being edited
+	self.cur_edit_sub_iter = None
+
+        #self.scroll = 0
+        self.videoWidgetGst = None
+        self.player = None
+        self.t_duration = 0
+        self.media = []
+
+        self.wTree=gtk.glade.XML(gladefile,windowname)
+        self.gladefile = gladefile
+        dic = { "gtk_main_quit" : (gtk.main_quit),\
+            "on_main_file_quit_activate": (gtk.main_quit), \
+            "on_main_file_open_activate": self.mainFileOpen, \
+            "on_TOOL_PLAY_clicked": self.playerPlay,\
+            "on_TOOL_STOP_clicked": self.playerStop,\
+            "on_TOOL_SEEK_FORWARD_clicked": self.playerSeekForward,\
+            "on_TOOL_SEEK_REWIND_clicked": self.playerSeekRewind,\
+            "on_TOOL_HIDE_STREAMS_clicked": self.cb_hideStreamsPane,\
+            "on_TOOL_HIDE_SUBLIST_clicked": self.cb_hideSubPane,\
+            "on_MEDIA_ADJUSTMENT_button_press_event": self.buttonPressAdjustment,\
+            "on_MEDIA_ADJUSTMENT_button_release_event": self.buttonReleaseAdjustment,\
+            "on_MEDIA_ADJUSTMENT_change_value": self.changeValueAdjustment,\
+            "on_VIDEO_OUT_PUT_expose_event": self.exposeEventVideoOut,\
+            "on_main_file_save_activate": self.cb_onSaveMenu,\
+            "on_main_file_save_as_activate": self.cb_onSaveAsMenu,\
+            "on_main_file_new_activate": self.cb_onNewMenu,\
+            "on_MAIN_VIEW_STREAMS_PANE_activate": self.cb_showStreamsPane,\
+            "on_MAIN_VIEW_SUBTITLES_activate": self.cb_showSubtitlePane,\
+            "on_TOOL_DEL_STREAM_clicked": self.cb_delStream,\
+	    "on_TOOL_MOD_STREAM_clicked": self.cb_modStream,\
+	    "on_TOOL_NEW_STREAM_clicked": self.cb_newStream,\
+	    "on_TOOL_ADD_STREAM_clicked": self.cb_addNewStream,\
+	    "on_LIST_SUBS_button_release_event": self.cb_onSubsListSelect,\
+	    "on_LIST_SUBS_button_press_event": self.cb_onSubsListSelect,\
+	    "on_txt_subedit_key_release_event": self.cb_onSubtitleEdit,\
+	    "on_TOOL_SAVE_STREAM_clicked": self.cb_saveStream,\
+	    "on_TOOL_DEL_SUBS_clicked": self.cb_subDel,\
+	    "on_TOOL_OUT_SUB_clicked": self.cb_subOut,\
+	    "on_TOOL_IN_SUB_clicked": self.cb_subIn,\
+	    "on_TOOL_INS_B4_SUB_clicked": self.cb_onSubInsB4,\
+	    "on_TOOL_INS_AFTER_SUB_clicked": self.cb_onSubInsAfter,\
+	    "on_TOOL_IN_SUB_clicked": self.cb_subIn}
+        self.wTree.signal_autoconnect (dic)
+        
+	self.windowMainWindow=self.wTree.get_widget("MAIN_WINDOW")
+        self.windowProjectOpen=None
+        self.windowProjectSO=None
+        self.PFileName=None
+        self.windowMediaOpen=None
+        #self.windowStreams=gtk.glade.XML (self.gladefile,"STREAM_WINDOW")
+        #dic = {"on_TOOL_DEL_STREAM_clicked": self.cb_delStream,\
+        #        "on_TOOL_MOD_STREAM_clicked": self.cb_modStream,\
+        #        "on_TOOL_NEW_STREAM_clicked": self.cb_newStream,\
+        #        "on_TOOL_ADD_STREAM_clicked": self.cb_addNewStream,\
+        #        "on_STREAM_WINDOW_delete_event": self.cb_StreamWindowDelete}
+        #self.windowStreams.signal_autoconnect (dic)
+        ### Setup LIST_STREAMS
+        #LIST = self.windowStreams.get_widget("LIST_STREAMS")
+        LIST = self.wTree.get_widget("LIST_STREAMS")
+        if LIST:
+            self.streamsTreeStore = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_UINT)
+            LIST.set_model(self.streamsTreeStore)
+            cell = gtk.CellRendererText()
+            tvcolumn = gtk.TreeViewColumn('Streams', cell, text = 0)
+            LIST.append_column(tvcolumn)
+        
+        #self.windowSubsList=gtk.glade.XML (self.gladefile,"SUBS_LIST")
+        #dic = {"on_LIST_SUBS_cursor_changed": self.cb_onSubsListSelect,\
+        #        "on_TOOL_SAVE_STREAM_clicked": self.cb_saveStream,\
+        #        "on_TOOL_DEL_SUBS_clicked": self.cb_subDel,\
+        #        "on_TOOL_OUT_SUB_clicked": self.cb_subOut,\
+        #        "on_TOOL_IN_SUB_clicked": self.cb_subIn,\
+        #        "on_TOOL_INS_B4_SUB_clicked": self.cb_onSubInsB4,\
+        #        "on_TOOL_INS_AFTER_SUB_clicked": self.cb_onSubInsAfter,\
+        #        "on_TOOL_IN_SUB_clicked": self.cb_subIn,\
+        #        "on_SUBS_LIST_delete_event": self.cb_onSubsWindowDelete}
+        #self.windowSubsList.signal_autoconnect (dic)
+        #SUBLIST = self.windowSubsList.get_widget("LIST_SUBS")
+        SUBLIST = self.wTree.get_widget("LIST_SUBS")
+	SUBLIST.add_events(gtk.gdk._2BUTTON_PRESS)
+        if SUBLIST:
+            self.subsListStore = gtk.ListStore(gobject.TYPE_UINT,
+                                                gobject.TYPE_UINT,
+						gobject.TYPE_UINT,
+                                                gobject.TYPE_STRING)
+            SUBLIST.set_model(self.subsListStore)
+            cell = gtk.CellRendererText()
+            tvcolumn = gtk.TreeViewColumn('#', cell, text = 0)
+            SUBLIST.append_column(tvcolumn)
+            cell = gtk.CellRendererText()
+            tvcolumn = gtk.TreeViewColumn('Start', cell, text = 1)
+            SUBLIST.append_column(tvcolumn)
+            cell = gtk.CellRendererText()
+            tvcolumn = gtk.TreeViewColumn('End', cell, text = 2)
+            SUBLIST.append_column(tvcolumn)
+            cell = gtk.CellRendererText()
+            tvcolumn = gtk.TreeViewColumn('Text', cell, text = 3)
+	    tvcolumn.set_resizable(True)
+            SUBLIST.append_column(tvcolumn)
+        #WND=self.windowStreams.get_widget("STREAM_WINDOW")
+        #WND.hide()
+        #WND=self.windowSubsList.get_widget("SUBS_LIST")
+        #WND.hide()
+        ### Main window setup
+        self.videoWidget = self.wTree.get_widget("VIDEO_OUT_PUT")
+        self.adjustment = self.wTree.get_widget("MEDIA_ADJUSTMENT")
+        self.labelHour = self.wTree.get_widget("LABEL_HOUR")
+        self.labelMin = self.wTree.get_widget("LABEL_MIN")
+        self.labelSec = self.wTree.get_widget("LABEL_SEC")
+        self.labelMSec = self.wTree.get_widget("LABEL_MSEC")
+        self.playButton = self.wTree.get_widget("TOOL_PLAY")
+	self.lbl_cur_fps = self.wTree.get_widget("lbl_cur_fps")
+	self.streams_pane = self.wTree.get_widget("streams_pane")
+	self.subtitle_pane = self.wTree.get_widget("subtitle_pane")
+	self.txt_subedit = self.wTree.get_widget("txt_subedit")
+	self.subList = SUBLIST
+	#self.windowMainWindow.maximize()
+        return
+#==============================================================================
+    def cb_hideSubPane(self, widget):
+	"""
+	    Hide the subtitles pane
+	"""
+	self.subtitle_pane.hide()
+	return
+#==============================================================================
+    def cb_hideStreamsPane(self, widget):
+	"""
+	    Hide the streams pane
+	"""
+	self.streams_pane.hide()
+	return
+#==============================================================================
+    def cb_showStreamsPane(self, widget):
+	"""
+	    Hide the streams pane
+	"""
+	self.streams_pane.show()
+	return
+#==============================================================================
+    def cb_onSubInsB4(self, widget):
+	"""
+	    Insert new subtitle before current selected
+	"""
+	subsList = self.wTree.get_widget("LIST_SUBS")
+	selection = subsList.get_selection()
+	result = selection.get_selected()
+	if result:
+            model, iter = result
+	    if self.subsListStore.iter_is_valid(iter):
+		cur, sTime, eTime = self.subsListStore.get(iter, 0, 1, 2)
+		self.Subtitle.subAdd(sTime-1,sTime-2,'',None,1)
+		self.subsListStore.insert_before(iter, (cur, sTime-1, sTime-2, 'New subtitle...'))
+		self.reorder_SubsListStore()
+	return
+#==============================================================================
+    def cb_onSubInsAfter(self, widget):
+	"""
+	    Insert new subtitle after current selected
+	"""
+	subsList = self.wTree.get_widget("LIST_SUBS")
+	selection = subsList.get_selection()
+	result = selection.get_selected()
+	if result:
+            model, iter = result
+	    if self.subsListStore.iter_is_valid(iter):
+		cur, sTime, eTime = self.subsListStore.get(iter, 0, 1, 2)
+		self.Subtitle.subAdd(eTime+1,eTime+2,'',None,1)
+		cur += 1
+		self.subsListStore.insert_after(iter, (cur, eTime+1, eTime+2, 'New subtitle...'))
+		self.reorder_SubsListStore()
+	return
+#==============================================================================
+    def reorder_SubsListStore(self):
+	"""
+	    Reorder the subs listStore when added or deleted
+	"""
+	iter = self.subsListStore.get_iter_first()
+	cur = 0
+	while iter is not None:
+	    if iter is not None:
+		self.subsListStore.set_value(iter, 0, cur)
+		cur += 1
+		iter = self.subsListStore.iter_next(iter)
+#==============================================================================
+    def cb_subDel(self, widget):
+	"""
+	    Delete a subtile from the list store and from memory
+	"""
+	subsList = self.wTree.get_widget("LIST_SUBS")
+	selection = subsList.get_selection()
+	result = selection.get_selected()
+	if result:
+            model, iter = result
+	    subKey = self.subsListStore.get(iter, 1)
+            self.Subtitle.subDel(subKey[0])
+	    model.remove(iter)
+	    self.reorder_SubsListStore()
+#==============================================================================
+    def cb_subOut(self, widget):
+	"""
+	    Set subtitle endtime
+	"""
+	if self.player:
+	    subsList = self.windowSubsList.get_widget("LIST_SUBS")
+	    selection = subsList.get_selection()
+	    result = selection.get_selected()
+	    if result:
+		model, iter = result
+		subKey, end_time = self.subsListStore.get(iter, 1, 2)
+		try:
+		    self.Subtitle.getSub(subKey).end_time = self.p_position/1000000
+		    self.Subtitle.subUpdate(subKey)
+		except:
+		    print "Error while setting subtitle timecode"
+		    return
+		self.subsListStore.set(iter,2,self.p_position/1000000)
+	return True
+#==============================================================================
+    def cb_subIn(self, widget):
+	"""
+	    Set subtitle start time
+	"""
+	if self.player:
+	    subsList = self.windowSubsList.get_widget("LIST_SUBS")
+	    selection = subsList.get_selection()
+	    result = selection.get_selected()
+	    if result:
+		model, iter = result
+		subKey = self.subsListStore.get(iter, 1)
+		try:
+		    self.Subtitle.getSub(subKey[0]).start_time = self.p_position/1000000
+		    self.Subtitle.subUpdate(subKey[0])
+		except:
+		    print "Error while setting subtitle timecode"
+		    return
+		self.subsListStore.set(iter,1,self.p_position/1000000)
+	return True
+#==============================================================================
+    def cb_onSubsWindowDelete(self, widget, event):
+        widget.hide()
+        return True
+#==============================================================================
+    def cb_StreamWindowDelete(self, widget, event):
+        widget.hide()
+        return True
+#==============================================================================
+    def cb_onSubtitleWindow(self, menu):
+        if self.windowSubsList:
+            WND=self.windowSubsList.get_widget("SUBS_LIST")
+            WND.show()
+#==============================================================================
+    def cb_showSubtitlePane(self, menu):
+	"""
+	   Show subtitle pane
+	"""
+	self.subtitle_pane.show()
+#==============================================================================
+    def cb_onStreamsWindow(self, menu):
+        if self.windowStreams:
+            WND=self.windowStreams.get_widget("STREAM_WINDOW")
+            WND.show()
+#==============================================================================
+    def getSubtitle(self, source):
+        for i in self.Subtitles:
+            if i.subSource==source:
+                return i
+        return None
+#==============================================================================
+    def cb_saveStream(self, widget):
+        if not self.windowStreams:
+            return
+        if not self.streamsTreeStore:
+            return
+        TView = self.windowStreams.get_widget("LIST_STREAMS")
+        TSelec = TView.get_selection()
+        TModel, TIter = TSelec.get_selected()
+        if not TIter:
+            return
+        N=TModel.get_value(TIter, 1)
+        mInfo = self.media[N]
+        if "subtitle" in mInfo.MIME:
+            tSubtitle = self.getSubtitle(mInfo.Streams[0].ID)
+            tSubtitle.subSave(mInfo.source, 1)
+#==============================================================================
+    def cb_modStream(self, widget):
+	# We have removed the window
+        #if not self.windowStreams:
+        #    return
+        if not self.streamsTreeStore:
+            return
+        #TView = self.windowStreams.get_widget("LIST_STREAMS")
+        TView = self.wTree.get_widget("LIST_STREAMS")
+        TSelec = TView.get_selection()
+        TModel, TIter = TSelec.get_selected()
+        if not TIter:
+            return
+        N=TModel.get_value(TIter, 0)
+	# FIXME: We should actually get the selected subtitle
+	if "Subtitle" in N:
+	    self.setSubtitle()
+#==============================================================================
+    def cb_newStream(self, widget):
+	"""
+	   Create a new subtitle
+	"""
+	print "Create a new stream"
+	#TODO: Lets popup something that will let us choose sub type
+	return
+#==============================================================================
+    def setSubtitle(self):
+        if self.Subtitle:
+	    # We have removed the window for now
+            #if (self.windowStreams):
+            #    WND=self.windowSubsList.get_widget("SUBS_LIST")
+            #    WND.show()
+            self.subsWindowUpdate()
+#==============================================================================
+    def updateStreamWindow(self):
+	#FIXME: This should be more complete and better handled
+	# Maybe all streams must be on the same list/dict
+        if not self.streamsTreeStore:
+            return
+        self.streamsTreeStore.clear()
+	for sub in self.Subtitles:
+            iter = self.streamsTreeStore.append(None)
+	    self.streamsTreeStore.set(iter, 0, "Subtitle: "+ sub.filename, 1, self.Subtitles.index(sub))
+	    child = self.streamsTreeStore.append(iter)
+	    self.streamsTreeStore.set(child, 0, "Type: " + sub.subType, \
+		    1, self.Subtitles.index(sub))
+        for mInfo in self.media:
+            iter = self.streamsTreeStore.append(None)
+            self.streamsTreeStore.set(iter, 0, mInfo.source, 1, self.media.index(mInfo))
+	    if mInfo.has_video:
+                child = self.streamsTreeStore.append(iter)
+		self.streamsTreeStore.set(child, 0, "Mimetype: " + mInfo.MIME.split("/")[1], \
+			1, self.media.index(mInfo))
+                child = self.streamsTreeStore.append(iter)
+		self.streamsTreeStore.set(child, 0, "Resolution: %dx%d "% (mInfo.videoWidth, mInfo.videoHeight), \
+			1, self.media.index(mInfo))
+                child = self.streamsTreeStore.append(iter)
+		self.streamsTreeStore.set(child, 0, ("Framerate: %.2f" % mInfo.framerate), \
+			1, self.media.index(mInfo))
+                child = self.streamsTreeStore.append(iter)
+		self.streamsTreeStore.set(child, 0, ("Length: %s s" % mInfo.videoLengthS), \
+			1, self.media.index(mInfo))
+                child = self.streamsTreeStore.append(iter)
+		self.streamsTreeStore.set(child, 0, ("Frames: %d" % (mInfo.videoLengthS/(1/mInfo.framerate))), \
+			1, self.media.index(mInfo))
+                child = self.streamsTreeStore.append(iter)
+#==============================================================================
+    def cb_delStream(self, widget):
+	"""
+	    Remove a stream from the current project
+	"""
+	#FIXME: We broke this ...
+        if not self.windowStreams:
+            return
+        if not self.streamsTreeStore:
+            return
+        TView = self.windowStreams.get_widget("LIST_STREAMS")
+        TSelec = TView.get_selection()
+        TModel, TIter = TSelec.get_selected()
+        if not TIter:
+            return
+        N=TModel.get_value(TIter, 1)
+        self.updateStreamWindow()
+#==============================================================================
+    def cb_openMediaCancel(self, widget):
+        if self.windowMediaOpen:
+            WND=self.windowMediaOpen.get_widget("OPEN_MEDIA")
+            WND.hide()
+#==============================================================================
+    def cb_openMediaOpen(self, widget):
+        WND=self.windowMediaOpen.get_widget("OPEN_MEDIA")
+        FN=WND.get_filename()
+        URI=WND.get_uri()
+	self.TEST_SUB_URI = URI
+        WND.hide()
+
+	extension = os.path.splitext(FN)[1]
+	tmpSub = Subtitles(FN)
+	if extension in tmpSub.getSupportedTypes():
+	    #TODO: We should improve the way we check subtitles
+	    tmpSub.subLoad(FN)
+	    self.Subtitle = tmpSub
+	    self.Subtitles.append(tmpSub)
+	    self.updateStreamWindow()
+	else:
+	    #TODO: Check if it is media or throw error
+	    MI = MediaInfo(FN, URI)
+	    # Lets poll for information
+	    gobject.timeout_add(30, self.addMedia, MI)
+
+#==============================================================================
+    def cb_addNewStream(self, widget):
+        if(self.windowMediaOpen==None):
+            self.windowMediaOpen=gtk.glade.XML (self.gladefile,"OPEN_MEDIA")
+            dic={"on_OPEN_BUTTON_CANCEL_clicked": self.cb_openMediaCancel,\
+                "on_OPEN_BUTTON_OPEN_clicked": self.cb_openMediaOpen }
+            self.windowMediaOpen.signal_autoconnect(dic)
+        else:
+            WND=self.windowMediaOpen.get_widget("OPEN_MEDIA")
+            if not WND:
+                self.windowMediaOpen=None
+            else:
+                WND.show()
+        return
+#==============================================================================
+    def cb_onNewMenu(self, menu):
+        if self.windowStreams:
+            WND=self.windowStreams.get_widget("STREAM_WINDOW")
+            WND.show()
+#==============================================================================
+    def cb_onSubsListSelect(self, widget, event):
+	"""
+	    Do the proper thing when subtitle is selected
+	    2 clicks seeks de video to its timecode
+	    1 click edits on the TextView
+	"""
+	#FIXME: Something nasty happens on the selection of the subtitle
+	# Only happens the first time and throws an exception
+	Row=None
+	Selection = widget.get_selection()
+	if Selection==None:
+	    return
+	Model, Rows = Selection.get_selected_rows()
+	if Rows != None:
+	    Row = Model[Rows[0][0]]
+	    if self.Subtitle:
+		Sub = self.Subtitle.subs[Row[1]]
+	if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
+	    if self.player:
+		B=0;
+		self.player.set_subtitle_text(Sub.text)
+		if self.player.is_playing():
+		    B=1
+		    self.play_toggled()
+		real = long(Row[1]) # in ns
+		self.player.seek(real*1000000)
+		# allow for a preroll
+		self.player.get_state(timeout=50*gst.MSECOND) # 50 ms
+		if B==1:
+		    self.play_toggled()
+	if event.type == gtk.gdk.BUTTON_RELEASE:
+	    model, self.cur_edit_sub_iter =  Selection.get_selected() 
+	    self.setSubtitleEdit(Sub.text)
+#==============================================================================
+    def cb_onSubTextEdited(self, cell, path, new_text):
+	"""
+	    Callback to change subtitle when subtitle text was changed
+	"""
+	iter = self.subsListStore.get_iter(path)
+	subKey, ETime, Text = self.subsListStore.get(iter, 1, 2, 3)
+	subtitle = self.Subtitle.getSub(subKey)
+	if subtitle.text != new_text:
+	    subAttr = subtitle.Attributes
+	    self.Subtitle.subDel(subKey)
+	    self.Subtitle.subAdd(subKey,ETime,new_text,subAttr,1)
+	    self.subsListStore.set(iter,3,new_text)
+
+        return True
+#==============================================================================
+    def cb_onSubtitleEdit(self, widget, event):
+	"""
+	    Updates the subtile list in realtime
+	"""
+	id, subKey, ETime = self.subsListStore.get(self.cur_edit_sub_iter, 0, 1, 2)
+	#self.Subtitle.subDel(subKey)
+	text = self.txt_subedit.get_buffer().get_property('text')
+	self.Subtitle.updateText(subKey,text)
+	#self.Subtitle.subAdd(subKey,ETime,text,None,0)
+	self.subsListStore.set(self.cur_edit_sub_iter, 3, text) 
+	return
+#==============================================================================
+    def setSubtitleEdit(self,sub):
+	"""
+	    Set the subtitle to be edited
+	"""
+	buf = self.txt_subedit.get_buffer()
+	buf.set_text(sub)
+#==============================================================================
+    def subsWindowUpdate(self):
+        if not self.Subtitle:
+            return
+	# We have removed the window for now
+        #if self.windowSubsList:
+	self.subsListStore.clear()
+	j=0
+	for i in self.Subtitle.subKeys:
+	    S=self.Subtitle.subs[i]
+	    iter = self.subsListStore.append(None)
+	    self.subsListStore.set(iter,0, j, 
+					1, int(S.start_time),
+					2, int(S.end_time),
+					3, str(S.text))
+	    j +=1
+#==============================================================================
+    def saveProject(self):
+        if not self.PFileName:
+            return
+        if self.PFileName[-4:]!=".spf":
+            self.PFileName=self.PFileName+".spf"
+        PXML=ProjectXML()
+        PXML.addHeadInfo("title", "Soufleur development version")
+        PXML.addHeadInfo("desc", "This is version current at development stage.")
+        PXML.addHeadInfo("author", "DarakuTenshi")
+        PXML.addHeadInfo("email", "otaky at ukr.net")
+        PXML.addHeadInfo("info", "Sample of save function")
+        for i in self.media:
+            PXML.addMedia(i)
+        for i in self.Subtitles:
+            PXML.addSubtitle(i)
+        PXML.write(self.PFileName)
+#==============================================================================
+    def cb_projectSaveOpen(self, widget):
+        WND=self.windowProjectSO.get_widget("SAVE_OPEN_PFILE")
+        self.PFileName=WND.get_filename()
+        self.saveProject()
+        WND.hide()
+#==============================================================================
+    def cb_projectSaveCancel(self, widget):
+        if(self.windowProjectSO==None): return
+        WND=self.windowProjectSO.get_widget("SAVE_OPEN_PFILE")
+        WND.hide()
+#==============================================================================
+    def cb_onSaveAsMenu(self, widget):
+        self.PFileName=None
+        self.cb_onSaveMenu(widget)
+#==============================================================================
+    def cb_onSaveMenu(self, widget):
+        if self.PFileName:
+            self.saveProject()
+            return
+        if(self.windowProjectSO==None):
+            self.windowProjectSO=gtk.glade.XML (self.gladefile,"SAVE_OPEN_PFILE")
+            dic={"on_PROJECT_BUTTON_CANCEL_clicked": self.cb_projectSaveCancel,\
+                "on_PROJECT_BUTTON_OK_clicked": self.cb_projectSaveOpen }
+            self.windowProjectSO.signal_autoconnect(dic)
+            WND=self.windowProjectSO.get_widget("SAVE_OPEN_PFILE")
+            WND.set_action(gtk.FILE_CHOOSER_ACTION_SAVE)
+            OKB = self.windowProjectSO.get_widget("PROJECT_BUTTON_OK")
+            OKB.set_label("gtk-save")
+            OKB.set_use_stock(True)
+            Filter=gtk.FileFilter()
+            Filter.set_name("Souffleur project file")
+            Filter.add_pattern("*.spf")
+            WND.add_filter(Filter)
+        else:
+            WND=self.windowProjectSO.get_widget("SAVE_OPEN_PFILE")
+            if(WND==None):
+                self.windowProjectSO=None
+                self.cb_onSaveMenu(widget)
+            else:
+                WND.show()
+#==============================================================================
+    def cb_setSubStartTime(self, widget):
+        self.subStartTime.set_value(self.p_position/1000000)
+#==============================================================================
+    def cb_setSubEndTime(self, widget):
+        self.subEndTime.set_value(self.p_position/1000000)
+#==============================================================================
+    def setSubStartTime(self, time):
+        self.subStartTime.set_value(time)
+#==============================================================================
+    def setSubEndTime(self, time):
+        self.subEndTime.set_value(time)
+#==============================================================================
+    def exposeEventVideoOut(self, widget, event):
+        if self.videoWidgetGst:
+            self.videoWidgetGst.do_expose_event(event)
+#==============================================================================
+    def changeValueAdjustment(self, widget, t1, t2):
+        #if (not self.scroll):
+            real = long(self.adjustment.get_value()) # in ns
+            self.player.seek(real)
+            # allow for a preroll
+            self.player.get_state(timeout=50*gst.MSECOND) # 50 ms
+
+#==============================================================================
+    def buttonReleaseAdjustment(self, widget, event):
+        self.scroll=0
+#==============================================================================
+    def buttonPressAdjustment(self, widget, event):
+        self.scroll=1
+#==============================================================================
+    def playerStop(self, widget):
+        if self.player:
+            if self.player.is_playing():
+                self.play_toggled()
+            self.player.stop()
+#==============================================================================
+    def playerPlay(self, widget):
+        if self.player:
+            self.play_toggled()
+#==============================================================================
+    def playerSlowMotion(self, widget):
+	"""
+	    Put the current playing video in slow motion
+	"""
+	#TODO: Implement it
+	pass
+#==============================================================================
+    def playerFastForward(self, widget):
+	"""
+	    Put the current playing video in FastForward 
+	"""
+	#TODO: Implement it
+	pass
+#==============================================================================
+    def playerSeekForward(self, widget):
+	"""
+	    Jump some time beyond current position
+	"""
+	#TODO: Implement it
+	pass
+#==============================================================================
+    def playerSeekRewind(self, widget):
+	"""
+	    Jump back som time
+	"""
+	#TODO: Implement it
+	pass
+#==============================================================================
+    def mainFileOpen(self, widget):
+        if(self.windowProjectOpen==None):
+            self.windowProjectOpen=gtk.glade.XML (self.gladefile,"SAVE_OPEN_PFILE")
+            dic={"on_PROJECT_BUTTON_CANCEL_clicked": self.openFileCancel,\
+                "on_PROJECT_BUTTON_OK_clicked": self.openFileOpen }
+            self.windowProjectOpen.signal_autoconnect(dic)
+            WND=self.windowProjectOpen.get_widget("SAVE_OPEN_PFILE")
+            WND.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
+            OKB = self.windowProjectOpen.get_widget("PROJECT_BUTTON_OK")
+            OKB.set_label("gtk-open")
+            OKB.set_use_stock(True)
+            Filter=gtk.FileFilter()
+            Filter.set_name("Souffleur project file")
+            Filter.add_pattern("*.spf")
+            WND.add_filter(Filter)
+        else:
+            WND=self.windowProjectOpen.get_widget("SAVE_OPEN_PFILE")
+            if(WND==None):
+                self.windowProjectOpen=None
+                self.mainFileOpen(widget)
+            else:
+                WND.show()
+        return
+#==============================================================================
+    def openFileCancel(self, widget):
+        if(self.windowProjectOpen==None): return
+        WND=self.windowProjectOpen.get_widget("SAVE_OPEN_PFILE")
+        WND.hide()
+        return
+#==============================================================================
+    def openFileOpen(self, widget):
+        WND=self.windowProjectOpen.get_widget("SAVE_OPEN_PFILE")
+        self.PFileName=WND.get_filename()
+        WND.hide()
+        PXML=ProjectXML()
+        PXML.load(self.PFileName)
+        for i in PXML.getMedia():
+            self.addMedia(i)
+        self.Subtitles=[]
+        for i in PXML.getSubtitle():
+            self.Subtitles.append(i)
+        if len(self.media)>0:
+            WND=self.windowStreams.get_widget("STREAM_WINDOW")
+            WND.show()
+        return
+#==============================================================================
+    def addMedia(self, mInfo):
+        if not mInfo:
+            return
+	# Frist, wait for media discovery 
+	if mInfo.poll():
+	    return True 
+	mInfo = mInfo.getMedia()
+        self.media.append(mInfo)
+        self.updateStreamWindow()
+	#Set videoWidget sizes according to media standards
+	self.videoWidget.set_size_request(mInfo.videoWidth, mInfo.videoHeight)
+	self.videoWidgetGst=VideoWidget(self.videoWidget)
+	self.player=GstPlayer(self.videoWidgetGst)
+	self.player.set_location("file://"+mInfo.source)
+	if self.videoWidget.flags() & gtk.REALIZED:
+	    self.play_toggled()
+	else:
+	    self.videoWidget.connect_after('realize',
+				       lambda *x: self.play_toggled())
+        return
+#==============================================================================
+    def play_toggled(self):
+        if self.player.is_playing():
+            self.player.pause()
+            self.playButton.set_stock_id(gtk.STOCK_MEDIA_PLAY)
+            #self.playButton.set_icon_name(gtk.STOCK_MEDIA_PLAY)
+	    if gobject.source_remove(self.update_id):
+		    self.update_id = -1
+        else:
+            self.player.play()
+            if self.update_id == -1:
+                self.update_id = gobject.timeout_add(self.UPDATE_INTERVAL,
+                                                     self.update_scale_cb)
+            self.playButton.set_stock_id(gtk.STOCK_MEDIA_PAUSE)
+#==============================================================================
+    def update_scale_cb(self):
+        had_duration = self.p_duration != gst.CLOCK_TIME_NONE
+        self.p_position, self.p_duration = self.player.query_position()
+        if self.p_duration != self.t_duration:
+            self.t_duration = self.p_duration
+            self.adjustment.set_range(0, self.t_duration)
+        tmSec= self.p_position/1000000
+        MSec = tmSec
+        tmSec = tmSec/1000
+        Sec = tmSec%60
+        tmSec = tmSec/60
+        Min = tmSec%60
+        Hour = tmSec/60
+        if self.Subtitle:
+            TText = self.Subtitle.getSub(MSec)
+            if self.player.is_playing():
+                if TText:
+		    self.player.set_subtitle_text(TText.text)
+		    #TODO: Select the current playing subtitle
+		    # Careful with any processor intesive tasks here
+		    # !!!Critical loop!!!
+                else:
+		    self.player.set_subtitle_text('')
+		    # Unselect what is not being played
+		    Selection = self.subList.get_selection()
+		    if Selection:
+			Selection.unselect_all()
+        if (self.p_position != gst.CLOCK_TIME_NONE):# and (not self.scroll):
+            value = self.p_position
+            self.adjustment.set_value(value)
+        self.labelHour.set_text("%02d"%Hour)
+        self.labelMin.set_text("%02d"%Min)
+        self.labelSec.set_text("%02d"%Sec)
+	#BUG: We are not displaying that correctly
+        self.labelMSec.set_text("%09d"%MSec)
+	#FIXME: We should know which media is playing
+	self.lbl_cur_fps.set_text("%d"%(MSec/1/self.media[0].framerate))
+        return True
+#==============================================================================
+#	MAIN:
+#==============================================================================
+souffleur=Souffleur()
+gtk.main()



More information about the commits mailing list