/****************************************************************************
** DialogMovie class
**
**   Created : Wed March 16 22:48:00 2005
**        by : Varol Okan using Kate
** Copyright : (c) Varol Okan
**   License : GPL v 2.0
**
****************************************************************************/
#include <stdlib.h>

#include <qlabel.h>
#include <qimage.h>
#include <qtimer.h>
#include <qregexp.h>
#include <qpixmap.h>
#include <qlayout.h>
#include <qlistbox.h>
#include <qspinbox.h>
#include <qlineedit.h>
#include <qlistview.h>
#include <qdatetime.h>
#include <qcheckbox.h>
#include <qfileinfo.h>
#include <qgroupbox.h>
#include <qcombobox.h>
#include <qtabwidget.h>
#include <qfiledialog.h>
#include <qpushbutton.h>
#include <qcolordialog.h>

#ifndef QPLAYER_ONLY
#include "dvdmenu.h"
#include "qdvdauthor.h"
#endif
#include "qplayer/mediainfo.h"
#include "qplayer/mediacreator.h"
#include "qplayer/startstopcontrol.h"
#include "qplayer/engines/mediainterface.h"

#include "importsrt.h"
#include "importssa.h"
#include "messagebox.h"
#include "movieobject.h"
#include "dialogmovie.h"
#include "dialogaudio.h"
#include "importchapter.h"
#include "dialoganimation.h"
#include "dialogmediainfo.h"
#include "uidialogsubtitle.h"
#include "smalldialogaudio.h"
#include "filepreviewdialog.h"
#include "dialogbuttontrans.h"

#define PROPERTIES_TAB  0
#define SUBTITLE_TAB    1
#define CHAPTERS_TAB    2
#define GEOMETRY_TAB    3
#define TRANSCODING_TAB 4

#define COLOR_TRANSCODE   238,  33,  43
#define COLOR_NOTRANSCODE 209, 226, 238

ListViewColorItem::ListViewColorItem (QListView *parent, Rgba theColor, QString l1, QString l2, QString l3, QString l4, QString l5, QString l6, QString l7, QString l8)
  : QListViewItem (parent, l1, l2, l3, l4, l5, l6, l7, l8)
{
  m_theColor = theColor;
}

void ListViewColorItem::paintCell ( QPainter *p, const QColorGroup & cg, int column, int width, int align)
{
  QColorGroup theColors = cg;
  if ( isSelected ( ) )  {
    theColors.setColor ( QColorGroup::Base, theColors.highlight       ( ) );
    theColors.setColor ( QColorGroup::Text, theColors.highlightedText ( ) );
  }
  else
    theColors.setColor ( QColorGroup::Base, m_theColor.color ( ) );
  QListViewItem::paintCell(p, theColors, column, width, align);
}

DialogMovie::DialogMovie(QWidget * parent, const char * name, WFlags f)
	: uiDialogMovie (parent, name, f)
{
	srand ( time ( NULL ) );
	m_pMediaInterface   = NULL;
	m_pStartStopControl = NULL;
	m_pTranscodeTab     = NULL;
	m_pMovieObject      = NULL;
	m_iMovieLength      =    1;// 1ms default, so we never have 0
	m_iTransitionForAll =   -1;
	m_pDVDMenu          = NULL;
	m_pSelectItem       = NULL;
	m_pParentSourceFileEntry = NULL; // needed to get correct audio / subtitle setting for a SourceFileInfo
	connect ( m_pEditWidth,       SIGNAL ( lostFocus ( ) ), this, SLOT ( slotWidth          ( ) ) );
	connect ( m_pEditHeight,      SIGNAL ( lostFocus ( ) ), this, SLOT ( slotHeight         ( ) ) );
	connect ( m_pButtonPlay,      SIGNAL ( clicked   ( ) ), this, SLOT ( slotPlay           ( ) ) );
	connect ( m_pButtonStop,      SIGNAL ( clicked   ( ) ), this, SLOT ( slotStop           ( ) ) );
	connect ( m_pButtonStart,     SIGNAL ( clicked   ( ) ), this, SLOT ( slotStart          ( ) ) );
	connect ( m_pButtonEnd,       SIGNAL ( clicked   ( ) ), this, SLOT ( slotEnd            ( ) ) );
        connect ( m_pButtonThumbnail, SIGNAL ( clicked   ( ) ), this, SLOT ( slotSetThumbnail   ( ) ) );
	connect ( m_pButtonTranscode, SIGNAL ( clicked   ( ) ), this, SLOT ( slotTranscode      ( ) ) );
	connect ( m_pButtonEncodeNow, SIGNAL ( clicked   ( ) ), this, SLOT ( slotEncodeNow      ( ) ) );
	connect ( m_pButtonAnimation, SIGNAL ( clicked   ( ) ), this, SLOT ( slotAnimation      ( ) ) );
	connect ( m_pButtonAddCK,     SIGNAL ( clicked   ( ) ), this, SLOT ( slotAddColorKey    ( ) ) );
	connect ( m_pButtonDelCK,     SIGNAL ( clicked   ( ) ), this, SLOT ( slotDelColorKey    ( ) ) );
	connect ( m_pButtonCK,        SIGNAL ( clicked   ( ) ), this, SLOT ( slotBrowseColorKey ( ) ) );
	connect ( m_pButtonEdit,      SIGNAL ( clicked   ( ) ), this, SLOT ( slotEditMediaInfo  ( ) ) );
	connect ( m_pCheckCreateSubtitles, SIGNAL ( toggled ( bool ) ), this, SLOT ( slotSubLangChanged ( bool ) ) );
}

DialogMovie::~DialogMovie()
{
  if ( m_pMediaInterface )
    delete m_pMediaInterface;
  if ( m_pStartStopControl )
    delete m_pStartStopControl;
}

void DialogMovie::initMe ( DVDMenu *pMenu )
{
  // Called when handling the background of a menu (Image background or MovieBackground.)
  if ( ! pMenu )
    return;

  CDVDMenuInterface *pInterface = pMenu->getInterface ( );
  if ( ( pInterface->qsMovieFileName.isNull ( ) ) && ( pInterface->qsBackgroundFileName.isNull ( ) ) )
    return;

  QFileInfo fileInfo;
  QString qsFormat, qsBackgroundName;
  int iPause = -1;

  m_pDVDMenu = pMenu;
  qsFormat = QString ("hh:mm:ss.zzz");
  QTime endingTime = pInterface->timeOffset.addMSecs ( -pInterface->timeDuration.msecsTo ( QTime ( ) ) );
  m_pEditStarting2->setText ( pInterface->timeOffset.toString ( qsFormat ) );
  m_pEditEnding2  ->setText ( endingTime.toString ( qsFormat ) );

  // Okay coming from the MovieObject we need only the Geometry - tab
  QWidget *pTab = m_pTabWidget->page (TRANSCODING_TAB);
  m_pTabWidget->removePage (pTab);
  delete pTab;
  pTab = m_pTabWidget->page (CHAPTERS_TAB);
  m_pTabWidget->removePage (pTab);
  delete pTab;
  // Also no transcoding buttons will be needed.
  delete m_pButtonTranscode;
  delete m_pButtonEncodeNow;
  m_pButtonTranscode = NULL;
  m_pButtonEncodeNow = NULL;
  // Here we trick the object in accepting the right QLineEdits
  m_pEditStarting1 = m_pEditStarting2;
  m_pEditEnding1   = m_pEditEnding2;
  m_pButtonEdit->setEnabled ( false );

  pTab = m_pTabWidget->page ( GEOMETRY_TAB );
  initAudioTab ( NULL, pMenu );

  // The following lines will display the [Change Size ...] button.
  QSizePolicy policy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
  delete textLabel4;
  delete m_pListViewCK;
  delete m_pButtonAddCK;
  delete m_pButtonDelCK;
  delete m_pEditCK;
  delete textLabel3_3;
  delete textLabel2_2;
  m_pButtonCK->setText (tr("Change Size ..."));
  m_pButtonCK->setSizePolicy ( policy );
  disconnect ( m_pButtonCK,  SIGNAL ( clicked ( ) ), this, SLOT ( slotBrowseColorKey ( ) ) );
  connect    ( m_pButtonCK,  SIGNAL ( clicked ( ) ), this, SLOT ( slotSizeDialog     ( ) ) );
  connect    ( m_pCheckLoop, SIGNAL ( clicked ( ) ), this, SLOT ( slotMenuLoop       ( ) ) );
  connect    ( m_pButtonTransition, SIGNAL ( clicked ( ) ), this, SLOT ( slotTransition ( ) ) );

  if ( pInterface->qsPost == "Loop" )  {
    m_pCheckLoop->setChecked ( true );
    slotMenuLoop ( );
  }
  groupBox8->setTitle ("");
  m_pCheckSameAsMenuLength->hide ( );
  m_pButtonLoop->hide ( );

  if (  (  ! pInterface->qsPause.isEmpty ( ) ) && 
        (    pInterface->qsPause !=  "inf" ) ) 
    iPause = pInterface->qsPause.toInt   ( );

  m_pLabelTitle->setText       ( "SubMenu:"       );
  m_pSpinBoxTitle->setValue    ( pInterface->iMenu     );
  m_pSpinBoxTitleset->setValue ( pInterface->iTitleset );
  m_pSpinBoxPause->setValue    ( iPause );
  // The VMGM Must stay in Titleset 0 !!!
  if ( ! pInterface->bIsSubMenu ) {
    m_pSpinBoxTitle->setEnabled    ( false );
    m_pSpinBoxTitleset->setEnabled ( false );
  }
  // Here we handle a MovieBackground ...
  if ( ! pInterface->qsMovieFileName.isEmpty ( ) )  {
    initMediaInterface ( pMenu );
    m_pTabWidget->setTabLabel   ( pTab, "MovieBackground" );
    m_pButtonThumbnail->setText ( tr ( "Set Background" ) );
    //    m_pTabWidget->setCurrentPage ( 1 );
  }
  else	{	// Here we handle a ImageBackground ...
    if ( ! pInterface->qsBackgroundFileName.isEmpty ( ) )  {
      QPixmap thePixmap;
      QImage theImage ( pInterface->qsBackgroundFileName );
      theImage = theImage.smoothScale (275, 275, QImage::ScaleFree);
      thePixmap.convertFromImage (theImage);
      m_pMediaPreview->setPixmap (thePixmap);
    }
    m_pMediaPreview->setFixedSize (275, 275);
    m_pEditStarting2->setEnabled  ( false );
    fileInfo.setFile ( pInterface->qsBackgroundFileName );
    m_pTextTitle->setText (tr ("ImageBackground : %1").arg(fileInfo.fileName()));
    setCaption ( fileInfo.fileName () );
    m_pTabWidget->setTabLabel (pTab, "ImageBackground");

    // And finally we hide the play buttons etc.
    delete m_pButtonPlay;
    delete m_pButtonStop;
    delete m_pButtonThumbnail;
    delete m_pButtonStart;
    delete m_pButtonEnd;
    delete m_pSliderVolume;
    delete m_pLabelCurrentPos;
    delete m_pFrameControl;
  }

  m_pComboPostCommand->clear ( );
  m_pComboPostCommand->insertItem ( " jump vmgm menu 1; " );

  if ( ! pInterface->qsPre.isEmpty  ( ) )
    m_pComboPreCommand->setCurrentText  ( pInterface->qsPre  );
  if ( ! pInterface->qsPost.isEmpty ( ) )
    m_pComboPostCommand->setCurrentText ( pInterface->qsPost );

  // These controls are not used ...
  delete groupBox2;
  resize ( 400, 300 );
}

void DialogMovie::initMe ( SourceFileEntry *pSourceFileEntry )
{
  if ( ( ! pSourceFileEntry ) || ( pSourceFileEntry->listFileInfos.count ( ) < 1 ) )
    return;

  m_sourceFileInfo   = *pSourceFileEntry->listFileInfos[0];
  QFileInfo fileInfo;
  QString qsFormat, qsBackgroundName;

  // Okay coming from transcodeAll ...
  QWidget *pTabChap = m_pTabWidget->page (CHAPTERS_TAB);
  QWidget *pTabGeom = m_pTabWidget->page (GEOMETRY_TAB);
  m_pTabWidget->removePage (pTabChap);
  delete pTabChap;
  m_pTabWidget->removePage (pTabGeom);
  delete pTabGeom;
  // Also no transcoding buttons will be needed.
  delete m_pButtonTranscode;
  delete m_pButtonEncodeNow;
  delete m_pGroupCurrentFormat;
  m_pButtonTranscode = NULL;
  m_pButtonEncodeNow = NULL;
  m_pEditStarting1   = NULL;
  m_pEditEnding1     = NULL;
  m_pComboPreCommand->setCurrentText  ( pSourceFileEntry->qsPre  );
  m_pComboPostCommand->setCurrentText ( pSourceFileEntry->qsPost );
  m_pLabelTransition->hide  ( );
  m_pButtonTransition->hide ( );

  setCaption ( "Transcoding all files of the SourceFileEntry" );
  m_pTextTitle->setText (tr ("SourceFileEntry : %1 Files").arg(pSourceFileEntry->listFileInfos.count()));
  // And finally we hide the play buttons etc.
  delete m_pMediaPreview;
  delete m_pButtonPlay;
  delete m_pButtonStop;
  delete m_pButtonThumbnail;
  delete m_pButtonStart;
  delete m_pButtonEnd;
  delete m_pSliderVolume;
  delete m_pLabelCurrentPos;
  delete m_pFrameControl;
  m_pCheckLoop->hide ( );

  connect (m_pComboVideoOut,        SIGNAL( activated(const QString &)), this, SLOT (slotVideoOutChanged(const QString &)));
  connect (m_pComboVideoResolution, SIGNAL( activated(const QString &)), this, SLOT (slotVideoResolutionChanged(const QString &)));
  connect (m_pComboVideoRate,       SIGNAL( activated(const QString &)), this, SLOT (slotVideoRateChanged(const QString &)));
  connect (m_pComboVideoType,       SIGNAL( activated(const QString &)), this, SLOT (slotVideoTypeChanged(const QString &)));
  connect (m_pComboVideoAspect,     SIGNAL( activated(const QString &)), this, SLOT (slotVideoAspectChanged(const QString &)));
  connect (m_pComboVideoBitrate,    SIGNAL( activated(const QString &)), this, SLOT (slotVideoBitrateChanged(const QString &)));
  resize ( 300, 250 );
}

