#include "outputdirectory.h" #include "filelist.h" #include "conversionoptions.h" #include "tagengine.h" #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include OutputDirectory::OutputDirectory( Config* _config, TQWidget* tqparent, const char* name ) : TQWidget( tqparent, name ) { config = _config; // create an icon loader object for loading icons KIconLoader *iconLoader = new KIconLoader(); TQGridLayout *grid = new TQGridLayout( this, 1, 1, 0, 3, "grid" ); TQHBoxLayout *box = new TQHBoxLayout( ); grid->addLayout( box, 0, 0 ); TQLabel *lOutput = new TQLabel( i18n("Output")+":", this, "lOutput" ); box->addWidget(lOutput); cMode = new KComboBox( this ); // cMode->insertItem( i18n("Default output directory") ); cMode->insertItem( i18n("By meta data") ); cMode->insertItem( i18n("Source directory") ); cMode->insertItem( i18n("Specify output directory") ); cMode->insertItem( i18n("Copy directory structure") ); //TQToolTip::add( cMode, i18n("Output all converted files into...") ); box->addWidget( cMode ); connect( cMode, TQT_SIGNAL(activated(int)), this, TQT_SLOT(modeChangedSlot(int)) ); modeJustChanged = false; /*pModeInfo = new KToolBarButton( "messagebox_info", 1010, this, "pModeInfo" ); TQToolTip::add( pModeInfo, i18n("Information about the output mode") ); box->addWidget( pModeInfo ); connect( pModeInfo, TQT_SIGNAL(clicked()), this, TQT_SLOT(modeInfo()) );*/ pClear = new KToolBarButton( "locationbar_erase", 1001, this, "pClear" ); TQToolTip::add( pClear, i18n("Clear the directory input field") ); box->addWidget( pClear ); lDir = new KLineEdit( this, "lDir" ); box->addWidget( lDir ); connect( lDir, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(directoryChangedSlot(const TQString&)) ); connect( pClear, TQT_SIGNAL(clicked()), lDir, TQT_SLOT(setFocus()) ); connect( pClear, TQT_SIGNAL(clicked()), lDir, TQT_SLOT(clear()) ); /*pDirInfo = new KToolBarButton( "messagebox_info", 1011, this, "pDirInfo" ); TQToolTip::add( pDirInfo, i18n("Information about the wildcards") ); box->addWidget( pDirInfo ); connect( pDirInfo, TQT_SIGNAL(clicked()), this, TQT_SLOT(dirInfo()) );*/ pDirSelect = new KToolBarButton( "folder", 1012, this, "pDirSelect" ); TQToolTip::add( pDirSelect, i18n("Choose an output directory") ); box->addWidget( pDirSelect ); connect( pDirSelect, TQT_SIGNAL(clicked()), this, TQT_SLOT(selectDir()) ); pDirGoto = new KToolBarButton( "konqueror", 1013, this, "pDirGoto" ); TQToolTip::add( pDirGoto, i18n("Open Konqueror with the output directory") ); box->addWidget( pDirGoto ); connect( pDirGoto, TQT_SIGNAL(clicked()), this, TQT_SLOT(gotoDir()) ); // delete the icon loader object delete iconLoader; modeChangedSlot( MetaData ); // TODO implement proper // save the current directory always on text change } OutputDirectory::~OutputDirectory() {} void OutputDirectory::disable() { cMode->setEnabled( false ); lDir->setEnabled( false ); pClear->setEnabled( false ); pDirSelect->setEnabled( false ); } void OutputDirectory::enable() { cMode->setEnabled( true ); modeChangedSlot( cMode->currentItem() ); } OutputDirectory::Mode OutputDirectory::mode() { return (Mode)cMode->currentItem(); } void OutputDirectory::setMode( OutputDirectory::Mode mode ) { cMode->setCurrentItem( (int)mode ); modeChangedSlot( (int)mode ); } TQString OutputDirectory::directory() { if( /*(Mode)cMode->currentItem() != Default && */(Mode)cMode->currentItem() != Source ) return lDir->text(); else return ""; } void OutputDirectory::setDirectory( const TQString& directory ) { if( /*(Mode)cMode->currentItem() != Default && */(Mode)cMode->currentItem() != Source ) lDir->setText( directory ); } TQString OutputDirectory::calcPath( FileListItem* fileListItem, Config* config, TQString extension ) { // TODO replace '//' by '/' ??? // FIXME test fvat names TQString path; if( extension.isEmpty() ) extension = fileListItem->options.encodingOptions.sFormat; // FIXME file name TQString fileName; if( fileListItem->track == -1 ) fileName = fileListItem->fileName; else if( fileListItem->tags != 0 ) fileName = TQString().sprintf("%02i",fileListItem->tags->track) + " - " + fileListItem->tags->title + "." + extension; else fileName = "track" + TQString::number(fileListItem->track) + "." + extension; // NOTE shouldn't be possible // if the user wants to change the output directory/file name per file! if( !fileListItem->options.outputFilePathName.isEmpty() ) { // path = uniqueFileName( changeExtension(fileListItem->options.outputFilePathName,extension) ); path = changeExtension(fileListItem->options.outputFilePathName,extension); if( config->data.general.useVFATNames ) path = vfatPath( path ); return path; } if( fileListItem->options.outputOptions.mode == Specify ) { // path = uniqueFileName( changeExtension(fileListItem->options.outputOptions.directory+"/"+fileName,extension) ); path = changeExtension(fileListItem->options.outputOptions.directory+"/"+fileName,extension); if( config->data.general.useVFATNames ) path = vfatPath( path ); return path; } else if( /*fileListItem->options.outputOptions.mode == Default || */fileListItem->options.outputOptions.mode == MetaData ) { /*if( fileListItem->options.outputOptions.mode == Default ) path = config->data.general.defaultOutputDirectory; else */path = fileListItem->options.outputOptions.directory; if( path.right(1) == "/" ) path += "%f"; else if( path.findRev(TQRegExp("%[aAbBcCdDfFgGnNpPtTyY]{1,1}")) < path.findRev("/") ) path += "/%f"; path.replace( "%a", "$replace_by_artist$" ); path.replace( "%b", "$replace_by_album$" ); path.replace( "%c", "$replace_by_comment$" ); path.replace( "%d", "$replace_by_disc$" ); path.replace( "%g", "$replace_by_genre$" ); path.replace( "%n", "$replace_by_track$" ); path.replace( "%p", "$replace_by_composer$" ); path.replace( "%t", "$replace_by_title$" ); path.replace( "%y", "$replace_by_year$" ); path.replace( "%f", "$replace_by_filename$" ); TQString artist = ( fileListItem->tags == 0 || fileListItem->tags->artist.isEmpty() ) ? i18n("Unknown Artist") : fileListItem->tags->artist; /// artist.replace("/","\\"); path.replace( "$replace_by_artist$", KURL::encode_string(artist).replace("/","%2f") ); TQString album = ( fileListItem->tags == 0 || fileListItem->tags->album.isEmpty() ) ? i18n("Unknown Album") : fileListItem->tags->album; /// album.replace("/","\\"); path.replace( "$replace_by_album$", KURL::encode_string(album).replace("/","%2f") ); TQString comment = ( fileListItem->tags == 0 || fileListItem->tags->comment.isEmpty() ) ? i18n("No Comment") : fileListItem->tags->comment; /// comment.replace("/","\\"); path.replace( "$replace_by_comment$", KURL::encode_string(comment).replace("/","%2f") ); TQString disc = ( fileListItem->tags == 0 ) ? "0" : TQString().sprintf("%i",fileListItem->tags->disc); path.replace( "$replace_by_disc$", disc ); TQString genre = ( fileListItem->tags == 0 || fileListItem->tags->genre.isEmpty() ) ? i18n("Unknown Genre") : fileListItem->tags->genre; /// genre.replace("/","\\"); path.replace( "$replace_by_genre$", KURL::encode_string(genre).replace("/","%2f") ); TQString track = ( fileListItem->tags == 0 ) ? "00" : TQString().sprintf("%02i",fileListItem->tags->track); path.replace( "$replace_by_track$", track ); TQString composer = ( fileListItem->tags == 0 || fileListItem->tags->composer.isEmpty() ) ? i18n("Unknown Composer") : fileListItem->tags->composer; /// composer.replace("/","\\"); path.replace( "$replace_by_composer$", KURL::encode_string(composer).replace("/","%2f") ); TQString title = ( fileListItem->tags == 0 || fileListItem->tags->title.isEmpty() ) ? i18n("Unknown Title") : fileListItem->tags->title; /// title.replace("/","\\"); path.replace( "$replace_by_title$", KURL::encode_string(title).replace("/","%2f") ); TQString year = ( fileListItem->tags == 0 ) ? "0000" : TQString().sprintf("%04i",fileListItem->tags->year); path.replace( "$replace_by_year$", year ); TQString filename = fileName.left( fileName.findRev(".") ); /// filename.replace("/","\\"); path.replace( "$replace_by_filename$", filename ); // path = uniqueFileName( path + "." + extension ); path = path + "." + extension; if( config->data.general.useVFATNames ) path = vfatPath( path ); return path; } else if( fileListItem->options.outputOptions.mode == CopyStructure ) { // TODO is that correct ??? TQString basePath = fileListItem->options.outputOptions.directory; TQString originalPath = fileListItem->options.filePathName; TQString cutted; while( basePath.length() > 0 ) { if( fileListItem->options.filePathName.find(basePath) == 0 ) { originalPath.replace( basePath, "" ); return uniqueFileName( changeExtension(basePath+cutted+originalPath,extension) ); } else { cutted = basePath.right( basePath.length() - basePath.findRev("/") ) + cutted; basePath = basePath.left( basePath.findRev("/") ); } } // path = uniqueFileName( changeExtension(fileListItem->options.outputOptions.directory+"/"+fileListItem->options.filePathName,extension) ); path = changeExtension(fileListItem->options.outputOptions.directory+"/"+fileListItem->options.filePathName,extension); if( config->data.general.useVFATNames ) path = vfatPath( path ); return path; } else { // path = uniqueFileName( changeExtension(fileListItem->options.filePathName,extension) ); path = changeExtension(fileListItem->options.filePathName,extension); if( config->data.general.useVFATNames ) path = vfatPath( path ); return path; } } TQString OutputDirectory::changeExtension( const TQString& filename, const TQString& extension ) { return filename.left( filename.findRev(".") + 1 ) + extension; } TQString OutputDirectory::uniqueFileName( const TQString& filename ) { TQString filePathName; if( filename.left( 1 ) == "/" ) { filePathName = filename; } else if( filename.left( 7 ) == "file://" ) { filePathName = filename; filePathName.remove( 0, 7 ); } else if( filename.left( 13 ) == "system:/home/" ) { filePathName = filename; filePathName.remove( 0, 13 ); filePathName = TQDir::homeDirPath() + "/" + filePathName; } else if( filename.left( 14 ) == "system:/users/" || filename.left( 6 ) == "home:/" ) { int length = ( filename.left(6) == "home:/" ) ? 6 : 14; TQString username = filename; username.remove( 0, length ); username = username.left( username.find("/") ); filePathName = filename; filePathName.remove( 0, length + username.length() ); KUser user( username ); filePathName = user.homeDir() + filePathName; } else if( filename.left( 14 ) == "system:/media/" || filename.left( 7 ) == "media:/" ) { int length = ( filename.left(7) == "media:/" ) ? 7 : 14; TQString device = filename; device.remove( 0, length ); device = "/dev/" + device.left( device.find( "/" ) ); KMountPoint::List mountPoints = KMountPoint::possibleMountPoints(); for( KMountPoint::List::ConstIterator jt = mountPoints.begin(); jt != mountPoints.end(); ++jt ) { const KSharedPtr mp = *jt; if( mp->mountedFrom() == device ) { filePathName = ( mp->mountPoint() == "/" ) ? mp->mountPoint() : mp->mountPoint() + "/"; filePathName += filename.right( filename.length() - device.length() - length + 4 ); } } } else { filePathName = filename; } TQFileInfo fileInfo( KURL::decode_string(filePathName) ); // generate a unique file name while( fileInfo.exists() ) { fileInfo.setFile( fileInfo.filePath().left( fileInfo.filePath().findRev(".")+1 ) + i18n("new") + fileInfo.filePath().right( fileInfo.filePath().length() - fileInfo.filePath().findRev(".") ) ); } return KURL::encode_string( fileInfo.filePath() ); // was: .replace( "//", "/" ) } TQString OutputDirectory::makePath( const TQString& path ) { TQFileInfo fileInfo( path ); TQStringList dirs = TQStringList::split( "/", fileInfo.dirPath() ); TQString mkDir; TQDir dir; for( TQStringList::Iterator it = dirs.begin(); it != dirs.end(); ++it ) { mkDir += "/" + KURL::decode_string(*it).replace("/","%2f"); dir.setPath( mkDir ); if( !dir.exists() ) dir.mkdir( mkDir ); } return path; } // copyright : (C) 2002 by Mark Kretschmann // email : markey@web.de // modified : 2008 Daniel Faust TQString OutputDirectory::vfatPath( const TQString& path ) { TQString s = KURL::decode_string(path.right( path.length() - path.findRev("/") - 1 )); TQString p = KURL::decode_string(path.left( path.findRev("/") + 1 )); for( uint i = 0; i < s.length(); i++ ) { TQChar c = s.ref( i ); if( c < TQChar(0x20) || c=='*' || c=='?' || c=='<' || c=='>' || c=='|' || c=='"' || c==':' || c=='/' || c=='\\' ) c = '_'; s.ref( i ) = c; } uint len = s.length(); if( len == 3 || (len > 3 && s[3] == '.') ) { TQString l = s.left(3).lower(); if( l=="aux" || l=="con" || l=="nul" || l=="prn" ) s = "_" + s; } else if( len == 4 || (len > 4 && s[4] == '.') ) { TQString l = s.left(3).lower(); TQString d = s.mid(3,1); if( (l=="com" || l=="lpt") && (d=="0" || d=="1" || d=="2" || d=="3" || d=="4" || d=="5" || d=="6" || d=="7" || d=="8" || d=="9") ) s = "_" + s; } while( s.startsWith( "." ) ) s = s.mid(1); while( s.endsWith( "." ) ) s = s.left( s.length()-1 ); s = s.left(255); len = s.length(); if( s[len-1] == ' ' ) s[len-1] = '_'; return TQString( p + s ).replace("%2f","_"); // return p + s; } void OutputDirectory::selectDir() { TQString startDir = lDir->text(); int i = startDir.find( TQRegExp("%[aAbBcCdDfFgGnNpPtTyY]{1,1}") ); if( i != -1 ) { i = startDir.findRev( "/", i ); startDir = startDir.left( i ); } TQString directory = KFileDialog::getExistingDirectory( startDir, this, i18n("Choose an output directory") ); if( !directory.isEmpty() ) { TQString dir = lDir->text(); i = dir.find( TQRegExp("%[aAbBcCdDfFgGnNpPtTyY]{1,1}") ); if( i != -1 && (Mode)cMode->currentItem() == MetaData ) { i = dir.findRev( "/", i ); lDir->setText( directory + dir.mid(i) ); } else { lDir->setText( directory ); } emit directoryChanged( directory ); } } void OutputDirectory::gotoDir() { TQString startDir = lDir->originalText(); int i = startDir.find( TQRegExp("%[aAbBcCdDfFgGnNpPtTyY]{1,1}") ); if( i != -1 ) { i = startDir.findRev( "/", i ); startDir = startDir.left( i ); } kfm.clearArguments(); kfm << "kfmclient"; kfm << "openURL"; kfm << startDir; kfm.start( KProcess::DontCare ); } void OutputDirectory::modeChangedSlot( int mode ) { modeJustChanged = true; /*if( (Mode)mode == Default ) { pClear->setEnabled( false ); lDir->setText( config->data.general.defaultOutputDirectory ); lDir->setEnabled( true ); lDir->setReadOnly( true ); lDir->setEnableSqueezedText( true ); pDirSelect->setEnabled( false ); // TODO hide pDirSelect and show pDirEdit pDirGoto->setEnabled( true ); //pDirInfo->hide(); TQToolTip::remove( cMode ); TQToolTip::add( cMode, i18n("Output all converted files into the soundKonverter default output directory") ); TQToolTip::remove( lDir ); } else */ if( (Mode)mode == MetaData ) { pClear->setEnabled( true ); if( config->data.general.metaDataOutputDirectory.isEmpty() ) config->data.general.metaDataOutputDirectory = TQDir::homeDirPath() + "/soundKonverter/%b/%d - %n - %a - %t"; lDir->setText( config->data.general.metaDataOutputDirectory ); lDir->setEnabled( true ); lDir->setReadOnly( false ); // lDir->setEnableSqueezedText( false ); pDirSelect->setEnabled( true ); pDirGoto->setEnabled( true ); //pDirInfo->show(); TQToolTip::remove( cMode ); TQToolTip::add( cMode, i18n("Name all converted files according to the specified pattern") ); TQToolTip::remove( lDir ); TQToolTip::add( lDir, i18n("

