~ubuntu-branches/ubuntu/trusty/k3b/trusty

« back to all changes in this revision

Viewing changes to .pc/Prefer-growisofs-to-wodim-for-DVD-BluRay-burning.patch/libk3b/projects/datacd/k3bdatajob.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-11-12 10:36:01 UTC
  • mfrom: (2.1.20 sid)
  • Revision ID: package-import@ubuntu.com-20131112103601-q6vvln9lv3mg7qxh
Tags: 2.0.2-7ubuntu1
* Merge with Debian, remaining changes:
  - Suggest, not recommend libk3b6-extracodecs (Cannot be on the CD)
  - Do not ship k3b documentation, it's for the KDE3 version.
  - Do not install unused scalable icons to save space
  - Keep kubuntu_02_kubuntu_restricted.diff
  - Keep kubuntu_03_no_missing_mp3_warn.diff
  - Keep kubuntu_05_no_system_settings.diff
  - Keep kubuntu_07_quicklists.diff
  - Disable 111_advice_debian_libk3b3-extracodes.diff and
    112_dont_require_mp3.diff which aren't required due to our mp3 patches.
  - swap kubuntu_06_libav_0.7.diff for Debian's
    Fixed_compilation_with_new_FFMPEG.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * Copyright (C) 2003-2009 Sebastian Trueg <trueg@k3b.org>
 
4
 *
 
5
 * This file is part of the K3b project.
 
6
 * Copyright (C) 1998-2009 Sebastian Trueg <trueg@k3b.org>
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 * See the file "COPYING" for the exact licensing terms.
 
13
 */
 
14
 
 
15
 
 
16
#include "k3bdatajob.h"
 
17
#include "k3bdatadoc.h"
 
18
#include "k3bisoimager.h"
 
19
#include "k3bdatamultisessionparameterjob.h"
 
20
#include "k3bchecksumpipe.h"
 
21
#include "k3bcore.h"
 
22
#include "k3bglobals.h"
 
23
#include "k3bversion.h"
 
24
#include "k3bdevice.h"
 
25
#include "k3bdevicehandler.h"
 
26
#include "k3btoc.h"
 
27
#include "k3btrack.h"
 
28
#include "k3bdevicehandler.h"
 
29
#include "k3bexternalbinmanager.h"
 
30
#include "k3bcdrecordwriter.h"
 
31
#include "k3bcdrdaowriter.h"
 
32
#include "k3bglobalsettings.h"
 
33
#include "k3bactivepipe.h"
 
34
#include "k3bfilesplitter.h"
 
35
#include "k3bverificationjob.h"
 
36
#include "k3biso9660.h"
 
37
#include "k3bisooptions.h"
 
38
#include "k3bdeviceglobals.h"
 
39
#include "k3bgrowisofswriter.h"
 
40
 
 
41
#include <kapplication.h>
 
42
#include <klocale.h>
 
43
#include <kstandarddirs.h>
 
44
#include <ktemporaryfile.h>
 
45
#include <kio/global.h>
 
46
#include <kio/job.h>
 
47
 
 
48
#include <qstring.h>
 
49
#include <qstringlist.h>
 
50
#include <qdatetime.h>
 
51
#include <qfile.h>
 
52
#include <qdatastream.h>
 
53
#include <kdebug.h>
 
54
 
 
55
 
 
56
 
 
57
class K3b::DataJob::Private
 
58
{
 
59
public:
 
60
    Private()
 
61
        : usedWritingApp(K3b::WritingAppCdrecord),
 
62
          verificationJob( 0 ),
 
63
          pipe( 0 ) {
 
64
    }
 
65
 
 
66
    K3b::DataDoc* doc;
 
67
 
 
68
    bool initializingImager;
 
69
    bool imageFinished;
 
70
    bool canceled;
 
71
 
 
72
    KTemporaryFile* tocFile;
 
73
 
 
74
    int usedDataMode;
 
75
    K3b::WritingApp usedWritingApp;
 
76
    K3b::WritingMode usedWritingMode;
 
77
 
 
78
    int copies;
 
79
    int copiesDone;
 
80
 
 
81
    K3b::VerificationJob* verificationJob;
 
82
 
 
83
    K3b::FileSplitter imageFile;
 
84
    K3b::ActivePipe* pipe;
 
85
 
 
86
    K3b::DataMultiSessionParameterJob* multiSessionParameterJob;
 
87
 
 
88
    QByteArray checksumCache;
 
89
};
 
90
 
 
91
 
 
92
K3b::DataJob::DataJob( K3b::DataDoc* doc, K3b::JobHandler* hdl, QObject* parent )
 
93
    : K3b::BurnJob( hdl, parent )
 
94
{
 
95
    d = new Private;
 
96
    d->multiSessionParameterJob = new K3b::DataMultiSessionParameterJob( doc, this, this );
 
97
    connectSubJob( d->multiSessionParameterJob,
 
98
                   SLOT( slotMultiSessionParamterSetupDone( bool ) ),
 
99
                   SIGNAL( newTask( const QString& ) ),
 
100
                   SIGNAL( newSubTask( const QString& ) ) );
 
101
 
 
102
    d->doc = doc;
 
103
    m_writerJob = 0;
 
104
    d->tocFile = 0;
 
105
    m_isoImager = 0;
 
106
}
 
107
 
 
108
 
 
109
K3b::DataJob::~DataJob()
 
110
{
 
111
    kDebug();
 
112
    delete d->pipe;
 
113
    delete d->tocFile;
 
114
    delete d;
 
115
}
 
116
 
 
117
 
 
118
K3b::Doc* K3b::DataJob::doc() const
 
119
{
 
120
    return d->doc;
 
121
}
 
122
 
 
123
 
 
124
K3b::Device::Device* K3b::DataJob::writer() const
 
125
{
 
126
    if( doc()->onlyCreateImages() )
 
127
        return 0; // no writer needed -> no blocking on K3b::BurnJob
 
128
    else
 
129
        return doc()->burner();
 
130
}
 
131
 
 
132
 
 
133
void K3b::DataJob::start()
 
134
{
 
135
    kDebug();
 
136
    jobStarted();
 
137
 
 
138
    d->canceled = false;
 
139
    d->imageFinished = false;
 
140
    d->copies = d->doc->copies();
 
141
    d->copiesDone = 0;
 
142
 
 
143
    prepareImager();
 
144
 
 
145
    if( d->doc->dummy() ) {
 
146
        d->doc->setVerifyData( false );
 
147
        d->copies = 1;
 
148
    }
 
149
 
 
150
    emit newTask( i18n("Preparing data") );
 
151
 
 
152
    // there is no harm in setting these even if we write on-the-fly
 
153
    d->imageFile.setName( d->doc->tempDir() );
 
154
 
 
155
    d->multiSessionParameterJob->start();
 
156
}
 
157
 
 
158
 
 
159
void K3b::DataJob::slotMultiSessionParamterSetupDone( bool success )
 
