/* * * $Id: k3bmovixdocpreparer.cpp 619556 2007-01-03 17:38:12Z trueg $ * Copyright (C) 2003 Sebastian Trueg * * This file is part of the K3b project. * Copyright (C) 1998-2007 Sebastian Trueg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * See the file "COPYING" for the exact licensing terms. */ #include "k3bmovixdocpreparer.h" #include "k3bmovixdoc.h" #include "k3bmovixprogram.h" #include "k3bmovixfileitem.h" #include #include #include #include #include #include #include #include #include #include #include #include class K3bMovixDocPreparer::Private { public: Private() : doc(0), playlistFile(0), isolinuxConfigFile(0), movixRcFile(0), isolinuxDir(0), movixDir(0), mplayerDir(0), playlistFileItem(0), structuresCreated(false) { } K3bMovixDoc* doc; const K3bMovixBin* eMovixBin; KTempFile* playlistFile; KTempFile* isolinuxConfigFile; KTempFile* movixRcFile; K3bDirItem* isolinuxDir; K3bDirItem* movixDir; K3bDirItem* mplayerDir; K3bFileItem* playlistFileItem; TQPtrList newMovixItems; bool structuresCreated; }; K3bMovixDocPreparer::K3bMovixDocPreparer( K3bMovixDoc* doc, K3bJobHandler* jh, TQObject* parent, const char* name ) : K3bJob( jh, parent, name ) { d = new Private(); d->doc = doc; } K3bMovixDocPreparer::~K3bMovixDocPreparer() { removeMovixStructures(); delete d; } K3bMovixDoc* K3bMovixDocPreparer::doc() const { return d->doc; } void K3bMovixDocPreparer::start() { kdDebug() << k_funcinfo << endl; jobStarted(); bool success = true; if( d->structuresCreated ) removeMovixStructures(); else success = createMovixStructures(); jobFinished(success); } void K3bMovixDocPreparer::cancel() { // do nothing... } bool K3bMovixDocPreparer::createMovixStructures() { kdDebug() << k_funcinfo << endl; removeMovixStructures(); if( doc() ) { doc()->setMultiSessionMode( K3bDataDoc::NONE ); doc()->prepareFilenames(); } d->eMovixBin = dynamic_cast( k3bcore->externalBinManager()->binObject("eMovix") ); if( d->eMovixBin ) { bool success = false; if( d->eMovixBin->version >= K3bVersion( 0, 9, 0 ) ) success = addMovixFilesNew(); else success = addMovixFiles(); d->structuresCreated = success; return success; } else { emit infoMessage( i18n("Could not find a valid eMovix installation."), ERROR ); return false; } } void K3bMovixDocPreparer::removeMovixStructures() { kdDebug() << k_funcinfo << endl; // remove movix files from doc // the dataitems do the cleanup in the doc delete d->movixDir; delete d->isolinuxDir; delete d->mplayerDir; delete d->playlistFileItem; d->movixDir = 0; d->isolinuxDir = 0; d->mplayerDir = 0; d->playlistFileItem = 0; d->newMovixItems.setAutoDelete( true ); d->newMovixItems.clear(); // remove all the temp files delete d->playlistFile; delete d->isolinuxConfigFile; delete d->movixRcFile; d->playlistFile = 0; d->isolinuxConfigFile = 0; d->movixRcFile = 0; d->structuresCreated = false; } bool K3bMovixDocPreparer::writePlaylistFile() { delete d->playlistFile; d->playlistFile = new KTempFile(); d->playlistFile->setAutoDelete(true); if( TQTextStream* s = d->playlistFile->textStream() ) { const TQPtrList& movixFileItems = d->doc->movixFileItems(); for( TQPtrListIterator it( movixFileItems ); *it; ++it ) { *s << "/cdrom/"; *s << it.current()->writtenName(); *s << endl; } d->playlistFile->close(); return true; } else { emit infoMessage( i18n("Could not write to temporary file %1").arg(d->playlistFile->name()), ERROR ); return false; } } bool K3bMovixDocPreparer::writeIsolinuxConfigFile( const TQString& originalPath ) { delete d->isolinuxConfigFile; d->isolinuxConfigFile = new KTempFile(); d->isolinuxConfigFile->setAutoDelete(true); if( TQTextStream* s = d->isolinuxConfigFile->textStream() ) { // now open the default isolinux.cfg and copy everything except the first line which contains // the default boot label TQFile f( originalPath ); if( f.open( IO_ReadOnly ) ) { TQTextStream isolinuxConfigOrig( &f ); if( d->doc->defaultBootLabel() != i18n("default") ) { isolinuxConfigOrig.readLine(); // skip first line *s << "default " << d->doc->defaultBootLabel() << endl; } TQString line = isolinuxConfigOrig.readLine(); while( !line.isNull() ) { *s << line << endl; line = isolinuxConfigOrig.readLine(); } d->isolinuxConfigFile->close(); return true; } else return false; } else { emit infoMessage( i18n("Could not write to temporary file %1").arg(d->isolinuxConfigFile->name()), ERROR ); return false; } } bool K3bMovixDocPreparer::writeMovixRcFile() { delete d->movixRcFile; d->movixRcFile = new KTempFile(); d->movixRcFile->setAutoDelete(true); if( TQTextStream* s = d->movixRcFile->textStream() ) { if( !d->doc->additionalMPlayerOptions().isEmpty() ) *s << "extra-mplayer-options=" << d->doc->additionalMPlayerOptions() << endl; if( !d->doc->unwantedMPlayerOptions().isEmpty() ) *s << "unwanted-mplayer-options=" << d->doc->unwantedMPlayerOptions() << endl; *s << "loop=" << d->doc->loopPlaylist() << endl; if( d->doc->shutdown() ) *s << "shut=y" << endl; if( d->doc->reboot() ) *s << "reboot=y" << endl; if( d->doc->ejectDisk() ) *s << "eject=y" << endl; if( d->doc->randomPlay() ) *s << "random=y" << endl; if( d->doc->noDma() ) *s << "dma=n" << endl; d->movixRcFile->close(); return true; } else { emit infoMessage( i18n("Could not write to temporary file %1").arg(d->movixRcFile->name()), ERROR ); return false; } } bool K3bMovixDocPreparer::addMovixFiles() { // first of all we create the directories d->isolinuxDir = new K3bDirItem( "isolinux", d->doc, d->doc->root() ); d->movixDir = new K3bDirItem( "movix", d->doc, d->doc->root() ); K3bDirItem* kernelDir = d->doc->addEmptyDir( "kernel", d->isolinuxDir ); // add the linux kernel (void)new K3bFileItem( d->eMovixBin->path + "/isolinux/kernel/vmlinuz", d->doc, kernelDir ); // add the boot image K3bBootItem* bootItem = d->doc->createBootItem( d->eMovixBin->path + "/isolinux/isolinux.bin", d->isolinuxDir ); bootItem->setImageType( K3bBootItem::NONE ); bootItem->setLoadSize( 4 ); bootItem->setBootInfoTable(true); // some sort weights as defined in isolinux d->isolinuxDir->setSortWeight( 100 ); kernelDir->setSortWeight( 50 ); bootItem->setSortWeight( 200 ); // rename the boot catalog file d->doc->bootCataloge()->setK3bName( "isolinux.boot" ); // the following sucks! Redesign it! // add all the isolinux files TQStringList isolinuxFiles = d->eMovixBin->isolinuxFiles(); isolinuxFiles.remove( "isolinux.bin" ); isolinuxFiles.remove( "isolinux.cfg" ); isolinuxFiles.remove( "kernel/vmlinuz" ); for( TQStringList::const_iterator it = isolinuxFiles.begin(); it != isolinuxFiles.end(); ++it ) { TQString path = d->eMovixBin->path + "/isolinux/" + *it; (void)new K3bFileItem( path, d->doc, d->isolinuxDir ); } const TQStringList& movixFiles = d->eMovixBin->movixFiles(); for( TQStringList::const_iterator it = movixFiles.begin(); it != movixFiles.end(); ++it ) { TQString path = d->eMovixBin->path + "/movix/" + *it; (void)new K3bFileItem( path, d->doc, d->movixDir ); } // add doku files TQString path = d->eMovixBin->languageDir( d->doc->bootMessageLanguage() ); TQDir dir(path); TQStringList helpFiles = dir.entryList(TQDir::Files); for( TQStringList::const_iterator it = helpFiles.begin(); it != helpFiles.end(); ++it ) { // some emovix installations include backup-files, no one's perfect ;) if( !(*it).endsWith( "~" ) ) (void)new K3bFileItem( path + "/" + *it, d->doc, d->isolinuxDir ); } // add subtitle font dir if( !d->doc->subtitleFontset().isEmpty() && d->doc->subtitleFontset() != i18n("none") ) { d->mplayerDir = new K3bDirItem( "mplayer", d->doc, d->doc->root() ); TQString fontPath = d->eMovixBin->subtitleFontDir( d->doc->subtitleFontset() ); TQFileInfo fontType( fontPath ); if( fontType.isDir() ) { K3bDirItem* fontDir = new K3bDirItem( "font", d->doc, d->mplayerDir ); TQDir dir( fontPath ); TQStringList fontFiles = dir.entryList( TQDir::Files ); for( TQStringList::const_iterator it = fontFiles.begin(); it != fontFiles.end(); ++it ) { (void)new K3bFileItem( fontPath + "/" + *it, d->doc, fontDir ); } } else { // just a ttf file // needs to be named: subfont.ttf and needs to be placed in mplayer/ // instead of mplayer/font (void)new K3bFileItem( fontPath, d->doc, d->mplayerDir, "subfont.ttf" ); } } // add movix-config-file and boot-config file if( writeMovixRcFile() && writeIsolinuxConfigFile( d->eMovixBin->path + "/isolinux/isolinux.cfg" ) && writePlaylistFile() ) { (void)new K3bFileItem( d->movixRcFile->name(), d->doc, d->movixDir, "movixrc" ); (void)new K3bFileItem( d->isolinuxConfigFile->name(), d->doc, d->isolinuxDir, "isolinux.cfg" ); d->playlistFileItem = new K3bFileItem( d->playlistFile->name(), d->doc, d->doc->root(), "movix.list" ); return true; } else return false; } bool K3bMovixDocPreparer::addMovixFilesNew() { // 1. get a list of files from the movixbin // 2. create file items (replace isolinux.cfg with the one created above) // 3. add movixrc and movix.list files // 4. set weights for isolinux files // FIXME: use the settings from the doc TQStringList files = d->eMovixBin->files( d->doc->keyboardLayout(), d->doc->subtitleFontset(), d->doc->audioBackground(), d->doc->bootMessageLanguage(), "all" /*d->doc->codecs()*/ ); // for now we simply don't allow selection for( TQStringList::iterator it = files.begin(); it != files.end(); ++it ) { TQString docPath = (*it).section( ' ', 0, 0 ); TQString filePath = (*it).section( ' ', 1, 1 ); TQString fileName = filePath.section( '/', -1 ); if( fileName == "isolinux.cfg" ) { // replace the local file with our modified one if( writeIsolinuxConfigFile( filePath ) ) createItem( d->isolinuxConfigFile->name(), docPath )->setK3bName( "isolinux.cfg" ); else return false; } else if( fileName == "isolinux.bin" ) { // create boot item (no need to remember this since it's in a dir which will be removed // anyway) K3bBootItem* bootItem = d->doc->createBootItem( filePath, createDir(docPath) ); bootItem->setImageType( K3bBootItem::NONE ); bootItem->setLoadSize( 4 ); bootItem->setBootInfoTable(true); // set the proper sort weight bootItem->setSortWeight( 200 ); bootItem->parent()->setSortWeight( 100 ); } else if( fileName != "movixrc" ) { // we create our own movixrc K3bFileItem* item = createItem( filePath, docPath ); // Truetype subtitle fonts needs to be named subfont.ttf if( fileName == d->doc->subtitleFontset() + ".ttf" ) { item->setK3bName( "subfont.ttf" ); } else if( fileName == "vmlinuz" ) item->setSortWeight( 50 ); } } // Some distributions (such as Gentoo for example) do use the win32codecs package instead of the // eMovix supplied codecs. These codecs are not picked up by the movix-conf script K3bDirItem* codecDir = dynamic_cast( d->doc->root()->findByPath( "/eMoviX/codecs" ) ); if( !codecDir || codecDir->isEmpty() ) { TQDir localCodecDir( d->eMovixBin->movixDataDir() + "/codecs" ); if( localCodecDir.exists() ) { TQStringList codecFiles = localCodecDir.entryList( TQDir::Files ); for( TQStringList::const_iterator it = codecFiles.begin(); it != codecFiles.end(); ++it ) createItem( localCodecDir.path() + '/' + *it, "/eMoviX/codecs" ); } } if( writePlaylistFile() && writeMovixRcFile() ) { // add the two items that are not listed by the script createItem( d->movixRcFile->name(), "/eMoviX/movix" )->setK3bName( "movixrc" ); createItem( d->playlistFile->name(), "/" )->setK3bName( "movix.list" ); return true; } else return false; } K3bFileItem* K3bMovixDocPreparer::createItem( const TQString& localPath, const TQString& docPath ) { // make sure the path in the doc exists K3bDirItem* dir = createDir( docPath ); // create the file in dir K3bFileItem* item = new K3bFileItem( localPath, d->doc, dir ); // remember the item to remove it becasue the dir cannot be removed if( dir == d->doc->root() ) d->newMovixItems.append( item ); return item; } K3bDirItem* K3bMovixDocPreparer::createDir( const TQString& docPath ) { TQStringList docPathSections = TQStringList::split( '/', docPath ); K3bDirItem* dir = d->doc->root(); for( TQStringList::iterator it = docPathSections.begin(); it != docPathSections.end(); ++it ) { K3bDataItem* next = dir->find( *it ); if( !next ) dir = new K3bDirItem( *it, d->doc, dir ); else if( next->isDir() ) dir = static_cast( next ); else { kdError() << "(K3bMovixDocPreparer) found non-dir item where a dir was needed." << endl; return 0; } } // remember the dir to remove it if( dir != d->doc->root() ) { K3bDirItem* delDir = dir; while( delDir->parent() != d->doc->root() ) delDir = delDir->parent(); if( d->newMovixItems.findRef( delDir ) == -1 ) d->newMovixItems.append( delDir ); } return dir; } #include "k3bmovixdocpreparer.moc"