/****************************************************************************
** StructureToolBar - class
**
** Created: Tue May 04 12:09:08 2004
**      by: Varol Okan using kate editor
**
** This class will create a toolbar, which displays all currently selected
** sources for the DVD, such as all Videos, and all Audio files.
**
** Besides displaying these it will also do some background checks.
** For this it will spawn a new thread, which will analyse the file
** and see if it needs to get converted for a propper usage.
**
** tcscan is your friend.
** 
** The result will be color coded.
** o	Gray, not yet determined
** o	any shades of green -> In DVD format.
** o	any shades of blue  -> will be converted before creating DVD
** o	any shades of red   -> Can not automatically handle this format.
**
****************************************************************************/
#include <stdlib.h>
#include <unistd.h>

#include <qapplication.h>
#include <qinputdialog.h>
#include <qmainwindow.h>
#include <qfiledialog.h>
#include <qpushbutton.h>
#include <qpopupmenu.h>
#include <qlistview.h>
#include <qdockarea.h>
#include <qcombobox.h>
#include <qlistbox.h>
#include <qcursor.h>
#include <qheader.h>

#include "global.h"
#include "sourcetoolbar.h"
#include "dialogslide.h"
#include "qdvdauthor.h"
#include "listviewmedia.h"
#include "listviewitemmedia.h"
#include "dvdmenuundoobject.h"
#include "menupreview.h"
#include "messagebox.h"
#include "dialogmovie.h"
#include "filepreviewdialog.h"

#include "qplayer/mediainfo.h"
#include "qplayer/mediacreator.h"
#include "qplayer/sourcefiledialog.h"

#define SOURCE_FILE_ENTRY_ID   0
#define SOURCE_FILE_ENTRY_NAME 1

SourceToolBar::SourceToolBar (const QString &qsLabel, QMainWindow *pMainWindow, QWidget *pParent, bool bNewLine, const char *pName, WFlags f)
	: QToolBar (qsLabel, pMainWindow, pParent, bNewLine, pName, f)
{
	m_pMediaInfo   = NULL;
	m_pSlideDialog = NULL;
	m_pDVDAuthor   = (QDVDAuthor *)pMainWindow;

	// Next is to create a MediaEngine in a separate thread to keep the application running and not stottering ...
	m_pMediaInfo   = MediaCreator::createInfo ();

	setResizeEnabled (true);
	setMovingEnabled (true);
	pMainWindow->addDockWindow (this, Left);
	m_pSourceWidget = new uiSourceWidget (this);

	QGridLayout *tabLayout = new QGridLayout(m_pSourceWidget->tab, 1, 1, 4, 4, "tabLayout");
	m_pListViewAllSources  = new ListViewMedia (m_pSourceWidget->tab, "m_pListViewAllSources" );
	tabLayout->addWidget( m_pListViewAllSources, 0, 0 );
	m_pListViewAllSources->clear ();
//	m_pListViewAllSources->setPaletteBackgroundColor (QColor(111,200,255));
	m_pListViewAllSources->header()->hide();
	m_pListViewAllSources->addColumn (QString("[Nr]") );
	m_pListViewAllSources->addColumn (QString ("Name"));
	m_pListViewAllSources->addColumn (QString ("")    );
	m_pListViewAllSources->setRootIsDecorated(true);
	m_pListViewAllSources->allColumnsShowFocus();

	m_pSourceWidget->m_pListViewVideoSources->clear ();
	m_pSourceWidget->m_pListViewAudioSources->clear ();

	connect( m_pListViewAllSources, SIGNAL( doubleClicked ( QListViewItem *, const QPoint &, int ) ), this, SLOT (slotDoubleClickedOnVideoList(QListViewItem *, const QPoint &, int) ) );
	connect( m_pListViewAllSources, SIGNAL( rightButtonClicked ( QListViewItem *, const QPoint &, int ) ), this, SLOT (slotRightClickedOnVideoList (QListViewItem *, const QPoint &, int) ) );
	connect( m_pListViewAllSources, SIGNAL( clicked ( QListViewItem *, const QPoint &, int ) ), this, SLOT (slotClickedOnVideoList      (QListViewItem *, const QPoint &, int) ) );
	connect( m_pListViewAllSources, SIGNAL( signalRemoveEntry ( SourceFileEntry * ) ), this, SLOT(slotRemoveEntry (SourceFileEntry *) ) );

	connect ( m_pSourceWidget->m_pButtonAddMovie,  SIGNAL( clicked ( ) ), this, SLOT ( slotAddMovie     ( ) ) );
	connect ( m_pSourceWidget->m_pButtonAddSlide,  SIGNAL( clicked ( ) ), this, SLOT ( slotAddSlideshow ( ) ) );

//	connect( m_pSourceWidget->m_pListViewVideoSources, SIGNAL( mouseButtonClicked(int,QListBoxItem*,const QPoint&)), this, SLOT(slotClickedOnVideoList(int,QListBoxItem*,const QPoint&) ) );
//	connect( m_pSourceWidget->m_pListViewAudioSources, SIGNAL( mouseButtonClicked(int,QListBoxItem*,const QPoint&)), this, SLOT(slotClickedOnVideoList(int,QListBoxItem*,const QPoint&) ) );
}

SourceToolBar::~SourceToolBar ()
{
	uint t;
	MediaCreator::unregisterFromMediaScanner ( this );
	for (t=0;t<m_listSourceFileEntries.count();t++)
		delete m_listSourceFileEntries[t];
	m_listSourceFileEntries.clear();
	if (m_pMediaInfo)
		delete m_pMediaInfo;
	if ( m_pSlideDialog )
		delete m_pSlideDialog;
}

QSize SourceToolBar::sizeHint () const
{
	QSize theSize = QToolBar::sizeHint();
	if ( (area() != 0) && (area()->orientation() == Qt::Vertical) )	// it is docked, make it at least 250 wide
		theSize.setWidth(10);
	return QSize (theSize);
}

QString SourceToolBar::convertFileSize(uint iFileSize)
{
	QString qsReturn;
	if (iFileSize > 1024 * 1024 * 1024)	// GBytes
		qsReturn = qsReturn.sprintf ("%.2f GB", (double)iFileSize / (1024*1024*1024));
	else if (iFileSize > 1024 * 1024)	// GBytes
		qsReturn = qsReturn.sprintf ("%.2f MB", (double)iFileSize / (1024*1024));
	else if (iFileSize > 1024)	// GBytes
		qsReturn = qsReturn.sprintf ("%.2f kB", (double)iFileSize / (1024));
	else
		qsReturn = qsReturn.sprintf ("%.2d Byte", iFileSize);

	return qsReturn;
}

void *SourceToolBar::getMediaEngine ()
{
	static int iCounter = 0;
	while (!m_pMediaInfo)	{
		// Init does not seem to have finished yet ...
		// So we wait for a second ...
		sleep (1);
		// this counter will break out of the loop after 5 unsuccessfull seconds
		if (iCounter ++ > 5)
			return NULL;
	}
	return m_pMediaInfo->getMediaEngine ();
}

MediaInfo *SourceToolBar::getMediaInfo ()
{
	// This is just to ensure we have a engine already created ...
	getMediaEngine ();
	return m_pMediaInfo;
}

int SourceToolBar::sourceFileCount()
{
	return (int)m_listSourceFileEntries.count();
}