void DialogMovie::initMe ( SourceFileInfo *pInfo, const void *pExistingMediaEngine, QDVDAuthor *pDVDAuthor )
{
  Utils theUtil;
  if ( ! pInfo )
    return;

  int t, i, iThumbnailSize = pDVDAuthor->getDragNDropContainer()->sizeThumbnail.width ( );
  SourceFileEntry *pEntry  = NULL;
  for ( t=0; t<pDVDAuthor->sourceFileCount  ( ); t++ ) {
    pEntry   = pDVDAuthor->sourceFileEntry ( t );
    if ( pEntry ) {
      for ( i=0; i<(int)pEntry->listFileInfos.count ( ); i++ ) {
        if ( pEntry->listFileInfos[i] == pInfo ) {
          m_pParentSourceFileEntry = pEntry;
          t = pDVDAuthor->sourceFileCount ( ); // exit t and i - loop
          break;
        }
      }
    }
  }

  // Okay coming from the SourceToolbar we do not need the Geometry - tab
  QWidget *pGeometry  = m_pTabWidget->page (GEOMETRY_TAB);
  m_pTranscodeTab = m_pTabWidget->page (TRANSCODING_TAB);
  m_pTabWidget->removePage (pGeometry);
  m_pTabWidget->removePage (m_pTranscodeTab);
  delete pGeometry;
  m_pLabelTransition->hide  ( );
  m_pButtonTransition->hide ( );
  // we keep the Transcode widget around in case the user wants to transcode the file.

  // And next we init the chapters - tab
  int iLength = theUtil.getMsFromString ( pInfo->qsLength );

  m_pCheckLoop->hide ( );

  // Here we copy the infos over ...
  m_sourceFileInfo = *pInfo;

  // and now on to initializing the dialog. Length : 00:07:23.123 File : Cool Video.mpg
  setHeader ( pInfo );

  m_pListBoxChapters->clear ( );
  if ( m_sourceFileInfo.listChapters.count  ( ) == 0 )
    m_pListBoxChapters->insertItem (QString ( "00:00:00.000" ) );
  m_pListBoxChapters->insertStringList   ( m_sourceFileInfo.listChapters );
  m_pListBoxChapters->setCurrentItem     ( 0 );
  m_pListBoxChapters->setSelected        ( 0, true );

  m_pComboPreCommand->setCurrentText  (m_sourceFileInfo.qsPreCommand);
  m_pComboPostCommand->setCurrentText (m_sourceFileInfo.qsPostCommand);
  m_pSpinBoxPause->setValue           (m_sourceFileInfo.iPause);

  m_pSpinBoxTitle->setEnabled  ( false );
  m_pSpinBoxTitleset->setValue ( m_sourceFileInfo.iTitleset );

  m_pMediaInterface = MediaCreator::createPreferredWidget (m_pMediaPreview, "ChapterXineWidget", (void *)pExistingMediaEngine);

  connect (m_pMediaInterface, SIGNAL(signalNewPosition(int, const QString&)), this, SLOT(slotNewPosition(int, const QString&)));
  QGridLayout *pVideoLayout = new QGridLayout (m_pMediaPreview, 1, 1, 2, 2, "MediaMainLayout");
  pVideoLayout->addWidget (m_pMediaInterface->getWidget(), 0, 0);
  // This is take care of in the polish () function for Xine and not necessary for MPlayer ...
  m_pMediaInterface->initMediaEngine();

  m_qsFileName      = m_sourceFileInfo.qsFileName;
  m_pExistingEngine = pExistingMediaEngine;

  // This is the new version, where I have a new WidgetControl.
  QGridLayout *pLayout = new QGridLayout      ( m_pFrameControl, 1, 1, 2, 2, "pLayout");
  m_pStartStopControl  = new StartStopControl ( m_pFrameControl );
  m_pStartStopControl->initMe ( m_sourceFileInfo.qsFileName, iThumbnailSize, iLength );
  connect (m_pStartStopControl, SIGNAL (signalSliderValues   ( float, float ) ), this, SLOT ( slotSliderValues   ( float, float ) ) );
  connect (m_pStartStopControl, SIGNAL (signalSliderReleased ( bool ) ),         this, SLOT ( slotSliderReleased ( bool ) ) );

  initAudioTab ( &m_sourceFileInfo );
  m_iMovieLength = iLength;
  if ( m_iMovieLength < 1 )
       m_iMovieLength = 1;
  pLayout->addWidget( m_pStartStopControl, 0, 0 );

  if ( m_sourceFileInfo.pTranscodeInterface )	{
    if ( m_sourceFileInfo.pTranscodeInterface->iEndingAt == 0 ) 
         m_sourceFileInfo.pTranscodeInterface->iEndingAt = m_iMovieLength;
    int  iMovieLength = m_sourceFileInfo.pTranscodeInterface->iEndingAt;
    if ( iMovieLength > m_iMovieLength )
         iMovieLength = m_iMovieLength;
    QString  qsFormat = QString ("hh:mm:ss.zzz");
    QTime endingTime, startingTime;
    startingTime = startingTime.addMSecs ( m_sourceFileInfo.pTranscodeInterface->iStartingAt );
    endingTime   = endingTime.addMSecs   ( iMovieLength  );
    m_pEditStarting1->setText ( startingTime.toString ( qsFormat ) );
    m_pEditEnding1  ->setText ( endingTime.toString   ( qsFormat ) );
  }

  m_pLabelVideoFormat->setText (QString ("%1(%2) %3Hz").arg( pInfo->qsVideoFormat ).arg ( pInfo->qsResolution ).arg ( pInfo->qsFPS ) );

  m_pLabelAudioFormat->setText(QString ("%1 %2bit %3").arg( pInfo->qsAudioFormat ).arg( pInfo->qsBits ).arg( pInfo->qsSample ) );

  m_pButtonEncodeNow->hide ( );

  // Here we init the properties - tab
  initTranscodeTab ( );
  m_pTabWidget->setCurrentPage ( 0 );

  // And finally here are the callback functions ...
  connect ( m_pButtonAdd,       SIGNAL( clicked ( ) ), this, SLOT ( slotAddChapter   ( ) ) );
  connect ( m_pButtonImport,    SIGNAL( clicked ( ) ), this, SLOT ( slotImportChapter( ) ) );
  connect ( m_pButtonDel,       SIGNAL( clicked ( ) ), this, SLOT ( slotDelChapters  ( ) ) );
  connect ( m_pButtonAuto,      SIGNAL( clicked ( ) ), this, SLOT ( slotAutoChapters ( ) ) );
  connect ( m_pListBoxChapters, SIGNAL( currentChanged (QListBoxItem *)), this, SLOT (slotCurrentChanged(QListBoxItem *)));

  connect (m_pComboVideoOut,        SIGNAL( activated(const QString &)), this, SLOT ( slotVideoOutChanged(const QString &)));
  connect (m_pComboVideoResolution, SIGNAL( activated(const QString &)), this, SLOT ( slotVideoResolutionChanged(const QString &)));
  connect (m_pComboVideoRate,       SIGNAL( activated(const QString &)), this, SLOT ( slotVideoRateChanged(const QString &)));
  connect (m_pComboVideoType,       SIGNAL( activated(const QString &)), this, SLOT ( slotVideoTypeChanged(const QString &)));
  connect (m_pComboVideoAspect,     SIGNAL( activated(const QString &)), this, SLOT ( slotVideoAspectChanged(const QString &)));
  connect (m_pComboVideoBitrate,    SIGNAL( activated(const QString &)), this, SLOT ( slotVideoBitrateChanged(const QString &)));
  connect (m_pSliderVolume,         SIGNAL( valueChanged (int)),         this, SLOT ( slotNewVolume (int) ) );

  QTimer::singleShot (  50, this, SLOT ( slotSetStartStop ( ) ) );
  QTimer::singleShot ( 100, this, SLOT ( slotSetMediaInfo ( ) ) );
}

void DialogMovie::setHeader ( SourceFileInfo *pInfo )
{
  if ( ! pInfo )
    return;

  Utils theUtil;
  QFileInfo fileInfo ( pInfo->qsFileName );

  // And next we init the chapters - tab
  int iLength = theUtil.getMsFromString ( pInfo->qsLength );

  // Check if the default 5 minutes chapter creation is out of range anyways ...
  QString qsReturn = theUtil.getStringFromMs ( iLength );
  if ( iLength < 5*60*1000 )      {
    m_pEditEvery->setText ( QString ("%1").arg ( (int)( iLength / 1000 ) ) );
    m_pEditAdd->setText   ( qsReturn );
  }
  m_pEditEnding1->setText ( qsReturn );

  // and now on to initializing the dialog. Length : 00:07:23.123 File : Cool Video.mpg
  m_pTextTitle->setText ( tr ( "Length : <%1> File : %2" ).arg ( pInfo->qsLength ).arg ( fileInfo.fileName ( ) ) );
  setCaption ( fileInfo.fileName ( ) );
}

void DialogMovie::slotSetMediaInfo ( )
{
  // Called from initMe ( SourceFileInfo * ... )
  bool bCreatedInfo = false;
  // This is required bc MPlayerInfo requires a running EventLoop to function
  // in the initMe function this is not yet given ( it is before the dialog.exec ( ) - call )
  m_pMediaInterface->initMediaEngine ( );

  m_pMediaInterface->openMRL  ( m_qsFileName );
  m_pMediaInterface->getScreenshot   ( );
  // Here we init the properties - tab
  MediaInfo *pMediaInfo = m_pMediaInterface->getMediaInfo ();
  if ( !  pMediaInfo )         {
    pMediaInfo = MediaCreator::createInfo ((void *)m_pExistingEngine);
    if ( ! pMediaInfo )
      return;
    pMediaInfo->setFileName ( m_qsFileName );
    bCreatedInfo = true;
  }

  m_pLabelVideoCodec->setText ( pMediaInfo->getCodec (  true ) );
  m_pLabelAudioCodec->setText ( pMediaInfo->getCodec ( false ) );  // Stereo 2.0

  if ( bCreatedInfo )
    delete pMediaInfo;
}

void DialogMovie::initMe ( MovieObject *pMovieObject )
{
  int t;
  // Called when coming from a MovieObject in the Menu.
  if ( ! pMovieObject )
    return;

  QString qsFormat;
  m_pMovieObject = pMovieObject;

  // Okay coming from the MovieObject we need only the Geometry - tab
  QWidget *pTab = m_pTabWidget->page (TRANSCODING_TAB);
  m_pTabWidget->removePage ( pTab );
  delete pTab;
  pTab = m_pTabWidget->page ( CHAPTERS_TAB );
  m_pTabWidget->removePage  ( pTab );
  delete pTab;
  pTab = m_pTabWidget->page ( SUBTITLE_TAB );
  m_pTabWidget->removePage  ( pTab );
  delete pTab;
  pTab = m_pTabWidget->page ( PROPERTIES_TAB );
  m_pTabWidget->removePage  ( pTab );
  delete pTab;
  // ALso no transcoding buttons will be needed.
  delete m_pButtonTranscode;
  delete m_pButtonEncodeNow;
  m_pButtonTranscode = NULL;
  m_pButtonEncodeNow = NULL;
  m_pEditStarting1   = m_pEditStarting2;
  m_pEditEnding1     = m_pEditEnding2;

  // Set the values .
  m_pEditX->setText (QString ("%1").arg(pMovieObject->rect().x()));
  m_pEditY->setText (QString ("%1").arg(pMovieObject->rect().y()));
  m_pEditWidth ->setText (QString ("%1").arg(pMovieObject->rect().width()));
  m_pEditHeight->setText (QString ("%1").arg(pMovieObject->rect().height()));

  qsFormat = QString ("hh:mm:ss.zzz");
  m_iMovieLength = -pMovieObject->duration ( ).msecsTo  ( QTime ( ) );

  m_pEditStarting2->setText ( pMovieObject->offset ( ).toString ( qsFormat ) );
  // m_pEditStarting2 must be set before calling maxEndTime
  QTime endingTime = maxEndTime ( ); //pMovieObject->offset ( ).addMSecs ( m_iMovieLength );
  QTime   clipTime ( pMovieObject->offset ( ) );
  clipTime = clipTime.addMSecs ( m_iMovieLength );
  if  ( m_iMovieLength > 0 )
        endingTime = clipTime;
  m_pEditEnding2->setText ( endingTime.toString  ( qsFormat ) );

  m_rectGeometry = pMovieObject->rect     ( );
  m_qsFileName   = pMovieObject->fileName ( );
  m_pCheckSameAsMenuLength->setChecked ( pMovieObject->isMenuLength ( ) );
  m_pEditEnding2->setEnabled         ( ! pMovieObject->isMenuLength ( ) );
  m_pButtonLoop->setEnabled          ( ! pMovieObject->isMenuLength ( ) );
  QString strLoop = "Stretch";
  if ( pMovieObject->loop ( ) == MovieObject::Loop )
       strLoop  =  "Loop";
  else if ( pMovieObject->loop ( ) == MovieObject::Stop )
       strLoop  =  "Stop";
  m_pButtonLoop->setText ( strLoop );

  Rgba theColor;
  ImageManipulator::colorKeying *pKey;
  ImageManipulator *pMan = &pMovieObject->manipulator ( );
  for ( t=0; t<(int)pMan->listColorKeys.count(); t++ )	{
    pKey = pMan->listColorKeys[t];
    theColor.setRgb ( pKey->theColor );
    new ListViewColorItem ( m_pListViewCK, theColor, theColor.toString ( ), QString ("%1").arg(pKey->fDeltaColor ) );
  }

  QFileInfo fileInfo(m_qsFileName);
  // and now on to initializing the dialog. Length : 00:07:23.123 File : Cool Video.mpg
  m_pTextTitle->setText ( tr ( "File : %1" ).arg ( fileInfo.fileName ( ) ) );

  // we'll init the MediaEngine here
  DVDMenu *pDVDMenu = pMovieObject->dvdMenu ( );
  initMediaInterface ( pDVDMenu );
  QString qsCaption = tr  ( "Menu Length : %1" ).arg ( pDVDMenu->getInterface ( )->timeDuration.toString ( qsFormat ) );
  setCaption ( qsCaption );

  connect ( m_pCheckSameAsMenuLength, SIGNAL ( clicked ( ) ), this, SLOT ( slotSameAsMenuLength ( ) ) );
  connect ( m_pButtonLoop,    SIGNAL ( clicked   ( ) ), this, SLOT ( slotLoop       ( ) ) );
  connect ( m_pEditEnding2,   SIGNAL ( lostFocus ( ) ), this, SLOT ( slotCheckEnd   ( ) ) );
  connect ( m_pEditStarting2, SIGNAL ( lostFocus ( ) ), this, SLOT ( slotCheckStart ( ) ) );
}

void DialogMovie::initMediaInterface ( DVDMenu *pDVDMenu )
{
  QFileInfo fileInfo;
  QString qsBackgroundName, qsFormat;
  int iThumbnailSize = 50;
  MediaInfo *pMediaInfo           = NULL;
  void      *pExistingMediaEngine = NULL;
  qsFormat = QString ("hh:mm:ss.zzz");

  if ( pDVDMenu )	{
    pMediaInfo = pDVDMenu->getDVDAuthor()->getMediaInfo ( );
    pExistingMediaEngine = pMediaInfo->getMediaEngine   ( );
    iThumbnailSize = pDVDMenu->getDVDAuthor()->getDragNDropContainer()->sizeThumbnail.width();
    if (m_qsFileName.isEmpty() || m_qsFileName.isNull() )	{
      if (pDVDMenu->getInterface()->qsMovieFileName.isNull())
        m_qsFileName = pDVDMenu->getInterface ( )->qsBackgroundFileName;
      else
        m_qsFileName = pDVDMenu->getInterface ( )->qsMovieFileName;
    }
    fileInfo.setFile (m_qsFileName);
    qsBackgroundName = QString (" : %1 <%2>").arg(fileInfo.fileName()).arg(pDVDMenu->getInterface()->timeDuration.toString(qsFormat));

    m_pTextTitle->setText (pDVDMenu->name() + qsBackgroundName);
  }
  // Here we create the MediaInterface (the widget) If the mediaengine in NULL or not ...
  m_pMediaInterface = MediaCreator::createPreferredWidget ( m_pMediaPreview, "ChapterXineWidget", pExistingMediaEngine );
  connect (m_pMediaInterface, SIGNAL(signalNewPosition(int, const QString&)), this, SLOT(slotNewPosition(int, const QString&)));

  QGridLayout *pVideoLayout = new QGridLayout ( m_pMediaPreview, 1, 1, 2, 2, "MediaMainLayout" );
  pVideoLayout->addWidget ( m_pMediaInterface->getWidget ( ), 0, 0 );
  // This is taken care of in the polish () function for Xine and not necessary for MPlayer ...
  m_pMediaInterface->initMediaEngine ( );

  QGridLayout *pLayout = new QGridLayout      ( m_pFrameControl, 1, 1, 2, 2, "pLayout" );
  m_pStartStopControl  = new StartStopControl ( m_pFrameControl );

  if ( m_pMovieObject || m_pDVDMenu )
    m_pStartStopControl->initMe ( m_qsFileName, iThumbnailSize );  // get length of movieObject a bit later.
  else
    m_pStartStopControl->initMe ( m_qsFileName, iThumbnailSize, m_iMovieLength );

  pLayout->addWidget( m_pStartStopControl, 0, 0 );

  QTimer::singleShot ( 500, this, SLOT ( slotInitMediaInterface ( ) ) );
}

