/****************************************************************************
** This is the CommandQueueDialog
**
** Created: Wed Mar 31 07:53:05 2004
**      by: Varol Okan using Kate
**
****************************************************************************/
#include <sys/stat.h>

#include <qvariant.h>
#include <qpushbutton.h>
#include <qtabwidget.h>
#include <qwidget.h>
#include <qframe.h>
#include <qgroupbox.h>
#include <qcheckbox.h>
#include <qlabel.h>
#include <qfiledialog.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qscrollview.h>
#include <qwhatsthis.h>
#include <qregexp.h> 

#include "execute.h"
#include "dialogexecute.h"
#include "dialogman.h"
#include "qdvdauthorinit.h"
#include "dialogcommandeditor.h"
#include "messagebox.h"

DialogExecute::DialogExecute(QValueList<ExecuteInterface *> listExecuteBlocks, bool bShowDialog )
    : QDialog( )
{
	uint t;
	
	// Init member variables.
	QStringList commandList;
	m_pInitObject      = NULL;
	m_pTranscodeParent = NULL;
	m_pTranscodeLayout = NULL;
	m_iTranscodeOffset = 0;
	// Here we concat all commands together ...
	for (t=0;t<listExecuteBlocks.count();t++)	// Lets get the default commands ...
		commandList += listExecuteBlocks[t]->listCommandList[0];
//	for (t=0;t<listExecuteBlocks.count();t++)	// Lets get the default commands ...
//		for (i=0;i<listExecuteBlocks[t]->listCommandList.count();i++)	// Lets get the default commands ...
//			commandList.append(listExecuteBlocks[t]->listCommandList[i][listExecuteBlocks[t]->listDefaults[t]]);
/* debugging the output.
for (t=0;t<listExecuteBlocks.count();t++)  {
for (int i=0;i<listExecuteBlocks[t]->listCommandList.count ();i++)  {
QStringList qsCommandList = listExecuteBlocks[t]->listCommandList[i];
for (int j=0;j<qsCommandList.count();j++)  {
printf ( "DialogExecute::DialogExecute <%d><%d><%d> = <%s>\n", t, i, j, qsCommandList[j].ascii() );
}
}
}
printf ("\n\n");
*/

	// In case the user does not want to display a execute Dialog but instead prefers the default settings.
	if (!bShowDialog)
		m_doSomething.system (commandList);

	createMainForm ();
	createPreprocessing  ();
	createDVDAuthorTab   (listExecuteBlocks);
	createPostprocessing ();

	languageChange();
	show ();
	resize( QSize(877, 662).expandedTo(minimumSizeHint()) );
	clearWState( WState_Polished );
	slotCheckBlock (true);
}

DialogExecute::~DialogExecute()
{
	// Destroys the object and frees any allocated resources
	// no need to delete child widgets, Qt does it all for us
	delete m_pInitObject;
}

void DialogExecute::setInit(QDVDAuthorInit *pInit)
{
	m_pInitObject = pInit;
	// Here we save over the ToolsPaths. This list will be removed from the InitObject ...
	m_listToolsPaths = pInit->getToolsPaths ();
}

void DialogExecute::createMainForm ()
{
	setName( "DialogExecute" );
	setSizeGripEnabled( TRUE );
	DialogExecuteLayout = new QGridLayout( this, 1, 1, 11, 6, "DialogExecuteLayout");

	Layout1 = new QHBoxLayout( 0, 0, 6, "Layout1");

	buttonHelp = new QPushButton( this, "buttonHelp" );
	buttonHelp->setAutoDefault( TRUE );
	Layout1->addWidget( buttonHelp );
	QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
	Layout1->addItem( spacer );

	buttonExport = new QPushButton( this, "buttonExport" );
	buttonExport->setAutoDefault( TRUE );
	Layout1->addWidget( buttonExport );

	buttonOk = new QPushButton( this, "buttonOk" );
	buttonOk->setAutoDefault( TRUE );
	buttonOk->setDefault( TRUE );
	Layout1->addWidget( buttonOk );

	buttonCancel = new QPushButton( this, "buttonCancel" );
	buttonCancel->setAutoDefault( TRUE );
	Layout1->addWidget( buttonCancel );

	DialogExecuteLayout->addLayout( Layout1, 1, 0 );

	m_pTabWidget = new QTabWidget( this, "m_pTabWidget" );
	m_pTabWidget->setEnabled( TRUE );

		// signals and slots connections
	connect( buttonOk     , SIGNAL( clicked() ), this, SLOT( slotOkay  () ) );
	connect( buttonCancel , SIGNAL( clicked() ), this, SLOT( reject    () ) );
	connect( buttonExport , SIGNAL( clicked() ), this, SLOT( slotExport() ) );
	connect( buttonHelp ,   SIGNAL( clicked() ), this, SLOT( slotHelp  () ) );
	connect( m_pTabWidget , SIGNAL( currentChanged  (QWidget*)), this, SLOT(slotTabChanged(QWidget *)));
	connect(&m_doSomething, SIGNAL( signalRenderMenu(QString )), this, SLOT(slotRenderMenu(QString  )));
}