SourceFileEntry *SourceToolBar::sourceFileEntry(uint iEntryNumber)
{
	return m_listSourceFileEntries[iEntryNumber];
}

SourceFileEntry *SourceToolBar::getCurrentSourceFileEntry ()
{
	SourceFileEntry *pSourceFileEntry = NULL;

	ListViewItemMedia *pItem = (ListViewItemMedia *)m_pListViewAllSources->currentItem();
	if (!pItem)
		return NULL;
	pSourceFileEntry = pItem->sourceFileEntry ();
	// If the SourceFileEntry is NULL then we have a SourceFileInfo and
	// thus get the SourceFileEntry from the  parent item ..
	if (!pSourceFileEntry)
		 pSourceFileEntry = ((ListViewItemMedia *)pItem->parent())->sourceFileEntry();
	return pSourceFileEntry;
}

SourceFileInfo *SourceToolBar::getCurrentSourceFileInfo ()
{
	SourceFileInfo  *pSourceFileInfo  = NULL;
	SourceFileEntry *pSourceFileEntry = NULL;

	ListViewItemMedia *pItem = (ListViewItemMedia *)m_pListViewAllSources->currentItem();
	if (!pItem)
		return NULL;
	pSourceFileInfo  = pItem->sourceFileInfo  ();
	// If the Info is NULL then we have a header and want the first FileInfo of it ...
	if (!pSourceFileInfo)	{
		pSourceFileEntry = pItem->sourceFileEntry ();
		pSourceFileInfo = pSourceFileEntry->listFileInfos[0];
	}
	return pSourceFileInfo;
}
/*
SourceFileEntry *SourceToolBar::getCurrentSourceFileEntry()
{
	// This function will return the currently selected source file entry ...
	uint t;
	QString qsCurrentText;
	QListViewItem *pCurrentItem = m_pListViewAllSources->currentItem();
	if (pCurrentItem)
		qsCurrentText = pCurrentItem->text(SOURCE_FILE_ENTRY_NAME);
	for (t=0;t<m_listSourceFileEntries.count();t++)	{
		if (m_listSourceFileEntries[t]->qsDisplayName == qsCurrentText)
			return m_listSourceFileEntries[t];
	}
	return NULL;
}
*/
void SourceToolBar::slotDoubleClickedOnVideoList(QListViewItem *pItem, const QPoint &, int)
{
  // First we check if the item is valid ...
  if (pItem == NULL)	{
    slotAddMovie ( );
    return;
  }
  if (m_listSourceFileEntries.count() > 0)
    slotEditMovie ( );
}

void SourceToolBar::slotRightClickedOnVideoList (QListViewItem *pItem, const QPoint &thePoint, int)
{
	// First we check if the item is valid ...
	if (pItem == NULL)	{
		slotAddMovie ();
		return;
	}
	// here we handle the movie - right click ...
	// Here we pop open the properties dialog for the movie, where you can set
	// o size of movie (resizing tool used = ???
	// o Define Title # / Add Chapters to Title

	// Here we find out if we can actually play the file ... Meaning slideshows can not be played !!!
	uint t;
	bool bShow = true;
	SourceFileEntry *pSourceFileEntry = NULL;
	for (t=0;t<m_listSourceFileEntries.count();t++)	{
		if (pItem->text(SOURCE_FILE_ENTRY_NAME) == m_listSourceFileEntries[t]->qsDisplayName)	{
			if (m_listSourceFileEntries[t]->bIsSlideshow)
				bShow = false;
			pSourceFileEntry = m_listSourceFileEntries[t];
			break;
		}
	}

	QPopupMenu *pMenu = new QPopupMenu(m_pListViewAllSources);
	if (bShow)
		pMenu->insertItem ( tr ("Play"),               this, SLOT(slotPlayMovie    ()));
	pMenu->insertItem ( tr ("Properties ..."),             this, SLOT(slotEditMovie    ()));
	if ( (pSourceFileEntry) && (pSourceFileEntry->listFileInfos.count() > 1) ) {
		pMenu->insertItem ( tr ("Transcode All ..."),  this, SLOT(slotTranscodeAll ()));
		pMenu->insertItem ( tr ("All to titleset ..."),this, SLOT(slotAllToTitleset()));
	}
	else
		pMenu->insertItem ( tr ("Assign to titleset ..." ),this, SLOT(slotAllToTitleset()));
	pMenu->insertItem ( tr ("Delete"),                     this, SLOT(slotDeleteSource ()));
	pMenu->exec(thePoint, 2);
	
	delete pMenu;
}

void SourceToolBar::slotClickedOnVideoList(QListViewItem *pItem, const QPoint &thePoint, int)
{
	// If no Item was clicked the the user might want to add something ?
	if (pItem == NULL)	{
		// Here we translate the clicked position to idget coordinates
		QPoint p (m_pListViewAllSources->mapFromGlobal(thePoint));
		// and since we actually are only looking for a hight comparison,
		// we set x to always hit a entry (if there is one).
		p.setX(50);
		if (!m_pListViewAllSources->itemAt (p))
			slotAddMovie ();
	}
}

void SourceToolBar::slotSetThumbnail ( long iMSecOffset )
{
  // The user wants to set the current frame as the thumbnail instead of frame 0.
  ListViewItemMedia *pItem = (ListViewItemMedia *)m_pListViewAllSources->currentItem();
  if ( ! pItem )
    return;
  SourceFileInfo *pSourceFileInfo = pItem->sourceFileInfo ( );
  if ( pSourceFileInfo )  { // create new thumbnail ...
    pSourceFileInfo->iMSecPreview = iMSecOffset;
    MediaCreator::registerWithMediaScanner (this, pSourceFileInfo, iMSecOffset, false);
  }
}

