#!/usr/bin/env python
# coding: UTF-8

###############################################################################
# traGtor is a GUI for ffmpeg/avlib written 2008/2009 by Markus Schmidt       #
# http://mein-neues-blog.de                                                   #
#                                                                             #
# traGtor is written completely in Python and uses GTK as toolkit.            #
# It depends on ffmpeg/avlib and id3v2 and needs Python > 2.5 with            #
# pygtk-support                                                               #
#                                                                             #
# It is released under a GPL license which should be included in the archives #
###############################################################################

import lang_en
import lang_de
import lang_cz
import lang_it
import lang_es
import lang_br
import lang_zh
import lang_fr
import lang_ru
import sys
import os, os.path
import subprocess as sub
import gobject
import pango
import re, string
import datetime, time
import signal
import urllib
import hashlib
import multiprocessing
import ConfigParser as config
import dbus
from threading import Thread
try:
    import pygtk
    pygtk.require("2.6")
except:
    pass
try:
    import gtk
    import gtk.glade
except:
    sys.exit(1)
    
#gtk.gdk.threads_init()
gobject.threads_init()

basedir = os.path.dirname(os.path.realpath(__file__))
if not os.path.exists(os.path.join(basedir, "tragtor.py")):
    if os.path.exists(os.path.join(os.getcwd(), "tragtor.py")):
        basedir = os.getcwd()
sys.path.insert(0, basedir)

"""We need to determine the right command since the FFmpeg community is horribly
at loggerheads and it may be ffmpeg or avconv"""

_COMMAND = ""
def _command():
    global _COMMAND
    if not _COMMAND:
        if not os.system("which avconv >/dev/null 2>&1"):
            _COMMAND = "avconv"
        else:
            _COMMAND = "ffmpeg"
    return _COMMAND
_command()

class tragtorGUI(Thread):
    """This class is a GUI for ffmpeg/avlib"""
    
    _VERSION = open(os.path.join(sys.path[0], 'version')).read().strip()
    _TITLE = "traGtor %s" % _VERSION
    _AUTHOR = "Markus Schmidt in 2008/09\nhttp://mein-neues-blog.de"
    
    _LANGUAGE = "en"
    _LANGUAGES = {"en":"English", "de":"Deutsch", "cz":"čeština", "it":"Italiano", "es":"Español", "br":"Brasil", "zh":"简体中文", "fr":"Français", "ru":"русский"}
    
    _AUDIOSAMPLERATES = [8000,
                         11025,
                         22050,
                         32000,
                         44056,
                         44100,
                         47250,
                         48000,
                         50000,
                         50400,
                         88200,
                         96000,
                         176400,
                         192000]
    _AUDIOBITRATES = [ 8,
                       16,
                       32,
                       40,
                       48,
                       56,
                       64,
                       80,
                       96,
                       112,
                       128,
                       160,
                       192,
                       224,
                       256,
                       320,
                       384,
                       512,
                       1250,
                       1411,
                       5000,
                       15000,
                       36000,
                       54000]
    _DEFAULTBITRATE = 128
    _AUDIOCHANNELS = [ 1, 2, 3, 4, 5, 6, 7, 8 ]
    _SCALINGMETHODS = [ "Pad", "Crop", "Distort" ]
    _CACHEFORMAT = ["Width",
                    "Height",
                    "Framerate",
                    "Bitrate",
                    "AudioBitrate",
                    "AudioChannels",
                    "AudioSamplerate",
                    "Offset",
                    "Duration",
                    "Ratio"]
    _PAGES = ["in_file", "format", "meta", "proceed", "settings"]
    
    _COM_COLLAPSE = ("vf",)
    
    _CPU_USAGE_MODES = ["Soft", "Medium", "Aggressive"]
    _VIDEOFILTERS = ["Pad, Crop & Size", "Video Filter (x:y:w:h)", "Video Filter (w:h:x:y)"]
    _BITRATEMODES = ["-b / -ab", "-b:v / -b:a"]
    _PROGRESS_ACTIONS = ["Nothing", "Play File", "Close Progress Window", "Close traGtor",
                         "Shutdown", "Hibernate", "Suspend"]
    _STREAM_SEPARATORS = [".", ":"]
    _CFG_PATH = os.path.expanduser("~") + "/.tragtor"
    _CFG_PRESETS = "presets.cfg"
    _CFG_SETTINGS = "tragtor.cfg"
    _CACHE_PATH = os.path.join(_CFG_PATH, "cache")
    _DEFAULT_SETTINGS = {"language":"en",
                         "presetContainer":True,
                         "videofilter":0,
                         "cpuUsage":1,
                         "cleanup2Pass":True,
                         "bitrateMode":0,
                         "progressActions":0,
                         "streamSeparator":1,
                         "containerColumns":3,
                         "command":"",
                         "newstreamOption":True}
    _DEFAULT_PRESET = {"Width":320,
                       "Height":240,
                       "Ratio":1.3333333,
                       "FixedRatio":True,
                       "Bitrate":1024,
                       "Framerate":25,
                       "Deinterlace":False,
                       "AudioSamplerate":44100,
                       "AudioBitrate":128,
                       "AudioCodec":"",
                       "AudioChannels":2,
                       "Volume":256,
                       "Codec":"",
                       "Scaling":0,
                       "PadColor":"#000000000000",
                       "HiQ":True,
                       "2Pass":False,
                       "2PassNA":False,
                       "UserDefined":"",
                       "Container":""}
    _BACKGROUND_COLORS = [ "#BFE9C4",
                           "#E9DFBF",
                           "#BFC7E9",
                           "#E9BFE1",
                           "#E7E9BF",
                           "#D6BFE9",
                           "#BFE7E9",
                           "#E9BFC1"]
    
    if os.path.isfile("/usr/bin/gnome-open"):
        _OPENCOMMAND = "gnome-open"
    elif os.path.isfile("/usr/bin/kde-open"):
        _OPENCOMMAND = "kde-open"
    else:
        _OPENCOMMAND = False
    
    _settingsCPU = 1
    _videoFilter = 0
    _bitrateMode = 0
    _progressActions = 0
    _streamSeparator = 0
    
    _inFiles = []
    _videoStreams = []
    _audioStreams = []
    _previewThreads = []
    _inErrors = []
    _outFile = None
    
    if os.path.isdir(os.path.expanduser("~") + "/Desktop"):
        _defFile = os.path.expanduser("~") + "/Desktop"
    else:
        _defFile = os.path.expanduser("~") 
    
    _defFileName = "traGtor.output"
    _argInFiles = []
    _inFileAccessible = False
    _inFileReadable = False
    _outFileWriteable = False
    _outFileAccessible = False
    _outFileSize = 0
    
    _canProceed = False
    
    _outFileFormat = []
    _inStream = 0
    _inFileAdd = False
    
    _defaultWidth = 320
    _defaultHeight = 240
    _defaultRatio = 1.3333
    _defaultFixedRatio = True
    _defaultBitrate = 1024
    _defaultFramerate = 25
    _defaultDeinterlace = False
    _defaultAudioSamplerate = 44100
    _defaultAudioBitrate = 128
    _defaultAudioCodec = ""
    _defaultAudioChannels = 2
    _defaultVolume = 256
    _defaultCodec = ""
    _defaultOffset = 0
    _defaultDuration = 0
    _defaultScaling = 0
    _defaultPadColor = "#000000000000"
    _defaultHiQ = True
    _defaultBitrateVariation = 10
    _default2Pass = False
    _default2PassNA = False
    _defaultUserDefined = ""
    
    _codec_streamcopy = "[streamcopy]"
    _codec_filename = "[none]"
        
    _metaTitle = ""
    _metaAuthor = ""
    _metaCopyleft = ""
    _metaComment = ""
    _metaEnable = False
    _defaultMetaEnable = False
    
    _eec = 1
    _inProgress = False
    _cancelProcess = False
    _execute = ""
    _execute2 = ""
    _currentPass = 1
    _currpass = None
    _progressInStreams = False
    _progressFinishedGracefully = False
    _ffmpegOut = ""
    
    _formatMaxHeight = 100000000
    _formatMaxWidth = 100000000
    
    _previewOffset = 60.0
    _previewWidth = 24
    _previewHeight = 24
    _loadingAnimation = os.path.join(sys.path[0], "loading.svg")
    
    _languageCombos = [
            ["formatScaling", "format_scaling_methods_list"],
            ["settingsCPU", "cpu_usage_modes"],
            ["videoFilter", "video_filters"],
            ["bitrateMode", "bitrate_modes"],
            ["progressActions", "progress_actions"],
            ["streamSeparator", "stream_separators"]
            ]

    def __init__(self, argv=sys.argv):
        """Initiate the program"""
        
        signal.signal(signal.SIGINT, signal.SIG_IGN)
        signal.signal(signal.SIGINT, self.ctrlC)
        
        ### FIRST STEPS
        
        # change working directory for arguments
        #os.chroot(os.getcwd())
        
        if not os.path.exists(self._CFG_PATH):
            os.mkdir(self._CFG_PATH)
        if not os.path.exists(self._CACHE_PATH):
            os.mkdir(self._CACHE_PATH)
                
        # Create config file paths
        self._CFG_PRESETS = os.path.join(self._CFG_PATH, self._CFG_PRESETS)
        self._CFG_SETTINGS = os.path.join(self._CFG_PATH, self._CFG_SETTINGS)
        # Initiate config objects
        self.config = self.start_config(self._CFG_SETTINGS,
                                        self._DEFAULT_SETTINGS,
                                        ["Settings"],
                                        True)
        self.presets = self.start_config(self._CFG_PRESETS,
                                         self._DEFAULT_PRESET,
                                         [],
                                         True)
        
        # read ffmpeg's options and config
        self.ffmpegConfig = ffmpegConfig(self._command())
        #Thread.__init__(self)
        
        # create a window and it's corresponding internal objects
        self.createWindow()
        self.createWidgetObjects()
        self.setIcons(self.tragtorWindow)
        
        # Set Language
        if self.config.has_option("Settings", "language") \
        and self.config.get("Settings", "language") in self._LANGUAGES:
            self._LANGUAGE = self.config.get("Settings", "language")
        else:
            try:
                ln = gtk.get_default_language().to_string()[0:2]
                if ln in self._LANGUAGES:
                    self._LANGUAGE = ln
            except:
                True
        self.setLanguage()
        
        # Set Videofilter
        if self.config.has_option("Settings", "videofilter"):
            try:
                test = self._VIDEOFILTERS[int(self.config.get("Settings",
                                                              "videofilter"))]
                self._videoFilter = int(self.config.get("Settings",
                                                        "videofilter"))
            except:
                pass
        
        # Set Bitrate Mode
        if self.config.has_option("Settings", "bitratemode"):
            try:
                test = self._BITRATEMODES[int(self.config.get("Settings",
                                                              "bitratemode"))]
                self._bitrateMode = int(self.config.get("Settings",
                                                        "bitratemode"))
            except:
                pass
        
        # Set CPU usage
        if self.config.has_option("Settings", "cpuUsage"):
            try:
                test = self._CPU_USAGE_MODES[int(self.config.get("Settings",
                                                                 "cpuUsage"))]
                self._settingsCPU = int(self.config.get("Settings",
                                                      "cpuUsage"))
            except:
                pass
        
        # Set Action After
        if self.config.has_option("Settings", "progressActions"):
            try:
                test = self._PROGRESS_ACTIONS[int(self.config.get("Settings",
                                                                 "progressActions"))]
                self._progressActions = int(self.config.get("Settings",
                                                      "progressActions"))
            except:
                pass
        
        # Set Stream Separator
        if self.config.has_option("Settings", "streamSeparator"):
            try:
                test = self._STREAM_SEPARATORS[int(self.config.get("Settings",
                                                                 "streamSeparator"))]
                self._streamSeparator = int(self.config.get("Settings",
                                                      "streamSeparator"))
            except:
                pass
                
        # Set preset container switch
        if self.config.has_option("Settings", "presetContainer"):
            self.presetContainer.set_active(eval(self.config.get("Settings",
                                                            "presetContainer")))
        
        # Set cleanup 2 pass switch
        if self.config.has_option("Settings", "cleanup2Pass"):
            self.cleanup2Pass.set_active(eval(self.config.get("Settings",
                                                            "cleanup2Pass")))
        # Set newstream switch
        if self.config.has_option("Settings", "newstream"):
            self.newstream.set_active(eval(self.config.get("Settings",
                                                            "newstream")))
                                                        
        ### CREATE MISSING WIDGETS AND GADGETS
        # Audio-Tree
        # generates a treestore for the audio-treview
        self.inFileAudioStore = gtk.ListStore(
            gobject.TYPE_BOOLEAN,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
        )
        self.inFileAudioTree.set_model(self.inFileAudioStore)
        self.inFileAudioSelection = self.inFileAudioTree.get_selection()
        self.inFileAudioSelection.set_mode(gtk.SELECTION_MULTIPLE)
        
        # Video-Tree
        # generates a treestore for the video-treview
        self.inFileVideoStore = gtk.ListStore(
            gobject.TYPE_BOOLEAN,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gtk.gdk.Pixbuf
        )
        self.inFileVideoTree.set_model(self.inFileVideoStore)
        self.inFileVideoSelection = self.inFileVideoTree.get_selection()
        self.inFileVideoSelection.set_mode(gtk.SELECTION_MULTIPLE)
        
        # Open-Tree
        # generates a treestore for the open-treviewself.inFileMenu
        self.inFileOpenStore = gtk.ListStore(
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
            gobject.TYPE_STRING,
        )
        self.inFileOpenTree.set_model(self.inFileOpenStore)
        self.inFileOpenSelection = self.inFileOpenTree.get_selection()
        self.inFileOpenSelection.set_mode(gtk.SELECTION_SINGLE)
        
        # ffmpegOutText Object
        self.ffmpegOutText = gtk.TextBuffer()
        self.ffmpegOut.set_buffer(self.ffmpegOutText)
        self.ffmpegOut.modify_font(pango.FontDescription('mono 8'))


        # Language Selector
        for lan, lanstr in self._LANGUAGES.iteritems():
            self.languageSelector.append_text(lanstr)
        self.languageSelector.set_active(self._LANGUAGES.keys().index(self._LANGUAGE))
        
        # Videofilter Selector
        self.videoFilter.set_active(self._videoFilter)
        
        # bitratemode Selector
        self.bitrateMode.set_active(self._bitrateMode)
        
        # CPU usage Selector
        self.settingsCPU.set_sensitive(multiprocessing.cpu_count() > 1)
        self.settingsCPU.set_active(self._settingsCPU)
        
        # Presets
        for pre in self.presets.sections():
            self.presetName.append_text(pre)
        
        #AudioSamplerates
        for lan in self._AUDIOSAMPLERATES:
            self.formatAudioSamplerate.append_text("%i" % lan)
        self.formatAudioSamplerate.set_wrap_width(2)
        
        #AudioBitrates
        for lan in self._AUDIOBITRATES:
            self.formatAudioBitrate.append_text("%i" % lan)
        self.formatAudioBitrate.set_wrap_width(4)
        
        #AudioChannels
        for lan in self._AUDIOCHANNELS:
            self.formatAudioChannels.append_text("%i" % lan)
        
        #AudioCodecs
        self.formatAudioCodec.append_text(self._codec_filename)
        self.formatAudioCodec.append_text(self._codec_streamcopy)
        for lan in self.ffmpegConfig._saveAudioCodecs:
            self.formatAudioCodec.append_text(lan)
        self.formatAudioCodec.set_active(0)
        self.formatAudioCodec.set_wrap_width(4)

        #VideoCodecs
        self.formatCodec.append_text(self._codec_filename)
        self.formatCodec.append_text(self._codec_streamcopy)
        for lan in self.ffmpegConfig._saveVideoCodecs:
            self.formatCodec.append_text(lan)
        self.formatCodec.set_active(0)
        self.formatCodec.set_wrap_width(4)
        
        #OutfileSuffix
        self.outFileSuffix.append_text(self.lang.output_file_suffix_auto)
        for lan in self.ffmpegConfig._saveFileFormats:
            self.outFileSuffix.append_text("%s - %s (.%s)" % (lan[0],
                                                              lan[1],
                                                              lan[2]))
        if self.config.has_option("Settings", "containerColumns"):
            _ww = int(self.config.get("Settings", "containerColumns"))
        else:
            _ww = 3
        self.outFileSuffix.set_wrap_width(_ww)
        
        #in/outFile Filters
        self.reloadInFileFilter()
        self.reloadOutFileFilter()
        
        #duration-adjustment
        self.formatDurationAdjustment = gtk.Adjustment(0, 0, 21600, 0.001, 1, 0)
        self.formatDuration.set_adjustment(self.formatDurationAdjustment)
        
        #offset-adjustment
        self.formatOffsetAdjustment = gtk.Adjustment(0, 0, 21600, 0.001, 1, 0)
        self.formatOffset.set_adjustment(self.formatOffsetAdjustment)
        
        #ratio spin
        self.formatRatio.set_increments(0.0001,0.01)
        
        #hide changed-icons
        for i in self._CACHEFORMAT:
            if self.window.get_widget("button" + i):
                self.window.get_widget("button" + i).hide()
        
        # Previews in inFileCooser
        self.inFileChooser.set_preview_widget_active(True)
                
        #title
        self.window.get_widget("tragtor").set_title(
            self._TITLE + " :: " + eval("self.lang." + self._PAGES[0] + "_title")
        )
        
        # Arguments
        c = 0
        self._argInFiles = []
        for i in sys.argv:
            if c >= 1:
                f = i
                if f.startswith("file://"):
                    f = f[8:]
                if f[0] != "/":
                    f = os.path.normpath(os.getcwd() + "/" + f)
                if os.path.isfile(f):
                    self._argInFiles.append(f)
            c += 1
        if len(self._argInFiles) == 0 \
        and self.config.has_option("Settings", "inFiles"):
            _argInFiles = eval(self.config.get("Settings", "inFiles"))
            for i in _argInFiles:
                if os.path.isfile(i):
                    self._argInFiles.append(i)
        # BackwardCompat inFile
        if self.config.has_option("Settings", "inFile"):
            conffile = self.config.get("Settings", "inFile")
            if os.path.isfile(conffile):
                self._argInFiles.append(conffile)
            self.config.remove_option("Settings", "inFile")
        
        # Set inFileAdd
        if self.config.has_option("Settings", "inFileAdd"):
            self._inFileAdd = eval(self.config.get("Settings", "inFileAdd"))
        
        ### Communicate the rest
        self.connectWindow()
        self.reset()
        self.toggleNoAudio(self._format2Pass)
        
        # D'n'D inFileTree
        TARGET_TYPE_URI_LIST = 80
        dnd_list = [ ( 'text/uri-list', 0, TARGET_TYPE_URI_LIST ) ]
        self.inFileOpenTree.drag_dest_set(gtk.DEST_DEFAULT_MOTION
                                          | gtk.DEST_DEFAULT_HIGHLIGHT
                                          | gtk.DEST_DEFAULT_DROP,
                                          dnd_list,
                                          gtk.gdk.ACTION_COPY)
        #self.inFileOpenTree.connect('drag_data_received', self.drag_drop_themefile)

    def _command(self):
        if self.config.has_option("Settings", "command") \
        and self.config.get("Settings", "command") != "":
            return self.config.get("Settings", "command")
        return _command()
        
#######################################
# PRESETS
#######################################    
    
    def deletePreset(self, widget):
        """deletes a preset from config and combobox"""
        name = self.presetName.child.get_text()
        delete = False
        if self.presets.has_section(name):
            message = self.lang.question_delete_preset % name
            image = gtk.gdk.pixbuf_new_from_file(
                os.path.join(os.path.dirname(
                    os.path.realpath(__file__)
                ), "icons/" + self.getIconColor(self.tragtorWindow) + "/question.svg")
            )
            delete = self.messageDialog(
                message, self.lang.question_title,
                gtk.MESSAGE_WARNING,
                gtk.BUTTONS_OK_CANCEL,
                image)
        if delete == gtk.RESPONSE_OK:
            self.presets.remove_section(name)
            self.presets.write(open(self._CFG_PRESETS, "w"))
            #try:
            model = self.presetName.get_model()
            i = model.get_iter_first()
            while i:
                if model.get_value(i, 0) == name:
                    sel = i
                    break
                i = model.iter_next(i)
            try:
                model.remove(sel)
            except:
                1
            self.presetName.child.set_text("")
    
    def openPreset(self, widget):
        """opens a preset from config and sets the values"""
        name = self.presetName.child.get_text()
        if self.presets.has_section(name):
            self.presetFormat(name)
            self.fillFormat()
        
    def savePreset(self, widget):
        """saves a preset to config and adds it to combobox"""
        save = False
        name = self.presetName.child.get_text()
        if not self.presets.has_section(name) and name != "":
            self.presets.add_section(name);
            self.presetName.append_text(name)
            save = True
        elif name != "":
            message = self.lang.question_overwrite_preset % name
            image = gtk.gdk.pixbuf_new_from_file(
                os.path.join(os.path.dirname(
                    os.path.realpath(__file__)
                ), "icons/" + self.getIconColor(self.tragtorWindow) + "/question.svg")
            )
            save = self.messageDialog(
                message,
                self.lang.question_title,
                gtk.MESSAGE_WARNING,
                gtk.BUTTONS_OK_CANCEL,
                image)
        if save == gtk.RESPONSE_OK or save == True:
            for i in self._DEFAULT_PRESET:
                try:
                    self.presets.set(name, i, eval("self._format" + i))
                except:
                    pass
            self.presets.set(name, "Container", self.getOutFileContainer())
            self.presets.write(open(self._CFG_PRESETS, "w"))
            self.presets.readfp(open(self._CFG_PRESETS, "r"))