void DialogExecute::createPreprocessing ()
{
//	m_pTabPreparing = new QWidget( m_pTabWidget, "m_pTabPreparing" );
//	m_pTabWidget->insertTab( m_pTabPreparing, QString("Preparing") );
}

QGridLayout *DialogExecute::createBlockFrame(QWidget *pParent, QGridLayout *pParentLayout, ExecuteInterface *pInterface, int t, int iOffset)
{
	QGridLayout *pGroupBoxLayout;
	QCheckBox   *pCheckBox, *pCheckBox2;
	QGroupBox   *pGroupBox;

	pGroupBox = new QGroupBox( pParent, QString ("pGroupBox_%1").arg(t) );
	pGroupBox->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)1, 0, 0, pGroupBox->sizePolicy().hasHeightForWidth() ) );
	pGroupBox->setPaletteBackgroundColor(pInterface->backgroundColor);
	pGroupBox->setColumnLayout(0, Qt::Vertical );
	pGroupBox->layout()->setSpacing( 6 );
	pGroupBox->layout()->setMargin( 11 );
	m_listGroupBox.append (pGroupBox);

	pGroupBoxLayout = new QGridLayout( pGroupBox->layout() );
	pGroupBoxLayout->setAlignment( Qt::AlignTop );

	pCheckBox = new QCheckBox (pGroupBox, QString ("pCheckBox_%1").arg(t));
	pCheckBox->setChecked (pInterface->bShowBlock);
	pCheckBox->setMaximumWidth (25);
	pCheckBox->move (15, 0);
	connect( pCheckBox, SIGNAL( toggled(bool) ), this, SLOT( slotCheckBlock(bool) ) );
	m_listCheckBox.append(pCheckBox);

	if (iOffset == -1)	{
		pGroupBox->setTitle( QString ("           ") + pInterface->qsBlockName );
		pCheckBox2 = new QCheckBox (tr ("        Don't execute ") + 
			pInterface->qsBlockName, pParent, QString ("pCheckBox2_%1").arg(t));
	}
	else	{ // this will get the fileBaseName (as spec in the ini after the two possible conv tools)
		pGroupBox->setTitle (QString ("           Convert : ") + pInterface->listCommandList[0][pInterface->listSplitAt.count()] );
		pCheckBox2 = new QCheckBox (tr ("        Don't convert ") + 
			pInterface->listCommandList[0][pInterface->listSplitAt.count()], 
			pParent, QString ("pCheckBox2_%1").arg(t));
	}
	pCheckBox2->setPaletteBackgroundColor(pInterface->backgroundColor);
	connect( pCheckBox2, SIGNAL( toggled(bool) ), this, SLOT( slotCheckBlock(bool) ) );
	pCheckBox2->hide ();
	m_listCheckBox2.append(pCheckBox2);

	pParentLayout->addWidget( pCheckBox2, 2*t+1, 0 );
	pParentLayout->addWidget( pGroupBox, 2*t+2, 0 );

	return pGroupBoxLayout;
}