void SourceToolBar::slotTranscodeAll()
{
  uint t;
  QFileInfo fileInfo;
  // Called when the user clicks on the SourceFileEntry - header.
  // This function will transcode all associated SourceFiles into the same format.
  SourceFileEntry *pSourceFileEntry = NULL;
  SourceFileInfo  *pSourceFileInfo  = NULL;
  SourceFileInfo  *pFirstFileInfo   = NULL;
  QListViewItem   *pItem = m_pListViewAllSources->currentItem ();
  if ( ! pItem ) 
    return;
  for (t=0;t<m_listSourceFileEntries.count();t++)	{
    if (pItem->text(SOURCE_FILE_ENTRY_NAME) == m_listSourceFileEntries[t]->qsDisplayName)	{
      pSourceFileEntry = m_listSourceFileEntries[t];
      break;
    }
  }
  
  if ( ! pSourceFileEntry )
    return; // Could not find the currently selected SourceFileEntry
  
  // Okay we only want to convert if the FileInfos have the same transcoding information (Either none, or all values the same.
  pFirstFileInfo = pSourceFileEntry->listFileInfos[0];
  
  for (t=0;t<pSourceFileEntry->listFileInfos.count();t++)	{
    pSourceFileInfo = pSourceFileEntry->listFileInfos[t];
    if ( pFirstFileInfo->pTranscodeInterface )	{
      if ( ! pSourceFileInfo )
	return;
      if ( ! pSourceFileInfo->pTranscodeInterface )
	return;
      else if ( *pSourceFileInfo->pTranscodeInterface  != *pFirstFileInfo->pTranscodeInterface )
	return;
    }
    else if ( pSourceFileInfo && pSourceFileInfo->pTranscodeInterface )
      return;
  }
  
  // Here we open the MovieDialog.
  Utils theUtils;
  DialogMovie theDialog (this);
  theDialog.initMe (pSourceFileEntry);
  if (theDialog.exec () == QDialog::Rejected)
    return;
  
  // Check if there was a transcodeInterface created by the dialog.
  if (theDialog.sourceFileInfo()->pTranscodeInterface)	{
    for (t=0;t<pSourceFileEntry->listFileInfos.count();t++)	{
      pSourceFileInfo = pSourceFileEntry->listFileInfos[t];
      if ( ! pSourceFileInfo->pTranscodeInterface )
	pSourceFileInfo->pTranscodeInterface = new TranscodeInterface;
      *pSourceFileInfo->pTranscodeInterface = *theDialog.sourceFileInfo()->pTranscodeInterface;
      fileInfo.setFile ( pSourceFileInfo->qsFileName );
      pSourceFileInfo->pTranscodeInterface->qsTempFile = QString ( "%1/%2.mpeg2" ).arg (theUtils.getTempPath ( fileInfo.baseName () ) ).arg(fileInfo.baseName () );
      updateListViewItem ( pSourceFileInfo );
    }
  }
  else	{	// If there is none then remove all transcodeInterfaces from the files.
    for (t=0;t<pSourceFileEntry->listFileInfos.count();t++)	{
      pSourceFileInfo = pSourceFileEntry->listFileInfos[t];
      if ( pSourceFileInfo->pTranscodeInterface )	{
	delete pSourceFileInfo->pTranscodeInterface;
	pSourceFileInfo->pTranscodeInterface = NULL;
	updateListViewItem ( pSourceFileInfo );
      }
    }
  }
  pSourceFileEntry->qsPre  = theDialog.m_pComboPreCommand->currentText  ( );
  pSourceFileEntry->qsPost = theDialog.m_pComboPostCommand->currentText ( );

  updateEntryHeader ( pSourceFileEntry );
}

void SourceToolBar::slotAllToTitleset ( )
{
  int  t, iValue = -1;
  bool bOkay  = false;
  SourceFileEntry *pSourceFileEntry = getCurrentSourceFileEntry ( );

  if ( ! pSourceFileEntry )
    return;

  // Lets get the current Titleset for these/this SourceFileInfos.
  if ( pSourceFileEntry->listFileInfos.count ( ) > 0 )
    iValue = pSourceFileEntry->listFileInfos[0]->iTitleset;

  for ( t=0;t<(int)pSourceFileEntry->listFileInfos.count ( );t++ ) {
    if ( pSourceFileEntry->listFileInfos[t]->iTitleset != iValue ) {
      iValue = -1;
      break;
    }
  }

  iValue = QInputDialog::getInteger ( tr("Titleset Number ( 1 .. 99 )"), 
				      tr("Please enter a proposed titleset number for these entries.\n-1 = automtically assign."), 
				      iValue, -1, 99, 1, &bOkay );
  if ( bOkay == false )
    return;

  if ( iValue == 0 ) {
    MessageBox::information (NULL, tr ( "0 is not a valid choice." ), tr ( "0 is not a valid choice. Please try again." ), QMessageBox::Ok, QMessageBox::NoButton );
    slotAllToTitleset ( );
    return;
  }

  for ( t=0;t<(int)pSourceFileEntry->listFileInfos.count ( );t++ ) {
    pSourceFileEntry->listFileInfos[t]->iTitleset = iValue;
  }
  pSourceFileEntry->iTitleset = iValue;
}

// This is without background task to get the info ...
void SourceToolBar::slotAddMovie()
{
  if (!m_pDVDAuthor->checkForNewProject ( ) )
    return;
  // Some one clicked the "Add Movie" button.
  QString qsMovieFilter        = m_pDVDAuthor->getMovieFilter ( );
  void   *pExistingMediaEngine = getMediaEngine               ( );
  
  QStringList listAddMovies = FilePreviewDialog::getOpenFileNames ( pExistingMediaEngine, Global::qsCurrentPath, QString ("Movies ( ") + qsMovieFilter + QString (" );;All ( * )"));
  //QStringList listAddMovies = QFileDialog::getOpenFileNames (tr("Movie Files (")+qsFilter+QString (")"), Global::qsCurrentPath, this, tr("Open file dialog"), tr ("Add To Project ..."));
  // I tried to get the sorting of the names out of here but
  // detailViewSelectionChanged and listBoxSelectionChanged
  // are not flexible enough to handle this (yet).
  if (listAddMovies.count() < 1)
    return;
  
  addMovieList (listAddMovies);
}

void SourceToolBar::addMovieList (QStringList &listAddMovies, QString *pTitle)
{
	uint t;
	QFileInfo fileInfo (listAddMovies[0]);
	QString qsPath = fileInfo.filePath();
	Global::qsCurrentPath = qsPath;

	QCursor myCursor (QCursor::WaitCursor);
	QApplication::setOverrideCursor (myCursor);
	SourceFileEntry *pEntry = new SourceFileEntry;
	pEntry->sizeThumbnail = m_pDVDAuthor->getDragNDropContainer()->sizeThumbnail;
	pEntry->bSoundSource = false;
	SourceFileInfo *pInfo;
	for (t=0;t<listAddMovies.count();t++)	{
		pInfo = new SourceFileInfo;
		pInfo->qsFileName   = listAddMovies[t];
		// Here we generate a dummy image as a place holder
		pInfo->pPreview = new QImage (QImage().fromMimeSource( "please_wait.jpg" ));
		*pInfo->pPreview = pInfo->pPreview->smoothScale (m_pDVDAuthor->getDragNDropContainer()->sizeButton, QImage::ScaleMin);
		// and then register to obtain the info in the background.
		MediaCreator::registerWithMediaScanner ( this, pInfo );
		pEntry->listFileInfos.append(pInfo);
	}
	// Check if there is something in the Entry left to be added to the sourceToolbar.
	if (pEntry->listFileInfos.count() == 0)	{
		delete pEntry;
		return;
	}

	if (pTitle)	{	// If a title has been provided
		pEntry->qsDisplayName = *pTitle;
	}
	else if (listAddMovies.count () > 1)	{
		QString qsText = tr(" Movie Files>");
		pEntry->qsDisplayName.sprintf ("[%02d] - <%02d", getFreeSourceSlot (), (int)listAddMovies.count());
		pEntry->qsDisplayName += qsText;
	}
	else
		pEntry->qsDisplayName.sprintf ("[%02d] - %s", getFreeSourceSlot (), (const char *)fileInfo.baseName(true));
	m_listSourceFileEntries.append(pEntry);
	// Okay, now we should also add this into the list box ...
	addMovie (pEntry);
	QApplication::restoreOverrideCursor ();
}