The following strings are wildcards, that will be replaced by the information in the meta data:

%a - Artist
%b - Album
%c - Comment
%d - Disc number
%g - Genre
%n - Track number
%p - Composer
%t - Title
%y - Year
%f - Original file name

") ); } else if( (Mode)mode == Source ) { pClear->setEnabled( false ); lDir->setText( "" ); lDir->setEnabled( false ); lDir->setReadOnly( false ); // lDir->setEnableSqueezedText( false ); pDirSelect->setEnabled( false ); pDirGoto->setEnabled( false ); //pDirInfo->hide(); TQToolTip::remove( cMode ); TQToolTip::add( cMode, i18n("Output all converted files into the same directory as the original files") ); TQToolTip::remove( lDir ); } else if( (Mode)mode == Specify ) { pClear->setEnabled( true ); if( config->data.general.specifyOutputDirectory.isEmpty() ) config->data.general.specifyOutputDirectory = TQDir::homeDirPath() + "/soundKonverter"; lDir->setText( config->data.general.specifyOutputDirectory ); lDir->setEnabled( true ); lDir->setReadOnly( false ); // lDir->setEnableSqueezedText( false ); pDirSelect->setEnabled( true ); pDirGoto->setEnabled( true ); //pDirInfo->hide(); TQToolTip::remove( cMode ); TQToolTip::add( cMode, i18n("Output all converted files into the specified output directory") ); TQToolTip::remove( lDir ); } else if( (Mode)mode == CopyStructure ) { pClear->setEnabled( true ); if( config->data.general.copyStructureOutputDirectory.isEmpty() ) config->data.general.copyStructureOutputDirectory = TQDir::homeDirPath() + "/soundKonverter"; lDir->setText( config->data.general.copyStructureOutputDirectory ); lDir->setEnabled( true ); lDir->setReadOnly( false ); // lDir->setEnableSqueezedText( false ); pDirSelect->setEnabled( true ); pDirGoto->setEnabled( true ); //pDirInfo->hide(); TQToolTip::remove( cMode ); TQToolTip::add( cMode, i18n("Copy the whole directory structure for all converted files") ); TQToolTip::remove( lDir ); } emit modeChanged( (Mode)mode ); modeJustChanged = false; } void OutputDirectory::directoryChangedSlot( const TQString& directory ) { if( modeJustChanged ) { modeJustChanged = false; return; } Mode mode = (Mode)cMode->currentItem(); if( mode == MetaData ) { config->data.general.metaDataOutputDirectory = directory; } else if( mode == Specify ) { config->data.general.specifyOutputDirectory = directory; } else if( mode == CopyStructure ) { config->data.general.copyStructureOutputDirectory = directory; } emit directoryChanged( directory ); } /*void OutputDirectory::modeInfo() { int mode = cMode->currentItem(); TQString sModeString = cMode->currentText(); if( (Mode)mode == Default ) { KMessageBox::information( this, i18n("This will output each file into the soundKonverter default directory."), TQString(i18n("Mode")+": ").append(sModeString) ); } else if( (Mode)mode == Source ) { KMessageBox::information( this, i18n("This will output each file into the same directory as the original file."), TQString(i18n("Mode")+": ").append(sModeString) ); } else if( (Mode)mode == Specify ) { KMessageBox::information( this, i18n("This will output each file into the directory specified in the editbox behind."), TQString(i18n("Mode")+": ").append(sModeString) ); } else if( (Mode)mode == MetaData ) { KMessageBox::information( this, i18n("This will output each file into a directory, which is created based on the metadata in the audio files. Select a directory, where the new directories should be created."), TQString(i18n("Mode")+": ").append(sModeString) ); } else if( (Mode)mode == CopyStructure ) { KMessageBox::information( this, i18n("This will output each file into a directory, which is created based on the name of the original directory. So you can copy a whole directory structure, in one you have the original files, in the other the converted."), TQString(i18n("Mode")+": ").append(sModeString) ); } else { KMessageBox::error( this, i18n("This mode (%s) doesn't exist.", sModeString), TQString(i18n("Mode")+": ").append(sModeString) ); } }*/ /*void OutputDirectory::dirInfo() { KMessageBox::information( this, i18n("

The following strings are space holders, that will be replaced by the information in the metatags.

%a - Artist
%b - Album
%c - Comment
%d - Disc number
%g - Genre
%n - Track number
%p - Composer
%t - Title
%y - Year
%f - Original file name

"), TQString(i18n("Legend")) ); }*/