#######################################
# HANDLERS FOR GUI-INTERACTION
#######################################    

    def connectWindow(self):
        """set all connections to the signals in the main-window"""
        handlers = {"destroy" : self.destroy,
                "on_notebook_change" : self.changeNotebook,
                "on_inFileChange" : self.changeInFile,
                "on_inFiles_click" : self.inFilesClicked,
                "on_inFiles_key" : self.InFilesKey,
                "on_videoStreams_click" : self.videoStreamsClicked,
                "on_audioStreams_click" : self.audioStreamsClicked,
                "on_videoStreams_key" : self.videoStreamsKey,
                "on_audioStreams_key" : self.audioStreamsKey,
                "on_inFileDragDrop" : self.dragDropInFile,
                "on_inFileTreeDragDrop" : self.dragDropInFileTree,
                "on_inFileToggle_toggled" : self.changeInFileAdd,
                "on_outFileSuffix_changed" : self.changeOutFileSuffix,
                "on_outFileChooser_file_set" : self.changeOutFileChooser,
                "on_outFileName_changed" : self.changeOutFileName,
                "on_metaToggle_clicked" : self.changeToggleMeta,
                "on_languageSelector_changed" : self.changeLanguage,
                "on_settingsVideofilter_changed" : self.changeVideofilter,
                "on_settingsBitrateMode_changed" : self.changeBitrateMode,
                "on_settingsCPU_changed" : self.changeCPU,
                "on_settingsProgressActions_changed" : self.changeProgressActions,
                "on_settingsStreamSeparator_changed" : self.changeStreamSeparator,
                "on_buttonProceed_clicked" : self.confirm,
                "on_buttonReset_clicked" : self.triggerReset,
                "on_imageLogo_button_release_event" : self.troubleShooter,
                "on_formatWidth_changed" : self.changeWidth,
                "on_formatHeight_changed" : self.changeHeight,
                "on_formatRatio_changed" : self.changeRatio,
                "on_formatFixedRatio_clicked" : self.changeFixedRatio,
                "on_format4_3_clicked" : self.setFixed4_3,
                "on_format16_9_clicked" : self.setFixed16_9,
                "on_formatFramerate_changed" : self.changeFramerate,
                "on_formatDeinterlace_clicked" : self.changeDeinterlace,
                "on_formatAudioSamplerate_changed" : self.changeAudioSamplerate,
                "on_formatAudioBitrate_changed" : self.changeAudioBitrate,
                "on_formatAudioCodec_changed" : self.changeAudioCodec,
                "on_formatAudioChannels_changed" : self.changeAudioChannels,
                "on_formatVolumeDisplay_changed" : self.changeVolumeDisplay,
                "on_formatVolumeFader_changed" : self.changeVolumeSlider,
                "on_format2Pass_clicked" : self.change2Pass,
                "on_format2PassNA_toggled" : self.change2PassNA,
                "on_formatCodec_changed" : self.changeCodec,
                "on_formatBitrate_changed" : self.changeBitrate,
                "on_formatOffset_changed" : self.changeOffset,
                "on_formatDuration_changed" : self.changeDuration,
                "on_formatScaling_changed" : self.changeScaling,
                "on_formatPadColor_changed" : self.changePadColor,
                "on_formatUserDefined_changed" : self.changeUserDefined,
                "on_buttonWidth_clicked" : self.resetFormatValue,
                "on_buttonHeight_clicked" : self.resetFormatValue,
                "on_buttonRatio_clicked" : self.resetFormatValue,
                "on_buttonBitrate_clicked" : self.resetFormatValue,
                "on_buttonFramerate_clicked" : self.resetFormatValue,
                "on_buttonAudioChannels_clicked" : self.resetFormatValue,
                "on_buttonAudioSamplerate_clicked" : self.resetFormatValue,
                "on_buttonAudioBitrate_clicked" : self.resetFormatValue,
                "on_buttonOffset_clicked" : self.resetFormatValue,
                "on_buttonDuration_clicked" : self.resetFormatValue,
                "on_buttonUserDefined_clicked" : self.resetUserDefined,
                "on_buttonManual_clicked" : self.openManual,
                "on_buttonOpenUOE_clicked" : self.openUOE,
                "on_buttonOutName_clicked" : self.setOutFileNameClick,
                "on_buttonOutPath_clicked" : self.setOutFilePathClick,
                "on_presetSave_clicked" : self.savePreset,
                "on_presetDelete_clicked" : self.deletePreset,
                "on_presetOpen_clicked" : self.openPreset,
                "on_presetContainer_toggled" : self.changePresetContainer,
                "on_settingsCleanup2Pass_toggled" : self.changeCleanup2Pass,
                "on_settingsCleanup2Pass_toggled" : self.changeNewstream,
                }
                
        self.window.signal_autoconnect(handlers)    
    
    
    def changeNotebook(self, widget, page, pagenum):
        """triggers some updates of widgets and sets the title"""
        self.window.get_widget("tragtor").set_title(
            self._TITLE + " :: " + \
            eval("self.lang." + \
            self._PAGES[pagenum] + "_title")
        )
        self.checkProceed()
        
        
    ### INPUT
    
    def videoStreamsClicked(self, widget, event):
        self.inFileOpenTree.get_selection().unselect_all()
        self.inFileAudioTree.get_selection().unselect_all()
        if not widget.get_path_at_pos(int(event.x), int(event.y)):
            self.inFileVideoTree.get_selection().unselect_all()
        else:
            self._inFilesSelection = int(widget.get_path_at_pos(int(event.x),
                                                            int(event.y))[0][0])
            if (event.button == 3):
                #This is a right-click
                try:
                    self.tragtorPreview.destroy()
                except:
                    True
                cachefile = self._videoStreams[self._inFilesSelection]["preview"]
                if not os.path.isfile(cachefile):
                    self.tragtorWindow.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
                    duration =  self._inFiles[self._videoStreams[self._inFilesSelection]["file"]]["duration"]
                    if duration < self._previewOffset:
                        duration = float(duration) / 2
                    else:
                        duration = float(self._previewOffset)
                    gobject.idle_add(self.createPreview,
                                 self._inFiles[self._videoStreams[self._inFilesSelection]["file"]]["file"],
                                 duration,
                                 cachefile,
                                 self._inFilesSelection)
                else:
                    gladeTree = gtk.glade.XML(self.gladefile, "tragtorPreview",)
                    self.tragtorPreview = gladeTree.get_widget("tragtorPreview")
                    handlers = {
                        "on_imagePreview_clicked" : self.destroyPreview,
                        "on_imagePreview_unfocus" : self.destroyPreview,
                        }
                    gladeTree.signal_autoconnect(handlers)
                    gladeTree.get_widget("imagePreview").set_from_file(
                        self._videoStreams[self._inFilesSelection]["preview"]
                    )
                    self.repositionPreview(self.tragtorPreview)
                    
            if len(self._videoStreams) > 1 or len(self._audioStreams) > 1:
                self.selectStreamTreeRange(self._inFilesSelection,
                                           self.inFileVideoTree,
                                           self._videoStreams)
                self.selectStreamTreeRange(self._inFilesSelection,
                                           self.inFileAudioTree,
                                           self._audioStreams)
                self.inFileOpenTree.get_selection().select_path(
                    self._inFilesSelection
                )
    
    def dragDropInFile(self, widget, source = None, x = None, y = None,
                       data = None, info = None, time = None):
        """handler for Drag&Drop on inFile-Chooser"""
        uri = data.data.strip()
        if uri[0:7] == "file://":
            inFile = self.setInFile(urllib.unquote(uri)[7:])
            self.addInFile(inFile)
            self.displayInFiles()
    
    def dragDropInFileTree(self, widget, source = None, x = None, y = None,
                       data = None, info = None, time = None):
        """handler for Drag&Drop on inFile-TreeView"""
        uri = data.data.strip()
        if uri[0:7] == "file://":
            inFile = self.setInFile(urllib.unquote(uri)[7:])
            self.addInFile(inFile)
            self.displayInFiles()
    
    def changeInFile(self, widget):
        """handler for inFile-Chooser"""
        inFile = self.setInFile(self.inFileChooser.get_filename())
        if inFile:
            self.addInFile(inFile)
            self.displayInFiles()
    
    def destroyPreview(self, widget, click):
        self.tragtorPreview.destroy()
    
    def repositionPreview(self, win):
        x, y = win.get_position()
        w, h = win.get_size()
        sw = win.get_screen().get_width()
        sh = win.get_screen().get_height()
        if x < 0:
            win.move(0, y)
        if x + w > sw:
            win.move(sw - w, y)
        if y < 0:
            win.move(x, 0)
        if y + h > sh:
            win.move(x, sh - h)
    
    def audioStreamsClicked(self, widget, event):
        self.inFileOpenTree.get_selection().unselect_all()
        self.inFileVideoTree.get_selection().unselect_all()
        if not widget.get_path_at_pos(int(event.x), int(event.y)):
            self.inFileAudioTree.get_selection().unselect_all()
        elif len(self._videoStreams) > 1 or len(self._audioStreams) > 1:
            self._inFilesSelection = self._audioStreams[\
                int(widget.get_path_at_pos(int(event.x), int(event.y))[0][0])\
            ]["file"]
            self.selectStreamTreeRange(self._inFilesSelection,
                                       self.inFileVideoTree,
                                       self._videoStreams)
            self.selectStreamTreeRange(self._inFilesSelection,
                                       self.inFileAudioTree,
                                       self._audioStreams)
            self.inFileOpenTree.get_selection().select_path(
                self._inFilesSelection
            )
            
    def inFilesClicked(self, widget, event):
        self._inFilesSelection = None
        self.inFileAudioTree.get_selection().unselect_all()
        self.inFileVideoTree.get_selection().unselect_all()
        if widget.get_path_at_pos(int(event.x), int(event.y)):
            self._inFilesSelection = int(widget.get_path_at_pos(int(event.x),
                                                            int(event.y))[0][0])
            if (event.button == 3):
                #This is a right-click
                self.createInFileMenu(event.time)
            elif len(self._videoStreams) > 1 or len(self._audioStreams) > 1:
                self.selectStreamTreeRange(self._inFilesSelection,
                                           self.inFileVideoTree,
                                           self._videoStreams)
                self.selectStreamTreeRange(self._inFilesSelection,
                                           self.inFileAudioTree,
                                           self._audioStreams)
        else:
            widget.get_selection().unselect_all()
    
    def InFilesKey(self, widget, event):
        if gtk.gdk.keyval_name(event.keyval) == "Delete" \
        and self._inFilesSelection != None:
            self.removeInFileFromList(self._inFilesSelection)
        if gtk.gdk.keyval_name(event.keyval) == "space" \
        and self._inFilesSelection != None:
            self.createInFileMenu(event.time)
                
    def openInFile(self, widget, event):
        if self._inFilesSelection != None:
            if self._OPENCOMMAND:
                os.popen3(self._OPENCOMMAND + (
                    " 'file://%s'" % self._inFiles[self._inFilesSelection]["file"])
                )
            else:
                self.messageDialog(
                    message, self.lang.error_no_opener,
                    gtk.MESSAGE_WARNING,
                    gtk.BUTTONS_OK,
                    image)
    
    def setOutFilePath(self, widget, event):
        if self._inFilesSelection != None:
            self.setOutFile(os.path.join(os.path.dirname(
                                self._inFiles[self._inFilesSelection]["file"]),
                                         os.path.basename(self._outFile)))
    
    
                                                
    def setOutFileName(self, widget, event):
        if self._inFilesSelection != None:
            self.setOutFile(os.path.join(os.path.dirname(self._outFile),
                                         os.path.basename(
                                self._inFiles[self._inFilesSelection]["file"])))
    
    def removeInFile(self, widget, event):
        if self._inFilesSelection != None:
            self.removeInFileFromList(self._inFilesSelection)
    
    def deleteInFile(self, widget, event):
        message = self.lang.question_delete_in_file % (self._inFilesSelection + 1)
        image = gtk.gdk.pixbuf_new_from_file(os.path.join(os.path.dirname(
                    os.path.realpath(__file__)), "icons/" + self.getIconColor(self.tragtorWindow) + "/question.svg"))
        delete = self.messageDialog(
            message, self.lang.question_title,
            gtk.MESSAGE_WARNING,
            gtk.BUTTONS_OK_CANCEL,
            image)
        if delete == gtk.RESPONSE_OK and self._inFilesSelection != None:
            try:
                os.remove(self._inFiles[self._inFilesSelection]["file"])
                self.removeInFileFromList(self._inFilesSelection)
            except:
                True
    
    def readInFileMeta(self, widget, event):
        if self._inFilesSelection != None:
            self.setMeta(self._inFilesSelection)
            self.fillMeta()
            
    def changeInFileAdd(self, widget):
         self._inFileAdd = widget.get_active()
         self.setInFileToggle(self._inFileAdd)
         self.saveConfigValue("Settings",
                              "inFileAdd",
                              self._inFileAdd,
                              self._CFG_SETTINGS)
    
    def selectVideo(self, cell, path, model):
