/****************************************************************************
** Form implementation generated from reading ui file 'uidialogmovie.ui'
**
** Created: Fri April 9 22:06:51 2004
**      by: Varol Okan using the kate text editor
**
** This Dialog helps to generate background movie files for as menu. It is
** NOT intended in converting a movie file to mpeg2. THis is done using
** the transcode command line tool.
**
** Here we are using xine-lib to display the video in the MoviePreview - pane
** and then extract the video/audio fo rthe set length.
**
****************************************************************************/

#include <stdlib.h>
#include <unistd.h>

#include <qpushbutton.h>
#include <qcombobox.h>
#include <qlistview.h>
#include <qpixmap.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qdir.h>
#include <qmessagebox.h>
#include <qinputdialog.h>
#include <qslider.h>
#include <qpainter.h>
#include <qlayout.h>
#include <qstringlist.h>
#include <qtabwidget.h>
#include <qlistbox.h>
#include <qfiledialog.h>
#include <qlistview.h>

#include "qplayer_global.h"
#include "sourcefiledialog.h"
#include "listviewfileitem.h"

#include "../sourcefileentry.h" 

#if 0
#ifndef QPLAYER_ONLY
#define QPLAYER_ONLY 1
#include "../dialogmovie.h"
#undef QPLAYER_ONLY
#endif
#endif

#include "mediacreator.h"
#include "mediainfo.h"

/*
TODO: 
-	Autodetection of the Desktop directory for gnome ???
-	If changing the tab, the Start/Stop marker do not get drawn.
-	Handling of the Movie title. This should probably be something like >Format PAL 720x568 29.97Hz< or >Format jpg 1024x768<
-	Implementation of greying out for Image files the movie buttons, slider bar.
-	Implementation of all movie button functionalities -> simply forward them to MoviePreview.
-	Finishing of all image functions.
*/

SourceFileDialog::SourceFileDialog( void *pXineEngine, QWidget* parent, int iTab, const char* name, bool modal, WFlags fl )
    : uiSourceFileDialog ( parent, name, modal, fl )
{
	initMe (iTab, pXineEngine);
}

SourceFileDialog::SourceFileDialog( QWidget* parent, int iTab, const char* name, bool modal, WFlags fl )
    : uiSourceFileDialog ( parent, name, modal, fl )
{
	initMe (iTab);
}


SourceFileDialog::~SourceFileDialog()
{
}

#include <qimage.h>
void SourceFileDialog::initMe (int iTab, void *pExistingEngine)
{
	m_pOriginalSourceFileEntry = NULL;
	m_pCurrentSourceFileEntry = NULL;
	m_pActiveQuickButton = NULL;
	m_pMediaInterface = NULL;
	// Initial directories ...
	m_qsProjectDir   = QDir::currentDirPath() + QString ("/");
	m_qsHomeDir      = QDir::homeDirPath() + QString ("/");
	m_qsRootDir      = QDir::rootDirPath();
	m_qsDocumentsDir = m_qsHomeDir + QString ("Desktop/Documents/");
	m_qsDesktopDir   = m_qsHomeDir + QString ("Desktop/");
	m_qsTempDir      = QString (STATIC_TEMP);
	m_iHistoryMax    = 15;
	
	// Here we refine the Desktop directory ...
	QString qsRCDir = m_qsHomeDir + QString (".kderc");
	QString qsDesktopDir;
	bool bFound = findDesktopDir (qsRCDir);
	if (!bFound) 	{
		qsRCDir = QString ("/etc/kderc");
		bFound = findDesktopDir (qsRCDir);
	}
	if (bFound)	{
		// So we found the kde default directory, we should use it
		// instead of my dummy directory (if present).
		QFile file (STATIC_TEMP"lucas.txt");
		file.open (IO_ReadOnly);
		m_qsDesktopDir = QString ();
		QString qsLine;
		while (file.readLine(qsLine, 2048) > -1)	{
 			qsDesktopDir += qsLine;
		}
		file.close();
		if (qsDesktopDir.length() > 1)
			m_qsDesktopDir = qsDesktopDir;
	}
	// And we should also search for a Documents directory ...
	const char *pArray[5] = {"Documents", "documents", "MyDocuments", "myDocuments", "mydocuments" };
	QString qsDocs, qsPreDir = m_qsDesktopDir;
	QDir docDir;
	int t, i;
	// The first time we are looking under the desktop directory for the documents directory.
	for (i=0;i<2;i++)	{
		for (t=0;t<5;t++)	{
			qsDocs = qsPreDir + QString (pArray[t]);
			docDir.setPath(qsDocs);
			if (docDir.exists())	{
				m_qsDocumentsDir = qsDocs;
				t = i = 6; 	// exit both loops ...
			}
		}
		qsPreDir = m_qsHomeDir;	// the second time around we are searching in the Home Directory
	}
	m_pTabWidget->setCurrentPage        (iTab);
	m_pButtonSourceSave->setEnabled    (false);
	m_pButtonSourceDel->setEnabled     (false);
	m_pButtonSourceUp->setEnabled      (false);
	m_pButtonSourceDown->setEnabled    (false);
	m_pButtonDeleteChapter->setEnabled (false);

	// Here we disable sorting because we rely on the order we put the entries in there ...
	m_pListViewSourceEntry->setSorting (-1);
	// Here we create the QXineWidget with the QFrame (m_pMoviePreview) as parent.
	m_pMediaInterface = MediaCreator::createPreferredWidget (m_pMoviePreview, "MediaWidget", pExistingEngine);

	if (!m_pMediaInterface)
		return;
	m_pVideoLayout = new QGridLayout (m_pMoviePreview, 1, 1, 4, 6, "MediaMainLayout");
	m_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_pMediaInterface->openMRL        (QString());
//	m_pMediaInterface->getScreenshot  ();

	m_pButtonProject  ->setPixmap( QPixmap::fromMimeSource ( "project.png" ));
	m_pButtonDocuments->setPixmap( QPixmap::fromMimeSource ( "documents.png" ));
	m_pButtonDesktop  ->setPixmap( QPixmap::fromMimeSource ( "desktop.png" ));
	m_pButtonHome     ->setPixmap( QPixmap::fromMimeSource ( "home.png" ));
	m_pButtonRoot     ->setPixmap( QPixmap::fromMimeSource ( "root.png" ));
	m_pButtonTemp     ->setPixmap( QPixmap::fromMimeSource ( "temp.png" ));

	m_pButtonFForward ->setPaletteBackgroundColor (QColor (COLOR_QUICK_NORMAL));
	m_pButtonForward  ->setPaletteBackgroundColor (QColor (COLOR_QUICK_NORMAL));
	m_pButtonStop     ->setPaletteBackgroundColor (QColor (COLOR_QUICK_SELECTED));
	m_pButtonBackward ->setPaletteBackgroundColor (QColor (COLOR_QUICK_NORMAL));
	m_pButtonFBackward->setPaletteBackgroundColor (QColor (COLOR_QUICK_NORMAL));

	connect (m_pButtonProject,   SIGNAL (clicked ()), this, SLOT(slotQuickDir()));
	connect (m_pButtonDocuments, SIGNAL (clicked ()), this, SLOT(slotQuickDir()));
	connect (m_pButtonDesktop,   SIGNAL (clicked ()), this, SLOT(slotQuickDir()));
	connect (m_pButtonHome,      SIGNAL (clicked ()), this, SLOT(slotQuickDir()));
	connect (m_pButtonRoot,      SIGNAL (clicked ()), this, SLOT(slotQuickDir()));
	connect (m_pButtonTemp,      SIGNAL (clicked ()), this, SLOT(slotQuickDir()));
	connect (m_pButtonOk,        SIGNAL (clicked ()), this, SLOT(accept()));

	connect (m_pButtonBack,            SIGNAL (clicked ()), this, SLOT(slotDirectoryBack()));
	connect (m_pButtonUp,              SIGNAL (clicked ()), this, SLOT(slotDirectoryUp  ()));
	connect (m_pButtonNewDirectory,    SIGNAL (clicked ()), this, SLOT(slotDirectoryNew ()));

	connect (m_pComboFileType,         SIGNAL(activated (int)), this, SLOT (slotFilterChanged (int)));
	connect (m_pComboDirectoryHistory, SIGNAL(activated (const QString &)), this, SLOT (slotDirectoryHistoryChanged(const QString &)));
	connect (m_pEditFileName,          SIGNAL(returnPressed ()), this , SLOT(slotFileNameChanged()));

	connect (m_pListViewFiles,      SIGNAL(pressed (QListViewItem *, const QPoint &, int)), this , SLOT(slotListViewPressed(QListViewItem *, const QPoint &, int)));
	connect (m_pListViewFiles,      SIGNAL(doubleClicked (QListViewItem *)), this , SLOT(slotListViewDoubleClicked(QListViewItem *)));
//	connect (m_pListViewFiles,      SIGNAL(doubleClicked (QListViewItem *, const QPoint &, int)), this , SLOT(slotListViewDoubleClicked(QListViewItem *, const QPoint &, int)));

	connect (m_pButtonFBackward,    SIGNAL(clicked()), this, SLOT(slotFBackward()));
	connect (m_pButtonBackward,     SIGNAL(clicked()), this, SLOT(slotBackward()));
	connect (m_pButtonStop,         SIGNAL(clicked()), this, SLOT(slotStop()));
	connect (m_pButtonForward,      SIGNAL(clicked()), this, SLOT(slotForward()));
	connect (m_pButtonFForward,     SIGNAL(clicked()), this, SLOT(slotFForward()));
	connect (m_pButtonSetAsStart,   SIGNAL(clicked()), this, SLOT(slotSetAsStart()));
	connect (m_pButtonSetAsEnd,     SIGNAL(clicked()), this, SLOT(slotSetAsEnd()));

	connect (m_pSliderPosition,     SIGNAL(valueChanged (int)), this, SLOT(slotSliderValueChanged(int)));
	connect (m_pEditFrameNumber,    SIGNAL(returnPressed()), this, SLOT(slotNewFrameNumber()));
	connect (m_pEditSourceFileName, SIGNAL(lostFocus()), this, SLOT(slotSourceNameChanged()));

	// Here the connection for the SourceFileEntry - tab
	connect (m_pButtonSourceAdd,    SIGNAL (clicked ()), this, SLOT(slotSourceAdd()));
	connect (m_pButtonSourceSave,   SIGNAL (clicked ()), this, SLOT(slotSourceSave()));
	connect (m_pButtonSourceDel,    SIGNAL (clicked ()), this, SLOT(slotSourceDel()));
	connect (m_pButtonSourceDown,   SIGNAL (clicked ()), this, SLOT(slotSourceDown()));
	connect (m_pButtonSourceUp,     SIGNAL (clicked ()), this, SLOT(slotSourceUp()));
	connect (m_pButtonImportChapter,SIGNAL (clicked ()), this, SLOT(slotSourceImportChapter()));
	connect (m_pButtonEditChapter,  SIGNAL (clicked ()), this, SLOT(slotSourceEditChapter()));
	connect (m_pButtonDeleteChapter,SIGNAL (clicked ()), this, SLOT(slotSourceDeleteChapter()));

	connect (m_pListViewSourceEntry,SIGNAL (selectionChanged(QListViewItem *)), this, SLOT(slotSourceSelectionChanged (QListViewItem *)));
	connect (m_pListBoxChapters,    SIGNAL (selectionChanged()),                this, SLOT(slotSourceChaptersSelectionChanged ()));
	initDirectoryHistory();
	setCurrentDir (m_qsProjectDir);

	// Here we draw the Start/Stop marker on the m_pFrameStartStop.
	drawStartStopMarker (0, 1000);

	m_pEditFileName->setMinimumWidth(420);
}