160
{
 
161
    kDebug() << success;
 
162
    if ( success ) {
 
163
        prepareWriting();
 
164
    }
 
165
    else {
 
166
        if ( d->multiSessionParameterJob->hasBeenCanceled() ) {
 
167
            emit canceled();
 
168
        }
 
169
        cleanup();
 
170
        jobFinished( false );
 
171
    }
 
172
}
 
173
 
 
174
 
 
175
void K3b::DataJob::prepareWriting()
 
176
{
 
177
    kDebug();
 
178
    if( !d->doc->onlyCreateImages() &&
 
179
        ( d->multiSessionParameterJob->usedMultiSessionMode() == K3b::DataDoc::CONTINUE ||
 
180
          d->multiSessionParameterJob->usedMultiSessionMode() == K3b::DataDoc::FINISH ) ) {
 
181
        unsigned int nextSessionStart = d->multiSessionParameterJob->nextSessionStart();
 
182
        // for some reason cdrdao needs 150 additional sectors in the ms info
 
183
        if( writingApp() == K3b::WritingAppCdrdao ) {
 
184
            nextSessionStart += 150;
 
185
        }
 
186
        m_isoImager->setMultiSessionInfo( QString().sprintf( "%u,%u",
 
187
                                                             d->multiSessionParameterJob->previousSessionStart(),
 
188
                                                             nextSessionStart ),
 
189
                                          d->multiSessionParameterJob->importPreviousSession() ? d->doc->burner() : 0 );
 
190
    }
 
191
    else {
 
192
        m_isoImager->setMultiSessionInfo( QString(), 0 );
 
193
    }
 
194
 
 
195
    d->initializingImager = true;
 
196
    m_isoImager->init();
 
197
}
 
198
 
 
199
 
 
200
void K3b::DataJob::writeImage()
 
201
{
 
202
    kDebug();
 
203
    d->initializingImager = false;
 
204
 
 
205
    emit burning(false);
 
206
 
 
207
    // get image file path
 
208
    if( d->doc->tempDir().isEmpty() )
 
209
        d->doc->setTempDir( K3b::findUniqueFilePrefix( d->doc->isoOptions().volumeID() ) + ".iso" );
 
210
 
 
211
    // TODO: check if the image file is part of the project and if so warn the user
 
212
    //       and append some number to make the path unique.
 
213
 
 
214
    //
 
215
    // Check the image file
 
216
    if( !d->doc->onTheFly() || d->doc->onlyCreateImages() ) {
 
217
        d->imageFile.setName( d->doc->tempDir() );
 
218
        if( !d->imageFile.open( QIODevice::WriteOnly ) ) {
 
219
            emit infoMessage( i18n("Could not open %1 for writing", d->doc->tempDir() ), MessageError );
 
220
            cleanup();
 
221
            jobFinished(false);
 
222
            return;
 
223
        }
 
224
    }
 
225
 
 
226
    emit newTask( i18n("Creating image file") );
 
227
    emit newSubTask( i18n("Track 1 of 1") );
 
228
    emit infoMessage( i18n("Creating image file in %1",d->doc->tempDir()), MessageInfo );
 
229
 
 
230
    m_isoImager->start();
 
231
    startPipe();
 
232
}
 
233
 
 
234
 
 
235
void K3b::DataJob::startPipe()
 
236
{
 
237
    kDebug();
 
238
    //
 
239
    // Open the active pipe which does the streaming
 
240
    //
 
241
    delete d->pipe;
 
242
    if ( d->imageFinished || !d->doc->verifyData() )
 
243
        d->pipe = new K3b::ActivePipe();
 
244
    else
 
245
        d->pipe = new K3b::ChecksumPipe();
 
246
 
 
247
#ifdef __GNUC__
 
248
#warning Growisofs needs stdin to be closed in order to exit gracefully. Cdrecord does not. However,  if closed with cdrecord we loose parts of stderr. Why?
 
249
#endif
 
250
    if( d->imageFinished || ( d->doc->onTheFly() && !d->doc->onlyCreateImages() ) )
 
251
        d->pipe->writeTo( m_writerJob->ioDevice(), d->usedWritingApp != K3b::WritingAppCdrecord );
 
252
    else
 
253
        d->pipe->writeTo( &d->imageFile, true );
 
254
 
 
255
    if ( d->imageFinished )
 
256
        d->pipe->readFrom( &d->imageFile, true );
 
257
    else
 
258
        d->pipe->readFrom( m_isoImager->ioDevice(), true );
 
259
 
 
260
    d->pipe->open( true );
 
261
}
 
262
 
 
263
 
 
264
bool K3b::DataJob::startOnTheFlyWriting()
 
265
{
 
266
    kDebug();
 
267
    if( prepareWriterJob() ) {
 
268
        if( startWriterJob() ) {
 
269
            d->initializingImager = false;
 
270
            m_isoImager->start();
 
271
            startPipe();
 
272
            return true;
 
273
        }
 
274
    }
 
275
    return false;
 
276
}
 
277
 
 
278
 
 
279
void K3b::DataJob::cancel()
 
280
{
 
281
    kDebug();
 
282
 
 
283
    emit canceled();
 
284
 
 
285
    d->canceled = true;
 
286
 
 
287
    //
 
288
    // Just cancel all and return, let slotMultiSessionParamterSetupDone,
 
289
    // slotIsoImagerFinished, and slotWriterJobFinished take care of the rest
 
290
    //
 
291
    if ( active() && !cancelAll() ) {
 
292
        kDebug() << "cancellation already done";
 
293
        cleanup();
 
294
        jobFinished( false );
 
295
    }
 
296
}
 
297
 
 
298
 
 
299
bool K3b::DataJob::cancelAll()
 
300
{
 
301
    kDebug();
 
302
    bool somethingCanceled = false;
 
303
    if ( m_isoImager->active() ) {
 
304
        kDebug() << "cancelling iso imager";
 
305
        m_isoImager->cancel();
 
306
        somethingCanceled = true;
 
307
    }
 
308
    if( m_writerJob && m_writerJob->active() ) {
 
309
        kDebug() << "cancelling writing job";
 
310
        m_writerJob->cancel();
 
311
        somethingCanceled = true;
 
312
    }
 
313
    if( d->verificationJob && d->verificationJob->active() ) {
 
314
        kDebug() << "cancelling verification job";
 
315
        d->verificationJob->cancel();
 
316
        somethingCanceled = true;
 
317
    }
 
318
    if ( d->multiSessionParameterJob && d->multiSessionParameterJob->active() ) {
 
319
        kDebug() << "cancelling multiSessionParameterJob";
 
320
        d->multiSessionParameterJob->cancel();
 
321
        somethingCanceled = true;
 
322
    }
 
323
 
 
324
    kDebug() << somethingCanceled;
 
325
    return somethingCanceled;
 
326
}
 