#        self.inFileVideoStore[int(path)][0] = not self.inFileVideoStore[int(path)][0]
#        self._videoStreams[int(path)]["active"] = self.inFileVideoStore[int(path)][0]
        act = self.inFileVideoStore[int(path)][0]
        for i in self.inFileVideoStore:
            i[0] = False
        for i in self._videoStreams:
            i["active"] = False
        self.inFileVideoStore[int(path)][0] = not act
        self._videoStreams[int(path)]["active"] = not act
        self.toggleVideo(self.videoActive())
        self.calculateTargetInfo()
        self.checkProceed()
        self.setInFileFormat()
        self.setFormat()
        self.fillFormat()
            
    def selectAudio(self, cell, path, model):
        self.inFileAudioStore[int(path)][0] = \
            not self.inFileAudioStore[int(path)][0]
        self._audioStreams[int(path)]["active"] = \
            self.inFileAudioStore[int(path)][0]
        self.toggleAudio(self.audioActive())
        self.calculateTargetInfo()
        self.checkProceed()
        self.setInFileFormat()
        self.setFormat()
        self.fillFormat()
    
    def videoStreamsKey(self, widget, event):
        if gtk.gdk.keyval_name(event.keyval) == "space" \
        and self._inFilesSelection != None:
            1
            
    def audioStreamsKey(self, widget, event):
        if gtk.gdk.keyval_name(event.keyval) == "space" \
        and self._inFilesSelection != None:
            1
    
    
    ### FORMAT
    
    def changeVolumeSlider(self, widget):
        value = widget.get_value()
        self._formatVolume = int(value)
        self.formatVolumeDisplay.set_text("%i%s" % (self.value2perc(256,
                                                    self._formatVolume,
                                                    True), "%"))
        
    def changeVolumeDisplay(self, widget):
        perc = widget.get_text()
        if perc != "" and perc[-1] == "%":
            perc = perc.strip("%")
        if perc != "":
            self._formatVolume = self.perc2value(256, int(perc), True)
            self.formatVolumeDisplay.set_text("%i%s" % (self.value2perc(256,
                                                        self._formatVolume,
                                                        True), "%"))
            self.formatVolumeFader.set_value(self._formatVolume)
        
    def resetFormatValue(self, widget):
        """handler for reset-icons wich appear if a value differs from default"""
        objectName = widget.get_name()[6:]
        targetWidget = eval("self.format" + objectName)
        if targetWidget.class_path()[-16:] != "GtkComboBoxEntry":
            targetWidget.set_value(eval("self._inFile" + objectName))
        else:
            targetWidget.child.set_text("%i" % eval("self._inFile" + objectName))
        exec("self._format" + objectName + " = self._inFile" + objectName)
        self.setFormatChanged(objectName)
        
    def resetUserDefined(self, widget):
        self.formatUserDefined.set_text("")
        
    def changeWidth(self, widget):
        """calculates height, ratio on change of width
        and sets the other values depending on fixedRatio-value"""
        widget.update()
        self.formatRatio.update()
        self.formatHeight.update()
        if widget.get_value() != "":
            self._formatWidth = round(widget.get_value())
            if self._formatFixedRatio \
            and self._formatWidth > 0 \
            and self._formatRatio > 0:
                if self._formatWidth / self._formatRatio < self._formatMaxHeight:
                    self._formatHeight = round(self._formatWidth / self._formatRatio)
                    self.formatHeight.set_value(round(self._formatHeight))
            else:
                self._formatRatio = self.roundFloat(self._formatWidth / self._formatHeight, 4)
                self.formatRatio.set_value(self._formatRatio)
            self.checkProceed()
            self.setFormatChanged("Width")
                    
    def changeHeight(self, widget):
        """calculates width, ratio on change of height
        and sets the other values depending on fixedRatio-value"""            
        widget.update()
        self.formatRatio.update()
        self.formatWidth.update()
        if widget.get_value() != "":
            self._formatHeight = round(widget.get_value())
            if self._formatFixedRatio \
            and self._formatHeight * self._formatRatio < self._formatMaxWidth:
                self._formatWidth = round(self._formatHeight * self._formatRatio)
                self.formatWidth.set_value(round(self._formatWidth))
            else:
                self._formatRatio = self.roundFloat(self._formatWidth / self._formatHeight, 4)
                self.formatRatio.set_value(self._formatRatio)
            self.checkProceed()
            self.setFormatChanged("Height")
                    
    def changeRatio(self, widget):
        """calculates height, width on change of ratio
        and sets the other values"""
        widget.update()
        self.formatHeight.update()
        self.formatWidth.update()
        if widget.get_value() != "":
            self._formatRatio = self.roundFloat(widget.get_value(), 4)    
            if self._formatWidth > 0:
                self._formatHeight = round(self._formatWidth / self._formatRatio)
                self.formatHeight.set_value(self._formatHeight)
            else:
                self._formatWidth = round(self._formatHeight * self._formatRatio)
                self.formatWidth.set_value(self._formatWidth)
            
            self.checkProceed()
            self.setRatioButtons(self._formatRatio)
            self.setFormatChanged("Ratio")
    
    def setFixed4_3(self, widget):
        """handler for 4:3"""
        if widget.get_active():
            if self.format16_9.get_active():
                self.format16_9.set_active(False)
            if not self.formatFixedRatio.get_active():
                self.formatFixedRatio.set_active(True)
            self.formatRatio.set_value(1.3333)
            self.setFormatChanged("Ratio")
            
    
    def setFixed16_9(self, widget):
        """handler for 16:9"""
        if widget.get_active():
            if self.format4_3.get_active():
                self.format4_3.set_active(False)
            if not self.formatFixedRatio.get_active():
                self.formatFixedRatio.set_active(True)
            self.formatRatio.set_value(1.7777)
            self.setFormatChanged("Ratio")
            
    
    def changeFramerate(self, widget):
        """handler for framerate-spin"""
        if widget.get_text() != "":
            widget.update()
        if self.formatFramerate.get_value() != "":
            self._formatFramerate = self.roundFloat(
                self.formatFramerate.get_value(), 2
            )
            self.checkProceed()
            self.setFormatChanged("Framerate")
        
    def changeDeinterlace(self, widget):
        """handler for deinterlace-button"""
        self._formatDeinterlace = self.formatDeinterlace.get_active()
        
    def changeAudioSamplerate(self, widget):
        """handler for audio-samplerate"""
        try:
            self._formatAudioSamplerate = eval(
                self.formatAudioSamplerate.child.get_text()
            )
            self.checkProceed()
            self.setFormatChanged("AudioSamplerate")
        except:
            1
        
    def changeAudioBitrate(self, widget):
        """handler for audiobitrate"""
        try:
            self._formatAudioBitrate = eval(
                self.formatAudioBitrate.child.get_text()
            )
            self.calculateTargetInfo()
            self.checkProceed()
            self.setFormatChanged("AudioBitrate")
        except:
            1
        
    def changeAudioCodec(self, widget):
        """handler for audio-codec"""
        model = self.formatAudioCodec.get_model()
        iter = self.formatAudioCodec.get_active_iter()
        if iter >= 0:
            self._formatAudioCodec = model.get_value(iter, 0)
        else:
            self._formatAudioCodec = ""
        if self._formatAudioCodec == self._codec_streamcopy:
            self.toggleAudio(False, True)
        else:
            self.toggleAudio(True, True)
        self.checkProceed()
            
    def changeAudioChannels(self, widget):
        """handler for audio-channels"""
        try:
            self._formatAudioChannels = eval(
                self.formatAudioChannels.child.get_text()
            )
            self.checkProceed()
            self.setFormatChanged("AudioChannels")
        except:
            1
        
    def change2Pass(self, widget):
        """handler for 2-pass encoding switch"""
        self._format2Pass = self.format2Pass.get_active()
        self.toggleNoAudio(self._format2Pass)
    
    def change2PassNA(self, widget):
        """handler for 2-pass no audio encoding switch"""
        self._format2PassNA = self.format2PassNA.get_active()
        
    def changeCodec(self, widget):
        """handler for video-codec"""
        model = self.formatCodec.get_model()
        iter = self.formatCodec.get_active_iter()
        if iter >= 0:
            self._formatCodec = model.get_value(iter, 0)
        else:
            self._formatCodec = ""
        if self._formatCodec == self._codec_streamcopy:
            self.toggleVideo(False, True)
        else:
            self.toggleVideo(True, True)
        self.checkProceed()
            
    def changeBitrate(self, widget, key = False):
        """handler for bitrate"""
        if widget.get_text() != "":
            widget.update()
        self._formatBitrate = self.formatBitrate.get_value()
        self.calculateTargetInfo()
        self.checkProceed()
        self.setFormatChanged("Bitrate")
        
    def changeOffset(self, widget):
        """handler for offset-value"""
        #widget.update()
        self._formatOffset = self.formatOffset.get_value()
        self.window.get_widget("labelOffsetOut").set_text(
            "(%s)" % self.seconds2timestring(self._formatOffset)
        )
        #self.formatDurationAdjustment.upper = self._inFileDuration - self._formatOffset
        if self._formatDuration > self._inFileDuration + self._inFileOffset - self._formatOffset:
            self._formatDuration = self._inFileDuration + self._inFileOffset - self._formatOffset
            self.formatDuration.set_value(self._formatDuration)
            self.window.get_widget("labelDurationOut").set_text(
                "(%s)" % self.seconds2timestring(self._formatDuration)
            )
        self.calculateTargetInfo()
        self.checkProceed()
        self.setFormatChanged("Offset")
        
    def changeDuration(self, widget):
        """handler for offset-value"""
        #widget.update()
        self._formatDuration = self.formatDuration.get_value()
        self.window.get_widget("labelDurationOut").set_text(
            "(%s)" % self.seconds2timestring(self._formatDuration)
        )
        #self.formatOffsetAdjustment.upper = self._inFileDuration - self._formatDuration
        if self._formatOffset > self._inFileDuration + self._inFileOffset - self._formatDuration:
            self._formatOffset = self._inFileDuration + self._inFileOffset - self._formatDuration
            self.formatOffset.set_value(self._formatOffset)
            self.window.get_widget("labelOffsetOut").set_text(
                "(%s)" % self.seconds2timestring(self._formatOffset)
            )
        self.calculateTargetInfo()
        self.checkProceed()
        self.setFormatChanged("Duration")
        
    def changeScaling(self, widget):
        """handler for scalingmethod"""
        self._formatScaling = self.formatScaling.get_active()
        if self._formatScaling == -1:
            self._formatScaling = 0
        
    def changePadColor(self, widget):
        """handler for pad-color"""
        color = self.formatPadColor.get_color()
        self._formatPadColor = color.to_string()
        
    def changeFixedRatio(self, widget):
        """handler for fixed-ratio"""
        self._formatFixedRatio = widget.get_active()
    
    def changeUserDefined(self, widget):
        """handler for user defined options"""
        self._formatUserDefined = self.formatUserDefined.get_text()
        self.setFormatChanged("Bitrate")
        
    def openManual(self, widget):
        man = os.popen("%s -h" % self._command())
        output = ""
        while 1:
            line = man.readline()
            if not line: break
            output += line
        if output == "":
            self.messageDialog(self.lang.error_message_no_manual,
                                self.lang.error_message_title,
                                gtk.MESSAGE_ERROR,
                                gtk.BUTTONS_OK)
        else:
            self.createHelp(output)
            
    def openUOE( self, widget ):
        """OPens the user optin editor window"""
        self. createUOE()
        
    def buildUserOption(self, widget):
        """build the user options from the UOE"""
        if self._format2Pass:
            self.formatUserDefined.set_text(
                "%s|%s" % (
                self.UOEWin.get_widget("textviewPass1").get_buffer().get_text(
                    self.UOEWin.get_widget("textviewPass1").get_buffer().get_start_iter(),
                    self.UOEWin.get_widget("textviewPass1").get_buffer().get_end_iter()),
                self.UOEWin.get_widget("textviewPass2").get_buffer().get_text(
                    self.UOEWin.get_widget("textviewPass2").get_buffer().get_start_iter(),
                    self.UOEWin.get_widget("textviewPass2").get_buffer().get_end_iter())
                ))
        else:
            self.formatUserDefined.set_text(
                self.UOEWin.get_widget("textviewPass1").get_buffer().get_text(
                    self.UOEWin.get_widget("textviewPass1").get_buffer().get_start_iter(),
                    self.UOEWin.get_widget("textviewPass1").get_buffer().get_end_iter())
                )
        self.killUOE(False)
        



    ### META

    def changeToggleMeta(self, widget):
        """handler for the meta-Enable-switch"""
        self._metaEnable = self.metaToggle.get_active()
        self.toggleMeta(self._metaEnable)

    ### PROCESS
    
    def setOutFilePathClick(self, widget):
        if len(self._inFiles):
            self.setOutFile(os.path.join(os.path.dirname(
                                    self._inFiles[0]["file"]),
                                             os.path.basename(self._outFile)))
    
    def setOutFileNameClick(self, widget):
        if len(self._inFiles):
            self.setOutFile(os.path.join(os.path.dirname(self._outFile),
                                             os.path.basename(
                                    self._inFiles[0]["file"])))
    
    def changeCPU(self, widget):
        model = widget.get_model()
        self._settingsCPU = widget.get_active()
        self.saveConfigValue("Settings",
                             "cpuUsage",
                             self._settingsCPU,
                             self._CFG_SETTINGS)
    
    def changeOutFileChooser(self, widget):
        if widget.get_filename():
            self.setOutFile(os.path.join(widget.get_filename(), self.outFileName.get_text()), False, False)
    
    def changeOutFileName(self, widget):
        if self.outFileChooser.get_filename() == None:
            return
        self.setOutFile(os.path.join(self.outFileChooser.get_filename(), widget.get_text()), False, False)
    
    def changeOutFileSuffix(self, widget):
        """handler for the suffix-selector in output"""
        self.saveConfigValue("Settings",
                             "outFileSuffix",
                             widget.get_active(),
                             self._CFG_SETTINGS)
        self._outFileSuffix = widget.get_active()
        self.analyzeOutFile()
        self.checkProceed()
                
    ### SETTINGS
    
    def changeLanguage(self, widget):
        """handler for languageSelector"""
        model = widget.get_model()
        lanstr = model.get_value(widget.get_active_iter(), 0)
        self._LANGUAGE = self._LANGUAGES.keys()[self._LANGUAGES.values().index(lanstr)]
        self.setLanguage()
        self.fillLabels()
        self.setInFileToggle(self._inFileAdd)
        if self.inputRead(): self.resetFormatLabels()
        self.fillTextCombos(refill = True)
        self.reloadInFileFilter()
        self.reloadOutFileFilter()
        self.reloadOutFileSuffix()
        self.reloadTreeViewColumns()
        self.calculateTargetInfo()
        
    def changeVideofilter(self, widget):
        model = widget.get_model()
        self._videoFilter = widget.get_active()
        self.saveConfigValue("Settings",
                             "videofilter",
                             self._videoFilter,
                             self._CFG_SETTINGS)
    
    def changeBitrateMode(self, widget):
        model = widget.get_model()
        self._bitrateMode = widget.get_active()
        self.saveConfigValue("Settings",
                             "bitratemode",
                             self._bitrateMode,
                             self._CFG_SETTINGS)
                             
    def changeProgressActions(self, widget):
        self._progressActions = widget.get_active()
        self.saveConfigValue("Settings", "progressActions", widget.get_active(), self._CFG_SETTINGS)
        
    def changeStreamSeparator(self, widget):
        self._streamSeparator = widget.get_active()
        self.saveConfigValue("Settings", "streamSeparator", widget.get_active(), self._CFG_SETTINGS)
        
    def changePresetContainer(self, widget):
        self.saveConfigValue("Settings",
                             "presetContainer",
                             widget.get_active(),
                             self._CFG_SETTINGS)
    
    def changeCleanup2Pass(self, widget):
        self.saveConfigValue("Settings",
                             "cleanup2Pass",
                             widget.get_active(),
                             self._CFG_SETTINGS)
    
    def changeNewstream(self, widget):
        self.saveConfigValue("Settings",
                             "newstreamOption",
                             widget.get_active(),
                             self._CFG_SETTINGS)
                             
    def triggerReset(self,widget):
        """reset all values by clicking the Reset-button"""
        self.reset()    
    
#######################################
# SOURCE-OPERATIONS
#######################################    
        
    def setInFile(self, inFile):
        """check if argument is a file, a directory or nothing
        and set the file and path in the inFileCooser-dialog
        returns file if argument is a file, otherwise false"""
        if inFile != None:
            sfile = os.path.abspath(inFile)
            if os.path.isfile(sfile):
                if self.inFileChooser.get_filename() != sfile:
                    self.inFileChooser.unselect_all()
                    self.inFileChooser.set_current_folder(os.path.dirname(sfile))
                    self.inFileChooser.select_filename(sfile)
                inFile = sfile
            elif os.path.isdir(sfile):
                self.inFileChooser.set_current_folder(sfile)
                self.inFileChooser.unselect_all()
                inFile = None
            else:
                self.inFileChooser.unselect_all()
                inFile = None
        else:
            self.inFileChooser.unselect_all()
            inFile = None
        return inFile

    def addInFile(self, inFile):
        """triggers analyzing on inFile. if file can be read by ffmpeg/avlib,
        all GUI-related stuff is executed. otherwise error-dialogs
        are opened. inFile-Info is triggered afterwards"""
        if not inFile:
            return False
        if not self.inFileAccessible(inFile):
            self._inErrors.append({"file":inFile,"error":"not_accessible"})
        elif not self.inFileReadable(inFile):
            self._inErrors.append({"file":inFile,"error":"not_readable"})
        else:
            if not self._inFileAdd:
                self.clearInFiles()
            
            if not self.inFileExists(inFile):
                infos, video, audio = self.analyzeInFile(inFile)
                fileID = len(self._inFiles)
                infos["ID"] = fileID
                for i in video:
                    i["file"] = fileID
                for i in audio:
                    i["file"] = fileID
                
                self._inFiles.append(infos)
                self._audioStreams = self._audioStreams + audio
                self._videoStreams = self._videoStreams + video
                self.saveInFiles()
    
    def removeInFileFromList(self, inFile):
        del self._inFiles[inFile]
        files = self.getInFilesList()
        cache = self._inFileAdd
        if len(self._inFiles) > 1:
            self._inFileAdd = True
        self.clearInFiles()
        self.resetInFileInfo()
        if len(files):
            for f in files:
                self.addInFile(f)
        else:
            self.saveInFiles()
        self._inFileAdd = cache
        self.displayInFiles()
        
    def saveInFiles(self):
        self.saveConfigValue("Settings",
                             "inFiles",
                             self.getInFilesList(),
                             self._CFG_SETTINGS)
        
    def clearInFiles(self):
        self._inFiles = []
        self._audioStreams = []
        self._videoStreams = []
        
    def displayInFiles(self):
        
        self.resetInFileInfo()
        
        self.fillInFiles()
        self.fillInFileStreams()
        self.displayInFileErrors()
        
        if self.videoAvail(): self.inFileVideo.show()
        else: self.inFileVideo.hide()
        if self.audioAvail(): self.inFileAudio.show()
        else: self.inFileAudio.hide()
        
        if len(self._inFiles) > 0:
            self.inFileOpen.show()
        
        self.toggleVideo(self.videoActive())
        self.toggleAudio(self.audioActive())
        
        self.checkProceed()

        self.resetFFmpegOut()
        self.setInFileFormat()
        self.setFormat()
        self.fillFormat()
        self.calculateTargetInfo()

    def inFileAccessible(self, inFile):
        if os.access(inFile, os.R_OK) == False \
        or os.path.getsize(inFile) <= 1 \
        or os.path.isdir(inFile):
            return False
        else:
            return True
    
    def inFileReadable(self, inFile):
        ffmpegout = sub.Popen("%s -i '%s'" % (self._command(), inFile),
                              shell=True,
                              stdout=sub.PIPE,
                              stderr=sub.PIPE)
        for line in ffmpegout.stderr.readlines():
            if line.strip().endswith("Unknown format") \
            or line.strip().endswith("could not find codec parameters"):
                return False
        return True
        
    def inFileExists(self, inFile):
        for i in self._inFiles:
            if i["file"] == inFile:    
                return True
        return False
        
    def resetInFileInfo(self):
        """resets the inFile-page to blank"""
        self.inFileAudioStore.clear()
        self.inFileVideoStore.clear()
        self.inFileOpenStore.clear()
        
        self.inFileVideo.hide()
        self.inFileAudio.hide()
        self.inFileOpen.hide()
        
    def fillInFiles(self):
        if len(self._inFiles):
            for i in self._inFiles:
                self.inFileOpenStore.append([i["ID"] + 1,
                                            i["file"],
                                            self.bytes2string(i["size"]) + "B",
                                            i["format"],
                                            str(int(round(i["duration"]))) + " s",
                                            self._BACKGROUND_COLORS[\
                                                int(i["ID"]) % len(
                                                    self._BACKGROUND_COLORS
                                                )\
                                            ]])
    
    def fillInFileStreams(self):
        """fill the treestores with stream data """
        for stream in self._videoStreams:
            try:
                pb = gtk.gdk.pixbuf_new_from_file_at_size(stream["preview"],
                                                          self._previewWidth,
                                                          self._previewHeight)
            except:
                pb = gtk.gdk.pixbuf_new_from_file_at_size(self._loadingAnimation,
                                                          self._previewWidth,
                                                          self._previewHeight)
            self.inFileVideoStore.append([stream["active"],
                                          str(int(stream["file"]) + 1),
                                          str(int(stream["ID"]) + 1),
                                          stream["codec"], stream["method"],
                                          stream["size"],
                                          stream["fps"],
                                          stream["lang"],
                                          self._BACKGROUND_COLORS[\
                                            int(stream["file"]) % len(
                                                self._BACKGROUND_COLORS
                                            )\
                                          ],
                                          pb])
        for stream in self._audioStreams:
            self.inFileAudioStore.append([stream["active"],
                                          str(int(stream["file"]) + 1),
                                          str(int(stream["ID"]) + 1),
                                          stream["codec"],
                                          stream["samplerate"],
                                          stream["channels"],
                                          stream["bitrate"],
                                          stream["lang"],
                                          self._BACKGROUND_COLORS[\
                                            int(stream["file"]) % len(
                                                self._BACKGROUND_COLORS
                                            )\
                                          ]])
    
    def getInFilesList(self):
        result = []
        for i in self._inFiles:
            result.append(i["file"])
        return result
    
    def displayInFileErrors(self):
        ok = False
        if len(self._inErrors) == 1:
            ok = self.messageDialog(self.lang.error_in_file_single,
                self.lang.error_message_title,
                gtk.MESSAGE_ERROR,
                gtk.BUTTONS_OK_CANCEL)
        elif len(self._inErrors) > 1:
            ok = self.messageDialog(self.lang.error_in_file_multi % len(self._inErrors),
                self.lang.error_message_title,
                gtk.MESSAGE_ERROR,
                gtk.BUTTONS_OK_CANCEL)
        if ok == gtk.RESPONSE_OK or ok == True:
            out = ""
            acc = read = 0
            for i in self._inErrors:
                if i["error"] == "not_accessible":
                    out += self.lang.error_in_file_not_accessible % i["file"]
                    out += "\n\n"
                    acc += 1
                elif i["error"] == "not_readable":
                    out += self.lang.error_in_file_not_readable % i["file"]
                    out += "\n\n"
                    read += 1
            out += "\n"
            if acc > 0:
                out += (self.lang.error_in_file_not_accessible_explain)
                out += "\n\n"
            if read > 0:
                out += self.lang.error_in_file_not_readable_explain + "\n\n\n"
                out += self.lang.ffmpeg_options % (self.ffmpegConfig._compileOptions,
                    " ".join(["%s" % (k) for k, v, s in self.ffmpegConfig._openFileFormats]), " ".join(["%s" % (k) for k, v, s in self.ffmpegConfig._saveFileFormats]),
                    " ".join(self.ffmpegConfig._openAudioCodecs),
                    " ".join(self.ffmpegConfig._saveAudioCodecs),
                    " ".join(self.ffmpegConfig._openVideoCodecs),
                    " ".join(self.ffmpegConfig._saveVideoCodecs))
                out += "\n\n"
            self.createHelp(out)
                    
        self._inErrors = []
    
    def analyzeInFile(self, inFile):
        """This operation analyzes a given file with ffmpeg/avlib and returns
            inFileFormat[file, format, duration, start, bitrate]
            inFileStreams[n][ID, format, codec, (color or samplerate),
            (size or channels), (fps or audiobitrate)]"""
        if not inFile:
            return False
        infos = {    "file":"",
                    "ID":0,
                    "format":"N/A",
                    "duration":0.0,
                    "start":0.0,
                    "bitrate":0,
                    "size":0 }
        audio = []
        video = []
        print("\n### Analyzing: %s" % inFile)
        # execute ffmpeg/avlib
        ffmpegout = sub.Popen("%s -i \"%s\"" % (self._command(), inFile),
                              shell=True,
                              stdout=sub.PIPE,
                              stderr=sub.PIPE)
        for line in ffmpegout.stderr.readlines():
            _REGEX_STREAM  = "Stream #([0-9]+(\.|:)[0-9]+)([\[\(][0x]?[0-9A-Za-z]+[\]\)])*: "
            #REGEX_STREAM  = "Stream #([0-9]+\.[0-9]+)([\[|(][0x]?[0-9A-Za-z]+[\]|)])?: "
            _REGEX_STREAM += "(Audio|Video): ([A-Za-z0-9\-_:\[\]]+)"
            stream = re.search(_REGEX_STREAM, line)
            data = re.search("Duration:", line)
            info = line[:5] == "Input"
            if data:
                # parse more formatinfo and append to fileformat:
                # inFileFormat[file, format, duration, start, bitrate]
                print(line.strip())
                elements = line.split(", ")
                for el in elements:
                    p = el.split(": ")
                    if p[0].strip() == "Duration":
                        infos["duration"] = self.timestring2seconds(p[1].strip())
                    elif p[0].strip() == "start":
                        infos["start"] = float(p[1].strip())
                    elif p[0].strip() == "bitrate":
                        bitrate = p[1].strip()
                        if bitrate != "N/A":
                            infos["bitrate"] = int(bitrate[:-5])
                        else:
                            infos["bitrate"] = 0
            elif stream:
                # parse streams inside Input
                # _audioStreams[n][ID, format, codec, samplerate, channels, audiobitrate, languagecode]
                # _videoStreams[n][ID, format, codec, video, size , fps, languagecode]
                if not re.search("least one output file", line):
                    print(line.strip())
                ids = stream.group(1).split(stream.group(2))
                lang = "N/A"
                if stream.group(3):
                    lang = stream.group(3)
                array = {    "ID":int(ids[1]),
                            "file":int(ids[0]),
                            "format":stream.group(4),
                            "codec":stream.group(5),
                            "samplerate":0,
                            "channels":0,
                            "bitrate":0,
                            "method":"N/A",
                            "size":"0x0",
                            "fps":0,
                            "lang":lang,
                            "preview":None,
                            "active":False }
                if array["format"] == "Audio":
                    substr = line.strip()[len(stream.group(0)):]
                    sr = re.search("([0-9]+) Hz", substr)
                    if sr:
                        array["samplerate"] = int(sr.group(1))
                    ch = re.search("(stereo|mono)", substr)
                    if ch:
                        if ch.group(1) == "stereo":
                            array["channels"] = 2
                        elif ch.group(1) =="mono":
                            array["channels"] = 1
                    else:
                        ch = re.search("([0-9]+) channels", substr)
                        if ch:
                            array["channels"] = int(ch.group(1))
                    br = re.search("([0-9]+) kb/s", substr)
                    if br:
                        array["bitrate"] = int(br.group(1))
                    audio.append(array)
                    if len(audio) == 1 and len(self._audioStreams) == 0:
                        audio[0]["active"] = True
                
                elif array["format"] == "Video":
                    substr = line.strip()[len(stream.group(0)):]
                    me = re.search("\A(([0-9A-Za-z])+),", substr.strip())
                    if me:
                        array["method"] = me.group(1)
                    sz = re.search("(([1-9][0-9]+)x([0-9]+))", substr)
                    if sz:
                        array["size"] = sz.group(1)
                    fr = re.search("([0-9]{1,2}(\.[0-9]{0,2}){0,1}) (fps|tb)(\([cr]\)){0,1}", substr)
                    if fr:
                        array["fps"] = float(fr.group(1))
                    br = re.search("([0-9]+) kb/s", substr)
                    if br:
                        array["bitrate"] = int(br.group(1))
                    array["preview"] = self.getPreview(inFile)
                    video.append(array)
                    if len(video) == 1 and len(self._videoStreams) == 0:
                        video[0]["active"] = True

            elif info:
                #print line.strip()
                # Begin Input section:
                elements = line.split(", ", 2)
                infos["file"] = elements[2][6:-3]
                infos["ID"] = -1
                infos["format"] = elements[1]

        ffmpegout.terminate()
        infos["size"] = os.path.getsize(inFile)
        
        return (infos, video, audio)
        
    def getPreview(self, _file):
        if os.path.isfile(_file):
            m = hashlib.md5()
            m.update(_file)
            m.update("%i" % os.stat(_file)[8])
            cachefile = os.path.join(self._CACHE_PATH,
                                     "%s.jpg" % m.hexdigest())
            return cachefile
        return False
    
    def createPreview(self, _file, duration, cachefile, sid):
        self.tragtorWindow.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
        pid = len(self._previewThreads)
        self._previewThreads.append(Preview(_file, cachefile, duration, self.drawPreviews, pid))
    
    def drawPreviews(self, pid):
        sid = 0
        for stream in self._videoStreams:
            it = self.inFileVideoStore.get_iter(sid)
            avail = 0
            loading = 0
            try:
                pb = gtk.gdk.pixbuf_new_from_file_at_size(stream["preview"],
                                                          self._previewWidth,
                                                          self._previewHeight)
                avail += 1
            except:
                pb = gtk.gdk.pixbuf_new_from_file_at_size(self._loadingAnimation,
                                                          self._previewWidth,
                                                          self._previewHeight)
                loading += 1
            self.inFileVideoStore.set(it, 9, pb)
            if(loading):
                self.tragtorWindow.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
            else:
                self.tragtorWindow.window.set_cursor(None)
            sid += 1
        try: 
            self._previewThreads[pid] = None
        except:
            1
        for pid in self._previewThreads:
            if pid:
                self.tragtorWindow.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
                return
        self.tragtorWindow.window.set_cursor(None)
        