void SourceFileDialog::setProjectDir (QString qsProjectDir)
{
	m_qsProjectDir = qsProjectDir;
}

void SourceFileDialog::setDocumentsDir (QString qsDocumentsDir)
{
	m_qsDocumentsDir = qsDocumentsDir;
}

void SourceFileDialog::setDesktopDir (QString qsDesktopDir)
{
	m_qsDesktopDir = qsDesktopDir;
}

void SourceFileDialog::setTempDir (QString qsTempDir)
{
	m_qsTempDir = qsTempDir;
}

bool SourceFileDialog::findDesktopDir (QString qsDir)
{
	// This function takes an input file and searches it for the Desktop=... entry.
	// It will then invoke the shell to write the absolute path into a file in the temp directory.
	bool bReturn = false;
	QFile file (qsDir);
	if ( file.open( IO_ReadOnly ) ) {
		QTextStream stream( &file );
		QString line;
		while ( !stream.atEnd() ) {
			line = stream.readLine(); // line of text excluding '\n'
			if (line.find ("Desktop=") != -1)	{
				// found the coresponding line Desktop=$HOME/KDesktop or similar
				QStringList theList;
				theList = QStringList::split( QString("="), line );
				if (theList.count() > 1)	{
					// here we get the complete path to the Desktop ...
					QString command = QString ("echo -n ") + theList[1] + QString (" > /tmp/lucas.txt");
					if ( system (command) == -1 )
						bReturn = false;
					bReturn = true;
				}
			}
		}
		file.close();
	}
	return bReturn;
}

void SourceFileDialog::setCurrentDir (QString qsDir)
{
	// Here we set the Directory selector on the top, which holds a History of the previous
	// visited directories ...
	addDirectoryHistory (qsDir);
	setCurrentDir ();
}

void SourceFileDialog::slotDirectoryHistoryChanged(const QString &)
{
	setCurrentDir ();
}

QString SourceFileDialog::getPermissions (QString qsFileName)
{
	// Yeah, what I need to get from my wife now ... But if she's asleep, I call this function instead.
	int iPermissionArray[9] = {
			//QFileInfo::ReadOwner - The file is readable by the owner of the file.
			//QFileInfo::WriteOwner - The file is writable by the owner of the file.
			//QFileInfo::ExeOwner - The file is executable by the owner of the file.
			QFileInfo::ReadUser, // - The file is readable by the user.
			QFileInfo::WriteUser,	// - The file is writable by the user.
			QFileInfo::ExeUser,	// - The file is executable by the user.
			QFileInfo::ReadGroup,	// - The file is readable by the group.
			QFileInfo::WriteGroup,	// - The file is writable by the group.
			QFileInfo::ExeGroup,	// - The file is executable by the group.
			QFileInfo::ReadOther,	// - The file is readable by anyone.
			QFileInfo::WriteOther,	// - The file is writable by anyone.
			QFileInfo::ExeOther};	// - The file is executable by anyone.
	QString qsPermissions;
	char cPermission[12];
	int t;
	for (t=0;t<10;t++)
		cPermission[t] = '-';
	cPermission[10] = 0;	// the termination '0' for a string
	QFileInfo fileInfo (qsFileName);
	for (t=0;t<3;t++)	{
		if (fileInfo.permission(iPermissionArray[3*t]))
			cPermission [3*t+1] = 'r';
		if (fileInfo.permission(iPermissionArray[3*t+1]))
			cPermission [3*t+2] = 'w';
		if (fileInfo.permission(iPermissionArray[3*t+2]))
			cPermission [3*t+3] = 'x';
	}
	if (fileInfo.isDir())
		cPermission[0] = 'd';
	qsPermissions = QString ((char *)cPermission);
	return qsPermissions;
}