void DialogMovie::slotInitMediaInterface ( )
{
  m_pMediaInterface->openMRL ( m_qsFileName );
  m_pMediaInterface->getScreenshot ( );
  m_pMediaInterface->setScreenshot ( 1.0f );

  QFileInfo fileInfo ( m_qsFileName );
  MediaInfo *pMediaInfo = NULL;  
  //int iThumbnailSize = 70;
  // Here we ensure the availability of a MediaInfo - object
  pMediaInfo = m_pMediaInterface->getMediaInfo ( );
  if ( ! pMediaInfo )
    return;

  QString qsFormat = QString ("hh:mm:ss.zzz");
  // here we extract some information + the screenshot.
  pMediaInfo->setFileName ( m_qsFileName );

  if ( m_pMovieObject ) { // For MovieObjects, the actual video length is not the clip length
    QTime zeroTime;
    long  iMSecOffset = zeroTime.msecsTo ( m_pMovieObject->offset ( ) );
    unsigned long int iMovieLength = pMediaInfo->getLength ( );
    m_pMediaInterface->setScreenshot ( iMSecOffset );

    DVDMenu *pDVDMenu = m_pMovieObject->dvdMenu ( );
    long iMenuLength  = zeroTime.msecsTo  ( pDVDMenu->getInterface ( )->timeDuration );

    if ( iMenuLength >= (long)iMovieLength )  {
      m_pCheckSameAsMenuLength->setChecked ( FALSE );
      m_pCheckSameAsMenuLength->setEnabled ( FALSE );
      slotSameAsMenuLength ( );
    }

    if ( iMovieLength < 1 )
      iMovieLength = m_iMovieLength;
    m_iMovieLength =   iMovieLength;
    //m_pEditEnding2->setText ( maxEndTime ( ).toString  ( qsFormat ) );
    m_pStartStopControl->createThumbnails ( m_iMovieLength );
  }
  else if ( m_pDVDMenu ) {
    QTime zeroTime;
    long  iMSecOffset = zeroTime.msecsTo ( m_pDVDMenu->getInterface ( )->timeOffset );
    unsigned long int iMovieLength = pMediaInfo->getLength ( );
    m_pMediaInterface->setScreenshot ( iMSecOffset );
    if ( iMovieLength < 1 )
      iMovieLength = m_iMovieLength;
    m_iMovieLength =   iMovieLength;
    m_pStartStopControl->createThumbnails ( m_iMovieLength );
  }

  QTime   lengthTime;
  lengthTime = lengthTime.addMSecs ( m_iMovieLength );
  QString qsLength = lengthTime.toString ( qsFormat );

  m_pTextTitle->setText   ( tr ("Length : <%1> File : %2").arg( qsLength ).arg ( fileInfo.fileName ( ) ) );
//  setCaption ( fileInfo.fileName ( ) );

  // next is to set the satrting / ending points ...
  QTimer::singleShot ( 50, this, SLOT ( slotSetStartStop ( ) ) );
  connect ( m_pStartStopControl, SIGNAL ( signalSliderValues ( float, float)), this, SLOT ( slotSliderValues   ( float, float ) ) );
  connect ( m_pStartStopControl, SIGNAL ( signalSliderReleased ( bool ) ),     this, SLOT ( slotSliderReleased ( bool ) ) );
  connect ( m_pSliderVolume,     SIGNAL ( valueChanged         ( int  ) ),     this, SLOT ( slotNewVolume      ( int  ) ) );
}

void DialogMovie::initAudioTab ( SourceFileInfo *pInfo, DVDMenu *pMenu )
{
  int t;
  Utils      theUtils;
  Subtitles *pSubtitle;
  if ( pInfo ) {
    for ( t=0; t<MAX_SUBTITLES; t++ ) {
      pSubtitle = pInfo->arraySubtitles[t];
      if ( pSubtitle ) {
        // #, code, Language, file
        new QListViewItem ( m_pListViewSubtitles, QString ( "%1" ).arg ( pSubtitle->m_iSubtitleNumber ), pSubtitle->m_qsIso639, theUtils.iso639 ( pSubtitle->m_qsIso639, false ), QString ( "%1" ).arg ( pSubtitle->m_listOfSubtitles.count ( ) ) );
      }
    }
    // The first pass we figure out the set audio tracks.
    createAudioList ( );
  }
  else if ( pMenu ) {
    CDVDMenuInterface *pInterface = pMenu->getInterface  ( );
    Utils theUtils;
    for ( t=0; t<(int)pInterface->listSoundEntries.count ( ); t++ ) {
      Audio *pAudio = pInterface->listSoundEntries[t];
      QString qsCode = theUtils.iso639 ( pAudio->qsIso639, false );
      if ( pAudio ) {
        new QListViewItem ( m_pListViewAudio, QString ( "%1" ).arg ( pAudio->iAudioNumber), pAudio->qsIso639, qsCode, pAudio->qsFileName );
      }
    }
    m_pFrameSubtitles->hide ( );
  }

  m_pButtonEditAudio     ->setEnabled ( false );
  m_pButtonDeleteAudio   ->setEnabled ( false );
  m_pButtonEditSubtitle  ->setEnabled ( false );
  m_pButtonDeleteSubtitle->setEnabled ( false );
  connect ( m_pButtonAddAudio,       SIGNAL ( clicked ( ) ), this, SLOT ( slotAddAudio       ( ) ) );
  connect ( m_pButtonEditAudio,      SIGNAL ( clicked ( ) ), this, SLOT ( slotEditAudio      ( ) ) );
  connect ( m_pButtonDeleteAudio,    SIGNAL ( clicked ( ) ), this, SLOT ( slotDeleteAudio    ( ) ) );
  connect ( m_pButtonAddSubtitle,    SIGNAL ( clicked ( ) ), this, SLOT ( slotAddSubtitle    ( ) ) );
  connect ( m_pButtonEditSubtitle,   SIGNAL ( clicked ( ) ), this, SLOT ( slotEditSubtitle   ( ) ) );
  connect ( m_pButtonDeleteSubtitle, SIGNAL ( clicked ( ) ), this, SLOT ( slotDeleteSubtitle ( ) ) );
  connect ( m_pListViewAudio,        SIGNAL ( pressed ( QListViewItem * )), this, SLOT ( slotAudioSelectionChanged    ( QListViewItem * ) ) );
  connect ( m_pListViewSubtitles,    SIGNAL ( pressed ( QListViewItem * )), this, SLOT ( slotSubtitleSelectionChanged ( QListViewItem * ) ) );
}

void DialogMovie::createAudioList ( )
{
  // Based on m_sourceFileInfo
  int t;
  Utils theUtils;
  m_pListViewAudio->clear ( );
  Audio *arrayAudio[MAX_AUDIO], *pAudio;
  int iMaxAudio = 0; // Audio Track sohould always be displayed.
  for ( t=0; t<MAX_AUDIO; t++ )
    arrayAudio[t] = NULL;
  for ( t=0; t<MAX_AUDIO; t++ )  {
    pAudio = m_sourceFileInfo.arrayAudio[t];
    if ( pAudio )  {
      if ( iMaxAudio < pAudio->iAudioNumber )
           iMaxAudio = pAudio->iAudioNumber;
      if ( pAudio->iAudioNumber < MAX_AUDIO )
           arrayAudio[pAudio->iAudioNumber] = pAudio;
    }
  }
  iMaxAudio++;
  // Note: m_pParentSourceFileEntry should be set.
  for ( t=0; t<iMaxAudio; t++ ) {
    pAudio = arrayAudio[t]; //pInfo->arrayAudio[t];
    if ( pAudio ) {
      // #, code, Language, file
      new QListViewItem ( m_pListViewAudio, QString ( "%1" ).arg ( pAudio->iAudioNumber ), pAudio->qsIso639, theUtils.iso639 ( pAudio->qsIso639, false ), pAudio->qsFileName );
    }
    else if ( t == 0 )  {
      QFileInfo fileInfo ( m_sourceFileInfo.qsFileName );
      QString qsAudioName = tr ( "Audio track of : " ) + fileInfo.fileName ( );
      new QListViewItem  ( m_pListViewAudio, QString ( "%1" ).arg ( t ), "--", "---", ( m_sourceFileInfo.bHasAudioTrack ) ? qsAudioName : tr ( "No Audio" ) );
    }
    else
      new QListViewItem ( m_pListViewAudio, QString ( "%1" ).arg ( t ), "--", "---", tr ( "No Audio" ) );
  }
}

void DialogMovie::slotAudioSelectionChanged ( QListViewItem * )
{
  QListViewItem *pItem = m_pListViewAudio->selectedItem ( );
  bool bEnabled = true;
  if ( ! pItem )
    bEnabled = false;

  m_pButtonEditAudio  ->setEnabled ( bEnabled );
  m_pButtonDeleteAudio->setEnabled ( bEnabled );
}

void DialogMovie::slotSubtitleSelectionChanged ( QListViewItem * )
{
  QListViewItem *pItem = m_pListViewSubtitles->selectedItem ( );
  bool bEnabled = true;
  if ( ! pItem ) 
    bEnabled = false;

  m_pButtonEditSubtitle  ->setEnabled ( bEnabled );
  m_pButtonDeleteSubtitle->setEnabled ( bEnabled );
}

void DialogMovie::slotAddAudio ( )
{
  bool bTooMany = false;
  QDVDAuthor *pDVDAuthor = NULL;
  if ( m_pDVDMenu ) {
    pDVDAuthor = m_pDVDMenu->getDVDAuthor ( );
    CDVDMenuInterface *pInterface = m_pDVDMenu->getInterface ( );
    if ( pInterface->listSoundEntries.count ( ) > 7 )
      bTooMany = true;
  }
  else if ( m_sourceFileInfo.audioCount ( ) > 7 )
    bTooMany = true;

  if ( bTooMany ) {
    MessageBox::warning ( this, tr ( "Too many audio files." ), tr ( "DVD spec allows a max of 8 audi channels.\nPlease remove one audio channel first." ) );
    return;
  }

  QString qsDialogFilter;
  if ( pDVDAuthor )
    qsDialogFilter = tr ( pDVDAuthor->getSoundFilter ( ) );
  else
    qsDialogFilter = tr ( "*.mp2 *.mp3 *.ogg *.ac3 *.m2a *.pcm *.wav *.MP2 *.MP3 *.OGG *.AC3 *.M2A *.PCM *.WAV" );

  QStringList listFiles  =  FilePreviewDialog::getOpenFileNames ( Global::qsCurrentPath, QString::null, 
		             this, "Sound File Dialog", tr( "Select sound files" ), &qsDialogFilter );
  if ( listFiles.size ( ) < 1 )
    return;
  QString qsSelFileName  = listFiles[0];
  QFileInfo fileInfo ( qsSelFileName );
  Global::qsCurrentPath = fileInfo.absFilePath ( );

  if ( m_pDVDMenu ) {
    QDVDAuthor *pDVDAuthor = m_pDVDMenu->getDVDAuthor ( );
    if ( pDVDAuthor ) {
      pDVDAuthor->addSound ( listFiles );

      SourceFileEntry *pNewEntry = pDVDAuthor->sourceFileEntry( pDVDAuthor->sourceFileCount ( ) -1 );
      if ( ! pNewEntry )
	return;

      int iFreeAudioTrack = 0;
      for ( unsigned int t=0; t<m_pDVDMenu->getInterface()->listSoundEntries.count ( ); t++ ) {
	if ( iFreeAudioTrack == m_pDVDMenu->getInterface()->listSoundEntries[t]->iAudioNumber ) {
	  iFreeAudioTrack ++;
	  t = 0;
	}
      }
      if ( iFreeAudioTrack > 7 ) {
	// Error 
	pDVDAuthor->removeSourceFileEntry ( pNewEntry );
	delete pNewEntry;
	return;
      }

      Audio  *pAudio = new Audio;
      Utils   theUtils;
      QString qsLanguage   = theUtils.iso639 ( Global::qsDefaultLanguage, false );
      pAudio->qsFileName   = pNewEntry->qsDisplayName;
      pAudio->iAudioNumber = iFreeAudioTrack;
      m_pDVDMenu->getInterface ( )->listSoundEntries.append ( pAudio );
      m_pDVDMenu->slotUpdateStructure ( );

      new QListViewItem ( m_pListViewAudio, QString ( "%1" ).arg ( iFreeAudioTrack ), pAudio->qsIso639, qsLanguage, pAudio->qsFileName );
    }
    return;
  }
  // handling multiple audio streams for a SourceFileInfo ...
  int iValue, iSelectedValue;
  Utils          theUtils;
  DialogAudio    theDialog;
  QString        qsCode, qsLang, qsFileName;
  QListViewItem      *pSelectedItem       = NULL;
  TranscodeInterface *pTranscodeInterface = NULL;

  pTranscodeInterface = checkRightAudioFormat ( qsSelFileName );
  // Note we deliver both the local copy as the original.
  theDialog.initMe ( &m_sourceFileInfo, m_pParentSourceFileEntry, qsSelFileName );
  theDialog.setTranscode ( pTranscodeInterface );
  if ( theDialog.exec ( ) == QDialog::Rejected )
    return;
  iSelectedValue = theDialog.getSelectedNumber ( );
  pTranscodeInterface = theDialog.getTranscode ( );

  // At this point both loal copy and original have been updated to reflect the changes 
  // made in DialogAudio.

  /*
  { // VAROL
    SourceFileEntry *p = m_pParentSourceFileEntry;
    printf ( "%s::%s : %d > iSelected<%d> ORIG > ", __FILE__, __FUNCTION__, __LINE__, iSelectedValue );
    for ( int e=0;e<MAX_AUDIO;e++ )
      printf ( "[%d=%s] ", p->arrayAudioEntries[e].iAudioNumber, p->arrayAudioEntries[e].qsIso639.ascii() );
    printf ( "\n" );
    SourceFileInfo *p1 = &m_sourceFileInfo;
    printf ( "%s::%s : %d > NEW  > ", __FILE__, __FUNCTION__, __LINE__ );
    for ( int e=0;e<MAX_AUDIO;e++ )
      if ( p1->arrayAudio[e] )
	printf ( "[%d=%s<%p>] ", p1->arrayAudio[e]->iAudioNumber, p1->arrayAudio[e]->qsIso639.ascii(), p1->arrayAudio[e]->pTranscodeInterface );
    printf ( "\n" );
  }
  */
  // we ought to reflect the changes in the ListView ...
  createAudioList ( );

  QListViewItem *pChild = m_pListViewAudio->firstChild ( );
  while ( pChild )  {
    iValue = pChild->text ( 0 ).toInt ( );
    if ( iValue == iSelectedValue )  {
      pSelectedItem = pChild;
      break;
    }
    pChild = pChild->nextSibling ( );
  }

  if ( pTranscodeInterface )
    delete pTranscodeInterface;
  // And lastly we should selected the newly added Language ...
  if ( pSelectedItem ) {
    m_pSelectItem = pSelectedItem;
    QTimer::singleShot ( 10, this, SLOT ( slotSetSelectedItem ( ) ) );
    pSelectedItem->setText ( 4, qsSelFileName );
  }
}