#######################################
# TARGET-OPERATIONS
#######################################
    
    def setOutFileChooser(self):
        if(self.outFileChooser.get_filename() != self._outFile
        and os.path.dirname(str(self.outFileChooser.get_filename())) != self._outFile):
            f = self._outFile
            while not os.path.isdir(f):
                f = os.path.dirname(f)
            self.outFileChooser.set_current_folder(f)
        
    def setOutFileName(self):
        if(os.path.isdir(self._outFile)):
            s = ""
        else:
            s = os.path.basename(self._outFile)
        if s != self.outFileName.get_text():
            self.outFileName.set_text(s)
                
    def setOutFile(self, outFile, setChooser = True, setEntry = True):
        """set the file and path in the outFileChooser-dialog"""
        self._outFile = outFile
        self.saveConfigValue("Settings",
                             "outFile",
                             self._outFile,
                             self._CFG_SETTINGS)
        if setEntry: self.setOutFileName()
        if setChooser: self.setOutFileChooser()
        self.analyzeOutFile()
        self.checkProceed()
    
    def analyzeOutFile(self):
        """analyzes, if selected outfile is writable"""
        self._outFileAccessible = self._outFileWriteable = False
        outFile = self.filterOutFileSuffix()
        if outFile != None:
            if os.access(os.path.dirname(os.path.abspath(outFile)), os.W_OK) == False:
                self._outFileAccessible = False
            else:
                self._outFileAccessible = True
            filename = os.path.basename(outFile)
            suffix = filename[filename.rfind(".") + 1:]
            for s in self.ffmpegConfig._saveFileFormats:
                if s[2].lower() == suffix.lower() and s[2] != "":
                    self._outFileWriteable = True
                    self._outFileFormat = s
                    break;
            return (self._outFileAccessible, self._outFileWriteable)
        else:
            return (False, False)    
    
    def filterOutFileSuffix(self):
        if not self._outFile: return
        if self._outFileSuffix > 0 and re.search(r"\.[A-Za-z0-9]{3}",
                                                 self._outFile[-4:]):
            self._outFile = self._outFile[:-4]
        if self._outFileSuffix > 0 \
        and not self._outFile.endswith("." + self.getOutFileSuffix()):
            outFile = self._outFile + "." + self.getOutFileSuffix()
        else:
            outFile = self._outFile
        return outFile
    
    def getOutFileSuffix(self):
        outSfx = self.outFileSuffix.get_active()
        if outSfx > 0:
            return self.ffmpegConfig._saveFileFormats[\
                self.outFileSuffix.get_active() - 1\
            ][2]
        else:
            return False
    
    def getOutFileContainer(self):
        outSfx = self.outFileSuffix.get_active()
        if outSfx > 0:
            return self.ffmpegConfig._saveFileFormats[\
                self.outFileSuffix.get_active() - 1\
            ][0]
        else:
            return False
    
    def checkInAsOut(self, outFile):
        streams = self._videoStreams + self._audioStreams
        for s in streams:
            if s["active"] and self._inFiles[s["file"]]["file"] == outFile:
                return True
        return False
    
#######################################
# CHECK IF WE CAN GO ON
#######################################            
    
    def checkProceed(self):
        """checks some values to decide if proceedButton can be enabled"""

        self._canProceed = False
        error = False
        
        if len(self._inFiles) == 0:
            error = self.lang.error_button_not_in_media
        elif self.checkInAsOut(self.filterOutFileSuffix()):
            error = self.lang.error_button_in_as_out
        elif not self._outFileAccessible:
            error = self.lang.error_button_not_writable
        elif not self._outFileWriteable:
            error = self.lang.error_button_not_out_media
        elif len(self._videoStreams) == 0 and not self.audioActive():
            error = self.lang.error_button_no_audio
        elif not self.audioActive() and not self.videoActive():
            error = self.lang.error_button_no_content
        elif self._formatDuration == 0:
            error = self.lang.error_button_duration
        elif self._formatWidth == 0 or self._formatHeight == 0:
            error = self.lang.error_button_size
        elif self._formatBitrate == 0 or self._formatAudioBitrate == 0:
            error = self.lang.error_button_bitrate
        elif self._formatAudioSamplerate == 0:
            error = self.lang.error_button_sample_rate
        elif self._formatAudioChannels == 0:
            error = self.lang.error_button_channels
        elif self._formatFramerate == 0:
            error = self.lang.error_button_frame_rate
        elif len(self._formatAudioCodec) > 0 and self._formatAudioBitrate == 0:
            error = self.lang.error_button_no_audio_bitrate
        elif len(self._formatCodec) > 0 and self._formatBitrate == 0:
            error = self.lang.error_button_no_video_bitrate
        else: self._canProceed = True

        if self._canProceed == True:
            label = self.buttonProceedActive()
            self.buttonProceedIcon.set_from_file(sys.path[0] + \
                "/icons/" + self.getIconColor(self.buttonProceedIcon) + "/proceed-enabled.svg")
            sens = True
        else:
            label = self.buttonProceedInactive(error)
            self.buttonProceedIcon.set_from_file(sys.path[0] + \
                "/icons/" + self.getIconColor(self.buttonProceedIcon) + "/proceed-disabled.svg")
            sens = False
        self.buttonProceedLabel.set_text(label)
        self.buttonProceedIcon.show()
        self.buttonProceed.set_sensitive(sens)
        
        
#######################################
# CONFIRMATION
#######################################            

    def confirm(self, widget):
        """IN YOUR FACE!"""
        if self._canProceed:
            
            # build commandline
            mapping1 = ""
            mapping2 = ""
            options = ""
            audio = ""
            video = ""
            user1 = ""
            user2 = ""
            newstreams = ""
            meta = ""
                    
            # duration
            if self._inFileDuration != self._formatDuration:
                options += " -t " + self.seconds2timestring(self._formatDuration)
            # start
            if self._formatOffset != 0 \
            and self._inFileOffset != self._formatOffset:
                options += " -ss " + self.seconds2timestring(self._formatOffset)
            
            # threading
            if self._settingsCPU == 1 and multiprocessing.cpu_count() > 2:
                # medium with more than 2 cpu's
                options += " -threads %i" % round(multiprocessing.cpu_count() / 2)
            if self._settingsCPU == 2 and multiprocessing.cpu_count() > 1:
                # aggressive on multiprocessor
                options += " -threads %i" % multiprocessing.cpu_count()
            
            
            # video
            if self.videoActive() \
            and self._formatCodec != self._codec_streamcopy:
                if self._inFileBitrate != self._formatBitrate:
                    if self._bitrateMode == 0:
                        video += " -b %ik" % self._formatBitrate
                    else:
                        video += " -b:v %ik" % self._formatBitrate
                if self._inFileFramerate != self._formatFramerate:
                    video += " -r %.2f " % self._formatFramerate
                if self._formatCodec != "" \
                and self._formatCodec != self._codec_filename:
                    video += " -vcodec " + self._formatCodec
                if self._formatDeinterlace:
                    video += " -deinterlace"
                # padcolor
                #000000000000
                r = "%02X" % (int(eval("0x" + self._formatPadColor[1:5])) / 256)
                g = "%02X" % (int(eval("0x" + self._formatPadColor[5:9])) / 256)
                b = "%02X" % (int(eval("0x" + self._formatPadColor[9:12])) / 256)
                
                # aspect
                if self.format4_3.get_active():
                    options += " -aspect 4:3"
                elif self.format16_9.get_active():
                    options += " -aspect 16:9"
                
                #r = r[2:].zfill(2)
                #g = g[2:].zfill(2)
                #b = b[2:].zfill(2)
                
                if self._inFileWidth != self._formatWidth \
                or self._inFileHeight != self._formatHeight:
                    #print "inFileWidth: %f" % self._inFileWidth
                    #print "inFileHeight: %f" % self._inFileHeight
                    #print "inFileRatio: %f" % self._inFileRatio
                    #print "formatWidth: %f" % self._formatWidth
                    #print "formatHeight: %f" % self._formatHeight
                    #print "formatRatio: %f" % self._formatRatio
                    
                    # pad areas
                    if self._formatScaling == 0 :
                        padcolor = "%s%s%s" % (r, g, b)
                        if self._inFileRatio < self._formatRatio:
                            # pad left & right
                            pad = self.roundPad(((self._formatHeight * self._inFileRatio) - self._formatWidth) / 2)
                            if self._videoFilter == 1:
                                video += " -vf \"scale=-1:%i,pad=%i:%i:%i:0:0x%s\"" % (self.equalSize(self._formatHeight),
                                                                                      self.equalSize(self._formatWidth),
                                                                                      self.equalSize(self._formatHeight),
                                                                                      pad,
                                                                                      padcolor)
                            elif self._videoFilter == 2:
                                video += " -vf \"scale=-1:%i,pad=%i:0:%i:%i:0x%s\"" % (self.equalSize(self._formatHeight),
                                                                                      pad,
                                                                                      self.equalSize(self._formatWidth),
                                                                                      self.equalSize(self._formatHeight),
                                                                                      padcolor)
                            else:
                                video += " -padleft %i -padright %i" % pad
                                video += " -s %ix%i" % self.roundSize(self._formatHeight * self._inFileRatio, self._formatHeight)
                        elif self._inFileRatio > self._formatRatio:
                            # pad top & bottom
                            pad = self.roundPad(((self._formatWidth / self._inFileRatio) - self._formatHeight) / 2)
                            if self._videoFilter == 1:
                                video += " -vf \"scale=%i:-1,pad=%i:%i:0:%i:0x%s\"" % (self.equalSize(self._formatWidth),
                                                                                      self.equalSize(self._formatWidth),
                                                                                      self.equalSize(self._formatHeight),
                                                                                      pad,
                                                                                      padcolor)
                            elif self._videoFilter == 2:
                                video += " -vf \"scale=%i:-1,pad=0:%i:%i:%i:0x%s\"" % (self.equalSize(self._formatWidth),
                                                                                      pad,
                                                                                      self.equalSize(self._formatWidth),
                                                                                      self.equalSize(self._formatHeight),
                                                                                      padcolor)
                            else:
                                video += " -padtop %i -padbottom %i" % pad
                                video += " -s %ix%i" % self.roundSize(self._formatWidth, self._formatWidth / self._formatRatio)
                        else:
                            # resize (no change in ratio)
                            if self._videoFilter > 0:
                                video += " -vf \"scale=%i:%i\"" % (self.equalSize(self._formatWidth),
                                                                   self.equalSize(self._formatHeight))
                            else:
                                video += " -s %ix%i" % self.roundSize(self._formatWidth, self._formatHeight)
                    # crop areas
                    elif self._formatScaling == 1:
                        if self._inFileRatio < self._formatRatio:
                            # crop top & bottom
                            crop = round((self._inFileHeight - (self._inFileWidth / self._formatRatio)) / 2)
                            if self._videoFilter == 1:
                                video += " -vf \"crop=0:%i:%i:%i, scale=%i:%i\"" % ( crop,
                                                                                    round(self._inFileWidth),
                                                                                    round(self._inFileHeight - (crop * 2)),
                                                                                    round(self._formatWidth),
                                                                                    round(self._formatHeight))
                            elif self._videoFilter == 2:
                                video += " -vf \"crop=%i:%i:0:%i, scale=%i:%i\"" % ( round(self._inFileWidth),
                                                                                    round(self._inFileHeight - (crop * 2)),
                                                                                    crop,
                                                                                    round(self._formatWidth),
                                                                                    round(self._formatHeight))
                            else:
                                video += " -croptop %i -cropbottom %i" % (crop, crop)
                                video += " -s %ix%i" % self.roundSize(self._formatWidth, self._formatHeight)
                        elif self._inFileRatio > self._formatRatio:
                            # crop left & right
                            crop = round((self._inFileWidth - (self._inFileHeight * self._formatRatio)) / 2)
                            if self._videoFilter == 1:
                                video += " -vf \"crop=%i:0:%i:%i, scale=%i:%i\"" % ( crop,
                                                                                    round(self._inFileWidth - (crop * 2)),
                                                                                    round(self._inFileHeight),
                                                                                    round(self._formatWidth),
                                                                                    round(self._formatHeight))
                            elif self._videoFilter == 2:
                                video += " -vf \"crop=%i:%i:%i:0, scale=%i:%i\"" % ( round(self._inFileWidth - (crop * 2)),
                                                                                    round(self._inFileHeight),
                                                                                    crop,
                                                                                    round(self._formatWidth),
                                                                                    round(self._formatHeight))
                            else:
                                video += " -cropleft %i -cropright %i" % (crop, crop)
                                video += " -s %ix%i" % self.roundSize(self._formatWidth, self._formatHeight)
                        else:
                            # resize (no change in ratio)
                            if self._videoFilter > 0:
                                video += " -vf \"scale=%i:%i\"" % (self.equalSize(self._formatWidth),
                                                                   self.equalSize(self._formatHeight))
                            else:
                                video += " -s %ix%i" % self.roundSize(self._formatWidth, self._formatHeight)
                    # scale
                    else:
                        if self._videoFilter > 0:
                            video += " -vf \"scale=%i:%i\"" % (self.equalSize(self._formatWidth), self.equalSize(self._formatHeight))
                        else:
                            video += " -s %ix%i" % self.roundSize(self._formatWidth, self._formatHeight)
            elif self.videoActive():
                video += " -vcodec copy"
            else:
                options += " -vn"
                        
            # audio
            newaudio = ""
            if self.audioActive() and self._formatAudioCodec != self._codec_streamcopy:
                # force codec
                if self._formatAudioCodec != "" \
                and self._formatAudioCodec != self._codec_filename:
                    audio += " -acodec " + self._formatAudioCodec
                #if self._inFileAudioBitrate != self._formatAudioBitrate:
                if self._bitrateMode == 0:
                    audio += (" -ab %ik" % self._formatAudioBitrate)
                else:
                    audio += (" -b:a %ik" % self._formatAudioBitrate)
                #if self._inFileAudioSamplerate != self._formatAudioSamplerate:
                audio += (" -ar %i" % self._formatAudioSamplerate)
                #if self._inFileAudioChannels != self._formatAudioChannels:
                audio += (" -ac %i" % self._formatAudioChannels)
                if self._formatVolume != self._defaultVolume:
                    audio += (" -vol %i" % self._formatVolume)
            elif self.audioActive():
                audio += " -acodec copy"
            else:
                options += " -an"
                    
            # meta
            if self._metaEnable:
                if self._metaTitle != "":
                    meta += " -title '" + self._metaTitle + "'"
                if self._metaAuthor != "":
                    meta += " -author '" + self._metaAuthor + "'"
                if self._metaCopyleft != "":
                    meta += " -copyright '" + self._metaCopyleft + "'"
                if self._metaComment != "":
                    meta += " -comment '" + \
                        self._metaComment.encode('string_escape') + "'"
            
            # mapping
            defvideo = True
            defaudio = True
            
            for i in range(0, len(self._videoStreams)):
                if self._videoStreams[i]["active"]:
                    mapping1 += " -map "
                    mapping1 += "%s%s%s" % (self._videoStreams[i]["file"],
                                          self._STREAM_SEPARATORS[self._streamSeparator],
                                          self._videoStreams[i]["ID"])
                    if self.newstream.get_active():
                        if defvideo:
                            defvideo = False
                        else:
                            newstreams += " %s -newvideo" % video
                        
            for i in range(0, len(self._audioStreams)):
                if self._audioStreams[i]["active"]:
                    mapping2 += " -map "
                    mapping2 += "%s%s%s" % (self._audioStreams[i]["file"],
                                          self._STREAM_SEPARATORS[self._streamSeparator],
                                          self._audioStreams[i]["ID"])
                    if self.newstream.get_active():
                        if defaudio:
                            defaudio = False
                        else:
                            newstreams += " %s -newaudio" % audio
                        
            # force overwrite
            options += " -y"
            
            # force container
            if self.getOutFileContainer():
                    options += " -f %s " % self.getOutFileContainer()
                    
            # user defined
            if self._formatUserDefined != "":
                if self._format2Pass:
                    uo = self._formatUserDefined.split("|")
                    user1 = uo[0].strip()
                    if len(uo) > 1:
                        user2 = uo[1].strip()
                    else:
                        user2 = user1
                else:
                    user1 = self._formatUserDefined
            
            infiles = ""
            for f in self._inFiles:
                infiles += " -i \"%s\"" % f["file"]
                
            # build command lines and create confirm window
            if self._format2Pass:
                if self._format2PassNA:
                    command_options1 = "%s%s %s %s -an %s %s \"%s\" %s" % (
                                                           self._command(),
                                                           infiles,
                                                           mapping1,
                                                           options + " -pass 1",
                                                           video,
                                                           user1,
                                                           "/dev/null",
                                                           newstreams)
                else:
                    command_options1 = "%s%s %s %s %s %s %s \"%s\" %s" % (
                                                           self._command(),
                                                           infiles,
                                                           mapping1 + mapping2,
                                                           options + " -pass 1",
                                                           audio,
                                                           video,
                                                           user1,
                                                           "/dev/null",
                                                           newstreams)
                                                           
                command_options2 = "%s%s %s %s %s %s %s \"%s\" %s" % (
                                                           self._command(),
                                                           infiles,
                                                           mapping1 + mapping2,
                                                           options + " -pass 2",
                                                           audio,
                                                           video,
                                                           user2,
                                                           self.filterOutFileSuffix(),
                                                           newstreams) 
                self.createConfirmation(self.buildConfirmInfo(),
                                        self.comCollapse(command_options1, self._COM_COLLAPSE),
                                        self.comCollapse(command_options2, self._COM_COLLAPSE))
            else:
                command_options = "%s%s %s %s %s %s %s \"%s\" %s" % (
                                                           self._command(),
                                                           infiles,
                                                           mapping1 + mapping2,
                                                           options,
                                                           audio,
                                                           video,
                                                           user1,
                                                           self.filterOutFileSuffix(),
                                                           newstreams)
                self.createConfirmation(self.buildConfirmInfo(),
                                        self.comParse(command_options),
                                        False)
    
    def comParse(self, com):
        """parses the overall commandline for different substitutions and
        manipulations"""
        # multiple options
        com = self.comCollapse(com, self._COM_COLLAPSE)
        # multiple whitespaces
        com = " ".join(com.split())
        return com
        
    def comCollapse(self, com, options):
        """replace multiple options with a single instance separated by colons
        and wrapped in quotes"""
        for o in options:
            r = re.compile('(-%s [^ "]+|-%s "[^"]+")' % (o, o))
            m = r.findall(com)
            c = 0
            str_ = ""
            pos = 0
            for i in m:
                if c == 0:
                    pos = com.find(i)
                com = com.replace(i, "")
                i = i[4:].strip("\"")
                str_ += i + ", "
                c += 1
            if len(str_) > 2:
                str_ = str_[:-2]
                com = com[:pos] + ("-%s \"" % o) + str_ + "\" " + com[pos:]
        return com
            
