You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdemultimedia/kaudiocreator/ripper.cpp

264 lines
6.9 KiB

/**
* This file is part of the KAudioCreator package
* Copyright (C) 2003 Benjamin C Meyer (ben+kaudiocreator at meyerhome dot net)
*
* 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.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "ripper.h"
#include "prefs.h"
#include <tqfile.h>
#include <tqtimer.h>
#include <tdetempfile.h>
#include <tdemessagebox.h>
#include <knotifyclient.h>
#include <kstandarddirs.h>
#include <tdeio/scheduler.h>
/**
* Constructor, load settings.
*/
Ripper::Ripper( TQObject* parent, const char* name) : TQObject(parent,name) {
loadSettings();
}
/**
* Loads the settings
*/
void Ripper::loadSettings(){
for(uint i=0; i<(uint)Prefs::maxWavFiles(); i++)
tendToNewJobs();
}
/**
* Deconstructor, remove pending jobs, remove current jobs, save settings.
*/
Ripper::~Ripper(){
pendingJobs.clear();
TQMap<TDEIO::Job*, Job*>::Iterator it;
for( it = jobs.begin(); it != jobs.end(); ++it ){
TDEIO::Job* ioJob = it.key();
Job *job = it.data();
delete job;
if(ioJob){
TDEIO::FileCopyJob *copyJob = static_cast<TDEIO::FileCopyJob*> (ioJob);
disconnect(copyJob, TQ_SIGNAL(result(TDEIO::Job*)), this, TQ_SLOT(copyJobResult(TDEIO::Job*)));
disconnect(copyJob, TQ_SIGNAL(percent ( TDEIO::Job *, unsigned long)), this, TQ_SLOT(updateProgress ( TDEIO::Job *, unsigned long)));
TQString fileDestination = (copyJob->destURL()).path();
copyJob->kill();
TQFile file( fileDestination );
file.remove();
}
}
jobs.clear();
}
/**
* @return The number of active jobs
*/
int Ripper::activeJobCount() {
return jobs.count();
}
/**
* @return The number of pending jobs
*/
int Ripper::pendingJobCount() {
return pendingJobs.count();
}
/**
* Cancel and remove the job with the matching id.
* Remove it from the local collection of jobs, delete the temp file if
* there is one.
* @param id the id number of the job to remove.
*/
void Ripper::removeJob(int id){
TQMap<TDEIO::Job*, Job*>::Iterator it;
for( it = jobs.begin(); it != jobs.end(); ++it ){
if(it.data()->id == id){
TDEIO::FileCopyJob *copyJob = dynamic_cast<TDEIO::FileCopyJob*> (it.key());
if(copyJob){
TQString fileDestination = (copyJob->destURL()).path();
copyJob->kill();
// This here is such a hack, shouldn't kill() do this, or why isn't there a stop()?
// TODO add to copyJob a stop() function.
TQFile file( fileDestination );
if(file.exists())
file.remove();
else {
TQFile f( fileDestination+".part" );
f.remove();
}
}
jobs.remove(it.key());
break;
}
}
Job *job = pendingJobs.first();
while(job){
if(job->id == id)
break;
job = pendingJobs.next();
}
if(job){
pendingJobs.remove(job);
delete job;
}
//tqDebug(TQString("Done removing Job:%1").arg(id).latin1());
tendToNewJobs();
}
/**
* Begin to rip the track specified in job.
* @param job the new job that this module should take over.
* @param job the new job that we need to handle.
*/
void Ripper::ripTrack(Job *job){
if(!job)
return;
emit(addJob(job, i18n("Ripping: %1 - %2").arg(job->track_artist).arg(job->track_title)));
pendingJobs.append(job);
tendToNewJobs();
}
/**
* See if there are are new jobs to attend too. If we are all loaded up
* then just loop.
*/
void Ripper::tendToNewJobs(){
if(pendingJobs.count() == 0){
emit jobsChanged();
return;
}
// If we are currently ripping the max try again in a little bit.
if(jobs.count() >= (uint)Prefs::maxWavFiles()){
emit jobsChanged();
return;
}
Job *job = pendingJobs.first();
if(!job)
return;
pendingJobs.remove(job);
TQMap<TQString, TQString> map;
TQString defaultTempDir;
if(Prefs::enableTempDir())
defaultTempDir = Prefs::tempDir();
else
defaultTempDir = locateLocal("tmp", "");
// For cases like "/tmp" where there is a missing /
defaultTempDir = KURL(defaultTempDir).path(1);
KTempFile tmp( defaultTempDir, ".wav" );
tmp.setAutoDelete(true);
TQString wavFile;
TQString args = job->device;
if(!args.isEmpty())
args = TQString("?device=%1").arg(args);
args = args+"&fileNameTemplate=Track %{number}";
if(job->track < 10)
wavFile = TQString("audiocd:/Wav/Track 0%1.wav%2").arg(job->track).arg(args);
else
wavFile = TQString("audiocd:/Wav/Track %1.wav%2").arg(job->track).arg(args);
KURL source(wavFile);
KURL dest(tmp.name());
TDEIO::FileCopyJob *copyJob = new TDEIO::FileCopyJob(source, dest, 0644, false, true, false, false);
jobs.insert(copyJob, job);
connect(copyJob, TQ_SIGNAL(result(TDEIO::Job*)), this, TQ_SLOT(copyJobResult(TDEIO::Job*)));
connect(copyJob, TQ_SIGNAL(percent ( TDEIO::Job *, unsigned long)), this, TQ_SLOT(updateProgress ( TDEIO::Job *, unsigned long)));
emit jobsChanged();
}
/**
* Copies the data from the TDEIO Job. Uses this data to fill in the
* information dialog.
* @param copyjob the IO job to copy from
*/
void Ripper::copyJobResult(TDEIO::Job *copyjob){
if(!copyjob)
return;
TDEIO::FileCopyJob *copyJob = dynamic_cast<TDEIO::FileCopyJob*> (copyjob);
KNotifyClient::event("track ripped");
if(jobs.find(copyjob) == jobs.end())
return;
Job *newJob = jobs[copyjob];
jobs.remove(copyjob);
if(Prefs::beepAfterRip())
KNotifyClient::beep();
if ( copyJob->error() == 0 ){
emit updateProgress(newJob->id, 100);
newJob->location = copyJob->destURL().path();
emit( encodeWav(newJob));
}
else{
copyJob->showErrorDialog(0);
TQFile file( (copyJob->destURL()).path());
file.remove();
emit updateProgress(newJob->id, -1);
delete newJob;
newJob = 0;
}
if(newJob && newJob->lastSongInAlbum){
if(Prefs::autoEjectAfterRip()){
// Don't eject device if a pending job has that device
Job *job = pendingJobs.first();
while( job ){
if( job->device == newJob->device )
break;
job = pendingJobs.next();
}
if( !job ){
deviceToEject = newJob->device;
TQTimer::singleShot( Prefs::autoEjectDelay()*1000 + 500, this, TQ_SLOT(ejectNow()));
}
}
KNotifyClient::event("cd ripped");
}
tendToNewJobs();
}
void Ripper::ejectNow(){
emit eject(deviceToEject);
}
/**
* Update the progress of the file copy.
* @param job the current ioslave job in progress
* @param percent the current percent that the ioslave has done.
*/
void Ripper::updateProgress( TDEIO::Job *job, unsigned long percent){
if(job){
Job *ripJob = (jobs[job]);
if(ripJob)
emit updateProgress(ripJob->id, percent);
}
}
#include "ripper.moc"