void DialogExecute::createCommandBlock (QWidget *pParent, QGridLayout *pParentLayout, ExecuteInterface *pInterface, int t, int i)
{
	int iYPos;
	QLabel		*pComment;
	QComboBox	*pCommand;
	QPushButton	*pButton, *pButtonEdit, *pButtonDefault;

	// Add another Layout with d/e - buttons oriented Vertically and in between the man button and the Combo box
	QVBoxLayout *pEDButtons;
	// setting : m_listCheckBox/m_listCheckBox2/m_listGroupBox
	iYPos = 2*i;
	pEDButtons = new QVBoxLayout( 2, QString ("buttonbox_%1-%2t").arg(t).arg(i));
	pComment = new QLabel( pParent,   QString ("comment_%1-%2t").arg(t).arg(i));
	pCommand = new QComboBox( FALSE, pParent, QString ("command_%1-%2t").arg(t).arg(i));
	pButton  = new QPushButton( pParent, QString ("button_%1-%2t" ).arg(t).arg(i));
	pButton->setText( tr( "man" ) );
	pButtonEdit  = new QPushButton( pParent, QString ("button_%1-%2t" ).arg(t).arg(i));
	pButtonEdit->setMaximumSize ( 25, 25 );
	pButtonEdit->setText( tr( "e" ) );
	// If this is the internal render then we don't want to allow the user to change the command.
	pButtonDefault  = new QPushButton( pParent, QString ("button_%1-%2t" ).arg(t).arg(i));
	pButtonDefault->setMaximumSize ( 25, 25 );
	pButtonDefault->setText( tr( "d" ) );
	if (pInterface->listCommandList[i][0].find (QString (RENDER_MENU)) > -1)	{
		pCommand->setEditable(FALSE);
		pButtonEdit->setEnabled (false);
	}
	else
		pCommand->setEditable(TRUE);
	pCommand->insertStringList (pInterface->listCommandList[i]);
	pComment->setText          (pInterface->commentList    [i]);
	pCommand->setCurrentItem   (pInterface->listDefaults   [i]);

	pEDButtons->addWidget( pButtonEdit );
	pEDButtons->addWidget( pButtonDefault );
	pParentLayout->addMultiCellWidget( pComment, iYPos, iYPos, 0, 2 );
	pParentLayout->addWidget( pCommand,   1+iYPos, 0 );
	pParentLayout->addLayout( pEDButtons, 1+iYPos, 1 );
	pParentLayout->addWidget( pButton,    1+iYPos, 2 );

	m_listCommandsWidget.append      ( pCommand );
	m_listCommentsWidget.append      ( pComment );
	m_listButtonWidgets.append       ( pButton  );
	m_listButtonEdit.append          ( pButtonEdit );
	m_listButtonSetAsDefault.append  ( pButtonDefault );
	m_listBlockID.append             ( pInterface->listBlockIDs[i] );
	m_listBlockExecuteInterface.append(t);// this connects the ExecuteInterface with the generated Block
	connect (pButton, SIGNAL(clicked ()), this, SLOT(slotManButtonClicked()));
	connect (pButtonEdit, SIGNAL(clicked ()), this, SLOT(slotEditButtonClicked()));
	connect (pButtonDefault, SIGNAL(clicked ()), this, SLOT(slotDefaultButtonClicked()));
}

void DialogExecute::createStandardBlock (QWidget *pParent, QGridLayout *pParentLayout, ExecuteInterface *pInterface, int t)
{
	int i;
	QGridLayout	*pGroupBoxLayout;
	// setting : m_listCheckBox/m_listCheckBox2/m_listGroupBox
	pGroupBoxLayout = createBlockFrame (pParent, pParentLayout, pInterface, t); 

	for (i=0;i<(int)pInterface->listCommandList.count();i++)
		createCommandBlock (m_listGroupBox.last(), pGroupBoxLayout, pInterface, t, i);
}