#######################################
# FINALLY... DO IT!
#######################################    
    def processCall(self, widget):
        """execute the generated, edited and confirmed command"""
        self.preProcess()
        self.ffmpegExec = ffmpegExec(self, self._execute,
                                     self.updateProgress,
                                     self.finishProgress,
                                     self._settingsCPU)
        self.ffmpegExec.start()
        
    def preProcess(self):
        """some procedures to call before we can beat the monkey"""
        self._progressInStreams = False
        self._progressFfinishedGracefully = False
        self._ffmpegOut = ""
        try:
            self.confirmWin.get_widget("tragtorConfirm").destroy()
        except:
            pass
        if self._format2Pass == True and self._currentPass == 1:
            # 2-pass - pass 1
            self._execute = self.commandlineText1.get_text(
                self.commandlineText1.get_start_iter(),
                self.commandlineText1.get_end_iter(),
                include_hidden_chars=True
            )
            self._execute2 = self.commandlineText2.get_text(
                self.commandlineText2.get_start_iter(),
                self.commandlineText2.get_end_iter(),
                include_hidden_chars=True
            )
            self.resetFFmpegOut()
            self._currpass = 1
        elif self._format2Pass == True:
            # 2-pass - pass 2
            self._execute = self._execute2
            self._currpass = 2
        else:
            # single pass
            self._execute = self.commandlineText1.get_text(
                self.commandlineText1.get_start_iter(),
                self.commandlineText1.get_end_iter(),
                include_hidden_chars=True
            )
            self.resetFFmpegOut()
            self._currpass = None
            
        self._inProgress = True
        self._cancelProcess = False
        self.buttonProceed.set_sensitive(False)
        
        self.createProgressWin()
      
    def postProcess(self):
        """clean up when you've finished or trigger 2nd pass"""
        if self._format2Pass == True and self._currentPass == 1:
            self._currentPass = 2
            self.processCall(False)
        else:
            if(self.config.has_option("Settings", "progressActions")):
                try:
                    action = eval(self.config.get("Settings", "progressActions"))
                except:
                    action = self.config.get("Settings", "progressActions")
                if(action == 1):
                    # play file
                    os.popen(self._OPENCOMMAND + " \"%s\"" % self.filterOutFileSuffix())
                if(action == 2):
                    # close progress
                    self.progressWin.get_widget("tragtorProgress").destroy()
                if(action == 3):
                    # close tragtor
                    self.progressWin.get_widget("tragtorProgress").destroy()
                    self.window.get_widget("tragtor").destroy()
                    self.destroy(False)
                    exit(0)
                if(action > 3):
                    bus = dbus.SystemBus()
                    bus_object = bus.get_object("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer")
                if(action == 4):
                    # shutdown
                    bus_object.Shutdown(0, dbus_interface="org.freedesktop.Hal.Device.SystemPowerManagement")
                    exit(0)
                if(action == 5):
                    # hibernate
                    bus_object.Hibernate(0, dbus_interface="org.freedesktop.Hal.Device.SystemPowerManagement")
                    exit(0)
                if(action == 6):
                    # suspend
                    bus_object.Suspend(0, dbus_interface="org.freedesktop.Hal.Device.SystemPowerManagement")
                    exit(0)
            self._currentPass = 1
            self.cleanup()
            self.buttonProceed.set_sensitive(True)
            self.analyzeOutFile()
            self.checkProceed()
    
    def cleanup (self):
        if self.cleanup2Pass.get_active():
            os.system("rm -f %s/ffmpeg2pass*.log %s/av2pass*.log" % (os.getcwd(), os.getcwd()))
    
#######################################
# RESET EVERYTHING
#######################################            

    def reset(self, init = False):
        """Reset all values to default, fills all labels,
        combos and buttons with default values"""
        # reset all internals
        self.resetFormat()
        self.resetMeta()
        # erase ffmpegOut
        self.resetFFmpegOut()
        # reset suffix to "as filename"
        if self.config.has_option("Settings", "outFileSuffix"):
            self._outFileSuffix = int(self.config.get("Settings",
                                                      "outFileSuffix"))
        else:
            self._outFileSuffix = 0
        self.outFileSuffix.set_active(self._outFileSuffix)
        # look for an inFile as argument on startup
        cache = self._inFileAdd
        if len(self._argInFiles):
            if len(self._argInFiles) > 1:
                self._inFileAdd = True
            for i in self._argInFiles:
                f = self.setInFile(i)
                if f:
                    self.addInFile(f)
        else:
            f = self.setInFile(self._defFile)
            if f:
                self.addInFile(f)
        self._inFileAdd = cache
        
        if self.config.has_option("Settings", "outFile"):
            self.setOutFile(self.config.get("Settings", "outFile"))
        elif len(self._inFiles):
            self.setOutFile(self._inFiles[0]["file"])
        else:
            self.setOutFile(os.path.join(self._defFile, self._defFileName))
        
        self.displayInFiles()
        self.setInFileToggle(self._inFileAdd)
        self.fillLabels()
        self.fillTextCombos(refill = False)
        self.reloadTreeViewColumns()
        self.toggleMeta(self._metaEnable)
        self.analyzeOutFile()
        
#######################################
# SET INTERNAL VALUES
#######################################                
    def setInFileFormat(self):
        """fill inFileFormats depending on active streams"""
        self.zeroInFileFormat()
        c = 0
        streams = self._videoStreams + self._audioStreams
        for i in streams:
            if i["active"]:
                if i["format"] == "Video":
                    xy = i["size"].split("x")
                    if c == 0 or int(xy[0]) > self._inFileWidth:
                        self._inFileWidth = int(xy[0])
                        self._inFileHeight = int(xy[1])
                        if self._inFileHeight > 0:
                            self._inFileRatio = self.roundFloat(
                                float(self._inFileWidth) / float(self._inFileHeight), 4
                            )
                        else:
                            self._inFileRatio = 1.0
                    if c == 0 or i["fps"] > self._inFileFramerate:
                        self._inFileFramerate = i["fps"]
                    
                    br = self._inFiles[i["file"]]["bitrate"] if self._inFiles[i["file"]]["bitrate"] > i["bitrate"] else i["bitrate"]
                    if c == 0 \
                    or br > self._inFileBitrate:
                        self._inFileBitrate = br  
                if i["format"] == "Audio":
                    if c == 0 \
                    or i["samplerate"] > self._inFileAudioSamplerate:
                        self._inFileAudioSamplerate = i["samplerate"]
                    if c == 0 \
                    or i["bitrate"] > self._inFileAudioBitrate:
                        self._inFileAudioBitrate = i["bitrate"]
                    if c == 0 \
                    or i["channels"] > self._inFileAudioChannels:
                        self._inFileAudioChannels = i["channels"]
                if c == 0 \
                or self._inFiles[i["file"]]["duration"] > self._inFileDuration:
                    self._inFileDuration = self._inFiles[i["file"]]["duration"]
                if c == 0 \
                or self._inFiles[i["file"]]["start"] < self._inFileOffset:
                    self._inFileOffset = self._inFiles[i["file"]]["start"]
                c += 1
        if self._inFileBitrate - self._inFileAudioBitrate <= 0:
            self._inFileBitrate = self._defaultBitrate
        self.unzeroInFileFormat()
        
    def setFormat(self):
        """Fill the internal format-values with presets
        depending on sourcefiles"""
        
        self._formatWidth = self._inFileWidth
        self._formatHeight = self._inFileHeight
        self._formatRatio = self._inFileRatio
        self._formatFramerate = self._inFileFramerate
        if self._inFileBitrate != "N/A":
            self._formatBitrate = self._inFileBitrate
        else:
            self._formatBitrate = 0

        self._formatAudioSamplerate = self._inFileAudioSamplerate
        self._formatAudioBitrate = self.calulateNewBitrate(self._inFileAudioBitrate)
        self._formatAudioChannels =    self._inFileAudioChannels
    
        self._formatDuration = self._inFileDuration
        self._formatOffset = self._inFileOffset
        self._formatFramerate = self._inFileFramerate
        if self._formatFramerate <= 0.0: self._formatFramerate = self._defaultFramerate
            
    def setMeta(self, inFile):
        """Fill the meta-related internal values depending on sourcefile"""
        self._metaComment = self.lang.meta_comment_text
        if len(self._inFiles) > inFile:
            self._metaTitle = os.path.basename(
                self._inFiles[inFile]["file"]
            )[:os.path.basename(self._inFiles[inFile]["file"]).rfind(".")].title()
        else:
            self._metaTitle = ""
        self._metaAuthor = ""
        self._metaCopyright = ""
        try:
            id3v2obj = id3v2(self._inFiles[int(inFile)])
            if id3v2obj.id3v1:
                if id3v2obj.id3v1["Title"] != "":
                    self._metaTitle = id3v2obj.id3v1["Title"]
                if id3v2obj.id3v1["Artist"] != "":
                    self._metaAuthor = id3v2obj.id3v1["Artist"]
                if id3v2obj.id3v1["Comment"] != "":
                    self._metaComment = id3v2obj.id3v1["Comment"]
        except:
            True        

    def setLanguage(self):
        """changes the language-object to internal language"""
        self.lang = eval("lang_" + self._LANGUAGE + ".tragtorLang")()
        self.saveConfigValue("Settings",
                             "language",
                             self._LANGUAGE,
                             self._CFG_SETTINGS)
    
    def setInFileToggle(self, state):
        if state:
            self.inFileToggle.set_label(self.lang.in_file_add_label)
        else:
            self.inFileToggle.set_label(self.lang.in_file_select_label)
        self.inFileToggle.set_active(state)
        
        
#######################################
# RESET INTERNAL VALUES
#######################################
    
    def zeroInFileFormat(self):
        """resets the internal values to default"""
        self._inFileWidth = 0
        self._inFileHeight = 0
        self._inFileRatio = 0
        self._inFileFramerate = 0
        self._inFileBitrate = 0
        self._inFileAudioSamplerate = 0
        self._inFileAudioBitrate = 0
        self._inFileAudioChannels = 0
        self._inFileOffset = 0
        self._inFileDuration = 0
    
    def unzeroInFileFormat(self):
        """resets the internal values to default"""
        if not self._inFileWidth:
            self._inFileWidth = self._defaultWidth
        if not self._inFileHeight:
            self._inFileHeight = self._defaultHeight
        if not self._inFileRatio:
            self._inFileRatio = self._defaultRatio
        if not self._inFileFramerate:
            self._inFileFramerate = self._defaultFramerate
        if not self._inFileBitrate:
            self._inFileBitrate = self._defaultBitrate
        if not self._inFileAudioSamplerate:
            self._inFileAudioSamplerate = self._defaultAudioSamplerate
        if not self._inFileAudioBitrate:
            self._inFileAudioBitrate = self._defaultAudioBitrate
        if not self._inFileAudioChannels:
            self._inFileAudioChannels = self._defaultAudioChannels
        if not self._inFileOffset:
            self._inFileOffset = self._defaultOffset
        if not self._inFileDuration:
            self._inFileDuration = self._defaultDuration
            
    def resetFormat(self):
        """resets the internal values to default"""
        self._formatWidth = self._defaultWidth
        self._formatHeight = self._defaultHeight
        self._formatRatio = self._defaultRatio
        self._formatFixedRatio = self._defaultFixedRatio
        self._formatFramerate = self._defaultFramerate
        self._formatDeinterlace = self._defaultDeinterlace
        self._formatBitrate = self._defaultBitrate
        self._formatAudioSamplerate = self._defaultAudioSamplerate
        self._formatAudioBitrate = self._defaultAudioBitrate
        self._formatAudioCodec = self._defaultAudioCodec
        self._formatAudioChannels = self._defaultAudioChannels
        self._formatVolume = self._defaultVolume
        self._formatCodec = self._defaultCodec
        self._formatOffset = self._defaultOffset
        self._formatDuration = self._defaultDuration
        self._formatScaling = self._defaultScaling
        self._formatPadColor = self._defaultPadColor
        self._formatHiQ = self._defaultHiQ
        self._formatBitrateVariation = self._defaultBitrateVariation
        self._format2Pass = self._default2Pass
        self._format2PassNA = self._default2PassNA
        self._formatUserDefined = self._defaultUserDefined
        
    def resetMeta(self):
        """resets internal metaData to none"""
        self._metaTitle = ""
        self._metaAuthor = ""
        self._metaCopyleft = ""
        self._metaComment = ""
        self._metaEnable = self._defaultMetaEnable

#######################################
# SET INTERNAL VALUES DEPENDING ON PRESET
#######################################

    def presetFormat(self, name):
        for i in self._DEFAULT_PRESET:
            try:
                value = self.presets.get(name, i)
                if value == "" \
                or (re.search(r"[A-Za-z\-_#{}\[\]\\=\?\*\+§\!\%\&<>]", str(value)) \
                and not re.match(r"^(True|False)$", str(value).strip())):
                        value = "'%s'" % str(value)
                exec("self._format%s = %s" % (i, value))
            except:
                True
        if self.presetContainer.get_active():
            cont = ""
            try:
                cont = self.presets.get(name, "Container")
                for j in range(0, len(self.ffmpegConfig._saveFileFormats)):
                    if self.ffmpegConfig._saveFileFormats[j][0] == cont:
                        self._outFileSuffix = j + 1
                        self.outFileSuffix.set_active(self._outFileSuffix)
            except:
                True
            
            

