File indexing completed on 2024-10-06 04:25:59
0001 /* 0002 SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <config-k3b.h> 0008 0009 0010 #include "k3bdiskinfoview.h" 0011 #include "k3bthememanager.h" 0012 #include "k3bapplication.h" 0013 0014 #include "k3bdiskinfo.h" 0015 #include "k3bcdtext.h" 0016 #include "k3bdeviceglobals.h" 0017 #include "k3bglobals.h" 0018 #include "k3biso9660.h" 0019 0020 #include <KCDDB/CDInfo> 0021 0022 #include <KIconLoader> 0023 #include <KLocalizedString> 0024 #include <KIO/Global> 0025 0026 #include <QDebug> 0027 #include <QString> 0028 #include <QFont> 0029 #include <QColor> 0030 #include <QPainter> 0031 #include <QPalette> 0032 #include <QPixmap> 0033 #ifdef HAVE_QTWEBENGINEWIDGETS 0034 #include <QWebEngineView> 0035 #endif 0036 #include <QLabel> 0037 #include <QLayout> 0038 #include <QTextBrowser> 0039 0040 namespace { 0041 QString sectionHeader( const QString& title ) { 0042 return "<h1 class=\"title\">" + title + "</h1>"; 0043 } 0044 0045 QString tableRow( const QString& s1, const QString& s2 ) { 0046 return "<tr><td class=\"infokey\">" + s1 + "</td><td class=\"infovalue\">" + s2 + "</td></tr>"; 0047 } 0048 } 0049 0050 0051 K3b::DiskInfoView::DiskInfoView( QWidget* parent ) 0052 : K3b::MediaContentsView( true, 0053 Medium::ContentAll, 0054 Device::MEDIA_ALL|Device::MEDIA_NONE|Device::MEDIA_UNKNOWN, 0055 Device::STATE_ALL|Device::STATE_NO_MEDIA|Device::STATE_UNKNOWN, 0056 parent ) 0057 { 0058 #ifdef HAVE_QTWEBENGINEWIDGETS 0059 m_infoView = new QWebEngineView( this ); 0060 #else 0061 m_infoView = new QTextBrowser( this ); 0062 #endif 0063 setMainWidget( m_infoView ); 0064 } 0065 0066 0067 K3b::DiskInfoView::~DiskInfoView() 0068 { 0069 } 0070 0071 0072 void K3b::DiskInfoView::reloadMedium() 0073 { 0074 updateTitle(); 0075 0076 QString s; 0077 K3b::Theme* theme = k3bappcore->themeManager()->currentTheme(); 0078 if (medium().diskInfo().diskState() == K3b::Device::STATE_NO_MEDIA) { 0079 s = QString("<font color=\"%1\">%2</font>").arg(theme ? 0080 theme->palette().color(QPalette::WindowText).name() : 0081 "green").arg(i18n("No medium present")); 0082 } else { 0083 // FIXME: import a css stylesheet from the theme and, more importantly, 0084 // create a nicer css 0085 // We are not designers :) 0086 s = "<head>" 0087 "<title></title>" 0088 "<style type=\"text/css\">"; 0089 if (theme) { 0090 s += QString(".title { padding:4px; font-size:medium; background-color:%1; color:%2 } ") 0091 .arg(theme->palette().color(QPalette::Window).name()) 0092 .arg(theme->palette().color(QPalette::WindowText).name()); 0093 } 0094 s += QString(".infovalue { font-weight:bold; padding-left:10px; color:%1; } " 0095 ".infokey { color:%1; } " 0096 ".trackheader { text-align:left; color:%1; } " 0097 ".session { font-style:italic; color:%1; } " 0098 ".cdtext { font-weight:bold; font-style:italic; color:%1; } " 0099 ".tracknumber { color:%1; } " 0100 ".tracktype { color:%1; } " 0101 ".trackattributes { color:%1; } " 0102 ".trackrange { color:%1; } " 0103 ".tracklength { color:%1; } " 0104 "td { vertical-align:top; } ") 0105 .arg(theme->palette().color(QPalette::WindowText).name()); 0106 s += "</style>" 0107 "</head>" 0108 "<body>"; 0109 0110 s += sectionHeader(i18n("Medium")); 0111 s += createMediaInfoItems(medium()); 0112 0113 if (medium().content() & K3b::Medium::ContentData) { 0114 s += sectionHeader(i18n("ISO 9660 Filesystem Info")); 0115 s += createIso9660InfoItems(medium().iso9660Descriptor()); 0116 } 0117 0118 if (!medium().toc().isEmpty()) { 0119 s += sectionHeader(i18n("Tracks")); 0120 s += createTrackItems(medium()); 0121 } 0122 } 0123 0124 s += "</body>"; 0125 0126 m_infoView->setHtml(s); 0127 #ifdef K3B_DEBUG 0128 qDebug() << s; 0129 #endif 0130 } 0131 0132 0133 void K3b::DiskInfoView::updateTitle() 0134 { 0135 QString title = medium().shortString(); 0136 QString subTitle = medium().shortString( Medium::NoStringFlags ); 0137 if( title == subTitle ) 0138 subTitle.truncate(0); 0139 setTitle( title, subTitle ); 0140 0141 if( medium().diskInfo().diskState() == K3b::Device::STATE_NO_MEDIA ) { 0142 setRightPixmap( K3b::Theme::MEDIA_NONE ); 0143 } 0144 else { 0145 if( medium().diskInfo().empty() ) { 0146 setRightPixmap( K3b::Theme::MEDIA_EMPTY ); 0147 } 0148 else { 0149 switch( medium().toc().contentType() ) { 0150 case K3b::Device::AUDIO: 0151 setRightPixmap( K3b::Theme::MEDIA_AUDIO ); 0152 break; 0153 case K3b::Device::DATA: { 0154 if( medium().content() & K3b::Medium::ContentVideoDVD ) { 0155 setRightPixmap( K3b::Theme::MEDIA_VIDEO ); 0156 } 0157 else { 0158 setRightPixmap( K3b::Theme::MEDIA_DATA ); 0159 } 0160 break; 0161 } 0162 case K3b::Device::MIXED: 0163 setRightPixmap( K3b::Theme::MEDIA_MIXED ); 0164 break; 0165 default: 0166 setRightPixmap( K3b::Theme::MEDIA_NONE ); 0167 } 0168 } 0169 } 0170 } 0171 0172 0173 namespace { 0174 QString trackItem( const K3b::Medium& medium, int trackIndex ) { 0175 K3b::Device::Track track = medium.toc()[trackIndex]; 0176 0177 QString s = "<tr>"; 0178 0179 // FIXME: Icons 0180 0181 // track number 0182 s += "<td class=\"tracknumber\">" + QString::number(trackIndex+1).rightJustified( 2, ' ' ); 0183 s += "</td>"; 0184 0185 // track type 0186 s += "<td class=\"tracktype\">("; 0187 if( track.type() == K3b::Device::Track::TYPE_AUDIO ) { 0188 // item->setPixmap( QIcon::fromTheme("audio-x-generic").pixmap(KIconLoader::SizeSmall) ); 0189 s += i18n("Audio"); 0190 } else { 0191 // item->setPixmap( QIcon::fromTheme("application-x-tar").pixmap(KIconLoader::SizeSmall) ); 0192 if( track.mode() == K3b::Device::Track::MODE1 ) 0193 s += i18n("Data/Mode1"); 0194 else if( track.mode() == K3b::Device::Track::MODE2 ) 0195 s += i18n("Data/Mode2"); 0196 else if( track.mode() == K3b::Device::Track::XA_FORM1 ) 0197 s += i18n("Data/Mode2 XA Form1"); 0198 else if( track.mode() == K3b::Device::Track::XA_FORM2 ) 0199 s += i18n("Data/Mode2 XA Form2"); 0200 else 0201 s += i18n("Data"); 0202 } 0203 s += ")</td>"; 0204 0205 // track attributes 0206 s += "<td class=\"trackattributes\">"; 0207 s += QString( "%1/%2" ) 0208 .arg( track.copyPermitted() ? i18n("copy") : i18n("no copy") ) 0209 .arg( track.type() == K3b::Device::Track::TYPE_AUDIO 0210 ? ( track.preEmphasis() ? i18n("preemp") : i18n("no preemp") ) 0211 : ( track.recordedIncremental() ? i18n("incremental") : i18n("uninterrupted") ) ); 0212 s += "</td>"; 0213 0214 // track range 0215 s += "<td class=\"trackrange\">"; 0216 s += QString("%1 - %2") 0217 .arg(track.firstSector().lba()) 0218 .arg(track.lastSector().lba()); 0219 s += "</td>"; 0220 0221 // track length 0222 s += "<td class=\"tracklength\">" + QString::number( track.length().lba() ) + " (" + track.length().toString() + ")</td>"; 0223 0224 #ifdef K3B_DEBUG 0225 s += "<td>"; 0226 if( track.type() == K3b::Device::Track::TYPE_AUDIO ) 0227 s += QString( "%1 (%2)" ).arg(track.index0().toString()).arg(track.index0().lba()); 0228 s += "</td>"; 0229 #endif 0230 0231 s += "</tr>"; 0232 0233 if( !medium.cdText().isEmpty() || 0234 medium.cddbInfo().isValid() ) { 0235 s += "<tr><td></td><td class=\"cdtext\" colspan=\"4\">"; 0236 if( !medium.cdText().isEmpty() ) { 0237 K3b::Device::TrackCdText text = medium.cdText().track( trackIndex ); 0238 s += text.performer() + " - " + text.title() + " (" + i18n("CD-Text") + ')'; 0239 } 0240 else { 0241 KCDDB::TrackInfo info = medium.cddbInfo().track( trackIndex ); 0242 s += info.get( KCDDB::Artist ).toString() + " - " + info.get( KCDDB::Title ).toString(); 0243 } 0244 s += "</td></tr>"; 0245 } 0246 0247 return s; 0248 } 0249 0250 QString sessionItem( int session ) { 0251 return "<tr><td class=\"session\" colspan=\"5\">" + i18n( "Session %1", session ) + "</td></tr>"; 0252 } 0253 } 0254 0255 QString K3b::DiskInfoView::createTrackItems( const K3b::Medium& medium ) 0256 { 0257 QString s = "<table>"; 0258 0259 // table header 0260 s += "<tr><th class=\"trackheader\" colspan=\"2\">" 0261 + i18n("Type") 0262 + "</th><th class=\"trackheader\">" 0263 + i18n("Attributes") 0264 + "</th><th class=\"trackheader\">" 0265 + i18n("First-Last Sector") 0266 + "</th><th class=\"trackheader\">" 0267 + i18n("Length"); 0268 #ifdef K3B_DEBUG 0269 s += "</td></td>Index0"; 0270 #endif 0271 s += "</th></tr>"; 0272 0273 int lastSession = 0; 0274 0275 // if we have multiple sessions we create a header item for every session 0276 if( medium.diskInfo().numSessions() > 1 && medium.toc()[0].session() > 0 ) { 0277 s += sessionItem( 1 ); 0278 lastSession = 1; 0279 } 0280 0281 // create items for the tracks 0282 for( int index = 0; index < medium.toc().count(); ++index ) { 0283 K3b::Device::Track track = medium.toc()[index]; 0284 if( medium.diskInfo().numSessions() > 1 && track.session() != lastSession ) { 0285 lastSession = track.session(); 0286 s += sessionItem( lastSession ); 0287 } 0288 s += trackItem( medium, index ); 0289 } 0290 0291 s += "</table>"; 0292 0293 return s; 0294 } 0295 0296 0297 QString K3b::DiskInfoView::createMediaInfoItems( const K3b::Medium& medium ) 0298 { 0299 const K3b::Device::DiskInfo& info = medium.diskInfo(); 0300 0301 QString s = "<table>"; 0302 0303 QString typeStr; 0304 if( info.mediaType() != K3b::Device::MEDIA_UNKNOWN ) 0305 typeStr = K3b::Device::mediaTypeString( info.mediaType() ); 0306 else 0307 typeStr = i18n("Unknown (probably CD-ROM)"); 0308 s += tableRow( i18n( "Type:" ), typeStr ); 0309 if( Device::isDvdMedia( info.mediaType() ) ) 0310 s += tableRow( i18n("Media ID:"), !info.mediaId().isEmpty() ? QString::fromLatin1( info.mediaId() ) : i18n("unknown") ); 0311 s += tableRow( i18n("Capacity:"), i18n("%1 min",info.capacity().toString()) + " (" + KIO::convertSize(info.capacity().mode1Bytes()) + ')' ); 0312 if( !info.empty() ) 0313 s += tableRow( i18n("Used Capacity:"), i18n("%1 min", medium.actuallyUsedCapacity().toString()) + " (" + KIO::convertSize(medium.actuallyUsedCapacity().mode1Bytes()) + ')' ); 0314 if( !info.empty() || 0315 info.appendable() || 0316 ( info.mediaType() & ( Device::MEDIA_DVD_PLUS_RW|Device::MEDIA_DVD_RW_OVWR|Device::MEDIA_BD_RE ) ) ) 0317 s += tableRow( i18n("Remaining:"), i18n("%1 min", medium.actuallyRemainingSize().toString() ) + " (" + KIO::convertSize(medium.actuallyRemainingSize().mode1Bytes()) + ')' ); 0318 s += tableRow( i18n("Rewritable:"), info.rewritable() ? i18nc("Availability", "yes") : i18nc("Availability", "no") ); 0319 s += tableRow( i18n("Appendable:"), info.appendable() || ( info.mediaType() & ( Device::MEDIA_DVD_PLUS_RW|Device::MEDIA_DVD_RW_OVWR|Device::MEDIA_BD_RE ) ) ? i18nc("Availability", "yes") : i18nc("Availability", "no") ); 0320 s += tableRow( i18n("Empty:"), info.empty() ? i18nc("Availability", "yes") : i18nc("Availability", "no") ); 0321 if( !( info.mediaType() & K3b::Device::MEDIA_CD_ALL ) ) 0322 s += tableRow( i18nc("Number of layers on an optical medium", "Layers:"), QString::number( info.numLayers() ) ); 0323 0324 if( info.mediaType() == K3b::Device::MEDIA_DVD_PLUS_RW ) { 0325 QString bgf; 0326 switch( info.bgFormatState() ) { 0327 case K3b::Device::BG_FORMAT_NONE: 0328 bgf = i18n("not formatted"); 0329 break; 0330 case K3b::Device::BG_FORMAT_INCOMPLETE: 0331 bgf = i18n("incomplete"); 0332 break; 0333 case K3b::Device::BG_FORMAT_IN_PROGRESS: 0334 bgf = i18n("in progress"); 0335 break; 0336 case K3b::Device::BG_FORMAT_COMPLETE: 0337 bgf = i18n("complete"); 0338 break; 0339 default: 0340 bgf = i18n("unknown state"); 0341 } 0342 0343 s += tableRow( i18n("Background Format:"), bgf ); 0344 } 0345 0346 s += tableRow( i18n("Sessions:"), QString::number( info.numSessions() ) ); 0347 0348 if( info.mediaType() & K3b::Device::MEDIA_WRITABLE ) { 0349 QString speedStr; 0350 if( medium.writingSpeeds().isEmpty() ) { 0351 speedStr = '-'; 0352 } 0353 else { 0354 foreach( int speed, medium.writingSpeeds() ) { 0355 if( !speedStr.isEmpty() ) { 0356 speedStr.append( "<br>" ); 0357 } 0358 0359 if( K3b::Device::isCdMedia( info.mediaType() ) ) 0360 speedStr.append( QString( "%1x (%2 KB/s)" ).arg( speed/K3b::Device::SPEED_FACTOR_CD ).arg( speed ) ); 0361 else if( K3b::Device::isDvdMedia( info.mediaType() ) ) 0362 speedStr.append( QString::asprintf( "%.1fx (%d KB/s)", (double)speed / ( double )K3b::Device::SPEED_FACTOR_DVD, speed ) ); 0363 else if ( K3b::Device::isBdMedia( info.mediaType() ) ) 0364 speedStr.append( QString::asprintf( "%.1fx (%d KB/s)", (double)speed / ( double )K3b::Device::SPEED_FACTOR_BD, speed ) ); 0365 } 0366 } 0367 0368 s += tableRow( i18n("Supported writing speeds:"), speedStr ); 0369 } 0370 0371 s += "</table>"; 0372 0373 return s; 0374 } 0375 0376 0377 QString K3b::DiskInfoView::createIso9660InfoItems( const K3b::Iso9660SimplePrimaryDescriptor& iso ) 0378 { 0379 QString s = "<table>"; 0380 0381 s += tableRow( i18n("System Id:"), iso.systemId.isEmpty() ? QString("-") : iso.systemId ); 0382 s += tableRow( i18n("Volume Id:"), iso.volumeId.isEmpty() ? QString("-") : iso.volumeId ); 0383 s += tableRow( i18n("Volume Set Id:"), iso.volumeSetId.isEmpty() ? QString("-") : iso.volumeSetId ); 0384 s += tableRow( i18n("Publisher Id:"), iso.publisherId.isEmpty() ? QString("-") : iso.publisherId ); 0385 s += tableRow( i18n("Preparer Id:"), iso.preparerId.isEmpty() ? QString("-") : iso.preparerId ); 0386 s += tableRow( i18n("Application Id:"), iso.applicationId.isEmpty() ? QString("-") : iso.applicationId ); 0387 s += tableRow( i18n("Volume Size:"), 0388 QString( "%1 (%2 * %3 = %4)" ) 0389 .arg(KIO::convertSize(iso.logicalBlockSize*iso.volumeSpaceSize)) 0390 .arg(i18nc( "Size of one block, always 2048", "%1 B", iso.logicalBlockSize) ) 0391 .arg(i18ncp( "Number of blocks (one block has 2048 bytes)", "1 block", "%1 blocks", iso.volumeSpaceSize) ) 0392 .arg(i18np( "1 B", "%1 B", iso.logicalBlockSize*iso.volumeSpaceSize ) ) ); 0393 0394 s += "</table>"; 0395 0396 return s; 0397 } 0398 0399 #include "moc_k3bdiskinfoview.cpp"