File indexing completed on 2024-05-05 04:51:43
0001 /* 0002 SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "k3bdatamultisessionimportdialog.h" 0007 #include "k3bcore.h" 0008 #include "k3bdatadoc.h" 0009 #include "k3btoc.h" 0010 #include "k3bdevice.h" 0011 #include "k3bdevicemanager.h" 0012 #include "k3bdiskinfo.h" 0013 #include "k3biso9660.h" 0014 #include "k3bmedium.h" 0015 #include "k3bmediacache.h" 0016 0017 #include "../k3bapplication.h" 0018 #include "../k3b.h" 0019 0020 #include <KIconLoader> 0021 #include <KLocalizedString> 0022 #include <KMessageBox> 0023 0024 #include <QMap> 0025 #include <QCursor> 0026 #include <QFont> 0027 #include <QDialogButtonBox> 0028 #include <QLabel> 0029 #include <QLayout> 0030 #include <QPushButton> 0031 #include <QTreeWidget> 0032 #include <QVBoxLayout> 0033 0034 namespace { 0035 class SessionInfo 0036 { 0037 public: 0038 SessionInfo() 0039 : sessionNumber( 0 ), 0040 device( 0 ) {} 0041 0042 SessionInfo( int num, K3b::Device::Device* dev ) 0043 : sessionNumber( num ), 0044 device( dev ) {} 0045 0046 int sessionNumber; 0047 K3b::Device::Device* device; 0048 }; 0049 0050 typedef QMap<QTreeWidgetItem*, SessionInfo> Sessions; 0051 } 0052 0053 0054 class K3b::DataMultisessionImportDialog::Private 0055 { 0056 public: 0057 K3b::DataDoc* doc; 0058 QTreeWidget* sessionView; 0059 QPushButton* okButton; 0060 0061 Sessions sessions; 0062 }; 0063 0064 0065 K3b::DataDoc* K3b::DataMultisessionImportDialog::importSession( K3b::DataDoc* doc, QWidget* parent ) 0066 { 0067 K3b::DataMultisessionImportDialog dlg( parent ); 0068 dlg.importSession( doc ); 0069 dlg.exec(); 0070 return dlg.d->doc; 0071 } 0072 0073 0074 void K3b::DataMultisessionImportDialog::slotOk() 0075 { 0076 Sessions::const_iterator session = d->sessions.constFind( d->sessionView->currentItem() ); 0077 if ( session != d->sessions.constEnd() ) { 0078 QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); 0079 0080 K3b::Device::Device* dev = session->device; 0081 0082 // 0083 // Mkisofs does not properly import joliet filenames from an old session 0084 // 0085 // See bug 79215 for details 0086 // 0087 K3b::Iso9660 iso( dev ); 0088 if( iso.open() ) { 0089 if( iso.firstRRDirEntry() == 0 && iso.jolietLevel() > 0 ) 0090 KMessageBox::error( this, 0091 i18n("<p>K3b found session containing Joliet information for long filenames " 0092 "but no Rock Ridge extensions." 0093 "<p>The filenames in the imported session will be converted to a restricted " 0094 "character set in the new session. This character set is based on the ISO 9660 " 0095 "settings in the K3b project. K3b is not able to display these converted filenames yet."), 0096 i18n("Session Import Warning") ); 0097 iso.close(); 0098 } 0099 0100 if( !d->doc ) { 0101 d->doc = static_cast<K3b::DataDoc*>( k3bappcore->k3bMainWindow()->slotNewDataDoc() ); 0102 } 0103 0104 d->doc->setBurner( dev ); 0105 d->doc->importSession( dev, session->sessionNumber ); 0106 0107 QApplication::restoreOverrideCursor(); 0108 0109 done( 0 ); 0110 } 0111 } 0112 0113 0114 void K3b::DataMultisessionImportDialog::slotCancel() 0115 { 0116 reject(); 0117 } 0118 0119 0120 void K3b::DataMultisessionImportDialog::importSession( K3b::DataDoc* doc ) 0121 { 0122 d->doc = doc; 0123 updateMedia(); 0124 slotSelectionChanged(); 0125 } 0126 0127 0128 void K3b::DataMultisessionImportDialog::updateMedia() 0129 { 0130 d->sessionView->clear(); 0131 d->sessions.clear(); 0132 0133 QList<K3b::Device::Device*> devices = k3bcore->deviceManager()->allDevices(); 0134 0135 bool haveMedium = false; 0136 for( QList<K3b::Device::Device *>::const_iterator it = devices.constBegin(); 0137 it != devices.constEnd(); ++it ) { 0138 K3b::Medium medium = k3bappcore->mediaCache()->medium( *it ); 0139 0140 if ( medium.diskInfo().mediaType() & K3b::Device::MEDIA_WRITABLE && 0141 medium.diskInfo().diskState() == K3b::Device::STATE_INCOMPLETE ) { 0142 addMedium( medium ); 0143 haveMedium = true; 0144 } 0145 else if ( !medium.diskInfo().empty() && 0146 medium.diskInfo().mediaType() & ( K3b::Device::MEDIA_DVD_PLUS_RW|K3b::Device::MEDIA_DVD_RW_OVWR ) ) { 0147 addMedium( medium ); 0148 haveMedium = true; 0149 } 0150 } 0151 0152 if ( !haveMedium ) { 0153 QTreeWidgetItem* noMediaItem = new QTreeWidgetItem( d->sessionView ); 0154 QFont fnt( noMediaItem->font(0) ); 0155 fnt.setItalic( true ); 0156 noMediaItem->setText( 0, i18n( "Please insert an appendable medium" ) ); 0157 noMediaItem->setFont( 0, fnt ); 0158 } 0159 else if( QTreeWidgetItem* firstMedium = d->sessionView->topLevelItem(0) ) { 0160 if( firstMedium->childCount() > 0 ) 0161 d->sessionView->setCurrentItem( firstMedium->child( firstMedium->childCount()-1 ) ); 0162 else 0163 d->sessionView->setCurrentItem( firstMedium ); 0164 } 0165 0166 d->sessionView->setEnabled( haveMedium ); 0167 } 0168 0169 0170 void K3b::DataMultisessionImportDialog::addMedium( const K3b::Medium& medium ) 0171 { 0172 QTreeWidgetItem* mediumItem = new QTreeWidgetItem( d->sessionView ); 0173 QFont fnt( mediumItem->font(0) ); 0174 fnt.setBold( true ); 0175 mediumItem->setText( 0, medium.shortString() ); 0176 mediumItem->setFont( 0, fnt ); 0177 mediumItem->setIcon( 0, QIcon::fromTheme("media-optical-recordable") ); 0178 0179 const K3b::Device::Toc& toc = medium.toc(); 0180 QTreeWidgetItem* sessionItem = 0; 0181 int lastSession = 0; 0182 for ( K3b::Device::Toc::const_iterator it = toc.begin(); it != toc.end(); ++it ) { 0183 const K3b::Device::Track& track = *it; 0184 0185 if( track.session() != lastSession ) { 0186 lastSession = track.session(); 0187 QString sessionInfo; 0188 if ( track.type() == K3b::Device::Track::TYPE_DATA ) { 0189 K3b::Iso9660 iso( medium.device(), track.firstSector().lba() ); 0190 if ( iso.open() ) { 0191 sessionInfo = iso.primaryDescriptor().volumeId; 0192 } 0193 } 0194 else { 0195 int numAudioTracks = 1; 0196 while ( it != toc.end() 0197 && ( *it ).type() == K3b::Device::Track::TYPE_AUDIO 0198 && ( *it ).session() == lastSession ) { 0199 ++it; 0200 ++numAudioTracks; 0201 } 0202 --it; 0203 sessionInfo = i18np("1 audio track", "%1 audio tracks", numAudioTracks ); 0204 } 0205 0206 sessionItem = new QTreeWidgetItem( mediumItem, sessionItem ); 0207 sessionItem->setText( 0, i18n( "Session %1", lastSession ) 0208 + ( sessionInfo.isEmpty() ? QString() : " (" + sessionInfo + ')' ) ); 0209 if ( track.type() == K3b::Device::Track::TYPE_AUDIO ) 0210 sessionItem->setIcon( 0, QIcon::fromTheme( "audio-x-generic" ) ); 0211 else 0212 sessionItem->setIcon( 0, QIcon::fromTheme( "application-x-tar" ) ); 0213 0214 d->sessions.insert( sessionItem, SessionInfo( lastSession, medium.device() ) ); 0215 } 0216 } 0217 0218 if( 0 == lastSession ) { 0219 // the medium item in case we have no session info (will always use the last session) 0220 d->sessions.insert( mediumItem, SessionInfo( 0, medium.device() ) ); 0221 } 0222 else { 0223 // we have a session item, there is no need to select the medium as a whole 0224 mediumItem->setFlags( mediumItem->flags() ^ Qt::ItemIsSelectable ); 0225 } 0226 0227 mediumItem->setExpanded( true ); 0228 } 0229 0230 0231 void K3b::DataMultisessionImportDialog::slotSelectionChanged() 0232 { 0233 Sessions::const_iterator session = d->sessions.constFind( d->sessionView->currentItem() ); 0234 if ( session != d->sessions.constEnd() ) { 0235 d->okButton->setEnabled( true ); 0236 } 0237 else { 0238 d->okButton->setEnabled( false ); 0239 } 0240 } 0241 0242 0243 K3b::DataMultisessionImportDialog::DataMultisessionImportDialog( QWidget* parent ) 0244 : QDialog( parent), 0245 d( new Private() ) 0246 { 0247 setModal(true); 0248 setWindowTitle(i18n("Session Import")); 0249 QVBoxLayout* layout = new QVBoxLayout( this ); 0250 0251 QLabel* label = new QLabel( i18n( "Please select a session to import." ), this ); 0252 d->sessionView = new QTreeWidget( this ); 0253 d->sessionView->setHeaderHidden( true ); 0254 d->sessionView->setItemsExpandable( false ); 0255 d->sessionView->setRootIsDecorated( false ); 0256 0257 QDialogButtonBox* buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this ); 0258 d->okButton = buttonBox->button( QDialogButtonBox::Ok ); 0259 connect( buttonBox, SIGNAL(accepted()), SLOT(accept()) ); 0260 connect( buttonBox, SIGNAL(rejected()), SLOT(reject()) ); 0261 0262 layout->addWidget( label ); 0263 layout->addWidget( d->sessionView ); 0264 layout->addWidget( buttonBox ); 0265 0266 connect( k3bappcore->mediaCache(), SIGNAL(mediumChanged(K3b::Device::Device*)), 0267 this, SLOT(updateMedia()) ); 0268 connect( d->sessionView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), 0269 this, SLOT(slotSelectionChanged()) ); 0270 connect(d->sessionView, SIGNAL(itemActivated(QTreeWidgetItem*,int)), SLOT(slotOk()) ); 0271 connect(d->okButton, SIGNAL(clicked()), this, SLOT(slotOk())); 0272 connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(slotCancel())); 0273 } 0274 0275 0276 K3b::DataMultisessionImportDialog::~DataMultisessionImportDialog() 0277 { 0278 delete d; 0279 } 0280 0281 #include "moc_k3bdatamultisessionimportdialog.cpp"