#######################################
# FILL THE GUI WITH VALUES AND LABELS
#######################################
    
    def fillFormat(self):
        """fill the format-widgets with object-values"""
        if self.inputRead():
            self.formatDurationAdjustment.upper = self._inFileDuration + self._inFileOffset
            self.formatOffsetAdjustment.upper = self._inFileDuration + self._inFileOffset
        else:
            self.formatDurationAdjustment.upper = 0
            self.formatOffsetAdjustment.upper = 0
            
        
        self.formatOffset.set_value(self._formatOffset)
        self.formatDuration.set_value(self._formatDuration)
        self.formatRatio.set_value(self._formatRatio)
        self.formatWidth.set_value(self._formatWidth)
        self.formatHeight.set_value(self._formatHeight)
        
        self.formatFramerate.set_value(self._formatFramerate)
        self.formatBitrate.set_value(self._formatBitrate)
        self.formatAudioSamplerate.child.set_text("%i" % self._formatAudioSamplerate)
        self.formatAudioBitrate.child.set_text("%i" % self._formatAudioBitrate)
        self.formatAudioChannels.child.set_text("%i" % self._formatAudioChannels)
        self.formatVolumeDisplay.set_text("%i%s" % (self.value2perc(256,
                                                            self._formatVolume,
                                                            True), "%"))
        self.formatVolumeFader.set_value(self._formatVolume)
        if self._formatAudioCodec in self.ffmpegConfig._saveAudioCodecs:
            self.formatAudioCodec.set_active(
                self.ffmpegConfig._saveAudioCodecs.index(self._formatAudioCodec) + 2
            )
        elif self._formatAudioCodec == self._codec_streamcopy:
            self.formatAudioCodec.set_active(1)
        else:
            self.formatAudioCodec.set_active(0)
        if self._formatCodec in self.ffmpegConfig._saveVideoCodecs:
            self.formatCodec.set_active(
                self.ffmpegConfig._saveVideoCodecs.index(self._formatCodec) + 2
            )
        elif self._formatCodec == self._codec_streamcopy:
            self.formatCodec.set_active(1)
        else:
            self.formatCodec.set_active(0)
            
        self.formatScaling.set_active(self._formatScaling)
        self.formatFixedRatio.set_active(self._formatFixedRatio)
        self.format2Pass.set_active(self._format2Pass)
        self.format2PassNA.set_active(self._format2PassNA)
        self.toggleNoAudio(self._format2Pass)
        self.formatPadColor.set_color(gtk.gdk.color_parse(self._formatPadColor))
        self.formatUserDefined.set_text(self._formatUserDefined)
        self.formatDeinterlace.set_active(self._formatDeinterlace)
        
    def fillMeta(self):
        self.metaTitle.set_text(self._metaTitle)
        self.metaAuthor.set_text(self._metaAuthor)
        self.metaCopyleft.set_text(self._metaCopyleft)
        self.metaComment.set_text(self._metaComment)
                
    def fillLabels(self):
        """Fill al the labels with language-depending text"""
        self.window.get_widget("labelInput").set_text(self.lang.in_file_label)
        self.window.get_widget("labelFormatAudio").set_text(self.lang.format_audio_label)
        self.window.get_widget("labelFormatVideo").set_text(self.lang.format_video_label)
        self.window.get_widget("labelFormatRender").set_text(self.lang.format_render_label)
        self.window.get_widget("labelFormatResults").set_text(self.lang.format_results_label)
        self.window.get_widget("labelMeta").set_text(self.lang.meta_label)
        self.window.get_widget("labelProceed").set_text(self.lang.proceed_label)
        self.window.get_widget("labelSettings").set_text(self.lang.settings_label)
        
        self.window.get_widget("labelInFileAudio").set_text(self.lang.in_file_audio_label)
        self.window.get_widget("labelInFileVideo").set_text(self.lang.in_file_video_label)
        self.window.get_widget("labelInFileOpen").set_text(self.lang.in_file_open_label)
        
        self.window.get_widget("notebookInput").set_text(self.lang.in_file_notebook)
        self.window.get_widget("notebookFormat").set_text(self.lang.format_notebook)
        self.window.get_widget("notebookMeta").set_text(self.lang.meta_notebook)
        self.window.get_widget("notebookProceed").set_text(self.lang.proceed_notebook)
        self.window.get_widget("notebookSettings").set_text(self.lang.settings_notebook)
        
        self.window.get_widget("labelFormatWidth").set_text(self.lang.format_width_label)
        self.window.get_widget("labelFormatHeight").set_text(self.lang.format_height_label)
        self.window.get_widget("labelFormatRatio").set_text(self.lang.format_ratio_label)
        self.window.get_widget("labelFormatFixed").set_text(self.lang.format_fixed_ratio_label)
        self.window.get_widget("labelFormatFramerate").set_text(self.lang.format_frame_rate_label)
        self.window.get_widget("labelFormatDeinterlace").set_text(self.lang.format_deinterlace_label)
        
        self.window.get_widget("labelFormatAudioSamplerate").set_text(self.lang.format_audio_sample_rate_label)
        self.window.get_widget("labelFormatAudioBitrate").set_text(self.lang.format_audio_bitrate_label)
        self.window.get_widget("labelFormatAudioCodec").set_text(self.lang.format_audio_codec_label)
        self.window.get_widget("labelFormatAudioChannels").set_text(self.lang.format_audio_channels_label)
        
        self.window.get_widget("labelFormatCodec").set_text(self.lang.format_codec_label)
        self.window.get_widget("labelFormatBitrate").set_text(self.lang.format_bitrate_label)
        self.window.get_widget("labelFormatOffset").set_text(self.lang.format_offset_label)
        self.window.get_widget("labelFormatDuration").set_text(self.lang.format_duration_label)
        self.window.get_widget("labelFormatScaling").set_text(self.lang.format_scaling_label)
        self.window.get_widget("labelFormatPadColor").set_text(self.lang.format_pad_color_label)
        self.window.get_widget("labelFormat2Pass").set_text(self.lang.format_2_pass_label)
        self.window.get_widget("labelFormat2PassNA").set_text(self.lang.format_2_pass_no_audio_label)
        self.window.get_widget("labelFormatVolume").set_text(self.lang.format_volume_label)
        self.window.get_widget("labelFormatUserDefined").set_text(self.lang.format_user_defined_label)
        self.window.get_widget("buttonManual").set_label(self.lang.format_manual_button)
        
        self.window.get_widget("labelPresets").set_text(self.lang.presets_label)
        self.window.get_widget("labelFormatPreset").set_label(self.lang.presets_container)
        
        self.window.get_widget("labelMetaTitle").set_text(self.lang.meta_title_label)
        self.window.get_widget("labelMetaAuthor").set_text(self.lang.meta_author_label)
        self.window.get_widget("labelMetaCopyleft").set_text(self.lang.meta_copyleft_label)
        self.window.get_widget("labelMetaComment").set_text(self.lang.meta_comment_label)    
        self.window.get_widget("labelMetaEnable").set_text(self.lang.meta_toggle_label)
        
        self.window.get_widget("frameOutput").set_label(self.lang.frame_output)
        self.window.get_widget("frameProceed").set_label(self.lang.frame_proceed)
        self.window.get_widget("labelProceedFolder").set_label(self.lang.proceed_folder_label)
        self.window.get_widget("labelProceedSuffix").set_label(self.lang.proceed_suffix_label)
        self.window.get_widget("labelProceedName").set_label(self.lang.proceed_name_label)
        self.window.get_widget("buttonOutName").set_label(self.lang.out_file_menu_name)
        self.window.get_widget("buttonOutPath").set_label(self.lang.out_file_menu_path)
        
        self.window.get_widget("labelSettingsLanguage").set_text(self.lang.settings_language_label)    
        self.window.get_widget("labelSettingsReset").set_text(self.lang.settings_reset_label)    
        self.window.get_widget("buttonLabelSettingsReset").set_text(self.lang.settings_reset_button)    
        self.window.get_widget("labelSettingsVideofilter").set_text(self.lang.settings_video_filter_label)
        self.window.get_widget("labelSettingsBitrateMode").set_text(self.lang.settings_bitrate_mode_label)
        self.window.get_widget("labelSettingsCleanup2Pass").set_text(self.lang.settings_cleanup_2_pass_label)
        self.window.get_widget("labelSettingsNewstream").set_text(self.lang.settings_newstream_label)
        self.window.get_widget("labelSettingsCPU").set_text(self.lang.settings_cpu_label)
        self.window.get_widget("labelSettingsProgressActions").set_text(self.lang.settings_progress_actions)
        self.window.get_widget("labelSettingsTragtor").set_text(self.lang.settings_tragtor_label)
        self.window.get_widget("labelSettingsFFmpeg").set_text(self.lang.settings_ffmpeg_label)
        self.window.get_widget("labelSettingsStreamSeparator").set_text(self.lang.settings_stream_label)
        self.window.get_widget("infoTragtor").set_text("Version %s" % self._VERSION)
        txt = ("%s\n%s%s" % (self.ffmpegConfig._ffmpegVersion,
                               self.ffmpegConfig._build,
                               self.ffmpegConfig._libs))
        self.window.get_widget("infoFFmpeg").set_text(txt)
        self.window.get_widget("labelVersionExpander").set_markup(self.lang.settings_version_label)
        self.window.get_widget("tableSettingsInfo").hide_all()
        self.window.get_widget("tableSettingsInfo").show_all()
        self.checkProceed()
    
    def fillTextCombos(self, refill):
        """fills all configured comboBoxes with language-specific values"""
        for i in range(len(self._languageCombos)):
            array = eval("self.lang." + self._languageCombos[i][1])
            obj = eval("self." + self._languageCombos[i][0])
            val = eval("self._" + self._languageCombos[i][0])
            lst = obj.get_model()
            if refill:
                lst.clear()
            for c in range(len(array)):
                obj.append_text(array[c])
            obj.set_active(val)

    #inFile Filters
    def reloadInFileFilter(self):
        """reloads the language-specific entries in the
        fileselector on source-page"""
        for f in self.inFileChooser.list_filters():
            self.inFileChooser.remove_filter(f)
            f.destroy()
        self.inFileFilter = gtk.FileFilter()
        self.inFileFilter.set_name(self.lang.title_in_file_media_files)
        for f in self.ffmpegConfig._openFileFormats:
            self.inFileFilter.add_pattern("*" + f[2])
        self.inFileChooser.add_filter(self.inFileFilter)
        self.inFileNoFilter = gtk.FileFilter()
        self.inFileNoFilter.set_name(self.lang.title_in_file_all_files)
        self.inFileNoFilter.add_pattern("*")
        self.inFileChooser.add_filter(self.inFileNoFilter)
        self.inFileChooser.set_filter(self.inFileNoFilter)
        
    #outFile Filters
    def reloadOutFileFilter(self):
        """reloads the language-specific entries in the
        fileselector-dialog on target-page"""
        for f in self.outFileChooser.list_filters():
            self.outFileChooser.remove_filter(f)
            f.destroy()
        self.outFileFilter = gtk.FileFilter()
        self.outFileFilter.set_name(self.lang.title_out_file_media_files)
        for f in self.ffmpegConfig._saveFileFormats:
            self.outFileFilter.add_pattern("*" + f[0])
        self.outFileChooser.add_filter(self.outFileFilter)
        self.outFileNoFilter = gtk.FileFilter()
        self.outFileNoFilter.set_name(self.lang.title_out_file_all_files)
        self.outFileNoFilter.add_pattern("*")
        self.outFileChooser.add_filter(self.outFileNoFilter)
        self.outFileChooser.set_filter(self.outFileFilter)
                
    def reloadOutFileSuffix(self):
        """reloads the language-specific part in the
        suffix-selector on target-page"""
        active = self.outFileSuffix.get_active()
        self.outFileSuffix.remove_text(0)
        self.outFileSuffix.insert_text(0, self.lang.output_file_suffix_auto)
        self.outFileSuffix.set_active(active)
    
    def reloadTreeViewColumns(self):
        """adds all columns to audio- and video treestore
        on inFile-page"""
        # VideoTreeView
        for c in self.inFileVideoTree.get_columns():
            self.inFileVideoTree.remove_column(c)
        
        column = gtk.TreeViewColumn(self.lang.in_file_video_preview)
        cell = gtk.CellRendererPixbuf()
        cell.set_fixed_size(-1, 24)
        column.pack_start(cell, False)
        column.add_attribute(cell, "pixbuf", 9)
        self.inFileVideoTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_video_file)
        cell = gtk.CellRendererText()
        column.pack_start(cell, False)
        column.add_attribute(cell, "text", 1)
        column.add_attribute(cell, "background", 8)
        cell.set_property("foreground", "#666")
        self.inFileVideoTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_video_id)
        cell = gtk.CellRendererText()
        column.pack_start(cell, False)
        column.add_attribute(cell, "text", 2)
        self.inFileVideoTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_video_select)
        cell = gtk.CellRendererToggle()
        column.pack_start(cell, False) #2nd: expand
        cell.connect("toggled", self.selectVideo, self.inFileVideoTree)
        cell.set_property("activatable", True)
        column.add_attribute(cell, "active", 0)
        self.inFileVideoTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_video_codec)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 3)
        self.inFileVideoTree.append_column(column)
            
        column = gtk.TreeViewColumn(self.lang.in_file_video_method)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 4)
        self.inFileVideoTree.append_column(column)
            
        column = gtk.TreeViewColumn(self.lang.in_file_video_size)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 5)
        self.inFileVideoTree.append_column(column)
            
        column = gtk.TreeViewColumn(self.lang.in_file_video_fps)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 6)
        self.inFileVideoTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_video_language)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 7)
        self.inFileVideoTree.append_column(column)
        
        #AudioTreeView
        for c in self.inFileAudioTree.get_columns():
            self.inFileAudioTree.remove_column(c)
            
        column = gtk.TreeViewColumn(self.lang.in_file_audio_file)
        cell = gtk.CellRendererText()
        cell.set_fixed_size(-1, 24)
        column.pack_start(cell, False)
        column.add_attribute(cell, "text", 1)
        column.add_attribute(cell, "background", 8)
        cell.set_property("foreground", "#666")
        self.inFileAudioTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_audio_id)
        cell = gtk.CellRendererText()
        column.pack_start(cell, False)
        column.add_attribute(cell, "text", 2)
        self.inFileAudioTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_video_select)
        cell = gtk.CellRendererToggle()
        column.pack_start(cell, False) #2nd: expand
        cell.connect("toggled", self.selectAudio, self.inFileAudioTree)
        cell.set_property("activatable", True)
        column.add_attribute(cell, "active", 0)
        self.inFileAudioTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_audio_codec)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 3)
        self.inFileAudioTree.append_column(column)
            
        column = gtk.TreeViewColumn(self.lang.in_file_audio_sample_rate)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 4)
        self.inFileAudioTree.append_column(column)
            
        column = gtk.TreeViewColumn(self.lang.in_file_audio_channels)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 5)
        self.inFileAudioTree.append_column(column)
            
        column = gtk.TreeViewColumn(self.lang.in_file_audio_bitrate)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 6)
        self.inFileAudioTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_audio_language)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 7)
        self.inFileAudioTree.append_column(column)
        
        #FileTreeView
        for c in self.inFileOpenTree.get_columns():
            self.inFileOpenTree.remove_column(c)
            
        column = gtk.TreeViewColumn(self.lang.in_file_open_id)
        cell = gtk.CellRendererText()
        cell.set_fixed_size(-1, 24)
        column.pack_start(cell, False)
        column.add_attribute(cell, "text", 0)
        column.add_attribute(cell, "background", 5)
        cell.set_property("foreground", "#666")
        self.inFileOpenTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_open_file)
        cell = gtk.CellRendererText()
        column.pack_start(cell, False)
        column.add_attribute(cell, "text", 1)
        column.set_expand(True)
        self.inFileOpenTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_open_size)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 2)
        self.inFileOpenTree.append_column(column)
            
        column = gtk.TreeViewColumn(self.lang.in_file_open_container)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 3)
        self.inFileOpenTree.append_column(column)
        
        column = gtk.TreeViewColumn(self.lang.in_file_open_duration)
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        column.add_attribute(cell, "text", 4)
        self.inFileOpenTree.append_column(column)
                
#######################################
# FORMAT AND DISPLAY TEXT
#######################################

    def resetFFmpegOut(self):
        """resets the ffmpegOut-Textarea to blank"""
        self.ffmpegOutText.set_text("")
        
    def calculateTargetInfo(self):
        """generates a readable string with output-results"""
        if self.inputRead():
            videosize = self._formatDuration * self._formatBitrate
            audiosize = self._formatDuration * self._formatAudioBitrate
            videosize = videosize * self.videoActiveCount()
            audiosize = audiosize * self.audioActiveCount()
            overall = self.kbs2string(videosize + audiosize)
            audiosize = self.kbs2string(audiosize)
            videosize = self.kbs2string(videosize)
            if not self.audioActive() and self.videoActive():
                output = self.lang.format_target_info % (
                    self.lang.format_target_info_video % (
                        self.seconds2human(self._formatDuration), videosize))
            elif self.audioActive() and self.videoActive():
                output = self.lang.format_target_info % (
                    self.lang.format_target_info_av % (
                        self.seconds2human(self._formatDuration), overall))
            elif self.audioActive() and not self.videoActive():
                output = self.lang.format_target_info % (
                    self.lang.format_target_info_audio % (
                        self.seconds2human(self._formatDuration), audiosize))
            else:
                output = self.lang.format_target_info_nothing
            self.formatResultInfo.set_markup(output)
        else:
            self.formatResultInfo.set_markup(self.lang.format_target_no_file)

    def buildConfirmInfo(self):
        """creates the infotext for the confirmation-dialog from lang-files"""
        videosize = self._formatDuration * self._formatBitrate
        audiosize = self._formatDuration * self._formatAudioBitrate
        infiles = ""
        if len(self._inFiles) > 1:
            in_file_label = self.lang.label_confirm_in_files
        else:
            in_file_label = self.lang.label_confirm_in_file
        for i in self._inFiles:
            infiles += "\n" + self.htmlEncode(os.path.basename(
                i["file"])
            ) + " " + self.lang.label_confirm_in_size % self.bytes2string(i["size"])
        output = (in_file_label % infiles) + "\n"
        output += (self.lang.label_confirm_out_file % (
            "\n" + self.htmlEncode(os.path.basename(self.filterOutFileSuffix()))
        )) + " "
        if not self.audioActive() and self.videoActive():
            output += self.lang.label_confirm_out_size % \
                self.kbs2string(videosize) + "\n"
            self._outFileSize = videosize
        elif self.audioActive() and self.videoActive():
            output += self.lang.label_confirm_out_size % \
                self.kbs2string(videosize + audiosize) + "\n"
            self._outFileSize = videosize + audiosize
        elif self.audioActive() and not self.videoActive():
            output += self.lang.label_confirm_out_size % \
                self.kbs2string(audiosize) + "\n"
            self._outFileSize = audiosize
        else:
            output +=  "\n"
        output +=  "\n"
        output += self.lang.label_confirm_format % (
            self._outFileFormat[0] + " (" + self._outFileFormat[1]
        ) + ")\n"
        if self.videoActive():
            output += self.lang.label_confirm_size % (
                "%ix%i" % (self._formatWidth, self._formatHeight)
            ) + "\n"
            if self._formatCodec != "":
                output += self.lang.label_confirm_video % \
                    (self._formatCodec) + "\n"
        if self.audioActive():
            if self._formatAudioCodec != "":
                output += (self.lang.label_confirm_audio % \
                    self._formatAudioCodec) + "\n"
        if not self.audioActive():
            output += (self.lang.label_confirm_audio % \
                self.lang.label_confirm_audio_disabled) + "\n"
        output += self.lang.label_confirm_offset % \
            self.seconds2human(self._formatOffset) + "\n"
        output += self.lang.label_confirm_duration % \
            self.seconds2human(self._formatDuration) + "\n"
        return output
                

#######################################
# HELPERS AND STUFF
#######################################

    def htmlDecode(self, s):
        """ Returns the ASCII decoded version of the given HTML string. """
        htmlCodes = [
            ['&', '&amp;'],
            ['<', '&lt;'],
            ['>', '&gt;'],
            ['"', '&quot;'],
        ]
        for code in htmlCodes:
            s = s.replace(code[1], code[0])
        return s

    def htmlEncode(self, s):
        """ Returns the HTML encoded version of the given string.."""
        htmlCodes = [
            ['&', '&amp;'],
            ['<', '&lt;'],
            ['>', '&gt;'],
            ['"', '&quot;'],
        ]
        for code in htmlCodes:
            s = s.replace(code[0], code[1])
        return s
    
    def roundFloat(self, value, digits):
        strval = str(value)
        while len(strval) < 6:
            strval += "0"
        if strval[2] == strval[3] == strval[4] == strval[5]:
            return eval(strval[:6])
        value *= 10 ** digits
        return round(value) / 10 ** digits

    def roundSize(self, width, height):
        width = round(width)
        height = round(height)
        if width % 2 == 1: width -= 1
        if height % 2 == 1: height -= 1
        return (width, height)

    def equalSize(self, size):
        size = round(size)
        if size % 2 == 1: size -=1
        return size
    
    def roundPad(self, pad):
        if pad < 0 : pad *= -1
        if self._videoFilter > 0:
            pad = round(pad)
            return int(pad)
        if pad % 1:
            pad1 = int(pad)
            pad2 = int(pad) + 1
        else: pad1 = pad2 = pad
        if pad1 % 2 == 1: pad1 -= 1
        if pad2 % 2 == 1: pad2 += 1
        return (pad1, pad2)
    
    def seconds2frames(self, seconds, fps):
        """converts a given second-float to frames and seconds,
        no zero-fps allowed"""
        ms = int(seconds * 1000)
        fms = 1000 / fps
        frames = int(ms / fms)
        framesover = int(frames % fps)
        seconds = int(frames / fps)
        msover = framesover * fms
        return [frames, framesover, seconds, msover]

    def seconds2timetuple(self, seconds):
        if seconds > 0:
            h = int(seconds / (60 * 60))
            m = int((seconds - (h * 60 * 60)) / 60)
            s = int(seconds - (h * 60 * 60) - (m * 60))
            x = int(round((seconds % 1) * 1000))
            return (h, m, s, x)
        else:
            return (0, 0, 0, 0)
    
    def seconds2timestring(self, seconds):
        """generates hh:mm:ss.xxx from seconds"""
        return "%.2d:%.2d:%.2d.%.3d" % self.seconds2timetuple(seconds)
            
    def seconds2human(self, seconds):
        """converts a timetuple in a readable string"""
        return self.timetuple2human(self.seconds2timetuple(seconds))

    def timetuple2seconds(self, timetuple):
        """returns a timetuple to seconds-float"""
        h, m, s, x = timetuple
        return float((h * 3600) + (m * 60) + s + (float(x) / 1000))

    def timetuple2timestring(self, timetuple):
        """creates a string hhh:mmm:sss:xxx from tuple"""
        h, m, s, x = timetuple
        return "%.2d:%.2d:%.2d.%.3d" % (h, m, s, x)    

    def timetuple2human(self, timetuple):
        """converts a timetuple in a readable string"""
        h, m, s, x = timetuple
        out = ""
        if h > 0 and h == 1: out += ("%i " % h) + self.lang.hour + ", "
        elif h > 0: out += ("%i " % h) + self.lang.hours + ", "
        if m > 0 and m == 1: out += ("%i " % m) + self.lang.minute + " "
        elif m > 0: out += ("%i " % m) + self.lang.minutes + " "
        elif len(out) > 0: out = out[:-2] + " "
        if len(out) > 0 and s > 0: out += self.lang._and + " "
        if s > 0 and s == 1: out += ("%i " % s) + self.lang.second
        elif s > 0 or len(out) == 0: out += ("%i " % s) + self.lang.seconds
        return out
        
    def timestring2timetuple(self, string):
        """creates a valid timetuple from string"""
        ints = []
        p = re.compile('[0-9]+')
        items = p.findall(string)
        while len(items) < 4:
            items.append("0")
        for i in items:
            ints.append(int(i))
        return tuple(ints)
        
    def timestring2seconds(self, string):
        """creates a valid second-float from string"""
        return self.timetuple2seconds(self.timestring2timetuple(string))
        
    def bits2bytes(self, bits):
        """returns bytes calculated from bits"""
        return round(bits / 8)
        
    def kbits2bytes(self, bits):
        """returns bytes calculated from bits"""
        return round(bits / 8 / 1024)    
            
    def bytes2string(self, value):
        """returns a formatted string from bytes (1024)"""
        value = float(value)
        if value >= (1024**4) :
            return self.scaleFloat(value/(1024.0**4)) + " T"
        if value >= (1024**3) :
            return self.scaleFloat(value/(1024.0**3)) + " G"
        if value >= (1024**2) :
            return self.scaleFloat(value/(1024.0**2)) + " M"
        if value >= 1024 :
            return self.scaleFloat(value/1024.0) + " k"
        else : return ("%i" % value) + ""

    def kbytes2string(self, value):
        """returns a formatted string from kbytes (1024)"""
        value = float(value)
        if value >= (1024**4) :
            return self.scaleFloat(value/(1024.0**4)) + " P"
        if value >= (1024**3) :
            return self.scaleFloat(value/(1024.0**3)) + " T"
        if value >= (1024**2) :
            return self.scaleFloat(value/(1024.0**2)) + " G"
        if value >= 1024 :
            return self.scaleFloat(value/1024.0) + " M"
        else : return ("%i" % value) + " k"

    def kbs2string(self, value):
        """returns a formatted string from kbits(1000)"""
        value = float(value) / 8
        if value >= (1024**4) :
            return self.scaleFloat(value/(1000.0**4)) + " P"
        if value >= (1024**3) :
            return self.scaleFloat(value/(1000.0**3)) + " T"
        if value >= (1024**2) :
            return self.scaleFloat(value/(1000.0**2)) + " G"
        if value >= 1024 :
            return self.scaleFloat(value/1000.0) + " M"
        else : return ("%i" % value) + " k"

    def scaleFloat(self, value):
        """scales floatings to readable sizes"""
        if value >= 100 :
            return "%d" % round(value)
        if value >= 10 :
            return "%.1f" % value
        else : return "%.2f" % value
    
    def value2perc(self, base, value, integer = False):
        if value == 0:
            return 0
        perc = (float(value) / float(base)) * 100.0
        if integer:
            perc = round(perc)
            perc = int(perc)
        return perc
    
    def perc2value(self, base, perc, integer = False):
        if perc == 0:
            return 0
        value = float(base) * (float(perc) / 100.0)
        if integer:
            value = round(value)
            value = int(value)
        return value
    
    
    
    def inputRead(self):
        """returns if inFile is read- and accessible"""
        if len(self._inFiles) > 0:
            return True
        else:
            return False
            
    def outputWrite(self):
        """returns if outFile is write- and accessible"""
        if self._outFileWriteable and self._outFileAccessible:
            return True
        else:
            return False
            
    def videoActive(self):
        """returns true, if formatVDisableVideo is False"""
        for i in self._videoStreams:
            if i["active"]:
                return True
        return False
    
    def videoAvail(self):
        if len(self._videoStreams):
            return True
        else:
            return False
    
    def videoActiveCount(self):
        c = 0
        for i in self._videoStreams:
            if i["active"]:
                c += 1
        return c
    
    def audioActive(self):
        """returns true, if formatVDisableVideo is False"""
        for i in self._audioStreams:
            if i["active"]:
                return True
        return False

    def audioAvail(self):
        if len(self._audioStreams):
            return True
        else:
            return False

    def audioActiveCount(self):
        c = 0
        for i in self._audioStreams:
            if i["active"]:
                c += 1
        return c