QString SourceFileDialog::getFileName()
{
	return m_pEditFileName->text();
}

void SourceFileDialog::accept()
{
	// Let us take care of some things ...
	if (m_pCurrentSourceFileEntry)	{
		// Let us give the currentSourceFileEntry the name the user chosen to.
		if (!m_pEditSourceFileName->text().isEmpty())
			m_pCurrentSourceFileEntry->qsDisplayName = m_pEditSourceFileName->text();
		// And here we copy the temp object's information over into the original ...
		*m_pOriginalSourceFileEntry = *m_pCurrentSourceFileEntry;
		// delete the temp object 
		delete m_pCurrentSourceFileEntry;
	}
	// and return 
	uiSourceFileDialog::accept();
}

/////////////////////////////////////////////////////////////////////////////
//
// The functions for the QuickDir selector.
//
// This is the sidebar on the left side.
//
/////////////////////////////////////////////////////////////////////////////
void SourceFileDialog::slotQuickDir()
{
	// here we handle the quick directory buttons on the left side
	// of this dialog. They ought to be tagglod uniquely.
	QPushButton *pButtonArray[6] = {m_pButtonProject, m_pButtonDocuments, m_pButtonDesktop,
		m_pButtonHome, m_pButtonRoot, m_pButtonTemp};
	QString *pStringArray[6] = {&m_qsProjectDir, &m_qsDocumentsDir, &m_qsDesktopDir,
		&m_qsHomeDir, &m_qsRootDir, &m_qsTempDir};

	int t;
	for (t=0;t<6;t++)	{
		if ( (pButtonArray[t]->isOn()) && (pButtonArray[t] != m_pActiveQuickButton) )	{
			setCurrentDir (*pStringArray[t]);
		}
	}
	m_pTabWidget->setCurrentPage (0);
}

