File indexing completed on 2024-04-21 04:49:09

0001 /*
0002     SPDX-FileCopyrightText: 1998-2010 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 
0007 #include "k3bjob.h"
0008 #include "k3bglobals.h"
0009 #include "k3bcore.h"
0010 #include "k3b_i18n.h"
0011 
0012 #include <QDebug>
0013 #include <QEventLoop>
0014 #include <QStringList>
0015 
0016 
0017 
0018 class K3b::Job::Private
0019 {
0020 public:
0021     K3b::JobHandler* jobHandler;
0022     QList<K3b::Job*> runningSubJobs;
0023 
0024     bool canceled;
0025     bool active;
0026 
0027     QList<QEventLoop*> waitLoops;
0028 };
0029 
0030 
0031 const char K3b::Job::DEFAULT_SIGNAL_CONNECTION[] = "K3b::JobDefault";
0032 
0033 
0034 K3b::Job::Job( K3b::JobHandler* handler, QObject* parent )
0035     : QObject( parent ),
0036       d( new Private() )
0037 {
0038     d->jobHandler = handler;
0039     d->canceled = false;
0040     d->active = false;
0041 
0042     connect( this, SIGNAL(canceled()),
0043              this, SLOT(slotCanceled()) );
0044 }
0045 
0046 K3b::Job::~Job()
0047 {
0048     //
0049     // Normally a job (or the user of a job should take care of this
0050     // but we do this here for security reasons.
0051     //
0052     if( d->active ) {
0053         qDebug() << "Finishing job in destructor! This is NOT good. Fix the job.";
0054         jobFinished( false );
0055     }
0056 
0057     delete d;
0058 }
0059 
0060 
0061 K3b::JobHandler* K3b::Job::jobHandler() const
0062 {
0063     return d->jobHandler;
0064 }
0065 
0066 
0067 bool K3b::Job::active() const
0068 {
0069     return d->active;
0070 }
0071 
0072 
0073 bool K3b::Job::hasBeenCanceled() const
0074 {
0075     return d->canceled;
0076 }
0077 
0078 
0079 QList<K3b::Job*> K3b::Job::runningSubJobs() const
0080 {
0081     return d->runningSubJobs;
0082 }
0083 
0084 
0085 void K3b::Job::setJobHandler( K3b::JobHandler* jh )
0086 {
0087     d->jobHandler = jh;
0088 }
0089 
0090 
0091 void K3b::Job::jobStarted()
0092 {
0093     d->canceled = false;
0094     d->active = true;
0095 
0096     if( jobHandler() && jobHandler()->isJob() )
0097         static_cast<K3b::Job*>(jobHandler())->registerSubJob( this );
0098     else
0099         k3bcore->registerJob( this );
0100 
0101     emit started();
0102 }
0103 
0104 
0105 void K3b::Job::jobFinished( bool success )
0106 {
0107     d->active = false;
0108 
0109     if( jobHandler() && jobHandler()->isJob() )
0110         static_cast<K3b::Job*>(jobHandler())->unregisterSubJob( this );
0111     else
0112         k3bcore->unregisterJob( this );
0113 
0114     foreach( QEventLoop* loop, d->waitLoops ) {
0115         loop->exit();
0116     }
0117 
0118     emit finished( success );
0119 }
0120 
0121 
0122 void K3b::Job::slotCanceled()
0123 {
0124     d->canceled = true;
0125 }
0126 
0127 
0128 K3b::Device::MediaType K3b::Job::waitForMedium( K3b::Device::Device* device,
0129                                                 Device::MediaStates mediaState,
0130                                                 Device::MediaTypes mediaType,
0131                                                 const K3b::Msf& minMediaSize,
0132                                                 const QString& message )
0133 {
0134     // TODO: What about:   emit newSubTask( i18n("Waiting for media") );
0135     return d->jobHandler->waitForMedium( device, mediaState, mediaType, minMediaSize, message );
0136 }
0137 
0138 
0139 bool K3b::Job::questionYesNo( const QString& text,
0140                               const QString& caption,
0141                               const KGuiItem& buttonYes,
0142                               const KGuiItem& buttonNo )
0143 {
0144     return d->jobHandler->questionYesNo( text, caption, buttonYes, buttonNo );
0145 }
0146 
0147 
0148 void K3b::Job::blockingInformation( const QString& text,
0149                                     const QString& caption )
0150 {
0151     return d->jobHandler->blockingInformation( text, caption );
0152 }
0153 
0154 void K3b::Job::connectJob( K3b::Job* subJob,
0155                            const char* finishedSlot,
0156                            const char* newTaskSlot,
0157                            const char* newSubTaskSlot,
0158                            const char* progressSlot,
0159                            const char* subProgressSlot,
0160                            const char* processedSizeSlot,
0161                            const char* processedSubSizeSlot )
0162 {
0163     // standard connections
0164     connect( subJob, SIGNAL(debuggingOutput(QString,QString)),
0165              this, SIGNAL(debuggingOutput(QString,QString)) );
0166     connect( subJob, SIGNAL(infoMessage(QString,int)),
0167              this, SIGNAL(infoMessage(QString,int)) );
0168 
0169     // task connections
0170     if( newTaskSlot == DEFAULT_SIGNAL_CONNECTION )
0171         connect( subJob, SIGNAL(newTask(QString)), this, SIGNAL(newTask(QString)) );
0172     else if( newTaskSlot )
0173         connect( subJob, SIGNAL(newTask(QString)), this, newTaskSlot );
0174 
0175     if( newSubTaskSlot == DEFAULT_SIGNAL_CONNECTION )
0176         connect( subJob, SIGNAL(newSubTask(QString)), this, SIGNAL(newSubTask(QString)) );
0177     else if( newSubTaskSlot )
0178         connect( subJob, SIGNAL(newSubTask(QString)), this, newSubTaskSlot );
0179 
0180     if( finishedSlot == DEFAULT_SIGNAL_CONNECTION )
0181         connect( subJob, SIGNAL(finished(bool)), this, SIGNAL(finished(bool)) );
0182     else if( finishedSlot )
0183         connect( subJob, SIGNAL(finished(bool)), this, finishedSlot );
0184 
0185     // progress
0186     if( progressSlot == DEFAULT_SIGNAL_CONNECTION )
0187         connect( subJob, SIGNAL(percent(int)), this, SIGNAL(percent(int)) );
0188     else if( progressSlot )
0189         connect( subJob, SIGNAL(percent(int)), this, progressSlot );
0190 
0191     if( subProgressSlot == DEFAULT_SIGNAL_CONNECTION )
0192         connect( subJob, SIGNAL(subPercent(int)), this, SIGNAL(subPercent(int)) );
0193     else if( subProgressSlot )
0194         connect( subJob, SIGNAL(subPercent(int)), this, subProgressSlot );
0195 
0196     // processed size
0197     if( processedSizeSlot == DEFAULT_SIGNAL_CONNECTION )
0198         connect( subJob, SIGNAL(processedSize(int,int)), this, SIGNAL(processedSize(int,int)) );
0199     else if( processedSizeSlot )
0200         connect( subJob, SIGNAL(processedSize(int,int)), this, processedSizeSlot );
0201 
0202     if( processedSubSizeSlot == DEFAULT_SIGNAL_CONNECTION )
0203         connect( subJob, SIGNAL(processedSubSize(int,int)), this, SIGNAL(processedSubSize(int,int)) );
0204     else if( processedSubSizeSlot )
0205         connect( subJob, SIGNAL(processedSubSize(int,int)), this, processedSubSizeSlot );
0206 }
0207 
0208 
0209 void K3b::Job::connectSubJob( K3b::Job* subJob,
0210                               const char* finishedSlot,
0211                               const char* newTaskSlot,
0212                               const char* newSubTaskSlot,
0213                               const char* progressSlot,
0214                               const char* subProgressSlot,
0215                               const char* processedSizeSlot,
0216                               const char* processedSubSizeSlot )
0217 {
0218     // standard connections
0219     connect( subJob, SIGNAL(debuggingOutput(QString,QString)),
0220              this, SIGNAL(debuggingOutput(QString,QString)) );
0221     connect( subJob, SIGNAL(infoMessage(QString,int)),
0222              this, SIGNAL(infoMessage(QString,int)) );
0223 
0224     // task connections
0225     if( newTaskSlot == DEFAULT_SIGNAL_CONNECTION )
0226         connect( subJob, SIGNAL(newTask(QString)), this, SIGNAL(newSubTask(QString)) );
0227     else if( newTaskSlot )
0228         connect( subJob, SIGNAL(newTask(QString)), this, newTaskSlot );
0229 
0230     if( newSubTaskSlot == DEFAULT_SIGNAL_CONNECTION )
0231         connect( subJob, SIGNAL(newSubTask(QString)), this, SLOT(slotNewSubTask(QString)) );
0232     else if( newSubTaskSlot )
0233         connect( subJob, SIGNAL(newSubTask(QString)), this, newSubTaskSlot );
0234 
0235     if( finishedSlot == DEFAULT_SIGNAL_CONNECTION )
0236         connect( subJob, SIGNAL(finished(bool)), this, SIGNAL(finished(bool)) );
0237     else if( finishedSlot )
0238         connect( subJob, SIGNAL(finished(bool)), this, finishedSlot );
0239 
0240     // progress
0241     if( progressSlot == DEFAULT_SIGNAL_CONNECTION )
0242         connect( subJob, SIGNAL(percent(int)), this, SIGNAL(subPercent(int)) );
0243     else if( progressSlot )
0244         connect( subJob, SIGNAL(percent(int)), this, progressSlot );
0245 
0246     if( subProgressSlot != DEFAULT_SIGNAL_CONNECTION )
0247         connect( subJob, SIGNAL(subPercent(int)), this, subProgressSlot );
0248 
0249     // processed size
0250     if( processedSizeSlot == DEFAULT_SIGNAL_CONNECTION )
0251         connect( subJob, SIGNAL(processedSize(int,int)), this, SIGNAL(processedSubSize(int,int)) );
0252     else if( processedSizeSlot )
0253         connect( subJob, SIGNAL(processedSize(int,int)), this, processedSizeSlot );
0254 
0255     if( processedSubSizeSlot != DEFAULT_SIGNAL_CONNECTION )
0256         connect( subJob, SIGNAL(processedSubSize(int,int)), this, processedSubSizeSlot );
0257 }
0258 
0259 
0260 int K3b::Job::numRunningSubJobs() const
0261 {
0262     return d->runningSubJobs.count();
0263 }
0264 
0265 
0266 void K3b::Job::slotNewSubTask( const QString& str )
0267 {
0268     emit infoMessage( str, MessageInfo );
0269 }
0270 
0271 
0272 void K3b::Job::registerSubJob( K3b::Job* job )
0273 {
0274     d->runningSubJobs.append( job );
0275 }
0276 
0277 
0278 void K3b::Job::unregisterSubJob( K3b::Job* job )
0279 {
0280     d->runningSubJobs.removeOne( job );
0281 }
0282 
0283 
0284 void K3b::Job::wait()
0285 {
0286     if ( active() ) {
0287         QEventLoop loop;
0288         d->waitLoops.append( &loop );
0289         loop.exec();
0290         d->waitLoops.removeOne( &loop );
0291     }
0292 }
0293 
0294 
0295 
0296 
0297 class K3b::BurnJob::Private
0298 {
0299 public:
0300     K3b::WritingApp writeMethod;
0301 };
0302 
0303 
0304 
0305 K3b::BurnJob::BurnJob( K3b::JobHandler* handler, QObject* parent )
0306     : K3b::Job( handler, parent ),
0307       d( new Private() )
0308 {
0309     d->writeMethod = K3b::WritingAppAuto;
0310 }
0311 
0312 
0313 K3b::BurnJob::~BurnJob()
0314 {
0315     delete d;
0316 }
0317 
0318 
0319 K3b::WritingApp K3b::BurnJob::writingApp() const
0320 {
0321     return d->writeMethod;
0322 }
0323 
0324 
0325 void K3b::BurnJob::setWritingApp( K3b::WritingApp w )
0326 {
0327     d->writeMethod = w;
0328 }
0329 
0330 
0331 K3b::WritingApps K3b::BurnJob::supportedWritingApps() const
0332 {
0333     return K3b::WritingAppAuto | K3b::WritingAppCdrdao | K3b::WritingAppCdrecord;
0334 }
0335 
0336 #include "moc_k3bjob.cpp"