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