void DialogExecute::createTranscodeBlock (ExecuteInterface *pInterface, int t)
{
	int i, j, iYPos;
	QLabel		*pComment;
	QComboBox	*pCommand;
	QPushButton	*pButtonDefault;
	QGridLayout *pGroupBoxLayout = NULL;

	// m_listCheckBox/m_listCheckBox2/m_listGroupBox
	if  ( ! m_pTranscodeLayout )	{
		m_pTranscodeLayout = createBlockFrame (m_pScrollFrame, m_pScrollFrameLayout, pInterface, t); 
		m_pTranscodeParent = m_listGroupBox.last();
	}
	iYPos = 2*m_iTranscodeOffset++;

	pGroupBoxLayout = createBlockFrame (m_pTranscodeParent, m_pTranscodeLayout, pInterface, t, m_iTranscodeOffset);
	pComment = new QLabel( m_listGroupBox.last(),   QString ("comment_%1-0").arg(t));
	pCommand = new QComboBox( FALSE, m_listGroupBox.last(), QString ("command_%1-0").arg(t));
	// If this is the internal render then we don't want to allow the user to change the command.
	pButtonDefault  = new QPushButton( m_listGroupBox.last(), QString ("button_%1-0" ).arg(t));
	pButtonDefault->setMaximumSize ( 25, 25 );
	pButtonDefault->setText( tr( "d" ) );
	pCommand->setEditable(FALSE);
	for (i=0;i<(int)pInterface->listSplitAt.count ();i++)
		pCommand->insertItem (pInterface->listCommandList[0][i]);
	pComment->setText            (pInterface->commentList    [0]);
	pCommand->setCurrentItem     (pInterface->listDefaults   [0]);

	pGroupBoxLayout->addMultiCellWidget ( pComment, iYPos, iYPos, 0, 1 );
	iYPos ++;
	pGroupBoxLayout->addMultiCellWidget ( pCommand, iYPos, iYPos, 0, 1 );
	pGroupBoxLayout->addWidget ( pButtonDefault, iYPos, 2 );
	iYPos ++;

	m_listTranscodeCombos.append     ( pCommand );
	m_listCommandsWidget.append      ( pCommand );
	m_listCommentsWidget.append      ( pComment );
	m_listButtonWidgets.append       ( NULL     );
	m_listButtonEdit.append          ( NULL     );
	m_listButtonSetAsDefault.append  ( pButtonDefault );
	m_listBlockID.append             ( pInterface->listBlockIDs[0] );
	m_listBlockExecuteInterface.append(t);// this connects the ExecuteInterface with the generated Block
	connect (pCommand,       SIGNAL(activated (int)), this, SLOT(slotTranscodeSelectionChanged(int)));
	connect (pButtonDefault, SIGNAL(clicked ()), this, SLOT(slotDefaultButtonClicked()));

	QGridLayout *pGroupBoxLayout2;
	QGroupBox   *pGroupBox;
	int iSplitAtStart, iSplitAtEnd;

	for (i=0;i<(int)pInterface->listSplitAt.count ();i++)	{
		iSplitAtStart = pInterface->listSplitAt[i] + 1;
		if (i+1 < (int)pInterface->listSplitAt.count ())
			iSplitAtEnd = pInterface->listSplitAt[i+1] + 1;
		else
			iSplitAtEnd = pInterface->listCommandList.count ();
//printf ("DialogExecute::createTranscodeBlock i<%d> count<%d> count<%d> <%d>\n", i, pInterface->listDefaults.count (), pInterface->listCommandList.count (),  pInterface->listDefaults[i]);
		pGroupBox = new QGroupBox( m_listGroupBox.last(), QString ("pGroupBox_%1").arg(t) );
		pGroupBox->setPaletteBackgroundColor(pInterface->backgroundColor);
		pGroupBox->setColumnLayout(0, Qt::Vertical );

		pGroupBoxLayout2 = new QGridLayout( pGroupBox->layout() );
		pGroupBoxLayout2->setAlignment( Qt::AlignTop );

		pGroupBoxLayout->addMultiCellWidget ( pGroupBox, iYPos, iYPos, 0, 2 );
//		pGroupBoxLayout->addWidget ( pGroupBox, iYPos, 0 );
		iYPos ++;
		for (j=iSplitAtStart;j<iSplitAtEnd;j++)
			createCommandBlock (pGroupBox, pGroupBoxLayout2, pInterface, t, j);
		// Hide everything but the default selection.
		if (pInterface->listDefaults[0] != i)
			pGroupBox->hide ();
		m_listTranscodeFrames.append ( pGroupBox );
	}
}

