/****************************************************************************
** DialogAnimation class
**
**   Created : Mon May 30 22:48:00 2005
**        by : Varol Okan using xemacs
** Copyright : (c) Varol Okan
**   License : GPL v 2.0
**
** Note this dialog plays hand in hand with the TemplateDialog.
** All templates are first loaded from the $PREFIX directory
** and then from $HOME/.qdvdauthor
**
** Also in planing is another dialog, to generate templates.
** The output of this dialog will contain of :
** o  the <template_name>.tar.gz
** o  the code snipplet to be added to index.xml (to put the templte onto the server)
** o  the <template_name>.png ( same as preview.png )
**
****************************************************************************/
/* XML format
<Templates>
        <Entry name="basic6" type="static" >
                <Description>This is a basic Layout for 6 Buttons.</Description>
                <Thumbnail size="44311">basic6.png</Thumbnail>
                <Location size="1123725">basic6.tar.gz</Location>
        </Entry>
	<Entry> ...
	</Entry>
</Templates>
*/

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef QDVD_LINUX 
#include <unistd.h>
#endif

#include <qprogressbar.h>
#include <qradiobutton.h>
#include <qpushbutton.h>
#include <qtabwidget.h>
#include <qcombobox.h>
#include <qtextedit.h>
#include <qiconview.h>
#include <qprocess.h>
#include <qlabel.h>
#include <qfile.h>
#include <qdir.h>


#include <qnetwork.h>

#include "win32.h"
#include "CONFIG.h"
#include "global.h"
#include "messagebox.h"
#include "templatedownload.h"

//////////////////////////////////////////////////////////////////////////////////
//
// Entry - class to parse the XML file.
//
/////////////////////////////////////////////////////////////////////////////////

TemplateDownload::Xml::Entry::Entry ( )
{
  iThumbnailSize      = 0;
  iLocationSize       = 0;
  bSelectedForInstall = false;
}

TemplateDownload::Xml::Entry *TemplateDownload::Xml::entry ( int iEntry )
{
  if ( ( iEntry < 0 ) || ( iEntry >= (int) m_listOfEntries.count () ) )
    return NULL;
  return m_listOfEntries.at ( iEntry );
}

bool TemplateDownload::Xml::parseXml ( QString &fileContents )
{
  QDomDocument xmlDoc    ( TEMPLATES_DOCTYPE );
  QDomNode     xmlNode, xmlSubNode;
  QDomElement  docElem, xmlEntry, xmlSubEntry;
  QDomAttr     attrib;
  Entry       *pEntry;

  if ( ! xmlDoc.setContent ( fileContents ) )
    return false;

  // And at last lets try to read the information of the file.
  
  docElem = xmlDoc.documentElement();
  if ( docElem.tagName () != TEMPLATES_TEMPLATES ) 
    return false;

  clear ( );
  xmlNode = docElem.firstChild ( );
  while ( ! xmlNode.isNull () ) { 
    xmlEntry = xmlNode.toElement ( );
    if ( xmlEntry.tagName ( ) == TEMPLATES_ENTRY ) { 
      pEntry = new Entry;
      attrib = xmlEntry.attributeNode ( TEMPLATES_ATTRIB_NAME );
      pEntry->qsName = attrib.value   ( );
      attrib = xmlEntry.attributeNode ( TEMPLATES_ATTRIB_TYPE );
      pEntry->qsType = attrib.value   ( );
      xmlSubNode = xmlEntry.firstChild( );
      while ( ! xmlSubNode.isNull ( ) ) {
	xmlSubEntry = xmlSubNode.toElement ( );
	if ( xmlSubEntry.tagName ( ) == TEMPLATES_ENTRY_DESCRIPTION ) {
	  pEntry->qsDescription = xmlSubEntry.text ( );
	}
	else if ( xmlSubEntry.tagName ( ) == TEMPLATES_ENTRY_THUMBNAIL ) {
	  attrib = xmlSubEntry.attributeNode ( TEMPLATES_ATTRIB_SIZE );
	  if ( ! attrib.value ( ).isEmpty ( ) )
	    pEntry->iThumbnailSize = attrib.value ( ).toInt ( );
	  pEntry->qsThumbnail = xmlSubEntry.text ( );
	}
	else if ( xmlSubEntry.tagName ( ) == TEMPLATES_ENTRY_LOCATION ) {
	  attrib = xmlSubEntry.attributeNode ( TEMPLATES_ATTRIB_SIZE );
	  if ( ! attrib.value ( ).isEmpty ( ) )
	    pEntry->iLocationSize = attrib.value ( ).toInt ( );
	  pEntry->qsLocation = xmlSubEntry.text ( );
	}
	xmlSubNode = xmlSubNode.nextSibling ( );
      }
      m_listOfEntries.append ( pEntry );
    }
    xmlNode = xmlNode.nextSibling ( );
  }

  return true;
}