327
 
 
328
 
 
329
void K3b::DataJob::slotIsoImagerPercent( int p )
 
330
{
 
331
    if( d->doc->onlyCreateImages() ) {
 
332
        emit subPercent( p );
 
333
        emit percent( p );
 
334
    }
 
335
    else if( !d->doc->onTheFly() ) {
 
336
        double totalTasks = d->copies;
 
337
        double tasksDone = d->copiesDone; // =0 when creating an image
 
338
        if( d->doc->verifyData() ) {
 
339
            totalTasks*=2;
 
340
            tasksDone*=2;
 
341
        }
 
342
        if( !d->doc->onTheFly() ) {
 
343
            totalTasks+=1.0;
 
344
        }
 
345
 
 
346
        emit subPercent( p );
 
347
        emit percent( (int)((100.0*tasksDone + (double)p) / totalTasks) );
 
348
    }
 
349
}
 
350
 
 
351
 
 
352
void K3b::DataJob::slotIsoImagerFinished( bool success )
 
353
{
 
354
    kDebug();
 
355
    if( d->initializingImager ) {
 
356
        if( success ) {
 
357
            if( d->doc->onTheFly() && !d->doc->onlyCreateImages() ) {
 
358
                if( !startOnTheFlyWriting() ) {
 
359
                    cleanup();
 
360
                    jobFinished( false );
 
361
                }
 
362
            }
 
363
            else {
 
364
                writeImage();
 
365
            }
 
366
        }
 
367
        else {
 
368
            if( m_isoImager->hasBeenCanceled() ) {
 
369
                cancel();
 
370
            }
 
371
            else if ( !cancelAll() ) {
 
372
                cleanup();
 
373
                jobFinished( false );
 
374
            }
 
375
        }
 
376
    }
 
377
    else {
 
378
        // cache the calculated checksum since the ChecksumPipe may be deleted below
 
379
        if ( ChecksumPipe* cp = qobject_cast<ChecksumPipe*>( d->pipe ) )
 
380
            d->checksumCache = cp->checksum();
 
381
 
 
382
        if( !d->doc->onTheFly() ||
 
383
            d->doc->onlyCreateImages() ) {
 
384
 
 
385
            if( success ) {
 
386
                emit infoMessage( i18n("Image successfully created in %1", d->doc->tempDir()), K3b::Job::MessageSuccess );
 
387
                d->imageFinished = true;
 
388
 
 
389
                if( d->doc->onlyCreateImages() ) {
 
390
                    jobFinished( true );
 
391
                }
 
392
                else if( !d->imageFile.open( QIODevice::ReadOnly ) ) {
 
393
                    emit infoMessage( i18n("Could not open file %1", d->doc->tempDir() ), MessageError );
 
394
                    cleanup();
 
395
                    jobFinished(false);
 
396
                }
 
397
                else if( prepareWriterJob() ) {
 
398
                    startWriterJob();
 
399
                    startPipe();
 
400
                }
 
401
            }
 
402
            else {
 
403
                if( m_isoImager->hasBeenCanceled() )
 
404
                    emit canceled();
 
405
                else
 
406
                    emit infoMessage( i18n("Error while creating ISO image"), MessageError );
 
407
 
 
408
                cancelAll();
 
409
                cleanup();
 
410
                jobFinished( false );
 
411
            }
 
412
        }
 
413
        else { // on-the-fly
 
414
            if( success ) {
 
415
                if ( !m_writerJob->active() )
 
416
                    finishCopy();
 
417
            }
 
418
            else {
 
419
                //
 
420
                // In case the imager failed let's make sure the writer does not emit an unusable
 
421
                // error message.
 
422
                //
 
423
                if( m_writerJob && m_writerJob->active() )
 
424
                    m_writerJob->setSourceUnreadable( true );
 
425
 
 
426
                // there is one special case which we need to handle here: the iso imager might be canceled
 
427
                // FIXME: the iso imager should not be able to cancel itself
 
428
                if( m_isoImager->hasBeenCanceled() && !this->hasBeenCanceled() )
 
429
                    cancel();
 
430
            }
 
431
        }
 
432
    }
 
433
}
 
434
 
 
435
 
 
436
bool K3b::DataJob::startWriterJob()
 
437
{
 
438
    kDebug();
 
439
    if( d->doc->dummy() )
 
440
        emit newTask( i18n("Simulating") );
 
441
    else if( d->copies > 1 )
 
442
        emit newTask( i18n("Writing Copy %1",d->copiesDone+1) );
 
443
    else
 
444
        emit newTask( i18n("Writing") );
 
445
 
 
446
    emit burning(true);
 
447
    m_writerJob->start();
 
448
    return true;
 
449
}
 
450
 
 
451
 
 
452
void K3b::DataJob::slotWriterJobPercent( int p )
 
453
{
 
454
    double totalTasks = d->copies;
 
455
    double tasksDone = d->copiesDone;
 
456
    if( d->doc->verifyData() ) {
 
457
        totalTasks*=2;
 
458
        tasksDone*=2;
 
459
    }
 
460
    if( !d->doc->onTheFly() ) {
 
461
        totalTasks+=1.0;
 
462
        tasksDone+=1.0;
 
463
    }
 
464
 
 
465
    emit percent( (int)((100.0*tasksDone + (double)p) / totalTasks) );
 
466
}
 
467
 
 
468
 
 
469
void K3b::DataJob::slotWriterNextTrack( int t, int tt )
 
470
{
 
471
    emit newSubTask( i18n("Writing Track %1 of %2",t,tt) );
 
472
}
 
473
 
 
474
 
 
475
void K3b::DataJob::slotWriterJobFinished( bool success )
 
476
{
 
477
    kDebug();
 
478
 
 
479
    if( success ) {
 
480
        if ( !d->doc->onTheFly() ||
 
481
             !m_isoImager->active() ) {
 
482
            finishCopy();
 
483
        }
 
484
    }
 
485
    else {
 
486
        if ( !cancelAll() ) {
 
487
            cleanup();
 
488
            jobFinished( false );
 
489
        }
 
490
    }
 
491
}
 
492
 
 
493
 
 
494
void K3b::DataJob::finishCopy()
 