void SourceFileDialog::setQuickDir (int iCurrent)
{
	QPushButton *pButtonArray[6] = {m_pButtonProject, m_pButtonDocuments, m_pButtonDesktop,
		m_pButtonHome, m_pButtonRoot, m_pButtonTemp};
	QLabel *pLabelArray[6] = {m_pLabelProject, m_pLabelDocuments, m_pLabelDesktop,
		m_pLabelHome, m_pLabelRoot, m_pLabelTemp};

	int t;
	for (t=0;t<6;t++)	{
		if ( t == iCurrent )	{
				m_pActiveQuickButton = pButtonArray[t];
				pButtonArray[t]->setOn (true);
				pButtonArray[t]->setPaletteBackgroundColor( QColor( COLOR_QUICK_SELECTED ) );
				pLabelArray[t] ->setPaletteBackgroundColor( QColor( COLOR_QUICK_SELECTED ) );
		}
		else	{
			pButtonArray[t]->setOn (false);
			pButtonArray[t]->setPaletteBackgroundColor( QColor( COLOR_QUICK_NORMAL ) );
			pLabelArray[t] ->setPaletteBackgroundColor( QColor( COLOR_QUICK_NORMAL ) );
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
//
// The functions for the Movie/Image Selection - tab
//
// These functions are exclusively handling of the XinePreview - Widget.
//
/////////////////////////////////////////////////////////////////////////////
void SourceFileDialog::setCurrentDir ()
{
	// Here we display the directory files/directories
	int t, iCurrent=-1;
	QDir theDir;
	QString qsDir = m_pComboDirectoryHistory->currentText();
	QDir::setCurrent(qsDir);
	// Next we should get the current file list ... m_pListViewFiles
	m_pListViewFiles->clear ();

	// Name Size Type Date Attributes
	QFileInfo fileInfo;
	QListViewItem *pItem;
	QString qsAttributes;
	// First we want only the Directories ...
	theDir.setNameFilter ("*");
	for (t=0;t<(int)theDir.count();t++)	{
		fileInfo.setFile(theDir[t]);
		qsAttributes = getPermissions (theDir[t]);
		if ( (fileInfo.isDir()) && (fileInfo.fileName() != QString (".")) )
			pItem = new ListViewFileItem (m_pListViewFiles,
				fileInfo.fileName(),
				QString (),
				QString (),
				fileInfo.lastModified().toString(Qt::ISODate),
				qsAttributes );

	}
	// Next we want the files, but only the filtered ones ...
	theDir.setNameFilter (getFileTypes ());
	for (t=0;t<(int)theDir.count();t++)	{
		fileInfo.setFile(theDir[t]);
		qsAttributes = getPermissions (theDir[t]);
		if (!fileInfo.isDir())
			pItem = new ListViewFileItem (m_pListViewFiles,
				fileInfo.fileName(),
				QString ("%1").arg(fileInfo.size()),
				fileInfo.extension(),
				fileInfo.lastModified().toString(Qt::ISODate),
				qsAttributes );

	}

	for (t=0;t<6;t++)	{
		if (qsDir == m_qsProjectDir)
			iCurrent = 0;
		else if (qsDir == m_qsDocumentsDir)
			iCurrent = 1;
		else if (qsDir == m_qsDesktopDir)
			iCurrent = 2;
		else if (qsDir == m_qsHomeDir)
			iCurrent = 3;
		else if (qsDir == m_qsRootDir)
			iCurrent = 4;
		else if (qsDir == m_qsTempDir)
			iCurrent = 5;
	}
	setQuickDir (iCurrent);
}

void SourceFileDialog::initDirectoryHistory()
{
	// This function inits the Directory History Combo box.
	// It takes the current path and takes  each path down to the root path.
	uint t;
	QString qsDirectory;

	QDir theDir;
	QString qsCurrentDir = theDir.currentDirPath();

	QStringList listPath = QStringList::split (QString ("/"),qsCurrentDir);
	qsDirectory = QString ("/");
	for (t=0;t<listPath.count()-1;t++)	{
		qsDirectory += listPath[t] + QString ("/");
		addDirectoryHistory (qsDirectory);
	}
}

void SourceFileDialog::addDirectoryHistory(QString qsDirectory)
{
	// Here we add the current directory but cut out the last if we are over the limit ...
	QStringList listDirectories;
	int t, iCutoff = 0;
	if (m_pComboDirectoryHistory->count() > m_iHistoryMax)
		iCutoff = 1;
	// Okay now let us construct the list ...
	listDirectories.append (qsDirectory);
	for (t=m_pComboDirectoryHistory->currentItem();t<m_pComboDirectoryHistory->count()-iCutoff;t++)
		listDirectories.append (m_pComboDirectoryHistory->text (t));

	// and finally we clear the entries and insert the new list ...
	m_pComboDirectoryHistory->clear ();
	m_pComboDirectoryHistory->insertStringList (listDirectories);
}

QString SourceFileDialog::getFileTypes ()
{
	// This function gets all filter out of m_pComboFileType -> like Image Files (*.jpg *.bmp)
	uint iCurrentItem;
	QString qsReturn;

	// Lets check if the user typed in a filter in the FileName LineEdit ...
	if (!m_qsManualFilter.isEmpty())
		return m_qsManualFilter;

	iCurrentItem = m_pComboFileType->currentItem();
	qsReturn = QString ("*");
	if (iCurrentItem <m_listFileType.count())
		qsReturn = m_listFileType[iCurrentItem];
	return qsReturn;
}

void SourceFileDialog::setFileTypes (QStringList listFilter)
{
	// One convention here :
	// If we want to add all supported movie files to the list, then the 
	// user supplied string should be as follows:
	// "Movie/Image Files ( +Movies+ *.jpg *.png)"
	uint t, i, j;
	int iStartPos, iEndPos;
	// First we take care of the Combo box.
	m_pComboFileType->clear ();
	// next we handle the fileType - list.
	m_listFileType.clear ();
	for (t=0;t<listFilter.count ();t++)	{
		iStartPos = listFilter[t].find ('(');
		iEndPos = listFilter[t].find (')');
		// error checking ...
		if ( (iStartPos == -1) || (iEndPos == -1) )
			continue;
		QString qsFilter = listFilter[t].mid (iStartPos+1, iEndPos-iStartPos-1);
		QStringList listFilterPart = QStringList::split(" ", qsFilter);
		qsFilter = QString();
		// Here we build the filter list ...
		for (i=0; i<listFilterPart.count();i++)	{
			// We will first check if the user wants us to add all of Xines supported extensions
			if (listFilterPart[i] == QString("+Movies+"))	{
				// Okay here we add all supported ovie formats to the current list.
				QString qsMediaEngineExtensions = m_pMediaInterface->supportedExtensions ();
				if (qsMediaEngineExtensions.isEmpty())	{
					MediaInfo *pInfo = MediaCreator::createInfo(m_pMediaInterface->getMediaEngine());
					qsMediaEngineExtensions  = pInfo->getExtensions(true);
					delete pInfo;
				}
//				QString qsXineExtensions("*.mpg *.mpeg *.avi *.wmf *.wmv");
				QStringList listXineParts = QStringList::split (" ", qsMediaEngineExtensions);
				for (j=0;j<listXineParts.count();j++)	{ 
//					qsFilter += QString ("*.") + listXineParts[j] + QString (" ");
					qsFilter += listXineParts[j] + QString (" ");
				}
			}
			else 
				qsFilter += listFilterPart[i] + QString (" ");
		}
		// The FileType entry is something like "*.jpg *.mpg *.m2v"
		m_listFileType.append (qsFilter);
		m_pComboFileType->insertItem (listFilter[t].left (iStartPos+1) + qsFilter + QString (")"));
	}
	setCurrentDir();
}

void SourceFileDialog::slotListViewPressed(QListViewItem *pItem, const QPoint &, int)
{
	// Here we take the current item and display it in the FileName Edit ...
	// But only if it is a file and not a directory !!!
	// We also stop playing the actual image/movie (if any) and display a black background.
	if (pItem->text(4)[0] == 'd')
		return;
	m_qsManualFilter = QString ();
	m_pEditFileName->setText (pItem->text(0));
	
	slotStop();
}

void SourceFileDialog::slotListViewDoubleClicked(QListViewItem *pItem)
{
	// Here we change into the directory, if the user doubleClicked on one.
	if (pItem->text(4)[0] == 'd')	{
		QString qsDirectory = pItem->text(0);
		if (qsDirectory == QString (".."))	{
			int iEnd = m_pComboDirectoryHistory->currentText().findRev("/", -2);
			qsDirectory = m_pComboDirectoryHistory->currentText().left(++iEnd);
		}
		else
			qsDirectory = m_pComboDirectoryHistory->currentText() +  pItem->text(0) + QString ("/");
		setCurrentDir(qsDirectory);
		return;
	}
	// Otherwise, we take the file and accept the choice ...
	accept();
}

void SourceFileDialog::slotFileNameChanged()
{
	// The user changed something in the LineEdit object, lets check and do something really cool ...
	QString qsFileName = m_pEditFileName->text();
	// Here we search for * as an indication that the user simply wants a new filter and has not given the final name ...
	if ( (qsFileName.find('*') != -1) || (qsFileName.find('?') != -1) )	{
		m_qsManualFilter = qsFileName;
		setCurrentDir();
		return;
	}
	// Otherwise we should check if the file exists ...
	QFileInfo fileInfo(qsFileName);
	if ( (fileInfo.exists()) && (fileInfo.isFile()) )
		accept();
}

void SourceFileDialog::slotFilterChanged (int)
{
	m_qsManualFilter = QString ();
	setCurrentDir ();
}

void SourceFileDialog::slotDirectoryBack ()
{
	// sets the current directory to the previous directory
	if (m_pComboDirectoryHistory->currentItem() < m_pComboDirectoryHistory->count()-1)	{
		m_pComboDirectoryHistory->setCurrentItem(m_pComboDirectoryHistory->currentItem() + 1);
		setCurrentDir();
	}
}

void SourceFileDialog::slotDirectoryUp   ()
{
	// sets the current directory to the one one level up.
	QString qsDirectory;
	int iEnd = m_pComboDirectoryHistory->currentText().findRev("/", -2);
	qsDirectory = m_pComboDirectoryHistory->currentText().left(++iEnd);
	setCurrentDir(qsDirectory);
}

void SourceFileDialog::slotDirectoryNew  ()
{
	// creates a new directory.
	QString qsDirectoryName = QInputDialog::getText (tr("Please enter a new directopry name."), tr("New Directory :"));
	if (qsDirectoryName.isEmpty())
		return;
	// Next we should check if the name already exists ...
	QFileInfo dirInfo (qsDirectoryName);
	if (dirInfo.exists())	{
		QMessageBox::information (this, tr("Warning, Directroy exists already."), tr ("This name is already present in the current directory.\n Please choose a differen name."), QMessageBox::Ok);
		return;
	}
	// Okay ready to create ...
	QDir theDir;
	if (!theDir.mkdir (qsDirectoryName))	{
		QMessageBox::information (this, tr("Error.."), tr ("I could not create this directory.\n Please check if you have sufficient permissions."), QMessageBox::Ok);	
	}
	setCurrentDir();
}

/////////////////////////////////////////////////////////////////////////////
//
// The functions for the MoviePreview - part of the File load tab.
//
// This part handles all functions for the Movie/Image preview,
// including the slider, Start/Stop, Play etc. pp
//
/////////////////////////////////////////////////////////////////////////////
void SourceFileDialog::drawStartStopMarker (int, int)
{
	int iHeight, iWidth;
	// the rnage of the marker is [0 .. 1000]
	QPainter thePainter(m_pFrameStartStop);
	QColor theColor (COLOR_QUICK_SELECTED);
	QBrush theBrush(theColor);
	QPen thePen(Qt::NoPen);
	thePainter.setBrush(theBrush);
	thePainter.setPen(thePen);

	QPointArray startPoints(3), endPoints(3);

	iHeight = m_pFrameStartStop->height();
	iWidth  = m_pFrameStartStop->width();
	// startPoints / endPoints are simply the points of a triangle
	startPoints.setPoint (0,  0+XOFFSET, 0);
	startPoints.setPoint (1, 10+XOFFSET, 0);
	startPoints.setPoint (2,  5+XOFFSET, iHeight);

	endPoints.setPoint (0, iWidth-10-XOFFSET, 0);
	endPoints.setPoint (1, iWidth   -XOFFSET, 0);
	endPoints.setPoint (2, iWidth- 5-XOFFSET, iHeight);

	thePainter.drawPolygon (startPoints); //, bool winding = FALSE, int index = 0, int npoints = -1 );

	thePainter.drawPolygon (endPoints); //, bool winding = FALSE, int index = 0, int npoints = -1 );

}

void SourceFileDialog::paintEvent ( QPaintEvent *p)
{
	uiSourceFileDialog::paintEvent(p);
	drawStartStopMarker(0, 1000);
}

void SourceFileDialog::slotFBackward ()
{
	emit (signalFBackward ());
	m_pMediaInterface->playChapter (+1);
	colorMovieButtons (m_pButtonFBackward);
}

void SourceFileDialog::slotBackward ()
{
	emit (signalBackward());
	m_pMediaInterface->playChapter (-1);
	colorMovieButtons (m_pButtonBackward);
}

void SourceFileDialog::slotStop ()
{
	emit (signalStop());
	m_pMediaInterface->stop();
	colorMovieButtons (m_pButtonStop);
}

void SourceFileDialog::slotForward ()
{
	QString qsFileName = QDir::currentDirPath() + QString ("/") + m_pEditFileName->text();

	if      (m_pMediaInterface->isPaused ())
		 m_pMediaInterface->play ();
	else if (m_pMediaInterface->isPlaying())
		 m_pMediaInterface->pause();
	else
		m_pMediaInterface->playMRL(qsFileName);
	colorMovieButtons (m_pButtonForward);
}

void SourceFileDialog::slotFForward ()
{
	emit (signalFForward ());
	m_pMediaInterface->setSpeed (2.0);
	colorMovieButtons (m_pButtonFForward);
}

void SourceFileDialog::slotSetAsStart ()
{

}

void SourceFileDialog::slotSetAsEnd ()
{
	//m_pFrameStartStop
}

void SourceFileDialog::slotNewFrameNumber ()
{
	//m_pEditFrameNumber->text();
}

void SourceFileDialog::slotSliderValueChanged (int iNewPos)
{
	// fPos in % of total length ...
	float fPos = (float)iNewPos / 1000;

	emit (signalSeek (fPos));
}

void SourceFileDialog::colorMovieButtons (void *pButton)
{
	static QPushButton *pPreviousButton = m_pButtonStop;
//	static QColor normalColor = m_pButtonStop->paletteBackgroundColor();
//	pPreviousButton->setPaletteBackgroundColor (normalColor);
	pPreviousButton->setPaletteBackgroundColor (QColor (COLOR_QUICK_NORMAL));
	pPreviousButton = (QPushButton *)pButton;
	pPreviousButton->setPaletteBackgroundColor (QColor (COLOR_QUICK_SELECTED));
}

/////////////////////////////////////////////////////////////////////////////
//
// The functions for the Sound Options - tab
//
// In this tab you can assign a Sound channel to the movie/background Image
// and you can also extract existing sound channels to harddrive using transcode.
//
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//
// The functions for the SourceFileEntry - tab
//
// This tab is only visible when edit was clicked within the SourceFileEntry
// listBox.
// The tab handles the Position of the ovie file in the sourceFIleEntry list,
// capters, and assignement of the DisplayName of the SourceFileEntry.
//
// Note, a SourceFileEntry can have multiple movie files.
//
/////////////////////////////////////////////////////////////////////////////
void SourceFileDialog::setSourceFileEntries(QValueList<SourceFileEntry *> &listSourceFileEntries, int iCurrentEntry)
{
	uint t;
	m_pComboAddToSourceEntry->clear();
	for (t=0;t<listSourceFileEntries.count();t++)
		m_pComboAddToSourceEntry->insertItem(listSourceFileEntries[t]->qsDisplayName);
	setCurrentSourceFileEntry(listSourceFileEntries[iCurrentEntry]);
	// here we store the original entry for later usage ...
	m_pOriginalSourceFileEntry = listSourceFileEntries[iCurrentEntry];
	m_pComboAddToSourceEntry->setCurrentItem (iCurrentEntry);
}

void SourceFileDialog::setCurrentSourceFileEntry(SourceFileEntry *pSourceFileEntry)
{
	int t;
	m_pEditSourceFileName->setText(pSourceFileEntry->qsDisplayName);
	for (t=(int)pSourceFileEntry->listFileInfos.count()-1;t > -1; t--)	{
		new QListViewItem (m_pListViewSourceEntry,
			pSourceFileEntry->listFileInfos[t]->qsVideoFormat,
			pSourceFileEntry->listFileInfos[t]->qsResolution,
			pSourceFileEntry->listFileInfos[t]->qsLength,
			pSourceFileEntry->listFileInfos[t]->qsSize,
			pSourceFileEntry->listFileInfos[t]->qsRatio,
			pSourceFileEntry->listFileInfos[t]->qsFPS,
			pSourceFileEntry->listFileInfos[t]->qsStatus,
			pSourceFileEntry->listFileInfos[t]->qsFileName);
	}
	// We need a temp here otherwise we might delete the object before we use the info to clone the new object
	SourceFileEntry *pTemp = m_pCurrentSourceFileEntry;
	
	m_pCurrentSourceFileEntry  = new SourceFileEntry();
	*m_pCurrentSourceFileEntry = *pSourceFileEntry;
	// And now we can delete the copy ...
	if (pTemp)
		delete pTemp;
	setChapters (0);
}

void SourceFileDialog::setChapters (uint iWhichPart)
{
	// And finally we set the new chapter info ,,,
	m_pListBoxChapters->clear ();
	SourceFileInfo *pInfo = m_pCurrentSourceFileEntry->listFileInfos[iWhichPart];
	if (pInfo->listChapters.count () > 0)
		m_pListBoxChapters->insertStringList (pInfo->listChapters);
	else
		m_pListBoxChapters->insertItem (QString ("00:00:00.000"));
	
	slotSourceChaptersSelectionChanged ();
}

int SourceFileDialog::getCurrentSourceItem ()
{
	int iCurrentItem = 0;

	QListViewItem *pCurrentItem = m_pListViewSourceEntry->selectedItem();
	QListViewItem *pItem = m_pListViewSourceEntry->firstChild();
	iCurrentItem = 0;

	// Sanity check ...
	if ( (!pCurrentItem) || (!pItem) )
		return -1;

	while ( (pItem != pCurrentItem) || (!pItem) )	{
		pItem= pItem->itemBelow();
		iCurrentItem ++;
	}
	// Sanity check, The bottom was reached without finding the selected entry ...
	if (!pItem)
		return -1;
	return iCurrentItem;
}

void SourceFileDialog::setCurrentSourceItem (int iCurrentItem)
{
	uint t;
	// Here we set the active entry in the SourceEntries File list ...
	QListViewItem *pItem = m_pListViewSourceEntry->firstChild();
	for (t=0;(int)t<iCurrentItem;t++)
		pItem = pItem->itemBelow();
	m_pListViewSourceEntry->setSelected(pItem, TRUE);
	m_pListViewSourceEntry->setCurrentItem(pItem);
}

void SourceFileDialog::slotSourceNameChanged ()
{
	int t;
	// The user changed the name of the sourceEntry.
	// Here we check if it is a unique name in the list.
	// It ought to be unique since a lot of code depends on this.
	QString qsNewName = m_pEditSourceFileName->text();
	// first we check if the name has changed ...
	if (!m_pCurrentSourceFileEntry)
		return;
	if (qsNewName == m_pCurrentSourceFileEntry->qsDisplayName)
		return;
	for (t=0;t<m_pComboAddToSourceEntry->count();t++)	{
		if (m_pComboAddToSourceEntry->text(t) == qsNewName)	{
			QMessageBox::information (this, tr("Warning, Name exists."), tr ("This name is already in use.\nPlease choose a differen name."), QMessageBox::Ok);
 			m_pEditSourceFileName->setText(m_pCurrentSourceFileEntry->qsDisplayName);
		}
	}
}

void SourceFileDialog::slotSourceSelectionChanged (QListViewItem *)
{
	int iCounter, iCurrentItem;
	bool bState;
	iCurrentItem = getCurrentSourceItem ();
	iCounter = m_pListViewSourceEntry->childCount();
	if (iCurrentItem == -1)	{
		m_pButtonSourceSave->setEnabled (false);
		m_pButtonSourceDel->setEnabled  (false);
		m_pButtonSourceUp->setEnabled   (false);
		m_pButtonSourceDown->setEnabled (false);
		return;
	}

	bState = true;
	if (iCurrentItem == 0)
		bState = false;
	m_pButtonSourceUp->setEnabled   (bState);
	bState = true;
	if (iCurrentItem == iCounter-1)
		bState = false;
	m_pButtonSourceDown->setEnabled   (bState);
	bState = true;
	if (iCounter < 2)
		bState = false;
	m_pButtonSourceDel->setEnabled  (bState);

	m_pButtonSourceSave->setEnabled (true);
	setChapters (iCurrentItem);
}

void SourceFileDialog::slotSourceChaptersSelectionChanged ()
{
	// The only thing to take care of here is to change the state of m_pButtonSourceDeleteChapters.
	int iCurrentItem = getCurrentSourceItem ();
	if (iCurrentItem == -1)
		return;
	// Next we make the neccesary changes to the entry ...
	SourceFileInfo *pInfo = m_pCurrentSourceFileEntry->listFileInfos[iCurrentItem];

	int t, iCountSelected = 0;
	bool bState = false;
	for (t=0;t<(int)m_pListBoxChapters->count();t++)	{
		if (m_pListBoxChapters->isSelected (t))
			iCountSelected ++;
	}
	if (	(iCountSelected > 0) &&
		(pInfo->listChapters.count () > 1) )
		bState = true;
	m_pButtonDeleteChapter->setEnabled  (bState);
}

void SourceFileDialog::slotSourceImportChapter()
{
	int iRead, iSourceFileNumber;
	uint t;
	QString qsChaptersString, qsChapters, qsFileName;
	QString qsDir = m_pComboDirectoryHistory->currentText();
	// Sanity check ...
	if (!m_pCurrentSourceFileEntry)
		return;
	// Here we import the chapter description from e.g. a dvd-slideshow - generated movie
	QString qsChaptersFileName = QFileDialog::getOpenFileName(qsDir, tr("Chapter Files (*.chapter *.CHAPTER *.xml *.XML)"), this, tr("Open Project file dialog"), tr("Open Project File"));
	// Sanity check .. Did te user choose a new project file ?
	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 = getAttribute("chapters", qsChaptersString);
	qsFileName = getAttribute("file", qsChaptersString);

	// Okay here we search for the file name if it corresponds to one of the files in the SourceFileInfo - list
	// And if there is no entry selected, we go for the first entry ...
	iSourceFileNumber = 0; 
	for (t=0;t<m_pCurrentSourceFileEntry->listFileInfos.count();t++)	{
		if (m_pCurrentSourceFileEntry->listFileInfos[t]->qsFileName == qsFileName)	{
			iSourceFileNumber = t;
			break; // out ...
		}
	}
	// If we could not find the file in the list, we take the currently selected entry instead ...
	if (t >= m_pCurrentSourceFileEntry->listFileInfos.count())	{
		QListViewItem *pItem = m_pListViewSourceEntry->currentItem ();
		for (t=0;t<m_pCurrentSourceFileEntry->listFileInfos.count();t++)	{
			if (m_pCurrentSourceFileEntry->listFileInfos[t]->qsFileName == pItem->text (7))
				iSourceFileNumber = t;
		}
	}
	// 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] = formatChapter(listChapters[t]);
	// Note that this is called Import ... Thus we remove any older chapters or this entry ...
	m_pCurrentSourceFileEntry->listFileInfos[iSourceFileNumber]->listChapters = listChapters;
	setChapters (iSourceFileNumber);
}

QString SourceFileDialog::formatChapter (QString qsInput)
{
	char cBuffer[20];
	QString qsReturn ("00:00:00.000");
	if (qsInput == QString ("0"))
		return qsReturn;
	// Here we tidy up the chapter. E.g. 0 gets converted to 00:00:00.000, 0.0.32 to 00:00:32.000 etc
	QStringList listParts = QStringList::split(":", qsInput);
	// SanityCheck ...
	if (listParts.count() < 3)
		return qsReturn;
	int iInput = (int)listParts[2].toFloat();
	sprintf (cBuffer, "%02d:%02d:%02d.%03d", listParts[0].toInt(), listParts[1].toInt(), iInput, (int)((listParts[2].toFloat() - iInput) * 1000));
	qsReturn = QString (cBuffer);
	return qsReturn;
}

QString SourceFileDialog::getAttribute (QString qsAttrName, QString qsFullString)
{
	QString qsReturn;
	int iStart, iEnd;
	iStart = qsFullString.find (qsAttrName);
	if (iStart < 1)
		return qsReturn;
	// increase iStart to skip e.g.[chapters="] and get to the start of the chapters.
	iStart += qsAttrName.length() + 2;
	// Now we find the end ...
	iEnd = qsFullString.find ("\"", iStart);
	if (iEnd < 1) 
		return qsReturn;
	qsReturn = qsFullString.mid (iStart, iEnd-iStart);
	return qsReturn;
}

void SourceFileDialog::slotSourceEditChapter()
{
#if 0
#ifndef QPLAYER_ONLY
#define QPLAYER_ONLY 1
	// Here we edit the chapters list ...
	uint t;
	int iSourceFileNumber = 0;
	// Here we check for the currently selected entry ...
	QListViewItem *pItem = m_pListViewSourceEntry->currentItem ();
	for (t=0;t<m_pCurrentSourceFileEntry->listFileInfos.count();t++)	{
		if (m_pCurrentSourceFileEntry->listFileInfos[t]->qsFileName == pItem->text (7))
			iSourceFileNumber = t;
	}
	// Remeber that the fallback is entry 0.
	SourceFileInfo *pInfo = m_pCurrentSourceFileEntry->listFileInfos[iSourceFileNumber];
 
	DialogMovie *pDialog = new DialogMovie (this); 
	pDialog->initMe (pInfo, m_pMediaInterface->getMediaEngine(), m_pCurrentSourceFileEntry->sizeThumbnail.width());
	if (pDialog->exec () == QDialog::Accepted)
		*pInfo = *pDialog->sourceFileInfo();
	// And finally we set the new chapter info ,,,
	setChapters(iSourceFileNumber);
	delete pDialog;
#undef QPLAYER_ONLY
#endif
#endif
}

void SourceFileDialog::slotSourceDeleteChapter()
{
	// 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];
	// And afterwards we take a look at the damage we made ...
	// Okay to find which entries  chapters we were happily deleting ...
	int iCurrentItem = getCurrentSourceItem ();
	if (iCurrentItem == -1)
		return;
	// Next we make the neccesary changes to the entry ...
	SourceFileInfo *pInfo = m_pCurrentSourceFileEntry->listFileInfos[iCurrentItem];
	pInfo->listChapters.clear ();
	for (t=0;t<m_pListBoxChapters->count();t++)
		pInfo->listChapters.append (m_pListBoxChapters->text(t));
	// to finally set the chapters again ...
	setChapters (iCurrentItem);
}

void SourceFileDialog::slotSourceAdd()
{
/*
	// this button adds a new movie file to the SourceFileEntry.
	// Please keep in mind that one SourceFileEntry can consist of many movie files.
	uint t;
	bool bBeenHere = false;
	SourceFileInfo *pInfo;
	
	if (m_pCurrentSourceFileEntry->bSoundSource)	{
		QMessageBox::information (this, tr("Warning."), tr ("You seem to try add something to an audio entry.\nPlease use the Sound Option tab instead."), QMessageBox::Ok);
		return;
	}

	XineInfo *pXineInfo = new XineInfo ((xine_t *)m_pMediaWidget->GetXineEngine ());
	// First let us get all supported video stream extensions ...
	QString qsFileMovieExtensions = m_listFileType[1];	// 1 = Movie File formats only ...
	// Next we are looking for the current directory
	QString qsDir = m_pComboDirectoryHistory->currentText();
	// And then we can get all video streams to add in one neat list ...
	QStringList listAddFiles = QFileDialog::getOpenFileNames (qsFileMovieExtensions, qsDir);
	// ASanity check ...
	if (listAddFiles.count () < 1)
		return;
	// Next we will create a SourceFileInfo - object for each and every one of the new files.
	for  (t=0;t<listAddFiles.count();t++)	{
		pXineInfo->setStream (listAddFiles[t]);
		// Sanity check. This function is currently only called from the SourceEdit - tab
		// which at this time only handles Movie files.
		// We check if the source(s) are sound instead, which would lead to a mixed bag which we do not support.
		if ( (!pXineInfo->hasVideo()) && (pXineInfo->hasAudio()) )	{
			// bBeenHere ensures we only show this dialog once ...
			if (!bBeenHere)	
				QMessageBox::information (this, tr("Warning."), tr ("You seem to try to mix sound and Movie streams.\nPlease don't try to confuse me."), QMessageBox::Ok);
			bBeenHere = true;
			continue;
		}

		pInfo = new SourceFileInfo ();
		pInfo->qsVideoFormat= pXineInfo->getFormat     ( true  );
		pInfo->qsAudioFormat= pXineInfo->getFormat     ( false );
		pInfo->qsResolution = pXineInfo->getResolutionString ( );
		pInfo->qsLength     = pXineInfo->getLengthString     ( );
		pInfo->qsSize       = pXineInfo->getSizeString       ( );
		pInfo->qsRatio      = pXineInfo->getRatio            ( );
		pInfo->qsFPS        = QString ("%1").arg(pXineInfo->getFPS());
		pInfo->qsStatus     = pXineInfo->getStatus           ( );

		pInfo->qsBPS        = pXineInfo->getBPSString  ( false );
		pInfo->qsBits       = pXineInfo->getBits             ( );
		pInfo->qsSample     = pXineInfo->getSampleString     ( );
		pInfo->qsFileName   = listAddFiles[t];
		if (m_pCurrentSourceFileEntry)
			m_pCurrentSourceFileEntry->listFileInfos.append (pInfo);
	}
	// FIXME: Here we should check for m_pCurrentSourceFileEntry->bSoundSource, if all Info's are of the same type.
	m_pListViewSourceEntry->clear ();
	setCurrentSourceFileEntry(m_pCurrentSourceFileEntry);
	if (m_pListViewSourceEntry->childCount() > 1)
		m_pButtonSourceDel->setEnabled (true);
	delete pXineInfo;
*/
}

void SourceFileDialog::slotSourceSave()
{
	// Here we store the SourceFileInfo - part of the SourceFileEntry into a
	// dvd-slideshow type of file (I.e. <vob chapters="0,0:0:14.0,0:0:22.0" file="/path/movie.mpg"  />)

	// Okay to get the actual list of chapters we are interested in ...
	int iCurrentItem = getCurrentSourceItem ();
	if (iCurrentItem == -1)
		return;
	// Next we make the neccesary changes to the entry ...
	SourceFileInfo *pInfo = m_pCurrentSourceFileEntry->listFileInfos[iCurrentItem];

	QString qsDir = m_pComboDirectoryHistory->currentText();
	QString fileName = QFileDialog::getSaveFileName ( qsDir, tr ("Chapter files ( *.chapter *.CHAPTER *.xml *.XML)"));
	if (fileName.isNull())
		return;

	// Next we check if the file name has an extension ...
	QFileInfo fileInfo (fileName);
	if (fileInfo.extension().isEmpty())
		fileName = fileName + QString (".chapter");

	QFile file (fileName);
	if ( file.open( IO_WriteOnly ) ) {
		QTextStream stream( &file );
		stream << "   <vob chapters=\"" << pInfo->listChapters.join(",") << "\" file=\"" << pInfo->qsFileName << "\" />";
		file.close();
	}
}

void SourceFileDialog::slotSourceDel()
{
	// First get the actual number of the selected Item ...
	int iCurrentItem = getCurrentSourceItem ();
	
	// Here we ensure to keep at least one child ...
	if ( (m_pListViewSourceEntry->childCount() < 2) || (iCurrentItem == -1) )
		return;
	// Next we make the neccesary changes to the entry ...
	SourceFileInfo *pInfo = m_pCurrentSourceFileEntry->listFileInfos[iCurrentItem];
	m_pCurrentSourceFileEntry->listFileInfos.remove (pInfo);
	delete pInfo;
	delete m_pListViewSourceEntry->selectedItem();
	// Okay if we deleted all but one entry we should disable the delete button ...
	if (m_pListViewSourceEntry->childCount() < 2)
		m_pButtonSourceDel->setEnabled (false);
}

void SourceFileDialog::slotSourceUp()
{
//QListViewItem->moveItem (QListViewItem *pAfter);
	// FIXME: selection based button activation ...
	// Here we move the selected entry up by one position ...
	// o	only active, when one entry is selected
	// o	only active, entry not already topmost
	// o	only active, when more then one SourceFileInfo in this SourceFileEntry.
	uint t;
	// Okay to get the actual list of chapters we are interested in ...
	int iCurrentItem = getCurrentSourceItem ();
	if (iCurrentItem < 1)
		return;
	// Next we make the neccesary changes to the entry ...
	QValueList<SourceFileInfo *> listNewOrder;
	for (t=0;t<m_pCurrentSourceFileEntry->listFileInfos.count ();t++)	{
		if ((int)t == iCurrentItem - 1)	{
			//Okay here we switch and also inclrease t to skip the next entry, which was already added
			listNewOrder.append(m_pCurrentSourceFileEntry->listFileInfos[iCurrentItem]);
			listNewOrder.append(m_pCurrentSourceFileEntry->listFileInfos[t++]);
		}
		else
			listNewOrder.append(m_pCurrentSourceFileEntry->listFileInfos[t]);
	}
	m_pCurrentSourceFileEntry->listFileInfos.clear ();
	m_pCurrentSourceFileEntry->listFileInfos = listNewOrder;
	m_pListViewSourceEntry->clear ();
	setCurrentSourceFileEntry(m_pCurrentSourceFileEntry);
	setCurrentSourceItem(iCurrentItem-1);
}

void SourceFileDialog::slotSourceDown()
{
	// FIXME: selection based button activation ...
	// Here we move the selected entry up by one position ...
	// o	only active, when one entry is selected
	// o	only active, entry not already bottommost
	// o	only active, when more then one SourceFileInfo in this SourceFileEntry.
	uint t;
	// Okay to get the actual list of chapters we are interested in ...
	int iCurrentItem = getCurrentSourceItem ();
	if (iCurrentItem == -1)
		return;
	// Next we make the neccesary changes to the entry ...
	QValueList<SourceFileInfo *> listNewOrder;
	if (iCurrentItem >= (int)m_pCurrentSourceFileEntry->listFileInfos.count ()-1)
		return;
	
	for (t=0;t<m_pCurrentSourceFileEntry->listFileInfos.count ();t++)	{
		if ((int)t == iCurrentItem)	{
			//Okay here we switch and also inclrease t to skip the next entry, which was already added
			listNewOrder.append(m_pCurrentSourceFileEntry->listFileInfos[++t]);
			listNewOrder.append(m_pCurrentSourceFileEntry->listFileInfos[iCurrentItem]);
		}
		else
			listNewOrder.append(m_pCurrentSourceFileEntry->listFileInfos[t]);
	}
	m_pCurrentSourceFileEntry->listFileInfos.clear ();
	m_pCurrentSourceFileEntry->listFileInfos = listNewOrder;
	m_pListViewSourceEntry->clear ();
	setCurrentSourceFileEntry(m_pCurrentSourceFileEntry);
	setCurrentSourceItem(iCurrentItem+1);
	// Here we set the active entry ...
/*	QListViewItem *pItem = m_pListViewSourceEntry->firstChild();
	for (t=0;(int)t<iCurrentItem+1;t++)
		pItem = pItem->itemBelow();
	m_pListViewSourceEntry->setSelected(pItem, TRUE);
	m_pListViewSourceEntry->setCurrentItem(pItem);
*/
}

/////////////////////////////////////////////////////////////////////////////
//
// The functions for the Movie/Image Options - tab
//
// This tab handles resizing of the Video,
// transcoding into a different Format,
// and chapter handling,
//////////////////////////////////////////////////////////////////////////////




/////////////////////////////////////////////////////////////////////////////
//
// OUT TAKES.
//
// Here are code snipplets used for testing purposes ...
// 
// 
//////////////////////////////////////////////////////////////////////////////

/*
// for now abused to test the ability to fetch infos about a stream from xine-lib
	// We assume at this point that the engine is already loaded with the stream info (I.e. the file has been set).
	xine_t *pXine = (xine_t *) m_pXineWidget->GetXineEngine();

	// next we should fetch the informations ...
	XineInfo *pXineInfo = new XineInfo(pXine);
	pXineInfo->setStream("/home/varol/dvdproject/NTSC_DVD_title1.mpg");

	printf ("FileName : <%s>\n", (const char *) pXineInfo->getFileName());
	printf ("Size : <%d> = <%s>\n", pXineInfo->getSize(), (const char *) pXineInfo->getSizeString());
	printf ("Length : <%d> = <%s>\n\n", pXineInfo->getLength(), (const char *) pXineInfo->getLengthString());
	printf ("Resolution : <%d><%d> = <%s>\n", pXineInfo->getResolution(true), pXineInfo->getResolution(false), (const char *) pXineInfo->getResolutionString());
	printf ("Ratio : <%s>\n", (const char *) pXineInfo->getRatio());
	printf ("FPS : <%f>\n", pXineInfo->getFPS());
	printf ("Video BPS : <%d=%s>\n", pXineInfo->getBPS(true), (const char *) pXineInfo->getBPSString(true));
	printf ("Video Format : <%s>\n", (const char *) pXineInfo->getFormat(true));
	printf ("Video Codec : <%s>\n", (const char *) pXineInfo->getCodec(true));
	printf ("Sample : <%d> = <%s>\n", pXineInfo->getSample(), (const char *) pXineInfo->getSampleString());
	printf ("Audio Format : <%s>\n", (const char *) pXineInfo->getFormat(false));
	printf ("Audio Codec : <%s>\n", (const char *) pXineInfo->getCodec(false));
	printf ("Audio BPS : <%d=%s>\n", pXineInfo->getBPS(false), (const char *) pXineInfo->getBPSString(false));
	printf ("Audio <has/handled>/ Video <has/handled> <%d/%d><%d/%d>\n", pXineInfo->hasAudio (), pXineInfo->audioHandled (),  pXineInfo->hasVideo(), pXineInfo->videoHandled ());
	printf ("Status : <%s>\n", (const char *) pXineInfo->getStatus());

	pXineInfo->setStream("/home/varol/dvdproject/NTSC_DVD_title2.mpg");
printf ("\n\n");
	printf ("FileName : <%s>\n", (const char *) pXineInfo->getFileName());
	printf ("Size : <%d> = <%s>\n", pXineInfo->getSize(), (const char *) pXineInfo->getSizeString());
	printf ("Length : <%d> = <%s>\n\n", pXineInfo->getLength(), (const char *) pXineInfo->getLengthString());
	printf ("Resolution : <%d><%d> = <%s>\n", pXineInfo->getResolution(true), pXineInfo->getResolution(false), (const char *) pXineInfo->getResolutionString());
	printf ("Ratio : <%s>\n", (const char *) pXineInfo->getRatio());
	printf ("FPS : <%f>\n", pXineInfo->getFPS());
	printf ("Video BPS : <%d=%s>\n", pXineInfo->getBPS(true), (const char *) pXineInfo->getBPSString(true));
	printf ("Video Format : <%s>\n", (const char *) pXineInfo->getFormat(true));
	printf ("Sample : <%d> = <%s>\n", pXineInfo->getSample(), (const char *) pXineInfo->getSampleString());
	printf ("Audio Format : <%s>\n", (const char *) pXineInfo->getFormat(false));
	printf ("Audio BPS : <%d=%s>\n", pXineInfo->getBPS(false), (const char *) pXineInfo->getBPSString(false));
	printf ("Audio <has/handled>/ Video <has/handled> <%d/%d><%d/%d>\n", pXineInfo->hasAudio (), pXineInfo->audioHandled (),  pXineInfo->hasVideo(), pXineInfo->videoHandled ());
	printf ("Status : <%s>\n", (const char *) pXineInfo->getStatus());

	delete pXineInfo;
*/