bool SourceToolBar::checkRightFileFormat ( SourceFileInfo *pInfo )
{
  Utils     theUtil;
  // this function will check if we have a VOB stream.
  // if not, if we have a Mpeg2 stream
  // if not the set transcode parameters for this SourceFileInfo - object.

  // If we have a VOB - stream we can safely return ...
  // Note, we assume VOBUs == right resolution. Why else would you have a VOB stream ?
  if ( theUtil.hasVobus ( pInfo->qsFileName ) ) 
    return true;

  // If the user selected not to transcode this file, so be it.
  if ( ! pInfo->bAutotranscode )
    return true;

  // Also if there is already a TranscodeInterface defined, then keep our hands off !!!
  if ( pInfo->pTranscodeInterface ) 
    return true;
  
  QFileInfo fileInfo ( pInfo->qsFileName );
  int       iWidth, iHeight;
  // Everything else needs to be transcoded !!!
  TranscodeInterface *pTranscode = new TranscodeInterface;
  pInfo->pTranscodeInterface = pTranscode;
  pTranscode->qsTempFile     = QString ( "%1/%2.mpeg2" ).arg ( theUtil.getTempPath ( fileInfo.baseName () ) ).arg(fileInfo.baseName () );

  iWidth  = theUtil.getWHFromResolution ( pInfo->qsResolution, true  );
  iHeight = theUtil.getWHFromResolution ( pInfo->qsResolution, false );
  if ( theUtil.getFormat ( iWidth, iHeight ) != FORMAT_NONE ) {
    pTranscode->bRemuxOnly = true;
    return true;
  }

  //  if ( theUtil.isMpeg2 ( pInfo->qsFileName ) ) {
    // Mpeg 2 stream detected. Lets check resolution.
    QString qsFormat          = "ntsc";
    pTranscode->fFrameRate    = 29.97;
    pTranscode->qsResolution  = "720x480"; 
    if ( (pInfo->qsVideoFormat == "pal") || (pInfo->qsVideoFormat == "PAL") ) {
      qsFormat                = "pal";
      pTranscode->fFrameRate  = 25.0;
      pTranscode->qsResolution= "720x576"; 
    }
    
    pTranscode->qsVideoFormat = qsFormat;
    pTranscode->qsVideoType   = "mpeg2";
    pTranscode->iVideoBitrate = 6600000;
    pTranscode->qsRatio       = pInfo->qsRatio;
    pTranscode->qsAudioFormat = "mp2"; //pInfo->;
    pTranscode->qsAudioType   = "stereo";
    pTranscode->iAudioBitrate = 128*1024; // 128kbps
    pTranscode->iSample       = 48000;
    pTranscode->bTranscoding  = false;
    return true;
    //  }

  return false;
}

void SourceToolBar::timerEvent(QTimerEvent *pTimerEvent)
{
  // Called after the background thread has generated the preview ...
  uint t, i;
  SourceFileEntry *pEntry = NULL;
  SourceFileInfo  *pInfo  = NULL;
  
  switch ( pTimerEvent->timerId() )	{
  case MEDIASCANNER_EVENT:
    m_mutexThumbnails.lock ();
    // We could simply call this function but it would be a brute force approach as the whole tree would get rebuild.
    //refreshToolBarEntries ();
    // So rather we check all SourceFileInfo's for the flag bUpdateImage and do so singularily.
    for (t=0;t<m_listSourceFileEntries.count();t++)	{
      pEntry = m_listSourceFileEntries[t];
      for (i=0;i<pEntry->listFileInfos.count();i++)	{
	// Okay found the SourceFileInfo now we need the ListViewItemMedia - object for this Info.
	pInfo = pEntry->listFileInfos[i];
	if (pInfo->bUpdateInfo)	{
	  // next we check if the file is an VOB stream, Mpeg2 stream or any other ...
	  checkRightFileFormat ( pInfo );

	  ListViewItemMedia *pChild = (ListViewItemMedia *)m_pListViewAllSources->firstChild ();
	  while (pChild)	{
	    // Got it and it fits ...
	    pChild->replaceInfo(pInfo);
	    pChild = (ListViewItemMedia *)pChild->nextSibling();
	  }
	  // Oh and the ListViewVideoSources should also be updated ...
	  QListViewItem *pItem = m_pSourceWidget->m_pListViewVideoSources->firstChild ();
	  while (pItem)	{
	    if (pItem->text (MOVIE_FILE_NAME_INDEX) == pInfo->qsFileName)	{
	      pItem->setText (0, pInfo->qsVideoFormat);
	      pItem->setText (1, pInfo->qsResolution);
	      pItem->setText (2, pInfo->qsLength);
	      pItem->setText (3, pInfo->qsSize);
	      pItem->setText (4, pInfo->qsRatio);
	      pItem->setText (5, pInfo->qsFPS);
	      pItem->setText (6, pInfo->qsStatus);
	    }
	    pItem = pItem->nextSibling();
	  }
	  pInfo->bUpdateInfo = false;
	  m_pDVDAuthor->slotCalculateSize();
	  updateEntryHeader ( pEntry );
	  m_mutexThumbnails.unlock ();
	  return;
	}
      }
    }
    m_mutexThumbnails.unlock ();
    break;
  }
}

void SourceToolBar::updateEntryHeader ( SourceFileEntry *pEntry )
{
  uint t, i;
  QString qsFormat ("--");
  SourceFileInfo *pInfo;
  QListViewItem  *pItem;
  // Oh and the ListViewVideoSources should also be updated ...
  for (t=0;t<pEntry->listFileInfos.count();t++)	{
    // Okay found the SourceFileInfo now we need the ListViewItemMedia - object for this Info.
    pInfo = pEntry->listFileInfos[t];
    pItem = m_pListViewAllSources->firstChild ();
    while ( pItem )	{
      if  ( pItem->text ( 1 ) == pEntry->qsDisplayName ) {
	// Okay, we found the Item that belongs to this SourceFileEntry
	if ( pEntry->listFileInfos.count () > 0 )
	  qsFormat = pEntry->listFileInfos[0]->qsVideoFormat;
	for (i=1;i<pEntry->listFileInfos.count();i++)	{
	  if ( pEntry->listFileInfos[i]->qsVideoFormat != qsFormat ) {
	    qsFormat = "Mixed";
	    break; // out of the inner for - loop
	  }
	}
	pItem->setText ( 0, qsFormat );
	return;
      }
      pItem = pItem->nextSibling();
    }
  }
}

void SourceToolBar::updateListViewItem ( SourceFileInfo *pInfo )
{
  ListViewItemMedia *pItem, *pSubItem;
  // Okay found the SourceFileInfo now we need the ListViewItemMedia - object for this Info.
  pItem = (ListViewItemMedia *)m_pListViewAllSources->firstChild ();
  while ( pItem )	{
    pSubItem = (ListViewItemMedia *)pItem->firstChild ();
    while ( pSubItem ) {
      if  ( pSubItem->sourceFileInfo () == pInfo ) {
	pSubItem->updateItem ( );
	m_pListViewAllSources->repaintItem ( pSubItem );
	pSubItem = NULL;
      }
      else
	pSubItem = (ListViewItemMedia *)pSubItem->nextSibling();
    }
    pItem = (ListViewItemMedia *)pItem->nextSibling();
  }

  QListViewItem *pVideoItem = m_pSourceWidget->m_pListViewVideoSources->firstChild ();
  while ( pVideoItem ) {
    if  ( pVideoItem->text( MOVIE_FILE_NAME_INDEX ) == pInfo->qsFileName ) {
      pVideoItem->setText (0, pInfo->qsVideoFormat);
      pVideoItem->setText (1, pInfo->qsResolution);
      pVideoItem->setText (2, pInfo->qsLength);
      pVideoItem->setText (3, pInfo->qsSize);
      pVideoItem->setText (4, pInfo->qsRatio);
      pVideoItem->setText (5, pInfo->qsFPS);
      pVideoItem->setText (6, pInfo->qsStatus);
      pVideoItem = NULL;
    }
    else
      pVideoItem = pVideoItem->nextSibling ();
  }

  QListViewItem *pAudioItem = m_pSourceWidget->m_pListViewAudioSources->firstChild ();
  while ( pAudioItem ) {
    if  ( pAudioItem->text( AUDIO_FILE_NAME_INDEX ) == pInfo->qsFileName ) {
      pAudioItem->setText (0, pInfo->qsAudioFormat);
      pAudioItem->setText (1, pInfo->qsLength);
      pAudioItem->setText (2, pInfo->qsBits);
      pAudioItem->setText (3, pInfo->qsSample);
      pAudioItem->setText (4, pInfo->qsBPS);
      pAudioItem->setText (5, pInfo->qsSize);
      pAudioItem->setText (6, pInfo->qsStatus);
      pAudioItem = NULL;
    }
    else
      pAudioItem = pAudioItem->nextSibling ();
  }
}

