diff --git a/changes.txt b/changes.txt
new file mode 100644
index 0000000..c8ada05
--- /dev/null
+++ b/changes.txt
@@ -0,0 +1,18 @@
+
+--------- TODO --------------
+
+Allow to continue a previously failed conversion
+check maximum files allowed (69)
+Allow to select subtitles in MKV files
+Render MKV subtitles in the Right Way(tm)
+Remove v4mv
+Widescreen menus
+Allow to run a command after finishing a DVD
+Check menu size and abort if it's zero
+Use asynchronous reading in the processing of the output in Mencoder, DVDAuthor and so on
+Support for a plugable menu system
+Multithread support for parallel encoding
+Allow to extract VOB files from DVDs
+Select times for chapters
+Allow for global changes to files
+Create slideshows
diff --git a/devede-debug b/devede-debug
new file mode 100644
index 0000000..44b43e4
--- /dev/null
+++ b/devede-debug
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+devede > devede.debug 2>&1
+
diff --git a/devede.desktop b/devede.desktop
new file mode 100644
index 0000000..d0d2720
--- /dev/null
+++ b/devede.desktop
@@ -0,0 +1,20 @@
+[Desktop Entry]
+X-MultipleArgs=false
+Type=Application
+Name=DeVeDe
+GenericName=DVD/CD Video Creator
+X-GNOME-FullName=DeVeDe DVD/CD Video Creator
+X-GNOME-FullName[ca]=DeVeDe creador de CD/DVDs de vídeo
+X-GNOME-FullName[es]=DeVeDe creador de CD/DVDs de vídeo
+X-GNOME-FullName[gl]=DeVeDe creador de CD/DVDs de vídeo
+X-GNOME-FullName[pl]=DeVeDe tworzenie wideo na CD/DVD
+X-GNOME-FullName[it]=DeVeDe creatore di video CD/DVD
+Comment=Allows to create video CDs and DVDs, suitable to be reproduced in home DVD players
+Comment[ca]=Permet crear CDs i DVDs de vídeo, que poden reproduir-se en reproductors domèstics
+Comment[es]=Permite crear video CDs y DVDs, que pueden reproducirse en reproductores domésticos
+Comment[gl]=Permite crear video CDs e DVDs, que poden reproducirse en reproductores domésticos
+Comment[pl]=Pozwala stworzyć wideo na płytach CD lub DVD, do otwarzania w domowych odtwarzaczach DVD
+TryExec=devede
+Exec=devede
+Categories=AudioVideo;
+Icon=devede
diff --git a/devede.py b/devede.py
new file mode 100755
index 0000000..d83a8f3
--- /dev/null
+++ b/devede.py
@@ -0,0 +1,332 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+
+import sys
+import os
+import pygtk # for testing GTK version number
+pygtk.require ('2.0')
+import gtk
+import gobject
+import subprocess
+import locale
+import gettext
+import stat
+import shutil
+import pickle
+import cairo
+
+print "DeVeDe 3.16.9"
+if (sys.platform!="win32") and (sys.platform!="win64"):
+ try:
+ print "Locale: "+str(os.environ["LANG"])
+ except:
+ print "Locale not defined"
+
+# append the directories where we install the devede's own modules
+tipo=-1
+try:
+ fichero=open("/usr/share/devede/wmain.ui","r")
+ fichero.close()
+ tipo=0
+ found=True
+except:
+ found=False
+
+if found==False:
+ try:
+ fichero=open("/usr/local/share/devede/wmain.ui","r")
+ fichero.close()
+ tipo=1
+ found=True
+ except:
+ found=False
+
+if found==False:
+ try:
+ fichero=open("./interface/wmain.ui","r")
+ fichero.close()
+ tipo=2
+ found=True
+ except:
+ found=False
+
+if tipo==0:
+ #gettext.bindtextdomain('devede', '/usr/share/locale')
+ #Note also before python 2.3 you need the following if
+ #you need translations from non python code (glibc,libglade etc.)
+ #there are other access points to this function
+ #gtk.glade.bindtextdomain("devede","/usr/share/locale")
+ #arbol=gtk.Builder("/usr/share/devede/devede.glade",domain="devede")
+ # append the directories where we install the devede's own modules
+
+ share_locale="/usr/share/locale"
+ glade="/usr/share/devede"
+ sys.path.append("/usr/lib/devede")
+ font_path="/usr/share/devede"
+ pic_path="/usr/share/devede"
+ other_path="/usr/share/devede"
+ help_path="/usr/share/doc/devede"
+ print "Using package-installed files"
+
+elif tipo==1:
+ # if the files aren't at /usr, try with /usr/local
+ #gettext.bindtextdomain('devede', '/usr/share/locale')
+ #Note also before python 2.3 you need the following if
+ #you need translations from non python code (glibc,libglade etc.)
+ #there are other access points to this function
+ #gtk.glade.bindtextdomain("devede","/usr/share/locale")
+ #arbol=gtk.Builder("/usr/local/share/devede/devede.glade",domain="devede")
+
+ share_locale="/usr/share/locale" # Are you sure?
+ # if the files aren't at /usr, try with /usr/local
+ glade="/usr/local/share/devede"
+ sys.path.append("/usr/local/lib/devede")
+ font_path="/usr/local/share/devede"
+ pic_path="/usr/local/share/devede"
+ other_path="/usr/local/share/devede"
+ help_path="/usr/local/share/doc/devede"
+ print "Using local-installed files"
+
+elif tipo==2:
+ # if the files aren't at /usr/local, try with ./
+ #gettext.bindtextdomain('devede', './po/')
+ #Note also before python 2.3 you need the following if
+ #you need translations from non python code (glibc,libglade etc.)
+ #there are other access points to this function
+ #gtk.glade.bindtextdomain("devede","/usr/share/locale")
+ #arbol=gtk.Builder("./devede.glade",domain="devede")
+
+ # if the files aren't at /usr/local, try with ./
+ share_locale="./po/"
+ glade="./interface"
+ sys.path.append(os.getcwd())#("./")
+ font_path=os.getcwd()#"./"
+ pic_path=os.path.join(font_path, "pixmaps") #pic_path=font_path
+ other_path=os.path.join(font_path,"pixmaps")
+ help_path=os.path.join(font_path,"doc")
+ print "Using direct files"
+
+else:
+ print "Can't locate extra files. Aborting."
+ sys.exit(1)
+
+
+#####################
+# GetText Stuff #
+#####################
+
+gettext.bindtextdomain('devede',share_locale)
+locale.setlocale(locale.LC_ALL,"")
+gettext.textdomain('devede')
+gettext.install("devede",localedir=share_locale) # None is sys default locale
+# Note also before python 2.3 you need the following if
+# you need translations from non python code (glibc,libglade etc.)
+# there are other access points to this function
+#gtk.glade.bindtextdomain("devede",share_locale)
+
+arbol=gtk.Builder()
+arbol.set_translation_domain("devede")
+
+# To actually call the gettext translation functions
+# just replace your strings "string" with gettext("string")
+# The following shortcut are usually used:
+_ = gettext.gettext
+
+try:
+ import devede_other
+except:
+ print "Failed to load modules DEVEDE_OTHER. Exiting"
+ sys.exit(1)
+try:
+ import devede_convert
+except:
+ print "Failed to load modules DEVEDE_CONVERT. Exiting"
+ sys.exit(1)
+try:
+ import devede_newfiles
+except:
+ print "Failed to load module DEVEDE_NEWFILES. Exiting"
+ sys.exit(1)
+try:
+ import devede_xml_menu
+except:
+ print "Failed to load module DEVEDE_XML_MENU"
+ sys.exit(1)
+
+try:
+ import devede_disctype
+except:
+ print "Failed to load module DEVEDE_DISCTYPE"
+ sys.exit(1)
+
+try:
+ import devede_fonts
+except:
+ print "Failed to load module DEVEDE_FONTS"
+ sys.exit(1)
+
+
+home=devede_other.get_home_directory()
+
+#locale.setlocale(locale.LC_ALL,"")
+#gettext.textdomain('devede')
+#_ = gettext.gettext
+
+# global variables used (they are stored in a single dictionary to
+# avoid true global variables):
+# there are these two that aren't stored in the dictionary because they are very widely used:
+# arbol
+# structure
+
+global_vars={}
+
+if pic_path[-1]!=os.sep:
+ pic_path+=os.sep
+
+global_vars["PAL"]=True
+global_vars["disctocreate"]=""
+global_vars["path"]=pic_path
+global_vars["install_path"]=other_path
+global_vars["menu_widescreen"]=False
+global_vars["gladefile"]=glade
+global_vars["erase_temporary_files"]=True
+global_vars["number_actions"]=1
+global_vars["expand_advanced"]=False
+global_vars["erase_files"]=True
+global_vars["action_todo"]=2
+global_vars["filmpath"]=""
+global_vars["help_path"]=help_path
+global_vars["finalfolder"]=""
+global_vars["sub_codepage"]="ISO-8859-1"
+global_vars["sub_language"]="EN (ENGLISH)"
+global_vars["with_menu"]=True
+#global_vars[""]=""
+
+if font_path[-1]!=os.sep:
+ font_path+=os.sep
+font_path+="devedesans.ttf"
+global_vars["font_path"]=font_path
+
+print "Entro en fonts"
+fonts_found=devede_fonts.prepare_devede_font(home,font_path)
+print "Salgo de fonts"
+
+devede_other.load_config(global_vars) # load configuration
+
+errors="" # check for installed programs
+if (sys.platform=="win32") or (sys.platform=="win64"):
+ try:
+ devede_other.check_program(["mplayer.exe", "-v"])
+ except:
+ errors+="mplayer\n"
+ try:
+ devede_other.check_program(["mencoder.exe", "-msglevel", "help"])
+ except:
+ errors+="mencoder\n"
+ try:
+ devede_other.check_program(["dvdauthor.exe", "--help"])
+ except:
+ errors+="dvdauthor\n"
+ try:
+ devede_other.check_program(["vcdimager.exe", "--help"])
+ except:
+ errors+="vcdimager\n"
+ try:
+ devede_other.check_program(["iconv.exe", "--help"])
+ except:
+ errors+="iconv\n"
+
+ try:
+ devede_other.check_program(["mkisofs.exe"])
+ mkisofs=True
+ global_vars["iso_creator"]="mkisofs.exe"
+ except:
+ mkisofs=False
+
+ if mkisofs==False:
+ try:
+ devede_other.check_program(["genisoimage.exe"])
+ global_vars["iso_creator"]="genisoimage.exe"
+ except:
+ errors+="genisoimage/mkisofs\n"
+
+ try:
+ devede_other.check_program(["spumux.exe", "--help"])
+ except:
+ errors+="spumux\n"
+
+else:
+
+ if 127==devede_other.check_program("mplayer -v"):
+ errors+="mplayer\n"
+ if 127==devede_other.check_program("mencoder -msglevel help"):
+ errors+="mencoder\n"
+ if 127==devede_other.check_program("dvdauthor --help"):
+ errors+="dvdauthor\n"
+ if 127==devede_other.check_program("vcdimager --help"):
+ errors+="vcdimager\n"
+ if 127==devede_other.check_program("iconv --help"):
+ errors+="iconv\n"
+ if 127==devede_other.check_program("mkisofs -help"):
+ if 127==devede_other.check_program("genisoimage -help"):
+ errors+="genisoimage/mkisofs\n"
+ else:
+ global_vars["iso_creator"]="genisoimage"
+ else:
+ global_vars["iso_creator"]="mkisofs"
+
+ if 127==devede_other.check_program("spumux --help"):
+ errors+="spumux\n"
+
+
+def program_exit(widget):
+
+ gtk.main_quit()
+
+
+
+if errors!="":
+ arbol.add_from_file(os.path.join(glade,"wprograms.ui"))
+ w=arbol.get_object("programs_label")
+ w.set_text(errors)
+ wprograms=arbol.get_object("wprograms")
+ wprograms.show()
+ w=arbol.get_object("program_exit")
+ w.connect("clicked",program_exit)
+ wprograms.connect("destroy",program_exit)
+elif fonts_found==False:
+ arbol.add_from_file(os.path.join(glade,"wnofonts.ui"))
+ wprograms=arbol.get_object("wnofonts")
+ wprograms.show()
+ w=arbol.get_object("fonts_program_exit")
+ w.connect("clicked",program_exit)
+ wprograms.connect("destroy",program_exit)
+else:
+ new_file=devede_disctype.disctype(global_vars)
+
+gtk.main()
+print "Saving configuration"
+devede_other.save_config(global_vars)
+print "Exiting"
+print "Have a nice day"
+sys.stdout.flush()
+sys.stderr.flush()
diff --git a/devede.svg b/devede.svg
new file mode 100644
index 0000000..5057da1
--- /dev/null
+++ b/devede.svg
@@ -0,0 +1,273 @@
+
+
\ No newline at end of file
diff --git a/devede_bincue.py b/devede_bincue.py
new file mode 100755
index 0000000..d0caa0f
--- /dev/null
+++ b/devede_bincue.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2007 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+
+import signal
+import os
+import sys
+import re
+import shutil
+
+import devede_executor
+
+class xvcd_generator(devede_executor.executor):
+
+ """ This class creates BIN/CUE images for VCD, sVCD or CVD """
+
+ def __init__(self,filename,filefolder,progresbar,proglabel,structure,disctocreate):
+
+ devede_executor.executor.__init__(self,filename,filefolder,progresbar)
+
+ proglabel.set_text(_("Creating BIN/CUE files"))
+
+ cantidad=len(structure[0])-1
+ if (sys.platform!="win32") and (sys.platform!="win64"):
+ lista=["vcdimager","-c",filefolder+filename+".cue","-b",filefolder+filename+".bin","-t"]
+ else:
+ lista=["vcdimager.exe","-c",filefolder+filename+".cue","-b",filefolder+filename+".bin","-t"]
+
+ if disctocreate=="vcd":
+ lista.append("vcd2")
+ else:
+ lista.append("svcd")
+
+ for variable in range(cantidad):
+ currentfile=self.create_filename(filefolder+filename,1,variable+1,False)
+ lista.append(currentfile)
+
+ self.print_error=_("Failed to create the BIN/CUE files\nMaybe you ran out of disk space")
+ self.launch_program(lista,output=False)
+
+
+ def end_process(self,eraser,erase_temporal_files):
+
+ print "End process bin/cue"
+ if erase_temporal_files:
+ eraser.delete_mpg()
+ eraser.delete_menu()
+ eraser.delete_xml()
+
+
+class iso_generator(devede_executor.executor):
+
+ """ This class generates the ISO image for DVDs """
+
+ def __init__(self,filename,filefolder,progresbar,proglabel,command):
+
+ devede_executor.executor.__init__(self,filename,filefolder,progresbar)
+
+ proglabel.set_text(_("Creating ISO file"))
+ progresbar.set_fraction(0.0)
+ progresbar.set_text("0%")
+
+ volume="DVDVIDEO"
+ self.print_error=_("Failed to create the ISO image\nMaybe you ran out of disk space")
+ self.launch_program([command,"-dvd-video","-V",volume,"-v","-o",filefolder+filename+".iso",filefolder+filename])
+
+
+ def set_progress_bar(self):
+
+ punto=self.cadena.find("done, estimate")
+ if (punto!=-1):
+ if ((self.cadena[punto-6].isdigit()) and ((self.cadena[punto-7].isdigit()) or (self.cadena[punto-7]==" "))):
+ percent2=float(self.cadena[punto-7:punto-2])
+ self.bar.set_fraction(percent2/100)
+ self.bar.set_text(str(int(percent2))+"%")
+ return True
+ return False
+
+
+ def end_process(self,eraser,erase_temporal_files):
+ print "intento borrar"
+ if erase_temporal_files:
+ eraser.delete_directory()
diff --git a/devede_convert.py b/devede_convert.py
new file mode 100755
index 0000000..a6ae5e7
--- /dev/null
+++ b/devede_convert.py
@@ -0,0 +1,527 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+
+#################################################################
+# This block contains all the functions to convert a video file #
+# into an MPEG2-PS DVD-compliant file #
+#################################################################
+
+import time
+import select
+import signal
+import subprocess
+import sys
+import os
+import re
+import shutil
+import glob
+import posixpath
+import gtk
+import devede_other
+import gobject
+import cairo
+if (sys.platform=="win32") or (sys.platform=="win64"):
+ import win32api
+
+import devede_other
+import devede_video_convert
+import devede_subtitles
+import devede_xml_menu
+import devede_delete
+import devede_dvd
+import devede_bincue
+import devede_executor
+import devede_dialogs
+
+import gc
+
+class create_all:
+
+ def cancel_clicked(self,widget,temp=False):
+
+ newtree=devede_other.create_tree(self,"wcancel_job_dialog",self.gladefile,False)
+ window=newtree.get_object("wcancel_job_dialog")
+ window.show()
+ value=window.run()
+ window.hide()
+ window.destroy()
+ if value!=-5: # no
+ return True
+
+ self.runner.cancel()
+ self.runner.wait_end()
+ gobject.source_remove(self.timer)
+ self.window.hide()
+ self.window.destroy()
+ newtree=devede_other.create_tree(self,"waborted_dialog",self.gladefile,False)
+ window=newtree.get_object("waborted_dialog")
+ window.show()
+ window.run()
+ window.hide()
+ window.destroy()
+ window=None
+ gc.collect()
+ (self.main_window_callback)() # show the main window
+ return True
+
+
+ def iso_changed(self,args,arbol):
+
+ iso_name=arbol.get_object("iso_filename")
+ iso_folder=arbol.get_object("final_directory")
+
+ w=arbol.get_object("button_folder_accept")
+
+ mode=True
+
+ if iso_name.get_text()=="":
+ mode=False
+
+ folder=iso_folder.get_current_folder()
+ if folder==None:
+ mode=False
+ elif folder=="":
+ mode=False
+
+ w.set_sensitive(mode)
+
+
+ def check_free_space(self,filefolder,structure,actions,erase_temporary_files,sound_duration):
+
+ """ Returns TRUE if the free space in FILEFOLDER is insuficient to generate
+ the disk STRUCTURE """
+ # TODO Windows Stuff
+ estado=''
+ freespace=''
+ if (sys.platform!="win32") and (sys.platform!="win64"):
+ print "Checking "+str(filefolder)
+ estado=os.statvfs(filefolder) # eg. f="C:\Documents and Settings\User name\Desktop"
+ freespace=95*estado.f_bsize*estado.f_bavail/100000
+ else:
+ try:
+ test_drive = os.path.splitdrive(filefolder)[0] + "\\" # So it will also work on Windows 2000
+ spc, bps, fc, tc = win32api.GetDiskFreeSpace(test_drive)
+ freespace=fc * spc * bps
+
+ except ImportError:
+ pass
+ print "Free space in "+str(filefolder)+": "+str(freespace)
+ print "estatus ", estado, "\n"
+
+ total=devede_other.calcula_tamano_total(structure,sound_duration,self.disk_type)
+
+ print "Free: "+str(freespace)
+ print "Needed: "+str(total)
+
+ if (actions!=3):
+ total*=actions # if we only create the MPEG files or the DVD structure...
+ else:
+ if erase_temporary_files: # or if we create the ISO image
+ total*=2
+ else:
+ total*=3
+ total*=1.1 # a safe margin of 10%
+
+ if (freespace devede.debug 2>&1
+
diff --git a/devede_delete.py b/devede_delete.py
new file mode 100755
index 0000000..045eb31
--- /dev/null
+++ b/devede_delete.py
@@ -0,0 +1,223 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2007 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2007 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+
+import os
+import shutil
+import glob
+
+class delete_files:
+
+ """ This class allows to delete temporary files and directories """
+
+ def __init__(self,filename,filefolder):
+
+ self.filename=filename
+ self.filefolder=filefolder
+ self.filepath=os.path.join(filefolder,filename)
+ print "Path para borrar: "+str(self.filepath)
+
+
+ def delete_all(self):
+
+ self.delete_avi()
+ self.delete_bin_cue()
+ self.delete_directory()
+ self.delete_iso()
+ self.delete_menu_temp()
+ self.delete_menu()
+ self.delete_mpg()
+ self.delete_log()
+ self.delete_sub_xml()
+ self.delete_xml()
+ self.delete_main_dir()
+
+
+ def delete_mpg(self):
+
+ print "Deleting "+self.filename+"_??_??.mpg"
+ try:
+ listfiles=glob.glob(self.filepath+"_[0-9][0-9]_[0-9][0-9]"+".mpg")
+ for afile in listfiles:
+ print "Trying to delete "+afile
+ try:
+ os.remove(afile)
+ except OSError:
+ print str(afile.strip())+" not found to remove"
+ except OSError:
+ print self.filepath+"._??_??.mpg not found"
+
+
+ def delete_log(self):
+
+ print "Deleting "+self.filename+".log"
+ try:
+ os.remove(self.filename+".log")
+ except OSError:
+ print self.filepath+".log not found"
+
+
+ def delete_avi(self):
+
+ try:
+ listfiles=glob.glob(self.filepath+"_01_[0-9][0-9]"+".avi")
+ for afile in listfiles:
+ try:
+ os.remove(afile)
+ except OSError:
+ print str(afile.strip())+" not found to remove"
+ except OSError:
+ print self.filepath+"._01_??.avi not found"
+
+
+ def delete_xml(self):
+
+ try:
+ os.remove(self.filepath+".xml")
+ listfiles=glob.glob(self.filepath+"_menu_[0-9]"+".xml")
+ for afile in listfiles:
+ try:
+ os.remove(afile)
+ except OSError:
+ print str(afile.strip())+" not found to remove"
+ except OSError:
+ print self.filepath+".xml not found"
+
+
+ def delete_menu_temp(self):
+
+ print "delete menu temp"
+ try:
+ listfiles=glob.glob(self.filepath+"_menu[0-9]"+"_bg.png")
+ for afile in listfiles:
+ try:
+ os.remove(afile)
+ except OSError:
+ print str(afile.strip())+" not found to remove"
+ except OSError:
+ print "Can't delete "+self.filepath+"_menu?_bg.png"
+
+ try:
+ listfiles=glob.glob(self.filepath+"_menu[0-9]"+"_bg_active_out.png")
+ for afile in listfiles:
+ try:
+ os.remove(afile)
+ except OSError:
+ print str(afile.strip())+" not found to remove"
+ except OSError:
+ print "Can't delete "+self.filepath+"_menu?_bg_active_out.png"
+
+ try:
+ listfiles=glob.glob(self.filepath+"_menu[0-9]"+"_bg_inactive_out.png")
+ for afile in listfiles:
+ try:
+ os.remove(afile)
+ except OSError:
+ print str(afile.strip())+" not found to remove"
+ except OSError:
+ print "Can't delete "+self.filepath+"_menu?_bg_inactive_out.png"
+
+ try:
+ listfiles=glob.glob(self.filepath+"_menu[0-9]"+"_bg_select_out.png")
+ for afile in listfiles:
+ try:
+ os.remove(afile)
+ except OSError:
+ print str(afile.strip())+" not found to remove"
+ except OSError:
+ print "Can't delete "+self.filepath+"_menu?_bg_select_out.png"
+
+ try:
+ listfiles=glob.glob(self.filepath+"_menu_[0-9]"+".mpg")
+ for afile in listfiles:
+ try:
+ os.remove(afile)
+ except OSError:
+ print str(afile.strip())+" not found to remove"
+ except OSError:
+ print "Can't delete "+self.filepath+"_menu_?.mpg"
+
+
+ def delete_menu(self):
+
+ print "delete menu"
+
+ try:
+ listfiles=glob.glob(self.filepath+"_menu2_[0-9]"+".mpg")
+ for afile in listfiles:
+ try:
+ os.remove(afile)
+ except OSError:
+ print str(afile.strip())+" not found to remove"
+ except OSError:
+ print "Can't delete "+self.filepath+"_menu2_?.mpg"
+
+
+ def delete_sub_xml(self,xtrasub=""):
+
+ try:
+ os.remove(self.filepath+"_sub.xml")
+ except OSError:
+ print self.filepath+".xml not found"
+ if xtrasub!="":
+ try:
+ os.remove(xtrasub)
+ except OSError:
+ print str(xtrasub)+" not found"
+
+
+ def delete_iso(self):
+
+ try:
+ os.remove(self.filepath+".iso")
+ except OSError:
+ print self.filepath+".iso not found"
+
+
+ def delete_bin_cue(self):
+
+ try:
+ os.remove(self.filepath+".cue")
+ except OSError:
+ print self.filepath+".cue not found"
+
+ try:
+ os.remove(self.filepath+".bin")
+ except OSError:
+ print self.filepath+".bin not found"
+
+
+ def delete_directory(self):
+
+ try:
+ shutil.rmtree(self.filepath)
+ except OSError:
+ print self.filepath+os.sep+" not found"
+
+ def delete_main_dir(self):
+
+ print "Borro principal"
+ return
+
+ try:
+ shutil.rmtree(self.filepath)
+ except OSError:
+ print self.filepath+os.sep+" not found"
diff --git a/devede_dialogs.py b/devede_dialogs.py
new file mode 100755
index 0000000..3f487b2
--- /dev/null
+++ b/devede_dialogs.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2007 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2007 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+import pygtk # for testing GTK version number
+pygtk.require ('2.0')
+import gtk
+import devede_other
+
+class show_error:
+
+ def __init__(self,gladefile,message):
+
+ """ Shows a window with an error """
+
+ self.newtree=devede_other.create_tree(self,"werror_dialog",gladefile,False)
+ label=self.newtree.get_object("label_error_dialog")
+ label.set_text(message)
+ window=self.newtree.get_object("werror_dialog")
+ window.show()
+ window.run()
+ window.hide()
+ window.destroy()
+ window=None
+
+
+class show_warning:
+
+ def __init__(self,gladefile,message):
+
+ """ Shows a window with an error """
+
+ self.newtree=devede_other.create_tree(self,"wwarning_dialog",gladefile,False)
+ label=self.newtree.get_object("wwarning_dialog_text")
+ label.set_text(message)
+ window=self.newtree.get_object("wwarning_dialog")
+ window.show()
+ window.run()
+ window.hide()
+ window.destroy()
+ window=None
+
+
+class ask_exit:
+
+ def __init__(self,gladefile):
+
+ self.newtree=devede_other.create_tree(self,"wcancel_dialog",gladefile,False)
+ self.window=self.newtree.get_object("wcancel_dialog")
+
+ def run(self):
+ self.window.show()
+ retval=self.window.run()
+ self.window.hide()
+ self.window.destroy()
+ self.window=None
+ return retval
+
+
+class ask_overwrite_onload:
+
+ def __init__(self,gladefile):
+
+ self.newtree=devede_other.create_tree(self,"wloosecurrent",gladefile,False)
+ self.window=self.newtree.get_object("wloosecurrent")
+
+ def run(self):
+ self.window.show()
+ retval=self.window.run()
+ self.window.hide()
+ self.window.destroy()
+ self.window=None
+ return retval
+
+
+class ask_delete_title:
+
+ def __init__(self,titlename,gladefile):
+
+ self.newtree=devede_other.create_tree(self,"wdel_title_dialog",gladefile,False)
+ self.window=self.newtree.get_object("wdel_title_dialog")
+ label=self.newtree.get_object("what_title")
+ label.set_text(titlename)
+
+ def run(self):
+ self.window.show()
+ retval=self.window.run()
+ self.window.hide()
+ self.window.destroy()
+ self.window=None
+ return retval
+
+
+class ask_delete_chapter:
+
+ def __init__(self,titlename,gladefile):
+
+ self.newtree=devede_other.create_tree(self,"wdel_chapter_dialog",gladefile,False)
+ self.window=self.newtree.get_object("wdel_chapter_dialog")
+ label=self.newtree.get_object("labelchapter")
+ label.set_text(titlename)
+
+ def run(self):
+ self.window.show()
+ retval=self.window.run()
+ self.window.hide()
+ self.window.destroy()
+ self.window=None
+ return retval
+
+
+class ask_erase_all:
+
+ def __init__(self,gladefile):
+
+ self.newtree=devede_other.create_tree(self,"werase_dialog",gladefile,False)
+ self.window=self.newtree.get_object("werase_dialog")
+
+ def run(self):
+ self.window.show()
+ retval=self.window.run()
+ self.window.hide()
+ self.window.destroy()
+ self.window=None
+ return retval
+
+
+class show_about:
+
+ def __init__(self,gladefile):
+
+ """ Shows the About dialog """
+
+ self.newtree=devede_other.create_tree(self,"aboutdialog1",gladefile,False)
+ window=self.newtree.get_object("aboutdialog1")
+ window.show()
+ window.run()
+ window.hide()
+ window.destroy()
+ window=None
diff --git a/devede_disctype.py b/devede_disctype.py
new file mode 100755
index 0000000..02413ce
--- /dev/null
+++ b/devede_disctype.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+import pygtk # for testing GTK version number
+pygtk.require ('2.0')
+import gtk
+import devede_main
+import devede_dialogs
+import os
+import devede_other
+
+class disctype:
+
+ def __init__(self,global_vars):
+
+ self.gladefile=global_vars["gladefile"]
+ self.global_vars=global_vars
+
+ self.tree=devede_other.create_tree(self,"wdisk_type",self.gladefile)
+ self.window=self.tree.get_object("wdisk_type")
+ self.main_window=None
+ self.window.show()
+
+
+ def on_wdisk_type_delete_event(self,widget,signal):
+ """ Callback which shows the "Are you sure?" window """
+
+ return self.ask_cancel()
+
+
+ def on_wdisk_type_cancel_clicked(self,widget):
+ """ Callback which shows the "Are you sure?" window """
+
+ return self.ask_cancel()
+
+
+ def ask_cancel(self):
+
+ window=devede_dialogs.ask_exit(self.gladefile)
+ retval=window.run()
+ window=None
+ print "Retorno: ",
+ print retval
+ if retval==-5:
+ gtk.main_quit()
+ return False
+ return True
+
+
+ def on_disctype_dvd(self,widget):
+
+ self.global_vars["disctocreate"]="dvd"
+ self.set_disk_type()
+
+
+ def on_disctype_vcd(self,widget):
+
+ self.global_vars["disctocreate"]="vcd"
+ self.set_disk_type()
+
+
+ def on_disctype_svcd(self,widget):
+
+ self.global_vars["disctocreate"]="svcd"
+ self.set_disk_type()
+
+
+ def on_disctype_cvd(self,widget):
+
+ self.global_vars["disctocreate"]="cvd"
+ self.set_disk_type()
+
+
+ def on_disctype_divx(self,widget):
+
+ self.global_vars["disctocreate"]="divx"
+ self.set_disk_type()
+
+
+ def set_disk_type(self):
+
+ if self.main_window==None:
+ self.main_window=devede_main.main_window(self.global_vars,self.show_again)
+ self.main_window.set_disc_type(True)
+ self.main_window.show()
+ self.window.hide()
+
+
+ def show_again(self):
+
+ """ Callback which is called from main window when the user wants to change the
+ disk type """
+
+ self.main_window.hide()
+ self.window.show()
diff --git a/devede_dvd.py b/devede_dvd.py
new file mode 100755
index 0000000..e7482cf
--- /dev/null
+++ b/devede_dvd.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2007 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2007 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+
+import signal
+import os
+import sys
+import re
+import shutil
+
+import devede_executor
+
+class dvd_generator(devede_executor.executor):
+
+ def __init__(self,filename,filefolder,progresbar,proglabel):
+
+ devede_executor.executor.__init__(self,filename,filefolder,progresbar)
+ proglabel.set_text(_("Creating DVD tree structure"))
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ command="dvdauthor.exe"
+ else:
+ command="dvdauthor"
+
+ self.print_error=_("Failed to create the DVD tree\nMaybe you ran out of disk space")
+ self.launch_program([command,"-x",filefolder+filename+".xml"])
+
+
+ def set_progress_bar(self):
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ # This seems to be about all that can be done with dvdauthor on windows
+ self.bar.pulse()
+ return True
+
+ if self.cadena.find("INFO: Video")!=-1:
+ self.bar.pulse()
+ return True
+ else:
+ position=self.cadena.find("STAT: VOBU ")
+ if position!=-1:
+ self.bar.pulse()
+ self.bar.set_text("VOBU "+self.cadena[position+11:self.cadena.find(" ",position+11)])
+ return True
+ else:
+ position=self.cadena.find("STAT: fixing VOBU at ")
+ if (position!=-1):
+ position2=self.cadena.find("%",position+21)
+ if (position2!=-1):
+ cadena=self.cadena[position2-2:position2]
+ self.bar.set_text(cadena+"%")
+ self.bar.set_fraction((float(cadena))/100.0)
+ self.read_chars=200
+ return True
+ return False
+
+
+ def end_process(self,eraser,erase_temporal_files):
+
+ if erase_temporal_files:
+ eraser.delete_mpg()
+ eraser.delete_menu()
+ eraser.delete_xml()
diff --git a/devede_dvdmenu.py b/devede_dvdmenu.py
new file mode 100755
index 0000000..c95a557
--- /dev/null
+++ b/devede_dvdmenu.py
@@ -0,0 +1,388 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+import pygtk # for testing GTK version number
+pygtk.require ('2.0')
+import gtk
+import cairo
+import os
+
+import devede_other
+import devede_dialogs
+import devede_xml_menu
+import devede_newfiles
+import devede_help
+
+
+class menu_options:
+
+ def __init__(self,gladefile,structure,global_vars,callback):
+
+ self.global_vars=global_vars
+ self.gladefile=gladefile
+ self.structure=structure
+ self.callback=callback
+
+ self.tree=devede_other.create_tree(self,"wmenu_properties",self.gladefile)
+ self.window=self.tree.get_object("wmenu_properties")
+
+ menu_filename=global_vars["menu_bg"]
+ if menu_filename==None:
+ menu_filename=os.path.join(global_vars["path"],"backgrounds","default_bg.png")
+ w=self.tree.get_object("menu_bg_file")
+ w.set_filename(menu_filename)
+ filter=gtk.FileFilter()
+ filter.add_mime_type("image/*")
+ filter.set_name("Pictures")
+ w.add_filter(filter)
+
+ self.preview_x=200
+ self.preview_y=200
+ self.sf_final=cairo.ImageSurface(cairo.FORMAT_ARGB32,self.preview_x,self.preview_y)
+ self.preview=gtk.DrawingArea()
+ self.preview.set_size_request(self.preview_x,self.preview_y)
+ self.preview.connect("expose-event",self.repaint_preview)
+ w.set_preview_widget(self.preview)
+
+ self.on_menu_bg_file_update_preview(w,menu_filename)
+
+ self.adding_sound=True
+ w=self.tree.get_object("menu_sound")
+ print "filtro"
+ filter2=gtk.FileFilter()
+ filter2.add_mime_type("audio/mpeg")
+ filter2.add_mime_type("audio/x-wav")
+ filter2.add_mime_type("application/ogg")
+ filter2.add_mime_type("audio/ogg")
+ filter2.set_name("Audio files")
+ w.add_filter(filter2)
+ print "filtrado"
+ w.set_filename(global_vars["menu_sound"])
+ print "Añado"
+
+ w=self.tree.get_object("menufont")
+ w.set_font_name(global_vars["fontname"])
+
+ w=self.tree.get_object("unselected_color")
+ color=global_vars["menu_font_color"]
+ c1=gtk.gdk.Color(color[0],color[1],color[2])
+ w.set_color(c1)
+ w.set_alpha(color[3])
+
+ w=self.tree.get_object("selected_color")
+ color=global_vars["menu_selc_color"]
+ c1=gtk.gdk.Color(color[0],color[1],color[2])
+ w.set_color(c1)
+
+ w=self.tree.get_object("shadow_color")
+ color=global_vars["menu_shadow_color"]
+ c1=gtk.gdk.Color(color[0],color[1],color[2])
+ w.set_color(c1)
+ w.set_alpha(color[3])
+
+ w=self.tree.get_object("bg_color")
+ color=global_vars["menu_bgcolor"]
+ c1=gtk.gdk.Color(color[0],color[1],color[2])
+ w.set_color(c1)
+ w.set_alpha(color[3])
+
+ if global_vars["menu_alignment"]==0:
+ w=self.tree.get_object("menutop")
+ elif global_vars["menu_alignment"]==1:
+ w=self.tree.get_object("menubottom")
+ else:
+ w=self.tree.get_object("menumiddle")
+ w.set_active(True)
+
+ if global_vars["menu_halignment"]==0:
+ w=self.tree.get_object("menuleft")
+ elif global_vars["menu_halignment"]==1:
+ w=self.tree.get_object("menuright")
+ else:
+ w=self.tree.get_object("menucenter")
+ w.set_active(True)
+
+ if global_vars["do_menu"]:
+ w=self.tree.get_object("domenu")
+ else:
+ w=self.tree.get_object("notmenu")
+ w.set_active(True)
+
+ w=self.tree.get_object("menu_title_text")
+ w.set_text(global_vars["menu_title_text"])
+
+ w=self.tree.get_object("menu_title_color")
+ color=global_vars["menu_title_color"]
+ c1=gtk.gdk.Color(color[0],color[1],color[2])
+ w.set_color(c1)
+ w.set_alpha(color[3])
+
+ w=self.tree.get_object("menu_title_shadow")
+ color=global_vars["menu_title_shadow"]
+ c1=gtk.gdk.Color(color[0],color[1],color[2])
+ w.set_color(c1)
+ w.set_alpha(color[3])
+
+ w=self.tree.get_object("menu_title_font")
+ w.set_font_name(global_vars["menu_title_fontname"])
+
+ self.window.show()
+
+
+ def repaint_preview(self,dwidget,evento):
+ try:
+ cr=dwidget.window.cairo_create()
+ cr.set_source_surface(self.sf_final)
+ cr.paint()
+ except:
+ return
+
+
+ def on_menu_bg_file_update_preview(self,widget,filename2=None):
+ try:
+ if filename2==None:
+ filename=widget.get_preview_filename()
+ else:
+ filename=filename2
+
+ print "Using "+str(filename)+" as menu background"
+
+ pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
+ x = pixbuf.get_width()
+ y = pixbuf.get_height()
+
+ sf_base = cairo.ImageSurface(0,x,y)
+
+ ct = cairo.Context(sf_base)
+ ct2 = gtk.gdk.CairoContext(ct)
+
+ ct2.set_source_pixbuf(pixbuf,0,0)
+ ct2.paint()
+ ct2.stroke()
+
+ xbase=float(sf_base.get_width())
+ ybase=float(sf_base.get_height())
+
+ cr_final=cairo.Context(self.sf_final)
+ cr_final.set_source_rgb(1.0,1.0,1.0)
+ cr_final.paint()
+ if xbase>ybase:
+ divisor=xbase
+ else:
+ divisor=ybase
+
+ cr_final.scale(float(self.preview_x)/divisor,float(self.preview_y)/divisor)
+
+ cr_final.set_source_surface(sf_base)
+ cr_final.paint()
+ self.repaint_preview(self.preview,"")
+ widget.set_preview_widget_active(True)
+ except:
+ widget.set_preview_widget_active(False)
+
+
+ def on_menu_sound_selection_changed(self,widget):
+
+ print "Entro"
+
+ if self.adding_sound:
+ self.adding_sound=False
+ return
+
+ filename=widget.get_filename()
+ if (filename==None) or (filename==""):
+ return
+
+ test=devede_newfiles.file_get_params()
+ check,channels=test.read_file_values(filename,True)
+ if (check!=False) or (channels!=1):
+ filename=os.path.join(self.global_vars["path"],"silence.ogg")
+ widget.set_filename(filename)
+ w = devede_dialogs.show_error(self.gladefile,_("The menu soundtrack seems damaged. Using the default silent soundtrack."))
+ w = None
+ test=None
+
+
+ def on_menu_no_sound_clicked(self,widget):
+
+ w=self.tree.get_object("menu_sound")
+ w.set_filename(os.path.join(self.global_vars["path"],"silence.ogg"))
+
+ def on_menu_help_clicked(self,widget):
+
+ help_class=devede_help.show_help(self.gladefile,self.global_vars["help_path"],"menu.html")
+
+ def on_menuprop_cancel_clicked(self,widget):
+
+ self.window.hide()
+ self.window.destroy()
+ self.window=None
+
+
+ def on_menuprop_accept_clicked(self,widget):
+
+ self.set_new_bg(self.global_vars)
+ self.window.hide()
+ self.window.destroy()
+ self.window=None
+
+
+ def on_menu_preview_clicked(self,widget):
+
+ global_vars2={}
+ global_vars2["PAL"]=self.global_vars["PAL"]
+ global_vars2["with_menu"]=True
+ self.set_new_bg(global_vars2)
+ window=menu_preview(self.gladefile,self.structure,global_vars2)
+ window=None
+
+
+ def on_menu_default_bg_clicked(self,widget):
+
+ self.global_vars["menu_bg"]=os.path.join(self.global_vars["path"],"backgrounds","default_bg.png")
+ w=self.tree.get_object("menu_bg_file")
+ w.set_filename(self.global_vars["menu_bg"])
+
+
+ def set_new_bg(self,global_vars):
+
+ w=self.tree.get_object("menu_bg_file")
+ menu_filename=w.get_filename()
+ if menu_filename==None:
+ menu_filename=os.path.join(self.global_vars["path"],"backgrounds","default_bg.png")
+ global_vars["menu_bg"]=menu_filename
+
+ w=self.tree.get_object("menu_sound")
+ sound_filename=w.get_filename()
+ test=devede_newfiles.file_get_params()
+ check,channels=test.read_file_values(sound_filename,True)
+ global_vars["menu_sound"]=sound_filename
+ global_vars["menu_sound_duration"]=test.length
+ test=None
+
+ w=self.tree.get_object("menufont")
+ global_vars["fontname"]=w.get_font_name()
+
+ w=self.tree.get_object("unselected_color")
+ color=w.get_color()
+ global_vars["menu_font_color"]=[color.red,color.green,color.blue,w.get_alpha()]
+
+ w=self.tree.get_object("selected_color")
+ color=w.get_color()
+ global_vars["menu_selc_color"]=[color.red,color.green,color.blue,65535]
+
+ w=self.tree.get_object("shadow_color")
+ color=w.get_color()
+ global_vars["menu_shadow_color"]=[color.red,color.green,color.blue,w.get_alpha()]
+
+ w=self.tree.get_object("bg_color")
+ color=w.get_color()
+ global_vars["menu_bgcolor"]=[color.red,color.green,color.blue,w.get_alpha()]
+
+ align=0 # top
+ w=self.tree.get_object("menumiddle")
+ if w.get_active():
+ align=2 # middle
+ else:
+ w=self.tree.get_object("menubottom")
+ if w.get_active():
+ align=1 # bottom
+ global_vars["menu_alignment"]=align
+
+ halign=0 # left
+ w=self.tree.get_object("menucenter")
+ if w.get_active():
+ halign=2 # middle
+ else:
+ w=self.tree.get_object("menuright")
+ if w.get_active():
+ halign=1 # right
+ global_vars["menu_halignment"]=halign
+
+ w=self.tree.get_object("domenu")
+ global_vars["do_menu"]=w.get_active()
+
+ w=self.tree.get_object("menu_title_text")
+ global_vars["menu_title_text"]=w.get_text()
+
+ w=self.tree.get_object("menu_title_color")
+ color=w.get_color()
+ global_vars["menu_title_color"]=[color.red,color.green,color.blue,w.get_alpha()]
+
+ w=self.tree.get_object("menu_title_shadow")
+ color=w.get_color()
+ global_vars["menu_title_shadow"]=[color.red,color.green,color.blue,w.get_alpha()]
+
+ w=self.tree.get_object("menu_title_font")
+ global_vars["menu_title_fontname"]=w.get_font_name()
+
+ # repaint the used size
+ self.callback()
+
+
+class menu_preview:
+
+ def menu_preview_expose(self,widget,event):
+
+ """ Callback to repaint the menu preview window when it
+ sends the EXPOSE event """
+
+ if self.menu_preview==None:
+ return
+ cr=self.menu_preview.window.cairo_create()
+ cr.set_source_surface(self.sf)
+ cr.paint()
+
+
+ def __init__(self,gladefile,structure,global_vars):
+
+ """ Shows a window with a preview of the disc menu """
+
+ self.menu_preview=None
+ if global_vars["PAL"]:
+ newtree=devede_other.create_tree(self,"wmenu_preview_pal",gladefile)
+ window=newtree.get_object("wmenu_preview_pal")
+ self.menu_preview=newtree.get_object("preview_draw_pal")
+ else:
+ newtree=devede_other.create_tree(self,"wmenu_preview_ntsc",gladefile)
+ window=newtree.get_object("wmenu_preview_ntsc")
+ self.menu_preview=newtree.get_object("preview_draw_ntsc")
+ print self.menu_preview
+
+ if global_vars.has_key("install_path")==False:
+ global_vars["install_path"]=None
+ if global_vars.has_key("path")==False:
+ global_vars["path"]=""
+ if global_vars.has_key("menu_sound")==False:
+ global_vars["menu_sound"]=""
+ if global_vars.has_key("menu_sound_duration")==False:
+ global_vars["menu_sound_duration"]=1
+ clase=devede_xml_menu.xml_files(None,None,None,structure,global_vars,"","")
+ self.sf=clase.create_menu_bg(0,0)
+
+ if self.sf==None:
+ devede_dialogs.show_error(gladefile,_("Can't find the menu background.\nCheck the menu options."))
+ else:
+ window.show()
+ window.run()
+ window.hide()
+ window.destroy()
+ window=None
diff --git a/devede_executor.py b/devede_executor.py
new file mode 100755
index 0000000..5f03244
--- /dev/null
+++ b/devede_executor.py
@@ -0,0 +1,421 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+
+import signal
+import os
+import sys
+import subprocess
+import select
+import time
+if (sys.platform=="win32") or (sys.platform=="win64"):
+ import win32api
+ import win32process
+ import win32con
+ import time
+
+import threading
+import gobject
+
+class executor:
+
+ """ Base class for all launchers (Mplayer, Mencoder, SPUmux, DVDauthor, mkisofs...). """
+
+ def __init__(self,filename=None,filefolder=None,progresbar=None):
+
+ # FILENAME is the generic file name given by the user
+ # FILEFOLDER is the path where all the temporary and finall files will be created
+ # PROGRESBAR is the GtkProgressBar where the class will show the progress
+
+ self.initerror=False
+ self.handle=None
+
+ if filename!=None:
+ self.bar=progresbar
+ if progresbar!=None:
+ progresbar.set_text(" ")
+ self.filefolder=filefolder
+ self.filename=filename
+ self.platform_win32=((sys.platform=="win32") or (sys.platform=="win64"))
+ self.cadena=""
+ self.printout=True
+ self.print_error="Undefined error"
+
+
+ def cancel(self):
+
+ """ Called to kill this process. """
+
+ if self.handle==None:
+ return
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ try:
+ win32api.TerminateProcess(int(self.handle._handle), -1)
+ except Exception , err:
+ print "Error: ", err
+ else:
+ os.kill(self.handle.pid,signal.SIGKILL)
+
+
+ def wait_end(self):
+
+ """ Wait until the process ends """
+
+ if self.handle==None:
+ return 0
+
+ self.handle.wait()
+ return self.handle.returncode
+
+
+ def launch_shell(self,program,read_chars=80,output=True,stdinout=None):
+
+ """ Launches a program from a command line shell. Usefull for programs like SPUMUX, which
+ takes the input stream from STDIN and gives the output stream to STDOUT, or for programs
+ like COPY, CP or LN """
+
+ self.read_chars=read_chars
+ self.output=output
+ self.handle=None
+
+ if stdinout!=None: # we want to apply a file as STDIN and another one as STDOUT
+ lprogram=program+' < "'+stdinout[0]+'" > "'+stdinout[1]+'"'
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ try:
+ pos=program.find(" ")
+ if pos==-1:
+ command=program
+ else:
+ command=program[:pos] # get the command itself (usually SPUMUX.EXE)
+ wd=sys.path[-1:] # Current working Directory. To work with py2exe
+ b=os.path.join(wd[0], "bin", command)
+ lprogram=lprogram.replace(command, '"' + b + '"')
+ batfile=open(os.path.join(wd[0],"menu.bat"),"w")
+ batfile.write(lprogram)
+ batfile.close()
+ except:
+ return None
+ lprogram=os.path.join(wd[0],"menu.bat")
+ else:
+ lprogram=program
+
+ print "Launching shell program: "+str(lprogram)
+ print
+
+ try:
+ if output:
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ handle=MyPopen(lprogram,shell=False,bufsize=32767,stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=win32process.CREATE_NO_WINDOW)
+ else:
+ handle=subprocess.Popen(lprogram,shell=True,bufsize=32767,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+ else:
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ handle=subprocess.Popen(lprogram,shell=True,stdin=subprocess.PIPE, stdout=subprocess.PIPE, creationflags=win32process.CREATE_NO_WINDOW)
+ else:
+ handle=subprocess.Popen(lprogram,shell=True)
+ except OSError:
+ print "error launching shell\n\n\n\n"
+ pass
+ else:
+ self.handle=handle
+ return handle
+
+ print "Fallo"
+ return None
+
+
+ def launch_program(self,program,read_chars=80,output=True,win32arg=True,with_stderr=True):
+
+ """ Launches a program that can be located in any of the directories stored in PATHLIST """
+
+ self.read_chars=read_chars
+ self.output=output
+ self.handle=None
+
+ wd=sys.path[-1:] # working directory. This works with py2exe
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ pathlist=[os.path.join(wd[0],"bin"),os.path.join(os.getcwd(),"bin"), r'C:\WINDOWS', r'C:\WINDOWS\system32', r'C:\WINNT']
+ else:
+ pathlist=["/usr/bin","/usr/local/bin","/usr/share/bin","/usr/share/local/bin","/bin",os.path.join(wd[0],"bin")]
+
+ print "Launching program: ",
+ for elemento in program:
+ print str(elemento),
+ print
+
+ for elemento in pathlist:
+ print "elemento: ", elemento
+ if elemento[-1]!=os.sep:
+ elemento+=os.sep
+ try:
+ program2=program[:]
+ program2[0]=elemento+program2[0]
+ if output:
+ if with_stderr:
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ handle=MyPopen(program2,executable=program2[0],shell=False,stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=win32process.CREATE_NO_WINDOW, threaded=win32arg, read=read_chars)
+ else:
+ handle=subprocess.Popen(program2,executable=program[0],shell=False,bufsize=32767,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+ else:
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ handle=MyPopen(program2,executable=program2[0],shell=False,stdin=subprocess.PIPE, stdout=subprocess.PIPE, creationflags=win32process.CREATE_NO_WINDOW, threaded=False, read=read_chars)
+ else:
+ handle=subprocess.Popen(program2,executable=program[0],shell=False,bufsize=32767,stdout=subprocess.PIPE)
+ else:
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ handle=MyPopen(program2,executable=program2[0],shell=False,creationflags=win32process.CREATE_NO_WINDOW, threaded=win32arg, read=read_chars)
+ else:
+ handle=subprocess.Popen(program2,executable=program[0],shell=False)
+ except OSError:
+ print "error in launch program\n"
+ pass
+ else:
+ self.handle=handle
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ handle.set_priority()
+ return handle
+ return None
+
+
+ def refresh(self):
+
+ """ Reads STDOUT and STDERR and refreshes the progress bar. """
+
+ if self.handle==None:
+ return -1 # there's no program running
+
+ if self.output==False: # if we don't want to read the output...
+ self.bar.pulse() # just PULSE the progress bar
+ if self.handle.poll()==None:
+ return 0 # if the program didn't end, return 0
+ else:
+ return 1 # and 1 if the program ended
+
+ ret_value=1
+ v1=[]
+ while self.handle.poll()==None:
+ if self.read_line_from_output():
+ ret_value=0
+ break
+
+ if (self.set_progress_bar()): # progress_bar is defined in each subclass to fit the format
+ self.cadena=""
+
+ if ret_value==1: # read what remains in the STDOUT and STDERR queues
+ while self.read_line_from_output():
+ tmp=1
+
+ return ret_value # 0: nothing to read; 1: program ended
+
+
+ def read_line_from_output(self):
+ if self.platform_win32:
+ v1 = self.handle.recv_some()
+ else:
+ v1,v2,v3=select.select([self.handle.stderr,self.handle.stdout],[],[],0)
+
+ if len(v1)==0:
+ return True # nothing to read, so get out of the WHILE loop
+
+ for element in v1:
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ readed = element#[0,self.read_chars]
+ self.cadena+=readed
+ if (self.printout) or (element==self.handle.stderr):
+ print readed,
+ break # this break statement and setting the priority lower in launch_program makes devede work a lot better on windows
+ else:
+ readed=element.readline(self.read_chars)
+ self.cadena+=readed
+ if (self.printout) or (element==self.handle.stderr):
+ print readed,
+
+ return False
+
+
+ def set_progress_bar(self):
+
+ # By default, just do nothing
+ if self.filename!=None:
+ self.bar.pulse()
+ return True
+
+
+ def create_filename(self,filename,title,file,avi):
+
+ """ Starting from the generic filename, adds the title and chapter numbers and the extension """
+
+ currentfile=filename+"_"
+ if title<10:
+ currentfile+="0"
+ currentfile+=str(title)+"_"
+
+ if file<10:
+ currentfile+="0"
+
+ if avi:
+ currentfile+=str(file)+'.avi'
+ else:
+ currentfile+=str(file)+'.mpg'
+ return currentfile
+
+
+ def remove_ansi(self,line):
+
+ output=""
+ while True:
+ pos=line.find("\033[") # try with double-byte ESC
+ jump=2
+ if pos==-1:
+ pos=line.find("\233") # if not, try with single-byte ESC
+ jump=1
+ if pos==-1: # no ANSI characters; we ended
+ output+=line
+ break
+
+ output+=line[:pos]
+ line=line[pos+jump:]
+
+ while True:
+ if len(line)==0:
+ break
+ if (ord(line[0])<64) or (ord(line[0])>126):
+ line=line[1:]
+ else:
+ line=line[1:]
+ break
+ return output
+
+
+class MyPopen(subprocess.Popen):
+
+ class Sender(gobject.GObject):
+ def __init__(self):
+ self.__gobject_init__()
+
+ class PipeThread(threading.Thread):
+ def __init__(self, parent, fin, chars=80):
+ threading.Thread.__init__(self)
+ self.chars=chars
+ self.fin = fin
+ self.sout = []
+ self.parent = parent
+ self.sender = parent.Sender()
+ self.sender.connect("z_signal", parent.read_callback)
+ #self.sout = ""
+
+ def run(self):
+ self.sender.connect("z_signal", self.parent.read_callback)
+ while True:
+ try:
+ timer = threading.Timer(10, self.__alarm_handler)
+ temp=self.fin.read(self.chars)
+ if not temp: self.sout.append("")
+ if not temp: break
+ self.sender.emit("z_signal", temp)
+ timer.cancel()
+ except Exception, e:
+ if not str(e) == 'timeout': # something else went wrong ..
+ pass
+ #raise # got the timeout exception from alarm .. proc is hung; kill it
+ break
+
+ def __alarm_handler(self):
+ print "Process read timeout exception"
+ raise Exception("timeout")
+
+ def get_output(self):
+ return self.sout
+
+ def reset(self):
+ self.sout = []
+ #self.sout = ""
+
+ def __init__(self, args=None, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, threaded=True, read=80):
+ subprocess.Popen.__init__(self,args=args, bufsize=bufsize, executable=executable, stdin=stdin, stdout=stdout, stderr=stderr, preexec_fn=preexec_fn, close_fds=close_fds, shell=shell, cwd=cwd, env=env, universal_newlines=universal_newlines, startupinfo=startupinfo, creationflags=creationflags)
+
+ self.sout = []
+ self.lock = threading.Lock()
+
+ if not threaded:
+ pass
+ else:
+ try:
+ gobject.type_register(self.Sender)
+ gobject.signal_new("z_signal", self.Sender, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (object,))
+ except:
+ print "Error registering z_signal"
+
+ self.out_pipe, self.err_pipe = self.PipeThread(self, self.stdout, read), self.PipeThread(self, self.stderr)
+ self.out_pipe.start(), self.err_pipe.start()
+
+ def read_callback(self, object, data):
+ self.__set_data(data)
+ #print "Data Received:", data
+
+ def __set_data(self, data):
+
+ self.lock.acquire()
+ self.sout.append(data)
+ self.lock.release()
+
+ def __get_data(self):
+ self.lock.acquire()
+ out = self.sout
+ self.sout = []
+ self.lock.release()
+ return out
+
+ def is_data(self):
+ self.lock.acquire()
+ value = self.sout
+ self.lock.release()
+ if len(value) > 0:
+ return True
+ return False
+
+ def recv_some(self):
+ """
+ Returns a copy of the lists holding stdout and stderr
+ Before returning it clears the original lists
+ """
+
+ out = self.__get_data()
+ time.sleep(0.02)
+ return out #[out, err]
+
+
+ def set_priority(self, pid=None, priority=0):
+
+ """
+ Set the Priority of a Windows Process. Priority is a value between 0-5 where
+ 2 is normal priority. Defaults to lowest Priority.
+ """
+ priority_classes=[win32process.IDLE_PRIORITY_CLASS,
+ win32process.BELOW_NORMAL_PRIORITY_CLASS,
+ win32process.NORMAL_PRIORITY_CLASS,
+ win32process.ABOVE_NORMAL_PRIORITY_CLASS,
+ win32process.HIGH_PRIORITY_CLASS,
+ win32process.REALTIME_PRIORITY_CLASS]
+ if pid == None:
+ pid=self.pid
+ handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid)
+ win32process.SetPriorityClass(handle, priority_classes[priority])
diff --git a/devede_fonts.py b/devede_fonts.py
new file mode 100644
index 0000000..51a750e
--- /dev/null
+++ b/devede_fonts.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2007 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+import os
+import shutil
+import sys
+
+def prepare_devede_font(home,font_path):
+
+ """ This function copies the default font for subtitles into $HOME/.spumux
+ It's made this way because Red Hat package mandates removing font files
+ from RPM files, so DeVeDe must search in several directories """
+
+ path_list=[font_path,"/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf","/usr/share/fonts/truetype/ttf-dejavu/dejavusans.ttf"]
+
+ #if our font for subtitles isn't installed, we install it
+
+ exists=True
+ try:
+ if (sys.platform!="win32") and (sys.platform!="win64"):
+ fichero=open(home+".spumux/devedesans.ttf")
+ fichero.close()
+ else: # get home
+ t=os.path.join(os.environ["WINDIR"], "Fonts", "devedesans.ttf")
+ fichero=open(t)
+ fichero.close()
+ return True
+ except:
+ exists=False
+
+ if exists:
+ return
+
+ if (sys.platform!="win32") and (sys.platform!="win64"):
+ try:
+ t=os.path.join(home,".spumux")
+ print "Creating spumux directory"+str(t)
+ os.mkdir(t)
+ except:
+ print "Already existed"
+ pass
+
+ for element in path_list:
+ print element
+ try:
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ print "win32"
+ t=os.path.join(os.environ["WINDIR"], "Fonts" )#=r'C:\WINDOWS\Fonts\\'
+ t2=os.path.join(t,"devedesans.ttf")
+ # spummux needs font in the windows font directory
+ print "\n\nFont Path: " , element
+ print "\n\nT: " , t
+ shutil.copyfile(element,t2)
+ else:
+ print "Hago"
+ t=os.path.join(home,".spumux")
+ t2=os.path.join(t,"devedesans.ttf")
+ print t2
+ shutil.copyfile(element,t2)
+ print "hecho"
+ #handle=subprocess.Popen("mkdir "+home+".spumux",bufsize=8192,shell=True)
+ #handle.wait()
+ #handle=subprocess.Popen("cp "+font_path+" "+home+".spumux/",bufsize=8192,shell=True)
+ #handle.wait()
+ print "retorno"
+ return True
+ except:
+ print "fallo"
+ pass
+
+ return False
\ No newline at end of file
diff --git a/devede_help.py b/devede_help.py
new file mode 100755
index 0000000..c3d4c9c
--- /dev/null
+++ b/devede_help.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2007 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2007 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+
+import os
+import sys
+import devede_dialogs
+
+import devede_executor
+
+if (sys.platform=="win32") or (sys.platform=="win64"):
+ import webbrowser
+
+class show_help(devede_executor.executor):
+
+ def __init__(self,gladefile,installpath,filename):
+
+ devede_executor.executor.__init__(self)
+ self.printout=False
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ webbrowser.open_new(os.path.join(installpath, filename))
+ return
+
+ self.printout=False
+
+ launch_list=[[True,"yelp"],[False,"epiphany"],[False,"konqueror"],[False,"firefox","-new-window"],[False,"opera","-newwindow"]]
+
+ file=os.path.join(installpath,"html",filename)
+
+ for program in launch_list:
+ if program[0]:
+ program.append("file://"+file)
+ else:
+ program.append(file)
+ retval=self.launch_program(program[1:],80,False)
+ if retval!=None:
+ break
+
+ if retval==None:
+ msg=devede_dialogs.show_error(gladefile,_("Can't open the help files."))
+
\ No newline at end of file
diff --git a/devede_loadsave.py b/devede_loadsave.py
new file mode 100755
index 0000000..2657461
--- /dev/null
+++ b/devede_loadsave.py
@@ -0,0 +1,331 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+import pygtk # for testing GTK version number
+pygtk.require ('2.0')
+import gtk
+import pickle
+import os
+
+import devede_other
+import devede_dialogs
+import devede_newfiles
+
+class load_save_config:
+
+ def __init__(self,gladefile,structure,global_vars,tree):
+
+ self.tree=tree
+ self.gladefile=gladefile
+ self.structure=structure
+ self.global_vars=global_vars
+
+ def load(self,file_name):
+
+ """ This method loads a configuration file """
+
+ self.done = False
+
+ if (len(self.structure)>1) or (len(self.structure[0])>1):
+ w = devede_dialogs.ask_overwrite_onload(self.gladefile)
+ retval = w.run()
+ w = None
+ if retval!=-8:
+ return
+
+ if file_name==None:
+ tree=devede_other.create_tree(self,"wloadconfig",self.gladefile,False)
+ window = tree.get_object("wloadconfig")
+
+ filter = gtk.FileFilter()
+ filter.add_pattern("*.devede")
+ filter.set_name(".devede")
+ window.add_filter(filter)
+
+ window.show()
+ retval = window.run()
+ window.hide()
+ if retval!=-5:
+ window.destroy()
+ window = None
+ return
+
+ file_name=window.get_filename()
+ window.destroy()
+ window = None
+
+ try:
+ output=open(file_name)
+ except:
+ w = devede_dialogs.show_error(self.gladefile,_("Can't open the file."))
+ w = None
+ return
+
+ try:
+ values=pickle.load(output)
+ except:
+ w = devede_dialogs.show_error(self.gladefile,_("That file doesn't contain a disc structure."))
+ w = None
+ return
+
+ if values!="DeVeDe":
+ w = devede_dialogs.show_error(self.gladefile,_("That file doesn't contain a disc structure."))
+ w = None
+ return
+
+ global_vars2={}
+ try:
+ values=pickle.load(output)
+ global_vars2=pickle.load(output)
+ except:
+ w = devede_dialogs.show_error(self.gladefile,_("That file doesn't contain a DeVeDe structure."))
+ w = None
+ return
+
+
+ output.close()
+
+ not_found=[]
+ for element in values:
+ for element2 in element[1:]:
+ try:
+ v=os.stat(element2["path"])
+ except:
+ not_found.append(str(element2["path"]))
+ continue
+
+ if False==element2.has_key("copy_audio"):
+ element2["copy_audio"]=False # for backward compatibility
+ if False==element2.has_key("sound51"):
+ element2["sound51"]=False # for backward compatibility
+ if False==element2.has_key("rotate"):
+ element2["rotate"]=0
+ if False==element2.has_key("vmirror"):
+ element2["vmirror"]=False
+ if False==element2.has_key("hmirror"):
+ element2["hmirror"]=False
+ if False==element2.has_key("gop12"):
+ element2["gop12"]=True # for backward compatibility
+ if False==element2.has_key("isvob"):
+ element2["isvob"]=False # for backward compatibility
+ if False==element2.has_key("swap_fields"):
+ element2["swap_fields"]=False # for backward compatibility
+ if False==element2.has_key("twopass"):
+ element2["twopass"]=False # for backward compatibility
+ if False==element2.has_key("turbo1stpass"):
+ element2["turbo1stpass"]=False # for backward compatibility
+ if False==element2.has_key("subfont_size"):
+ element2["subfont_size"]=28 # subtitle font size
+ if False==element2.has_key("volume"):
+ element2["volume"]=100 # default volume (in percentage)
+ if False==element2.has_key("force_subs"):
+ element2["force_subs"]=False # by default, subtitles aren't forced
+
+ if False==element2.has_key("audio_stream"):
+ fileprop=devede_newfiles.newfile("","")
+ (fine,audio)=fileprop.read_file_values(element2["path"],0)
+ if fine and (audio==0):
+ element2["audio_list"]=fileprop.file_values["audio_list"]
+ element2["audio_stream"]=fileprop.file_values["audio_stream"]
+ fileprop=None
+
+ if False==element2.has_key("sub_list"):
+ element2["sub_list"]=[]
+ if element2["subtitles"]!="":
+ tmp={}
+ tmp["subtitles"]=element2["subtitles"]
+ tmp["sub_codepage"]=element2["sub_codepage"]
+ tmp["sub_language"]="EN (ENGLISH)"
+ tmp["subtitles_up"]=element2["subtitles_up"]
+ del element2["subtitles"]
+ del element2["sub_codepage"]
+ del element2["subtitles_up"]
+ element2["sub_list"].append(tmp)
+
+
+ if len(not_found)!=0:
+ t_string=_("Can't find the following movie files. Please, add them and try to load the disc structure again.\n")
+ for element in not_found:
+ t_string+="\n"+element
+ w = devede_dialogs.show_error(self.gladefile,t_string)
+ w = None
+ return
+
+ try:
+ os.stat(global_vars2["menu_bg"])
+ except:
+ w = devede_dialogs.show_error(self.gladefile,_("Can't find the menu background. I'll open the disc structure anyway with the default menu background, so don't forget to fix it before creating the disc."))
+ w = None
+ global_vars2["menu_bg"]=os.path.join(self.global_vars["path"],"backgrounds","default_bg.png")
+
+ use_default_sound=False
+
+ if False==global_vars2.has_key("menu_sound"):
+ use_default_sound=True
+ else:
+ if (global_vars2["menu_sound"][-11:]=="silence.mp3"):
+ global_vars2["menu_sound"]=os.path.join(self.global_vars["path"],"silence.ogg")
+ try:
+ os.stat(global_vars2["menu_sound"])
+ except:
+ use_default_sound=True
+ w = devede_dialogs.show_error(self.gladefile,_("Can't find the menu soundtrack file. I'll open the disc structure anyway with a silent soundtrack, so don't forget to fix it before creating the disc."))
+ w = None
+
+ if (use_default_sound):
+ global_vars2["menu_sound"]=os.path.join(self.global_vars["path"],"silence.ogg")
+
+ if False==global_vars2.has_key("with_menu"):
+ global_vars2["with_menu"]=True
+
+ if False==global_vars2.has_key("menu_halignment"):
+ global_vars2["menu_halignment"]=2 # center
+
+ if False==global_vars2.has_key("menu_shadow_color"):
+ global_vars2["menu_shadow_color"]=[0,0,0,0]
+
+ if False==global_vars2.has_key("menu_title_shadow"):
+ global_vars2["menu_title_shadow"]=[0,0,0,0]
+
+ test=devede_newfiles.file_get_params()
+ check,channels=test.read_file_values(global_vars2["menu_sound"],True)
+ if (check!=False) or (channels!=1):
+ global_vars2["menu_sound"]=os.path.join(self.global_vars["path"],"silence.ogg")
+ w = devede_dialogs.show_error(self.gladefile,_("The menu soundtrack seems damaged. Using the default silent soundtrack."))
+ w = None
+ check,channels=test.read_file_values(global_vars2["menu_sound"],True)
+
+ global_vars2["menu_sound_duration"]=test.length
+ test=None
+
+ while (len(self.structure)>0):
+ self.structure.pop()
+
+ for element in values:
+ self.structure.append(element)
+ for element in global_vars2:
+ self.global_vars[element]=global_vars2[element]
+
+ if self.global_vars.has_key("menu_bgcolor")==False:
+ self.global_vars["menu_bgcolor"]=[0,0,0,49152]
+ self.global_vars["menu_font_color"]=[65535,65535,65535]
+ self.global_vars["menu_selc_color"]=[0,65535,65535,65535]
+ self.global_vars["menu_alignment"]=2 # middle
+
+ if self.global_vars.has_key("menu_title_text")==False:
+ self.global_vars["menu_title_color"]=[0,0,0,65535]
+ self.global_vars["menu_title_text"]=""
+ self.global_vars["menu_title_fontname"]="Sans 14"
+
+ if global_vars2.has_key("erase_files")==False:
+ w=self.tree.get_object("create_iso")
+ w.set_active(True)
+ w=self.tree.get_object("erase_files")
+ w.set_active(True)
+
+ self.global_vars["struct_name"]=file_name # update the path
+
+ self.done = True
+
+
+ def save(self,mode):
+
+ """ This method stores the current disc structure in a file. If MODE is True,
+ it will ask before a new name. If it's False and there's a filename
+ (from a previous save), it will overwrite the old file """
+
+ if mode or (self.global_vars["struct_name"]==""):
+ tree=devede_other.create_tree(self,"wsaveconfig",self.gladefile,False)
+ saveconfig=tree.get_object("wsaveconfig")
+
+ filter=gtk.FileFilter()
+ filter.add_pattern("*.devede")
+ filter.set_name(".devede")
+ saveconfig=tree.get_object("wsaveconfig")
+ saveconfig.add_filter(filter)
+ saveconfig.set_do_overwrite_confirmation(True)
+
+ saveconfig.show()
+ value=saveconfig.run()
+ saveconfig.hide()
+ if value!=-5:
+ saveconfig.destroy()
+ saveconfig=None
+ return
+ fname=saveconfig.get_filename()
+ saveconfig.destroy()
+ saveconfig=None
+
+ if fname==None:
+ w=devede_dialogs.show_error(self.gladefile,_("No filename"))
+ w=None
+ return
+
+ if (len(fname)<7) or (fname[-7:]!=".devede"):
+ fname+=".devede"
+
+ self.global_vars["struct_name"]=fname
+
+ try:
+ output=open(self.global_vars["struct_name"],"wb")
+ id="DeVeDe"
+ pickle.dump(id,output)
+ pickle.dump(self.structure,output)
+ vars={}
+ vars["disctocreate"]=self.global_vars["disctocreate"]
+ vars["titlecounter"]=self.global_vars["titlecounter"]
+ vars["do_menu"]=self.global_vars["do_menu"]
+ vars["with_menu"]=self.global_vars["with_menu"]
+ vars["menu_widescreen"]=self.global_vars["menu_widescreen"]
+ vars["PAL"]=self.global_vars["PAL"]
+ vars["menu_bg"]=self.global_vars["menu_bg"]
+ vars["menu_sound"]=self.global_vars["menu_sound"]
+ vars["menu_bgcolor"]=self.global_vars["menu_bgcolor"]
+ vars["menu_font_color"]=self.global_vars["menu_font_color"]
+ vars["menu_selc_color"]=self.global_vars["menu_selc_color"]
+ vars["menu_shadow_color"]=self.global_vars["menu_shadow_color"]
+ vars["menu_alignment"]=self.global_vars["menu_alignment"]
+ vars["menu_halignment"]=self.global_vars["menu_halignment"]
+ vars["struct_name"]=self.global_vars["struct_name"]
+ vars["fontname"]=self.global_vars["fontname"]
+ vars["menu_title_color"]=self.global_vars["menu_title_color"]
+ vars["menu_title_shadow"]=self.global_vars["menu_title_shadow"]
+ vars["menu_title_text"]=self.global_vars["menu_title_text"]
+ vars["menu_title_fontname"]=self.global_vars["menu_title_fontname"]
+
+ w=self.tree.get_object("erase_files")
+ vars["erase_files"]=w.get_active()
+ if self.tree.get_object("create_iso").get_active():
+ vars["action_todo"]=2
+ elif self.tree.get_object("create_dvd").get_active():
+ vars["action_todo"]=1
+ else:
+ vars["action_todo"]=0
+
+ print "Erase: "+str(vars["erase_files"])
+ print "Action: "+str(vars["action_todo"])
+ print "Variables: "+str(vars)
+ pickle.dump(vars,output)
+ output.close()
+ except:
+ w=devede_dialogs.show_error(self.gladefile,_("Can't save the file."))
+ w=None
+
diff --git a/devede_main.py b/devede_main.py
new file mode 100755
index 0000000..1e77936
--- /dev/null
+++ b/devede_main.py
@@ -0,0 +1,1078 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+import pygtk # for testing GTK version number
+pygtk.require ('2.0')
+import gtk
+import gobject
+import os
+import sys
+
+import devede_other
+import devede_newfiles
+import devede_dvdmenu
+import devede_loadsave
+import devede_title_properties
+import devede_dialogs
+import devede_convert
+import devede_help
+
+if (sys.platform=="win32") or (sys.platform=="win64"):
+ import win32api
+
+class main_window:
+
+ def __init__(self,global_vars,callback):
+
+ self.global_vars=global_vars
+ self.gladefile=global_vars["gladefile"]
+
+ self.tree=devede_other.create_tree(self,"wmain",self.gladefile)
+ self.window=self.tree.get_object("wmain")
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ self.window.drag_dest_set(0,[],0)
+ self.window.connect('drag_drop', self.drop_cb)
+ else:
+ self.window.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP,[ ( "text/plain", 0, 80), ( "video/*", 0, 81) ],gtk.gdk.ACTION_COPY)
+ self.global_vars["main_window"]=self.window
+
+ self.list_titles=gtk.TreeStore(gobject.TYPE_PYOBJECT,gobject.TYPE_STRING)
+ self.list_chapters=gtk.TreeStore(gobject.TYPE_PYOBJECT,gobject.TYPE_STRING)
+
+ ltitles=self.tree.get_object("ltitles")
+ lchapters=self.tree.get_object("lchapters")
+
+ ltitles.set_model(self.list_titles)
+ lchapters.set_model(self.list_chapters)
+
+ renderertitles=gtk.CellRendererText()
+ columntitles = gtk.TreeViewColumn("Title", renderertitles, text=1)
+ ltitles.append_column(columntitles)
+
+ rendererchapters=gtk.CellRendererText()
+ columnchapters = gtk.TreeViewColumn("Title", rendererchapters, text=1)
+ lchapters.append_column(columnchapters)
+
+ #ltitles.connect("button_release_event",self.on_titleclick)
+ #lchapters.connect("button_release_event",self.on_chapterclick)
+
+ self.set_default_global()
+
+ self.callback=callback # callback to call to show again the SELECT_DISK dialog
+
+ if global_vars["PAL"]:
+ w=self.tree.get_object("default_pal")
+ else:
+ w=self.tree.get_object("default_ntsc")
+ w.set_active(True)
+
+ self.window.show()
+
+ print "Cores: "+str(self.get_cores())
+
+
+ def hide(self):
+ if self.window!=None:
+ self.window.hide()
+
+
+ def show(self):
+ if self.window!=None:
+ self.window.show()
+
+
+ def drop_cb(self, wid, context, x, y, time):
+ # Used with windows drag and drop
+ print 'drop'
+ self.have_drag = False
+ if context.targets:
+ wid.drag_get_data(context, context.targets[0], time)
+ return True
+ return False
+
+
+ def set_default_global(self):
+
+ """ Sets the default GLOBAL vars each time the user wants to create a new disc """
+
+ self.global_vars["action_todo"]=2
+ self.global_vars["erase_files"]=True
+ self.global_vars["struct_name"]=""
+ self.global_vars["do_menu"]=True
+ self.global_vars["with_menu"]=True
+ self.global_vars["menu_bg"]=os.path.join(self.global_vars["path"],"backgrounds","default_bg.png")
+ self.global_vars["menu_sound"]=os.path.join(self.global_vars["path"],"silence.ogg")
+ test=devede_newfiles.file_get_params()
+ check,channels=test.read_file_values(self.global_vars["menu_sound"],True)
+ if (check!=False) or (channels!=1):
+ self.global_vars["menu_sound_duration"]=20
+ else:
+ self.global_vars["menu_sound_duration"]=test.length
+ print "Longitud sonido: "+str(test.length)
+ test=None
+ self.global_vars["titlecounter"]=2
+ self.current_title_selected=-1
+ self.current_file_selected=-2
+ self.global_vars["fontname"]="Sans 12"
+ self.global_vars["menu_bgcolor"]=[0,0,0,49152]
+ self.global_vars["menu_font_color"]=[65535,65535,65535,65535]
+ self.global_vars["menu_selc_color"]=[0,65535,65535,65535]
+ self.global_vars["menu_shadow_color"]=[0,0,0,0]
+ self.global_vars["menu_alignment"]=2 # middle
+ self.global_vars["menu_halignment"]=2 # center
+ self.global_vars["menu_title_color"]=[0,0,0,65535]
+ self.global_vars["menu_title_shadow"]=[0,0,0,0]
+ self.global_vars["menu_title_text"]=""
+ self.global_vars["menu_title_fontname"]="Sans 14"
+
+
+ def set_disc_type(self,delete_structure):
+
+ """ Changes the interface to adjust to the disk type """
+
+ if delete_structure:
+ self.structure=[]
+ self.structure.append(self.create_new_structure(1))
+ self.set_default_global()
+
+ self.disctocreate = self.global_vars["disctocreate"]
+
+ # choose the default disk type
+ w = self.tree.get_object("dvdsize")
+ if (self.disctocreate == "dvd") or (self.disctocreate == "divx"):
+ w.set_active(4)
+ else:
+ w.set_active(2)
+
+ w = self.tree.get_object("autosize")
+ if (self.disctocreate == "vcd"):
+ w.hide()
+ else:
+ w.show()
+
+ w = self.tree.get_object("include_menu")
+ if (self.disctocreate == "dvd"):
+ w.show()
+ else:
+ w.hide()
+
+ w1 = self.tree.get_object("frame1") # contains the titles
+ w2 = self.tree.get_object("create_dvd") # toggle to create the DVD structure
+ w5 = self.tree.get_object("menuoptions") # button to show the menu options
+ w6 = self.tree.get_object("menu_preview") # button to preview the menu
+
+ if self.disctocreate == "dvd":
+ w1.show()
+ w2.show()
+ w5.show()
+ w6.show()
+ else:
+ self.global_vars["do_menu"] = False
+ w1.hide()
+ w2.hide()
+ w5.hide()
+ w6.hide()
+
+ w1 = self.tree.get_object("frame5") # ACTION frame
+ w2 = self.tree.get_object("erase_files")
+ if self.disctocreate == "divx":
+ w1.hide()
+ w2.hide()
+ self.global_vars["action_todo"]=0
+ w = self.tree.get_object("only_convert")
+ w.set_active(True)
+ else:
+ w1.show()
+ w2.show()
+ if self.global_vars["action_todo"]==2:
+ w=self.tree.get_object("create_iso")
+ elif self.global_vars["action_todo"]==1:
+ w=self.tree.get_object("create_dvd")
+ else:
+ w=self.tree.get_object("only_convert")
+ self.global_vars["action_todo"]=0
+ w.set_active(True)
+
+ w=self.tree.get_object("erase_files")
+ w.set_active(self.global_vars["erase_files"])
+
+ # now select the first title and chapter
+
+ ltitles=self.tree.get_object("ltitles")
+ ltitles.get_selection().select_path( (0,))
+
+ lchapters=self.tree.get_object("lchapters")
+ lchapters.get_selection().select_path( (0,))
+
+ w=self.tree.get_object("multicore")
+ if (self.global_vars["multicore"]==1):
+ w.set_active(False)
+ else:
+ w.set_active(True)
+ self.global_vars["multicore"]=self.get_cores()
+
+ # refresh the title and chapter lists
+ self.refresh_titles()
+ self.refresh_chapters()
+
+ # set the window title
+ self.set_title()
+
+ # and set the buttons'status
+ self.set_buttons()
+
+
+ def get_surface(self,element):
+
+ """ Return data from a video, to be able to compute the optimal bitrate to fullfill the disk.
+ SIZE is the size in kbytes
+ SURFACE is the surface in square pixels
+ LENGTH is the efective length in seconds
+ AUDIORATE is the audio rate """
+
+ length = float(element["olength"])
+ speed1,speed2=devede_other.get_speedup(element)
+ if (speed1!=speed2): # we are speeding up the film, so we must take it into account
+ length*=((float(speed2))/(float(speed1)))
+
+ if element["cutting"]!=0: # we want only half the file
+ length/=2
+
+ surface = float(element["width"]*element["height"])
+
+ surface/=84480.0 # normalize surface respect to 352x240
+
+ if (element["copy_audio"]):
+ audiorate=element["oarate"]
+ else:
+ audiorate=element["arate"]
+
+ if (element["ismpeg"]):
+ size=element["filesize"]/1000
+ else:
+ size=(length*(element["vrate"]+audiorate))/8
+
+ return size,surface,length,audiorate
+
+
+ def get_number(self,line):
+
+ pos=line.find(":")
+ if pos==-1:
+ return -1
+
+ return int(line[pos+1:])
+
+
+ def get_cores(self):
+
+ """ Returns the number of cores available in the system """
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ logical_cores = win32api.GetSystemInfo()[5] #Logical Cores
+ return logical_cores
+
+ try:
+ proc=open("/proc/cpuinfo","r")
+ except:
+ return 1 # if we can't open /PROC/CPUINFO, return only one CPU (just in case)
+
+ siblings=1 # default values
+ cpu_cores=1 # for siblings and cpu cores
+ notfirst=False
+ ncores=0
+ while(True):
+ line=proc.readline()
+
+ if (((line[:9]=="processor") and notfirst) or (line=="")):
+
+ # each entry is equivalent to CPU_CORES/SIBLINGS real cores
+ # (always 1 except in HyperThreading systems, where it counts 1/2)
+
+ ncores+=(float(cpu_cores))/(float(siblings))
+ siblings=1
+ cpu_cores=1
+
+ if line=="":
+ break
+
+ if line[:9]=="processor":
+ notfirst=True
+ elif (line[:8]=="siblings"):
+ siblings=self.get_number(line)
+ elif (line[:9]=="cpu cores"):
+ cpu_cores=self.get_number(line)
+
+ if(ncores<=1.0):
+ return 1
+ else:
+ return int(ncores)
+
+ # Callbacks
+
+ def on_autosize_clicked(self,widget):
+
+ """ Adjust the videorate of each file to ensure that the disk usage is optimal """
+
+ fixed_size=[]
+ variable_size=[]
+
+ # First, set the non-adjustable bitrate videos in a different list
+
+ for element in self.structure:
+ for element2 in element[1:]:
+ if (element2["ismpeg"]) or (element2["isvob"]):
+ fixed_size.append(element2)
+ else:
+ variable_size.append(element2)
+
+ discsize,minrate,maxrate=devede_other.get_dvd_size(self.tree,self.disctocreate)
+ discsize*=1000 # size in kbytes
+ # remove the space needed by menus
+ discsize-=devede_other.calcule_menu_size(self.structure,self.global_vars["menu_sound_duration"])
+
+ size_error=False
+ dowhile=True
+ while(dowhile):
+ dowhile=False
+ v_fixed_size=0
+ for element in fixed_size:
+ size,surface,length,arate = self.get_surface(element)
+ subrate=8*len(element["sub_list"])
+ v_fixed_size+=size+int((subrate*element["olength"])/8)
+
+ available_size=discsize-v_fixed_size
+
+ if (available_size<0): # the fixed_size videos need more disk space than the currently available
+ size_error=True
+ break
+
+ if (len(variable_size)==0):
+ break
+
+ total_len=0.0
+ total_surface=0.0
+ for element in variable_size:
+ size,surface,length,arate = self.get_surface(element)
+ total_len+=length
+ total_surface+=surface*length
+
+ for element in variable_size:
+ subrate=8*len(element["sub_list"])
+ size,surface,length,arate = self.get_surface(element)
+ videorate=8*(float(available_size))*((surface*length)/total_surface)
+ videorate/=length
+ videorate-=(arate+subrate)
+ element["vrate"]=int(videorate)
+ print int(videorate)
+ if videoratemaxrate:
+ element["vrate"]=maxrate
+ dowhile=True
+ fixed_size.append(element)
+ variable_size.remove(element)
+ break
+
+ if size_error:
+ devede_dialogs.show_error(self.gladefile,_("Too many videos for this disc size.\nPlease, select a bigger disc type or remove some videos."))
+
+ self.set_video_values()
+
+
+ def wmain_delete_event_cb(self,widget,signal):
+
+ """ Delete callback for main window """
+
+ self.on_main_cancel_clicked(widget)
+ return True
+
+
+ def on_main_cancel_clicked(self,widget):
+
+ """ Callback for Exit button (in main window) and Quit menu item,
+ where it shows the "Are you sure?" window """
+
+ window=devede_dialogs.ask_exit(self.gladefile)
+ retval=window.run()
+ window=None
+ if retval==-5:
+ gtk.main_quit()
+ return
+
+
+ def draganddrop(self,widget,drag_context, x, y, selection, info, time):
+
+ """ Manages the Drag&Drop in the main window """
+
+ converter=devede_newfiles.newfile(self.global_vars["PAL"],self.disctocreate)
+
+ list=converter.split_dnd(selection.data)
+
+ if (len(list)==1): # check if it's a configuration file
+ filename=list[0].lower()
+ if len(filename)>6:
+ if filename[-7:]==".devede":
+ self.on_devede_open_activate(None, list[0])
+ return
+
+ fine=True
+ list2=[]
+ for element in list:
+ done,audio=converter.create_default_video_parameters(element) # check if files are videos
+ print done
+ print audio
+ if (done==False):
+ fine=False
+ break
+ list2.append(converter.file_properties)
+
+ if fine:
+ title,chapter=self.get_marked()
+ element=self.structure[title]
+ for element2 in list2:
+ element.append(element2)
+ self.refresh_chapters()
+ self.set_buttons()
+ else:
+ error=devede_dialogs.show_error(self.gladefile,_("Some files weren't video files.\nNone added."))
+ error=None
+
+
+ def on_default_pal_toggled(self,widget):
+
+ if widget.get_active():
+ self.global_vars["PAL"]=True
+ else:
+ self.global_vars["PAL"]=False
+ print "PAL: "+str(self.global_vars["PAL"])
+
+
+ def on_chapterclick(self,widget,event,step=None):
+
+ """ Callback for click event in the chapter list. It
+ sets the buttons and film info """
+
+ self.set_buttons()
+
+
+ def on_dvdsize_changed(self,widget):
+
+ """ This function is called when the user changes the media size """
+
+ self.set_video_values()
+
+
+ def on_include_menu_toggled(self,widget):
+
+ w1=self.tree.get_object("menuoptions")
+ w2=self.tree.get_object("menu_preview")
+ status=widget.get_active()
+ w1.set_sensitive(status)
+ w2.set_sensitive(status)
+ self.global_vars["with_menu"]=status
+
+
+ def on_main_go_clicked(self,widget):
+
+ total=0
+ for title in self.structure:
+ total+=len(title)-1
+
+ maxtitles=devede_other.get_max_titles(self.disctocreate)
+ if total>maxtitles:
+ devede_dialogs.show_error(self.gladefile,(_("Your project contains %(X)d movie files, but the maximum is %(MAX)d. Please, remove some files and try again.")) % {"X":total , "MAX":maxtitles})
+ return
+
+ actions=0
+ w=self.tree.get_object("only_convert")
+ if w.get_active():
+ actions=1
+ else:
+ w=self.tree.get_object("create_dvd")
+ if (w.get_active()) or ((self.disctocreate!="dvd") and (self.disctocreate!="divx")):
+ actions=2
+ else:
+ actions=3
+
+ self.global_vars["number_actions"]=actions
+ w=self.tree.get_object("erase_files")
+ self.global_vars["erase_temporary_files"]=w.get_active()
+
+ print "Threads: "+str(self.global_vars["multicore"])
+ conversor=devede_convert.create_all(self.gladefile,self.structure,self.global_vars,self.callback2)
+ if conversor.create_disc():
+ self.window.hide()
+
+
+ def on_multicore_toggled(self,widget):
+
+ w=self.tree.get_object("multicore")
+ if w.get_active():
+ self.global_vars["multicore"]=self.get_cores()
+ else:
+ self.global_vars["multicore"]=1
+
+
+ # titles-related callbacks
+
+
+ def on_titleclick(self,widget,event,step=None):
+
+ """ Callback for click event in the title list. It refreshes the chapters
+ and sets the buttons and film info """
+
+ self.refresh_chapters()
+ self.set_buttons()
+
+
+ def on_add_title_clicked(self,widget):
+
+ """ Callback for "Add title" button. It adds a new title and
+ refreshes the list of titles """
+
+ self.structure.append(self.create_new_structure(self.global_vars["titlecounter"]))
+ self.global_vars["titlecounter"]+=1
+ self.current_title_selected=10000 # to ensure that we select the newly created
+ self.refresh_titles()
+ self.refresh_chapters()
+ self.set_buttons()
+
+
+ def on_del_title_clicked(self,widget):
+
+ """ Callback for "Delete title" button. It asks the user if
+ is sure """
+
+ title,chapter=self.get_marked()
+ window=devede_dialogs.ask_delete_title(self.structure[title][0]["nombre"],self.gladefile)
+ retval=window.run()
+ window=None
+ if retval==-6:
+ return
+ title,chapter=self.get_marked()
+ self.structure.pop(title)
+ self.refresh_titles()
+ self.refresh_chapters()
+ self.set_buttons()
+
+
+ def on_titleup_clicked(self,widget):
+
+ """ Moves a title up in the list """
+
+ title,chapter=self.get_marked()
+
+ temp=self.structure[title-1]
+ self.structure[title-1]=self.structure[title]
+ self.structure[title]=temp
+
+ self.current_title_selected-=1
+ self.refresh_titles()
+ self.refresh_chapters()
+ self.set_buttons()
+
+
+ def on_titledown_clicked(self,widget):
+
+ """ Moves a title down in the list """
+
+ title,chapter=self.get_marked()
+
+ temp=self.structure[title+1]
+ self.structure[title+1]=self.structure[title]
+ self.structure[title]=temp
+ self.current_title_selected+=1
+ self.refresh_titles()
+ self.refresh_chapters()
+ self.set_buttons()
+
+
+ def on_prop_titles_clicked(self,widget):
+
+ title,chapter=self.get_marked()
+ w = devede_title_properties.title_properties(self.gladefile,self.structure,title)
+ w = None
+ self.refresh_titles()
+ self.refresh_chapters()
+
+
+ # chapter-related callbacks
+
+
+ def on_add_chapter_clicked(self,widget):
+
+ """ Callback for the "Add chapter" button """
+
+ title,chapter=self.get_marked()
+ window=devede_newfiles.file_properties(self.global_vars,title,-1,self.structure,self.refresh_all)
+
+
+ def on_prop_chapter_clicked(self,widget):
+
+ """ Callback for the "Modify chapter" button """
+
+ title,chapter=self.get_marked()
+ window=devede_newfiles.file_properties(self.global_vars,title,chapter,self.structure,self.refresh_all)
+
+
+ def on_del_chapter_clicked(self,widget):
+
+ title,chapter=self.get_marked()
+
+ w=devede_dialogs.ask_delete_chapter(self.structure[title][chapter]["filename"],self.gladefile)
+ retval=w.run()
+ w=None
+ if retval!=-5:
+ return
+
+ self.structure[title].pop(chapter)
+
+ self.refresh_chapters()
+ self.set_buttons()
+
+
+ def on_main_preview_clicked(self,widget):
+
+ title,chapter=self.get_marked()
+ self.global_vars["erase_temporary_files"]=True
+ self.global_vars["number_actions"]=1
+ tmp_structure=[["",self.structure[title][chapter]]]
+ converter=devede_convert.create_all(self.gladefile,tmp_structure,self.global_vars,self.callback3)
+ self.global_vars["temp_folder"]=converter.preview(self.global_vars["temp_folder"])
+ print "Temp folder changed to "+str(self.global_vars["temp_folder"])
+
+
+ def callback3(self):
+
+ """ This method is called after a preview """
+
+ return None # do nothing
+
+
+ def on_filesup_clicked(self,widget):
+
+ """ Moves a chapter up in the list """
+
+ title,chapter=self.get_marked()
+
+ temp=self.structure[title][chapter-1]
+ self.structure[title][chapter-1]=self.structure[title][chapter]
+ self.structure[title][chapter]=temp
+ self.current_file_selected-=1
+ self.refresh_chapters()
+ self.set_buttons()
+
+
+ def on_filesdown_clicked(self,widget):
+
+ """ Moves a chapter down in the list """
+
+ title,chapter=self.get_marked()
+
+ temp=self.structure[title][chapter+1]
+ self.structure[title][chapter+1]=self.structure[title][chapter]
+ self.structure[title][chapter]=temp
+ self.current_file_selected+=1
+ self.refresh_chapters()
+ self.set_buttons()
+
+
+ # dvd-menu-related callbacks
+
+ def on_menu_preview_clicked(self,widget):
+
+ window=devede_dvdmenu.menu_preview(self.gladefile,self.structure,self.global_vars)
+ window=None
+
+
+ def on_menuoptions_clicked(self,widget):
+
+ window=devede_dvdmenu.menu_options(self.gladefile,self.structure,self.global_vars,self.set_video_values)
+ window=None
+
+
+ # Main menu callbacks
+
+ def on_devede_about_activate(self,widget):
+
+ window=devede_dialogs.show_about(self.gladefile)
+ window=None
+
+
+ def on_devede_new_activate(self,widget):
+
+ """ Callback for NEW menu item, where it asks for confirmation """
+
+ print self.structure
+ w = devede_dialogs.ask_erase_all(self.gladefile)
+ retval=w.run()
+ w = None
+ if retval==-5:
+ (self.callback)()
+
+
+ def on_devede_open_activate(self,widget,filename=None):
+
+ """ Callback for OPEN menu item """
+
+ load = devede_loadsave.load_save_config(self.gladefile,self.structure,self.global_vars,self.tree)
+ load.load(filename)
+ if load.done==False:
+ load=None
+ return
+
+ self.set_disc_type(False)
+ self.refresh_titles()
+ self.refresh_chapters()
+ self.set_buttons()
+ self.set_title()
+ if self.global_vars["PAL"]:
+ w=self.tree.get_object("default_pal")
+ else:
+ w=self.tree.get_object("default_ntsc")
+ w.set_active(True)
+
+ w=self.tree.get_object("include_menu")
+ print"Con menu: "+str(self.global_vars["with_menu"])
+ w.set_active(self.global_vars["with_menu"])
+ load=None
+
+
+ def on_devede_save_activate(self,widget):
+
+ self.save_file(False)
+
+
+ def on_devede_saveas_activate(self,widget):
+
+ self.save_file(True)
+
+
+ def on_main_help_clicked(self,widget):
+
+ help_class=devede_help.show_help(self.gladefile,self.global_vars["help_path"],"main.html")
+
+
+ def on_help_index_activate(self,widget):
+
+ help_class=devede_help.show_help(self.gladefile,self.global_vars["help_path"],"index.html")
+
+
+ # help methods
+
+ def callback2(self):
+
+ """ This method is called when the conversion ends """
+
+ self.window.show()
+
+
+ def refresh_all(self):
+
+ self.refresh_chapters()
+ self.set_buttons()
+
+
+ def save_file(self,mode):
+
+ """ Saves the current structure """
+
+ save=devede_loadsave.load_save_config(self.gladefile,self.structure,self.global_vars,self.tree)
+ save.save(mode)
+ self.set_title()
+ save=None
+
+
+ def get_marked(self):
+
+ """ Returns the title and chapter currently marked in the main window """
+
+ ltitles=self.tree.get_object("ltitles")
+ lchapters=self.tree.get_object("lchapters")
+
+ try:
+ ctree,iter=ltitles.get_selection().get_selected()
+ title=ctree.get_value(iter,0)
+ except:
+ title=-1
+
+ try:
+ ctree,iter=lchapters.get_selection().get_selected()
+ chapter=1+ctree.get_value(iter,0) # zero is the Title value
+ except:
+ chapter=-1
+
+ self.current_title_selected=title
+ self.current_file_selected=chapter
+
+ return title,chapter
+
+
+ def set_buttons(self):
+
+ """ Enables or disables the button to create a DVD, and the
+ buttons to move up or down a title or chapter """
+
+ title,chapter=self.get_marked()
+
+ if title==-1:
+ title_marked=False
+ else:
+ title_marked=True
+
+ title_up=self.tree.get_object("titleup")
+ if title==0:
+ title_up.set_sensitive(False)
+ else:
+ title_up.set_sensitive(True)
+
+ title_down=self.tree.get_object("titledown")
+ if (title+1)==len(self.structure):
+ title_down.set_sensitive(False)
+ else:
+ title_down.set_sensitive(True)
+
+ if chapter==-1:
+ chapter_marked=False
+ else:
+ chapter_marked=True
+
+ files_up=self.tree.get_object("filesup")
+ if chapter<2:
+ files_up.set_sensitive(False)
+ else:
+ files_up.set_sensitive(True)
+
+ files_down=self.tree.get_object("filesdown")
+ if (chapter==-1) or (chapter+1==len(self.structure[title])):
+ files_down.set_sensitive(False)
+ else:
+ files_down.set_sensitive(True)
+
+ del_title=self.tree.get_object("del_title")
+ if len(self.structure)>1:
+ del_title.set_sensitive(title_marked)
+ else:
+ del_title.set_sensitive(False)
+
+ add_title=self.tree.get_object("add_title")
+ if (len(self.structure)<61):
+ add_title.set_sensitive(True)
+ else:
+ add_title.set_sensitive(False)
+
+ add_chapter=self.tree.get_object("add_chapter")
+ add_chapter.set_sensitive(title_marked)
+
+ del_chapter=self.tree.get_object("del_chapter")
+ del_chapter.set_sensitive(chapter_marked)
+
+ main_preview=self.tree.get_object("main_preview")
+ main_preview.set_sensitive(chapter_marked)
+
+ prop_chapter=self.tree.get_object("prop_chapter")
+ prop_chapter.set_sensitive(chapter_marked)
+
+ value=False
+ for element in self.structure:
+ if len(element)>1:
+ value=True
+ break
+
+ main_go=self.tree.get_object("main_go")
+ main_go.set_sensitive(value)
+ self.set_video_values()
+
+
+ def set_video_values(self):
+
+ """ Sets the video values in the main window when the user clicks
+ a chapter """
+
+ title,chapter=self.get_marked()
+ if (chapter!=-1) and (title!=-1) and (title1.5:
+ w.set_text("16:9")
+ else:
+ w.set_text("4:3")
+
+ w=self.tree.get_object("o_size")
+ w.set_text(str(found["owidth"])+"x"+str(found["oheight"]))
+
+ w=self.tree.get_object("leng")
+ w.set_text(str(found["olength"]))
+
+ w=self.tree.get_object("vrate")
+ w.set_text(str(found["vrate"]))
+
+ w=self.tree.get_object("arate")
+ w.set_text(str(found["arate"]))
+
+ w=self.tree.get_object("eleng")
+ speed1,speed2=devede_other.get_speedup(found)
+ length=devede_other.calcula_tamano_parcial(found["vrate"],found["arate"],found["filesize"],found["olength"],len(found["sub_list"]),found["ismpeg"],found["isvob"],found["cutting"],speed1,speed2)
+ #length=int(((found["vrate"]+found["arate"])*found["olength"])/8000)
+ w.set_text(str(int(length/1000)))
+
+ w=self.tree.get_object("achap")
+ if found["lchapters"]==0:
+ w.set_text(_("no chapters"))
+ else:
+ w.set_text(str(int(found["lchapters"])))
+
+ w=self.tree.get_object("video_format")
+ if found["fps"]==25:
+ w.set_text("25 (PAL)")
+ elif found["fps"]==30:
+ if (found["ofps"]==24) and (self.disctocreate!="vcd") and (self.disctocreate!="svcd") and (self.disctocreate!="cvd"):
+ w.set_text("24 (NTSC)")
+ else:
+ w.set_text("30 (NTSC)")
+ else:
+ w.set_text(str(int(found["fps"])))
+
+ w=self.tree.get_object("fsizem")
+ w.set_text(str(found["width"])+"x"+str(found["height"]))
+
+ else:
+
+ w=self.tree.get_object("oaspect")
+ w.set_text("")
+ w=self.tree.get_object("o_size")
+ w.set_text("")
+ w=self.tree.get_object("leng")
+ w.set_text("")
+ w=self.tree.get_object("vrate")
+ w.set_text("")
+ w=self.tree.get_object("arate")
+ w.set_text("")
+ w=self.tree.get_object("eleng")
+ w.set_text("")
+ w=self.tree.get_object("achap")
+ w.set_text("")
+ w=self.tree.get_object("video_format")
+ w.set_text("")
+ w=self.tree.get_object("fsizem")
+ w.set_text("")
+
+ total=devede_other.calcula_tamano_total(self.structure,self.global_vars["menu_sound_duration"],self.disctocreate)
+ total/=1000
+
+ tamano,minvrate,maxvrate = devede_other.get_dvd_size(self.tree,self.disctocreate)
+
+ w=self.tree.get_object("usage")
+ if total>tamano:
+ w.set_fraction(1.0)
+ addv=1
+ else:
+ w.set_fraction(total/tamano)
+ addv=0
+ w.set_text(str(addv+int((total/tamano)*100))+"%")
+
+
+ def set_title(self):
+
+ """ Sets the window's title, with the current structure name if saved """
+
+ name=os.path.basename(str(self.global_vars["struct_name"]))
+ if name=="":
+ name=_("Unsaved disc structure")
+ self.window.set_title(name+' - DeVeDe')
+
+
+ def refresh_titles(self):
+
+ """ Refreshes the title list """
+
+ self.current_file_selected=-1
+
+ self.list_titles.clear()
+ self.list_chapters.clear()
+
+ counter=-1
+ for element in self.structure:
+ counter+=1
+ entry=self.list_titles.insert_before(None,None)
+ self.list_titles.set_value(entry,1,element[0]["nombre"])
+ self.list_titles.set_value(entry,0,counter)
+
+ if counter.
+
+import os
+import stat
+
+import pygtk # for testing GTK version number
+pygtk.require ('2.0')
+import gtk
+import gobject
+import sys
+import gc
+import copy
+import time
+
+import devede_other
+import devede_executor
+import devede_convert
+import devede_dialogs
+import devede_help
+
+# How to add new file options:
+
+# In the class NEWFILE, method CREATE_DEFAULT_VIDEO_PARAMETERS, add the new option
+# to the SELF.FILE_PROPERTIES dictionary, setting its default value based in the
+# SELF.FILE_VALUES values (the ones obtained with MPLAYER --IDENTIFY), SELF.PAL (True
+# for PAL output video, False for NTSC output video) and SELF.DISCTOCREATE (DVD, VCD, SVCD
+# CVD or DIVX)
+
+# In the class FILE_PROPERTIES
+
+# In the method GET_WIDGETS, set the parameter value in the SELF.FILE_PROPERTIES
+# dictionary using the widget's current value
+
+# In the method SET_WIDGETS, set the widget's value using the parameter value in
+# SELF.FILE_PROPERTIES
+
+# If the widget must be disabled or enabled under some circumstances (other widgets)
+# set that code in method SET_FILM_BUTTONS
+#
+# Finally, add the needed code in DEVEDE_LOADSAVE.PY to ensure that old project files
+# work fine with the new options
+
+class file_get_params(devede_executor.executor):
+
+
+ def read_file_values(self,filename,check_audio):
+
+ """ Reads the values of the video (width, heigth, fps...) and stores them
+ into file_values.
+
+ Returns (False,AUDIO) if the file is not a video (with AUDIO the number
+ of audio tracks)
+
+ Returns (True,0) if the file is a right video file """
+
+ handler=''
+
+ vrate=0
+ arate=0
+ width=0
+ height=0
+ fps=0
+ length=0
+ audio=0
+ video=0
+ audiorate=0
+ aspect_ratio=1.3333333333
+ self.length=0
+
+ # if CHECK_AUDIO is TRUE, we just check if it's an audio file
+
+ if check_audio:
+ nframes=0
+ else:
+ nframes=1
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ command="mplayer.exe"
+ else:
+ command="mplayer"
+ launcher=[command, "-loop","1","-identify", "-ao", "null", "-vo", "null", "-frames", str(nframes), filename]
+ handler=self.launch_program(launcher, win32arg=False,with_stderr=False)
+
+ minimum_audio=10000
+ audio_list=[]
+ while True:
+ linea=handler.stdout.readline()
+ linea=self.remove_ansi(linea)
+ if linea=="":
+ break
+ position=linea.find("ID_")
+ if position==-1:
+ continue
+ linea=linea[position:]
+ if linea[:16]=="ID_VIDEO_BITRATE":
+ vrate=int(linea[17:])
+ if linea[:14]=="ID_VIDEO_WIDTH":
+ width=int(linea[15:])
+ if linea[:15]=="ID_VIDEO_HEIGHT":
+ height=int(linea[16:])
+ if linea[:15]=="ID_VIDEO_ASPECT":
+ aspect_ratio=float(linea[16:])
+ if linea[:12]=="ID_VIDEO_FPS":
+ fps2=linea[13:]
+ while ord(fps2[-1])<32:
+ fps2=fps2[:-1]
+ posic=linea.find(".")
+ if posic==-1:
+ fps=int(linea[13:])
+ else:
+ fps=int(linea[13:posic])
+ if linea[posic+1]=="9":
+ fps+=1
+ if linea[:16]=="ID_AUDIO_BITRATE":
+ arate=int(linea[17:])
+ if linea[:13]=="ID_AUDIO_RATE":
+ audiorate=int(linea[14:])
+ if linea[:9]=="ID_LENGTH":
+ length=int(float(linea[10:]))
+ if linea[:11]=="ID_VIDEO_ID":
+ video+=1
+ if linea[:11]=="ID_AUDIO_ID":
+ audio+=1
+ audio_track=int(linea[12:])
+ if minimum_audio>audio_track:
+ minimum_audio=audio_track
+ audio_list.append(audio_track)
+
+ handler.wait()
+
+ if (video==0) or (width==0) or (height==0):
+ if (audio!=0):
+ self.length=length
+ self.audio=audio
+ return False,audio
+
+ if aspect_ratio==0.0:
+ aspect_ratio=(float(width))/(float(height))
+ if aspect_ratio<=1.5:
+ aspect_ratio=(4.0/3.0)
+
+ self.file_values={}
+ self.file_values["vrate"]=vrate
+ self.file_values["arate"]=arate
+ self.file_values["video_streams"]=video
+ self.file_values["audio_streams"]=audio
+ self.file_values["width"]=width
+ self.file_values["height"]=height
+ self.file_values["fps"]=fps
+ self.file_values["ofps2"]=fps2
+ self.file_values["length"]=length
+ self.file_values["aspect_ratio"]=aspect_ratio
+ self.file_values["audiorate"]=audiorate
+ self.file_values["audio_list"]=audio_list
+ self.file_values["audio_stream"]=minimum_audio
+
+ return True,0
+
+class newfile(file_get_params):
+
+ def __init__(self,pal,disctocreate):
+ """ This class manages every new film added. It reads its parameters (resolution, FPS, number of
+ channels...) and allows to generate the default values, both when choosing manually a file from the
+ Properties window, or when dragging&dropping them into the main window """
+
+ self.pal=pal
+ self.disctocreate=disctocreate
+ self.file_values=None
+ self.file_properties=None
+
+
+ def get_recomended_resolution(self,vrate,arate,desired_resolution):
+
+ """ Returns the recomended resolution for a video based in its original
+ resolution and the resolution chosed by the user.
+
+ DESIRED_RESOLUTION is a value from 0 to 7:
+ 0=auto, 1=720x480, 2=704x480, 3=480x480, 4=352x480, 5=352x240
+ 6=1280x720, 7=1920x1080, 8 160x128
+
+ It returns the recomended audio and video rate for that resolution,
+ but only if the user hasn't changed them """
+
+ if self.pal:
+ nheigh1=576
+ nheigh2=288
+ else:
+ nheigh1=480
+ nheigh2=240
+
+ if self.file_values==None:
+ return 0,0,False,0,0
+
+ if desired_resolution==0: # default resolution; we have to take the most similar resolution
+ if self.disctocreate=="vcd":
+ resx=352
+ resy=nheigh2
+ elif self.disctocreate=="cvd":
+ resx=352
+ resy=nheigh1
+ elif self.disctocreate=="svcd":
+ resx=480
+ resy=nheigh1
+ else: # dvd o divx
+ if self.file_values["width"]<=352:
+ resx=352
+ if self.file_values["height"]<=nheigh2:
+ resy=nheigh2
+ else:
+ resy=nheigh1
+ else:
+ resx=720
+ resy=nheigh1
+ elif desired_resolution==1:
+ resx=720
+ resy=nheigh1
+ elif desired_resolution==2:
+ resx=704
+ resy=nheigh1
+ elif desired_resolution==3:
+ resx=480
+ resy=nheigh1
+ elif desired_resolution==4:
+ resx=352
+ resy=nheigh1
+ elif desired_resolution==5:
+ resx=352
+ resy=nheigh2
+ elif desired_resolution==6:
+ resx=1280
+ resy=720
+ elif desired_resolution==7:
+ resx=1920
+ resy=1080
+ elif desired_resolution==8:
+ resx=160
+ resy=128
+
+ if (((resx==720) and (resy==nheigh1)) or ((self.disctocreate=="divx") and (desired_resolution!=8))) and (self.file_values["aspect_ratio"]>=1.77):
+ use_widescreen=True
+ else:
+ use_widescreen=False
+
+ if (vrate==5001) or (vrate==3001) or (vrate==2001):
+ if (resx>703):
+ vrate=5001
+ if (resx==480) or ((resx==352) and (resy==nheigh1)):
+ vrate=3001
+ if (resx==352) and (resy==nheigh2):
+ vrate=2001
+ if (self.disctocreate!="dvd") and (self.disctocreate!="divx"):
+ vrate=2001
+
+ if self.disctocreate=="vcd":
+ vrate=1152
+ arate=224
+
+ return resx,resy,use_widescreen,vrate,arate
+
+
+ def create_default_video_parameters(self,filename):
+
+ """ This method fills the FILE_PROPERTIES property with the default values for the file.
+ It returns False if the file isn't a valid video. The tuple contains the number of sound
+ tracks found, so if it's different from 0, its an audio-only file. """
+
+ if filename==None:
+ return False,0
+
+ isvideo,audio_tracks=self.read_file_values(filename,True)
+ if isvideo==False:
+ return False,audio_tracks
+ isvideo,audio_tracks=self.read_file_values(filename,False) # get all the values in FILE_VALUES
+
+ while filename[-1]==os.sep:
+ filename=filename[:-1]
+
+ nombre=filename
+ while True: # get the filename without the path
+ posic=nombre.find(os.path.sep)
+ if posic==-1:
+ break
+ else:
+ nombre=nombre[posic+1:]
+
+ # filename[0]; path[1]; width[2]; heigh[3]; length[4] (seconds); original fps[5];
+ # original videorate["oarate"]; original audiorate[7];
+ # final videorate[8]; final arate[9]; final width[10]; final heigh[11];
+ # 0=Black bars, 1=Scale picture [12];
+ # length of chapters[13]; audio delay["fps"]; final fps["arateunc"]; original audio rate (uncompressed)["oaspect"];
+ # original aspect ratio[17]; final aspect ratio[18];
+ # 0=full length, 1=first half, 2=second half [19];
+ # Resolution: 0=auto, 1=720x480, 2=704x480, 3=480x480, 4=352x480, 5=352x240, 6=1280x720, 7=1920x1080 [20]
+ # extra parameters [21]
+
+ self.file_properties={}
+ self.file_properties["filename"]=nombre # filename without path
+ self.file_properties["path"]=filename # file with complete path
+ self.file_properties["owidth"]=self.file_values["width"] # original width
+ self.file_properties["oheight"]=self.file_values["height"] # original height
+ self.file_properties["olength"]=self.file_values["length"] # original length (in seconds)
+ self.file_properties["ovrate"]=self.file_values["vrate"]/1000 # original videorate (in kbytes/second)
+ self.file_properties["oarate"]=self.file_values["arate"]/1000 # original audiorate (in kbytes/second)
+ self.file_properties["arateunc"]=self.file_values["audiorate"] # original uncompressed audiorate
+ self.file_properties["oaspect"]=self.file_values["aspect_ratio"] # original aspect ratio
+ self.file_properties["audio_list"]=self.file_values["audio_list"][:]
+ self.file_properties["audio_stream"]=self.file_values["audio_stream"]
+
+ if self.pal:
+ self.file_properties["fps"]=25
+ else:
+ self.file_properties["fps"]=30
+
+ self.file_properties["ofps"]=self.file_values["fps"]
+ self.file_properties["ofps2"]=self.file_values["ofps2"]
+
+ self.file_properties["blackbars"]=0 # black bars, no scale
+ self.file_properties["lchapters"]=5
+ self.file_properties["adelay"]=0 # no audio delay
+ self.file_properties["cutting"]=0 # full length
+ self.file_properties["resolution"]=0 # output resolution = auto
+ self.file_properties["params"]="" # no mencoder extra parameters
+ self.file_properties["params_vf"]="" # no mencoder extra VF parameters
+ self.file_properties["params_lavc"]="" # no mencoder extra LAVC parameters
+ self.file_properties["params_lame"]="" # no mencoder extra LAME parameters
+ self.file_properties["ismpeg"]=False # is already an MPEG-2 compliant file
+ self.file_properties["copy_audio"]=False # recompress the audio
+ self.file_properties["isvob"]=False # recompress both audio and video
+ self.file_properties["swap_fields"]=False # swap fields in interlaced videos
+ self.file_properties["subfont_size"]=28 # subtitle font size
+ self.file_properties["sound51"]=False # don't use 5.1 sound
+ self.file_properties["gop12"]=True # GOP of 12 by default to increase compatibility
+ self.file_properties["filesize"]=os.stat(filename)[stat.ST_SIZE] # file size
+ self.file_properties["trellis"]=True # use trellis
+ self.file_properties["twopass"]=False # two pass encoding
+ self.file_properties["turbo1stpass"]=False # use turbo 1st pass on two pass encoding
+ self.file_properties["mbd"]=2 # maximum quality
+ self.file_properties["deinterlace"]="none" # don't deinterlace
+ self.file_properties["sub_list"]=[]
+ self.file_properties["force_subs"]=False
+
+ resx,resy,use_widescreen,vrate,arate=self.get_recomended_resolution(5001, 224, 0)
+ self.file_properties["width"]=resx
+ self.file_properties["height"]=resy
+ self.file_properties["vrate"]=vrate
+ self.file_properties["arate"]=arate
+
+ self.file_properties["rotate"]=0 # no rotation
+ self.file_properties["hmirror"]=False
+ self.file_properties["vmirror"]=False
+
+ if use_widescreen:
+ self.file_properties["aspect"]=1.7777777
+ else:
+ self.file_properties["aspect"]=1.3333333
+
+ self.file_properties["volume"]=100
+
+ return True,audio_tracks
+
+
+ def split_dnd(self,data):
+
+ """ Takes the list of files dragged into the window and returns them in a list """
+
+ lista=[]
+ item=""
+ tempo=""
+ mode=0
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ length=8
+ else:
+ length=7
+
+ for elemento in data:
+ if (elemento=="\n") and (item!=""):
+ if item[:8]=="file:///":
+ lista.append(item[length:])
+ item=""
+ continue
+ if ord(elemento)<32:
+ continue
+ if mode==0:
+ if elemento=="%":
+ mode=1
+ else:
+ item+=elemento
+ elif mode==1:
+ tempo=elemento
+ mode=2
+ else:
+ mode=0
+ item+=chr(int(tempo+elemento,16))
+ print "Dragged files: "+str(lista)
+ return lista
+
+
+##################################################################################
+
+
+class file_properties(newfile):
+
+ """ This class manages the properties window, where the user can choose the properties
+ of each video file """
+
+ # public methods
+
+ def __init__(self,global_vars,title,chapter,structure,callback_refresh):
+
+ newfile.__init__(self,global_vars["PAL"],global_vars["disctocreate"])
+ self.gladefile=global_vars["gladefile"]
+ self.global_vars=global_vars
+ self.title=title
+ self.chapter=chapter
+ self.structure=structure
+ self.callback_refresh=callback_refresh
+
+ self.tree=devede_other.create_tree(self,"wfile",self.gladefile)
+ self.window=self.tree.get_object("wfile")
+ self.window.show()
+ self.window.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP,[ ( "text/plain", 0, 80 ), ( "video/*", 0, 81) ],gtk.gdk.ACTION_COPY)
+ w = self.tree.get_object("expander_advanced")
+ w.set_expanded(self.global_vars["expand_advanced"])
+
+ if global_vars["PAL"]:
+ w=self.tree.get_object("video_pal")
+ else:
+ w=self.tree.get_object("video_ntsc")
+ w.set_active(True)
+
+ # Model and view for subtitles
+ # first element: position
+ # second: filename
+ # third: codepage
+
+ self.sub_model=gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
+ self.sub_tree=self.tree.get_object("sub_treeview")
+ self.sub_tree.set_model(self.sub_model)
+ render1=gtk.CellRendererText()
+ column1=gtk.TreeViewColumn(_("Subtitle"),render1,text=1)
+ self.sub_tree.append_column(column1)
+ render2=gtk.CellRendererText()
+ column2=gtk.TreeViewColumn(_("Codepage"),render2,text=2)
+ self.sub_tree.append_column(column2)
+ render3=gtk.CellRendererText()
+ column3=gtk.TreeViewColumn(_("Language"),render3,text=3)
+ self.sub_tree.append_column(column3)
+
+ # Model and view for audio tracks
+
+ self.audio_model=gtk.ListStore(gobject.TYPE_STRING)
+ self.audio_view=self.tree.get_object("audiotrack")
+ self.audio_view.set_model(self.audio_model)
+ audiorender=gtk.CellRendererText()
+ self.audio_view.pack_start(audiorender,True)
+ self.audio_view.add_attribute(audiorender,"text",0)
+
+ w1 = self.tree.get_object("subtitles_label")
+ w2 = self.tree.get_object("frame_special")
+ w3 = self.tree.get_object("gop12")
+ w4 = self.tree.get_object("res1280x720")
+ w5 = self.tree.get_object("res1920x1080")
+ w6 = self.tree.get_object("subtitles_list")
+ w7 = self.tree.get_object("res160x128")
+
+ if (self.disctocreate == "divx"):
+ w1.show()
+ w2.hide()
+ w3.hide()
+ w4.show()
+ w5.show()
+ w6.hide()
+ w7.show()
+ else:
+ w1.hide()
+ w2.show()
+ w3.show()
+ w4.hide()
+ w5.hide()
+ w6.show()
+ w7.hide()
+
+ w=self.tree.get_object("noaudiotracks")
+ w.hide()
+
+ w=self.tree.get_object("file_split_frame")
+ if (self.disctocreate=="vcd") or (self.disctocreate=="svcd") or (self.disctocreate=="cvd"):
+ w.show()
+ else:
+ w.hide()
+
+ w = self.tree.get_object("frame_division") # SPLIT THE FILES IN CHAPTERS FOR EASY SEEKING
+ if (self.disctocreate == "dvd"):
+ w.show()
+ else:
+ w.hide()
+
+ self.set_resolution()
+ self.change_file=False
+ if (self.chapter!=-1): # we want to modify a chapter
+ the_chapter=structure[title][chapter]
+ print "Chequeo "+str(the_chapter["path"])
+ isvideo,audio_tracks=self.read_file_values(the_chapter["path"],True)
+ if isvideo==True:
+ self.read_file_values(the_chapter["path"],False) # get all the values in FILE_VALUES
+ self.file_properties=copy.deepcopy(the_chapter)
+ self.change_file=True # we are changing the file name manually
+ w=self.tree.get_object("moviefile")
+ print "Pongo nombre por propiedades"
+ w.set_filename(self.file_properties["path"])
+ else:
+ w1.set_sensitive(False)
+ else:
+ if (self.global_vars["filmpath"]!=""):
+ w=self.tree.get_object("moviefile")
+ w.set_current_folder(self.global_vars["filmpath"])
+
+ w=self.tree.get_object("moviefile")
+ self.file_filter_videos=gtk.FileFilter()
+ self.file_filter_videos.set_name(_("Video files"))
+ if (sys.platform!="win32") and (sys.platform!="win64"):
+ self.file_filter_videos.add_mime_type("video/*")
+ self.file_filter_videos.add_pattern("*.rmvb")
+ else:
+ self.file_filter_videos.add_custom(gtk.FILE_FILTER_FILENAME|gtk.FILE_FILTER_DISPLAY_NAME, self.custom_video_filter)
+ self.file_filter_all=gtk.FileFilter()
+ self.file_filter_all.set_name(_("All files"))
+ self.file_filter_all.add_pattern("*")
+ print "Anado filtro"
+ w.add_filter(self.file_filter_videos)
+ print "Anado filtro"
+ w.add_filter(self.file_filter_all)
+ self.set_widgets()
+ if (self.chapter!=-1): # we want to modify a chapter
+ self.set_global_values()
+ self.set_film_buttons()
+ if (self.chapter!=-1): # we want to modify a chapter
+ print "Modificando"
+ w=self.tree.get_object("fileaccept")
+ w.set_sensitive(True)
+ w=self.tree.get_object("preview_film")
+ w.set_sensitive(True)
+
+ print "Fin"
+
+
+ # help methods
+
+ def custom_video_filter(self, filter_info=None, data=None):
+ """Custom file filter. Filter for video files when running on win32"""
+ video_types=["wmv", "avi", "asf", "flv", "bin", "vob", "es", "ps", "pes","qt", "mov", "mp4", "mpg", "mpeg", "rm", "mkv", "nut", "nsv", "vivo", "fli", "yuv4mpeg", "cpk","ogm", "asx", "3gp"]
+ if os.path.splitext(filter_info[2])[1][1:] in video_types:
+ return True
+ return False
+
+
+ def get_desired_resolution(self):
+
+ """ Returns the resolution desired by the user as a single number """
+
+ if (self.tree.get_object("res160x128").get_active()):
+ return 8
+ if (self.tree.get_object("res1920x1080").get_active()):
+ return 7
+ if (self.tree.get_object("res1280x720").get_active()):
+ return 6
+
+ if (self.tree.get_object("res720x480").get_active()):
+ return 1
+ if (self.tree.get_object("res704x480").get_active()):
+ return 2
+ if (self.tree.get_object("res480x480").get_active()):
+ return 3
+ if (self.tree.get_object("res352x480").get_active()):
+ return 4
+ if (self.tree.get_object("res352x240").get_active()):
+ return 5
+ return 0
+
+
+ def adjust_resolution(self):
+
+ """ Sets the final resolution and bitrate based on the original resolution and the
+ desired one by the user """
+
+ if self.file_properties==None:
+ return
+
+ w1=self.tree.get_object("video_rate")
+ vrate=w1.get_value()
+ w2=self.tree.get_object("audio_rate")
+ arate=w2.get_value()
+ resx,resy,use_widescreen,vrate,arate=self.get_recomended_resolution(vrate, arate, self.get_desired_resolution())
+ self.file_properties["width"]=resx
+ self.file_properties["height"]=resy
+ w1.set_value(vrate)
+ w2.set_value(arate)
+ w=self.tree.get_object("aspect_ratio_4_3")
+ if ((resx<720) or (resy<480)) and (self.disctocreate!="divx"):
+ w.set_active(True)
+
+ if w.get_active():
+ self.file_properties["aspect"]=1.3333333
+ else:
+ self.file_properties["aspect"]=1.7777777
+
+
+ def get_widgets(self):
+
+ """ Fills the file_properties list with the values expressed in the widgets """
+
+ if len(self.file_properties["audio_list"])>0:
+ w=self.tree.get_object("audiotrack")
+ pos=w.get_active()
+ if (pos==-1):
+ pos=0
+ self.file_properties["audio_stream"]=self.file_properties["audio_list"][pos]
+
+
+ w=self.tree.get_object("force_subs")
+ self.file_properties["force_subs"]=w.get_active()
+
+ w=self.tree.get_object("blackbars")
+ if w.get_active():
+ self.file_properties["blackbars"]=0
+ else:
+ self.file_properties["blackbars"]=1
+
+ w=self.tree.get_object("trell")
+ self.file_properties["trellis"]=w.get_active()
+
+ w=self.tree.get_object("twopass")
+ self.file_properties["twopass"]=w.get_active()
+
+ w=self.tree.get_object("turbo1stpass")
+ self.file_properties["turbo1stpass"]=w.get_active()
+
+ self.file_properties["mbd"]=0
+ w=self.tree.get_object("mbd1")
+ if w.get_active():
+ self.file_properties["mbd"]=1
+ w=self.tree.get_object("mbd2")
+ if w.get_active():
+ self.file_properties["mbd"]=2
+
+ self.file_properties["deinterlace"]="none"
+ w=self.tree.get_object("deinterlace_lb")
+ if w.get_active():
+ self.file_properties["deinterlace"]="lb"
+ w=self.tree.get_object("deinterlace_md")
+ if w.get_active():
+ self.file_properties["deinterlace"]="md"
+ w=self.tree.get_object("deinterlace_fd")
+ if w.get_active():
+ self.file_properties["deinterlace"]="fd"
+ w=self.tree.get_object("deinterlace_l5")
+ if w.get_active():
+ self.file_properties["deinterlace"]="l5"
+ w=self.tree.get_object("deinterlace_yadif")
+ if w.get_active():
+ self.file_properties["deinterlace"]="yadif"
+
+ w=self.tree.get_object("ismpeg")
+ self.file_properties["ismpeg"]=w.get_active()
+
+ self.file_properties["swap_fields"]=self.tree.get_object("swap_fields").get_active()
+
+ w=self.tree.get_object("copy_audio")
+ self.file_properties["copy_audio"]=w.get_active()
+
+ w=self.tree.get_object("isvob")
+ self.file_properties["isvob"]=w.get_active()
+
+ w=self.tree.get_object("sound51")
+ self.file_properties["sound51"]=w.get_active()
+
+ w=self.tree.get_object("gop12")
+ self.file_properties["gop12"]=w.get_active()
+
+ w=self.tree.get_object("do_chapters")
+ if w.get_active():
+ w=self.tree.get_object("chapter_long")
+ self.file_properties["lchapters"]=w.get_value()
+ else:
+ self.file_properties["lchapters"]=0
+
+ w=self.tree.get_object("subfont_size")
+ self.file_properties["subfont_size"]=int(w.get_value())
+
+ w=self.tree.get_object("audiodelay")
+ self.file_properties["adelay"]=float(w.get_value())
+
+ w=self.tree.get_object("video_rate")
+ self.file_properties["vrate"]=int(w.get_value())
+ w=self.tree.get_object("audio_rate")
+ self.file_properties["arate"]=int(w.get_value())
+
+ w=self.tree.get_object("volume_adj")
+ self.file_properties["volume"]=int(w.get_value())
+
+ w=self.tree.get_object("full_length")
+ if w.get_active():
+ self.file_properties["cutting"]=0
+ else:
+ w=self.tree.get_object("first_half")
+ if w.get_active():
+ self.file_properties["cutting"]=1
+ else:
+ self.file_properties["cutting"]=2
+
+ w=self.tree.get_object("video_pal")
+ if w.get_active():
+ self.file_properties["fps"]=25
+ else:
+ self.file_properties["fps"]=30
+
+ if (self.disctocreate=="dvd") or (self.disctocreate=="divx"):
+ w=self.tree.get_object("aspect_ratio_16_9")
+ if w.get_active():
+ self.file_properties["aspect"]=1.77777777
+ else:
+ self.file_properties["aspect"]=1.33333333
+ else:
+ self.file_properties["aspect"]=1.33333333
+
+ self.file_properties["resolution"]=self.get_desired_resolution()
+
+ w=self.tree.get_object("custom_params")
+ self.file_properties["params"]=w.get_text()
+
+ w=self.tree.get_object("custom_params_vf")
+ self.file_properties["params_vf"]=w.get_text()
+
+ w=self.tree.get_object("custom_params_lavcopts")
+ self.file_properties["params_lavc"]=w.get_text()
+
+ if (self.disctocreate=="divx"):
+ w=self.tree.get_object("custom_params_lameopts")
+ self.file_properties["params_lame"]=w.get_text()
+
+ w=self.tree.get_object("rotation0")
+ if w.get_active():
+ self.file_properties["rotate"]=0 # no rotation
+ w=self.tree.get_object("rotation90")
+ if w.get_active():
+ self.file_properties["rotate"]=90 # rotate 90 degrees clockwise
+ w=self.tree.get_object("rotation180")
+ if w.get_active():
+ self.file_properties["rotate"]=180 # rotate 180 degrees
+ w=self.tree.get_object("rotation270")
+ if w.get_active():
+ self.file_properties["rotate"]=270 # rotate 90 degrees counter-clockwise
+
+ w=self.tree.get_object("hmirror")
+ self.file_properties["hmirror"]=w.get_active()
+ w=self.tree.get_object("vmirror")
+ self.file_properties["vmirror"]=w.get_active()
+
+ # Callbacks
+
+ def on_reset_volume_clicked(self,widget):
+ w=self.tree.get_object("volume_adj")
+ w.set_value(100)
+
+
+ def on_sub_add_clicked(self,widget):
+
+ window=ask_subtitle(self.gladefile,self.global_vars["filmpath"],self.global_vars)
+ ret=window.run()
+ window=None
+ if ret!=None:
+ self.file_properties["sub_list"].append(ret)
+ self.refresh_subtitles()
+ self.set_global_values()
+
+
+ def on_sub_remove_clicked(self,widget):
+
+ w=self.tree.get_object("sub_treeview")
+ try:
+ ctree,iter=w.get_selection().get_selected()
+ subtitle=ctree.get_value(iter,0)
+ except:
+ subtitle=-1
+
+ if subtitle==-1:
+ return
+
+ newtree=devede_other.create_tree(self,"wdel_subtitle",self.gladefile,False)
+ window=newtree.get_object("wdel_subtitle")
+ window.show()
+ ret=window.run()
+ window.hide()
+ window.destroy()
+ window=None
+ newtree=None
+ if ret==-5:
+ del (self.file_properties["sub_list"])[subtitle]
+
+ self.refresh_subtitles()
+ self.set_global_values()
+
+
+ def on_filecancel_clicked(self,widget):
+
+ w=self.tree.get_object("expander_advanced")
+ self.global_vars["expand_advanced"]=w.get_expanded()
+ self.window.destroy()
+ self.window=None
+ gc.collect()
+
+
+ def on_fileaccept_clicked(self,widget):
+
+ w=self.tree.get_object("expander_advanced")
+ self.global_vars["expand_advanced"]=w.get_expanded()
+ self.get_widgets()
+ if self.chapter==-1: # add this file as a new chapter
+ self.structure[self.title].append(self.file_properties)
+ else:
+ self.structure[self.title][self.chapter]=self.file_properties
+ self.window.destroy()
+ self.window=None
+ (self.callback_refresh)()
+ gc.collect()
+
+
+ def on_wfile_delete_event(self,widget,arg2):
+ self.window.destroy()
+ self.window=None
+ gc.collect()
+ return True
+
+
+ def on_wfile_destroy_event(self,widget,arg2):
+ self.window.destroy()
+ self.window=None
+ gc.collect()
+
+
+ def on_clear_subtitles_clicked(self,widget):
+
+ """ clears the subtitle filechooser """
+
+ w=self.tree.get_object("subtitles_chooser")
+ w.unselect_all()
+
+
+ def on_moviefile_file_set(self,widget):
+
+ w=self.tree.get_object("moviefile")
+ filename=widget.get_filename()
+
+ print "File changed to "+str(filename)
+
+ if (filename==None) or (filename==""):
+ self.set_widgets()
+ self.set_global_values()
+ self.set_film_buttons()
+ return
+
+ self.global_vars["filmpath"]=os.path.split(filename)[0]
+
+ if self.change_file:
+ self.set_widgets()
+ self.set_global_values()
+ self.set_film_buttons()
+ self.change_file=False
+ return
+
+ fine,tracks=self.create_default_video_parameters(filename)
+ if fine==False: # it's not a video file
+ if tracks==0: # it's not a multimedia file
+ devede_dialogs.show_error(self.gladefile,_("File doesn't seem to be a video file."))
+ else:
+ devede_dialogs.show_error(self.gladefile,_("File seems to be an audio file."))
+ w.unselect_all()
+ self.set_widgets()
+ self.set_global_values()
+ self.set_film_buttons()
+
+
+ def on_video_pal_toggled(self,widget):
+
+ """ Detects the change in the option PAL/NTSC """
+
+ w=self.tree.get_object("video_pal")
+ self.pal=w.get_active()
+ self.set_resolution()
+ self.adjust_resolution()
+ self.set_global_values()
+
+
+ def on_res_toggled(self,widget):
+
+ self.adjust_resolution()
+ self.set_global_values()
+ self.set_film_buttons()
+
+
+ def on_length_toggled(self,widget):
+
+ self.set_global_values()
+
+
+ def on_video_rate_value_changed(self,widget):
+ self.set_global_values()
+
+
+ def on_audio_rate_value_changed(self,widget):
+ self.set_global_values()
+
+
+ def on_subtitles_chooser_selection_changed(self,widget):
+ self.set_global_values()
+
+
+ def on_aspect_ratio_toggled(self,widget):
+
+ if self.file_properties==None:
+ return
+
+ w=self.tree.get_object("aspect_ratio_16_9")
+ if w.get_active()==False:
+ return
+
+ self.set_resolution()
+ if (self.file_properties["width"]<720) or (self.file_properties["height"]<480):
+ w=self.tree.get_object("res720x480")
+ w.set_active(True)
+
+
+ def on_ismpeg_toggled(self,widget):
+
+ self.set_film_buttons()
+ self.set_global_values()
+
+
+ def on_copy_audio_toggled(self,widget):
+
+ self.set_film_buttons()
+ self.set_global_values()
+
+
+ def on_isvob_toggled(self,widget):
+
+ self.set_film_buttons()
+ self.set_global_values()
+
+ def on_twopass_toggled(self,widget):
+ w = self.tree.get_object("turbo1stpass")
+ if widget.get_active():
+ w.set_sensitive(True)
+ else:
+ w.set_active(False)
+ w.set_sensitive(False)
+
+ def on_sound51_toggled(self,widget):
+
+ self.set_film_buttons()
+ self.set_global_values()
+
+
+ def on_preview_film_clicked(self,widget):
+
+ self.get_widgets()
+ self.global_vars["erase_temporary_files"]=True
+ self.global_vars["number_actions"]=1
+ tmp_structure=[["",self.file_properties]]
+ converter=devede_convert.create_all(self.gladefile,tmp_structure,self.global_vars,self.callback)
+ self.global_vars["temp_folder"]=converter.preview(self.global_vars["temp_folder"])
+ print "Temp folder changed to "+str(self.global_vars["temp_folder"])
+
+
+ def on_file_help_clicked(self,widget):
+
+ help_class=devede_help.show_help(self.gladefile,self.global_vars["help_path"],"file.html")
+
+
+ def callback(self):
+
+ """ This method is called after a preview """
+
+ return None # do nothing
+
+
+ def draganddrop(self,widget,drag_context, x, y, selection, info, time):
+
+ """ Manages the Drag&Drop in the property window """
+
+ sub_extensions3=[".sub",".srt",".ssa",".smi",".txt",".aqt",".jss", ".ass"]
+ sub_extensions2=[".rt",".js"]
+
+ lista=self.split_dnd(selection.data)
+
+ if len(lista)==0:
+ return
+
+ if len(lista)>1:
+ devede_dialogs.show_error(self.gladefile,_("Please, add only one file each time."))
+ return
+
+ if self.disctocreate!="divx":
+ print("Entro en subs")
+ filename=str(lista[0]).lower()
+ if len(filename)>=4:
+ extension3=filename[-4:]
+ extension2=filename[-3:]
+ print "Extensiones: "+str(extension3)+" "+str(extension2)
+ if (0!=sub_extensions3.count(extension3)) or (0!=sub_extensions2.count(extension2)): # is a subtitle
+ current_file=self.tree.get_object("moviefile").get_filename()
+ if (current_file=="") or (current_file==None):
+ devede_dialogs.show_error(self.gladefile,_("Please, add a movie file before adding subtitles."))
+ return
+ window=ask_subtitle(self.gladefile,self.global_vars["filmpath"],self.global_vars,lista[0])
+ ret=window.run()
+ window=None
+ if ret!=None:
+ self.file_properties["sub_list"].append(ret)
+ self.refresh_subtitles()
+ self.set_global_values()
+ return
+
+ w=self.tree.get_object("moviefile")
+ print "Adding "+str(lista[0])
+ w.set_filename(str(lista[0]))
+
+
+ # data visualization methods
+
+
+ def set_resolution(self):
+
+ """ Sets the labels with the rigth resolution values, depending
+ if the user selected PAL/SECAM or NTSC """
+
+ if self.pal:
+ res1="288"
+ res2="576"
+ else:
+ res1="240"
+ res2="480"
+
+ w=self.tree.get_object("res720x480")
+ w.set_label("720x"+res2)
+ w=self.tree.get_object("res704x480")
+ w.set_label("704x"+res2)
+ w=self.tree.get_object("res480x480")
+ w.set_label("480x"+res2)
+ w=self.tree.get_object("res352x480")
+ w.set_label("352x"+res2)
+ w=self.tree.get_object("res352x240")
+ w.set_label("352x"+res1)
+
+
+ def set_widgets(self):
+
+ """ sets the widgets to the values specificated in SELF.FILE_PROPERTIES """
+
+ dsize,minvid,maxvid=devede_other.get_dvd_size(None,self.disctocreate)
+
+ if self.disctocreate=="vcd":
+ w=self.tree.get_object("video_rate_adj")
+ w.set_value(1152)
+ w=self.tree.get_object("audio_rate_adj")
+ w.set_value(224)
+ elif (self.disctocreate=="svcd") or (self.disctocreate=="cvd"):
+ w=self.tree.get_object("audio_rate_adj")
+ w.set_lower(64)
+ w.set_upper(384)
+ #w.set_range(64,384)
+ else:
+ print "entro en parte critica"
+ w=self.tree.get_object("audio_rate_adj")
+ print "paso por set_lower"
+ w.set_lower(128)
+ w.set_upper(448)
+ #w.set_range(128,448)
+
+ if self.disctocreate!="vcd":
+ w=self.tree.get_object("video_rate_adj")
+ w.set_lower(minvid)
+ w.set_upper(maxvid)
+ #w.set_range(minvid,maxvid)
+
+ if self.file_properties==None:
+ return
+
+ w=self.tree.get_object("force_subs")
+ w.set_active(self.file_properties["force_subs"])
+
+ w1=self.tree.get_object("aspect_ratio_4_3")
+ w2=self.tree.get_object("aspect_ratio_16_9")
+ w1.set_active(True)
+ print "Activo ASPECT_RATIO"
+ print self.disctocreate
+ if (self.disctocreate=="dvd") or (self.disctocreate=="divx"):
+ w1.set_sensitive(True)
+ w2.set_sensitive(True)
+ if self.file_properties["aspect"]>1.6:
+ w2.set_active(True)
+ else:
+ w1.set_active(True)
+ else:
+ w1.set_sensitive(False)
+ w2.set_sensitive(False)
+
+ if self.file_properties["resolution"]==0: # auto resolution
+ w=self.tree.get_object("resauto")
+ elif self.file_properties["resolution"]==1: # 720x480
+ w=self.tree.get_object("res720x480")
+ elif self.file_properties["resolution"]==2: # 704x480
+ w=self.tree.get_object("res704x480")
+ elif self.file_properties["resolution"]==3: # 480x480
+ w=self.tree.get_object("res480x480")
+ elif self.file_properties["resolution"]==4: # 352x480
+ w=self.tree.get_object("res352x480")
+ elif self.file_properties["resolution"]==6: # 1280x720
+ w=self.tree.get_object("res1280x720")
+ elif self.file_properties["resolution"]==7: # 1920x1080
+ w=self.tree.get_object("res1920x1080")
+ elif self.file_properties["resolution"]==8: # 160x128
+ w=self.tree.get_object("res160x128")
+ else:
+ w=self.tree.get_object("res352x240")
+
+ w.set_active(True)
+
+ w=self.tree.get_object("trell")
+ w.set_active(self.file_properties["trellis"])
+
+ w=self.tree.get_object("twopass")
+ w.set_active(self.file_properties["twopass"])
+
+ w=self.tree.get_object("turbo1stpass")
+ w.set_active(self.file_properties["turbo1stpass"])
+
+ if self.file_properties["mbd"]==0:
+ w=self.tree.get_object("mbd")
+ elif self.file_properties["mbd"]==1:
+ w=self.tree.get_object("mbd1")
+ else:
+ w=self.tree.get_object("mbd2")
+ w.set_active(True)
+
+ if self.file_properties["deinterlace"]=="none":
+ w=self.tree.get_object("deinterlace")
+ else:
+ w=self.tree.get_object("deinterlace_"+self.file_properties["deinterlace"])
+ w.set_active(True)
+
+ w=self.tree.get_object("volume_adj")
+ w.set_value(self.file_properties["volume"])
+
+ w=self.tree.get_object("ismpeg")
+ w.set_active(self.file_properties["ismpeg"])
+
+ w=self.tree.get_object("copy_audio")
+ w.set_active(self.file_properties["copy_audio"])
+
+ w=self.tree.get_object("isvob")
+ w.set_active(self.file_properties["isvob"])
+
+ w=self.tree.get_object("sound51")
+ w.set_active(self.file_properties["sound51"])
+
+ w=self.tree.get_object("gop12")
+ w.set_active(self.file_properties["gop12"])
+
+ w=self.tree.get_object("subfont_size")
+ w.set_value(self.file_properties["subfont_size"])
+
+ w=self.tree.get_object("swap_fields")
+ w.set_active(self.file_properties["swap_fields"])
+
+ w=self.tree.get_object("custom_params")
+ w.set_text(self.file_properties["params"])
+
+ w=self.tree.get_object("custom_params_lavcopts")
+ w.set_text(self.file_properties["params_lavc"])
+
+ w=self.tree.get_object("custom_params_vf")
+ w.set_text(self.file_properties["params_vf"])
+
+ if (self.disctocreate=="divx"):
+ w=self.tree.get_object("custom_params_lameopts")
+ w.set_text(self.file_properties["params_lame"])
+
+ vrate=self.tree.get_object("video_rate")
+ vrate.set_value(self.file_properties["vrate"])
+ arate=self.tree.get_object("audio_rate")
+ arate.set_value(self.file_properties["arate"])
+ w=self.tree.get_object("audiodelay")
+ w.set_value(self.file_properties["adelay"])
+ if self.file_properties["blackbars"]==0:
+ w=self.tree.get_object("blackbars")
+ else:
+ w=self.tree.get_object("scalepict")
+ w.set_active(True)
+
+ w=self.tree.get_object("do_chapters")
+ if self.file_properties["lchapters"]==0:
+ w.set_active(False)
+ w=self.tree.get_object("chapter_long")
+ w.set_sensitive(False)
+ else:
+ w.set_active(True)
+ w=self.tree.get_object("chapter_long")
+ w.set_sensitive(True)
+ w.set_value(self.file_properties["lchapters"])
+
+ if self.file_properties["fps"]==25:
+ w=self.tree.get_object("video_pal")
+ else:
+ w=self.tree.get_object("video_ntsc")
+ w.set_active(True)
+
+ if self.file_properties["cutting"]==0:
+ w=self.tree.get_object("full_length")
+ elif self.file_properties["cutting"]==1:
+ w=self.tree.get_object("first_half")
+ else:
+ w=self.tree.get_object("second_half")
+ w.set_active(True)
+
+ print "Rotate: "+str(self.file_properties["rotate"])
+ if self.file_properties["rotate"]==0:
+ w=self.tree.get_object("rotation0")
+ elif self.file_properties["rotate"]==90:
+ w=self.tree.get_object("rotation90")
+ elif self.file_properties["rotate"]==180:
+ w=self.tree.get_object("rotation180")
+ elif self.file_properties["rotate"]==270:
+ w=self.tree.get_object("rotation270")
+ w.set_active(True)
+
+ w=self.tree.get_object("hmirror")
+ w.set_active(self.file_properties["hmirror"])
+ w=self.tree.get_object("vmirror")
+ w.set_active(self.file_properties["vmirror"])
+
+ self.audio_model.clear()
+ if len(self.file_properties["audio_list"])>0:
+ w=self.tree.get_object("hasaudiotracks")
+ w.show()
+ w=self.tree.get_object("noaudiotracks")
+ w.hide()
+ position=0
+ for track in self.file_properties["audio_list"]:
+ print "Meto pista "+str(track)
+ iterator=self.audio_model.insert(position)
+ self.audio_model.set_value(iterator,0,track)
+ position+=1
+ print "Pista seleccionada: "+str(self.file_properties["audio_stream"])
+ w=self.tree.get_object("audiotrack")
+ w.set_active(self.file_properties["audio_list"].index(self.file_properties["audio_stream"]))
+ else:
+ w=self.tree.get_object("hasaudiotracks")
+ w.hide()
+ w=self.tree.get_object("noaudiotracks")
+ w.show()
+
+ self.refresh_subtitles()
+
+ def refresh_subtitles(self):
+
+ self.sub_model.clear()
+ position=0
+ for subtitle in self.file_properties["sub_list"]:
+ iterator=self.sub_model.insert(position)
+ self.sub_model.set_value(iterator,0,position)
+ name=subtitle["subtitles"]
+ while True:
+ pos=name.find(os.sep)
+ if (pos==-1):
+ break
+ name=name[pos+1:]
+
+ self.sub_model.set_value(iterator,1,name)
+ self.sub_model.set_value(iterator,2,subtitle["sub_codepage"])
+ self.sub_model.set_value(iterator,3,subtitle["sub_language"])
+ position+=1
+ w=self.tree.get_object("sub_treeview")
+ w.get_selection().select_path(0)
+ self.set_film_buttons()
+
+
+ def set_film_buttons(self):
+
+ """ Enables or disables all the buttons, based in the current disk type and other widgets """
+
+ w1=self.tree.get_object("fileaccept")
+ w=self.tree.get_object("moviefile")
+ cfile=w.get_filename()
+
+ w=self.tree.get_object("preview_film")
+ if (cfile=="") or (cfile==None):
+ w.set_sensitive(False)
+ w1.set_sensitive(False)
+ else:
+ w.set_sensitive(True)
+ w1.set_sensitive(True)
+
+ w0=self.tree.get_object("ismpeg")
+ w0s=w0.get_active()
+ if w0s:
+ grupo2=False
+ else:
+ grupo2=True
+
+ w1=self.tree.get_object("copy_audio")
+ w1s=w1.get_active()
+ if w1s:
+ copy_audio=False
+ else:
+ copy_audio=grupo2
+
+ w2=self.tree.get_object("isvob")
+ w2s=w2.get_active()
+ if w2s:
+ isvob=False
+ else:
+ isvob=grupo2
+
+ if (self.disctocreate!="dvd") and (self.disctocreate!="divx"):
+ w1.set_active(False)
+ w1.set_sensitive(False)
+ sound51=False
+ else:
+ w1.set_sensitive(grupo2)
+ sound51=grupo2
+
+ if w0s:
+ w2.set_sensitive(False)
+ w1.set_sensitive(False)
+ else:
+ w2.set_sensitive(True)
+ w1.set_sensitive(True)
+ if w1s:
+ w2.set_sensitive(False)
+ else:
+ w2.set_sensitive(True)
+ if w2s:
+ w0.set_sensitive(False)
+ w1.set_sensitive(False)
+ else:
+ w1.set_sensitive(True)
+ w0.set_sensitive(True)
+
+ if self.disctocreate =="vcd":
+ grupo1=False
+ else:
+ grupo1=grupo2
+
+ if (self.disctocreate=="dvd") or (self.disctocreate=="divx"):
+ w=self.tree.get_object("sound51")
+ if w.get_active():
+ w=self.tree.get_object("audio_rate_adj")
+ w.set_lower(384)
+ w.set_upper(448)
+ if w.get_value()<384:
+ w.set_value(384)
+ #w.set_range(384,448)
+ else:
+ w=self.tree.get_object("audio_rate_adj")
+ w.set_lower(128)
+ w.set_upper(448)
+ #w.set_range(128,448)
+
+ grupo3=grupo2
+ try:
+ if self.file_properties["olength"]<60:
+ grupo3=False
+ except:
+ grupo3=False
+
+ w=self.tree.get_object("video_rate")
+ w.set_sensitive(grupo1 and isvob)
+ w=self.tree.get_object("audio_rate")
+ w.set_sensitive(grupo1 and copy_audio and isvob)
+ w=self.tree.get_object("swap_fields")
+ w.set_sensitive(grupo1 and isvob)
+ w=self.tree.get_object("gop12")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("volume_scale")
+ w.set_sensitive(grupo2 and isvob and copy_audio)
+ w=self.tree.get_object("volume_level")
+ w.set_sensitive(grupo2 and isvob and copy_audio)
+ w=self.tree.get_object("reset_volume")
+ w.set_sensitive(grupo2 and isvob and copy_audio)
+ w=self.tree.get_object("sound51")
+ if grupo1==False:
+ w.set_active(False)
+ w.set_sensitive(sound51)
+ w=self.tree.get_object("resauto")
+ w.set_sensitive(grupo1 and isvob)
+ if (w.get_active()) and (self.disctocreate=="divx"):
+ set_aspect=False
+ else:
+ set_aspect=True
+ w=self.tree.get_object("res352x240")
+ w.set_sensitive(grupo1 and isvob)
+ w=self.tree.get_object("res352x480")
+ w.set_sensitive(grupo1 and isvob)
+ w=self.tree.get_object("res480x480")
+ w.set_sensitive(grupo1 and isvob)
+ w=self.tree.get_object("res704x480")
+ w.set_sensitive(grupo1 and isvob)
+ w=self.tree.get_object("res720x480")
+ w.set_sensitive(grupo1 and isvob)
+
+ w=self.tree.get_object("full_length")
+ w.set_sensitive(grupo3)
+ w=self.tree.get_object("first_half")
+ w.set_sensitive(grupo3)
+ w=self.tree.get_object("second_half")
+ w.set_sensitive(grupo3)
+ w=self.tree.get_object("video_pal")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("video_ntsc")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("audiodelay")
+ w.set_sensitive(copy_audio and isvob)
+ w=self.tree.get_object("blackbars")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("scalepict")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("custom_params")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("custom_params_vf")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("custom_params_lavcopts")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("custom_params_lameopts")
+ w.set_sensitive(copy_audio and isvob)
+ w2=self.tree.get_object("lameopts_label")
+ if self.disctocreate=="divx":
+ w.show()
+ w2.show()
+ else:
+ w.hide()
+ w2.hide()
+
+ w=self.tree.get_object("trell")
+ w.set_sensitive(grupo2 and isvob)
+
+ w=self.tree.get_object("rotation0")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("rotation90")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("rotation180")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("rotation270")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("hmirror")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("vmirror")
+ w.set_sensitive(grupo2 and isvob)
+
+ w=self.tree.get_object("mbd")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("mbd1")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("mbd2")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("twopass")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("turbo1stpass")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("deinterlace")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("deinterlace_lb")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("deinterlace_md")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("deinterlace_fd")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("deinterlace_l5")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("deinterlace_yadif")
+ w.set_sensitive(grupo2 and isvob)
+ w=self.tree.get_object("audiotrack")
+ w.set_sensitive(grupo2)
+ w1=self.tree.get_object("aspect_ratio_4_3")
+ w2=self.tree.get_object("aspect_ratio_16_9")
+ if (self.disctocreate == "dvd") or (self.disctocreate == "divx"):
+ w1.set_sensitive(grupo2 and isvob and set_aspect)
+ w2.set_sensitive(grupo2 and isvob and set_aspect)
+ else:
+ w1.set_sensitive(False)
+ w2.set_sensitive(False)
+
+ w1=self.tree.get_object("sub_remove")
+ w2=self.tree.get_object("sub_add")
+ try:
+ sub_number=len(self.file_properties["sub_list"])
+ if sub_number==0:
+ w1.set_sensitive(False)
+ else:
+ w1.set_sensitive(True)
+
+ if sub_number>=32:
+ w2.set_sensitive(False)
+ else:
+ w2.set_sensitive(True)
+ except:
+ w1.set_sensitive(False)
+ w2.set_sensitive(False)
+
+
+ def set_global_values(self):
+
+ """ Repaints all the data about the current film, recalculating
+ the size needed and other params """
+
+ if self.file_properties==None:
+ empty=True
+ else:
+ empty=False
+
+ w=self.tree.get_object("o_size2")
+ if empty:
+ w.set_text("")
+ else:
+ w.set_text(str(self.file_properties["owidth"])+"x"+str(self.file_properties["oheight"]))
+
+ w=self.tree.get_object("leng2")
+ if empty:
+ w.set_text("")
+ else:
+ w.set_text(str(self.file_properties["olength"]))
+
+ w=self.tree.get_object("fps")
+ if empty:
+ w.set_text("")
+ else:
+ w.set_text(str(self.file_properties["ofps"]))
+
+ w=self.tree.get_object("vrate2")
+ if empty:
+ w.set_text("")
+ else:
+ w.set_text(str(self.file_properties["ovrate"]))
+
+ w=self.tree.get_object("arate2")
+ if empty:
+ w.set_text("")
+ else:
+ w.set_text(str(self.file_properties["oarate"]))
+
+ w=self.tree.get_object("video_rate")
+ vrate=w.get_value()
+ w=self.tree.get_object("audio_rate")
+ arate=w.get_value()
+
+ w=self.tree.get_object("full_length")
+ if w.get_active():
+ divide=False
+ divide2=0
+ else:
+ divide=True
+ divide2=1
+
+ w=self.tree.get_object("eleng2")
+ if empty:
+ w.set_text("")
+ else:
+ w2=self.tree.get_object("ismpeg")
+ w4=self.tree.get_object("isvob")
+ props={}
+ props["ofps"]=self.file_properties["ofps"]
+ props["ofps2"]=self.file_properties["ofps2"]
+ w3=self.tree.get_object("video_pal")
+ if w3.get_active():
+ props["fps"]=25
+ else:
+ props["fps"]=30
+ w3=self.tree.get_object("copy_audio")
+ props["copy_audio"]=w3.get_active()
+ w3=self.tree.get_object("ismpeg")
+ props["ismpeg"]=w3.get_active()
+ print "Props: "+str(props)
+ speed1,speed2=devede_other.get_speedup(props)
+ l=devede_other.calcula_tamano_parcial(vrate,arate,self.file_properties["filesize"],self.file_properties["olength"],len(self.file_properties["sub_list"]),w2.get_active(),w4.get_active(),divide2,speed1,speed2)
+ #if w2.get_active():
+ # l=int(self.file_properties["filesize"]/1000000)
+ #else:
+ # l=int(((vrate+arate)*self.file_properties["olength"])/8000)
+ # if divide:
+ # l/=2
+
+ #l+=int((8.0*float(len(self.file_properties["sub_list"]))*self.file_properties["olength"])/8000.0)
+ w.set_text(str(int(l/1000)))
+
+ w=self.tree.get_object("f_size2")
+ if empty:
+ w.set_text("")
+ else:
+ w.set_text(str(self.file_properties["width"])+"x"+str(self.file_properties["height"]))
+
+
+class ask_subtitle:
+
+ def __init__(self,gladefile,filepath,gvars,filename=None):
+
+ self.global_vars=gvars
+ self.gladefile=gladefile
+ self.tree=devede_other.create_tree(self,"add_subtitle2",self.gladefile)
+ self.lang_list=[]
+ self.cpage_list=[]
+
+ pos=0
+ self.lang=-1
+ self.asciie=-1
+ self.utf8e=-1
+ self.utf16e=-1
+ self.isoe=-1
+ languages=open(os.path.join(self.gladefile,"languages.lst"),"r")
+ w=self.tree.get_object("sub_language")
+ for element in languages:
+ if element[:-1]==self.global_vars["sub_language"]:
+ self.lang=pos
+ w.append_text(element[:-1])
+ self.lang_list.append(element[:-1])
+ pos+=1
+ languages.close()
+ w.set_active(self.lang)
+
+ pos=0
+ self.chelement=0
+ codepages=open(os.path.join(self.gladefile,"codepages.lst"),"r")
+ w=self.tree.get_object("sub_codepage")
+ for element in codepages:
+ if element[:-1]=="ASCII":
+ self.asciie=pos
+ if element[:-1]=="UTF-8":
+ self.utf8e=pos
+ if element[:-1]=="UTF-16":
+ self.utf16e=pos
+ if element[:-1]=="ISO-8859-1":
+ self.isoe=pos
+ if element[:-1]==self.global_vars["sub_codepage"]:
+ self.chelement=pos
+ w.append_text(element[:-1])
+ self.cpage_list.append(element[:-1])
+ pos+=1
+ codepages.close()
+ if self.chelement!=-1:
+ w.set_active(self.chelement)
+ elif (self.utf8e!=-1):
+ w.set_active(self.utf8e)
+ else:
+ w.set_active(self.isoe)
+
+ self.window=self.tree.get_object("add_subtitle")
+ if (filepath!=""):
+ w=self.tree.get_object("subtitles_chooser")
+ w.set_current_folder(filepath)
+ if (filename!=None) and (filename!=""):
+ self.tree.get_object("subtitles_chooser").set_filename(filename)
+ self.window.show()
+ self.set_status()
+
+
+ def on_clear_subtitles_clicked(self,widget):
+
+ file=self.tree.get_object("subtitles_chooser")
+ file.unselect_all()
+
+
+ def on_subtitles_chooser_selection_changed(self,widget):
+
+ filename=widget.get_filename()
+ if (filename!="") and (filename!=None):
+ w=self.tree.get_object("sub_codepage")
+ autotype=devede_other.check_utf().do_check(filename)
+ print "Subtitles changed to type: "+str(autotype)
+ if autotype=="ascii":
+ w.set_active(self.asciie)
+ self.autotype="ASCII"
+ elif autotype=="utf8":
+ w.set_active(self.utf8e)
+ self.autotype="UTF-8"
+ elif autotype=="utf16":
+ w.set_active(self.utf16e)
+ self.autotype="UTF-16"
+ elif self.chelement!=-1:
+ w.set_active(self.chelement)
+ self.autotype=""
+ else:
+ w.set_active(self.isoe)
+ self.autotype=""
+ self.set_status()
+
+
+ def set_status(self):
+
+ filename=self.tree.get_object("subtitles_chooser").get_filename()
+
+ if (filename=="") or (filename==None):
+ status=False
+ else:
+ status=True
+
+ w=self.tree.get_object("sub_accept")
+ w.set_sensitive(status)
+
+
+ def run(self):
+
+ ret=self.window.run()
+ if ret==-5: # OK
+ ret_val={}
+ w=self.tree.get_object("subtitles_chooser")
+ ret_val["subtitles"]=w.get_filename()
+ w=self.tree.get_object("sub_codepage")
+ ret_val["sub_codepage"]=self.cpage_list[w.get_active()]
+ if (ret_val["sub_codepage"]!=self.autotype) and (ret_val["sub_codepage"][:3]!="UTF"):
+ self.global_vars["sub_codepage"]=ret_val["sub_codepage"]
+ w=self.tree.get_object("sub_language")
+ ret_val["sub_language"]=self.lang_list[w.get_active()]
+ self.global_vars["sub_language"]=ret_val["sub_language"]
+ w=self.tree.get_object("sub_up")
+ ret_val["subtitles_up"]=w.get_active()
+ else:
+ ret_val=None
+ self.window.hide()
+ self.window.destroy()
+ self.window=None
+ return(ret_val)
diff --git a/devede_other.py b/devede_other.py
new file mode 100755
index 0000000..d55c661
--- /dev/null
+++ b/devede_other.py
@@ -0,0 +1,689 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+
+###########################################################################
+# This block contains generic help functions that are used in the program #
+###########################################################################
+
+import os
+import subprocess
+import stat
+import sys
+import shutil
+import cairo
+import gtk
+import struct
+
+import devede_executor
+
+
+class check_utf(devede_executor.executor):
+
+ """ This class allows to detect if a file is pure ASCII, UTF-8 or UTF-16, and allows
+ to convert from UTF-16 to UFT-8 """
+
+ def check_ascii(self,filename):
+
+ try:
+ file=open(filename,"rb")
+ except:
+ return False
+
+ while True:
+ element=file.read(1)
+ if len(element)==0:
+ return True
+ if ord(element)>127:
+ return False
+
+
+ def read_utf8_element(self,file,base_value,nb):
+
+ value=base_value
+ for counter in range(nb-1):
+ element=file.read(1)
+ if element=="":
+ return False
+ if (ord(element)>191) or (ord(element)<128):
+ return False
+ value*=64 # rotate value 6 bits to the left
+ value+=ord(element)-128
+ return value
+
+
+ def check_utf8(self,filename):
+
+ try:
+ file=open(filename,"rb")
+ except:
+ return False
+
+ while True:
+ el=file.read(1)
+ if el=="":
+ file.close()
+ return True
+ element=ord(el)
+
+ if element<128:
+ continue
+
+ if element<194: # it's a mid-sequence element or a 2-byte start sequence for an element smaller than 128
+ print "Elemento 1"
+ file.close()
+ return False # invalid element found
+
+ if element<224: # two-byte element
+ value=self.read_utf8_element(file,element-192, 2)
+ if value==False:
+ print "Elemento 2"
+ file.close()
+ return False # invalid sequence
+ if value<128:
+ print "Elemento 3"
+ file.close()
+ return False # invalid value for a 2-byte sequence
+ continue
+
+ if element<240: # three-byte element
+ value=self.read_utf8_element(file,element-224, 3)
+ if value==False:
+ print "Elemento 4"
+ file.close()
+ return False # invalid sequence
+ if value<2048:
+ print "Elemento 5"
+ file.close()
+ return False # invalid value for a 3-byte sequence
+ continue
+
+ if element<245: # four-byte element
+ value=self.read_utf8_element(file,element-240, 4)
+ if value==False:
+ print "Elemento 6"
+ file.close()
+ return False # invalid sequence
+ if value<65536:
+ print "Elemento 7"
+ file.close()
+ return False # invalid value for a 4-byte sequence
+ continue
+
+ file.close()
+ return False # invalid value
+
+
+ def read_16(self,file,format_b):
+ element=file.read(2)
+ if element=="":
+ return ""
+ if len(element)!=2:
+ return False
+ value=struct.unpack(format_b,element)[0]
+ return value
+
+
+ def read_full16(self,file,format_b):
+ value=self.read_16(file, format_b)
+ if value=="":
+ return True # end of file
+ if value==False:
+ return False
+ if (value>=56320) and (value<=57343): # invalid value
+ return False
+ if (value>55295) and (value<56320): # surrogate pair
+ value-=55296
+ value2=self.read_16(file, format_b)
+ if (value2==False) or (value2==""):
+ return False
+ if (value2<56320) or (value2>57343): # invalid surrogate pair
+ return False
+ value2-=56320
+ return ((value*1024+value2)+65536)
+ else:
+ return value
+
+
+ def write_utf8(self,file,value):
+
+ if value<128:
+ file.write(struct.pack("B",value))
+ elif value<2048:
+ v1=(value/64) & 31
+ v2= value & 63
+ file.write(struct.pack("BB",v1+192,v2+128))
+ elif value<65536:
+ v1=(value/4096) & 15
+ v2=(value/64) & 63
+ v3= value & 63
+ file.write(struct.pack("BBB",v1+224,v2+128,v3+128))
+ else:
+ v1=(value/262143) & 7
+ v2=(value/4096) & 63
+ v3=(value/64) & 63
+ v4= value & 63
+ file.write(struct.pack("BBBB",v1+240,v2+128,v3+128,v4+128))
+
+
+ def check_utf16BE(self,filename):
+
+ try:
+ file=open(filename,"rb")
+ except:
+ return False
+ value=self.read_16(file, ">H")
+ file.close()
+ if value==65279:
+ return True
+ return False
+
+
+ def check_utf16LE(self,filename):
+
+ try:
+ file=open(filename,"rb")
+ except:
+ return False
+ value=self.read_16(file, " "'+str(outfile_n)+'"'
+ return self.launch_shell(command_line).wait()
+
+
+ def convert_16_to_8(self,infile_n,outfile_n):
+
+ if self.check_utf16BE(infile_n):
+ format_b=">H"
+ else:
+ format_b="(pos+1)):
+ if (videofile["ofps2"][pos+1]=="9"):
+ rational_fps=True
+
+ # if it's rational, we have to use a different pair of values to achieve good precission
+
+ if (videofile["ofps"]==24) and (videofile["fps"]==25) and (videofile["copy_audio"]==False) and (videofile["ismpeg"]==False):
+ if rational_fps:
+ return 25025,24000
+ else:
+ return 25,24
+ else:
+ return 1,1
+
+
+def get_font_params(font_name):
+
+ font_elements=[]
+ font_temp=font_name
+
+ font_elements=font_name.split(" ")
+
+ if (len(font_elements))<2:
+ fontname="Sans"
+ fontstyle=cairo.FONT_WEIGHT_NORMAL
+ fontslant=cairo.FONT_SLANT_NORMAL
+ fontsize=12
+ else:
+ fontname=""
+ fontstyle=cairo.FONT_WEIGHT_NORMAL
+ fontslant=cairo.FONT_SLANT_NORMAL
+ for counter2 in range(len(font_elements)-1):
+ if font_elements[counter2]=="Bold":
+ fontstyle=cairo.FONT_WEIGHT_BOLD
+ elif font_elements[counter2]=="Italic":
+ fontslant=cairo.FONT_SLANT_ITALIC
+ else:
+ fontname+=" "+font_elements[counter2]
+ if fontname!="":
+ fontname=fontname[1:]
+ else:
+ fontname="Sans"
+
+ try:
+ fontsize=float(font_elements[-1])
+ except:
+ fontsize=12
+
+ return fontname,fontstyle,fontslant,fontsize
+
+
+def calcula_tamano_parcial(vrate,arate,filesize,length,subs,ismpeg,isvob,cutting,speed1,speed2):
+
+ """ Calculates the estimated final size.
+
+ VRATE and ARATE is the bit rate for video and audio.
+ FILESIZE is the size of the original file.
+ LENGTH is the file length in seconds
+ SUBS is the number of subs
+ ISMPEG is true if the file is already an MPEG-compliant file
+ CUTTING is different than 0 if we are cutting the file in half.
+
+ """
+
+ if (speed1!=speed2): # we are speeding up the film, so we must take it into account
+ length=int((float(length))*((float(speed2))/(float(speed1))))
+
+ if ismpeg or isvob:
+ l=filesize/1000
+ else:
+ l=float(((vrate+arate)*length)/8)
+ if cutting!=0:
+ l/=2
+ l+=float((8*subs*length)/8) # add the subtitles (assume 8kbit/sec for each one)
+ return l
+
+
+def calcule_menu_size(structure,sound_duration):
+
+ # each menu needs 1128 kbits/sec * sound_duration / 8
+ return (141*sound_duration)*((len(structure)+9)/10)
+
+
+def calcula_tamano_total(structure,sound_duration,disktype):
+
+ """ Calculates the total size of the DVD """
+
+ print "Calculating size for disk :"+str(disktype)
+ total=0.0
+ for element in structure:
+ if len(element)>1:
+ for film in element[1:]:
+ speed1,speed2=get_speedup(film)
+ total+=calcula_tamano_parcial(film["vrate"],film["arate"],film["filesize"],film["olength"],len(film["sub_list"]),film["ismpeg"],film["isvob"],film["cutting"],speed1,speed2)
+
+ if disktype=="dvd":
+ total+=calcule_menu_size(structure,sound_duration)
+
+ return total
+
+
+def check_program(programa):
+
+ """ This function allows to check that a program is available in the system, just
+ by calling it without arguments and checking the error returned """
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ launcher=devede_executor.executor()
+ p=launcher.launch_program(programa,win32arg=False)
+ else:
+ p=subprocess.Popen(programa+" >/dev/null 2>/dev/null",shell=True)
+
+ p.wait()
+ return p.returncode
+
+
+def load_config(global_vars):
+
+ """ Load the configuration """
+ home=get_home_directory()
+ global_vars["PAL"]=True
+ global_vars["multicore"]=1 # it shouldn't use multicore by default
+
+ # TODO change to allow a windows temp directory
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ #global_vars["temp_folder"]=os.environ["TEMP"]
+ global_vars["temp_folder"]=os.path.join(home,"Local Settings", "Temp")
+ else:
+ global_vars["temp_folder"]="/var/tmp"
+
+ print "Temp Directory is: " , global_vars["temp_folder"]
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ home=os.path.join(home,"Application Data", "devede","devede.conf")
+ else:
+ home+=".devede"
+
+ print "home load: ", home
+ menuformat_found=False
+ try:
+ archivo=open(home,"r")
+ while True:
+ linea=archivo.readline()
+ print "linea: ", linea
+ if linea=="":
+ break
+ if linea[-1]=="\n":
+ linea=linea[:-1]
+ if linea=="pal":
+ global_vars["PAL"]=True
+ if linea=="ntsc":
+ global_vars["PAL"]=False
+ if linea[:13]=="video_format:":
+ if linea[13:]=="pal":
+ global_vars["PAL"]=True
+ if linea[13:]=="ntsc":
+ global_vars["PAL"]=False
+ if linea[:12]=="temp_folder:":
+ global_vars["temp_folder"]=linea[12:]
+ if linea[:10]=="multicore:":
+ global_vars["multicore"]=int(linea[10:]) # don't remember multicore
+ if linea[:13]=="final_folder:":
+ global_vars["finalfolder"]=linea[13:]
+ if linea[:13]=="sub_language:":
+ global_vars["sub_language"]=linea[13:]
+ if linea[:13]=="sub_codepage:":
+ global_vars["sub_codepage"]=linea[13:]
+ #if linea[:]==":":
+ # global_vars[""]=linea[:]
+ archivo.close()
+ except IOError:
+ pass
+
+
+def save_config(global_vars):
+
+ """ Stores the configuration """
+
+ home=get_home_directory()
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ home=os.path.join(home,"Application Data", "devede")
+ if not os.path.isdir(home):
+ os.mkdir(home)
+ home=os.path.join(home, "devede.conf")
+ else:
+ home+=".devede"
+
+ if global_vars["temp_folder"][-1]!=os.sep:
+ global_vars["temp_folder"]+=os.sep
+ try:
+ archivo=open(home,"w")
+ if global_vars["PAL"]:
+ archivo.write("video_format:pal\n")
+ else:
+ archivo.write("video_format:ntsc\n")
+ archivo.write("temp_folder:"+global_vars["temp_folder"]+"\n")
+ archivo.write("multicore:"+str(global_vars["multicore"])+"\n")
+ if global_vars["finalfolder"]!="":
+ archivo.write("final_folder:"+str(global_vars["finalfolder"])+"\n")
+ archivo.write("sub_language:"+str(global_vars["sub_language"])+"\n")
+ archivo.write("sub_codepage:"+str(global_vars["sub_codepage"])+"\n")
+ archivo.close()
+ except IOError:
+ pass
+
+
+def get_new_param(parameters):
+
+ """ This function groups the parameters passed by the user into a list """
+
+ new_param=""
+
+ while(True):
+ if (parameters.find(" ")==0):
+ parameters=parameters[1:] # erase blank spaces at start
+ else:
+ break
+
+ if len(parameters)==0:
+ return "",""
+
+ p0=0
+ while True:
+ p1=parameters.find('\\',p0)
+ p2=parameters.find(' ',p0)
+ if p2==p1+1:
+ p0=p2+1
+ else:
+ if p2<0: # no next space, take all the string
+ retorno=""
+ doble=False
+ print parameters
+ for letra in parameters:
+ if (letra!='\\') or doble:
+ retorno+=letra
+ doble=False
+ else:
+ doble=True
+ return "",retorno
+ else:
+ retorno=""
+ doble=False
+ print parameters[:p2]
+ for letra in parameters[:p2]:
+ if (letra!='\\') or doble:
+ retorno+=letra
+ doble=False
+ else:
+ doble=True
+ return parameters[p2+1:],retorno
+
+
+def get_home_directory():
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ home=os.environ["USERPROFILE"]
+ else:
+ home=os.environ.get("HOME")
+
+ if home[-1]!=os.sep:
+ home=home+os.sep
+
+ print home
+ return home
+
+
+def return_time(seconds,empty):
+
+ """ cuts a time in seconds into seconds, minutes and hours """
+
+ seconds2=int(seconds)
+
+ hours=str(seconds2/3600)
+ if empty:
+ if len(hours)==1:
+ hours="0"+hours
+ else:
+ if hours=="0":
+ hours=""
+ if hours!="":
+ hours+=":"
+
+ minutes=str((seconds2/60)%60)
+ if empty or (hours!=""):
+ if len(minutes)==1:
+ minutes="0"+minutes
+ elif (minutes=="0") and (hours==""):
+ minutes=""
+ if minutes!="":
+ minutes+=":"
+
+ secs=str(seconds2%60)
+ if (len(secs)==1) and (minutes!=""):
+ secs="0"+secs
+
+ return hours+minutes+secs
+
+
+def get_max_titles(disctocreate):
+
+ """ Returns the maximum number of titles/chapters for each type of disc """
+
+ if disctocreate=="dvd":
+ return 61
+ else:
+ return 99
+
+def get_dvd_size(tree,disctocreate):
+
+ """ Returns the size for the currently selected disk type, and the minimum and maximum
+ videorate for the current video disk """
+
+ if tree!=None:
+ w=tree.get_object("dvdsize")
+ active=w.get_active()
+
+ # here we choose the size in Mbytes for the media
+ if 0==active:
+ tamano=170.0
+ elif 1==active:
+ tamano=700.0
+ elif 2==active:
+ tamano=750.0
+ elif 3==active:
+ tamano=1100.0
+ elif 4==active:
+ tamano=4200.0
+ else:
+ tamano=8000.0
+ else:
+ tamano=0
+
+ if disctocreate=="vcd":
+ minvrate=1152
+ maxvrate=1152
+ elif (disctocreate=="svcd") or (disctocreate=="cvd"):
+ minvrate=400
+ maxvrate=2300
+ elif (disctocreate=="dvd"):
+ minvrate=400
+ maxvrate=8500
+ elif (disctocreate=="divx"):
+ minvrate=300
+ maxvrate=6000
+
+ tamano*=0.92 # a safe margin of 8% to ensure that it never will be bigger
+ # (it's important to have in mind the space needed by disk structures like
+ # directories, file entries, and so on)
+
+ return tamano,minvrate,maxvrate
+
+
+def get_picture_type(filename):
+
+ try:
+ f=open(filename,"r")
+ except:
+ return ""
+
+ ftype=""
+ line=f.read(4)
+
+ if (line[0]=="\211") and (line[1:]=="PNG"):
+ ftype="png"
+
+ line2=f.read(7)
+ if (line[0]=="\377") and (line[1]=="\330") and (line[2]=="\377") and (line[3]=="\340") and (line2[2:6]=="JFIF") and (line2[6]=="\000"):
+ ftype="jpeg"
+
+ f.close()
+ print "tipo: "+str(ftype)
+ return ftype
+
+
+def create_tree(sobject,filename,builderpath="",autoconnect=True):
+
+ tree=gtk.Builder()
+ tree.set_translation_domain("devede")
+ filename=os.path.join(builderpath,filename+".ui")
+ print "Creating window "+filename
+ tree.add_from_file(filename)
+ if autoconnect:
+ tree.connect_signals(sobject)
+
+ return tree
diff --git a/devede_subtitles.py b/devede_subtitles.py
new file mode 100755
index 0000000..5b2a039
--- /dev/null
+++ b/devede_subtitles.py
@@ -0,0 +1,212 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+
+import signal
+import os
+import sys
+import re
+import shutil
+
+import devede_executor
+import devede_other
+
+class subtitles_adder(devede_executor.executor):
+
+ def expand_xml(self,text):
+
+ text=text.replace('&','&')
+ text=text.replace('<','<')
+ text=text.replace('>','>')
+ text=text.replace('"','"')
+ text=text.replace("'",''')
+ return text
+
+
+ def __init__(self,videofile,filename,filefolder,progresbar,proglabel,disctype,title,chapter,stream):
+
+ """ This class adds the subtitles to an already converted file
+
+ VIDEOFILE contains the parameters to convert the video
+ FILENAME is the generic file name given by the user
+ FILEFOLDER is the path where all the temporary and finall files will be created
+ PROGRESBAR is the progress bar where the class will show the progress
+ PROGLABEL is the label where the class will show what is it doing
+ DISCTYPE can be dvd, vcd, svcd, cvd or divx
+ TITLE and CHAPTER are the numbers used to identify the TITLE and CHAPTER number for this file
+ STREAMS is the stream number (to allow to add several subtitles)
+ """
+
+ devede_executor.executor.__init__(self,filename,filefolder,progresbar)
+ progresbar.pulse()
+ proglabel.set_text(_("Adding subtitles to")+"\n"+videofile["filename"])
+ self.currentfile=self.create_filename(filefolder+filename,title,chapter,disctype=="divx")
+
+ subtitle_list=videofile["sub_list"][stream]
+
+ # generate the XML file
+
+ self.error=""
+
+ try:
+ print "Trying to create "+filefolder+filename+"_sub.xml"
+ fichero=open(filefolder+filename+"_sub.xml","w")
+ except IOError:
+ print "IOError en subtitulos"
+ self.print_error=_("Failed to write to the destination directory.\nCheck that you have privileges and free space there.")
+ self.initerror=True
+ return
+
+ fichero.write('\n\t')
+ if (subtitle_list["sub_codepage"]!="UTF-8"):
+ final_type="UTF-8"
+ subfilename=os.path.join(filefolder,filename+"_sub_tmp.sub")
+ self.deletesub=subfilename
+ if 0!=devede_other.check_utf().convert_to_UTF8(subtitle_list["subtitles"],subfilename,subtitle_list["sub_codepage"]):
+ #except IOError:
+ print "IOError al convertir a UTF8"
+ self.print_error=_("Failed to write to the destination directory.\nCheck that you have privileges and free space there.")
+ self.initerror=True
+ return
+ else:
+ self.deletesub=""
+ final_type=subtitle_list["sub_codepage"]
+ subfilename=subtitle_list["subtitles"]
+ fichero.write('\n\t\t')
+ fichero.write("\n\t\n")
+ fichero.close()
+
+ comando=""
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ comando=["spumux.exe"]
+ comando.append("-m")
+ if disctype=="vcd":
+ comando.append("svcd")
+ else:
+ comando.append(disctype)
+ comando.append("-s")
+ comando.append(str(stream))
+
+ comando.append(filefolder+filename+"_sub.xml")
+ comando.append("-i")
+ comando.append(self.currentfile)
+ comando.append("-o")
+ comando.append(self.currentfile+".sub")
+ self.print_error=_("Conversion failed.\nIt seems a bug of SPUMUX.")
+ self.launch_program(comando,output=True)
+ else:
+ comando="spumux -m "
+ if disctype=="vcd":
+ comando+="svcd"
+ else:
+ comando+=disctype
+
+ comando+=' -s '+str(stream)+' "'+filefolder+filename+'_sub.xml"'
+
+ self.print_error=_("Conversion failed.\nIt seems a bug of SPUMUX.")
+ self.launch_shell(comando,output=True,stdinout=[self.currentfile,self.currentfile+".sub"])
+
+
+ def end_process(self,eraser,erase_temporal_files):
+
+ shutil.move(self.currentfile+".sub", self.currentfile)
+ if erase_temporal_files:
+ eraser.delete_sub_xml(self.deletesub)
+
+
+
+ def set_progress_bar(self):
+
+ self.bar.pulse()
+ position=self.cadena.find("STAT: ")
+ if (position!=-1):
+ position2=self.cadena.find(".",position+6)
+ if position2!=-1:
+ self.bar.set_text(self.cadena[position:position2])
+ return True
diff --git a/devede_title_properties.py b/devede_title_properties.py
new file mode 100755
index 0000000..69dc1fc
--- /dev/null
+++ b/devede_title_properties.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2007 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2007 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+import pygtk # for testing GTK version number
+pygtk.require ('2.0')
+import gtk
+
+import devede_other
+import devede_dialogs
+
+class title_properties:
+
+ def __init__(self,gladefile,structure,title):
+
+ self.structure=structure
+ self.title=title
+
+ self.tree=devede_other.create_tree(self,"wtitle_properties_dialog",gladefile,True)
+ self.window=self.tree.get_object("wtitle_properties_dialog")
+ w=self.tree.get_object("title_name")
+ w.set_text(structure[title][0]["nombre"])
+ w.grab_focus()
+ action=structure[title][0]["jumpto"]
+ if action=="menu":
+ w=self.tree.get_object("title_jmenu")
+ elif action=="first":
+ w=self.tree.get_object("title_jfirst")
+ elif action=="prev":
+ w=self.tree.get_object("title_jprev")
+ elif action=="loop":
+ w=self.tree.get_object("title_jthis")
+ elif action=="next":
+ w=self.tree.get_object("title_jnext")
+ elif action=="last":
+ w=self.tree.get_object("title_jlast")
+ w.set_active(True)
+
+ self.window.show()
+ retval=self.window.run()
+ print "Salgo de propiedades "+str(retval)
+ self.window.hide()
+
+ if retval==-5:
+ self.update_title()
+
+ self.window.destroy()
+ self.window=None
+
+ def on_title_name_activate(self,values):
+
+ self.window.response(-5)
+
+
+ def update_title(self):
+
+ w=self.tree.get_object("title_name")
+ self.structure[self.title][0]["nombre"]=w.get_text()
+
+ w=self.tree.get_object("title_jmenu")
+ if w.get_active():
+ self.structure[self.title][0]["jumpto"]="menu"
+ w=self.tree.get_object("title_jfirst")
+ if w.get_active():
+ self.structure[self.title][0]["jumpto"]="first"
+ w=self.tree.get_object("title_jprev")
+ if w.get_active():
+ self.structure[self.title][0]["jumpto"]="prev"
+ w=self.tree.get_object("title_jthis")
+ if w.get_active():
+ self.structure[self.title][0]["jumpto"]="loop"
+ w=self.tree.get_object("title_jnext")
+ if w.get_active():
+ self.structure[self.title][0]["jumpto"]="next"
+ w=self.tree.get_object("title_jlast")
+ if w.get_active():
+ self.structure[self.title][0]["jumpto"]="last"
diff --git a/devede_video_convert.py b/devede_video_convert.py
new file mode 100755
index 0000000..88eb4e1
--- /dev/null
+++ b/devede_video_convert.py
@@ -0,0 +1,567 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+
+import signal
+import os
+import sys
+import re
+import shutil
+import math
+
+import devede_other
+
+import devede_executor
+
+if (sys.platform == "win32") or (sys.platform=="win64"):
+ import win32file
+
+class video_converter(devede_executor.executor):
+
+ def adjust_audiorate(self,audiorate,isdvd):
+
+ """ Mencoder allows only a limited list of audio bitrates. This function chooses the nearest legal value """
+
+ if isdvd:
+ values=[448,384,320,256,224,192,160,128,112,96,80,64,56,48,32]
+ else:
+ values=[384,320,256,224,192,160,128,112,96,80,64,56,48,32]
+
+ for element in values:
+ if audiorate>=element:
+ return element
+
+ return 32
+
+
+ def __init__(self,global_vars,videofile,filename,filefolder,progresbar,proglabel,disctype,title,chapter,threads,seconds,encpass):
+
+ """ This class converts a video file to MPEG-1 or MPEG-2 format
+
+ VIDEOFILE contains the parameters to convert the video
+ FILENAME is the generic file name given by the user
+ FILEFOLDER is the path where all the temporary and finall files will be created
+ PROGRESBAR is the progress bar where the class will show the progress
+ PROGLABEL is the label where the class will show what is it doing
+ DISCTYPE can be dvd, vcd, svcd, cvd or divx
+ TITLE and CHAPTER are the numbers used to identify the TITLE and CHAPTER number for this file
+ THREADS is the number of threads to use
+ SECONDS is the number of seconds we want to convert (for previews)
+ ENCPASS is the number of encoding pass"""
+
+ devede_executor.executor.__init__(self,filename,filefolder,progresbar)
+ self.printout=False
+
+ self.percent2=120
+ if seconds==0:
+ self.divide=float(videofile["olength"])
+ if (videofile["cutting"]==1) or (videofile["cutting"]==2): # if we want only one half of the file
+ self.divide/=2
+ else:
+ self.divide=float(seconds)
+
+ if self.divide==0:
+ self.divide=1
+
+ self.error=""
+ progresbar.set_fraction(0)
+ progresbar.set_text("")
+
+ if videofile["ismpeg"]: # if the file hasn't to be converted, we simply copy or link it
+ self.pulse=True
+ self.print_error=_("File copy failed\nMaybe you ran out of disk space?")
+ if seconds==0:
+ texto=_("Copying the file")+"\n"
+ else:
+ texto=_("Creating preview")+"\n"
+ proglabel.set_text(texto+videofile["filename"])
+ currentfile=self.create_filename(filefolder+filename,title,chapter,disctype=="divx")
+
+ print "\ncurrentfile is: ", currentfile , "\n"
+
+ try:
+ os.remove(currentfile)
+ except:
+ pass
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ # links do not work on windows, so just copy the file
+ # self.launch_shell('copy "'+videofile["path"].replace('"','""')+'" "'+currentfile+'"',output=False)
+ # Only hardlinks are available on 2000 and XP, reparse points are available from vista onwards.
+ win32file.CreateHardLink(currentfile, videofile["path"].replace('"','""'))
+ else:
+ if len(videofile["sub_list"])==0:
+ self.launch_shell('ln -s "'+videofile["path"].replace('"','\\"')+'" "'+currentfile+'"',output=False)
+ else:
+ self.launch_shell('cp "'+videofile["path"].replace('"','\\"')+'" "'+currentfile+'"',output=False)
+ return
+
+ isvob=videofile["isvob"]
+
+ self.pulse=False
+ if seconds==0:
+ texto=(_("Converting files from title %(title_number)s (pass %(pass_number)s)\n\n%(file_name)s") % {"title_number":str(title),"pass_number":str(encpass),"file_name":videofile["filename"]} )
+ proglabel.set_text(texto) #+" "+str(title)+" Pass: "+ str(encpass) +"\n\n"+videofile["filename"] )
+ else:
+ texto=_("Creating preview")
+ proglabel.set_text(texto+"\n"+videofile["filename"])
+
+ addbars=False
+ framerate=int(videofile["ofps"])
+ videorate=int(videofile["vrate"])
+ audiorate=self.adjust_audiorate(int(videofile["arate"]),disctype=="dvd")
+
+ audio_final_rate=int(videofile["arateunc"])
+ audiodelay=float(videofile["adelay"])
+ final_framerate=float(videofile["fps"])
+ aspect_ratio_original=videofile["oaspect"]
+ aspect_ratio_final=videofile["aspect"]
+ resx_final=videofile["width"]
+ resy_final=videofile["height"]
+ resx_original=videofile["owidth"]
+ resy_original=videofile["oheight"]
+ copy_audio=videofile["copy_audio"]
+ sound51=videofile["sound51"]
+ gop12=videofile["gop12"]
+ audiostream=videofile["audio_stream"]
+ swap_fields=videofile["swap_fields"]
+ volume=videofile["volume"]
+ if (videofile["resolution"]==0) and (disctype=="divx"):
+ default_res=True
+ else:
+ default_res=False
+
+ speed1,speed2=devede_other.get_speedup(videofile)
+ if speed1==speed2:
+ speedup=None
+ else:
+ speedup=str(speed1)+":"+str(speed2)
+
+ if aspect_ratio_original<1.3:
+ aspect_ratio_original=float(videofile["owidth"])/(float(videofile["oheight"]))
+ if aspect_ratio_original<1.33333333:
+ aspect_ratio_original=1.33333333
+
+ max_videorate=int(videorate*2)
+ min_videorate=int(videorate*0.75)
+
+ dsize,minvid,maxvid=devede_other.get_dvd_size(None,disctype)
+
+ if max_videorate>maxvid:
+ max_videorate=maxvid
+ if min_videorateresy_inter)):
+ addbars=False
+
+ if addbars==False:
+ resx_inter=resx_original
+ resy_inter=resy_original
+ else:
+ addx=0
+ addy=int((resy_inter-resy_original)/2)
+ if(addy%2)==1:
+ addy+=1
+
+ command_var=[]
+ if (sys.platform!="win32") and (sys.platform!="win64"):
+ command_var=["mencoder"]
+ else:
+ command_var=["mencoder.exe"]
+
+ if (disctype=="dvd") or (disctype=="divx"):
+ audio_desired_final_rate=48000
+ else:
+ audio_desired_final_rate=44100
+
+ afvalues=""
+
+ if isvob==False:
+ if ((audio_final_rate!=audio_desired_final_rate) and (copy_audio==False)) or (speedup!=None):
+ command_var.append("-srate")
+ command_var.append(str(audio_desired_final_rate))
+ afvalues+="lavcresample="+str(audio_desired_final_rate)
+
+ if (copy_audio==False) and volume!=100:
+ if afvalues!="":
+ afvalues+=":"
+ afvalues+="volume="+str(10*math.log(volume/10,10))
+
+ # Add the speedup code
+
+ if speedup!=None:
+ command_var.append("-speed")
+ command_var.append(speedup)
+
+ if afvalues!="":
+ command_var.append("-af")
+ command_var.append(afvalues)
+
+ command_var.append("-noautosub")
+
+ command_var.append("-oac")
+ if copy_audio or isvob:
+ command_var.append("copy")
+ else:
+ if (disctype=="divx"):
+ command_var.append("mp3lame")
+ else:
+ command_var.append("lavc")
+
+ if (audiostream!=10000):
+ command_var.append("-aid")
+ command_var.append(str(audiostream))
+
+
+
+ telecine=False
+ if final_framerate==30:
+ if (framerate==24) and ((disctype=="dvd") or (disctype=="divx")):
+ str_final_framerate="24000/1001"
+ keyintv=15
+ telecine=True
+ else:
+ str_final_framerate="30000/1001"
+ keyintv=18
+ else:
+ str_final_framerate=str(int(final_framerate))
+ keyintv=15
+
+ if gop12:
+ keyintv=12
+
+ command_var.append("-ovc")
+ if isvob:
+ command_var.append("copy")
+ else:
+ command_var.append("lavc")
+
+ if (disctype!="divx"):
+ command_var.append("-of")
+ command_var.append("mpeg")
+ command_var.append("-mpegopts")
+ if disctype=="dvd":
+ if telecine and isvob==False:
+ command_var.append("format=dvd:tsaf:telecine")
+ else:
+ command_var.append("format=dvd:tsaf")
+ elif disctype=="vcd":
+ command_var.append("format=xvcd")
+ elif (disctype=="svcd") or (disctype=="cvd"):
+ command_var.append("format=xsvcd")
+ else:
+ print "Error, disc format incorrect. Talk with the creator."
+ sys.exit(1)
+
+ if seconds!=0:
+ command_var.append("-endpos")
+ command_var.append(str(seconds))
+ else:
+ if videofile["cutting"]==1: # first half only
+ command_var.append("-endpos")
+ command_var.append(str(videofile["olength"]/2))
+ elif videofile["cutting"]==2: # second half only
+ command_var.append("-ss")
+ command_var.append(str((videofile["olength"]/2)-5)) # start 5 seconds before
+
+ if (audiodelay!=0.0) and (copy_audio==False) and (isvob==False):
+ command_var.append("-delay")
+ command_var.append(str(audiodelay))
+
+ if sound51:
+ command_var.append("-channels")
+ command_var.append("6")
+
+ if (isvob==False) and (default_res==False):
+ command_var.append("-ofps")
+ command_var.append(str_final_framerate)
+
+ if disctype=="divx":
+ command_var.append("-ffourcc")
+ command_var.append("DX50")
+
+ lineatemp=""
+ acoma=False;
+
+ if swap_fields:
+ lineatemp+="phase=a"
+ acoma=True
+
+ extra_params=videofile["params_vf"] # take the VF extra params
+ while (extra_params!=""):
+ extra_params,new_param=devede_other.get_new_param(extra_params)
+ if (new_param!="") and (new_param!=','):
+ while (len(new_param)>1) and (new_param[0]==','):
+ new_param=new_param[1:]
+ while (len(new_param)>1) and (new_param[-1]==','):
+ new_param=new_param[:-1]
+ if acoma:
+ lineatemp+=","
+ lineatemp+=new_param
+ acoma=True
+
+ vmirror=0
+ hmirror=0
+ passlog_var = None
+
+ if videofile["deinterlace"]!="none":
+ if acoma:
+ lineatemp+=","
+ if videofile["deinterlace"]!="yadif":
+ lineatemp+="pp="+videofile["deinterlace"]
+ else:
+ lineatemp+="yadif=0"
+ acoma=True
+
+ if videofile["rotate"]==180:
+ vmirror=1-vmirror
+ hmirror=1-hmirror
+
+ if videofile["vmirror"]:
+ vmirror=1-vmirror
+
+ if videofile["hmirror"]:
+ hmirror=1-hmirror
+
+ if vmirror==1:
+ if acoma:
+ lineatemp+=","
+ lineatemp+="flip"
+ acoma=True
+
+ if hmirror==1:
+ if acoma:
+ lineatemp+=","
+ lineatemp+="mirror"
+ acoma=True
+
+ print "Addbars "+str(addbars)+" resx_o "+str(resx_original)+" resy_o "+str(resy_original)
+ print "resx_i "+str(resx_inter)+" resy_i "+str(resy_inter)
+ if addbars and ((resx_inter!=resx_original) or (resy_inter!=resy_original)) and (default_res==False):
+ if acoma:
+ lineatemp+=","
+ lineatemp+="expand="+str(resx_inter)+":"+str(resy_inter)+":"+str(addx)+":"+str(addy)
+ acoma=True
+
+ if videofile["rotate"]==90:
+ if acoma:
+ lineatemp+=","
+ lineatemp+="rotate=1"
+ acoma=True
+
+ if videofile["rotate"]==270:
+ if acoma:
+ lineatemp+=","
+ lineatemp+="rotate=2"
+ acoma=True
+
+ if ((resx_inter!=resx_final) or (resy_inter!=resy_final)) and (default_res==False):
+ if acoma:
+ lineatemp+=","
+ lineatemp+="scale="+str(resx_final)+":"+str(resy_final)
+ acoma=True
+
+ if disctype!="divx":
+ if acoma:
+ lineatemp+=","
+ lineatemp+="harddup"
+ acoma=True
+
+ if (lineatemp!="") and (isvob==False):
+ command_var.append("-vf")
+ command_var.append(lineatemp)
+
+ if isvob==False:
+ command_var.append("-lavcopts")
+
+ lavcopts=""
+
+ # Currently Mencoder supports up to 8 threads
+ if threads>8:
+ nthreads=8
+ else:
+ nthreads=threads
+
+ if nthreads>1:
+ lavcopts="threads="+str(nthreads)+":"
+ lavcopts+="vcodec="
+ if disctype=="vcd":
+ lavcopts+="mpeg1video"
+ elif disctype=="divx":
+ lavcopts+="mpeg4"
+ else:
+ lavcopts+="mpeg2video"
+
+ if videofile["trellis"]:
+ lavcopts+=":trell"
+
+ if videofile["mbd"]==0:
+ lavcopts+=":mbd=0"
+ elif videofile["mbd"]==1:
+ lavcopts+=":mbd=1"
+ elif videofile["mbd"]==2:
+ lavcopts+=":mbd=2"
+
+ lavcopts+=":sc_threshold=1000000000:cgop"
+
+ if disctype!="divx":
+ lavcopts+=":vstrict=0:vrc_maxrate="+str(max_videorate)
+ lavcopts+=":vrc_buf_size="
+ if (disctype=="vcd"):
+ lavcopts+="327"
+ elif (disctype=="svcd") or (disctype=="cvd"):
+ lavcopts+="917"
+ elif (disctype=="dvd"):
+ lavcopts+="1835"
+ if disctype=="vcd":
+ lavcopts+=":vrc_minrate="+str(min_videorate)
+
+ lavcopts+=":vbitrate="+str(videorate)
+
+ if disctype!="divx":
+ lavcopts+=":keyint="+str(keyintv)
+ if(copy_audio==False):
+ lavcopts+=":acodec="
+ if disctype=="dvd":
+ lavcopts+="ac3"
+ else:
+ lavcopts+="mp2"
+ lavcopts+=":abitrate="+str(audiorate)
+
+ if (default_res==False):
+ if aspect_ratio_final>1.4:
+ lavcopts+=":aspect=16/9"
+ else:
+ lavcopts+=":aspect=4/3"
+
+ if encpass > 0:
+ lavcopts+=":vpass=" + str(encpass)
+ passlog_var = os.path.join(filefolder,filename)+".log"
+ if encpass==1:
+ try:
+ os.remove(passlog_var)
+ except:
+ pass
+ if videofile["turbo1stpass"]:
+ lavcopts+=":turbo"
+
+
+ extra_params=videofile["params_lavc"] # take the LAVC extra params
+ while (extra_params!=""):
+ extra_params,new_param=devede_other.get_new_param(extra_params)
+ if (new_param!="") and (new_param!=':'):
+ while (len(new_param)>1) and (new_param[0]==':'):
+ new_param=new_param[1:]
+ while (len(new_param)>1) and (new_param[-1]==':'):
+ new_param=new_param[:-1]
+ lavcopts+=":"+new_param
+ command_var.append(lavcopts)
+
+ if (disctype=="divx") and (copy_audio==False) and (isvob==False):
+ lameopts="abr:br="+str(audiorate)
+ command_var.append("-lameopts")
+ extra_params=videofile["params_lame"] # take the LAME extra params
+ while (extra_params!=""):
+ extra_params,new_param=devede_other.get_new_param(extra_params)
+ if (new_param!="") and (new_param!=':'):
+ while (len(new_param)>1) and (new_param[0]==':'):
+ new_param=new_param[1:]
+ while (len(new_param)>1) and (new_param[-1]==':'):
+ new_param=new_param[:-1]
+ lameopts+=":"+new_param
+ command_var.append(lameopts)
+
+ currentfile=self.create_filename(filefolder+filename,title,chapter,disctype=="divx")
+
+ if (passlog_var != None):
+ command_var.append("-passlogfile")
+ command_var.append(passlog_var)
+
+ command_var.append("-o")
+ command_var.append(currentfile)
+ command_var.append(videofile["path"])
+
+ extra_params=videofile["params"] # take the extra params
+ while (extra_params!=""):
+ extra_params,new_param=devede_other.get_new_param(extra_params)
+ if new_param!="":
+ command_var.append(new_param)
+
+ self.print_error=_("Conversion failed.\nIt seems a bug of Mencoder.")
+ if (videofile["params"]!="") or (videofile["params_vf"]!="") or (videofile["params_lavc"]!="") or (videofile["params_lame"]!=""):
+ self.print_error+="\n"+_("Also check the extra params passed to Mencoder for syntax errors.")
+ self.error_not_done=True
+ self.launch_program(command_var,read_chars=300)
+
+
+
+ def end_process(self,eraser,erase_temporal_files):
+
+ return
+
+
+ def set_progress_bar(self):
+
+ if self.pulse:
+ self.bar.pulse()
+ return True
+
+ pos=self.cadena.find("Pos:")
+ if pos==-1:
+ return False # don't erase the string
+ pos2=self.cadena.find("s",pos+3)
+ if pos2==-1:
+ return False
+ valuetemp=float(self.cadena[pos+4:pos2])
+ value=(100.0*valuetemp)/self.divide
+ if (value!=self.percent2) or (self.percent2==120):
+ if (value)>100.0:
+ value=100.0
+ self.bar.set_fraction(value/100.0)
+ self.bar.set_text(str(int(value))+"%")
+ self.percent2=value
+ if self.error_not_done:
+ self.error_not_done=False
+ self.print_error=_("Conversion failed\nMaybe you ran out of disk space?")
+ return True
diff --git a/devede_xml_menu.py b/devede_xml_menu.py
new file mode 100755
index 0000000..47519f3
--- /dev/null
+++ b/devede_xml_menu.py
@@ -0,0 +1,937 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
+# Copyright 2006-2009 (C) Peter Gill - win32 parts
+
+# This file is part of DeVeDe
+#
+# DeVeDe 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 3 of the License, or
+# (at your option) any later version.
+#
+# DeVeDe 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, see .
+
+import gtk
+import cairo
+import time
+import sys
+import os
+import devede_executor
+import devede_other
+
+class xml_files(devede_executor.executor):
+
+ """ This class creates the XML files and the menues """
+
+ def __init__(self,pbar,filename,filefolder,structure,global_vars,proglabel,extcr=None):
+
+ devede_executor.executor.__init__(self,filename,filefolder,pbar)
+ self.proglabel=proglabel
+ self.print_error=_("Failed to create the menues.")
+ self.output=False
+ self.structure=structure
+ self.with_menu=global_vars["with_menu"]
+ if (len(structure)==1) and (len(structure[0])==2) and (not self.with_menu):
+ self.onlyone=True
+ else:
+ self.onlyone=False
+
+ self.do_menu=global_vars["do_menu"]
+ self.menu_bg=global_vars["menu_bg"]
+ self.menu_sound=global_vars["menu_sound"]
+ self.menu_sound_duration=global_vars["menu_sound_duration"]
+ self.font_name=global_vars["fontname"]
+ self.mplexed=True
+ self.installpath=global_vars["install_path"]
+ self.title_text=global_vars["menu_title_text"]
+ self.title_color=global_vars["menu_title_color"]
+ self.title_shadow=global_vars["menu_title_shadow"]
+ self.title_fontname=global_vars["menu_title_fontname"]
+
+ # for menu, use the same format than the global format
+ self.menu_PAL=global_vars["PAL"]
+ print "Menu PAL: "+str(self.menu_PAL)
+ self.bgcolor=global_vars["menu_bgcolor"]
+ self.fontcolor=global_vars["menu_font_color"]
+ self.activecolor=global_vars["menu_selc_color"]
+ self.shadowcolor=global_vars["menu_shadow_color"]
+ self.inactivecolor=[65535-self.activecolor[0],65535-self.activecolor[1],65535-self.activecolor[2],self.activecolor[3]]
+
+ self.align=global_vars["menu_alignment"]
+ self.halign=global_vars["menu_halignment"]
+ self.extcr=extcr
+
+ self.elements_per_menu=10
+ self.lines_per_menu=10
+
+ counter=0
+ if self.with_menu:
+ self.nmenues=0
+ while (len(self.structure[counter:])!=0):
+ counter+=self.elements_per_menu
+ self.nmenues+=1
+ else:
+ self.nmenues=1
+
+ self.margin_x=0.1
+ self.shadow_offset=0.0025
+
+ self.print_error=None
+
+
+ def do_menus(self):
+ return self.with_menu
+
+
+ def wait_end(self):
+
+ if self.print_error!=None:
+ return -1
+
+ retval=devede_executor.executor.wait_end(self)
+ if retval!=0:
+ self.print_error=_("Menu generation failed.")
+ return retval
+ self.create_menu2(self.counter,self.nelement)
+ if self.print_error!=None:
+ return -1
+ retval=devede_executor.executor.wait_end(self)
+ if retval!=0:
+ self.print_error=_("Can't add the buttons to the menus.\nIt seems a bug of SPUMUX.")
+ return retval
+
+
+
+ def get_elements_per_menu(self):
+
+ return (self.elements_per_menu)
+
+
+ def create_files(self):
+
+ if self.create_xml():
+ return _("Failed to write to the destination directory.\nCheck that you have privileges and free space there.")
+
+
+ def expand_xml(self,text):
+
+ text=text.replace('&','&')
+ text=text.replace('<','<')
+ text=text.replace('>','>')
+ text=text.replace('"','"')
+ text=text.replace("'",''')
+ return text
+
+
+ def create_xml(self):
+
+ """ Creates the XML file for DVDAuthor """
+
+ # calculate the position for each title
+
+ title_list=[]
+ counter=1
+ for element in self.structure:
+ title_list.append(counter)
+ counter+=((len(element))-1)
+
+ try:
+ fichero=open(self.filefolder+self.filename+".xml","w")
+ fichero.write('\n')
+
+ if self.onlyone:
+ fichero.write('\t\n')
+ else:
+
+ fichero.write('\t\n')
+
+ # MENU
+
+ # in the FPC we do a jump to the first menu in the first titleset if we wanted MENU
+ # or we jump to the second titleset if we didn't want MENU at startup
+
+ fichero.write('\t\t\n')
+ fichero.write('\t\t\tg0=100;\n')
+ if self.do_menu and self.with_menu:
+ fichero.write('\t\t\tg1=0;\n')
+ else:
+ fichero.write('\t\t\tg1=100;\n')
+ fichero.write('\t\t\tg2=1024;\n')
+ fichero.write('\t\t\tjump menu 1;\n')
+ fichero.write('\t\t\n')
+
+ # in the VMGM menu we create a code to jump to the title specified in G0
+ # but if the title is 100, we jump to the menus. There we show the menu number
+ # contained in G1
+
+ fichero.write("\t\t\n")
+
+ fichero.write('\t\t\t\n')
+
+ fichero.write('\t\t\t\n')
+ fichero.write('\t\t\t\t
\n')
+
+ counter=1
+ for element in self.structure:
+ for element2 in element[1:]:
+ fichero.write('\t\t\t\t\tif (g0 eq '+str(counter)+') {\n')
+ fichero.write('\t\t\t\t\t\tjump titleset '+str(1+counter)+' menu;\n')
+ fichero.write('\t\t\t\t\t}\n')
+ counter+=1
+ fichero.write('\t\t\t\t\tif (g0 eq 100) {\n')
+ fichero.write('\t\t\t\t\t\tg2=1024;\n')
+ fichero.write('\t\t\t\t\t\tjump titleset 1 menu;\n')
+ fichero.write('\t\t\t\t\t}\n')
+ fichero.write('\t\t\t\t
\n')
+ # fake video (one black picture with one second of sound) to ensure 100% compatibility
+ fichero.write('\t\t\t\t\n')
+ fichero.write('\t\t\t\n')
+ fichero.write('\t\t\n')
+ fichero.write("\t\n")
+
+ fichero.write("\n")
+
+ # the first titleset contains all the menus. G1 allows us to jump to the desired menu
+
+ fichero.write('\t\n')
+ fichero.write('\t\t\n')
+ fichero.write('\t\t\t\n')
+
+ button_counter=0
+ for menu_number in range(self.nmenues):
+ fichero.write('\t\t\t\n')
+ fichero.write('\t\t\t\t
\n')
+ # first we recover the currently selected button
+ fichero.write('\t\t\t\t\ts8=g2;\n')
+ if menu_number==0: # here we add some code to jump to each menu
+ for menu2 in range(self.nmenues-1):
+ fichero.write('\t\t\t\t\tif (g1 eq '+str(menu2+1)+') {\n')
+ fichero.write('\t\t\t\t\t\tjump menu '+str(menu2+2)+';\n')
+ fichero.write('\t\t\t\t\t}\n')
+
+ # this code is to fix a bug in some players
+ fichero.write('\t\t\t\t\tif (g1 eq 100) {\n')
+ fichero.write('\t\t\t\t\t\tjump title 1;\n')#menu '+str(self.nmenues+1)+';\n')
+ fichero.write('\t\t\t\t\t}\n')
+
+ fichero.write('\t\t\t\t
\n')
+ fichero.write('\t\t\t\t\n')
+
+ if self.with_menu:
+ cantidad=len(self.structure[self.elements_per_menu*menu_number:(menu_number+1)*self.elements_per_menu])
+ for nbutton in range(cantidad):
+ fichero.write('\t\t\t\t\n')
+ button_counter+=1
+
+ if (menu_number!=0):
+ fichero.write('\t\t\t\t\n')
+
+ if (menu_number!=self.nmenues-1) and (self.nmenues>1):
+ fichero.write('\t\t\t\t\n')
+
+ fichero.write('\t\t\t\t\n')
+ fichero.write('\t\t\t\t\tg2=s8;\n')
+ fichero.write('\t\t\t\t\tg1='+str(menu_number)+';\n')
+ fichero.write('\t\t\t\t\tjump menu '+str(menu_number+1)+';\n')
+ fichero.write('\t\t\t\t\n')
+ fichero.write('\t\t\t\n')
+
+ fichero.write('\t\t\n')
+ fichero.write('\t\t\n')
+ fichero.write('\t\t\t\n')
+ fichero.write('\t\t\t\n')
+ fichero.write('\t\t\t\t\n')
+ fichero.write('\t\t\t\t\n')
+ fichero.write('\t\t\t\t\tg0=1;\n')
+ fichero.write('\t\t\t\t\tg1=0;\n')
+ fichero.write('\t\t\t\t\tg2=1024;\n')
+ fichero.write('\t\t\t\t\tcall vmgm menu entry title;\n')
+ fichero.write('\t\t\t\t\n')
+ fichero.write('\t\t\t\n')
+ fichero.write('\t\t\n')
+ fichero.write("\t\n")
+
+ fichero.write("\n")
+
+ # Now we create the titleset for each video
+
+ total_t=len(self.structure)
+ titleset=1
+ titles=0
+ counter=0
+ for element in self.structure:
+ files=0
+ num_chapters=len(element)-1
+ action=element[0]["jumpto"]
+ for element2 in element[1:]:
+ fichero.write("\n")
+
+ if element2["ismpeg"]:
+
+ # if it's already an MPEG-2 compliant file, we use the original values
+ if element2["ofps"]==25:
+ pal_ntsc="pal"
+ ispal=True
+ else:
+ pal_ntsc="ntsc"
+ ispal=False
+ if element2["oaspect"]>1.6:
+ faspect='16:9'
+ fwide=True
+ else:
+ faspect='4:3'
+ fwide=False
+ else:
+ # but if we are converting it, we use the desired values
+ if element2["fps"]==25:
+ pal_ntsc="pal"
+ ispal=True
+ else:
+ pal_ntsc="ntsc"
+ ispal=False
+ if element2["aspect"]>1.6:
+ faspect='16:9'
+ fwide=True
+ else:
+ faspect='4:3'
+ fwide=False
+
+ fichero.write("\t\n")
+ if not self.onlyone:
+ fichero.write("\t\t\n")
+ fichero.write('\t\t\t\n')
+
+ fichero.write("\t\t\t\n")
+ fichero.write("\t\t\t\t
\n')
+
+ currentfile=self.create_filename(self.filefolder+self.filename,titles+1,files+1,False)
+ fichero.write('\t\t\t\t5):
+ if (element2["lchapters"]!=0): # add chapters
+ toadd=int(element2["lchapters"])
+ seconds=toadd*60
+ while seconds<(element2["olength"]-4):
+ thetime=devede_other.return_time(seconds,False)
+ fichero.write(","+thetime)
+ seconds+=(toadd*60)
+ fichero.write(','+devede_other.return_time((element2["olength"]-2),False))
+ fichero.write('" />\n')
+
+ if not self.onlyone:
+ fichero.write('\t\t\t\t\n')
+ files+=1
+ fichero.write('\t\t\t\t\tg1='+str(titles/self.elements_per_menu)+';\n')
+ if (files==num_chapters) and (action=="menu"): # last chapter
+ fichero.write('\t\t\t\t\tg0=100;\n')
+ fichero.write('\t\t\t\t\tcall vmgm menu entry title;\n')
+ else:
+ fichero.write('\t\t\t\t\tg0=')
+ if (files==num_chapters): # last chapter; do ACTION
+ if action=="prev":
+ if titles==0:
+ prev_t=total_t-1
+ else:
+ prev_t=titles-1
+ fichero.write(str(title_list[prev_t]))
+ elif action=="loop":
+ fichero.write(str(title_list[titles]))
+ elif action=="next":
+ if titles==total_t-1:
+ next_t=0
+ else:
+ next_t=titles+1
+ fichero.write(str(title_list[next_t]))
+ elif action=="last":
+ fichero.write(str(title_list[total_t-1]))
+ else:
+ fichero.write('1') # first
+ else:
+ # jump to next chapter in title
+ fichero.write(str(title_list[titles]+files))
+ fichero.write(';\n')
+ fichero.write('\t\t\t\t\tcall vmgm menu entry title;\n')
+ fichero.write('\t\t\t\t\n')
+ fichero.write("\t\t\t\n")
+ fichero.write("\t\t\n")
+ fichero.write("\t\n")
+ counter+=1
+ titles+=1
+ fichero.write("")
+ fichero.close()
+ return False
+ except IOError:
+ return True
+
+
+ def create_menu1(self,counter,nelement,threads):
+
+ """ Creates all the menu elements """
+
+ self.threads=threads
+ self.counter=counter
+ self.nelement=nelement
+ if self.proglabel!=None:
+ self.proglabel.set_text((_("Creating menu %(menu_number)d")) % {"menu_number":nelement+1})
+ print "Menu1 "+str(counter)+" "+str(nelement)
+
+ # create the XML file for the menu NELEMENT
+ if self.create_menu_stream(counter,nelement):
+ self.print_error=_("Failed to write to the destination directory.\nCheck that you have privileges and free space there.")
+ return None
+ # create the background picture for the menu NELEMENT
+ if None==self.create_menu_bg(counter,nelement,0):
+ self.print_error=_("Can't find the menu background.\nCheck the menu options.")
+ return None
+ # create the ACTIVE picture for the menu NELEMENT
+ if None==self.create_menu_bg(counter,nelement,1):
+ self.print_error=_("Failed to write to the destination directory.\nCheck that you have privileges and free space there.")
+ return None
+ # create the INACTIVE picture for the menu NELEMENT
+ if None==self.create_menu_bg(counter,nelement,2):
+ self.print_error=_("Failed to write to the destination directory.\nCheck that you have privileges and free space there.")
+ return None
+ # create the SELECTED picture for the menu NELEMENT
+ if None==self.create_menu_bg(counter,nelement,3):
+ self.print_error=_("Failed to write to the destination directory.\nCheck that you have privileges and free space there.")
+ return None
+ # creates an MPEG file with the sound and the background picture
+ if self.create_menu_mpg(nelement):
+ self.print_error=_("Menu generation failed.")
+
+ return None
+
+ def create_menu2(self,counter,nelement):
+
+ """ Mixes all files to create the NELEMENT menu MPEG file with the buttons embedded """
+
+ if self.menu_mplex_buttons(nelement):
+ self.print_error=_("Can't add the buttons to the menus.\nIt seems a bug of SPUMUX.")
+
+ return None
+
+
+ def create_menu_stream(self,first_element,nelement):
+
+ """ Creates the menu XML file """
+
+ cantidad=len(self.structure[first_element:first_element+self.elements_per_menu])
+ if self.align!=0:
+ offset=(self.lines_per_menu-cantidad)/self.align
+ else:
+ offset=0
+
+ if self.menu_PAL:
+ formato="pal"
+ else:
+ formato="ntsc"
+
+ try:
+ fichero=open(self.filefolder+self.filename+"_menu_"+str(nelement)+".xml","w")
+ fichero.write('\n\n\n')
+ if self.menu_PAL:
+ coord_y=[(92,128),(130,166),(168,204),(206,242),(244,280),(282,320),(322,358),(360,396),(398,436),(438,474),(476,512)]
+ else:
+ coord_y=[(76,106),(108,138),(140,170),(172,202),(204,234),(236,266),(268,298),(300,330),(332,362),(364,394),(396,426)]
+
+ if (nelement!=0):
+ has_previous=True
+ else:
+ has_previous=False
+
+ if ((nelement!=self.nmenues-1) and (self.nmenues>1)):
+ has_next=True
+ else:
+ has_next=False
+
+ for contador in range(cantidad):
+ fichero.write('\n')
+
+ if has_previous:
+ fichero.write('\n')
+
+ if has_next:
+ fichero.write('\n')
+ fichero.write("\n\n\n")
+ fichero.close()
+
+ return False
+ except IOError:
+ return True
+
+
+ def menu_set_bg(self,cr,x,y,width,bgcolor,fgcolor=None,shcolor=None):
+
+ """ paints the rounded rectangles used as background for titles and buttons """
+
+ radius=0.0375
+ border=0.0048
+ linea=0.0024
+ # I created the button image for this size, so I must respect it :(
+ #xb,yb,width,height,cx,cy=cr.text_extents("Título 1")
+
+ height=0.0391604010025
+
+ if width==1:
+ half_button=False
+ else:
+ half_button=True
+ width-=2*self.margin_x
+
+ if half_button: # we want half button
+ if x==0:
+ xi=x+self.margin_x
+ xf=xi+0.5-self.margin_x*1.5
+ else:
+ xf=x-self.margin_x
+ xi=xf-0.5+self.margin_x*1.5
+ else:
+ xi=x+self.margin_x
+ xf=xi+width
+
+ cr.set_line_width(linea)
+
+ cor=float(bgcolor[0])/65535.0
+ cog=float(bgcolor[1])/65535.0
+ cob=float(bgcolor[2])/65535.0
+ coa=float(bgcolor[3])/65535.0
+ cr.set_source_rgba(cor,cog,cob,coa)
+
+ cr.move_to(xi,y-border)
+ cr.line_to(xf,y-border)
+ cr.curve_to(xf+radius,y-border,xf+radius,y+height+border,xf,y+height+border)
+ cr.line_to(xi,y+height+border)
+ cr.curve_to(xi-radius,y+height+border,xi-radius,y-border,xi,y-border)
+ cr.fill()
+
+ arrowx=(xi+xf)/2
+ if x==0:
+ arrowx+=0.0175
+ s=True
+ else:
+ s=False
+ arrowx-=0.0175
+
+
+ self.menu_paint_arrow(cr, arrowx+self.shadow_offset, y+self.shadow_offset, s, height, shcolor)
+ self.menu_paint_arrow(cr, arrowx, y, s, height, fgcolor)
+
+
+ def menu_paint_arrow(self,cr,x,y,s,height,color):
+
+ if color==None:
+ return
+
+ cor=float(color[0])/65535.0
+ cog=float(color[1])/65535.0
+ cob=float(color[2])/65535.0
+ coa=float(color[3])/65535.0
+ cr.set_source_rgba(cor,cog,cob,coa)
+
+ cr.move_to(x,y)
+ if s:
+ cr.line_to(x-0.035,y+height/2)
+ else:
+ cr.line_to(x+0.035,y+height/2)
+ cr.line_to(x,y+height)
+ cr.line_to(x,y)
+ cr.fill()
+
+
+ def menu_set_text(self,cr,x,y,halign,texto,bgcolor,fontcolor,myfontname="Sans",myfontstyle=cairo.FONT_WEIGHT_BOLD,myfontslant=cairo.FONT_SLANT_NORMAL,myfontsize=12,vcenter=True):
+
+ fontsize2=myfontsize*0.00315
+
+ cr.select_font_face(myfontname,myfontslant,myfontstyle)
+
+ # I created the button image for this size, so I must respect it :(
+ #xb,yb,width,height,cx,cy=cr.text_extents("Título 1")
+ height=0.0391604010025
+
+ cr.set_font_size(fontsize2)
+ xb,y2,width,h2,cx,cy2=cr.text_extents(texto)
+
+ #if ((bgcolor[0]<512) and (bgcolor[1]<512) and (bgcolor[2]<512)):
+ # bgcolor[0]=512
+ # bgcolor[1]=512
+ # bgcolor[2]=512
+
+ #if ((fontcolor[0]<512) and (fontcolor[1]<512) and (fontcolor[2]<512)):
+ # fontcolor[0]=512
+ # fontcolor[1]=512
+ # fontcolor[2]=512
+
+ cor=float(fontcolor[0])/65535.0
+ cog=float(fontcolor[1])/65535.0
+ cob=float(fontcolor[2])/65535.0
+ coa=float(fontcolor[3])/65535.0
+ cr.set_source_rgba(cor,cog,cob,coa)
+ if halign==2: # center
+ nx=.5-width/2.0-xb
+ elif halign==0: # left
+ nx=self.margin_x
+ elif halign==1: # right
+ nx=1.0-self.margin_x-width
+
+ nx+=x
+
+ if vcenter:
+ ny=y-y2+(height-h2)/2.0
+ else:
+ ny=y-y2+(height-h2)
+
+ cr.move_to(nx,ny)
+ cr.show_text(texto)
+
+
+ def create_menu_bg(self,counter,element,paint_bg=0):
+
+ """ Paints the menu in a Cairo surface. PAINT_BG can be:
+ 0: paints everything for the base picture
+ 1: paints the HIGHLIGHT picture
+ 2: paints the ACTIVE picture
+ 3: paints the SELECT picture
+ """
+
+ if paint_bg==0:
+ try:
+ print "Uso "+str(self.menu_bg)
+ extra_pixbuf = gtk.gdk.pixbuf_new_from_file(self.menu_bg)
+ extra_x = extra_pixbuf.get_width()
+ extra_y = extra_pixbuf.get_height()
+
+ sf_base = cairo.ImageSurface(0,extra_x,extra_y)
+
+ extra_ct = cairo.Context(sf_base)
+ extra_ct2 = gtk.gdk.CairoContext(extra_ct)
+
+ extra_ct2.set_source_pixbuf(extra_pixbuf,0,0)
+ extra_ct2.paint()
+ extra_ct2.stroke()
+ except:
+ return None
+
+ if self.menu_PAL:
+ y=576.0
+ else:
+ y=480.0
+
+ sf=cairo.ImageSurface(cairo.FORMAT_ARGB32,720,int(y))
+ cr=cairo.Context(sf)
+ if paint_bg!=0: # if we are creating something different than the base, we use a 1bit surface
+ fo=cairo.FontOptions()
+ fo.set_antialias(cairo.ANTIALIAS_NONE)
+ cr.set_font_options(fo)
+ cr.set_antialias(cairo.ANTIALIAS_NONE)
+ else:
+ cr.set_source_rgb(1.0,1.0,1.0)
+ cr.paint()
+
+ cr.identity_matrix()
+
+ if paint_bg==0:
+ wbase=float(sf_base.get_width())
+ hbase=float(sf_base.get_height())
+ cr.scale(720.0/wbase,y/hbase)
+ cr.set_source_surface(sf_base)
+ cr.paint()
+ cr.identity_matrix()
+
+
+ cr.scale(sf.get_width(),1.33*sf.get_height()) # picture gets from 0 to 1 in X and from 0 to 0.75 in Y
+
+ pos_y=0.125
+
+ if self.align!=0:
+ pos_y+=0.05*float((self.lines_per_menu-len(self.structure[counter:counter+self.elements_per_menu]))/self.align)
+
+ fontname,fontstyle,fontslant,fontsize=devede_other.get_font_params(self.font_name)
+
+ shadowcolor=self.shadowcolor
+ if paint_bg!=2:
+ pos_y2=pos_y
+ if paint_bg==0:
+ bgcolor=self.bgcolor
+ fontcolor=self.fontcolor
+ arrowcolor=self.fontcolor
+ arrowshadowcolor=shadowcolor
+ elif paint_bg==1:
+ bgcolor=[0,0,0,0]
+ fontcolor=self.activecolor
+ arrowcolor=self.activecolor
+ strokecolor=self.activecolor
+ arrowshadowcolor=None
+ elif paint_bg==2:
+ bgcolor=[0,0,0,0]
+ fontcolor=self.activecolor
+ arrowcolor=self.activecolor
+ strokecolor=self.activecolor
+ arrowshadowcolor=None
+ else:
+ bgcolor=[0,0,0,0]
+ fontcolor=self.inactivecolor
+ arrowcolor=self.inactivecolor
+ strokecolor=self.inactivecolor
+ arrowshadowcolor=None
+
+ for entrada in self.structure[counter:counter+self.elements_per_menu]:
+ print pos_y
+ self.menu_set_bg(cr, 0, pos_y, 1, bgcolor)
+ if paint_bg==0: # print the shadow first
+ self.menu_set_text(cr,self.shadow_offset,pos_y+self.shadow_offset,self.halign,entrada[0]["nombre"],bgcolor,shadowcolor,fontname,fontstyle,fontslant,fontsize)
+ self.menu_set_text(cr,0,pos_y,self.halign,entrada[0]["nombre"],bgcolor,fontcolor,fontname,fontstyle,fontslant,fontsize)
+ pos_y+=0.05
+
+ print "Paint_bg "+str(paint_bg)+" title text: "+str(self.title_text)
+ if (paint_bg==0) and (self.title_text!=""):
+ print "pongo titulo "+self.title_text
+ fontname,fontstyle,fontslant,fontsize=devede_other.get_font_params(self.title_fontname)
+ self.menu_set_text(cr,self.shadow_offset, 0.075+self.shadow_offset,2,self.title_text, [0,0,0,0], self.title_shadow, fontname, fontstyle, fontslant, fontsize, False)
+ self.menu_set_text(cr,0, 0.075,2,self.title_text, [0,0,0,0], self.title_color, fontname, fontstyle, fontslant, fontsize, False)
+
+ pos_y=0.625
+ # check if we have to paint the NEXT MENU button
+ if (element!=self.nmenues-1) and (self.nmenues>1):
+ self.menu_set_bg(cr, 1, pos_y, 0.4, bgcolor,arrowcolor,arrowshadowcolor)
+ # check if we have to paint the PREVIOUS MENU button
+ if (element!=0) or ((self.extcr!=None) and (self.nmenues>1)):
+ self.menu_set_bg(cr, 0, pos_y, 0.4, bgcolor,arrowcolor,arrowshadowcolor)
+
+ if self.extcr==None:
+ if paint_bg==0:
+ sf.write_to_png(self.filefolder+self.filename+"_menu"+str(element)+"_bg.png")
+ elif paint_bg==1:
+ sf.write_to_png(self.filefolder+self.filename+"_menu"+str(element)+"_bg_active_out.png")
+ elif paint_bg==2:
+ sf.write_to_png(self.filefolder+self.filename+"_menu"+str(element)+"_bg_inactive_out.png")
+ else:
+ sf.write_to_png(self.filefolder+self.filename+"_menu"+str(element)+"_bg_select_out.png")
+ return sf
+
+
+ def create_menu_mpg(self,counter):
+
+ print "Creating menus"
+
+ self.mplexed=False
+ command_var=[]
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ command_var=["mencoder.exe"]
+ else:
+ command_var=["mencoder"]
+
+ currentfile=self.filefolder+self.filename+"_menu_"+str(counter)+".mpg"
+
+ command_var.append("-srate")
+ command_var.append("48000")
+ command_var.append("-af")
+ command_var.append("lavcresample=48000")
+ command_var.append("-oac")
+ command_var.append("lavc")
+ command_var.append("-ovc")
+ command_var.append("lavc")
+ command_var.append("-of")
+ command_var.append("mpeg")
+ command_var.append("-mpegopts")
+ command_var.append("format=dvd:tsaf")
+ command_var.append("-ofps")
+ audio=self.menu_sound
+ #audio="/home/raster/Escritorio/lazy.mp3"
+ if self.menu_PAL:
+ command_var.append("25")
+ else:
+ command_var.append("30000/1001")
+
+ wide="4/3"
+ command_var.append("-vf")
+ if self.menu_PAL:
+ command_var.append("scale=720:576,harddup")
+ else:
+ command_var.append("scale=720:480,harddup")
+ command_var.append("-lavcopts")
+ if self.threads>8:
+ nthreads=8
+ else:
+ nthreads=self.threads
+
+ if nthreads>1:
+ lavcopts="threads="+str(nthreads)+":"
+ else:
+ lavcopts=""
+ lavcopts+="vcodec=mpeg2video:sc_threshold=1000000000:cgop:trell:mbd=2:vstrict=0:"
+ lavcopts+="vrc_maxrate=7000:vrc_buf_size=1835:vbitrate=1000:keyint=12:"
+ lavcopts+="acodec=ac3:abitrate=128:aspect="+wide
+ command_var.append(lavcopts)
+ command_var.append("-o")
+ command_var.append(currentfile)
+ command_var.append("-audiofile")
+ command_var.append(audio)
+ command_var.append("-mf")
+ command_var.append("type=png:fps=1/"+str(self.menu_sound_duration))
+ origDir=os.getcwd()
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ temp=os.path.split(self.filefolder+self.filename+"_menu"+str(counter)+"_bg.png")
+ picDir=temp[0]
+ picName=temp[1]
+ command_var.append("mf://"+picName)
+ os.chdir(picDir)
+ else:
+ command_var.append("mf://"+self.filefolder+self.filename+"_menu"+str(counter)+"_bg.png")
+ print "Lanzo "+str(command_var)
+
+ self.launch_program(command_var)
+
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ os.chdir(origDir)
+
+
+ def menu_mplex_buttons(self,counter):
+
+ self.mplexed=True
+ if (sys.platform=="win32") or (sys.platform=="win64"):
+ comando=["spumux.exe"]
+ # The -i -o is with a custom patched version of
+ # dvdauthor. Best and easiest way of making it work
+ comando.append(self.filefolder+self.filename+"_menu_"+str(counter)+".xml")
+ comando.append("-i")
+ comando.append(self.filefolder+self.filename+"_menu_"+str(counter)+".mpg")
+ comando.append("-o")
+ comando.append(self.filefolder+self.filename+"_menu2_"+str(counter)+".mpg")
+ self.launch_program(comando)
+ else:
+ comando="spumux"
+
+ comando+=' "' +self.filefolder+self.filename+'_menu_'+str(counter)+'.xml"'
+
+ print "Launch: "+comando
+ self.launch_shell(comando,stdinout=[self.filefolder+self.filename+"_menu_"+str(counter)+".mpg",self.filefolder+self.filename+"_menu2_"+str(counter)+".mpg"])
+
+
+ def end_process(self,eraser,erase_temporary_files):
+
+ if erase_temporary_files and self.mplexed:
+ eraser.delete_menu_temp()
diff --git a/devedesans.ttf b/devedesans.ttf
new file mode 100644
index 0000000..47308bb
Binary files /dev/null and b/devedesans.ttf differ
diff --git a/docs/changelog.Debian b/docs/changelog.Debian
new file mode 100644
index 0000000..838f1c7
--- /dev/null
+++ b/docs/changelog.Debian
@@ -0,0 +1,415 @@
+devede (3.16.8-0~rastersoft1) karmic; urgency=low
+
+ * New upstream version
+
+ - Fixed a bug which prevented to create VCD, sVCD and CVD
+
+ -- Sergio Costas Rodriguez Thu, 18 Apr 2010 00:09:34 +0001
+
+devede (3.16.7-0~rastersoft1) karmic; urgency=low
+
+ * New upstream version
+
+ - Video info is updated when changing selection with arrow keys
+ - Allows up to 448Kbps for audio when using AC3
+
+ -- Sergio Costas Rodriguez Thu, 11 Apr 2010 00:09:34 +0001
+
+devede (3.16.6-0~rastersoft1) karmic; urgency=low
+
+ * New upstream version
+ - Buttons in main window now has a border, like all other buttons
+ - Desktop launcher now shows a much more HIG-compliant description
+ - Pressing RETURN key in Title properties and Create disc dialogs works like
+ clicking the Accept button
+
+ -- Sergio Costas Rodriguez Thu, 19 Mar 2010 00:09:34 +0001
+
+devede (3.16.5-0~rastersoft1) karmic; urgency=low
+
+ * New upstream version
+ - Don't show by default the subtitles in MKV files
+ - Fixed dependencies in .deb package to ensure Debian compatibility
+
+ -- Sergio Costas Rodriguez Thu, 9 Mar 2010 00:09:34 +0001
+
+devede (3.16.4-0~rastersoft1) karmic; urgency=low
+
+ * New upstream version
+ - Adjusts the audio bitrate to the list of legal values supported by Mencoder
+
+ -- Sergio Costas Rodriguez Thu, 24 Feb 2010 00:09:34 +0001
+
+devede (3.16.3-0~rastersoft1) karmic; urgency=low
+
+ * New upstream version
+ - Allows blank spaces in subtitles filenames
+
+ -- Sergio Costas Rodriguez Thu, 22 Feb 2010 00:09:34 +0001
+
+devede (3.16.2-0~rastersoft1) karmic; urgency=low
+
+ * New upstream version
+ - Fixed audio bitrate when using 5.1 sound
+
+ -- Sergio Costas Rodriguez Thu, 21 Feb 2010 00:09:34 +0001
+
+devede (3.16.1-0~rastersoft1) karmic; urgency=low
+
+ * New upstream version
+ - Fixed a hang when repacking MPEG files instead of reencoding them
+ - Fixed Galician translation
+
+ -- Sergio Costas Rodriguez Thu, 21 Feb 2010 00:09:34 +0001
+
+devede (3.16.0-0~rastersoft1) karmic; urgency=low
+
+ * New upstream version
+ - Added support for two-pass encoding (thanks to Gustavo Sanchez)
+ - Added support for 64bit Windows
+ - Fixed a bug when importing old .devede files
+ - Fixed a bug that prevented to manually choose the aspect ratio
+ - Allows to change the final volume
+ - Now remembers the last output directory used, and the last subtitle language and codepage
+ - Added support for UTF-16 subtitles
+ - Autodetects ASCII, UTF-8 and UTF-16 subtitles
+ - Allows to remove menu
+ - Check if there's a /, | or \ in the file name
+ - Allows to force the subtitles by default
+ - Flush stdout and stderr at end, so it should finally allow to have full debugging info
+ - Several bugfixes for Windows version (thanks to Peter Gill)
+
+ -- Sergio Costas Rodriguez Thu, 07 Jan 2010 00:09:34 +0001
+
+devede (3.15.2-0~rastersoft1) jaunty; urgency=low
+
+ * New upstream version
+ - Improved debugging
+
+ -- Sergio Costas Rodriguez Thu, 30 Nov 2009 00:09:34 +0001
+
+devede (3.15.1-0~rastersoft1) jaunty; urgency=medium
+
+ * New upstream version
+ - Fixed a bug when the program can't write the subtitle's XML file
+ - Added Miguel Bouzada to the list of translators
+
+ -- Sergio Costas Rodriguez Thu, 29 Nov 2009 00:09:34 +0001
+
+devede (3.15.0-0~rastersoft1) jaunty; urgency=low
+
+ * New upstream version
+ - Added -loop 1 in mplayer commands to avoid problems when the user has a mplayer.config file
+ - Changed shape of the main window to better fit wide screens
+ - Added support for OGG/Vorbis for menu sound
+ - Added new backgrounds
+ - Support for RMVB file extension
+ - Preview button now can hide the icon when global preferences says it
+ - When creating a DivX, if Default resolution is selected, won't touch size, nor aspect ratio, nor add bars
+ - Updated translation to French
+ - Updated translation to Galician
+ - Translation to Tradicional Chinese
+ - Support for filenames with double quotes (thanks to Christian)
+ - Allows to split a film in two disks in SVCD and CVD, not only in VCD
+
+ -- Sergio Costas Rodriguez Thu, 27 Nov 2009 00:09:34 +0001
+
+devede (3.14.0-0~rastersoft1) jaunty; urgency=low
+
+ * New upstream version
+ - Now doesn't add black bars when creating an NTSC disc from an 720x480
+ file without ASPECT RATIO parameter embedded
+ - Allows to repack a file as MPEG-PS without recompress the streams
+ (useful to work with VOB files)
+ - Allows to swap the field order in interlaced videos
+ - Allows to change the subtitle's font size
+ - Now supports subtitle filenames with XML-reserved characters
+ - Supports all picture types for menu backgrounds (not only PNG)
+ - Now removes previous preview files if they already existed, when
+ using LN
+ - Fixed free disk space calcule in Windows 2000 and the SetPriority
+ function (thanks to Peter Gill)
+ - Adjusted the media sizes to ensure that the ISOs always will fit in the
+ disc
+
+ -- Sergio Costas Rodriguez Thu, 3 Jul 2009 00:09:34 +0001
+
+devede (3.13.1-0~rastersoft1) jaunty; urgency=low
+
+ * Minor bugfixes
+ - Save as... option now works.
+ - The Title properties window closes when the user changes the action to
+ do when the title ends. Fixed.
+ - When the $HOME/.spumux directory didn't exists, DeVeDe is unable to find
+ the font for subtitles. Fixed.
+ - Added TTF-DEJAVU-CORE package in the DEB dependencies.
+
+ -- Sergio Costas Rodriguez Thu, 25 May 2009 15:30:04 +0001
+
+devede (3.13.0-0~rastersoft1) jaunty; urgency=low
+
+ * New upstream version
+ - Fixed greek translation
+ - Doesn't fail when LANG is not defined
+ - Migration from LibGLADE to GtkBuilder
+
+ -- Sergio Costas Rodriguez Thu, 14 May 2009 21:42:04 +0001
+
+devede (3.12-0~rastersoft3) hardy; urgency=low
+
+ * Minor bugfixes (equal to DeVeDe 3.12c)
+ - Updated french translation
+ - Updated file Changelog.Debian
+
+ -- Sergio Costas Rodriguez Tue, 27 Jan 2009 00:49:43 +0001
+
+devede (3.12-0~rastersoft2) hardy; urgency=low
+
+ * Minor bugfixes (equal to DeVeDe 3.12b)
+ - Fixed a bug in the french translation
+ - Added italian translation
+
+ -- Sergio Costas Rodriguez Mon, 26 Jan 2009 00:32:23 +0001
+
+devede (3.12-0~rastersoft1) hardy; urgency=low
+
+ * New upstream version
+ - Allows to add files with the characters <, > &, " and '
+ - When the user selects a directory in the menu, removes the preview, to avoid a bug.
+ - Now, when the output directory already exists, asks to the user before deleting it.
+ - New disc type selection window (thanks to Jonathan Estrella).
+
+ -- Sergio Costas Rodriguez Sun, 25 Jan 2009 01:14:12 +0001
+
+devede (3.11-0~rastersoft1) hardy; urgency=low
+
+ * New upstream version
+ - Now recovers the menu options when loading a disc structure
+ - Changed the appearance to make it more eye-candy
+ - Shows the menu's NTSC preview at the right size
+ - Shows right the menu's title tipography
+ - Added compatibility with GenISOimage
+ - Better code to avoid antialiasing when creating the menu entries
+ - Now limits the number of files to 61 to avoid problems with DVDAuthor
+
+ -- Sergio Costas Rodriguez Sat, 24 Aug 2008 20:14:20 +0001
+
+devede (3.10-0~rastersoft1) hardy; urgency=low
+
+ * New upstream version
+ - Now the user chooses a global format (PAL or NTSC) for videos and
+ menus.
+ - Removed the limit of 12 titles; now can create discs with up to 90
+ titles and/or 90 files.
+ - Allows to add a title to the menu, and shadows to the menu texts.
+ - Allows to put the menu texts at the right, left or center.
+ - Now shows a preview of the selected picture when choosing the menu
+ background.
+ - Added YADIF deinterlace filter support.
+ - Added contextual help.
+ - New background picture.
+ - Support for resolution of 160x128 pixels in DivX.
+ - Added a preview button in the Menu options window.
+ - Now hides the advanced options in the main window.
+ - Fixed the bug that made the menus to be shown only one second in some
+ players.
+ - Now it always honours the PAL/NTSC menu type.
+ - Now,when creating a PAL disk from a 24fps source, DeVeDe speeds up it
+ instead of adding one frame each 24, obtaining a more fluid animation.
+ - The silence sound file has been changed from WAV to MP3 to free some
+ disk space.
+ - Fixed a little bug when using HD resolutions for DivX.
+ - Modified code to simplify adding new options to the DVD's menus.
+
+ -- Sergio Costas Rodriguez Sat, 16 Aug 2008 16:40:20 +0001
+
+devede (3.9-0~getdeb1) hardy; urgency=low
+
+ * New upstream version
+ - Due to the use of VRC_MINRATE option, sometimes the final disk size was
+ bigger than the predicted. Fixed.
+ - Now remembers the directory from where the user added a movie file.
+ - Fixed the detection of the number of cores in the system.
+ - Adds the menu type (PAL or NTSC) when creating a menuless disk.
+ - Uses transparent pictures for the menus, ensuring that they work fine
+ in more players.
+ - Removed CONVERT dependency (Thanks to Peter Gill).
+
+ -- Festor Wailon Dacoba Tue, 24 Jun 2008 12:35:21 +0000
+
+devede (3.8-0~getdeb1) hardy; urgency=low
+
+ * New upstream version
+ - Automatic video bitrate adjust, to ensure that the ISO or BIN/CUE
+ image occupies the maximum size in the disk.
+ - Support for up to 32 subtitles tracks.
+ - Allows to specify the subtitle's language.
+ - Allows to choose the language to use when the original video contains
+ several audio tracks.
+ - Added the L5 deinterlacing filter.
+ - Support for rotating and flipping the video.
+ - Muticore support.
+ - Allows to mix classic and widescreen videos in the same disk.
+ - High Definition support in DivX.
+ - Allows to Drag&Drop subtitles in the properties window, or to load
+ a configuration file by Dragging&Dropping.
+ - By default uses a GOP of 12 frames to ensure maximum compatibility.
+ - Uses the Telecine parameter to improve quality in 24fps films.
+ - Allows to add extra parameters in -lavcopts, -vf and -lameopts.
+ - Now stores the status of the buttons for delete temporary files
+ and to choose the action to do.
+ - Added an icon to all windows.
+ - More elegant menu system (based on code from Mojoholder)
+ - Allows to choose the colors and the position of the menus.
+ - Adjusted the maximum bitrate for DivX.
+ - Fixed a bug when Mplayer is compiled with --enable-color-console.
+
+ -- Joao Pinto Sun, 25 May 2008 15:55:18 +0000
+
+devede (3.7-1~getdeb1) gutsy; urgency=low
+
+ * New upstream version
+
+ -- Joao Pinto Wed, 16 Apr 2008 21:28:29 +0000
+
+devede (3.6-0~getdeb1) gutsy; urgency=low
+
+ * Backported to Gutsy
+
+ -- Matthew Beaver Thu, 03 Jan 2008 18:29:50 -0800
+
+devede (3.6-0.0ubuntu1) hardy; urgency=low
+
+ * New upstream release.
+ * debian/control
+ - added Maintainer and Homepage
+ - Updated to Debian Python Policy
+ - Changed Standards-Version to 3.7.3
+ - Changed section to x11
+ * debian/rules
+ - added get-orig-source
+ * Fixes: (LP: #130342), (LP: #175742)
+
+ -- Pedro Fragoso Mon, 10 Dec 2007 01:01:36 +0000
+
+devede (2.13-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Mon, 16 Apr 2007 13:26:38 +0200
+
+devede (2.12-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Mon, 26 Feb 2007 09:37:36 +0100
+
+devede (2.11-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Thu, 8 Feb 2007 10:19:26 +0100
+
+devede (2.10-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Wed, 17 Jan 2007 10:57:56 +0100
+
+devede (2.9-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Sun, 31 Dec 2006 10:15:40 +0100
+
+devede (2.8-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Thu, 21 Dec 2006 11:15:40 +0100
+
+devede (2.7-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Mon, 18 Dec 2006 10:14:08 +0100
+
+devede (2.5-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Sun, 15 Oct 2006 19:20:16 +0200
+
+devede (2.4-0.1) unstable; urgency=low
+
+ * Need to depends on vcdimager (Thanks to Par Johansson).
+
+ -- Christian Marillat Fri, 6 Oct 2006 10:27:21 +0200
+
+devede (2.4-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Mon, 25 Sep 2006 10:14:48 +0200
+
+devede (2.3-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Sat, 2 Sep 2006 09:34:44 +0200
+
+devede (2.2-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Fri, 18 Aug 2006 10:51:58 +0200
+
+devede (2.1-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Thu, 6 Jul 2006 17:15:27 +0200
+
+devede (2.0-0.1) unstable; urgency=low
+
+ * Use dpatch so I don't loss my patch (need to call python2.4 instead of
+ python in devede script).
+
+ -- Christian Marillat Sun, 18 Jun 2006 13:54:15 +0200
+
+devede (2.0-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Sun, 18 Jun 2006 13:42:06 +0200
+
+devede (1.6-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Fri, 2 Jun 2006 08:23:24 +0200
+
+devede (1.5-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Wed, 24 May 2006 08:20:12 +0200
+
+devede (1.4-0.0) unstable; urgency=low
+
+ * News upstream release.
+
+ -- Christian Marillat Sun, 19 Mar 2006 10:56:52 +0100
+
+devede (1.3-0.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Marillat Sun, 26 Feb 2006 16:39:08 +0100
+
+devede (1.2-0.0) unstable; urgency=low
+
+ * Initial release.
+
+ -- Christian Marillat Thu, 23 Feb 2006 11:35:45 +0100
+
diff --git a/docs/copyright b/docs/copyright
new file mode 100644
index 0000000..627e40d
--- /dev/null
+++ b/docs/copyright
@@ -0,0 +1,22 @@
+This package was debianized by Sergio Costas
+based on the original Debian package by Christian Marillat
+ on Thu, 23 Feb 2006 11:35:45 +0100.
+
+It was downloaded from http://www.rastersoft.com/programas/devede.html
+
+Copyright Holder: Sergio Costas
+
+License: 2005 Sergio Costas
+ DeVeDe 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 3 of the License, or
+ (at your option) any later version.
+
+ DeVeDe 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, see .
+
diff --git a/docs/html/basic.html b/docs/html/basic.html
new file mode 100644
index 0000000..0eb37e9
--- /dev/null
+++ b/docs/html/basic.html
@@ -0,0 +1,62 @@
+
+
+
+
+DeVeDe, a video DVD creator
+
+
+
Before explaining all the options in DeVeDe, I'll give you the common sequence to create a disk.
+
+
First, you choose the disk type you want to create (DVD, VCD, sVCD, CVD or DivX). Then, you drag&drop
+the files you want in the main window, creating (if is a DVD) the titles you want, or add them one-each-time
+with the Add file button.
+
+
If you want to add subtitles or fine-tune the properties of a file, you should use the Properties button.
+
+
Then you should click the Adjust disk usage button. This will automatically set the video bitrate for each
+file (which depends on the final size of the file, if it has one or more subtitles, if it's already a converted
+file...).
+
+
After that, use the Menu preview button to ensure that you like the menu that DeVeDe will create. If not,
+you can use the Menu options button to change them. Remember that the menu will use the names of the titles.
+
+
Finally, just click the Forward button, choose a destination directory and a name, and enjoy a good
+coffee while DeVeDe works.
+
+
When the ISO or BIN/CUE file has been created, you can use K3b, GnomeBaker or Brasero to burn it. Under Gnome
+(is possible that under KDE there's a simmilar option) you can right-click on the file and choose Burn to disk
+too. Or you can use the safest option: command line:
The options Load, Save and Save as in the File menu allow you to save
+the current disk structure, in the case that you want continue your work later, or reuse it for another,
+slightly different, disk. DeVeDe stores the disk format adding the extension .devede.
+
+
When you load a disk structure, DeVeDe checks that every file is still in its place. If there is a missing,
+it will show an error message listing all the missing files (the complete path) and will refuse to load the
+structure, to avoid incorrect results. There's a trick to still load it: just copy another movie to the
+right directory and rename it with the right name, and after loading the structure, remove it from DeVeDe.
+
+
If the missing file is the menu background or the menu soundtrack, DeVeDe will load the structure anyway, but
+showing a warning message and using the default background and/or soundtrack instead.
+
+
+
\ No newline at end of file
diff --git a/docs/html/choose.jpg b/docs/html/choose.jpg
new file mode 100644
index 0000000..d82883d
Binary files /dev/null and b/docs/html/choose.jpg differ
diff --git a/docs/html/contact.html b/docs/html/contact.html
new file mode 100644
index 0000000..99788de
--- /dev/null
+++ b/docs/html/contact.html
@@ -0,0 +1,21 @@
+
+
+
+
+DeVeDe, a video DVD creator
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/html/create.jpg b/docs/html/create.jpg
new file mode 100644
index 0000000..c1610e9
Binary files /dev/null and b/docs/html/create.jpg differ
diff --git a/docs/html/disk.html b/docs/html/disk.html
new file mode 100644
index 0000000..b93d99d
--- /dev/null
+++ b/docs/html/disk.html
@@ -0,0 +1,32 @@
+
+
+
+
+DeVeDe, a video DVD creator
+
+
+
After adding all the files you want and clicking in the Forward button, you will be prompted for a
+directory where DeVeDe will create all the files, and a generic name for them. The directory must have
+enought free space to hold all the
+temporary files (aprox. the double of the final CD/DVD size if you delete temporary files, or the triple if you
+don't). The generic name will be used to name all
+the temporary files, so the MPEG files will be named as GENERICNAME_XX_YY.MPG, the DVD tree directory will
+be named GENERICNAME, the ISO image will be named GENERICNAME.ISO, and the BIN/CUE files will be
+GENERICNAME.BIN and GENERICNAME.CUE.
+
+
Finally, the program will start to create the files. Remember that this is a very slow process, and can
+need more than two hours to be completed, depending on the files.
+
+
When the disk image has been created, you can use several methods to burn it into a CD or DVD. Just
+read the FAQ.
+
+
\ No newline at end of file
diff --git a/docs/html/faq.html b/docs/html/faq.html
new file mode 100644
index 0000000..e12cec9
--- /dev/null
+++ b/docs/html/faq.html
@@ -0,0 +1,258 @@
+
+
+
+
+DeVeDe, a video DVD creator
+
+
+
I installed DeVeDe in Ubuntu 9.10, but the icons in the buttons dissapeared. How can I put them again?
+
It's a bug in Ubuntu. To fix it, press Alt+F2, type gconf-editor to enter Gnome's configuration system, and activate the entry / ->
+desktop -> gnome -> interface -> buttons_have_icons.
+As a bonus, you can get again the icons in the main menu by activating the entry / -> desktop -> gnome -> interface -> menus_have_icons
+
Here is a picture to explain it better:
+
+
+
+
I'm running Ubuntu 8.10/Debian stable and I can't run DeVeDe. What's happening?
+
Last versions of DeVeDe need Gtk 2.16 or latter. Those distros have older versions. You must update your system.
+
+
+I installed DeVeDe using the DEB package, but it doesn't work fine. I miss some features explained in
+the instructions.
+
To install the DEB version you must remove first any version installed from a TAR.BZ2 package, or they will
+interfere. You can do it just running sudo ./uninstall.sh (from the TAR.BZ2 package) and then installing
+the DEB package.
+
+
+I created a PAL disc, and the final movie is played slightly faster, but older versions of DeVeDe
+converts them at the right speed, but with a little jump each second. Why?
+
This happens only when the original file has 24 frames per second (like classic films), and you create a
+PAL disc, which needs 25 frames per second. In older versions DeVeDe converted the original 24 fps to
+25 just by repeating one after 24. Unfortunately that produces a noticeable "jump" each second, because the
+picture, literally, stops during 1/25 of a second.
+
To avoid this, in this version DeVeDe does the same that does a TV station: plays the movie at 25 fps instead
+of 24fps. That means that it's played about a 4% faster. That means that the pitch will be higher. Usually
+you won't be able to notice it, unless you compare the original and the new sound.
+
+
+
+I added a VOB file and marked the option "This is already a DVD/xCD-suitable MPEG file", but DeVeDe fails.
+
The VOB files aren't fully suitable for DVDAuthor. In order to get the right file you can repackage it
+(without recompressing, so you will not loose quality) just marking the option Repack audio and video without reencoding.
+
+
+
+DeVeDe creates an ISO (or BIN/CUE) file instead of burning a CD/DVD. How can I create the final disk?
+
For ISO files, under GNOME, the fastest method it to just right-click in the ISO file and choose "Burn to CD...".
Where /dev/dvd is the device which corresponds to your DVD burner (in some computers it can be /dev/dvd1;
+to be sure, just type ls /dev/dvd* to see the right value).
Finally, you can use your preferred CD/DVD burner program like GnomeBaker, Brasero or K3b.
+
+
+
+DeVeDe is very slow compared to Mencoder alone!
+
By default, Mencoder uses fast options, but DeVeDe uses high quality options.
+If you want speed, just go to the tab Quality options (in the
+Advanced options section) and there disable Trellis and choose Use MBCMP. Now DeVeDe
+should be as fast as Mencoder with default options.
+
+
+
Why can't I use a VFAT/FAT32 partition to create my DVDs?
+
VFAT and FAT32 file systems doesn't understand uppercase/lowercase letters, and shows everything in
+lowercase. Unfortunately, the creation of a DVD tree is case sensitive.
+
+
+
+DeVeDe does not start in windows
+
First you need python 2.5. Then you have to make sure you have gtk for windows installed. It is more easy
+to get the Gtk+/Win32 Development Environment (runtime, devel, docs, glade) version. Then you need pygtk.
+Now you need to install python 2.5 extension pywin32. Any of the needed programs such as mplayer that are
+not already installed should now be automatically installed next time you run mplayer. Or you can wait for
+a win32 installer to be made (any voluteers in the room?).
+
+
+
+I adjust the bitrate to use the 100%, but the final size is smaller.
+
Unfortunately is impossible to accurately predict the disk's final size, because you specify a bitrate, but
+Mencoder can decide to use an smaller value in certain parts if it can compress it more without quality loss
+(like in very static scenes). That means that the final size can be smaller than the estimation made by DeVeDe,
+but never bigger.
+
+
+
+What about using VRC_MINRATE to ensure that the final size is mucho more acurate?
+
I added that option in DeVeDe 3.7; unfortunately the result was that, in a lot of cases, the final size was
+bigger than the predicted size, so I removed it in version 3.9.
+
+
+
+When I add empty titles, the disk usage grows. Why?
+
Each menu can hold up to 10 titles. If you create more titles DeVeDe will need more menus, and
+each one needs some disk space.
+
+
+
+What kind of disk is CVD?
+
It stands for China Video Disk. It's an alternative format to SuperVCD, using a resolution of 352x480 (or
+352x576 in PAL), which can result in better image quality in some players, because the widht and height are
+compatible with DVD standard (SuperVCD uses a width of 480 pixels, which can result in some picture artifacts
+in some players).
+
+
+
+In some fast scenes the picture is jerky. I use bigger bitrates but it doesn't work. How can I fix it?
+
Try to deinterlace your video. You can find the deinterlace options in the Properties window for
+that file, expanding the Advanced options and choosing the Quality tab.
+
+
+
+Fine, but... what is the better deinterlacing filter?
+
That's a good question. In guru-multimedia
+you can find a comparison. The YADIF in DeVeDe is "yadif=0", without adding "mcdeint".
+
+
+
+Why I can't add more than 61 files in a DVD?
+
Because the DVD standard allows to put up to 128 commands in each menu. The current menu system needs two
+commands for each file, and six extra commands, which leaves only 61 files.
+
The limit for VCDs, sVCDs and CVDs is 99 files.
+
+
+
+
+
Subtitles
+
+
+
+
I preview a video with subtitles and the text looks bad (text colors are inverted)
+
Don't worry, it's a bug of MPlayer when showing DVD subtitles from a file instead of a true DVD.
+In the final disk they will look fine.
+
+
+
I preview a video with subtitles, but it doesn't show the subtitles...
+
Some Mplayer/Mencoder versions seems to fail to show the subtitles when you watch an MPEG file from
+hard disk, but they are there. SVN versions seems to have this fixed.
+
+
I dislike the font used to render the subtitles. How can I change it?
+
Just choose a TrueType font you like and copy it in $HOME/.spumux directory, renaming it to
+devedesans.ttf.
+
+
+
I tried to create a DivX file with subtitles, but in the tab it says it's not possible. How can
+I add subtitles to a DivX?
+
DivX format doesn't allow embedded subtitles, but nearly all software players (MPlayer, VLC...) and a
+lot of hardware players can render them on-demand if you put the file with the subtitles in the same
+directory than the movie, and rename the former with the same name than the later (this is, if your movie
+file is MYMOVIE.AVI and your subtitles are in .SRT format, just put the subtitles file in the same directory
+and rename it to MYMOVIE.SRT). The player should allow you to enable/disable them with the
+same button used for DVD subtitles.
+
+
+
+
+
Menus
+
+
+
+
How can I add a menu to a VCD/SVCD/CVD?
+
Currently you can't with DeVeDe.
+
+
+
The menus created by DeVeDe are simplistic. Will you add a menu editor to allow to create more
+complex menues?
+
Probably not. My intention is to maintain DeVeDe as an easy-to-use tool. If you want to create complex
+menues you have excellent tools like DVD Styler,
+Q DVD Author or
+PoliDori.
+
+
+
+In older versions I was able to create a DVD without a menu. How can I do it now?
+
Creating a DVD without a menu results in some compatibility problems with the new title/chapter system,
+so now DeVeDe always creates one. But you can go to the menu options and select Jump to the first title at
+startup, so the DVD will start playing the first title, and will only show the menu when it ends, or when
+the user presses the MENU key in the DVD player's remote.
+
+
+
+
+
Bugs
+
+
+
+
+When I click on the Properties button to change a film's properties, sometimes the button with the
+filename is empty, so I can't change them, but sometimes it works fine.
+
There's a bug in GTK 2.12.0 (the one used in Ubuntu 7.10) that produces that behaviour. I already reported it,
+but developers need time to fix it. Until then, there's only one workaround: pressing cancel and clicking again
+the Properties button, until the filename appears in the filebutton. The same if you use Drag&Drop.
+
+
+
I tried to create a disk but the sound is pure noise.
+
Version 1.0-rc1 of MPlayer/Mencoder (the one released, at least at April 20, 2007 with Ubuntu Feisty
+and other Linux distributions) is buggy and doesn't work fine. While they don't launch a fixed release,
+just download the file mplayer_fixed from DeVeDe's homepage and follow the instructions there. Or,
+if you are brave and experimented, you can compile MPlayer/Mencoder from SVN.
+
Update (21 Nov. 2007): Mplayer/Mencoder 1.0 RC2 is out and fixes this bug. You can find .deb packages
+in the GUTSY-BACKPORTS repository.
+
+
+
I created a DVD and my DVD player is unable to play it, but other players can.
+
Go to Advanced options->Misc, and be sure that you have marked the option Use a GOP of 12
+frames.
+
+
+
+I created a DVD from Ubuntu 8.04, but it doesn't play under WinXP: it doesn't show the folders AUDIO_TS nor
+VIDEO_TS.
+
Unfortunately it's a known bug.
+Since DeVeDe uses MKISOFS (which is an alias to GENISOIMAGE), it's susceptible to this bug. As it says
+the people at the forum, there are two ways of fixing it:
+
+
Uninstalling GENISOIMAGE package and compiling the last version from source code.
+
Or installing the GENISOIMAGE package from Feisty (which is version 1.1.2).
+
+
This bug can prevent the discs from playing in some commercial players too.
+
+
+
I created a 5.1 DVD marking the Create DVD with 5.1 channel sound option, but the channels are
+out of order.
+
If your source video file has AC3 audio, use the This file already has AC3 sound instead.
+
+
+
DeVeDe fails to create watchable videos, or makes a 0-byte ISO file
+
Be sure that you are using the last version of MPlayer/Mencoder (at least 1.0Pre8, but later is better).
+The very common version 1.0Pre7 has some bugs that can lead to problems with DeVeDe. But warning with
+version 1.0-rc1.
+
+
+
I receive an error when I try to create a DIVX/MPEG4 file
+
Be sure that your MPlayer/Mencoder version is compiled with MP3lame support. The creation of DIVX files
+needs it.
+
+
DeVeDe still fails. How can I report a bug?
+
You can ask everything you need in the DeVeDe Forum, at http://groups.google.com/group/devede-forum/
+
If asked for a dump of DeVeDe's output, just open a terminal, launch DeVeDe with this command:
+
devede_debug
+
and create again the disc. When it fails (or when it fully ends), take the file DEVEDE.DEBUG, which will be
+created in your HOME directory, and send it to the forum.
To add a new file you have two options: first, you can drag and drop one or more files into the main
+window, so DeVeDe will give them some fine default values; or you can choose the "Add" button, so you will see
+this window:
+
+
+
+
First you choose the file you want to add (you can do it by drag and drop in this window too). After
+doing it, you can see its properties at the File info block. You can then choose the format (PAL or
+NTSC) and, if the movie has more than one audio track (like several languages), you can choose which
+one you want to use.
+
+
Maybe you ask why is here another PAL/NTSC option, when we already have chosen it in the main window.
+The answer is: because this way you can create hybrid DVDs, with some films in PAL/SECAM format and
+others in NTSC. What is the utility of this? Simply: modern TV sets and DVD players can play both formats,
+so if you manually choose the one that fits better the original framerate of the file, you will have an
+smoother video. This is: if the original file has 25 fps, select PAL, and if it has 24 or 30 fps, select
+NTSC (the telecine option seems to work better with NTSC). Of course you can
+force one of them and DeVeDe will adjust the framerate to 25 or 30 fps, ensuring that the DVD will have
+the rigth framerate and will play fine in all TV sets, but maybe the motion won't be not as smooth as it could
+be.
+
+
Then you can choose the audio track to use (currently DeVeDe can set only one audio track per movie), and
+adjust its volume if it is too low or too loud.
+
+
If you are creating a VCD, sVCD or CVD, you can choose if you want to put the whole file, or only the first
+or the second half. This is specially usefull when creating VCDs: you can cut a long film in two disks if it's
+too long to fit in a single disk. But if the length of the film is less than 60 seconds, you won't be able to
+choose them.
+
+
Remember that this option is applied to each file, so if you put two files in a xCD and choose in
+both the first half, you will have a xCD with the first half of the first file followed by the first half
+of the second file.
+
+
Finally, you can add up to 32 subtitle files, each one with one language. You can use the Add button
+or just drag&drop a file with subtitles (DeVeDe will check if the extension is .sub, .srt, .ssa, .smi, .txt,
+.aqt, .jss or .ass). These will be true DVD subtitles, in the sense that you can enable or disable
+them, and choose the language you want. When you do that, DeVeDe will show you this window:
+
+
+
+
In File you can choose the file with the subtitles. If you are using subtitle files coded with a
+codepage different than ISO-8859-1 (or pure ASCII) you will have to choose the right Codepage (UTF-8 is
+twice in the list to make it easier to find). DeVeDe tries to detect if the file is pure ASCII, UTF-8 or
+UTF-16; in case it's unable to do so, it will set the last format selected.
+
+
You must choose the language too. This allows the DVD player to show the language code when you enable
+the subtitles.
+
+
Finally, the option "Put subtitles upper" makes DeVeDe to render the subtitles a little upper that normally.
+This is fine when you have a 16:9 film in 3:4 format (with black bars up and down) and want to use the ZOOM
+option in your TV without loosing the subtitles, or when your TV is old and misses too many lines in bottom and
+cuts the ordinary subtitles.
+
+
You can also change the font size for subtitles if you think that the default 28 points are too small or large.
+
+
Have in mind that if you preview a video from DeVeDe with subtitles, they will be shown in order to allow
+you to ensure that the sincronization is fine (needs MPlayer 1.0rc1 or later, and not always works :( ).
+
+
Currently you can't add subtitles when creating DIVX files, so this block will be unavailable in that mode.
+But if you put the subtitles in the same directory than your DIVX file, usually the player should show them.
+Read the FAQ for details.
+
+
There's a Preview button that converts some seconds (you can choose how many), allowing you to
+check the audio/video quality and the audio sync. It will create the temporary file by default at
+/var/tmp, but you can choose other place if you preffer.
+
+
Finally there's an expansor named Advanced options. If you expand it, you will see that there are
+six tabs with new options, not needed normally but which can give much more control to advanced users:
+
+
+
+
In the General tab you can manually adjust the audio and video bitrate, if you are unhappy with
+the values assigned by the Adjust disk usage button. You can choose if you want to split each file
+in several chapters and its lenght too. This allows to jump forward in the movie and select scenes.
+
+
+
+
In the Video format tab you can choose the final resolution for this video and the aspect ratio (this
+is, if you want a classic, or a widescreen video). A bigger resolution will give you
+sharper pictures, but will need more bitrate to avoid the horrible MPEG artifacs. If you choose Default,
+DeVeDe will choose automagically the best resolution, based in the original video resolution and the disk
+format you wanted. For Video DVD, DeVeDe will use resolutions of 352x288 for PAL/SECAM, or 352x240 for NTSC, if the video's
+resolution is smaller or equal than that. If not, it will jump to 352x480 (NTSC) or 352x576 (PAL) if this
+way the video fits. If not, it will use 720x576 for PAL/SECAM or 720x480 for NTSC. For VCD, SuperVCD or CVD,
+DeVeDe will use, as default, the standard resolution of each format. Finally, for DivX, it will use the same resolution
+and aspect ratio than the original. Remember that you should click again
+the Adjust disk usage button after changing the final resolution, adding or removing subtitles or, in general,
+after doing any modification in these parameters, in order to assign a good video bit rate to each film.
+
+
Have in mind that the DVD standard only allows to create a 16:9 DVD with a width of 720 pixels, so
+if you activate this option, DeVeDe will ensure that the final width will be 720. For the same reason, if
+you choose a different width, the 16:9 option will be deactivated. This is not true for DivX files.
+
+
You can create 16:9 DVDs and DivX, but not 16:9 VCDs, SVCDs or CVDs because the formats don't allow it.
+
+
+
+
If you are creating a DivX file, you will be able to choose High Definition (1920x1080 and 1280x720) and
+Mobile Devices (160x128) resolutions too, as you can see in the above picture, but you have to do it manually.
+
+
+
+
In the Video options tab you have:
+
+
Rotation: allows you to rotate the video before converting. Useful when you filmed something with
+the camera rotated (example: movies filmed with the mobil phone).
+
+
Mirror: allows to flip horizontally or vertically the video.
+
+
Field order: when you have an interlaced video (like video from a DV camera), and the field order is incorrect,
+you can change it just by checking this option.
+
+
Scaling mode: here you can choose the expand method to use when the aspect ratio of the original file is not 4/3.
+The first method is the preferred, and consists in adding the classic black bars up and down. It has the
+advantage of maintain the aspect ratio, so the faces will look natural. The alternative method consists
+in expand the film, so the faces will look enlarged. Of course, if you have a 16:9 TV you can put it to
+Full Screen, and enjoy a full-resolution panoramic film.
+
+
+
+
+
In the Quality tab you have:
+
+
+
+
MacroBlock decision algorithm: allows to choose the MBD algorithm, so you can choose to
+have better quality at the cost of slower conversion.
+
+
Use Trellis Searched Quantization: this option makes Mencoder to find the optimal encoding for each
+8x8 block, giving more video quality at the cost of a little slower conversion.
+
+
Two pass encoding: when marked, it will do a two-pass encoding of this movie. This gives much better quality
+at the cost of being slower. Marking Turbo 1st pass will make it slightly faster.
+
+
Deinterlacing: allows to apply a deinterlace algorithm to the video. Useful when creating
+a DVD from a TV program or TV camera. You have five different algoritms to choose.
+
+
+
+
+
In the Audio tab you will find:
+
+
Audio delay: it's used to adjust the audio/video sync, allowing to fix videos with audio out
+of sync. You can set positive or negative values.
+
+
Create DVD with 5.1 channel sound: checking this will send to MENCODER the parameter -channels 6, so,
+if the source file has 5.1 sound, it will be preserved. But depending on the Mencoder version, is possible that the
+audio channels will be misordered.
+
+
This file already has AC3 sound: checking this will copy the audio tracks instead of recompressing them. This
+way, if the source file has a 5.1 sound track, it will be copied "as is", maintaining all the quality and the channel
+order (of course, if the original movie has 5.1 sound, the converted movie will have it too). If your file has AC3
+sound is better to use this option instead of Create DVD with 5.1 channel sound.
+
+
+
+
In the Misc tab you have:
+
+
+
+
This file is already a DVD/xCD-suitable MPEG-PS file option.
+When active, nearly all options will became insensitive because DeVeDe will not recompress that file, but
+will use it directly when creating the DVD/xCD structure. This option is usefull when you have some
+already-compressed files (Eg. when you capture a TV signal and store it directly in MPEG2-PS format), because
+you will not need to wait the conversion time. Of course, you can mix MPEG-PS and non-MPEG-PS files in the
+same disc, because DeVeDe will recompress the non-MPEG-PS files, and use directly the MPEG-PS ones.
+
+
Repack audio and video without reencoding: this option is useful when you have MPEG2 video and MP2 audio
+in a container different than MPEG-PS (like a VOB file, or an MPEG2 video in an AVI container). When active, it
+extracts the video and audio without uncompressing and recompressing it, and stores them unchanged in a MPEG-PS container,
+as needed for a DVD, allowing to use these files without quality loss.
+
+
Use a GOP of 12 frames: if thischeckbox is active, DeVeDe will use 12-frame GOPs. Althoug the standard
+allows for up to 15-frame GOPs for PAL or up to 18-frame GOPs for NTSC, some DVD players dislikes GOPs bigger
+than 12. If you have problems to play DVDs created with the default option, check this.
+
+
Extra parameters for Mencoder: allows you to add extra parameters to Mencoder, allowing
+you to add hardcoded subtitles, set picture quality, and much more. Is divided in three parts:
+
+
Main: here you can add "classic" parameters to Mencoder, like -sub (to hard-render
+subtitles in the file). Each parameter is prepended with a dash, and uses blank space as separator. Remember
+to use '\ ' to put blank spaces. An example: -sub /home/raster/holidays\ at\ galicia.sub will hard
+render the subtitles from the file "holidays at galicia.sub".
+
-VF: allows to add extra sub-parameters in the -vf parameter. Parameters uses comma as separator.
+
-LAVCOPTS: allows to add extra sub-parameters in the -lavcopts parameter. Parameters uses colon as
+separator.
+
+
+
\ No newline at end of file
diff --git a/docs/html/gpl.html b/docs/html/gpl.html
new file mode 100644
index 0000000..3de8835
--- /dev/null
+++ b/docs/html/gpl.html
@@ -0,0 +1,694 @@
+
+
+
+GNU General Public License - GNU Project - Free Software Foundation (FSF)
+
+
+
Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
Preamble
+
+
The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+
The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+
When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+
To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+
For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+
Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+
For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+
Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+
Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+
The precise terms and conditions for copying, distribution and
+modification follow.
+
+
TERMS AND CONDITIONS
+
+
0. Definitions.
+
+
“This License” refers to version 3 of the GNU General Public License.
+
+
“Copyright” also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+
“The Program” refers to any copyrightable work licensed under this
+License. Each licensee is addressed as “you”. “Licensees” and
+“recipients” may be individuals or organizations.
+
+
To “modify” a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a “modified version” of the
+earlier work or a work “based on” the earlier work.
+
+
A “covered work” means either the unmodified Program or a work based
+on the Program.
+
+
To “propagate” a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+
To “convey” a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+
An interactive user interface displays “Appropriate Legal Notices”
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+
1. Source Code.
+
+
The “source code” for a work means the preferred form of the work
+for making modifications to it. “Object code” means any non-source
+form of a work.
+
+
A “Standard Interface” means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+
The “System Libraries” of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+“Major Component”, in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+
The “Corresponding Source” for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+
The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+
The Corresponding Source for a work in source code form is that
+same work.
+
+
2. Basic Permissions.
+
+
All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+
You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+
Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+
No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+
When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+
4. Conveying Verbatim Copies.
+
+
You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+
You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+
5. Conveying Modified Source Versions.
+
+
You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+
+
a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+
b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ “keep intact all notices”.
+
+
c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+
d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+
+
A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+“aggregate” if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+
6. Conveying Non-Source Forms.
+
+
You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+
+
a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+
b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+
c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+
d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+
e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+
+
A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+
A “User Product” is either (1) a “consumer product”, which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, “normally used” refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+
“Installation Information” for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+
If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+
The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+
Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+
7. Additional Terms.
+
+
“Additional permissions” are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+
When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+
Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+
+
a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+
b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+
c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+
d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+
e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+
f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+
+
All other non-permissive additional terms are considered “further
+restrictions” within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+
If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+
Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+
8. Termination.
+
+
You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+
However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+
Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+
Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+
9. Acceptance Not Required for Having Copies.
+
+
You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+
10. Automatic Licensing of Downstream Recipients.
+
+
Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+
An “entity transaction” is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+
You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+
11. Patents.
+
+
A “contributor” is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's “contributor version”.
+
+
A contributor's “essential patent claims” are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, “control” includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+
Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+
In the following three paragraphs, a “patent license” is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To “grant” such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+
If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. “Knowingly relying” means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+
If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+
A patent license is “discriminatory” if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+
Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+
12. No Surrender of Others' Freedom.
+
+
If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+
13. Use with the GNU Affero General Public License.
+
+
Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+
14. Revised Versions of this License.
+
+
The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+
Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License “or any later version” applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+
If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+
Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+
15. Disclaimer of Warranty.
+
+
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+
16. Limitation of Liability.
+
+
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+
17. Interpretation of Sections 15 and 16.
+
+
If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+
END OF TERMS AND CONDITIONS
+
+
How to Apply These Terms to Your New Programs
+
+
If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+
To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the “copyright” line and a pointer to where the full notice is found.
+
+
<one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+
+
+
Also add information on how to contact you by electronic and paper mail.
+
+
If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+
<program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+
+
The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an “about box”.
+
+
You should also get your employer (if you work as a programmer) or school,
+if any, to sign a “copyright disclaimer” for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+
The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+
+
+
\ No newline at end of file
diff --git a/docs/html/index.html b/docs/html/index.html
new file mode 100644
index 0000000..80c25df
--- /dev/null
+++ b/docs/html/index.html
@@ -0,0 +1,33 @@
+
+
+
+
+DeVeDe, a video DVD creator
+
+
+
DeVeDe, a video DVD creator
+
Current version: 3.16.9
+
What is it?
+
DeVeDe is a program that allows you to create a video DVD from an MPEG, AVI, MOV... video file,
+suitable for home DVD players. DeVeDe uses Mplayer, Mencoder, DVDAuthor and
+VCDimager, so you can use any video playable with Mplayer.
+
+
DISCLAIMER
+This software is distributed as is, under the GPL license (version 3 or later), and
+without warranty of any kind. Use it at your own risk. Press here to read the
+GPLv3 license.
+
+
+
+
diff --git a/docs/html/index.html~ b/docs/html/index.html~
new file mode 100644
index 0000000..658a5c5
--- /dev/null
+++ b/docs/html/index.html~
@@ -0,0 +1,33 @@
+
+
+
+
+DeVeDe, a video DVD creator
+
+
+
DeVeDe, a video DVD creator
+
Current version: 3.16.8
+
What is it?
+
DeVeDe is a program that allows you to create a video DVD from an MPEG, AVI, MOV... video file,
+suitable for home DVD players. DeVeDe uses Mplayer, Mencoder, DVDAuthor and
+VCDimager, so you can use any video playable with Mplayer.
+
+
DISCLAIMER
+This software is distributed as is, under the GPL license (version 3 or later), and
+without warranty of any kind. Use it at your own risk. Press here to read the
+GPLv3 license.
+
+
To install DeVeDe, first you must ensure you have Mplayer, Mencoder, DVDAuthor,
+VCDimager and mkisofs or genisoimage in your system. You need Python 2.4 or later, PyGTK and
+PyGlade too. Then, just run the install.sh script as root:
+
sudo ./install.sh
+
+
It will copy all the files at the right place. It should even create an entry in your
+Gnome/KDE/freedesktop-compatible-windowmanager menu.
+
+
For advanced users, there are some extra paremeters that you can pass to the install.sh script (thanks to
+Patrick Monnerat). These are the --targeted=(yes/no), --uninstall=(yes/no), and the more common
+ones (--DESTDIR=..., --prefix=...).
+
+
The --targeted parameter means that you want to install DeVeDe in a directory different than /usr/local.
+If you put it to yes you must use --DESTDIR= and --prefix= at least to specify where to
+store the files.
+
+
The --uninstall parameter was a need due to a mistake in the first versions of DeVeDe. Up to version
+2.8, the install.sh script installed DeVeDe in /usr, but starting from version 2.9 it used /usr/local.
+To avoid problems when an user updates from a version lower than 2.9 to a higher one, by default the install.sh
+script first uninstall DeVeDe from all possible locations (/usr and /usr/local), and then proceed with the
+installation itself. This is a good effect until you want to create a .deb or .rpm package. In this case, just
+add the --uninstall=no parameter and the install.sh script will only do the install process,
+skipping the previous uninstall.
+
+
So if you are a package developer, you should use a command line like:
If you want to install DeVeDe from a DEB package, you must ensure that any previous version installed from
+a TAR.BZ2 package has been removed. You can do that with the uninstall.sh script available in the TAR.BZ2
+package. But you don't need to uninstall previous versions installed from a DEB package.
After choosing the kind of disk you want, you will see the main interface:
+
+
Main interface for DVD discs
+
+
A DVD is divided in Titles and Files. Each title is a film on its own, and,
+when played, you have to choose the one you want to see. Into each title you can add as many files as
+you want, and cut them in chapters to allow an easy search. But remember that a DVD can contain up to 61 files,
+and a VideoCD, SuperVCD or CVD up to 99 files.
+
+
Main interface for VCD/SVCD/CVD discs
+
+
In VideoCDs, Super VideoCDs and CVDs there's no title concept, so that frame won't be visible when you
+choose to create one of them.
+
+
Main window properties
+
+
In the DVD window screenshot we can see that there are two titles, and title two has two files.
+The files in a title will be played one after another, like a single film. So if you only want to
+create a DVD with one single film from multiple files, you have to put all of them in a single title. Your
+player will merge all in a single film.
+
+
The File info box contains all the information about the selected file: the final audio an video
+rate, original and final size, FPS and length in seconds. It has the estimated size in Mbytes, but have in mind
+that is an estimation, so the final size can be lower (but never higher).
+
+
The Disk usage bar shows the percentage of the disk currently used. You can occupy more than the
+100% because it's based in an estimation, so the final size can (and probably will) be lower than the
+espected, but never higher (see the FAQ for details). You can choose the CD/DVD size too.
+Have in mind another thing: a 700MB CD can contain 80 minutes of compressed audio/video, which, at 1152 kbps are
+about 800MB. This means that, when the media is a CD, you MUST use the bar to know how many disc space you are
+using, and not the estimated size of the files, because you can put up to 800MB of compressed video in a 700MB
+CD, or about 720MB in a 650MB CD.
+
+
Under the bar is the Adjust disk usage button. Clicking on it will adjust the video rate in each video
+in order to use the 100% of the disk. To do so, DeVeDe takes in account the final resolution and the length,
+giving more bits per second to the videos with a higher resolution, but always in a proportional way. Remember
+that you should always click again the Adjust disk usage button after changing the final resolution,
+adding or removing subtitles, adding or removing titles, or, in general, before creating your disk,
+in order to assign a good video bit rate to each film. Remember that changing the soundtrack used in the menus
+will change the disk usage too.
+
+
The Default format sets the format used by default in your disk. It's used to create the menus
+and each time you add a video file. But, as we will see in a moment, you can use a different format in some
+videos if you want, having PAL and NTSC videos mixed in the same disk.
+
+
The Preview menu button allows you to see how will be the DVD menus. If you dislike it, you can
+change their properties (background picture, text colors, title...) with the Menu properties button. This will be
+explained with more detail in the section Creating the DVD menu. You can choose if you
+want or not a menu in your disk checking or unchecking the Create a menu with the titles checkbox.
+
+
Finally, there is an expander which hiddes the advanced options. If you expand it, you will see this:
+
+
Main interface for DVD discs with advanced
+options expanded.
+
+
Here, the Action block allows you to choose what do you want to create. The first option,Only
+convert film files to compliant MPEG files takes each file and converts it to a DVD-compliant MPEG-PS
+file, or to VCD, SVCD or CVD-compliant MPEG-PS. You can choose a generic name, being the default name "movie",
+so the files will have names like movie_XX_YY.mpg, being XX the title, and YY the file position
+into the title. An example: if you have two titles, and two files in the first title and three files at
+the second title, you will get five files: movie_01_01.mpg, movie_01_02.mpg, movie_02_01.mpg,
+movie_02_02.mpg and movie_02_03.mpg. This option is specially usefull when you want to create DVD menus
+with other program like DVD Styler,
+Q DVD Author or
+PoliDori. Of course, with VCD, SVCD or CVD, the title
+number will be always "01".
+
+
The second option, Create disk structure, is visible only when you create a DVD. It creates the
+MPEG files and then uses DVDAuthor to create the DVD tree structure. After that, it erases the MPEG files (unless
+you unckeck the Erase temporary files button). You can use this option to create the folder and files
+for a DVD and use your own DVD recording program to create the ISO image and burn it into a DVD.
+
+
The third option, (second if you are creating a VCD, SVCD or CVD), Create an ISO or BIN/CUE image,
+ready to burn to a disk, converts the files to MPEG, creates the DVD tree if needed and, using
+MKISOFS, creates the ISO file, erasing then the MPEG and DVD tree to free disk space. With CD media,
+it converts the files to MPEG and uses VCDImager to create a BIN/CUE image, ready to be burned
+to a CD. Use this option to create a disk image ready to be burned to a CD/DVD with a program like
+GnomeBaker or K3b, or directly
+from the Gnome Desktop.
+
+
These options will be unavailable when creating DIVX files, because there you will create only files, not
+disk images.
+
+
The next block, options, starts with Erase temporary files, which allows to choose if you want
+DeVeDe to erase the temporary files as soon as they are needed no more. Selecting it, DeVeDe will need
+only about twice the final disk space, but if you don't mark it, you will need about three times the final
+disk space, but you will have all the temporary files to analize them.
+
The next option, Use optimizations for multicore CPUs, when marked, makes Mencoder to use several
+threads to convert the videos, thus getting advantage of multicore CPUs to run faster.
DeVeDe allows to add a menu to the video DVDs. This menu will allow to jump to each title. Here you can see
+the default menu, with two titles:
+
+
+
+
If you click the Menu options button in the main window, you will see this:
+
+
+
+
The first block allows you to add a title to your menu. This title will be shown at the upper part of the menu,
+always centered. You can choose the font type and color, and you can add a shadow under it with the color
+you want. You can freely choose the font size too, because the title will never touch the menu entries.
+
+
When choosing a color you can set the transparency level using the Opacity option. If this value is
+set to 0, that color will be fully transparent, so the element with that color will be invisible. If this value
+is 255, that color will be fully opaque. With other values the element will be semitransparent, allowing to
+"see through" it. An example: if you don't want DeVeDe to add the black background rectangles under each title,
+just set its opacity to 0, rendering it invisible.
+
+
When the opacity is set to 0, that color
+is transparent, so the element rendered with it will be invisible.
+
+
The second block allows you to change the background picture. This way you can create a custom menu
+for your DVD. You can use all picture formats supported by Gnome. Clicking the Set default background will
+set again the default picture used by DeVeDe: a white background with a DVD disk.
+
+
The third block allows to choose a sound file to use as soundtrack for the menu. By default the menus use
+a file with 38 seconds of pure silence, but you can change it, having this way menus with music. Again, the
+Set menus without sound button will restore the original silence file.
+
+
The next block allows you to choose the alignment. You can put the list of titles in the top, middle or bottom
+of the screen; you can also choose to put them left, center or right aligned too.
+
+
In the next block allows you to change the font style and size, and the colors used to render the inactive
+text, the active text, the text background color and the shadow color. Again you can use transparency, in order to
+remove the elements you don't want.
+
+
+
+
Here you must be carefull: you can only change the font size, not the button size, so if you make it too big,
+you will have a menu like this:
+
+
You must be carefull with the font size, or
+you will get incorrect results like this.
+
+
The optimal font size is 12 points, but maybe for some special fonts it can be different, so always
+use the Preview menu button to ensure that everything has the desired size.
+
+
Finally the last block allows to decide if you want the menu to be shown when you put the disk in the
+player, or only when you press the Menu button in the remote. In the later case, when the disk is inserted
+it starts to play the first title.
+
+
Let's see an example. Let's create a menu with the following options:
+
+
+
+
Here we set the background color to fully transparent, added yellow shadows to the titles list, and set a
+red ink with a black shadow to the title. We also moved the menu to the left. The result is here:
+
+
\ No newline at end of file
diff --git a/docs/html/menu.jpg b/docs/html/menu.jpg
new file mode 100644
index 0000000..e34e693
Binary files /dev/null and b/docs/html/menu.jpg differ
diff --git a/docs/html/menu2.jpg b/docs/html/menu2.jpg
new file mode 100644
index 0000000..e12c512
Binary files /dev/null and b/docs/html/menu2.jpg differ
diff --git a/docs/html/menu_bad.jpg b/docs/html/menu_bad.jpg
new file mode 100644
index 0000000..1c28c2f
Binary files /dev/null and b/docs/html/menu_bad.jpg differ
diff --git a/docs/html/menu_example.jpg b/docs/html/menu_example.jpg
new file mode 100644
index 0000000..2d1e903
Binary files /dev/null and b/docs/html/menu_example.jpg differ
diff --git a/docs/html/menu_opts.jpg b/docs/html/menu_opts.jpg
new file mode 100644
index 0000000..5146683
Binary files /dev/null and b/docs/html/menu_opts.jpg differ
diff --git a/docs/html/menu_opts2.jpg b/docs/html/menu_opts2.jpg
new file mode 100644
index 0000000..6ddacae
Binary files /dev/null and b/docs/html/menu_opts2.jpg differ
diff --git a/docs/html/menu_trans.jpg b/docs/html/menu_trans.jpg
new file mode 100644
index 0000000..d6b2cda
Binary files /dev/null and b/docs/html/menu_trans.jpg differ
diff --git a/docs/html/movie1.jpg b/docs/html/movie1.jpg
new file mode 100644
index 0000000..9e1c9ec
Binary files /dev/null and b/docs/html/movie1.jpg differ
diff --git a/docs/html/movie2.jpg b/docs/html/movie2.jpg
new file mode 100644
index 0000000..a776450
Binary files /dev/null and b/docs/html/movie2.jpg differ
diff --git a/docs/html/movie3.jpg b/docs/html/movie3.jpg
new file mode 100644
index 0000000..e0c2504
Binary files /dev/null and b/docs/html/movie3.jpg differ
diff --git a/docs/html/movie3b.jpg b/docs/html/movie3b.jpg
new file mode 100644
index 0000000..99d7099
Binary files /dev/null and b/docs/html/movie3b.jpg differ
diff --git a/docs/html/movie4.jpg b/docs/html/movie4.jpg
new file mode 100644
index 0000000..61679bc
Binary files /dev/null and b/docs/html/movie4.jpg differ
diff --git a/docs/html/movie5.jpg b/docs/html/movie5.jpg
new file mode 100644
index 0000000..394471a
Binary files /dev/null and b/docs/html/movie5.jpg differ
diff --git a/docs/html/movie6.jpg b/docs/html/movie6.jpg
new file mode 100644
index 0000000..e2fbbdb
Binary files /dev/null and b/docs/html/movie6.jpg differ
diff --git a/docs/html/movie7.jpg b/docs/html/movie7.jpg
new file mode 100644
index 0000000..fa77308
Binary files /dev/null and b/docs/html/movie7.jpg differ
diff --git a/docs/html/psf.html b/docs/html/psf.html
new file mode 100644
index 0000000..4cfea6f
--- /dev/null
+++ b/docs/html/psf.html
@@ -0,0 +1,281 @@
+
+
+
+
+
+
+This is the official license for the Python 2.5 release:
+
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC. Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team. In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation, see http://www.zope.com). In 2001, the Python Software
+Foundation (PSF, see http://www.python.org/psf/) was formed, a
+non-profit organization created specifically to own Python-related
+Intellectual Property. Zope Corporation is a sponsoring member of
+the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition). Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+ Release Derived Year Owner GPL-
+ from compatible? (1)
+
+ 0.9.0 thru 1.2 1991-1995 CWI yes
+ 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
+ 1.6 1.5.2 2000 CNRI no
+ 2.0 1.6 2000 BeOpen.com no
+ 1.6.1 1.6 2001 CNRI yes (2)
+ 2.1 2.0+1.6.1 2001 PSF no
+ 2.0.1 2.0+1.6.1 2001 PSF yes
+ 2.1.1 2.1+2.0.1 2001 PSF yes
+ 2.2 2.1.1 2001 PSF yes
+ 2.1.2 2.1.1 2002 PSF yes
+ 2.1.3 2.1.2 2002 PSF yes
+ 2.2.1 2.2 2002 PSF yes
+ 2.2.2 2.2.1 2002 PSF yes
+ 2.2.3 2.2.2 2003 PSF yes
+ 2.3 2.2.2 2002-2003 PSF yes
+ 2.3.1 2.3 2002-2003 PSF yes
+ 2.3.2 2.3.1 2002-2003 PSF yes
+ 2.3.3 2.3.2 2002-2003 PSF yes
+ 2.3.4 2.3.3 2004 PSF yes
+ 2.3.5 2.3.4 2005 PSF yes
+ 2.4 2.3 2004 PSF yes
+ 2.4.1 2.4 2005 PSF yes
+ 2.4.2 2.4.1 2005 PSF yes
+ 2.4.3 2.4.2 2006 PSF yes
+ 2.5 2.4 2006 PSF yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+ the GPL. All Python licenses, unlike the GPL, let you distribute
+ a modified version without making your changes open source. The
+ GPL-compatible licenses make it possible to combine Python with
+ other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+ because its license has a choice of law clause. According to
+ CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+ is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python
+alone or in any derivative version, provided, however, that PSF's
+License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights
+Reserved" are retained in Python alone or in any derivative version
+prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee. This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions. Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee. This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party. As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee. Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement. This Agreement together with
+Python 1.6.1 may be located on the Internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013. This
+Agreement may also be obtained from a proxy server on the Internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee. This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+ ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands. All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+
+
diff --git a/docs/html/select.html b/docs/html/select.html
new file mode 100644
index 0000000..68771f0
--- /dev/null
+++ b/docs/html/select.html
@@ -0,0 +1,48 @@
+
+
+
+
+DeVeDe, a video DVD creator
+
+
+
When you launch DeVeDe, it will show you this window, asking what kind of disk you want to create.
+You can choose between:
+
+
+
+
Video DVD: a classic video DVD, like the ones you rent in your videoclub or buy in your video shop.
+
VideoCD: a CD with CBR MPEG-1 video at a resolution of 352x240 pixels (352x288 with PAL), a fixed bitrate
+of 1152 kbits/second for video and 224 kbits/second for audio. The quality is comparable to analog VHS,
+and a CD can contain as much compressed audio/video than uncompressed audio (this is, a 80-minutes CD
+can contain about 80 minutes of compressed video/audio). Is compatible with all DVD players, but video
+quality is medium-bad.
+
Super VideoCD: a CD with VBR MPEG-2 video at a resolution of 480x480 pixels (480x576 with PAL) and
+video bitrates between 500 and 2600 kbits/second. The quality is comparable to LaserDisc, and a 80-minutes CD
+can contain about 60 minutes con compressed video/audio (more if you reduce the bitrate, but with less
+quality). Is compatible with a lot of DVD players, but maybe there is one very cheap which doesn't support it.
+Video quality is good.
+
CVD (China Video Disk): identical to Super VideoCD, but with a resolution of 352x480 pixels (352x576
+with PAL). Offers less artifacts with same bitrate, but image is a bit less sharper than Super VideoCD. Is
+compatible with a lot of DVD players, but maybe there is one very cheap which doesn't support it.
+
DIVX/MPEG4: creates one-pass DIVX files, ready to be played in DIVX-compliant players.
+
+
+
Of course you aren't limited to theses options, since you can choose, if you want, another resolution
+for your CD/DVD. This allows you to create Super VideoCDs with a resolution of 352x240 (or 352x288 for PAL),
+which is a very good compromise if you want to store a lot of video in a single CD. I don't recomend to use
+other resolutions with VideoCDs, because CBR MPEG-1 is very limited. Choose the Super VideoCD or CVD option
+(which uses VBR MPEG-2) and use there the resolution you want.
+
+
+
\ No newline at end of file
diff --git a/docs/html/subs.jpg b/docs/html/subs.jpg
new file mode 100644
index 0000000..dafb5b0
Binary files /dev/null and b/docs/html/subs.jpg differ
diff --git a/docs/html/title.html b/docs/html/title.html
new file mode 100644
index 0000000..5226818
--- /dev/null
+++ b/docs/html/title.html
@@ -0,0 +1,33 @@
+
+
+
+
+DeVeDe, a video DVD creator
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/html/title_prop.jpg b/docs/html/title_prop.jpg
new file mode 100644
index 0000000..d39f73b
Binary files /dev/null and b/docs/html/title_prop.jpg differ
diff --git a/docs/html/ubuntu_9_10.png b/docs/html/ubuntu_9_10.png
new file mode 100644
index 0000000..4674967
Binary files /dev/null and b/docs/html/ubuntu_9_10.png differ
diff --git a/docs/html/versions.html b/docs/html/versions.html
new file mode 100644
index 0000000..cf4ad12
--- /dev/null
+++ b/docs/html/versions.html
@@ -0,0 +1,571 @@
+
+
+
+
+DeVeDe, a video DVD creator
+
+
+
Fixed a bug which prevented to create VCD, sVCD and CVD
+
+
+
Version 3.16.7 (2010-04-11)
+
+
Video info is updated when changing selection with arrow keys
+
Allows up to 448Kbps for audio when using AC3
+
+
+
+
Version 3.16.6 (2010-03-19)
+
+
Buttons in main window now has a border, like all other buttons
+
Desktop launcher now shows a much more HIG-compliant description
+
Pressing RETURN key in Title properties and Create disc dialogs has the same effect than the Accept button
+
+
+
Version 3.16.5 (2010-03-09)
+
+
Don't show by default the subtitles in MKV files
+
Fixed dependencies in .deb package to ensure Debian compatibility
+
+
+
+
Version 3.16.4 (2010-02-24)
+
+
Adjusts the audio bitrate to the list of legal values supported by Mencoder
+
+
+
Version 3.16.3 (2010-02-22)
+
+
Supports blank spaces in subtitles filenames
+
+
+
Version 3.16.2 (2010-02-21)
+
+
Fixed audio bitrate when using 5.1 sound
+
+
+
Version 3.16.1 (2010-02-21)
+
+
Fixed a hang when repacking MPEG files instead of reencoding them
+
Fixed Galician translation
+
+
+
Version 3.16.0 (2010-01-07)
+
+
Added support for two-pass encoding (thanks to Gustavo Sanchez)
+
Added support for 64bit Windows
+
Fixed a bug when importing old .devede files
+
Fixed a bug that prevented to manually choose the aspect ratio
+
Allows to change the final volume
+
Now remembers the last output directory used, and the last subtitle language and codepage
+
Added support for UTF-16 subtitles
+
Autodetects ASCII, UTF-8 and UTF-16 subtitles
+
Allows to remove menu
+
Check if there's a /, | or \ in the file name
+
Allows to force the subtitles by default
+
Flush stdout and stderr at end, so it should finally allow to have full debugging info
+
Several bugfixes for Windows version (thanks to Peter Gill)
+
+
+
Version 3.15.2 (2009-11-30)
+
+
Improved debugging
+
+
+
Version 3.15.1 (2009-11-29)
+
+
Fixed a bug when the program can't write the subtitle's XML file
+
Added Miguel Bouzada to the list of translators
+
+
+
Version 3.15.0 (2009-11-27)
+
+
Added -loop 1 in mplayer commands to avoid problems when the user has a mplayer.config file
+
Changed shape of the main window to better fit wide screens
+
Added support for OGG/Vorbis for menu sound
+
Added new backgrounds
+
Support for RMVB file extension
+
Preview button now can hide the icon when global preferences says it
+
When creating a DivX, if Default resolution is selected, won't touch size, nor aspect ratio, nor add bars
+
Updated translation to French
+
Updated translation to Galician
+
Translation to Tradicional Chinese
+
Support for filenames with double quotes (thanks to Christian)
+
Allows to split a film in two disks in SVCD and CVD, not only in VCD
+
+
+
Version 3.14.0 (2009-07-20)
+
+
Now doesn't add black bars when creating an NTSC disc from an 720x480 file without ASPECT RATIO parameter embedded
+
Allows to repack a file as MPEG-PS without recompress the streams (useful to work with VOB files)
+
Allows to swap the field order in interlaced videos
+
Allows to change the subtitle's font size
+
Now supports subtitle filenames with XML-reserved characters
+
Supports all picture types for menu backgrounds (not only PNG)
+
Now removes previous preview files if they already existed, when using LN
+
Fixed free disk space calcule in Windows 2000 and the SetPriority function (thanks to Peter Gill)
+
Adjusted the media sizes to ensure that the ISOs always will fit in the disc
+
Now doesn't hangs when adding a video file in an unknown format
+
+
+
Version 3.13.1 (2009-05-25)
+
+
+
Save as... option now works.
+
The Title properties window closes when the user changes the action to do when the title ends. Fixed.
+
When the $HOME/.spumux directory didn't exists, DeVeDe is unable to find the font for subtitles. Fixed.
+
Added TTF-DEJAVU-CORE package in the DEB dependencies.
+
+
+
Version 3.13.0 (2009-05-14)
+
+
+
Fixed the greek translation
+
Doesn't fail when LANG is not defined
+
Migration from LibGLADE to GtkBuilder
+
+
+
Version 3.12c (2009-01-27)
+
+
+
Updated french translation
+
Updated file Changelog.Debian
+
+
+
+
Version 3.12b (2009-01-26)
+
+
+
Fixed french translation and added italian translation
+
+
+
Version 3.12 (2009-01-25)
+
+
+
Supports pathnames with &, <, >, ' and "
+
When the user chooses a folder in the menu background, it removes the preview
+
New disc type chooser window (based on a model from Jonathan Estrella)
+
When the output path exists, it asks before deleting it
+
+
+
Version 3.11b (2008-08-27)
+
+
+
Fixed some language issues in EL, PL, SK and SV locales.
+
+
+
Version 3.11 (2008-08-24)
+
+
+
Now recovers the menu options when loading a disc structure
+
Changed the appearance to make it more eye-candy
+
Shows the menu's NTSC preview at the right size
+
Shows right the menu's title tipography
+
Added compatibility with GenISOimage
+
Better code to avoid antialiasing when creating the menu entries
+
Now limits the number of files to 61 to avoid problems with DVDAuthor
+
+
+
+
Version 3.10 (2008-08-16)
+
+
+
Now the user chooses a global format (PAL or NTSC) for videos and menus.
+
Removed the limit of 12 titles; now can create discs with up to 90 titles and/or 90 files.
+
Allows to add a title to the menu, and shadows to the menu texts.
+
Allows to put the menu texts at the right, left or center.
+
Now shows a preview of the selected picture when choosing the menu background.
+
Added YADIF deinterlace filter support.
+
Added contextual help.
+
New background picture.
+
Support for resolution of 160x128 pixels in DivX.
+
Added a preview button in the Menu options window.
+
Now hides the advanced options in the main window.
+
Fixed the bug that made the menus to be shown only one second in some players.
+
Now it always honours the PAL/NTSC menu type.
+
Now,when creating a PAL disk from a 24fps source, DeVeDe speeds up it instead of adding one frame each 24,
+obtaining a more fluid animation.
+
The silence sound file has been changed from WAV to MP3 to free some disk space.
+
Fixed a little bug when using HD resolutions for DivX.
+
Modified code to simplify adding new options to the DVD's menus.
+
+
+
Version 3.9 (2008-06-24)
+
+
Due to the use of VRC_MINRATE option, sometimes the final disk size was bigger than the predicted. Fixed.
+
Now remembers the directory from where the user added a movie file.
+
Fixed the detection of the number of cores in the system.
+
Adds the menu type (PAL or NTSC) when creating a menuless disk.
+
Uses transparent pictures for the menus, ensuring that they work fine in more players.
+
Removed CONVERT dependency (Thanks to Peter Gill).
+
+
+
Version 3.8c (2008-05-25)
+
+
Now are really fixed the translation bugs.
+
+
+
Version 3.8b (2008-05-25)
+
+
Fixed a bug in the italian translation.
+
Fixed a bug in the poland translation.
+
+
+
Version 3.8 (2008-05-25)
+
+
Automatic video bitrate adjust, to ensure that the ISO or BIN/CUE image occupies the maximum size in the disk.
+
Support for up to 32 subtitles tracks.
+
Allows to specify the subtitle's language.
+
Allows to choose the language to use when the original video contains several audio tracks.
+
Added the L5 deinterlacing filter.
+
Support for rotating and flipping the video.
+
Muticore support.
+
Allows to mix classic and widescreen videos in the same disk.
+
High Definition support in DivX.
+
Allows to Drag&Drop subtitles in the properties window, or to load a configuration
+file by Dragging&Dropping.
+
Uses a GOP of 12 frames to ensure maximum compatibility.
+
Uses the Telecine parameter to improve quality in 24fps films.
+
Adjusted the maximum bitrate for DivX.
+
Allows to add extra parameters in -lavcopts, -vf and -lameopts.
+
Now stores the status of the buttons for delete temporary files and to choose the action to do.
+
Added an icon to all windows.
+
Fixed a bug when Mplayer is compiled with --enable-color-console.
+
Allows to choose the colors and the position of the menus.
+
More elegant menu system (based on code from Mojoholder)
+
+
+
Version 3.7 (2008-04-16)
+
+
Fixed a bug when runing in a system configured with Catalan language
+
Now asks for confirmation when closing the disk type selection window
+
The final size of the ISO image is now much more accurate
+
Fixed some Win32 bugs (thanks to Peter Gill)
+
+
+
Version 3.6 (2007-12-10)
+
+
Added a safe margin 5% in the occupied size, to have in mind the size needed by disk structures (like
+directories, file info and so on).
+
Fixed a some bugs in poland translation.
+
Fixed some windows compatibility bugs.
+
+
+
Version 3.5 (2007-12-08)
+
+
Improved compatibility by using CGOP and SC_THRESOLD.
+
Now uses a GOP of 15 frames instead of 18 when creating a NTSC, 24fps disc, as dictates the standard.
+
Fixed a bug in italian translation which prevented the "Not enought disk space" message to be shown.
+
Added translation to russian and greek.
+
+
+
Version 3.4 (2007-11-21)
+
+
Allows to create DVDs with 5.1 sound
+
Allows to use a GOP of 12 frames to improve compatibility with some broken DVD players
+
Fixes a bug when creating VCD disks
+
Fixed a bug which prevented to previsualizate in DIVX mode.
+
Final code refactorization: finally the code is clean and maintenable.
+
+
+
Version 3.3 (2007-11-14)
+
+
The EXPAND parameter in Mencoder now uses always an even offset to avoid some artifacts when the offset was odd.
+
Fixed a bug when draging&dropping video files.
+
+
+
Version 3.2
+
+
Fixed a bug when using extra parameters with Mencoder
+
Fixed pt_PT translation
+
Fixed a bug with pl translation
+
+
+
Version 3.1b
+
+
+
Fixed a little bug which prevented version 3.1 to work with Python 2.4
+
+
+
Version 3.1
+
+
+
Fixed some problems under windows.
+
Now returns to the main window after creating the disk.
+
When opening the file selector, it filters the files by type, showing only the videos.
+
When using the NEW menu option to clean the disk structure and start again, it asks the disk type again.
+
Now, when loading a disk structure, if the disk type is different than the current selected,
+automatically changes to the new type.
+
Added new translations.
+
Added new icon (thanks to Jonah Naylor).
+
Second major code refactorization to improve maintenability.
+
License changed to GPL version 3.
+
+
+
Version 3.01
+
+
Added new patches for windows version.
+
Removed the use of lower priority, because it made the conversion slower.
+
Fixed a little bug when the final directory contains blank spaces.
+
Added translation to Catala, and fixed the French one.
+
+
+
Version 3.0
+
+
Allows to add a menu to the DVD with a list of the titles and a custom background picture.
+
Allows to save the current disc structure, in order to reutilize it, or continue working in other moment.
+
Allows to choose up to 448kbit/sec for audio.
+
Now asks before canceling a job.
+
A little bigger font size for subtitles.
+
When creating a DivX file, now it uses .AVI extension.
+
Fixed a bug with non-UTF8 locales.
+
Fixed a bug in the "Insuficient free space..." message. Now is shown translated.
+
Fixed a bug when erasing conflicting files and directories.
+
Fixed a bug when trying to create a DivX from a file with an original size equal to the final size.
+
Now, when the conversion fails, it doesn't show a "Success" message.
+
+
+
Version 2.13d
+
+
Fixed the german translation
+
Changed the Mplayer/Mencoder version to the one from Ubuntu Edgy, due to some bugs when creating
+PAL videos.
+
+
+
Version 2.13c
+
+
Changed the MPlayer/Mencoder files, using version 0.99Pre8.
+
+
+
+
Version 2.13b
+
+
Added a MPlayer/Mencoder package for Ubuntu Feisty users.
+
+
+
Version 2.13
+
+
+
Added creation of MPEG4/DIVX files.
+
Added swedish and slovak translations.
+
Fixed some issues with translations (thanks to Marco de Freitas).
+
+
+
+
Version 2.12
+
+
+
New and more flexibles install and uninstall scripts (thanks to Patrick Monnerat).
+
Added french translation.
+
Fixed some issues with non-UTF8 systems (thanks to Marco de Freitas).
+
+
+
Version 2.11
+
+
Allows to specify the codepage for subtitles, allowing to use UTF-8 coded files (or with other codepages).
+
Allows to put the subtitles a little upper, fine when using the ZOOM option in 16:9 TVs or with old CRT receivers
+
Now can add subtitles with horizontal resolutions of 480 and 352 pixels without using too big fonts, nor crashing SPUMUX.
+
When the original video has 24 fps and the destination is a NTSC DVD, DeVeDe will use 24000/1001 fps instead of 30000/1001.
+
Fixed some little bugs when erasing temporary files.
+
Fixed some bugs in the main loop that sometimes hanged up the conversion process.
+
Now shows a kind of progress numbers during subtitle adding and while creating the DVD structure.
+
Now translates fine all the sentences in the interface.
+
Now detects if DeVeDe has permissions to write in the destination directory when doing a preview.
+
Now uses MP2 instead of AC3 to ensure full compatibility.
+
Now detects again when mencoder or spumux fails and shows an error message.
+
Now really allows to abort the process while adding subtitles.
+
Now supplies all the needed data to SPUMUX, so subtitles in NTSC format will be full visible.
+
Fixed some issues in Windows code (thanks again to Peter Gill).
+
Added new translations into German and norwegian, and completed the old ones.
+
+
+
Version 2.10
+
+
Added italian translation
+
The INSTALL script didn't create the GNOME/KDE menu entry. Fixed.
+
+
+
Version 2.9
+
+
Now DeVeDe can work under Windows, thanks to Peter Gill (see the FAQ for details).
+
Fixed some little bugs that prevented to use DeVeDe with some files taken from video capture cards.
+
Fixed a bug with the Drag&Drop in the main window.
+
Fixed a bug that prevented DeVeDe to detect errors in the execution of MKISOFS.
+
Added a warning about VFAT/FAT32 partitions.
+
+
+
Version 2.8
+
+
Now only allows to create 16:9 DVDs when the final width is 720 pixels, and
+don't allow to create 16:9 VCDs, SVCDs or CVDs.
+
+
+
Version 2.7
+
+
+
Support for true DVD subtitles
+
Can create 16:9 DVDs from widescreen videos
+
Default MBD changed to 2 (slower but greater quality)
+
Now installs in /urs/local
+
+
+
Version 2.6
+
+
+
When the video wasn't subdivided in chapters, the XML file was incorrect and DVDAuthor complained. Fixed.
+
Fixed a bug when the output directory was no writable.
+
Added translation for Portugues do Brasil
+
Added a FAQ.
+
+
+
Version 2.5
+
+
+
Fixed another bug with directories and/or filenames with blank spaces
+
Added a workaround for a bug found in very old DVD Players, that can't play fast forward between the last
+chapter and the end of a file.
+
+
+
Version 2.4A
+
+
+
Added translation for Czech
+
+
+
Version 2.4
+
+
+
Allows to specify that a file is already a DVD-compliant MPEG-PS file, so it won't be recompresed, but
+stored "as is" into the disc (usefull when you capture video from a TV capturer of other sources).
+
Alows to deinterlace the video.
+
Allows to choose the MacroBlock algorithm and use Trellis, to enhace the final picture quality.
+
Allows to choose the directory for the temporary file used during preview, and remembers it.
+
Before creating a new disc it erases the files with conflicting names in the destination directory.
+
Allows to cancel the process during the creation of the BIN/CUE image of a VCD, SVCD or CVD.
+
Added a VRC_MINRATE parameter when creating VCDs, SVCDs and CVDs, to ensure full compatibility.
+
Changed the video bitrate for VCDs from 1150 to 1152, and the minimum video bitrate for SVCDs and CVD
+from 500 to 600.
+
Ensures that the progress bar while converting a file is refreshed at least each two senconds.
+
First major code refactorization to enhace the maintenability.
+
+
+
Version 2.3
+
+
+
Removed the use of B-frames (which was added in version 2.1) because it produces problems with some
+DVD players.
+
+
+
Version 2.2
+
+
+
In some very inusual cases mencoder could trigger a bug with an undeclared variable. Fixed.
+
+
+
Version 2.1
+
+
+
Optimized some loops. Now DeVeDe is about 30% faster during video conversion.
+
Now checks that you have enought free disk space.
+
Allows to maintain the temporary files instead of deleting them.
+
Fixed a little bug with the erasing of temporary files.
+
+
+
Version 2.0
+
+
+
Now can create VideoCD, SuperVideoCD and China VideoDisks.
+
Allows the user to override the default resolution and use the one he wants.
+
Allows to pass custom commands to Mencoder, allowing to render subtitles, cut the file in chunks, select
+an audio stream when the file has two or more...
+
Allows to change the order of the files and titles.
+
Changed the position of some elements, making the interface a little more intuitive.
+
The advanced features have been grouped, so novices will see only the
+most important options while advanced users can have access to a lot of extra functions with just a single
+click.
+
Fixed a litle bug when a video header tells that it has an aspect ratio of 0 or 1.
+
Installation more compliant with FreeDesktop and Debian normatives.
+
+
+
Version 1.6
+
+
+
Added support for resolutions 352x480 (in NTSC) and 352x576 (in PAL).
+
Fully support for movies with aspect ratios different than 4:3 (now, with 16:9 movies it adds the right black bars to ensure that a circle IS a circle).
+
Fixed a bug with audio/video sync when converting a PAL video to NTSC or vice-versa.
+
+
+
Version 1.5
+
+
+
Now works with video files without audio track.
+
Transforms blank spaces in the generic filename to underscores (in previous versions, DeVeDe failed if a blank space was inserted).
+
Fixed the translation to Galego.
+
Added an uninstall script.
+
+
+
Version 1.4
+
+
+
Added Drag&Drop support.
+
Translatable strings (currently supports english, spanish and galego).
+
Set a default video rate based on the final resolution.
+
Shows the elapsed time used to create de DVD.
+
+
+
Version 1.3
+
+
+
Added fully support for PAL/SECAM and NTSC. Now the user can choose the kind of disc to create.
+
Added support for more resolutions (352x288/352x240), so DVDs made from low-resolution videos will have better quality.
+
Now DeVeDe scales the video or resamples the audio if needed, so the conversion is a litle faster (not much faster, but faster anyway).
+
Some minor bugfixes.
+
+
+
Version 1.2
+
+
+
Now DeVeDe REALLY creates a NTSC DVD when the framerate is 30fps (that was the original intention, but due to a litle bug it didn't work before).
+
+
+
Version 1.1
+
+
Allows to adjust the audio delay, to ensure perfect audio/video sync.
+
Added a Preview button, to check the video quality and the audio sync without converting all the files.
+
Now DeVeDe reduces a litle its priority when launched, allowing to continue working with the computer without speed penalties.
+
Now checks if you have write permissions at the destination directory.
+
Fixed the install script; now doesn't supposes that install is at /usr/bin.
+
Interface much more compliant with the Gnome HIG.
+
+
+
Version 1.02b
+
Due to the hurry to fix an error, I packed an incorrect version in the .tar.bz2. Fixed here.
+
+
Version 1.02
+
With some specific files DeVeDe failed. Fixed in this version.
+
Now DeVeDe can be installed in the home directory.
Fixed a bug which prevented to create VCD, sVCD and CVD
+
+
+
Version 3.16.7 (2010-04-11)
+
+
Video info is updated when changing selection with arrow keys
+
Allows up to 448Kbps for audio when using AC3
+
+
+
+
Version 3.16.6 (2010-03-19)
+
+
Buttons in main window now has a border, like all other buttons
+
Desktop launcher now shows a much more HIG-compliant description
+
Pressing RETURN key in Title properties and Create disc dialogs has the same effect than the Accept button
+
+
+
Version 3.16.5 (2010-03-09)
+
+
Don't show by default the subtitles in MKV files
+
Fixed dependencies in .deb package to ensure Debian compatibility
+
+
+
+
Version 3.16.4 (2010-02-24)
+
+
Adjusts the audio bitrate to the list of legal values supported by Mencoder
+
+
+
Version 3.16.3 (2010-02-22)
+
+
Supports blank spaces in subtitles filenames
+
+
+
Version 3.16.2 (2010-02-21)
+
+
Fixed audio bitrate when using 5.1 sound
+
+
+
Version 3.16.1 (2010-02-21)
+
+
Fixed a hang when repacking MPEG files instead of reencoding them
+
Fixed Galician translation
+
+
+
Version 3.16.0 (2010-01-07)
+
+
Added support for two-pass encoding (thanks to Gustavo Sanchez)
+
Added support for 64bit Windows
+
Fixed a bug when importing old .devede files
+
Fixed a bug that prevented to manually choose the aspect ratio
+
Allows to change the final volume
+
Now remembers the last output directory used, and the last subtitle language and codepage
+
Added support for UTF-16 subtitles
+
Autodetects ASCII, UTF-8 and UTF-16 subtitles
+
Allows to remove menu
+
Check if there's a /, | or \ in the file name
+
Allows to force the subtitles by default
+
Flush stdout and stderr at end, so it should finally allow to have full debugging info
+
Several bugfixes for Windows version (thanks to Peter Gill)
+
+
+
Version 3.15.2 (2009-11-30)
+
+
Improved debugging
+
+
+
Version 3.15.1 (2009-11-29)
+
+
Fixed a bug when the program can't write the subtitle's XML file
+
Added Miguel Bouzada to the list of translators
+
+
+
Version 3.15.0 (2009-11-27)
+
+
Added -loop 1 in mplayer commands to avoid problems when the user has a mplayer.config file
+
Changed shape of the main window to better fit wide screens
+
Added support for OGG/Vorbis for menu sound
+
Added new backgrounds
+
Support for RMVB file extension
+
Preview button now can hide the icon when global preferences says it
+
When creating a DivX, if Default resolution is selected, won't touch size, nor aspect ratio, nor add bars
+
Updated translation to French
+
Updated translation to Galician
+
Translation to Tradicional Chinese
+
Support for filenames with double quotes (thanks to Christian)
+
Allows to split a film in two disks in SVCD and CVD, not only in VCD
+
+
+
Version 3.14.0 (2009-07-20)
+
+
Now doesn't add black bars when creating an NTSC disc from an 720x480 file without ASPECT RATIO parameter embedded
+
Allows to repack a file as MPEG-PS without recompress the streams (useful to work with VOB files)
+
Allows to swap the field order in interlaced videos
+
Allows to change the subtitle's font size
+
Now supports subtitle filenames with XML-reserved characters
+
Supports all picture types for menu backgrounds (not only PNG)
+
Now removes previous preview files if they already existed, when using LN
+
Fixed free disk space calcule in Windows 2000 and the SetPriority function (thanks to Peter Gill)
+
Adjusted the media sizes to ensure that the ISOs always will fit in the disc
+
Now doesn't hangs when adding a video file in an unknown format
+
+
+
Version 3.13.1 (2009-05-25)
+
+
+
Save as... option now works.
+
The Title properties window closes when the user changes the action to do when the title ends. Fixed.
+
When the $HOME/.spumux directory didn't exists, DeVeDe is unable to find the font for subtitles. Fixed.
+
Added TTF-DEJAVU-CORE package in the DEB dependencies.
+
+
+
Version 3.13.0 (2009-05-14)
+
+
+
Fixed the greek translation
+
Doesn't fail when LANG is not defined
+
Migration from LibGLADE to GtkBuilder
+
+
+
Version 3.12c (2009-01-27)
+
+
+
Updated french translation
+
Updated file Changelog.Debian
+
+
+
+
Version 3.12b (2009-01-26)
+
+
+
Fixed french translation and added italian translation
+
+
+
Version 3.12 (2009-01-25)
+
+
+
Supports pathnames with &, <, >, ' and "
+
When the user chooses a folder in the menu background, it removes the preview
+
New disc type chooser window (based on a model from Jonathan Estrella)
+
When the output path exists, it asks before deleting it
+
+
+
Version 3.11b (2008-08-27)
+
+
+
Fixed some language issues in EL, PL, SK and SV locales.
+
+
+
Version 3.11 (2008-08-24)
+
+
+
Now recovers the menu options when loading a disc structure
+
Changed the appearance to make it more eye-candy
+
Shows the menu's NTSC preview at the right size
+
Shows right the menu's title tipography
+
Added compatibility with GenISOimage
+
Better code to avoid antialiasing when creating the menu entries
+
Now limits the number of files to 61 to avoid problems with DVDAuthor
+
+
+
+
Version 3.10 (2008-08-16)
+
+
+
Now the user chooses a global format (PAL or NTSC) for videos and menus.
+
Removed the limit of 12 titles; now can create discs with up to 90 titles and/or 90 files.
+
Allows to add a title to the menu, and shadows to the menu texts.
+
Allows to put the menu texts at the right, left or center.
+
Now shows a preview of the selected picture when choosing the menu background.
+
Added YADIF deinterlace filter support.
+
Added contextual help.
+
New background picture.
+
Support for resolution of 160x128 pixels in DivX.
+
Added a preview button in the Menu options window.
+
Now hides the advanced options in the main window.
+
Fixed the bug that made the menus to be shown only one second in some players.
+
Now it always honours the PAL/NTSC menu type.
+
Now,when creating a PAL disk from a 24fps source, DeVeDe speeds up it instead of adding one frame each 24,
+obtaining a more fluid animation.
+
The silence sound file has been changed from WAV to MP3 to free some disk space.
+
Fixed a little bug when using HD resolutions for DivX.
+
Modified code to simplify adding new options to the DVD's menus.
+
+
+
Version 3.9 (2008-06-24)
+
+
Due to the use of VRC_MINRATE option, sometimes the final disk size was bigger than the predicted. Fixed.
+
Now remembers the directory from where the user added a movie file.
+
Fixed the detection of the number of cores in the system.
+
Adds the menu type (PAL or NTSC) when creating a menuless disk.
+
Uses transparent pictures for the menus, ensuring that they work fine in more players.
+
Removed CONVERT dependency (Thanks to Peter Gill).
+
+
+
Version 3.8c (2008-05-25)
+
+
Now are really fixed the translation bugs.
+
+
+
Version 3.8b (2008-05-25)
+
+
Fixed a bug in the italian translation.
+
Fixed a bug in the poland translation.
+
+
+
Version 3.8 (2008-05-25)
+
+
Automatic video bitrate adjust, to ensure that the ISO or BIN/CUE image occupies the maximum size in the disk.
+
Support for up to 32 subtitles tracks.
+
Allows to specify the subtitle's language.
+
Allows to choose the language to use when the original video contains several audio tracks.
+
Added the L5 deinterlacing filter.
+
Support for rotating and flipping the video.
+
Muticore support.
+
Allows to mix classic and widescreen videos in the same disk.
+
High Definition support in DivX.
+
Allows to Drag&Drop subtitles in the properties window, or to load a configuration
+file by Dragging&Dropping.
+
Uses a GOP of 12 frames to ensure maximum compatibility.
+
Uses the Telecine parameter to improve quality in 24fps films.
+
Adjusted the maximum bitrate for DivX.
+
Allows to add extra parameters in -lavcopts, -vf and -lameopts.
+
Now stores the status of the buttons for delete temporary files and to choose the action to do.
+
Added an icon to all windows.
+
Fixed a bug when Mplayer is compiled with --enable-color-console.
+
Allows to choose the colors and the position of the menus.
+
More elegant menu system (based on code from Mojoholder)
+
+
+
Version 3.7 (2008-04-16)
+
+
Fixed a bug when runing in a system configured with Catalan language
+
Now asks for confirmation when closing the disk type selection window
+
The final size of the ISO image is now much more accurate
+
Fixed some Win32 bugs (thanks to Peter Gill)
+
+
+
Version 3.6 (2007-12-10)
+
+
Added a safe margin 5% in the occupied size, to have in mind the size needed by disk structures (like
+directories, file info and so on).
+
Fixed a some bugs in poland translation.
+
Fixed some windows compatibility bugs.
+
+
+
Version 3.5 (2007-12-08)
+
+
Improved compatibility by using CGOP and SC_THRESOLD.
+
Now uses a GOP of 15 frames instead of 18 when creating a NTSC, 24fps disc, as dictates the standard.
+
Fixed a bug in italian translation which prevented the "Not enought disk space" message to be shown.
+
Added translation to russian and greek.
+
+
+
Version 3.4 (2007-11-21)
+
+
Allows to create DVDs with 5.1 sound
+
Allows to use a GOP of 12 frames to improve compatibility with some broken DVD players
+
Fixes a bug when creating VCD disks
+
Fixed a bug which prevented to previsualizate in DIVX mode.
+
Final code refactorization: finally the code is clean and maintenable.
+
+
+
Version 3.3 (2007-11-14)
+
+
The EXPAND parameter in Mencoder now uses always an even offset to avoid some artifacts when the offset was odd.
+
Fixed a bug when draging&dropping video files.
+
+
+
Version 3.2
+
+
Fixed a bug when using extra parameters with Mencoder
+
Fixed pt_PT translation
+
Fixed a bug with pl translation
+
+
+
Version 3.1b
+
+
+
Fixed a little bug which prevented version 3.1 to work with Python 2.4
+
+
+
Version 3.1
+
+
+
Fixed some problems under windows.
+
Now returns to the main window after creating the disk.
+
When opening the file selector, it filters the files by type, showing only the videos.
+
When using the NEW menu option to clean the disk structure and start again, it asks the disk type again.
+
Now, when loading a disk structure, if the disk type is different than the current selected,
+automatically changes to the new type.
+
Added new translations.
+
Added new icon (thanks to Jonah Naylor).
+
Second major code refactorization to improve maintenability.
+
License changed to GPL version 3.
+
+
+
Version 3.01
+
+
Added new patches for windows version.
+
Removed the use of lower priority, because it made the conversion slower.
+
Fixed a little bug when the final directory contains blank spaces.
+
Added translation to Catala, and fixed the French one.
+
+
+
Version 3.0
+
+
Allows to add a menu to the DVD with a list of the titles and a custom background picture.
+
Allows to save the current disc structure, in order to reutilize it, or continue working in other moment.
+
Allows to choose up to 448kbit/sec for audio.
+
Now asks before canceling a job.
+
A little bigger font size for subtitles.
+
When creating a DivX file, now it uses .AVI extension.
+
Fixed a bug with non-UTF8 locales.
+
Fixed a bug in the "Insuficient free space..." message. Now is shown translated.
+
Fixed a bug when erasing conflicting files and directories.
+
Fixed a bug when trying to create a DivX from a file with an original size equal to the final size.
+
Now, when the conversion fails, it doesn't show a "Success" message.
+
+
+
Version 2.13d
+
+
Fixed the german translation
+
Changed the Mplayer/Mencoder version to the one from Ubuntu Edgy, due to some bugs when creating
+PAL videos.
+
+
+
Version 2.13c
+
+
Changed the MPlayer/Mencoder files, using version 0.99Pre8.
+
+
+
+
Version 2.13b
+
+
Added a MPlayer/Mencoder package for Ubuntu Feisty users.
+
+
+
Version 2.13
+
+
+
Added creation of MPEG4/DIVX files.
+
Added swedish and slovak translations.
+
Fixed some issues with translations (thanks to Marco de Freitas).
+
+
+
+
Version 2.12
+
+
+
New and more flexibles install and uninstall scripts (thanks to Patrick Monnerat).
+
Added french translation.
+
Fixed some issues with non-UTF8 systems (thanks to Marco de Freitas).
+
+
+
Version 2.11
+
+
Allows to specify the codepage for subtitles, allowing to use UTF-8 coded files (or with other codepages).
+
Allows to put the subtitles a little upper, fine when using the ZOOM option in 16:9 TVs or with old CRT receivers
+
Now can add subtitles with horizontal resolutions of 480 and 352 pixels without using too big fonts, nor crashing SPUMUX.
+
When the original video has 24 fps and the destination is a NTSC DVD, DeVeDe will use 24000/1001 fps instead of 30000/1001.
+
Fixed some little bugs when erasing temporary files.
+
Fixed some bugs in the main loop that sometimes hanged up the conversion process.
+
Now shows a kind of progress numbers during subtitle adding and while creating the DVD structure.
+
Now translates fine all the sentences in the interface.
+
Now detects if DeVeDe has permissions to write in the destination directory when doing a preview.
+
Now uses MP2 instead of AC3 to ensure full compatibility.
+
Now detects again when mencoder or spumux fails and shows an error message.
+
Now really allows to abort the process while adding subtitles.
+
Now supplies all the needed data to SPUMUX, so subtitles in NTSC format will be full visible.
+
Fixed some issues in Windows code (thanks again to Peter Gill).
+
Added new translations into German and norwegian, and completed the old ones.
+
+
+
Version 2.10
+
+
Added italian translation
+
The INSTALL script didn't create the GNOME/KDE menu entry. Fixed.
+
+
+
Version 2.9
+
+
Now DeVeDe can work under Windows, thanks to Peter Gill (see the FAQ for details).
+
Fixed some little bugs that prevented to use DeVeDe with some files taken from video capture cards.
+
Fixed a bug with the Drag&Drop in the main window.
+
Fixed a bug that prevented DeVeDe to detect errors in the execution of MKISOFS.
+
Added a warning about VFAT/FAT32 partitions.
+
+
+
Version 2.8
+
+
Now only allows to create 16:9 DVDs when the final width is 720 pixels, and
+don't allow to create 16:9 VCDs, SVCDs or CVDs.
+
+
+
Version 2.7
+
+
+
Support for true DVD subtitles
+
Can create 16:9 DVDs from widescreen videos
+
Default MBD changed to 2 (slower but greater quality)
+
Now installs in /urs/local
+
+
+
Version 2.6
+
+
+
When the video wasn't subdivided in chapters, the XML file was incorrect and DVDAuthor complained. Fixed.
+
Fixed a bug when the output directory was no writable.
+
Added translation for Portugues do Brasil
+
Added a FAQ.
+
+
+
Version 2.5
+
+
+
Fixed another bug with directories and/or filenames with blank spaces
+
Added a workaround for a bug found in very old DVD Players, that can't play fast forward between the last
+chapter and the end of a file.
+
+
+
Version 2.4A
+
+
+
Added translation for Czech
+
+
+
Version 2.4
+
+
+
Allows to specify that a file is already a DVD-compliant MPEG-PS file, so it won't be recompresed, but
+stored "as is" into the disc (usefull when you capture video from a TV capturer of other sources).
+
Alows to deinterlace the video.
+
Allows to choose the MacroBlock algorithm and use Trellis, to enhace the final picture quality.
+
Allows to choose the directory for the temporary file used during preview, and remembers it.
+
Before creating a new disc it erases the files with conflicting names in the destination directory.
+
Allows to cancel the process during the creation of the BIN/CUE image of a VCD, SVCD or CVD.
+
Added a VRC_MINRATE parameter when creating VCDs, SVCDs and CVDs, to ensure full compatibility.
+
Changed the video bitrate for VCDs from 1150 to 1152, and the minimum video bitrate for SVCDs and CVD
+from 500 to 600.
+
Ensures that the progress bar while converting a file is refreshed at least each two senconds.
+
First major code refactorization to enhace the maintenability.
+
+
+
Version 2.3
+
+
+
Removed the use of B-frames (which was added in version 2.1) because it produces problems with some
+DVD players.
+
+
+
Version 2.2
+
+
+
In some very inusual cases mencoder could trigger a bug with an undeclared variable. Fixed.
+
+
+
Version 2.1
+
+
+
Optimized some loops. Now DeVeDe is about 30% faster during video conversion.
+
Now checks that you have enought free disk space.
+
Allows to maintain the temporary files instead of deleting them.
+
Fixed a little bug with the erasing of temporary files.
+
+
+
Version 2.0
+
+
+
Now can create VideoCD, SuperVideoCD and China VideoDisks.
+
Allows the user to override the default resolution and use the one he wants.
+
Allows to pass custom commands to Mencoder, allowing to render subtitles, cut the file in chunks, select
+an audio stream when the file has two or more...
+
Allows to change the order of the files and titles.
+
Changed the position of some elements, making the interface a little more intuitive.
+
The advanced features have been grouped, so novices will see only the
+most important options while advanced users can have access to a lot of extra functions with just a single
+click.
+
Fixed a litle bug when a video header tells that it has an aspect ratio of 0 or 1.
+
Installation more compliant with FreeDesktop and Debian normatives.
+
+
+
Version 1.6
+
+
+
Added support for resolutions 352x480 (in NTSC) and 352x576 (in PAL).
+
Fully support for movies with aspect ratios different than 4:3 (now, with 16:9 movies it adds the right black bars to ensure that a circle IS a circle).
+
Fixed a bug with audio/video sync when converting a PAL video to NTSC or vice-versa.
+
+
+
Version 1.5
+
+
+
Now works with video files without audio track.
+
Transforms blank spaces in the generic filename to underscores (in previous versions, DeVeDe failed if a blank space was inserted).
+
Fixed the translation to Galego.
+
Added an uninstall script.
+
+
+
Version 1.4
+
+
+
Added Drag&Drop support.
+
Translatable strings (currently supports english, spanish and galego).
+
Set a default video rate based on the final resolution.
+
Shows the elapsed time used to create de DVD.
+
+
+
Version 1.3
+
+
+
Added fully support for PAL/SECAM and NTSC. Now the user can choose the kind of disc to create.
+
Added support for more resolutions (352x288/352x240), so DVDs made from low-resolution videos will have better quality.
+
Now DeVeDe scales the video or resamples the audio if needed, so the conversion is a litle faster (not much faster, but faster anyway).
+
Some minor bugfixes.
+
+
+
Version 1.2
+
+
+
Now DeVeDe REALLY creates a NTSC DVD when the framerate is 30fps (that was the original intention, but due to a litle bug it didn't work before).
+
+
+
Version 1.1
+
+
Allows to adjust the audio delay, to ensure perfect audio/video sync.
+
Added a Preview button, to check the video quality and the audio sync without converting all the files.
+
Now DeVeDe reduces a litle its priority when launched, allowing to continue working with the computer without speed penalties.
+
Now checks if you have write permissions at the destination directory.
+
Fixed the install script; now doesn't supposes that install is at /usr/bin.
+
Interface much more compliant with the Gnome HIG.
+
+
+
Version 1.02b
+
Due to the hurry to fix an error, I packed an incorrect version in the .tar.bz2. Fixed here.
+
+
Version 1.02
+
With some specific files DeVeDe failed. Fixed in this version.
+
Now DeVeDe can be installed in the home directory.