File indexing completed on 2025-04-20 07:29:16
0001 /* 0002 SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include <config-k3b.h> 0007 0008 #include "k3bmedium.h" 0009 #include "k3bmedium_p.h" 0010 #include "k3bcddb.h" 0011 #include "k3bdeviceglobals.h" 0012 #include "k3bglobals.h" 0013 #include "k3biso9660.h" 0014 #include "k3biso9660backend.h" 0015 #include "k3b_i18n.h" 0016 0017 #include <KIO/Global> 0018 0019 #include <QList> 0020 #include <QSharedData> 0021 0022 #include <KCDDB/CDInfo> 0023 0024 0025 0026 K3b::MediumPrivate::MediumPrivate() 0027 : device( 0 ), 0028 content( K3b::Medium::ContentNone ) 0029 { 0030 } 0031 0032 0033 K3b::Medium::Medium() 0034 { 0035 d = new K3b::MediumPrivate; 0036 } 0037 0038 0039 0040 K3b::Medium::Medium( const K3b::Medium& other ) 0041 { 0042 d = other.d; 0043 } 0044 0045 0046 K3b::Medium::Medium( K3b::Device::Device* dev ) 0047 { 0048 d = new K3b::MediumPrivate; 0049 d->device = dev; 0050 } 0051 0052 0053 K3b::Medium::~Medium() 0054 { 0055 } 0056 0057 0058 K3b::Medium& K3b::Medium::operator=( const K3b::Medium& other ) 0059 { 0060 d = other.d; 0061 return *this; 0062 } 0063 0064 0065 bool K3b::Medium::isValid() const 0066 { 0067 return d->device != 0; 0068 } 0069 0070 0071 void K3b::Medium::setDevice( K3b::Device::Device* dev ) 0072 { 0073 if( d->device != dev ) { 0074 reset(); 0075 d->device = dev; 0076 } 0077 } 0078 0079 K3b::Device::Device* K3b::Medium::device() const 0080 { 0081 return d->device; 0082 } 0083 0084 0085 K3b::Device::DiskInfo K3b::Medium::diskInfo() const 0086 { 0087 return d->diskInfo; 0088 } 0089 0090 0091 K3b::Device::Toc K3b::Medium::toc() const 0092 { 0093 return d->toc; 0094 } 0095 0096 0097 K3b::Device::CdText K3b::Medium::cdText() const 0098 { 0099 return d->cdText; 0100 } 0101 0102 0103 KCDDB::CDInfo K3b::Medium::cddbInfo() const 0104 { 0105 return d->cddbInfo; 0106 } 0107 0108 0109 QList<int> K3b::Medium::writingSpeeds() const 0110 { 0111 return d->writingSpeeds; 0112 } 0113 0114 0115 K3b::Medium::MediumContents K3b::Medium::content() const 0116 { 0117 return d->content; 0118 } 0119 0120 0121 const K3b::Iso9660SimplePrimaryDescriptor& K3b::Medium::iso9660Descriptor() const 0122 { 0123 return d->isoDesc; 0124 } 0125 0126 0127 K3b::Msf K3b::Medium::actuallyUsedCapacity() const 0128 { 0129 // DVD+RW, BD-RE, and DVD-RW in restricted overwrite mode have a single track that does not 0130 // change in size. Thus, the remainingSize value from the disk info is of no great value. 0131 if ( !d->diskInfo.empty() && 0132 d->diskInfo.mediaType() & ( Device::MEDIA_DVD_PLUS_RW|Device::MEDIA_DVD_RW_OVWR|Device::MEDIA_BD_RE ) ) { 0133 return d->isoDesc.volumeSpaceSize; 0134 } 0135 else { 0136 return d->diskInfo.size(); 0137 } 0138 } 0139 0140 0141 K3b::Msf K3b::Medium::actuallyRemainingSize() const 0142 { 0143 // DVD+RW, BD-RE, and DVD-RW in restricted overwrite mode have a single track that does not 0144 // change in size. Thus, the remainingSize value from the disk info is of no great value. 0145 if ( !d->diskInfo.empty() && 0146 d->diskInfo.mediaType() & ( Device::MEDIA_DVD_PLUS_RW|Device::MEDIA_DVD_RW_OVWR|Device::MEDIA_BD_RE ) ) { 0147 return d->diskInfo.capacity() - d->isoDesc.volumeSpaceSize; 0148 } 0149 else { 0150 return d->diskInfo.remainingSize(); 0151 } 0152 } 0153 0154 0155 void K3b::Medium::reset() 0156 { 0157 d->diskInfo = K3b::Device::DiskInfo(); 0158 d->toc.clear(); 0159 d->cdText.clear(); 0160 d->writingSpeeds.clear(); 0161 d->content = ContentNone; 0162 d->cddbInfo.clear(); 0163 0164 // clear the desc 0165 d->isoDesc = K3b::Iso9660SimplePrimaryDescriptor(); 0166 } 0167 0168 0169 void K3b::Medium::update() 0170 { 0171 if( d->device ) { 0172 reset(); 0173 0174 d->diskInfo = d->device->diskInfo(); 0175 0176 if( d->diskInfo.diskState() != K3b::Device::STATE_NO_MEDIA ) { 0177 qDebug() << "found medium: (" << d->device->blockDeviceName() << ')' << Qt::endl 0178 << "====================================================="; 0179 d->diskInfo.debug(); 0180 qDebug() << "====================================================="; 0181 } 0182 else { 0183 qDebug() << "no medium found"; 0184 } 0185 0186 if( diskInfo().diskState() == K3b::Device::STATE_COMPLETE || 0187 diskInfo().diskState() == K3b::Device::STATE_INCOMPLETE ) { 0188 d->toc = d->device->readToc(); 0189 if( d->toc.contentType() == K3b::Device::AUDIO || 0190 d->toc.contentType() == K3b::Device::MIXED ) { 0191 0192 // update CD-Text 0193 d->cdText = d->device->readCdText(); 0194 } 0195 } 0196 0197 if( diskInfo().mediaType() & K3b::Device::MEDIA_WRITABLE ) { 0198 d->writingSpeeds = d->device->determineSupportedWriteSpeeds(); 0199 } 0200 0201 analyseContent(); 0202 } 0203 } 0204 0205 0206 void K3b::Medium::analyseContent() 0207 { 0208 // set basic content types 0209 switch( d->toc.contentType() ) { 0210 case K3b::Device::AUDIO: 0211 d->content = ContentAudio; 0212 break; 0213 case K3b::Device::DATA: 0214 d->content = ContentData; 0215 break; 0216 case K3b::Device::MIXED: 0217 d->content = ContentAudio|ContentData; 0218 break; 0219 default: 0220 d->content = ContentNone; 0221 } 0222 0223 // analyze filesystem 0224 if( d->content & ContentData ) { 0225 //qDebug() << "(K3b::Medium) Checking file system."; 0226 0227 unsigned long startSec = 0; 0228 0229 if( diskInfo().numSessions() > 1 && !d->toc.isEmpty() ) { 0230 // We use the last data track 0231 // this way we get the latest session on a ms cd 0232 for( int i = d->toc.size()-1; i >= 0; --i ) { 0233 if( d->toc.at(i).type() == K3b::Device::Track::TYPE_DATA ) { 0234 startSec = d->toc.at(i).firstSector().lba(); 0235 break; 0236 } 0237 } 0238 } 0239 else if( !d->toc.isEmpty() ) { 0240 // use first data track 0241 for( int i = 0; i < d->toc.size(); ++i ) { 0242 if( d->toc.at(i).type() == K3b::Device::Track::TYPE_DATA ) { 0243 startSec = d->toc.at(i).firstSector().lba(); 0244 break; 0245 } 0246 } 0247 } 0248 else { 0249 qDebug() << "(K3b::Medium) ContentData is set and Toc is empty, disk is probably broken!"; 0250 } 0251 0252 //qDebug() << "(K3b::Medium) Checking file system at " << startSec; 0253 0254 // force the backend since we don't need decryption 0255 // which just slows down the whole process 0256 K3b::Iso9660 iso( new K3b::Iso9660DeviceBackend( d->device ) ); 0257 iso.setStartSector( startSec ); 0258 iso.setPlainIso9660( true ); 0259 if( iso.open() ) { 0260 d->isoDesc = iso.primaryDescriptor(); 0261 qDebug() << "(K3b::Medium) found volume id from start sector " << startSec 0262 << ": '" << d->isoDesc.volumeId << "'" ; 0263 0264 if( const Iso9660Directory* firstDirEntry = iso.firstIsoDirEntry() ) { 0265 if( Device::isDvdMedia( diskInfo().mediaType() ) ) { 0266 // Every VideoDVD needs to have a VIDEO_TS.IFO file 0267 if( firstDirEntry->entry( "VIDEO_TS/VIDEO_TS.IFO" ) != 0 ) 0268 d->content |= ContentVideoDVD; 0269 } 0270 else { 0271 qDebug() << "(K3b::Medium) checking for VCD."; 0272 0273 // check for VCD 0274 const K3b::Iso9660Entry* vcdEntry = firstDirEntry->entry( "VCD/INFO.VCD" ); 0275 const K3b::Iso9660Entry* svcdEntry = firstDirEntry->entry( "SVCD/INFO.SVD" ); 0276 const K3b::Iso9660File* vcdInfoFile = 0; 0277 if( vcdEntry ) { 0278 qDebug() << "(K3b::Medium) found vcd entry."; 0279 if( vcdEntry->isFile() ) 0280 vcdInfoFile = static_cast<const K3b::Iso9660File*>(vcdEntry); 0281 } 0282 if( svcdEntry && !vcdInfoFile ) { 0283 qDebug() << "(K3b::Medium) found svcd entry."; 0284 if( svcdEntry->isFile() ) 0285 vcdInfoFile = static_cast<const K3b::Iso9660File*>(svcdEntry); 0286 } 0287 0288 if( vcdInfoFile ) { 0289 char buffer[8]; 0290 0291 if ( vcdInfoFile->read( 0, buffer, 8 ) == 8 && 0292 ( !qstrncmp( buffer, "VIDEO_CD", 8 ) || 0293 !qstrncmp( buffer, "SUPERVCD", 8 ) || 0294 !qstrncmp( buffer, "HQ-VCD ", 8 ) ) ) 0295 d->content |= ContentVideoCD; 0296 } 0297 } 0298 } 0299 else { 0300 qDebug() << "(K3b::Medium) root ISO directory is null, disk is probably broken!"; 0301 } 0302 } // opened iso9660 0303 } 0304 } 0305 0306 0307 QString K3b::Medium::contentTypeString() const 0308 { 0309 QString mediaTypeString = K3b::Device::mediaTypeString( diskInfo().mediaType(), true ); 0310 0311 switch( d->toc.contentType() ) { 0312 case K3b::Device::AUDIO: 0313 return i18n("Audio CD"); 0314 0315 case K3b::Device::MIXED: 0316 return i18n("Mixed CD"); 0317 0318 case K3b::Device::DATA: 0319 if( content() & ContentVideoDVD ) { 0320 return i18n("Video DVD"); 0321 } 0322 else if( content() & ContentVideoCD ) { 0323 return i18n("Video CD"); 0324 } 0325 else if( diskInfo().diskState() == K3b::Device::STATE_INCOMPLETE ) { 0326 return i18n("Appendable Data %1", mediaTypeString ); 0327 } 0328 else { 0329 return i18n("Complete Data %1", mediaTypeString ); 0330 } 0331 0332 case K3b::Device::NONE: 0333 return i18n("Empty"); 0334 } 0335 0336 // make gcc shut up 0337 return QString(); 0338 } 0339 0340 0341 QString K3b::Medium::shortString( MediumStringFlags flags ) const 0342 { 0343 QString mediaTypeString = K3b::Device::mediaTypeString( diskInfo().mediaType(), true ); 0344 0345 if( diskInfo().diskState() == K3b::Device::STATE_UNKNOWN ) { 0346 return i18n("No medium information"); 0347 } 0348 0349 else if( diskInfo().diskState() == K3b::Device::STATE_NO_MEDIA ) { 0350 return i18n("No medium present"); 0351 } 0352 0353 else if( diskInfo().diskState() == K3b::Device::STATE_EMPTY ) { 0354 return i18n("Empty %1 medium", mediaTypeString ); 0355 } 0356 0357 else { 0358 if( flags & WithContents ) { 0359 // AUDIO + MIXED 0360 if( d->toc.contentType() == K3b::Device::AUDIO || 0361 d->toc.contentType() == K3b::Device::MIXED ) { 0362 QString title = cdText().title(); 0363 QString performer = cdText().performer(); 0364 if ( title.isEmpty() ) { 0365 title = cddbInfo().get( KCDDB::Title ).toString(); 0366 } 0367 if ( performer.isEmpty() ) { 0368 performer = cddbInfo().get( KCDDB::Artist ).toString(); 0369 } 0370 if( !performer.isEmpty() && !title.isEmpty() ) { 0371 return QString("%1 - %2") 0372 .arg( performer ) 0373 .arg( title ); 0374 } 0375 else if( d->toc.contentType() == K3b::Device::AUDIO ) { 0376 return contentTypeString(); 0377 } 0378 else { 0379 return beautifiedVolumeId(); 0380 } 0381 } 0382 0383 // DATA CD and DVD 0384 else if( !volumeId().isEmpty() ) { 0385 return beautifiedVolumeId(); 0386 } 0387 else { 0388 return contentTypeString(); 0389 } 0390 } 0391 0392 // without content 0393 else { 0394 if( diskInfo().diskState() == K3b::Device::STATE_INCOMPLETE ) { 0395 return i18n("Appendable %1 medium", mediaTypeString ); 0396 } 0397 else { 0398 return i18n("Complete %1 medium", mediaTypeString ); 0399 } 0400 } 0401 } 0402 } 0403 0404 0405 QString K3b::Medium::longString( MediumStringFlags flags ) const 0406 { 0407 QString s = QString("<p><nobr><b style=\"font-size:large;\">%1</b></nobr><br/>(%2)") 0408 .arg( shortString( flags ) ) 0409 .arg( flags & WithContents 0410 ? contentTypeString() 0411 : K3b::Device::mediaTypeString( diskInfo().mediaType(), true ) ); 0412 0413 if( diskInfo().diskState() == K3b::Device::STATE_COMPLETE || 0414 diskInfo().diskState() == K3b::Device::STATE_INCOMPLETE ) { 0415 s += "<br/>" + i18np("%2 in %1 track", "%2 in %1 tracks", 0416 d->toc.count(), 0417 KIO::convertSize(diskInfo().size().mode1Bytes()) ); 0418 if( diskInfo().numSessions() > 1 ) 0419 s += i18np(" and %1 session", " and %1 sessions", diskInfo().numSessions() ); 0420 } 0421 0422 if( diskInfo().diskState() == K3b::Device::STATE_EMPTY || 0423 diskInfo().diskState() == K3b::Device::STATE_INCOMPLETE ) 0424 s += "<br/>" + i18n("Free space: %1", 0425 KIO::convertSize( diskInfo().remainingSize().mode1Bytes() ) ); 0426 0427 if( !diskInfo().empty() && diskInfo().rewritable() ) 0428 s += "<br/>" + i18n("Capacity: %1", 0429 KIO::convertSize( diskInfo().capacity().mode1Bytes() ) ); 0430 0431 if( flags & WithDevice ) 0432 s += QString("<br/><small><nobr>%1 %2 (%3)</nobr></small>") 0433 .arg( d->device->vendor() ) 0434 .arg( d->device->description() ) 0435 .arg( d->device->blockDeviceName() ); 0436 0437 return s; 0438 } 0439 0440 0441 QString K3b::Medium::volumeId() const 0442 { 0443 return iso9660Descriptor().volumeId; 0444 } 0445 0446 0447 QString K3b::Medium::beautifiedVolumeId() const 0448 { 0449 const QString oldId = volumeId(); 0450 QString newId; 0451 0452 bool newWord = true; 0453 for( int i = 0; i < oldId.length(); ++i ) { 0454 QChar c = oldId[i]; 0455 // 0456 // first let's handle the cases where we do not change 0457 // the id anyway 0458 // 0459 // In case the id already contains spaces or lower case chars 0460 // it is likely that it already looks good and does ignore 0461 // the restricted iso9660 charset (like almost every project 0462 // created with K3b) 0463 // 0464 if( c.isLetter() && c.toLower() == c ) 0465 return oldId; 0466 else if( c.isSpace() ) 0467 return oldId; 0468 0469 // replace underscore with space 0470 else if( c.unicode() == 95 ) { 0471 newId.append( ' ' ); 0472 newWord = true; 0473 } 0474 0475 // from here on only upper case chars and numbers and stuff 0476 else if( c.isLetter() ) { 0477 if( newWord ) { 0478 newId.append( c ); 0479 newWord = false; 0480 } 0481 else { 0482 newId.append( c.toLower() ); 0483 } 0484 } 0485 else { 0486 newId.append( c ); 0487 } 0488 } 0489 0490 return newId; 0491 } 0492 0493 0494 QIcon K3b::Medium::icon() const 0495 { 0496 if( diskInfo().diskState() == Device::STATE_NO_MEDIA ) { 0497 return QIcon::fromTheme( "media-optical" ); 0498 } 0499 else if( diskInfo().diskState() == Device::STATE_EMPTY ) { 0500 return QIcon::fromTheme( "media-optical-recordable" ); 0501 } 0502 else if( content() == (ContentAudio | ContentData) ) { 0503 return QIcon::fromTheme( "media-optical-mixed-cd" ); 0504 } 0505 else if( content() == ContentAudio ) { 0506 return QIcon::fromTheme( "media-optical-audio" ); 0507 } 0508 else if( content() == ContentData ) { 0509 return QIcon::fromTheme( "media-optical-data" ); 0510 } 0511 else if( content() & ContentVideoDVD ) { 0512 return QIcon::fromTheme( "media-optical-dvd-video" ); 0513 } 0514 else if( content() & ContentVideoCD ) { 0515 return QIcon::fromTheme( "media-optical-cd-video" ); 0516 } 0517 else { 0518 return QIcon::fromTheme( "media-optical" ); 0519 } 0520 } 0521 0522 0523 bool K3b::Medium::operator==( const K3b::Medium& other ) const 0524 { 0525 if( this->d == other.d ) 0526 return true; 0527 0528 return( this->device() == other.device() && 0529 this->diskInfo() == other.diskInfo() && 0530 this->toc() == other.toc() && 0531 this->cdText() == other.cdText() && 0532 d->cddbInfo == other.d->cddbInfo && 0533 this->content() == other.content() && 0534 this->iso9660Descriptor() == other.iso9660Descriptor() ); 0535 } 0536 0537 0538 bool K3b::Medium::operator!=( const K3b::Medium& other ) const 0539 { 0540 if( this->d == other.d ) 0541 return false; 0542 0543 return( this->device() != other.device() || 0544 this->diskInfo() != other.diskInfo() || 0545 this->toc() != other.toc() || 0546 this->cdText() != other.cdText() || 0547 d->cddbInfo != other.d->cddbInfo || 0548 this->content() != other.content() || 0549 this->iso9660Descriptor() != other.iso9660Descriptor() ); 0550 } 0551 0552 0553 bool K3b::Medium::sameMedium( const K3b::Medium& other ) const 0554 { 0555 if( this->d == other.d ) 0556 return true; 0557 0558 // here we do ignore cddb info 0559 return( this->device() == other.device() && 0560 this->diskInfo() == other.diskInfo() && 0561 this->toc() == other.toc() && 0562 this->cdText() == other.cdText() && 0563 this->content() == other.content() && 0564 this->iso9660Descriptor() == other.iso9660Descriptor() ); 0565 } 0566 0567 0568 // static 0569 QStringList K3b::Medium::mediaRequestStrings(QList< K3b::Medium > unsuitableMediums, K3b::Device::MediaTypes requestedMediaTypes, K3b::Device::MediaStates requestedMediaStates, const K3b::Msf& requestedSize, K3b::Device::Device* dev) 0570 { 0571 QStringList toReturn; 0572 0573 bool okMediaType; 0574 bool okMediaState; 0575 bool okSize; 0576 QString deviceString; 0577 0578 Q_FOREACH(K3b::Medium medium, unsuitableMediums) { 0579 K3b::Device::Device *device = medium.device(); 0580 0581 if ( dev && ( device->blockDeviceName() != dev->blockDeviceName() ) ) 0582 continue; 0583 0584 K3b::Device::DiskInfo diskInfo = medium.diskInfo(); 0585 0586 okMediaType = ( diskInfo.mediaType() & requestedMediaTypes ); 0587 okMediaState = ( diskInfo.diskState() & requestedMediaStates ); 0588 okSize = ( diskInfo.capacity() >= requestedSize ); 0589 0590 deviceString = device->vendor() + ' ' + device->description() + QLatin1String(" (") + device->blockDeviceName() + ')'; 0591 0592 if (!okMediaType) { 0593 QString desiredMedium; 0594 if( requestedMediaTypes == (Device::MEDIA_WRITABLE_DVD|Device::MEDIA_WRITABLE_BD) || 0595 requestedMediaTypes == (Device::MEDIA_WRITABLE_DVD_DL|Device::MEDIA_WRITABLE_BD) ) 0596 desiredMedium = i18nc("To be shown when a DVD or Blu-ray is required but another type of medium is inserted.", "DVD or Blu-ray"); 0597 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_BD ) 0598 desiredMedium = i18nc("To be shown when a Blu-ray is required but another type of medium is inserted.", "Blu-ray"); 0599 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_CD ) 0600 desiredMedium = i18nc("To be shown when a CD is required but another type of medium is inserted.", "CD"); 0601 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_DVD ) 0602 desiredMedium = i18nc("To be shown when a DVD is required but another type of medium is inserted.", "DVD"); 0603 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_DVD_DL ) 0604 desiredMedium = i18nc("To be shown when a DVD-DL is required but another type of medium is inserted.", "DVD-DL"); 0605 0606 if ( requestedMediaTypes == Device::MEDIA_REWRITABLE ) { 0607 if ( desiredMedium.isEmpty() ) { 0608 desiredMedium = i18n("rewritable medium"); 0609 } 0610 else { 0611 desiredMedium = i18nc("%1 is type of medium (e.g. DVD)", "rewritable %1", desiredMedium); 0612 } 0613 } 0614 0615 if ( desiredMedium.isEmpty() ) 0616 desiredMedium = i18nc("To be shown when a specific type of medium is required but another type of medium is inserted.", "suitable medium"); 0617 0618 toReturn.append(i18n("Medium in %1 is not a %2.", deviceString, desiredMedium)); 0619 } 0620 else if (!okMediaState) { 0621 QString desiredState; 0622 if( requestedMediaStates == Device::STATE_EMPTY ) 0623 desiredState = i18nc("To be shown when an empty medium is required", "empty"); 0624 else if (requestedMediaStates == (Device::STATE_EMPTY|Device::STATE_INCOMPLETE) ) 0625 desiredState = i18nc("To be shown when an empty or appendable medium is required", "empty or appendable"); 0626 else if( requestedMediaStates == (Device::STATE_COMPLETE|Device::STATE_INCOMPLETE) ) 0627 desiredState = i18nc("To be shown when an non-empty medium is required", "non-empty"); 0628 else 0629 desiredState = i18nc("To be shown when the state of the inserted medium is not suitable.", "suitable"); 0630 0631 toReturn.append(i18n("Medium in %1 is not %2.", deviceString, desiredState)); 0632 } 0633 else if ( !okSize ) { 0634 toReturn.append(i18n("Capacity of the medium in %1 is smaller than required.", deviceString)); 0635 } 0636 } 0637 0638 if (toReturn.isEmpty()) 0639 toReturn.append(mediaRequestString( requestedMediaTypes, requestedMediaStates, requestedSize, dev)); 0640 return toReturn; 0641 } 0642 0643 // static 0644 QString K3b::Medium::mediaRequestString( Device::MediaTypes requestedMediaTypes, Device::MediaStates requestedMediaStates, const K3b::Msf& requestedSize, Device::Device* dev ) 0645 { 0646 // 0647 // The following cases make sense and are used in K3b: 0648 // 0. empty writable medium (data/emovix project and image) 0649 // 1. empty writable CD (audio/vcd project and copy and image) 0650 // 2. empty writable DVD (video dvd project and copy) 0651 // 2.1 empty writable DL DVD (video dvd project and copy) 0652 // 3. empty writable Blu-ray (copy and image) 0653 // 3.1 empty writable DL Blu-ray (image, copy) 0654 // 3.2 empty writable DVD or Blu-ray (image) 0655 // 4. non-empty rewritable medium (format) 0656 // 5. empty or appendable medium (data/emovix project) 0657 // 6. empty or appendable DVD or Blu-ray (could be handled via size) 0658 // 7. empty or appendable Blu-ray (could be handled via size) 0659 // 8. non-empty CD (CD cloning) 0660 // 9. non-empty medium (copy) 0661 0662 QString deviceString; 0663 if( dev ) 0664 deviceString = dev->vendor() + ' ' + dev->description() + QLatin1String(" (") + dev->blockDeviceName() + ')'; 0665 0666 // restrict according to requested size 0667 // FIXME: this does not handle all cases, for example: we have SL and DL DVD in the media types, but only plain BD 0668 if( requestedSize > 0 ) { 0669 if( requestedSize > K3b::MediaSizeCd100Min ) 0670 requestedMediaTypes &= ~Device::MEDIA_CD_ALL; 0671 if( requestedSize > K3b::MediaSizeDvd4Gb ) 0672 requestedMediaTypes &= ~Device::MEDIA_WRITABLE_DVD_SL; 0673 if( requestedSize > K3b::MediaSizeDvd8Gb ) 0674 requestedMediaTypes &= ~Device::MEDIA_WRITABLE_DVD_DL; 0675 } 0676 0677 #ifdef __GNUC__ 0678 #warning Use the i18n string formatting like <strong> or whatever instead of normal html/rtf like <b> 0679 #endif 0680 if( requestedMediaStates == Device::STATE_EMPTY ) { 0681 if( requestedMediaTypes == Device::MEDIA_WRITABLE ) { 0682 if( dev ) 0683 return i18n("Please insert an empty medium into drive<p><b>%1</b>", deviceString); 0684 else 0685 return i18n("Please insert an empty medium"); 0686 } 0687 else if( requestedMediaTypes == (Device::MEDIA_WRITABLE_DVD|Device::MEDIA_WRITABLE_BD) || 0688 requestedMediaTypes == (Device::MEDIA_WRITABLE_DVD_DL|Device::MEDIA_WRITABLE_BD) ) { // special case for data job 0689 if( dev ) 0690 return i18n("Please insert an empty DVD or Blu-ray medium into drive<p><b>%1</b>", deviceString); 0691 else 0692 return i18n("Please insert an empty DVD or Blu-ray medium"); 0693 } 0694 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_BD ) { 0695 if( dev ) 0696 return i18n("Please insert an empty Blu-ray medium into drive<p><b>%1</b>", deviceString); 0697 else 0698 return i18n("Please insert an empty Blu-ray medium"); 0699 } 0700 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_CD ) { 0701 if( dev ) 0702 return i18n("Please insert an empty CD medium into drive<p><b>%1</b>", deviceString); 0703 else 0704 return i18n("Please insert an empty CD medium"); 0705 } 0706 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_DVD ) { 0707 if( dev ) 0708 return i18n("Please insert an empty DVD medium into drive<p><b>%1</b>", deviceString); 0709 else 0710 return i18n("Please insert an empty DVD medium"); 0711 } 0712 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_DVD_DL ) { 0713 if( dev ) 0714 return i18n("Please insert an empty DVD-DL medium into drive<p><b>%1</b>", deviceString); 0715 else 0716 return i18n("Please insert an empty DVD-DL medium"); 0717 } 0718 else if ( requestedSize > 0 ) { 0719 if ( dev ) 0720 return i18n( "Please insert an empty medium of size %1 or larger into drive<p><b>%2</b>", 0721 KIO::convertSize( requestedSize.mode1Bytes() ), deviceString); 0722 else 0723 return i18n( "Please insert an empty medium of size %1 or larger", KIO::convertSize( requestedSize.mode1Bytes() ) ); 0724 } 0725 } 0726 else if( requestedMediaStates == (Device::STATE_EMPTY|Device::STATE_INCOMPLETE) ) { 0727 if( requestedMediaTypes == Device::MEDIA_WRITABLE ) { 0728 if( dev ) 0729 return i18n("Please insert an empty or appendable medium into drive<p><b>%1</b>", deviceString); 0730 else 0731 return i18n("Please insert an empty or appendable medium"); 0732 } 0733 else if( requestedMediaTypes == (Device::MEDIA_WRITABLE_DVD|Device::MEDIA_WRITABLE_BD) ) { 0734 if( dev ) 0735 return i18n("Please insert an empty or appendable DVD or Blu-ray medium into drive<p><b>%1</b>", deviceString); 0736 else 0737 return i18n("Please insert an empty or appendable DVD or Blu-ray medium"); 0738 } 0739 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_BD ) { 0740 if( dev ) 0741 return i18n("Please insert an empty or appendable Blu-ray medium into drive<p><b>%1</b>", deviceString); 0742 else 0743 return i18n("Please insert an empty or appendable Blu-ray medium"); 0744 } 0745 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_CD ) { 0746 if( dev ) 0747 return i18n("Please insert an empty or appendable CD medium into drive<p><b>%1</b>", deviceString); 0748 else 0749 return i18n("Please insert an empty or appendable CD medium"); 0750 } 0751 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_DVD ) { 0752 if( dev ) 0753 return i18n("Please insert an empty or appendable DVD medium into drive<p><b>%1</b>", deviceString); 0754 else 0755 return i18n("Please insert an empty or appendable DVD medium"); 0756 } 0757 else if( requestedMediaTypes == Device::MEDIA_WRITABLE_DVD_DL ) { 0758 if( dev ) 0759 return i18n("Please insert an empty or appendable DVD-DL medium into drive<p><b>%1</b>", deviceString); 0760 else 0761 return i18n("Please insert an empty or appendable DVD-DL medium"); 0762 } 0763 } 0764 else if( requestedMediaStates == (Device::STATE_COMPLETE|Device::STATE_INCOMPLETE) ) { 0765 if( requestedMediaTypes == Device::MEDIA_ALL ) { 0766 if( dev ) 0767 return i18n("Please insert a non-empty medium into drive<p><b>%1</b>", deviceString); 0768 else 0769 return i18n("Please insert a non-empty medium"); 0770 } 0771 else if( requestedMediaTypes == Device::MEDIA_REWRITABLE ) { 0772 if( dev ) 0773 return i18n("Please insert a non-empty rewritable medium into drive<p><b>%1</b>", deviceString); 0774 else 0775 return i18n("Please insert a non-empty rewritable medium"); 0776 } 0777 } 0778 else if( requestedMediaStates == (Device::STATE_COMPLETE|Device::STATE_INCOMPLETE|Device::STATE_EMPTY) ) { 0779 if( requestedMediaTypes == Device::MEDIA_REWRITABLE ) { 0780 if( dev ) 0781 return i18n("Please insert a rewritable medium into drive<p><b>%1</b>", deviceString); 0782 else 0783 return i18n("Please insert a rewritable medium"); 0784 } 0785 } 0786 0787 // fallback 0788 if( dev ) 0789 return i18n("Please insert a suitable medium into drive<p><b>%1</b>", deviceString); 0790 else 0791 return i18n("Please insert a suitable medium"); 0792 } 0793 0794 0795 // static 0796 QString K3b::Medium::mediaRequestString( MediumContents content, Device::Device* dev ) 0797 { 0798 QString deviceString; 0799 if( dev ) 0800 deviceString = dev->vendor() + ' ' + dev->description() + QLatin1String(" (") + dev->blockDeviceName() + ')'; 0801 0802 if( content == K3b::Medium::ContentVideoCD ) { 0803 if( dev ) 0804 return i18n("Please insert a Video CD medium into drive<p><b>%1</b>", deviceString); 0805 else 0806 return i18n("Please insert a Video CD medium"); 0807 } 0808 else if ( content == K3b::Medium::ContentVideoDVD ) { 0809 if( dev ) 0810 return i18n("Please insert a Video DVD medium into drive<p><b>%1</b>", deviceString); 0811 else 0812 return i18n("Please insert a Video DVD medium"); 0813 } 0814 else if( content == (K3b::Medium::ContentAudio|K3b::Medium::ContentData) ) { 0815 if( dev ) 0816 return i18n("Please insert a Mixed Mode CD medium into drive<p><b>%1</b>", deviceString); 0817 else 0818 return i18n("Please insert a Mixed Mode CD medium"); 0819 } 0820 else if( content == K3b::Medium::ContentAudio ) { 0821 if( dev ) 0822 return i18n("Please insert an Audio CD medium into drive<p><b>%1</b>", deviceString); 0823 else 0824 return i18n("Please insert an Audio CD medium"); 0825 } 0826 else if( content == K3b::Medium::ContentData ) { 0827 if( dev ) 0828 return i18n("Please insert a Data medium into drive<p><b>%1</b>", deviceString); 0829 else 0830 return i18n("Please insert a Data medium"); 0831 } 0832 0833 // fallback 0834 if( dev ) 0835 return i18n("Please insert a suitable medium into drive<p><b>%1</b>", deviceString); 0836 else 0837 return i18n("Please insert a suitable medium"); 0838 }