495
{
 
496
    // the writerJob should have emitted the "simulation/writing successful" signal
 
497
 
 
498
    if( d->doc->verifyData() ) {
 
499
        if( !d->verificationJob ) {
 
500
            d->verificationJob = new K3b::VerificationJob( this, this );
 
501
            connect( d->verificationJob, SIGNAL(infoMessage(const QString&, int)),
 
502
                     this, SIGNAL(infoMessage(const QString&, int)) );
 
503
            connect( d->verificationJob, SIGNAL(newTask(const QString&)),
 
504
                     this, SIGNAL(newSubTask(const QString&)) );
 
505
            connect( d->verificationJob, SIGNAL(newSubTask(const QString&)),
 
506
                     this, SIGNAL(newSubTask(const QString&)) );
 
507
            connect( d->verificationJob, SIGNAL(percent(int)),
 
508
                     this, SLOT(slotVerificationProgress(int)) );
 
509
            connect( d->verificationJob, SIGNAL(percent(int)),
 
510
                     this, SIGNAL(subPercent(int)) );
 
511
            connect( d->verificationJob, SIGNAL(finished(bool)),
 
512
                     this, SLOT(slotVerificationFinished(bool)) );
 
513
            connect( d->verificationJob, SIGNAL(debuggingOutput(const QString&, const QString&)),
 
514
                     this, SIGNAL(debuggingOutput(const QString&, const QString&)) );
 
515
 
 
516
        }
 
517
        d->verificationJob->clear();
 
518
        d->verificationJob->setDevice( d->doc->burner() );
 
519
        d->verificationJob->setGrownSessionSize( m_isoImager->size() );
 
520
        d->verificationJob->addTrack( 0, d->checksumCache, m_isoImager->size() );
 
521
 
 
522
        emit burning(false);
 
523
 
 
524
        emit newTask( i18n("Verifying written data") );
 
525
 
 
526
        d->verificationJob->start();
 
527
    }
 
528
    else {
 
529
        d->copiesDone++;
 
530
 
 
531
        if( d->copiesDone < d->copies ) {
 
532
            if( !K3b::eject( d->doc->burner() ) ) {
 
533
                blockingInformation( i18n("K3b was unable to eject the written disk. Please do so manually.") );
 
534
            }
 
535
 
 
536
            bool failed = false;
 
537
            if( d->doc->onTheFly() )
 
538
                failed = !startOnTheFlyWriting();
 
539
            else
 
540
                failed = !prepareWriterJob() || !startWriterJob();
 
541
 
 
542
            if( failed ) {
 
543
                cancel();
 
544
            }
 
545
            else if( !d->doc->onTheFly() ) {
 
546
#ifdef __GNUC__
 
547
#warning Growisofs needs stdin to be closed in order to exit gracefully. Cdrecord does not. However,  if closed with cdrecord we loose parts of stderr. Why?
 
548
#endif
 
549
                d->pipe->writeTo( m_writerJob->ioDevice(), d->usedWritingApp != K3b::WritingAppCdrecord );
 
550
                d->pipe->open(true);
 
551
            }
 
552
        }
 
553
        else {
 
554
            cleanup();
 
555
            if ( k3bcore->globalSettings()->ejectMedia() ) {
 
556
                K3b::Device::eject( d->doc->burner() );
 
557
            }
 
558
            jobFinished(true);
 
559
        }
 
560
    }
 
561
}
 
562
 
 
563
 
 
564
void K3b::DataJob::slotVerificationProgress( int p )
 
565
{
 
566
    double totalTasks = d->copies*2;
 
567
    double tasksDone = d->copiesDone*2 + 1; // the writing of the current copy has already been finished
 
568
 
 
569
    if( !d->doc->onTheFly() ) {
 
570
        totalTasks+=1.0;
 
571
        tasksDone+=1.0;
 
572
    }
 
573
 
 
574
    emit percent( (int)((100.0*tasksDone + (double)p) / totalTasks) );
 
575
}
 
576
 
 
577
 
 
578
void K3b::DataJob::slotVerificationFinished( bool success )
 
579
{
 
580
    kDebug();
 
581
    d->copiesDone++;
 
582
 
 
583
    // reconnect our imager which we deconnected for the verification
 
584
    connectImager();
 
585
 
 
586
    if( k3bcore->globalSettings()->ejectMedia() || d->copiesDone < d->copies )
 
587
        K3b::Device::eject( d->doc->burner() );
 
588
 
 
589
    if( !d->canceled && d->copiesDone < d->copies ) {
 
590
        bool failed = false;
 
591
        if( d->doc->onTheFly() )
 
592
            failed = !startOnTheFlyWriting();
 
593
        else
 
594
            failed = !prepareWriterJob() || !startWriterJob();
 
595
 
 
596
        if( failed )
 
597
            cancel();
 
598
        else if( !d->doc->onTheFly() ) {
 
599
#ifdef __GNUC__
 
600
#warning Growisofs needs stdin to be closed in order to exit gracefully. Cdrecord does not. However,  if closed with cdrecord we loose parts of stderr. Why?
 
601
#endif
 
602
            d->pipe->writeTo( m_writerJob->ioDevice(), d->usedWritingApp != K3b::WritingAppCdrecord );
 
603
            d->pipe->open(true);
 
604
        }
 
605
    }
 
606
    else {
 
607
        cleanup();
 
608
        jobFinished( success );
 
609
    }
 
610
}
 
611
 
 
612
 
 
613
void K3b::DataJob::setWriterJob( K3b::AbstractWriter* writer )
 
614
{
 
615
    kDebug();
 
616
    // FIXME: progressedsize for multiple copies
 
617
    m_writerJob = writer;
 
618
    connect( m_writerJob, SIGNAL(infoMessage(const QString&, int)), this, SIGNAL(infoMessage(const QString&, int)) );
 
619
    connect( m_writerJob, SIGNAL(percent(int)), this, SLOT(slotWriterJobPercent(int)) );
 
620
    connect( m_writerJob, SIGNAL(processedSize(int, int)), this, SIGNAL(processedSize(int, int)) );
 
621
    connect( m_writerJob, SIGNAL(subPercent(int)), this, SIGNAL(subPercent(int)) );
 
622
    connect( m_writerJob, SIGNAL(processedSubSize(int, int)), this, SIGNAL(processedSubSize(int, int)) );
 
623
    connect( m_writerJob, SIGNAL(nextTrack(int, int)), this, SLOT(slotWriterNextTrack(int, int)) );
 
624
    connect( m_writerJob, SIGNAL(buffer(int)), this, SIGNAL(bufferStatus(int)) );
 
625
    connect( m_writerJob, SIGNAL(deviceBuffer(int)), this, SIGNAL(deviceBuffer(int)) );
 
626
    connect( m_writerJob, SIGNAL(writeSpeed(int, K3b::Device::SpeedMultiplicator)), this, SIGNAL(writeSpeed(int, K3b::Device::SpeedMultiplicator)) );
 
627
    connect( m_writerJob, SIGNAL(finished(bool)), this, SLOT(slotWriterJobFinished(bool)) );
 
628
    connect( m_writerJob, SIGNAL(newSubTask(const QString&)), this, SIGNAL(newSubTask(const QString&)) );
 
629
    connect( m_writerJob, SIGNAL(debuggingOutput(const QString&, const QString&)),
 
630
             this, SIGNAL(debuggingOutput(const QString&, const QString&)) );
 
631
}
 
632
 
 
633
 
 
634
void K3b::DataJob::setImager( K3b::IsoImager* imager )
 
635
{
 
636
    kDebug();
 
637
    if( m_isoImager != imager ) {
 
638
        delete m_isoImager;
 
639
 
 
640
        m_isoImager = imager;
 
641
 
 
642
        connectImager();
 
643
    }
 
644
}
 