void TemplateDownload::Xml::clear ( )
{
  uint t;
  for ( t=0;t<m_listOfEntries.count ();t++ ) {
    delete m_listOfEntries.at ( t );
  }
  m_listOfEntries.clear ( );
}

//////////////////////////////////////////////////////////////////////////////////
//
// Download - dialog for the Templates.
//
/////////////////////////////////////////////////////////////////////////////////
TemplateDownload::TemplateDownload (QWidget *pParent, const char *pName, WFlags f )
	: uiTemplateDownload (pParent, pName, f)
{
  qInitNetworkProtocols ( );
  resetDialog ( );
  m_pNewProcess = NULL;

  m_pIconViewStatic->setSelectionMode     ( QIconView::Extended );
  m_pIconViewAnimated->setSelectionMode   ( QIconView::Extended );
  m_pIconViewTransition->setSelectionMode ( QIconView::Extended );

  connect ( m_pButtonConnect,  SIGNAL ( clicked ( ) ), this, SLOT ( slotConnect  ( ) ) );
  connect ( m_pButtonDownload, SIGNAL ( clicked ( ) ), this, SLOT ( slotDownload ( ) ) );
  connect ( m_pButtonNext,     SIGNAL ( clicked ( ) ), this, SLOT ( slotNext     ( ) ) );
  connect ( m_pButtonHelp,     SIGNAL ( clicked ( ) ), this, SLOT ( slotHelp     ( ) ) );

  connect ( &m_Network, SIGNAL ( start    ( QNetworkOperation * ) ), this, SLOT ( slotNetworkStart    ( QNetworkOperation * ) ) );
  connect ( &m_Network, SIGNAL ( finished ( QNetworkOperation * ) ), this, SLOT ( slotNetworkFinished ( QNetworkOperation * ) ) );
  connect ( &m_Network, SIGNAL ( data( const QByteArray &, QNetworkOperation * ) ),        this, SLOT ( slotNetworkData ( const QByteArray &, QNetworkOperation * ) ) );
  connect ( &m_Network, SIGNAL ( dataTransferProgress ( int, int, QNetworkOperation * ) ), this, SLOT ( slotNetworkProgress ( int, int, QNetworkOperation * ) ) );
}

TemplateDownload::~TemplateDownload ()
{
}

void TemplateDownload::resetDialog ()
{
  m_pLabelPleaseWait->hide ( );
  m_pProgressConnect->setProgress ( 0 );  
  m_iStage           = -1;
  m_iTotalBytes      =  0;
  m_iCurrentEntry    =  0;
  m_iCurrentBytes    =  0;
  m_bytes = QByteArray ( );
  m_qsIndexFile      =  "";
  m_xml.clear ( );
  m_pTabMain->setCurrentPage ( 0 );
  QWidget *pServerTab = m_pTabMain->page       ( 0 );
  m_pTabMain->setTabEnabled ( pServerTab,     true );
  QWidget *pSelectionTab = m_pTabMain->page    ( 1 );
  m_pTabMain->setTabEnabled ( pSelectionTab, false );
  QWidget *pInstallTab = m_pTabMain->page      ( 2 );
  m_pTabMain->setTabEnabled ( pInstallTab,   false );
  m_pEditConnect->clear        ( );
  m_pEditDownload->clear       ( );
  m_pIconViewStatic->clear     ( );
  m_pIconViewAnimated->clear   ( );
  m_pIconViewTransition->clear ( );
  m_pButtonNext->setText ( "Next >>>" );
}

