/* * * $Id: sourceheader 511311 2006-02-19 14:51:05Z trueg $ * Copyright (C) 2006 Sebastian Trueg * * This file is part of the K3b project. * Copyright (C) 1998-2007 Sebastian Trueg * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * See the file "COPYING" for the exact licensing terms. */ #include "k3baudiotrackaddingdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class K3bAudioTrackAddingDialog::AnalyserThread : public K3bThread { public: AnalyserThread() : K3bThread(), m_decoder(0) { } void run() { emitStarted(); m_decoder->analyseFile(); emitFinished( m_decoder->isValid() ); } K3bAudioDecoder* m_decoder; }; K3bAudioTrackAddingDialog::K3bAudioTrackAddingDialog( TQWidget* tqparent, const char* name ) : KDialogBase( Plain, i18n("Please be patient..."), Cancel, Cancel, tqparent, name, true, true ), m_bCanceled(false) { TQWidget* page = plainPage(); TQGridLayout* grid = new TQGridLayout( page ); grid->setSpacing( spacingHint() ); grid->setMargin( marginHint() ); m_infoLabel = new TQLabel( page ); m_busyWidget = new K3bBusyWidget( page ); grid->addWidget( m_infoLabel, 0, 0 ); grid->addWidget( m_busyWidget, 1, 0 ); m_analyserThread = new AnalyserThread(); m_analyserJob = new K3bThreadJob( m_analyserThread, this, TQT_TQOBJECT(this) ); connect( m_analyserJob, TQT_SIGNAL(finished(bool)), this, TQT_SLOT(slotAnalysingFinished(bool)) ); } K3bAudioTrackAddingDialog::~K3bAudioTrackAddingDialog() { delete m_analyserThread; } int K3bAudioTrackAddingDialog::addUrls( const KURL::List& urls, K3bAudioDoc* doc, K3bAudioTrack* afterTrack, K3bAudioTrack* parentTrack, K3bAudioDataSource* afterSource, TQWidget* tqparent ) { if( urls.isEmpty() ) return 0; K3bAudioTrackAddingDialog dlg( tqparent ); dlg.m_urls = extractUrlList( urls ); dlg.m_doc = doc; dlg.m_trackAfter = afterTrack; dlg.m_parentTrack = parentTrack; dlg.m_sourceAfter = afterSource; dlg.m_infoLabel->setText( i18n("Adding files to project \"%1\"...").tqarg(doc->URL().fileName()) ); dlg.m_busyWidget->showBusy(true); TQTimer::singleShot( 0, &dlg, TQT_SLOT(slotAddUrls()) ); int ret = dlg.exec(); TQString message; if( !dlg.m_unreadableFiles.isEmpty() ) message += TQString("

%1:
%2") .tqarg( i18n("Insufficient permissions to read the following files") ) .tqarg( dlg.m_unreadableFiles.join( "
" ) ); if( !dlg.m_notFoundFiles.isEmpty() ) message += TQString("

%1:
%2") .tqarg( i18n("Unable to find the following files") ) .tqarg( dlg.m_notFoundFiles.join( "
" ) ); if( !dlg.m_nonLocalFiles.isEmpty() ) message += TQString("

%1:
%2") .tqarg( i18n("No non-local files supported") ) .tqarg( dlg.m_unreadableFiles.join( "
" ) ); if( !dlg.m_unsupportedFiles.isEmpty() ) message += TQString("

