diff options
Diffstat (limited to 'src/misc')
-rw-r--r-- | src/misc/Makefile.am | 14 | ||||
-rw-r--r-- | src/misc/k3bblankingdialog.cpp | 343 | ||||
-rw-r--r-- | src/misc/k3bblankingdialog.h | 86 | ||||
-rw-r--r-- | src/misc/k3bcdcopydialog.cpp | 556 | ||||
-rw-r--r-- | src/misc/k3bcdcopydialog.h | 96 | ||||
-rw-r--r-- | src/misc/k3bcdimagewritingdialog.cpp | 1049 | ||||
-rw-r--r-- | src/misc/k3bcdimagewritingdialog.h | 116 | ||||
-rw-r--r-- | src/misc/k3bdvdcopydialog.cpp | 455 | ||||
-rw-r--r-- | src/misc/k3bdvdcopydialog.h | 79 | ||||
-rw-r--r-- | src/misc/k3bdvdformattingdialog.cpp | 185 | ||||
-rw-r--r-- | src/misc/k3bdvdformattingdialog.h | 55 | ||||
-rw-r--r-- | src/misc/k3bisoimagewritingdialog.cpp | 580 | ||||
-rw-r--r-- | src/misc/k3bisoimagewritingdialog.h | 90 |
13 files changed, 3704 insertions, 0 deletions
diff --git a/src/misc/Makefile.am b/src/misc/Makefile.am new file mode 100644 index 0000000..ea1809b --- /dev/null +++ b/src/misc/Makefile.am @@ -0,0 +1,14 @@ +AM_CPPFLAGS = -I$(srcdir)/../../libk3b/core \ + -I$(srcdir)/../../libk3bdevice \ + -I$(srcdir)/../../libk3b/tools \ + -I$(srcdir)/../../libk3b/jobs \ + -I$(srcdir)/../../libk3b/projects \ + -I$(srcdir)/.. \ + $(all_includes) + +METASOURCES = AUTO + +noinst_LTLIBRARIES = libmisc.la + +libmisc_la_SOURCES = k3bdvdformattingdialog.cpp k3bcdcopydialog.cpp k3bdvdcopydialog.cpp \ + k3bcdimagewritingdialog.cpp k3bisoimagewritingdialog.cpp k3bblankingdialog.cpp diff --git a/src/misc/k3bblankingdialog.cpp b/src/misc/k3bblankingdialog.cpp new file mode 100644 index 0000000..5f4b531 --- /dev/null +++ b/src/misc/k3bblankingdialog.cpp @@ -0,0 +1,343 @@ +/* + * + * $Id: k3bblankingdialog.cpp 689551 2007-07-18 14:53:32Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include "k3bblankingdialog.h" +#include "k3bdebuggingoutputdialog.h" +#include "k3bdebuggingoutputfile.h" + +#include <k3bdevice.h> +#include <k3bdevicemanager.h> +#include "k3bblankingjob.h" +#include "k3bwriterselectionwidget.h" +#include <k3bprogressdialog.h> +#include <k3bglobals.h> +#include <k3bcore.h> +#include <k3bemptydiscwaiter.h> + +#include <klocale.h> +#include <kmessagebox.h> +#include <klistview.h> +#include <kiconloader.h> +#include <kguiitem.h> +#include <kstdguiitem.h> +#include <kconfig.h> + +#include <qgroupbox.h> +#include <qpushbutton.h> +#include <qcheckbox.h> +#include <qlayout.h> +#include <qtextview.h> +#include <qcombobox.h> +#include <qlabel.h> +#include <qheader.h> +#include <qmap.h> +#include <qtooltip.h> +#include <qwhatsthis.h> + + + +class K3bBlankingDialog::Private +{ +public: + Private() + : job(0), + erasingDlg(0) { + } + + K3bBlankingJob* job; + K3bProgressDialog* erasingDlg; + K3bDebuggingOutputDialog* debugDialog; + K3bDebuggingOutputFile debugFile; + QMap<int, int> comboTypeMap; + QMap<int, int> typeComboMap; + + bool jobRunning; +}; + + +K3bBlankingDialog::K3bBlankingDialog( QWidget* parent, const char* name ) + : K3bInteractionDialog( parent, name, + i18n("Erase CD-RW"), + QString::null, + START_BUTTON|CANCEL_BUTTON, + START_BUTTON, + "CDRW Erasing" ) +{ + d = new Private(); + d->debugDialog = new K3bDebuggingOutputDialog( this ); + + setupGui(); + + connect( m_writerSelectionWidget, SIGNAL(writerChanged()), this, SLOT(slotWriterChanged()) ); + connect( m_writerSelectionWidget, SIGNAL(writingAppChanged(int)), this, SLOT(slotWritingAppChanged(int)) ); + slotWriterChanged(); + slotWritingAppChanged( m_writerSelectionWidget->writingApp() ); +} + + +K3bBlankingDialog::~K3bBlankingDialog() +{ + delete d; +} + + +void K3bBlankingDialog::setDevice( K3bDevice::Device* dev ) +{ + m_writerSelectionWidget->setWriterDevice( dev ); +} + + +void K3bBlankingDialog::setupGui() +{ + QWidget* frame = mainWidget(); + + m_writerSelectionWidget = new K3bWriterSelectionWidget( frame ); + m_writerSelectionWidget->setWantedMediumType( K3bDevice::MEDIA_CD_RW ); + m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_COMPLETE|K3bDevice::STATE_INCOMPLETE ); + + // --- setup the blanking type button group ----------------------------- + QGroupBox* groupBlankType = new QGroupBox( 1, Qt::Vertical, i18n("&Erase Type"), frame ); + groupBlankType->layout()->setSpacing( spacingHint() ); + groupBlankType->layout()->setMargin( marginHint() ); + + m_comboEraseMode = new QComboBox( groupBlankType ); + // ---------------------------------------------------------------------- + + QGridLayout* grid = new QGridLayout( frame ); + grid->setSpacing( spacingHint() ); + grid->setMargin( 0 ); + grid->addWidget( m_writerSelectionWidget, 0, 0 ); + grid->addWidget( groupBlankType, 1, 0 ); +} + + +void K3bBlankingDialog::slotStartClicked() +{ + // start the blankingjob and connect to the info-signal + // disable the user1 button and enable the cancel button + d->debugDialog->clear(); + d->debugFile.open(); + + if( d->job == 0 ) { + d->job = new K3bBlankingJob( this, this ); + connect( d->job, SIGNAL(debuggingOutput(const QString&, const QString&)), + d->debugDialog, SLOT(addOutput(const QString&, const QString&)) ); + connect( d->job, SIGNAL(debuggingOutput(const QString&, const QString&)), + &d->debugFile, SLOT(addOutput(const QString&, const QString&)) ); + connect( d->job, SIGNAL(finished(bool)), + this, SLOT(slotJobFinished(bool)) ); + } + + d->job->setDevice( m_writerSelectionWidget->writerDevice() ); + d->job->setSpeed( m_writerSelectionWidget->writerSpeed() ); + // why should one ever not want to force? + d->job->setForce( true ); + d->job->setWritingApp(m_writerSelectionWidget->writingApp()); + d->job->setMode( d->comboTypeMap[m_comboEraseMode->currentItem()] ); + + if( !d->erasingDlg ) + d->erasingDlg = new K3bProgressDialog( i18n("Erasing CD-RW"), this ); + + connect( d->erasingDlg, SIGNAL(cancelClicked()), d->job, SLOT(cancel()) ); + + if( !exitLoopOnHide() ) + hide(); + + d->jobRunning = true; + d->job->start(); + if( d->jobRunning ) // in case the job already finished in the start slot + d->erasingDlg->exec(false); + + if( KConfigGroup( k3bcore->config(), "General Options" ).readBoolEntry( "keep action dialogs open", false ) && + !exitLoopOnHide() ) + show(); + else + close(); +} + + +void K3bBlankingDialog::slotJobFinished( bool success ) +{ + d->jobRunning = false; + d->erasingDlg->hide(); + d->debugFile.close(); + + if( success ) + KMessageBox::information( this, + i18n("Successfully erased CD-RW."), + i18n("Success") ); + else if( d->job->hasBeenCanceled() ) + KMessageBox::information( this, + i18n("Erasing CD-RW canceled."), + i18n("Canceled") ); + else if( KMessageBox::warningYesNo( this, + i18n("The Erasing process failed. Do you want to see the debugging output?"), + i18n("Erasing failed.") ) == KMessageBox::Yes ) + d->debugDialog->exec(); +} + + +void K3bBlankingDialog::slotWriterChanged() +{ + // check if it is a cdrw writer + K3bDevice::Device* dev = m_writerSelectionWidget->writerDevice(); + + if( !dev ) + setButtonEnabled( START_BUTTON, false ); + else if( dev->writesCdrw() ) + setButtonEnabled( START_BUTTON, true ); + else { + setButtonEnabled( START_BUTTON, false ); + KMessageBox::sorry( this, i18n("%1 does not support CD-RW writing.").arg(dev->devicename()) ); + } +} + +void K3bBlankingDialog::slotWritingAppChanged(int app) +{ + QWhatsThis::remove( m_comboEraseMode ); + QString whatsThisInfo; + + static QString wsComplete = i18n("Erases the complete disk. This takes as long " + "as writing the complete CD."); + static QString wsFast = i18n("Erases just the TOC, the PMA, and the pregap."); + static QString wsTrack = i18n("Erases just the last track."); + static QString wsUnclose = i18n("Reopen the last session to make it possible to append " + "further data."); + static QString wsSession = i18n("Erases the last session of a multisession CD."); + + int lastMode = d->comboTypeMap[m_comboEraseMode->currentItem()]; + + m_comboEraseMode->clear(); + d->comboTypeMap.clear(); + d->typeComboMap.clear(); + + m_comboEraseMode->insertItem( i18n("Fast") ); + d->comboTypeMap[0] = K3bBlankingJob::Fast; + d->typeComboMap[K3bBlankingJob::Fast] = 0; + m_comboEraseMode->insertItem( i18n("Complete") ); + d->comboTypeMap[1] = K3bBlankingJob::Complete; + d->typeComboMap[K3bBlankingJob::Complete] = 1; + + whatsThisInfo = "<p>" + i18n("Blanking mode:") + + "<p><b>" + i18n("Fast") + "</b><br>" + wsFast; + whatsThisInfo += "<p><b>" + i18n("Complete") + "</b><br>" + wsComplete; + + if ( app != K3b::CDRDAO ) { + m_comboEraseMode->insertItem( i18n("Erase Last Track") ); + d->comboTypeMap[2] = K3bBlankingJob::Track; + d->typeComboMap[K3bBlankingJob::Track] = 2; + whatsThisInfo += "<p><b>" + i18n("Erase Last Track") + "</b><br>" + wsTrack; + m_comboEraseMode->insertItem( i18n("Reopen Last Session") ); + d->comboTypeMap[3] = K3bBlankingJob::Unclose; + d->typeComboMap[K3bBlankingJob::Unclose] = 3; + whatsThisInfo += "<p><b>" + i18n("Reopen Last Session") + "</b><br>" + wsUnclose; + m_comboEraseMode->insertItem( i18n("Erase Last Session") ); + d->comboTypeMap[4] = K3bBlankingJob::Session; + d->typeComboMap[K3bBlankingJob::Session] = 4; + whatsThisInfo += "<p><b>" + i18n("Erase Last Session") + "</b><br>" + wsSession; + } + + QWhatsThis::add( m_comboEraseMode, whatsThisInfo ); + + // try to reset last mode + if( d->typeComboMap.contains( lastMode ) ) + m_comboEraseMode->setCurrentItem( d->typeComboMap[lastMode] ); + else + m_comboEraseMode->setCurrentItem( d->typeComboMap[K3bBlankingJob::Fast] ); +} + + +void K3bBlankingDialog::loadK3bDefaults() +{ + m_writerSelectionWidget->loadDefaults(); + m_comboEraseMode->setCurrentItem( d->typeComboMap[K3bBlankingJob::Fast] ); +} + +void K3bBlankingDialog::loadUserDefaults( KConfigBase* c ) +{ + m_writerSelectionWidget->loadConfig( c ); + slotWritingAppChanged( m_writerSelectionWidget->writingApp() ); + + QString mode = c->readEntry( "erase_mode" ); + kdDebug() << "(K3bBlankingDialog) slotWritingAppChanged mode: " << mode << endl; + m_comboEraseMode->setCurrentItem( d->typeComboMap[K3bBlankingJob::Fast] ); + if( mode == "complete" ) + m_comboEraseMode->setCurrentItem( d->typeComboMap[K3bBlankingJob::Complete] ); + else if( d->typeComboMap.size() > 2 ) { + if( mode == "session" ) + m_comboEraseMode->setCurrentItem( d->typeComboMap[K3bBlankingJob::Session] ); + else if( mode == "track" ) + m_comboEraseMode->setCurrentItem( d->typeComboMap[K3bBlankingJob::Track] ); + else if( mode == "unclose_session" ) + m_comboEraseMode->setCurrentItem( d->typeComboMap[K3bBlankingJob::Unclose] ); + } +} + +void K3bBlankingDialog::saveUserDefaults( KConfigBase* c ) +{ + QString mode; + switch( d->comboTypeMap[m_comboEraseMode->currentItem()] ) { + case K3bBlankingJob::Complete: + mode = "complete"; + break; + case K3bBlankingJob::Session: + mode = "session"; + break; + case K3bBlankingJob::Track: + mode = "track"; + break; + case K3bBlankingJob::Unclose: + mode = "unclose_session"; + break; + default: + mode = "fast"; + break; + } + c->writeEntry( "erase_mode", mode ); + + m_writerSelectionWidget->saveConfig( c ); +} + + +int K3bBlankingDialog::waitForMedia( K3bDevice::Device* device, + int mediaState, + int mediaType, + const QString& message ) +{ + // this is only needed for the formatting + return K3bEmptyDiscWaiter::wait( device, mediaState, mediaType, message, this ); +} + + +bool K3bBlankingDialog::questionYesNo( const QString& text, + const QString& caption, + const QString& yesText, + const QString& noText ) +{ + return ( KMessageBox::questionYesNo( this, + text, + caption, + yesText.isEmpty() ? KStdGuiItem::yes() : KGuiItem(yesText), + noText.isEmpty() ? KStdGuiItem::no() : KGuiItem(noText) ) == KMessageBox::Yes ); +} + + +void K3bBlankingDialog::blockingInformation( const QString& text, + const QString& caption ) +{ + KMessageBox::information( this, text, caption ); +} + +#include "k3bblankingdialog.moc" diff --git a/src/misc/k3bblankingdialog.h b/src/misc/k3bblankingdialog.h new file mode 100644 index 0000000..cbd5583 --- /dev/null +++ b/src/misc/k3bblankingdialog.h @@ -0,0 +1,86 @@ +/* + * + * $Id: k3bblankingdialog.h 619556 2007-01-03 17:38:12Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + + +#ifndef K3B_BLANKING_DIALOG_H +#define K3B_BLANKING_DIALOG_H + +#include "k3binteractiondialog.h" +#include <k3bjobhandler.h> + +class QGroupBox; +class QComboBox; +class QCloseEvent; +class KListView; +class K3bWriterSelectionWidget; +namespace K3bDevice { + class Device; +} + + +class K3bBlankingDialog : public K3bInteractionDialog, public K3bJobHandler +{ +Q_OBJECT + + public: + K3bBlankingDialog( QWidget*, const char* ); + ~K3bBlankingDialog(); + + /** + * @reimplemented from K3bJobHandler + */ + int waitForMedia( K3bDevice::Device*, + int mediaState = K3bDevice::STATE_EMPTY, + int mediaType = K3bDevice::MEDIA_WRITABLE_CD, + const QString& message = QString::null ); + + /** + * @reimplemented from K3bJobHandler + */ + bool questionYesNo( const QString& text, + const QString& caption = QString::null, + const QString& yesText = QString::null, + const QString& noText = QString::null ); + + /** + * reimplemented from K3bJobHandler + */ + void blockingInformation( const QString& text, + const QString& caption = QString::null ); + + public slots: + void setDevice( K3bDevice::Device* ); + + protected slots: + void slotStartClicked(); + void slotWriterChanged(); + void slotWritingAppChanged( int ); + void slotJobFinished( bool ); + + private: + void setupGui(); + void loadK3bDefaults(); + void loadUserDefaults( KConfigBase* ); + void saveUserDefaults( KConfigBase* ); + + K3bWriterSelectionWidget* m_writerSelectionWidget; + + QComboBox* m_comboEraseMode; + + class Private; + Private* d; +}; + +#endif diff --git a/src/misc/k3bcdcopydialog.cpp b/src/misc/k3bcdcopydialog.cpp new file mode 100644 index 0000000..4f1ce3b --- /dev/null +++ b/src/misc/k3bcdcopydialog.cpp @@ -0,0 +1,556 @@ +/* + * + * $Id: k3bcdcopydialog.cpp 733470 2007-11-06 12:10:29Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * Klaus-Dieter Krannich <kd@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + + +#include "k3bcdcopydialog.h" + +#include "k3bmediaselectioncombobox.h" +#include "k3bcdcopyjob.h" +#include "k3bclonejob.h" + +#include <k3bwriterselectionwidget.h> +#include <k3btempdirselectionwidget.h> +#include <k3bcore.h> +#include <k3bstdguiitems.h> +#include <k3bdevice.h> +#include <k3bdevicemanager.h> +#include <k3bburnprogressdialog.h> +#include <k3bglobals.h> +#include <k3bexternalbinmanager.h> +#include <k3bthememanager.h> +#include <k3bwritingmodewidget.h> +#include <k3bapplication.h> +#include <k3bmediacache.h> + +#include <kguiitem.h> +#include <klocale.h> +#include <kstdguiitem.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> +#include <kconfig.h> +#include <kapplication.h> +#include <kiconloader.h> + +#include <qcheckbox.h> +#include <qspinbox.h> +#include <qcombobox.h> +#include <qlayout.h> +#include <qgroupbox.h> +#include <qptrlist.h> +#include <qlabel.h> +#include <qtooltip.h> +#include <qtabwidget.h> +#include <qwhatsthis.h> +#include <qhbox.h> +#include <qpushbutton.h> +#include <qbuttongroup.h> +#include <qradiobutton.h> +#include <qsizepolicy.h> +#include <qfile.h> +#include <qfileinfo.h> + + +K3bCdCopyDialog::K3bCdCopyDialog( QWidget *parent, const char *name, bool modal ) + : K3bInteractionDialog( parent, name, i18n("CD Copy"), i18n("and CD Cloning"), + START_BUTTON|CANCEL_BUTTON, + START_BUTTON, + "CD Copy", + modal ) +{ + QWidget* main = mainWidget(); + + QGridLayout* mainGrid = new QGridLayout( main ); + mainGrid->setSpacing( spacingHint() ); + mainGrid->setMargin( 0 ); + + QGroupBox* groupSource = new QGroupBox( 1, Qt::Vertical, i18n("Source Medium"), main ); + groupSource->setInsideSpacing( spacingHint() ); + groupSource->setInsideMargin( marginHint() ); + m_comboSourceDevice = new K3bMediaSelectionComboBox( groupSource ); + m_comboSourceDevice->setWantedMediumType( K3bDevice::MEDIA_WRITABLE_CD|K3bDevice::MEDIA_CD_ROM ); + m_comboSourceDevice->setWantedMediumState( K3bDevice::STATE_COMPLETE|K3bDevice::STATE_INCOMPLETE ); + + m_writerSelectionWidget = new K3bWriterSelectionWidget( main ); + m_writerSelectionWidget->setWantedMediumType( K3bDevice::MEDIA_WRITABLE_CD ); + m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_EMPTY ); + m_writerSelectionWidget->setSupportedWritingApps( K3b::CDRECORD ); + + // tab widget -------------------- + QTabWidget* tabWidget = new QTabWidget( main ); + + // + // option tab -------------------- + // + QWidget* optionTab = new QWidget( tabWidget ); + QGridLayout* optionTabGrid = new QGridLayout( optionTab ); + optionTabGrid->setSpacing( spacingHint() ); + optionTabGrid->setMargin( marginHint() ); + + QGroupBox* groupCopyMode = new QGroupBox( 1, Qt::Vertical, i18n("Copy Mode"), optionTab ); + groupCopyMode->setInsideMargin( marginHint() ); + groupCopyMode->setInsideSpacing( spacingHint() ); + m_comboCopyMode = new QComboBox( groupCopyMode ); + m_comboCopyMode->insertItem( i18n("Normal Copy") ); + m_comboCopyMode->insertItem( i18n("Clone Copy") ); + + QGroupBox* groupWritingMode = new QGroupBox( 1, Qt::Vertical, i18n("Writing Mode"), optionTab ); + groupWritingMode->setInsideMargin( marginHint() ); + m_writingModeWidget = new K3bWritingModeWidget( groupWritingMode ); + + QGroupBox* groupCopies = new QGroupBox( 2, Qt::Horizontal, i18n("Copies"), optionTab ); + groupCopies->setInsideSpacing( spacingHint() ); + groupCopies->setInsideMargin( marginHint() ); + QLabel* pixLabel = new QLabel( groupCopies ); + pixLabel->setPixmap( SmallIcon( "cdcopy", KIcon::SizeMedium ) ); + pixLabel->setScaledContents( false ); + m_spinCopies = new QSpinBox( 1, 999, 1, groupCopies ); + + QGroupBox* groupOptions = new QGroupBox( 5, Qt::Vertical, i18n("Settings"), optionTab ); + groupOptions->setInsideSpacing( spacingHint() ); + groupOptions->setInsideMargin( marginHint() ); + m_checkSimulate = K3bStdGuiItems::simulateCheckbox( groupOptions ); + m_checkCacheImage = K3bStdGuiItems::createCacheImageCheckbox( groupOptions ); + m_checkOnlyCreateImage = K3bStdGuiItems::onlyCreateImagesCheckbox( groupOptions ); + m_checkDeleteImages = K3bStdGuiItems::removeImagesCheckbox( groupOptions ); + + optionTabGrid->addWidget( groupCopyMode, 0, 0 ); + optionTabGrid->addWidget( groupWritingMode, 1, 0 ); + optionTabGrid->addMultiCellWidget( groupOptions, 0, 2, 1, 1 ); + optionTabGrid->addWidget( groupCopies, 2, 0 ); + optionTabGrid->setRowStretch( 2, 1 ); + optionTabGrid->setColStretch( 1, 1 ); + + tabWidget->addTab( optionTab, i18n("&Options") ); + + + // + // image tab ------------------ + // + QWidget* imageTab = new QWidget( tabWidget ); + QGridLayout* imageTabGrid = new QGridLayout( imageTab ); + imageTabGrid->setSpacing( spacingHint() ); + imageTabGrid->setMargin( marginHint() ); + + m_tempDirSelectionWidget = new K3bTempDirSelectionWidget( imageTab ); + + imageTabGrid->addWidget( m_tempDirSelectionWidget, 0, 0 ); + + tabWidget->addTab( imageTab, i18n("&Image") ); + + + // + // advanced tab ------------------ + // + QWidget* advancedTab = new QWidget( tabWidget ); + QGridLayout* advancedTabGrid = new QGridLayout( advancedTab ); + advancedTabGrid->setSpacing( spacingHint() ); + advancedTabGrid->setMargin( marginHint() ); + + m_groupAdvancedDataOptions = new QGroupBox( 3, Qt::Vertical, i18n("Data"), advancedTab, "data_options" ); + m_groupAdvancedDataOptions->setInsideSpacing( spacingHint() ); + m_groupAdvancedDataOptions->setInsideMargin( marginHint() ); + QHBox* box = new QHBox( m_groupAdvancedDataOptions ); + box->setSpacing( spacingHint() ); + box->setStretchFactor( new QLabel( i18n("Read retries:"), box ), 1 ); + m_spinDataRetries = new QSpinBox( 1, 128, 1, box ); + m_checkIgnoreDataReadErrors = K3bStdGuiItems::ignoreAudioReadErrorsCheckBox( m_groupAdvancedDataOptions ); + m_checkNoCorrection = new QCheckBox( i18n("No error correction"), m_groupAdvancedDataOptions ); + + m_groupAdvancedAudioOptions = new QGroupBox( 5, Qt::Vertical, i18n("Audio"), advancedTab, "audio_options" ); + m_groupAdvancedAudioOptions->setInsideSpacing( spacingHint() ); + m_groupAdvancedAudioOptions->setInsideMargin( marginHint() ); + box = new QHBox( m_groupAdvancedAudioOptions ); + box->setSpacing( spacingHint() ); + box->setStretchFactor( new QLabel( i18n("Read retries:"), box ), 1 ); + m_spinAudioRetries = new QSpinBox( 1, 128, 1, box ); + m_checkIgnoreAudioReadErrors = K3bStdGuiItems::ignoreAudioReadErrorsCheckBox( m_groupAdvancedAudioOptions ); + box = new QHBox( m_groupAdvancedAudioOptions ); + box->setSpacing( spacingHint() ); + box->setStretchFactor(new QLabel( i18n("Paranoia mode:"), box ), 1 ); + m_comboParanoiaMode = K3bStdGuiItems::paranoiaModeComboBox( box ); + m_checkReadCdText = new QCheckBox( i18n("Copy CD-Text"), m_groupAdvancedAudioOptions ); + m_checkPrefereCdText = new QCheckBox( i18n("Prefer CD-Text"), m_groupAdvancedAudioOptions ); + + advancedTabGrid->addWidget( m_groupAdvancedDataOptions, 0, 1 ); + advancedTabGrid->addWidget( m_groupAdvancedAudioOptions, 0, 0 ); + + tabWidget->addTab( advancedTab, i18n("&Advanced") ); + + mainGrid->addWidget( groupSource, 0, 0 ); + mainGrid->addWidget( m_writerSelectionWidget, 1, 0 ); + mainGrid->addWidget( tabWidget, 2, 0 ); + mainGrid->setRowStretch( 2, 1 ); + + + connect( m_comboSourceDevice, SIGNAL(selectionChanged(K3bDevice::Device*)), this, SLOT(slotToggleAll()) ); + connect( m_comboSourceDevice, SIGNAL(selectionChanged(K3bDevice::Device*)), + this, SLOT(slotSourceMediumChanged(K3bDevice::Device*)) ); + connect( m_writerSelectionWidget, SIGNAL(writerChanged()), this, SLOT(slotToggleAll()) ); + connect( m_writerSelectionWidget, SIGNAL(writerChanged(K3bDevice::Device*)), + m_writingModeWidget, SLOT(setDevice(K3bDevice::Device*)) ); + connect( m_writingModeWidget, SIGNAL(writingModeChanged(int)), this, SLOT(slotToggleAll()) ); + connect( m_checkCacheImage, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) ); + connect( m_checkSimulate, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) ); + connect( m_checkOnlyCreateImage, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) ); + connect( m_comboCopyMode, SIGNAL(activated(int)), this, SLOT(slotToggleAll()) ); + connect( m_checkReadCdText, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) ); + + QToolTip::add( m_checkIgnoreDataReadErrors, i18n("Skip unreadable data sectors") ); + QToolTip::add( m_checkNoCorrection, i18n("Disable the source drive's error correction") ); + QToolTip::add( m_checkPrefereCdText, i18n("Use CD-Text instead of cddb if available.") ); + QToolTip::add( m_checkReadCdText, i18n("Copy CD-Text from the source CD if available.") ); + + QWhatsThis::add( m_checkNoCorrection, i18n("<p>If this option is checked K3b will disable the " + "source drive's ECC/EDC error correction. This way sectors " + "that are unreadable by intention can be read." + "<p>This may be useful for cloning CDs with copy " + "protection based on corrupted sectors.") ); + QWhatsThis::add( m_checkReadCdText, i18n("<p>If this option is checked K3b will search for CD-Text on the source CD. " + "Disable it if your CD drive has problems with reading CD-Text or you want " + "to stick to Cddb info.") ); + QWhatsThis::add( m_checkPrefereCdText, i18n("<p>If this option is checked and K3b finds CD-Text on the source media it will be " + "copied to the resulting CD ignoring any potentially existing Cddb entries.") ); + QWhatsThis::add( m_checkIgnoreDataReadErrors, i18n("<p>If this option is checked and K3b is not able to read a data sector from the " + "source CD/DVD it will be replaced with zeros on the resulting copy.") ); + + QWhatsThis::add( m_comboCopyMode, + "<p><b>" + i18n("Normal Copy") + "</b>" + + i18n("<p>This is the normal copy mode recommended for most CD types. " + "It allows copying Audio CDs, multi and single session Data CDs, and " + "Enhanced Audio CDs (an Audio CD containing an additional data session)." + "<p>For VideoCDs please use the CD Cloning mode.") + + "<p><b>" + i18n("Clone Copy") + "</b>" + + i18n("<p>In CD Cloning mode K3b performs a raw copy of the CD. That means it does " + "not care about the content but simply copies the CD bit by bit. It may be used " + "to copy VideoCDs or CDs which contain erroneous sectors." + "<p><b>Caution:</b> Only single session CDs can be cloned.") ); +} + + +K3bCdCopyDialog::~K3bCdCopyDialog() +{ +} + + +void K3bCdCopyDialog::init() +{ + slotSourceMediumChanged( m_comboSourceDevice->selectedDevice() ); +} + + +void K3bCdCopyDialog::setReadingDevice( K3bDevice::Device* dev ) +{ + m_comboSourceDevice->setSelectedDevice( dev ); +} + + +K3bDevice::Device* K3bCdCopyDialog::readingDevice() const +{ + return m_comboSourceDevice->selectedDevice(); +} + + +void K3bCdCopyDialog::slotStartClicked() +{ + // + // Let's check the available size + // + if( m_checkCacheImage->isChecked() || m_checkOnlyCreateImage->isChecked() ) { + if( neededSize()/1024 > m_tempDirSelectionWidget->freeTempSpace() ) { + if( KMessageBox::warningContinueCancel( this, i18n("There seems to be not enough free space in temporary directory. " + "Write anyway?") ) == KMessageBox::Cancel ) + return; + } + } + + + K3bJobProgressDialog* dlg = 0; + if( m_checkOnlyCreateImage->isChecked() ) { + dlg = new K3bJobProgressDialog( kapp->mainWidget() ); + } + else { + dlg = new K3bBurnProgressDialog( kapp->mainWidget() ); + } + + K3bBurnJob* burnJob = 0; + + if( m_comboCopyMode->currentItem() == 1 ) { + + // + // check for m_tempDirSelectionWidget->tempPath() and + // m_tempDirSelectionWidget-tempPath() + ".toc" + // + if( QFileInfo( m_tempDirSelectionWidget->tempPath() ).isFile() ) { + if( KMessageBox::warningContinueCancel( this, + i18n("Do you want to overwrite %1?").arg(m_tempDirSelectionWidget->tempPath()), + i18n("File Exists"), i18n("Overwrite") ) + != KMessageBox::Continue ) + return; + } + + if( QFileInfo( m_tempDirSelectionWidget->tempPath() + ".toc" ).isFile() ) { + if( KMessageBox::warningContinueCancel( this, + i18n("Do you want to overwrite %1?").arg(m_tempDirSelectionWidget->tempPath() + ".toc"), + i18n("File Exists"), i18n("Overwrite") ) + != KMessageBox::Continue ) + return; + } + + K3bCloneJob* job = new K3bCloneJob( dlg, this ); + + job->setWriterDevice( m_writerSelectionWidget->writerDevice() ); + job->setReaderDevice( m_comboSourceDevice->selectedDevice() ); + job->setImagePath( m_tempDirSelectionWidget->tempPath() ); + job->setNoCorrection( m_checkNoCorrection->isChecked() ); + job->setRemoveImageFiles( m_checkDeleteImages->isChecked() && !m_checkOnlyCreateImage->isChecked() ); + job->setOnlyCreateImage( m_checkOnlyCreateImage->isChecked() ); + job->setSimulate( m_checkSimulate->isChecked() ); + job->setWriteSpeed( m_writerSelectionWidget->writerSpeed() ); + job->setCopies( m_checkSimulate->isChecked() ? 1 : m_spinCopies->value() ); + job->setReadRetries( m_spinDataRetries->value() ); + + burnJob = job; + } + else { + K3bCdCopyJob* job = new K3bCdCopyJob( dlg, this ); + + job->setWriterDevice( m_writerSelectionWidget->writerDevice() ); + job->setReaderDevice( m_comboSourceDevice->selectedDevice() ); + job->setSpeed( m_writerSelectionWidget->writerSpeed() ); + job->setSimulate( m_checkSimulate->isChecked() ); + job->setOnTheFly( !m_checkCacheImage->isChecked() ); + job->setKeepImage( !m_checkDeleteImages->isChecked() || m_checkOnlyCreateImage->isChecked() ); + job->setOnlyCreateImage( m_checkOnlyCreateImage->isChecked() ); + job->setTempPath( m_tempDirSelectionWidget->plainTempPath() ); + job->setCopies( m_checkSimulate->isChecked() ? 1 : m_spinCopies->value() ); + job->setParanoiaMode( m_comboParanoiaMode->currentText().toInt() ); + job->setDataReadRetries( m_spinDataRetries->value() ); + job->setAudioReadRetries( m_spinAudioRetries->value() ); + job->setCopyCdText( m_checkReadCdText->isChecked() ); + job->setPreferCdText( m_checkPrefereCdText->isChecked() ); + job->setIgnoreDataReadErrors( m_checkIgnoreDataReadErrors->isChecked() ); + job->setIgnoreAudioReadErrors( m_checkIgnoreAudioReadErrors->isChecked() ); + job->setNoCorrection( m_checkNoCorrection->isChecked() ); + job->setWritingMode( m_writingModeWidget->writingMode() ); + + burnJob = job; + } + + if( !exitLoopOnHide() ) + hide(); + + dlg->startJob( burnJob ); + + delete dlg; + delete burnJob; + + if( KConfigGroup( k3bcore->config(), "General Options" ).readBoolEntry( "keep action dialogs open", false ) && + !exitLoopOnHide() ) + show(); + else + close(); +} + + +void K3bCdCopyDialog::toggleAll() +{ + updateOverrideDevice(); + + K3bDevice::Device* dev = m_writerSelectionWidget->writerDevice(); + + m_checkSimulate->setEnabled( !m_checkOnlyCreateImage->isChecked() ); + m_checkDeleteImages->setEnabled( !m_checkOnlyCreateImage->isChecked() && m_checkCacheImage->isChecked() ); + m_spinCopies->setDisabled( m_checkSimulate->isChecked() || m_checkOnlyCreateImage->isChecked() ); + m_tempDirSelectionWidget->setDisabled( !m_checkCacheImage->isChecked() ); + m_checkOnlyCreateImage->setEnabled( m_checkCacheImage->isChecked() ); + m_writerSelectionWidget->setDisabled( m_checkOnlyCreateImage->isChecked() ); + m_checkCacheImage->setEnabled( !m_checkOnlyCreateImage->isChecked() ); + + if( m_comboCopyMode->currentItem() == 1 ) { + // cdrecord does not support cloning on-the-fly + m_checkCacheImage->setChecked(true); + m_checkCacheImage->setEnabled(false); + + m_writingModeWidget->setSupportedModes( K3b::RAW ); + } + else { + m_writingModeWidget->setSupportedModes( K3b::TAO|K3b::DAO|K3b::RAW ); + } + + + + static_cast<QWidget*>( child( "audio_options" ) )->setDisabled( m_comboCopyMode->currentItem() == 1 ); + + m_checkIgnoreDataReadErrors->setDisabled( m_comboCopyMode->currentItem() == 1 ); + + m_groupAdvancedAudioOptions->setEnabled( k3bappcore->mediaCache()->medium( m_comboSourceDevice->selectedDevice() ).content() & K3bMedium::CONTENT_AUDIO && + m_comboCopyMode->currentItem() == 0 ); + + m_writingModeWidget->setEnabled( !m_checkOnlyCreateImage->isChecked() ); + + m_tempDirSelectionWidget->setNeededSize( neededSize() ); + + setButtonEnabled( START_BUTTON, m_comboSourceDevice->selectedDevice() && + (dev || m_checkOnlyCreateImage->isChecked()) ); +} + + +void K3bCdCopyDialog::slotSourceMediumChanged( K3bDevice::Device* dev ) +{ + updateOverrideDevice(); + + K3bMedium medium = k3bappcore->mediaCache()->medium( dev ); + + m_tempDirSelectionWidget->setNeededSize( neededSize() ); + + if( k3bappcore->mediaCache()->toc( dev ).contentType() == K3bDevice::DATA ) { + m_tempDirSelectionWidget->setSelectionMode( K3bTempDirSelectionWidget::FILE ); + m_tempDirSelectionWidget->setDefaultImageFileName( medium.volumeId().lower() + + ( medium.toc().count() == 1 ? QString(".iso") : QString::null ) ); + } + else { + m_tempDirSelectionWidget->setSelectionMode( K3bTempDirSelectionWidget::DIR ); + } + + m_groupAdvancedAudioOptions->setEnabled( k3bappcore->mediaCache()->medium( dev ).content() & K3bMedium::CONTENT_AUDIO ); + m_groupAdvancedDataOptions->setEnabled( k3bappcore->mediaCache()->medium( dev ).content() & K3bMedium::CONTENT_DATA ); + + // we can only clone single session CDs + if( k3bappcore->mediaCache()->toc( dev ).sessions() > 1 ) { + m_comboCopyMode->setEnabled( false ); + m_comboCopyMode->setCurrentItem( 0 ); + } + else { + m_comboCopyMode->setEnabled( true ); + } + + toggleAll(); +} + + +void K3bCdCopyDialog::updateOverrideDevice() +{ + if( !m_checkCacheImage->isChecked() ) { + m_writerSelectionWidget->setOverrideDevice( 0 ); + m_writerSelectionWidget->setIgnoreDevice( m_comboSourceDevice->selectedDevice() ); + } + else { + m_writerSelectionWidget->setIgnoreDevice( 0 ); + m_writerSelectionWidget->setOverrideDevice( m_comboSourceDevice->selectedDevice(), + i18n("Use the same device for burning"), + i18n("<qt>Use the same device for burning <i>(Or insert another medium)</i>") ); + } +} + + +void K3bCdCopyDialog::loadUserDefaults( KConfigBase* c ) +{ + m_writerSelectionWidget->loadConfig( c ); + m_comboSourceDevice->setSelectedDevice( k3bcore->deviceManager()->findDevice( c->readEntry( "source_device" ) ) ); + m_writingModeWidget->loadConfig( c ); + m_checkSimulate->setChecked( c->readBoolEntry( "simulate", false ) ); + m_checkCacheImage->setChecked( !c->readBoolEntry( "on_the_fly", false ) ); + m_checkDeleteImages->setChecked( c->readBoolEntry( "delete_images", true ) ); + m_checkOnlyCreateImage->setChecked( c->readBoolEntry( "only_create_image", false ) ); + m_comboParanoiaMode->setCurrentItem( c->readNumEntry( "paranoia_mode", 0 ) ); + + m_spinCopies->setValue( c->readNumEntry( "copies", 1 ) ); + + m_tempDirSelectionWidget->readConfig( c ); + + if( c->readEntry( "copy mode", "normal" ) == "normal" ) + m_comboCopyMode->setCurrentItem( 0 ); + else + m_comboCopyMode->setCurrentItem( 1 ); + + m_checkReadCdText->setChecked( c->readBoolEntry( "copy cdtext", true ) ); + m_checkPrefereCdText->setChecked( c->readBoolEntry( "prefer cdtext", false ) ); + m_checkIgnoreDataReadErrors->setChecked( c->readBoolEntry( "ignore data read errors", false ) ); + m_checkIgnoreAudioReadErrors->setChecked( c->readBoolEntry( "ignore audio read errors", true ) ); + m_checkNoCorrection->setChecked( c->readBoolEntry( "no correction", false ) ); + + m_spinDataRetries->setValue( c->readNumEntry( "data retries", 128 ) ); + m_spinAudioRetries->setValue( c->readNumEntry( "audio retries", 5 ) ); + + slotToggleAll(); +} + + +void K3bCdCopyDialog::saveUserDefaults( KConfigBase* c ) +{ + m_writingModeWidget->saveConfig( c ); + c->writeEntry( "simulate", m_checkSimulate->isChecked() ); + c->writeEntry( "on_the_fly", !m_checkCacheImage->isChecked() ); + c->writeEntry( "delete_images", m_checkDeleteImages->isChecked() ); + c->writeEntry( "only_create_image", m_checkOnlyCreateImage->isChecked() ); + c->writeEntry( "paranoia_mode", m_comboParanoiaMode->currentText().toInt() ); + c->writeEntry( "copies", m_spinCopies->value() ); + + m_writerSelectionWidget->saveConfig( c ); + m_tempDirSelectionWidget->saveConfig( c ); + + c->writeEntry( "source_device", m_comboSourceDevice->selectedDevice() ? m_comboSourceDevice->selectedDevice()->devicename() : QString() ); + + c->writeEntry( "copy cdtext", m_checkReadCdText->isChecked() ); + c->writeEntry( "prefer cdtext", m_checkPrefereCdText->isChecked() ); + c->writeEntry( "ignore data read errors", m_checkIgnoreDataReadErrors->isChecked() ); + c->writeEntry( "ignore audio read errors", m_checkIgnoreAudioReadErrors->isChecked() ); + c->writeEntry( "no correction", m_checkNoCorrection->isChecked() ); + c->writeEntry( "data retries", m_spinDataRetries->value() ); + c->writeEntry( "audio retries", m_spinAudioRetries->value() ); + + QString s; + if( m_comboCopyMode->currentItem() == 1 ) + s = "clone"; + else + s = "normal"; + c->writeEntry( "copy mode", s ); +} + + +void K3bCdCopyDialog::loadK3bDefaults() +{ + m_writingModeWidget->setWritingMode( K3b::WRITING_MODE_AUTO ); + m_writerSelectionWidget->loadDefaults(); + m_checkSimulate->setChecked( false ); + m_checkCacheImage->setChecked( true ); + m_checkDeleteImages->setChecked( true ); + m_checkOnlyCreateImage->setChecked( false ); + m_comboParanoiaMode->setCurrentItem(0); + m_spinCopies->setValue(1); + m_checkReadCdText->setChecked(true); + m_checkPrefereCdText->setChecked(false); + m_checkIgnoreDataReadErrors->setChecked(false); + m_checkIgnoreAudioReadErrors->setChecked(true); + m_checkNoCorrection->setChecked(false); + m_comboCopyMode->setCurrentItem( 0 ); // normal + m_spinDataRetries->setValue(128); + m_spinAudioRetries->setValue(5); + m_tempDirSelectionWidget->setTempPath( K3b::defaultTempPath() ); + + slotToggleAll(); +} + + +KIO::filesize_t K3bCdCopyDialog::neededSize() const +{ + if( m_comboCopyMode->currentItem() == 0 ) + return k3bappcore->mediaCache()->medium( m_comboSourceDevice->selectedDevice() ).diskInfo().size().mode1Bytes(); + else + return k3bappcore->mediaCache()->medium( m_comboSourceDevice->selectedDevice() ).diskInfo().size().rawBytes(); +} + +#include "k3bcdcopydialog.moc" diff --git a/src/misc/k3bcdcopydialog.h b/src/misc/k3bcdcopydialog.h new file mode 100644 index 0000000..b7a4bd2 --- /dev/null +++ b/src/misc/k3bcdcopydialog.h @@ -0,0 +1,96 @@ +/* + * + * $Id: k3bcdcopydialog.h 733470 2007-11-06 12:10:29Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * Klaus-Dieter Krannich <kd@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + + +#ifndef K3BCDCOPYDIALOG_H +#define K3BCDCOPYDIALOG_H + + +#include <k3binteractiondialog.h> + +#include <kio/global.h> + +namespace K3bDevice { + class Device; + class DeviceManager; +} + +class K3bWriterSelectionWidget; +class K3bTempDirSelectionWidget; +class K3bMediaSelectionComboBox; +class QCheckBox; +class QSpinBox; +class QComboBox; +class K3bWritingModeWidget; +class QButtonGroup; +class QGroupBox; + + +/** + *@author Sebastian Trueg + */ +class K3bCdCopyDialog : public K3bInteractionDialog +{ + Q_OBJECT + + public: + K3bCdCopyDialog(QWidget *parent = 0, const char *name = 0, bool modal = true ); + ~K3bCdCopyDialog(); + + void setReadingDevice( K3bDevice::Device* ); + K3bDevice::Device* readingDevice() const; + + private slots: + void slotStartClicked(); + + void slotSourceMediumChanged( K3bDevice::Device* ); + void updateOverrideDevice(); + + protected: + void init(); + void toggleAll(); + + private: + void loadUserDefaults( KConfigBase* ); + void saveUserDefaults( KConfigBase* ); + void loadK3bDefaults(); + + KIO::filesize_t neededSize() const; + + K3bWriterSelectionWidget* m_writerSelectionWidget; + K3bTempDirSelectionWidget* m_tempDirSelectionWidget; + QCheckBox* m_checkSimulate; + QCheckBox* m_checkCacheImage; + QCheckBox* m_checkDeleteImages; + QCheckBox* m_checkOnlyCreateImage; + QCheckBox* m_checkReadCdText; + QCheckBox* m_checkPrefereCdText; + QCheckBox* m_checkIgnoreDataReadErrors; + QCheckBox* m_checkIgnoreAudioReadErrors; + QCheckBox* m_checkNoCorrection; + K3bMediaSelectionComboBox* m_comboSourceDevice; + QComboBox* m_comboParanoiaMode; + QSpinBox* m_spinCopies; + QSpinBox* m_spinDataRetries; + QSpinBox* m_spinAudioRetries; + K3bWritingModeWidget* m_writingModeWidget; + QComboBox* m_comboCopyMode; + + QGroupBox* m_groupAdvancedDataOptions; + QGroupBox* m_groupAdvancedAudioOptions; +}; + +#endif diff --git a/src/misc/k3bcdimagewritingdialog.cpp b/src/misc/k3bcdimagewritingdialog.cpp new file mode 100644 index 0000000..b071d94 --- /dev/null +++ b/src/misc/k3bcdimagewritingdialog.cpp @@ -0,0 +1,1049 @@ +/* + * + * $Id: k3bcdimagewritingdialog.cpp 630454 2007-02-05 13:06:45Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include <config.h> + +#include "k3bcdimagewritingdialog.h" +#include "k3biso9660imagewritingjob.h" +#include "k3bbinimagewritingjob.h" +#include "k3bcuefileparser.h" +#include "k3bclonetocreader.h" +#include "k3baudiocuefilewritingjob.h" +#include <k3bclonejob.h> + +#include <k3btempdirselectionwidget.h> +#include <k3bdevicemanager.h> +#include <k3bdevice.h> +#include <k3bwriterselectionwidget.h> +#include <k3bburnprogressdialog.h> +#include <kcutlabel.h> +#include <k3bstdguiitems.h> +#include <k3bmd5job.h> +#include <k3bdatamodewidget.h> +#include <k3bglobals.h> +#include <k3bwritingmodewidget.h> +#include <k3bcore.h> +#include <k3blistview.h> +#include <k3biso9660.h> +#include <k3btoc.h> +#include <k3btrack.h> +#include <k3bcdtext.h> + +#include <kapplication.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kurlrequester.h> +#include <kfiledialog.h> +#include <kstdguiitem.h> +#include <kguiitem.h> +#include <kiconloader.h> +#include <kconfig.h> +#include <kio/global.h> +#include <kurl.h> +#include <kinputdialog.h> +#include <kurldrag.h> + +#include <qheader.h> +#include <qgroupbox.h> +#include <qcheckbox.h> +#include <qlabel.h> +#include <qcombobox.h> +#include <qlayout.h> +#include <qptrlist.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qfont.h> +#include <qfontmetrics.h> +#include <qpushbutton.h> +#include <qtabwidget.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qspinbox.h> +#include <qmap.h> +#include <qptrqueue.h> +#include <qpopupmenu.h> +#include <qclipboard.h> + + +class K3bCdImageWritingDialog::Private +{ +public: + Private() + : md5SumItem(0), + haveMd5Sum( false ), + foundImageType( IMAGE_UNKNOWN ), + imageForced( false ) { + } + + K3bListViewItem* md5SumItem; + QString lastCheckedFile; + + K3bMd5Job* md5Job; + bool haveMd5Sum; + + int foundImageType; + + QMap<int,int> imageTypeSelectionMap; + QMap<int,int> imageTypeSelectionMapRev; + QString imageFile; + QString tocFile; + + QTabWidget* optionTabbed; + + QWidget* advancedTab; + QWidget* tempPathTab; + bool advancedTabVisible; + bool tempPathTabVisible; + + bool imageForced; +}; + + +K3bCdImageWritingDialog::K3bCdImageWritingDialog( QWidget* parent, const char* name, bool modal ) + : K3bInteractionDialog( parent, name, + i18n("Burn CD Image"), + "iso cue toc", + START_BUTTON|CANCEL_BUTTON, + START_BUTTON, + "image writing", // config group + modal ) +{ + d = new Private(); + + setAcceptDrops( true ); + + setupGui(); + + d->md5Job = new K3bMd5Job( 0, this ); + connect( d->md5Job, SIGNAL(finished(bool)), + this, SLOT(slotMd5JobFinished(bool)) ); + connect( d->md5Job, SIGNAL(percent(int)), + this, SLOT(slotMd5JobPercent(int)) ); + + connect( m_writerSelectionWidget, SIGNAL(writerChanged()), + this, SLOT(slotToggleAll()) ); + connect( m_writerSelectionWidget, SIGNAL(writingAppChanged(int)), + this, SLOT(slotToggleAll()) ); + connect( m_writerSelectionWidget, SIGNAL(writerChanged(K3bDevice::Device*)), + m_writingModeWidget, SLOT(setDevice(K3bDevice::Device*)) ); + connect( m_comboImageType, SIGNAL(activated(int)), + this, SLOT(slotToggleAll()) ); + connect( m_writingModeWidget, SIGNAL(writingModeChanged(int)), + this, SLOT(slotToggleAll()) ); + connect( m_editImagePath, SIGNAL(textChanged(const QString&)), + this, SLOT(slotUpdateImage(const QString&)) ); + connect( m_checkDummy, SIGNAL(toggled(bool)), + this, SLOT(slotToggleAll()) ); + connect( m_checkCacheImage, SIGNAL(toggled(bool)), + this, SLOT(slotToggleAll()) ); +} + + +K3bCdImageWritingDialog::~K3bCdImageWritingDialog() +{ + d->md5Job->cancel(); + delete d; +} + + +void K3bCdImageWritingDialog::init() +{ + if( !d->imageForced ) { + // when opening the dialog first the default settings are loaded and afterwards we set the + // last written image because that's what most users want + KConfig* c = k3bcore->config(); + c->setGroup( configGroup() ); + QString image = c->readPathEntry( "last written image" ); + if( QFile::exists( image ) ) + m_editImagePath->setURL( image ); + } +} + + +void K3bCdImageWritingDialog::setupGui() +{ + QWidget* frame = mainWidget(); + + // image + // ----------------------------------------------------------------------- + QGroupBox* groupImageUrl = new QGroupBox( 1, Qt::Horizontal, i18n("Image to Burn"), frame ); + m_editImagePath = new KURLRequester( groupImageUrl ); + m_editImagePath->setMode( KFile::File|KFile::ExistingOnly ); + m_editImagePath->setCaption( i18n("Choose Image File") ); + m_editImagePath->setFilter( i18n("*.iso *.toc *.ISO *.TOC *.cue *.CUE|Image Files") + + "\n" + + i18n("*.iso *.ISO|ISO9660 Image Files") + + "\n" + + i18n("*.cue *.CUE|Cue Files") + + "\n" + + i18n("*.toc *.TOC|Cdrdao TOC Files and Cdrecord Clone Images") + + "\n" + + i18n("*|All Files") ); + + QGroupBox* groupImageType = new QGroupBox( 1, Qt::Horizontal, i18n("Image Type"), frame ); + m_comboImageType = new QComboBox( groupImageType ); + m_comboImageType->insertItem( i18n("Auto Detection") ); + m_comboImageType->insertItem( i18n("ISO9660 Image") ); + m_comboImageType->insertItem( i18n("Cue/Bin Image") ); + m_comboImageType->insertItem( i18n("Audio Cue File") ); + m_comboImageType->insertItem( i18n("Cdrdao TOC File") ); + m_comboImageType->insertItem( i18n("Cdrecord Clone Image") ); + d->imageTypeSelectionMap[1] = IMAGE_ISO; + d->imageTypeSelectionMap[2] = IMAGE_CUE_BIN; + d->imageTypeSelectionMap[3] = IMAGE_AUDIO_CUE; + d->imageTypeSelectionMap[4] = IMAGE_CDRDAO_TOC; + d->imageTypeSelectionMap[5] = IMAGE_CDRECORD_CLONE; + d->imageTypeSelectionMapRev[IMAGE_ISO] = 1; + d->imageTypeSelectionMapRev[IMAGE_CUE_BIN] = 2; + d->imageTypeSelectionMapRev[IMAGE_AUDIO_CUE] = 3; + d->imageTypeSelectionMapRev[IMAGE_CDRDAO_TOC] = 4; + d->imageTypeSelectionMapRev[IMAGE_CDRECORD_CLONE] = 5; + + + // image info + // ----------------------------------------------------------------------- + m_infoView = new K3bListView( frame ); + m_infoView->addColumn( "key" ); + m_infoView->addColumn( "value" ); + m_infoView->header()->hide(); + m_infoView->setNoItemText( i18n("No image file selected") ); + m_infoView->setSorting( -1 ); + m_infoView->setAlternateBackground( QColor() ); + m_infoView->setFullWidth(true); + m_infoView->setSelectionMode( QListView::NoSelection ); + + connect( m_infoView, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), + this, SLOT(slotContextMenu(KListView*, QListViewItem*, const QPoint&)) ); + + + m_writerSelectionWidget = new K3bWriterSelectionWidget( frame ); + m_writerSelectionWidget->setWantedMediumType( K3bDevice::MEDIA_WRITABLE_CD ); + m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_EMPTY ); + + // options + // ----------------------------------------------------------------------- + d->optionTabbed = new QTabWidget( frame ); + + QWidget* optionTab = new QWidget( d->optionTabbed ); + QGridLayout* optionTabLayout = new QGridLayout( optionTab ); + optionTabLayout->setAlignment( Qt::AlignTop ); + optionTabLayout->setSpacing( spacingHint() ); + optionTabLayout->setMargin( marginHint() ); + + QGroupBox* writingModeGroup = new QGroupBox( 1, Vertical, i18n("Writing Mode"), optionTab ); + writingModeGroup->setInsideMargin( marginHint() ); + m_writingModeWidget = new K3bWritingModeWidget( writingModeGroup ); + + + // copies -------- + QGroupBox* groupCopies = new QGroupBox( 2, Qt::Horizontal, i18n("Copies"), optionTab ); + groupCopies->setInsideSpacing( spacingHint() ); + groupCopies->setInsideMargin( marginHint() ); + QLabel* pixLabel = new QLabel( groupCopies ); + pixLabel->setPixmap( SmallIcon( "cdcopy", KIcon::SizeMedium ) ); + pixLabel->setScaledContents( false ); + m_spinCopies = new QSpinBox( groupCopies ); + m_spinCopies->setMinValue( 1 ); + m_spinCopies->setMaxValue( 999 ); + // -------- copies + + QGroupBox* optionGroup = new QGroupBox( 3, Vertical, i18n("Settings"), optionTab ); + optionGroup->setInsideMargin( marginHint() ); + optionGroup->setInsideSpacing( spacingHint() ); + m_checkDummy = K3bStdGuiItems::simulateCheckbox( optionGroup ); + m_checkCacheImage = K3bStdGuiItems::createCacheImageCheckbox( optionGroup ); + m_checkVerify = K3bStdGuiItems::verifyCheckBox( optionGroup ); + + optionTabLayout->addWidget( writingModeGroup, 0, 0 ); + optionTabLayout->addWidget( groupCopies, 1, 0 ); + optionTabLayout->addMultiCellWidget( optionGroup, 0, 1, 1, 1 ); + optionTabLayout->setRowStretch( 1, 1 ); + optionTabLayout->setColStretch( 1, 1 ); + + d->optionTabbed->addTab( optionTab, i18n("Settings") ); + + + // image tab ------------------------------------ + d->tempPathTab = new QWidget( d->optionTabbed ); + QGridLayout* imageTabGrid = new QGridLayout( d->tempPathTab ); + imageTabGrid->setSpacing( spacingHint() ); + imageTabGrid->setMargin( marginHint() ); + + m_tempDirSelectionWidget = new K3bTempDirSelectionWidget( d->tempPathTab ); + + imageTabGrid->addWidget( m_tempDirSelectionWidget, 0, 0 ); + + d->optionTabbed->addTab( d->tempPathTab, i18n("&Image") ); + d->tempPathTabVisible = true; + // ------------------------------------------------------------- + + + // advanced --------------------------------- + d->advancedTab = new QWidget( d->optionTabbed ); + QGridLayout* advancedTabLayout = new QGridLayout( d->advancedTab ); + advancedTabLayout->setAlignment( Qt::AlignTop ); + advancedTabLayout->setSpacing( spacingHint() ); + advancedTabLayout->setMargin( marginHint() ); + + m_dataModeWidget = new K3bDataModeWidget( d->advancedTab ); + m_checkNoFix = K3bStdGuiItems::startMultisessionCheckBox( d->advancedTab ); + + advancedTabLayout->addWidget( new QLabel( i18n("Data mode:"), d->advancedTab ), 0, 0 ); + advancedTabLayout->addWidget( m_dataModeWidget, 0, 1 ); + advancedTabLayout->addMultiCellWidget( m_checkNoFix, 1, 1, 0, 2 ); + advancedTabLayout->setRowStretch( 2, 1 ); + advancedTabLayout->setColStretch( 2, 1 ); + + d->optionTabbed->addTab( d->advancedTab, i18n("Advanced") ); + d->advancedTabVisible = true; + // ----------------------------------------------------------------------- + + + + + QGridLayout* grid = new QGridLayout( frame ); + grid->setSpacing( spacingHint() ); + grid->setMargin( 0 ); + + grid->addWidget( groupImageUrl, 0, 0 ); + grid->addWidget( groupImageType, 0, 1 ); + grid->addMultiCellWidget( m_infoView, 1, 1, 0, 1 ); + grid->addMultiCellWidget( m_writerSelectionWidget, 2, 2, 0, 1 ); + grid->addMultiCellWidget( d->optionTabbed, 3, 3, 0, 1 ); + + grid->setRowStretch( 1, 1 ); +} + + +void K3bCdImageWritingDialog::slotStartClicked() +{ + // FIXME: this results in a call to slotMd5JobFinished + // if this dialog is deleted becasue it is not opened with exec(false) + // this results in a crash. + // For now this is not a problem in K3b since the dialog is not deleted + // when hiding (due to the exec(false) call in k3b.cpp + d->md5Job->cancel(); + + // save the path + KConfig* c = k3bcore->config(); + c->setGroup( configGroup() ); + c->writePathEntry( "last written image", imagePath() ); + + if( d->imageFile.isEmpty() ) + d->imageFile = imagePath(); + if( d->tocFile.isEmpty() ) + d->tocFile = imagePath(); + + // create a progresswidget + K3bBurnProgressDialog dlg( kapp->mainWidget(), "burnProgress", true ); + + // create the job + K3bBurnJob* job = 0; + switch( currentImageType() ) { + case IMAGE_CDRECORD_CLONE: + { + K3bCloneJob* _job = new K3bCloneJob( &dlg, this ); + _job->setWriterDevice( m_writerSelectionWidget->writerDevice() ); + _job->setImagePath( d->imageFile ); + _job->setSimulate( m_checkDummy->isChecked() ); + _job->setWriteSpeed( m_writerSelectionWidget->writerSpeed() ); + _job->setCopies( m_checkDummy->isChecked() ? 1 : m_spinCopies->value() ); + _job->setOnlyBurnExistingImage( true ); + + job = _job; + } + break; + + case IMAGE_AUDIO_CUE: + { + K3bAudioCueFileWritingJob* job_ = new K3bAudioCueFileWritingJob( &dlg, this ); + + job_->setBurnDevice( m_writerSelectionWidget->writerDevice() ); + job_->setSpeed( m_writerSelectionWidget->writerSpeed() ); + job_->setSimulate( m_checkDummy->isChecked() ); + job_->setWritingMode( m_writingModeWidget->writingMode() ); + job_->setCueFile( d->tocFile ); + job_->setCopies( m_checkDummy->isChecked() ? 1 : m_spinCopies->value() ); + job_->setOnTheFly( !m_checkCacheImage->isChecked() ); + job_->setTempDir( m_tempDirSelectionWidget->tempPath() ); + + job = job_; + } + break; + + case IMAGE_CUE_BIN: + // for now the K3bBinImageWritingJob decides if it's a toc or a cue file + case IMAGE_CDRDAO_TOC: + { + K3bBinImageWritingJob* job_ = new K3bBinImageWritingJob( &dlg, this ); + + job_->setWriter( m_writerSelectionWidget->writerDevice() ); + job_->setSpeed( m_writerSelectionWidget->writerSpeed() ); + job_->setTocFile( d->tocFile ); + job_->setSimulate(m_checkDummy->isChecked()); + job_->setMulti( false /*m_checkNoFix->isChecked()*/ ); + job_->setCopies( m_checkDummy->isChecked() ? 1 : m_spinCopies->value() ); + + job = job_; + } + break; + + case IMAGE_ISO: + { + K3bIso9660 isoFs( d->imageFile ); + if( isoFs.open() ) { + if( K3b::filesize( KURL::fromPathOrURL(d->imageFile) ) < (KIO::filesize_t)(isoFs.primaryDescriptor().volumeSpaceSize*2048) ) { + if( KMessageBox::questionYesNo( this, + i18n("<p>This image has an invalid file size." + "If it has been downloaded make sure the download is complete." + "<p>Only continue if you know what you are doing."), + i18n("Warning"), + i18n("Continue"), + i18n("Cancel") ) == KMessageBox::No ) + return; + } + } + + K3bIso9660ImageWritingJob* job_ = new K3bIso9660ImageWritingJob( &dlg ); + + job_->setBurnDevice( m_writerSelectionWidget->writerDevice() ); + job_->setSpeed( m_writerSelectionWidget->writerSpeed() ); + job_->setSimulate( m_checkDummy->isChecked() ); + job_->setWritingMode( m_writingModeWidget->writingMode() ); + job_->setVerifyData( m_checkVerify->isChecked() ); + job_->setNoFix( m_checkNoFix->isChecked() ); + job_->setDataMode( m_dataModeWidget->dataMode() ); + job_->setImagePath( d->imageFile ); + job_->setCopies( m_checkDummy->isChecked() ? 1 : m_spinCopies->value() ); + + job = job_; + } + break; + + default: + kdDebug() << "(K3bCdImageWritingDialog) this should really not happen!" << endl; + break; + } + + if( job ) { + job->setWritingApp( m_writerSelectionWidget->writingApp() ); + + if( !exitLoopOnHide() ) + hide(); + + dlg.startJob(job); + + delete job; + + if( KConfigGroup( k3bcore->config(), "General Options" ).readBoolEntry( "keep action dialogs open", false ) && + !exitLoopOnHide() ) + show(); + else + close(); + } +} + + +void K3bCdImageWritingDialog::slotUpdateImage( const QString& ) +{ + QString path = imagePath(); + + // check the image types + + d->haveMd5Sum = false; + d->md5Job->cancel(); + m_infoView->clear(); + m_infoView->header()->resizeSection( 0, 20 ); + d->md5SumItem = 0; + d->foundImageType = IMAGE_UNKNOWN; + d->tocFile.truncate(0); + d->imageFile.truncate(0); + + QFileInfo info( path ); + if( info.isFile() ) { + + // ------------------------------------------------ + // Test for iso9660 image + // ------------------------------------------------ + K3bIso9660 isoF( path ); + if( isoF.open() ) { +#ifdef K3B_DEBUG + isoF.debug(); +#endif + + createIso9660InfoItems( &isoF ); + isoF.close(); + calculateMd5Sum( path ); + + d->foundImageType = IMAGE_ISO; + d->imageFile = path; + } + + if( d->foundImageType == IMAGE_UNKNOWN ) { + + // check for cdrecord clone image + // try both path and path.toc as tocfiles + K3bCloneTocReader cr; + + if( path.right(4) == ".toc" ) { + cr.openFile( path ); + if( cr.isValid() ) { + d->tocFile = path; + d->imageFile = cr.imageFilename(); + } + } + if( d->imageFile.isEmpty() ) { + cr.openFile( path + ".toc" ); + if( cr.isValid() ) { + d->tocFile = cr.filename(); + d->imageFile = cr.imageFilename(); + } + } + + if( !d->imageFile.isEmpty() ) { + // we have a cdrecord clone image + createCdrecordCloneItems( d->tocFile, d->imageFile ); + calculateMd5Sum( d->imageFile ); + + d->foundImageType = IMAGE_CDRECORD_CLONE; + } + } + + if( d->foundImageType == IMAGE_UNKNOWN ) { + + // check for cue/bin stuff + // once again we try both path and path.cue + K3bCueFileParser cp; + + if( path.right(4).lower() == ".cue" ) + cp.openFile( path ); + else if( path.right(4).lower() == ".bin" ) + cp.openFile( path.left( path.length()-3) + "cue" ); + + if( cp.isValid() ) { + d->tocFile = cp.filename(); + d->imageFile = cp.imageFilename(); + } + + if( d->imageFile.isEmpty() ) { + cp.openFile( path + ".cue" ); + if( cp.isValid() ) { + d->tocFile = cp.filename(); + d->imageFile = cp.imageFilename(); + } + } + + if( !d->imageFile.isEmpty() ) { + // we have a cue file + if( cp.toc().contentType() == K3bDevice::AUDIO ) { + d->foundImageType = IMAGE_AUDIO_CUE; + createAudioCueItems( cp ); + } + else { + d->foundImageType = IMAGE_CUE_BIN; // we cannot be sure if writing will work... :( + createCueBinItems( d->tocFile, d->imageFile ); + calculateMd5Sum( d->imageFile ); + } + } + } + + if( d->foundImageType == IMAGE_UNKNOWN ) { + // TODO: check for cdrdao tocfile + } + + + + if( d->foundImageType == IMAGE_UNKNOWN ) { + K3bListViewItem* item = new K3bListViewItem( m_infoView, m_infoView->lastItem(), + i18n("Seems not to be a usable image") ); + item->setForegroundColor( 0, Qt::red ); + item->setPixmap( 0, SmallIcon( "stop") ); + } + } + else { + K3bListViewItem* item = new K3bListViewItem( m_infoView, m_infoView->lastItem(), + i18n("File not found") ); + item->setForegroundColor( 0, Qt::red ); + item->setPixmap( 0, SmallIcon( "stop") ); + } + + slotToggleAll(); +} + + +void K3bCdImageWritingDialog::createIso9660InfoItems( K3bIso9660* isoF ) +{ + K3bListViewItem* isoRootItem = new K3bListViewItem( m_infoView, m_infoView->lastItem(), + i18n("Detected:"), + i18n("Iso9660 image") ); + isoRootItem->setForegroundColor( 0, palette().disabled().foreground() ); + isoRootItem->setPixmap( 0, SmallIcon( "cdimage") ); + + KIO::filesize_t size = K3b::filesize( KURL::fromPathOrURL(isoF->fileName()) ); + K3bListViewItem* item = new K3bListViewItem( isoRootItem, m_infoView->lastItem(), + i18n("Filesize:"), + KIO::convertSize( size ) ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("System Id:"), + isoF->primaryDescriptor().systemId.isEmpty() + ? QString("-") + : isoF->primaryDescriptor().systemId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Volume Id:"), + isoF->primaryDescriptor().volumeId.isEmpty() + ? QString("-") + : isoF->primaryDescriptor().volumeId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Volume Set Id:"), + isoF->primaryDescriptor().volumeSetId.isEmpty() + ? QString("-") + : isoF->primaryDescriptor().volumeSetId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Publisher Id:"), + isoF->primaryDescriptor().publisherId.isEmpty() + ? QString("-") + : isoF->primaryDescriptor().publisherId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Preparer Id:"), + isoF->primaryDescriptor().preparerId.isEmpty() + ? QString("-") : isoF->primaryDescriptor().preparerId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Application Id:"), + isoF->primaryDescriptor().applicationId.isEmpty() + ? QString("-") + : isoF->primaryDescriptor().applicationId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + isoRootItem->setOpen( true ); +} + + +void K3bCdImageWritingDialog::createCdrecordCloneItems( const QString& tocFile, const QString& imageFile ) +{ + K3bListViewItem* isoRootItem = new K3bListViewItem( m_infoView, m_infoView->lastItem(), + i18n("Detected:"), + i18n("Cdrecord clone image") ); + isoRootItem->setForegroundColor( 0, palette().disabled().foreground() ); + isoRootItem->setPixmap( 0, SmallIcon( "cdimage") ); + + K3bListViewItem* item = new K3bListViewItem( isoRootItem, m_infoView->lastItem(), + i18n("Filesize:"), KIO::convertSize( K3b::filesize(KURL::fromPathOrURL(imageFile)) ) ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Image file:"), + imageFile ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("TOC file:"), + tocFile ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + isoRootItem->setOpen( true ); +} + + +void K3bCdImageWritingDialog::createCueBinItems( const QString& cueFile, const QString& imageFile ) +{ + K3bListViewItem* isoRootItem = new K3bListViewItem( m_infoView, m_infoView->lastItem(), + i18n("Detected:"), + i18n("Cue/bin image") ); + isoRootItem->setForegroundColor( 0, palette().disabled().foreground() ); + isoRootItem->setPixmap( 0, SmallIcon( "cdimage") ); + + K3bListViewItem* item = new K3bListViewItem( isoRootItem, m_infoView->lastItem(), + i18n("Filesize:"), KIO::convertSize( K3b::filesize(KURL::fromPathOrURL(imageFile)) ) ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Image file:"), + imageFile ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Cue file:"), + cueFile ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + isoRootItem->setOpen( true ); +} + + +void K3bCdImageWritingDialog::createAudioCueItems( const K3bCueFileParser& cp ) +{ + K3bListViewItem* rootItem = new K3bListViewItem( m_infoView, m_infoView->lastItem(), + i18n("Detected:"), + i18n("Audio Cue Image") ); + rootItem->setForegroundColor( 0, palette().disabled().foreground() ); + rootItem->setPixmap( 0, SmallIcon( "sound") ); + + K3bListViewItem* trackParent = new K3bListViewItem( rootItem, + i18n("%n track", "%n tracks", cp.toc().count() ), + cp.toc().length().toString() ); + if( !cp.cdText().isEmpty() ) + trackParent->setText( 1, + QString("%1 (%2 - %3)") + .arg(trackParent->text(1)) + .arg(cp.cdText().performer()) + .arg(cp.cdText().title()) ); + + unsigned int i = 1; + for( K3bDevice::Toc::const_iterator it = cp.toc().begin(); + it != cp.toc().end(); ++it ) { + + K3bListViewItem* trackItem = + new K3bListViewItem( trackParent, m_infoView->lastItem(), + i18n("Track") + " " + QString::number(i).rightJustify( 2, '0' ), + " " + ( i < cp.toc().count() + ? (*it).length().toString() + : QString("??:??:??") ) ); + + if( !cp.cdText().isEmpty() && !cp.cdText()[i-1].isEmpty() ) + trackItem->setText( 1, + QString("%1 (%2 - %3)") + .arg(trackItem->text(1)) + .arg(cp.cdText()[i-1].performer()) + .arg(cp.cdText()[i-1].title()) ); + + ++i; + } + + rootItem->setOpen( true ); + trackParent->setOpen( true ); +} + + +void K3bCdImageWritingDialog::toggleAll() +{ + // enable the Write-Button if we found a valid image or the user forced an image type + setButtonEnabled( START_BUTTON, m_writerSelectionWidget->writerDevice() + && currentImageType() != IMAGE_UNKNOWN + && QFile::exists( imagePath() ) ); + + // cdrecord clone and cue both need DAO + if( m_writerSelectionWidget->writingApp() != K3b::CDRDAO + && ( currentImageType() == IMAGE_ISO || + currentImageType() == IMAGE_AUDIO_CUE ) ) + m_writingModeWidget->setSupportedModes( K3b::TAO|K3b::DAO|K3b::RAW ); // stuff supported by cdrecord + else + m_writingModeWidget->setSupportedModes( K3b::DAO ); + + // some stuff is only available for iso images + if( currentImageType() == IMAGE_ISO ) { + m_checkVerify->show(); + if( !d->advancedTabVisible ) + d->optionTabbed->addTab( d->advancedTab, i18n("Advanced") ); + d->advancedTabVisible = true; + if( m_checkDummy->isChecked() ) { + m_checkVerify->setEnabled( false ); + m_checkVerify->setChecked( false ); + } + else + m_checkVerify->setEnabled( true ); + } + else { + if( d->advancedTabVisible ) + d->optionTabbed->removePage( d->advancedTab ); + d->advancedTabVisible = false; + m_checkVerify->hide(); + } + + // and some other stuff only makes sense for audio cues + if( currentImageType() == IMAGE_AUDIO_CUE ) { + if( !d->tempPathTabVisible ) + d->optionTabbed->addTab( d->tempPathTab, i18n("&Image") ); + d->tempPathTabVisible = true; + m_tempDirSelectionWidget->setDisabled( !m_checkCacheImage->isChecked() ); + } + else { + if( d->tempPathTabVisible ) + d->optionTabbed->removePage( d->tempPathTab ); + d->tempPathTabVisible = false; + } + m_checkCacheImage->setShown( currentImageType() == IMAGE_AUDIO_CUE ); + + m_spinCopies->setEnabled( !m_checkDummy->isChecked() ); + + switch( currentImageType() ) { + case IMAGE_CDRDAO_TOC: + m_writerSelectionWidget->setSupportedWritingApps( K3b::CDRDAO ); + break; + case IMAGE_CDRECORD_CLONE: + m_writerSelectionWidget->setSupportedWritingApps( K3b::CDRECORD ); + break; + default: + m_writerSelectionWidget->setSupportedWritingApps( K3b::CDRECORD|K3b::CDRDAO ); + break; + } + + K3bListViewItem* item = dynamic_cast<K3bListViewItem*>(m_infoView->firstChild()); + if( item ) + item->setForegroundColor( 1, + currentImageType() != d->foundImageType + ? Qt::red + : m_infoView->colorGroup().foreground() ); +} + + +void K3bCdImageWritingDialog::setImage( const KURL& url ) +{ + d->imageForced = true; +#if KDE_IS_VERSION(3,4,0) + m_editImagePath->setKURL( url ); +#else + m_editImagePath->setURL( url.path() ); +#endif +} + + +void K3bCdImageWritingDialog::calculateMd5Sum( const QString& file ) +{ + d->haveMd5Sum = false; + + if( !d->md5SumItem ) + d->md5SumItem = new K3bListViewItem( m_infoView, m_infoView->firstChild() ); + + d->md5SumItem->setText( 0, i18n("Md5 Sum:") ); + d->md5SumItem->setForegroundColor( 0, palette().disabled().foreground() ); + d->md5SumItem->setProgress( 1, 0 ); + d->md5SumItem->setPixmap( 0, SmallIcon( "exec") ); + + if( file != d->lastCheckedFile ) { + d->lastCheckedFile = file; + d->md5Job->setFile( file ); + d->md5Job->start(); + } + else + slotMd5JobFinished( true ); +} + + +void K3bCdImageWritingDialog::slotMd5JobPercent( int p ) +{ + d->md5SumItem->setProgress( 1, p ); +} + + +void K3bCdImageWritingDialog::slotMd5JobFinished( bool success ) +{ + if( success ) { + d->md5SumItem->setText( 1, d->md5Job->hexDigest() ); + d->haveMd5Sum = true; + } + else { + d->md5SumItem->setForegroundColor( 1, Qt::red ); + if( d->md5Job->hasBeenCanceled() ) + d->md5SumItem->setText( 1, i18n("Calculation cancelled") ); + else + d->md5SumItem->setText( 1, i18n("Calculation failed") ); + d->md5SumItem->setPixmap( 0, SmallIcon( "stop") ); + d->lastCheckedFile.truncate(0); + } + + d->md5SumItem->setDisplayProgressBar( 1, false ); +} + + +void K3bCdImageWritingDialog::slotContextMenu( KListView*, QListViewItem*, const QPoint& pos ) +{ + if( !d->haveMd5Sum ) + return; + + QPopupMenu popup; + int copyItem = popup.insertItem( i18n("Copy checksum to clipboard") ); + int compareItem = popup.insertItem( i18n("Compare checksum...") ); + + int r = popup.exec( pos ); + + if( r == compareItem ) { + bool ok; + QString md5sumToCompare = KInputDialog::getText( i18n("MD5 Sum Check"), + i18n("Please insert the MD5 Sum to compare:"), + QString::null, + &ok, + this ); + if( ok ) { + if( md5sumToCompare.lower().utf8() == d->md5Job->hexDigest().lower() ) + KMessageBox::information( this, i18n("The MD5 Sum of %1 equals the specified.").arg(imagePath()), + i18n("MD5 Sums Equal") ); + else + KMessageBox::sorry( this, i18n("The MD5 Sum of %1 differs from the specified.").arg(imagePath()), + i18n("MD5 Sums Differ") ); + } + } + else if( r == copyItem ) { + QApplication::clipboard()->setText( d->md5Job->hexDigest().lower(), QClipboard::Clipboard ); + } +} + + +void K3bCdImageWritingDialog::loadUserDefaults( KConfigBase* c ) +{ + m_writingModeWidget->loadConfig( c ); + m_checkDummy->setChecked( c->readBoolEntry("simulate", false ) ); + m_checkNoFix->setChecked( c->readBoolEntry("multisession", false ) ); + m_checkCacheImage->setChecked( !c->readBoolEntry("on_the_fly", true ) ); + + m_dataModeWidget->loadConfig(c); + + m_spinCopies->setValue( c->readNumEntry( "copies", 1 ) ); + + m_checkVerify->setChecked( c->readBoolEntry( "verify_data", false ) ); + + m_writerSelectionWidget->loadConfig( c ); + + if( !d->imageForced ) { + QString image = c->readPathEntry( "image path", c->readPathEntry( "last written image" ) ); + if( QFile::exists( image ) ) + m_editImagePath->setURL( image ); + } + + QString imageType = c->readEntry( "image type", "auto" ); + int x = 0; + if( imageType == "iso9660" ) + x = d->imageTypeSelectionMapRev[IMAGE_ISO]; + else if( imageType == "cue-bin" ) + x = d->imageTypeSelectionMapRev[IMAGE_CUE_BIN]; + else if( imageType == "audio-cue" ) + x = d->imageTypeSelectionMapRev[IMAGE_AUDIO_CUE]; + else if( imageType == "cdrecord-clone" ) + x = d->imageTypeSelectionMapRev[IMAGE_CDRECORD_CLONE]; + else if( imageType == "cdrdao-toc" ) + x = d->imageTypeSelectionMapRev[IMAGE_CDRDAO_TOC]; + + m_comboImageType->setCurrentItem( x ); + + m_tempDirSelectionWidget->setTempPath( K3b::defaultTempPath() ); + + slotToggleAll(); +} + + +void K3bCdImageWritingDialog::saveUserDefaults( KConfigBase* c ) +{ + m_writingModeWidget->saveConfig( c ), + c->writeEntry( "simulate", m_checkDummy->isChecked() ); + c->writeEntry( "multisession", m_checkNoFix->isChecked() ); + c->writeEntry( "on_the_fly", !m_checkCacheImage->isChecked() ); + m_dataModeWidget->saveConfig(c); + + c->writeEntry( "verify_data", m_checkVerify->isChecked() ); + + m_writerSelectionWidget->saveConfig( c ); + + c->writePathEntry( "image path", imagePath() ); + + c->writeEntry( "copies", m_spinCopies->value() ); + + QString imageType; + if( m_comboImageType->currentItem() == 0 ) + imageType = "auto"; + else { + switch( d->imageTypeSelectionMap[m_comboImageType->currentItem()] ) { + case IMAGE_ISO: + imageType = "iso9660"; + break; + case IMAGE_CUE_BIN: + imageType = "cue-bin"; + break; + case IMAGE_AUDIO_CUE: + imageType = "audio-cue"; + break; + case IMAGE_CDRECORD_CLONE: + imageType = "cdrecord-clone"; + break; + case IMAGE_CDRDAO_TOC: + imageType = "cdrdao-toc"; + break; + } + } + c->writeEntry( "image type", imageType ); + + if( m_tempDirSelectionWidget->isEnabled() ) + m_tempDirSelectionWidget->saveConfig(); +} + +void K3bCdImageWritingDialog::loadK3bDefaults() +{ + m_writerSelectionWidget->loadDefaults(); + m_writingModeWidget->setWritingMode( K3b::WRITING_MODE_AUTO ); + m_checkDummy->setChecked( false ); + m_checkVerify->setChecked( false ); + m_checkNoFix->setChecked( false ); + m_checkCacheImage->setChecked( false ); + m_dataModeWidget->setDataMode( K3b::DATA_MODE_AUTO ); + m_comboImageType->setCurrentItem(0); + m_spinCopies->setValue( 1 ); + + slotToggleAll(); +} + + +int K3bCdImageWritingDialog::currentImageType() +{ + if( m_comboImageType->currentItem() == 0 ) + return d->foundImageType; + else + return d->imageTypeSelectionMap[m_comboImageType->currentItem()]; +} + + +QString K3bCdImageWritingDialog::imagePath() const +{ + return K3b::convertToLocalUrl( KURL::fromPathOrURL( m_editImagePath->url() ) ).path(); +} + + +void K3bCdImageWritingDialog::dragEnterEvent( QDragEnterEvent* e ) +{ + e->accept( KURLDrag::canDecode(e) ); +} + + +void K3bCdImageWritingDialog::dropEvent( QDropEvent* e ) +{ + KURL::List urls; + KURLDrag::decode( e, urls ); +#if KDE_IS_VERSION(3,4,0) + m_editImagePath->setKURL( urls.first() ); +#else + m_editImagePath->setURL( urls.first().path() ); +#endif +} + +#include "k3bcdimagewritingdialog.moc" diff --git a/src/misc/k3bcdimagewritingdialog.h b/src/misc/k3bcdimagewritingdialog.h new file mode 100644 index 0000000..143f023 --- /dev/null +++ b/src/misc/k3bcdimagewritingdialog.h @@ -0,0 +1,116 @@ +/* + * + * $Id$ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + + +#ifndef _K3B_CDIMAGEWRITINGDIALOG_H_ +#define _K3B_CDIMAGEWRITINGDIALOG_H_ + +#include <k3binteractiondialog.h> + + +class QCheckBox; +class K3bWriterSelectionWidget; +class QLabel; +class KURL; +class KActiveLabel; +class KProgress; +class K3bDataModeWidget; +class K3bWritingModeWidget; +class K3bTempDirSelectionWidget; +class KURLRequester; +class K3bListView; +class QSpinBox; +class QComboBox; +class K3bIso9660; +class K3bCueFileParser; +class QDragEnterEvent; +class QDropEvent; +class KListView; +class QListViewItem; +class QPoint; + + +/** + *@author Sebastian Trueg + */ +class K3bCdImageWritingDialog : public K3bInteractionDialog +{ + Q_OBJECT + + public: + K3bCdImageWritingDialog( QWidget* = 0, const char* = 0, bool = true ); + ~K3bCdImageWritingDialog(); + + void setImage( const KURL& url ); + + protected slots: + void slotStartClicked(); + + void slotMd5JobPercent( int ); + void slotMd5JobFinished( bool ); + void slotContextMenu( KListView*, QListViewItem*, const QPoint& pos ); + + void slotUpdateImage( const QString& ); + + protected: + void loadUserDefaults( KConfigBase* ); + void saveUserDefaults( KConfigBase* ); + void loadK3bDefaults(); + + void calculateMd5Sum( const QString& ); + void dragEnterEvent( QDragEnterEvent* ); + void dropEvent( QDropEvent* ); + + void init(); + + void toggleAll(); + + private: + enum { + IMAGE_UNKNOWN, + IMAGE_ISO, + IMAGE_CUE_BIN, + IMAGE_AUDIO_CUE, + IMAGE_CDRDAO_TOC, + IMAGE_CDRECORD_CLONE }; + + void setupGui(); + void createIso9660InfoItems( K3bIso9660* ); + void createCdrecordCloneItems( const QString&, const QString& ); + void createCueBinItems( const QString&, const QString& ); + void createAudioCueItems( const K3bCueFileParser& cp ); + int currentImageType(); + QString imagePath() const; + + K3bWriterSelectionWidget* m_writerSelectionWidget; + QCheckBox* m_checkDummy; + QCheckBox* m_checkNoFix; + QCheckBox* m_checkCacheImage; + QCheckBox* m_checkVerify; + K3bDataModeWidget* m_dataModeWidget; + K3bWritingModeWidget* m_writingModeWidget; + QSpinBox* m_spinCopies; + + KURLRequester* m_editImagePath; + QComboBox* m_comboImageType; + + K3bListView* m_infoView; + K3bTempDirSelectionWidget* m_tempDirSelectionWidget; + + class Private; + Private* d; +}; + +#endif diff --git a/src/misc/k3bdvdcopydialog.cpp b/src/misc/k3bdvdcopydialog.cpp new file mode 100644 index 0000000..f93abba --- /dev/null +++ b/src/misc/k3bdvdcopydialog.cpp @@ -0,0 +1,455 @@ +/* + * + * $Id: k3bdvdcopydialog.cpp 733470 2007-11-06 12:10:29Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include "k3bdvdcopydialog.h" +#include "k3bdvdcopyjob.h" + +#include <k3btempdirselectionwidget.h> +#include <k3bwriterselectionwidget.h> +#include <k3bglobals.h> +#include <k3bstdguiitems.h> +#include <k3bmediaselectioncombobox.h> +#include <k3bdevice.h> +#include <k3bdevicemanager.h> +#include <k3bexternalbinmanager.h> +#include <k3bburnprogressdialog.h> +#include <k3bwritingmodewidget.h> +#include <k3bthememanager.h> +#include <k3bapplication.h> +#include <k3bmediacache.h> +#include <k3biso9660.h> + +#include <qlayout.h> +#include <qgroupbox.h> +#include <qcheckbox.h> +#include <qlabel.h> +#include <qtabwidget.h> +#include <qspinbox.h> +#include <qptrlist.h> +#include <qfile.h> +#include <qpushbutton.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qhbox.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kconfig.h> +#include <kapplication.h> +#include <kstandarddirs.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kglobal.h> + + + +K3bDvdCopyDialog::K3bDvdCopyDialog( QWidget* parent, const char* name, bool modal ) + : K3bInteractionDialog( parent, name, + i18n("DVD Copy"), + i18n("No video transcoding!"), + START_BUTTON|CANCEL_BUTTON, + START_BUTTON, + "default dvd copy settings", + modal ) +{ + QWidget* w = mainWidget(); + + // + // Source group + // ////////////////////////////////////////////////////////////////////////// + QGroupBox* groupSource = new QGroupBox( 1, Qt::Vertical, i18n("Source Medium"), w ); + groupSource->setInsideSpacing( spacingHint() ); + groupSource->setInsideMargin( marginHint() ); + m_comboSourceDevice = new K3bMediaSelectionComboBox( groupSource ); + m_comboSourceDevice->setWantedMediumType( K3bDevice::MEDIA_WRITABLE_DVD|K3bDevice::MEDIA_DVD_ROM ); + m_comboSourceDevice->setWantedMediumState( K3bDevice::STATE_COMPLETE|K3bDevice::STATE_INCOMPLETE ); + // ////////////////////////////////////////////////////////////////////////// + + // + // Writer group + // ////////////////////////////////////////////////////////////////////////// + m_writerSelectionWidget = new K3bWriterSelectionWidget( w ); + m_writerSelectionWidget->setSupportedWritingApps( K3b::GROWISOFS ); + m_writerSelectionWidget->setWantedMediumType( K3bDevice::MEDIA_WRITABLE_DVD ); + m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_EMPTY ); + // ////////////////////////////////////////////////////////////////////////// + + // + // Option tab + // ////////////////////////////////////////////////////////////////////////// + QTabWidget* tabWidget = new QTabWidget( w ); + + // option tab -------------------- + QWidget* optionTab = new QWidget( tabWidget ); + QGridLayout* optionTabGrid = new QGridLayout( optionTab ); + optionTabGrid->setSpacing( spacingHint() ); + optionTabGrid->setMargin( marginHint() ); + + QGroupBox* groupWritingMode = new QGroupBox( 1, Qt::Vertical, i18n("Writing Mode"), optionTab ); + groupWritingMode->setInsideMargin( marginHint() ); + m_writingModeWidget = new K3bWritingModeWidget( groupWritingMode ); + + QGroupBox* groupOptions = new QGroupBox( 5, Qt::Vertical, i18n("Settings"), optionTab ); + groupOptions->setInsideSpacing( spacingHint() ); + groupOptions->setInsideMargin( marginHint() ); + m_checkSimulate = K3bStdGuiItems::simulateCheckbox( groupOptions ); + m_checkCacheImage = K3bStdGuiItems::createCacheImageCheckbox( groupOptions ); + m_checkOnlyCreateImage = K3bStdGuiItems::onlyCreateImagesCheckbox( groupOptions ); + m_checkDeleteImages = K3bStdGuiItems::removeImagesCheckbox( groupOptions ); + m_checkVerifyData = K3bStdGuiItems::verifyCheckBox( groupOptions ); + + QGroupBox* groupCopies = new QGroupBox( 2, Qt::Horizontal, i18n("Copies"), optionTab ); + groupCopies->setInsideSpacing( spacingHint() ); + groupCopies->setInsideMargin( marginHint() ); + QLabel* pixLabel = new QLabel( groupCopies ); + pixLabel->setPixmap( SmallIcon( "cdcopy", KIcon::SizeMedium ) ); + pixLabel->setScaledContents( false ); + m_spinCopies = new QSpinBox( groupCopies ); + m_spinCopies->setMinValue( 1 ); + m_spinCopies->setMaxValue( 999 ); + + optionTabGrid->addWidget( groupWritingMode, 0, 0 ); + optionTabGrid->addMultiCellWidget( groupOptions, 0, 1, 1, 1 ); + optionTabGrid->addWidget( groupCopies, 1, 0 ); + optionTabGrid->setRowStretch( 1, 1 ); + optionTabGrid->setColStretch( 1, 1 ); + + tabWidget->addTab( optionTab, i18n("&Options") ); + + + // + // Image tab + // ////////////////////////////////////////////////////////////////////////// + QWidget* imageTab = new QWidget( tabWidget ); + QGridLayout* imageTabGrid = new QGridLayout( imageTab ); + imageTabGrid->setSpacing( spacingHint() ); + imageTabGrid->setMargin( marginHint() ); + + m_tempDirSelectionWidget = new K3bTempDirSelectionWidget( imageTab ); + m_tempDirSelectionWidget->setSelectionMode( K3bTempDirSelectionWidget::FILE ); + + imageTabGrid->addWidget( m_tempDirSelectionWidget, 0, 0 ); + + tabWidget->addTab( imageTab, i18n("&Image") ); + + + // + // advanced tab ------------------ + // ////////////////////////////////////////////////////////////////////////// + QWidget* advancedTab = new QWidget( tabWidget ); + QGridLayout* advancedTabGrid = new QGridLayout( advancedTab ); + advancedTabGrid->setSpacing( spacingHint() ); + advancedTabGrid->setMargin( marginHint() ); + + QGroupBox* groupGeneral = new QGroupBox( 2, Qt::Vertical, i18n("General"), advancedTab ); + groupGeneral->setInsideSpacing( spacingHint() ); + groupGeneral->setInsideMargin( marginHint() ); + QHBox* box = new QHBox( groupGeneral ); + box->setSpacing( spacingHint() ); + box->setStretchFactor( new QLabel( i18n("Read retries:"), box ), 1 ); + m_spinRetries = new QSpinBox( 1, 128, 1, box ); + m_checkIgnoreReadErrors = new QCheckBox( i18n("Ignore read errors"), groupGeneral ); + + advancedTabGrid->addWidget( groupGeneral, 0, 0 ); + + tabWidget->addTab( advancedTab, i18n("&Advanced") ); + // ////////////////////////////////////////////////////////////////////////// + + + // + // setup layout + // ////////////////////////////////////////////////////////////////////////// + QGridLayout* grid = new QGridLayout( w ); + grid->setMargin( 0 ); + grid->setSpacing( spacingHint() ); + + grid->addWidget( groupSource, 0, 0 ); + grid->addWidget( m_writerSelectionWidget, 1, 0 ); + grid->addWidget( tabWidget, 2, 0 ); + grid->setRowStretch( 2, 1 ); + // ////////////////////////////////////////////////////////////////////////// + + + // tab order + setTabOrder( m_writingModeWidget, m_spinCopies ); + setTabOrder( m_spinCopies, groupOptions ); + + + // + // setup connections + // ////////////////////////////////////////////////////////////////////////// + connect( m_writerSelectionWidget, SIGNAL(writerChanged()), this, SLOT(slotToggleAll()) ); + connect( m_comboSourceDevice, SIGNAL(selectionChanged(K3bDevice::Device*)), this, SLOT(slotToggleAll()) ); + connect( m_comboSourceDevice, SIGNAL(selectionChanged(K3bDevice::Device*)), + this, SLOT(slotSourceMediumChanged(K3bDevice::Device*)) ); + connect( m_checkSimulate, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) ); + connect( m_checkCacheImage, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) ); + connect( m_checkOnlyCreateImage, SIGNAL(toggled(bool)), this, SLOT(slotToggleAll()) ); + connect( m_writingModeWidget, SIGNAL(writingModeChanged(int)), this, SLOT(slotToggleAll()) ); + + QToolTip::add( m_checkIgnoreReadErrors, i18n("Skip unreadable sectors") ); + QWhatsThis::add( m_checkIgnoreReadErrors, i18n("<p>If this option is checked and K3b is not able to read a sector from the " + "source CD/DVD it will be replaced with zeros on the resulting copy.") ); +} + + +K3bDvdCopyDialog::~K3bDvdCopyDialog() +{ +} + + +void K3bDvdCopyDialog::init() +{ + slotSourceMediumChanged( m_comboSourceDevice->selectedDevice() ); +} + + +void K3bDvdCopyDialog::setReadingDevice( K3bDevice::Device* dev ) +{ + m_comboSourceDevice->setSelectedDevice( dev ); +} + + +K3bDevice::Device* K3bDvdCopyDialog::readingDevice() const +{ + return m_comboSourceDevice->selectedDevice(); +} + + +void K3bDvdCopyDialog::slotStartClicked() +{ + // + // Let's check the available size + // + if( m_checkCacheImage->isChecked() || m_checkOnlyCreateImage->isChecked() ) { + if( neededSize()/1024 > m_tempDirSelectionWidget->freeTempSpace() ) { + if( KMessageBox::warningContinueCancel( this, i18n("There seems to be not enough free space in temporary directory. " + "Write anyway?") ) == KMessageBox::Cancel ) + return; + } + } + + // + // The job asks if we want to overwrite. + // + + K3bJobProgressDialog* dlg = 0; + if( m_checkOnlyCreateImage->isChecked() ) { + dlg = new K3bJobProgressDialog( kapp->mainWidget() ); + } + else { + dlg = new K3bBurnProgressDialog( kapp->mainWidget() ); + } + + K3bDvdCopyJob* job = new K3bDvdCopyJob( dlg, this ); + + job->setWriterDevice( m_writerSelectionWidget->writerDevice() ); + job->setReaderDevice( m_comboSourceDevice->selectedDevice() ); + job->setImagePath( m_tempDirSelectionWidget->tempPath() ); + job->setRemoveImageFiles( m_checkDeleteImages->isChecked() && !m_checkOnlyCreateImage->isChecked() ); + job->setOnlyCreateImage( m_checkOnlyCreateImage->isChecked() ); + job->setSimulate( m_checkSimulate->isChecked() ); + job->setOnTheFly( !m_checkCacheImage->isChecked() ); + job->setWriteSpeed( m_writerSelectionWidget->writerSpeed() ); + job->setCopies( m_checkSimulate->isChecked() ? 1 : m_spinCopies->value() ); + job->setWritingMode( m_writingModeWidget->writingMode() ); + job->setIgnoreReadErrors( m_checkIgnoreReadErrors->isChecked() ); + job->setReadRetries( m_spinRetries->value() ); + job->setVerifyData( m_checkVerifyData->isChecked() ); + + if( !exitLoopOnHide() ) + hide(); + + dlg->startJob( job ); + + delete dlg; + delete job; + + if( KConfigGroup( k3bcore->config(), "General Options" ).readBoolEntry( "keep action dialogs open", false ) && + !exitLoopOnHide() ) + show(); + else + close(); +} + + +void K3bDvdCopyDialog::loadUserDefaults( KConfigBase* c ) +{ + m_comboSourceDevice->setSelectedDevice( k3bcore->deviceManager()->findDevice( c->readEntry( "source_device" ) ) ); + + m_writerSelectionWidget->loadConfig( c ); + + m_writingModeWidget->loadConfig( c ); + + m_tempDirSelectionWidget->readConfig( c ); + + m_checkSimulate->setChecked( c->readBoolEntry( "simulate", false ) ); + m_checkCacheImage->setChecked( !c->readBoolEntry( "on_the_fly", false ) ); + m_checkOnlyCreateImage->setChecked( c->readBoolEntry( "only_create_image", false ) ); + m_checkDeleteImages->setChecked( c->readBoolEntry( "remove_image", true ) ); + m_checkIgnoreReadErrors->setChecked( c->readBoolEntry( "ignore read errors", false ) ); + m_spinRetries->setValue( c->readNumEntry( "retries", 128 ) ); + m_spinCopies->setValue( c->readNumEntry( "copies", 1 ) ); + m_checkVerifyData->setChecked( c->readBoolEntry( "verify data", false ) ); + + slotToggleAll(); +} + + +void K3bDvdCopyDialog::saveUserDefaults( KConfigBase* c ) +{ + m_tempDirSelectionWidget->saveConfig(); + + m_writingModeWidget->saveConfig( c ); + m_tempDirSelectionWidget->saveConfig( c ); + + c->writeEntry( "source_device", m_comboSourceDevice->selectedDevice() ? m_comboSourceDevice->selectedDevice()->devicename() : QString() ); + + c->writeEntry( "simulate", m_checkSimulate->isChecked() ); + c->writeEntry( "on_the_fly", !m_checkCacheImage->isChecked() ); + c->writeEntry( "only_create_image", m_checkOnlyCreateImage->isChecked() ); + c->writeEntry( "remove_image", m_checkDeleteImages->isChecked() ); + c->writeEntry( "ignore read errors", m_checkIgnoreReadErrors->isChecked() ); + c->writeEntry( "retries", m_spinRetries->value() ); + c->writeEntry( "copies", m_spinCopies->value() ); + c->writeEntry( "verify data", m_checkVerifyData->isChecked() ); + + m_writerSelectionWidget->saveConfig( c ); + + if( m_tempDirSelectionWidget->isEnabled() ) + m_tempDirSelectionWidget->saveConfig(); +} + + +void K3bDvdCopyDialog::loadK3bDefaults() +{ + m_writerSelectionWidget->loadDefaults(); + m_tempDirSelectionWidget->setTempPath( K3b::defaultTempPath() ); + + m_writingModeWidget->setWritingMode( K3b::WRITING_MODE_AUTO ); + + m_checkSimulate->setChecked( false ); + m_checkCacheImage->setChecked( true ); + m_checkOnlyCreateImage->setChecked( false ); + m_checkDeleteImages->setChecked( true ); + m_checkIgnoreReadErrors->setChecked(false); + m_spinCopies->setValue( 1 ); + m_spinRetries->setValue(128); + m_checkVerifyData->setChecked( false ); + + slotToggleAll(); +} + + +void K3bDvdCopyDialog::toggleAll() +{ + updateOverrideDevice(); + + m_checkSimulate->setDisabled( m_checkOnlyCreateImage->isChecked() ); + m_checkCacheImage->setDisabled( m_checkOnlyCreateImage->isChecked() ); + + K3bDevice::Device* dev = m_writerSelectionWidget->writerDevice(); + if( dev ) { + // select the proper writing modes + // if writing and reading devices are the same we cannot use + // K3bWritingModeWidget::determineSupportedModesFromMedium since the inserted medium is not the one we + // will be using for burning. In that case we go the old fashioned way. + if( dev == m_comboSourceDevice->selectedDevice() ) { + int modes = 0; + if( dev->type() & (K3bDevice::DVDR|K3bDevice::DVDRW) ) { + modes |= K3b::DAO|K3b::WRITING_MODE_RES_OVWR; + if( dev->featureCurrent( K3bDevice::FEATURE_INCREMENTAL_STREAMING_WRITABLE ) != 0 ) + modes |= K3b::WRITING_MODE_INCR_SEQ; + } + + m_writingModeWidget->setSupportedModes( modes ); + m_checkSimulate->setDisabled( m_checkOnlyCreateImage->isChecked() ); + } + else { + m_writingModeWidget->determineSupportedModesFromMedium( dev ); + + if( k3bappcore->mediaCache()->diskInfo( dev ).mediaType() & K3bDevice::MEDIA_DVD_PLUS_ALL ) { + // no simulation support for DVD+R(W) media + m_checkSimulate->setChecked(false); + m_checkSimulate->setEnabled(false); + } + else { + m_checkSimulate->setDisabled( m_checkOnlyCreateImage->isChecked() ); + } + } + } + + + + m_writingModeWidget->setDisabled( m_checkOnlyCreateImage->isChecked() ); + m_writerSelectionWidget->setDisabled( m_checkOnlyCreateImage->isChecked() ); + m_tempDirSelectionWidget->setDisabled( !m_checkCacheImage->isChecked() && !m_checkOnlyCreateImage->isChecked() ); + m_writingModeWidget->setDisabled( m_checkOnlyCreateImage->isChecked() ); + m_checkDeleteImages->setDisabled( m_checkOnlyCreateImage->isChecked() || !m_checkCacheImage->isChecked() ); + m_spinCopies->setDisabled( m_checkSimulate->isChecked() || m_checkOnlyCreateImage->isChecked() ); + m_checkVerifyData->setDisabled( m_checkOnlyCreateImage->isChecked() || m_checkSimulate->isChecked() ); + + setButtonEnabled( START_BUTTON, m_comboSourceDevice->selectedDevice() && + (dev || m_checkOnlyCreateImage->isChecked()) ); +} + + +void K3bDvdCopyDialog::slotSourceMediumChanged( K3bDevice::Device* dev ) +{ + updateOverrideDevice(); + + K3bMedium medium = k3bappcore->mediaCache()->medium( dev ); + + m_writerSelectionWidget->setWantedMediumType( k3bappcore->mediaCache()->diskInfo( dev ).numLayers() > 1 && + k3bappcore->mediaCache()->diskInfo( dev ).size().mode1Bytes() > 4700372992LL + ? K3bDevice::MEDIA_WRITABLE_DVD_DL + : K3bDevice::MEDIA_WRITABLE_DVD_SL ); + + m_tempDirSelectionWidget->setNeededSize( neededSize() ); + + m_tempDirSelectionWidget->setDefaultImageFileName( medium.volumeId().lower() + ".iso" ); + + toggleAll(); +} + + +void K3bDvdCopyDialog::updateOverrideDevice() +{ + if( !m_checkCacheImage->isChecked() ) { + m_writerSelectionWidget->setOverrideDevice( 0 ); + m_writerSelectionWidget->setIgnoreDevice( m_comboSourceDevice->selectedDevice() ); + } + else { + m_writerSelectionWidget->setIgnoreDevice( 0 ); + m_writerSelectionWidget->setOverrideDevice( m_comboSourceDevice->selectedDevice(), + i18n("Use the same device for burning"), + i18n("<qt>Use the same device for burning <i>(Or insert another medium)</i>") ); + } +} + + +KIO::filesize_t K3bDvdCopyDialog::neededSize() const +{ + K3bMedium medium = k3bappcore->mediaCache()->medium( m_comboSourceDevice->selectedDevice() ); + + if( medium.diskInfo().diskState() == K3bDevice::STATE_NO_MEDIA ) + return 0; + else if( medium.diskInfo().mediaType() & (K3bDevice::MEDIA_DVD_RW_OVWR|K3bDevice::MEDIA_DVD_PLUS_RW) ) + return (KIO::filesize_t)medium.iso9660Descriptor().volumeSpaceSize * (KIO::filesize_t)2048; + else + return medium.diskInfo().size().mode1Bytes(); +} + +#include "k3bdvdcopydialog.moc" diff --git a/src/misc/k3bdvdcopydialog.h b/src/misc/k3bdvdcopydialog.h new file mode 100644 index 0000000..be696c4 --- /dev/null +++ b/src/misc/k3bdvdcopydialog.h @@ -0,0 +1,79 @@ +/* + * + * $Id: k3bdvdcopydialog.h 619556 2007-01-03 17:38:12Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + + +#ifndef _K3B_DVD_COPY_DIALOG_H_ +#define _K3B_DVD_COPY_DIALOG_H_ + +#include <k3binteractiondialog.h> + +#include <kio/global.h> + + +namespace K3bDevice { + class Device; + class DeviceManager; +} + +class K3bTempDirSelectionWidget; +class K3bWriterSelectionWidget; +class K3bMediaSelectionComboBox; +class QCheckBox; +class QSpinBox; +class K3bWritingModeWidget; + + +class K3bDvdCopyDialog : public K3bInteractionDialog +{ + Q_OBJECT + + public: + K3bDvdCopyDialog( QWidget* parent = 0, const char* name = 0, bool modal = true ); + ~K3bDvdCopyDialog(); + + void setReadingDevice( K3bDevice::Device* ); + K3bDevice::Device* readingDevice() const; + + private slots: + void slotStartClicked(); + void slotSourceMediumChanged( K3bDevice::Device* ); + void updateOverrideDevice(); + + protected: + void init(); + void toggleAll(); + + private: + void loadUserDefaults( KConfigBase* ); + void saveUserDefaults( KConfigBase* ); + void loadK3bDefaults(); + + KIO::filesize_t neededSize() const; + + K3bWriterSelectionWidget* m_writerSelectionWidget; + K3bTempDirSelectionWidget* m_tempDirSelectionWidget; + K3bMediaSelectionComboBox* m_comboSourceDevice; + QCheckBox* m_checkSimulate; + QCheckBox* m_checkDeleteImages; + QCheckBox* m_checkOnlyCreateImage; + QCheckBox* m_checkCacheImage; + QCheckBox* m_checkVerifyData; + QSpinBox* m_spinCopies; + QSpinBox* m_spinRetries; + QCheckBox* m_checkIgnoreReadErrors; + K3bWritingModeWidget* m_writingModeWidget; +}; + +#endif diff --git a/src/misc/k3bdvdformattingdialog.cpp b/src/misc/k3bdvdformattingdialog.cpp new file mode 100644 index 0000000..d84c4fc --- /dev/null +++ b/src/misc/k3bdvdformattingdialog.cpp @@ -0,0 +1,185 @@ +/* + * + * $Id: k3bdvdformattingdialog.cpp 640188 2007-03-07 09:15:25Z trueg $ + * Copyright (C) 2003-2007 Sebastian Trueg <trueg@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#include "k3bdvdformattingdialog.h" +#include "k3bdvdformattingjob.h" + +#include <k3bdevice.h> +#include <k3bdevicemanager.h> +#include <k3bglobals.h> +#include <k3bcore.h> +#include <k3bwriterselectionwidget.h> +#include <k3bwritingmodewidget.h> +#include <k3bjobprogressdialog.h> + +#include <klocale.h> +#include <kmessagebox.h> +#include <kconfig.h> +#include <kapplication.h> + +#include <qgroupbox.h> +#include <qlayout.h> +#include <qcheckbox.h> +#include <qframe.h> +#include <qpushbutton.h> +#include <qtooltip.h> +#include <qwhatsthis.h> + + +K3bDvdFormattingDialog::K3bDvdFormattingDialog( QWidget* parent, const char* name, bool modal ) + : K3bInteractionDialog( parent, name, + i18n("DVD Formatting"), + i18n("DVD%1RW").arg("±"), + START_BUTTON|CANCEL_BUTTON, + START_BUTTON, + "DVD Formatting", // config group + modal ) +{ + QWidget* frame = mainWidget(); + + m_writerSelectionWidget = new K3bWriterSelectionWidget( frame ); + m_writerSelectionWidget->setWantedMediumType( K3bDevice::MEDIA_REWRITABLE_DVD ); + // we need state empty here for preformatting DVD+RW. + m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_COMPLETE| + K3bDevice::STATE_INCOMPLETE| + K3bDevice::STATE_EMPTY ); + m_writerSelectionWidget->setSupportedWritingApps( K3b::DVD_RW_FORMAT ); + m_writerSelectionWidget->setForceAutoSpeed(true); + + QGroupBox* groupWritingMode = new QGroupBox( 1, Qt::Vertical, i18n("Writing Mode"), frame ); + groupWritingMode->layout()->setMargin( marginHint() ); + groupWritingMode->layout()->setSpacing( spacingHint() ); + m_writingModeWidget = new K3bWritingModeWidget( K3b::WRITING_MODE_INCR_SEQ|K3b::WRITING_MODE_RES_OVWR, + groupWritingMode ); + + + QGroupBox* groupOptions = new QGroupBox( 2, Qt::Vertical, i18n("Settings"), frame ); + groupOptions->layout()->setMargin( marginHint() ); + groupOptions->layout()->setSpacing( spacingHint() ); + m_checkForce = new QCheckBox( i18n("Force"), groupOptions ); + m_checkQuickFormat = new QCheckBox( i18n("Quick format"), groupOptions ); + + QGridLayout* grid = new QGridLayout( frame ); + grid->setMargin( 0 ); + grid->setSpacing( spacingHint() ); + + grid->addMultiCellWidget( m_writerSelectionWidget, 0, 0, 0, 1 ); + grid->addWidget( groupWritingMode, 1, 0 ); + grid->addWidget( groupOptions, 1, 1 ); + grid->setRowStretch( 1, 1 ); + + + QToolTip::add( m_checkForce, i18n("Force formatting of empty DVDs") ); + QWhatsThis::add( m_checkForce, i18n("<p>If this option is checked K3b will format a " + "DVD-RW even if it is empty. It may also be used to " + "force K3b to format a DVD+RW or a DVD-RW in restricted " + "overwrite mode." + "<p><b>Caution:</b> It is not recommended to often format a DVD " + "since it may already be unusable after 10-20 reformat procedures." + "<p>DVD+RW media only needs to be formatted once. After that it " + "just needs to be overwritten. The same applies to DVD-RW in " + "restricted overwrite mode.") ); + + QToolTip::add( m_checkQuickFormat, i18n("Try to perform quick formatting") ); + QWhatsThis::add( m_checkQuickFormat, i18n("<p>If this option is checked K3b will tell the writer " + "to perform a quick format." + "<p>Formatting a DVD-RW completely can take a very long " + "time and some DVD writers perform a full format even if " + "quick format is enabled." ) ); + + connect( m_writerSelectionWidget, SIGNAL(writerChanged()), this, SLOT(slotWriterChanged()) ); + connect( m_writerSelectionWidget, SIGNAL(writerChanged(K3bDevice::Device*)), + m_writingModeWidget, SLOT(determineSupportedModesFromMedium(K3bDevice::Device*)) ); + + slotWriterChanged(); +} + + +K3bDvdFormattingDialog::~K3bDvdFormattingDialog() +{ +} + + +void K3bDvdFormattingDialog::setDevice( K3bDevice::Device* dev ) +{ + m_writerSelectionWidget->setWriterDevice( dev ); +} + + +void K3bDvdFormattingDialog::slotStartClicked() +{ + // + // create a jobprogressdialog and start the job + // + + + + K3bJobProgressDialog d( kapp->mainWidget(), "formattingProgress", false ); + + K3bDvdFormattingJob* job = new K3bDvdFormattingJob( &d, this ); + job->setDevice( m_writerSelectionWidget->writerDevice() ); + job->setMode( m_writingModeWidget->writingMode() ); + job->setForce( m_checkForce->isChecked() ); + job->setQuickFormat( m_checkQuickFormat->isChecked() ); + + if( !exitLoopOnHide() ) + hide(); + + d.startJob( job ); + + delete job; + + if( KConfigGroup( k3bcore->config(), "General Options" ).readBoolEntry( "keep action dialogs open", false ) && + !exitLoopOnHide() ) + show(); + else + close(); +} + + +void K3bDvdFormattingDialog::slotWriterChanged() +{ + setButtonEnabled( START_BUTTON, m_writerSelectionWidget->writerDevice() != 0 ); +} + + +void K3bDvdFormattingDialog::loadUserDefaults( KConfigBase* c ) +{ + m_checkForce->setChecked( c->readBoolEntry( "force", false ) ); + m_checkQuickFormat->setChecked( c->readBoolEntry( "quick format", true ) ); + m_writerSelectionWidget->loadConfig( c ); + m_writingModeWidget->loadConfig( c ); +} + + +void K3bDvdFormattingDialog::saveUserDefaults( KConfigBase* c ) +{ + c->writeEntry( "force", m_checkForce->isChecked() ); + c->writeEntry( "quick format", m_checkQuickFormat->isChecked() ); + m_writerSelectionWidget->saveConfig( c ); + m_writingModeWidget->saveConfig( c ); +} + + +void K3bDvdFormattingDialog::loadK3bDefaults() +{ + m_writerSelectionWidget->loadDefaults(); + m_checkForce->setChecked( false ); + m_checkQuickFormat->setChecked( true ); + m_writingModeWidget->setWritingMode( K3b::WRITING_MODE_AUTO ); +} + + +#include "k3bdvdformattingdialog.moc" diff --git a/src/misc/k3bdvdformattingdialog.h b/src/misc/k3bdvdformattingdialog.h new file mode 100644 index 0000000..1314ae1 --- /dev/null +++ b/src/misc/k3bdvdformattingdialog.h @@ -0,0 +1,55 @@ +/* + * + * $Id: k3bdvdformattingdialog.h 619556 2007-01-03 17:38:12Z trueg $ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + +#ifndef _K3B_DVD_FORMATTING_DIALOG_H_ +#define _K3B_DVD_FORMATTING_DIALOG_H_ + +#include <k3binteractiondialog.h> + + +class QCheckBox; +class K3bWritingModeWidget; +class K3bWriterSelectionWidget; +namespace K3bDevice { + class Device; +} + +class K3bDvdFormattingDialog : public K3bInteractionDialog +{ + Q_OBJECT + + public: + K3bDvdFormattingDialog( QWidget* = 0, const char* = 0, bool modal = true ); + ~K3bDvdFormattingDialog(); + + public slots: + void setDevice( K3bDevice::Device* ); + + protected slots: + void slotStartClicked(); + void slotWriterChanged(); + + private: + void loadUserDefaults( KConfigBase* ); + void saveUserDefaults( KConfigBase* ); + void loadK3bDefaults(); + + K3bWriterSelectionWidget* m_writerSelectionWidget; + K3bWritingModeWidget* m_writingModeWidget; + QCheckBox* m_checkForce; + QCheckBox* m_checkQuickFormat; +}; + +#endif diff --git a/src/misc/k3bisoimagewritingdialog.cpp b/src/misc/k3bisoimagewritingdialog.cpp new file mode 100644 index 0000000..1832ee5 --- /dev/null +++ b/src/misc/k3bisoimagewritingdialog.cpp @@ -0,0 +1,580 @@ +/* + * + * $Id$ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + + +#include "k3bisoimagewritingdialog.h" +#include "k3biso9660imagewritingjob.h" + +#include <k3bdevicemanager.h> +#include <k3bdevice.h> +#include <k3bwriterselectionwidget.h> +#include <k3bburnprogressdialog.h> +#include <kcutlabel.h> +#include <k3bstdguiitems.h> +#include <k3bmd5job.h> +#include <k3bglobals.h> +#include <k3bwritingmodewidget.h> +#include <k3bcore.h> +#include <k3blistview.h> +#include <k3biso9660.h> +#include <k3bapplication.h> +#include <k3bmediacache.h> + +#include <kapplication.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kurlrequester.h> +#include <kfiledialog.h> +#include <kstdguiitem.h> +#include <kguiitem.h> +#include <kiconloader.h> +#include <kconfig.h> +#include <kio/global.h> +#include <kurl.h> +#include <kinputdialog.h> +#include <kurldrag.h> +#include <klineedit.h> + +#include <qheader.h> +#include <qgroupbox.h> +#include <qcheckbox.h> +#include <qlabel.h> +#include <qcombobox.h> +#include <qlayout.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qpushbutton.h> +#include <qtabwidget.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qspinbox.h> +#include <qevent.h> +#include <qpopupmenu.h> +#include <qclipboard.h> + + +class K3bIsoImageWritingDialog::Private +{ +public: + Private() + : md5SumItem(0), + haveMd5Sum( false ), + imageForced( false ) { + } + + K3bListViewItem* md5SumItem; + bool haveMd5Sum; + QString lastCheckedFile; + bool isIsoImage; + + bool imageForced; +}; + + +K3bIsoImageWritingDialog::K3bIsoImageWritingDialog( QWidget* parent, const char* name, bool modal ) + : K3bInteractionDialog( parent, name, + i18n("Burn Iso9660 Image"), + i18n("to DVD"), + START_BUTTON|CANCEL_BUTTON, + START_BUTTON, + "DVD image writing", + modal ) +{ + d = new Private(); + + setAcceptDrops(true); + setupGui(); + + m_writerSelectionWidget->setWantedMediumType( K3bDevice::MEDIA_WRITABLE_DVD ); + m_writerSelectionWidget->setWantedMediumState( K3bDevice::STATE_EMPTY ); + m_writerSelectionWidget->setSupportedWritingApps( K3b::GROWISOFS ); + m_writingModeWidget->setSupportedModes( K3b::DAO|K3b::WRITING_MODE_INCR_SEQ|K3b::WRITING_MODE_RES_OVWR ); + + m_md5Job = new K3bMd5Job( 0, this ); + connect( m_md5Job, SIGNAL(finished(bool)), + this, SLOT(slotMd5JobFinished(bool)) ); + connect( m_md5Job, SIGNAL(percent(int)), + this, SLOT(slotMd5JobPercent(int)) ); + + updateImageSize( imagePath() ); + + connect( m_writerSelectionWidget, SIGNAL(writerChanged()), + this, SLOT(slotWriterChanged()) ); + connect( m_writerSelectionWidget, SIGNAL(writingAppChanged(int)), + this, SLOT(slotWriterChanged()) ); + connect( m_writingModeWidget, SIGNAL(writingModeChanged(int)), + this, SLOT(slotWriterChanged()) ); + connect( m_editImagePath, SIGNAL(textChanged(const QString&)), + this, SLOT(updateImageSize(const QString&)) ); + connect( m_checkDummy, SIGNAL(toggled(bool)), + this, SLOT(slotWriterChanged()) ); +} + + +K3bIsoImageWritingDialog::~K3bIsoImageWritingDialog() +{ + delete d; +} + + +void K3bIsoImageWritingDialog::init() +{ + if( !d->imageForced ) { + // when opening the dialog first the default settings are loaded and afterwards we set the + // last written image because that's what most users want + KConfig* c = k3bcore->config(); + c->setGroup( configGroup() ); + QString image = c->readPathEntry( "last written image" ); + if( QFile::exists( image ) ) + m_editImagePath->setURL( image ); + } +} + + +void K3bIsoImageWritingDialog::setupGui() +{ + QWidget* frame = mainWidget(); + + // image + // ----------------------------------------------------------------------- + QGroupBox* groupImageUrl = new QGroupBox( 1, Qt::Horizontal, i18n("Image to Burn"), frame ); + m_editImagePath = new KURLRequester( groupImageUrl ); + m_editImagePath->setMode( KFile::File|KFile::ExistingOnly ); + m_editImagePath->setCaption( i18n("Choose Image File") ); + m_editImagePath->setFilter( i18n("*.iso *.ISO|ISO9660 Image Files") + "\n" + + i18n("*|All Files") ); + + connect( m_editImagePath->lineEdit(), SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotWriterChanged() ) ); + + // image info + // ----------------------------------------------------------------------- + m_infoView = new K3bListView( frame ); + m_infoView->addColumn( "key" ); + m_infoView->addColumn( "value" ); + m_infoView->header()->hide(); + m_infoView->setNoItemText( i18n("No image file selected") ); + m_infoView->setSorting( -1 ); + m_infoView->setAlternateBackground( QColor() ); + m_infoView->setFullWidth(true); + m_infoView->setSelectionMode( QListView::NoSelection ); + + connect( m_infoView, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), + this, SLOT(slotContextMenu(KListView*, QListViewItem*, const QPoint&)) ); + + m_writerSelectionWidget = new K3bWriterSelectionWidget( frame ); + + // options + // ----------------------------------------------------------------------- + QTabWidget* optionTabbed = new QTabWidget( frame ); + + QWidget* optionTab = new QWidget( optionTabbed ); + QGridLayout* optionTabLayout = new QGridLayout( optionTab ); + optionTabLayout->setAlignment( Qt::AlignTop ); + optionTabLayout->setSpacing( spacingHint() ); + optionTabLayout->setMargin( marginHint() ); + + QGroupBox* writingModeGroup = new QGroupBox( 1, Vertical, i18n("Writing Mode"), optionTab ); + writingModeGroup->setInsideMargin( marginHint() ); + m_writingModeWidget = new K3bWritingModeWidget( writingModeGroup ); + + + // copies -------- + QGroupBox* groupCopies = new QGroupBox( 2, Qt::Horizontal, i18n("Copies"), optionTab ); + groupCopies->setInsideSpacing( spacingHint() ); + groupCopies->setInsideMargin( marginHint() ); + QLabel* pixLabel = new QLabel( groupCopies ); + pixLabel->setPixmap( SmallIcon( "cdcopy", KIcon::SizeMedium ) ); + pixLabel->setScaledContents( false ); + m_spinCopies = new QSpinBox( groupCopies ); + m_spinCopies->setMinValue( 1 ); + m_spinCopies->setMaxValue( 999 ); + // -------- copies + + QGroupBox* optionGroup = new QGroupBox( 3, Vertical, i18n("Settings"), optionTab ); + optionGroup->setInsideMargin( marginHint() ); + optionGroup->setInsideSpacing( spacingHint() ); + m_checkDummy = K3bStdGuiItems::simulateCheckbox( optionGroup ); + m_checkVerify = K3bStdGuiItems::verifyCheckBox( optionGroup ); + + + optionTabLayout->addWidget( writingModeGroup, 0, 0 ); + optionTabLayout->addWidget( groupCopies, 1, 0 ); + optionTabLayout->addMultiCellWidget( optionGroup, 0, 1, 1, 1 ); + optionTabLayout->setRowStretch( 1, 1 ); + optionTabLayout->setColStretch( 1, 1 ); + + optionTabbed->addTab( optionTab, i18n("Settings") ); + + + QGridLayout* grid = new QGridLayout( frame ); + grid->setSpacing( spacingHint() ); + grid->setMargin( 0 ); + + grid->addWidget( groupImageUrl, 0, 0 ); + grid->addWidget( m_infoView, 1, 0 ); + grid->addWidget( m_writerSelectionWidget, 2, 0 ); + grid->addWidget( optionTabbed, 3, 0 ); + + grid->setRowStretch( 1, 1 ); +} + + +void K3bIsoImageWritingDialog::slotStartClicked() +{ + if( !d->isIsoImage ) { + if( KMessageBox::warningContinueCancel( this, + i18n("The image you selected is not a valid ISO9660 image. " + "Are you sure you want to burn it anyway? " + "(There may exist other valid image types that are not detected by K3b but " + "will work fine.)"), i18n("Burn") ) == KMessageBox::Cancel ) + return; + } + + K3bIso9660 isoFs( imagePath() ); + if( isoFs.open() ) { + if( K3b::imageFilesize( KURL::fromPathOrURL( imagePath() ) ) < (KIO::filesize_t)(isoFs.primaryDescriptor().volumeSpaceSize*2048) ) { + if( KMessageBox::questionYesNo( this, + i18n("<p>This image has an invalid file size." + "If it has been downloaded make sure the download is complete." + "<p>Only continue if you know what you are doing."), + i18n("Warning"), + i18n("Continue"), + i18n("Cancel") ) == KMessageBox::No ) + return; + } + } + + m_md5Job->cancel(); + + // save the path + KConfig* c = k3bcore->config(); + c->setGroup( configGroup() ); + if( c->readPathEntry( "last written image" ).isEmpty() ) + c->writePathEntry( "last written image", imagePath() ); + + // create a progresswidget + K3bBurnProgressDialog dlg( kapp->mainWidget(), "burnProgress", true ); + + // create the job + K3bIso9660ImageWritingJob* job = new K3bIso9660ImageWritingJob( &dlg ); + + job->setBurnDevice( m_writerSelectionWidget->writerDevice() ); + job->setSpeed( m_writerSelectionWidget->writerSpeed() ); + job->setSimulate( m_checkDummy->isChecked() ); + job->setWritingMode( m_writingModeWidget->writingMode() ); + job->setVerifyData( m_checkVerify->isChecked() ); + job->setCopies( m_checkDummy->isChecked() ? 1 : m_spinCopies->value() ); + job->setImagePath( imagePath() ); + + // HACK (needed since if the medium is forced the stupid K3bIso9660ImageWritingJob defaults to cd writing) + job->setWritingApp( K3b::GROWISOFS ); + + if( !exitLoopOnHide() ) + hide(); + + dlg.startJob( job ); + + delete job; + + if( KConfigGroup( k3bcore->config(), "General Options" ).readBoolEntry( "keep action dialogs open", false ) && + !exitLoopOnHide() ) + show(); + else + close(); +} + + +void K3bIsoImageWritingDialog::updateImageSize( const QString& path ) +{ + m_md5Job->cancel(); + m_infoView->clear(); + d->md5SumItem = 0; + d->haveMd5Sum = false; + d->isIsoImage = false; + + QFileInfo info( path ); + if( info.isFile() ) { + + KIO::filesize_t imageSize = K3b::filesize( KURL::fromPathOrURL(path) ); + + // ------------------------------------------------ + // Test for iso9660 image + // ------------------------------------------------ + K3bIso9660 isoF( path ); + if( isoF.open() ) { + + d->isIsoImage = true; + + K3bListViewItem* isoRootItem = new K3bListViewItem( m_infoView, m_infoView->lastItem(), + i18n("Iso9660 image") ); + isoRootItem->setForegroundColor( 0, palette().disabled().foreground() ); + isoRootItem->setPixmap( 0, SmallIcon( "cdimage") ); + + K3bListViewItem* item = new K3bListViewItem( isoRootItem, m_infoView->lastItem(), + i18n("Filesize:"), KIO::convertSize( imageSize ) ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("System Id:"), + isoF.primaryDescriptor().systemId.isEmpty() + ? QString("-") + : isoF.primaryDescriptor().systemId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Volume Id:"), + isoF.primaryDescriptor().volumeId.isEmpty() + ? QString("-") + : isoF.primaryDescriptor().volumeId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Volume Set Id:"), + isoF.primaryDescriptor().volumeSetId.isEmpty() + ? QString("-") + : isoF.primaryDescriptor().volumeSetId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Publisher Id:"), + isoF.primaryDescriptor().publisherId.isEmpty() + ? QString("-") + : isoF.primaryDescriptor().publisherId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Preparer Id:"), + isoF.primaryDescriptor().preparerId.isEmpty() + ? QString("-") : isoF.primaryDescriptor().preparerId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + item = new K3bListViewItem( isoRootItem, + m_infoView->lastItem(), + i18n("Application Id:"), + isoF.primaryDescriptor().applicationId.isEmpty() + ? QString("-") + : isoF.primaryDescriptor().applicationId ); + item->setForegroundColor( 0, palette().disabled().foreground() ); + + isoRootItem->setOpen( true ); + + isoF.close(); + } + else { + K3bListViewItem* item = new K3bListViewItem( m_infoView, m_infoView->lastItem(), + i18n("Not an Iso9660 image") ); + item->setForegroundColor( 0, Qt::red ); + item->setPixmap( 0, SmallIcon( "stop") ); + } + + calculateMd5Sum( path ); + } + + slotWriterChanged(); +} + + +void K3bIsoImageWritingDialog::slotWriterChanged() +{ + K3bDevice::Device* dev = m_writerSelectionWidget->writerDevice(); + if( dev ) { + K3bMedium medium = k3bappcore->mediaCache()->medium( dev ); + if( medium.diskInfo().mediaType() & K3bDevice::MEDIA_DVD_PLUS_ALL ) { + // no simulation support for DVD+R(W) media + m_checkDummy->setChecked(false); + m_checkDummy->setEnabled(false); + } + else { + m_checkDummy->setDisabled( false ); + } + + m_writingModeWidget->determineSupportedModesFromMedium( dev ); + + if( m_checkDummy->isChecked() ) { + m_checkVerify->setEnabled( false ); + m_checkVerify->setChecked( false ); + } + else + m_checkVerify->setEnabled( true ); + + m_spinCopies->setEnabled( !m_checkDummy->isChecked() ); + } + + setButtonEnabled( START_BUTTON, + dev && !m_editImagePath->lineEdit()->text().isEmpty() ); +} + + +void K3bIsoImageWritingDialog::setImage( const KURL& url ) +{ + d->imageForced = true; +#if KDE_IS_VERSION(3,4,0) + m_editImagePath->setKURL( url ); +#else + m_editImagePath->setURL( url.path() ); +#endif +} + + +void K3bIsoImageWritingDialog::calculateMd5Sum( const QString& file ) +{ + d->haveMd5Sum = false; + + if( !d->md5SumItem ) + d->md5SumItem = new K3bListViewItem( m_infoView, m_infoView->firstChild() ); + + d->md5SumItem->setText( 0, i18n("Md5 Sum:") ); + d->md5SumItem->setForegroundColor( 0, palette().disabled().foreground() ); + d->md5SumItem->setProgress( 1, 0 ); + d->md5SumItem->setPixmap( 0, SmallIcon( "exec") ); + + if( file != d->lastCheckedFile ) { + d->lastCheckedFile = file; + m_md5Job->setFile( file ); + m_md5Job->start(); + } + else + slotMd5JobFinished( true ); +} + + +void K3bIsoImageWritingDialog::slotMd5JobPercent( int p ) +{ + d->md5SumItem->setProgress( 1, p ); +} + + +void K3bIsoImageWritingDialog::slotMd5JobFinished( bool success ) +{ + if( success ) { + d->md5SumItem->setText( 1, m_md5Job->hexDigest() ); + d->haveMd5Sum = true; + } + else { + d->md5SumItem->setForegroundColor( 1, Qt::red ); + if( m_md5Job->hasBeenCanceled() ) + d->md5SumItem->setText( 1, i18n("Calculation cancelled") ); + else + d->md5SumItem->setText( 1, i18n("Calculation failed") ); + d->md5SumItem->setPixmap( 0, SmallIcon( "stop") ); + d->lastCheckedFile.truncate(0); + } + + d->md5SumItem->setDisplayProgressBar( 1, false ); +} + + +void K3bIsoImageWritingDialog::slotContextMenu( KListView*, QListViewItem*, const QPoint& pos ) +{ + if( !d->haveMd5Sum ) + return; + + QPopupMenu popup; + int copyItem = popup.insertItem( i18n("Copy checksum to clipboard") ); + int compareItem = popup.insertItem( i18n("Compare checksum...") ); + + int r = popup.exec( pos ); + + if( r == compareItem ) { + bool ok; + QString md5sumToCompare = KInputDialog::getText( i18n("MD5 Sum Check"), + i18n("Please insert the MD5 Sum to compare:"), + QString::null, + &ok, + this ); + if( ok ) { + if( md5sumToCompare.lower().utf8() == m_md5Job->hexDigest().lower() ) + KMessageBox::information( this, i18n("The MD5 Sum of %1 equals the specified.").arg(imagePath()), + i18n("MD5 Sums Equal") ); + else + KMessageBox::sorry( this, i18n("The MD5 Sum of %1 differs from the specified.").arg(imagePath()), + i18n("MD5 Sums Differ") ); + } + } + else if( r == copyItem ) { + QApplication::clipboard()->setText( m_md5Job->hexDigest().lower(), QClipboard::Clipboard ); + } +} + + +void K3bIsoImageWritingDialog::loadUserDefaults( KConfigBase* c ) +{ + m_writingModeWidget->loadConfig( c ); + m_checkDummy->setChecked( c->readBoolEntry("simulate", false ) ); + m_checkVerify->setChecked( c->readBoolEntry( "verify_data", false ) ); + m_spinCopies->setValue( c->readNumEntry( "copies", 1 ) ); + + m_writerSelectionWidget->loadConfig( c ); + + if( !d->imageForced ) { + QString image = c->readPathEntry( "image path", c->readPathEntry( "last written image" ) ); + if( QFile::exists( image ) ) + m_editImagePath->setURL( image ); + } +} + + +void K3bIsoImageWritingDialog::saveUserDefaults( KConfigBase* c ) +{ + m_writingModeWidget->saveConfig( c ), + c->writeEntry( "simulate", m_checkDummy->isChecked() ); + c->writeEntry( "verify_data", m_checkVerify->isChecked() ); + c->writeEntry( "copies", m_spinCopies->value() ); + + m_writerSelectionWidget->saveConfig( c ); + + c->writePathEntry( "image path", imagePath() ); +} + + +void K3bIsoImageWritingDialog::loadK3bDefaults() +{ + m_writerSelectionWidget->loadDefaults(); + m_writingModeWidget->setWritingMode( K3b::WRITING_MODE_AUTO ); + m_checkDummy->setChecked( false ); + m_checkVerify->setChecked( false ); + m_spinCopies->setValue( 1 ); +} + + +QString K3bIsoImageWritingDialog::imagePath() const +{ + return K3b::convertToLocalUrl( KURL::fromPathOrURL( m_editImagePath->url() ) ).path(); +} + + +void K3bIsoImageWritingDialog::dragEnterEvent( QDragEnterEvent* e ) +{ + e->accept( KURLDrag::canDecode(e) ); +} + + +void K3bIsoImageWritingDialog::dropEvent( QDropEvent* e ) +{ + KURL::List urls; + KURLDrag::decode( e, urls ); +#if KDE_IS_VERSION(3,4,0) + m_editImagePath->setKURL( urls.first() ); +#else + m_editImagePath->setURL( urls.first().path() ); +#endif +} + +#include "k3bisoimagewritingdialog.moc" diff --git a/src/misc/k3bisoimagewritingdialog.h b/src/misc/k3bisoimagewritingdialog.h new file mode 100644 index 0000000..caf0f4f --- /dev/null +++ b/src/misc/k3bisoimagewritingdialog.h @@ -0,0 +1,90 @@ +/* + * + * $Id$ + * Copyright (C) 2003 Sebastian Trueg <trueg@k3b.org> + * + * This file is part of the K3b project. + * Copyright (C) 1998-2007 Sebastian Trueg <trueg@k3b.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file "COPYING" for the exact licensing terms. + */ + + +#ifndef K3BISOIMAGEWRITINGDIALOG_H +#define K3BISOIMAGEWRITINGDIALOG_H + +#include <k3binteractiondialog.h> + + +class QCheckBox; +class K3bWriterSelectionWidget; +class QLabel; +class KURL; +class K3bMd5Job; +class K3bWritingModeWidget; +class KURLRequester; +class K3bListView; +class QSpinBox; +class QDragEnterEvent; +class QDropEvent; +class KListView; +class QListViewItem; +class QPoint; + + +/** + *@author Sebastian Trueg + */ +class K3bIsoImageWritingDialog : public K3bInteractionDialog +{ + Q_OBJECT + + public: + K3bIsoImageWritingDialog( QWidget* = 0, const char* = 0, bool = true ); + ~K3bIsoImageWritingDialog(); + + void setImage( const KURL& url ); + + protected slots: + void slotStartClicked(); + void updateImageSize( const QString& ); + void slotWriterChanged(); + void slotMd5JobPercent( int ); + void slotMd5JobFinished( bool ); + void slotContextMenu( KListView*, QListViewItem*, const QPoint& pos ); + + protected: + void loadUserDefaults( KConfigBase* ); + void saveUserDefaults( KConfigBase* ); + void loadK3bDefaults(); + + void calculateMd5Sum( const QString& ); + void dragEnterEvent( QDragEnterEvent* ); + void dropEvent( QDropEvent* ); + + void init(); + + private: + void setupGui(); + QString imagePath() const; + + K3bMd5Job* m_md5Job; + + K3bWriterSelectionWidget* m_writerSelectionWidget; + QCheckBox* m_checkDummy; + QCheckBox* m_checkVerify; + QSpinBox* m_spinCopies; + K3bWritingModeWidget* m_writingModeWidget; + + KURLRequester* m_editImagePath; + K3bListView* m_infoView; + + class Private; + Private* d; +}; + +#endif |