//////////////////////////////////////////////////////////////////////////////////
//
// Functions for the "Server Settings" Tab
//
/////////////////////////////////////////////////////////////////////////////////
void TemplateDownload::slotConnect ()
{
  m_pLabelPleaseWait->show ( );
  QString qsUrl = m_pComboServer->currentText ( ) + "/index.xml";

  if ( ! verifyUrl ( qsUrl ) )
    return;
  
  m_pEditConnect->setText ( tr ("Trying to obtain the file :\n" ) );
  m_pEditConnect->append  ( qsUrl );

  m_iStage      = 1; // getting the index file
  m_qsIndexFile = "";
  m_Network     = QUrlOperator ( qsUrl );
  m_Network.get ( );
}

void TemplateDownload::slotNext ( )
{
  switch ( m_iStage ) {
  case -1:
  case  2:
    slotConnect  ( );
  break;
  case  3:// this is after the index.xml file is loaded and the first Tab is disabled.
    slotDownload ( );
  break;
  case  4: // before install
  break;
  case  5: // after install
    accept ( );
  break;
  default:
    ; // NOOP
  }
}

void TemplateDownload::slotHelp ()
{
  QString qsHtml;

  if ( m_pTabMain->currentPageIndex ( ) == 0 ) {
    qsHtml  = tr ("You have to connect to the server by clicking on [<B>Connect</B>].<P>");
    qsHtml += tr ("After the information was found on the server you will be able to select and Download / Install the templates.<BR>");
  }
  else if ( m_pTabMain->currentPageIndex ( ) == 1 ) {
    qsHtml  = tr ("In this tab you can select the templates you want to install on your computer.<P>"); 
    qsHtml += tr ("You can select multiple templates by pressing SHIFT, or CTRL while selecting the templates.");
  }
  else if ( m_pTabMain->currentPageIndex ( ) == 2 ) {
    qsHtml  = tr ("First you <U>have to</U> decide if you want to install the templates in your home directory or or the whole system.<P>");
    qsHtml += tr ("[<B>Download & Install</B>] will then install all selcted templates on your computer.");
  }

  MessageBox::html  ( NULL, tr( "Template Download Help" ), qsHtml );
}

bool TemplateDownload::verifyUrl ( QString &qsUrl )
{
  QString qsProtocol;
  QUrl::decode ( qsUrl );
  QUrl  theUrl ( qsUrl );

  if ( ! theUrl.isValid () ) {
    m_pEditConnect->append ( tr ( "This does not seem to be a valid URL : %1.\n" ).arg ( qsUrl ) );
    return false;
  }

  qsProtocol = theUrl.protocol ( );
  if ( qsProtocol.isEmpty ( ) )
    qsProtocol = "http";

  if ( ( qsProtocol != "http" ) && ( qsProtocol != "ftp" ) ) {
    m_pEditConnect->append ( tr( "Only http, and ftp protocol are currently supported.\n" ) );
    return false;
  }
  return true;
}

void TemplateDownload::slotNetworkStart  ( QNetworkOperation * )
{
  m_pEditConnect->append ( "slotNetworkStart\n" );

}

void TemplateDownload::slotNetworkFinished  ( QNetworkOperation *pOperation )
{
  if ( pOperation->operation ( ) != QNetworkProtocol::OpGet )
    return;
  Xml::Entry *pEntry = NULL;
  //  m_pEditConnect->append ( QString("slotNetworkFinished <%1><%2>\n" ).arg ( m_iCurrentBytes ).arg ( m_iTotalBytes) );
  switch ( m_iStage ) {
  case 1: // download the index - file - stage
    if ( m_qsIndexFile.isEmpty () ) {
      m_pEditConnect->append ( tr( "Could not find the index file with Template information\n" ) );
      resetDialog ( );
    }
    else 
      parseIndexFile ( );
    break;
  case 2:// download the thumbnails - stage.
    createThumbnail  ( );
    break;
  case 4:
    pEntry = m_xml.entry ( m_iCurrentEntry );
    if ( pEntry ) 
      m_iCurrentBytes += pEntry->iLocationSize;
    downloadTemplate ( ++m_iCurrentEntry );
  break;
  }
}