#######################################
# WIDGETS HELPER
#######################################

    def buttonProceedInactive(self, error):
        return self.lang.proceed_button_inactive % error
        
    def buttonProceedActive(self):
        if os.path.exists(self.filterOutFileSuffix()):
            return self.lang.proceed_button_overwrite
        else:
            return self.lang.proceed_button_active
            
    def calulateNewBitrate(self, bitrate):
        if bitrate < 8: bitrate = self._DEFAULTBITRATE
        while True:
            try:
                i = self._AUDIOBITRATES.index(bitrate)
                break
            except ValueError:
                bitrate -= 1
                i = -1
        if i >= 0: return self._AUDIOBITRATES[i]
        else: return bitrate
    
    def setFormatChanged(self, object):
        try:
            var = eval("self._inFile" + object)
        except(AttributeError):
            pass
        else:
            button = self.window.get_widget("button" + object)
            if button:
                if self.inputRead():
                    a = eval("self._inFile" + object)
                    b = eval("self._format" + object)
                    if a != b:
                        button.show()
                        button.set_tooltip_text(self.lang.format_tooltip_changed % str(a))
                        img = button.get_child()
                        pth = os.path.join(sys.path[0], "icons", self.getIconColor(img))
                        if a < b:
                            img.set_from_file(os.path.join(pth, "changed_up.svg"))
                        elif a > b:
                            img.set_from_file(os.path.join(pth, "changed_down.svg"))
                        else:
                            img.set_from_file(os.path.join(pth, "changed.svg"))
                    else:
                       button.hide()
                else: button.hide()
            
    def resetFormatLabels(self):
        for label in self._CACHEFORMAT:
            self.setFormatChanged(label)    
            
    def setRatioButtons(self, ratio):
        self.format16_9.set_active(self._formatRatio == 1.7777)
        self.format4_3.set_active(self._formatRatio == 1.3333)
            
#######################################
# TREE OPERATIONS
#######################################    
    
    def selectStreamTreeRange(self, fileid, treeview, streams):
        start = -1
        stop = -1
        inside = False
        c = 0
        for i in streams:
            if i["file"] == fileid:
                if not inside:
                    start = c
                    stop = c
                    inside = True
                else:
                    stop = c
            c += 1
        if start >= 0 and stop >=0:
            treeview.get_selection().select_range(start, stop)
    
    def select_row_by_id(self, treeview, id, file, unselect=False):
        """if name matches one of the entries in treeview,
        select it. otherwise unselect all"""
        selection = treeview.get_selection()
        model = treeview.get_model()
        sel = False
        i = model.get_iter_first()
        while i:
            if model.get_value(i, 2) == id and model.get_value(i, 1) == file:
                selection.select_iter(i)
                sel = i
                break
            i = model.iter_next(i)
        if not sel:
            if unselect:
                selection.unselect_all()
            return None
        else:
            return sel        
            
#######################################
# TOGGLE AUDIO/VIDEO SENSITIVITY
#######################################    
        
    def toggleVideo(self, active, keepcodec = False):
        if not keepcodec:
            self.imageFormatVideo.set_sensitive(active)
            self.window.get_widget("labelFormatVideo").set_sensitive(active)
            self.window.get_widget("labelFormatCodec").set_sensitive(active)
            self.formatCodec.set_sensitive(active)
        self.window.get_widget("labelFormatBitrate").set_sensitive(active)
        self.formatBitrate.set_sensitive(active)
        self.window.get_widget("labelFormatFramerate").set_sensitive(active)
        self.formatFramerate.set_sensitive(active)
        self.window.get_widget("labelFormatWidth").set_sensitive(active)
        self.formatWidth.set_sensitive(active)
        self.window.get_widget("labelFormatHeight").set_sensitive(active)
        self.formatHeight.set_sensitive(active)
        self.window.get_widget("labelFormatRatio").set_sensitive(active)
        self.formatRatio.set_sensitive(active)
        self.window.get_widget("labelFormatFixed").set_sensitive(active)
        self.formatFixedRatio.set_sensitive(active)
        self.window.get_widget("labelFormatDeinterlace").set_sensitive(active)
        self.formatDeinterlace.set_sensitive(active)
        self.window.get_widget("labelFormatScaling").set_sensitive(active)
        self.formatScaling.set_sensitive(active)
        self.window.get_widget("labelFormatPadColor").set_sensitive(active)
        self.formatPadColor.set_sensitive(active)
        self.window.get_widget("labelFormat2Pass").set_sensitive(active)
        self.format2Pass.set_sensitive(active)
        self.window.get_widget("labelFormat2PassNA").set_sensitive(active)
        self.format2PassNA.set_sensitive(active)
        self.format4_3.set_sensitive(active)
        self.format16_9.set_sensitive(active)
        
    def toggleAudio(self, active, keepcodec = False):
        if not keepcodec:
            self.imageFormatAudio.set_sensitive(active)
            self.window.get_widget("labelFormatAudio").set_sensitive(active)
            self.window.get_widget("labelFormatAudioCodec").set_sensitive(active)
            self.formatAudioCodec.set_sensitive(active)
        self.window.get_widget("labelFormatAudioBitrate").set_sensitive(active)
        self.formatAudioBitrate.set_sensitive(active)
        self.window.get_widget("labelFormatAudioSamplerate").set_sensitive(active)
        self.formatAudioSamplerate.set_sensitive(active)
        self.window.get_widget("labelFormatAudioChannels").set_sensitive(active)
        self.formatAudioChannels.set_sensitive(active)
        self.window.get_widget("labelFormatVolume").set_sensitive(active)
        self.formatVolumeFader.set_sensitive(active)
        self.formatVolumeDisplay.set_sensitive(active)
        
    def toggleMeta(self, active):
        self.window.get_widget("labelMetaTitle").set_sensitive(active)
        self.window.get_widget("labelMetaAuthor").set_sensitive(active)
        self.window.get_widget("labelMetaCopyleft").set_sensitive(active)
        self.window.get_widget("labelMetaComment").set_sensitive(active)
        self.metaTitle.set_sensitive(active)
        self.metaAuthor.set_sensitive(active)
        self.metaCopyleft.set_sensitive(active)
        self.metaComment.set_sensitive(active)
        if self.metaToggle.get_active() == False and active:
            self.metaToggle.set_active(True)
        if self.metaToggle.get_active() and active == False:
            self.metaToggle.set_active(False)

    def toggleNoAudio(self, active):
        # sensitive no audio
        self.format2PassNA.set_sensitive(active)
        self.labelFormat2PassNA.set_sensitive(active)         
              
#######################################
# WINDOW-FUNCTIONS
#######################################
    def createInFileMenu(self, time):
        #try:
        #    self.inFileMenu.get_widget("inFileMenu").destroy()
        #except:
        #    True
        gladeXML = gtk.glade.XML(self.gladefile, "inFileMenu",)
        self.inFileMenu = gladeXML.get_widget("inFileMenu")
        handlers = {
            "on_inFile_open" : self.openInFile,
            "on_inFile_remove" : self.removeInFile,
            "on_inFile_delete" : self.deleteInFile,
            "on_inFile_meta" : self.readInFileMeta,
            "on_inFile_path" : self.setOutFilePath,
            "on_inFile_name" : self.setOutFileName,
            }
        gladeXML.signal_autoconnect(handlers)
        gladeXML.get_widget("menuInFileName").get_children()[0].set_text(
            self.lang.in_file_menu_name)
        gladeXML.get_widget("menuInFilePath").get_children()[0].set_text(
            self.lang.in_file_menu_path)
        gladeXML.get_widget("menuInFileMeta").get_children()[0].set_text(
            self.lang.in_file_menu_meta)
        if not self._OPENCOMMAND:
            gladeXML.get_widget("menuInFileOpen").set_sensitive(False)
        self.inFileMenu.popup( None, None, None, 3, time)
        
    def messageDialog(self, message,
                      title = "tragtor-Message",
                      behavior = gtk.MESSAGE_INFO,
                      buttons = gtk.BUTTONS_OK,
                      image = None):
        """creates a message-dialog with variable
        tile, message, behavior and buttons"""
        dialog = gtk.MessageDialog(
            parent=None,
            flags=gtk.DIALOG_DESTROY_WITH_PARENT,
            type=behavior,
            buttons=buttons,
            message_format=message)
        dialog.set_title(title)
        if image:
            dialog.set_image = gtk.image_new_from_pixbuf(image)
            dialog.set_icon = image
        dialogreturn = dialog.run()
        dialog.destroy()
        return dialogreturn
        
    def createConfirmation(self, labeltext, commandline1, commandline2):
        try:
            self.confirmWin.get_widget("tragtorConfirm").destroy()
            self.confirmWin.destroy()
        except:
            pass
        self.confirmWin = gtk.glade.XML(self.gladefile, "tragtorConfirm",)
        self.commandlineText1 = gtk.TextBuffer()
        self.confirmWin.get_widget("textCommandline1").set_buffer(
            self.commandlineText1)
        self.commandlineText1.set_text(commandline1)
        if commandline2:
            self.commandlineText2 = gtk.TextBuffer()
            self.confirmWin.get_widget("textCommandline2").set_buffer(
                self.commandlineText2)
            self.commandlineText2.set_text(commandline2)
            self.confirmWin.get_widget("labelCommandline1").set_text(
                self.lang.label_confirm_commandline + (
                    " (%s)" % self.lang.label_pass_1)
            )
            self.confirmWin.get_widget("labelCommandline2").set_text(
                self.lang.label_confirm_commandline + (
                    " (%s)" % self.lang.label_pass_2)
            )
        else:
            self.confirmWin.get_widget("labelCommandline1").set_text(
                self.lang.label_confirm_commandline
            )
            self.confirmWin.get_widget("expander2").hide()
        self.confirmWin.get_widget("tragtorConfirm").set_title(
            self.lang.title_confirmation_window)
        self.confirmWin.get_widget("labelConfirmation").set_text(
            self.lang.label_confirmation)
        self.confirmWin.get_widget("labelConfirmationInfo").set_markup(
            labeltext)
        handlers = {
            "on_buttonConfirmOK_clicked" : self.processCall,
            "on_buttonConfirmCancel_clicked" : self.killConfirm,
            }
        self.confirmWin.signal_autoconnect(handlers)
        self.setIcons(self.confirmWin)
        return self.confirmWin

    def killConfirm(self, widget):
        self.confirmWin.get_widget("tragtorConfirm").destroy()
    
    def createHelp(self, text):
        try:
            self.helpWin.get_widget("tragtorHelp").destroy()
        except:
            True
        self.helpWin = gtk.glade.XML(self.gladefile, "tragtorHelp",)
        self.helpText = gtk.TextBuffer()
        self.helpWin.get_widget("textHelp").modify_font(
            pango.FontDescription("monospace,9"))
        self.helpWin.get_widget("textHelp").set_buffer(self.helpText)
        self.helpText.set_text(text)
        self.helpWin.get_widget("tragtorHelp").set_title(
            self.lang.title_help_window)
        handlers = {
            "on_close_clicked" : self.killHelp,
        }
        self.helpWin.signal_autoconnect(handlers)
        self.setIcons(self.helpWin)
        return self.helpWin
    
    def createUOE(self):
        try:
            self.UOEWin.get_widget("tragtorUOE").destroy()
        except:
            True
        self.UOEWin = gtk.glade.XML(self.gladefile, "tragtorUOE",)
        self.UOEWin.get_widget("labelUOE").set_markup(self.lang.label_UOE)
        option = self.formatUserDefined.get_text()
        if self._format2Pass:
            passes = option.split("|")
            self.UOEWin.get_widget("textviewPass1").get_buffer().set_text(
                passes[0])
            if len(passes) > 1:
                self.UOEWin.get_widget("textviewPass2").get_buffer().set_text(
                    passes[1])
            self.UOEWin.get_widget("labelPass1").set_text(
                self.lang.label_pass_1)
            self.UOEWin.get_widget("labelPass2").set_text(
                self.lang.label_pass_2)
            self.UOEWin.get_widget("framePass2").set_visible(True)
        else:
            self.UOEWin.get_widget("textviewPass1").get_buffer().set_text(
                option)
            self.UOEWin.get_widget("labelPass1").set_text(
                self.lang.label_single)
            self.UOEWin.get_widget("framePass2").set_visible(False)
        
        #self.UOEWin.get_widget("textHelp").set_buffer(self.helpText)
        #self.UOEWin.get_widget("tragtorHelp").set_title(self.lang.title_help_window)
        handlers = {
            "on_buttonUOECancel_clicked" : self.killUOE,
            "on_buttonUOEOK_clicked" : self.buildUserOption,
        }
        self.UOEWin.signal_autoconnect(handlers)
        self.setIcons(self.UOEWin)
        return self.UOEWin
    
    def killHelp(self, widget):
        self.helpWin.get_widget("tragtorHelp").destroy()
    
    def killUOE(self, widget):
        self.UOEWin.get_widget("tragtorUOE").destroy()
        
    def createWindow(self):
        """create the main-window"""
        self.gladefile = sys.path[0] + "/tragtor.glade"  
        self.window = gtk.glade.XML(self.gladefile, "tragtor","tragtor")
        
    def destroy(self, widget):
        """wtf?!1"""
        gtk.main_quit()

    def ctrlC(self, signum, frame):
        self.destroy(None)
    
    def getIconColor(self, widget):
        col = widget.get_property("style").bg[gtk.STATE_NORMAL]
        r = (col.red_float + col.green_float + col.blue_float) / 3.
        if r < 0.5:
            return "white"
        return "black"
           
    def setIcons(self, widget):
        a = []
        self.getThemedImages(widget, a)
        for i in a:
            i.set_from_file("%s/icons/%s/%s" % (sys.path[0],
                                                self.getIconColor(i),
                                                i.get_name().split("_", 2)[2]))
        
    def getThemedImages(self, widget, lst):
        if isinstance(widget, gtk.Image) and widget.get_name()[:6] == "themed":
            lst.append(widget)
        if hasattr(widget, 'forall') and callable(getattr(widget, 'forall')):
            widget.forall(self.getThemedImages, lst)
        
    def createWidgetObjects(self):
        """here we wrap all widgets to local objects for easier calls"""
        self.inFileChooser = self.window.get_widget("inFileChooser")
        self.inFileAudio = self.window.get_widget("inFileAudio")
        self.inFileVideo = self.window.get_widget("inFileVideo")
        self.inFileAudioTree = self.window.get_widget("inFileAudioTree")
        self.inFileVideoTree = self.window.get_widget("inFileVideoTree")
        self.inFileAudioIcon = self.window.get_widget("inFileAudioIcon")
        self.inFileVideoIcon = self.window.get_widget("inFileVideoIcon")
        self.inFileAudioVideo = self.window.get_widget("inFileAudioVideo")
        self.inFileToggle = self.window.get_widget("inFileToggle")
        self.inFileOpenTree = self.window.get_widget("inFileOpenTree")
        self.inFileOpen = self.window.get_widget("inFileOpen")
        self.inFileMenu = self.window.get_widget("inFileMenu")
        self.inFilePreview = self.window.get_widget("inFilePreview")

        self.outFileChooser = self.window.get_widget("outFileChooser")
        self.outFileSuffix = self.window.get_widget("outFileSuffix")
        self.outFileName = self.window.get_widget("outFileName")
        
        self.buttonProceed = self.window.get_widget("buttonProceed")
        self.buttonProceedIcon =self.window.get_widget("buttonProceedIcon")
        self.buttonProceedLabel = self.window.get_widget("buttonProceedLabel")
        self.ffmpegOut = self.window.get_widget("ffmpegOut")
                
        self.buttonReload = self.window.get_widget("buttonReload")
        self.buttonReset = self.window.get_widget("buttonReset")
        self.languageSelector = self.window.get_widget("languageSelector")
        self.videoFilter = self.window.get_widget("settingsVideofilter")
        self.bitrateMode = self.window.get_widget("settingsBitrateMode")
        self.settingsCPU = self.window.get_widget("settingsCPU")
        self.progressActions = self.window.get_widget("settingsProgressActions")
        self.streamSeparator = self.window.get_widget("settingsStreamSeparator")
        self.cleanup2Pass = self.window.get_widget("settingsCleanup2Pass")
        self.newstream = self.window.get_widget("settingsNewstream")
        
        self.formatWidth = self.window.get_widget("formatWidth")
        self.formatHeight = self.window.get_widget("formatHeight")
        self.formatRatio = self.window.get_widget("formatRatio")
        self.formatFixedRatio = self.window.get_widget("formatFixedRatio")
        self.format4_3 = self.window.get_widget("format4_3")
        self.format16_9 = self.window.get_widget("format16_9")
        self.formatFramerate = self.window.get_widget("formatFramerate")
        self.formatDeinterlace = self.window.get_widget("formatDeinterlace")
        self.formatAudioSamplerate = self.window.get_widget("formatAudioSamplerate")
        self.formatAudioBitrate = self.window.get_widget("formatAudioBitrate")
        self.formatAudioCodec = self.window.get_widget("formatAudioCodec")
        self.formatAudioChannels = self.window.get_widget("formatAudioChannels")
        self.formatVolumeDisplay = self.window.get_widget("formatVolumeDisplay")
        self.formatVolumeFader = self.window.get_widget("formatVolumeFader")        
        self.formatCodec = self.window.get_widget("formatCodec")
        self.format2Pass = self.window.get_widget("format2Pass")
        self.format2PassNA = self.window.get_widget("format2PassNA")
        self.formatBitrate = self.window.get_widget("formatBitrate")
        self.formatOffset = self.window.get_widget("formatOffset")
        self.formatOffsetOut = self.window.get_widget("formatOffsetOut")
        self.formatDuration = self.window.get_widget("formatDuration")
        self.formatDurationOut = self.window.get_widget("formatDurationOut")
        self.formatScaling = self.window.get_widget("formatScaling")
        self.formatPadColor = self.window.get_widget("formatPadColor")
        self.formatResultInfo = self.window.get_widget("formatResultInfo")
        self.formatUserDefined = self.window.get_widget("formatUserDefined")
        self.buttonManual = self.window.get_widget("buttonManual")
        self.buttonOpenUOE = self.window.get_widget("buttonOpenUOE")
        self.imageFormatVideo = self.window.get_widget("themed__format-video.svg")
        self.imageFormatAudio = self.window.get_widget("themed__format-audio.svg")
        self.imageFormatRender = self.window.get_widget("imageFormatRender")
        self.imageFormatResults = self.window.get_widget("imageFormatResults")
        
        self.metaTitle = self.window.get_widget("metaTitle")
        self.metaAuthor = self.window.get_widget("metaAuthor")
        self.metaCopyleft = self.window.get_widget("metaCopyleft")
        self.metaComment = self.window.get_widget("metaComment")
        self.metaToggle = self.window.get_widget("metaToggle")
        
        self.presetName = self.window.get_widget("presetName")
        self.presetSave = self.window.get_widget("presetSave")
        self.presetOpen = self.window.get_widget("presetOpen")
        self.presetDelete = self.window.get_widget("presetDelete")
        self.presetContainer = self.window.get_widget("presetContainer")
        self.labelFormatPreset = self.window.get_widget("labelFormatPreset")
        self.labelFormat2PassNA = self.window.get_widget("labelFormat2PassNA")
        
        self.tragtorWindow = self.window.get_widget("tragtor")
    
    def start_config(self, cfgfile, defaults={}, sections=[], optionxform_off = False):
        if not os.path.exists(os.path.dirname(cfgfile)):
            os.mkdir(os.path.dirname(cfgfile))
        if not os.path.exists(cfgfile):
            c = open(cfgfile, "w")
            c.close()
        cfg = config.RawConfigParser(defaults)
        if optionxform_off:
            cfg.optionxform = str
        cfg.readfp(open(cfgfile))
        for s in sections:
            if not cfg.has_section(s):
                cfg.add_section(s)
        return cfg
    
    def saveConfigValue(self, section, var, value, file):
        try:
            self.config.add(section, var, value)
        except:
            self.config.set(section, var, value)
        self.config.write(open(file, "w"))
            
    def troubleShooter(self, widget, ee):
        """This function represents the truth!"""
        self._eec += 1
        if self._eec >=8:
            self.eeWin = gtk.glade.XML(self.gladefile, "tragtorEE",)
            self._eec = 0