645
 
 
646
 
 
647
void K3b::DataJob::connectImager()
 
648
{
 
649
    kDebug();
 
650
    m_isoImager->disconnect( this );
 
651
    connect( m_isoImager, SIGNAL(infoMessage(const QString&, int)), this, SIGNAL(infoMessage(const QString&, int)) );
 
652
    connect( m_isoImager, SIGNAL(percent(int)), this, SLOT(slotIsoImagerPercent(int)) );
 
653
    connect( m_isoImager, SIGNAL(finished(bool)), this, SLOT(slotIsoImagerFinished(bool)) );
 
654
    connect( m_isoImager, SIGNAL(debuggingOutput(const QString&, const QString&)),
 
655
             this, SIGNAL(debuggingOutput(const QString&, const QString&)) );
 
656
}
 
657
 
 
658
 
 
659
void K3b::DataJob::prepareImager()
 
660
{
 
661
    kDebug();
 
662
    if( !m_isoImager )
 
663
        setImager( new K3b::IsoImager( d->doc, this, this ) );
 
664
}
 
665
 
 
666
 
 
667
bool K3b::DataJob::prepareWriterJob()
 
668
{
 
669
    kDebug();
 
670
    if( m_writerJob ) {
 
671
        delete m_writerJob;
 
672
        m_writerJob = 0;
 
673
    }
 
674
 
 
675
    // if we append a new session we asked for an appendable cd already
 
676
    if( !waitForBurnMedium() ) {
 
677
        return false;
 
678
    }
 
679
 
 
680
    // It seems as if cdrecord is not able to append sessions in dao mode whereas cdrdao is
 
681
    if( d->usedWritingApp == K3b::WritingAppCdrecord )  {
 
682
        if( !setupCdrecordJob() ) {
 
683
            return false;
 
684
        }
 
685
    }
 
686
    else if ( d->usedWritingApp == K3b::WritingAppCdrdao ) {
 
687
        if ( !setupCdrdaoJob() ) {
 
688
            return false;
 
689
        }
 
690
    }
 
691
    else {
 
692
        if ( !setupGrowisofsJob() ) {
 
693
            return false;
 
694
        }
 
695
    }
 
696
 
 
697
    return true;
 
698
}
 
699
 
 
700
 
 
701
bool K3b::DataJob::waitForBurnMedium()
 