void DialogMovie::slotEditAudio ( )
{
  SourceFileEntry *pEntry = NULL;
  QListViewItem   *pItem  = m_pListViewAudio->selectedItem ( );
  if ( ! pItem )
    return;

  unsigned int t;
  Utils    theUtils;

  Audio   *pAudio = NULL;
  QString  qsCode, qsLanguage = "English";

  if ( m_pDVDMenu ) {
    QString  qsDisplayName = pItem->text ( 3 );
    pEntry    =  m_pDVDMenu->getDVDAuthor ( )->getSourceEntryByDisplayName ( qsDisplayName );
    for ( t=0; t<m_pDVDMenu->getInterface ( )->listSoundEntries.count ( ); t++ ) {
      pAudio  =  m_pDVDMenu->getInterface ( )->listSoundEntries[t];
      if ( ! pAudio )
        continue;
      if ( pAudio->qsFileName == qsDisplayName )
        break;
      pAudio = NULL;
    }
  }
  else { // coming from a SourceFileInfo
    QString qsAudioNr  = pItem->text ( 0 );
    qsCode             = pItem->text ( 1 );
    QString qsFileName = pItem->text ( 3 );
    // if video has an audio track, then we can't set the language settings for it. Sorry.
    if ( m_sourceFileInfo.bHasAudioTrack )  {
      if ( qsAudioNr == "0" )
        return;
    }
    else  {
      bool bHasTrackZero = false;
      for ( t=0; t<MAX_AUDIO; t++ )  {
        pAudio =  m_sourceFileInfo.arrayAudio[t];
        if ( pAudio && pAudio->iAudioNumber == 0 )  {
          bHasTrackZero  = true;
          break;
        }
      }
      if ( ! bHasTrackZero ) // Return if no track zero exists.
        return;
    }

    for ( t=0; t<MAX_AUDIO; t++ )  {
      pAudio = m_sourceFileInfo.arrayAudio[t];
      if ( ! pAudio || pAudio->iAudioNumber == -1 )
        continue;
      if ( ( qsFileName == pAudio->qsFileName ) &&
           ( qsCode     == pAudio->qsIso639   ) )
        break;
      pAudio = NULL;
    }
  }
  if ( pAudio )
    qsLanguage = theUtils.iso639 ( pAudio->qsIso639, false );

  SmallDialogAudio theDialog;
  // Note we deliver both the local copy as the original.
  if ( pEntry )
    theDialog.initMe ( pEntry );
  else
    theDialog.initMe ( pAudio );
  theDialog.setLanguageText ( qsLanguage );
  if (  theDialog.exec ( ) == QDialog::Rejected )
    return;

  qsLanguage = theDialog.languageText ( );
  qsLanguage = qsLanguage.remove ( QRegExp ( "<[^>]*>" ) );
  qsCode     = theUtils.iso639 ( qsLanguage, true );
  if ( pAudio )  {
    if ( m_pParentSourceFileEntry && ( pAudio->qsIso639 != qsCode ) )
         m_pParentSourceFileEntry->changeAudioTrack ( pAudio->iAudioNumber, qsCode );
    pAudio->qsIso639 = qsCode;
  }
  pItem->setText  ( 1, qsCode );
  pItem->setText  ( 2, qsLanguage );
}

void DialogMovie::slotDeleteAudio ( )
{
  QListViewItem *pItem = m_pListViewAudio->selectedItem ( );
  if ( pItem ) {
    // check if this is the dialog for a DVDMenu.
    if ( m_pDVDMenu ) {
      QString qsFileName = pItem->text ( 3 );
      m_pDVDMenu->removeBackgroundAudio( qsFileName, false );
      delete pItem;
      return;
    }
    bool   bOkay, bFound;
    Audio *pAudio;
    int t, i, iAudioNumber = pItem->text ( 0 ).toInt ( &bOkay );
    if ( ! bOkay )
      return;
    for ( t=0; t<MAX_AUDIO; t++ ) {
      pAudio = m_sourceFileInfo.arrayAudio [ t ];
      if ( pAudio && pAudio->iAudioNumber == iAudioNumber )  {
        delete pAudio;
        m_sourceFileInfo.arrayAudio [ t ] = NULL;
        break;
      }
    }

    if ( ( iAudioNumber == 0 ) && ( m_sourceFileInfo.bHasAudioTrack ) )
      return;

    // remove from m_pParentSourceFileEntry if this has been the last reference to this audio track.
    bFound = false;
    SourceFileInfo *pInfo;
    if ( m_pParentSourceFileEntry ) {
      for ( t=0; t<(int)m_pParentSourceFileEntry->listFileInfos.count ( ) && ( ! bFound ); t++ ) {
        pInfo = m_pParentSourceFileEntry->listFileInfos[t];
        if ( pInfo->qsFileName == m_sourceFileInfo.qsFileName )
          continue;
        for ( i=0; i<MAX_AUDIO && ( ! bFound ); i++ ) {
          pAudio = pInfo->arrayAudio[i];
          if ( pAudio && pAudio->iAudioNumber == iAudioNumber ) {
            bFound = true;
            break;
          }
        }
      }
      if ( ! bFound ) {
        m_pParentSourceFileEntry->arrayAudioEntries[ iAudioNumber ].iAudioNumber = -1;
        m_pParentSourceFileEntry->arrayAudioEntries[ iAudioNumber ].qsIso639     = QString ( );
      }
    }
    // And finally we remove the item from the ListView ...
    createAudioList ( );
  }
}

void DialogMovie::slotAddSubtitle ( )
{
  int  t, iValue;
  QString qsLang ( "English" );

  QString qsImportFile = QFileDialog::getOpenFileName ( Global::qsCurrentPath, QObject::tr ( "Subtitle files (*.srt *.SRT *.ssa *.SSA *.ass *.ASS)"), NULL, QObject::tr ( "Open Subtitles File" ) );

  QFileInfo fileInfo ( qsImportFile );
  Global::qsCurrentPath = fileInfo.dirPath ( true );

  Import::Srt srtImporter;
  Import::Ssa ssaImporter;
  Import::BaseSubtitle *pImporter = &ssaImporter;
  if ( fileInfo.extension ( false ) == "srt" )
    pImporter = &srtImporter;

  if ( ! pImporter->readFile ( qsImportFile ) )
    return;

  for ( t=0; t<MAX_SUBTITLES; t++ ) {
    if ( ! m_sourceFileInfo.arraySubtitles [ t ] ) 
      break;
  }
  iValue = t;

  if ( ! subtitleDialog ( iValue, qsLang ) )
    return;

  if ( ! sanityCheckSubtitleTrack ( iValue, qsLang ) )
    return;

  QString qsFileName = pImporter->getFileName ( );
  if ( qsFileName.length ( )  >  1 )  {
    QFileInfo fileInfo   ( qsFileName );
    Global::qsCurrentPath = fileInfo.absFilePath ( );
  }

  if ( m_sourceFileInfo.arraySubtitles [ iValue ] ) {
    QFileInfo fileInfo ( m_sourceFileInfo.qsFileName );
    // the subtitle already exists in the sourcefileinfo.
    if ( MessageBox::question ( this, tr ( "Subtitle exists" ), tr ( "Warning, the subtitle number %1 exists already.\nDo you want to remove the current subtitle %2 from the file %3 ?" ).arg ( iValue ).arg ( iValue ).arg ( fileInfo.fileName ( ) ), QMessageBox::Yes, QMessageBox::No ) == QMessageBox::No )
      return;
  }

  QValueList<Subtitles::entry *> listOfEntries = pImporter->takeSubtitles ( );
  addSubtitle ( qsLang, iValue,  listOfEntries,  pImporter->getFileName ( ) );
}

void DialogMovie::slotEditSubtitle ( )
{
  QListViewItem *pItem = m_pListViewSubtitles->selectedItem ( );
  if ( ! pItem )
    return;

  bool    bOkay      = true;
  QString qsNumber   = pItem->text    ( 0 );
  QString qsLanguage = pItem->text    ( 2 );
  int t,  iNumber    = qsNumber.toInt ( &bOkay );
  if ( ( ! bOkay ) || ( iNumber > MAX_SUBTITLES ) )
    return;

  Subtitles *pSubtitle = m_sourceFileInfo.arraySubtitles [ iNumber ];
  if ( ! pSubtitle )
    return;

  t = iNumber;
  if ( ! subtitleDialog ( iNumber, qsLanguage ) ) // iNumber might be changed here.
    return;
  if ( t != iNumber ) {
    if ( ! sanityCheckSubtitleTrack ( iNumber, qsLanguage ) )
      return;

    if ( m_sourceFileInfo.arraySubtitles [ iNumber ] ) {
      QFileInfo fileInfo ( m_sourceFileInfo.qsFileName );
      // the subtitle already exists in the sourcefileinfo.
      if ( MessageBox::question ( this, tr ( "Subtitle exists" ), tr ( "Warning, the subtitle number %1 exists already.\nDo you want to remove the current subtitle %2 from the file %3 ?" ).arg ( iNumber ).arg ( iNumber ).arg ( fileInfo.fileName ( ) ), 
	   QMessageBox::Yes, QMessageBox::No ) == QMessageBox::No )
	return;

      // Okay we need to delete the previous one
      delete m_sourceFileInfo.arraySubtitles [ iNumber ];
      m_sourceFileInfo.arraySubtitles [ iNumber ] = NULL;

      int iItemNumber;
      QListViewItem *pItem = m_pListViewSubtitles->firstChild ( );
      while ( pItem ) {
	iItemNumber = pItem->text ( 0 ).toInt ( &bOkay );
	if ( ( iItemNumber == iNumber )  &&   (  bOkay ) )  {
	  delete pItem;
	  break;
	}
	pItem = pItem->nextSibling ( );
      }
    }
    m_sourceFileInfo.arraySubtitles [ t ]       = NULL;
    m_sourceFileInfo.arraySubtitles [ iNumber ] = pSubtitle;
  }

  Utils   theUtils;
  QString qsIso639 = theUtils.iso639 ( qsLanguage, true );
  // At this point we are sure that iNmber is available
  pSubtitle->m_iSubtitleNumber = iNumber;
  pSubtitle->m_qsIso639        = qsIso639;
  pItem->setText ( 0, QString ( "%1" ).arg ( iNumber ) );
  pItem->setText ( 1, qsIso639   );
  pItem->setText ( 2, qsLanguage );

  m_pListViewSubtitles->clearSelection ( );
  m_pSelectItem = pItem;
  QTimer::singleShot ( 10, this, SLOT ( slotSetSelectedItem ( ) ) );
}

bool DialogMovie::subtitleDialog ( int &iNumber, QString &qsLanguage )
{
  int t;
  Utils    theUtils;
  QString  qsText, qsLang;
  uiDialogSubtitle theDialog;
  // Okay time to initialize the Language selection - dialog
  t = 0; qsLang = "something";
  theDialog.m_pComboLanguage->clear ( );
  //  theDialog.m_pComboLanguage->insertItem ( tr ( "Language" ) );
  while ( ! qsLang.isEmpty ( ) ) {
    qsLang = theUtils.iso639(  qsText,  false,  t++ );
    theDialog.m_pComboLanguage->insertItem ( qsLang );
  }
  theDialog.m_pComboLanguage->setCurrentText ( qsLanguage );
  theDialog.m_pSpinboxNumber->setValue ( iNumber );
  if ( theDialog.exec ( ) == QDialog::Rejected )
    return false;

  iNumber    = theDialog.m_pSpinboxNumber->value ( );
  qsLanguage = theDialog.m_pComboLanguage->currentText ( );
  return true;
}

void DialogMovie::addSubtitle ( QString qsLang, int iValue, QValueList<Subtitles::entry *> &listOfEntries, QString qsFileName )
{
  QString   qsCode, qsCount, qsXmlFile;
  QFileInfo fileInfo;
  Utils     theUtils;

  qsCode = theUtils.iso639 ( qsLang, true );
  // First we attach the new subtitle - object to the SourceFileInfo ...
  fileInfo.setFile ( m_sourceFileInfo.qsFileName );
  qsXmlFile.sprintf ( "/subtitle_%d.xml", iValue );
  qsXmlFile = theUtils.getTempFile ( fileInfo.baseName ( TRUE ) ) + qsXmlFile;
  if ( m_sourceFileInfo.arraySubtitles[iValue] )
    delete m_sourceFileInfo.arraySubtitles[iValue];

  int iWidth  = theUtils.getWHFromResolution ( m_sourceFileInfo.qsResolution, true  );
  int iHeight = theUtils.getWHFromResolution ( m_sourceFileInfo.qsResolution, false );

  m_sourceFileInfo.arraySubtitles [ iValue ] = new Subtitles ( iWidth, iHeight );
  m_sourceFileInfo.arraySubtitles [ iValue ]->m_qsFileName      = qsFileName;
  m_sourceFileInfo.arraySubtitles [ iValue ]->m_iSubtitleNumber = iValue;
  m_sourceFileInfo.arraySubtitles [ iValue ]->m_qsIso639        = qsCode;
  m_sourceFileInfo.arraySubtitles [ iValue ]->m_listOfSubtitles = listOfEntries;
  m_sourceFileInfo.arraySubtitles [ iValue ]->m_qsXmlFile       = qsXmlFile;

  if ( m_pParentSourceFileEntry ) {
    m_pParentSourceFileEntry->arraySubtitleEntries [ iValue ].m_iSubtitleNumber = iValue;
    m_pParentSourceFileEntry->arraySubtitleEntries [ iValue ].m_qsIso639        = qsCode;
  }

  QListViewItem *pItem = m_pListViewSubtitles->firstChild ( );
  while ( pItem ) {
    if ( pItem->text( 0 ).toInt ( ) == iValue ) {
      delete pItem;
      break;
    }
    pItem = pItem->nextSibling ( );
  }
  m_pListViewSubtitles->clearSelection ( );
  qsCount = QString ( "%1" ).arg (  m_sourceFileInfo.arraySubtitles [ iValue ]->m_listOfSubtitles.count ( ) );
  pItem = new QListViewItem ( m_pListViewSubtitles, QString ( "%1" ).arg ( iValue ), qsCode, qsLang, qsCount );
  m_pSelectItem = pItem;
  QTimer::singleShot ( 10, this, SLOT ( slotSetSelectedItem ( ) ) );
}