void TemplateDownload::createThumbnail () 
{
  Xml::Entry *pEntry = m_xml.entry ( m_iCurrentEntry );
  if ( pEntry ) {
    //    QUrl  theUrl ( pEntry->qsThumbnail );
    //    QString qsFile = "/tmp/" + theUrl.fileName ( );
    m_iCurrentBytes += pEntry->iThumbnailSize;
    //    pEntry->theThumbnail = QImage ( qsFile );
  }
  downloadThumbnail ( ++m_iCurrentEntry );
}

void TemplateDownload::createThumbnails ( ) 
{
  uint t;
  for (t=0; t<(uint)m_xml.entryCount ();t++) {
    Xml::Entry *pEntry = m_xml.entry ( t );
    if ( pEntry ) {
      QUrl  theUrl ( pEntry->qsThumbnail );
      QString qsFile = "/tmp/" + theUrl.fileName ( );
      pEntry->theThumbnail = QImage ( qsFile );
    }
  }
}
/* QUrlOperator.get does not seem to work with binary data.
void TemplateDownload::createThumbnail () 
{
  Xml::Entry *pEntry = m_xml.entry ( m_iCurrentEntry );
  if ( pEntry ) {
    if ( pEntry->iThumbnailSize != (int) m_bytes.size () )
      ; // error
    
    pEntry->theThumbnail = QImage ( m_bytes );
  }

  m_iCurrentBytes += m_bytes.size ( );
  m_bytes = QByteArray ();
  downloadThumbnail ( ++m_iCurrentEntry );
}
*/
void TemplateDownload::downloadThumbnail ( int iCurrentEntry )
{
  QString qsStatus;
  if ( iCurrentEntry < m_xml.entryCount ( ) ) {
    Xml::Entry *pEntry = m_xml.entry ( iCurrentEntry );
    if ( pEntry ) {
      qsStatus = tr ( "Retrieving Thumbnail<br> %1" ).arg ( pEntry->qsThumbnail );
      m_pEditConnect->append ( tr ( "Getting Thumbnail : %1" ).arg ( pEntry->qsThumbnail ) );
      displayStatus ( qsStatus );

      QString qsUrl = m_pComboServer->currentText ( ) + "/" + pEntry->qsThumbnail;
      if ( ! verifyUrl ( qsUrl ) ) { 
	downloadThumbnail ( ++m_iCurrentEntry );
	return;
      }
      m_Network = QUrlOperator ( qsUrl );
      //      m_Network.get ( );
      m_Network.copy ( qsUrl, "/tmp" );
      return;
    }
  }
  m_iStage = 3;
  qsStatus = tr ( "Done downloading thumbnails." );
  displayStatus   ( qsStatus );
  lockDialog      ( false    );
  createSelection ( );
}

void TemplateDownload::downloadThumbnails ( )
{
  int t;
  QStringList listOfThumbnails;
  for (t=0;t<m_xml.entryCount();t++) {
    Xml::Entry *pEntry = m_xml.entry ( t );
    if ( pEntry ) {
      m_pEditConnect->append ( tr ( "Getting Thumbnail : %1" ).arg ( pEntry->qsThumbnail ) );
      //      displayStatus (  QString ( "Retrieving Thumbnail : %1" ).arg ( pEntry->qsThumbnail ) );

      QString qsUrl = m_pComboServer->currentText ( ) + "/" + pEntry->qsThumbnail;
      if ( ! verifyUrl ( qsUrl ) )
	continue;
      listOfThumbnails.append ( qsUrl );
    }
  }
  if (listOfThumbnails.count () > 0 )
    m_Network.copy ( listOfThumbnails, "/tmp" );
}

void TemplateDownload::slotNetworkData ( const QByteArray &someBytes, QNetworkOperation * )
{
  switch ( m_iStage ) {
  case 1:
    m_qsIndexFile += QString ( someBytes );
    break;
  }
  //  m_pEditConnect->append ( QString( "slotNetworkData <%1><%2>\n" ).arg(m_iCurrentBytes).arg(m_bytes.size()) );
}