702
{
 
703
    // start with all media types supported by the writer
 
704
    Device::MediaTypes m  = d->doc->supportedMediaTypes() & d->doc->burner()->writeCapabilities();
 
705
 
 
706
    // if everything goes wrong we are left with no possible media to request
 
707
    if ( !m ) {
 
708
        emit infoMessage( i18n( "Internal Error: No medium type fits. This project cannot be burned." ), MessageError );
 
709
        return false;
 
710
    }
 
711
 
 
712
    emit newSubTask( i18n("Waiting for a medium") );
 
713
    Device::MediaType foundMedium = waitForMedium( d->doc->burner(),
 
714
                                                   usedMultiSessionMode() == K3b::DataDoc::CONTINUE ||
 
715
                                                   usedMultiSessionMode() == K3b::DataDoc::FINISH ?
 
716
                                                   K3b::Device::STATE_INCOMPLETE :
 
717
                                                   K3b::Device::STATE_EMPTY,
 
718
                                                   m,
 
719
                                                   d->doc->burningLength() );
 
720
 
 
721
    if( foundMedium == Device::MEDIA_UNKNOWN || hasBeenCanceled() ) {
 
722
        return false;
 
723
    }
 
724
 
 
725
    // -------------------------------
 
726
    // CD-R(W)
 
727
    // -------------------------------
 
728
    else if ( foundMedium & K3b::Device::MEDIA_CD_ALL ) {
 
729
        emit infoMessage( i18n( "Writing %1" , K3b::Device::mediaTypeString( foundMedium ) ), MessageInfo );
 
730
 
 
731
        // first of all we determine the data mode
 
732
        if( d->doc->dataMode() == K3b::DataModeAuto ) {
 
733
            if( !d->doc->onlyCreateImages() &&
 
734
                ( usedMultiSessionMode() == K3b::DataDoc::CONTINUE ||
 
735
                  usedMultiSessionMode() == K3b::DataDoc::FINISH ) ) {
 
736
 
 
737
                // try to get the last track's datamode
 
738
                // we already asked for an appendable cdr when fetching
 
739
                // the ms info
 
740
                kDebug() << "(K3b::DataJob) determining last track's datamode...";
 
741
 
 
742
                // FIXME: use the DeviceHandler
 
743
                K3b::Device::Toc toc = d->doc->burner()->readToc();
 
744
                if( toc.isEmpty() ) {
 
745
                    kDebug() << "(K3b::DataJob) could not retrieve toc.";
 
746
                    emit infoMessage( i18n("Unable to determine the last track's datamode. Using default."), MessageError );
 
747
                    d->usedDataMode = K3b::DataMode2;
 
748
                }
 
749
                else {
 
750
                    if( toc.back().mode() == K3b::Device::Track::MODE1 )
 
751
                        d->usedDataMode = K3b::DataMode1;
 
752
                    else
 
753
                        d->usedDataMode = K3b::DataMode2;
 
754
 
 
755
                    kDebug() << "(K3b::DataJob) using datamode: "
 
756
                             << (d->usedDataMode == K3b::DataMode1 ? "mode1" : "mode2")
 
757
                             << endl;
 
758
                }
 
759
            }
 
760
            else if( usedMultiSessionMode() == K3b::DataDoc::NONE )
 
761
                d->usedDataMode = K3b::DataMode1;
 
762
            else
 
763
                d->usedDataMode = K3b::DataMode2;
 
764
        }
 
765
        else
 
766
            d->usedDataMode = d->doc->dataMode();
 
767
 
 
768
        // determine the writing mode
 
769
        if( d->doc->writingMode() == K3b::WritingModeAuto ) {
 
770
            // TODO: put this into the cdreocrdwriter and decide based on the size of the
 
771
            // track
 
772
            if( writer()->dao() && d->usedDataMode == K3b::DataMode1 &&
 
773
                usedMultiSessionMode() == K3b::DataDoc::NONE )
 
774
                d->usedWritingMode = K3b::WritingModeSao;
 
775
            else
 
776
                d->usedWritingMode = K3b::WritingModeTao;
 
777
        }
 
778
        else
 
779
            d->usedWritingMode = d->doc->writingMode();
 
780
 
 
781
 
 
782
        if ( writingApp() == K3b::WritingAppGrowisofs ) {
 
783
            emit infoMessage( i18n( "Cannot write %1 media using %2. Falling back to default application." , QString("CD") , QString("growisofs") ), MessageWarning );
 
784
            setWritingApp( K3b::WritingAppAuto );
 
785
        }
 
786
        // cdrecord seems to have problems writing xa 1 disks in dao mode? At least on my system!
 
787
        if( writingApp() == K3b::WritingAppAuto ) {
 
788
            if( d->usedWritingMode == K3b::WritingModeSao ) {
 
789
                if( usedMultiSessionMode() != K3b::DataDoc::NONE )
 
790
                    d->usedWritingApp = K3b::WritingAppCdrdao;
 
791
                else if( d->usedDataMode == K3b::DataMode2 )
 
792
                    d->usedWritingApp = K3b::WritingAppCdrdao;
 
793
                else
 
794
                    d->usedWritingApp = K3b::WritingAppCdrecord;
 
795
            }
 
796
            else
 
797
                d->usedWritingApp = K3b::WritingAppCdrecord;
 
798
        }
 
799
        else {
 
800
            d->usedWritingApp = writingApp();
 
801
        }
 
802
    }
 
803
 
 
804
    else if ( foundMedium & K3b::Device::MEDIA_DVD_ALL ) {
 
805
        if ( writingApp() == K3b::WritingAppCdrdao ) {
 
806
            emit infoMessage( i18n( "Cannot write %1 media using %2. Falling back to default application.",
 
807
                                    K3b::Device::mediaTypeString( foundMedium, true ), "cdrdao" ), MessageWarning );
 
808
            setWritingApp( K3b::WritingAppAuto );
 
809
        }
 
810
 
 
811
        // make sure that we use the proper parameters for cdrecord
 
812
        d->usedDataMode = K3b::DataMode1;
 
813
 
 
814
        d->usedWritingApp = writingApp();
 
815
        // let's default to cdrecord for the time being (except for special cases below)
 
816
        if ( d->usedWritingApp == K3b::WritingAppAuto ) {
 
817
            d->usedWritingApp = K3b::WritingAppCdrecord;
 
818
        }
 
819
 
 
820
        // -------------------------------
 
821
        // DVD Plus
 
822
        // -------------------------------
 
823
        if( foundMedium & K3b::Device::MEDIA_DVD_PLUS_ALL ) {
 
824
            if( d->doc->dummy() ) {
 
825
                if( !questionYesNo( i18n("%1 media do not support write simulation. "
 
826
                                         "Do you really want to continue? The disc will actually be "
 
827
                                         "written to.", Device::mediaTypeString(foundMedium, true)),
 
828
                                    i18n("No Simulation with %1", Device::mediaTypeString(foundMedium, true)) ) ) {
 
829
                    return false;
 
830
                }
 
831
 
 
832
                d->doc->setDummy( false );
 
833
            }
 
834
 
 
835
            if( d->doc->writingMode() != K3b::WritingModeAuto && d->doc->writingMode() != K3b::WritingModeRestrictedOverwrite )
 
836
                emit infoMessage( i18n("Writing mode ignored when writing %1 media.", Device::mediaTypeString(foundMedium, true)), MessageInfo );
 
837
            d->usedWritingMode = K3b::WritingModeSao; // since cdrecord uses -sao for DVD+R(W)
 
838
 
 
839
            // Cdrecord doesn't support multisession DVD+R(W) disks
 
840
            if( usedMultiSessionMode() != DataDoc::NONE &&
 
841
                d->usedWritingApp == K3b::WritingAppCdrecord ) {
 
842
                d->usedWritingApp = WritingAppGrowisofs;
 
843
            }
 
844
 
 
845
            if( foundMedium & K3b::Device::MEDIA_DVD_PLUS_RW &&
 
846
                ( usedMultiSessionMode() == K3b::DataDoc::CONTINUE ||
 
847
                  usedMultiSessionMode() == K3b::DataDoc::FINISH ) )
 
848
                emit infoMessage( i18n("Growing ISO9660 filesystem on %1.", Device::mediaTypeString(foundMedium, true)), MessageInfo );
 
849
            else
 
850
                emit infoMessage( i18n("Writing %1.", Device::mediaTypeString(foundMedium, true)), MessageInfo );
 
851
        }
 
852
 
 
853
        // -------------------------------
 
854
        // DVD Minus
 
855
        // -------------------------------
 
856
        else if ( foundMedium & K3b::Device::MEDIA_DVD_MINUS_ALL ) {
 
857
            if( d->doc->dummy() && !d->doc->burner()->dvdMinusTestwrite() ) {
 
858
                if( !questionYesNo( i18n("Your writer (%1 %2) does not support simulation with DVD-R(W) media. "
 
859
                                         "Do you really want to continue? The media will actually be "
 
860
                                         "written to.",
 
861
                                         d->doc->burner()->vendor(),
 
862
                                         d->doc->burner()->description()),
 
863
                                    i18n("No Simulation with DVD-R(W)") ) ) {
 
864
                    return false;
 
865
                }
 
866
 
 
867
                d->doc->setDummy( false );
 
868
            }
 
869
 
 
870
            // RESTRICTED OVERWRITE
 
871
            // --------------------
 
872
            if( foundMedium & K3b::Device::MEDIA_DVD_RW_OVWR ) {
 
873
                d->usedWritingMode = K3b::WritingModeRestrictedOverwrite;
 
874
                if( usedMultiSessionMode() == K3b::DataDoc::NONE ||
 
875
                    usedMultiSessionMode() == K3b::DataDoc::START ) {
 
876
                    // FIXME: can cdrecord handle this?
 
877
                    emit infoMessage( i18n("Writing DVD-RW in restricted overwrite mode."), MessageInfo );
 
878
                }
 
879
                else {
 
880
                    emit infoMessage( i18n("Growing ISO9660 filesystem on DVD-RW in restricted overwrite mode."), MessageInfo );
 
881
                    // we can only do this with growisofs
 
882
                    d->usedWritingApp = K3b::WritingAppGrowisofs;
 
883
                }
 
884
            }
 
885
 
 
886
            // NORMAL
 
887
            // ------
 
888
            else {
 
889
 
 
890
                // FIXME: DVD-R DL jump and stuff
 
891
 
 
892
                if( d->doc->writingMode() == K3b::WritingModeSao ) {
 
893
                    d->usedWritingMode = K3b::WritingModeSao;
 
894
                    emit infoMessage( i18n("Writing %1 in DAO mode.", K3b::Device::mediaTypeString(foundMedium, true) ), MessageInfo );
 
895
                }
 
896
 
 
897
                else {
 
898
                    // check if the writer supports writing sequential and thus multisession (on -1 the burner cannot handle
 
899
                    // features and we simply ignore it and hope for the best)
 
900
                    if( d->doc->burner()->featureCurrent( K3b::Device::FEATURE_INCREMENTAL_STREAMING_WRITABLE ) == 0 ) {
 
901
                        if( !questionYesNo( i18n("Your writer (%1 %2) does not support Incremental Streaming with %3 "
 
902
                                                 "media. Multisession will not be possible. Continue anyway?",
 
903
                                                 d->doc->burner()->vendor(),
 
904
                                                 d->doc->burner()->description(),
 
905
                                                 K3b::Device::mediaTypeString(foundMedium, true) ),
 
906
                                            i18n("No Incremental Streaming") ) ) {
 
907
                            return false;
 
908
                        }
 
909
                        else {
 
910
                            d->usedWritingMode = K3b::WritingModeSao;
 
911
                            emit infoMessage( i18n("Writing %1 in DAO mode.", K3b::Device::mediaTypeString(foundMedium, true) ), MessageInfo );
 
912
                        }
 
913
                    }
 
914
                    else {
 
915
                        d->usedWritingMode = K3b::WritingModeIncrementalSequential;
 
916
                        if( !(foundMedium & (K3b::Device::MEDIA_DVD_RW|K3b::Device::MEDIA_DVD_RW_OVWR|K3b::Device::MEDIA_DVD_RW_SEQ)) &&
 
917
                            d->doc->writingMode() == K3b::WritingModeRestrictedOverwrite )
 
918
                            emit infoMessage( i18n("Restricted Overwrite is not possible with DVD-R media."), MessageInfo );
 
919
 
 
920
                        emit infoMessage( i18n("Writing %1 in incremental mode.", K3b::Device::mediaTypeString(foundMedium, true) ), MessageInfo );
 
921
                    }
 
922
                }
 
923
            }
 
924
        }
 
925
    }
 
926
 
 
927
    // --------------------
 
928
    // Blu-ray
 
929
    // --------------------
 
930
    else if ( foundMedium & K3b::Device::MEDIA_BD_ALL ) {
 
931
        d->usedWritingApp = writingApp();
 
932
        if( d->usedWritingApp == K3b::WritingAppAuto ) {
 
933
            d->usedWritingApp = K3b::WritingAppCdrecord;
 
934
        }
 
935
 
 
936
        if ( d->usedWritingApp == K3b::WritingAppCdrecord &&
 
937
             !k3bcore->externalBinManager()->binObject("cdrecord")->hasFeature( "blu-ray" ) ) {
 
938
            d->usedWritingApp = K3b::WritingAppGrowisofs;
 
939
        }
 
940
 
 
941
        if( d->doc->dummy() ) {
 
942
            if( !questionYesNo( i18n("%1 media do not support write simulation. "
 
943
                                     "Do you really want to continue? The disc will actually be "
 
944
                                     "written to.", Device::mediaTypeString(foundMedium, true)),
 
945
                                i18n("No Simulation with %1", Device::mediaTypeString(foundMedium, true)) ) ) {
 
946
                return false;
 
947
            }
 
948
 
 
949
            d->doc->setDummy( false );
 
950
        }
 
951
 
 
952
        if( d->doc->writingMode() != K3b::WritingModeAuto )
 
953
            emit infoMessage( i18n("Writing mode ignored when writing %1 media.", Device::mediaTypeString(foundMedium, true)), MessageInfo );
 
954
        d->usedWritingMode = K3b::WritingModeSao; // cdrecord uses -sao for DVD+R(W), let's assume it's used also for BD-R(E)
 
955
 
 
956
        // Cdrecord probably doesn't support multisession BD-R disks
 
957
        // FIXME: check if above is actually true
 
958
        if( usedMultiSessionMode() != DataDoc::NONE &&
 
959
            d->usedWritingApp == K3b::WritingAppCdrecord ) {
 
960
            d->usedWritingApp = WritingAppGrowisofs;
 
961
        }
 
962
 
 
963
        if( foundMedium & K3b::Device::MEDIA_BD_RE &&
 
964
            ( usedMultiSessionMode() == K3b::DataDoc::CONTINUE ||
 
965
              usedMultiSessionMode() == K3b::DataDoc::FINISH ) )
 
966
            emit infoMessage( i18n("Growing ISO9660 filesystem on %1.", Device::mediaTypeString(foundMedium, true)), MessageInfo );
 
967
        else
 
968
            emit infoMessage( i18n("Writing %1.", Device::mediaTypeString(foundMedium, true)), MessageInfo );
 
969
    }
 
970
 
 
971
    return true;
 
972
}
 