void DialogExecute::createDVDAuthorTab   (QValueList<ExecuteInterface *> listExecuteBlocks)
{
	uint t;

	m_listExecuteInterface = listExecuteBlocks;

	// Here we create the ScrollView and Layouts ...
	m_pTabExpert = new QWidget( m_pTabWidget, "m_pTabExpert" );
	tabLayout = new QGridLayout( m_pTabExpert, 1, 1, 11, 6, "tabLayout");

	m_pScrollView = new QScrollView (m_pTabExpert, "ScrollView");

	m_pScrollFrame = new QFrame( m_pScrollView, "m_pScrollFrame" );
	m_pScrollFrame->setPaletteBackgroundColor( QColor( 238, 230, 234 ) );
	m_pScrollFrame->setFrameShape( QFrame::StyledPanel );
	m_pScrollFrame->setFrameShadow( QFrame::Raised );
	m_pScrollFrameLayout = new QGridLayout( m_pScrollFrame, 1, 1, 11, 6, "m_pScrollFrameLayout");

	for (t=0;t<listExecuteBlocks.count();t++)	{
		// Check if this is a transoding block ...
		if (listExecuteBlocks[t]->listSplitAt.count() > 0 )
			createTranscodeBlock (listExecuteBlocks[t], t);
		else
			createStandardBlock  (m_pScrollFrame, m_pScrollFrameLayout, listExecuteBlocks[t], t);
	}

	m_pScrollView->addChild (m_pScrollFrame);

	m_pFrameExplain = new QFrame( m_pScrollFrame, "m_pFrameExplain" );
	m_pFrameExplain->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)1, (QSizePolicy::SizeType)1, 0, 0, m_pFrameExplain->sizePolicy().hasHeightForWidth() ) );
	m_pFrameExplain->setPaletteBackgroundColor( QColor( 177, 211, 238 ) );
	m_pFrameExplain->setFrameShape( QFrame::GroupBoxPanel );
	m_pFrameExplain->setFrameShadow( QFrame::Sunken );
	m_pFrameExplain->setMaximumHeight(150);
	m_pFrameExplainLayout = new QGridLayout( m_pFrameExplain, 1, 1, 11, 6, "m_pFrameExplainLayout");

	m_pLabelExplain = new QLabel( m_pFrameExplain, "m_pLabelExplain" );
	m_pLabelExplain->setPaletteBackgroundColor( QColor( 177, 211, 238 ) );

	m_pFrameExplainLayout->addWidget( m_pLabelExplain, 0, 0 );

	m_pScrollFrameLayout->addWidget( m_pFrameExplain, 0, 0 );

	tabLayout->addWidget( m_pScrollView, 0, 0 );
	m_pTabWidget->insertTab( m_pTabExpert, QString("") );

	DialogExecuteLayout->addWidget( m_pTabWidget, 0, 0 );
}

void DialogExecute::createPostprocessing ()
{
//	m_pTabPostprocessing = new QWidget( m_pTabWidget, "m_pTabPostprocessing" );
//	m_pTabWidget->insertTab( m_pTabPostprocessing, QString("Cleaning") );
}

void DialogExecute::resizeEvent (QResizeEvent *p)
{
	// Here we keep the width of the inner Frame in sync with the resized Dialog ...
	QDialog::resizeEvent(p);
	slotTabChanged (m_pTabExpert);
}

void DialogExecute::slotTranscodeSelectionChanged (int iNewSelection)
{
	uint t, i, iComboCount;
	// Called when the user changes from e.g Transcode, to MEncoder ...
	for (t=0;t<m_listTranscodeCombos.count();t++)	{
		if (m_listTranscodeCombos[t]->hasFocus ())	{
			// Okay every transcode block has the same amount of options 
			// (currently only transcode and mencoder)
			iComboCount = m_listTranscodeCombos[t]->count ();
			for (i=0;i<iComboCount;i++)	{
				if (iNewSelection == (int)i)
					m_listTranscodeFrames[t*iComboCount+i]->show ();
				else
					m_listTranscodeFrames[t*iComboCount+i]->hide ();
			}
			slotTabChanged (m_pTabExpert);
			return;
		}
	}
}

void DialogExecute::slotTabChanged(QWidget *pTab)
{
	int iWidth, iViewWidth, iOffset;
	uint t;
	QPoint pos, globPos;

	if (pTab == m_pTabExpert)	{
		m_pScrollFrame->adjustSize();
		iViewWidth = m_pScrollView->visibleWidth();
		if (iViewWidth < 100)
			iViewWidth = 200;
		for (t=0;t<m_listCommandsWidget.count();t++)	{
			iOffset = 0;
			pos = m_listCommandsWidget[t]->pos();
			globPos = m_listCommandsWidget[t]->mapTo(m_pScrollFrame, pos);
			// If the this is not a SubSubFrame, then we can extend it by 11 (Layout margin)
			if (m_listCommandsWidget[t]->parentWidget ()->parent () == m_pScrollFrame)
				iOffset = 11;
			iWidth = iViewWidth - 139 + iOffset - globPos.x();
			if (iWidth < 100)
				iWidth = 200;
			m_listCommandsWidget[t]->setFixedWidth(iWidth);
		}
	}
}

