File indexing completed on 2024-12-01 13:50:22
0001 /*************************************************************************** 0002 batchrenamer.h - description 0003 ------------------- 0004 begin : Sat Aug 18 2001 0005 copyright : (C) 2001 by Dominik Seichter 0006 email : domseichter@web.de 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This program is free software; you can redistribute it and/or modify * 0012 * it under the terms of the GNU General Public License as published by * 0013 * the Free Software Foundation; either version 2 of the License, or * 0014 * (at your option) any later version. * 0015 * * 0016 ***************************************************************************/ 0017 0018 #ifndef BATCHRENAMER_H 0019 #define BATCHRENAMER_H 0020 0021 #include <QList> 0022 #include <QObject> 0023 0024 #include "krenamefile.h" 0025 0026 class QFile; 0027 class QProgressDialog; 0028 class QString; 0029 class QTextStream; 0030 0031 typedef struct __tag_tCounterValues { 0032 int value; // current value of this counter 0033 int start; // start value of this counter (for findResetCounter) 0034 int step; // stepping value of this counter; 0035 } tCounterValues; 0036 0037 /** A structure describing a string or regular 0038 * expression that is to be found in the final/resulting 0039 * filename and to be replaced with another string. 0040 */ 0041 typedef struct __tag_TReplaceItem { 0042 QString find; ///< Text to replace 0043 QString replace; ///< Replace with 0044 bool reg; ///< is it a reg expression ? 0045 bool doProcessTokens; ///< Process tokens in result 0046 } TReplaceItem; 0047 0048 /** An enum to set the renaming mode of KRename 0049 */ 0050 enum ERenameMode { 0051 eRenameMode_Rename, ///< All files are renamed in place 0052 eRenameMode_Move, ///< All files are moved to a new directory and renamed 0053 eRenameMode_Copy, ///< Only copies of the files are renamed 0054 eRenameMode_Link ///< Symbolic links are created and renamed 0055 }; 0056 0057 class QObject; 0058 class ProgressDialog; 0059 0060 /** This is the core class for renaming. 0061 * 0062 * It transforms the filenames according to 0063 * the users settings using custom functions 0064 * and external plugins. 0065 * Also the actual renaming, copying or moving 0066 * of the files is done by this class 0067 * 0068 * @author Dominik Seichter 0069 */ 0070 class BatchRenamer : public QObject 0071 { 0072 Q_OBJECT 0073 0074 public: 0075 BatchRenamer(); 0076 ~BatchRenamer(); 0077 0078 /** Sets the list of files 0079 * which contains all filenames which should be transformed. 0080 * 0081 * The renamed filenames are stored in this list, too,. 0082 * 0083 * @param list a list of KRenameFile objects 0084 */ 0085 inline void setFiles(KRenameFile::List *list); 0086 0087 /** Get access to the list of files used for renaming. 0088 * @returns the list of files or NULL if none was set. 0089 */ 0090 inline const KRenameFile::List *files() const; 0091 0092 /** 0093 * @returns the current renaming mode 0094 */ 0095 inline ERenameMode renameMode() const; 0096 0097 /** 0098 * @returns the current start index for counters 0099 */ 0100 inline int numberStartIndex() const; 0101 0102 /** 0103 * @returns the stepping for counters 0104 */ 0105 inline int numberStepping() const; 0106 0107 /** 0108 * @returns if counters are reset on new directories 0109 */ 0110 inline int numberReset() const; 0111 0112 /** 0113 * @returns the list of numbers that are skipped during renaming 0114 */ 0115 inline QList<int> numberSkipList() const; 0116 0117 /** Does the actuall renaming, 0118 * transforming all source filenames in the file list 0119 * to the new destination filenames. 0120 * 0121 * No actuall renaming is done, only the new filenames 0122 * are calculated. 0123 */ 0124 void processFilenames(); 0125 0126 /** Process all files 0127 * 0128 * processFilenames has to be called before 0129 * 0130 * All files will be renamed according to the users settings. 0131 * 0132 * Output will be reported through a progress dialog 0133 * 0134 * @param p use this dialog to report progress to the user 0135 */ 0136 void processFiles(ProgressDialog *p); 0137 0138 /** undo all files 0139 * 0140 * processFiles has to be called before 0141 * 0142 * A previous renaming operation will be undone. 0143 * 0144 * Output will be reported through a progress dialog 0145 * 0146 * @param p use this dialog to report progress to the user 0147 */ 0148 void undoFiles(ProgressDialog *p); 0149 0150 /** Build the destination url from a KRenameFile 0151 * 0152 * @param file a KRenameFile 0153 * @returns a valid QUrl 0154 */ 0155 const QUrl buildDestinationUrl(const KRenameFile &file) const; 0156 0157 inline void setUndoScript(const QString &t) 0158 { 0159 m_undoScript = t; 0160 } 0161 inline void setUndo(bool b) 0162 { 0163 undo = b; 0164 } 0165 0166 inline void setReplaceList(const QList<TReplaceItem> &r) 0167 { 0168 m_replace = r; 0169 } 0170 inline const QList<TReplaceItem> &replaceList() const 0171 { 0172 return m_replace; 0173 } 0174 0175 inline void setMode(int m) 0176 { 0177 m_mode = m; 0178 } 0179 inline int mode() const 0180 { 0181 return m_mode; 0182 } 0183 0184 QString findToken(const QString &oldname, QString token, int i); 0185 QString findPartStrings(QString oldname, QString token); 0186 static QString findDirName(QString token, QString path); 0187 0188 /** 0189 * Replace the token [dirsep] with a slash "/". 0190 * This token is useful to create directories from within regular expressions. 0191 */ 0192 static QString findDirSep(const QString &token, const QString &path); 0193 0194 static QString &doEscape(QString &text); 0195 static QString &unEscape(QString &text); 0196 static void escape(QString &text, const QString &token, const QString &sequence); 0197 0198 /** Capitalize a string. 0199 * 0200 * Used to implement the * token. 0201 * 0202 * @param a text string 0203 * @return a capitalized version of this string (every first letter is a capital letter now) 0204 */ 0205 QString capitalize(const QString &text) const; 0206 0207 /** Handle the [length] tokens 0208 * 0209 * @param token a token found in square brackets 0210 * @param name the filename of the current file 0211 * 0212 * @return QString::null if no length token was found or the a new string 0213 */ 0214 QString findLength(const QString &token, const QString &name); 0215 0216 /** Handle the [trimmed] token 0217 * 0218 * @param token a token found in square brackets 0219 * @param name the filename of the current file 0220 * @param index index of the current file 0221 * 0222 * @return QString::null if no length token was found or the a new string 0223 */ 0224 QString findTrimmed(const QString &token, const QString &name, int index); 0225 0226 QString processString(QString text, const QString &originalName, int i, bool doFindReplace = true); 0227 QString processBrackets(QString text, int *length, const QString &oldname, int index); 0228 QString processNumber(int length, const QString &appendix); 0229 QString processToken(QString token, QString oldname, int i); 0230 0231 public Q_SLOTS: 0232 0233 /** Sets the current mode of renaming. 0234 * KRename can rename files, move them while 0235 * renaming to another directory, rename copies 0236 * or create renamed sym-links. 0237 * 0238 * This mode specifies what should be done with the files. 0239 * 0240 * @param mode the renaming mode. 0241 */ 0242 inline void setRenameMode(ERenameMode mode); 0243 0244 /** Sets the template for the filename that is used 0245 * to transform the filename to its final representation. 0246 * 0247 * @param t the new template 0248 */ 0249 inline void setFilenameTemplate(const QString &t); 0250 0251 /** Sets the template for the filename that is used 0252 * to transform the filename to its final representation. 0253 * 0254 * @param t the new template 0255 */ 0256 inline void setExtensionTemplate(const QString &t); 0257 0258 /** Set the start index for the basic counters 0259 * which do not specify an own start index in their 0260 * appendiy (e.g. ###{7}, means 7 is the start index 0261 * 0262 * @param i start index 0263 */ 0264 inline void setNumberStartIndex(int i) 0265 { 0266 m_index = i; 0267 } 0268 0269 /** Set the stepping for the basic counters 0270 * which do not specify an own stepping in their 0271 * appendiy (e.g. ###{1,2}, means 2 is the stepping 0272 * 0273 * @param s stepping 0274 */ 0275 inline void setNumberStepping(int s) 0276 { 0277 m_step = s; 0278 } 0279 0280 /** Sets whether all counters should be reset for new 0281 * directories 0282 * 0283 * @param r if true counters will be reset 0284 */ 0285 inline void setNumberReset(bool r) 0286 { 0287 m_reset = r; 0288 } 0289 0290 /** Sets the list of numbers that are skipped by counters 0291 * 0292 * @param s a list of numbers that is skipped 0293 */ 0294 inline void setNumberSkipList(const QList<int> &s) 0295 { 0296 m_skip = s; 0297 } 0298 0299 /** Sets if existing files maybe overwritten during renaming 0300 * 0301 * @param overwrite if true existing files will be overwritten 0302 */ 0303 inline void setOverwriteExistingFiles(bool overwrite) 0304 { 0305 m_overwrite = overwrite; 0306 } 0307 0308 /** Sets the destination url (a directory) for copy, move and link operations 0309 * 0310 * @param url destination directory 0311 */ 0312 inline void setDestinationDir(const QUrl &url) 0313 { 0314 m_destination = url; 0315 } 0316 0317 private: 0318 /** Do find and replace on the final resulting filename. 0319 * 0320 * \param text the new final filename with all other changes applied. 0321 * 0322 * \returns the new filename with all find and replace being done. 0323 * 0324 * \see m_replace 0325 */ 0326 QString findReplace(const QString &text, const QString &origFilename, int index); 0327 0328 /** 0329 * Replace one string (which might be a regular expression) in the final filename 0330 * with another string and return a new filename. 0331 * 0332 * \param text the new final filename with all other changes applied. 0333 * \param find the string or regular expression to find 0334 * \param replace replace a matched string with this value 0335 * \param reg if true treat find as regular expression 0336 * \param doProcessTokens process tokens in replaced results 0337 * \param originalName original filename for replacing tokens 0338 * \param index current index 0339 * 0340 * \returns the new filename with find and replace being done. 0341 */ 0342 QString doReplace(const QString &text, const QString &find, const QString &replace, 0343 bool reg, bool doProcessTokens, const QString &origFilename, int index); 0344 0345 private: 0346 /** Execute all plugins of a certain type 0347 * 0348 * @param index the current index 0349 * @param filenameOrPath the current filename or path 0350 * @param type the type of the plugins to run 0351 * @param errorCount the number of errors will be written to this value 0352 * @param p dialog for error reporting (maybe NULL) 0353 * 0354 * @returns either a new filename or an error message (depends on plugin type) 0355 */ 0356 QString executePlugin(int index, const QString &filenameOrPath, int type, int &errorCount, ProgressDialog *p); 0357 0358 void work(ProgressDialog *p); 0359 void writeUndoScript(QTextStream *t); 0360 0361 /** 0362 * Parse a new filename and create missing subdirectories. 0363 * 0364 * This will look for '/' and create all not existing directories 0365 * 0366 * @param destUrl to check for not existing directories 0367 * @param dialog ProgressDialog for error reporting 0368 */ 0369 void createMissingSubDirs(const QUrl &destUrl, ProgressDialog *dialog); 0370 0371 /** resets all counters to there start value if the directory name at @p i 0372 * in m_files changes. 0373 * The caller has to check m_reset before calling this function. 0374 */ 0375 void findCounterReset(int i); 0376 0377 QString text; // template 0378 QString extext; // Extension template 0379 QString m_undoScript; // Filename of undoscript 0380 bool undo; // create an undo script 0381 bool m_reset; // reset counter on new directories 0382 int m_mode; // renaming mode 0383 QList<int> m_skip; // Numbers to skip 0384 0385 // a is used in find number and 0386 // required for skipping. 0387 int m_counter_index; 0388 int m_index; // index for numbers 0389 int m_step; // step for numbers 0390 0391 QList<tCounterValues> m_counters; 0392 0393 private: 0394 KRenameFile::List *m_files; ///< The list of files to rename and the resulting renamed filenames 0395 ERenameMode m_renameMode; ///< The rename mode specifies if files are renamed, copied or moved (or linked) 0396 bool m_overwrite; ///< Overwrite existing files 0397 QUrl m_destination; ///< Destination directory for copy, move and link 0398 0399 QList<TReplaceItem> m_replace; ///< List of strings for find and replace 0400 0401 protected: 0402 QFile *f; 0403 QTime t; 0404 QProgressDialog *progress; 0405 }; 0406 0407 void BatchRenamer::setFiles(KRenameFile::List *list) 0408 { 0409 m_files = list; 0410 } 0411 0412 const KRenameFile::List *BatchRenamer::files() const 0413 { 0414 return m_files; 0415 } 0416 0417 void BatchRenamer::setRenameMode(ERenameMode mode) 0418 { 0419 m_renameMode = mode; 0420 } 0421 0422 ERenameMode BatchRenamer::renameMode() const 0423 { 0424 return m_renameMode; 0425 } 0426 0427 void BatchRenamer::setFilenameTemplate(const QString &t) 0428 { 0429 text = t; 0430 } 0431 0432 void BatchRenamer::setExtensionTemplate(const QString &t) 0433 { 0434 extext = t; 0435 } 0436 0437 int BatchRenamer::numberStartIndex() const 0438 { 0439 return m_index; 0440 } 0441 0442 int BatchRenamer::numberStepping() const 0443 { 0444 return m_step; 0445 } 0446 0447 int BatchRenamer::numberReset() const 0448 { 0449 return m_reset; 0450 } 0451 0452 QList<int> BatchRenamer::numberSkipList() const 0453 { 0454 return m_skip; 0455 } 0456 0457 #endif