1 
2 #include "outputdirectory.h"
3 #include "filelistitem.h"
4 #include "core/conversionoptions.h"
5 #include "config.h"
6 
7 #include <QApplication>
8 #include <QLayout>
9 #include <QHBoxLayout>
10 #include <QDir>
11 #include <QFileInfo>
12 #include <QString>
13 #include <QStringList>
14 #include <QLabel>
15 #include <QRegExp>
16 #include <QProcess>
17 
18 #include <KLocale>
19 #include <KFileDialog>
20 #include <KComboBox>
21 #include <KLineEdit>
22 #include <KIcon>
23 #include <KPushButton>
24 #include <kmountpoint.h>
25 
26 
OutputDirectory(Config * _config,QWidget * parent)27 OutputDirectory::OutputDirectory( Config *_config, QWidget *parent )
28     : QWidget( parent ),
29     config( _config )
30 {
31     QGridLayout *grid = new QGridLayout( this );
32     grid->setMargin( 0 );
33 
34     QHBoxLayout *box = new QHBoxLayout( );
35     grid->addLayout( box, 0, 0 );
36 
37     cMode = new KComboBox( this );
38     cMode->addItem( i18n("By meta data") );
39     cMode->addItem( i18n("Source directory") );
40     cMode->addItem( i18n("Specify output directory") );
41     cMode->addItem( i18n("Copy directory structure") );
42     box->addWidget( cMode );
43     connect( cMode, SIGNAL(activated(int)), this, SLOT(modeChangedSlot(int)) );
44 
45     cDir = new KComboBox( true, this );
46     box->addWidget( cDir, 1 );
47     connect( cDir, SIGNAL(editTextChanged(const QString&)),  this, SLOT(directoryChangedSlot(const QString&)) );
48 
49     pDirSelect = new KPushButton( KIcon("folder"), "", this );
50     box->addWidget( pDirSelect );
51     pDirSelect->setFixedWidth( pDirSelect->height() );
52     pDirSelect->setToolTip( i18n("Choose an output directory") );
53     connect( pDirSelect, SIGNAL(clicked()), this, SLOT(selectDir()) );
54     pDirGoto = new KPushButton( KIcon("system-file-manager"), "", this );
55     box->addWidget( pDirGoto );
56     pDirGoto->setFixedWidth( pDirGoto->height() );
57     pDirGoto->setToolTip( i18n("Open the output directory with Dolphin") );
58     connect( pDirGoto, SIGNAL(clicked()), this, SLOT(gotoDir()) );
59 
60     setMode( (OutputDirectory::Mode)config->data.general.lastOutputDirectoryMode );
61 }
62 
~OutputDirectory()63 OutputDirectory::~OutputDirectory()
64 {}
65 
disable()66 void OutputDirectory::disable()
67 {
68     cMode->setEnabled( false );
69     cDir->setEnabled( false );
70     pDirSelect->setEnabled( false );
71 }
72 
enable()73 void OutputDirectory::enable()
74 {
75     cMode->setEnabled( true );
76     modeChangedSlot( cMode->currentIndex() );
77 }
78 
mode()79 OutputDirectory::Mode OutputDirectory::mode()
80 {
81     return (Mode)cMode->currentIndex();
82 }
83 
setMode(OutputDirectory::Mode mode)84 void OutputDirectory::setMode( OutputDirectory::Mode mode )
85 {
86     cMode->setCurrentIndex( (int)mode );
87     updateMode( mode );
88 }
89 
directory()90 QString OutputDirectory::directory()
91 {
92     if( (Mode)cMode->currentIndex() != Source )
93         return cDir->currentText();
94     else
95         return "";
96 }
97 
setDirectory(const QString & directory)98 void OutputDirectory::setDirectory( const QString& directory )
99 {
100     if( (Mode)cMode->currentIndex() != Source )
101         cDir->setEditText( directory );
102 }
103 
filesystem()104 QString OutputDirectory::filesystem()
105 {
106     return filesystemForDirectory( directory() );
107 }
108 
filesystemForDirectory(const QString & dir)109 QString OutputDirectory::filesystemForDirectory( const QString& dir )
110 {
111     if( dir.isEmpty() )
112         return QString();
113 
114     KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByPath( dir );
115     if( !mp )
116         return QString();
117 
118     return mp->mountType();
119 }
120 
calcPath(FileListItem * fileListItem,Config * config,const QStringList & usedOutputNames)121 KUrl OutputDirectory::calcPath( FileListItem *fileListItem, Config *config, const QStringList& usedOutputNames )
122 {
123     QRegExp regEx( "%[abcdfgnpsty]{1,1}", Qt::CaseInsensitive );
124 
125     const ConversionOptions *options = config->conversionOptionsManager()->getConversionOptions(fileListItem->conversionOptionsId);
126     if( !options )
127         return KUrl();
128 
129     QString path;
130     KUrl url;
131 
132     QString extension;
133     if( config->pluginLoader()->codecExtensions(options->codecName).count() > 0 )
134         extension = config->pluginLoader()->codecExtensions(options->codecName).first();
135 
136     if( extension.isEmpty() )
137         extension = options->codecName;
138 
139     QString fileName;
140     if( fileListItem->track == -1 )
141         fileName = fileListItem->url.fileName();
142     else
143         fileName =  QString().sprintf("%02i",fileListItem->tags->track) + " - " + fileListItem->tags->artist + " - " + fileListItem->tags->title + "." + extension;
144 
145     if( options->outputDirectoryMode == Specify )
146     {
147         path = options->outputDirectory+"/"+fileName;
148 
149         if( config->data.general.useVFATNames || options->outputFilesystem == "vfat" )
150             path = vfatPath( path );
151 
152         if( options->outputFilesystem == "ntfs" || options->outputFilesystem == "fuseblk" )
153             path = ntfsPath( path );
154 
155         url = changeExtension( KUrl(path), extension );
156 
157         if( config->data.general.conflictHandling == Config::Data::General::NewFileName )
158             url = uniqueFileName( url, usedOutputNames );
159 
160         return url;
161     }
162     else if( options->outputDirectoryMode == MetaData )
163     {
164         path = options->outputDirectory;
165 
166         // TODO a little bit redundant, adding %f if file name wasn't set properly
167         // TODO these restrictions could be a little bit over the top
168         if( path.right(1) == "/" )
169             path += "%f";
170         else if( path.lastIndexOf(regEx) < path.lastIndexOf("/") )
171             path += "/%f";
172 
173         const int fileNameBegin = path.lastIndexOf("/");
174         if( fileListItem->tags == 0 ||
175             ( path.mid(fileNameBegin).contains("%n") && fileListItem->tags->track == 0 ) ||
176             ( path.mid(fileNameBegin).contains("%t") && fileListItem->tags->title.isEmpty() )
177           )
178         {
179             path = path.left( fileNameBegin ) + "/%f";
180         }
181 
182         path.replace( "\\[", "$quared_bracket_open$" );
183         path.replace( "\\]", "$quared_bracket_close$" );
184 
185         QRegExp reg( "\\[(.*)%([abcdfgnpsty])(.*)\\]", Qt::CaseInsensitive );
186         reg.setMinimal( true );
187         while( path.indexOf(reg) != -1 )
188         {
189             if( fileListItem->tags &&
190                 (
191                   ( reg.cap(2) == "a" && !fileListItem->tags->artist.isEmpty() ) ||
192                   ( reg.cap(2) == "z" && !fileListItem->tags->albumArtist.isEmpty() ) ||
193                   ( reg.cap(2) == "b" && !fileListItem->tags->album.isEmpty() ) ||
194                   ( reg.cap(2) == "c" && !fileListItem->tags->comment.isEmpty() ) ||
195                   ( reg.cap(2) == "d" && fileListItem->tags->disc != 0 ) ||
196                   ( reg.cap(2) == "g" && !fileListItem->tags->genre.isEmpty() ) ||
197                   ( reg.cap(2) == "n" && fileListItem->tags->track != 0 ) ||
198                   ( reg.cap(2) == "p" && !fileListItem->tags->composer.isEmpty() ) ||
199                   ( reg.cap(2) == "t" && !fileListItem->tags->title.isEmpty() ) ||
200                   ( reg.cap(2) == "y" && fileListItem->tags->year != 0 )
201                 )
202               )
203             {
204                 path.replace( reg, "\\1%\\2\\3" );
205             }
206             else
207             {
208                 path.replace( reg, "" );
209             }
210         }
211 
212         path.replace( "$quared_bracket_open$", "[" );
213         path.replace( "$quared_bracket_close$", "]" );
214 
215         while( path.contains("//") )
216             path.replace( "//", "/" );
217 
218         path.replace( "%a", "$replace_by_artist$" );
219         path.replace( "%z", "$replace_by_albumartist$" );
220         path.replace( "%b", "$replace_by_album$" );
221         path.replace( "%c", "$replace_by_comment$" );
222         path.replace( "%d", "$replace_by_disc$" );
223         path.replace( "%g", "$replace_by_genre$" );
224         path.replace( "%n", "$replace_by_track$" );
225         path.replace( "%p", "$replace_by_composer$" );
226         path.replace( "%t", "$replace_by_title$" );
227         path.replace( "%y", "$replace_by_year$" );
228         path.replace( "%f", "$replace_by_filename$" );
229         path.replace( "%s", "$replace_by_sourcedir$" );
230 
231         QString artist = ( fileListItem->tags == 0 || fileListItem->tags->artist.isEmpty() ) ? i18n("Unknown Artist") : fileListItem->tags->artist;
232         artist.replace("/",",");
233         path.replace( "$replace_by_artist$", artist );
234 
235         QString albumArtist;
236         if( fileListItem->tags )
237         {
238             albumArtist = fileListItem->tags->albumArtist.isEmpty() ? fileListItem->tags->artist : fileListItem->tags->albumArtist;
239         }
240         if( albumArtist.isEmpty() )
241         {
242             albumArtist = i18n("Unknown Artist");
243         }
244         albumArtist.replace("/",",");
245         path.replace( "$replace_by_albumartist$", albumArtist );
246 
247         QString album = ( fileListItem->tags == 0 || fileListItem->tags->album.isEmpty() ) ? i18n("Unknown Album") : fileListItem->tags->album;
248         album.replace("/",",");
249         path.replace( "$replace_by_album$", album );
250 
251         QString comment = ( fileListItem->tags == 0 || fileListItem->tags->comment.isEmpty() ) ? i18n("No Comment") : fileListItem->tags->comment;
252         comment.replace("/",",");
253         path.replace( "$replace_by_comment$", comment );
254 
255         QString disc = ( fileListItem->tags == 0 ) ? "0" : QString().sprintf("%i",fileListItem->tags->disc);
256         path.replace( "$replace_by_disc$", disc );
257 
258         QString genre = ( fileListItem->tags == 0 || fileListItem->tags->genre.isEmpty() ) ? i18n("Unknown Genre") : fileListItem->tags->genre;
259         genre.replace("/",",");
260         path.replace( "$replace_by_genre$", genre );
261 
262         QString track = ( fileListItem->tags == 0 ) ? "00" : QString().sprintf("%02i",fileListItem->tags->track);
263         path.replace( "$replace_by_track$", track );
264 
265         QString composer = ( fileListItem->tags == 0 || fileListItem->tags->composer.isEmpty() ) ? i18n("Unknown Composer") : fileListItem->tags->composer;
266         composer.replace("/",",");
267         path.replace( "$replace_by_composer$", composer );
268 
269         QString title = ( fileListItem->tags == 0 || fileListItem->tags->title.isEmpty() ) ? i18n("Unknown Title") : fileListItem->tags->title;
270         title.replace("/",",");
271         path.replace( "$replace_by_title$", title );
272 
273         QString year = ( fileListItem->tags == 0 ) ? "0000" : QString().sprintf("%04i",fileListItem->tags->year);
274         path.replace( "$replace_by_year$", year );
275 
276         QString filename = fileName.left( fileName.lastIndexOf(".") );
277         filename.replace("/",",");
278         path.replace( "$replace_by_filename$", filename );
279 
280         QString sourcedir = fileListItem->url.directory();
281         path.replace( "$replace_by_sourcedir$", sourcedir );
282 
283         if( config->data.general.useVFATNames || options->outputFilesystem == "vfat" )
284             path = vfatPath( path );
285 
286         if( options->outputFilesystem == "ntfs" || options->outputFilesystem == "fuseblk" )
287             path = ntfsPath( path );
288 
289         url = KUrl( path + "." + extension );
290 
291         if( config->data.general.conflictHandling == Config::Data::General::NewFileName )
292             url = uniqueFileName( url, usedOutputNames );
293 
294         return url;
295     }
296     else if( options->outputDirectoryMode == CopyStructure )
297     {
298         QString basePath = options->outputDirectory;
299         QString originalPath = fileListItem->url.pathOrUrl();
300         int cutpos = basePath.length();
301         while( basePath.left(cutpos) != originalPath.left(cutpos) )
302         {
303             cutpos = basePath.lastIndexOf( '/', cutpos - 1 );
304         }
305         // At this point, basePath and originalPath overlap on the left for cutpos characters (which might be 0).
306         path = basePath+originalPath.mid(cutpos);
307 
308         if( config->data.general.useVFATNames || options->outputFilesystem == "vfat" )
309             path = vfatPath( path );
310 
311         if( options->outputFilesystem == "ntfs" || options->outputFilesystem == "fuseblk" )
312             path = ntfsPath( path );
313 
314         url = changeExtension( KUrl(path), extension );
315 
316         if( config->data.general.conflictHandling == Config::Data::General::NewFileName )
317             url = uniqueFileName( url, usedOutputNames );
318 
319         return url;
320     }
321     else // SourceDirectory
322     {
323         path = fileListItem->url.toLocalFile();
324 
325         if( config->data.general.useVFATNames )
326             path = vfatPath( path );
327 
328         url = changeExtension( KUrl(path), extension );
329 
330         if( config->data.general.conflictHandling == Config::Data::General::NewFileName )
331             url = uniqueFileName( url, usedOutputNames );
332 
333         return url;
334     }
335 }
336 
changeExtension(const KUrl & url,const QString & extension)337 KUrl OutputDirectory::changeExtension( const KUrl& url, const QString& extension )
338 {
339     KUrl changedUrl = url;
340 
341     const QString urlFileName = url.fileName();
342     const QString fileName = urlFileName.left( urlFileName.lastIndexOf(".")+1 ) + extension;
343     changedUrl.setFileName( fileName );
344 
345     return changedUrl;
346 }
347 
uniqueFileName(const KUrl & url,const QStringList & usedOutputNames)348 KUrl OutputDirectory::uniqueFileName( const KUrl& url, const QStringList& usedOutputNames )
349 {
350     KUrl uniqueUrl = url;
351 
352     while( QFile::exists(uniqueUrl.toLocalFile()) || usedOutputNames.contains(uniqueUrl.toLocalFile()) )
353     {
354         const QString newString = i18nc("will be appended to the filename if a file with the same name already exists","new");
355         const QString urlFileName = uniqueUrl.fileName();
356         const QString fileName = urlFileName.left( urlFileName.lastIndexOf(".")+1 ) + newString + urlFileName.mid( urlFileName.lastIndexOf(".") );
357         uniqueUrl.setFileName( fileName );
358     }
359 
360     return uniqueUrl;
361 }
362 
makePath(const KUrl & url)363 KUrl OutputDirectory::makePath( const KUrl& url )
364 {
365     QFileInfo fileInfo( url.toLocalFile() );
366 
367     QStringList directories = fileInfo.absoluteDir().absolutePath().split( "/" );
368     QString mkDir;
369     QDir dir;
370     foreach( const QString& directory, directories )
371     {
372         mkDir += "/" + directory;
373         dir.setPath( mkDir );
374         if( !dir.exists() )
375         {
376             if( !dir.mkdir(mkDir) )
377             {
378                 return KUrl();
379             }
380         }
381     }
382 
383     return url;
384 }
385 
386 // from amarok 2.3.0
387 // copyright            : (C) 2010 by Amarok developers
388 // web                  : amarok.kde.org
vfatPath(const QString & path)389 QString OutputDirectory::vfatPath( const QString& path )
390 {
391     QString s = path;
392 
393     if( QDir::separator() == '/' ) // we are on *nix, \ is a valid character in file or directory names, NOT the dir separator
394         s.replace( '\\', '_' );
395     else
396         s.replace( '/', '_' ); // on windows we have to replace / instead
397 
398     for( int i = 0; i < s.length(); i++ )
399     {
400         QChar c = s[ i ];
401         if( c < QChar(0x20) || c == QChar(0x7F) // 0x7F = 127 = DEL control character
402             || c=='*' || c=='?' || c=='<' || c=='>'
403             || c=='|' || c=='"' || c==':' )
404             c = '_';
405         else if( c == '[' )
406             c = '(';
407         else if ( c == ']' )
408             c = ')';
409         s[ i ] = c;
410     }
411 
412     /* beware of reserved device names */
413     uint len = s.length();
414     if( len == 3 || (len > 3 && s[3] == '.') )
415     {
416         QString l = s.left(3).toLower();
417         if( l=="aux" || l=="con" || l=="nul" || l=="prn" )
418             s = '_' + s;
419     }
420     else if( len == 4 || (len > 4 && s[4] == '.') )
421     {
422         QString l = s.left(3).toLower();
423         QString d = s.mid(3,1);
424         if( (l=="com" || l=="lpt") &&
425                 (d=="0" || d=="1" || d=="2" || d=="3" || d=="4" ||
426                     d=="5" || d=="6" || d=="7" || d=="8" || d=="9") )
427             s = '_' + s;
428     }
429 
430     // "clock$" is only allowed WITH extension, according to:
431     // http://en.wikipedia.org/w/index.php?title=Filename&oldid=303934888#Comparison_of_file_name_limitations
432     if( QString::compare( s, "clock$", Qt::CaseInsensitive ) == 0 )
433         s = '_' + s;
434 
435     /* max path length of Windows API */
436     s = s.left(255);
437 
438     /* whitespace at the end of folder/file names or extensions are bad */
439     len = s.length();
440     if( s[len-1] == ' ' )
441         s[len-1] = '_';
442 
443     int extensionIndex = s.lastIndexOf( '.' ); // correct trailing spaces in file name itself
444     if( ( s.length() > 1 ) &&  ( extensionIndex > 0 ) )
445         if( s.at( extensionIndex - 1 ) == ' ' )
446             s[extensionIndex - 1] = '_';
447 
448     for( int i = 1; i < s.length(); i++ ) // correct trailing whitespace in folder names
449     {
450         if( ( s.at( i ) == QDir::separator() ) && ( s.at( i - 1 ) == ' ' ) )
451             s[i - 1] = '_';
452     }
453 
454     return s;
455 }
456 
ntfsPath(const QString & path)457 QString OutputDirectory::ntfsPath( const QString& path )
458 {
459     QString s = path;
460 
461     if( QDir::separator() == '/' ) // we are on *nix, \ is a valid character in file or directory names, NOT the dir separator
462         s.replace( '\\', '_' );
463     else
464         s.replace( '/', '_' ); // on windows we have to replace / instead
465 
466     for( int i = 0; i < s.length(); i++ )
467     {
468         QChar c = s[ i ];
469         if( c=='*' || c=='?' || c=='<' || c=='>' || c=='|' || c=='"' || c==':' )
470             c = '_';
471         s[ i ] = c;
472     }
473 
474     /* max path length of Windows API */
475     s = s.left(255);
476 
477     return s;
478 }
479 
selectDir()480 void OutputDirectory::selectDir()
481 {
482     QRegExp regEx( "%[abcdfgnpsty]{1,1}", Qt::CaseInsensitive );
483 
484     QString dir = cDir->currentText();
485     QString startDir = dir;
486     QString params;
487     int i = dir.indexOf( regEx );
488     if( i != -1 && cMode->currentIndex() == 0 )
489     {
490         i = dir.lastIndexOf( "/", i );
491         startDir = dir.left( i );
492         params = dir.mid( i );
493     }
494 
495     QString directory = KFileDialog::getExistingDirectory( startDir, this, i18n("Choose an output directory") );
496     if( !directory.isEmpty() )
497     {
498         if( i != -1 && cMode->currentIndex() == 0 )
499         {
500             cDir->setEditText( directory + params );
501         }
502         else
503         {
504             cDir->setEditText( directory );
505         }
506         emit directoryChanged( cDir->currentText() );
507     }
508 }
509 
gotoDir()510 void OutputDirectory::gotoDir()
511 {
512     QRegExp regEx( "%[abcdfgnpsty]{1,1}", Qt::CaseInsensitive );
513 
514     QString startDir = cDir->currentText();
515     int i = startDir.indexOf( regEx );
516     if( i != -1 )
517     {
518         i = startDir.lastIndexOf( "/", i );
519         startDir = startDir.left( i );
520     }
521 
522     QProcess::startDetached( "dolphin", QStringList(startDir) );
523 }
524 
modeChangedSlot(int mode)525 void OutputDirectory::modeChangedSlot( int mode )
526 {
527     config->data.general.lastOutputDirectoryMode = mode;
528 
529     disconnect( cDir, SIGNAL(editTextChanged(const QString&)), 0, 0 );
530 
531     updateMode( (Mode)mode );
532 
533     connect( cDir, SIGNAL(editTextChanged(const QString&)),  this, SLOT(directoryChangedSlot(const QString&)) );
534 
535     emit modeChanged( mode );
536 }
537 
updateMode(Mode mode)538 void OutputDirectory::updateMode( Mode mode )
539 {
540     const int fontHeight = QFontMetrics(QApplication::font()).boundingRect("M").size().height();
541 
542     if( mode == MetaData )
543     {
544         cDir->clear();
545         cDir->addItems( config->data.general.lastMetaDataOutputDirectoryPaths );
546         cDir->setEditText( config->data.general.metaDataOutputDirectory );
547         cDir->setEnabled( true );
548         pDirSelect->setEnabled( true );
549         pDirGoto->setEnabled( true );
550         cMode->setToolTip( i18n("Name all converted files according to the specified pattern") );
551         cDir->setToolTip( i18n("The following strings are wildcards that will be replaced\nby the information in the meta data:\n\n"
552                 "%a - Artist\n%z - Album artist\n%b - Album\n%c - Comment\n%d - Disc number\n%g - Genre\n%n - Track number\n%p - Composer\n%t - Title\n%y - Year\n%f - Original file name\n%s - Path to the source directory\n\n"
553                 "You may parenthesize these wildcards and surrounding characters with squared brackets ('[' and ']')\nso they will be ignored if the replacement value is empty.\n"
554                 "In order to use squared brackets you will have to escape them with a backslash ('\\[' and '\\]').") );
555     }
556     else if( mode == Source )
557     {
558         cDir->clear();
559         cDir->setEditText( "" );
560         cDir->setEnabled( false );
561         pDirSelect->setEnabled( false );
562         pDirGoto->setEnabled( false );
563         cMode->setToolTip( i18n("Output all converted files into the same directory as the original files") );
564         cDir->setToolTip("");
565     }
566     else if( mode == Specify )
567     {
568         cDir->clear();
569         cDir->addItems( config->data.general.lastNormalOutputDirectoryPaths );
570         cDir->setEditText( config->data.general.specifyOutputDirectory );
571         cDir->setEnabled( true );
572         pDirSelect->setEnabled( true );
573         pDirGoto->setEnabled( true );
574         cMode->setToolTip( i18n("Output all converted files into the specified output directory") );
575         cDir->setToolTip("");
576     }
577     else if( mode == CopyStructure )
578     {
579         cDir->clear();
580         cDir->addItems( config->data.general.lastNormalOutputDirectoryPaths );
581         cDir->setEditText( config->data.general.copyStructureOutputDirectory );
582         cDir->setEnabled( true );
583         pDirSelect->setEnabled( true );
584         pDirGoto->setEnabled( true );
585         cMode->setToolTip( i18n("Copy the whole directory structure for all converted files") );
586         cDir->setToolTip("");
587     }
588 
589     // Prevent the directory combo box from beeing too wide because of the directory history
590     cDir->setMinimumWidth( 20*fontHeight );
591     cDir->view()->setMinimumWidth( cDir->view()->sizeHintForColumn(0) );
592 }
593 
directoryChangedSlot(const QString & directory)594 void OutputDirectory::directoryChangedSlot( const QString& directory )
595 {
596     Mode mode = (Mode)cMode->currentIndex();
597 
598     if( mode == MetaData )
599         config->data.general.metaDataOutputDirectory = directory;
600     else if( mode == Specify )
601         config->data.general.specifyOutputDirectory = directory;
602     else if( mode == CopyStructure )
603         config->data.general.copyStructureOutputDirectory = directory;
604 
605     emit directoryChanged( directory );
606 }
607 
608 /*void OutputDirectory::modeInfo()
609 {
610     int mode = cMode->currentItem();
611     QString sModeString = cMode->currentText();
612 
613     if( (Mode)mode == Default ) {
614         KMessageBox::information( this,
615             i18n("This will output each file into the soundKonverter default directory."),
616             QString(i18n("Mode")+": ").append(sModeString) );
617     }
618     else if( (Mode)mode == Source ) {
619         KMessageBox::information( this,
620             i18n("This will output each file into the same directory as the original file."),
621             QString(i18n("Mode")+": ").append(sModeString) );
622     }
623     else if( (Mode)mode == Specify ) {
624         KMessageBox::information( this,
625             i18n("This will output each file into the directory specified in the editbox behind."),
626             QString(i18n("Mode")+": ").append(sModeString) );
627     }
628     else if( (Mode)mode == MetaData ) {
629         KMessageBox::information( this,
630             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."),
631             QString(i18n("Mode")+": ").append(sModeString) );
632     }
633     else if( (Mode)mode == CopyStructure ) {
634         KMessageBox::information( this,
635             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."),
636             QString(i18n("Mode")+": ").append(sModeString) );
637     }
638     else {
639         KMessageBox::error( this,
640             i18n("This mode (%s) doesn't exist.", sModeString),
641             QString(i18n("Mode")+": ").append(sModeString) );
642     }
643 }*/
644 
645