#######################################
# PROGRESS-WINDOW
#######################################
            
    def createProgressWin(self):
        """Open a progress window to display ffmpeg/avlib's
        progress while converting"""
        try:
            self.progressWin.get_widget("tragtorProgress").destroy()
            self.progressWin.destroy()
        except:
            pass
        self.progressWin = gtk.glade.XML(self.gladefile, "tragtorProgress",)
        self.progressWin.get_widget("labelProgress").set_text(
            self.lang.label_progress)
        self.progressWin.get_widget("labelProgressActions").set_text(
            self.lang.label_progress_actions)
        combo = self.progressWin.get_widget("progressActions")
        combo.get_model().clear()
        for c in range(len(self.lang.progress_actions)):
            combo.append_text(self.lang.progress_actions[c])
        if self.config.has_option("Settings", "progressActions"):
            try:
                action = eval(self.config.get("Settings", "progressActions"))
            except:
                action = self.config.get("Settings", "progressActions")
            combo.set_active(action)
        if self._currpass != None:
            title = "%s %s" % (self.lang.title_progress_window,
                               self.lang.title_progress_window_pass % self._currpass)
        else:
            title = self.lang.title_progress_window
        self.progressWin.get_widget("tragtorProgress").set_title(title)

        handlers = {
            "on_buttonProgressCancel_clicked" : self.stopProgress,
            "on_buttonProgressOpen_clicked" : self.openfileProgress,
            "on_buttonProgressPlay_clicked" : self.playfileProgress,
            "on_progressActions_changed" : self.actionsProgress,
            "destroy" : self.stopProgress,
            "delete_event" : self.stopProgress
            }
        self.progressWin.signal_autoconnect(handlers)
        self.setIcons(self.progressWin)
        return self.progressWin
    
    def updateProgress(self, line):
        self._TIMELINE = re.compile(".*size.*time.*bitrate")
        self._FINISHLINE = re.compile("video:.*audio:.*headers.*muxing overhead.*")
        if line != "Press [q] to stop encoding" and line != "Press ctrl-c to stop encoding":
            if self._FINISHLINE.match(line):
                self._ffmpegOut += line + "\n"
                self.updateProgressLabel(line)
                self.updateProgressText(self._ffmpegOut)
                self._progressFinishedGracefully = True
                print(line)
            elif self._TIMELINE.match(line):
                self.updateProgressLabel(line)
                self._progressInStreams = False
            elif line != "" and (self._progressInStreams or line[0:5] == "Input"):
                self._ffmpegOut += line + "\n"
                self.updateProgressText(self._ffmpegOut)
                self._progressInStreams = True
                print(line)
        self.updateProgressBar(line)
        
    def finishProgress(self, line):
        if self.progressWin.get_widget("tragtorProgress"):
            if not self._progressFinishedGracefully:
                self.progressWin.get_widget("text1Progress").set_markup(
                    self.lang.label_progress_error)
                self.progressWin.get_widget("text2Progress").set_markup(
                    self.lang.label_progress_error_explain)
                self.progressWin.get_widget("tragtorProgress").set_title(
                    self.lang.title_progress_window_error)
            else:
                self.progressWin.get_widget("buttonProgressPlay").set_sensitive(
                    True)
                self.progressWin.get_widget("tragtorProgress").set_title(
                    self.lang.title_progress_window_finished)
            self.progressWin.get_widget("progressProgress").set_fraction(1)
            self.progressWin.get_widget("progressProgress").set_text(
                "%i%s" % (100, "%"))
            self.progressWin.get_widget("buttonProgressCancel").set_label(
                "gtk-close")
        self.postProcess()
    
    def updateProgressText(self, text):
        self.ffmpegOutText.set_text(text)
    
    def updateProgressLabel(self, line):
        """Update the text labels in the progress window"""
        if self.progressWin.get_widget("text1Progress") != None and line.strip() != "":
            txt1 = ""
            txt2 = ""
            c = re.search(r"time=([0-9]+):([0-9]+):([0-9]+)\.([0-9]+)", line)
            if c:
                h = eval(re.sub("^0","",c.group(1)))
                m = eval(re.sub("^0","",c.group(2)))
                s = eval(re.sub("^0","",c.group(3)))
                f = eval(re.sub("^0","",c.group(4)))
                dur = h * 60 * 60 + m * 60 + s + f / 100
                txt1 = "%s\n%s" % (txt1, self.lang.label_progress_time)
                txt2 = "%s\n%.2f / %.2f s" % (txt2, dur, self._formatDuration)
            c = re.search(r"frame=[\s]*([0-9]+(\.[0-9]+)?)", line)
            if c:
                txt1 = "%s\n%s" % (txt1, self.lang.label_progress_frame)
                txt2 = "%s\n%s / %i" % (txt2, c.group(1), int(
                    round(self._formatFramerate * self._formatDuration)))
            c = re.search(r"size=[\s]*([0-9]+(\.[0-9]+)?)", line)
            if c:
                txt1 = "%s\n%s" % (txt1, self.lang.label_progress_size)
                txt2 = "%s\n%sBytes" % (txt2, self.kbytes2string(eval(c.group(1))))
            c = re.search(r"bitrate=[\s]*([0-9]+(\.[0-9]+)?)", line)
            if c:
                txt1 = "%s\n%s" % (txt1, self.lang.label_progress_bitrate)
                txt2 = "%s\n%s kB/s" % (txt2, c.group(1))
            c = re.search(r"q=[\s]*([0-9]+(\.[0-9]+)?)", line)
            if c:
                txt1 = "%s\n%s" % (txt1, self.lang.label_progress_quantizer)
                txt2 = "%s\n%s" % (txt2, c.group(1))
            
            c = re.search(r"video:[\s]*([0-9]+(\.[0-9]+)?kB)", line)
            if c and c.group(1) != "0kB":
                txt1 = "%s\n%s" % (txt1, self.lang.label_progress_video)
                txt2 = "%s\n%s" % (txt2, c.group(1))
            c = re.search(r"audio:[\s]*([0-9]+(\.[0-9]+)?kB)", line)
            if c and c.group(1) != "0kB":
                txt1 = "%s\n%s" % (txt1, self.lang.label_progress_audio)
                txt2 = "%s\n%s" % (txt2, c.group(1))
            c = re.search(r"global headers:[\s]*([0-9]+(\.[0-9]+)?kB)", line)
            if c and c.group(1) != "0kB":
                txt1 = "%s\n%s" % (txt1, self.lang.label_progress_headers)
                txt2 = "%s\n%s" % (txt2, c.group(1))
            c = re.search(r"muxing overhead [\s]*([0-9]+(\.[0-9]+)?%)", line)
            if c:
                txt1 = "%s\n%s" % (txt1, self.lang.label_progress_overhead)
                txt2 = "%s\n%s" % (txt2, c.group(1))
                
            txt1 = txt1.strip()
            txt2 = txt2.strip()
            self.progressWin.get_widget("text1Progress").set_markup(txt1)
            self.progressWin.get_widget("text2Progress").set_markup(txt2)
        else:
            return False
    
    def updateProgressBar(self, line):
        """update the progress bar"""
        progress = 0
        duration = re.search(r"time=([0-9]+):([0-9]+):([0-9]+)\.([0-9]+)", line)
        if duration:
            h = eval(re.sub("^0","",duration.group(1)))
            m = eval(re.sub("^0","",duration.group(2)))
            s = eval(re.sub("^0","",duration.group(3)))
            f = eval(re.sub("^0","",duration.group(4)))
            dur = h * 60 * 60 + m * 60 + s + f / 100
            progress = dur / self._formatDuration
        duration = re.search(r"time=([0-9]+)\.([0-9]+)", line)
        if duration:
            print duration.group(1), duration.group(2)
            s = int(duration.group(1))
            f = int(duration.group(2))
            dur = s + f / 100
            progress = dur / self._formatDuration
        if progress > 1.0 : progress = 1
        if self.progressWin.get_widget("progressProgress") != None:
            self.progressWin.get_widget("progressProgress").set_fraction(
                progress)
            self.progressWin.get_widget("progressProgress").set_text(
                "%i%s" % (int(progress*100), "%"))
        else:
            return False
    
    def stopProgress(self, widget):
        """Do some GUI stuff and exit ffmpeg/avlib"""
        if self.ffmpegExec:
            self.ffmpegExec.stop()
        if self.progressWin.get_widget("tragtorProgress") != None:
            self.progressWin.get_widget("tragtorProgress").destroy()
            
    def openfileProgress(self, widget):
        if self._OPENCOMMAND:
            os.popen(self._OPENCOMMAND + " \"%s\"" % os.path.dirname(
                self.filterOutFileSuffix()))
        
    def playfileProgress(self, widget):
        if self._OPENCOMMAND:
            os.popen(self._OPENCOMMAND + " \"%s\"" % self.filterOutFileSuffix())
    
    def actionsProgress(self, widget):
        self._progressActions = widget.get_active()
        self.progressActions.set_active(self._progressActions)
        self.saveConfigValue("Settings", "progressActions", widget.get_active(), self._CFG_SETTINGS)
        
#######################################
# FFMPEG/AVLIB
#######################################

class ffmpegExec(Thread):
    """This class is the ffmpeg/avlib-executable"""

    _execute = ""
    _caller = None
    _ffmpegOut = ""
    
    _running = False
    _stop = False
    
    def  __init__(self, caller, command, onProgress, onFinished, cpu):
        """init to given command"""
        self._stop = False
        self._running = False
        self._execute = command
        self._caller = caller
        self._onProgress = onProgress
        self._onFinished = onFinished
        self._cpu = cpu
        Thread.__init__(self)
    
    #def start(self, *args, **kwargs):
    #    threading.Thread(target=self.run, args=args, kwargs=kwargs).start()
       
    def run(self):
        """execute the command and return the output."""
        if self._cpu == 0 and os.nice(0) < 20:
            os.nice(20)
            
        self._running = True
        self._PROCESS = sub.Popen(self._execute,
            stdout = sub.PIPE,
            stderr = sub.STDOUT,
            stdin = sub.PIPE,
            universal_newlines = True,
            shell = True,
            preexec_fn=os.setsid)
            
        lastline = ""
        while self._PROCESS.poll() == None and self._stop == False:
            out = self._PROCESS.stdout.readline().strip()
            gobject.idle_add(self._onProgress, out)
        
        self._PROCESS.stdout.close()
        self._PROCESS.stdin.close()
        self._running = False
        time.sleep(0.5)
        gobject.idle_add(self._onFinished, out)
        
        return False
    
    def stop(self):
        """Stop method, sets the event to terminate the thread's main loop"""
        if self._running and self._PROCESS.stdin:
            self._PROCESS.stdin.write("q")
            os.killpg(self._PROCESS.pid, signal.SIGINT)
            time.sleep(1.0)
        #self._stop = True
        return False
        
#######################################
# FFMPEG/AVLIB-CONFIG
#######################################

class ffmpegConfig():
    """this class reads the config of ffmpeg/avlib and stores it in various lists"""
    _FILE_CONTAINER = {"adts":"aac", "asf_stream":"asf", "avm2":"swf",
                       "bethsoftvid":"vid", "daud":"wav", "dirac":"avi",
                       "dnxhd":"mxf", "dvd":"mpg", "f32be":"wav", "f32le":"wav",
                       "f64be":"wav", "f64le":"wav", "film_cpk":"cpk",
                       "filmstrip":"flm", "flic":"fli", "framecrc":"crc",
                       "h261":"261", "h263":"263", "h264":"264", "image2":"jpg",
                       "image2pipe":"jpg", "ingenient":"cgi", "ipmovie":"mve",
                       "ipod":"mp4", "matroska":"mkv", "mjpeg":"jpg", "mpeg":"mpg",
                       "mpeg1video":"mpg", "mpeg2video":"mpg", "mpegts":"ts",
                       "mpjpeg":"jpg", "mulaw":"pcm", "mxf_d10":"mxf", "null":"0",
                       "psp":"mp4", "psxstr":"str", "s16be":"wav", "s16le":"wav",
                       "s24be":"wav", "s24le":"wav", "s32be":"wav", "s32le":"wav",
                       "s8":"wav", "svcd":"mpg", "tiertexseq":"seq", "u16be":"wav",
                       "u16le":"wav", "u24be":"wav", "u24le":"wav", "u32be":"wav",
                       "u32le":"wav", "u8":"wav", "vcd":"mpg", "vc1test":"vc1",
                       "wc3movie":"mve", "wsaud":"aud", "wsvqa":"vqa",
                       "yuv4mpegpipe":"mpg"}
    _ADD_INFILE_CONTAINER = {"m4a":"QuickTime/MPEG-4",
                             "mj2":"Motion JPEG 2000 format",
                             "oga":"OGG Vorbis Audio",
                             "ogv":"OGG Vorbis Video",
                             "mpeg":"MPEG System format",
                             "jpeg":"JPEG Image",
                             "aiff":"AIFF Audio Format",
                             "aif":"AIFF Audio Format"}

    _ffmpegVersion   = ""
    _compileOptions  = ""
    _openFileFormats = []
    _saveFileFormats = []
    _openAudioCodecs = []
    _openVideoCodecs = []
    _saveAudioCodecs = []
    _saveVideoCodecs = []
    _libs            = ""
    _build           = ""
    _configuration   = ""
    _command         = ""
    def  __init__(self, command):
        """parse the config from the comandline and fill
            compileOptions
            openAudioCodecs
            openVideoCodecs
            saveAudioCodecs
            saveVideoCodecs
            openFileFormats
            saveFileFormats"""
        self._command = command
        inFormats = False
        inCodecs = False
        ffmpegout = sub.Popen("%s -formats" % self._command,
                              shell=True,
                              stdout=sub.PIPE,
                              stderr=sub.PIPE)
        for line in ffmpegout.stderr.readlines():
            line = line.strip()
            c = re.search(r"(avconv|ffmpeg) version[\s]*([0-9\.A-Za-z\-\+:_]+)",
                line, flags=re.IGNORECASE)
            if c:
                self._ffmpegVersion = "Version %s (%s)" % (c.group(2), c.group(1))
            if line[:3] == "lib":
                self._libs = "%s\n   • %s" % (self._libs, line)
            if line[:14] == "configuration:":
                self._configuration = "%s%s\n" % (self._configuration, line[15:])
            if line[:8] == "built on":
                self._build = "Built %s" % line[9:]
                
        for line in ffmpegout.stdout.readlines():
            if inFormats and not re.search(r"\.", line[0:7]) \
                and line.strip() != "" and line[0:1] == " ":
                if line[1:2] == "D":
                    pos = string.find(line[4:-1],' ')
                    format = line[4:pos+5].strip()
                    desc = line[pos+5:-1].strip()
                    try:
                        suffix = self._FILE_CONTAINER[format]
                    except:
                        suffix = format
                    self._openFileFormats.append([format, self.shorten(desc), suffix])
                if line[2:3] == "E":
                    pos = string.find(line[4:-1],' ')
                    format = line[4:pos+5].strip()
                    desc = line[pos+5:-1].strip()
                    try:
                        suffix = self._FILE_CONTAINER[format]
                    except:
                        suffix = format
                    self._saveFileFormats.append([format, self.shorten(desc), suffix])
                    
            elif inCodecs and not re.search(r"\.", line[0:7]) \
                and line.strip() != "" and line[0:1] == " ":
                if line[1:2] == "D":
                    if line[3:4] == "A":
                        for m in self.getCodecs(line, True):
                            self._openAudioCodecs.append(m)
                    if line[3:4] == "V":
                        for m in self.getCodecs(line, True):
                            self._openVideoCodecs.append(m)
                if line[2:3] == "E":
                    if line[3:4] == "A":
                        for m in self.getCodecs(line, False):
                            self._saveAudioCodecs.append(m)
                    if line[3:4] == "V":
                        for m in self.getCodecs(line, False):
                            self._saveVideoCodecs.append(m)
            if line[:13] == "File formats:":
                inFormats = True
            if line[:7] == "Codecs:":
                inFormats = False
                inCodecs = True        
        ffmpegout.terminate()
        for key in self._ADD_INFILE_CONTAINER.keys():
            self._openFileFormats.append(["", self._ADD_INFILE_CONTAINER[key], key])
            
        ffmpegout = sub.Popen("%s -codecs" % self._command,
                              shell=True,
                              stdout=sub.PIPE,
                              stderr=sub.PIPE)
        for line in ffmpegout.stdout.readlines():
            line = line.strip()
            if inCodecs and line != "":
                if line[0:1] == "D":
                    if line[2:3] == "A":
                        for m in self.getCodecs(line, True):
                            self._openAudioCodecs.append(m)
                    if line[2:3] == "V":
                        for m in self.getCodecs(line, True):
                            self._openVideoCodecs.append(m)
                if line[1:2] == "E":
                    if line[2:3] == "A":
                        for m in self.getCodecs(line, False):
                            self._saveAudioCodecs.append(m)
                    if line[2:3] == "V":
                        for m in self.getCodecs(line, False):
                            self._saveVideoCodecs.append(m)
            if line[:7] == "Codecs:":
                inFormats = False
                inCodecs = True
        ffmpegout.terminate()
        
    def getCodecs(self, line, decoder):
        arr = []
        if decoder:
            match = re.search(r"\(decoders: (.*?)\)", line)
        else:
            match = re.search(r"\(encoders: (.*?)\)", line)
        if match:
            for m in match.group(1).split(" "):
                if m:
                    arr.append(m)
        else:
            arr.append(string.split(line[7:-1])[0])
        return arr
        
    def shorten(self, desc):
        if len(desc) > 24:
            return "%s..." % desc[0:24]
        return desc
#######################################
# ID3V2
#######################################

class id3v2():
    """this one interacts with the commandline-tool id3v2.
    at the moment it is able to read id3v1-tags, in the future
    a complete wrapper with read/write-support for v1 and v2 
    is planned"""
    
    emptyVal = ""
    
    id3v1 = False
    id3v2 = False

    def __init__(self, file):
        """analyze the file"""
        self.id3v1 = False
        self.id3v2 = False
        if os.access(file, os.R_OK):
            id3v2out = sub.Popen("id3v2 -l " + file,
                                 stderr=sub.PIPE,
                                 stdout=sub.PIPE)
            inV1 = False
            inV2 = False
            countV1 = 0
            for line in id3v2out.stdout.readlines():
                line = line.strip()
                if inV1:
                    if countV1 == 0:
                        if line[9:39].strip() != "":
                            self.id3v1 = {"Title": line[9:39].strip()}
                        else:
                            self.id3v1 = {"Title": self.emptyVal}
                        if line[49:].strip() != "":
                            self.id3v1["Artist"] = line[49:].strip()
                        else:
                            self.id3v1["Artist"] = self.emptyVal
                    if countV1 == 1:
                        if line[9:39].strip() != "":
                            self.id3v1["Album"] = line[9:39].strip()
                        else:
                            self.id3v1["Album"] = self.emptyVal
                        if line[47:51].strip() != "":
                            self.id3v1["Year"] = line[47:51].strip()
                        else:
                            self.id3v1["Year"] = self.emptyVal
                        if line[60:line.rfind("(")].strip() != "":
                            self.id3v1["Genre"] = line[60:line.rfind("(")].strip()
                        else:
                            self.id3v1["Genre"] = self.emptyVal
                        if line[(line.rfind("(") + 1):line.rfind(")")].strip() != "":
                            self.id3v1["GenreNum"] = line[(line.rfind("(") + 1):line.rfind(")")].strip()
                        else:
                            self.id3v1["GenreNum"] = self.emptyVal
                    if countV1 == 2:
                        if line[9:39].strip() != "":
                            self.id3v1["Comment"] = line[9:39].strip()
                        else:
                            self.id3v1["Comment"] = self.emptyVal
                        if line[48:].strip() != "":
                            self.id3v1["Track"] = line[48:].strip()
                        else:
                            self.id3v1["Track"] = self.emptyVal
                    countV1 += 1

                if inV2:
                    self.id3v2 = True
                if line == "id3v1 tag info for %s:" % file:
                    inV1 = True
                if line == "id3v2 tag info for %s:" % file:
                    inV2 = True
                    inV1 = False
            id3v2out.terminate()
        else:
            return False

#######################################
# PREVIEW
#######################################
        
class Preview(Thread):
    def __init__(self, _file, _cache, _duration, cb_ready = None, cb_args = None):
        Thread.__init__(self)
        self._FILE = _file
        self._CACHE = _cache
        self._DURATION = _duration
        self._CB_READY = cb_ready
        self._CB_ARGS = cb_args
        self.start()
    
    def run(self):
        command = "%s -y -i \"%s\" -f mjpeg -vframes 1 -ss %f -s 320x240 '%s' 2> /dev/null" % (_command(), self._FILE, self._DURATION, self._CACHE)
        os.system(command)
        if self._CB_READY:
            if self._CB_ARGS is not None:
                self._CB_READY(self._CB_ARGS)
            else:
                self._CB_READY()  
        
def main_quit(obj):
    """main_quit function, it stops the thread and the gtk's main loop"""
    gtk.main_quit()
            
#######################################
# EVERYTHING HAS TO COME TO AN END
#######################################            
            
if __name__ =="__main__":
    tragtorWindow = tragtorGUI()
    gtk.main()
