File indexing completed on 2024-05-05 04:51:41
0001 /* 0002 SPDX-FileCopyrightText: 2006-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 "k3baudiotrackaddingdialog.h" 0010 #include "k3baudiofileanalyzerjob.h" 0011 0012 #include "k3baudiodoc.h" 0013 #include "k3baudiotrack.h" 0014 #include "k3baudiofile.h" 0015 #include "k3baudiodecoder.h" 0016 #include "k3bbusywidget.h" 0017 #include "k3bglobals.h" 0018 #include "k3bcuefileparser.h" 0019 0020 #include <KLocalizedString> 0021 #include <KMessageBox> 0022 0023 #include <QDebug> 0024 #include <QDir> 0025 #include <QFileInfo> 0026 #include <QThread> 0027 #include <QDialogButtonBox> 0028 #include <QLabel> 0029 #include <QVBoxLayout> 0030 #include <QPushButton> 0031 0032 0033 K3b::AudioTrackAddingDialog::AudioTrackAddingDialog( const QList<QUrl>& urls, 0034 AudioDoc* doc, 0035 AudioTrack* afterTrack, 0036 AudioTrack* parentTrack, 0037 AudioDataSource* afterSource, 0038 QWidget* parent ) 0039 : QDialog( parent), 0040 m_urls( AudioDoc::extractUrlList( urls ) ), 0041 m_doc( doc ), 0042 m_trackAfter( afterTrack ), 0043 m_parentTrack( parentTrack ), 0044 m_sourceAfter( afterSource ), 0045 m_bCanceled( false ) 0046 { 0047 setWindowTitle(i18n("Please be patient...")); 0048 0049 m_infoLabel = new QLabel( this ); 0050 m_infoLabel->setText( i18n("Adding files to project \"%1\"...",doc->URL().fileName()) ); 0051 m_busyWidget = new K3b::BusyWidget( this ); 0052 m_busyWidget->showBusy( true ); 0053 0054 QDialogButtonBox* buttonBox = new QDialogButtonBox( QDialogButtonBox::Cancel, this ); 0055 connect( buttonBox, SIGNAL(rejected()), SLOT(reject()) ); 0056 0057 QVBoxLayout* layout = new QVBoxLayout( this ); 0058 layout->addWidget( m_infoLabel ); 0059 layout->addWidget( m_busyWidget ); 0060 layout->addWidget( buttonBox ); 0061 0062 m_analyserJob = new K3b::AudioFileAnalyzerJob( this, this ); 0063 connect( m_analyserJob, SIGNAL(finished(bool)), this, SLOT(slotAnalysingFinished(bool)) ); 0064 connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(slotCancelClicked())); 0065 } 0066 0067 0068 K3b::AudioTrackAddingDialog::~AudioTrackAddingDialog() 0069 { 0070 QString message; 0071 if( !m_unreadableFiles.isEmpty() ) 0072 message += QString("<p><b>%1:</b><br>%2") 0073 .arg( i18n("Insufficient permissions to read the following files") ) 0074 .arg( m_unreadableFiles.join( "<br>" ) ); 0075 if( !m_notFoundFiles.isEmpty() ) 0076 message += QString("<p><b>%1:</b><br>%2") 0077 .arg( i18n("Unable to find the following files") ) 0078 .arg( m_notFoundFiles.join( "<br>" ) ); 0079 if( !m_nonLocalFiles.isEmpty() ) 0080 message += QString("<p><b>%1:</b><br>%2") 0081 .arg( i18n("No non-local files supported") ) 0082 .arg( m_unreadableFiles.join( "<br>" ) ); 0083 if( !m_unsupportedFiles.isEmpty() ) 0084 message += QString("<p><b>%1:</b><br><i>%2</i><br>%3") 0085 .arg( i18n("Unable to handle the following files due to an unsupported format" ) ) 0086 .arg( i18n("You may manually convert these audio files to wave using another " 0087 "application supporting the audio format and then add the wave files " 0088 "to the K3b project.") ) 0089 .arg( m_unsupportedFiles.join( "<br>" ) ); 0090 0091 if( !message.isEmpty() ) 0092 KMessageBox::detailedError( parentWidget(), i18n("Problems while adding files to the project."), message ); 0093 } 0094 0095 0096 void K3b::AudioTrackAddingDialog::addUrls( const QList<QUrl>& urls, 0097 K3b::AudioDoc* doc, 0098 K3b::AudioTrack* afterTrack, 0099 K3b::AudioTrack* parentTrack, 0100 K3b::AudioDataSource* afterSource, 0101 QWidget* parent ) 0102 { 0103 if( !urls.isEmpty() ) 0104 { 0105 K3b::AudioTrackAddingDialog* dlg = new K3b::AudioTrackAddingDialog( 0106 urls, doc, afterTrack, parentTrack, afterSource, parent ); 0107 dlg->setAttribute( Qt::WA_DeleteOnClose ); 0108 QMetaObject::invokeMethod( dlg, "exec", Qt::QueuedConnection ); 0109 QMetaObject::invokeMethod( dlg, "slotAddUrls", Qt::QueuedConnection ); 0110 } 0111 } 0112 0113 0114 void K3b::AudioTrackAddingDialog::slotAddUrls() 0115 { 0116 if( m_bCanceled ) 0117 return; 0118 0119 if( m_urls.isEmpty() ) { 0120 accept(); 0121 return; 0122 } 0123 0124 QUrl url = m_urls.first(); 0125 bool valid = true; 0126 0127 if( url.toLocalFile().right(3).toLower() == "cue" ) { 0128 // see if its a cue file 0129 K3b::CueFileParser parser( url.toLocalFile() ); 0130 if( parser.isValid() && parser.toc().contentType() == K3b::Device::AUDIO ) { 0131 if ( parser.imageFileType() == QLatin1String( "bin" ) ) { 0132 // no need to analyze -> raw audio data 0133 m_doc->importCueFile( url.toLocalFile(), m_trackAfter, 0 ); 0134 m_urls.erase( m_urls.begin() ); 0135 QMetaObject::invokeMethod( this, "slotAddUrls", Qt::QueuedConnection ); 0136 return; 0137 } 0138 else { 0139 // remember cue url and set the new audio file url 0140 m_cueUrl = url; 0141 url = m_urls[0] = QUrl::fromLocalFile( parser.imageFilename() ); 0142 } 0143 } 0144 } 0145 0146 m_infoLabel->setText( i18n("Analysing file '%1'..." , url.fileName() ) ); 0147 0148 if( !url.isLocalFile() ) { 0149 valid = false; 0150 m_nonLocalFiles.append( url.toLocalFile() ); 0151 } 0152 else { 0153 QFileInfo fi( url.toLocalFile() ); 0154 if( !fi.exists() ) { 0155 valid = false; 0156 m_notFoundFiles.append( url.toLocalFile() ); 0157 } 0158 else if( !fi.isReadable() ) { 0159 valid = false; 0160 m_unreadableFiles.append( url.toLocalFile() ); 0161 } 0162 } 0163 0164 if( valid ) { 0165 bool reused; 0166 K3b::AudioDecoder* dec = m_doc->getDecoderForUrl( url, &reused ); 0167 if( dec ) { 0168 m_analyserJob->setDecoder( dec ); 0169 if( reused ) 0170 slotAnalysingFinished( true ); 0171 else 0172 m_analyserJob->start(); 0173 } 0174 else { 0175 valid = false; 0176 m_unsupportedFiles.append( url.toLocalFile() ); 0177 } 0178 } 0179 0180 // invalid file, next url 0181 if( !valid ) { 0182 m_urls.erase( m_urls.begin() ); 0183 QMetaObject::invokeMethod( this, "slotAddUrls", Qt::QueuedConnection ); 0184 } 0185 } 0186 0187 0188 void K3b::AudioTrackAddingDialog::slotAnalysingFinished( bool /*success*/ ) 0189 { 0190 if( m_bCanceled ) { 0191 // We only started the analyser thread in case the decoder was new 0192 // thus, we can safely delete it since no other source needs it. 0193 delete m_analyserJob->decoder(); 0194 return; 0195 } 0196 0197 QUrl url = m_urls.first(); 0198 m_urls.erase( m_urls.begin() ); 0199 0200 if( m_cueUrl.isValid() ) { 0201 // import the cue file 0202 m_doc->importCueFile( m_cueUrl.toLocalFile(), m_trackAfter, m_analyserJob->decoder() ); 0203 m_cueUrl = QUrl(); 0204 } 0205 else { 0206 // create the track and source items 0207 K3b::AudioDecoder* dec = m_analyserJob->decoder(); 0208 K3b::AudioFile* file = new K3b::AudioFile( dec, m_doc ); 0209 if( m_parentTrack ) { 0210 if( m_sourceAfter ) 0211 file->moveAfter( m_sourceAfter ); 0212 else 0213 file->moveAhead( m_parentTrack->firstSource() ); 0214 m_sourceAfter = file; 0215 } 0216 else { 0217 K3b::AudioTrack* track = new K3b::AudioTrack( m_doc ); 0218 track->setFirstSource( file ); 0219 0220 track->setTitle( dec->metaInfo( K3b::AudioDecoder::META_TITLE ) ); 0221 track->setArtist( dec->metaInfo( K3b::AudioDecoder::META_ARTIST ) ); 0222 track->setSongwriter( dec->metaInfo( K3b::AudioDecoder::META_SONGWRITER ) ); 0223 track->setComposer( dec->metaInfo( K3b::AudioDecoder::META_COMPOSER ) ); 0224 track->setCdTextMessage( dec->metaInfo( K3b::AudioDecoder::META_COMMENT ) ); 0225 0226 if( m_trackAfter ) 0227 track->moveAfter( m_trackAfter ); 0228 else if ( m_doc->lastTrack() ) 0229 track->moveAfter( m_doc->lastTrack() ); 0230 else 0231 m_doc->addTrack( track, 0 ); 0232 0233 m_trackAfter = track; 0234 } 0235 } 0236 0237 QMetaObject::invokeMethod( this, "slotAddUrls", Qt::QueuedConnection ); 0238 } 0239 0240 0241 void K3b::AudioTrackAddingDialog::slotCancelClicked() 0242 { 0243 m_bCanceled = true; 0244 m_analyserJob->cancel(); 0245 m_analyserJob->wait(); 0246 } 0247 0248 #include "moc_k3baudiotrackaddingdialog.cpp"