File indexing completed on 2024-04-14 05:34:15
0001 /* 0002 SPDX-FileCopyrightText: 2011 Vishesh Yadav <vishesh3y@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef HGWRAPPER_H 0008 #define HGWRAPPER_H 0009 0010 #include <QProcess> 0011 #include <QString> 0012 #include <QHash> 0013 #include <QTextCodec> 0014 #include <KFileItem> 0015 #include <Dolphin/KVersionControlPlugin> 0016 0017 class QTextCodec; 0018 0019 0020 //TODO: Create signals for infoMessage and errorMessage which will be 0021 // caught by main plugin interface. 0022 0023 /** 0024 * A singleton class providing implementation of many Mercurial commands 0025 */ 0026 class HgWrapper : public QObject 0027 { 0028 Q_OBJECT 0029 public: 0030 explicit HgWrapper(QObject *parent = nullptr); 0031 0032 static HgWrapper *instance(); 0033 static void freeInstance(); 0034 0035 /** 0036 * Start a mercurial command with given arguments. 0037 * 0038 * @param hgCommand Command to be executed. eg. diff, status 0039 * @param arguments Arguments for the given command 0040 * @param primaryOperation Will emit primaryOperationFinished, 0041 * primaryOperationError signals. 0042 */ 0043 void executeCommand(const QString &hgCommand, 0044 const QStringList &arguments = QStringList(), 0045 bool primaryOperation=false); 0046 /** 0047 * Start a mercurial command with given arguments and return until 0048 * process completes. 0049 * 0050 * @param hgCommand Command to be executed. eg. diff, status 0051 * @param arguments Arguments for the given command 0052 * @param primaryOperation Will emit primaryOperationCompleted, 0053 * primaryOperationError signals. 0054 * @return true if operations completed successfully, otherwise false 0055 */ 0056 bool executeCommandTillFinished(const QString &hgCommand, 0057 const QStringList &arguments = QStringList(), 0058 bool primaryOperation=false); 0059 /** 0060 * Start a mercurial command with given arguments, write standard output 0061 * to output parameter and return till finished. 0062 * 0063 * @param hgCommand Command to be executed. eg. diff, status 0064 * @param arguments Arguments for the given command 0065 * @param output Append standard output of process to this string 0066 * @param primaryOperation Will emit primaryOperationCompleted, 0067 * primaryOperationError signals. 0068 * @return true if operations completed successfully, otherwise false 0069 */ 0070 bool executeCommand(const QString &hgCommand, 0071 const QStringList &arguments, 0072 QString &output, 0073 bool primaryOperation=false); 0074 0075 /** 0076 * Get the root directory of Mercurial repository. Using 'hg root' 0077 * 0078 * @return String containing path of the root directory. 0079 */ 0080 QString getBaseDir() const; 0081 0082 /** 0083 * Sets the current directory being browsed with plugin enabled. 0084 * Updates base directory of repository accordingly 0085 */ 0086 void setCurrentDir(const QString &directory); 0087 0088 /** 0089 * Get the directory path that is currently used as the working directory 0090 * to execute the commands by the HgWrapper. 0091 */ 0092 QString getCurrentDir() const; 0093 0094 /** 0095 * Set the root directory of repository as working directory. 0096 */ 0097 void setBaseAsWorkingDir(); 0098 0099 /** 0100 * Get FileName-ItemVersion pairs of the repository returned by 0101 * 0102 * $hg status --modified --added --removed --deleted --unknown --ignored 0103 * 0104 * Hence returns files with ItemVersion 0105 * - LocallyModifiedVersion 0106 * - AddedVersion 0107 * - RemovedVersion 0108 * - RemovedVersion 0109 * - UnversionedVersion 0110 * - IgnoredVersion 0111 * - MissingVersion 0112 * 0113 * @param result A hashmap containing FileName-ItemVersion pairs 0114 * 0115 */ 0116 void getItemVersions(QHash<QString, KVersionControlPlugin::ItemVersion> &result); 0117 0118 void addFiles(const KFileItemList &fileList); 0119 void removeFiles(const KFileItemList &fileList); 0120 bool renameFile(const QString &source, const QString &destination); 0121 0122 /** 0123 * Commits changes made to the working directory. 0124 * @param message Commit message. Should not be empty. 0125 * @param files List of files to be committed. Files changed but not 0126 * listed here will be ignored during commit. 0127 * If the list is empty, all modified files will be 0128 * committed, the default behavior. 0129 * @param closeCurrentBranch Closes the current branch after commit. 0130 * @return true if successful, otherwise false 0131 */ 0132 bool commit(const QString &message, 0133 const QStringList &files = QStringList(), 0134 bool closeCurrentBranch = false); 0135 0136 /** 0137 * Create a new branch 0138 * @param name Name of new branch to be createdialog 0139 * @return true if successfully created, otherwise false 0140 */ 0141 bool createBranch(const QString &name); 0142 0143 /** 0144 * Update current working directory to another branch 0145 * @param name Name of the branch to which working directory 0146 * has to be updated. 0147 * @return true if successful, otherwise false 0148 */ 0149 bool switchBranch(const QString &name); 0150 0151 /** 0152 * Create tag for current changeset(the changeset of working directory) 0153 * @param name Name of the new tag to be createdialog 0154 * @return true if successful, otherwise false 0155 */ 0156 bool createTag(const QString &name); 0157 0158 /** 0159 * Update working directory to a changeset named by given tag 0160 * @param name Tag of the changeset to which working directory 0161 * has to be updated. 0162 * @return true if successful, otherwise false 0163 */ 0164 bool switchTag(const QString &name); 0165 0166 /** 0167 * Reverts all local changes made to working directory. Will update to 0168 * last changeset of current branch, ie state just after last commit. 0169 */ 0170 bool revertAll(); 0171 0172 /** 0173 * Reverts local changes made to selected files. All changes made to 0174 * these files after last commit will be lost. 0175 */ 0176 bool revert(const KFileItemList &fileList); 0177 0178 /** 0179 * Undo's last transaction. Like commit, pull, push(to this repo). 0180 * Does not alter working directory. 0181 * 0182 * Use with care. Rollback cant be undone. See Mercurial man page FOR 0183 * more info. 0184 * 0185 * @param dryRun Do not actually perform action, but just print output 0186 * Used to check if Rollback can be done, and if yes then 0187 * what will be rolled back. 0188 * @return true if successful, otherwise false 0189 */ 0190 bool rollback(bool dryRun=false); 0191 0192 /** 0193 * Checks if the working directory is clean, ie there are no 0194 * uncommitted changes present. 0195 * 0196 * @return true if clean otherwise false 0197 */ 0198 bool isWorkingDirectoryClean(); 0199 0200 QString getParentsOfHead(); 0201 0202 /** 0203 * Returns list of all branch names. 0204 */ 0205 QStringList getBranches(); 0206 0207 /** 0208 * Returns list of all tags 0209 */ 0210 QStringList getTags(); 0211 0212 inline QString readAllStandardOutput() { 0213 return QTextCodec::codecForLocale()->toUnicode(m_process.readAllStandardOutput()); 0214 } 0215 0216 inline QString readAllStandardError() { 0217 return QTextCodec::codecForLocale()->toUnicode(m_process.readAllStandardError()); 0218 } 0219 0220 /** 0221 * Check if some Mercurial operation is currently being executed or 0222 * about to be started. 0223 */ 0224 inline bool isBusy() { 0225 return (m_process.state() == QProcess::Running || 0226 m_process.state() == QProcess::Starting); 0227 } 0228 0229 public Q_SLOTS: 0230 /** 0231 * Try to terminate the currently running operation. 0232 */ 0233 void terminateCurrentProcess(); 0234 0235 Q_SIGNALS: 0236 ///equivalent to the signals of QProcess 0237 void finished(int exitCode, QProcess::ExitStatus exitStatus); 0238 void errorOccurred(QProcess::ProcessError error); 0239 void started(); 0240 void stateChanged(QProcess::ProcessState state); 0241 void primaryOperationFinished(int exitCode, QProcess::ExitStatus exitStatus); 0242 void primaryOperationError(QProcess::ProcessError error); 0243 0244 private: 0245 ///Get and update m_hgBaseDir 0246 void updateBaseDir(); 0247 0248 private Q_SLOTS: 0249 void slotOperationCompleted(int exitCode, QProcess::ExitStatus exitStatus); 0250 void slotOperationError(QProcess::ProcessError error); 0251 0252 private: 0253 static HgWrapper *m_instance; 0254 0255 QProcess m_process; 0256 QTextCodec *m_localCodec; 0257 0258 QString m_hgBaseDir; 0259 QString m_currentDir; 0260 0261 bool m_primaryOperation; // to differentiate intermediate process 0262 }; 0263 0264 #endif // HGWRAPPER_H 0265