int SourceToolBar::getFreeSourceSlot ()
{
	// this function will return a free number according to the SourceEntries currently in the list.
	// Note : a standard entry start like "[xx] - " where xx is a number
	uint t;
	int iPos, iSourceNumber, iInquireNumber;
	bool bOk;
	QString qsPart;
	iInquireNumber = 1;
	for (t=0;t<m_listSourceFileEntries.count();t++)	{
		iPos = m_listSourceFileEntries[t]->qsDisplayName.find ("]", 1);
		if (iPos == -1)
			continue;
		qsPart = m_listSourceFileEntries[t]->qsDisplayName.mid (1, iPos-1);
		if (qsPart.isNull ())
			continue;
		iSourceNumber = qsPart.toInt(&bOk);
		if (!bOk)
			continue;
		if (iSourceNumber == iInquireNumber)	{
			iInquireNumber ++;
			t = 0;
		}
	}
	// And at this point we should have a correct number ...
	return iInquireNumber;
//	return m_listSourceFileEntries.count()+1;
}

void SourceToolBar::addMovie (SourceFileEntry *pEntry)
{
  uint t;
  QColor statusColor (COLOR_MOVIE_FILES_OK);
  
  SourceFileInfo *pInfo;
  for (t=0;t<pEntry->listFileInfos.count();t++)	{
    pInfo = pEntry->listFileInfos[t];
    // Here we check that ALL sources are ok
    if (pInfo->qsStatus != QString ("Ok"))
      statusColor = QColor(COLOR_MOVIE_FILES_BAD);
    
    new QListViewItem (m_pSourceWidget->m_pListViewVideoSources, pInfo->qsVideoFormat,
		       pInfo->qsResolution, pInfo->qsLength, pInfo->qsSize, pInfo->qsRatio,
		       pInfo->qsFPS, pInfo->qsStatus, pInfo->qsFileName);
  }
  new ListViewItemMedia (m_pListViewAllSources, pEntry, statusColor);
}

void SourceToolBar::appendSourceFileEntry(SourceFileEntry *pEntry)
{
  // This function is called when loading from an XML-project file ???
  m_listSourceFileEntries.append(pEntry);
  QColor statusColor (COLOR_MOVIE_FILES_BAD);
  // Here we set the preview size ...
  pEntry->sizeThumbnail = m_pDVDAuthor->getDragNDropContainer()->sizeThumbnail;
  if (!pEntry->bSoundSource)	{	// Here we handle a Movie SourceFileEntry ...
    for (uint t=0;t<pEntry->listFileInfos.count();t++)	{
      SourceFileInfo *pInfo = pEntry->listFileInfos[t];
      // Add the plaeas - wait image
      pInfo->pPreview = new QImage (QImage().fromMimeSource( "please_wait.jpg" ));
      // and the request the preview from a background thread.
      MediaCreator::registerWithMediaScanner (this, pInfo, pInfo->iMSecPreview, false);
      *pInfo->pPreview = pInfo->pPreview->smoothScale (m_pDVDAuthor->getDragNDropContainer()->sizeButton, QImage::ScaleMin);
      // And show what we have thus far.
      new QListViewItem (m_pSourceWidget->m_pListViewVideoSources, pInfo->qsVideoFormat, pInfo->qsResolution, pInfo->qsLength,  pInfo->qsSize, pInfo->qsRatio, pInfo->qsFPS, pInfo->qsStatus, pInfo->qsFileName);
    }
  }
  else	{	// And here we have a Sound SourceFileEntry
    statusColor = QColor (COLOR_SOUND_FILES_OK);
    
    for (uint t=0;t<pEntry->listFileInfos.count();t++)	{
      SourceFileInfo *pInfo = pEntry->listFileInfos[t];
      if (pInfo->qsStatus != QString ("Ok"))
	statusColor = QColor (COLOR_SOUND_FILES_BAD);
      
       pInfo->pPreview = new QImage (QImage().fromMimeSource( "sound_file.jpg" ));
      *pInfo->pPreview = pInfo->pPreview->smoothScale (m_pDVDAuthor->getDragNDropContainer()->sizeButton, QImage::ScaleMin);
      new QListViewItem (m_pSourceWidget->m_pListViewAudioSources, pInfo->qsAudioFormat, pInfo->qsLength, pInfo->qsBits, pInfo->qsSample, pInfo->qsBPS, pInfo->qsSize, pInfo->qsStatus, pInfo->qsFileName);
    }
  }
  new ListViewItemMedia (m_pListViewAllSources, pEntry, statusColor);
}

void SourceToolBar::slotRemoveEntry(SourceFileEntry *pEntry)
{
  m_listSourceFileEntries.remove(pEntry);
  if ( m_pDVDAuthor )
    // So the user has decided to delete this source, then we should change the associated
    // buttons - action !!!
    m_pDVDAuthor->removedSourceEntry( pEntry );
}

void SourceToolBar::slotAddSound()
{
	// never used, the real function comes from 
	// QDVDMenu::slotAddSound()->DVDAuthor::addSound()->SourceToolBar::addSound()
	QString qsFilter = m_pDVDAuthor->getSoundFilter();
	// For now we assume this is slotEditAdd()
	QStringList listAddSounds = QFileDialog::getOpenFileNames(tr("Sound Files (")+qsFilter+QString(")"), Global::qsCurrentPath, this, tr("Open file dialog"), tr("Add To Project ..."));
	if (listAddSounds.count() < 1)
		return;
	// Okay, now we should also add this into the list box ...
	addSound (listAddSounds);
}