void TemplateDownload::slotNetworkProgress ( int iDone, int iTotal, QNetworkOperation *pOperation )
{
  QProgressBar *pProgress = m_pProgressConnect;
  if ( m_iStage == 4 )
    pProgress = m_pProgressDownload;

  if ( pOperation->operation ( ) == QNetworkProtocol::OpGet ) {
    if ( m_iTotalBytes > 0 )
      pProgress->setProgress ( m_iCurrentBytes + iDone, m_iTotalBytes );
    else
      pProgress->setProgress ( iDone, iTotal );
  }
}

void TemplateDownload::parseIndexFile ( )
{
  QString qsStatus; 
  int t, iNumberOfTemplates = 0;
  Xml::Entry *pEntry;

  m_pEditConnect->append ( tr ( "Parsing index file\n" ) );

  if ( ! m_xml.parseXml ( m_qsIndexFile ) ) {
    resetDialog   ( );
    qsStatus = tr ( "Error Parsing index.xml - file from server.<BR>Try again ?\n" );
    // Debug info ...
    //m_pEditConnect->append  ( QString ( "CurrBytes<%1> vs totalBytes<%2>\n" ).arg ( m_iCurrentBytes ).arg ( m_iTotalBytes ) );
    //m_pEditConnect->append  ( m_qsIndexFile );
    displayStatus ( qsStatus );
    return;
  }
  iNumberOfTemplates = m_xml.entryCount ( );
  m_iCurrentEntry = m_iCurrentBytes = m_iTotalBytes = 0;
  // At this point we should have all the information required.
  for (t=0;t<iNumberOfTemplates;t++ ) {
    pEntry = m_xml.entry ( t );
    if ( pEntry )
      m_iTotalBytes += pEntry->iThumbnailSize;
  }
  
  m_pEditConnect->append ( tr ( "Discovered %1 templates. Downloading thumbnails.\n" ).arg ( iNumberOfTemplates ) );
  m_iStage = 2;
  lockDialog ( true );
  downloadThumbnail ( 0 );
  //downloadThumbnails ( );
}

void TemplateDownload::lockDialog ( bool bLock )
{
  bLock = bLock;
  // enables / disables all buttons but the Cancel button.
}

void TemplateDownload::displayStatus ( QString &qsStatus )
{
  if ( ! m_pLabelPleaseWait->isVisible () )
         m_pLabelPleaseWait->show ();
  m_pLabelPleaseWait->setText ( "<p align=\"center\"><b><font size=\"+3\" color=\"red\" >" + qsStatus + "</font></b></p>");  
}

//////////////////////////////////////////////////////////////////////////////////
//
// Functions for the "Template Selection" Tab
//
/////////////////////////////////////////////////////////////////////////////////

void TemplateDownload::createSelection () 
{
  // This function will fill in the previews in their preview tabs for the user to select
  QWidget *pServerTab = m_pTabMain->page      ( 0 );
  m_pTabMain->setTabEnabled ( pServerTab,   false );
  QWidget *pSelectionTab = m_pTabMain->page   ( 1 );
  m_pTabMain->setTabEnabled ( pSelectionTab, true );
  QWidget *pInstallTab = m_pTabMain->page     ( 2 );
  m_pTabMain->setTabEnabled ( pInstallTab,   true );
  m_pTabMain->setCurrentPage ( 1 );

  createThumbnails ( );

  int t;
  Xml::Entry *pEntry;
  QIconView  *pIconView;
  for (t=0;t<(int)m_xml.entryCount ();t++) {
    pEntry = m_xml.entry ( t );
    if ( pEntry ) {
      pIconView = m_pIconViewStatic;
      if ( pEntry->qsType == "animated" )
	pIconView = m_pIconViewAnimated;
      else if ( pEntry->qsType == "transition" )
	pIconView = m_pIconViewTransition;
      QString qsDesc = pEntry->qsName + "\n" + pEntry->qsDescription;
      QIconViewItem *pItem = new QIconViewItem ( pIconView, qsDesc, pEntry->theThumbnail );
      pItem->setKey ( pEntry->qsName );
      pItem->setSelectable  ( true  );
     }
  }
}

//////////////////////////////////////////////////////////////////////////////////
//
// Functions for the "Download and Install" Tab
//
/////////////////////////////////////////////////////////////////////////////////