973
 
 
974
 
 
975
QString K3b::DataJob::jobDescription() const
 
976
{
 
977
    if( d->doc->onlyCreateImages() ) {
 
978
        return i18n("Creating Data Image File");
 
979
    }
 
980
    else if( d->doc->multiSessionMode() == K3b::DataDoc::NONE ||
 
981
             d->doc->multiSessionMode() == K3b::DataDoc::AUTO ) {
 
982
        return i18n("Writing Data Project")
 
983
            + ( d->doc->isoOptions().volumeID().isEmpty()
 
984
                ? QString()
 
985
                : QString( " (%1)" ).arg(d->doc->isoOptions().volumeID()) );
 
986
    }
 
987
    else {
 
988
        return i18n("Writing Multisession Project")
 
989
            + ( d->doc->isoOptions().volumeID().isEmpty()
 
990
                ? QString()
 
991
                : QString( " (%1)" ).arg(d->doc->isoOptions().volumeID()) );
 
992
    }
 
993
}
 
994
 
 
995
 
 
996
QString K3b::DataJob::jobDetails() const
 
997
{
 
998
    if( d->doc->copies() > 1 &&
 
999
        !d->doc->dummy() &&
 
1000
        !(d->doc->multiSessionMode() == K3b::DataDoc::CONTINUE ||
 
1001
          d->doc->multiSessionMode() == K3b::DataDoc::FINISH) )
 
1002
        return i18np("ISO9660 Filesystem (Size: %2) - %1 copy",
 
1003
                     "ISO9660 Filesystem (Size: %2) - %1 copies",
 
1004
                     d->doc->copies(),
 
1005
                     KIO::convertSize( d->doc->size() ) );
 
1006
    else
 
1007
        return i18n( "ISO9660 Filesystem (Size: %1)",
 
1008
                     KIO::convertSize( d->doc->size() ) );
 
1009
}
 
1010
 
 
1011
 
 
1012
K3b::DataDoc::MultiSessionMode K3b::DataJob::usedMultiSessionMode() const
 
1013
{
 
1014
    return d->multiSessionParameterJob->usedMultiSessionMode();
 
1015
}
 
1016
 
 
1017
 
 
1018
void K3b::DataJob::cleanup()
 
1019
{
 
1020
    kDebug();
 
1021
    if( !d->doc->onTheFly() && ( d->doc->removeImages() || d->canceled ) ) {
 
1022
        if( QFile::exists( d->doc->tempDir() ) ) {
 
1023
            d->imageFile.remove();
 
1024
            emit infoMessage( i18n("Removed image file %1",d->doc->tempDir()), K3b::Job::MessageSuccess );
 
1025
        }
 
1026
    }
 
1027
 
 
1028
    if( d->tocFile ) {
 
1029
        delete d->tocFile;
 
1030
        d->tocFile = 0;
 
1031
    }
 
1032
}
 