void SourceToolBar::addSound (QStringList &listSoundNames)
{
	uint t;
	QFileInfo fileInfo (listSoundNames[0]);
	QString qsFileName = fileInfo.fileName();

	// And here we set the  current Directory for the application ...
	QString qsPath = fileInfo.filePath();
	Global::qsCurrentPath = qsPath;

	// Before we insert it we should remove all previous entries so that we hold only one entry for one sound file
	removeEntry (qsFileName);

	MediaInfo *pMediaInfo = MediaCreator::createInfo (getMediaEngine());
	QColor statusColor (COLOR_SOUND_FILES_OK);
	SourceFileInfo  *pInfo;
	SourceFileEntry *pEntry = new SourceFileEntry;
	pEntry->bSoundSource = true;
	pEntry->sizeThumbnail = m_pDVDAuthor->getDragNDropContainer()->sizeThumbnail;
	for (t=0;t<listSoundNames.count();t++)	{
		pMediaInfo->setFileName (listSoundNames[t]);
		// Lets create a new SoourceFileEntry for this sound file ...
		pInfo = new SourceFileInfo;

		pInfo->qsSize        = pMediaInfo->getSizeString();
		pInfo->qsBits        = QString ("%1").arg(pMediaInfo->getBits());
		pInfo->qsSample      = pMediaInfo->getSampleString ();
		pInfo->qsBPS         = pMediaInfo->getBPSString (false);
		pInfo->qsLength      = pMediaInfo->getLengthString ();
		pInfo->qsAudioFormat = pMediaInfo->getFormat (false);
		pInfo->qsStatus      = pMediaInfo->getStatus();
		pInfo->qsFileName    = listSoundNames[t];
		pInfo->pPreview      = new QImage (QImage().fromMimeSource( "sound_file.jpg" ));
		*pInfo->pPreview     = pInfo->pPreview->smoothScale (m_pDVDAuthor->getDragNDropContainer()->sizeButton, QImage::ScaleMin);

		if (pInfo->qsStatus != QString ("Ok"))
			statusColor = QColor (COLOR_SOUND_FILES_BAD);

		pEntry->listFileInfos.append (pInfo);
	}
	if ( listSoundNames.count ( ) > 1 )
		pEntry->qsDisplayName.sprintf ("[%02d] - <%02d Sound Files>", getFreeSourceSlot ( ), (int)listSoundNames.count ( ) );
	else
		pEntry->qsDisplayName.sprintf ("[%02d] - %s",getFreeSourceSlot (), (const char *)fileInfo.fileName());
	m_listSourceFileEntries.append(pEntry);

	// this new sound is assigned to the current DVDMenu's Preview. Phew what a long list to get there ...
	DVDMenu *pCurrentSubMenu = m_pDVDAuthor->getCurrentSubMenu();
	if ( pCurrentSubMenu )
	  pCurrentSubMenu->getMenuPreview()->undoBuffer()->push (new DVDMenuUndoObject(DVDMenuUndoObject::NEW_AUDIO, pEntry ));	// And finally we add it to the list ...
	new ListViewItemMedia (m_pListViewAllSources, pEntry, statusColor);

	// And further on to the m_pListViewVideoSources ...
	new QListViewItem (m_pSourceWidget->m_pListViewAudioSources, pInfo->qsAudioFormat, pInfo->qsLength, pInfo->qsBits, pInfo->qsSample, pInfo->qsBPS, pInfo->qsSize,  pInfo->qsStatus, pInfo->qsFileName);
	delete pMediaInfo;
}

void SourceToolBar::slotAddSlideshow()
{
	Utils theUtil;
	if (!m_pDVDAuthor->checkForNewProject ())
		return;
	// First we pop up the slideshow generation dialog box
	QString qsTempPath = theUtil.getTempFile(QString ());
	if ( ! m_pSlideDialog )  {
		m_pSlideDialog = new CSlideDialog;
		m_pSlideDialog->initMe(this, qsTempPath);
	}
	m_pSlideDialog->show();
	// Note that the SourceFileEntry is generated  when we have given a name to the
	// newly generated slideshow. This is then done SourceToolBar::slotAddSlideshow(QString);
}

void SourceToolBar::slotEditMovie()
{
	// Here we open the MovieDialog.
	ListViewItemMedia *pItem = (ListViewItemMedia *)m_pListViewAllSources->currentItem();
	if (!pItem)
		return;
	SourceFileInfo *pSourceFileInfo = pItem->sourceFileInfo();
	if (pSourceFileInfo)	{
		DialogMovie *pDialog = new DialogMovie (this);
		pDialog->initMe (pSourceFileInfo, getMediaEngine(), m_pDVDAuthor->getDragNDropContainer()->sizeThumbnail.width());
		connect ( pDialog, SIGNAL ( signalSetThumbnail ( long ) ), this, SLOT ( slotSetThumbnail ( long ) ) );
		if (pDialog->exec () == QDialog::Accepted) {
			*pSourceFileInfo = *pDialog->sourceFileInfo();
			// next is to update the entries if neccesary ...
			updateListViewItem ( pSourceFileInfo );
		}
		disconnect ( pDialog, SIGNAL ( signalSetThumbnail ( long ) ), this, SLOT ( slotSetThumbnail ( long ) ) );
		delete pDialog;
		return;
	}
	
	QStringList listFileTypes;
	SourceFileEntry *pSourceFileEntry = getCurrentSourceFileEntry ();
	if (!pSourceFileEntry)
		return;

//	QListViewItem *pItem = m_pListViewAllSources->currentItem ();
//	int iCurrent = (int)( (float)pItem->itemPos() / (float)pItem->height());
	int iCurrent = 0;
	for (iCurrent=0;iCurrent<(int)m_listSourceFileEntries.count();iCurrent++)
		if (m_listSourceFileEntries[iCurrent] == pSourceFileEntry)
			break;

	QString qsOriginalDisplayName = pSourceFileEntry->qsDisplayName;
	listFileTypes.append (tr ("Movie/Image Files (+Movies+ *.bmp *.png *.jpg *.gif *.xbm)"));
	listFileTypes.append (tr ("Movie Files (+Movies+)"));
	listFileTypes.append (tr ("Image Files (*.bmp *.png *.jpg *.gif *.xbm)"));
	listFileTypes.append (tr ("All Files (*)"));

	// Here we try to find out if we have a movie or a sound ...
	int iWhichTab = SOURCE_FILE_TAB;
//	if (	(iCurrent < (int)m_listSourceFileEntries.count ()) &&
//			(m_listSourceFileEntries[iCurrent]->bSoundSource) )
	if (pSourceFileEntry->bSoundSource)
		iWhichTab = SOUND_OPTIONS_TAB;


	SourceFileDialog *pDialog = new SourceFileDialog(getMediaEngine (), this, iWhichTab);
	pDialog->setFileTypes (listFileTypes);
	pDialog->setSourceFileEntries(m_listSourceFileEntries,  iCurrent);

	int iReturn = pDialog->exec();
	if (iReturn == QDialog::Rejected)
		return;
	refreshToolBarEntries();
	// Here we check if the DisplayName has been changed. Note that the pointer has not changed, only the values.
	if ( (qsOriginalDisplayName != pSourceFileEntry->qsDisplayName) && (m_pDVDAuthor) )
			m_pDVDAuthor->replaceSourceDisplayName(qsOriginalDisplayName, pSourceFileEntry->qsDisplayName);

	delete pDialog;
}

