File indexing completed on 2024-10-06 04:25:59
0001 /* 0002 SPDX-FileCopyrightText: 1998-2010 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 0007 #include "k3bemptydiscwaiter.h" 0008 #include "k3bmediacache.h" 0009 #include "k3bapplication.h" 0010 #include "k3bdevice.h" 0011 #include "k3bdeviceglobals.h" 0012 #include "k3bdevicehandler.h" 0013 #include "k3bglobals.h" 0014 #include "k3bcore.h" 0015 #include "k3biso9660.h" 0016 #include "k3bblankingjob.h" 0017 #include "k3bbusywidget.h" 0018 #include "k3bdvdformattingjob.h" 0019 0020 #include <KConfig> 0021 #include <KConfigGroup> 0022 #include <KSharedConfig> 0023 #include <KIconLoader> 0024 #include <KLocalizedString> 0025 #include <KNotification> 0026 #include <KGuiItem> 0027 #include <KMessageBox> 0028 0029 #include <QEventLoop> 0030 #include <QTimer> 0031 #include <QFont> 0032 #include <QApplication> 0033 #include <QDialogButtonBox> 0034 #include <QGridLayout> 0035 #include <QLabel> 0036 #include <QLayout> 0037 #include <QProgressDialog> 0038 #include <QPushButton> 0039 #include <QToolTip> 0040 0041 0042 class K3b::EmptyDiscWaiter::Private 0043 { 0044 public: 0045 Private() 0046 : erasingInfoDialog(0) { 0047 dialogVisible = false; 0048 inLoop = false; 0049 mediumChanged = 0; 0050 blockMediaChange = false; 0051 } 0052 0053 K3b::Device::Device* device; 0054 0055 Device::MediaTypes wantedMediaType; 0056 Device::MediaStates wantedMediaState; 0057 Msf wantedMinMediaSize; 0058 0059 Device::MediaType result; 0060 int dialogVisible; 0061 bool inLoop; 0062 0063 bool blockMediaChange; 0064 int mediumChanged; 0065 0066 bool canceled; 0067 0068 bool waitingDone; 0069 0070 QLabel* labelRequest; 0071 QLabel* labelFoundMedia; 0072 QLabel* pixLabel; 0073 0074 QProgressDialog* erasingInfoDialog; 0075 }; 0076 0077 0078 0079 K3b::EmptyDiscWaiter::EmptyDiscWaiter( K3b::Device::Device* device, QWidget* parent ) 0080 : QDialog( parent ), 0081 d( new Private() ) 0082 { 0083 setWindowTitle(i18n("Waiting for Disk")); 0084 setModal(true); 0085 0086 d->device = device; 0087 0088 // setup the gui 0089 // ----------------------------- 0090 d->labelRequest = new QLabel( this ); 0091 d->labelRequest->setAlignment( Qt::AlignLeft | Qt::AlignVCenter ); 0092 d->labelFoundMedia = new QLabel( this ); 0093 d->pixLabel = new QLabel( this ); 0094 d->pixLabel->setAlignment( Qt::AlignHCenter | Qt::AlignTop ); 0095 0096 QFont f( d->labelFoundMedia->font() ); 0097 f.setBold(true); 0098 d->labelFoundMedia->setFont( f ); 0099 0100 QDialogButtonBox* buttonBox = new QDialogButtonBox( this ); 0101 0102 QPushButton* cancelButton = buttonBox->addButton( QDialogButtonBox::Cancel ); 0103 connect( cancelButton, SIGNAL(clicked()), this, SLOT(slotCancel()) ); 0104 0105 QPushButton* ejectButton = new QPushButton( this ); 0106 KGuiItem::assign( ejectButton, KGuiItem( i18n("Eject"), QString::fromLatin1( "media-eject" ) ) ); 0107 buttonBox->addButton( ejectButton, QDialogButtonBox::NoRole ); 0108 connect( ejectButton, SIGNAL(clicked()), this, SLOT(slotEject()) ); 0109 0110 QPushButton* loadButton = buttonBox->addButton( i18n("Load"), QDialogButtonBox::NoRole ); 0111 connect( loadButton, SIGNAL(clicked()), this, SLOT(slotLoad()) ); 0112 0113 QVBoxLayout* box = new QVBoxLayout( this ); 0114 QHBoxLayout* hbox = new QHBoxLayout( this ); 0115 0116 hbox->addWidget(d->pixLabel); 0117 QVBoxLayout* vbox = new QVBoxLayout( this ); 0118 vbox->addWidget(new QLabel(i18n("Found medium:"), this)); 0119 vbox->addWidget(d->labelFoundMedia); 0120 vbox->addWidget(d->labelRequest); 0121 hbox->addLayout( vbox ); 0122 box->addLayout( hbox ); 0123 box->addWidget(buttonBox); 0124 // ----------------------------- 0125 0126 connect( k3bappcore->mediaCache(), SIGNAL(mediumChanged(K3b::Device::Device*)), 0127 this, SLOT(slotMediumChanged(K3b::Device::Device*)) ); 0128 } 0129 0130 0131 K3b::EmptyDiscWaiter::~EmptyDiscWaiter() 0132 { 0133 delete d; 0134 } 0135 0136 0137 K3b::Device::MediaType K3b::EmptyDiscWaiter::waitForDisc( Device::MediaStates mediaState, 0138 Device::MediaTypes mediaType, 0139 const K3b::Msf& minMediaSize, 0140 const QString& message ) 0141 { 0142 if ( d->inLoop ) { 0143 qCritical() << "Recursive call detected." << Qt::endl; 0144 return Device::MEDIA_UNKNOWN; 0145 } 0146 0147 qDebug() << "Waiting for medium" << mediaState << mediaType << message; 0148 0149 d->wantedMediaState = mediaState; 0150 d->wantedMediaType = mediaType; 0151 d->wantedMinMediaSize = minMediaSize; 0152 d->dialogVisible = false; 0153 d->canceled = false; 0154 d->waitingDone = false; 0155 d->blockMediaChange = false; 0156 d->mediumChanged = 0; 0157 0158 // FIXME: reproducibility race? 0159 if (message.isEmpty()) 0160 d->labelRequest->setText( Medium::mediaRequestString( d->wantedMediaType, d->wantedMediaState, minMediaSize, d->device ) ); 0161 else 0162 d->labelRequest->setText( message ); 0163 0164 if( d->wantedMediaType & K3b::Device::MEDIA_WRITABLE_DVD ) 0165 d->pixLabel->setPixmap( KIconLoader::global()->loadIcon( "media-optical-dvd", 0166 KIconLoader::NoGroup, KIconLoader::SizeMedium ) ); 0167 else 0168 d->pixLabel->setPixmap( KIconLoader::global()->loadIcon( "media-optical-recordable", 0169 KIconLoader::NoGroup, KIconLoader::SizeMedium ) ); 0170 0171 adjustSize(); 0172 0173 slotMediumChanged( d->device ); 0174 0175 // 0176 // in case we already found a medium and thus the dialog is not shown entering 0177 // the loop only causes problems (since there is no dialog yet the user could 0178 // not have canceled yet 0179 // 0180 if( !d->waitingDone ) { 0181 d->inLoop = true; 0182 enterLoop(); 0183 } 0184 return d->result; 0185 } 0186 0187 void K3b::EmptyDiscWaiter::enterLoop() 0188 { 0189 QEventLoop eventLoop; 0190 connect(this, SIGNAL(leaveModality()), 0191 &eventLoop, SLOT(quit())); 0192 eventLoop.exec(); 0193 } 0194 0195 int K3b::EmptyDiscWaiter::exec() 0196 { 0197 return waitForDisc(); 0198 } 0199 0200 0201 void K3b::EmptyDiscWaiter::slotMediumChanged( K3b::Device::Device* dev ) 0202 { 0203 qDebug() << dev->blockDeviceName(); 0204 if( d->canceled || d->device != dev ) 0205 return; 0206 0207 // 0208 // This slot may open dialogs which enter a new event loop and that 0209 // may result in another call to this slot if a medium changes while 0210 // a dialog is open 0211 // 0212 if( d->blockMediaChange ) { 0213 d->mediumChanged++; 0214 return; 0215 } 0216 0217 d->blockMediaChange = true; 0218 0219 bool formatWithoutAsking = KConfigGroup( KSharedConfig::openConfig(), QStringLiteral("General Options") ).readEntry( "auto rewritable erasing", false ); 0220 0221 K3b::Medium medium = k3bappcore->mediaCache()->medium( dev ); 0222 0223 d->labelFoundMedia->setText( medium.shortString( Medium::NoStringFlags ) ); 0224 0225 if( medium.diskInfo().diskState() == K3b::Device::STATE_NO_MEDIA ) { 0226 continueWaiting(); 0227 d->blockMediaChange = false; 0228 return; 0229 } 0230 0231 // QString mediaState; 0232 // if( medium.diskInfo().diskState() == K3b::Device::STATE_COMPLETE ) 0233 // mediaState = i18n("complete"); 0234 // else if( medium.diskInfo().diskState() == K3b::Device::STATE_INCOMPLETE ) 0235 // mediaState = i18n("appendable"); 0236 // else if( medium.diskInfo().diskState() == K3b::Device::STATE_EMPTY ) 0237 // mediaState = i18n("empty"); 0238 0239 // if( !mediaState.isEmpty() ) 0240 // mediaState = " (" + mediaState +")"; 0241 0242 // ///////////////////////////////////////////////////////////// 0243 // 0244 // BD-RE handling 0245 // 0246 // ///////////////////////////////////////////////////////////// 0247 if ( (d->wantedMediaType & K3b::Device::MEDIA_BD_RE) && 0248 (medium.diskInfo().mediaType() & K3b::Device::MEDIA_BD_RE) ) { 0249 0250 qDebug() << "------ found BD-RE as wanted."; 0251 0252 #ifdef _MSC_VER 0253 #pragma message ("WARNING: FIXME: We need to preformat empty BD-RE just like we do with empty DVD+RW") 0254 #else 0255 #warning FIXME: We need to preformat empty BD-RE just like we do with empty DVD+RW 0256 #endif 0257 0258 if( d->wantedMediaState == K3b::Device::STATE_EMPTY && 0259 ( d->wantedMinMediaSize <= medium.diskInfo().capacity() || 0260 IsOverburnAllowed( d->wantedMinMediaSize, medium.diskInfo().capacity() ) ) ) { 0261 // check if the media contains a filesystem 0262 K3b::Iso9660 isoF( d->device ); 0263 bool hasIso = isoF.open(); 0264 0265 if( formatWithoutAsking || 0266 !hasIso || 0267 KMessageBox::warningContinueCancel( parentWidgetToUse(), 0268 i18n("Found %1 medium in %2 - %3. Should it be overwritten?", 0269 QLatin1String("BD-RE"), 0270 d->device->vendor(), 0271 d->device->description()), 0272 i18n("Found %1", QLatin1String("BD-RE")), 0273 KStandardGuiItem::overwrite(), 0274 KGuiItem(i18n("&Eject"), "media-eject") ) == KMessageBox::Continue ) { 0275 finishWaiting( K3b::Device::MEDIA_BD_RE ); 0276 } 0277 else { 0278 qDebug() << "starting devicehandler: no BD-RE overwrite"; 0279 K3b::eject( d->device ); 0280 continueWaiting(); 0281 } 0282 } 0283 0284 // 0285 // We want a BD-RE not necessarily empty. No problem, just use this one. Because incomplete and complete 0286 // are handled the same everywhere (isofs is grown). 0287 // 0288 else if ( d->wantedMediaState != Device::STATE_EMPTY && 0289 ( d->wantedMinMediaSize <= medium.actuallyRemainingSize() || 0290 IsOverburnAllowed( d->wantedMinMediaSize, medium.diskInfo().capacity(), medium.actuallyUsedCapacity() ) ) ) { 0291 finishWaiting( K3b::Device::MEDIA_BD_RE ); 0292 } 0293 else { 0294 qDebug() << "BD-RE medium too small"; 0295 continueWaiting(); 0296 } 0297 } 0298 0299 // ///////////////////////////////////////////////////////////// 0300 // 0301 // DVD+RW handling 0302 // 0303 // ///////////////////////////////////////////////////////////// 0304 0305 // DVD+RW: if empty we need to preformat. Although growisofs does it before writing doing it here 0306 // allows better control and a progress bar. If it's not empty we should check if there is 0307 // already a filesystem on the medium. 0308 else if( (d->wantedMediaType & K3b::Device::MEDIA_DVD_PLUS_RW) && 0309 (medium.diskInfo().mediaType() & K3b::Device::MEDIA_DVD_PLUS_RW) ) { 0310 0311 qDebug() << "------ found DVD+RW as wanted."; 0312 0313 if( medium.diskInfo().diskState() == K3b::Device::STATE_EMPTY ) { 0314 if( d->wantedMediaState & K3b::Device::STATE_EMPTY && 0315 ( d->wantedMinMediaSize <= medium.diskInfo().capacity() || 0316 IsOverburnAllowed( d->wantedMinMediaSize, medium.diskInfo().capacity() ) ) ) { 0317 // special case for the formatting job which wants to preformat on it's own! 0318 if( d->wantedMediaState & K3b::Device::STATE_COMPLETE && 0319 d->wantedMediaState & K3b::Device::STATE_EMPTY ) { 0320 qDebug() << "special case: DVD+RW for the formatting job."; 0321 finishWaiting( K3b::Device::MEDIA_DVD_PLUS_RW ); 0322 } 0323 else { 0324 // empty - preformat without asking 0325 prepareErasingDialog(); 0326 0327 K3b::DvdFormattingJob job( this ); 0328 job.setDevice( d->device ); 0329 job.setFormattingMode( FormattingQuick ); 0330 job.setForce( false ); 0331 job.setForceNoEject( true ); 0332 0333 d->erasingInfoDialog->reset(); 0334 d->erasingInfoDialog->setLabelText( i18n("Preformatting DVD+RW") ); 0335 d->erasingInfoDialog->setRange( 0, 100 ); 0336 connect( &job, SIGNAL(finished(bool)), this, SLOT(slotErasingFinished(bool)) ); 0337 connect( &job, SIGNAL(percent(int)), d->erasingInfoDialog, SLOT(setValue(int)) ); 0338 connect( d->erasingInfoDialog, SIGNAL(cancelClicked()), &job, SLOT(cancel()) ); 0339 job.start( medium.diskInfo() ); 0340 d->erasingInfoDialog->exec(); 0341 } 0342 } 0343 else { 0344 qDebug() << "starting devicehandler: empty DVD+RW where a non-empty was requested."; 0345 continueWaiting(); 0346 } 0347 } 0348 else { 0349 // 0350 // We have a DVD+RW medium which is already preformatted 0351 // 0352 if( d->wantedMediaState == K3b::Device::STATE_EMPTY ) { 0353 if ( d->wantedMinMediaSize <= medium.diskInfo().capacity() || 0354 IsOverburnAllowed( d->wantedMinMediaSize, medium.diskInfo().capacity() ) ) { 0355 // check if the media contains a filesystem 0356 K3b::Iso9660 isoF( d->device ); 0357 bool hasIso = isoF.open(); 0358 0359 if( formatWithoutAsking || 0360 !hasIso || 0361 KMessageBox::warningContinueCancel( parentWidgetToUse(), 0362 i18n("Found %1 medium in %2 - %3. " 0363 "Should it be overwritten?", 0364 QString("DVD+RW"), 0365 d->device->vendor(), 0366 d->device->description()), 0367 i18n("Found %1",QString("DVD+RW")), 0368 KStandardGuiItem::overwrite(), 0369 KGuiItem(i18n("&Eject"), "media-eject") ) == KMessageBox::Continue ) { 0370 finishWaiting( K3b::Device::MEDIA_DVD_PLUS_RW ); 0371 } 0372 else { 0373 qDebug() << "starting devicehandler: no DVD+RW overwrite"; 0374 K3b::eject( d->device ); 0375 continueWaiting(); 0376 } 0377 } 0378 else { 0379 qDebug() << "starting devicehandler: DVD+RW too small"; 0380 continueWaiting(); 0381 } 0382 } 0383 0384 // 0385 // We want a DVD+RW not necessarily empty. No problem, just use this one. Because incomplete and complete 0386 // are handled the same everywhere (isofs is grown). 0387 // 0388 else if ( d->wantedMinMediaSize <= medium.actuallyRemainingSize() || 0389 IsOverburnAllowed( d->wantedMinMediaSize, medium.diskInfo().capacity(), medium.actuallyUsedCapacity() ) ) { 0390 finishWaiting( K3b::Device::MEDIA_DVD_PLUS_RW ); 0391 } 0392 else { 0393 qDebug() << "starting devicehandler: DVD+RW too small"; 0394 continueWaiting(); 0395 } 0396 } 0397 } // --- DVD+RW -------- 0398 0399 0400 // ///////////////////////////////////////////////////////////// 0401 // 0402 // DVD-RW handling 0403 // 0404 // ///////////////////////////////////////////////////////////// 0405 0406 // 0407 // DVD-RW in sequential mode can be empty. DVD-RW in restricted overwrite mode is always complete. 0408 // 0409 else if( (d->wantedMediaType & (K3b::Device::MEDIA_DVD_RW| 0410 K3b::Device::MEDIA_DVD_RW_SEQ| 0411 K3b::Device::MEDIA_DVD_RW_OVWR) ) && 0412 (medium.diskInfo().mediaType() & (K3b::Device::MEDIA_DVD_RW| 0413 K3b::Device::MEDIA_DVD_RW_SEQ| 0414 K3b::Device::MEDIA_DVD_RW_OVWR) ) ) { 0415 0416 qDebug() << "------ found DVD-R(W) as wanted."; 0417 0418 // we format in the following cases: 0419 // seq. incr. and not empty and empty requested 0420 // seq. incr. and restr. overwri. requested 0421 // restr. ovw. and seq. incr. requested 0422 0423 // we have exactly what was requested (K3b never requests a specific 0424 // size for read-only cases, thus using remainingSize() is perfectly fine) 0425 if( (d->wantedMediaType & medium.diskInfo().mediaType()) && 0426 (d->wantedMediaState & medium.diskInfo().diskState()) && 0427 ( d->wantedMinMediaSize <= medium.actuallyRemainingSize() || 0428 IsOverburnAllowed( d->wantedMinMediaSize, medium.diskInfo().capacity(), medium.actuallyUsedCapacity() ) ) ) { 0429 finishWaiting( medium.diskInfo().mediaType() ); 0430 } 0431 0432 // DVD-RW in restr. overwrite may just be overwritten 0433 else if( (medium.diskInfo().mediaType() & K3b::Device::MEDIA_DVD_RW_OVWR) && 0434 (d->wantedMediaType & K3b::Device::MEDIA_DVD_RW_OVWR) ) { 0435 if( d->wantedMediaState == K3b::Device::STATE_EMPTY && 0436 ( d->wantedMinMediaSize <= medium.diskInfo().capacity() || 0437 IsOverburnAllowed( d->wantedMinMediaSize, medium.diskInfo().capacity() ) ) ) { 0438 0439 qDebug() << "------ DVD-RW restricted overwrite."; 0440 0441 // check if the media contains a filesystem 0442 K3b::Iso9660 isoF( d->device ); 0443 bool hasIso = isoF.open(); 0444 0445 if( formatWithoutAsking || 0446 !hasIso || 0447 KMessageBox::warningContinueCancel( parentWidgetToUse(), 0448 i18n("Found %1 medium in %2 - %3. " 0449 "Should it be overwritten?", 0450 K3b::Device::mediaTypeString(medium.diskInfo().mediaType()), 0451 d->device->vendor(), 0452 d->device->description()), 0453 i18n("Found %1",QString("DVD-RW")), 0454 KStandardGuiItem::overwrite(), 0455 KGuiItem(i18n("&Eject"), "media-eject")) == KMessageBox::Continue ) { 0456 finishWaiting( K3b::Device::MEDIA_DVD_RW_OVWR ); 0457 } 0458 else { 0459 qDebug() << "starting devicehandler: no DVD-RW overwrite."; 0460 K3b::eject( d->device ); 0461 continueWaiting(); 0462 } 0463 } 0464 0465 // no need to check the size here. K3b never asks for non-empty media by size 0466 else if( !(d->wantedMediaState & K3b::Device::STATE_EMPTY ) ) { 0467 // check if the media contains a filesystem 0468 K3b::Iso9660 isoF( d->device ); 0469 bool hasIso = isoF.open(); 0470 0471 if( hasIso ) { 0472 finishWaiting( K3b::Device::MEDIA_DVD_RW_OVWR ); 0473 } 0474 else { 0475 qDebug() << "starting devicehandler: empty DVD-RW where a non-empty was requested."; 0476 continueWaiting(); 0477 } 0478 } 0479 0480 // 0481 // We want a DVD-RW overwrite not necessarily empty. No problem, just use this one. Because incomplete and complete 0482 // are handled the same everywhere (isofs is grown). 0483 // 0484 else if ( d->wantedMinMediaSize <= medium.actuallyRemainingSize() || 0485 IsOverburnAllowed( d->wantedMinMediaSize, medium.diskInfo().capacity(), medium.actuallyUsedCapacity() ) ) { 0486 finishWaiting( K3b::Device::MEDIA_DVD_RW_OVWR ); 0487 } 0488 else { 0489 qDebug() << "starting devicehandler: DVD-RW too small"; 0490 continueWaiting(); 0491 } 0492 } 0493 0494 // formatting 0495 else if( ( (d->wantedMediaType & K3b::Device::MEDIA_DVD_RW_OVWR) && 0496 (medium.diskInfo().mediaType() & K3b::Device::MEDIA_DVD_RW_SEQ) && 0497 !(d->wantedMediaType & K3b::Device::MEDIA_DVD_RW_SEQ) ) || 0498 0499 ( (d->wantedMediaType & K3b::Device::MEDIA_DVD_RW_SEQ) && 0500 (medium.diskInfo().mediaType() & K3b::Device::MEDIA_DVD_RW_OVWR) && 0501 !(d->wantedMediaType & K3b::Device::MEDIA_DVD_RW_OVWR) ) || 0502 0503 ( (d->wantedMediaType & K3b::Device::MEDIA_DVD_RW_SEQ) && 0504 (medium.diskInfo().mediaType() & K3b::Device::MEDIA_DVD_RW_SEQ) && 0505 (d->wantedMediaState & K3b::Device::STATE_EMPTY) && 0506 (medium.diskInfo().diskState() != K3b::Device::STATE_EMPTY) ) ) { 0507 0508 qDebug() << "------ DVD-RW needs to be formatted."; 0509 0510 if( formatWithoutAsking || 0511 KMessageBox::warningContinueCancel( parentWidgetToUse(), 0512 i18n("Found %1 medium in %2 - %3. " 0513 "Should it be formatted?", 0514 K3b::Device::mediaTypeString(medium.diskInfo().mediaType()), 0515 d->device->vendor(), 0516 d->device->description()), 0517 i18n("Found %1",QString("DVD-RW")), 0518 KGuiItem(i18n("&Format"), "tools-media-optical-format"), 0519 KGuiItem(i18n("&Eject"), "media-eject")) == KMessageBox::Continue ) { 0520 0521 qDebug() << "------ formatting DVD-RW."; 0522 0523 prepareErasingDialog(); 0524 0525 K3b::DvdFormattingJob job( this ); 0526 job.setDevice( d->device ); 0527 // we prefer the current mode of the media if no special mode has been requested 0528 job.setMode( ( (d->wantedMediaType & K3b::Device::MEDIA_DVD_RW_SEQ) && 0529 (d->wantedMediaType & K3b::Device::MEDIA_DVD_RW_OVWR) ) 0530 ? ( medium.diskInfo().mediaType() == K3b::Device::MEDIA_DVD_RW_OVWR 0531 ? K3b::WritingModeRestrictedOverwrite 0532 : K3b::WritingModeIncrementalSequential ) 0533 : ( (d->wantedMediaType & K3b::Device::MEDIA_DVD_RW_SEQ) 0534 ? K3b::WritingModeIncrementalSequential 0535 : K3b::WritingModeRestrictedOverwrite ) ); 0536 job.setFormattingMode( FormattingQuick ); 0537 job.setForce( false ); 0538 job.setForceNoEject(true); 0539 0540 d->erasingInfoDialog->reset(); 0541 d->erasingInfoDialog->setLabelText( i18n("Formatting DVD-RW") ); 0542 d->erasingInfoDialog->setRange( 0, 100 ); 0543 connect( &job, SIGNAL(finished(bool)), this, SLOT(slotErasingFinished(bool)) ); 0544 connect( &job, SIGNAL(percent(int)), d->erasingInfoDialog, SLOT(setValue(int)) ); 0545 connect( d->erasingInfoDialog, SIGNAL(cancelClicked()), &job, SLOT(cancel()) ); 0546 job.start( medium.diskInfo() ); 0547 d->erasingInfoDialog->exec(); 0548 } 0549 else { 0550 qDebug() << "starting devicehandler: no DVD-RW formatting."; 0551 K3b::eject( d->device ); 0552 continueWaiting(); 0553 } 0554 } 0555 else { 0556 qDebug() << "------ nothing useful found."; 0557 continueWaiting(); 0558 } 0559 } // --- DVD-RW ------ 0560 0561 0562 // ///////////////////////////////////////////////////////////// 0563 // 0564 // CD-RW handling 0565 // 0566 // ///////////////////////////////////////////////////////////// 0567 0568 // format CD-RW 0569 else if( medium.diskInfo().mediaType() == Device::MEDIA_CD_RW && 0570 (d->wantedMediaType & medium.diskInfo().mediaType()) && 0571 (d->wantedMediaState & K3b::Device::STATE_EMPTY) && 0572 !medium.diskInfo().empty() && 0573 medium.diskInfo().rewritable() ) { 0574 0575 if( formatWithoutAsking || 0576 KMessageBox::questionTwoActions(parentWidgetToUse(), 0577 i18n("Found rewritable medium in %1 - %2. " 0578 "Should it be erased?",d->device->vendor(),d->device->description()), 0579 i18n("Found Rewritable Disk"), 0580 KGuiItem(i18n("E&rase"), "tools-media-optical-erase"), 0581 KGuiItem(i18n("&Eject"), "media-eject") ) == KMessageBox::PrimaryAction ) { 0582 0583 0584 prepareErasingDialog(); 0585 0586 // start a k3bblankingjob 0587 d->erasingInfoDialog->reset(); 0588 d->erasingInfoDialog->setLabelText( i18n("Erasing CD-RW") ); 0589 d->erasingInfoDialog->setRange( 0, 0 ); 0590 0591 // the user may be using cdrdao for erasing as cdrecord does not work 0592 WritingApp erasingApp = K3b::WritingAppAuto; 0593 if( KSharedConfig::openConfig()->group( QStringLiteral("General Options") ).readEntry( "Show advanced GUI", false ) ) { 0594 erasingApp = K3b::writingAppFromString( KSharedConfig::openConfig()->group( QStringLiteral("CDRW Erasing") ).readEntry( "writing_app" ) ); 0595 } 0596 0597 K3b::BlankingJob job( this ); 0598 job.setDevice( d->device ); 0599 job.setFormattingMode( FormattingQuick ); 0600 job.setForce(true); 0601 job.setForceNoEject(true); 0602 job.setSpeed( 0 ); // Auto 0603 job.setWritingApp( erasingApp ); 0604 connect( &job, SIGNAL(finished(bool)), this, SLOT(slotErasingFinished(bool)) ); 0605 connect( d->erasingInfoDialog, SIGNAL(cancelClicked()), &job, SLOT(cancel()) ); 0606 job.start(); 0607 d->erasingInfoDialog->exec(); 0608 } 0609 else { 0610 qDebug() << "starting devicehandler: no CD-RW overwrite."; 0611 K3b::eject( d->device ); 0612 continueWaiting(); 0613 } 0614 } 0615 0616 // ///////////////////////////////////////////////////////////// 0617 // 0618 // All the non-rewritable media types are handled here 0619 // 0620 // ///////////////////////////////////////////////////////////// 0621 0622 // we have exactly what was requested (K3b never requests a specific 0623 // size for read-only cases, thus using remainingSize() is perfectly fine) 0624 else if( (d->wantedMediaType & medium.diskInfo().mediaType()) && 0625 (d->wantedMediaState & medium.diskInfo().diskState()) && 0626 (d->wantedMinMediaSize <= medium.actuallyRemainingSize() || 0627 IsOverburnAllowed( d->wantedMinMediaSize, medium.diskInfo().capacity(), medium.actuallyUsedCapacity() )) ) { 0628 finishWaiting( medium.diskInfo().mediaType() ); 0629 } 0630 0631 // this is for CD drives that are not able to determine the state of a disk 0632 else if( medium.diskInfo().diskState() == K3b::Device::STATE_UNKNOWN && 0633 medium.diskInfo().mediaType() == K3b::Device::MEDIA_CD_ROM && 0634 d->wantedMediaType & K3b::Device::MEDIA_CD_ROM ) { 0635 finishWaiting( medium.diskInfo().mediaType() ); 0636 } 0637 0638 else { 0639 qDebug() << "------ nothing useful found."; 0640 continueWaiting(); 0641 } 0642 0643 // handle queued medium changes 0644 d->blockMediaChange = false; 0645 if( d->mediumChanged > 0 ) { 0646 d->mediumChanged--; 0647 slotMediumChanged( dev ); 0648 } 0649 } 0650 0651 0652 void K3b::EmptyDiscWaiter::showDialog() 0653 { 0654 // we need to show the dialog if not done already 0655 if( !d->dialogVisible ) { 0656 0657 KNotification::event( "WaitingForMedium", i18n("Waiting for Medium") ); 0658 0659 d->dialogVisible = true; 0660 //clear it. 0661 setAttribute(Qt::WA_DeleteOnClose,false); 0662 setWindowModality( Qt::NonModal ); 0663 setResult( 0 ); 0664 show(); 0665 } 0666 } 0667 0668 0669 void K3b::EmptyDiscWaiter::continueWaiting() 0670 { 0671 showDialog(); 0672 } 0673 0674 0675 void K3b::EmptyDiscWaiter::slotCancel() 0676 { 0677 qDebug() << "slotCancel() "; 0678 d->canceled = true; 0679 finishWaiting( Device::MEDIA_UNKNOWN ); 0680 } 0681 0682 0683 void K3b::EmptyDiscWaiter::slotEject() 0684 { 0685 K3b::unmount( d->device ); 0686 K3b::Device::eject( d->device ); 0687 } 0688 0689 0690 void K3b::EmptyDiscWaiter::slotLoad() 0691 { 0692 K3b::Device::load( d->device ); 0693 } 0694 0695 0696 void K3b::EmptyDiscWaiter::finishWaiting( Device::MediaType type ) 0697 { 0698 qDebug() << "finishWaiting() "; 0699 0700 d->waitingDone = true; 0701 d->result = type; 0702 0703 if( d->dialogVisible ) 0704 hide(); 0705 0706 if( d->inLoop ) { 0707 d->inLoop = false; 0708 qDebug() << "exitLoop "; 0709 emit leaveModality(); 0710 } 0711 } 0712 0713 0714 void K3b::EmptyDiscWaiter::slotErasingFinished( bool success ) 0715 { 0716 if( success ) { 0717 // close the dialog thus ending it's event loop -> back to slotMediumChanged 0718 d->erasingInfoDialog->hide(); 0719 } 0720 else { 0721 K3b::Device::eject( d->device ); 0722 KMessageBox::error( d->erasingInfoDialog, i18n("Erasing failed.") ); 0723 d->erasingInfoDialog->hide(); // close the dialog thus ending it's event loop -> back to slotMediumChanged 0724 } 0725 } 0726 0727 0728 K3b::Device::MediaType K3b::EmptyDiscWaiter::wait( K3b::Device::Device* device, 0729 Device::MediaStates mediaState, 0730 Device::MediaTypes mediaType, 0731 const K3b::Msf& minMediaSize, 0732 const QString& message, 0733 QWidget* parent ) 0734 { 0735 if( device != 0 ) { 0736 K3b::EmptyDiscWaiter d( device, parent ? parent : qApp->activeWindow() ); 0737 return d.waitForDisc( mediaState, mediaType, minMediaSize, message ); 0738 } 0739 else { 0740 return Device::MEDIA_UNKNOWN; 0741 } 0742 } 0743 0744 0745 void K3b::EmptyDiscWaiter::prepareErasingDialog() 0746 { 0747 // we hide the emptydiskwaiter so the info dialog needs to have the same parent 0748 if( !d->erasingInfoDialog ) 0749 d->erasingInfoDialog = new QProgressDialog( parentWidget() ); 0750 0751 // 0752 // hide the dialog 0753 // 0754 if( d->dialogVisible ) { 0755 hide(); 0756 d->dialogVisible = false; 0757 } 0758 } 0759 0760 0761 QWidget* K3b::EmptyDiscWaiter::parentWidgetToUse() 0762 { 0763 // we might also show dialogs if the discwaiter widget is not visible yet 0764 if( d->dialogVisible ) 0765 return this; 0766 else 0767 return parentWidget(); 0768 } 0769 0770 0771 K3b::Device::MediaType K3b::EmptyDiscWaiter::waitForMedium( K3b::Device::Device* device, 0772 Device::MediaStates mediaState, 0773 Device::MediaTypes mediaType, 0774 const K3b::Msf& minMediaSize, 0775 const QString& message ) 0776 { 0777 // this is only needed for the formatting 0778 return wait( device, mediaState, mediaType, minMediaSize, message, d->erasingInfoDialog ); 0779 } 0780 0781 0782 bool K3b::EmptyDiscWaiter::questionYesNo( const QString& text, 0783 const QString& caption, 0784 const KGuiItem& buttonYes, 0785 const KGuiItem& buttonNo ) 0786 { 0787 return ( KMessageBox::questionTwoActions( parentWidgetToUse(), 0788 text, 0789 caption, 0790 buttonYes, 0791 buttonNo ) == KMessageBox::PrimaryAction ); 0792 } 0793 0794 0795 void K3b::EmptyDiscWaiter::blockingInformation( const QString& text, 0796 const QString& caption ) 0797 { 0798 KMessageBox::information( this, text, caption ); 0799 } 0800 0801 #include "moc_k3bemptydiscwaiter.cpp"