diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-03 02:15:56 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-03 02:15:56 +0000 |
commit | 50b48aec6ddd451a6d1709c0942477b503457663 (patch) | |
tree | a9ece53ec06fd0a2819de7a2a6de997193566626 /libk3b/jobs/k3biso9660imagewritingjob.cpp | |
download | k3b-50b48aec6ddd451a6d1709c0942477b503457663.tar.gz k3b-50b48aec6ddd451a6d1709c0942477b503457663.zip |
Added abandoned KDE3 version of K3B
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k3b@1084400 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'libk3b/jobs/k3biso9660imagewritingjob.cpp')
-rw-r--r-- | libk3b/jobs/k3biso9660imagewritingjob.cpp | 458 |
1 files changed, 458 insertions, 0 deletions
diff --git a/libk3b/jobs/k3biso9660imagewritingjob.cpp b/libk3b/jobs/k3biso9660imagewritingjob.cpp new file mode 100644 index 0000000..1fb3871 --- /dev/null +++ b/libk3b/jobs/k3biso9660imagewritingjob.cpp @@ -0,0 +1,458 @@ +/* + * + * $Id: k3biso9660imagewritingjob.cpp 690187 2007-07-20 09:18:03Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <[email protected]> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <[email protected]> + * + * 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 "k3biso9660imagewritingjob.h" +#include "k3bverificationjob.h" + +#include <k3bdevice.h> +#include <k3bdiskinfo.h> +#include <k3bdevicehandler.h> +#include <k3bcdrecordwriter.h> +#include <k3bcdrdaowriter.h> +#include <k3bgrowisofswriter.h> +#include <k3bglobals.h> +#include <k3bcore.h> +#include <k3bversion.h> +#include <k3bexternalbinmanager.h> +#include <k3bchecksumpipe.h> +#include <k3bfilesplitter.h> + +#include <kdebug.h> +#include <kconfig.h> +#include <klocale.h> +#include <ktempfile.h> +#include <kio/global.h> + +#include <qstring.h> +#include <qtextstream.h> +#include <qfile.h> +#include <qapplication.h> + + +class K3bIso9660ImageWritingJob::Private +{ +public: + K3bChecksumPipe checksumPipe; + K3bFileSplitter imageFile; +}; + + +K3bIso9660ImageWritingJob::K3bIso9660ImageWritingJob( K3bJobHandler* hdl ) + : K3bBurnJob( hdl ), + m_writingMode(K3b::WRITING_MODE_AUTO), + m_simulate(false), + m_device(0), + m_noFix(false), + m_speed(2), + m_dataMode(K3b::DATA_MODE_AUTO), + m_writer(0), + m_tocFile(0), + m_copies(1), + m_verifyJob(0) +{ + d = new Private; +} + +K3bIso9660ImageWritingJob::~K3bIso9660ImageWritingJob() +{ + delete m_tocFile; + delete d; +} + + +void K3bIso9660ImageWritingJob::start() +{ + m_canceled = m_finished = false; + m_currentCopy = 1; + + jobStarted(); + + if( m_simulate ) + m_verifyData = false; + + emit newTask( i18n("Preparing data") ); + + if( !QFile::exists( m_imagePath ) ) { + emit infoMessage( i18n("Could not find image %1").arg(m_imagePath), K3bJob::ERROR ); + jobFinished( false ); + return; + } + + unsigned long gb = K3b::imageFilesize( m_imagePath )/1024/1024; + + // very rough test but since most dvd images are 4,x or 8,x GB it should be enough + m_dvd = ( gb > 900 ); + + startWriting(); +} + + +void K3bIso9660ImageWritingJob::slotWriterJobFinished( bool success ) +{ + if( m_canceled ) { + m_finished = true; + emit canceled(); + jobFinished(false); + return; + } + + d->checksumPipe.close(); + + if( success ) { + if( !m_simulate && m_verifyData ) { + emit burning(false); + + // allright + // the writerJob should have emited the "simulation/writing successful" signal + + if( !m_verifyJob ) { + m_verifyJob = new K3bVerificationJob( this ); + connectSubJob( m_verifyJob, + SLOT(slotVerificationFinished(bool)), + true, + SLOT(slotVerificationProgress(int)), + SIGNAL(subPercent(int)) ); + } + m_verifyJob->setDevice( m_device ); + m_verifyJob->clear(); + m_verifyJob->addTrack( 1, d->checksumPipe.checksum(), K3b::imageFilesize( m_imagePath )/2048 ); + + if( m_copies == 1 ) + emit newTask( i18n("Verifying written data") ); + else + emit newTask( i18n("Verifying written copy %1 of %2").arg(m_currentCopy).arg(m_copies) ); + + m_verifyJob->start(); + } + else if( m_currentCopy >= m_copies ) { + m_finished = true; + jobFinished(true); + } + else { + m_currentCopy++; + startWriting(); + } + } + else { + m_finished = true; + jobFinished(false); + } +} + + +void K3bIso9660ImageWritingJob::slotVerificationFinished( bool success ) +{ + if( m_canceled ) { + m_finished = true; + emit canceled(); + jobFinished(false); + return; + } + + if( success && m_currentCopy < m_copies ) { + m_currentCopy++; + connect( K3bDevice::eject( m_device ), SIGNAL(finished(bool)), + this, SLOT(startWriting()) ); + return; + } + + k3bcore->config()->setGroup("General Options"); + if( !k3bcore->config()->readBoolEntry( "No cd eject", false ) ) + K3bDevice::eject( m_device ); + + m_finished = true; + jobFinished( success ); +} + + +void K3bIso9660ImageWritingJob::slotVerificationProgress( int p ) +{ + emit percent( (int)(100.0 / (double)m_copies * ( (double)(m_currentCopy-1) + 0.5 + (double)p/200.0 )) ); +} + + +void K3bIso9660ImageWritingJob::slotWriterPercent( int p ) +{ + emit subPercent( p ); + + if( m_verifyData ) + emit percent( (int)(100.0 / (double)m_copies * ( (double)(m_currentCopy-1) + ((double)p/200.0) )) ); + else + emit percent( (int)(100.0 / (double)m_copies * ( (double)(m_currentCopy-1) + ((double)p/100.0) )) ); +} + + +void K3bIso9660ImageWritingJob::slotNextTrack( int, int ) +{ + if( m_copies == 1 ) + emit newSubTask( i18n("Writing image") ); + else + emit newSubTask( i18n("Writing copy %1 of %2").arg(m_currentCopy).arg(m_copies) ); +} + + +void K3bIso9660ImageWritingJob::cancel() +{ + if( !m_finished ) { + m_canceled = true; + + if( m_writer ) + m_writer->cancel(); + if( m_verifyData && m_verifyJob ) + m_verifyJob->cancel(); + } +} + + +void K3bIso9660ImageWritingJob::startWriting() +{ + emit newSubTask( i18n("Waiting for medium") ); + + // we wait for the following: + // 1. if writing mode auto and writing app auto: all writable media types + // 2. if writing mode auto and writing app not growisofs: all writable cd types + // 3. if writing mode auto and writing app growisofs: all writable dvd types + // 4. if writing mode TAO or RAW: all writable cd types + // 5. if writing mode DAO and writing app auto: all writable cd types and DVD-R(W) + // 6. if writing mode DAO and writing app GROWISOFS: DVD-R(W) + // 7. if writing mode DAO and writing app CDRDAO or CDRECORD: all writable cd types + // 8. if writing mode WRITING_MODE_INCR_SEQ: DVD-R(W) + // 9. if writing mode WRITING_MODE_RES_OVWR: DVD-RW or DVD+RW + + int mt = 0; + if( m_writingMode == K3b::WRITING_MODE_AUTO ) { + if( writingApp() == K3b::DEFAULT ) { + if( m_dvd ) + mt = K3bDevice::MEDIA_WRITABLE_DVD; + else + mt = K3bDevice::MEDIA_WRITABLE_CD; + } + else if( writingApp() != K3b::GROWISOFS ) + mt = K3bDevice::MEDIA_WRITABLE_CD; + else + mt = K3bDevice::MEDIA_WRITABLE_DVD; + } + else if( m_writingMode == K3b::TAO || m_writingMode == K3b::RAW ) + mt = K3bDevice::MEDIA_WRITABLE_CD; + else if( m_writingMode == K3b::DAO ) { + if( writingApp() == K3b::DEFAULT ) { + if( m_dvd ) + mt = K3bDevice::MEDIA_WRITABLE_DVD; + else + mt = K3bDevice::MEDIA_WRITABLE_CD; + } + else if( writingApp() == K3b::GROWISOFS ) + mt = K3bDevice::MEDIA_WRITABLE_DVD; + else + mt = K3bDevice::MEDIA_WRITABLE_CD; + } + else if( m_writingMode == K3b::WRITING_MODE_RES_OVWR ) + mt = K3bDevice::MEDIA_DVD_PLUS_R|K3bDevice::MEDIA_DVD_PLUS_R_DL|K3bDevice::MEDIA_DVD_PLUS_RW|K3bDevice::MEDIA_DVD_RW_OVWR; + else + mt = K3bDevice::MEDIA_WRITABLE_DVD; + + + // wait for the media + int media = waitForMedia( m_device, K3bDevice::STATE_EMPTY, mt ); + if( media < 0 ) { + m_finished = true; + emit canceled(); + jobFinished(false); + return; + } + + // we simply always calculate the checksum, thus making the code simpler + d->imageFile.close(); + d->imageFile.setName( m_imagePath ); + d->imageFile.open( IO_ReadOnly ); + d->checksumPipe.close(); + d->checksumPipe.readFromIODevice( &d->imageFile ); + + if( prepareWriter( media ) ) { + emit burning(true); + m_writer->start(); + d->checksumPipe.writeToFd( m_writer->fd(), true ); + d->checksumPipe.open( K3bChecksumPipe::MD5, true ); + } + else { + m_finished = true; + jobFinished(false); + } +} + + +bool K3bIso9660ImageWritingJob::prepareWriter( int mediaType ) +{ + if( mediaType == 0 ) { // media forced + // just to get it going... + if( writingApp() != K3b::GROWISOFS && !m_dvd ) + mediaType = K3bDevice::MEDIA_CD_R; + else + mediaType = K3bDevice::MEDIA_DVD_R; + } + + delete m_writer; + + if( mediaType == K3bDevice::MEDIA_CD_R || mediaType == K3bDevice::MEDIA_CD_RW ) { + int usedWritingMode = m_writingMode; + if( usedWritingMode == K3b::WRITING_MODE_AUTO ) { + // cdrecord seems to have problems when writing in mode2 in dao mode + // so with cdrecord we use TAO + if( m_noFix || m_dataMode == K3b::MODE2 || !m_device->dao() ) + usedWritingMode = K3b::TAO; + else + usedWritingMode = K3b::DAO; + } + + int usedApp = writingApp(); + if( usedApp == K3b::DEFAULT ) { + if( usedWritingMode == K3b::DAO && + ( m_dataMode == K3b::MODE2 || m_noFix ) ) + usedApp = K3b::CDRDAO; + else + usedApp = K3b::CDRECORD; + } + + + if( usedApp == K3b::CDRECORD ) { + K3bCdrecordWriter* writer = new K3bCdrecordWriter( m_device, this ); + + writer->setWritingMode( usedWritingMode ); + writer->setSimulate( m_simulate ); + writer->setBurnSpeed( m_speed ); + + if( m_noFix ) { + writer->addArgument("-multi"); + } + + if( (m_dataMode == K3b::DATA_MODE_AUTO && m_noFix) || + m_dataMode == K3b::MODE2 ) { + if( k3bcore->externalBinManager()->binObject("cdrecord") && + k3bcore->externalBinManager()->binObject("cdrecord")->hasFeature( "xamix" ) ) + writer->addArgument( "-xa" ); + else + writer->addArgument( "-xa1" ); + } + else + writer->addArgument("-data"); + + // read from stdin + writer->addArgument( QString("-tsize=%1s").arg( K3b::imageFilesize( m_imagePath )/2048 ) )->addArgument( "-" ); + + m_writer = writer; + } + else { + // create cdrdao job + K3bCdrdaoWriter* writer = new K3bCdrdaoWriter( m_device, this ); + writer->setCommand( K3bCdrdaoWriter::WRITE ); + writer->setSimulate( m_simulate ); + writer->setBurnSpeed( m_speed ); + // multisession + writer->setMulti( m_noFix ); + + // now write the tocfile + delete m_tocFile; + m_tocFile = new KTempFile( QString::null, "toc" ); + m_tocFile->setAutoDelete(true); + + if( QTextStream* s = m_tocFile->textStream() ) { + if( (m_dataMode == K3b::DATA_MODE_AUTO && m_noFix) || + m_dataMode == K3b::MODE2 ) { + *s << "CD_ROM_XA" << "\n"; + *s << "\n"; + *s << "TRACK MODE2_FORM1" << "\n"; + } + else { + *s << "CD_ROM" << "\n"; + *s << "\n"; + *s << "TRACK MODE1" << "\n"; + } + *s << "DATAFILE \"-\" " << QString::number( K3b::imageFilesize( m_imagePath ) ) << "\n"; + + m_tocFile->close(); + } + else { + kdDebug() << "(K3bDataJob) could not write tocfile." << endl; + emit infoMessage( i18n("IO Error"), ERROR ); + return false; + } + + writer->setTocFile( m_tocFile->name() ); + + m_writer = writer; + } + } + else { // DVD + if( mediaType & K3bDevice::MEDIA_DVD_PLUS_ALL ) { + if( m_simulate ) { + if( questionYesNo( i18n("K3b does not support simulation with DVD+R(W) media. " + "Do you really want to continue? The media will be written " + "for real."), + i18n("No Simulation with DVD+R(W)") ) ) { + return false; + } + } + + m_simulate = false; + } + + K3bGrowisofsWriter* writer = new K3bGrowisofsWriter( m_device, this ); + writer->setSimulate( m_simulate ); + writer->setBurnSpeed( m_speed ); + writer->setWritingMode( m_writingMode == K3b::DAO ? K3b::DAO : 0 ); + writer->setImageToWrite( QString::null ); // read from stdin + writer->setCloseDvd( !m_noFix ); + writer->setTrackSize( K3b::imageFilesize( m_imagePath )/2048 ); + + m_writer = writer; + } + + connect( m_writer, SIGNAL(infoMessage(const QString&, int)), this, SIGNAL(infoMessage(const QString&, int)) ); + connect( m_writer, SIGNAL(nextTrack(int, int)), this, SLOT(slotNextTrack(int, int)) ); + connect( m_writer, SIGNAL(percent(int)), this, SLOT(slotWriterPercent(int)) ); + connect( m_writer, SIGNAL(processedSize(int, int)), this, SIGNAL(processedSize(int, int)) ); + connect( m_writer, SIGNAL(buffer(int)), this, SIGNAL(bufferStatus(int)) ); + connect( m_writer, SIGNAL(deviceBuffer(int)), this, SIGNAL(deviceBuffer(int)) ); + connect( m_writer, SIGNAL(writeSpeed(int, int)), this, SIGNAL(writeSpeed(int, int)) ); + connect( m_writer, SIGNAL(finished(bool)), this, SLOT(slotWriterJobFinished(bool)) ); + connect( m_writer, SIGNAL(newTask(const QString&)), this, SIGNAL(newTask(const QString&)) ); + connect( m_writer, SIGNAL(newSubTask(const QString&)), this, SIGNAL(newSubTask(const QString&)) ); + connect( m_writer, SIGNAL(debuggingOutput(const QString&, const QString&)), + this, SIGNAL(debuggingOutput(const QString&, const QString&)) ); + + return true; +} + + +QString K3bIso9660ImageWritingJob::jobDescription() const +{ + if( m_simulate ) + return i18n("Simulating ISO9660 Image"); + else + return ( i18n("Burning ISO9660 Image") + + ( m_copies > 1 + ? i18n(" - %n Copy", " - %n Copies", m_copies) + : QString::null ) ); +} + + +QString K3bIso9660ImageWritingJob::jobDetails() const +{ + return m_imagePath.section("/", -1) + QString( " (%1)" ).arg(KIO::convertSize(K3b::filesize(KURL::fromPathOrURL(m_imagePath)))); +} + + +#include "k3biso9660imagewritingjob.moc" |