%1:
%2
%3") .tqarg( i18n("Unable to handle the following files due to an unsupported format" ) ) .tqarg( i18n("You may manually convert these audio files to wave using another " "application supporting the audio format and then add the wave files " "to the K3b project.") ) .tqarg( dlg.m_unsupportedFiles.join( "
" ) ); if( !message.isEmpty() ) KMessageBox::detailedSorry( tqparent, i18n("Problems while adding files to the project."), message ); return ret; } void K3bAudioTrackAddingDialog::slotAddUrls() { if( m_bCanceled ) return; if( m_urls.isEmpty() ) { accept(); return; } KURL url = m_urls.first(); bool valid = true; if( url.path().right(3).lower() == "cue" ) { // see if its a cue file K3bCueFileParser parser( url.path() ); if( parser.isValid() && parser.toc().contentType() == K3bDevice::AUDIO ) { // remember cue url and set the new audio file url m_cueUrl = url; url = m_urls[0] = KURL::fromPathOrURL( parser.imageFilename() ); } } m_infoLabel->setText( i18n("Analysing file '%1'...").tqarg( url.fileName() ) ); if( !url.isLocalFile() ) { valid = false; m_nonLocalFiles.append( url.path() ); } else { TQFileInfo fi( url.path() ); if( !fi.exists() ) { valid = false; m_notFoundFiles.append( url.path() ); } else if( !fi.isReadable() ) { valid = false; m_unreadableFiles.append( url.path() ); } } if( valid ) { bool reused; K3bAudioDecoder* dec = m_doc->getDecoderForUrl( url, &reused ); if( dec ) { m_analyserThread->m_decoder = dec; if( reused ) slotAnalysingFinished( true ); else m_analyserJob->start(); } else { valid = false; m_unsupportedFiles.append( url.path() ); } } // invalid file, next url if( !valid ) { m_urls.remove( m_urls.begin() ); TQTimer::singleShot( 0, this, TQT_SLOT(slotAddUrls()) ); } } void K3bAudioTrackAddingDialog::slotAnalysingFinished( bool /*success*/ ) { if( m_bCanceled ) { // We only started the analyser thread in case the decoder was new // thus, we can safely delete it since no other source needs it. delete m_analyserThread->m_decoder; return; } KURL url = m_urls.first(); m_urls.remove( m_urls.begin() ); if( m_cueUrl.isValid() ) { // import the cue file m_doc->importCueFile( m_cueUrl.path(), m_trackAfter, m_analyserThread->m_decoder ); m_cueUrl = KURL(); } else { // create the track and source items K3bAudioDecoder* dec = m_analyserThread->m_decoder; K3bAudioFile* file = new K3bAudioFile( dec, m_doc ); if( m_parentTrack ) { if( m_sourceAfter ) file->moveAfter( m_sourceAfter ); else file->moveAhead( m_parentTrack->firstSource() ); m_sourceAfter = file; } else { K3bAudioTrack* track = new K3bAudioTrack( m_doc ); track->setFirstSource( file ); track->setTitle( dec->metaInfo( K3bAudioDecoder::META_TITLE ) ); track->setArtist( dec->metaInfo( K3bAudioDecoder::META_ARTIST ) ); track->setSongwriter( dec->metaInfo( K3bAudioDecoder::META_SONGWRITER ) ); track->setComposer( dec->metaInfo( K3bAudioDecoder::META_COMPOSER ) ); track->setCdTextMessage( dec->metaInfo( K3bAudioDecoder::META_COMMENT ) ); if( m_trackAfter ) track->moveAfter( m_trackAfter ); else track->moveAfter( m_doc->lastTrack() ); m_trackAfter = track; } } TQTimer::singleShot( 0, this, TQT_SLOT(slotAddUrls()) ); } void K3bAudioTrackAddingDialog::slotCancel() { m_bCanceled = true; m_analyserJob->cancel(); KDialogBase::slotCancel(); } KURL::List K3bAudioTrackAddingDialog::extractUrlList( const KURL::List& urls ) { KURL::List allUrls = urls; KURL::List urlsFromPlaylist; KURL::List::iterator it = allUrls.begin(); while( it != allUrls.end() ) { const KURL& url = *it; TQFileInfo fi( url.path() ); if( fi.isDir() ) { it = allUrls.remove( it ); // add all files in the dir TQDir dir(fi.filePath()); TQStringList entries = dir.entryList( TQDir::Files ); KURL::List::iterator oldIt = it; // add all files into the list after the current item for( TQStringList::iterator dirIt = entries.begin(); dirIt != entries.end(); ++dirIt ) it = allUrls.insert( oldIt, KURL::fromPathOrURL( dir.absPath() + "/" + *dirIt ) ); } else if( K3bAudioDoc::readPlaylistFile( url, urlsFromPlaylist ) ) { it = allUrls.remove( it ); KURL::List::iterator oldIt = it; // add all files into the list after the current item for( KURL::List::iterator dirIt = urlsFromPlaylist.begin(); dirIt != urlsFromPlaylist.end(); ++dirIt ) it = allUrls.insert( oldIt, *dirIt ); } else ++it; } return allUrls; } #include "k3baudiotrackaddingdialog.moc"