File indexing completed on 2024-04-28 04:50:04
0001 /* 0002 SPDX-FileCopyrightText: 2003-2009 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-FileCopyrightText: 2010 Michal Malek <michalm@jabster.pl> 0004 SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "k3bimagewritingdialog.h" 0010 #include "k3biso9660imagewritingjob.h" 0011 #include "k3bbinimagewritingjob.h" 0012 #include "k3bcuefileparser.h" 0013 #include "k3bclonetocreader.h" 0014 #include "k3baudiocuefilewritingjob.h" 0015 #include "k3bclonejob.h" 0016 #include "k3bmediacache.h" 0017 #include "k3bapplication.h" 0018 0019 #include <config-k3b.h> 0020 0021 #include "k3btempdirselectionwidget.h" 0022 #include "k3bdevicemanager.h" 0023 #include "k3bdevice.h" 0024 #include "k3bwriterselectionwidget.h" 0025 #include "k3bburnprogressdialog.h" 0026 #include "k3bstdguiitems.h" 0027 #include "k3bmd5job.h" 0028 #include "k3bdatamodewidget.h" 0029 #include "k3bglobals.h" 0030 #include "k3bwritingmodewidget.h" 0031 #include "k3bcore.h" 0032 #include "k3biso9660.h" 0033 #include "k3btoc.h" 0034 #include "k3btrack.h" 0035 #include "k3bcdtext.h" 0036 0037 #include <KComboBox> 0038 #include <KConfig> 0039 #include <KSharedConfig> 0040 #include <KColorScheme> 0041 #include <KIconLoader> 0042 #include <KIO/Global> 0043 #include <KLocalizedString> 0044 #include <KMessageBox> 0045 #include <KStandardGuiItem> 0046 #include <KUrlRequester> 0047 #include <kio_version.h> 0048 0049 #include <QFile> 0050 #include <QFileInfo> 0051 #include <QList> 0052 #include <QMap> 0053 #include <QMimeData> 0054 #include <QUrl> 0055 #include <QClipboard> 0056 #include <QDragEnterEvent> 0057 #include <QDropEvent> 0058 #include <QFont> 0059 #include <QFontMetrics> 0060 #include <QApplication> 0061 #include <QCheckBox> 0062 #include <QInputDialog> 0063 #include <QComboBox> 0064 #include <QGridLayout> 0065 #include <QGroupBox> 0066 #include <QHeaderView> 0067 #include <QLabel> 0068 #include <QLayout> 0069 #include <QMenu> 0070 #include <QProgressBar> 0071 #include <QPushButton> 0072 #include <QSpinBox> 0073 #include <QTabWidget> 0074 #include <QToolTip> 0075 #include <QTreeWidget> 0076 0077 namespace { 0078 0079 enum ImageType { 0080 IMAGE_UNKNOWN, 0081 IMAGE_ISO, 0082 IMAGE_CUE_BIN, 0083 IMAGE_AUDIO_CUE, 0084 IMAGE_CDRDAO_TOC, 0085 IMAGE_CDRECORD_CLONE, 0086 IMAGE_RAW 0087 }; 0088 0089 } // namespace 0090 0091 class K3b::ImageWritingDialog::Private 0092 { 0093 public: 0094 Private() 0095 : md5SumItem(0), 0096 haveMd5Sum( false ), 0097 foundImageType( IMAGE_UNKNOWN ), 0098 imageForced( false ) { 0099 } 0100 0101 WriterSelectionWidget* writerSelectionWidget; 0102 QCheckBox* checkDummy; 0103 QCheckBox* checkNoFix; 0104 QCheckBox* checkCacheImage; 0105 QCheckBox* checkVerify; 0106 DataModeWidget* dataModeWidget; 0107 WritingModeWidget* writingModeWidget; 0108 QSpinBox* spinCopies; 0109 0110 KUrlRequester* editImagePath; 0111 KComboBox* comboRecentImages; 0112 QComboBox* comboImageType; 0113 0114 QTreeWidget* infoView; 0115 TempDirSelectionWidget* tempDirSelectionWidget; 0116 0117 QTreeWidgetItem* md5SumItem; 0118 QString lastCheckedFile; 0119 0120 K3b::Md5Job* md5Job; 0121 bool haveMd5Sum; 0122 0123 ImageType foundImageType; 0124 0125 QMap<int,int> imageTypeSelectionMap; 0126 QMap<int,int> imageTypeSelectionMapRev; 0127 QString imageFile; 0128 QString tocFile; 0129 0130 QTabWidget* optionTabbed; 0131 0132 QWidget* advancedTab; 0133 QWidget* tempPathTab; 0134 bool advancedTabVisible; 0135 bool tempPathTabVisible; 0136 0137 int advancedTabIndex; 0138 int tempPathTabIndex; 0139 0140 bool imageForced; 0141 0142 QColor infoTextColor; 0143 QColor negativeTextColor; 0144 QColor normalTextColor; 0145 0146 static KIO::filesize_t volumeSpaceSize( const Iso9660& iso ); 0147 void createIso9660InfoItems( Iso9660* ); 0148 void createCdrecordCloneItems( const QString&, const QString& ); 0149 void createCueBinItems( const QString&, const QString& ); 0150 void createAudioCueItems( const CueFileParser& cp ); 0151 int currentImageType(); 0152 QString imagePath() const; 0153 }; 0154 0155 0156 KIO::filesize_t K3b::ImageWritingDialog::Private::volumeSpaceSize( const Iso9660& isoFs ) 0157 { 0158 return static_cast<KIO::filesize_t>( isoFs.primaryDescriptor().volumeSpaceSize*2048 ); 0159 } 0160 0161 0162 void K3b::ImageWritingDialog::Private::createIso9660InfoItems( K3b::Iso9660* isoF ) 0163 { 0164 QTreeWidgetItem* isoRootItem = new QTreeWidgetItem( infoView ); 0165 isoRootItem->setText( 0, i18n("Detected:") ); 0166 isoRootItem->setText( 1, i18n("ISO 9660 image") ); 0167 isoRootItem->setForeground( 0, infoTextColor ); 0168 isoRootItem->setIcon( 1, QIcon::fromTheme( "application-x-cd-image") ); 0169 isoRootItem->setTextAlignment( 0, Qt::AlignRight ); 0170 0171 const KIO::filesize_t size = K3b::filesize( QUrl::fromLocalFile(isoF->fileName()) ); 0172 const KIO::filesize_t volumeSpaceSize = Private::volumeSpaceSize( *isoF ); 0173 0174 QTreeWidgetItem* item = new QTreeWidgetItem( infoView ); 0175 item->setText( 0, i18n("Filesize:") ); 0176 item->setForeground( 0, infoTextColor ); 0177 item->setTextAlignment( 0, Qt::AlignRight ); 0178 if( size < volumeSpaceSize ) { 0179 item->setText( 1, i18n("%1 (different than declared volume size)", KIO::convertSize( size )) ); 0180 item->setForeground( 1, negativeTextColor ); 0181 item->setIcon( 1, QIcon::fromTheme( "dialog-error") ); 0182 0183 item = new QTreeWidgetItem( infoView ); 0184 item->setText( 0, i18n("Volume Size:") ); 0185 item->setText( 1, KIO::convertSize( volumeSpaceSize ) ); 0186 item->setForeground( 0, infoTextColor ); 0187 item->setTextAlignment( 0, Qt::AlignRight ); 0188 } 0189 else { 0190 item->setText( 1, KIO::convertSize( size ) ); 0191 } 0192 0193 item = new QTreeWidgetItem( infoView ); 0194 item->setText( 0, i18n("System Id:") ); 0195 item->setText( 1, isoF->primaryDescriptor().systemId.isEmpty() 0196 ? QString("-") 0197 : isoF->primaryDescriptor().systemId ); 0198 item->setForeground( 0, infoTextColor ); 0199 item->setTextAlignment( 0, Qt::AlignRight ); 0200 0201 item = new QTreeWidgetItem( infoView ); 0202 item->setText( 0, i18n("Volume Id:") ); 0203 item->setText( 1, isoF->primaryDescriptor().volumeId.isEmpty() 0204 ? QString("-") 0205 : isoF->primaryDescriptor().volumeId ); 0206 item->setForeground( 0, infoTextColor ); 0207 item->setTextAlignment( 0, Qt::AlignRight ); 0208 0209 item = new QTreeWidgetItem( infoView ); 0210 item->setText( 0, i18n("Volume Set Id:") ); 0211 item->setText( 1, isoF->primaryDescriptor().volumeSetId.isEmpty() 0212 ? QString("-") 0213 : isoF->primaryDescriptor().volumeSetId ); 0214 item->setForeground( 0, infoTextColor ); 0215 item->setTextAlignment( 0, Qt::AlignRight ); 0216 0217 item = new QTreeWidgetItem( infoView ); 0218 item->setText( 0, i18n("Publisher Id:") ); 0219 item->setText( 1, isoF->primaryDescriptor().publisherId.isEmpty() 0220 ? QString("-") 0221 : isoF->primaryDescriptor().publisherId ); 0222 item->setForeground( 0, infoTextColor ); 0223 item->setTextAlignment( 0, Qt::AlignRight ); 0224 0225 item = new QTreeWidgetItem( infoView ); 0226 item->setText( 0, i18n("Preparer Id:") ); 0227 item->setText( 1, isoF->primaryDescriptor().preparerId.isEmpty() 0228 ? QString("-") : isoF->primaryDescriptor().preparerId ); 0229 item->setForeground( 0, infoTextColor ); 0230 item->setTextAlignment( 0, Qt::AlignRight ); 0231 0232 item = new QTreeWidgetItem( infoView ); 0233 item->setText( 0, i18n("Application Id:") ); 0234 item->setText( 1, isoF->primaryDescriptor().applicationId.isEmpty() 0235 ? QString("-") 0236 : isoF->primaryDescriptor().applicationId ); 0237 item->setForeground( 0, infoTextColor ); 0238 item->setTextAlignment( 0, Qt::AlignRight ); 0239 } 0240 0241 0242 void K3b::ImageWritingDialog::Private::createCdrecordCloneItems( const QString& tocFile, const QString& imageFile ) 0243 { 0244 QTreeWidgetItem* isoRootItem = new QTreeWidgetItem( infoView ); 0245 isoRootItem->setText( 0, i18n("Detected:") ); 0246 isoRootItem->setText( 1, i18n("Cdrecord clone image") ); 0247 isoRootItem->setForeground( 0, infoTextColor ); 0248 isoRootItem->setIcon( 1, QIcon::fromTheme( "application-x-cd-image") ); 0249 isoRootItem->setTextAlignment( 0, Qt::AlignRight ); 0250 0251 QTreeWidgetItem* item = new QTreeWidgetItem( infoView ); 0252 item->setText( 0, i18n("Filesize:") ); 0253 item->setText( 1, KIO::convertSize( K3b::filesize(QUrl::fromLocalFile(imageFile)) ) ); 0254 item->setForeground( 0, infoTextColor ); 0255 item->setTextAlignment( 0, Qt::AlignRight ); 0256 0257 item = new QTreeWidgetItem( infoView ); 0258 item->setText( 0, i18n("Image file:") ); 0259 item->setText( 1, imageFile ); 0260 item->setForeground( 0, infoTextColor ); 0261 item->setTextAlignment( 0, Qt::AlignRight ); 0262 0263 item = new QTreeWidgetItem( infoView ); 0264 item->setText( 0, i18n("TOC file:") ); 0265 item->setText( 1, tocFile ); 0266 item->setForeground( 0, infoTextColor ); 0267 item->setTextAlignment( 0, Qt::AlignRight ); 0268 } 0269 0270 0271 void K3b::ImageWritingDialog::Private::createCueBinItems( const QString& cueFile, const QString& imageFile ) 0272 { 0273 QTreeWidgetItem* isoRootItem = new QTreeWidgetItem( infoView ); 0274 isoRootItem->setText( 0, i18n("Detected:") ); 0275 isoRootItem->setText( 1, i18n("Cue/bin image") ); 0276 isoRootItem->setForeground( 0, infoTextColor ); 0277 isoRootItem->setIcon( 1, QIcon::fromTheme( "application-x-cd-image") ); 0278 isoRootItem->setTextAlignment( 0, Qt::AlignRight ); 0279 0280 QTreeWidgetItem* item = new QTreeWidgetItem( infoView ); 0281 item->setText( 0, i18n("Filesize:") ); 0282 item->setText( 1, KIO::convertSize( K3b::filesize(QUrl::fromLocalFile(imageFile)) ) ); 0283 item->setForeground( 0, infoTextColor ); 0284 item->setTextAlignment( 0, Qt::AlignRight ); 0285 0286 item = new QTreeWidgetItem( infoView ); 0287 item->setText( 0, i18n("Image file:") ); 0288 item->setText( 1, imageFile ); 0289 item->setForeground( 0, infoTextColor ); 0290 item->setTextAlignment( 0, Qt::AlignRight ); 0291 0292 item = new QTreeWidgetItem( infoView ); 0293 item->setText( 0, i18n("Cue file:") ); 0294 item->setText( 1, cueFile ); 0295 item->setForeground( 0, infoTextColor ); 0296 item->setTextAlignment( 0, Qt::AlignRight ); 0297 } 0298 0299 0300 void K3b::ImageWritingDialog::Private::createAudioCueItems( const K3b::CueFileParser& cp ) 0301 { 0302 QTreeWidgetItem* rootItem = new QTreeWidgetItem( infoView ); 0303 rootItem->setText( 0, i18n("Detected:") ); 0304 rootItem->setText( 1, i18n("Audio Cue Image") ); 0305 rootItem->setForeground( 0, infoTextColor ); 0306 rootItem->setIcon( 1, QIcon::fromTheme( "audio-x-generic") ); 0307 rootItem->setTextAlignment( 0, Qt::AlignRight ); 0308 0309 QTreeWidgetItem* trackParent = new QTreeWidgetItem( infoView ); 0310 trackParent->setText( 0, i18np("One track", "%1 tracks", cp.toc().count() ) ); 0311 trackParent->setText( 1, cp.toc().length().toString() ); 0312 if( !cp.cdText().isEmpty() ) { 0313 trackParent->setText( 1, 0314 QString("%1 (%2 - %3)") 0315 .arg(trackParent->text(1)) 0316 .arg(cp.cdText().performer()) 0317 .arg(cp.cdText().title()) ); 0318 } 0319 0320 int i = 1; 0321 foreach( const K3b::Device::Track& track, cp.toc() ) { 0322 0323 QTreeWidgetItem* trackItem = new QTreeWidgetItem( trackParent ); 0324 trackItem->setText( 0, i18n("Track") + ' ' + QString::number(i).rightJustified( 2, '0' ) ); 0325 trackItem->setText( 1, " " + ( i < cp.toc().count() 0326 ? track.length().toString() 0327 : QString("??:??:??") ) ); 0328 0329 if( !cp.cdText().isEmpty() && (cp.cdText().count() > 0) &&!cp.cdText()[i-1].isEmpty() ) 0330 trackItem->setText( 1, 0331 QString("%1 (%2 - %3)") 0332 .arg(trackItem->text(1)) 0333 .arg(cp.cdText()[i-1].performer()) 0334 .arg(cp.cdText()[i-1].title()) ); 0335 0336 ++i; 0337 } 0338 0339 trackParent->setExpanded( true ); 0340 } 0341 0342 0343 int K3b::ImageWritingDialog::Private::currentImageType() 0344 { 0345 if( comboImageType->currentIndex() == 0 ) 0346 return foundImageType; 0347 else 0348 return imageTypeSelectionMap[comboImageType->currentIndex()]; 0349 } 0350 0351 0352 QString K3b::ImageWritingDialog::Private::imagePath() const 0353 { 0354 return K3b::convertToLocalUrl( editImagePath->url() ).toLocalFile(); 0355 } 0356 0357 0358 K3b::ImageWritingDialog::ImageWritingDialog( QWidget* parent ) 0359 : K3b::InteractionDialog( parent, 0360 i18n("Burn Image"), 0361 "iso cue toc", 0362 START_BUTTON|CANCEL_BUTTON, 0363 START_BUTTON, 0364 "image writing" ) // config group 0365 { 0366 d = new Private(); 0367 const KColorScheme colorScheme( QPalette::Normal, KColorScheme::View ); 0368 d->infoTextColor = palette().color( QPalette::Disabled, QPalette::Text ); 0369 d->negativeTextColor = colorScheme.foreground( KColorScheme::NegativeText ).color(); 0370 d->normalTextColor = colorScheme.foreground( KColorScheme::NormalText ).color(); 0371 0372 setAcceptDrops( true ); 0373 0374 setupGui(); 0375 0376 d->md5Job = new K3b::Md5Job( 0, this ); 0377 connect( d->md5Job, SIGNAL(finished(bool)), 0378 this, SLOT(slotMd5JobFinished(bool)) ); 0379 connect( d->md5Job, SIGNAL(percent(int)), 0380 this, SLOT(slotMd5JobPercent(int)) ); 0381 0382 connect( d->writerSelectionWidget, SIGNAL(writerChanged()), 0383 this, SLOT(slotToggleAll()) ); 0384 connect( d->writerSelectionWidget, SIGNAL(writingAppChanged(K3b::WritingApp)), 0385 this, SLOT(slotToggleAll()) ); 0386 connect( d->writerSelectionWidget, SIGNAL(writerChanged(K3b::Device::Device*)), 0387 d->writingModeWidget, SLOT(setDevice(K3b::Device::Device*)) ); 0388 connect( d->comboImageType, SIGNAL(activated(int)), 0389 this, SLOT(slotToggleAll()) ); 0390 connect( d->writingModeWidget, SIGNAL(writingModeChanged(WritingMode)), 0391 this, SLOT(slotToggleAll()) ); 0392 connect( d->editImagePath, SIGNAL(textChanged(QString)), 0393 this, SLOT(slotUpdateImage(QString)) ); 0394 connect( d->checkDummy, SIGNAL(toggled(bool)), 0395 this, SLOT(slotToggleAll()) ); 0396 connect( d->checkCacheImage, SIGNAL(toggled(bool)), 0397 this, SLOT(slotToggleAll()) ); 0398 } 0399 0400 0401 K3b::ImageWritingDialog::~ImageWritingDialog() 0402 { 0403 d->md5Job->cancel(); 0404 0405 KConfigGroup c( KSharedConfig::openConfig(), configGroup() ); 0406 QStringList recentImages; 0407 // do not store more than 10 recent images 0408 for ( int i = 0; i < d->comboRecentImages->count() && recentImages.count() < 10; ++i ) { 0409 QString image = d->comboRecentImages->itemText( i ); 0410 if ( !recentImages.contains( image ) ) 0411 recentImages += image; 0412 } 0413 c.writePathEntry( "recent images", recentImages ); 0414 0415 delete d; 0416 } 0417 0418 0419 void K3b::ImageWritingDialog::init() 0420 { 0421 KConfigGroup c( KSharedConfig::openConfig(), configGroup() ); 0422 0423 if( !d->imageForced ) { 0424 // when opening the dialog first the default settings are loaded and afterwards we set the 0425 // last written image because that's what most users want 0426 QString image = c.readPathEntry( "last written image", QString() ); 0427 if( QFile::exists( image ) ) 0428 d->editImagePath->setUrl( QUrl::fromLocalFile( image ) ); 0429 0430 d->comboRecentImages->clear(); 0431 } 0432 0433 d->comboRecentImages->addItems( c.readPathEntry( "recent images", QStringList() ) ); 0434 } 0435 0436 0437 void K3b::ImageWritingDialog::setupGui() 0438 { 0439 QWidget* frame = K3b::InteractionDialog::mainWidget(); 0440 0441 // image 0442 // ----------------------------------------------------------------------- 0443 QGroupBox* groupImageUrl = new QGroupBox( i18n("Image to Burn"), frame ); 0444 d->comboRecentImages = new KComboBox( true, this ); 0445 d->comboRecentImages->setSizeAdjustPolicy( QComboBox::AdjustToMinimumContentsLengthWithIcon ); 0446 d->editImagePath = new KUrlRequester( d->comboRecentImages, groupImageUrl ); 0447 d->editImagePath->setMode( KFile::File|KFile::ExistingOnly ); 0448 d->editImagePath->setWindowTitle( i18n("Choose Image File") ); 0449 #if KIO_VERSION >= QT_VERSION_CHECK(5, 108, 0) 0450 d->editImagePath->setNameFilters({ 0451 i18n("Image Files") + " (*.iso *.toc *.ISO *.TOC *.cue *.CUE)", 0452 i18n("ISO 9660 Image Files") + " (*.iso *.ISO)", 0453 i18n("Cue Files") + " (*.cue *.CUE)", 0454 i18n("Cdrdao TOC Files and Cdrecord Clone Images") + " (*.toc *.TOC)", 0455 i18n("All Files") + " (*)", 0456 }); 0457 #else 0458 d->editImagePath->setFilter( "*.iso *.toc *.ISO *.TOC *.cue *.CUE|" + i18n("Image Files") 0459 + '\n' 0460 + "*.iso *.ISO|" + i18n("ISO 9660 Image Files") 0461 + '\n' 0462 + "*.cue *.CUE|" + i18n("Cue Files") 0463 + '\n' 0464 + "*.toc *.TOC|" + i18n("Cdrdao TOC Files and Cdrecord Clone Images") 0465 + '\n' 0466 + "*|" + i18n("All Files") ); 0467 #endif 0468 QHBoxLayout* groupImageUrlLayout = new QHBoxLayout( groupImageUrl ); 0469 groupImageUrlLayout->addWidget( d->editImagePath ); 0470 0471 QGroupBox* groupImageType = new QGroupBox( i18n("Image Type"), frame ); 0472 QHBoxLayout* groupImageTypeLayout = new QHBoxLayout( groupImageType ); 0473 d->comboImageType = new QComboBox( groupImageType ); 0474 groupImageTypeLayout->addWidget( d->comboImageType ); 0475 groupImageTypeLayout->addStretch( 1 ); 0476 d->comboImageType->addItem( i18n("Auto Detection") ); 0477 d->comboImageType->addItem(i18n("ISO 9660 filesystem image")); 0478 d->comboImageType->addItem( i18n("Cue/bin image") ); 0479 d->comboImageType->addItem( i18n("Audio cue file") ); 0480 d->comboImageType->addItem( i18n("Cdrdao TOC file") ); 0481 d->comboImageType->addItem( i18n("Cdrecord clone image") ); 0482 d->comboImageType->addItem(i18n("Plain data image")); 0483 d->imageTypeSelectionMap[1] = IMAGE_ISO; 0484 d->imageTypeSelectionMap[2] = IMAGE_CUE_BIN; 0485 d->imageTypeSelectionMap[3] = IMAGE_AUDIO_CUE; 0486 d->imageTypeSelectionMap[4] = IMAGE_CDRDAO_TOC; 0487 d->imageTypeSelectionMap[5] = IMAGE_CDRECORD_CLONE; 0488 d->imageTypeSelectionMap[6] = IMAGE_RAW; 0489 d->imageTypeSelectionMapRev[IMAGE_ISO] = 1; 0490 d->imageTypeSelectionMapRev[IMAGE_CUE_BIN] = 2; 0491 d->imageTypeSelectionMapRev[IMAGE_AUDIO_CUE] = 3; 0492 d->imageTypeSelectionMapRev[IMAGE_CDRDAO_TOC] = 4; 0493 d->imageTypeSelectionMapRev[IMAGE_CDRECORD_CLONE] = 5; 0494 d->imageTypeSelectionMapRev[IMAGE_RAW] = 6; 0495 0496 0497 // image info 0498 // ----------------------------------------------------------------------- 0499 d->infoView = new QTreeWidget( frame ); 0500 d->infoView->setColumnCount( 2 ); 0501 d->infoView->headerItem()->setText( 0, "key" ); 0502 d->infoView->headerItem()->setText( 1, "value" ); 0503 d->infoView->setHeaderHidden( true ); 0504 d->infoView->setSelectionMode( QAbstractItemView::NoSelection ); 0505 d->infoView->setItemsExpandable( false ); 0506 d->infoView->setRootIsDecorated( false ); 0507 d->infoView->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents ); 0508 d->infoView->setFocusPolicy( Qt::NoFocus ); 0509 d->infoView->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ); 0510 d->infoView->setContextMenuPolicy( Qt::CustomContextMenu ); 0511 //d->infoView->setNoItemText( i18n("No image file selected") ); 0512 //d->infoView->setSorting( -1 ); 0513 //d->infoView->setAlternateBackground( QColor() ); 0514 //d->infoView->setFullWidth(true); 0515 //d->infoView->setSelectionMode( Q3ListView::NoSelection ); 0516 //d->infoView->setHScrollBarMode( Q3ScrollView::AlwaysOff ); 0517 0518 connect( d->infoView, SIGNAL(customContextMenuRequested(QPoint)), 0519 this, SLOT(slotContextMenuRequested(QPoint)) ); 0520 0521 d->writerSelectionWidget = new K3b::WriterSelectionWidget( frame ); 0522 d->writerSelectionWidget->setWantedMediumType( K3b::Device::MEDIA_WRITABLE ); 0523 d->writerSelectionWidget->setWantedMediumState( K3b::Device::STATE_EMPTY ); 0524 0525 // options 0526 // ----------------------------------------------------------------------- 0527 d->optionTabbed = new QTabWidget( frame ); 0528 0529 QWidget* optionTab = new QWidget( d->optionTabbed ); 0530 QGridLayout* optionTabLayout = new QGridLayout( optionTab ); 0531 optionTabLayout->setAlignment( Qt::AlignTop ); 0532 0533 QGroupBox* writingModeGroup = new QGroupBox( i18n("Writing Mode"), optionTab ); 0534 d->writingModeWidget = new K3b::WritingModeWidget( writingModeGroup ); 0535 QHBoxLayout* writingModeGroupLayout = new QHBoxLayout( writingModeGroup ); 0536 writingModeGroupLayout->addWidget( d->writingModeWidget ); 0537 0538 // copies -------- 0539 QGroupBox* groupCopies = new QGroupBox( i18n("Copies"), optionTab ); 0540 QLabel* pixLabel = new QLabel( groupCopies ); 0541 pixLabel->setPixmap( QIcon::fromTheme("tools-media-optical-copy").pixmap(KIconLoader::SizeMedium) ); 0542 pixLabel->setScaledContents( false ); 0543 d->spinCopies = new QSpinBox( groupCopies ); 0544 d->spinCopies->setMinimum( 1 ); 0545 d->spinCopies->setMaximum( 999 ); 0546 QHBoxLayout* groupCopiesLayout = new QHBoxLayout( groupCopies ); 0547 groupCopiesLayout->addWidget( pixLabel ); 0548 groupCopiesLayout->addWidget( d->spinCopies ); 0549 // -------- copies 0550 0551 QGroupBox* optionGroup = new QGroupBox( i18n("Settings"), optionTab ); 0552 d->checkDummy = K3b::StdGuiItems::simulateCheckbox( optionGroup ); 0553 d->checkCacheImage = K3b::StdGuiItems::createCacheImageCheckbox( optionGroup ); 0554 d->checkVerify = K3b::StdGuiItems::verifyCheckBox( optionGroup ); 0555 QVBoxLayout* optionGroupLayout = new QVBoxLayout( optionGroup ); 0556 optionGroupLayout->addWidget( d->checkDummy ); 0557 optionGroupLayout->addWidget( d->checkCacheImage ); 0558 optionGroupLayout->addWidget( d->checkVerify ); 0559 optionGroupLayout->addStretch( 1 ); 0560 0561 optionTabLayout->addWidget( writingModeGroup, 0, 0 ); 0562 optionTabLayout->addWidget( groupCopies, 1, 0 ); 0563 optionTabLayout->addWidget( optionGroup, 0, 1, 2, 1 ); 0564 optionTabLayout->setRowStretch( 1, 1 ); 0565 optionTabLayout->setColumnStretch( 1, 1 ); 0566 0567 d->optionTabbed->addTab( optionTab, i18n("Settings") ); 0568 0569 0570 // image tab ------------------------------------ 0571 d->tempPathTab = new QWidget( d->optionTabbed ); 0572 QGridLayout* imageTabGrid = new QGridLayout( d->tempPathTab ); 0573 0574 d->tempDirSelectionWidget = new K3b::TempDirSelectionWidget( d->tempPathTab ); 0575 0576 imageTabGrid->addWidget( d->tempDirSelectionWidget, 0, 0 ); 0577 0578 d->tempPathTabIndex = d->optionTabbed->addTab( d->tempPathTab, i18n("&Image") ); 0579 d->tempPathTabVisible = true; 0580 // ------------------------------------------------------------- 0581 0582 0583 // advanced --------------------------------- 0584 d->advancedTab = new QWidget( d->optionTabbed ); 0585 QGridLayout* advancedTabLayout = new QGridLayout( d->advancedTab ); 0586 advancedTabLayout->setAlignment( Qt::AlignTop ); 0587 0588 d->dataModeWidget = new K3b::DataModeWidget( d->advancedTab ); 0589 d->checkNoFix = K3b::StdGuiItems::startMultisessionCheckBox( d->advancedTab ); 0590 0591 advancedTabLayout->addWidget( new QLabel( i18n("Data mode:"), d->advancedTab ), 0, 0 ); 0592 advancedTabLayout->addWidget( d->dataModeWidget, 0, 1 ); 0593 advancedTabLayout->addWidget( d->checkNoFix, 1, 0, 1, 3 ); 0594 advancedTabLayout->setRowStretch( 2, 1 ); 0595 advancedTabLayout->setColumnStretch( 2, 1 ); 0596 0597 d->advancedTabIndex = d->optionTabbed->addTab( d->advancedTab, i18n("Advanced") ); 0598 d->advancedTabVisible = true; 0599 // ----------------------------------------------------------------------- 0600 0601 0602 0603 0604 QGridLayout* grid = new QGridLayout( frame ); 0605 grid->setContentsMargins( 0, 0, 0, 0 ); 0606 0607 grid->addWidget( groupImageUrl, 0, 0 ); 0608 grid->addWidget( groupImageType, 0, 1 ); 0609 grid->setColumnStretch( 0, 1 ); 0610 grid->addWidget( d->infoView, 1, 0, 1, 2 ); 0611 grid->addWidget( d->writerSelectionWidget, 2, 0, 1, 2 ); 0612 grid->addWidget( d->optionTabbed, 3, 0, 1, 2 ); 0613 0614 grid->setRowStretch( 1, 1 ); 0615 0616 0617 d->comboImageType->setWhatsThis( i18n("<p><b>Image types supported by K3b:</p>" 0618 "<p><b>Plain image</b><br/>" 0619 "Plain images are written as is to the medium using " 0620 "a single data track. Typical plain images are iso " 0621 "images as created by K3b's data project." 0622 "<p><b>Cue/bin images</b><br/>" 0623 "Cue/bin images consist of a cue file describing the " 0624 "table of contents of the medium and an image file " 0625 "which contains the actual data. The data will be " 0626 "written to the medium according to the cue file." 0627 "<p><b>Audio Cue image</b><br/>" 0628 "Audio cue images are a special kind of cue/bin image " 0629 "containing an image of an audio CD. The actual audio " 0630 "data can be encoded using any audio format supported " 0631 "by K3b. Audio cue files can also be imported into " 0632 "K3b audio projects which allows one to change the order " 0633 "and add or remove tracks." 0634 "<p><b>Cdrecord clone images</b><br/>" 0635 "K3b creates a cdrecord clone image of a single-session " 0636 "CD when copying a CD in clone mode. These images can " 0637 "be reused here." 0638 "<p><b>Cdrdao TOC files</b><br/>" 0639 "K3b supports writing cdrdao's own image format, the toc " 0640 "files.") ); 0641 } 0642 0643 0644 void K3b::ImageWritingDialog::slotStartClicked() 0645 { 0646 d->md5Job->cancel(); 0647 0648 // save the path 0649 KConfigGroup grp( KSharedConfig::openConfig(), configGroup() ); 0650 grp.writePathEntry( "last written image", d->imagePath() ); 0651 0652 if( d->imageFile.isEmpty() ) 0653 d->imageFile = d->imagePath(); 0654 if( d->tocFile.isEmpty() ) 0655 d->tocFile = d->imagePath(); 0656 0657 // create a progresswidget 0658 K3b::BurnProgressDialog dlg( parentWidget() ); 0659 0660 // create the job 0661 K3b::BurnJob* job = 0; 0662 switch( d->currentImageType() ) { 0663 case IMAGE_CDRECORD_CLONE: 0664 { 0665 K3b::CloneJob* _job = new K3b::CloneJob( &dlg, this ); 0666 _job->setWriterDevice( d->writerSelectionWidget->writerDevice() ); 0667 _job->setImagePath( d->imageFile ); 0668 _job->setSimulate( d->checkDummy->isChecked() ); 0669 _job->setWriteSpeed( d->writerSelectionWidget->writerSpeed() ); 0670 _job->setCopies( d->checkDummy->isChecked() ? 1 : d->spinCopies->value() ); 0671 _job->setOnlyBurnExistingImage( true ); 0672 0673 job = _job; 0674 } 0675 break; 0676 0677 case IMAGE_AUDIO_CUE: 0678 { 0679 K3b::AudioCueFileWritingJob* job_ = new K3b::AudioCueFileWritingJob( &dlg, this ); 0680 0681 job_->setBurnDevice( d->writerSelectionWidget->writerDevice() ); 0682 job_->setSpeed( d->writerSelectionWidget->writerSpeed() ); 0683 job_->setSimulate( d->checkDummy->isChecked() ); 0684 job_->setWritingMode( d->writingModeWidget->writingMode() ); 0685 job_->setCueFile( d->tocFile ); 0686 job_->setCopies( d->checkDummy->isChecked() ? 1 : d->spinCopies->value() ); 0687 job_->setOnTheFly( !d->checkCacheImage->isChecked() ); 0688 job_->setTempDir( d->tempDirSelectionWidget->tempPath() ); 0689 0690 job = job_; 0691 } 0692 break; 0693 0694 case IMAGE_CUE_BIN: 0695 // for now the K3b::BinImageWritingJob decides if it's a toc or a cue file 0696 case IMAGE_CDRDAO_TOC: 0697 { 0698 K3b::BinImageWritingJob* job_ = new K3b::BinImageWritingJob( &dlg, this ); 0699 0700 job_->setWriter( d->writerSelectionWidget->writerDevice() ); 0701 job_->setSpeed( d->writerSelectionWidget->writerSpeed() ); 0702 job_->setTocFile( d->tocFile ); 0703 job_->setSimulate(d->checkDummy->isChecked()); 0704 job_->setMulti( false /*d->checkNoFix->isChecked()*/ ); 0705 job_->setCopies( d->checkDummy->isChecked() ? 1 : d->spinCopies->value() ); 0706 0707 job = job_; 0708 } 0709 break; 0710 0711 case IMAGE_RAW: 0712 case IMAGE_ISO: 0713 { 0714 if (d->currentImageType() == IMAGE_ISO) { 0715 K3b::Iso9660 isoFs(d->imageFile); 0716 if (isoFs.open()) { 0717 if (K3b::filesize(QUrl::fromLocalFile(d->imageFile)) < Private::volumeSpaceSize(isoFs)) { 0718 if (KMessageBox::questionTwoActions(this, 0719 i18n("<p>The actual file size does not match the size declared in the file header. " 0720 "If it has been downloaded make sure the download is complete.</p>" 0721 "<p>Only continue if you know what you are doing.</p>"), 0722 i18n("Warning"), 0723 KStandardGuiItem::cont(), 0724 KStandardGuiItem::cancel() ) == KMessageBox::SecondaryAction ) 0725 return; 0726 } 0727 } 0728 } 0729 0730 // TODO: it needs a NON ISO 9660 images testcase 0731 K3b::Iso9660ImageWritingJob* job_ = new K3b::Iso9660ImageWritingJob( &dlg ); 0732 0733 job_->setBurnDevice( d->writerSelectionWidget->writerDevice() ); 0734 job_->setSpeed( d->writerSelectionWidget->writerSpeed() ); 0735 job_->setSimulate( d->checkDummy->isChecked() ); 0736 job_->setWritingMode( d->writingModeWidget->writingMode() ); 0737 job_->setVerifyData( d->checkVerify->isChecked() ); 0738 job_->setNoFix( d->checkNoFix->isChecked() ); 0739 job_->setDataMode( d->dataModeWidget->dataMode() ); 0740 job_->setImagePath( d->imageFile ); 0741 job_->setCopies( d->checkDummy->isChecked() ? 1 : d->spinCopies->value() ); 0742 0743 job = job_; 0744 } 0745 break; 0746 0747 default: 0748 qDebug() << "(K3b::ImageWritingDialog) this should really not happen!"; 0749 break; 0750 } 0751 0752 if( job ) { 0753 job->setWritingApp( d->writerSelectionWidget->writingApp() ); 0754 0755 hide(); 0756 0757 dlg.startJob(job); 0758 0759 delete job; 0760 0761 if( KConfigGroup( KSharedConfig::openConfig(), QStringLiteral("General Options") ).readEntry( "keep action dialogs open", false ) ) 0762 show(); 0763 else 0764 close(); 0765 } 0766 } 0767 0768 0769 void K3b::ImageWritingDialog::slotUpdateImage( const QString& ) 0770 { 0771 QString path = d->imagePath(); 0772 0773 // check the image types 0774 0775 d->haveMd5Sum = false; 0776 d->md5Job->cancel(); 0777 d->infoView->clear(); 0778 //d->infoView->header()->resizeSection( 0, 20 ); 0779 d->md5SumItem = 0; 0780 d->foundImageType = IMAGE_UNKNOWN; 0781 d->tocFile.truncate(0); 0782 d->imageFile.truncate(0); 0783 0784 QFileInfo info( path ); 0785 if( info.isFile() ) { 0786 0787 // ------------------------------------------------ 0788 // Test for iso9660 image 0789 // ------------------------------------------------ 0790 K3b::Iso9660 isoF( path ); 0791 if( isoF.open() ) { 0792 #ifdef K3B_DEBUG 0793 isoF.debug(); 0794 #endif 0795 0796 d->createIso9660InfoItems( &isoF ); 0797 isoF.close(); 0798 calculateMd5Sum( path ); 0799 0800 d->foundImageType = IMAGE_ISO; 0801 d->imageFile = path; 0802 } 0803 0804 if( d->foundImageType == IMAGE_UNKNOWN ) { 0805 0806 // check for cdrecord clone image 0807 // try both path and path.toc as tocfiles 0808 K3b::CloneTocReader cr; 0809 0810 if( path.right(4) == ".toc" ) { 0811 cr.openFile( path ); 0812 if( cr.isValid() ) { 0813 d->tocFile = path; 0814 d->imageFile = cr.imageFilename(); 0815 } 0816 } 0817 if( d->imageFile.isEmpty() ) { 0818 cr.openFile( path + ".toc" ); 0819 if( cr.isValid() ) { 0820 d->tocFile = cr.filename(); 0821 d->imageFile = cr.imageFilename(); 0822 } 0823 } 0824 0825 if( !d->imageFile.isEmpty() ) { 0826 // we have a cdrecord clone image 0827 d->createCdrecordCloneItems( d->tocFile, d->imageFile ); 0828 calculateMd5Sum( d->imageFile ); 0829 0830 d->foundImageType = IMAGE_CDRECORD_CLONE; 0831 } 0832 } 0833 0834 if( d->foundImageType == IMAGE_UNKNOWN ) { 0835 0836 // check for cue/bin stuff 0837 // once again we try both path and path.cue 0838 K3b::CueFileParser cp; 0839 0840 if( path.right(4).toLower() == ".cue" ) 0841 cp.openFile( path ); 0842 else if( path.right(4).toLower() == ".bin" ) 0843 cp.openFile( path.left( path.length()-3) + "cue" ); 0844 0845 if( cp.isValid() ) { 0846 d->tocFile = cp.filename(); 0847 d->imageFile = cp.imageFilename(); 0848 } 0849 0850 if( d->imageFile.isEmpty() ) { 0851 cp.openFile( path + ".cue" ); 0852 if( cp.isValid() ) { 0853 d->tocFile = cp.filename(); 0854 d->imageFile = cp.imageFilename(); 0855 } 0856 } 0857 0858 if( !d->imageFile.isEmpty() ) { 0859 // we have a cue file 0860 if( cp.toc().contentType() == K3b::Device::AUDIO ) { 0861 d->foundImageType = IMAGE_AUDIO_CUE; 0862 d->createAudioCueItems( cp ); 0863 } 0864 else { 0865 d->foundImageType = IMAGE_CUE_BIN; // we cannot be sure if writing will work... :( 0866 d->createCueBinItems( d->tocFile, d->imageFile ); 0867 calculateMd5Sum( d->imageFile ); 0868 } 0869 } 0870 } 0871 0872 if( d->foundImageType == IMAGE_UNKNOWN ) { 0873 // TODO: check for cdrdao tocfile 0874 } 0875 0876 // TODO: treat unusable image to opaque 0877 if (d->foundImageType == IMAGE_UNKNOWN) { 0878 if (KMessageBox::questionTwoActions(this, 0879 i18n("Type of image file is not recognizable. Do you want to burn it anyway?"), 0880 i18n("Unknown image type"), 0881 KGuiItem(i18n("Burn")), 0882 KStandardGuiItem::cancel()) == KMessageBox::PrimaryAction) { 0883 d->foundImageType = IMAGE_RAW; 0884 d->imageFile = path; 0885 } 0886 } 0887 0888 if( d->foundImageType == IMAGE_UNKNOWN ) { 0889 QTreeWidgetItem* item = new QTreeWidgetItem( d->infoView ); 0890 if ( !info.isReadable() ) { 0891 item->setText( 0, i18n("Unable to read image file") ); 0892 } else { 0893 item->setText( 0, i18n("Seems not to be a usable image") ); 0894 } 0895 item->setForeground( 0, d->negativeTextColor ); 0896 item->setIcon( 0, QIcon::fromTheme( "dialog-error") ); 0897 } 0898 else { 0899 // remember as recent image 0900 int i = 0; 0901 while ( i < d->comboRecentImages->count() && d->comboRecentImages->itemText(i) != path ) 0902 ++i; 0903 if ( i == d->comboRecentImages->count() ) 0904 d->comboRecentImages->insertItem( 0, path ); 0905 } 0906 } 0907 else { 0908 QTreeWidgetItem* item = new QTreeWidgetItem( d->infoView ); 0909 item->setText( 0, i18n("File not found") ); 0910 item->setForeground( 0, d->negativeTextColor ); 0911 item->setIcon( 0, QIcon::fromTheme( "dialog-error") ); 0912 } 0913 0914 slotToggleAll(); 0915 } 0916 0917 0918 void K3b::ImageWritingDialog::toggleAll() 0919 { 0920 0921 K3b::Medium medium = k3bappcore->mediaCache()->medium( d->writerSelectionWidget->writerDevice() ); 0922 0923 // set usable writing apps 0924 // for now we only restrict ourselves in case of CD images 0925 switch( d->currentImageType() ) { 0926 case IMAGE_CDRDAO_TOC: 0927 d->writerSelectionWidget->setSupportedWritingApps( K3b::WritingAppCdrdao ); 0928 break; 0929 case IMAGE_CDRECORD_CLONE: 0930 d->writerSelectionWidget->setSupportedWritingApps( K3b::WritingAppCdrecord ); 0931 break; 0932 default: { 0933 K3b::WritingApps apps = K3b::WritingAppCdrecord; 0934 if (d->currentImageType() == IMAGE_ISO || d->currentImageType() == IMAGE_RAW) { 0935 // DVD/BD is always ISO here 0936 apps |= K3b::WritingAppGrowisofs; 0937 } 0938 if ( K3b::Device::isCdMedia( medium.diskInfo().mediaType() ) ) 0939 apps |= K3b::WritingAppCdrdao; 0940 0941 d->writerSelectionWidget->setSupportedWritingApps( apps ); 0942 break; 0943 } 0944 } 0945 0946 // set a wanted media type 0947 // some image types can be put on any medium, some only on CD 0948 if (d->currentImageType() == IMAGE_ISO || 0949 d->currentImageType() == IMAGE_RAW || 0950 d->currentImageType() == IMAGE_UNKNOWN) { 0951 d->writerSelectionWidget->setWantedMediumType( K3b::Device::MEDIA_WRITABLE ); 0952 } 0953 else { 0954 d->writerSelectionWidget->setWantedMediumType( K3b::Device::MEDIA_WRITABLE_CD ); 0955 } 0956 0957 // set wanted image size 0958 if (d->currentImageType() == IMAGE_ISO || d->currentImageType() == IMAGE_RAW) 0959 d->writerSelectionWidget->setWantedMediumSize( K3b::filesize( QUrl::fromLocalFile(d->imagePath()) )/2048 ); 0960 else 0961 d->writerSelectionWidget->setWantedMediumSize( Msf() ); 0962 0963 // cdrecord clone and cue both need DAO 0964 if( d->writerSelectionWidget->writingApp() != K3b::WritingAppCdrdao 0965 && ( d->currentImageType() == IMAGE_ISO || 0966 d->currentImageType() == IMAGE_AUDIO_CUE ) ) 0967 d->writingModeWidget->determineSupportedModesFromMedium( medium ); 0968 else 0969 d->writingModeWidget->setSupportedModes( K3b::WritingModeSao ); 0970 0971 // enable the Write-Button if we found a valid image or the user forced an image type 0972 setButtonEnabled( START_BUTTON, d->writerSelectionWidget->writerDevice() 0973 && d->currentImageType() != IMAGE_UNKNOWN 0974 && QFile::exists( d->imagePath() ) ); 0975 0976 // some stuff is only available for iso and opaque images 0977 if (d->currentImageType() == IMAGE_ISO || d->currentImageType() == IMAGE_RAW) { 0978 d->checkVerify->show(); 0979 if( !d->advancedTabVisible ) { 0980 d->advancedTabIndex = d->optionTabbed->addTab( d->advancedTab, i18n("Advanced") ); 0981 } 0982 d->advancedTabVisible = true; 0983 if( d->checkDummy->isChecked() ) { 0984 d->checkVerify->setEnabled( false ); 0985 d->checkVerify->setChecked( false ); 0986 } 0987 else 0988 d->checkVerify->setEnabled( true ); 0989 } 0990 else { 0991 if( d->advancedTabVisible ) { 0992 d->optionTabbed->removeTab( d->advancedTabIndex ); 0993 } 0994 d->advancedTabVisible = false; 0995 d->checkVerify->hide(); 0996 } 0997 0998 0999 // and some other stuff only makes sense for audio cues 1000 if( d->currentImageType() == IMAGE_AUDIO_CUE ) { 1001 if( !d->tempPathTabVisible ) 1002 d->tempPathTabIndex = d->optionTabbed->addTab( d->tempPathTab, i18n("&Image") ); 1003 d->tempPathTabVisible = true; 1004 d->tempDirSelectionWidget->setDisabled( !d->checkCacheImage->isChecked() ); 1005 } 1006 else { 1007 if( d->tempPathTabVisible ) { 1008 d->optionTabbed->removeTab( d->tempPathTabIndex ); 1009 } 1010 d->tempPathTabVisible = false; 1011 } 1012 d->checkCacheImage->setVisible( d->currentImageType() == IMAGE_AUDIO_CUE ); 1013 1014 d->spinCopies->setEnabled( !d->checkDummy->isChecked() ); 1015 1016 1017 if( QTreeWidgetItem* item = d->infoView->topLevelItem( 0 ) ) { 1018 item->setForeground( 1, 1019 d->currentImageType() != d->foundImageType 1020 ? d->negativeTextColor : d->normalTextColor ); 1021 } 1022 } 1023 1024 1025 void K3b::ImageWritingDialog::setImage( const QUrl& url ) 1026 { 1027 d->imageForced = true; 1028 d->editImagePath->setUrl( url ); 1029 } 1030 1031 1032 void K3b::ImageWritingDialog::calculateMd5Sum( const QString& file ) 1033 { 1034 d->haveMd5Sum = false; 1035 1036 if( !d->md5SumItem ) { 1037 d->md5SumItem = new QTreeWidgetItem( d->infoView ); 1038 } 1039 1040 d->md5SumItem->setText( 0, i18n("MD5 Sum:") ); 1041 d->md5SumItem->setForeground( 0, d->infoTextColor ); 1042 d->md5SumItem->setTextAlignment( 0, Qt::AlignRight ); 1043 1044 if( file != d->lastCheckedFile ) { 1045 1046 QProgressBar* progress = new QProgressBar( d->infoView ); 1047 progress->setMaximumHeight( fontMetrics().height() ); 1048 progress->setRange( 0, 100 ); 1049 progress->setValue( 0 ); 1050 d->infoView->setItemWidget( d->md5SumItem, 1, progress ); 1051 d->lastCheckedFile = file; 1052 d->md5Job->setFile( file ); 1053 d->md5Job->start(); 1054 } 1055 else 1056 slotMd5JobFinished( true ); 1057 } 1058 1059 1060 void K3b::ImageWritingDialog::slotMd5JobPercent( int p ) 1061 { 1062 QWidget* widget = d->infoView->itemWidget( d->md5SumItem, 1 ); 1063 if( QProgressBar* progress = qobject_cast<QProgressBar*>( widget ) ) 1064 { 1065 progress->setValue( p ); 1066 } 1067 } 1068 1069 1070 void K3b::ImageWritingDialog::slotMd5JobFinished( bool success ) 1071 { 1072 if( success ) { 1073 d->md5SumItem->setText( 1, d->md5Job->hexDigest() ); 1074 d->md5SumItem->setIcon( 1, QIcon::fromTheme("dialog-information") ); 1075 d->haveMd5Sum = true; 1076 } 1077 else { 1078 d->md5SumItem->setForeground( 1, d->negativeTextColor ); 1079 if( d->md5Job->hasBeenCanceled() ) 1080 d->md5SumItem->setText( 1, i18n("Calculation canceled") ); 1081 else 1082 d->md5SumItem->setText( 1, i18n("Calculation failed") ); 1083 d->md5SumItem->setIcon( 1, QIcon::fromTheme("dialog-error") ); 1084 d->lastCheckedFile.truncate(0); 1085 } 1086 1087 // Hide progress bar 1088 d->infoView->setItemWidget( d->md5SumItem, 1, 0 ); 1089 } 1090 1091 1092 void K3b::ImageWritingDialog::slotContextMenuRequested( const QPoint& pos ) 1093 { 1094 if( !d->haveMd5Sum ) 1095 return; 1096 1097 QMenu popup; 1098 QAction *copyItem = popup.addAction( i18n("Copy checksum to clipboard") ); 1099 QAction *compareItem = popup.addAction( i18n("Compare checksum...") ); 1100 1101 QAction *act = popup.exec( d->infoView->mapToGlobal( pos ) ); 1102 1103 if( act == compareItem ) { 1104 bool ok; 1105 QString md5sumToCompare = QInputDialog::getText( this, 1106 i18n("MD5 Sum Check"), 1107 i18n("Please insert the MD5 Sum to compare:"), 1108 QLineEdit::Normal, 1109 QString(), 1110 &ok ); 1111 if( ok ) { 1112 if( md5sumToCompare.toLower().toUtf8() == d->md5Job->hexDigest().toLower() ) 1113 KMessageBox::information( this, i18n("The MD5 Sum of %1 equals that specified.",d->imagePath()), 1114 i18n("MD5 Sums Equal") ); 1115 else 1116 KMessageBox::error( this, i18n("The MD5 Sum of %1 differs from that specified.",d->imagePath()), 1117 i18n("MD5 Sums Differ") ); 1118 } 1119 } 1120 else if( act == copyItem ) { 1121 QApplication::clipboard()->setText( d->md5Job->hexDigest().toLower(), QClipboard::Clipboard ); 1122 } 1123 } 1124 1125 1126 void K3b::ImageWritingDialog::loadSettings( const KConfigGroup& c ) 1127 { 1128 d->writingModeWidget->loadConfig( c ); 1129 d->checkDummy->setChecked( c.readEntry("simulate", false ) ); 1130 d->checkNoFix->setChecked( c.readEntry("multisession", false ) ); 1131 d->checkCacheImage->setChecked( !c.readEntry("on_the_fly", true ) ); 1132 1133 d->dataModeWidget->loadConfig(c); 1134 1135 d->spinCopies->setValue( c.readEntry( "copies", 1 ) ); 1136 1137 d->checkVerify->setChecked( c.readEntry( "verify_data", false ) ); 1138 1139 d->writerSelectionWidget->loadConfig( c ); 1140 1141 if( !d->imageForced ) { 1142 QString image = c.readPathEntry( "image path", c.readPathEntry( "last written image", QString() ) ); 1143 if( QFile::exists( image ) ) 1144 d->editImagePath->setUrl( QUrl::fromLocalFile( image ) ); 1145 } 1146 1147 QString imageType = c.readEntry( "image type", "auto" ); 1148 int x = 0; 1149 if( imageType == "iso9660" ) 1150 x = d->imageTypeSelectionMapRev[IMAGE_ISO]; 1151 else if( imageType == "cue-bin" ) 1152 x = d->imageTypeSelectionMapRev[IMAGE_CUE_BIN]; 1153 else if( imageType == "audio-cue" ) 1154 x = d->imageTypeSelectionMapRev[IMAGE_AUDIO_CUE]; 1155 else if( imageType == "cdrecord-clone" ) 1156 x = d->imageTypeSelectionMapRev[IMAGE_CDRECORD_CLONE]; 1157 else if( imageType == "cdrdao-toc" ) 1158 x = d->imageTypeSelectionMapRev[IMAGE_CDRDAO_TOC]; 1159 else if (imageType == "opaque") 1160 x = d->imageTypeSelectionMapRev[IMAGE_RAW]; 1161 1162 d->comboImageType->setCurrentIndex( x ); 1163 1164 d->tempDirSelectionWidget->setTempPath( K3b::defaultTempPath() ); 1165 1166 slotToggleAll(); 1167 } 1168 1169 1170 void K3b::ImageWritingDialog::saveSettings( KConfigGroup c ) 1171 { 1172 d->writingModeWidget->saveConfig( c ), 1173 c.writeEntry( "simulate", d->checkDummy->isChecked() ); 1174 c.writeEntry( "multisession", d->checkNoFix->isChecked() ); 1175 c.writeEntry( "on_the_fly", !d->checkCacheImage->isChecked() ); 1176 d->dataModeWidget->saveConfig(c); 1177 1178 c.writeEntry( "verify_data", d->checkVerify->isChecked() ); 1179 1180 d->writerSelectionWidget->saveConfig( c ); 1181 1182 c.writePathEntry( "image path", d->imagePath() ); 1183 1184 c.writeEntry( "copies", d->spinCopies->value() ); 1185 1186 QString imageType; 1187 if( d->comboImageType->currentIndex() == 0 ) 1188 imageType = "auto"; 1189 else { 1190 switch( d->imageTypeSelectionMap[d->comboImageType->currentIndex()] ) { 1191 case IMAGE_ISO: 1192 imageType = "iso9660"; 1193 break; 1194 case IMAGE_CUE_BIN: 1195 imageType = "cue-bin"; 1196 break; 1197 case IMAGE_AUDIO_CUE: 1198 imageType = "audio-cue"; 1199 break; 1200 case IMAGE_CDRECORD_CLONE: 1201 imageType = "cdrecord-clone"; 1202 break; 1203 case IMAGE_CDRDAO_TOC: 1204 imageType = "cdrdao-toc"; 1205 break; 1206 case IMAGE_RAW: 1207 imageType = "opaque"; 1208 break; 1209 } 1210 } 1211 c.writeEntry( "image type", imageType ); 1212 1213 if( d->tempDirSelectionWidget->isEnabled() ) 1214 d->tempDirSelectionWidget->saveConfig(); 1215 } 1216 1217 1218 void K3b::ImageWritingDialog::dragEnterEvent( QDragEnterEvent* e ) 1219 { 1220 e->setAccepted( e->mimeData()->hasUrls() ); 1221 } 1222 1223 1224 void K3b::ImageWritingDialog::dropEvent( QDropEvent* e ) 1225 { 1226 QList<QUrl> urls = e->mimeData()->urls(); 1227 if( !urls.isEmpty() ) { 1228 d->editImagePath->setUrl( urls.first() ); 1229 } 1230 } 1231 1232 #include "moc_k3bimagewritingdialog.cpp"