From ff89f386926887c740040a29b639b78e3a4a797e Mon Sep 17 00:00:00 2001 From: Sergio Costas Date: Fri, 4 Nov 2016 00:06:19 +0100 Subject: [PATCH] Now allows to change from the main window if a file is shown in the DVD menu --- HISTORY.md | 3 + data/interface/wmain.ui | 17 +- po/es.po | 62 +- po/gl.po | 65 +- po/untitled.pot | 60 +- setup.py | 2 +- src/devedeng/file_movie.py | 1362 ++++++++++++++++++------------------ src/devedeng/project.py | 1233 ++++++++++++++++---------------- 8 files changed, 1427 insertions(+), 1377 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 72bafc3..3472369 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,4 +1,7 @@ ## History of versions ## +* version 4.8.4 (2016-11-03) + * Allows to set if a movie is shown or not in the DVD menu from the main window + * version 4.8.3 (2016-10-16) * Fixed the problem fixed bitrate problem with FFMpeg and AVConv (thanks to Juniorsnet) diff --git a/data/interface/wmain.ui b/data/interface/wmain.ui index ad90a42..2a9d15b 100644 --- a/data/interface/wmain.ui +++ b/data/interface/wmain.ui @@ -1,5 +1,5 @@ - + @@ -38,6 +38,8 @@ + + @@ -265,6 +267,19 @@ + + + In menu + + + + + + 4 + + + + diff --git a/po/es.po b/po/es.po index 9a0a492..adac6fe 100644 --- a/po/es.po +++ b/po/es.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: DeVeDe 3.12\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-03-14 16:01+0100\n" -"PO-Revision-Date: 2016-03-14 16:01+0100\n" +"POT-Creation-Date: 2016-11-03 23:59+0100\n" +"PO-Revision-Date: 2016-11-03 23:59+0100\n" "Last-Translator: Sergio Costas \n" "Language-Team: Español; Castellano \n" "Language: \n" @@ -49,7 +49,7 @@ msgstr "Convirtiendo %(X)s (pasada 1)" msgid "Converting %(X)s" msgstr "Convirtiendo %(X)s" -#: ../src/devedeng/avconv.py:362 ../src/devedeng/ffmpeg.py:355 +#: ../src/devedeng/avconv.py:474 ../src/devedeng/ffmpeg.py:467 #, python-format msgid "Creating menu %(X)d" msgstr "Creando el menú %(X)d" @@ -195,43 +195,43 @@ msgstr "Mezclando menú %(X)d" msgid "DevedeNG projects" msgstr "Proyectos DevedeNG" -#: ../src/devedeng/project.py:204 +#: ../src/devedeng/project.py:206 msgid "Abort the current DVD and exit?" msgstr "¿Interrumpir el DVD y salir?" -#: ../src/devedeng/project.py:204 +#: ../src/devedeng/project.py:206 msgid "Exit DeVeDe" msgstr "Salir de DeVeDe" -#: ../src/devedeng/project.py:259 +#: ../src/devedeng/project.py:270 msgid "The following files could not be added:" msgstr "No se han podido añadir los siguientes ficheros:" -#: ../src/devedeng/project.py:259 ../src/devedeng/project.py:719 +#: ../src/devedeng/project.py:270 ../src/devedeng/project.py:730 msgid "Error while adding files" msgstr "Error al añadir ficheros" -#: ../src/devedeng/project.py:271 +#: ../src/devedeng/project.py:282 #, python-format msgid "The file %(X)s (%(Y)s) will be removed." msgstr "El fichero %(X)s (%(Y)s) será borrado." -#: ../src/devedeng/project.py:271 +#: ../src/devedeng/project.py:282 msgid "Delete file" msgstr "Borrar archivo" -#: ../src/devedeng/project.py:474 +#: ../src/devedeng/project.py:485 #, python-format msgid "The limit for this format is %(l)d files, but your project has %(h)d." msgstr "" "El límite para este formato es de %(l)d ficheros, pero este proyecto tiene " "%(h)d." -#: ../src/devedeng/project.py:474 +#: ../src/devedeng/project.py:485 msgid "Too many files in the project" msgstr "Demasiados ficheros en el proyecto" -#: ../src/devedeng/project.py:483 +#: ../src/devedeng/project.py:494 #, python-format msgid "" "The selected folder already exists. To create the project, Devede must " @@ -250,27 +250,27 @@ msgstr "" "\n" " y todo su contenido será borrado. ¿Continuar?" -#: ../src/devedeng/project.py:483 +#: ../src/devedeng/project.py:494 msgid "Delete folder" msgstr "Borrar carpeta" -#: ../src/devedeng/project.py:618 +#: ../src/devedeng/project.py:629 msgid "Close current project and start a fresh one?" msgstr "¿Cerrar este proyecto y comenzar uno nuevo?" -#: ../src/devedeng/project.py:618 +#: ../src/devedeng/project.py:629 msgid "New project" msgstr "Nuevo proyecto" -#: ../src/devedeng/project.py:659 +#: ../src/devedeng/project.py:670 msgid "The file already exists. Overwrite it?" msgstr "El fichero ya existe. ¿Sobreescribirlo?" -#: ../src/devedeng/project.py:659 +#: ../src/devedeng/project.py:670 msgid "The file already exists" msgstr "El fichero ya existe" -#: ../src/devedeng/project.py:719 +#: ../src/devedeng/project.py:730 msgid "The following files in the project could not be added again:" msgstr "Los siguientes ficheros del proyecto no se pudieron añadir de nuevo:" @@ -433,7 +433,7 @@ msgstr "Cambiar las propiedades de estos ficheros" msgid "PAL/SECAM" msgstr "PAL/SECAM" -#: ../data/interface/wfile_properties.ui.h:16 ../data/interface/wmain.ui.h:15 +#: ../data/interface/wfile_properties.ui.h:16 ../data/interface/wmain.ui.h:16 msgid "NTSC" msgstr "NTSC" @@ -762,7 +762,7 @@ msgstr "Misc" msgid "Options" msgstr "Opciones" -#: ../data/interface/wfile_properties.ui.h:96 ../data/interface/wmain.ui.h:9 +#: ../data/interface/wfile_properties.ui.h:96 ../data/interface/wmain.ui.h:10 msgid "Preview" msgstr "Previsualizar" @@ -798,39 +798,43 @@ msgstr "Título" msgid "Duration" msgstr "Duración" -#: ../data/interface/wmain.ui.h:10 +#: ../data/interface/wmain.ui.h:9 +msgid "In menu" +msgstr "En el menú" + +#: ../data/interface/wmain.ui.h:11 msgid "Files" msgstr "Archivos" -#: ../data/interface/wmain.ui.h:11 +#: ../data/interface/wmain.ui.h:12 msgid "Media size:" msgstr "Tamaño del disco:" -#: ../data/interface/wmain.ui.h:12 +#: ../data/interface/wmain.ui.h:13 msgid "Adjust disc usage" msgstr "Ajustar el espacio ocupado en disco" -#: ../data/interface/wmain.ui.h:13 +#: ../data/interface/wmain.ui.h:14 msgid "Disc usage" msgstr "Ocupación del disco" -#: ../data/interface/wmain.ui.h:14 +#: ../data/interface/wmain.ui.h:15 msgid "PAL" msgstr "PAL" -#: ../data/interface/wmain.ui.h:16 +#: ../data/interface/wmain.ui.h:17 msgid "Default format" msgstr "Formato por defecto" -#: ../data/interface/wmain.ui.h:17 +#: ../data/interface/wmain.ui.h:18 msgid "Create a menu with the titles" msgstr "Crear un menú con los títulos" -#: ../data/interface/wmain.ui.h:18 +#: ../data/interface/wmain.ui.h:19 msgid "Menu options" msgstr "Opciones del menú" -#: ../data/interface/wmain.ui.h:19 +#: ../data/interface/wmain.ui.h:20 msgid "Menus" msgstr "Menús" diff --git a/po/gl.po b/po/gl.po index 78e6b4b..e094965 100644 --- a/po/gl.po +++ b/po/gl.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: DeVeDe 3.16\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-03-14 16:01+0100\n" -"PO-Revision-Date: 2016-03-14 15:57+0100\n" +"POT-Creation-Date: 2016-11-03 23:59+0100\n" +"PO-Revision-Date: 2016-11-04 00:00+0100\n" "Last-Translator: Sergio Costas \n" "Language-Team: Español; Castellano \n" "Language: gl\n" @@ -50,7 +50,7 @@ msgstr "Convertendo %(X)s (paso 1)" msgid "Converting %(X)s" msgstr "Convertendo %(X)s" -#: ../src/devedeng/avconv.py:362 ../src/devedeng/ffmpeg.py:355 +#: ../src/devedeng/avconv.py:474 ../src/devedeng/ffmpeg.py:467 #, python-format msgid "Creating menu %(X)d" msgstr "Creando o menú %(X)d" @@ -184,9 +184,8 @@ msgid "Creating ISO image" msgstr "Creando a imaxe ISO" #: ../src/devedeng/help.py:17 -#, fuzzy msgid "Can't open the help files." -msgstr "Non se pode abrir o ficheiro." +msgstr "Non se pode abrir o ficheiro de axuda." #: ../src/devedeng/mux_dvd_menu.py:34 #, python-format @@ -197,43 +196,43 @@ msgstr "Mesturando o menú %(X)d" msgid "DevedeNG projects" msgstr "Proxectos DevedeNG" -#: ../src/devedeng/project.py:204 +#: ../src/devedeng/project.py:206 msgid "Abort the current DVD and exit?" msgstr "Interromper o DVD e saír?" -#: ../src/devedeng/project.py:204 +#: ../src/devedeng/project.py:206 msgid "Exit DeVeDe" msgstr "Saír de DeVeDe" -#: ../src/devedeng/project.py:259 +#: ../src/devedeng/project.py:270 msgid "The following files could not be added:" msgstr "Non é posíbel engadir os seguintes ficheiros:" -#: ../src/devedeng/project.py:259 ../src/devedeng/project.py:719 +#: ../src/devedeng/project.py:270 ../src/devedeng/project.py:730 msgid "Error while adding files" msgstr "Produciuse un erro ao engadir ficheiros" -#: ../src/devedeng/project.py:271 +#: ../src/devedeng/project.py:282 #, python-format msgid "The file %(X)s (%(Y)s) will be removed." msgstr "O ficheiro %(X)s (%(Y)s) vai seren retirado." -#: ../src/devedeng/project.py:271 +#: ../src/devedeng/project.py:282 msgid "Delete file" msgstr "Eliminar o ficheiro" -#: ../src/devedeng/project.py:474 +#: ../src/devedeng/project.py:485 #, python-format msgid "The limit for this format is %(l)d files, but your project has %(h)d." msgstr "" "O limite para este formato é de %(l)d ficheiros, mais o seu proxecto ten " "%(h)d." -#: ../src/devedeng/project.py:474 +#: ../src/devedeng/project.py:485 msgid "Too many files in the project" msgstr "Hai ficheiros de máis no proxecto" -#: ../src/devedeng/project.py:483 +#: ../src/devedeng/project.py:494 #, python-format msgid "" "The selected folder already exists. To create the project, Devede must " @@ -252,27 +251,27 @@ msgstr "" "\n" " e todo o seu contido vai seren eliminado. Quere continuar?" -#: ../src/devedeng/project.py:483 +#: ../src/devedeng/project.py:494 msgid "Delete folder" msgstr "Eliminar o cartafol" -#: ../src/devedeng/project.py:618 +#: ../src/devedeng/project.py:629 msgid "Close current project and start a fresh one?" msgstr "Pechar o proxecto actual e comezar un novo?" -#: ../src/devedeng/project.py:618 +#: ../src/devedeng/project.py:629 msgid "New project" msgstr "Novo proxecto" -#: ../src/devedeng/project.py:659 +#: ../src/devedeng/project.py:670 msgid "The file already exists. Overwrite it?" msgstr "Xa existe o ficheiro. Quere sobrescribilo?" -#: ../src/devedeng/project.py:659 +#: ../src/devedeng/project.py:670 msgid "The file already exists" msgstr "Xa existe o ficheiro" -#: ../src/devedeng/project.py:719 +#: ../src/devedeng/project.py:730 msgid "The following files in the project could not be added again:" msgstr "Non poderán volver engadirse ao proxecto os seguintes ficheiros:" @@ -434,7 +433,7 @@ msgstr "Estabelecer as propiedades para estes ficheiros" msgid "PAL/SECAM" msgstr "PAL/SECAM" -#: ../data/interface/wfile_properties.ui.h:16 ../data/interface/wmain.ui.h:15 +#: ../data/interface/wfile_properties.ui.h:16 ../data/interface/wmain.ui.h:16 msgid "NTSC" msgstr "NTSC" @@ -763,7 +762,7 @@ msgstr "Misc" msgid "Options" msgstr "Opcións" -#: ../data/interface/wfile_properties.ui.h:96 ../data/interface/wmain.ui.h:9 +#: ../data/interface/wfile_properties.ui.h:96 ../data/interface/wmain.ui.h:10 msgid "Preview" msgstr "Previsualizar" @@ -799,39 +798,43 @@ msgstr "Título" msgid "Duration" msgstr "Duración" -#: ../data/interface/wmain.ui.h:10 +#: ../data/interface/wmain.ui.h:9 +msgid "In menu" +msgstr "No menú" + +#: ../data/interface/wmain.ui.h:11 msgid "Files" msgstr "Ficheiros" -#: ../data/interface/wmain.ui.h:11 +#: ../data/interface/wmain.ui.h:12 msgid "Media size:" msgstr "Tamaño do disco:" -#: ../data/interface/wmain.ui.h:12 +#: ../data/interface/wmain.ui.h:13 msgid "Adjust disc usage" msgstr "Axustar o uso de disco" -#: ../data/interface/wmain.ui.h:13 +#: ../data/interface/wmain.ui.h:14 msgid "Disc usage" msgstr "Ocupación do disco" -#: ../data/interface/wmain.ui.h:14 +#: ../data/interface/wmain.ui.h:15 msgid "PAL" msgstr "PAL" -#: ../data/interface/wmain.ui.h:16 +#: ../data/interface/wmain.ui.h:17 msgid "Default format" msgstr "Formato predeterminado" -#: ../data/interface/wmain.ui.h:17 +#: ../data/interface/wmain.ui.h:18 msgid "Create a menu with the titles" msgstr "Crear un menú cos títulos" -#: ../data/interface/wmain.ui.h:18 +#: ../data/interface/wmain.ui.h:19 msgid "Menu options" msgstr "Opcións do menú" -#: ../data/interface/wmain.ui.h:19 +#: ../data/interface/wmain.ui.h:20 msgid "Menus" msgstr "Menús" diff --git a/po/untitled.pot b/po/untitled.pot index 02ca352..ef86532 100644 --- a/po/untitled.pot +++ b/po/untitled.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-03-14 16:01+0100\n" +"POT-Creation-Date: 2016-11-03 23:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -47,7 +47,7 @@ msgstr "" msgid "Converting %(X)s" msgstr "" -#: ../src/devedeng/avconv.py:362 ../src/devedeng/ffmpeg.py:355 +#: ../src/devedeng/avconv.py:474 ../src/devedeng/ffmpeg.py:467 #, python-format msgid "Creating menu %(X)d" msgstr "" @@ -175,41 +175,41 @@ msgstr "" msgid "DevedeNG projects" msgstr "" -#: ../src/devedeng/project.py:204 +#: ../src/devedeng/project.py:206 msgid "Abort the current DVD and exit?" msgstr "" -#: ../src/devedeng/project.py:204 +#: ../src/devedeng/project.py:206 msgid "Exit DeVeDe" msgstr "" -#: ../src/devedeng/project.py:259 +#: ../src/devedeng/project.py:270 msgid "The following files could not be added:" msgstr "" -#: ../src/devedeng/project.py:259 ../src/devedeng/project.py:719 +#: ../src/devedeng/project.py:270 ../src/devedeng/project.py:730 msgid "Error while adding files" msgstr "" -#: ../src/devedeng/project.py:271 +#: ../src/devedeng/project.py:282 #, python-format msgid "The file %(X)s (%(Y)s) will be removed." msgstr "" -#: ../src/devedeng/project.py:271 +#: ../src/devedeng/project.py:282 msgid "Delete file" msgstr "" -#: ../src/devedeng/project.py:474 +#: ../src/devedeng/project.py:485 #, python-format msgid "The limit for this format is %(l)d files, but your project has %(h)d." msgstr "" -#: ../src/devedeng/project.py:474 +#: ../src/devedeng/project.py:485 msgid "Too many files in the project" msgstr "" -#: ../src/devedeng/project.py:483 +#: ../src/devedeng/project.py:494 #, python-format msgid "" "The selected folder already exists. To create the project, Devede must " @@ -221,27 +221,27 @@ msgid "" " and all its contents will be deleted. Continue?" msgstr "" -#: ../src/devedeng/project.py:483 +#: ../src/devedeng/project.py:494 msgid "Delete folder" msgstr "" -#: ../src/devedeng/project.py:618 +#: ../src/devedeng/project.py:629 msgid "Close current project and start a fresh one?" msgstr "" -#: ../src/devedeng/project.py:618 +#: ../src/devedeng/project.py:629 msgid "New project" msgstr "" -#: ../src/devedeng/project.py:659 +#: ../src/devedeng/project.py:670 msgid "The file already exists. Overwrite it?" msgstr "" -#: ../src/devedeng/project.py:659 +#: ../src/devedeng/project.py:670 msgid "The file already exists" msgstr "" -#: ../src/devedeng/project.py:719 +#: ../src/devedeng/project.py:730 msgid "The following files in the project could not be added again:" msgstr "" @@ -400,7 +400,7 @@ msgstr "" msgid "PAL/SECAM" msgstr "" -#: ../data/interface/wfile_properties.ui.h:16 ../data/interface/wmain.ui.h:15 +#: ../data/interface/wfile_properties.ui.h:16 ../data/interface/wmain.ui.h:16 msgid "NTSC" msgstr "" @@ -725,7 +725,7 @@ msgstr "" msgid "Options" msgstr "" -#: ../data/interface/wfile_properties.ui.h:96 ../data/interface/wmain.ui.h:9 +#: ../data/interface/wfile_properties.ui.h:96 ../data/interface/wmain.ui.h:10 msgid "Preview" msgstr "" @@ -761,39 +761,43 @@ msgstr "" msgid "Duration" msgstr "" -#: ../data/interface/wmain.ui.h:10 -msgid "Files" +#: ../data/interface/wmain.ui.h:9 +msgid "In menu" msgstr "" #: ../data/interface/wmain.ui.h:11 -msgid "Media size:" +msgid "Files" msgstr "" #: ../data/interface/wmain.ui.h:12 -msgid "Adjust disc usage" +msgid "Media size:" msgstr "" #: ../data/interface/wmain.ui.h:13 -msgid "Disc usage" +msgid "Adjust disc usage" msgstr "" #: ../data/interface/wmain.ui.h:14 +msgid "Disc usage" +msgstr "" + +#: ../data/interface/wmain.ui.h:15 msgid "PAL" msgstr "" -#: ../data/interface/wmain.ui.h:16 +#: ../data/interface/wmain.ui.h:17 msgid "Default format" msgstr "" -#: ../data/interface/wmain.ui.h:17 +#: ../data/interface/wmain.ui.h:18 msgid "Create a menu with the titles" msgstr "" -#: ../data/interface/wmain.ui.h:18 +#: ../data/interface/wmain.ui.h:19 msgid "Menu options" msgstr "" -#: ../data/interface/wmain.ui.h:19 +#: ../data/interface/wmain.ui.h:20 msgid "Menus" msgstr "" diff --git a/setup.py b/setup.py index 7e2185e..1d65447 100755 --- a/setup.py +++ b/setup.py @@ -64,7 +64,7 @@ except: setup( name='devedeng', - version='4.8.3', + version='4.8.4', description='A video DVD creator', long_description = "A program that allows to create video DVDs", diff --git a/src/devedeng/file_movie.py b/src/devedeng/file_movie.py index 6334a4e..8225be1 100644 --- a/src/devedeng/file_movie.py +++ b/src/devedeng/file_movie.py @@ -28,715 +28,721 @@ import devedeng.subtitles_mux class file_movie(devedeng.interface_manager.interface_manager): - __gsignals__ = {'title_changed': (GObject.SIGNAL_RUN_FIRST, None,(str,))} - - def __init__(self,file_name, list_files = None): - - self.list_files = list_files - - devedeng.interface_manager.interface_manager.__init__(self) - - self.wfile_properties = None - self.builder = None - - self.config = devedeng.configuration_data.configuration.get_config() - self.set_type(None, self.config.disc_type) - self.config.connect('disc_type',self.set_type) - - if list_files is None: - self.add_text("file_name", file_name) - self.add_text("title_name", os.path.splitext(os.path.basename(file_name))[0]) - self.add_label("original_size",None) - self.add_label("original_length",None) - self.add_label("original_videorate",None) - self.add_label("original_audiorate",None) - self.add_label("original_aspect_ratio",None) - self.add_label("original_fps",None) - self.add_toggle("show_in_menu", True) - else: - self.original_aspect_ratio = 1.777 # dummy value - - self.add_text("chapter_list_entry", None); - - self.add_dualtoggle("format_pal","format_ntsc",self.config.PAL) - self.add_toggle("video_rate_automatic", True) - self.add_toggle("audio_rate_automatic", True) - self.add_toggle("divide_in_chapters", True) - self.add_toggle("force_subtitles", False) - self.add_toggle("mirror_horizontal", False) - self.add_toggle("mirror_vertical", False) - self.add_toggle("two_pass_encoding", False) - self.add_toggle("sound5_1", False) - self.add_toggle("copy_sound", False) - self.add_toggle("is_mpeg_ps", False) - self.add_toggle("no_reencode_audio_video", False) - if (self.disc_type == "divx") or (self.disc_type == "mkv"): - self.add_toggle("gop12", False) - else: - self.add_toggle("gop12", True) - - self.add_group("final_size_pal", ["size_auto", "size_1920x1080", "size_1280x720", "size_720x576", "size_704x576", "size_480x576","size_352x576", "size_352x288"], "size_auto") - self.add_group("final_size_ntsc", ["size_auto_ntsc", "size_1920x1080_ntsc", "size_1280x720_ntsc", "size_720x480_ntsc", "size_704x480_ntsc", "size_480x480_ntsc","size_352x480_ntsc", "size_352x240_ntsc"], "size_auto_ntsc") - self.add_group("aspect_ratio", ["aspect_auto", "aspect_classic", "aspect_wide"], "aspect_auto") - self.add_group("scaling", ["add_black_bars", "scale_picture" ,"cut_picture"], "add_black_bars") - self.add_group("rotation",["rotation_0","rotation_90","rotation_180","rotation_270"], "rotation_0") - self.add_group("deinterlace", ["deinterlace_none", "deinterlace_ffmpeg", "deinterlace_yadif"], "deinterlace_none") - self.add_group("actions", ["action_stop","action_play_first","action_play_previous","action_play_again","action_play_next","action_play_last"], "action_stop") - - self.add_integer_adjustment("volume", 100) - if (self.disc_type == "dvd"): - self.add_integer_adjustment("video_rate", 5000) - elif (self.disc_type == "vcd"): - self.add_integer_adjustment("video_rate", 1152) - else: - self.add_integer_adjustment("video_rate", 2000) - - self.add_integer_adjustment("audio_rate", 224) - self.add_integer_adjustment("subt_font_size", 28) - self.add_float_adjustment("audio_delay", 0.0) - self.add_integer_adjustment("chapter_size", 5) - - self.add_colorbutton("subt_fill_color", self.config.subt_fill_color) - self.add_colorbutton("subt_outline_color", self.config.subt_outline_color) - self.add_float_adjustment("subt_thickness", self.config.subt_outline_thickness) - - if list_files is None: - self.add_list("subtitles_list") - else: - self.add_list("files_to_set") - for e in list_files: - self.files_to_set.append([e.title_name, e]) - - self.add_show_hide("format_pal", ["size_pal"], ["size_ntsc"]) - - self.add_enable_disable("divide_in_chapters", ["chapter_size_spinbutton", "chapter_list_entry"], []) - self.add_enable_disable("video_rate_automatic", [], ["video_spinbutton"]) - self.add_enable_disable("audio_rate_automatic", [], ["audio_spinbutton"]) - self.add_enable_disable("sound5_1", ["copy_sound"], []) - - if (self.disc_type == "dvd"): - self.add_enable_disable("aspect_wide", [], ["size_704x576", "size_480x576","size_352x576", "size_352x288","size_704x480_ntsc", "size_480x480_ntsc","size_352x480_ntsc", "size_352x240_ntsc"]) - - self.add_enable_disable("copy_sound", [], ["audio_delay_spinbutton","audio_rate_automatic","audio_spinbutton","spinbutton_volume","scale_volume","reset_volume"]) - - common_elements = ["gop12","video_rate_automatic","video_spinbutton","audio_rate_automatic","audio_spinbutton","format_pal","format_ntsc","spinbutton_volume","scale_volume","reset_volume", - "size_auto", "size_1920x1080", "size_1280x720", "size_720x576", "size_704x576", "size_480x576","size_352x576", "size_352x288", - "size_auto_ntsc", "size_1920x1080_ntsc", "size_1280x720_ntsc", "size_720x480_ntsc", "size_704x480_ntsc", "size_480x480_ntsc","size_352x480_ntsc", "size_352x240_ntsc", - "aspect_auto","aspect_classic","aspect_wide","mirror_horizontal","mirror_vertical","add_black_bars","scale_picture","cut_picture", - "rotation_0","rotation_90","rotation_180","rotation_270","two_pass_encoding","deinterlace_none","deinterlace_ffmpeg","deinterlace_yadif", - "audio_delay_spinbutton","sound5_1","copy_sound"] - - is_mpeg_ps_list = common_elements[:] - is_mpeg_ps_list.append("no_reencode_audio_video") - is_mpeg_ps_list.append("font_size_spinbutton") - is_mpeg_ps_list.append("force_subtitles") - is_mpeg_ps_list.append("add_subtitles") - is_mpeg_ps_list.append("del_subtitles") - no_reencode_audio_video_list = common_elements[:] - no_reencode_audio_video_list.append("is_mpeg_ps") - - self.add_enable_disable("is_mpeg_ps", [], is_mpeg_ps_list) - self.add_enable_disable("no_reencode_audio_video", [], no_reencode_audio_video_list) - - if list_files is None: - cv = devedeng.converter.converter.get_converter() - film_analizer = (cv.get_film_analizer())() - if (film_analizer.get_film_data(self.file_name)): - self.error = True - else: - self.error = False - self.audio_list = film_analizer.audio_list[:] - self.video_list = film_analizer.video_list[:] - self.audio_streams = film_analizer.audio_streams - self.video_streams = film_analizer.video_streams - self.original_width = film_analizer.original_width - self.original_height = film_analizer.original_height - self.original_length = film_analizer.original_length - self.original_size = film_analizer.original_size - self.original_aspect_ratio = film_analizer.original_aspect_ratio - self.original_videorate = film_analizer.original_videorate - self.original_audiorate = film_analizer.original_audiorate - - self.original_audiorate_uncompressed = film_analizer.original_audiorate_uncompressed - self.original_fps = film_analizer.original_fps - self.original_file_size = film_analizer.original_file_size - - if self.original_audiorate <= 0: - # just a guess, but usually correct - self.original_audiorate = 224 - if self.original_videorate <= 0: - # presume that there are only video and audio streams - self.original_videorate = ((8 * self.original_file_size) / self.original_length) - (self.original_audiorate * self.audio_streams) - # to avoid division by zero when a clip is very short - if self.original_length <= 0: - self.original_length = 1 - - self.width_midle = -1 - self.height_midle = -1 - self.width_final = -1 - self.height_final = -1 - self.video_rate_auto = self.video_rate - self.audio_rate_auto = self.audio_rate - self.video_rate_final = self.video_rate - self.audio_rate_final = self.audio_rate - self.aspect_ratio_final = None - self.converted_filename = None - - - def set_title(self,new_title): - self.title_name = new_title - self.emit('title_changed',self.title_name) - - - def get_duration(self): - return self.original_length - - - def get_estimated_size(self): - """ Returns the estimated final file size, in kBytes, based on the final audio and video rate, and the subtitles """ - - self.set_final_rates() - self.set_final_size_aspect() - - if self.is_mpeg_ps: - estimated_size = self.original_file_size / 1000 - else: - # let's asume 8kbps for each subtitle - sub_rate = 8 * len(self.subtitles_list) - estimated_size = ((self.video_rate_final + (self.audio_rate_final * self.audio_streams) + sub_rate) * self.original_length) / 8 - - return estimated_size - - - def get_size_data(self): - - estimated_size = self.get_estimated_size() - if self.is_mpeg_ps or self.no_reencode_audio_video: - videorate_fixed_size = True - else: - videorate_fixed_size = False - - # let's asume 8kbps for each subtitle - sub_rate = 8 * len(self.subtitles_list) - - return estimated_size, videorate_fixed_size, self.audio_rate_final * self.audio_streams, sub_rate, self.width_final, self.height_final, self.original_length - - - def set_auto_video_audio_rate(self, new_video_rate, new_audio_rate): - - self.video_rate_auto = int(new_video_rate) - self.audio_rate_auto = int(new_audio_rate) - - - def get_max_resolution(self,rx,ry,aspect): - - tmpx = ry*aspect - tmpy = rx/aspect - if (tmpx > rx): - return tmpx,ry - else: - return rx,tmpy - - - def set_final_rates(self): - - if (self.disc_type == "divx") or (self.disc_type == "mkv"): - self.audio_rate_auto = 192 - elif (self.disc_type == "vcd") or (self.disc_type == "svcd") or (self.disc_type == "cvd"): - self.audio_rate_auto = 224 - else: # dvd - if self.sound5_1: - self.audio_rate_auto = 384 - else: - self.audio_rate_auto = 224 - - if self.is_mpeg_ps or self.no_reencode_audio_video: - self.video_rate_final = self.original_videorate - self.audio_rate_final = self.original_audiorate - else: - if self.video_rate_automatic: - self.video_rate_final = self.video_rate_auto - else: - self.video_rate_final = self.video_rate - - if self.copy_sound: - self.audio_rate_final = self.original_audiorate - else: - if self.audio_rate_automatic: - self.audio_rate_final = self.audio_rate_auto - else: - self.audio_rate_final = self.audio_rate - - - def set_final_size_aspect(self): - - if self.is_mpeg_ps: - self.width_midle = self.original_width - self.width_final = self.original_width - self.height_midle = self.original_height - self.height_final = self.original_height - self.aspect_ratio_final = self.original_aspect_ratio - return - - if self.format_pal: - final_size = self.final_size_pal - else: - final_size = self.final_size_ntsc[:-5] # remove the "_ntsc" from the string - - # for divx or matroska, if the size and the aspect ratio is automatic, just don't change them - if ((self.disc_type == "divx") or (self.disc_type == "mkv")) and (final_size == "size_auto") and (self.aspect_ratio == "aspect_auto"): - self.width_midle = self.original_width - self.width_final = self.original_width - self.height_midle = self.original_height - self.height_final = self.original_height - self.aspect_ratio_final = self.original_aspect_ratio - return - - # The steps are: - # - Decide the final aspect ratio - # - Calculate the midle size: the original video will be cut to this size, or black bars will be added - # - Calculate the final size: the midle video will be scaled to this size - - aspect_wide = False - # first, decide the final aspect ratio - if (self.disc_type == "vcd") or (self.disc_type == "svcd") or (self.disc_type == "cvd"): - self.aspect_ratio_final = 4.0/3.0 - else: - if (self.aspect_ratio == "aspect_auto"): - if (self.disc_type != "dvd"): - self.aspect_ratio_final = self.original_aspect_ratio - else: - if self.original_aspect_ratio >= 1.7: - self.aspect_ratio_final = 16.0/9.0 - aspect_wide = True - else: - self.aspect_ratio_final = 4.0/3.0 - elif (self.aspect_ratio == "aspect_classic"): - self.aspect_ratio_final = 4.0/3.0 - else: - self.aspect_ratio_final = 16.0/9.0 - aspect_wide = True - - # now, the final resolution - if self.disc_type == "vcd": - self.width_final = 352 - if (self.format_pal): - self.height_final = 288 - else: - self.height_final = 240 - else: - if final_size == "size_auto": - if self.disc_type == "svcd": - self.width_final =480 - if (self.format_pal): - self.height_final = 576 - else: - self.height_final = 480 - elif self.disc_type == "cvd": - self.width_final =352 - if (self.format_pal): - self.height_final = 576 - else: - self.height_final = 480 - elif self.disc_type == "dvd": - if aspect_wide: - self.width_final = 720 - if (self.format_pal): - self.height_final = 576 - else: - self.height_final = 480 - else: - tx, ty = self.get_max_resolution(self.original_width,self.original_height,self.original_aspect_ratio) - if (self.format_pal): - th = 576 - th2 = 288 - else: - th = 480 - th2 = 240 - if ( tx <= 352 ) and (ty <= th2): - self.width_final = 352 - self.height_final = th2 - elif (tx <= 352) and (ty <= th): - self.width_final = 352 - self.height_final = th - elif (tx <= 704) and (ty <= th): - self.width_final = 704 - self.height_final = th - else: - self.width_final = 720 - self.height_final = th - else: - self.width_final , self.height_final = self.get_max_resolution(self.original_width,self.original_height,self.original_aspect_ratio) - else: - values = final_size[5:].split("x") - self.width_final = int(values[0]) - self.height_final = int(values[1]) - - self.width_final = int(self.width_final) - self.height_final = int(self.height_final) - - # finally, calculate the midle size - - if (self.rotation == "rotation_90") or (self.rotation == "rotation_270"): - midle_aspect_ratio = 1.0 / self.original_aspect_ratio - else: - midle_aspect_ratio = self.original_aspect_ratio - - if self.scaling == "scale_picture": - self.width_midle = int(self.original_width) - self.height_midle = int(self.original_height) - elif self.scaling == "add_black_bars": - if midle_aspect_ratio > self.aspect_ratio_final: # add horizontal black bars, at top and bottom - self.width_midle = int(self.original_width) - self.height_midle = int(self.original_height * midle_aspect_ratio / self.aspect_ratio_final) - else: # add vertical black bars, at left and right - self.width_midle = int(self.original_width * self.aspect_ratio_final / midle_aspect_ratio) - self.height_midle = int(self.original_height) - else: # cut picture - if midle_aspect_ratio > self.aspect_ratio_final: - self.width_midle = int(self.original_width * self.aspect_ratio_final / midle_aspect_ratio) - self.height_midle = int(self.original_height) - else: - self.width_midle = int(self.original_width) - self.height_midle = int(self.original_height * midle_aspect_ratio / self.aspect_ratio_final) - - - def set_type(self,obj = None,disc_type = None): - - if (disc_type is not None): - self.disc_type = disc_type - - - def delete_file(self): - - return - - def on_help_clicked(self,b): - - help_file = devedeng.help.help("file.html") - - - def properties(self): - - if (self.wfile_properties is not None): - self.wfile_properties.present() - return - - self.builder = Gtk.Builder() - self.builder.set_translation_domain(self.config.gettext_domain) - - self.builder.add_from_file(os.path.join(self.config.glade,"wfile_properties.ui")) - self.builder.connect_signals(self) - self.wfile_properties = self.builder.get_object("file_properties") - self.wfile_properties.show_all() - - self.wframe_title = self.builder.get_object("frame_title") - self.wframe_fileinfo = self.builder.get_object("frame_fileinfo") - self.wframe_multiproperties = self.builder.get_object("frame_multiproperties") - self.wtreeview_multiproperties = self.builder.get_object("treeview_multiproperties") - self.wbutton_preview = self.builder.get_object("button_preview") - - self.wshow_in_menu = self.builder.get_object("show_in_menu") - - self.wnotebook = self.builder.get_object("notebook") - - # elements in page GENERAL - self.wformat_pal = self.builder.get_object("format_pal") - self.wformat_ntsc = self.builder.get_object("format_ntsc") - self.wframe_video_rate = self.builder.get_object("frame_video_rate") - self.wframe_audio_rate = self.builder.get_object("frame_audio_rate") - self.waudio_rate = self.builder.get_object("audio_rate") - self.wframe_division_chapters = self.builder.get_object("frame_division_chapters") - - if (self.disc_type == "dvd") or (self.disc_type == "divx") or (self.disc_type == "mkv"): - self.waudio_rate.set_upper(448.0) - else: - self.waudio_rate.set_upper(384.0) - - # elements in page SUBTITLES - self.wsubtitles_list = self.builder.get_object("subtitles_list") - self.wtreview_subtitles = self.builder.get_object("treeview_subtitles") - self.wscrolledwindow_subtitles = self.builder.get_object("scrolledwindow_subtitles") - self.wadd_subtitles = self.builder.get_object("add_subtitles") - self.wdel_subtitles = self.builder.get_object("del_subtitles") - - selection = self.wtreview_subtitles.get_selection() - selection.set_mode(Gtk.SelectionMode.BROWSE) - - # elements in page VIDEO OPTIONS - self.wsize_1920x1080 = self.builder.get_object("size_1920x1080") - self.wsize_1280x720 = self.builder.get_object("size_1280x720") - self.wsize_1920x1080_ntsc = self.builder.get_object("size_1920x1080_ntsc") - self.wsize_1280x720_ntsc = self.builder.get_object("size_1280x720_ntsc") - self.wframe_final_size = self.builder.get_object("frame_final_size") - self.wframe_aspect_ratio = self.builder.get_object("frame_aspect_ratio") - self.waspect_classic = self.builder.get_object("aspect_classic") - self.waspect_wide = self.builder.get_object("aspect_wide") - self.wadd_black_bars_pic = self.builder.get_object("add_black_bars_pic") - self.wscale_picture_pic = self.builder.get_object("scale_picture_pic") - self.wcut_picture_pic = self.builder.get_object("cut_picture_pic") - - # elements in page AUDIO - self.wsound5_1 = self.builder.get_object("sound5_1") - self.wcopy_sound = self.builder.get_object("copy_sound") - - # Adjust the interface UI to the kind of disc - - if (self.disc_type == 'dvd'): - self.wsize_1920x1080.hide() - self.wsize_1280x720.hide() - self.wsize_1920x1080_ntsc.hide() - self.wsize_1280x720_ntsc.hide() - elif (self.disc_type == 'vcd'): - self.wshow_in_menu.hide() - self.wframe_video_rate.hide() - self.wframe_audio_rate.hide() - self.wframe_division_chapters.hide() - self.wframe_final_size.hide() - self.wframe_aspect_ratio.hide() - self.wsound5_1.hide() - self.wcopy_sound.hide() - self.wnotebook.remove_page(5) - elif (self.disc_type == 'svcd'): - self.wsize_1920x1080.hide() - self.wsize_1280x720.hide() - self.wsize_1920x1080_ntsc.hide() - self.wsize_1280x720_ntsc.hide() - self.wshow_in_menu.hide() - self.wframe_division_chapters.hide() - self.wframe_aspect_ratio.hide() - self.wsound5_1.hide() - self.wcopy_sound.hide() - self.wnotebook.remove_page(5) - elif (self.disc_type == 'cvd'): - self.wsize_1920x1080.hide() - self.wsize_1280x720.hide() - self.wsize_1920x1080_ntsc.hide() - self.wsize_1280x720_ntsc.hide() - self.wshow_in_menu.hide() - self.wframe_division_chapters.hide() - self.wframe_aspect_ratio.hide() - self.wsound5_1.hide() - self.wcopy_sound.hide() - self.wnotebook.remove_page(5) - elif (self.disc_type == 'divx'): - self.wshow_in_menu.hide() - self.wframe_division_chapters.hide() - self.wsound5_1.hide() - self.wcopy_sound.hide() - self.wnotebook.remove_page(5) - self.wnotebook.remove_page(1) - elif (self.disc_type == 'mkv'): - self.wshow_in_menu.hide() - self.wframe_division_chapters.hide() - self.wnotebook.remove_page(5) - - if self.list_files is None: - self.wframe_title.show() - self.wframe_fileinfo.show() - self.wframe_multiproperties.hide() - else: - self.wframe_title.hide() - self.wframe_fileinfo.hide() - self.wframe_multiproperties.show() - self.wscrolledwindow_subtitles.hide() - self.wbutton_preview.hide() - self.wadd_subtitles.hide() - self.wdel_subtitles.hide() - sel = self.wtreeview_multiproperties.get_selection() - sel.set_mode(Gtk.SelectionMode.MULTIPLE) - self.wtreeview_multiproperties.set_rubber_banding(True) - - - self.save_ui() - self.update_ui(self.builder) - self.on_aspect_classic_toggled(None) - self.on_treeview_subtitles_cursor_changed(None) - - - def on_aspect_classic_toggled(self,b): - - status1 = self.waspect_classic.get_active() - status2 = self.waspect_wide.get_active() - if (status1): - final_aspect = 4.0/3.0 - elif (status2): - final_aspect = 16.0/9.0 - else: - if self.original_aspect_ratio >= 1.7: - final_aspect = 16.0/9.0 - else: - final_aspect = 4.0/3.0 - if (final_aspect < self.original_aspect_ratio): - self.wadd_black_bars_pic.set_from_file(os.path.join(self.config.pic_path,"to_classic_blackbars.png")) - self.wcut_picture_pic.set_from_file(os.path.join(self.config.pic_path,"to_classic_cut.png")) - self.wscale_picture_pic.set_from_file(os.path.join(self.config.pic_path,"to_classic_scale.png")) - else: - self.wadd_black_bars_pic.set_from_file(os.path.join(self.config.pic_path,"to_wide_blackbars.png")) - self.wcut_picture_pic.set_from_file(os.path.join(self.config.pic_path,"to_wide_cut.png")) - self.wscale_picture_pic.set_from_file(os.path.join(self.config.pic_path,"to_wide_scale.png")) - - - def on_button_accept_clicked(self,b): - - self.store_ui(self.builder) - self.config.subt_fill_color = self.subt_fill_color - self.config.subt_outline_color = self.subt_outline_color - self.config.subt_outline_thickness = self.subt_thickness - if self.list_files is None: - # editing file properties - self.set_final_rates() - self.set_final_size_aspect() - self.emit('title_changed',self.title_name) - else: - # editing properties for a group of files - data = self.store_file() - sel = self.wtreeview_multiproperties.get_selection() - model, pathlist = sel.get_selected_rows() - for file_path in pathlist: - obj = model[file_path][1] - obj.restore_file(data) - - self.wfile_properties.destroy() - self.wfile_properties = None - self.builder = None - - - def on_button_cancel_clicked(self,b): - - if self.list_files is None: - self.restore_ui() - - self.wfile_properties.destroy() - self.wfile_properties = None - self.builder = None - - - def on_add_subtitles_clicked(self,b): - - subt = devedeng.ask_subtitles.ask_subtitles() - if (subt.run()): - self.wsubtitles_list.append([subt.filename, subt.encoding, subt.language, subt.put_upper]) - - - def get_selected_subtitle(self): - - selection = self.wtreview_subtitles.get_selection() - model, treeiter = selection.get_selected() - - if treeiter is not None: - return ( (model, treeiter) ) - else: - return ( (None, None) ) + __gsignals__ = {'title_changed': (GObject.SIGNAL_RUN_FIRST, None,(str,)), 'in_menu_changed': (GObject.SIGNAL_RUN_FIRST, None,(bool,))} + + def __init__(self,file_name, list_files = None): + + self.list_files = list_files + + devedeng.interface_manager.interface_manager.__init__(self) + + self.wfile_properties = None + self.builder = None + + self.config = devedeng.configuration_data.configuration.get_config() + self.set_type(None, self.config.disc_type) + self.config.connect('disc_type',self.set_type) + + if list_files is None: + self.add_text("file_name", file_name) + self.add_text("title_name", os.path.splitext(os.path.basename(file_name))[0]) + self.add_label("original_size",None) + self.add_label("original_length",None) + self.add_label("original_videorate",None) + self.add_label("original_audiorate",None) + self.add_label("original_aspect_ratio",None) + self.add_label("original_fps",None) + self.add_toggle("show_in_menu", True) + else: + self.original_aspect_ratio = 1.777 # dummy value + + self.add_text("chapter_list_entry", None); + + self.add_dualtoggle("format_pal","format_ntsc",self.config.PAL) + self.add_toggle("video_rate_automatic", True) + self.add_toggle("audio_rate_automatic", True) + self.add_toggle("divide_in_chapters", True) + self.add_toggle("force_subtitles", False) + self.add_toggle("mirror_horizontal", False) + self.add_toggle("mirror_vertical", False) + self.add_toggle("two_pass_encoding", False) + self.add_toggle("sound5_1", False) + self.add_toggle("copy_sound", False) + self.add_toggle("is_mpeg_ps", False) + self.add_toggle("no_reencode_audio_video", False) + if (self.disc_type == "divx") or (self.disc_type == "mkv"): + self.add_toggle("gop12", False) + else: + self.add_toggle("gop12", True) + + self.add_group("final_size_pal", ["size_auto", "size_1920x1080", "size_1280x720", "size_720x576", "size_704x576", "size_480x576","size_352x576", "size_352x288"], "size_auto") + self.add_group("final_size_ntsc", ["size_auto_ntsc", "size_1920x1080_ntsc", "size_1280x720_ntsc", "size_720x480_ntsc", "size_704x480_ntsc", "size_480x480_ntsc","size_352x480_ntsc", "size_352x240_ntsc"], "size_auto_ntsc") + self.add_group("aspect_ratio", ["aspect_auto", "aspect_classic", "aspect_wide"], "aspect_auto") + self.add_group("scaling", ["add_black_bars", "scale_picture" ,"cut_picture"], "add_black_bars") + self.add_group("rotation",["rotation_0","rotation_90","rotation_180","rotation_270"], "rotation_0") + self.add_group("deinterlace", ["deinterlace_none", "deinterlace_ffmpeg", "deinterlace_yadif"], "deinterlace_none") + self.add_group("actions", ["action_stop","action_play_first","action_play_previous","action_play_again","action_play_next","action_play_last"], "action_stop") + + self.add_integer_adjustment("volume", 100) + if (self.disc_type == "dvd"): + self.add_integer_adjustment("video_rate", 5000) + elif (self.disc_type == "vcd"): + self.add_integer_adjustment("video_rate", 1152) + else: + self.add_integer_adjustment("video_rate", 2000) + + self.add_integer_adjustment("audio_rate", 224) + self.add_integer_adjustment("subt_font_size", 28) + self.add_float_adjustment("audio_delay", 0.0) + self.add_integer_adjustment("chapter_size", 5) + + self.add_colorbutton("subt_fill_color", self.config.subt_fill_color) + self.add_colorbutton("subt_outline_color", self.config.subt_outline_color) + self.add_float_adjustment("subt_thickness", self.config.subt_outline_thickness) + + if list_files is None: + self.add_list("subtitles_list") + else: + self.add_list("files_to_set") + for e in list_files: + self.files_to_set.append([e.title_name, e]) + + self.add_show_hide("format_pal", ["size_pal"], ["size_ntsc"]) + + self.add_enable_disable("divide_in_chapters", ["chapter_size_spinbutton", "chapter_list_entry"], []) + self.add_enable_disable("video_rate_automatic", [], ["video_spinbutton"]) + self.add_enable_disable("audio_rate_automatic", [], ["audio_spinbutton"]) + self.add_enable_disable("sound5_1", ["copy_sound"], []) + + if (self.disc_type == "dvd"): + self.add_enable_disable("aspect_wide", [], ["size_704x576", "size_480x576","size_352x576", "size_352x288","size_704x480_ntsc", "size_480x480_ntsc","size_352x480_ntsc", "size_352x240_ntsc"]) + + self.add_enable_disable("copy_sound", [], ["audio_delay_spinbutton","audio_rate_automatic","audio_spinbutton","spinbutton_volume","scale_volume","reset_volume"]) + + common_elements = ["gop12","video_rate_automatic","video_spinbutton","audio_rate_automatic","audio_spinbutton","format_pal","format_ntsc","spinbutton_volume","scale_volume","reset_volume", + "size_auto", "size_1920x1080", "size_1280x720", "size_720x576", "size_704x576", "size_480x576","size_352x576", "size_352x288", + "size_auto_ntsc", "size_1920x1080_ntsc", "size_1280x720_ntsc", "size_720x480_ntsc", "size_704x480_ntsc", "size_480x480_ntsc","size_352x480_ntsc", "size_352x240_ntsc", + "aspect_auto","aspect_classic","aspect_wide","mirror_horizontal","mirror_vertical","add_black_bars","scale_picture","cut_picture", + "rotation_0","rotation_90","rotation_180","rotation_270","two_pass_encoding","deinterlace_none","deinterlace_ffmpeg","deinterlace_yadif", + "audio_delay_spinbutton","sound5_1","copy_sound"] + + is_mpeg_ps_list = common_elements[:] + is_mpeg_ps_list.append("no_reencode_audio_video") + is_mpeg_ps_list.append("font_size_spinbutton") + is_mpeg_ps_list.append("force_subtitles") + is_mpeg_ps_list.append("add_subtitles") + is_mpeg_ps_list.append("del_subtitles") + no_reencode_audio_video_list = common_elements[:] + no_reencode_audio_video_list.append("is_mpeg_ps") + + self.add_enable_disable("is_mpeg_ps", [], is_mpeg_ps_list) + self.add_enable_disable("no_reencode_audio_video", [], no_reencode_audio_video_list) + + if list_files is None: + cv = devedeng.converter.converter.get_converter() + film_analizer = (cv.get_film_analizer())() + if (film_analizer.get_film_data(self.file_name)): + self.error = True + else: + self.error = False + self.audio_list = film_analizer.audio_list[:] + self.video_list = film_analizer.video_list[:] + self.audio_streams = film_analizer.audio_streams + self.video_streams = film_analizer.video_streams + self.original_width = film_analizer.original_width + self.original_height = film_analizer.original_height + self.original_length = film_analizer.original_length + self.original_size = film_analizer.original_size + self.original_aspect_ratio = film_analizer.original_aspect_ratio + self.original_videorate = film_analizer.original_videorate + self.original_audiorate = film_analizer.original_audiorate + + self.original_audiorate_uncompressed = film_analizer.original_audiorate_uncompressed + self.original_fps = film_analizer.original_fps + self.original_file_size = film_analizer.original_file_size + + if self.original_audiorate <= 0: + # just a guess, but usually correct + self.original_audiorate = 224 + if self.original_videorate <= 0: + # presume that there are only video and audio streams + self.original_videorate = ((8 * self.original_file_size) / self.original_length) - (self.original_audiorate * self.audio_streams) + # to avoid division by zero when a clip is very short + if self.original_length <= 0: + self.original_length = 1 + + self.width_midle = -1 + self.height_midle = -1 + self.width_final = -1 + self.height_final = -1 + self.video_rate_auto = self.video_rate + self.audio_rate_auto = self.audio_rate + self.video_rate_final = self.video_rate + self.audio_rate_final = self.audio_rate + self.aspect_ratio_final = None + self.converted_filename = None + + + def set_title(self,new_title): + self.title_name = new_title + self.emit('title_changed',self.title_name) + + + def set_show_in_menu(self,show): + self.show_in_menu = show + self.emit('in_menu_changed',self.show_in_menu) + + + def get_duration(self): + return self.original_length + + + def get_estimated_size(self): + """ Returns the estimated final file size, in kBytes, based on the final audio and video rate, and the subtitles """ + + self.set_final_rates() + self.set_final_size_aspect() + + if self.is_mpeg_ps: + estimated_size = self.original_file_size / 1000 + else: + # let's asume 8kbps for each subtitle + sub_rate = 8 * len(self.subtitles_list) + estimated_size = ((self.video_rate_final + (self.audio_rate_final * self.audio_streams) + sub_rate) * self.original_length) / 8 + + return estimated_size + + + def get_size_data(self): + + estimated_size = self.get_estimated_size() + if self.is_mpeg_ps or self.no_reencode_audio_video: + videorate_fixed_size = True + else: + videorate_fixed_size = False + + # let's asume 8kbps for each subtitle + sub_rate = 8 * len(self.subtitles_list) + + return estimated_size, videorate_fixed_size, self.audio_rate_final * self.audio_streams, sub_rate, self.width_final, self.height_final, self.original_length + + + def set_auto_video_audio_rate(self, new_video_rate, new_audio_rate): + + self.video_rate_auto = int(new_video_rate) + self.audio_rate_auto = int(new_audio_rate) + + + def get_max_resolution(self,rx,ry,aspect): + + tmpx = ry*aspect + tmpy = rx/aspect + if (tmpx > rx): + return tmpx,ry + else: + return rx,tmpy + + + def set_final_rates(self): + + if (self.disc_type == "divx") or (self.disc_type == "mkv"): + self.audio_rate_auto = 192 + elif (self.disc_type == "vcd") or (self.disc_type == "svcd") or (self.disc_type == "cvd"): + self.audio_rate_auto = 224 + else: # dvd + if self.sound5_1: + self.audio_rate_auto = 384 + else: + self.audio_rate_auto = 224 + + if self.is_mpeg_ps or self.no_reencode_audio_video: + self.video_rate_final = self.original_videorate + self.audio_rate_final = self.original_audiorate + else: + if self.video_rate_automatic: + self.video_rate_final = self.video_rate_auto + else: + self.video_rate_final = self.video_rate + + if self.copy_sound: + self.audio_rate_final = self.original_audiorate + else: + if self.audio_rate_automatic: + self.audio_rate_final = self.audio_rate_auto + else: + self.audio_rate_final = self.audio_rate + + + def set_final_size_aspect(self): + + if self.is_mpeg_ps: + self.width_midle = self.original_width + self.width_final = self.original_width + self.height_midle = self.original_height + self.height_final = self.original_height + self.aspect_ratio_final = self.original_aspect_ratio + return + + if self.format_pal: + final_size = self.final_size_pal + else: + final_size = self.final_size_ntsc[:-5] # remove the "_ntsc" from the string + + # for divx or matroska, if the size and the aspect ratio is automatic, just don't change them + if ((self.disc_type == "divx") or (self.disc_type == "mkv")) and (final_size == "size_auto") and (self.aspect_ratio == "aspect_auto"): + self.width_midle = self.original_width + self.width_final = self.original_width + self.height_midle = self.original_height + self.height_final = self.original_height + self.aspect_ratio_final = self.original_aspect_ratio + return + + # The steps are: + # - Decide the final aspect ratio + # - Calculate the midle size: the original video will be cut to this size, or black bars will be added + # - Calculate the final size: the midle video will be scaled to this size + + aspect_wide = False + # first, decide the final aspect ratio + if (self.disc_type == "vcd") or (self.disc_type == "svcd") or (self.disc_type == "cvd"): + self.aspect_ratio_final = 4.0/3.0 + else: + if (self.aspect_ratio == "aspect_auto"): + if (self.disc_type != "dvd"): + self.aspect_ratio_final = self.original_aspect_ratio + else: + if self.original_aspect_ratio >= 1.7: + self.aspect_ratio_final = 16.0/9.0 + aspect_wide = True + else: + self.aspect_ratio_final = 4.0/3.0 + elif (self.aspect_ratio == "aspect_classic"): + self.aspect_ratio_final = 4.0/3.0 + else: + self.aspect_ratio_final = 16.0/9.0 + aspect_wide = True + + # now, the final resolution + if self.disc_type == "vcd": + self.width_final = 352 + if (self.format_pal): + self.height_final = 288 + else: + self.height_final = 240 + else: + if final_size == "size_auto": + if self.disc_type == "svcd": + self.width_final =480 + if (self.format_pal): + self.height_final = 576 + else: + self.height_final = 480 + elif self.disc_type == "cvd": + self.width_final =352 + if (self.format_pal): + self.height_final = 576 + else: + self.height_final = 480 + elif self.disc_type == "dvd": + if aspect_wide: + self.width_final = 720 + if (self.format_pal): + self.height_final = 576 + else: + self.height_final = 480 + else: + tx, ty = self.get_max_resolution(self.original_width,self.original_height,self.original_aspect_ratio) + if (self.format_pal): + th = 576 + th2 = 288 + else: + th = 480 + th2 = 240 + if ( tx <= 352 ) and (ty <= th2): + self.width_final = 352 + self.height_final = th2 + elif (tx <= 352) and (ty <= th): + self.width_final = 352 + self.height_final = th + elif (tx <= 704) and (ty <= th): + self.width_final = 704 + self.height_final = th + else: + self.width_final = 720 + self.height_final = th + else: + self.width_final , self.height_final = self.get_max_resolution(self.original_width,self.original_height,self.original_aspect_ratio) + else: + values = final_size[5:].split("x") + self.width_final = int(values[0]) + self.height_final = int(values[1]) + + self.width_final = int(self.width_final) + self.height_final = int(self.height_final) + + # finally, calculate the midle size + + if (self.rotation == "rotation_90") or (self.rotation == "rotation_270"): + midle_aspect_ratio = 1.0 / self.original_aspect_ratio + else: + midle_aspect_ratio = self.original_aspect_ratio + + if self.scaling == "scale_picture": + self.width_midle = int(self.original_width) + self.height_midle = int(self.original_height) + elif self.scaling == "add_black_bars": + if midle_aspect_ratio > self.aspect_ratio_final: # add horizontal black bars, at top and bottom + self.width_midle = int(self.original_width) + self.height_midle = int(self.original_height * midle_aspect_ratio / self.aspect_ratio_final) + else: # add vertical black bars, at left and right + self.width_midle = int(self.original_width * self.aspect_ratio_final / midle_aspect_ratio) + self.height_midle = int(self.original_height) + else: # cut picture + if midle_aspect_ratio > self.aspect_ratio_final: + self.width_midle = int(self.original_width * self.aspect_ratio_final / midle_aspect_ratio) + self.height_midle = int(self.original_height) + else: + self.width_midle = int(self.original_width) + self.height_midle = int(self.original_height * midle_aspect_ratio / self.aspect_ratio_final) + + + def set_type(self,obj = None,disc_type = None): + + if (disc_type is not None): + self.disc_type = disc_type + + + def delete_file(self): + + return + + def on_help_clicked(self,b): + + help_file = devedeng.help.help("file.html") + + + def properties(self): + + if (self.wfile_properties is not None): + self.wfile_properties.present() + return + + self.builder = Gtk.Builder() + self.builder.set_translation_domain(self.config.gettext_domain) + + self.builder.add_from_file(os.path.join(self.config.glade,"wfile_properties.ui")) + self.builder.connect_signals(self) + self.wfile_properties = self.builder.get_object("file_properties") + self.wfile_properties.show_all() + + self.wframe_title = self.builder.get_object("frame_title") + self.wframe_fileinfo = self.builder.get_object("frame_fileinfo") + self.wframe_multiproperties = self.builder.get_object("frame_multiproperties") + self.wtreeview_multiproperties = self.builder.get_object("treeview_multiproperties") + self.wbutton_preview = self.builder.get_object("button_preview") + + self.wshow_in_menu = self.builder.get_object("show_in_menu") + + self.wnotebook = self.builder.get_object("notebook") + + # elements in page GENERAL + self.wformat_pal = self.builder.get_object("format_pal") + self.wformat_ntsc = self.builder.get_object("format_ntsc") + self.wframe_video_rate = self.builder.get_object("frame_video_rate") + self.wframe_audio_rate = self.builder.get_object("frame_audio_rate") + self.waudio_rate = self.builder.get_object("audio_rate") + self.wframe_division_chapters = self.builder.get_object("frame_division_chapters") + + if (self.disc_type == "dvd") or (self.disc_type == "divx") or (self.disc_type == "mkv"): + self.waudio_rate.set_upper(448.0) + else: + self.waudio_rate.set_upper(384.0) + + # elements in page SUBTITLES + self.wsubtitles_list = self.builder.get_object("subtitles_list") + self.wtreview_subtitles = self.builder.get_object("treeview_subtitles") + self.wscrolledwindow_subtitles = self.builder.get_object("scrolledwindow_subtitles") + self.wadd_subtitles = self.builder.get_object("add_subtitles") + self.wdel_subtitles = self.builder.get_object("del_subtitles") + + selection = self.wtreview_subtitles.get_selection() + selection.set_mode(Gtk.SelectionMode.BROWSE) + + # elements in page VIDEO OPTIONS + self.wsize_1920x1080 = self.builder.get_object("size_1920x1080") + self.wsize_1280x720 = self.builder.get_object("size_1280x720") + self.wsize_1920x1080_ntsc = self.builder.get_object("size_1920x1080_ntsc") + self.wsize_1280x720_ntsc = self.builder.get_object("size_1280x720_ntsc") + self.wframe_final_size = self.builder.get_object("frame_final_size") + self.wframe_aspect_ratio = self.builder.get_object("frame_aspect_ratio") + self.waspect_classic = self.builder.get_object("aspect_classic") + self.waspect_wide = self.builder.get_object("aspect_wide") + self.wadd_black_bars_pic = self.builder.get_object("add_black_bars_pic") + self.wscale_picture_pic = self.builder.get_object("scale_picture_pic") + self.wcut_picture_pic = self.builder.get_object("cut_picture_pic") + + # elements in page AUDIO + self.wsound5_1 = self.builder.get_object("sound5_1") + self.wcopy_sound = self.builder.get_object("copy_sound") + + # Adjust the interface UI to the kind of disc + + if (self.disc_type == 'dvd'): + self.wsize_1920x1080.hide() + self.wsize_1280x720.hide() + self.wsize_1920x1080_ntsc.hide() + self.wsize_1280x720_ntsc.hide() + elif (self.disc_type == 'vcd'): + self.wshow_in_menu.hide() + self.wframe_video_rate.hide() + self.wframe_audio_rate.hide() + self.wframe_division_chapters.hide() + self.wframe_final_size.hide() + self.wframe_aspect_ratio.hide() + self.wsound5_1.hide() + self.wcopy_sound.hide() + self.wnotebook.remove_page(5) + elif (self.disc_type == 'svcd'): + self.wsize_1920x1080.hide() + self.wsize_1280x720.hide() + self.wsize_1920x1080_ntsc.hide() + self.wsize_1280x720_ntsc.hide() + self.wshow_in_menu.hide() + self.wframe_division_chapters.hide() + self.wframe_aspect_ratio.hide() + self.wsound5_1.hide() + self.wcopy_sound.hide() + self.wnotebook.remove_page(5) + elif (self.disc_type == 'cvd'): + self.wsize_1920x1080.hide() + self.wsize_1280x720.hide() + self.wsize_1920x1080_ntsc.hide() + self.wsize_1280x720_ntsc.hide() + self.wshow_in_menu.hide() + self.wframe_division_chapters.hide() + self.wframe_aspect_ratio.hide() + self.wsound5_1.hide() + self.wcopy_sound.hide() + self.wnotebook.remove_page(5) + elif (self.disc_type == 'divx'): + self.wshow_in_menu.hide() + self.wframe_division_chapters.hide() + self.wsound5_1.hide() + self.wcopy_sound.hide() + self.wnotebook.remove_page(5) + self.wnotebook.remove_page(1) + elif (self.disc_type == 'mkv'): + self.wshow_in_menu.hide() + self.wframe_division_chapters.hide() + self.wnotebook.remove_page(5) + + if self.list_files is None: + self.wframe_title.show() + self.wframe_fileinfo.show() + self.wframe_multiproperties.hide() + else: + self.wframe_title.hide() + self.wframe_fileinfo.hide() + self.wframe_multiproperties.show() + self.wscrolledwindow_subtitles.hide() + self.wbutton_preview.hide() + self.wadd_subtitles.hide() + self.wdel_subtitles.hide() + sel = self.wtreeview_multiproperties.get_selection() + sel.set_mode(Gtk.SelectionMode.MULTIPLE) + self.wtreeview_multiproperties.set_rubber_banding(True) + + + self.save_ui() + self.update_ui(self.builder) + self.on_aspect_classic_toggled(None) + self.on_treeview_subtitles_cursor_changed(None) + + + def on_aspect_classic_toggled(self,b): + + status1 = self.waspect_classic.get_active() + status2 = self.waspect_wide.get_active() + if (status1): + final_aspect = 4.0/3.0 + elif (status2): + final_aspect = 16.0/9.0 + else: + if self.original_aspect_ratio >= 1.7: + final_aspect = 16.0/9.0 + else: + final_aspect = 4.0/3.0 + if (final_aspect < self.original_aspect_ratio): + self.wadd_black_bars_pic.set_from_file(os.path.join(self.config.pic_path,"to_classic_blackbars.png")) + self.wcut_picture_pic.set_from_file(os.path.join(self.config.pic_path,"to_classic_cut.png")) + self.wscale_picture_pic.set_from_file(os.path.join(self.config.pic_path,"to_classic_scale.png")) + else: + self.wadd_black_bars_pic.set_from_file(os.path.join(self.config.pic_path,"to_wide_blackbars.png")) + self.wcut_picture_pic.set_from_file(os.path.join(self.config.pic_path,"to_wide_cut.png")) + self.wscale_picture_pic.set_from_file(os.path.join(self.config.pic_path,"to_wide_scale.png")) + + + def on_button_accept_clicked(self,b): + + self.store_ui(self.builder) + self.config.subt_fill_color = self.subt_fill_color + self.config.subt_outline_color = self.subt_outline_color + self.config.subt_outline_thickness = self.subt_thickness + if self.list_files is None: + # editing file properties + self.set_final_rates() + self.set_final_size_aspect() + self.emit('title_changed',self.title_name) + self.emit('in_menu_changed',self.show_in_menu) + else: + # editing properties for a group of files + data = self.store_file() + sel = self.wtreeview_multiproperties.get_selection() + model, pathlist = sel.get_selected_rows() + for file_path in pathlist: + obj = model[file_path][1] + obj.restore_file(data) + + self.wfile_properties.destroy() + self.wfile_properties = None + self.builder = None + + + def on_button_cancel_clicked(self,b): + + if self.list_files is None: + self.restore_ui() + + self.wfile_properties.destroy() + self.wfile_properties = None + self.builder = None + + + def on_add_subtitles_clicked(self,b): + + subt = devedeng.ask_subtitles.ask_subtitles() + if (subt.run()): + self.wsubtitles_list.append([subt.filename, subt.encoding, subt.language, subt.put_upper]) + + + def get_selected_subtitle(self): + + selection = self.wtreview_subtitles.get_selection() + model, treeiter = selection.get_selected() + + if treeiter is not None: + return ( (model, treeiter) ) + else: + return ( (None, None) ) - def on_del_subtitles_clicked(self,b): + def on_del_subtitles_clicked(self,b): - model, treeiter = self.get_selected_subtitle() - if (model is not None): - model.remove(treeiter) + model, treeiter = self.get_selected_subtitle() + if (model is not None): + model.remove(treeiter) - def on_treeview_subtitles_cursor_changed(self,b): + def on_treeview_subtitles_cursor_changed(self,b): - model, treeiter = self.get_selected_subtitle() - if (model is None): - self.wdel_subtitles.set_sensitive(False) - else: - self.wdel_subtitles.set_sensitive(True) + model, treeiter = self.get_selected_subtitle() + if (model is None): + self.wdel_subtitles.set_sensitive(False) + else: + self.wdel_subtitles.set_sensitive(True) - def do_conversion(self, output_path, duration = 0): + def do_conversion(self, output_path, duration = 0): - self.converted_filename = output_path - if self.is_mpeg_ps: - converter = devedeng.file_copy.file_copy(self.file_name,output_path) - else: - self.set_final_size_aspect() - self.set_final_rates() + self.converted_filename = output_path + if self.is_mpeg_ps: + converter = devedeng.file_copy.file_copy(self.file_name,output_path) + else: + self.set_final_size_aspect() + self.set_final_rates() - cv = devedeng.converter.converter.get_converter() - disc_converter = cv.get_disc_converter() - converter = disc_converter() - converter.convert_file(self,output_path,duration) + cv = devedeng.converter.converter.get_converter() + disc_converter = cv.get_disc_converter() + converter = disc_converter() + converter.convert_file(self,output_path,duration) - if len(self.subtitles_list) != 0: - last_process = converter - #if duration == 0: - # it seems that SPUMUX always fills the entire subtitles - duration2 = self.original_length - #else: - # duration2 = duration - stream_id = 0 - for subt in self.subtitles_list: - subt_file = subt[0] - subt_codepage = subt[1] - subt_lang = subt[2] - subt_upper = subt[3] - if self.aspect_ratio_final >= 1.7: - final_aspect = "16:9" - else: - final_aspect = "4:3" - subt_mux = devedeng.subtitles_mux.subtitles_mux() - subt_mux.multiplex_subtitles( output_path, subt_file, subt_codepage, subt_lang, subt_upper, - self.subt_font_size,self.format_pal,self.force_subtitles, - final_aspect, duration2, stream_id, - self.subt_fill_color, self.subt_outline_color, self.subt_thickness) - subt_mux.add_dependency(last_process) - converter.add_child_process(subt_mux) - last_process = subt_mux - stream_id += 1 + if len(self.subtitles_list) != 0: + last_process = converter + #if duration == 0: + # it seems that SPUMUX always fills the entire subtitles + duration2 = self.original_length + #else: + # duration2 = duration + stream_id = 0 + for subt in self.subtitles_list: + subt_file = subt[0] + subt_codepage = subt[1] + subt_lang = subt[2] + subt_upper = subt[3] + if self.aspect_ratio_final >= 1.7: + final_aspect = "16:9" + else: + final_aspect = "4:3" + subt_mux = devedeng.subtitles_mux.subtitles_mux() + subt_mux.multiplex_subtitles( output_path, subt_file, subt_codepage, subt_lang, subt_upper, + self.subt_font_size,self.format_pal,self.force_subtitles, + final_aspect, duration2, stream_id, + self.subt_fill_color, self.subt_outline_color, self.subt_thickness) + subt_mux.add_dependency(last_process) + converter.add_child_process(subt_mux) + last_process = subt_mux + stream_id += 1 - return converter + return converter - def on_button_preview_clicked(self,b): - self.store_ui(self.builder) - self.do_preview() + def on_button_preview_clicked(self,b): + self.store_ui(self.builder) + self.do_preview() - def do_preview(self): + def do_preview(self): - wpreview = devedeng.preview.preview_window() - if (wpreview.run() == False): - return + wpreview = devedeng.preview.preview_window() + if (wpreview.run() == False): + return - run_window = devedeng.runner.runner() - p = self.do_conversion(os.path.join(self.config.tmp_folder,"movie_preview.mpg"),wpreview.lvalue) - run_window.add_process(p) - run_window.connect("done",self.preview_done) - run_window.run() + run_window = devedeng.runner.runner() + p = self.do_conversion(os.path.join(self.config.tmp_folder,"movie_preview.mpg"),wpreview.lvalue) + run_window.add_process(p) + run_window.connect("done",self.preview_done) + run_window.run() - def preview_done(self,o,retval): + def preview_done(self,o,retval): - if (retval == 0): - cv = devedeng.converter.converter.get_converter() - disc_player = (cv.get_film_player())() - disc_player.play_film(os.path.join(self.config.tmp_folder,"movie_preview.mpg")) + if (retval == 0): + cv = devedeng.converter.converter.get_converter() + disc_player = (cv.get_film_player())() + disc_player.play_film(os.path.join(self.config.tmp_folder,"movie_preview.mpg")) - def store_file(self): + def store_file(self): - data = self.serialize() - if "files_to_set" in data: - del data["files_to_set"] + data = self.serialize() + if "files_to_set" in data: + del data["files_to_set"] - return data + return data - def restore_file(self,data): + def restore_file(self,data): - self.unserialize(data) + self.unserialize(data) - def on_select_all_clicked(self,b): + def on_select_all_clicked(self,b): - sel = self.wtreeview_multiproperties.get_selection() - sel.select_all() + sel = self.wtreeview_multiproperties.get_selection() + sel.select_all() - def on_unselect_all_clicked(self,b): + def on_unselect_all_clicked(self,b): - sel = self.wtreeview_multiproperties.get_selection() - sel.unselect_all() + sel = self.wtreeview_multiproperties.get_selection() + sel.unselect_all() diff --git a/src/devedeng/project.py b/src/devedeng/project.py index e742be4..3a6647e 100644 --- a/src/devedeng/project.py +++ b/src/devedeng/project.py @@ -42,686 +42,701 @@ import devedeng.help class devede_project: - def __init__(self): + def __init__(self): - self.config = devedeng.configuration_data.configuration.get_config() - - self.disc_type = self.config.disc_type - self.menu = devedeng.dvd_menu.dvd_menu() + self.config = devedeng.configuration_data.configuration.get_config() - self.current_title = None - self.project_file = None + self.disc_type = self.config.disc_type + self.menu = devedeng.dvd_menu.dvd_menu() - builder = Gtk.Builder() - builder.set_translation_domain(self.config.gettext_domain) + self.current_title = None + self.project_file = None - builder.add_from_file(os.path.join(self.config.glade,"wmain.ui")) - builder.connect_signals(self) + builder = Gtk.Builder() + builder.set_translation_domain(self.config.gettext_domain) - # Interface widgets - self.wmain_window = builder.get_object("wmain_window") - self.wdisc_size = builder.get_object("disc_size") - self.wliststore_files = builder.get_object("liststore_files") - self.wfiles = builder.get_object("files") - self.wdisc_fill_level = builder.get_object("disc_fill_level") - self.wuse_pal = builder.get_object("use_pal") - self.wuse_ntsc = builder.get_object("use_ntsc") - self.wframe_titles = builder.get_object("frame_titles") + builder.add_from_file(os.path.join(self.config.glade,"wmain.ui")) + builder.connect_signals(self) - self.wframe_menu = builder.get_object("frame_menu") - self.wcreate_menu = builder.get_object("create_menu") - self.wmenu_options = builder.get_object("menu_options") + # Interface widgets + self.wmain_window = builder.get_object("wmain_window") + self.wdisc_size = builder.get_object("disc_size") + self.wliststore_files = builder.get_object("liststore_files") + self.wfiles = builder.get_object("files") + self.wdisc_fill_level = builder.get_object("disc_fill_level") + self.wuse_pal = builder.get_object("use_pal") + self.wuse_ntsc = builder.get_object("use_ntsc") + self.wframe_titles = builder.get_object("frame_titles") + self.winmenu = builder.get_object("treeviewcolumn3") - self.wadd_file = builder.get_object("add_file") - self.wdelete_file = builder.get_object("delete_file") - self.wup_file = builder.get_object("up_file") - self.wdown_file = builder.get_object("down_file") - self.wproperties_file = builder.get_object("properties_file") - self.wpreview_file = builder.get_object("preview_file") + self.wframe_menu = builder.get_object("frame_menu") + self.wcreate_menu = builder.get_object("create_menu") + self.wmenu_options = builder.get_object("menu_options") - self.wcreate_disc = builder.get_object("create_disc") - selection = self.wfiles.get_selection() - selection.set_mode(Gtk.SelectionMode.BROWSE) + self.wadd_file = builder.get_object("add_file") + self.wdelete_file = builder.get_object("delete_file") + self.wup_file = builder.get_object("up_file") + self.wdown_file = builder.get_object("down_file") + self.wproperties_file = builder.get_object("properties_file") + self.wpreview_file = builder.get_object("preview_file") - if (self.config.PAL): - self.wuse_pal.set_active(True) - self.pal = True - else: - self.wuse_ntsc.set_active(True) - self.pal = False + self.wcreate_disc = builder.get_object("create_disc") - self.wcreate_menu.set_active(True) + selection = self.wfiles.get_selection() + selection.set_mode(Gtk.SelectionMode.BROWSE) - self.config.connect('disc_type',self.set_type) - if (self.disc_type is not None): - self.set_type(None, self.disc_type) + if (self.config.PAL): + self.wuse_pal.set_active(True) + self.pal = True + else: + self.wuse_ntsc.set_active(True) + self.pal = False - self.wmain_window.drag_dest_set(Gtk.DestDefaults.ALL,[],Gdk.DragAction.COPY) - targets = Gtk.TargetList.new([]) - targets.add(Gdk.Atom.intern("text/uri-list", False),0,0) - self.wmain_window.drag_dest_set_target_list(targets) + self.wcreate_menu.set_active(True) + self.config.connect('disc_type',self.set_type) + if (self.disc_type is not None): + self.set_type(None, self.disc_type) - def set_type(self,obj=None,disc_type=None): - """ this method sets the disk type to the specified one and adapts the interface - in the main window to it. Also leaves everything ready to start creating a - new disc """ + self.wmain_window.drag_dest_set(Gtk.DestDefaults.ALL,[],Gdk.DragAction.COPY) + targets = Gtk.TargetList.new([]) + targets.add(Gdk.Atom.intern("text/uri-list", False),0,0) + self.wmain_window.drag_dest_set_target_list(targets) - if (disc_type is not None): - self.disc_type = disc_type - self.wmain_window.show_all() - self.set_interface_status(None) - # Set the default disc size - if (self.disc_type == "dvd") or (self.disc_type == "mkv"): - self.wdisc_size.set_active(1) # 4.7 GB DVD - else: - self.wdisc_size.set_active(3) # 700 MB CD + def set_type(self,obj=None,disc_type=None): + """ this method sets the disk type to the specified one and adapts the interface + in the main window to it. Also leaves everything ready to start creating a + new disc """ - if (self.disc_type == "dvd"): - self.wframe_menu.show_all() - self.wcreate_menu.set_active(True) - else: - self.wframe_menu.hide() - self.wcreate_menu.set_active(False) + if (disc_type is not None): + self.disc_type = disc_type + self.wmain_window.show_all() + self.set_interface_status(None) + # Set the default disc size + if (self.disc_type == "dvd") or (self.disc_type == "mkv"): + self.wdisc_size.set_active(1) # 4.7 GB DVD + else: + self.wdisc_size.set_active(3) # 700 MB CD - def get_current_file(self): + if (self.disc_type == "dvd"): + self.winmenu.set_visible(True) + self.wframe_menu.show_all() + self.wcreate_menu.set_active(True) + else: + self.winmenu.set_visible(False) + self.wframe_menu.hide() + self.wcreate_menu.set_active(False) - """ returns the currently selected file """ - selection = self.wfiles.get_selection() - model, treeiter = selection.get_selected() + def get_current_file(self): - if treeiter is not None: - element = model[treeiter][0] - position = 0 - for row in self.wfiles.get_model(): - item = row.model[row.iter][0] - if element == item: - break - position += 1 - return ( (element, position, model, treeiter) ) - else: - return ( (None, -1, None, None) ) + """ returns the currently selected file """ + selection = self.wfiles.get_selection() + model, treeiter = selection.get_selected() - def get_all_files(self): + if treeiter is not None: + element = model[treeiter][0] + position = 0 + for row in self.wfiles.get_model(): + item = row.model[row.iter][0] + if element == item: + break + position += 1 + return ( (element, position, model, treeiter) ) + else: + return ( (None, -1, None, None) ) - retval = [] - for row in self.wfiles.get_model(): - retval.append(row.model[row.iter][0]) - return retval + def get_all_files(self): + retval = [] - def set_interface_status(self,b): + for row in self.wfiles.get_model(): + retval.append(row.model[row.iter][0]) + return retval - self.wadd_file.set_sensitive(True) - self.wdelete_file.set_sensitive(True) - self.wup_file.set_sensitive(True) - self.wdown_file.set_sensitive(True) - self.wproperties_file.set_sensitive(True) - self.wpreview_file.set_sensitive(True) - status = self.wcreate_menu.get_active() - self.wmenu_options.set_sensitive(status) + def set_interface_status(self,b): - self.pal = self.wuse_pal.get_active() + self.wadd_file.set_sensitive(True) + self.wdelete_file.set_sensitive(True) + self.wup_file.set_sensitive(True) + self.wdown_file.set_sensitive(True) + self.wproperties_file.set_sensitive(True) + self.wpreview_file.set_sensitive(True) - (element, position, model, treeiter) = self.get_current_file() - if (element is None): - self.wdelete_file.set_sensitive(False) - self.wup_file.set_sensitive(False) - self.wdown_file.set_sensitive(False) - self.wproperties_file.set_sensitive(False) - self.wpreview_file.set_sensitive(False) - else: - nfiles = len(self.wfiles.get_model()) - if (nfiles < 1): - self.wdelete_file.set_sensitive(False) - if (position == 0): - self.wup_file.set_sensitive(False) - if (position == (nfiles-1)): - self.wdown_file.set_sensitive(False) + status = self.wcreate_menu.get_active() + self.wmenu_options.set_sensitive(status) + self.pal = self.wuse_pal.get_active() - def on_cellrenderertext3_edited(self, widget, path, text): - self.wliststore_files[path][0].set_title(text) + (element, position, model, treeiter) = self.get_current_file() + if (element is None): + self.wdelete_file.set_sensitive(False) + self.wup_file.set_sensitive(False) + self.wdown_file.set_sensitive(False) + self.wproperties_file.set_sensitive(False) + self.wpreview_file.set_sensitive(False) + else: + nfiles = len(self.wfiles.get_model()) + if (nfiles < 1): + self.wdelete_file.set_sensitive(False) + if (position == 0): + self.wup_file.set_sensitive(False) + if (position == (nfiles-1)): + self.wdown_file.set_sensitive(False) - def on_use_pal_toggled(self,b): + def on_cellrenderertext3_edited(self, widget, path, text): + self.wliststore_files[path][0].set_title(text) - self.config.PAL = self.wuse_pal.get_active() - self.set_interface_status(None) + def on_cellrenderertext4_toggled(self,widget,path): + self.wliststore_files[path][0].set_show_in_menu(False if widget.get_active() else True) + def on_use_pal_toggled(self,b): - def on_wmain_window_delete_event(self,b,e=None): + self.config.PAL = self.wuse_pal.get_active() + self.set_interface_status(None) - ask = devedeng.ask.ask_window() - if (ask.run(_("Abort the current DVD and exit?"),_("Exit DeVeDe"))): - Gtk.main_quit() - return True - def title_changed(self,obj,new_title): + def on_wmain_window_delete_event(self,b,e=None): - for item in self.wliststore_files: - element = item.model[item.iter][0] - if element == obj: - item.model.set_value(item.iter,1,new_title) - self.refresh_disc_usage() + ask = devedeng.ask.ask_window() + if (ask.run(_("Abort the current DVD and exit?"),_("Exit DeVeDe"))): + Gtk.main_quit() + return True + def title_changed(self,obj,new_title): - def on_help_clicked(self,b): - - help_file = devedeng.help.help("main.html") + for item in self.wliststore_files: + element = item.model[item.iter][0] + if element == obj: + item.model.set_value(item.iter,1,new_title) + self.refresh_disc_usage() - def on_help_index_activate(self,b): - - help_file = devedeng.help.help("index.html") + def in_menu_changed(self,obj,new_inmenu): + for item in self.wliststore_files: + element = item.model[item.iter][0] + if element == obj: + item.model.set_value(item.iter,4,new_inmenu) + self.refresh_disc_usage() - def on_add_file_clicked(self,b): - ask_files = devedeng.add_files.add_files() - if (ask_files.run()): - self.add_several_files(ask_files.files) + def on_help_clicked(self,b): + + help_file = devedeng.help.help("main.html") + def on_help_index_activate(self,b): + + help_file = devedeng.help.help("index.html") - def duration_to_string(self,duration): - seconds = math.floor(duration%60) - minutes = math.floor((duration/60)%60) - hours = math.floor(duration/3600) + def on_add_file_clicked(self,b): - output = str(seconds)+"s" - if ((hours != 0) or (minutes != 0)): - output = str(minutes)+"m "+output - if (hours != 0): - output = str(hours)+"h "+output - return output + ask_files = devedeng.add_files.add_files() + if (ask_files.run()): + self.add_several_files(ask_files.files) - def add_several_files(self,file_list): - error_list = [] - for efile in file_list: - if efile.startswith("file://"): - efile = urllib.parse.unquote(efile[7:]) - new_file = devedeng.file_movie.file_movie(efile) - if (new_file.error): - error_list.append(os.path.basename(efile)) - else: - new_file.connect('title_changed',self.title_changed) - self.wliststore_files.append([new_file, new_file.title_name,True,self.duration_to_string(new_file.get_duration())]) - if (len(error_list)!=0): - devedeng.message.message_window(_("The following files could not be added:"),_("Error while adding files"),error_list) - self.set_interface_status(None) - self.refresh_disc_usage() - - - def on_delete_file_clicked(self,b): - - (element, position, model, treeiter) = self.get_current_file() - if (element is None): - return - - ask_w = devedeng.ask.ask_window() - if (ask_w.run(_("The file %(X)s (%(Y)s) will be removed.") % {"X":element.title_name, "Y":element.file_name},_("Delete file"))): - element.delete_file() - model.remove(treeiter) - self.set_interface_status(None) - self.refresh_disc_usage() - - - def on_up_file_clicked(self,b): - - (element, position, model, treeiter) = self.get_current_file() - if (element is None) or (position == 0): - return - - last_element = self.wfiles.get_model()[position-1] - self.wfiles.get_model().swap(last_element.iter,treeiter) - self.set_interface_status(None) + def duration_to_string(self,duration): + seconds = math.floor(duration%60) + minutes = math.floor((duration/60)%60) + hours = math.floor(duration/3600) - def on_down_file_clicked(self,b): + output = str(seconds)+"s" + if ((hours != 0) or (minutes != 0)): + output = str(minutes)+"m "+output + if (hours != 0): + output = str(hours)+"h "+output + return output - (element, position, model, treeiter) = self.get_current_file() - if (element is None) or (position == (len(self.wfiles.get_model())-1)): - return - last_element = self.wfiles.get_model()[position+1] - self.wfiles.get_model().swap(last_element.iter,treeiter) - self.set_interface_status(None) + def add_several_files(self,file_list): + error_list = [] + for efile in file_list: + if efile.startswith("file://"): + efile = urllib.parse.unquote(efile[7:]) + new_file = devedeng.file_movie.file_movie(efile) + if (new_file.error): + error_list.append(os.path.basename(efile)) + else: + new_file.connect('title_changed',self.title_changed) + new_file.connect('in_menu_changed',self.in_menu_changed) + self.wliststore_files.append([new_file, new_file.title_name,True,self.duration_to_string(new_file.get_duration()),new_file.show_in_menu]) + if (len(error_list)!=0): + devedeng.message.message_window(_("The following files could not be added:"),_("Error while adding files"),error_list) + self.set_interface_status(None) + self.refresh_disc_usage() + + + def on_delete_file_clicked(self,b): + + (element, position, model, treeiter) = self.get_current_file() + if (element is None): + return + + ask_w = devedeng.ask.ask_window() + if (ask_w.run(_("The file %(X)s (%(Y)s) will be removed.") % {"X":element.title_name, "Y":element.file_name},_("Delete file"))): + element.delete_file() + model.remove(treeiter) + self.set_interface_status(None) + self.refresh_disc_usage() + + + def on_up_file_clicked(self,b): + + (element, position, model, treeiter) = self.get_current_file() + if (element is None) or (position == 0): + return + + last_element = self.wfiles.get_model()[position-1] + self.wfiles.get_model().swap(last_element.iter,treeiter) + self.set_interface_status(None) + + + def on_down_file_clicked(self,b): + + (element, position, model, treeiter) = self.get_current_file() + if (element is None) or (position == (len(self.wfiles.get_model())-1)): + return + + last_element = self.wfiles.get_model()[position+1] + self.wfiles.get_model().swap(last_element.iter,treeiter) + self.set_interface_status(None) + + + def on_properties_file_clicked(self,b): + (element, position, model, treeiter) = self.get_current_file() + if (element is None): + return + element.properties() + + + def on_create_menu_toggled(self,b): + self.set_interface_status(None) + self.refresh_disc_usage() + + + def on_adjust_disc_usage_clicked(self,b): + total_resolution = 0 + fixed_size = 0 + to_adjust = [] + for f in self.get_all_files(): + estimated_size, videorate_fixed_size, audio_rate, sub_rate, width, height, time_length = f.get_size_data() + if videorate_fixed_size: + fixed_size += estimated_size + else: + fixed_size += ((audio_rate + sub_rate) * time_length) + # 76800 = 320x240, which is the smallest resolution + surface = ((float(width) * float(height)) / 76800.0) * float(time_length) + to_adjust.append( (f, surface, time_length, audio_rate, height) ) + total_resolution += surface + + if (self.disc_type == "dvd") and (self.wcreate_menu.get_active()): + fixed_size += self.menu.get_estimated_size() * 8.0 + + if (self.disc_type == "dvd"): + max_bps_base = {0: 9000} + min_bps = 300 + max_total = 10000 + elif (self.disc_type == "svcd") or (self.disc_type == "cvd"): + max_bps_base = {0: 2700} + min_bps = 200 + max_total = 2700 + elif (self.disc_type == "divx"): + max_bps_base = {0: 4854, 720: 9708, 1080: 20000} + min_bps = 300 + max_total = -1 + elif (self.disc_type == "mkv"): + max_bps_base = {0: 192, 240: 2000, 480: 14000, 720: 50000, 1080: 240000} + min_bps = 192 + max_total = -1 + else: + max_bps_base = {0: 9000} + min_bps = 300 + max_total = -1 + + if (total_resolution != 0): + remaining_disc_size = ((8000.0 * self.get_dvd_size()[0]) - fixed_size) # in kbits + for l in to_adjust: + f = l[0] + surface = l[1] + length = l[2] + audio_rate = l[3] + height = l[4] + + max_bps = max_bps_base[0] + resy = 0 + for bitrates in max_bps_base: + if (height >= bitrates) and (resy < bitrates): + resy = bitrates + max_bps = max_bps_base[bitrates] + + video_rate = (remaining_disc_size * surface) / ( length * total_resolution) + if max_total != -1: + max2 = max_total - audio_rate + if (max2 > max_bps): + max2 = max_bps + else: + max2 = max_bps + if (video_rate > max2): + video_rate = max2 + if (video_rate < min_bps): + video_rate = min_bps + f.set_auto_video_audio_rate(video_rate, audio_rate) + + self.refresh_disc_usage() + + + def refresh_disc_usage(self): + + used = 0.0 + + for f in self.get_all_files(): + estimated_size = f.get_estimated_size() + used += float(estimated_size) + + if self.wcreate_menu.get_active(): + used += float(self.menu.get_estimated_size()) + + used /= 1000.0 + + disc_size,minvrate,maxvrate = self.get_dvd_size() + + if used > disc_size: + self.wdisc_fill_level.set_fraction(1.0) + addv=1 + else: + self.wdisc_fill_level.set_fraction(used / disc_size) + addv=0 + + self.wdisc_fill_level.set_text(str(addv+int((used / disc_size)*100))+"%") + self.wdisc_fill_level.set_show_text(True) + + + def on_menu_options_clicked(self,b): + + self.menu.show_configuration(self.get_all_files()) + + + def get_dvd_size(self): + + """ Returns the size for the currently selected disk type, and the minimum and maximum + videorate for the current video disk """ + + active = self.wdisc_size.get_active() + + # here we choose the size in Mbytes for the media + if 5==active: + size=170.0 + elif 4==active: + size=700.0 + elif 3==active: + size=750.0 + elif 2==active: + size=1100.0 + elif 1==active: + size=4200.0 + else: + size=8000.0 + + if self.disc_type=="vcd": + minvrate=1152 + maxvrate=1152 + elif (self.disc_type == "svcd") or (self.disc_type == "cvd"): + minvrate=400 + maxvrate=2300 + elif (self.disc_type == "dvd"): + minvrate=400 + maxvrate=8500 + elif (self.disc_type == "divx") or (self.disc_type == "mkv"): + minvrate=300 + maxvrate=6000 + else: + minvrate = 0 + maxvrate = 8000 + + size *= 0.90 # a safe margin of 10% 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 size,minvrate,maxvrate + + + def on_disc_size_changed(self,c): + + self.refresh_disc_usage() + + + def on_create_disc_clicked(self,b): + + if self.disc_type == "dvd": + max_files = 62 + else: + max_files = -1 + + file_movies = self.get_all_files() + t = len(file_movies) + if (max_files != -1) and (t > max_files): + devedeng.message.message_window(_("The limit for this format is %(l)d files, but your project has %(h)d.") % {"l": max_files, "h" : t}, _("Too many files in the project")) + return + + data = devedeng.create_disk_window.create_disk_window() + if (not data.run()): + return + + if os.path.exists(data.path): + ask_w = devedeng.ask.ask_window() + retval = ask_w.run(_("The selected folder already exists. To create the project, Devede must delete it.\nIf you continue, the folder\n\n %s\n\n and all its contents will be deleted. Continue?") % data.path,_("Delete folder")) + if retval: + # delete only the bare minimun needed + shutil.rmtree(os.path.join(data.path,"dvd_tree"),True) + shutil.rmtree(os.path.join(data.path,"menu"),True) + shutil.rmtree(os.path.join(data.path,"movies"),True) + shutil.rmtree(os.path.join(data.path,"xml_data"),True) + if self.config.disc_type == "dvd": + try: + os.unlink(os.path.join(data.path,data.name+".iso")) + except: + pass + if (self.config.disc_type == "vcd") or (self.config.disc_type == "svcd") or (self.config.disc_type == "cvd"): + try: + os.unlink(os.path.join(data.path,data.name+".bin")) + except: + pass + try: + os.unlink(os.path.join(data.path,data.name+".cue")) + except: + pass + else: + return + + self.shutdown = data.shutdown + + run_window = devedeng.runner.runner() + + final_dependencies = [] + + if (self.disc_type == "dvd") and (self.wcreate_menu.get_active()): + processes,menu_entries = self.menu.create_dvd_menus(file_movies, data.path) + for p in processes: + run_window.add_process(p) + final_dependencies.append(p) + else: + menu_entries = None + + movie_folder = os.path.join(data.path,"movies") + try: + os.makedirs(movie_folder) + except: + pass + counter = 0 + for movie in file_movies: + p = movie.do_conversion(os.path.join(movie_folder,"movie_"+str(counter)+".mpg")) + run_window.add_process(p) + final_dependencies.append(p) + counter += 1 + + if (self.disc_type == "dvd"): + if (self.menu.at_startup == "menu_show_at_startup"): + start_with_menu = True + else: + start_with_menu = False + dvdauthor = devedeng.dvdauthor_converter.dvdauthor_converter() + dvdauthor.create_dvd_project(data.path, data.name, file_movies, menu_entries, start_with_menu, self.menu.play_all_c) + # dvdauthor must wait until all the files have been converted + for element in final_dependencies: + dvdauthor.add_dependency(element) + run_window.add_process(dvdauthor) + + cv = devedeng.converter.converter.get_converter() + isocreator = cv.get_mkiso()() + isocreator.create_iso(data.path, data.name) + isocreator.add_dependency(dvdauthor) + run_window.add_process(isocreator) + self.disc_image_name = os.path.join(data.path,data.name+".iso") + elif (self.disc_type == "vcd") or (self.disc_type == "svcd") or (self.disc_type == "cvd"): + vcdcreator = devedeng.vcdimager_converter.vcdimager_converter() + vcdcreator.create_cd_project(data.path, data.name, file_movies) + for element in final_dependencies: + vcdcreator.add_dependency(element) + run_window.add_process(vcdcreator) + self.disc_image_name = os.path.join(data.path,data.name+".cue") + else: + self.disc_image_name = None + + run_window.connect("done",self.disc_done) + self.wmain_window.hide() + self.time_start = time.time() + run_window.run() + + + def disc_done(self,object,value): + + if self.shutdown: + Gtk.main_quit() + devedeng.shutdown.shutdown() + + if value == 0: + ended = devedeng.end_job.end_window() + if self.disc_image_name is None: + do_burn = False + else: + do_burn = True + if (ended.run(time.time() - self.time_start, do_burn)): + cv = devedeng.converter.converter.get_converter() + burner = cv.get_burner()() + burner.burn(self.disc_image_name) + run_window = devedeng.runner.runner(False) + run_window.add_process(burner) + run_window.connect("done", self.disc_done2) + run_window.run() + return + + self.wmain_window.show() + + + def disc_done2(self,object, value): + + self.wmain_window.show() + + + def on_preview_file_clicked(self,b): + + (element, position, model, treeiter) = self.get_current_file() + if (element is None): + return + element.do_preview() + + + def on_settings_activate(self,b): + + w = devedeng.settings.settings_window() + + + def on_about_activate(self,b): + + w = devedeng.about.about_window() + + + def on_new_activate(self,b): + + w = devedeng.ask.ask_window() + if w.run(_("Close current project and start a fresh one?"), _("New project")): + self.wliststore_files.clear() + self.project_file = None + self.wmain_window.hide() + devedeng.choose_disc_type.choose_disc_type() + + + def on_wmain_window_drag_motion(self,wid, context, x, y, time): + Gdk.drag_status(context, Gdk.DragAction.COPY, time) + return True + + + def on_wmain_window_drag_drop(self, wid, context, x, y, time): + # Used with windows drag and drop + return True + + + def on_wmain_window_drag_data_received(self, widget, drag_context, x,y, data, info, time): + uris = data.get_uris() + self.add_several_files(uris) + Gtk.drag_finish (drag_context, True, Gdk.DragAction.COPY, time); + + + def on_save_activate(self,b): + if self.project_file is not None: + self.save_current_project() + else: + self.on_save_as_activate(None) - def on_properties_file_clicked(self,b): - (element, position, model, treeiter) = self.get_current_file() - if (element is None): - return - element.properties() - - - def on_create_menu_toggled(self,b): - self.set_interface_status(None) - self.refresh_disc_usage() - - - def on_adjust_disc_usage_clicked(self,b): - total_resolution = 0 - fixed_size = 0 - to_adjust = [] - for f in self.get_all_files(): - estimated_size, videorate_fixed_size, audio_rate, sub_rate, width, height, time_length = f.get_size_data() - if videorate_fixed_size: - fixed_size += estimated_size - else: - fixed_size += ((audio_rate + sub_rate) * time_length) - # 76800 = 320x240, which is the smallest resolution - surface = ((float(width) * float(height)) / 76800.0) * float(time_length) - to_adjust.append( (f, surface, time_length, audio_rate, height) ) - total_resolution += surface - - if (self.disc_type == "dvd") and (self.wcreate_menu.get_active()): - fixed_size += self.menu.get_estimated_size() * 8.0 - - if (self.disc_type == "dvd"): - max_bps_base = {0: 9000} - min_bps = 300 - max_total = 10000 - elif (self.disc_type == "svcd") or (self.disc_type == "cvd"): - max_bps_base = {0: 2700} - min_bps = 200 - max_total = 2700 - elif (self.disc_type == "divx"): - max_bps_base = {0: 4854, 720: 9708, 1080: 20000} - min_bps = 300 - max_total = -1 - elif (self.disc_type == "mkv"): - max_bps_base = {0: 192, 240: 2000, 480: 14000, 720: 50000, 1080: 240000} - min_bps = 192 - max_total = -1 - else: - max_bps_base = {0: 9000} - min_bps = 300 - max_total = -1 - - if (total_resolution != 0): - remaining_disc_size = ((8000.0 * self.get_dvd_size()[0]) - fixed_size) # in kbits - for l in to_adjust: - f = l[0] - surface = l[1] - length = l[2] - audio_rate = l[3] - height = l[4] - - max_bps = max_bps_base[0] - resy = 0 - for bitrates in max_bps_base: - if (height >= bitrates) and (resy < bitrates): - resy = bitrates - max_bps = max_bps_base[bitrates] - - video_rate = (remaining_disc_size * surface) / ( length * total_resolution) - if max_total != -1: - max2 = max_total - audio_rate - if (max2 > max_bps): - max2 = max_bps - else: - max2 = max_bps - if (video_rate > max2): - video_rate = max2 - if (video_rate < min_bps): - video_rate = min_bps - f.set_auto_video_audio_rate(video_rate, audio_rate) - - self.refresh_disc_usage() - - - def refresh_disc_usage(self): - - used = 0.0 - - for f in self.get_all_files(): - estimated_size = f.get_estimated_size() - used += float(estimated_size) - - if self.wcreate_menu.get_active(): - used += float(self.menu.get_estimated_size()) - - used /= 1000.0 - - disc_size,minvrate,maxvrate = self.get_dvd_size() - - if used > disc_size: - self.wdisc_fill_level.set_fraction(1.0) - addv=1 - else: - self.wdisc_fill_level.set_fraction(used / disc_size) - addv=0 - - self.wdisc_fill_level.set_text(str(addv+int((used / disc_size)*100))+"%") - self.wdisc_fill_level.set_show_text(True) - - - def on_menu_options_clicked(self,b): - - self.menu.show_configuration(self.get_all_files()) - - - def get_dvd_size(self): - - """ Returns the size for the currently selected disk type, and the minimum and maximum - videorate for the current video disk """ - - active = self.wdisc_size.get_active() - - # here we choose the size in Mbytes for the media - if 5==active: - size=170.0 - elif 4==active: - size=700.0 - elif 3==active: - size=750.0 - elif 2==active: - size=1100.0 - elif 1==active: - size=4200.0 - else: - size=8000.0 - - if self.disc_type=="vcd": - minvrate=1152 - maxvrate=1152 - elif (self.disc_type == "svcd") or (self.disc_type == "cvd"): - minvrate=400 - maxvrate=2300 - elif (self.disc_type == "dvd"): - minvrate=400 - maxvrate=8500 - elif (self.disc_type == "divx") or (self.disc_type == "mkv"): - minvrate=300 - maxvrate=6000 - else: - minvrate = 0 - maxvrate = 8000 - - size *= 0.90 # a safe margin of 10% 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 size,minvrate,maxvrate - - - def on_disc_size_changed(self,c): - - self.refresh_disc_usage() - - - def on_create_disc_clicked(self,b): - - if self.disc_type == "dvd": - max_files = 62 - else: - max_files = -1 - - file_movies = self.get_all_files() - t = len(file_movies) - if (max_files != -1) and (t > max_files): - devedeng.message.message_window(_("The limit for this format is %(l)d files, but your project has %(h)d.") % {"l": max_files, "h" : t}, _("Too many files in the project")) - return - - data = devedeng.create_disk_window.create_disk_window() - if (not data.run()): - return - - if os.path.exists(data.path): - ask_w = devedeng.ask.ask_window() - retval = ask_w.run(_("The selected folder already exists. To create the project, Devede must delete it.\nIf you continue, the folder\n\n %s\n\n and all its contents will be deleted. Continue?") % data.path,_("Delete folder")) - if retval: - # delete only the bare minimun needed - shutil.rmtree(os.path.join(data.path,"dvd_tree"),True) - shutil.rmtree(os.path.join(data.path,"menu"),True) - shutil.rmtree(os.path.join(data.path,"movies"),True) - shutil.rmtree(os.path.join(data.path,"xml_data"),True) - if self.config.disc_type == "dvd": - try: - os.unlink(os.path.join(data.path,data.name+".iso")) - except: - pass - if (self.config.disc_type == "vcd") or (self.config.disc_type == "svcd") or (self.config.disc_type == "cvd"): - try: - os.unlink(os.path.join(data.path,data.name+".bin")) - except: - pass - try: - os.unlink(os.path.join(data.path,data.name+".cue")) - except: - pass - else: - return - - self.shutdown = data.shutdown - - run_window = devedeng.runner.runner() - - final_dependencies = [] - - if (self.disc_type == "dvd") and (self.wcreate_menu.get_active()): - processes,menu_entries = self.menu.create_dvd_menus(file_movies, data.path) - for p in processes: - run_window.add_process(p) - final_dependencies.append(p) - else: - menu_entries = None - - movie_folder = os.path.join(data.path,"movies") - try: - os.makedirs(movie_folder) - except: - pass - counter = 0 - for movie in file_movies: - p = movie.do_conversion(os.path.join(movie_folder,"movie_"+str(counter)+".mpg")) - run_window.add_process(p) - final_dependencies.append(p) - counter += 1 - - if (self.disc_type == "dvd"): - if (self.menu.at_startup == "menu_show_at_startup"): - start_with_menu = True - else: - start_with_menu = False - dvdauthor = devedeng.dvdauthor_converter.dvdauthor_converter() - dvdauthor.create_dvd_project(data.path, data.name, file_movies, menu_entries, start_with_menu, self.menu.play_all_c) - # dvdauthor must wait until all the files have been converted - for element in final_dependencies: - dvdauthor.add_dependency(element) - run_window.add_process(dvdauthor) - - cv = devedeng.converter.converter.get_converter() - isocreator = cv.get_mkiso()() - isocreator.create_iso(data.path, data.name) - isocreator.add_dependency(dvdauthor) - run_window.add_process(isocreator) - self.disc_image_name = os.path.join(data.path,data.name+".iso") - elif (self.disc_type == "vcd") or (self.disc_type == "svcd") or (self.disc_type == "cvd"): - vcdcreator = devedeng.vcdimager_converter.vcdimager_converter() - vcdcreator.create_cd_project(data.path, data.name, file_movies) - for element in final_dependencies: - vcdcreator.add_dependency(element) - run_window.add_process(vcdcreator) - self.disc_image_name = os.path.join(data.path,data.name+".cue") - else: - self.disc_image_name = None - - run_window.connect("done",self.disc_done) - self.wmain_window.hide() - self.time_start = time.time() - run_window.run() - - - def disc_done(self,object,value): - - if self.shutdown: - Gtk.main_quit() - devedeng.shutdown.shutdown() - - if value == 0: - ended = devedeng.end_job.end_window() - if self.disc_image_name is None: - do_burn = False - else: - do_burn = True - if (ended.run(time.time() - self.time_start, do_burn)): - cv = devedeng.converter.converter.get_converter() - burner = cv.get_burner()() - burner.burn(self.disc_image_name) - run_window = devedeng.runner.runner(False) - run_window.add_process(burner) - run_window.connect("done", self.disc_done2) - run_window.run() - return - - self.wmain_window.show() - - - def disc_done2(self,object, value): - - self.wmain_window.show() - - - def on_preview_file_clicked(self,b): - - (element, position, model, treeiter) = self.get_current_file() - if (element is None): - return - element.do_preview() - - - def on_settings_activate(self,b): - - w = devedeng.settings.settings_window() - - - def on_about_activate(self,b): - - w = devedeng.about.about_window() - - - def on_new_activate(self,b): - - w = devedeng.ask.ask_window() - if w.run(_("Close current project and start a fresh one?"), _("New project")): - self.wliststore_files.clear() - self.project_file = None - self.wmain_window.hide() - devedeng.choose_disc_type.choose_disc_type() - - - def on_wmain_window_drag_motion(self,wid, context, x, y, time): - Gdk.drag_status(context, Gdk.DragAction.COPY, time) - return True - - - def on_wmain_window_drag_drop(self, wid, context, x, y, time): - # Used with windows drag and drop - return True - - - def on_wmain_window_drag_data_received(self, widget, drag_context, x,y, data, info, time): - uris = data.get_uris() - self.add_several_files(uris) - Gtk.drag_finish (drag_context, True, Gdk.DragAction.COPY, time); - - - def on_save_activate(self,b): - if self.project_file is not None: - self.save_current_project() - else: - self.on_save_as_activate(None) + def on_save_as_activate(self,b): + while True: + w = devedeng.opensave.opensave_window(True) + retval = w.run(self.project_file) + if retval is None: + return + if not retval.endswith(".devedeng"): + retval += ".devedeng" + if os.path.isfile(retval): + w = devedeng.ask.ask_window() + if not w.run(_("The file already exists. Overwrite it?"), _("The file already exists")): + continue + self.project_file = retval + self.save_current_project() + return - def on_save_as_activate(self,b): - while True: - w = devedeng.opensave.opensave_window(True) - retval = w.run(self.project_file) - if retval is None: - return - if not retval.endswith(".devedeng"): - retval += ".devedeng" - if os.path.isfile(retval): - w = devedeng.ask.ask_window() - if not w.run(_("The file already exists. Overwrite it?"), _("The file already exists")): - continue - self.project_file = retval - self.save_current_project() - return + def on_load_activate(self,b): + w = devedeng.opensave.opensave_window(False) + retval = w.run() + if retval is not None: + self.load_project(retval) - def on_load_activate(self,b): - w = devedeng.opensave.opensave_window(False) - retval = w.run() - if retval is not None: - self.load_project(retval) + def save_current_project(self): + project = {} - def save_current_project(self): + project["PAL"] = self.wuse_pal.get_active() + project["create_menu"] = self.wcreate_menu.get_active() + project["disc_type"] = self.config.disc_type + project["disc_size"] = self.wdisc_size.get_active() + project["files"] = [] + f = self.get_all_files() + for i in f: + project["files"].append(i.store_file()) + if self.disc_type == "dvd": + project["menu"] = self.menu.store_menu() - project = {} + with open(self.project_file, 'wb') as f: + pickle.dump(project, f, 3) - project["PAL"] = self.wuse_pal.get_active() - project["create_menu"] = self.wcreate_menu.get_active() - project["disc_type"] = self.config.disc_type - project["disc_size"] = self.wdisc_size.get_active() - project["files"] = [] - f = self.get_all_files() - for i in f: - project["files"].append(i.store_file()) - if self.disc_type == "dvd": - project["menu"] = self.menu.store_menu() - with open(self.project_file, 'wb') as f: - pickle.dump(project, f, 3) + def load_project(self,project_file): - - def load_project(self,project_file): - - self.wliststore_files.clear() - self.project_file = project_file - with open(project_file, 'rb') as f: - project = pickle.load(f) - if "disc_type" in project: - self.config.set_disc_type(project["disc_type"]) - if "PAL" in project: - self.wuse_pal.set_active(project["PAL"]) - if "create_menu" in project: - self.wcreate_menu.set_active(project["create_menu"]) - if "disc_size" in project: - self.wdisc_size.set_active(project["disc_size"]) - if "menu" in project: - self.menu.restore_menu(project["menu"]) - if "files" in project: - error_list = [] - for efile in project["files"]: - new_file = devedeng.file_movie.file_movie(efile["file_name"]) - if (new_file.error): - error_list.append(os.path.basename(efile["file_name"])) - else: - new_file.restore_file(efile) - new_file.connect('title_changed',self.title_changed) - self.wliststore_files.append([new_file, new_file.title_name,True,self.duration_to_string(new_file.get_duration())]) - if (len(error_list)!=0): - devedeng.message.message_window(_("The following files in the project could not be added again:"),_("Error while adding files"),error_list) - self.set_interface_status(None) - self.refresh_disc_usage() - - - def on_multiproperties_activate(self,b): - - e = devedeng.file_movie.file_movie(None,self.get_all_files()) - e.properties() + self.wliststore_files.clear() + self.project_file = project_file + with open(project_file, 'rb') as f: + project = pickle.load(f) + if "disc_type" in project: + self.config.set_disc_type(project["disc_type"]) + if "PAL" in project: + self.wuse_pal.set_active(project["PAL"]) + if "create_menu" in project: + self.wcreate_menu.set_active(project["create_menu"]) + if "disc_size" in project: + self.wdisc_size.set_active(project["disc_size"]) + if "menu" in project: + self.menu.restore_menu(project["menu"]) + if "files" in project: + error_list = [] + for efile in project["files"]: + new_file = devedeng.file_movie.file_movie(efile["file_name"]) + if (new_file.error): + error_list.append(os.path.basename(efile["file_name"])) + else: + new_file.restore_file(efile) + new_file.connect('title_changed',self.title_changed) + self.wliststore_files.append([new_file, new_file.title_name,True,self.duration_to_string(new_file.get_duration())]) + if (len(error_list)!=0): + devedeng.message.message_window(_("The following files in the project could not be added again:"),_("Error while adding files"),error_list) + self.set_interface_status(None) + self.refresh_disc_usage() + + + def on_multiproperties_activate(self,b): + + e = devedeng.file_movie.file_movie(None,self.get_all_files()) + e.properties()