File indexing completed on 2024-06-16 07:42:03

0001 /*
0002     SPDX-FileCopyrightText: 2003 Klaus-Dieter Krannich <kd@k3b.org>
0003     SPDX-FileCopyrightText: 2009 Sebastian Trueg <trueg@k3b.org>
0004     SPDX-FileCopyrightText: 2011 Michal Malek <michalm@jabster.pl>
0005     SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 
0011 #include "k3bbinimagewritingjob.h"
0012 #include "k3bcdrecordwriter.h"
0013 #include "k3bcdrdaowriter.h"
0014 #include "k3bcore.h"
0015 #include "k3bdevice.h"
0016 #include "k3bglobals.h"
0017 #include "k3bexternalbinmanager.h"
0018 #include "k3bglobalsettings.h"
0019 #include "k3bdevicehandler.h"
0020 #include "k3b_i18n.h"
0021 
0022 #include <QDebug>
0023 #include <QFile>
0024 #include <QTextStream>
0025 
0026 
0027 
0028 K3b::BinImageWritingJob::BinImageWritingJob( K3b::JobHandler* hdl, QObject* parent )
0029     : K3b::BurnJob( hdl, parent ),
0030       m_device(0),
0031       m_simulate(false),
0032       m_noFix(false),
0033       m_tocFile(),
0034       m_speed(2),
0035       m_copies(1),
0036       m_writer(0)
0037 {
0038 }
0039 
0040 K3b::BinImageWritingJob::~BinImageWritingJob()
0041 {
0042 }
0043 
0044 void K3b::BinImageWritingJob::start()
0045 {
0046     m_canceled =  false;
0047 
0048     if( m_copies < 1 )
0049         m_copies = 1;
0050     m_finishedCopies = 0;
0051 
0052     jobStarted();
0053     emit newTask( i18n("Write Binary Image") );
0054 
0055     if( prepareWriter() )
0056         writerStart();
0057     else
0058         cancel();
0059 
0060 }
0061 
0062 void K3b::BinImageWritingJob::cancel()
0063 {
0064     m_canceled = true;
0065     m_writer->cancel();
0066     emit canceled();
0067     jobFinished( false );
0068 }
0069 
0070 bool K3b::BinImageWritingJob::prepareWriter()
0071 {
0072     delete m_writer;
0073 
0074     int usedWritingApp = writingApp();
0075     const K3b::ExternalBin* cdrecordBin = k3bcore->externalBinManager()->binObject("cdrecord");
0076     if( usedWritingApp == K3b::WritingAppCdrecord ||
0077         ( usedWritingApp == K3b::WritingAppAuto && cdrecordBin && cdrecordBin->hasFeature("cuefile") && m_device->dao() ) ) {
0078         usedWritingApp = K3b::WritingAppCdrecord;
0079 
0080         // IMPROVEME: check if it's a cdrdao toc-file
0081         if( m_tocFile.right(4) == ".toc" ) {
0082             qDebug() << "(K3b::BinImageWritingJob) imagefile has ending toc.";
0083             usedWritingApp = K3b::WritingAppCdrdao;
0084         }
0085         else {
0086             // TODO: put this into K3b::CueFileParser
0087             // TODO: check K3b::CueFileParser::imageFilenameInCue()
0088             // let's see if cdrecord can handle the cue file
0089             QFile f( m_tocFile );
0090             if( f.open( QIODevice::ReadOnly ) ) {
0091                 QTextStream fStr( &f );
0092                 if( fStr.readAll().contains( "MODE1/2352" ) ) {
0093                     qDebug() << "(K3b::BinImageWritingJob) cuefile contains MODE1/2352 track. using cdrdao.";
0094                     usedWritingApp = K3b::WritingAppCdrdao;
0095                 }
0096                 f.close();
0097             }
0098             else
0099                 qDebug() << "(K3b::BinImageWritingJob) could not open file " << m_tocFile;
0100         }
0101     }
0102     else
0103         usedWritingApp = K3b::WritingAppCdrdao;
0104 
0105     if( usedWritingApp == K3b::WritingAppCdrecord ) {
0106         // create cdrecord job
0107         K3b::CdrecordWriter* writer = new K3b::CdrecordWriter( m_device, this );
0108 
0109         writer->setDao( true );
0110         writer->setSimulate( m_simulate );
0111         writer->setBurnSpeed( m_speed );
0112         writer->setCueFile ( m_tocFile );
0113         writer->setMulti( m_noFix );
0114 
0115         m_writer = writer;
0116     }
0117     else {
0118         // create cdrdao job
0119         K3b::CdrdaoWriter* writer = new K3b::CdrdaoWriter( m_device, this );
0120 
0121         writer->setCommand( K3b::CdrdaoWriter::WRITE );
0122         writer->setSimulate( m_simulate );
0123         writer->setBurnSpeed( m_speed );
0124         writer->setTocFile( m_tocFile );
0125         writer->setMulti( m_noFix );
0126 
0127         m_writer = writer;
0128     }
0129 
0130     connect( m_writer, SIGNAL(infoMessage(QString,int)), this, SIGNAL(infoMessage(QString,int)) );
0131     connect( m_writer, SIGNAL(percent(int)), this, SLOT(copyPercent(int)) );
0132     connect( m_writer, SIGNAL(subPercent(int)), this, SLOT(copySubPercent(int)) );
0133     connect( m_writer, SIGNAL(processedSize(int,int)), this, SIGNAL(processedSize(int,int)) );
0134     connect( m_writer, SIGNAL(buffer(int)), this, SIGNAL(bufferStatus(int)) );
0135     connect( m_writer, SIGNAL(deviceBuffer(int)), this, SIGNAL(deviceBuffer(int)) );
0136     connect( m_writer, SIGNAL(writeSpeed(int,K3b::Device::SpeedMultiplicator)), this, SIGNAL(writeSpeed(int,K3b::Device::SpeedMultiplicator)) );
0137     connect( m_writer, SIGNAL(finished(bool)), this, SLOT(writerFinished(bool)) );
0138     connect( m_writer, SIGNAL(newTask(QString)), this, SIGNAL(newTask(QString)) );
0139     connect( m_writer, SIGNAL(newSubTask(QString)), this, SIGNAL(newSubTask(QString)) );
0140     connect( m_writer, SIGNAL(nextTrack(int,int)), this, SLOT(slotNextTrack(int,int)) );
0141     connect( m_writer, SIGNAL(debuggingOutput(QString,QString)), this, SIGNAL(debuggingOutput(QString,QString)) );
0142 
0143     return true;
0144 }
0145 
0146 
0147 void K3b::BinImageWritingJob::writerStart()
0148 {
0149 
0150     if( waitForMedium( m_device ) == Device::MEDIA_UNKNOWN ) {
0151         cancel();
0152     }
0153     // just to be sure we did not get canceled during the async discWaiting
0154     else if( !m_canceled ) {
0155         emit burning(true);
0156         m_writer->start();
0157     }
0158 }
0159 
0160 void K3b::BinImageWritingJob::copyPercent(int p)
0161 {
0162     emit percent( (100*m_finishedCopies + p)/m_copies );
0163 }
0164 
0165 void K3b::BinImageWritingJob::copySubPercent(int p)
0166 {
0167     emit subPercent(p);
0168 }
0169 
0170 void K3b::BinImageWritingJob::writerFinished(bool ok)
0171 {
0172     if( m_canceled )
0173         return;
0174 
0175     if (ok) {
0176         m_finishedCopies++;
0177         if ( m_finishedCopies == m_copies ) {
0178             if ( k3bcore->globalSettings()->ejectMedia() ) {
0179                 K3b::Device::eject( m_device );
0180             }
0181             emit infoMessage( i18np("One copy successfully created", "%1 copies successfully created", m_copies),K3b::Job::MessageInfo );
0182             jobFinished( true );
0183         }
0184         else {
0185             K3b::Device::eject( m_device );
0186             writerStart();
0187         }
0188     }
0189     else {
0190         jobFinished(false);
0191     }
0192 }
0193 
0194 
0195 void K3b::BinImageWritingJob::slotNextTrack( int t, int tt )
0196 {
0197     emit newSubTask( i18n("Writing track %1 of %2",t,tt) );
0198 }
0199 
0200 
0201 QString K3b::BinImageWritingJob::jobDescription() const
0202 {
0203     return ( i18n("Writing cue/bin Image")
0204              + ( m_copies > 1
0205                  ? i18np(" - %1 Copy", " - %1 Copies", m_copies)
0206                  : QString() ) );
0207 }
0208 
0209 
0210 QString K3b::BinImageWritingJob::jobDetails() const
0211 {
0212     return m_tocFile.section('/', -1);
0213 }
0214 
0215 
0216 QString K3b::BinImageWritingJob::jobSource() const
0217 {
0218     return m_tocFile;
0219 }
0220 
0221 
0222 QString K3b::BinImageWritingJob::jobTarget() const
0223 {
0224     if( Device::Device* device = writer() )
0225         return device->vendor() + ' ' + device->description();
0226     else
0227         return QString();
0228 }
0229 
0230 
0231 void K3b::BinImageWritingJob::setTocFile(const QString& s)
0232 {
0233     m_tocFile = s;
0234 }
0235 
0236 #include "moc_k3bbinimagewritingjob.cpp"