void DialogExecute::slotCheckBlock(bool)
{
	static bool bWorking = false;
	// This function activates/deactivates all command lines in the checked // unchecked command block
	uint t;
	bool bShowCommandBlock;
	// This check will prevent the setChecked function calls in this function to mess up the logic.
	if (bWorking)
		return;
	bWorking = true;
	for (t=0;t<m_listGroupBox.count();t++)	{
		bShowCommandBlock = true;
		// First we need t figure out the logic ...
		// We are only interested in the negatives (I.e. when the block is NOT to be shown)
		// since the default is to show the command block.
		if ( (m_listGroupBox[t]->isVisible () ) && (!m_listCheckBox[t]->isChecked()) )
			bShowCommandBlock = false;
		if ( (!m_listGroupBox[t]->isVisible ()) && (!m_listCheckBox2[t]->isChecked()) )
			bShowCommandBlock = false;

		if (bShowCommandBlock)	{
			m_listCheckBox2[t]->hide();
			m_listGroupBox[t]->show ();
			m_listCheckBox[t]->setChecked (true);
		}
		else	{
			m_listGroupBox[t]->hide ();
			m_listCheckBox2[t]->show();
			m_listCheckBox2[t]->setChecked (false);
		}
	}
	bWorking = false;
}

// Sets the strings of the subwidgets using the current language.
void DialogExecute::languageChange()
{
    setCaption( tr( "Command Queue Dialog" ) );
    buttonHelp->setText( tr( "&Help" ) );
    buttonHelp->setAccel( QKeySequence( tr( "F1" ) ) );
    buttonOk->setText( tr( "&OK" ) );
    buttonOk->setAccel( QKeySequence( QString::null ) );
    buttonCancel->setText( tr( "&Cancel" ) );
    buttonCancel->setAccel( QKeySequence( QString::null ) );
    buttonExport->setText( tr( "&Export" ) );
    buttonExport->setAccel( QKeySequence( QString::null ) );
//    m_pTabWidget->changeTab( tab, tr( "Simple" ) );
    m_pLabelExplain->setText( tr( "<p align=\"center\"><b><h2>Here is the list of commands which will be executed. You can modify each single Command or accept the default settings.</h2></b></p>" ) );
    m_pTabWidget->changeTab( m_pTabExpert, tr( "Authoring" ) );
}

void DialogExecute::slotHelp ()
{
  MessageBox::warning (NULL, tr ("Help"), 
    tr ("In this dialog you see all commands that are going to get executed to create the DVD.\n\n"
	"[Export] Allows you to export all those commands to a script and execute one it fomr the command line.\n"
	"         Note: You can execute one command at a time. E.g. script.sh 1; script.sh 2 etc.\n"
	"[Help]   Displays this message.\n"
	"[e]      Opens the CommandEditorDialog. Using this button allows you to modify (and store) the command.\n"
	"[d]      Will set the current selected choice in the combo box as the default command.\n"
	"[man]    Will open a new dialog, which displays the man pages of all toools used in this command line.\n"
	"         Note: You can easily search for text through this dialog.\n"
	"[X]      (checkbox) this will enable / disable the commands for the whole selected command block.\n"
     ), QMessageBox::Ok , QMessageBox::NoButton );
  raise ();
}

void DialogExecute::slotManButtonClicked()
{
	QStringList listOfCommandsUsed;
	QWidget *pFromList;
	QWidget *pButton = childAt (mapFromGlobal(QCursor::pos()));
	if (!pButton)
		return;
	WId buttonID = pButton->winId();
	for (uint t=0;t<m_listButtonWidgets.count();t++)	{
		pFromList = m_listButtonWidgets[t];
		if ( ! pFromList )
			continue;
		if (m_listButtonWidgets[t]->winId() == buttonID)	{
			// Here we create the list of the commands in this commandString.
			QString qsCommand = m_listCommandsWidget[t]->currentText();
			QStringList partialCommandList = QStringList::split (";", qsCommand);
			for (uint i=0;i<partialCommandList.count();i++)	{
				QStringList partialCommandList2 = QStringList::split ("|", partialCommandList[i]);
				for (uint j=0;j<partialCommandList2.count();j++)	{
					QStringList argumentList =  QStringList::split (" ", partialCommandList2[j]);
					// the first argument is always the command.
					// but we don't want the cd command.
					if (argumentList[0] != "cd")
						listOfCommandsUsed.append(argumentList[0]);
				}
			}
			createManPages (listOfCommandsUsed);
			return;
		}
	}
}