void DialogMovie::timerEvent ( QTimerEvent *pEvent )
{
  if ( pEvent->timerId ( ) == MEDIASCANNER_EVENT + 3 ) {  // ExecuteJob::TYPE_SUBTITLES ...
    m_pListViewSubtitles->clear ( );
    Utils theUtils;
    for ( int t=0; t<MAX_SUBTITLES; t++ ) {
      Subtitles *pSubtitle = m_sourceFileInfo.arraySubtitles[t];
      if ( pSubtitle ) {
	// #, code, Language, file
	new QListViewItem ( m_pListViewSubtitles, QString ( "%1" ).arg ( pSubtitle->m_iSubtitleNumber ), pSubtitle->m_qsIso639, theUtils.iso639 ( pSubtitle->m_qsIso639, false ), QString ( "%1" ).arg ( pSubtitle->m_listOfSubtitles.count ( ) ) );
      }
    }
  }

  uiDialogMovie::timerEvent ( pEvent );
}

bool DialogMovie::sanityCheckSubtitleTrack ( int &iSubtitle, QString &qsLanguage )
{
  // This function will check the sourceFileEntry and all attached 
  // SourceFileInfos if the ubtitle track is aready in use.
  // If not this function will return and leave iSubtitle unchanged.
  // If it is in use the subtitle number will be changed.
  Utils theUtils;
  QString qsIso639 = theUtils.iso639 ( qsLanguage, true );
  SourceFileEntry *pEntry = m_pParentSourceFileEntry;
  SourceFileInfo  *pInfo;
  int t, iNewSubtitle;
  bool bFound = false;
  if ( pEntry ) {
    if ( pEntry->arraySubtitleEntries[ iSubtitle ].m_iSubtitleNumber == -1 )
      return true;  // All is well
    // The next step is to ensure that the current SourceFileInfo is
    // not the only one using this Subtitle
    for ( t=0; t<(int)pEntry->listFileInfos.count ( ); t++ ) {
      pInfo = pEntry->listFileInfos[t];
      if ( pInfo->qsFileName == m_sourceFileInfo.qsFileName )
	continue;
      if ( pInfo->arraySubtitles [ iSubtitle ] ) {
	bFound = true;
	break; // exit for - loop
      }
    }
    if ( !bFound )
      return true; // Okay the current subtitle is only used by the current SourceFileInfo ... No harm.

    // Find a proposed subtitle
    for ( iNewSubtitle=0; iNewSubtitle<MAX_SUBTITLES; iNewSubtitle++ ) {
      if ( ( pEntry->arraySubtitleEntries[iNewSubtitle].m_qsIso639  == qsIso639 ) ||
           ( pEntry->arraySubtitleEntries[iNewSubtitle].m_iSubtitleNumber == -1 ) ) {
        break;
      }
    }

    // In case the subtitle channel is alreay used we want to make sure the languages are the same
    if ( qsIso639 == pEntry->arraySubtitleEntries[iSubtitle].m_qsIso639 )  {
      return true;
    }
    if ( iNewSubtitle>MAX_SUBTITLES-1 ) {
      MessageBox::warning ( this, tr ( "Too many Subtitles." ), tr ( "Too many subtitles for the SourceFileEntry\n%1\nPlease remove a subtitle track first before trying to add a new one." ).arg ( pEntry->qsDisplayName ) );
      return false;
    }

    QString qsLang = theUtils.iso639 ( pEntry->arraySubtitleEntries[iSubtitle].m_qsIso639, false );
    if ( MessageBox::question ( this, tr ( "Subtitle track %1 already in use." ).arg ( iSubtitle ),
	   tr ( "Subtitle track %1 already in use for language [%2].\nProposing track %3 for language [%4] instead." ).arg ( iSubtitle ).arg ( qsLang ).arg ( iNewSubtitle ).arg ( qsLanguage ),
	   QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok ) {
      // Okay at this point we can change the subtitle number
      iSubtitle = iNewSubtitle;
      return true;
    }
  }
  return false;
}

void DialogMovie::slotDeleteSubtitle ( )
{
  QListViewItem *pItem = m_pListViewSubtitles->selectedItem ( );
  if ( pItem ) {
    bool       bOkay;
    int iSubtitleNumber = pItem->text ( 0 ).toInt ( &bOkay );
    if ( ! bOkay )
      return;

    deleteSubtitle ( iSubtitleNumber );
  }
}

void DialogMovie::deleteSubtitle ( int iSubtitleNumber )
{
  bool       bFound;
  Subtitles *pSubtitle;
  int t, i;
  for ( t=0; t<MAX_SUBTITLES; t++ ) {
    pSubtitle = m_sourceFileInfo.arraySubtitles [ t ];
    if ( pSubtitle && pSubtitle->m_iSubtitleNumber == iSubtitleNumber ) {
      // First set this to NULL to avoid this func being called from within.
      m_sourceFileInfo.arraySubtitles [ t ] = NULL;
      if ( pSubtitle->m_subtitleState == Subtitles::STATE_EXTRACTING ) {
	MediaCreator::unregisterFromMediaScanner ( &m_sourceFileInfo );
	m_pCheckCreateSubtitles->setChecked      ( false );
	m_pComboLanguage->setEnabled             ( false );
      }
      else if ( pSubtitle->m_subtitleState == Subtitles::STATE_META_INFO ) {
	m_pCheckCreateSubtitles->setChecked      ( false );
	m_pComboLanguage->setEnabled             ( false );
      }

      delete pSubtitle;
      break;
    }
  }
  // remove from m_pParentSourceFileEntry if this has been the last reference to this audio track.
  bFound = false;
  if ( m_pParentSourceFileEntry ) {
    for ( t=0; t<(int)m_pParentSourceFileEntry->listFileInfos.count ( ) && ( ! bFound ); t++ ) {
      for ( i=0; i<MAX_SUBTITLES && ( ! bFound ); i++ ) {
	pSubtitle = m_pParentSourceFileEntry->listFileInfos[t]->arraySubtitles[i];
	if ( pSubtitle && pSubtitle->m_iSubtitleNumber == iSubtitleNumber ) {
	  bFound = true;
	  break;
	}
      }
    }
    if ( ! bFound ) {
      m_pParentSourceFileEntry->arraySubtitleEntries[ iSubtitleNumber ].m_iSubtitleNumber = -1;
      m_pParentSourceFileEntry->arraySubtitleEntries[ iSubtitleNumber ].m_qsIso639        = QString ( );
    }
  }
  
  // And finally we remove the item from the ListView ...
  QListViewItem *pItem = m_pListViewSubtitles->firstChild ( );
  while ( pItem ) {
    if ( pItem->text ( 0 ).toInt ( ) == iSubtitleNumber ) {
      delete pItem;
      return;
    }
    pItem = pItem->nextSibling ( );
  }

  // Finally we select the first item there is ...
  m_pSelectItem = m_pListViewSubtitles->firstChild ( );
  QTimer::singleShot ( 10, this, SLOT ( slotSetSelectedItem ( ) ) );
}

void DialogMovie::slotSameAsMenuLength ( )
{
  bool bMenuLength = m_pCheckSameAsMenuLength->isChecked ( );
  m_pEditEnding2->setEnabled ( ! bMenuLength );
  if ( ! bMenuLength && m_pMovieObject )  {
    DVDMenu *pDVDMenu = m_pMovieObject->dvdMenu  ( );
    m_pMovieObject->setDuration ( pDVDMenu->getInterface ( )->timeDuration );
  }
  m_pEditEnding2->setText   ( maxEndTime (  ).toString  ( "hh:mm:ss.zzz" ) );
  m_pButtonLoop->setEnabled ( ! bMenuLength );

  if ( bMenuLength ) {
    // we should set the stopSlider and the duration of the MovieObject accordingly
  }
}

void DialogMovie::slotTransition ( )
{
  // m_iTransitionForAll; // -1==doNothing / 0=remove all transitions / 1=set all transitions
  if ( m_iTransitionForAll == 1 )  {
       m_iTransitionForAll = 0; // remove all transitions.
       m_pButtonTransition->setText ( tr ( "Set Transition" ) );
       return;
  }

  DialogButtonTrans dialog ( &m_allTransitions, m_listButtonTransitions  );
  if ( dialog.exec   ( ) ==  QDialog::Rejected )
       return;

  if ( dialog.getTransition ( ) )
       m_allTransitions   = *dialog.getTransition  ( );
  m_listButtonTransitions =  dialog.getEnabledList ( );
  if ( m_listButtonTransitions.size ( ) > 0 )  {
       m_pButtonTransition->setText ( tr ( "Unset Transition" ) );
       m_iTransitionForAll = 1; // Set transitions
  }
  else
       m_iTransitionForAll = -1; // do Nothing

}

void DialogMovie::slotMenuLoop ( )
{
  // The user wants the menu video to loop.
  // So we need to
  if ( m_pCheckLoop->isChecked ( ) )  {
    // Gray out Pause after and set to '0'
    m_pSpinBoxPause->setEnabled ( false );
    m_pSpinBoxPause->setValue   ( 0 );
    // Gray out Post command and fill in "Loop"
    m_pComboPostCommand->setEnabled     (  false );
    m_pComboPostCommand->setCurrentText ( "Loop" );
  }
  else  {
    // Enable Pause after and set to '-1'
    m_pSpinBoxPause->setEnabled ( true );
    m_pSpinBoxPause->setValue   (  -1  );
    // Gray out Post command and fill in "Loop"
    m_pComboPostCommand->setEnabled     ( true );
    m_pComboPostCommand->setCurrentText ( " jump vmgm menu 1; " );
  }
}

void DialogMovie::slotLoop ( )
{
  if ( m_pButtonLoop->text ( ) ==  tr ( "Loop" ) )
       m_pButtonLoop->setText ( tr ( "Stretch" ) );
  else if ( m_pButtonLoop->text ( ) == tr ( "Stretch" ) )
       m_pButtonLoop->setText ( tr ( "Stop" ) );
  else
       m_pButtonLoop->setText ( tr ( "Loop" ) );
}

QTime DialogMovie::maxEndTime ( )
{
  QTime movieTime, endingTime, startTime, duration, zeroTime;
  // Only used with MovieObject
  if ( ! m_pMovieObject )
    return endingTime;

  DVDMenu *pDVDMenu = m_pMovieObject->dvdMenu  ( );
  movieTime = zeroTime.addMSecs ( m_iMovieLength );
  startTime = QTime::fromString ( m_pEditStarting2->text ( ) );
  duration  = m_pMovieObject->duration ( );
  if ( ! pDVDMenu )
    return movieTime;

  // if the duration of the movie exceeds the length of the DVDMenu, we'll have to cut back.
  if ( ( m_pCheckSameAsMenuLength->isChecked ( ) ) ||
       ( duration > pDVDMenu->getInterface ( )->timeDuration ) )
         duration = pDVDMenu->getInterface ( )->timeDuration;

  endingTime = m_pMovieObject->offset    ( ).addMSecs ( zeroTime.msecsTo ( duration ) );
  endingTime = endingTime.addMSecs ( zeroTime.msecsTo ( startTime ) );
  // Now that we have the theoretical end time let us check if the movieLength is long enough
  if ( endingTime > movieTime )
       endingTime = movieTime;

  return endingTime;
}

QTime DialogMovie::duration ( )
{
  QTime duration, startTime, endTime;
  if ( ! m_pMovieObject )
    return duration;

  startTime = QTime::fromString ( m_pEditStarting2->text ( ) );
  endTime   = QTime::fromString ( m_pEditEnding2->text   ( ) );
  duration  = duration.addMSecs ( startTime.msecsTo  ( endTime ) );
  return duration;
}

void DialogMovie::slotCheckStart ( )
{
  // This function is only called after m_pEditStarting2 lost focus
  if ( ! m_pMovieObject )
    return;

  bool bEnable = false;
  DVDMenu *pDVDMenu = m_pMovieObject->dvdMenu  ( );
  if ( m_pCheckSameAsMenuLength->isChecked ( ) )  {
    QTime zeroTime;
    QTime startTime = QTime::fromString    ( m_pEditStarting2->text ( ) );
    QTime endTime = pDVDMenu->getInterface ( )->timeDuration;
    QTime maxTime = maxEndTime ( );
    if  ( endTime > maxTime )
          endTime = maxTime;

    endTime = endTime.addMSecs ( zeroTime.msecsTo ( startTime ) );
    if  ( endTime > maxTime )  {
          // Exception handling, set new end / start times based on max possible range.
          QTime duration;
          duration  = duration.addMSecs ( startTime.msecsTo ( endTime ) );
          endTime   = maxTime;
          startTime = endTime.addMSecs ( duration.msecsTo ( zeroTime ) );
          m_pEditStarting2->setText ( startTime.toString ( "hh:mm:ss.zzz" ) );
    }
    m_pEditEnding2->setText ( endTime.toString ( "hh:mm:ss.zzz" ) );
  }
  else  {
    // Here we have to ensure the start time is not > the end time.
    QTime startTime = QTime::fromString    ( m_pEditStarting2->text ( ) );
    QTime endTime   = QTime::fromString    ( m_pEditEnding2->text   ( ) );
    if ( startTime > endTime )  {
         startTime = endTime;
      startTime = startTime.addSecs ( -1 );
      m_pEditStarting2->setText ( startTime.toString ( "hh:mm:ss.zzz" ) );
    }
    if ( duration ( ) < pDVDMenu->getInterface ( )->timeDuration )
         bEnable   =    true;
  }
  setStartStop ( true );
  m_pButtonLoop->setEnabled ( bEnable );
}

void DialogMovie::slotCheckEnd ( )
{
  // Should only be called after m_pEditStarting2 lost focus
  if ( ! m_pMovieObject )
    return;

  bool bEnable  = false;
  QTime maxTime = maxEndTime ( );
  QTime newTime = QTime::fromString ( m_pEditEnding2->text ( ) );
  if   ( newTime.isValid ( ) )  {
    if ( newTime > maxTime )
         newTime = maxTime; 
  }
  else
    newTime = maxTime;

  if ( ! m_pCheckSameAsMenuLength->isChecked    ( ) )  {
    DVDMenu *pDVDMenu = m_pMovieObject->dvdMenu ( );
    if ( duration ( ) < pDVDMenu->getInterface  ( )->timeDuration )
         bEnable   =    true;
  }

  m_pEditEnding2->setText ( newTime.toString ( "hh:mm:ss.zzz" ) );
  setStartStop ( false );
  m_pButtonLoop->setEnabled ( bEnable );
}

void DialogMovie::slotSetSelectedItem ( )
{
  // Called from the timer. Else if set directly in a callback function it won't select the right thing.
  m_pListViewAudio->clearSelection ( );
  if ( m_pSelectItem ) {
    m_pSelectItem->setSelected ( true );
    m_pListViewAudio->setCurrentItem ( m_pSelectItem );
    m_pListViewSubtitles->setCurrentItem ( m_pSelectItem );
  }
  m_pSelectItem = NULL;
}

void DialogMovie::slotSetStartStop ()
{
	int iStarting, iEnding;
	QTime      zeroTime;
	iStarting = 0;
	iEnding = m_iMovieLength;

	if (m_pDVDMenu)	{
		iStarting = zeroTime.msecsTo (m_pDVDMenu->getInterface()->timeOffset);
		iEnding   = iStarting + zeroTime.msecsTo (m_pDVDMenu->getInterface()->timeDuration);
	}
	else if (m_pMovieObject)	{
		iStarting = zeroTime.msecsTo (m_pMovieObject->offset()); 
		iEnding   = iStarting + zeroTime.msecsTo(m_pMovieObject->duration());
	}
	else if (m_sourceFileInfo.pTranscodeInterface)	{
		iStarting = m_sourceFileInfo.pTranscodeInterface->iStartingAt;
		iEnding   = m_sourceFileInfo.pTranscodeInterface->iEndingAt;
	}
	m_pStartStopControl->setStart ((float) iStarting / m_iMovieLength);
	m_pStartStopControl->setEnd   ((float) iEnding   / m_iMovieLength);
}

void DialogMovie::slotEditMediaInfo ()
{
  // This will open the media info dialog, where the user can modify the auto detected values (through Xine, VLC or MPlayer)
  DialogMediaInfo theDialog ( this );
  theDialog.initMe ( &m_sourceFileInfo );

  if ( theDialog.exec () == QDialog::Accepted ) {
    m_sourceFileInfo.qsRatio       = theDialog.m_pEditVideoAspect->text ( );
    m_sourceFileInfo.qsFPS         = theDialog.m_pEditVideoFPS->text    ( );
    m_sourceFileInfo.qsLength      = theDialog.m_pEditVideoLength->text ( );
    m_sourceFileInfo.qsVideoFormat = theDialog.m_pEditVideoFormat->text ( );
    m_sourceFileInfo.qsAudioFormat = theDialog.m_pEditAudioFormat->text ( );
    m_sourceFileInfo.qsBits        = theDialog.m_pEditAudioBits->text   ( );
    m_sourceFileInfo.qsBPS         = theDialog.m_pEditAudioBPS->text    ( );
    m_sourceFileInfo.qsSample      = theDialog.m_pEditAudioSample->text ( );
    m_pLabelVideoFormat->setText (QString ("%1(%2) %3Hz")
	          .arg ( m_sourceFileInfo.qsVideoFormat )
	          .arg ( m_sourceFileInfo.qsResolution  )
                  .arg ( m_sourceFileInfo.qsFPS         )
    );
    m_pLabelAudioFormat->setText (QString ("%1 %2bit %3")
		  .arg ( m_sourceFileInfo.qsAudioFormat )
		  .arg ( m_sourceFileInfo.qsBits        )
		  .arg ( m_sourceFileInfo.qsSample      )
    );
    setHeader ( &m_sourceFileInfo );
  }
}

SourceFileInfo *DialogMovie::sourceFileInfo ( )
{
  return &m_sourceFileInfo;
}

void DialogMovie::slotNewVolume ( int iNewVolume )
{
  // slider min = 0 slider max = 100
  float fNewVolume = (100 - iNewVolume) / 100.0;
  m_pMediaInterface->setVolume ( fNewVolume );
}

void DialogMovie::slotBlink ( )
{
  if ( transcodeEnabled ( ) )  {
    if ( m_pTextTranscoding->paletteForegroundColor    ( ) == QColor ( 0, 0, 0 ) )
         m_pTextTranscoding->setPaletteForegroundColor ( QColor ( COLOR_TRANSCODE ) );
    else
      m_pTextTranscoding->setPaletteForegroundColor ( QColor ( 0, 0, 0 ) );
    QTimer::singleShot ( 1000, this, SLOT ( slotBlink ( ) ) );
  }
}

bool DialogMovie::transcodeEnabled ()
{
  // If the background color of the title is set to -RED- then we are in the transcoding mode
  return ( m_pTextTitle->paletteBackgroundColor ( ) == QColor ( COLOR_TRANSCODE ) );
}

void DialogMovie::initTranscodeTab ()
{
	// DVD restrictions ...
	// NTSC : 720x480 704x480 352x480 352x240 * 29.97Hz
	// PAL  : 720x576 704x576 352x576 352x288 * 25Hz
	// Mpeg2: up to 9800 kbps
	// Mpeg1: 352x288 or 352x240 limited to 4:3 up to 1856 kbps
	// Audio bitrate : 32 .. 1536 kbps
	// Video bitrate : Mpeg2 max9800kbps Mpeg1 max 1856 kbps
	// Allow for muxing with this error.
	// If Warn: skipping sector, waiting for first VOBU, then simply re-multiplex. (check kdvdauthor)
	
	QFileInfo fileInfo ( m_sourceFileInfo.qsFileName );
	Utils theUtils;
	if ( fileInfo.extension ( ).lower ( ) != "dv" ) {
	  m_pCheckCreateSubtitles->setEnabled ( false );
	  m_pComboLanguage->setEnabled        ( false );
	}
	else {
	  QString qsCode, qsLang = "something";
	  int t=0;
	  while ( ! qsLang.isEmpty ( ) ) {
	    qsLang = theUtils.iso639 ( qsCode, false, t++ );
	    m_pComboLanguage->insertItem ( qsLang );
	  }
	  m_pComboLanguage->setCurrentText ( "English" );
	}
	// Next step is to set the check (or not)
	Subtitles *pSubtitle;
	int t;
	bool bSetCheck = false;
	for ( t=0; t<MAX_SUBTITLES; t++ ) {
	  pSubtitle = m_sourceFileInfo.arraySubtitles [ t ];
	  if ( ! pSubtitle )
	    continue;
	  if ( ( pSubtitle->m_subtitleState == Subtitles::STATE_META_INFO  )  || 
	       ( pSubtitle->m_subtitleState == Subtitles::STATE_EXTRACTING ) )  {
	    bSetCheck = true;
	    break;
	  }
	}
	m_pCheckCreateSubtitles->setChecked ( bSetCheck );

	if (!m_sourceFileInfo.pTranscodeInterface) {
	  QString qsDummy;
	  if ( m_sourceFileInfo.qsVideoFormat.lower ( ) == "pal" ) {
	    m_pComboVideoOut->setCurrentText ( "PAL" );
	    slotVideoOutChanged ( qsDummy );
	  }
	  return;
	}

	m_sourceFileInfo.pTranscodeInterface->qsVideoFormat.remove ( "Keep " );
	m_sourceFileInfo.pTranscodeInterface->qsVideoType.remove   ( "Keep " );
	m_sourceFileInfo.pTranscodeInterface->qsResolution.remove  ( "Keep " );
	m_sourceFileInfo.pTranscodeInterface->qsRatio.remove       ( "Keep " );
	m_sourceFileInfo.pTranscodeInterface->qsAudioType.remove   ( "Keep " );

	m_pComboVideoOut->insertItem        (QString ("Keep %1").arg(m_sourceFileInfo.pTranscodeInterface->qsVideoFormat), 0);
	m_pComboVideoType->insertItem       (QString ("Keep %1").arg(m_sourceFileInfo.pTranscodeInterface->qsVideoType  ), 0);
	m_pComboVideoResolution->insertItem (QString ("Keep %1").arg(m_sourceFileInfo.pTranscodeInterface->qsResolution ), 0);
	if (m_sourceFileInfo.pTranscodeInterface->iVideoBitrate < 0)
		m_sourceFileInfo.pTranscodeInterface->iVideoBitrate *= -1;
	m_pComboVideoBitrate->insertItem    (QString ("Keep %1").arg(theUtils.longToNorm(m_sourceFileInfo.pTranscodeInterface->iVideoBitrate) + QString ("bps")), 0);
	if (m_sourceFileInfo.pTranscodeInterface->fFrameRate < 0.0)
		m_sourceFileInfo.pTranscodeInterface->fFrameRate *= -1.0;
	m_pComboVideoRate->insertItem       (QString ("Keep %1").arg(m_sourceFileInfo.pTranscodeInterface->fFrameRate), 0);
	m_pComboVideoAspect->insertItem     (QString ("Keep %1").arg(m_sourceFileInfo.pTranscodeInterface->qsRatio), 0);
	
	m_pComboAudioOut->insertItem        ("Keep Original", 0);
	m_pComboAudioType->insertItem       (QString ("Keep %1").arg(m_sourceFileInfo.pTranscodeInterface->qsAudioType), 0);

	if (m_sourceFileInfo.pTranscodeInterface->iAudioBitrate < 0)
		m_sourceFileInfo.pTranscodeInterface->iAudioBitrate *= -1;
	m_pComboAudioBitrate->insertItem    (QString ("Keep %1").arg(theUtils.longToNorm(m_sourceFileInfo.pTranscodeInterface->iAudioBitrate) + QString ("bps")), 0);
	if (m_sourceFileInfo.pTranscodeInterface->iSample < 0)
		m_sourceFileInfo.pTranscodeInterface->iSample *= -1;
	m_pComboAudioSampleRate->insertItem (QString ("Keep %1").arg(m_sourceFileInfo.pTranscodeInterface->iSample), 0);

	// And make the transcode - tab visible again ...
	slotTranscode ();
}

void DialogMovie::slotSubLangChanged ( bool bToggled )
{
  m_pComboLanguage->setEnabled ( bToggled );
  QString qsCommand;

  // invoke dv2sub to create srt and attach it to m_sourceFileInfo
  try {
    m_sourceFileInfo.bMetaSubtitles = bToggled;
    if ( bToggled ) {
      QString qsLang, qsIso639, qsTool;
      Utils   theUtils;
      qsTool = theUtils.getToolPath ( QString ( "dv2sub" ) );
      if ( qsTool.length ( ) < 6 )  
	MessageBox::warning ( this, tr ( "Warnig, tool not found." ), tr ( "I can not find the required tool dv2sub.\nPlease install it first ( http://dv2sub.sf.net )." ) );

      qsLang   = m_pComboLanguage->currentText  ( );
      qsIso639 = theUtils.iso639   ( qsLang, true );
      Subtitles::generateSubtitles ( this, &m_sourceFileInfo, qsIso639 );
    }
    else { // bToggled = false ...
      Subtitles *pSubtitle;
      int t;
      for ( t=0; t<MAX_SUBTITLES; t++ ) {
	pSubtitle = m_sourceFileInfo.arraySubtitles [ t ];
	if ( ! pSubtitle )
	  continue;
	if ( pSubtitle->m_subtitleState == Subtitles::STATE_META_INFO ) {
	  deleteSubtitle ( t );
	  break;
	}
	else if ( pSubtitle->m_subtitleState == Subtitles::STATE_EXTRACTING ) {
	  MessageBox::warning ( this, tr ( "Warnig, too early." ), tr ( "Subtitles are still being extracted. Please give some time and try again." ) );
	  m_pCheckCreateSubtitles->setChecked ( true ); // make sure does not cause an endless loop ...
	  return;
	}
      }
    }
  }
  catch ( ... ) {
    MessageBox::warning ( this, tr ( "Subtitle creation failed." ), tr ( "Could not create subtitles from source DV material<P>You can try invoking the following command manually : <BR><B>%1</B><P>" ).arg ( qsCommand ) );
    m_pComboLanguage->setEnabled ( false );
    m_pCheckCreateSubtitles->setChecked ( false );
  }
}

void DialogMovie::slotVideoOutChanged (const QString &)
{
	// NTSC : 720x480 704x480 352x480 352x240 * 29.97Hz
	// PAL  : 720x576 704x576 352x576 352x288 * 25Hz
	m_pComboVideoRate->clear ();
	m_pComboVideoAspect->clear ();
	m_pComboVideoResolution->clear ();
//	QString qsCurrentResolution = m_pComboVideoResolution->currentText ();
	QString qsNewString = m_pComboVideoOut->currentText ().upper();

	MediaInfo *pMediaInfo = NULL;
	if (m_pMediaInterface)
		m_pMediaInterface->getMediaInfo ();
	if (pMediaInfo)	{
		m_pComboVideoResolution->insertItem (QString ("Keep %1").arg(pMediaInfo->getResolutionString()));
		m_pComboVideoAspect->insertItem     (QString ("Keep %1").arg(pMediaInfo->getRatio()));
		m_pComboVideoRate->insertItem       (QString ("Keep %1").arg(pMediaInfo->getFPS()));
	}
	if ( (qsNewString == "PAL") || (qsNewString == "CUSTOM") )	{
		if (m_pComboVideoType->currentText () != "Mpeg 1")	{
			m_pComboVideoResolution->insertItem ("720x576");
			m_pComboVideoResolution->insertItem ("704x576");
			m_pComboVideoResolution->insertItem ("352x576");
		}
		m_pComboVideoResolution->insertItem ("352x288");
		m_pComboVideoRate->insertItem ("25");
	}
	if ( (qsNewString == "NTSC") || (qsNewString == "CUSTOM") )	{
		if (m_pComboVideoType->currentText () != "Mpeg 1")	{
			m_pComboVideoResolution->insertItem ("720x480");
			m_pComboVideoResolution->insertItem ("704x480");
			m_pComboVideoResolution->insertItem ("352x480");
		}
		m_pComboVideoResolution->insertItem ("352x240");
		m_pComboVideoRate->insertItem ("29.97");
	}

	m_pComboVideoAspect->insertItem ("4:3");
	m_pComboVideoAspect->insertItem ("1:1");
	if (m_pComboVideoType->currentText () != "Mpeg 1")	{
		m_pComboVideoAspect->insertItem ("16:9");
		m_pComboVideoAspect->insertItem ("2.21:1");
	}
}

void DialogMovie::slotVideoTypeChanged (const QString &)
{
	slotVideoOutChanged (QString ());
}

void DialogMovie::slotVideoResolutionChanged (const QString &)
{
}

void DialogMovie::slotVideoRateChanged (const QString &)
{
}

void DialogMovie::slotVideoAspectChanged (const QString &)
{
}

void DialogMovie::slotVideoBitrateChanged (const QString &)
{
}

void DialogMovie::slotAudioOutChanged (const QString &)
{
}

void DialogMovie::slotAudioTypeChanged (const QString &)
{
}

void DialogMovie::slotAudioBitrateChanged (const QString &)
{
}

void DialogMovie::slotAddColorKey ()
{
	float fDelta = m_pEditCK->text().toFloat();
	//QListViewItem *pItem = 
	new ListViewColorItem (m_pListViewCK, m_pButtonCK->paletteBackgroundColor(), QString (m_pButtonCK->paletteBackgroundColor().name ()), QString ("%1").arg(fDelta) );
}

void DialogMovie::slotDelColorKey ()
{
	QListViewItem *pItem = m_pListViewCK->selectedItem ();
	// First we check if anything has been selected.
	if ( ! pItem )
		return;
	delete pItem;
}

void DialogMovie::slotBrowseColorKey ()
{
  QColor theColor = QColorDialog::getColor ( m_pButtonCK->paletteBackgroundColor ( ) );
  m_pButtonCK->setPaletteBackgroundColor   ( theColor );
}

void DialogMovie::slotAutoChapters ()
{
	uint t, i, iDeltaStep, iStarting, iEnding, iChapter, iPreviousChapter;
	int iTotalLength, iNumberOfNewChapters;
	QString qsTimeString;
	Utils theUtil;
	// Here we read in the list of currently generated chapters
	// then we convert them into milliseconds, and store them in an array
	// And finally we generate the chapters, sort the array and put it back into the
	// m_pListBoxChapters, and m_sourceFileInfo - structures.
	int *pArrayExistingChapters = new int[m_pListBoxChapters->count()];
	for (t=0;t<m_pListBoxChapters->count(); t++)	{
		qsTimeString = m_pListBoxChapters->text(t);
		pArrayExistingChapters[t] = theUtil.getMsFromString (qsTimeString);
	}
	iStarting  = theUtil.getMsFromString ( m_pEditStarting1->text ( ) );
	iEnding    = theUtil.getMsFromString ( m_pEditEnding1->text   ( ) );
	iDeltaStep = theUtil.getMsFromString ( m_pEditEvery->text     ( ) );
	iTotalLength = (int)(iEnding - iStarting);
	// a DeltaStep of 0 would generate infinite number of chapters
	if ( ( iDeltaStep < 1 ) || ( iTotalLength < 1 ) ) {
	  delete []pArrayExistingChapters;
	  return;
	}
	if ( iDeltaStep > (uint)iTotalLength )
	     iDeltaStep = iTotalLength;
	iNumberOfNewChapters = (int)((float)iTotalLength / (float)iDeltaStep) + 1;

	QValueList<int> listAllChapters;
	// Okay this is the worst sort algo around but we would'nt sort thousands of chapters, now would we ???
	i = 0;
	for (t=0;t<(uint)iNumberOfNewChapters;t++)	{
		iChapter = iStarting + t * iDeltaStep;
		for (i=0;i<m_pListBoxChapters->count();i++)	{
			// If we find an entry which is the same as a calculated chapter we should skip it ...
		  if (pArrayExistingChapters[i] == (int)iChapter)
				pArrayExistingChapters[i] = -1;
			// If we find an entry which is smaller but not 0, then we should include them ...
		  else if ( ( pArrayExistingChapters[i] < (int)iChapter ) && 
				  ( pArrayExistingChapters[i] >       -1 ) )  {
				listAllChapters.append ( pArrayExistingChapters[i] );
				// Here we ensure the next time this entry is higher
				pArrayExistingChapters[i] = -1;
			}
		}
		listAllChapters.append (iChapter);
	}

	m_pListBoxChapters->clear ();
	iChapter = iPreviousChapter = 0;
	for (t=0;t<listAllChapters.count();t++)	{
		iChapter = listAllChapters[t];
		if (iChapter >= iPreviousChapter)
			m_pListBoxChapters->insertItem(theUtil.getStringFromMs (iChapter));
		iPreviousChapter = iChapter;
	}

	delete []pArrayExistingChapters;
}

void DialogMovie::slotAnimation ()
{
	// This function gets the Animation Dialog
	// Within this dialog, you can create a script
	// (or hardcode) Attributes of the object.
	// Before rendering the menu the script will 
	// get executed and all data sent to stdout 
	// will be captured in the data file, wich 
	// will provide the data for the animation.	
	QString qsEmpty, qsAnimation;
	int iType;
	DialogAnimation dialog ( this );
	if ( m_pMovieObject )	{
		dialog.initMe ( m_pMovieObject->animation(), m_pMovieObject->dvdMenu()->framesToRender(), m_pMovieObject->dvdMenu()->fps(), DialogAnimation::TypeMovie );
		if ( dialog.exec () == QDialog::Accepted )	{
			qsAnimation = dialog.string ();
			if (qsAnimation.length () < 5)
				qsAnimation = qsEmpty;
			m_pMovieObject->setAnimation ( qsAnimation );
		}
	}
	else if (m_pDVDMenu)	{
		iType = DialogAnimation::TypeImage;
		if (m_pEditStarting2->isEnabled ())
			iType = DialogAnimation::TypeMovie;
		dialog.initMe ( m_pDVDMenu->getInterface()->qsAnimation, m_pDVDMenu->framesToRender (), m_pDVDMenu->fps (), iType );
		if ( dialog.exec () == QDialog::Accepted )	{
			qsAnimation = dialog.string ();
			if (qsAnimation.length () < 5)
				qsAnimation = qsEmpty;
			m_pDVDMenu->getInterface()->qsAnimation = qsAnimation;
		}
	}
}

void DialogMovie::slotSizeDialog ( )
{
  if ( ! m_pDVDMenu )
    return;
  m_pDVDMenu->changeSize ( );
}

void DialogMovie::slotImportChapter ( )
{
  Import::Chapter theImporter;
  if ( theImporter.import ( ) ) {
    uint t;
    QStringList list = theImporter.getChapterList ( );
    for ( t=0; t<list.count ( ); t++ ) 
      addChapter ( list[t] );
  }
}

void DialogMovie::addChapter ( QString &qsChapter )
{
  // Here we add a chapter in the right space,
  // but only if this chapter does not already exists ...
  Utils theUtil;
  int iChapter, iAddChapter;
  uint t;
  iChapter = 0;
  iAddChapter = theUtil.getMsFromString  ( qsChapter ); //m_pEditAdd->text() );
  for ( t=0; t<m_pListBoxChapters->count ( ); t++ )  {
    iChapter = theUtil.getMsFromString   ( m_pListBoxChapters->text ( t ) );
    if ( iAddChapter == iChapter )
      break;
    else if ( iAddChapter < iChapter )  {
      m_pListBoxChapters->insertItem ( theUtil.getStringFromMs ( iAddChapter ), t );
      break;
    }
  }
  // and in case the Chpater is to be added at the end ...
  if ( iAddChapter > iChapter )
    m_pListBoxChapters->insertItem ( theUtil.getStringFromMs ( iAddChapter ) );
}

void DialogMovie::slotAddChapter ( )
{
  QString qsChapter = m_pEditAdd->text ( );
  addChapter ( qsChapter );
}

void DialogMovie::slotDelChapters ()
{
	// This function will remove all chapters which are currently selected in m_pListBoxChapters
	uint t;
	QValueList<QListBoxItem *> listItems;
	for (t=0;t<m_pListBoxChapters->count();t++)	{
		if (m_pListBoxChapters->isSelected (t))
			listItems.append (m_pListBoxChapters->item(t));
	}
	for (t=0;t<listItems.count();t++)
			delete listItems[t];
}

void DialogMovie::slotCurrentChanged (QListBoxItem *pItem)
{
  uint t, iCount;
  iCount = 0;
  // we first count the number of selected chapters
  for  ( t=0; t<m_pListBoxChapters->count ( ); t++ )  {
    if ( m_pListBoxChapters->isSelected  ( t ) )
      iCount ++;
  }
  if ( iCount != 1 )
    return;
  // Last we jump to the position
  if ( m_pListBoxChapters->isSelected ( pItem ) )  {
    int iChapter = 0;
    QTime chapterTime, zeroTime;
    QString qsChapter = m_pListBoxChapters->currentText ();

    chapterTime = QTime::fromString  (   qsChapter );
    iChapter = zeroTime.secsTo       ( chapterTime );
    m_pMediaInterface->setPositionByTime ( iChapter );
    if ( ! m_pMediaInterface->isPlaying  ( ) )
      slotPlay ( );

    m_pMediaInterface->setPositionByTime ( iChapter );
    if ( m_pMediaInterface->isPlaying    ( ) )
      slotPlay ( );
  }
}

void DialogMovie::slotTranscode ()
{
	if (m_pTranscodeTab)	{
		m_pTabWidget->addTab ( m_pTranscodeTab, tr ("Transcoding") );
		m_pTranscodeTab = NULL;
		m_pTabWidget->setCurrentPage                  ( 3 );
		m_pButtonTranscode->setText                   ( tr ("<<< Transcode") );
		m_pTextTitle->setBackgroundColor              ( QColor ( COLOR_TRANSCODE ) );
		m_pTextTranscoding->setBackgroundColor        ( QColor ( COLOR_TRANSCODE ) );
		m_pTextTranscoding->setPaletteBackgroundColor ( QColor ( COLOR_TRANSCODE ) );
		m_pFrameHeader->setPaletteBackgroundColor     ( QColor ( COLOR_TRANSCODE ) );
		QTimer::singleShot       ( 1,  this,  SLOT    ( slotBlink ( ) ) );
		m_pButtonEncodeNow->show ( );
	}
	else	{
		m_pTranscodeTab = m_pTabWidget->page          ( m_pTabWidget->count ( ) - 1 );
		m_pTabWidget->removePage                      ( m_pTranscodeTab );
		m_pButtonTranscode->setText                   ( tr ("Transcode >>>") );
		m_pTextTitle->setBackgroundColor              ( QColor ( COLOR_NOTRANSCODE ) );
		m_pTextTranscoding->setBackgroundColor        ( QColor ( COLOR_NOTRANSCODE ) );
		m_pTextTranscoding->setPaletteForegroundColor ( QColor ( COLOR_NOTRANSCODE ) );
		m_pFrameHeader->setPaletteBackgroundColor     ( QColor ( COLOR_NOTRANSCODE ) );
		m_pButtonEncodeNow->hide      (      );
		m_pStartStopControl->setStart ( 0.0f );
		m_pStartStopControl->setEnd   ( 1.0f );
	}
}

void DialogMovie::slotEncodeNow ()
{
	MessageBox::warning (NULL, tr("Warning"), tr("Not yet implemented"), QMessageBox::Ok, QMessageBox::NoButton);
}

void DialogMovie::slotWidth()
{
	if (m_pCheckAspect->isChecked())	{
		float fAspect = (float)m_rectGeometry.height() / (float)m_rectGeometry.width();
		int iWidth = m_pEditWidth->text().toInt();
		m_pEditHeight->setText (QString ("%1").arg((int)(fAspect * iWidth)));
	}
}

void DialogMovie::slotHeight()
{
	if (m_pCheckAspect->isChecked())	{
		float fAspect = (float)m_rectGeometry.width() / (float)m_rectGeometry.height();
		int iHeight = m_pEditHeight->text().toInt();
		m_pEditWidth->setText (QString ("%1").arg((int)(fAspect * iHeight)));
	}
}

void DialogMovie::slotPlay  ()
{
	if (m_pMediaInterface)	{
		bool bEnable = true;
		if      (m_pMediaInterface->isPaused ())
			 m_pMediaInterface->play ();
		else if (m_pMediaInterface->isPlaying())
			 m_pMediaInterface->pause();
		else
			m_pMediaInterface->playMRL(m_qsFileName);
	
		if ( m_pMediaInterface->isPaused ( ) )  {
			m_pButtonPlay->setText (tr("Play"));
			bEnable = false;
		}
		else
			m_pButtonPlay->setText (tr("Pause"));
	
		m_pButtonStart->setEnabled ( bEnable );
		m_pButtonEnd  ->setEnabled ( bEnable );
	}
}

void DialogMovie::slotStop  ()
{
	if (m_pMediaInterface)	{
		// In case the state is paused we should get back to play mode before stopping
		if (m_pMediaInterface->isPaused ())
			m_pMediaInterface->play ();
		m_pMediaInterface->stop ();
		// The button should display "Play" now
		m_pButtonPlay->setText (tr("Play"));
		// and then logically we should put the screen to the beginnning.
		m_pMediaInterface->getScreenshot ( );
		m_pButtonStart->setEnabled ( false );
		m_pButtonEnd  ->setEnabled ( false );
	}
}

void DialogMovie::slotSetThumbnail ()
{
  // The user presses SetAsThumbnail ...
  Utils theUtils;
  QRegExp rx ( "<[^>]*>" );
  QString qsCurrentTime =  m_pLabelCurrentPos->text ( );
  qsCurrentTime.replace ( rx, "" ); // = rx.cap ( 0 );

  long  iMSecOffset     = theUtils.getMsFromString ( qsCurrentTime );
  if  ( m_pEditStarting1 ) // indicates that we are coming from the Sourcetoolbar-SourceFileInfo
    emit ( signalSetThumbnail ( iMSecOffset ) ); // calls SourceToolbar::slotSetThumbnail ( long )

  m_sourceFileInfo.iMSecPreview = iMSecOffset;
}

void DialogMovie::slotStart ()
{	// This function will set the Start offset of the video clip
	if (m_qsPosition.length () < 8)
		m_pEditStarting1->setText (QString ("0") + m_qsPosition + QString (".000"));
	else
		m_pEditStarting1->setText (m_qsPosition);
	// But we also need to make sure that the start is not set before the end ...
	setStartStop (true);
}

void DialogMovie::slotEnd   ()
{
	if (m_qsPosition.length () < 8)
		m_pEditEnding1->setText (QString ("0") + m_qsPosition + QString (".000"));
	else
		m_pEditEnding1->setText (m_qsPosition);
	// But we also need to make sure that the end is not set before the start ...
	setStartStop (false);
}

void DialogMovie::setStartStop (bool bStart)
{
	QTime zeroTime;
	QTime startTime = QTime::fromString (m_pEditStarting1->text());
	QTime endTime   = QTime::fromString (m_pEditEnding1  ->text());
	if (endTime < startTime)	{
		if (bStart)
			m_pEditEnding1->setText (m_pEditStarting1->text());
		else
			m_pEditStarting1->setText (m_pEditEnding1->text());
	}
	// and last but not least we should set the slider controls ...
	int iStartTime = zeroTime.msecsTo (startTime);	
	int iEndTime   = zeroTime.msecsTo   (endTime);	
	float fPercentage = (float)iStartTime / (float)m_iMovieLength;
	m_pStartStopControl->setStart (fPercentage);
	fPercentage = (float)iEndTime / (float)m_iMovieLength;
	m_pStartStopControl->setEnd   (fPercentage);
	if ( (iStartTime > 10) || (fPercentage < 0.9999) )	{
		if ( (m_pButtonTranscode) && ( ! transcodeEnabled ()) )
			slotTranscode ();
	}
}

void DialogMovie::slotSliderReleased ( bool bStartSlider )
{
  // if the start slider was released AND the MediaEngine is NOT playing, then we 
  // should create a new preview in the MediaInterface - window.
  if ( bStartSlider ) {
    if ( ! m_pMediaInterface->isPlaying ( ) ) {
      m_pLabelCurrentPos->setText ( m_pEditStarting1->text ( ) );
      // The user presses SetAsThumbnail ...
      Utils theUtils;
      QRegExp rx ( "<[^>]*>" );
      QString qsCurrentTime =  m_pLabelCurrentPos->text ( );
      qsCurrentTime.replace ( rx, "" );

      long  iMSecOffset     = theUtils.getMsFromString ( qsCurrentTime );
      m_pMediaInterface->setScreenshot ( iMSecOffset );
    }
  }
}

void DialogMovie::slotSliderValues (float fStart, float fEnd)
{
  // This function is called when the user uses the slider controls (values in percentage)
  QTime startTime;
  QTime endTime;
  QString qsFormat ("hh:mm:ss.zzz");
  startTime = startTime.addMSecs ( (int)(fStart * m_iMovieLength ) );
  endTime   = endTime.addMSecs   ( (int)(fEnd   * m_iMovieLength ) );
  if ( ( ! m_pMovieObject ) && ( ! m_pDVDMenu  ) )
         m_pEditAdd->setText ( startTime.toString ( qsFormat ) );
  m_pEditStarting1 ->setText ( startTime.toString ( qsFormat ) );
  m_pEditEnding1   ->setText ( endTime.toString   ( qsFormat ) );

  if ( m_pMovieObject )  {
    DVDMenu *pDVDMenu = m_pMovieObject->dvdMenu ( );
//    QTime zeroTime;
    bool bEnable = true;
    QColor theColor = m_pEditX->paletteBackgroundColor ( ); // default background color
    if ( duration ( ) > pDVDMenu->getInterface ( )->timeDuration )  {
      theColor = QColor ( 255, 150, 150 );
      bEnable  = false;
    }
    m_pCheckSameAsMenuLength->setEnabled ( true );
    m_pCheckSameAsMenuLength->setChecked ( ! bEnable );
    m_pButtonLoop->setEnabled ( bEnable );
    m_pEditEnding2->setPaletteBackgroundColor ( theColor );
    m_pEditEnding2->setEnabled ( bEnable );
  }

  // For now we disable auto transcoding of only the start slider is moved ...
  //	if ( ( fStart > 0.0001 ) || ( fEnd < 0.9999) )	{
  if ( fEnd < 0.995 ){
    if ( ( m_pButtonTranscode ) && ( ! transcodeEnabled ( ) ) )
      slotTranscode ( );
  }
}

void DialogMovie::slotNewPosition(int, const QString &qsPosition)
{
	m_qsPosition = qsPosition;
	if (m_qsPosition.length() == 8)
		m_qsPosition += ".000";

	m_pLabelCurrentPos->setText ("<p align=\"center\">" + m_qsPosition + "</p>");
	if ( ( ! m_pDVDMenu ) && ( ! m_pMovieObject ) )	// if this is a BackgroundMovie/Image then this button does not exist.
		m_pEditAdd->setText (m_qsPosition);
	if (m_iMovieLength == 0)
		return;
	QTime curTime = QTime::fromString(qsPosition);
	QTime zeroTime;
	int iCurTime = zeroTime.msecsTo (curTime);	
	float fPercentage = (float)iCurTime / (float)m_iMovieLength;
	m_pStartStopControl->setProgress (fPercentage);
}

QString DialogMovie::keepClean ( const QString &qsInput )
{
  QString qsReturn = qsInput;
  qsReturn.remove ( "Keep " );
  return  qsReturn;
}

TranscodeInterface *DialogMovie::checkRightAudioFormat ( QString &qsFileName )
{
  MediaInfo *pMediaInfo = MediaCreator::createInfo ( );
  if ( ! pMediaInfo )
    return NULL;
  pMediaInfo->setFileName ( qsFileName );
  QString qsAudioCodec = pMediaInfo->getCodec  ( false );
  QString qsSample     = pMediaInfo->getSampleString ( );
  QFileInfo fileInfo   ( qsFileName );
  QString qsExtension  = fileInfo.extension ( FALSE );
  if ( ( qsAudioCodec == "mp2" ) ||
       ( qsAudioCodec == "ac3" ) ||
       ( qsAudioCodec == "pcm" ) ||
       ( qsExtension  == "MP2" ) ||
       ( qsExtension  == "AC3" ) ||
       ( qsExtension  == "PCM" )  ) {
    // At this point we have one of the above
    if ( qsSample.find ( "48" ) != -1 )
      return NULL; // code and sample rate seem to be ok, no transcoding required.
  }

  TranscodeInterface *pTranscode = new TranscodeInterface;
  //pTranscode->qsTempFile = QString ( "%1/%2.mpeg2" ).arg ( theUtil.getTempPath ( fileInfo.baseName ( TRUE ) ) ).arg(fileInfo.baseName ( TRUE ) );

  pTranscode->qsAudioFormat = "Stereo"; //
  pTranscode->qsAudioType   = "mp2";    //
  pTranscode->iAudioBitrate = 192;      // 192kbps
  pTranscode->iSample       = 48000;    //
  pTranscode->bTranscoding  = false;    //
  return pTranscode;
}

void DialogMovie::applyTransitions ( )
{
  // m_iTransitionForAll; // -1==doNothing / 0=remove all transitions / 1=set all transitions
  if ( ( m_iTransitionForAll == -1 ) || ! m_pDVDMenu )
    return; // do nothing ...

  QString qsMenuName, qsName, qsTempPath;
  ButtonTransition transition = m_allTransitions;

  ButtonObject   *pButton = NULL;
  QValueList<ButtonObject *> list = m_pDVDMenu->getButtons ( );
  QValueList<ButtonObject *>::iterator it = list.begin ( );
  if ( m_iTransitionForAll == 0 )  {  // Remove all transitions.
    while  ( it != list.end ( ) )  {
      pButton = *it++;
      pButton->setTransition ( NULL );
    }
    return;
  }

  if ( m_listButtonTransitions.size ( ) < 1 )
    return;

  int   iIdx;
  Utils theUtils;
  qsMenuName = m_pDVDMenu->getInterface ( )->qsMenuName;
  qsTempPath = theUtils.getTempFile ( "" );
  while  ( it != list.end ( ) )   {
    pButton = *it++;

    iIdx = rand ( )%m_listButtonTransitions.size ( );
    transition.qsTransitionName = m_listButtonTransitions[iIdx];

    qsName = qsMenuName + "/" + pButton->name ( );
    transition.qsName = qsName;
    theUtils.recMkdir ( qsTempPath + qsName );
    qsName += "/transition.vob";

    transition.qsTransitionVideoFileName = qsTempPath + qsName; // E.g. "/tmp/TestProjec/Main VMGM/Button
    pButton->setTransition ( &transition );
  }
  m_pDVDMenu->slotUpdateStructure ( );
}

void DialogMovie::accept ( )
{
	uint      t;
	long      iBitrate, iTemp;
	float     fTemp;
	QFileInfo fileInfo;
	Utils     theUtils;
	QString   qsTemp, qsFormat ("hh:mm:ss.zzz");
	QTime     startingTime, endingTime, duration, zeroTime;

	if ( m_pDVDMenu )  {
	  CDVDMenuInterface *pInterface = m_pDVDMenu->getInterface   ( );
	  startingTime = QTime::fromString ( m_pEditStarting1->text  ( ) );
	  int iSubMenu = m_pSpinBoxTitle->value ( );
	  if ( ( ( iSubMenu == 0 ) ) && // Check that the selected SubMenuNumber is valid.
	       ( pInterface->qsMenuName != VMGM_LABEL ) ) {
	    if ( MessageBox::warning ( this, tr ( "Invalid SubMenu number" ), tr ( "Invalid SubMenu number\nDo you want to assign the menu to SubMenu number 1 instead ?" ), QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes )
	      iSubMenu =  1;
	    else
	      iSubMenu = -1;
	  }

	  endingTime   = QTime::fromString ( m_pEditEnding1->text ( ) );
	  if ( m_pSpinBoxPause->value ( ) == -1 )
	    pInterface->qsPause = "inf";
	  else 
	    pInterface->qsPause = QString ("%1").arg ( m_pSpinBoxPause->value  ( ) );
	  if ( ! m_pComboPreCommand->currentText ( ).isEmpty  ( ) )
	    pInterface->qsPre   = m_pComboPreCommand->currentText  ( );
	  if ( ! m_pComboPostCommand->currentText ( ).isEmpty ( ) )
	    pInterface->qsPost  = m_pComboPostCommand->currentText ( );

	  if ( pInterface->qsMovieFileName.isEmpty ( ) )
	       startingTime = QTime ( );
	  // Here we hande the start/stop time.
	  if ( startingTime.isValid ( ) )       {
	    pInterface->timeOffset = startingTime;
	    if ( endingTime.isValid  ( ) )       {
	      int iMSecs = startingTime.msecsTo ( endingTime );
	      duration   = duration.addMSecs    ( iMSecs     );
	      pInterface->timeDuration = duration;
	    }
	  }
	  if ( pInterface->bIsSubMenu )  {
	       pInterface->iMenu     = iSubMenu;
	       pInterface->iTitleset = m_pSpinBoxTitleset->value ( );
	  }
	  // Lastly we handle the Transition settings.
	  applyTransitions ( );
	}
	else if ( m_pMovieObject )	{
		// Here we handle MovieObjects. Check out if we have set Color Keying.
		ImageManipulator::colorKeying *pColorKey;
		ListViewColorItem *pItem;
		float  fDelta;
		Rgba   theColor;
		// First we should remove all entries in the color Key
		ImageManipulator *pMan= &m_pMovieObject->manipulator();
		for (t=0;t<pMan->listColorKeys.count();t++)
			delete pMan->listColorKeys[t];
		pMan->listColorKeys.clear();
		// And then we add whats currently in the widget.
		if ( m_pListViewCK->childCount() )	{
			pItem = (ListViewColorItem *)m_pListViewCK->firstChild ();
			while (pItem)	{
				theColor.fromString ( pItem->text ( 0 ) );  // The Color name is stored in the first text
				fDelta = pItem->text ( 1 ).toFloat ( );     // The delta value is stored in the second column.
				pColorKey = new ImageManipulator::colorKeying ( theColor.rgb ( ), fDelta );
				pMan->listColorKeys.append ( pColorKey );
				pItem = (ListViewColorItem *)pItem->itemBelow ( );
			}
		}
	}
	else if (m_pEditStarting1)	{// used as an indicator if we were coming from the SourceToolbar->SourceFileInfo
		startingTime = QTime::fromString ( m_pEditStarting1->text ( ) );
		endingTime   = QTime::fromString ( m_pEditEnding1->text   ( ) );
		m_sourceFileInfo.iPause         =  m_pSpinBoxPause->value ( );
		m_sourceFileInfo.iTitleset      =  m_pSpinBoxTitleset->value        ( );
		m_sourceFileInfo.qsPreCommand   =  m_pComboPreCommand ->currentText ( );
		m_sourceFileInfo.qsPostCommand  =  m_pComboPostCommand->currentText ( );
		m_sourceFileInfo.bAutotranscode =  false; // once the user clicks ok we don't want to change any transcoding settings any more.

		if ( transcodeEnabled ( ) )  {
		        Utils theUtils;
			if (  ! m_sourceFileInfo.pTranscodeInterface )
				m_sourceFileInfo.pTranscodeInterface = new TranscodeInterface;
			m_sourceFileInfo.pTranscodeInterface->qsVideoFormat = keepClean ( m_pComboVideoOut->currentText        ( ) );
			m_sourceFileInfo.pTranscodeInterface->qsVideoType   = keepClean ( m_pComboVideoType->currentText       ( ) );
			m_sourceFileInfo.pTranscodeInterface->qsResolution  = keepClean ( m_pComboVideoResolution->currentText ( ) );
			fileInfo.setFile ( m_sourceFileInfo.qsFileName );
			m_sourceFileInfo.pTranscodeInterface->qsTempFile = QString ( "%1/%2.mpeg2" ).arg (theUtils.getTempPath ( fileInfo.baseName ( TRUE ) ) ).arg(fileInfo.baseName ( TRUE ) );
			qsTemp   = keepClean  ( m_pComboVideoBitrate->currentText ( ) );
			iBitrate = theUtils.normToLong ( qsTemp );
			m_sourceFileInfo.pTranscodeInterface->iVideoBitrate = iBitrate;
			qsTemp   = keepClean ( m_pComboVideoRate->currentText ( ) );
			fTemp    = qsTemp.toFloat ( );
			m_sourceFileInfo.pTranscodeInterface->fFrameRate    = fTemp;
			m_sourceFileInfo.pTranscodeInterface->qsRatio       = keepClean ( m_pComboVideoAspect->currentText ( ) );
			m_sourceFileInfo.pTranscodeInterface->qsAudioFormat = keepClean ( m_pComboAudioOut->currentText    ( ) );
			m_sourceFileInfo.pTranscodeInterface->qsAudioType   = keepClean ( m_pComboAudioType->currentText   ( ) );
			qsTemp = keepClean ( m_pComboAudioBitrate->currentText ( ) );
			iBitrate =  theUtils.normToLong ( qsTemp );
			m_sourceFileInfo.pTranscodeInterface->iAudioBitrate = iBitrate;
			qsTemp = keepClean ( m_pComboAudioSampleRate->currentText ( ) );
			iTemp =  qsTemp.toInt();
			m_sourceFileInfo.pTranscodeInterface->iSample       = iTemp;
			m_sourceFileInfo.pTranscodeInterface->iStartingAt   = zeroTime.msecsTo ( startingTime );
			m_sourceFileInfo.pTranscodeInterface->iEndingAt     = zeroTime.msecsTo ( endingTime   );
			if ( m_pCheckCreateSubtitles->isChecked ( ) )
			  m_sourceFileInfo.pTranscodeInterface->iSubtitleFromMetaInfo = m_pComboLanguage->currentItem ( );
			else
			  m_sourceFileInfo.pTranscodeInterface->iSubtitleFromMetaInfo = -1;
//		m_sourceFileInfo.pTranscodeInterface->bTranscoding  = later to indicate transcoding in progress.
		}
		else if (m_sourceFileInfo.pTranscodeInterface)	{
			// Okay there used to be a TranscodeInterface but now the user wants to undo the transcoding.
			delete m_sourceFileInfo.pTranscodeInterface;
			m_sourceFileInfo.pTranscodeInterface = NULL;
		}
	
		// Adding chapters ...
		m_sourceFileInfo.listChapters.clear ();
		for (t=0;t<m_pListBoxChapters->count ();t++)
			m_sourceFileInfo.listChapters.append(m_pListBoxChapters->text (t));
	}
	else {	// Or if we are coming from the transcodeAll context menu
	        m_sourceFileInfo.bAutotranscode = false;
		if (  ! m_sourceFileInfo.pTranscodeInterface )
			m_sourceFileInfo.pTranscodeInterface = new TranscodeInterface;
		m_sourceFileInfo.pTranscodeInterface->qsVideoFormat = keepClean ( m_pComboVideoOut->currentText        ( ) );
		m_sourceFileInfo.pTranscodeInterface->qsVideoType   = keepClean ( m_pComboVideoType->currentText       ( ) );
		m_sourceFileInfo.pTranscodeInterface->qsResolution  = keepClean ( m_pComboVideoResolution->currentText ( ) );
		iBitrate = theUtils.normToLong ( keepClean ( m_pComboVideoBitrate->currentText ( ) ) );
		m_sourceFileInfo.pTranscodeInterface->iVideoBitrate = iBitrate;
		m_sourceFileInfo.pTranscodeInterface->fFrameRate    = keepClean ( m_pComboVideoRate->currentText       ( ) ).toFloat();
		m_sourceFileInfo.pTranscodeInterface->qsRatio       = keepClean ( m_pComboVideoAspect->currentText     ( ) );
		m_sourceFileInfo.pTranscodeInterface->qsAudioFormat = keepClean ( m_pComboAudioOut->currentText        ( ) );
		m_sourceFileInfo.pTranscodeInterface->qsAudioType   = keepClean ( m_pComboAudioType->currentText       ( ) );
		iBitrate = theUtils.normToLong ( keepClean ( m_pComboAudioBitrate->currentText ( ) ) );
		m_sourceFileInfo.pTranscodeInterface->iAudioBitrate = iBitrate;
		m_sourceFileInfo.pTranscodeInterface->iSample       = keepClean ( m_pComboAudioSampleRate->currentText ( ) ).toInt();
		m_sourceFileInfo.pTranscodeInterface->iStartingAt   = 0;
		m_sourceFileInfo.pTranscodeInterface->iEndingAt     = 0;
	}

	QDialog::accept ( );
}