void SourceToolBar::refreshToolBarEntries()
{
  uint t, i;
  QColor statusColor;
  SourceFileEntry *pEntry;
  SourceFileInfo *pInfo;
  // This function will remove all entries from all listBox objects and re-create all information from
  // The current m_listSourceFileEntries.
  m_pListViewAllSources  ->clear ();
  m_pSourceWidget->m_pListViewVideoSources->clear ();
  m_pSourceWidget->m_pListViewAudioSources->clear ();
  for (t=0;t<m_listSourceFileEntries.count();t++)	{
    pEntry = m_listSourceFileEntries[t];
    // Okay here we decide if we have a Movie or sound stream ...
    //		if (pEntry->listFileInfos[0]->qsSample.isEmpty())	{
    if (!pEntry->bSoundSource)	{
      statusColor = QColor(COLOR_MOVIE_FILES_OK);
      for (i=0;i<pEntry->listFileInfos.count();i++)	{
	pInfo = pEntry->listFileInfos[i];
	// Here we check that ALL sources are ok
	if (pInfo->qsStatus != QString ("Ok"))
	  statusColor = QColor(COLOR_MOVIE_FILES_BAD);
	  
	  new QListViewItem (m_pSourceWidget->m_pListViewVideoSources, pInfo->qsVideoFormat,
			     pInfo->qsResolution, pInfo->qsLength, pInfo->qsSize, pInfo->qsRatio,
			     pInfo->qsFPS, pInfo->qsStatus, pInfo->qsFileName);
      }
    }
    else 	{
      statusColor = QColor (COLOR_SOUND_FILES_OK);
      for (i=0;i<pEntry->listFileInfos.count();i++)	{
	pInfo = pEntry->listFileInfos[i];
	if (pInfo->qsStatus != QString ("Ok"))
	  statusColor = QColor (COLOR_SOUND_FILES_BAD);
	
	new QListViewItem (m_pSourceWidget->m_pListViewAudioSources, pInfo->qsAudioFormat,
			   pInfo->qsLength, pInfo->qsBits, pInfo->qsSample, pInfo->qsBPS,
			   pInfo->qsSize,  pInfo->qsStatus, pInfo->qsFileName);
      }
    }
    new ListViewItemMedia (m_pListViewAllSources, pEntry, statusColor);
  }
}