void DialogExecute::slotEditButtonClicked()
{
  uint t, i;
  QStringList listOfCommandsUsed;
  QWidget *pFromList;
  int iWhichKeyset = Keyword::Keys;
  // In order to get the button we clicked we use the Cursor position ...
  QWidget *pButton = childAt ( mapFromGlobal ( QCursor::pos ( ) ) );
  if ( ! pButton )
    return;
  
  WId buttonID = pButton->winId ( );
  for ( t=0;t<m_listButtonEdit.count ( );t++ )	{
    pFromList = m_listButtonEdit[t];
    if (!pFromList)
      continue;
    if (pFromList->winId() == buttonID)	{
      // Here we open the CommandEditDialog ...
      if (m_pInitObject)	{
	QDVDAuthorInit::MenuBlock::Block *pBlock = m_pInitObject->getBlock (m_listBlockID[t], &iWhichKeyset );
	if (pBlock)	{
	  // Here we get the index to the appropriate ExecuteInterface for the given Block
	  int iInterface = m_listBlockExecuteInterface[t];
	  Keyword *pKeyword = m_pInitObject->getKeyword ( );
	  DialogCommandEditor *pEditor = new DialogCommandEditor (this);
	  pEditor->initMe (pBlock, m_listCommandsWidget[t]->currentItem(), pKeyword->getKeys ( iWhichKeyset ), m_listExecuteInterface[iInterface]->listKeywords.count() );
	  if (pEditor->exec () != QDialog::Rejected) {
	    // Here we set the command line to the modified strings. 
	    // and then we set the keywords for the found ExecuteInterface - object.
	    pKeyword->setKeywords( iWhichKeyset, m_listExecuteInterface[iInterface]->listKeywords );
	    // and finally we generate the command / header with the correct keywords ...
	    m_listCommandsWidget[t]->clear ();
	    for (i=0; i<pBlock->listCommands.count ( );
		 m_listCommandsWidget[t]->insertItem( pKeyword->resolvString( iWhichKeyset, pBlock->listCommands[i++] ) ) );
	    m_listCommentsWidget[t]->setText ( pKeyword->resolvString( iWhichKeyset, pBlock->listComments[0] ) );
	    m_pInitObject->setToolsPaths ( m_listToolsPaths );
	    m_pInitObject->saveIniFile   ( );
	    // this is to re-set the ToolsPaths information (keep it in here)
	    m_pInitObject->getToolsPaths ( );
	  }
	  delete pEditor;
	}
      }
      return;
    }
  }
}

void DialogExecute::slotDefaultButtonClicked()
{
	QWidget *pButton = childAt (mapFromGlobal(QCursor::pos()));
	if (!pButton)
		return;
	WId buttonID = pButton->winId();
	for (uint t=0;t<m_listButtonSetAsDefault.count();t++)	{
		if (m_listButtonSetAsDefault[t]->winId() == buttonID)	{
			if (m_pInitObject)	{
				m_pInitObject->setDefault (m_listBlockID[t], m_listCommandsWidget[t]->currentItem());
				m_pInitObject->setToolsPaths ( m_listToolsPaths );
				m_pInitObject->saveIniFile();
				// this is to re-set the ToolsPaths information (keep it in here)
				m_pInitObject->getToolsPaths ( );
			}
			return;
		}
	}
}

void DialogExecute::slotRenderMenu (QString qsMenuName)
{
	// Only here to forward the signal from the Execute - object (m_doSomething) to QDVDAuthor ...
	emit (signalRenderMenu(qsMenuName));
}

void DialogExecute::returnFromRenderMenu    ()
{
	// here we continue where we had a short break while rendering the menu.
	m_doSomething.raise();
	m_doSomething.startCommand ();
}

void DialogExecute::createManPages(QStringList &listOfCommandsUsed)
{
	// Create a modeless dialog, so we can work with DialogExecute and the DialogMan at the same time.
	DialogMan *pManDialog = new DialogMan(listOfCommandsUsed, this);
	pManDialog->show();
}

