diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-22 18:35:24 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-22 18:35:24 +0000 |
commit | aec5a842670a66ff24572847d35375a31c0b379e (patch) | |
tree | 465d7790602658d86ab031788852bf3dbdc96691 /krename/batchrenamer.cpp | |
download | krename-aec5a842670a66ff24572847d35375a31c0b379e.tar.gz krename-aec5a842670a66ff24572847d35375a31c0b379e.zip |
Added KDE3 version of krename
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/krename@1094420 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'krename/batchrenamer.cpp')
-rw-r--r-- | krename/batchrenamer.cpp | 950 |
1 files changed, 950 insertions, 0 deletions
diff --git a/krename/batchrenamer.cpp b/krename/batchrenamer.cpp new file mode 100644 index 0000000..89721e0 --- /dev/null +++ b/krename/batchrenamer.cpp @@ -0,0 +1,950 @@ +/*************************************************************************** + batchrenamer.cpp - description + ------------------- + begin : Sat Aug 18 2001 + copyright : (C) 2001 by Dominik Seichter + email : domseichter@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef VERSION + #define VERSION "unknown" +#endif + +// OS includes +#include <stdio.h> +#include <pwd.h> +#include <grp.h> +#include <unistd.h> +// chmod: +#include <sys/types.h> +#include <sys/stat.h> + +// QT includes +#include <qdir.h> +#include <qregexp.h> + +// KDE includes +#include <kapplication.h> +#include <kio/job.h> +#include <kio/netaccess.h> +#include <klocale.h> + +// Own includes +#include "ProgressDialog.h" +#include "batchrenamer.h" +#include "fileoperation.h" +#include "pluginloader.h" +#include "kmylistview.h" + +using namespace KIO; + +BatchRenamer::BatchRenamer() + : m_index( 0 ) +{ + plug = PluginLoader::instance(); + m_counter_index = 0; +} + +BatchRenamer::~BatchRenamer() +{ +} + +void BatchRenamer::processFiles( ProgressDialog* p, QObject* object ) +{ + delete object; + t.start(); + + m_counters.clear(); + + for( unsigned int i = 0; i < m_files.count(); i++) + { + m_counter_index = 0; + + if( m_mode == RENAME ) {// final Path = source Path + m_files[i].dst.directory = m_files[i].src.directory; + m_files[i].dst.url = m_files[i].src.url; + m_files[i].dst.url.setFileName( QString::null ); + } else { + m_files[i].dst.directory = dirname.path(); + m_files[i].dst.url = dirname; + } + + if( i == 0 ) + p->setDestination( m_files[i].dst.url ); + else + { + if( m_reset ) + findCounterReset( i ); + } + + m_files[i].dst.name = processString( text, m_files[i].src.name, i ); + if( !extext.isEmpty() ) + m_files[i].dst.extension = processString( extext, m_files[i].src.extension, i ); + + (void)applyManualChanges( i ); + + // Assemble filenames + parseSubdirs( &m_files[i] ); + // TODO: DOM + // ESCAPE HERE + + m_files[i].src.name = BatchRenamer::buildFilename( &m_files[i].src, true ); + + // Let's run the plugins that change the final filename, + // i.e the encodingsplugin + m_files[i].dst.name = parsePlugins( i, m_files[i].dst.name, TYPE_FINAL_FILENAME ); + + m_files[i].dst.name = BatchRenamer::buildFilename( &m_files[i].dst, true ); + + /* + * take care of renamed directories and + * correct the paths of their contents + */ + if( m_files[i].dir && (m_mode == RENAME || m_mode == MOVE) ) { + for( unsigned int c = i; c < m_files.count(); c++ ) { + if( m_files[c].src.directory.left( m_files[i].src.name.length() + 1 ) + == ( m_files[i].src.name + "/" ) ) { + + m_files[c].src.directory.replace( 0, m_files[i].src.name.length(), m_files[i].dst.name ); + m_files[c].src.url.setPath( BatchRenamer::buildFilename( &m_files[c].src, true ) ); + } + } + } + } + + p->print( QString( i18n("Filenames Processed after %1 seconds.")).arg(t.elapsed()/1000) ); + + work( p ); +} + +QString BatchRenamer::processString( QString text, QString oldname, int i ) +{ + /* + * Come on! Grep for this text and help me! + * + * note about krename escape sequences + * for certain characters: + * + * Krename will have problems with files + * which contain one of the following + * unicode characters: 60000, 60001, 60002 + * 60003, 60004, 60005, 60006. + * + * This is not a good solution, if you have a + * better one please tell me about it! + */ + + doEscape( oldname ); + /* + * Call here all functions that handle + * arguments that are single tokens (&,%,...). + * or in [brackets] + */ + text = findBrackets( oldname, text, i ); + text = findAndProcess( "$", text, oldname ); + text = findAndProcess( "%", text, oldname.lower() ); + text = findAndProcess( "&", text, oldname.upper() ); + text = findAndProcess( "\\", text, oldname.stripWhiteSpace() ); + text = findStar( oldname, text ); + text = findNumbers( text, m_files.count(), i ); + /* + * text is used as argument token for plugins! + */ + text = parsePlugins( i, text, TYPE_TOKEN ); + /* + * Replace after Plugins ! + * Replace shoud be the last the + * before re-escaping tokens ! + */ + text = findReplace( text ); + + // convert special chars back (e.g. &,$) + // TODO: this is to early, because + // parseSubdirs creates subdirectories + // for "/" returned by plugins!!!! + // text = unEscape( text ); + + return text; +} + +QString BatchRenamer::parsePlugins( int i, const QString& text, int type ) +{ + QPtrListIterator<PluginLoader::PluginLibrary> it( plug->libs ); + QString ret = text; + + if( type == TYPE_FINAL_FILE ) + ret = ""; + + for( ; it.current(); ++it ) + if( (*it)->usePlugin && (*it)->plugin->type() == type ) + { + ret = (*it)->plugin->processFile( this, i, text, type ); + doEscape( ret ); + } + + return ret; +} + +void BatchRenamer::createPreview( QListView* list ) +{ + KMyListViewItem* item1 = NULL; + QString tmp; + + m_counters.clear(); + for( unsigned int i = 0; i < m_files.count(); i++) + { + m_counter_index = 0; + + if( i && m_reset ) + findCounterReset( i ); + + m_files[i].dst.name = processString( text, m_files[i].src.name, i ); + if( !extext.isEmpty() ) + m_files[i].dst.extension = processString( extext, m_files[i].src.extension, i ); + + bool modified = applyManualChanges( i ); + + + QString sname = BatchRenamer::buildFilename( &m_files[i].src, false ); + + // Let's run the plugins that change the final filename, + // i.e the encodingsplugin + m_files[i].dst.name = parsePlugins( i, m_files[i].dst.name, TYPE_FINAL_FILENAME ); + QString dname = BatchRenamer::buildFilename( &m_files[i].dst, false ); + + item1 = new KMyListViewItem( modified, list, item1, sname, dname ); + } +} + +void BatchRenamer::work( ProgressDialog* p ) +{ + // TODO: use CopyJob here + + FileOperation fop; + QFile* fundo ( NULL ); + QTextStream* tundo ( NULL ); + + if( undo ) { + // Create header for undo script + fundo = new QFile( m_undoScript ); + if( fundo->open( IO_WriteOnly ) ) { + tundo = new QTextStream( fundo ); + writeUndoScript( tundo ); + } else { + undo = false; + p->error( i18n("Can't create undo script :") + fundo->name() ); + delete fundo; + } + } + + int error = 0; + RenamedList* renamedFiles = new RenamedList[m_files.count()]; + p->setProgressTotalSteps( m_files.count() + 1 ); + + /* + * Give the user some information... + */ + if( m_mode == COPY) + p->print( QString( i18n("Files will be copied to: %1") ).arg(m_files[0].dst.directory) ); + else if( m_mode == MOVE ) + p->print( QString( i18n("Files will be moved to: %1") ).arg(m_files[0].dst.directory) ); + else if( m_mode == LINK ) + p->print( QString( i18n("Symbolic links will be created in: %1") ).arg(m_files[0].dst.directory) ); + else if( m_mode == RENAME ) + p->print( i18n("Input files will be renamed.") ); + + unsigned int i; + for( i = 0; i < m_files.count(); i++) { + p->setProgress( i+1 ); + + if( p->wasCancelled() ) + break; + + KURL src = m_files[i].src.url; + KURL dst = m_files[i].dst.url; + dst.setPath( m_files[i].dst.name ); + + renamedFiles[i].src = src; + renamedFiles[i].dst = dst; + renamedFiles[i].dir = m_files[i].dir; + + FileOperation fop; + if( !fop.start( src, dst, m_mode, overwrite ) ) { + p->error( fop.error() ); + renamedFiles[i].error = true; + error++; + continue; + } else { + renamedFiles[i].error = false; + } + + // TODO: overwriting of files! + /* + * The renamed file should be on its correct location now, + * so that we can call the last plugins (e.g. for changing permissions) + * + * Remember, the token argument is the filename for this type of plugins! + * + * If the return value is not empty an error has occured! + * The plugin should return an error message in this case! + */ + + QString eplug = parsePlugins( i, QString::null, TYPE_FINAL_FILE ); + if( !eplug.isEmpty() ) { + p->error( eplug ); + error++; + } + + /* Create the undo script now */ + if( undo ) + if( dst.isLocalFile() && src.isLocalFile() ) { + // Plugins ??? + (*tundo) << "echo \"" << src.fileName() + << " -> " << dst.fileName() << "\"" << endl; + (*tundo) << "mv --force -b --suffix=.krename_ \"" << m_files[i].dst.name + << "\" \"" << m_files[i].src.name << "\"" << endl; + } else + p->warning( QString( i18n("Undo is not possible for remote file: %1") ).arg( dst.prettyURL() ) ); + + } + + if( !p->wasCancelled() ) { + QPtrListIterator<PluginLoader::PluginLibrary> it( plug->libs ); + for( ; it.current(); ++it ) { + if( (*it)->usePlugin ) + (*it)->plugin->finished(); + } + } + + const QString m = QString( i18n("Renamed %1 files successfully.") ).arg(i-error); + ( i - error ) ? p->print( m ) : p->warning( m ); + + if( error > 0 ) + p->warning( QString( i18n("%2 errors occurred!") ).arg(error)); + + p->print( QString( i18n("Elapsed time: %1 seconds") ).arg( t.elapsed()/1000 ), "kalarm" ); + p->print( i18n("KRename finished the renaming process."), "krename" ); + p->print( i18n("Press close to quit!") ); + p->setRenamedFiles( renamedFiles, m_files.count() ); + + if( undo ) { + (*tundo) << endl << "echo \"Finished undoing " << m_files.count() << " actions.\"" << endl; + delete tundo; + fundo->close(); + + // Make fundo exuteable + if( chmod( (const char*)m_undoScript, (unsigned int) S_IRUSR | S_IWUSR | S_IXUSR ) ) + p->error( i18n("Can't set executable bit on undo script.") ); + delete fundo; + } + + p->done( error, i-error, m_mode == MOVE || m_mode == RENAME ); + m_files.clear(); + delete this; +} + +void BatchRenamer::escape( QString & text, const QString & token, const QString & sequence ) +{ + /* + * NEVER, ABSOLUTELY NEVER change pos = 0 + * to pos = -1, it won't work ! + * This bug took hours to find and was + * a serious bug in 1.7. + */ +#if QT_VERSION >= 0x030100 + text.replace( token, sequence ); +#else + int pos = 0; + do { + pos = text.find( token, pos ); + if( pos >= 0 ) + text.replace( pos, token.length(), sequence ); + } while ( pos >= 0 ); +#endif +} + +QString & BatchRenamer::doEscape( QString & text, bool filename ) +{ + if( filename ) { + BatchRenamer::escape( text, "&", QChar( 60000 ) ); + BatchRenamer::escape( text, "$", QChar( 60001 ) ); + BatchRenamer::escape( text, "%", QChar( 60002 ) ); + BatchRenamer::escape( text, "#", QChar( 60004 ) ); + BatchRenamer::escape( text, "[", QChar( 60005 ) ); + BatchRenamer::escape( text, "]", QChar( 60006 ) ); + BatchRenamer::escape( text, "\\", QChar( 60007 ) ); + BatchRenamer::escape( text, "/", QChar( 60008 ) ); + BatchRenamer::escape( text, "{", QChar( 60009 ) ); + BatchRenamer::escape( text, "}", QChar( 60010 ) ); + BatchRenamer::escape( text, "*", QChar( 60011 ) ); + } else { + BatchRenamer::escape( text, "\\&", QChar( 60000 ) ); + BatchRenamer::escape( text, "\\$", QChar( 60001 ) ); + BatchRenamer::escape( text, "\\%", QChar( 60002 ) ); + BatchRenamer::escape( text, "\\#", QChar( 60004 ) ); + BatchRenamer::escape( text, "\\[", QChar( 60005 ) ); + BatchRenamer::escape( text, "\\]", QChar( 60006 ) ); + BatchRenamer::escape( text, "\\\\", QChar( 60007 ) ); + BatchRenamer::escape( text, "\\/", QChar( 60008 ) ); + BatchRenamer::escape( text, "\\{", QChar( 60009 ) ); + BatchRenamer::escape( text, "\\}", QChar( 60010 ) ); + BatchRenamer::escape( text, "\\*", QChar( 60011 ) ); + } + + return text; +} + +QString & BatchRenamer::unEscape( QString & text ) +{ + BatchRenamer::escape( text, QChar( 60000 ), "&" ); + BatchRenamer::escape( text, QChar( 60001 ), "$" ); + BatchRenamer::escape( text, QChar( 60002 ), "%" ); + BatchRenamer::escape( text, QChar( 60004 ), "#" ); + BatchRenamer::escape( text, QChar( 60005 ), "[" ); + BatchRenamer::escape( text, QChar( 60006 ), "]" ); + BatchRenamer::escape( text, QChar( 60007 ), "\\" ); + // %252f == /, it seems that filenames on unix cannot contain + // a /. So I use %252f, at least konqui displays it correctly + // this was needed, so that plugins that return a slash do not cause errors + BatchRenamer::escape( text, QChar( 60008 ), "%2f" ); + BatchRenamer::escape( text, QChar( 60009 ), "{" ); + BatchRenamer::escape( text, QChar( 60010 ), "}" ); + BatchRenamer::escape( text, QChar( 60011 ), "*" ); + + return text; +} + +int BatchRenamer::getCharacters( int n ) +{ + QString s; + s.sprintf( "%i", n ); + return s.length(); +} + +QString BatchRenamer::findAndProcess( const QString & token, QString text, const QString & replace ) +{ + /* + * pos can here be -1 because + * findRev is called with it as a + * value ! + */ +#if QT_VERSION >= 0x030100 + text.replace( token, replace ); +#else + int pos = -1; + do { + pos = text.findRev( token, pos ); + if( pos >= 0 ) + text.replace( pos, token.length(), replace ); + } while( pos >= 0 ); +#endif + return text; +} + +QString BatchRenamer::findNumbers( QString text, int count, int i ) +{ + // Rewritten in Version 0.8 + // Added numbers skipping in 1.3 + // Changed again in Version 1.8 to optimize it and fix a bug with skipping numbers + int pos = 0, counter = 1; + tCounterValues countervalues; + countervalues.start = m_index; + countervalues.step = m_step; + + if( text.contains( "#", FALSE ) <= 0 ) + return text; + + pos = text.find("#", pos); + pos++; + while( text[pos] == '#' ) { + text.remove(pos, 1); + counter++; + } + + findNumberAppendix( text, pos, &countervalues.start, &countervalues.step ); + + pos = text.find("#", 0); + + if( (signed int)m_counters.count() <= m_counter_index ) + { + countervalues.value = countervalues.start - countervalues.step; + // other wise the counter would start at: + // start + step instead of start + m_counters.append( countervalues ); + } + + do { + m_counters[m_counter_index].value += m_counters[m_counter_index].step; + } while( m_skip.contains( m_counters[m_counter_index].value ) ); + + /* + int v = start + (i*step) + m_skip_add[m_counter_index]; + for( unsigned int z = 0; z < m_skip.count(); z++ ) { + if( m_skip[z] == v ) { + m_skip_add[m_counter_index] += step; + v += step; + } + } + */ + + QString temp; + temp.sprintf("%0*i", counter, m_counters[m_counter_index].value ); + text.replace( pos, 1, temp); + + ++m_counter_index; + return findNumbers( text, count, i ); +} + +void BatchRenamer::findNumberAppendix( QString & text, int pos, int* start, int* step ) +{ + QString appendix = QString::null; + int tmp = 0; + int end = 0; + bool ok = false; + + if( text[pos] == '{' && (end = text.find( "}", pos )) > -1) + { + //qDebug("Found an appendix:" + appendix ); + appendix = text.mid( pos + 1, end - pos - 1); + text.remove( pos, end - pos + 1 ); + + tmp = appendix.section( ';', 0, 0 ).toInt( &ok ); // first section = start index + if( ok ) + *start = tmp; + + tmp = appendix.section( ';', 1, 1 ).toInt( &ok ); // second section = stepping + if( ok ) + *step = tmp; + } +} + +QString BatchRenamer::findStar( const QString & oldname, QString text ) +{ + int pos = -1; + do { + pos = text.findRev("*", pos); + if( pos >= 0 ) { + QString tmp = oldname.lower(); + if( tmp[0].isLetter() ) + tmp[0] = tmp[0].upper(); + + for( unsigned int i = 0; i < tmp.length(); i++ ) + if( tmp[i+1].isLetter() && !tmp[i].isLetter() && + tmp[i] != '\'' && tmp[i] != '?' && tmp[i] != '`' ) + tmp[i+1] = tmp[i+1].upper(); + + text.replace( pos, 1, tmp); + } + } while( pos >= 0 ); + return text; +} + +QString BatchRenamer::findBrackets( QString oldname, QString text, int i ) +{ + /* + * looks for a statement in brackets [ ] + * and calls findToken() with this statement. + */ + + int num, pos = -1, a; + QString token; + + if( text.contains("]", FALSE) <= 0 || text.isEmpty() ) + return text; + + num = text.contains("[", FALSE); + if(num <= 0 ) + return text; + + pos = text.findRev("[", pos); + a = text.find("]", pos ); + if( a < 0 && pos >= 0 ) + return text; + + if( pos < 0 && a >= 0 ) + return text; + + if( pos >= 0 && a >= 0 ) { + token = text.mid( pos+1, (a-pos)-1 ); + + // support [4-[length]] + token = findBrackets( oldname, token, i ); + + text.remove( pos, (a-pos)+1 ); + text.insert( pos, findToken( oldname, token, i )); + } + return findBrackets( oldname, text, i ); +} + +QString BatchRenamer::processToken( QString token, QString oldname, int i ) +{ + QString tmp; + + /* + * Call here all functions that handle + * arguments in brackets. + */ + tmp = findPartStrings( oldname, token ); + if( !tmp.isEmpty() ) + return tmp; + + tmp = findDirName( token, m_files[i].src.directory ); + if( !tmp.isEmpty() ) + return tmp; + + tmp = findLength( token, m_files[i].src.name ); + if( !tmp.isEmpty() ) + return tmp; + + Plugin* p = plug->findPlugin( token ); + if( p ) + { + tmp = p->processFile( this, i, token, TYPE_BRACKET ); + if( !tmp.isNull() ) + { + doEscape( tmp ); + return tmp; + } + } + + /* + * Maybe I should remove this! + * Krename simply ignores unknown tokens! + * Usefull for the MP3 Plugin! + */ + return QString::null; +} + +QString BatchRenamer::findToken( QString oldname, QString token, int i ) +{ + enum conversion { LOWER, UPPER, MIXED, STAR, STRIP, NONE, EMPTY, NUMBER }; + unsigned int numwidth = 0; + + conversion c = EMPTY; + if( !token.left(1).compare("$") ) + c = NONE; + else if( !token.left(1).compare("%") ) + c = LOWER; + else if( !token.left(1).compare("&") ) + c = UPPER; + else if( !token.left(1).compare("") ) + c = MIXED; + else if( !token.left(1).compare("*") ) + c = STAR; + else if( !token.left(1).compare("\\") ) + c = STRIP; + else if( !token.left(1).compare("#") ) { + while( !token.left(1).compare("#") ) { + token.remove( 0, 1 ); + ++numwidth; + } + + c = NUMBER; + } + + if( c != EMPTY && c != NUMBER ) + token.remove( 0, 1 ); + + QString save = token; + token = processToken( token, oldname, i ); + + switch( c ) { + case LOWER: + token = token.lower(); + break; + case UPPER: + token = token.upper(); + break; + case MIXED: + token = token.lower(); + token.replace( 0, 1, token[0].upper()); + break; + case STAR: + token = findStar( token, "*" ); + break; + case STRIP: + token = token.stripWhiteSpace(); + break; + case NUMBER: + { + bool b = false; + int n = token.toInt( &b ); + if( b ) + token = token.sprintf("%0*i", numwidth, n ); + } + break; + default: + break; + } + + doEscape( token ); + return token; +} + +QString BatchRenamer::findPartStrings( QString oldname, QString token ) +{ + QString first, second; + int pos = -1; + + // parse things like [2;4{[dirname]}] + if( token.contains( "{" ) >= 1 && token.contains( "}" ) >= 1 ) { + int pos = token.find( "{" ); + oldname = token.mid( pos + 1, token.findRev( "}" ) - pos - 1 ); + token = token.left( pos ); + } + + if( token.contains("-") ) { + pos = token.find( "-", 0 ); + first = token.left( pos ); + // ------- Code OK ^ ! + + second = token.mid( pos+1, token.length() ); + + // version < 1.7 + // return oldname.mid( first.toInt()-1, second.toInt()-first.toInt() +1 ); + // version > 1.7 + //return oldname.mid( first.toInt()-1, second.toInt()-first.toInt() ); + // version > 1.8 + + bool ok; + int sec = second.toInt( &ok ); + if( !ok || sec == 0 ) + sec = oldname.length(); + + /* + * x should not be larger than the old name + * and not smaller than zero. + */ + int x = sec-first.toInt(); + if( x > (signed int)oldname.length() || x < 0 ) + x = oldname.length()-first.toInt(); + + /* + * if I would comment my code I would understand this line :) + * without this line, there is sometimes the last letter + * of a filename missing. + */ + if( x != -1 ) + x++; + + return oldname.mid( first.toInt()-1, x ); + } else if( token.contains(";") ) { + pos = token.find( ";", 0 ); + + first = token.left( pos ); + second = token.mid( pos+1, token.length() ); + + return oldname.mid( first.toInt()-1, second.toInt() ); + } else { + bool ok = false; + int number = token.toInt( &ok ); + + if( ok && (number <= (signed int)oldname.length() && number > 0 ) ) + return QString(oldname[ number -1 ]); + else + return QString::null; + } +} + +QString BatchRenamer::findDirName( QString token, QString path ) +{ + if( token.left( 7 ).lower() == "dirname" ) { + if( path.right( 1 ) == "/" ) + path = path.left( path.length() - 1); + + int recursion = 1; + if( token.length() > 7 ) { + token = token.right( token.length() - 7 ); + recursion = token.contains( "." ); + if( recursion != (signed int)token.length() ) + return QString::null; + + recursion++; + } + + return path.section( "/", recursion * -1, recursion * -1); + } + + return QString::null; +} + +QString BatchRenamer::findLength( const QString & token, const QString & name ) +{ + if( token.lower().startsWith( "length" ) ) { + int minus = 0; + if( token[6] == '-' ) { + bool n = false; + minus = token.mid( 7, token.length() - 7 ).toInt( &n ); + if( !n ) + minus = 0; + } + + return QString::number( name.length() - minus ); + } + + return QString::null; +} + +QString BatchRenamer::findReplace( QString text ) +{ + // Call for each element in replace strings doReplace with correct values + for( unsigned int i = 0; i < m_replace.count(); i++ ) { + replacestrings s = m_replace[i]; + text = doReplace( text, unEscape( s.find ), s.replace, s.reg ); + } + + return text; +} + +QString BatchRenamer::doReplace( QString text, QString find, QString replace, bool reg ) +{ + if( !reg ) + { +#if QT_VERSION >= 0x030100 + // we use the escaped text here because the user might want + // to find a "&" and replace it + text.replace( doEscape( find ), replace ); +#else + int pos = 0; + QString f = doEscape( find ); + do { + + pos = text.find( f, pos ); + if( pos >= 0 ) { + text.replace( pos, f.length(), replace ); + pos += replace.length(); + } + } while( pos >= 0 ); +#endif + } + else + { +#if QT_VERSION >= 0x030100 + // no doEscape() here for the regexp, because it would destroy our regular expression + // other wise we will not find stuff like $, [ in the text + text = doEscape( unEscape( text ).replace( QRegExp( find ), replace ) ); +#else + // Test this code more! + pos = 0; + do { + QRegExp exp( find ); + pos = exp.search( text, pos ); + if( pos >= 0 ) { + text = doEscape( unEscape( text ).replace( pos, exp.matchedLength(), replace ) ); + pos += replace.length(); + } + } while( pos >= 0 ); +#endif + } + return text; +} + +void BatchRenamer::writeUndoScript( QTextStream* t ) +{ + // write header comments + (*t) << "#!/bin/bash" << endl + << "# KRename Undo Script" << endl << "#" << endl + << "# KRename was written by:" << endl + << "# Dominik Seichter <domseichter@web.de>" << endl + << "# http://krename.sourceforge.net" << endl << "#" << endl + << "# Script generated by KRename Version: " << VERSION << endl << endl + << "# This script must be started with the option --krename to work!" << endl; + + // write functions: + (*t) << "echo \"KRename Undo Script\"" << endl + << "echo \"http://krename.sourceforge.net\"" << endl + << "echo \"\"" << endl; + + (*t) << "if test --krename = $1 ; then" << endl + << " echo \"\"" << endl + << "else" << endl + << " echo \"You have to start this script\"" << endl + << " echo \"with the command line option\"" << endl + << " echo \"--krename\"" << endl + << " echo \"to undo a rename operation.\"" << endl + << " exit" << endl + << "fi" << endl; +} + +void BatchRenamer::parseSubdirs( data* f ) +{ + int pos = 0; + if( (pos = f->dst.name.findRev( "/", -1 ) ) > 0 ) { + QString dirs = f->dst.name.left( pos ); + f->dst.name = f->dst.name.right( f->dst.name.length() - pos - 1 ); + f->dst.directory += ( f->dst.directory.right( 1 ) == "/" ) ? "" : "/"; + + // create the missing subdir now + int i = 0; + QString d = ""; + while( (d = dirs.section( "/", i, i, QString::SectionSkipEmpty )) && ! d.isEmpty() ) { // asignment here! + KURL url = f->dst.url; + // it is important to unescape here + // to support dirnames containing "&" or + // similar tokens + url.addPath( unEscape( d ) ); + if( !NetAccess::exists( url ) && !NetAccess::mkdir( url ) ) + // TODO: GUI bug report + qDebug("Can't create %s", url.prettyURL().latin1() ); + + f->dst.url.addPath( d ); + f->dst.directory.append( d + "/" ); + i++; + } + } +} + +QString BatchRenamer::buildFilename( fileentry* entry, bool dir ) +{ + QString filename = ( dir ? entry->directory : QString::null ) + entry->name + ( entry->extension.isEmpty() ? QString::null : QString(".") ) + entry->extension; + // unescape here as filename is still escaped + unEscape( filename ); + return filename; +} + +bool BatchRenamer::applyManualChanges( int i ) +{ + /* + * The last step: make changes of + * the user visible + */ + + if( !m_changes.isEmpty() ) + for( unsigned int z = 0; z < m_changes.count(); z++ ) { + KURL file = m_changes[z].url; + if( file == m_files[i].src.url ) { + m_files[i].dst.name = m_changes[z].user; + // the file extension is already included + // in the users name + m_files[i].dst.extension = QString::null; + return true; + } + } + + return false; +} + +void BatchRenamer::findCounterReset( int i ) +{ + int z; + if( m_files[i-1].src.directory != m_files[i].src.directory ) + for( z=0;z<(int)m_counters.count();z++ ) + { + m_counters[z].value = m_counters[z].start - m_counters[z].step; + } +} + + |