File indexing completed on 2024-04-28 04:50:04

0001 /*
0002     SPDX-FileCopyrightText: 2007-2009 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "k3bmediacopydialog.h"
0009 
0010 #include "k3bmediaselectioncombobox.h"
0011 
0012 #include "k3bcdcopyjob.h"
0013 #include "k3bclonejob.h"
0014 #include "k3bdvdcopyjob.h"
0015 
0016 #include "k3bwriterselectionwidget.h"
0017 #include "k3btempdirselectionwidget.h"
0018 #include "k3bcore.h"
0019 #include "k3bstdguiitems.h"
0020 #include "k3bdevice.h"
0021 #include "k3bdevicemanager.h"
0022 #include "k3bburnprogressdialog.h"
0023 #include "k3bglobals.h"
0024 #include "k3bexternalbinmanager.h"
0025 #include "k3bthememanager.h"
0026 #include "k3bwritingmodewidget.h"
0027 #include "k3bapplication.h"
0028 #include "k3bmediacache.h"
0029 
0030 #include <KConfig>
0031 #include <KSharedConfig>
0032 #include <KIconLoader>
0033 #include <KLocalizedString>
0034 #include <KGuiItem>
0035 #include <KMessageBox>
0036 #include <KStandardGuiItem>
0037 
0038 #include <QFile>
0039 #include <QFileInfo>
0040 #include <QList>
0041 #include <QButtonGroup>
0042 #include <QCheckBox>
0043 #include <QComboBox>
0044 #include <QGridLayout>
0045 #include <QGroupBox>
0046 #include <QLayout>
0047 #include <QLabel>
0048 #include <QPushButton>
0049 #include <QRadioButton>
0050 #include <QSizePolicy>
0051 #include <QSpinBox>
0052 #include <QToolTip>
0053 #include <QTabWidget>
0054 
0055 
0056 K3b::MediaCopyDialog::MediaCopyDialog( QWidget *parent )
0057     : K3b::InteractionDialog( parent,
0058                             i18n("Disk Copy"),
0059                             i18n("and CD Cloning"),
0060                             START_BUTTON|CANCEL_BUTTON,
0061                             START_BUTTON,
0062                             "Disk Copy" )
0063 {
0064     QWidget* main = mainWidget();
0065 
0066     QGridLayout* mainGrid = new QGridLayout( main );
0067     mainGrid->setContentsMargins( 0, 0, 0, 0 );
0068 
0069     QGroupBox* groupSource = new QGroupBox( i18n("Source Medium"), main );
0070     m_comboSourceDevice = new K3b::MediaSelectionComboBox( groupSource );
0071     m_comboSourceDevice->setWantedMediumType( K3b::Device::MEDIA_ALL );
0072     m_comboSourceDevice->setWantedMediumState( K3b::Device::STATE_COMPLETE|K3b::Device::STATE_INCOMPLETE );
0073     QHBoxLayout* groupSourceLayout = new QHBoxLayout( groupSource );
0074     groupSourceLayout->addWidget( m_comboSourceDevice );
0075 
0076     m_writerSelectionWidget = new K3b::WriterSelectionWidget( main );
0077     m_writerSelectionWidget->setWantedMediumState( K3b::Device::STATE_EMPTY );
0078 
0079     // tab widget --------------------
0080     QTabWidget* tabWidget = new QTabWidget( main );
0081 
0082     //
0083     // option tab --------------------
0084     //
0085     QWidget* optionTab = new QWidget( tabWidget );
0086     QGridLayout* optionTabGrid = new QGridLayout( optionTab );
0087 
0088     QGroupBox* groupCopyMode = new QGroupBox( i18n("Copy Mode"), optionTab );
0089     m_comboCopyMode = new QComboBox( groupCopyMode );
0090     m_comboCopyMode->addItem( i18n("Normal Copy") );
0091     m_comboCopyMode->addItem( i18n("Clone Copy") );
0092     QHBoxLayout* groupCopyModeLayout = new QHBoxLayout( groupCopyMode );
0093     groupCopyModeLayout->addWidget( m_comboCopyMode );
0094 
0095     QGroupBox* groupWritingMode = new QGroupBox( i18n("Writing Mode"), optionTab );
0096     m_writingModeWidget = new K3b::WritingModeWidget( groupWritingMode );
0097     QHBoxLayout* groupWritingModeLayout = new QHBoxLayout( groupWritingMode );
0098     groupWritingModeLayout->addWidget( m_writingModeWidget );
0099 
0100     QGroupBox* groupCopies = new QGroupBox( i18n("Copies"), optionTab );
0101     QLabel* pixLabel = new QLabel( groupCopies );
0102     pixLabel->setPixmap( QIcon::fromTheme("tools-media-optical-copy").pixmap(KIconLoader::SizeMedium) );
0103     pixLabel->setScaledContents( false );
0104     m_spinCopies = new QSpinBox( groupCopies );
0105     m_spinCopies->setRange( 1, 999 );
0106     QHBoxLayout* groupCopiesLayout = new QHBoxLayout( groupCopies );
0107     groupCopiesLayout->addWidget( pixLabel );
0108     groupCopiesLayout->addWidget( m_spinCopies );
0109 
0110     QGroupBox* groupOptions = new QGroupBox( i18n("Settings"), optionTab );
0111     m_checkSimulate = K3b::StdGuiItems::simulateCheckbox( groupOptions );
0112     m_checkCacheImage = K3b::StdGuiItems::createCacheImageCheckbox( groupOptions );
0113     m_checkOnlyCreateImage = K3b::StdGuiItems::onlyCreateImagesCheckbox( groupOptions );
0114     m_checkDeleteImages = K3b::StdGuiItems::removeImagesCheckbox( groupOptions );
0115     m_checkVerifyData = K3b::StdGuiItems::verifyCheckBox( groupOptions );
0116     QVBoxLayout* groupOptionsLayout = new QVBoxLayout( groupOptions );
0117     groupOptionsLayout->addWidget( m_checkSimulate );
0118     groupOptionsLayout->addWidget( m_checkCacheImage );
0119     groupOptionsLayout->addWidget( m_checkOnlyCreateImage );
0120     groupOptionsLayout->addWidget( m_checkDeleteImages );
0121     groupOptionsLayout->addWidget( m_checkVerifyData );
0122     groupOptionsLayout->addStretch( 1 );
0123 
0124     optionTabGrid->addWidget( groupCopyMode, 0, 0 );
0125     optionTabGrid->addWidget( groupWritingMode, 1, 0 );
0126     optionTabGrid->addWidget( groupOptions, 0, 1, 3, 1 );
0127     optionTabGrid->addWidget( groupCopies, 2, 0 );
0128     optionTabGrid->setRowStretch( 2, 1 );
0129     optionTabGrid->setColumnStretch( 1, 1 );
0130 
0131     tabWidget->addTab( optionTab, i18n("&Options") );
0132 
0133 
0134     //
0135     // image tab ------------------
0136     //
0137     QWidget* imageTab = new QWidget( tabWidget );
0138     QGridLayout* imageTabGrid = new QGridLayout( imageTab );
0139 
0140     m_tempDirSelectionWidget = new K3b::TempDirSelectionWidget( imageTab );
0141 
0142     imageTabGrid->addWidget( m_tempDirSelectionWidget, 0, 0 );
0143 
0144     tabWidget->addTab( imageTab, i18n("&Image") );
0145 
0146 
0147     //
0148     // advanced tab ------------------
0149     //
0150     QWidget* advancedTab = new QWidget( tabWidget );
0151     QGridLayout* advancedTabGrid = new QGridLayout( advancedTab );
0152 
0153     m_groupAdvancedDataOptions = new QGroupBox( i18n("Data"), advancedTab );
0154     QGridLayout* groupAdvancedDataOptionsLayout = new QGridLayout( m_groupAdvancedDataOptions );
0155     m_spinDataRetries = new QSpinBox( m_groupAdvancedDataOptions );
0156     m_spinDataRetries->setRange( 1, 128 );
0157     m_checkIgnoreDataReadErrors = K3b::StdGuiItems::ignoreAudioReadErrorsCheckBox( m_groupAdvancedDataOptions );
0158     m_checkNoCorrection = new QCheckBox( i18n("No error correction"), m_groupAdvancedDataOptions );
0159     groupAdvancedDataOptionsLayout->addWidget( new QLabel( i18n("Read retries:"), m_groupAdvancedDataOptions ), 0, 0 );
0160     groupAdvancedDataOptionsLayout->addWidget( m_spinDataRetries, 0, 1 );
0161     groupAdvancedDataOptionsLayout->addWidget( m_checkIgnoreDataReadErrors, 1, 0, 1, 2 );
0162     groupAdvancedDataOptionsLayout->addWidget( m_checkNoCorrection, 2, 0, 1, 2 );
0163     groupAdvancedDataOptionsLayout->setRowStretch( 4, 1 );
0164 
0165     m_groupAdvancedAudioOptions = new QGroupBox( i18n("Audio"), advancedTab );
0166     QGridLayout* groupAdvancedAudioOptionsLayout = new QGridLayout( m_groupAdvancedAudioOptions );
0167     m_spinAudioRetries = new QSpinBox( m_groupAdvancedAudioOptions );
0168     m_spinAudioRetries->setRange( 1, 128 );
0169     m_checkIgnoreAudioReadErrors = K3b::StdGuiItems::ignoreAudioReadErrorsCheckBox( m_groupAdvancedAudioOptions );
0170     m_comboParanoiaMode = K3b::StdGuiItems::paranoiaModeComboBox( m_groupAdvancedAudioOptions );
0171     m_checkReadCdText = new QCheckBox( i18n("Copy CD-Text"), m_groupAdvancedAudioOptions );
0172     groupAdvancedAudioOptionsLayout->addWidget( new QLabel( i18n("Read retries:"), m_groupAdvancedAudioOptions ), 0, 0 );
0173     groupAdvancedAudioOptionsLayout->addWidget( m_spinAudioRetries, 0, 1 );
0174     groupAdvancedAudioOptionsLayout->addWidget( m_checkIgnoreAudioReadErrors, 1, 0, 1, 2 );
0175     groupAdvancedAudioOptionsLayout->addWidget( new QLabel( i18n("Paranoia mode:"), m_groupAdvancedAudioOptions ), 2, 0 );
0176     groupAdvancedAudioOptionsLayout->addWidget( m_comboParanoiaMode, 2, 1 );
0177     groupAdvancedAudioOptionsLayout->addWidget( m_checkReadCdText, 3, 0, 1, 2 );
0178     groupAdvancedAudioOptionsLayout->setRowStretch( 4, 1 );
0179 
0180     advancedTabGrid->addWidget( m_groupAdvancedDataOptions, 0, 1 );
0181     advancedTabGrid->addWidget( m_groupAdvancedAudioOptions, 0, 0 );
0182 
0183     tabWidget->addTab( advancedTab, i18n("&Advanced") );
0184 
0185     mainGrid->addWidget( groupSource, 0, 0  );
0186     mainGrid->addWidget( m_writerSelectionWidget, 1, 0  );
0187     mainGrid->addWidget( tabWidget, 2, 0 );
0188     mainGrid->setRowStretch( 2, 1 );
0189 
0190 
0191     connect( m_comboSourceDevice, SIGNAL(selectionChanged(K3b::Device::Device*)), this, SLOT(slotToggleAll()) );
0192     connect( m_comboSourceDevice, SIGNAL(selectionChanged(K3b::Device::Device*)),
0193              this, SLOT(slotToggleAll()) );
0194     connect( m_writerSelectionWidget, SIGNAL(writerChanged()), this, SLOT(slotToggleAll()) );
0195     connect( m_writerSelectionWidget, SIGNAL(writerChanged(K3b::Device::Device*)),
0196              m_writingModeWidget, SLOT(setDevice(K3b::Device::Device*)) );
0197     connect( m_writingModeWidget, SIGNAL(writingModeChanged(WritingMode)), this, SLOT(slotToggleAll()) );
0198     connect( m_checkCacheImage, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) );
0199     connect( m_checkSimulate, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) );
0200     connect( m_checkOnlyCreateImage, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) );
0201     connect( m_comboCopyMode, SIGNAL(activated(int)), this, SLOT(slotToggleAll()) );
0202     connect( m_checkReadCdText, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) );
0203 
0204     m_checkIgnoreDataReadErrors->setToolTip( i18n("Skip unreadable data sectors") );
0205     m_checkNoCorrection->setToolTip( i18n("Disable the source drive's error correction") );
0206     m_checkReadCdText->setToolTip( i18n("Copy CD-Text from the source CD if available.") );
0207 
0208     m_checkNoCorrection->setWhatsThis( i18n("<p>If this option is checked K3b will disable the "
0209                                             "source drive's ECC/EDC error correction. This way sectors "
0210                                             "that are unreadable by intention can be read."
0211                                             "<p>This may be useful for cloning CDs with copy "
0212                                             "protection based on corrupted sectors.") );
0213     m_checkReadCdText->setWhatsThis( i18n("<p>If this option is checked K3b will search for CD-Text on the source CD. "
0214                                           "Disable it if your CD drive has problems with reading CD-Text or you want "
0215                                           "to stick to CDDB info.") );
0216     m_checkIgnoreDataReadErrors->setWhatsThis( i18n("<p>If this option is checked and K3b is not able to read a data sector from the "
0217                                                     "source medium it will be replaced with zeros on the resulting copy.") );
0218 
0219     m_comboCopyMode->setWhatsThis(
0220         "<p><b>" + i18n("Normal Copy") + "</b>"
0221        + i18n("<p>This is the normal copy mode for DVD, Blu-ray, and most CD media types. "
0222                "It allows copying Audio CDs, multi and single session Data Media, and "
0223                "Enhanced Audio CDs (an Audio CD containing an additional data session)."
0224                "<p>For Video CDs please use the CD Cloning mode.")
0225         + "<p><b>" + i18n("Clone Copy") + "</b>"
0226         + i18n("<p>In CD Cloning mode K3b performs a raw copy of the CD. That means it does "
0227                "not care about the content but simply copies the CD bit by bit. It may be used "
0228                "to copy Video CDs or CDs which contain erroneous sectors."
0229                "<p><b>Caution:</b> Only single session CDs can be cloned.") );
0230 }
0231 
0232 
0233 K3b::MediaCopyDialog::~MediaCopyDialog()
0234 {
0235 }
0236 
0237 
0238 void K3b::MediaCopyDialog::init()
0239 {
0240     slotToggleAll();
0241 }
0242 
0243 
0244 void K3b::MediaCopyDialog::setReadingDevice( K3b::Device::Device* dev )
0245 {
0246     m_comboSourceDevice->setSelectedDevice( dev );
0247 }
0248 
0249 
0250 K3b::Device::Device* K3b::MediaCopyDialog::readingDevice() const
0251 {
0252     return m_comboSourceDevice->selectedDevice();
0253 }
0254 
0255 
0256 void K3b::MediaCopyDialog::slotStartClicked()
0257 {
0258     //
0259     // Let's check the available size
0260     //
0261     if( m_checkCacheImage->isChecked() || m_checkOnlyCreateImage->isChecked() ) {
0262         if( neededSize() > m_tempDirSelectionWidget->freeTempSpace() ) {
0263             if( KMessageBox::warningContinueCancel( this, i18n("There does not seem to be enough free space in the temporary folder. "
0264                                                                "Write anyway?") ) == KMessageBox::Cancel )
0265                 return;
0266         }
0267     }
0268 
0269     K3b::Device::Device* readDev = m_comboSourceDevice->selectedDevice();
0270     K3b::Device::Device* burnDev = m_writerSelectionWidget->writerDevice();
0271     K3b::Medium sourceMedium = k3bappcore->mediaCache()->medium( readDev );
0272     K3b::Medium burnMedium = k3bappcore->mediaCache()->medium( burnDev );
0273 
0274     K3b::JobProgressDialog* dlg = 0;
0275     if (m_checkOnlyCreateImage->isChecked())
0276         dlg = new K3b::JobProgressDialog(parentWidget());
0277     else
0278         dlg = new K3b::BurnProgressDialog(parentWidget());
0279     dlg->setAttribute(Qt::WA_DeleteOnClose);    // Memory-leak issue fixed!
0280 
0281     K3b::BurnJob* burnJob = 0;
0282 
0283     if( m_comboCopyMode->currentIndex() == 1 ) {
0284         //
0285         // check for m_tempDirSelectionWidget->tempPath() and
0286         // m_tempDirSelectionWidget-tempPath() + ".toc"
0287         //
0288         if( QFileInfo( m_tempDirSelectionWidget->tempPath() ).isFile() ) {
0289             if( KMessageBox::warningContinueCancel( this,
0290                                                     i18n("Do you want to overwrite %1?",m_tempDirSelectionWidget->tempPath()),
0291                                                     i18n("File Exists"),
0292                                                     KStandardGuiItem::overwrite() )
0293                 != KMessageBox::Continue )
0294                 return;
0295         }
0296 
0297         if( QFileInfo( m_tempDirSelectionWidget->tempPath() + ".toc" ).isFile() ) {
0298             if( KMessageBox::warningContinueCancel( this,
0299                                                     i18n("Do you want to overwrite %1?",m_tempDirSelectionWidget->tempPath() + ".toc"),
0300                                                     i18n("File Exists"),
0301                                                     KStandardGuiItem::overwrite() )
0302                 != KMessageBox::Continue )
0303                 return;
0304         }
0305 
0306         K3b::CloneJob* job = new K3b::CloneJob( dlg, this );
0307 
0308         job->setWriterDevice( m_writerSelectionWidget->writerDevice() );
0309         job->setReaderDevice( m_comboSourceDevice->selectedDevice() );
0310         job->setImagePath( m_tempDirSelectionWidget->tempPath() );
0311         job->setNoCorrection( m_checkNoCorrection->isChecked() );
0312         job->setRemoveImageFiles( m_checkDeleteImages->isChecked() && !m_checkOnlyCreateImage->isChecked() );
0313         job->setOnlyCreateImage( m_checkOnlyCreateImage->isChecked() );
0314         job->setSimulate( m_checkSimulate->isChecked() );
0315         job->setWriteSpeed( m_writerSelectionWidget->writerSpeed() );
0316         job->setCopies( m_checkSimulate->isChecked() ? 1 : m_spinCopies->value() );
0317         job->setReadRetries( m_spinDataRetries->value() );
0318 
0319         burnJob = job;
0320     }
0321     else if ( sourceMedium.diskInfo().mediaType() & K3b::Device::MEDIA_CD_ALL ) {
0322         K3b::CdCopyJob* job = new K3b::CdCopyJob( dlg, this );
0323 
0324         job->setWriterDevice( m_writerSelectionWidget->writerDevice() );
0325         job->setReaderDevice( m_comboSourceDevice->selectedDevice() );
0326         job->setSpeed( m_writerSelectionWidget->writerSpeed() );
0327         job->setSimulate( m_checkSimulate->isChecked() );
0328         job->setOnTheFly( !m_checkCacheImage->isChecked() );
0329         job->setKeepImage( !m_checkDeleteImages->isChecked() || m_checkOnlyCreateImage->isChecked() );
0330         job->setOnlyCreateImage( m_checkOnlyCreateImage->isChecked() );
0331         job->setTempPath( m_tempDirSelectionWidget->plainTempPath() );
0332         job->setCopies( m_checkSimulate->isChecked() ? 1 : m_spinCopies->value() );
0333         job->setParanoiaMode( m_comboParanoiaMode->currentText().toInt() );
0334         job->setDataReadRetries( m_spinDataRetries->value() );
0335         job->setAudioReadRetries( m_spinAudioRetries->value() );
0336         job->setCopyCdText( m_checkReadCdText->isChecked() );
0337         job->setIgnoreDataReadErrors( m_checkIgnoreDataReadErrors->isChecked() );
0338         job->setIgnoreAudioReadErrors( m_checkIgnoreAudioReadErrors->isChecked() );
0339         job->setNoCorrection( m_checkNoCorrection->isChecked() );
0340         job->setWritingMode( m_writingModeWidget->writingMode() );
0341 
0342         burnJob = job;
0343     }
0344     else if ( sourceMedium.diskInfo().mediaType() & ( K3b::Device::MEDIA_DVD_ALL|K3b::Device::MEDIA_BD_ALL ) ) {
0345         K3b::DvdCopyJob* job = new K3b::DvdCopyJob( dlg, this );
0346 
0347         job->setWriterDevice( m_writerSelectionWidget->writerDevice() );
0348         job->setReaderDevice( m_comboSourceDevice->selectedDevice() );
0349         job->setImagePath( m_tempDirSelectionWidget->tempPath() );
0350         job->setRemoveImageFiles( m_checkDeleteImages->isChecked() && !m_checkOnlyCreateImage->isChecked() );
0351         job->setOnlyCreateImage( m_checkOnlyCreateImage->isChecked() );
0352         job->setSimulate( m_checkSimulate->isChecked() );
0353         job->setOnTheFly( !m_checkCacheImage->isChecked() );
0354         job->setWriteSpeed( m_writerSelectionWidget->writerSpeed() );
0355         job->setCopies( m_checkSimulate->isChecked() ? 1 : m_spinCopies->value() );
0356         job->setWritingMode( m_writingModeWidget->writingMode() );
0357         job->setIgnoreReadErrors( m_checkIgnoreDataReadErrors->isChecked() );
0358         job->setReadRetries( m_spinDataRetries->value() );
0359         job->setVerifyData( m_checkVerifyData->isChecked() );
0360 
0361         burnJob = job;
0362     }
0363     else {
0364         // do not translate this as it is not intended to be included in the stable version!
0365         KMessageBox::error( this, "Ups", "No copy support for this source media type yet." );
0366         return;
0367     }
0368 
0369     hide();
0370 
0371     dlg->startJob( burnJob );
0372 
0373     delete burnJob;
0374 
0375     if( KConfigGroup( KSharedConfig::openConfig(), QStringLiteral("General Options") ).readEntry( "keep action dialogs open", false ) )
0376         show();
0377     else
0378         close();
0379 }
0380 
0381 
0382 void K3b::MediaCopyDialog::toggleAll()
0383 {
0384     updateOverrideDevice();
0385 
0386     K3b::Device::Device* readDev = m_comboSourceDevice->selectedDevice();
0387     K3b::Device::Device* burnDev = m_writerSelectionWidget->writerDevice();
0388     K3b::Medium sourceMedium = k3bappcore->mediaCache()->medium( readDev );
0389     K3b::Medium burnMedium = k3bappcore->mediaCache()->medium( burnDev );
0390 
0391     if ( burnDev ) {
0392         if( readDev != burnDev &&
0393             burnMedium.diskInfo().mediaType() & K3b::Device::MEDIA_DVD_PLUS_ALL ) {
0394             // no simulation support for DVD+R(W) media
0395             m_checkSimulate->setChecked(false);
0396             m_checkSimulate->setEnabled(false);
0397         }
0398         else {
0399             m_checkSimulate->setDisabled( m_checkOnlyCreateImage->isChecked() );
0400         }
0401     }
0402     else {
0403         m_checkSimulate->setEnabled( !m_checkOnlyCreateImage->isChecked() );
0404     }
0405 
0406     m_checkDeleteImages->setEnabled( !m_checkOnlyCreateImage->isChecked() && m_checkCacheImage->isChecked() );
0407     m_spinCopies->setDisabled( m_checkSimulate->isChecked() || m_checkOnlyCreateImage->isChecked() );
0408     m_tempDirSelectionWidget->setDisabled( !m_checkCacheImage->isChecked() && !m_checkOnlyCreateImage->isChecked() );
0409     m_writerSelectionWidget->setDisabled( m_checkOnlyCreateImage->isChecked() );
0410     m_checkCacheImage->setEnabled( !m_checkOnlyCreateImage->isChecked() );
0411     m_writingModeWidget->setEnabled( !m_checkOnlyCreateImage->isChecked() );
0412 
0413     // FIXME: no verification for CD yet
0414     m_checkVerifyData->setDisabled( sourceMedium.diskInfo().mediaType() & K3b::Device::MEDIA_CD_ALL ||
0415                                     sourceMedium.content() & K3b::Medium::ContentAudio ||
0416                                     m_checkSimulate->isChecked() );
0417 
0418     // we can only clone single session CDs
0419     if( K3b::Device::isCdMedia( sourceMedium.diskInfo().mediaType() ) ) {
0420         m_writerSelectionWidget->setWantedMediumType( K3b::Device::MEDIA_WRITABLE_CD );
0421         m_writerSelectionWidget->setSupportedWritingApps( K3b::WritingAppCdrecord );
0422 
0423         if ( sourceMedium.toc().sessions() == 1 ) {
0424             m_comboCopyMode->setEnabled( true );
0425         }
0426         else {
0427             m_comboCopyMode->setEnabled( false );
0428             m_comboCopyMode->setCurrentIndex( 0 );
0429         }
0430     }
0431     else {
0432         m_writerSelectionWidget->setSupportedWritingApps( K3b::WritingAppGrowisofs|K3b::WritingAppCdrecord );
0433 
0434         m_comboCopyMode->setEnabled( false );
0435         m_comboCopyMode->setCurrentIndex( 0 );
0436 
0437         // FIXME: at some point the media combo should also handle media sizes!
0438 
0439         if ( K3b::Device::isDvdMedia( sourceMedium.diskInfo().mediaType() ) ) {
0440             m_writerSelectionWidget->setWantedMediumType( sourceMedium.diskInfo().numLayers() > 1 &&
0441                                                           sourceMedium.diskInfo().size() > MediaSizeDvd4Gb
0442                                                           ? K3b::Device::MEDIA_WRITABLE_DVD_DL
0443                                                           : K3b::Device::MEDIA_WRITABLE_DVD );
0444         }
0445         else if( Device::isBdMedia( sourceMedium.diskInfo().mediaType() ) ) {
0446             // FIXME: do the same single layer/dual layer thing like with DVD
0447             m_writerSelectionWidget->setWantedMediumType( K3b::Device::MEDIA_WRITABLE_BD );
0448         }
0449         else {
0450             // generic media request in case we have no source medium
0451             m_writerSelectionWidget->setWantedMediumType( K3b::Device::MEDIA_WRITABLE );
0452         }
0453     }
0454 
0455     // CD Cloning
0456     if( m_comboCopyMode->currentIndex() == 1 ) {
0457         // cdrecord does not support cloning on-the-fly
0458         m_checkCacheImage->setChecked(true);
0459         m_checkCacheImage->setEnabled(false);
0460 
0461         m_writingModeWidget->setSupportedModes( K3b::WritingModeRaw );
0462     }
0463 
0464     // Normal CD/DVD/Blu-ray copy
0465     else {
0466         //
0467         // If the same device is used for reading and writing all we can present is a fuzzy
0468         // selection of the writing mode
0469         //
0470         if( burnDev == readDev ) {
0471             K3b::WritingModes modes = WritingModeAuto;
0472             if ( sourceMedium.diskInfo().mediaType() & K3b::Device::MEDIA_CD_ALL ) {
0473                 modes = K3b::WritingModeTao|K3b::WritingModeSao|K3b::WritingModeRaw;
0474             }
0475             else if ( sourceMedium.diskInfo().mediaType() & K3b::Device::MEDIA_DVD_ALL ) {
0476                 // only auto for DVD+R(W)
0477                 if (burnDev) {
0478                     if( burnDev->writeCapabilities() & (K3b::Device::MEDIA_DVD_R|K3b::Device::MEDIA_DVD_RW) ) {
0479                         modes |= K3b::WritingModeSao|K3b::WritingModeRestrictedOverwrite;
0480                         if( burnDev->featureCurrent( K3b::Device::FEATURE_INCREMENTAL_STREAMING_WRITABLE ) != 0 )
0481                             modes |= K3b::WritingModeIncrementalSequential;
0482                     }
0483 
0484                     // TODO: once we have layer jump support: this is where it goes
0485                     //if ( burnDev->supportsWritingMode( K3b::Device::WRITING_MODE_LAYER_JUMP ) )
0486                     //     modes |= K3b::Device::WRITING_MODE_LAYER_JUMP;
0487                 }
0488             }
0489             else if ( sourceMedium.diskInfo().mediaType() & K3b::Device::MEDIA_BD_ALL ) {
0490                 // no modes, only auto
0491             }
0492 
0493             m_writingModeWidget->setSupportedModes( modes );
0494         }
0495         else {
0496             m_writingModeWidget->determineSupportedModesFromMedium( burnDev );
0497         }
0498     }
0499 
0500     m_tempDirSelectionWidget->setNeededSize( neededSize() );
0501 
0502     if( sourceMedium.toc().contentType() == K3b::Device::DATA &&
0503         sourceMedium.toc().count() == 1 ) {
0504         m_tempDirSelectionWidget->setSelectionMode( K3b::TempDirSelectionWidget::FILE );
0505         QString mediumName = sourceMedium.volumeId().toLower();
0506         if ( mediumName.isEmpty() )
0507             mediumName = "k3bimage";
0508         m_tempDirSelectionWidget->setDefaultImageFileName( mediumName + QLatin1String(".iso"), true );
0509     }
0510     else {
0511         m_tempDirSelectionWidget->setSelectionMode( K3b::TempDirSelectionWidget::DIR );
0512 
0513         if ( sourceMedium.content() & K3b::Medium::ContentData && !sourceMedium.volumeId().isEmpty() ) {
0514             m_tempDirSelectionWidget->setTempPath( m_tempDirSelectionWidget->tempDirectory() + sourceMedium.volumeId().toLower() );
0515         }
0516         else if ( sourceMedium.content() & K3b::Medium::ContentAudio && !sourceMedium.cdText().title().isEmpty() ) {
0517             m_tempDirSelectionWidget->setTempPath( m_tempDirSelectionWidget->tempDirectory() + sourceMedium.cdText().title() );
0518         }
0519         else {
0520             m_tempDirSelectionWidget->setTempPath( m_tempDirSelectionWidget->tempDirectory() ); // let the copy job figure it out
0521         }
0522     }
0523 
0524     m_groupAdvancedAudioOptions->setEnabled( sourceMedium.content() & K3b::Medium::ContentAudio && m_comboCopyMode->currentIndex() == 0 );
0525     m_groupAdvancedDataOptions->setEnabled( sourceMedium.content() & K3b::Medium::ContentData );
0526 
0527     setButtonEnabled( START_BUTTON,
0528                       m_comboSourceDevice->selectedDevice() &&
0529                       (burnDev || m_checkOnlyCreateImage->isChecked()) );
0530 
0531     K3b::InteractionDialog::toggleAll();
0532 }
0533 
0534 
0535 void K3b::MediaCopyDialog::updateOverrideDevice()
0536 {
0537     if( !m_checkCacheImage->isChecked() ) {
0538         m_writerSelectionWidget->setOverrideDevice( 0 );
0539         m_writerSelectionWidget->setIgnoreDevice( m_comboSourceDevice->selectedDevice() );
0540     }
0541     else {
0542         m_writerSelectionWidget->setOverrideDevice( m_comboSourceDevice->selectedDevice(),
0543                                                     i18n("Use the same device for burning"),
0544                                                     i18n("<qt>Use the same device for burning <i>(Or insert another medium)</i>") );
0545         m_writerSelectionWidget->setIgnoreDevice( 0 );
0546     }
0547 }
0548 
0549 
0550 void K3b::MediaCopyDialog::loadSettings( const KConfigGroup& c )
0551 {
0552     m_writerSelectionWidget->loadConfig( c );
0553     m_comboSourceDevice->setSelectedDevice( k3bcore->deviceManager()->findDevice( c.readEntry( "source_device" ) ) );
0554     m_writingModeWidget->loadConfig( c );
0555     m_checkSimulate->setChecked( c.readEntry( "simulate", false ) );
0556     m_checkCacheImage->setChecked( !c.readEntry( "on_the_fly", false ) );
0557     m_checkDeleteImages->setChecked( c.readEntry( "delete_images", true ) );
0558     m_checkOnlyCreateImage->setChecked( c.readEntry( "only_create_image", false ) );
0559     m_comboParanoiaMode->setCurrentIndex( c.readEntry( "paranoia_mode", 0 ) );
0560     m_checkVerifyData->setChecked( c.readEntry( "verify data", false ) );
0561 
0562     m_spinCopies->setValue( c.readEntry( "copies", 1 ) );
0563 
0564     m_tempDirSelectionWidget->readConfig( c );
0565 
0566     if( c.readEntry( "copy mode", "normal" ) == "normal" )
0567         m_comboCopyMode->setCurrentIndex( 0 );
0568     else
0569         m_comboCopyMode->setCurrentIndex( 1 );
0570 
0571     m_checkReadCdText->setChecked( c.readEntry( "copy cdtext", true ) );
0572     m_checkIgnoreDataReadErrors->setChecked( c.readEntry( "ignore data read errors", false ) );
0573     m_checkIgnoreAudioReadErrors->setChecked( c.readEntry( "ignore audio read errors", true ) );
0574     m_checkNoCorrection->setChecked( c.readEntry( "no correction", false ) );
0575 
0576     m_spinDataRetries->setValue( c.readEntry( "data retries", 128 ) );
0577     m_spinAudioRetries->setValue( c.readEntry( "audio retries", 5 ) );
0578 
0579     slotToggleAll();
0580 }
0581 
0582 
0583 void K3b::MediaCopyDialog::saveSettings( KConfigGroup c )
0584 {
0585     m_writingModeWidget->saveConfig( c );
0586     c.writeEntry( "simulate", m_checkSimulate->isChecked() );
0587     c.writeEntry( "on_the_fly", !m_checkCacheImage->isChecked() );
0588     c.writeEntry( "delete_images", m_checkDeleteImages->isChecked() );
0589     c.writeEntry( "only_create_image", m_checkOnlyCreateImage->isChecked() );
0590     c.writeEntry( "paranoia_mode", m_comboParanoiaMode->currentText().toInt() );
0591     c.writeEntry( "copies", m_spinCopies->value() );
0592     c.writeEntry( "verify data", m_checkVerifyData->isChecked() );
0593 
0594     m_writerSelectionWidget->saveConfig( c );
0595     m_tempDirSelectionWidget->saveConfig( c );
0596 
0597     c.writeEntry( "source_device", m_comboSourceDevice->selectedDevice() ? m_comboSourceDevice->selectedDevice()->blockDeviceName() : QString() );
0598 
0599     c.writeEntry( "copy cdtext", m_checkReadCdText->isChecked() );
0600     c.writeEntry( "ignore data read errors", m_checkIgnoreDataReadErrors->isChecked() );
0601     c.writeEntry( "ignore audio read errors", m_checkIgnoreAudioReadErrors->isChecked() );
0602     c.writeEntry( "no correction", m_checkNoCorrection->isChecked() );
0603     c.writeEntry( "data retries", m_spinDataRetries->value() );
0604     c.writeEntry( "audio retries", m_spinAudioRetries->value() );
0605 
0606     QString s;
0607     if( m_comboCopyMode->currentIndex() == 1 )
0608         s = "clone";
0609     else
0610         s = "normal";
0611     c.writeEntry( "copy mode", s );
0612 }
0613 
0614 
0615 KIO::filesize_t K3b::MediaCopyDialog::neededSize() const
0616 {
0617     K3b::Medium medium = k3bappcore->mediaCache()->medium( m_comboSourceDevice->selectedDevice() );
0618 
0619     if( medium.diskInfo().diskState() == K3b::Device::STATE_NO_MEDIA )
0620         return 0;
0621     else if( medium.diskInfo().mediaType() & (K3b::Device::MEDIA_DVD_RW_OVWR|K3b::Device::MEDIA_DVD_PLUS_RW) )
0622         return (KIO::filesize_t)medium.iso9660Descriptor().volumeSpaceSize * (KIO::filesize_t)2048;
0623     else if ( m_comboCopyMode->currentIndex() == 0 )
0624         return medium.diskInfo().size().mode1Bytes();
0625     else
0626         return medium.diskInfo().size().rawBytes();
0627 }
0628 
0629 #include "moc_k3bmediacopydialog.cpp"