void DialogExecute::slotExport()
{
        uint t, iCounter = 0;
	int  i;
	// This function creates a script which the user can then execute ...
	QString fileName = QFileDialog::getSaveFileName("./", tr("Shell file (*.sh)"), this,tr( "Save file dialog"),tr( "Save File As ..."));
	if (fileName.isNull ())
		return;
	
	QFileInfo fileInfo(fileName);
	if (fileInfo.extension(FALSE).isEmpty())
		fileName += QString (".sh");
	
	QFile shellFile(fileName);
	QString qsComment;
	if ( shellFile.open( IO_WriteOnly ) ) {
		QTextStream stream( &shellFile );
		stream << Global::qsBashString;
		stream << "run=0\n";
		stream << "if [ $# -eq 0 ];\n";
		stream << "then\n";
		stream << "        run=1\n";
		stream << "fi;\n\n";
		stream << "while [ $# -gt 0 ] || [ $run -eq 1 ]\n";
		stream << "do\n\n";

		for (t=0;t<m_listCommandsWidget.count();t++)	{
			// First we check if the user wants this command to get executed after all ...
			if (m_listCommandsWidget[t]->isVisible ())	{
			  stream << "if [ 1 -eq $run ] || [ " << ++iCounter << " -eq $1 ];\n";
			  stream << "then\n";
			  // Okay to also output the comments ...
			  qsComment = stripTags(m_listCommentsWidget[t]->text());
			  stream << "# " << qsComment + "\n";
			  stream << "#############################################################################\n";
			  // we should offer all options as comments and the current one as the real deal ...
			  for (i=0;i<m_listCommandsWidget[t]->count();i++)	{
			    if (i != m_listCommandsWidget[t]->currentItem())	{
			      stream << "# Option " << i << " : \n";
			      stream << "# " <<  getToolsPath(m_listCommandsWidget[t]->text(i)) + "\n";
			    }
			  }
			  // And here we write the current selected Option ...
			  if ( m_listCommandsWidget[t]->currentText().find ( "#=-" ) == 0 )  // we should add this to avoid an error message for this script.
			    stream << "echo \"" << m_listCommandsWidget[t]->currentText() << "\"\n";
			  else
			    stream << getToolsPath(m_listCommandsWidget[t]->currentText()) + "\n";
			  stream << "fi;\n\n";
			}
		}
		stream << "shift\n";
		stream << "run=0\n";
		stream << "done\n\n";
		shellFile.close();
		chmod ((const char *)fileName, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
		emit (signalGenerateMasks ());
	}
}

QString DialogExecute::stripTags(QString qsInput)
{
	// This function will strip off all HTML TAGs (Or anything between < and >
	QString qsOutput = qsInput;
	QRegExp rx ("<[^>]*>");

	qsOutput.remove(rx);
	qsOutput.remove("\n");
	return qsOutput;
}

void DialogExecute::slotOkay()
{
	uint t;
	QStringList listCommands;
	// first let us create the masks ...
	emit (signalGenerateMasks ());
	for (t=0;t<m_listCommandsWidget.count();t++)	{
		if (m_listCommandsWidget[t]->isVisible())
			listCommands.append(getToolsPath(m_listCommandsWidget[t]->currentText()));
	}
	m_doSomething.system(listCommands);

	hide ();

	// for a blocking execution one has to start a timer, which checks m_doSomthing.isRunning()
	// And calls accept () only after all commands have been executed.
	// Also one needs to tak care of the user closing the execution-output-dialog.
//	accept();
}

QString DialogExecute::getToolsPath(QString qsCommandLine)
{
	// This function will take the command line as an input and add the full path to each of the tools used in this cmmand line.
	// E.g. 
	// jpeg2yuv -n 50 -j "/tmp/Main Menu VMGMbackground.jpg" | mpeg2enc -n p -o "/tmp//Main Menu VMGM.m2v"
	// will be converted into 
	// /usr/bin/jpeg2yuv -n 50 -j "/tmp/Main Menu VMGMbackground.jpg" | /usr/local/bin/mpeg2enc -n p -o "/tmp//Main Menu VMGM.m2v"
	/////////////////////////////////////////////////////////////////////

	uint t;
	QString qsReturn;
	QString qsCommand;
	QRegExp regExp;
	qsReturn = qsCommandLine;

	for (t=0;t<m_listToolsPaths.count ();t++)	{
		if (m_listToolsPaths[t]->bPresent)	{
 			// The first regExp takes care of all occurances of the tool which do NOT start with a '/'
			regExp = QRegExp ("(^|\\s(?!/+))"+m_listToolsPaths[t]->qsExecutableName+" ");
			qsReturn.replace (regExp, m_listToolsPaths[t]->qsFullPath+" ");
			// The second regExp takes care of the case where the user does not leave a blank between the pipe symbol '|' and the tool.
 			regExp = QRegExp ("\\|"+m_listToolsPaths[t]->qsExecutableName+" ");
			qsReturn.replace (regExp, "| "+m_listToolsPaths[t]->qsFullPath+" ");
		}
//		else
//			printf ("WARNING, %s not present in system.\n", (const char *) m_listToolsPaths[t]->qsExecutableName);
	}
	return qsReturn;
}
