File indexing completed on 2024-05-19 04:56:01
0001 /** 0002 * \file dirrenamer.h 0003 * Directory renamer. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 23 Jul 2011 0008 * 0009 * Copyright (C) 2011-2024 Urs Fleisch 0010 * 0011 * This file is part of Kid3. 0012 * 0013 * Kid3 is free software; you can redistribute it and/or modify 0014 * it under the terms of the GNU General Public License as published by 0015 * the Free Software Foundation; either version 2 of the License, or 0016 * (at your option) any later version. 0017 * 0018 * Kid3 is distributed in the hope that it will be useful, 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0021 * GNU General Public License for more details. 0022 * 0023 * You should have received a copy of the GNU General Public License 0024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0025 */ 0026 0027 #pragma once 0028 0029 #include <QObject> 0030 #include <QString> 0031 #include <QPersistentModelIndex> 0032 #include "frame.h" 0033 #include "iabortable.h" 0034 #include "kid3api.h" 0035 0036 class TaggedFile; 0037 class DirNameFormatReplacerContext; 0038 0039 /** 0040 * Directory renamer. 0041 */ 0042 class KID3_CORE_EXPORT DirRenamer : public QObject, public IAbortable { 0043 Q_OBJECT 0044 public: 0045 /** 0046 * Constructor. 0047 * @param parent parent object 0048 */ 0049 explicit DirRenamer(QObject* parent = nullptr); 0050 0051 /** 0052 * Destructor. 0053 */ 0054 ~DirRenamer() override; 0055 0056 /** 0057 * Check if operation is aborted. 0058 * 0059 * @return true if aborted. 0060 */ 0061 bool isAborted() const override; 0062 0063 /** 0064 * Clear state which is reported by isAborted(). 0065 */ 0066 void clearAborted() override; 0067 0068 /** 0069 * Set version of tags used to get rename information. 0070 * @param tagVersion tag version 0071 */ 0072 void setTagVersion(Frame::TagVersion tagVersion) { 0073 m_tagVersion = tagVersion; 0074 } 0075 0076 /** 0077 * Set action to be performed. 0078 * @param create true for create action 0079 */ 0080 void setAction(bool create) { m_actionCreate = create; } 0081 0082 /** 0083 * Set format to generate directory names. 0084 * @param format format 0085 */ 0086 void setFormat(const QString& format) { m_format = format; } 0087 0088 /** 0089 * Generate new directory name according to current settings. 0090 * 0091 * @param taggedFile file to get information from 0092 * @param olddir pointer to QString to place old directory name into, 0093 * NULL if not used 0094 * 0095 * @return new directory name. 0096 */ 0097 QString generateNewDirname(TaggedFile* taggedFile, QString* olddir); 0098 0099 /** 0100 * Clear the rename actions. 0101 * This method has to be called before scheduling new actions. 0102 */ 0103 void clearActions(); 0104 0105 /** 0106 * Schedule the actions necessary to rename the directory containing a file. 0107 * 0108 * @param taggedFile file in directory 0109 */ 0110 void scheduleAction(TaggedFile* taggedFile); 0111 0112 /** 0113 * Terminate scheduling of actions. 0114 * Has to be called after completing the scheduleAction() calls. It will 0115 * postprocess the actions when aggregate functions are used. 0116 */ 0117 void endScheduleActions(); 0118 0119 /** 0120 * Perform the scheduled rename actions. 0121 * 0122 * @param errorMsg if not 0 and an error occurred, a message is appended here, 0123 * otherwise it is not touched 0124 */ 0125 void performActions(QString* errorMsg); 0126 0127 /** 0128 * Set directory name. 0129 * This should be done before calling performActions(), so that the directory 0130 * name is changed when the application directory is renamed. 0131 * 0132 * @param dirName directory name 0133 */ 0134 void setDirName(const QString& dirName) { m_dirName = dirName; } 0135 0136 /** 0137 * Get directory name. 0138 * The directory name should be initialized with the value of 0139 * Kid3Application::getDirName() before performActions() is started and will 0140 * be updated if it is renamed while performing the actions. If it is 0141 * different from the application directory name after performActions(), the 0142 * new directory should be opened. 0143 * 0144 * @return directory. 0145 */ 0146 QString getDirName() const { return m_dirName; } 0147 0148 public slots: 0149 /** 0150 * Abort operation. 0151 */ 0152 void abort() override; 0153 0154 signals: 0155 /** 0156 * Is emitted after an action has been scheduled. 0157 * 0158 * @param actionStrs description of action 0159 */ 0160 void actionScheduled(const QStringList& actionStrs); 0161 0162 private: 0163 /** 0164 * An action performed while renaming a directory. 0165 */ 0166 class RenameAction { 0167 public: 0168 /** Action type. */ 0169 enum Type { 0170 CreateDirectory, 0171 RenameDirectory, 0172 RenameFile, 0173 ReportError, 0174 NumTypes 0175 }; 0176 0177 /** 0178 * Constructor. 0179 * @param type type of action 0180 * @param src source file or directory name 0181 * @param dest destination file or directory name 0182 * @param index model index of item to rename 0183 */ 0184 RenameAction(Type type, const QString& src, const QString& dest, 0185 const QPersistentModelIndex& index) 0186 : m_type(type), m_src(src), m_dest(dest), m_index(index) {} 0187 0188 /** 0189 * Constructor. 0190 */ 0191 RenameAction() : m_type(ReportError) {} 0192 0193 /** 0194 * Test for equality. 0195 * @param rhs right hand side 0196 * @return true if equal. 0197 */ 0198 bool operator==(const RenameAction& rhs) const { 0199 return m_type == rhs.m_type && m_src == rhs.m_src && m_dest == rhs.m_dest; 0200 } 0201 0202 Type m_type; /**< type of action */ 0203 QString m_src; /**< source file or directory name */ 0204 QString m_dest; /**< destination file or directory name */ 0205 QPersistentModelIndex m_index; /**< model index of item to rename */ 0206 }; 0207 0208 /** List of rename actions. */ 0209 typedef QList<RenameAction> RenameActionList; 0210 0211 /** 0212 * Create a directory if it does not exist. 0213 * 0214 * @param dir directory path 0215 * @param index model index of item to rename 0216 * @param errorMsg if not NULL and an error occurred, a message is appended here, 0217 * otherwise it is not touched 0218 * 0219 * @return true if directory exists or was created successfully. 0220 */ 0221 bool createDirectory(const QString& dir, const QPersistentModelIndex& index, 0222 QString* errorMsg) const; 0223 0224 /** 0225 * Rename a directory. 0226 * 0227 * @param olddir old directory name 0228 * @param newdir new directory name 0229 * @param errorMsg if not NULL and an error occurred, a message is 0230 * appended here, otherwise it is not touched 0231 * @param index model index of item to rename 0232 * 0233 * @return true if rename successful. 0234 */ 0235 bool renameDirectory( 0236 const QString& olddir, const QString& newdir, 0237 const QPersistentModelIndex& index, QString *errorMsg) const; 0238 0239 /** 0240 * Rename a file. 0241 * 0242 * @param oldfn old file name 0243 * @param newfn new file name 0244 * @param errorMsg if not NULL and an error occurred, a message is 0245 * appended here, otherwise it is not touched 0246 * @param index model index of item to rename 0247 * 0248 * @return true if rename successful or newfn already exists. 0249 */ 0250 bool renameFile(const QString& oldfn, const QString& newfn, 0251 const QPersistentModelIndex& index, QString* errorMsg) const; 0252 0253 /** 0254 * Add a rename action. 0255 * 0256 * @param type type of action 0257 * @param src source file or directory name 0258 * @param dest destination file or directory name 0259 * @param index model index of item to rename 0260 */ 0261 void addAction(RenameAction::Type type, const QString& src, 0262 const QString& dest, 0263 const QPersistentModelIndex& index = QPersistentModelIndex()); 0264 0265 /** 0266 * Add a rename action. 0267 * 0268 * @param type type of action 0269 * @param dest destination file or directory name 0270 */ 0271 void addAction(RenameAction::Type type, const QString& dest); 0272 0273 /** 0274 * Check if there is already an action scheduled for this source. 0275 * 0276 * @return true if a rename action for the source exists. 0277 */ 0278 bool actionHasSource(const QString& src) const; 0279 0280 /** 0281 * Check if there is already an action scheduled for this destination. 0282 * 0283 * @return true if a rename or create action for the destination exists. 0284 */ 0285 bool actionHasDestination(const QString& dest) const; 0286 0287 /** 0288 * Replace directory name if there is already a rename action. 0289 * 0290 * @param src directory name, will be replaced if there is a rename action 0291 */ 0292 void replaceIfAlreadyRenamed(QString& src) const; 0293 0294 /** 0295 * Get description of an actions to be performed. 0296 * @return (action, [src,] dst) list describing the action to be 0297 * performed. 0298 */ 0299 QStringList describeAction(const RenameAction& action) const; 0300 0301 DirNameFormatReplacerContext* m_fmtContext; 0302 RenameActionList m_actions; 0303 Frame::TagVersion m_tagVersion; 0304 QString m_format; 0305 QString m_dirName; 0306 bool m_aborted; 0307 bool m_actionCreate; 0308 };