1033
 
 
1034
 
 
1035
bool K3b::DataJob::hasBeenCanceled() const
 
1036
{
 
1037
    return d->canceled;
 
1038
}
 
1039
 
 
1040
 
 
1041
bool K3b::DataJob::setupCdrecordJob()
 
1042
{
 
1043
    kDebug();
 
1044
    K3b::CdrecordWriter* writer = new K3b::CdrecordWriter( d->doc->burner(), this, this );
 
1045
 
 
1046
    // cdrecord manpage says that "not all" writers are able to write
 
1047
    // multisession disks in dao mode. That means there are writers that can.
 
1048
 
 
1049
    // Does it really make sence to write Data ms cds in DAO mode since writing the
 
1050
    // first session of a cd-extra in DAO mode is no problem with my writer while
 
1051
    // writing the second data session is only possible in TAO mode.
 
1052
    if( d->usedWritingMode == K3b::WritingModeSao &&
 
1053
        usedMultiSessionMode() != K3b::DataDoc::NONE )
 
1054
        emit infoMessage( i18n("Most writers do not support writing "
 
1055
                               "multisession CDs in DAO mode."), MessageInfo );
 
1056
 
 
1057
    writer->setWritingMode( d->usedWritingMode );
 
1058
    writer->setSimulate( d->doc->dummy() );
 
1059
    writer->setBurnSpeed( d->doc->speed() );
 
1060
 
 
1061
    // multisession
 
1062
    writer->setMulti( usedMultiSessionMode() == K3b::DataDoc::START ||
 
1063
                      usedMultiSessionMode() == K3b::DataDoc::CONTINUE );
 
1064
 
 
1065
    if( d->doc->onTheFly() &&
 
1066
        ( usedMultiSessionMode() == K3b::DataDoc::CONTINUE ||
 
1067
          usedMultiSessionMode() == K3b::DataDoc::FINISH ) )
 
1068
        writer->addArgument("-waiti");
 
1069
 
 
1070
    if( d->usedDataMode == K3b::DataMode1 )
 
1071
        writer->addArgument( "-data" );
 
1072
    else {
 
1073
        if( k3bcore->externalBinManager()->binObject("cdrecord") &&
 
1074
            k3bcore->externalBinManager()->binObject("cdrecord")->hasFeature( "xamix" ) )
 
1075
            writer->addArgument( "-xa" );
 
1076
        else
 
1077
            writer->addArgument( "-xa1" );
 
1078
    }
 
1079
 
 
1080
    writer->addArgument( QString("-tsize=%1s").arg(m_isoImager->size()) )->addArgument("-");
 
1081
 
 
1082
    setWriterJob( writer );
 
1083
 
 
1084
    return true;
 
1085
}
 
1086
 
 
1087
 
 
1088
bool K3b::DataJob::setupCdrdaoJob()
 
1089
{
 
1090
    // create cdrdao job
 
1091
    K3b::CdrdaoWriter* writer = new K3b::CdrdaoWriter( d->doc->burner(), this, this );
 
1092
    writer->setCommand( K3b::CdrdaoWriter::WRITE );
 
1093
    writer->setSimulate( d->doc->dummy() );
 
1094
    writer->setBurnSpeed( d->doc->speed() );
 
1095
    // multisession
 
1096
    writer->setMulti( usedMultiSessionMode() == K3b::DataDoc::START ||
 
1097
                      usedMultiSessionMode() == K3b::DataDoc::CONTINUE );
 
1098
 
 
1099
    // now write the tocfile
 
1100
    if( d->tocFile ) delete d->tocFile;
 
1101
    d->tocFile = new KTemporaryFile();
 
1102
    d->tocFile->setSuffix( ".toc" );
 
1103
    d->tocFile->open();
 
1104
 
 
1105
    QTextStream s( d->tocFile );
 
1106
    if( d->usedDataMode == K3b::DataMode1 ) {
 
1107
        s << "CD_ROM" << "\n";
 
1108
        s << "\n";
 
1109
        s << "TRACK MODE1" << "\n";
 
1110
    }
 
1111
    else {
 
1112
        s << "CD_ROM_XA" << "\n";
 
1113
        s << "\n";
 
1114
        s << "TRACK MODE2_FORM1" << "\n";
 
1115
    }
 
1116
 
 
1117
    s << "DATAFILE \"-\" " << m_isoImager->size()*2048 << "\n";
 
1118
 
 
1119
    d->tocFile->close();
 
1120
 
 
1121
    writer->setTocFile( d->tocFile->fileName() );
 
1122
 
 
1123
    setWriterJob( writer );
 
1124
 
 
1125
    return true;
 
1126
}
 
1127
 
 
1128
 
 
1129
bool K3b::DataJob::setupGrowisofsJob()
 
1130
{
 
1131
    K3b::GrowisofsWriter* writer = new K3b::GrowisofsWriter( d->doc->burner(), this, this );
 
1132
 
 
1133
    // these do only make sense with DVD-R(W)
 
1134
    writer->setSimulate( d->doc->dummy() );
 
1135
    writer->setBurnSpeed( d->doc->speed() );
 
1136
 
 
1137
    // Andy said incremental sequential is the default mode and it seems uses have more problems with DAO anyway
 
1138
    // BUT: I also had a report that incremental sequential produced unreadable media!
 
1139
    if( d->doc->writingMode() == K3b::WritingModeSao )
 
1140
//     || ( d->doc->writingMode() == K3b::WritingModeAuto &&
 
1141
//       usedMultiSessionMode() == K3b::DataDoc::NONE ) )
 
1142
        writer->setWritingMode( K3b::WritingModeSao );
 
1143
 
 
1144
    writer->setMultiSession( usedMultiSessionMode() == K3b::DataDoc::CONTINUE ||
 
1145
                             usedMultiSessionMode() == K3b::DataDoc::FINISH );
 
1146
 
 
1147
    writer->setCloseDvd( usedMultiSessionMode() == K3b::DataDoc::NONE ||
 
1148
                         usedMultiSessionMode() == K3b::DataDoc::FINISH );
 
1149
 
 
1150
    writer->setImageToWrite( QString() );  // read from stdin
 
1151
    writer->setTrackSize( m_isoImager->size() );
 
1152
 
 
1153
    if( usedMultiSessionMode() != K3b::DataDoc::NONE ) {
 
1154
        //
 
1155
        // growisofs wants a valid -C parameter for multisession, so we get it from the
 
1156
        // K3b::MsInfoFetcher (see K3b::DataJob::prepareWriting)
 
1157
        //
 
1158
        writer->setMultiSessionInfo( m_isoImager->multiSessionInfo() );
 
1159
    }
 
1160
 
 
1161
    setWriterJob( writer );
 
1162
 
 
1163
    return true;
 
1164
}
 
1165
 
 
1166
#include "k3bdatajob.moc"