void SourceToolBar::slotDeleteSource()
{
	QListViewItem *pItem = m_pListViewAllSources->currentItem();
	if (!pItem)
		return;

	QString qsCurrentText = pItem->text(SOURCE_FILE_ENTRY_NAME);
	// Okay now I added the total play time also to the filename, we should 
	// disregard this from here ... E.g. "Title.mpg\n00:13:01"
	int iPos = qsCurrentText.find ("\n");
	qsCurrentText = qsCurrentText.left (iPos);
	// Called when the user right clicks in the SourceFileEntry - list
	SourceFileEntry *pSourceFileEntry = getCurrentSourceFileEntry ();
	if (!pSourceFileEntry)
		return;

	if ( (!pSourceFileEntry->bSoundSource) && (m_pDVDAuthor) )	{
		// Okay we should politely check if this source is in use by a button.
		if (m_pDVDAuthor->isSourceEntryUsed(qsCurrentText))	{
			if (MessageBox::warning (NULL, tr ("Warning, This source is in use."),
				tr ("This Source is in use.\nDo you realy want to delete this source ?\n"), 
				QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
					return;
		}
	}

	removeEntry (qsCurrentText, false);
}

void SourceToolBar::removeEntry (QString &qsEntry, bool bSourceOnly)
{
	uint t;
	QFileInfo fileInfo;
	SourceFileInfo  *pSourceFileInfo = NULL;
	SourceFileEntry *pSourceFileEntry = getCurrentSourceFileEntry ();
	if (!pSourceFileEntry)
		return;
	// First we check if the user wants to remove a whole SourceFileEntry
	if (pSourceFileEntry->qsDisplayName == qsEntry)	{
		// Here we remove the full entry from the m_listSourceFileEntris - list.
		removeEntry (pSourceFileEntry, bSourceOnly);
		// At this point we can delete the pSourceFileEntry ...
		delete pSourceFileEntry;
	}
	else {	// Okay here we check for the sourecFileInfo's ...
		for (t=0;t<pSourceFileEntry->listFileInfos.count();t++)	{
			pSourceFileInfo = pSourceFileEntry->listFileInfos[t];
			fileInfo.setFile (pSourceFileInfo->qsFileName);
			if (fileInfo.fileName() == qsEntry)	{
				pSourceFileEntry->listFileInfos.remove   ( pSourceFileInfo );
				MediaCreator::unregisterFromMediaScanner ( pSourceFileInfo );
				delete pSourceFileInfo;
				refreshToolBarEntries ();
				// Check if we have just removed the last source from this entry.
				if (pSourceFileEntry->listFileInfos.count () < 1)	{
					// in which case we want to alos delete the header ...
					removeEntry (pSourceFileEntry, bSourceOnly);
					delete pSourceFileEntry;
					return;
				}
			}
		}
	}
}

void SourceToolBar::removeEntry (SourceFileEntry *pSourceFileEntry, bool bSourceOnly)
{
	// This function is also called from UndoObjects.
	uint t;
	QStringList listFileNames;
	if (!pSourceFileEntry)
		return;
	m_listSourceFileEntries.remove (pSourceFileEntry);

	// The first thing we should ensure is that we are not registered with the MediaScanner, which could crash QDVDAuthor
	for (t=0;t<pSourceFileEntry->listFileInfos.count();t++)
	  MediaCreator::unregisterFromMediaScanner ( pSourceFileEntry->listFileInfos[t] );

	// Next we remove the entry from the AllSources - Tab
	QValueList<QListViewItem *> listDelItems;
	QListViewItem *pItem = m_pListViewAllSources->firstChild();
	for (t=0;t<(uint)m_pListViewAllSources->childCount();t++)	{
		if (pItem->text(SOURCE_FILE_ENTRY_NAME) == pSourceFileEntry->qsDisplayName)	{
			// Here we remove this entry from m_pListViewAllSources - widget.
			listDelItems.append (pItem);
		}
		pItem = pItem->nextSibling();
	}
	for (t=0;t<listDelItems.count();t++)
		delete listDelItems[t];
	listDelItems.clear();

	// we ceate here a temp list of all file names ...
	for (t=0;t<pSourceFileEntry->listFileInfos.count();t++)
		listFileNames.append(pSourceFileEntry->listFileInfos[t]->qsFileName);

	pItem = m_pSourceWidget->m_pListViewVideoSources->firstChild();
	while (pItem)	{
		// Here we remove this entry from m_pListViewVideos - widget.
		for (t=0;t<pSourceFileEntry->listFileInfos.count();t++)	{
			if (pItem->text(MOVIE_FILE_NAME_INDEX) == listFileNames[t])	{
				listDelItems.append(pItem);
				// FIXME: If we use SourceFileEntry->qsDisplay name rather then the single filename, we are better off here
				//        Since we remove only the associated files and leave the others untouched.
				// Okay if the user has the same file multiple times in there we only want to remove the entry once.
				listFileNames[t] = QString ("");
			}
		}
		pItem = pItem->nextSibling();
	}
	// And here we delete the items
	for (t=0;t<listDelItems.count();t++)
		delete listDelItems[t];
	listDelItems.clear();

	pItem = m_pSourceWidget->m_pListViewAudioSources->firstChild();
	while (pItem)	{
		// Here we remove this entry from m_pListViewAudio - widget.
		for (t=0;t<pSourceFileEntry->listFileInfos.count();t++)	{
			if (pItem->text(AUDIO_FILE_NAME_INDEX) == listFileNames[t])	{
				listDelItems.append(pItem);
				// Okay if the user has the same file multiple times in there we only want to remove the entry once.
				listFileNames[t] = QString ("");
			}
		}
		pItem = pItem->nextSibling();
	}
	for (t=0;t<listDelItems.count();t++)
		delete listDelItems[t];
	// If we should only remove the entry in the SoureToolBar and leave the ones in QDVDAuthor as is
	// This is the case when we create a new entry. The first thing done is to remove all
	// double entries but we want to leave the entries in the Menus intact.
	if (m_pDVDAuthor && !bSourceOnly)
		// So the user has decided to delete this source, then we should change the associated
		// buttons - action !!!
		m_pDVDAuthor->removedSourceEntry(pSourceFileEntry);
}

void SourceToolBar::slotPlayMovie()
{
	// Called when the user right clicks in the SourceFileEntry - list
	uint i;
	QString qsCommand = QString ("%1 ").arg(Global::qsExternalPlayer);
	SourceFileEntry *pSourceFileEntry = NULL;
	SourceFileInfo  *pSourceFileInfo  = NULL;

	ListViewItemMedia *pItem = (ListViewItemMedia *)m_pListViewAllSources->currentItem();
	if (!pItem)
		return;
	pSourceFileEntry = pItem->sourceFileEntry ();
	pSourceFileInfo  = pItem->sourceFileInfo  ();
	if (pSourceFileEntry)	{
		for (i=0;i<pSourceFileEntry->listFileInfos.count();i++)
			qsCommand += QString ("\"%1\" ").arg(pSourceFileEntry->listFileInfos[i]->qsFileName);
	}
	else	{
		if (!pSourceFileInfo)	// This should never happen but to make sure ...
			return;
		qsCommand += QString ("\"%1\" ").arg(pSourceFileInfo->qsFileName);
	}
	// Here we execute the external QXine video viewer application ...
	qsCommand += QString (" &");
	if ( system ((const char *)qsCommand) == -1)
		return;
}

// the following two functions are called from CSlideDialog, if avail ...
void SourceToolBar::slotAddSlideshow (QString qsSlideshowName)
{
	if ( ! m_pDVDAuthor->checkForNewProject () )
		return;

	// Lets create a new SourceFileEntry ...
	SourceFileEntry *pEntry = new SourceFileEntry;
	SourceFileInfo  *pInfo  = new SourceFileInfo;
	// Here we create the temp image
	pEntry->sizeThumbnail = m_pDVDAuthor->getDragNDropContainer()->sizeThumbnail;
	pInfo->pPreview  = new QImage (QImage().fromMimeSource( "create_slideshow.jpg" ));
	*pInfo->pPreview = pInfo->pPreview->smoothScale (m_pDVDAuthor->getDragNDropContainer()->sizeButton, QImage::ScaleMin);

	pEntry->bIsSlideshow = true;
	pInfo->qsFileName    = qsSlideshowName;
	pEntry->listFileInfos.append(pInfo);
	pEntry->qsDisplayName.sprintf ("[%02d] - %s", getFreeSourceSlot (), (const char *)qsSlideshowName);
	m_listSourceFileEntries.append(pEntry);
	// Okay, now we should also add this into the list box ...
	new ListViewItemMedia (m_pListViewAllSources, pEntry, QColor (COLOR_SLIDE_FILES_OK));
}

void SourceToolBar::slotSlideshowDone(QString qsSlideshowName, QString qsFileName)
{
	Utils theUtil;
	uint t;
	int iListBoxPosition = -1;
	SourceFileEntry *pEntry;
	QString qsItemText;
	QFileInfo fileInfo;
	QListViewItem *pItem, *pParentItem = m_pListViewAllSources->firstChild();
	for (t=0;t <(uint)m_pListViewAllSources->childCount();t++)	{
		if ( ! pParentItem )
			continue;
		pItem = pParentItem->firstChild ();
		if ( ! pItem )
			continue;
		qsItemText = pItem->text(SOURCE_FILE_ENTRY_NAME);
		qsItemText.remove ("\n");
		if (qsItemText == qsSlideshowName)	{
			iListBoxPosition = t;
			break;
		}
		pParentItem = pParentItem->nextSibling();
	}
	// Error ...
	if ( ! pParentItem )
		return;
	
	for (t=0;t<m_listSourceFileEntries.count();t++)	{
		pEntry = m_listSourceFileEntries[t];
		if (pEntry->qsDisplayName.find(qsSlideshowName) != -1)	{
			// First we determine the fileName of the generated mpeg video ...
			QFileInfo fileInfo (pEntry->listFileInfos[0]->qsFileName);
			pEntry->listFileInfos[0]->qsFileName = qsFileName; //theUtil.getTempFile(fileInfo.fileName()+QString (".mpeg"));
			pEntry->bIsSlideshow = false;	// now we hold a mpeg and not a xml - file ...
			pEntry->bSoundSource = false;

			delete pParentItem;
			new ListViewItemMedia (m_pListViewAllSources, pEntry,QColor (COLOR_MOVIE_FILES_OK));
			SourceFileInfo *pInfo = pEntry->listFileInfos[0];
			fileInfo.setFile ( qsFileName );
			qsFileName = QString ("%1/%2.xml").arg(fileInfo.dirPath( TRUE )).arg(fileInfo.baseName ());
			importChapters ( qsFileName, pInfo );
			new QListViewItem (m_pSourceWidget->m_pListViewVideoSources, pInfo->qsVideoFormat,
				pInfo->qsResolution, pInfo->qsLength, pInfo->qsSize, pInfo->qsRatio,
				pInfo->qsFPS, pInfo->qsStatus, pInfo->qsFileName);
			MediaCreator::registerWithMediaScanner (this, pInfo);
			return;
		}
	}
	m_pDVDAuthor->slotAutosave ();
}

void SourceToolBar::importChapters( QString qsChaptersFileName, SourceFileInfo *pInfo )
{
	int iRead;
	uint t;
	Utils theUtils;
	QString qsChaptersString, qsChapters, qsFileName;

	if (qsChaptersFileName.isNull ())
		return;

	QFile chaptersFile (qsChaptersFileName);
	chaptersFile.open( IO_ReadOnly );
	// Let us read in at max 16k of chapters ... Why 16k .. Just a guess !
	iRead = chaptersFile.readLine (qsChaptersString, 16000);
	// Error checking ...
	if (iRead < 1)
		return;
	
	// And finally we get to parse this string. Please note this is a very basic
	// parser for a very basic syntax a la <vob chapters="0,0:0:14.0,0:0:22.0" file="/tmp/slideshow.mpeg.mpg"  />
	qsChapters = theUtils.getAttribute("chapters", qsChaptersString);

	// Now let us split some hair here ...
	QStringList listChapters = QStringList::split (",", qsChapters);
	if (listChapters.count() < 1)
		return;
	// Here we format the Chapter strings ...
	for (t=0;t<listChapters.count();t++)	
		listChapters[t] = theUtils.formatChapter(listChapters[t]);
	// Note that this is called Import ... Thus we remove any older chapters or this entry ...
	pInfo->listChapters = listChapters;
}

void SourceToolBar::clear ()
{
	uint t;
	for (t=0;t<m_listSourceFileEntries.count();t++)
		delete m_listSourceFileEntries[t];
	m_listSourceFileEntries.clear();

	m_pListViewAllSources  ->clear();
	m_pSourceWidget->m_pListViewVideoSources->clear();
	m_pSourceWidget->m_pListViewAudioSources->clear();
}