void TemplateDownload::slotDownload ( )
{
  // Okay to gather the selection from the ListViews ...
  int t, i, iSelectedCounter;
  Xml::Entry             *pEntry;
  QString                 qsOutput;
  QIconViewItem          *pItem;
  QIconView              *pIconView = m_pIconViewStatic;

  m_pTabMain->setCurrentPage ( 2 );
  m_pButtonNext->setText ( "Finish" );
  m_iStage         = 4;
  m_iTotalBytes    = 0;
  m_iCurrentBytes  = 0;
  iSelectedCounter = 0;
  for (t=0;t<3;t++) {
    pItem  = pIconView->firstItem ( );    
    while ( pItem ) {
      if  ( pItem->isSelected ( ) ) {	
	for (i=0;i<m_xml.entryCount ();i++) {
	  pEntry = m_xml.entry ( i );
	  if ( pEntry ) {
	    if ( ( pEntry->qsName        == pItem->key  ( ) ) && 
		 ( pEntry->qsDescription == pItem->text ( ) ) ) {
	      pEntry->bSelectedForInstall = true;
	      iSelectedCounter ++;
	      m_iTotalBytes += pEntry->iLocationSize;
	    }
	  }
	}
      } // if pItem->isSelected ()
      pItem = pItem->nextItem ( );
    }   // while ( pItem ) ...

    if ( t == 0 )
      pIconView  = m_pIconViewAnimated;
    else if ( t == 1 )
      pIconView = m_pIconViewTransition;
  }

  qsOutput = tr ( "%1 Selected Templates. Total size = %2" ).arg ( iSelectedCounter ).arg ( m_iTotalBytes );
  m_pEditDownload->append ( qsOutput );
  // sanity check ...
  if ( iSelectedCounter < 1 ) {
    if ( MessageBox::question ( NULL, tr ( "Warning" ), tr ( "No templates selected.\nDo you want to start over again ?" ), QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes )
      resetDialog ( );
    else
      accept      ( );
    return;
  }

  // Okay at this point we can start downloading the template files.
  lockDialog ( true );
  m_pButtonDownload->setEnabled ( false );
  m_iCurrentEntry  = 0;
  downloadTemplate ( 0 );
}

void TemplateDownload::downloadTemplate ( int iCurrentEntry )
{
  if (   iCurrentEntry < m_xml.entryCount ( ) ) {
    Xml::Entry *pEntry = m_xml.entry ( iCurrentEntry );
    if ( ( ! pEntry ) || ( ! pEntry->bSelectedForInstall ) ) { // if this entry is not selected for download, then go to the next
      downloadTemplate ( ++m_iCurrentEntry );
      return;
    }
    if ( pEntry ) {
      m_pEditDownload->append ( tr ( "Retrieving Template<br>%1. Size = %2" ).arg ( pEntry->qsName ).arg ( pEntry->iLocationSize ) );

      QString qsUrl = m_pComboServer->currentText ( ) + "/" + pEntry->qsLocation;
      if ( ! verifyUrl ( qsUrl ) ) { 
	downloadTemplate ( ++m_iCurrentEntry );
	return;
      }
      m_Network = QUrlOperator ( qsUrl );
      //      m_Network.get ( );
      m_Network.copy ( qsUrl, "/tmp" );
      return;
    }
  }
  m_pButtonDownload->setEnabled ( true );
  m_pEditDownload->append ( tr( "Done downloading templates.") );
  installTemplates ( );
}

void TemplateDownload::installTemplates ( )
{
  m_iStage = 4;
  m_pEditDownload->append ( tr( "Starting Installing the templates.") );

  int t;
  QString qsScript, qsTemplatePath, qsExecutable;
  qsExecutable = Global::qsTempPath + QString ( "/execute.sh" );
  QFile file ( qsExecutable );
  qsTemplatePath = "~/.qdvdauthor/";
  if ( m_pRadioSystemWide->isChecked ( ) )
    qsTemplatePath = Global::qsSystemPath + "/share/qdvdauthor/";

  if ( file.open( IO_WriteOnly ) ) {
    QTextStream stream( &file );
    stream << Global::qsBashString;
    stream << "mkdir -p " << qsTemplatePath << "static\n";
    stream << "mkdir -p " << qsTemplatePath << "animated\n";
    stream << "mkdir -p " << qsTemplatePath << "transition\n";

    stream << "cd " + qsTemplatePath + "\n";

    for ( t=0; t<m_xml.entryCount ( ); t++ ) {
      Xml::Entry *pEntry = m_xml.entry ( t );
      if( pEntry && pEntry->bSelectedForInstall )
        stream << "tar -xzf /tmp/" + pEntry->qsLocation + "\n";
    }
    file.close();
  }
  // And here we grant read/write/execute permission.
  chmod ((const char *)QString( qsExecutable ), S_IXGRP | S_IWGRP | S_IRGRP | S_IEXEC | S_IRUSR | S_IWRITE | S_IROTH | S_IXOTH | S_IWOTH );

  // install the Templates ...
  installToSystem ( qsExecutable, m_pRadioLocally->isChecked ( ) );
}

void TemplateDownload::installToSystem ( QString &qsCommand, bool bInstallLocally )
{
  if (m_pNewProcess)	{
    if (m_pNewProcess->isRunning())
      return;
    else 
      delete m_pNewProcess;
  }

  Utils theUtils;
  m_pNewProcess  = new QProcess ( this );
  connect( m_pNewProcess, SIGNAL ( readyReadStdout ( ) ), this, SLOT ( slotReadFromProcess ( ) ) );
  connect( m_pNewProcess, SIGNAL ( readyReadStderr ( ) ), this, SLOT ( slotReadFromProcess ( ) ) );
  connect( m_pNewProcess, SIGNAL ( processExited   ( ) ), this, SLOT ( slotProcessExited   ( ) ) );

  if ( ! bInstallLocally ) {
    // the next check is to see if we can find kdesu
    QString qsGuiSU = theUtils.findGuiSU ( );
    if ( qsGuiSU.isEmpty ( ) ) {
      MessageBox::information (NULL, tr ( "Could not find kdesu, xsu, or gnomesu" ),
        tr ( "Without kdesu, xsu, or gnomesu I can not istall them templates in %1/share/qdvdauthor/.\n").
        arg ( Global::qsSystemPath ), QMessageBox::Ok ,  QMessageBox::NoButton);
      return;
    }
    if (qsGuiSU == QString ("kdesu"))	{
      m_pNewProcess->addArgument ("kdesu");
      m_pNewProcess->addArgument ("-n");
      m_pNewProcess->addArgument ("-t");
      m_pNewProcess->addArgument ("-c");
    }
    else if (qsGuiSU == QString ("xsu"))	{
      m_pNewProcess->addArgument ("xsu");
      m_pNewProcess->addArgument ("--username");
      m_pNewProcess->addArgument ("root");
      m_pNewProcess->addArgument ("--message");
      m_pNewProcess->addArgument ("Please type in the root password");
      m_pNewProcess->addArgument ("--command");
    }
    else if (qsGuiSU == QString ("gnomesu"))	{
      m_pNewProcess->addArgument ("xsu");
      m_pNewProcess->addArgument ("--username");
      m_pNewProcess->addArgument ("root");
      m_pNewProcess->addArgument ("--message");
      m_pNewProcess->addArgument ("Please type in the root password");
      m_pNewProcess->addArgument ("--command");
    }
  }
  m_pNewProcess->addArgument ( qsCommand );

  m_pNewProcess->start ( );
}

void TemplateDownload::slotReadFromProcess  ( )
{
  if ( ! m_pNewProcess )
    return;
  QString stdOut = m_pNewProcess->readStdout ( );
  if (stdOut.length() > 5)
    m_pEditDownload->append ( stdOut );
  QString stdErr = m_pNewProcess->readStderr ( );
  if (stdErr.length() > 5)
    m_pEditDownload->append ( stdErr );
}

void TemplateDownload::slotProcessExited ()
{
  m_iStage = 5;
  slotReadFromProcess ( );
  m_pProgressInstall->setProgress ( 100, 100 );
  // Allow closing this dialog again.
  lockDialog      ( false    );

  m_pEditDownload->append ( tr( "Finished Installing the templates.") );
}
