1 /////////////////////////////////////////////////////////////////////////////
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 2 of the License, or (at
6 // your option) any later version.
8 // This program is distributed in the hope that it will be useful, but
9 // WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 /////////////////////////////////////////////////////////////////////////////
18 * @file FileActionScript.cpp
20 * @brief Implementation of FileActionScript and related classes
24 #include "FileActionScript.h"
26 #include "UnicodeString.h"
28 #include "OptionsDef.h"
29 #include "OptionsMgr.h"
30 #include "ShellFileOperations.h"
36 * @brief Standard constructor.
38 FileActionScript::FileActionScript()
39 : m_bUseRecycleBin(true)
40 , m_bHasCopyOperations(false)
41 , m_bHasMoveOperations(false)
42 , m_bHasRenameOperations(false)
43 , m_bHasDelOperations(false)
44 , m_hParentWindow(nullptr)
45 , m_pCopyOperations(new ShellFileOperations())
46 , m_pMoveOperations(new ShellFileOperations())
47 , m_pRenameOperations(new ShellFileOperations())
48 , m_pDelOperations(new ShellFileOperations())
53 * @brief Standard destructor.
55 FileActionScript::~FileActionScript()
60 * @brief Remove last action item from the list.
61 * @return Item removed from the list.
63 FileActionItem FileActionScript::RemoveTailActionItem()
65 FileActionItem item = m_actions.back();
71 * @brief Create ShellFileOperations operation lists from our scripts.
73 * We use ShellFileOperations internally to do actual file operations.
74 * ShellFileOperations can do only one type of operation (copy, move, delete)
75 * with one instance at a time, so we use own instance for every
77 * @return One of CreateScriptReturn values.
79 int FileActionScript::CreateOperationsScripts()
82 FILEOP_FLAGS operFlags = 0;
83 bool bContinue = true;
85 // Copy operations first
87 operFlags |= FOF_NOCONFIRMMKDIR | FOF_MULTIDESTFILES | FOF_NOCONFIRMATION;
89 operFlags |= FOF_ALLOWUNDO;
91 vector<FileActionItem>::const_iterator iter = m_actions.begin();
92 while (iter != m_actions.end() && bContinue)
95 if ((*iter).atype == FileAction::ACT_COPY && !(*iter).dirflag)
99 if (!theApp.CreateBackup(true, (*iter).dest))
101 String strErr = _("Error backing up file");
102 AfxMessageBox(strErr.c_str(), MB_OK | MB_ICONERROR);
108 if ((*iter).atype == FileAction::ACT_COPY &&
111 m_pCopyOperations->AddSourceAndDestination((*iter).src, (*iter).dest);
112 m_bHasCopyOperations = true;
118 m_bHasCopyOperations = false;
119 m_pCopyOperations->Reset();
120 return SCRIPT_USERCANCEL;
123 if (m_bHasCopyOperations)
124 m_pCopyOperations->SetOperation(operation, operFlags, m_hParentWindow);
126 // Move operations next
128 operFlags = FOF_MULTIDESTFILES;
129 if (m_bUseRecycleBin)
130 operFlags |= FOF_ALLOWUNDO;
132 iter = m_actions.begin();
133 while (iter != m_actions.end())
135 if ((*iter).atype == FileAction::ACT_MOVE)
137 m_pMoveOperations->AddSourceAndDestination((*iter).src, (*iter).dest);
138 m_bHasMoveOperations = true;
142 if (m_bHasMoveOperations)
143 m_pMoveOperations->SetOperation(operation, operFlags, m_hParentWindow);
145 // Rename operations nextbbbb
146 operation = FO_RENAME;
147 operFlags = FOF_MULTIDESTFILES;
148 if (m_bUseRecycleBin)
149 operFlags |= FOF_ALLOWUNDO;
151 iter = m_actions.begin();
152 while (iter != m_actions.end())
154 if ((*iter).atype == FileAction::ACT_RENAME)
156 m_pRenameOperations->AddSourceAndDestination((*iter).src, (*iter).dest);
157 m_bHasRenameOperations = true;
161 if (m_bHasRenameOperations)
162 m_pRenameOperations->SetOperation(operation, operFlags, m_hParentWindow);
164 // Delete operations last
165 operation = FO_DELETE;
167 if (m_bUseRecycleBin)
168 operFlags |= FOF_ALLOWUNDO;
170 iter = m_actions.begin();
171 while (iter != m_actions.end())
173 if ((*iter).atype == FileAction::ACT_DEL)
175 m_pDelOperations->AddSource((*iter).src);
176 if (!(*iter).dest.empty())
177 m_pDelOperations->AddSource((*iter).dest);
178 m_bHasDelOperations = true;
182 if (m_bHasDelOperations)
183 m_pDelOperations->SetOperation(operation, operFlags, m_hParentWindow);
184 return SCRIPT_SUCCESS;
188 * @brief Run one operation set.
189 * @param [in] oplist List of operations to run.
190 * @param [out] userCancelled Did user cancel the operation?
191 * @return true if the operation succeeded and finished.
193 bool FileActionScript::RunOp(ShellFileOperations *oplist, bool & userCancelled)
195 bool fileOpSucceed = false;
198 fileOpSucceed = oplist->Run();
199 userCancelled = oplist->IsCanceled();
201 __except (EXCEPTION_EXECUTE_HANDLER)
203 fileOpSucceed = false;
205 return fileOpSucceed;
209 * @brief Execute fileoperations.
210 * @return `true` if all actions were done successfully, `false` otherwise.
212 bool FileActionScript::Run()
214 // Now process files/directories that got added to list
215 bool bFileOpSucceed = true;
216 bool bUserCancelled = false;
219 CreateOperationsScripts();
221 if (m_bHasCopyOperations)
223 vector<FileActionItem>::const_iterator iter = m_actions.begin();
224 while (iter != m_actions.end())
227 paths::CreateIfNeeded((*iter).dest);
230 bFileOpSucceed = RunOp(m_pCopyOperations.get(), bUserCancelled);
233 if (m_bHasMoveOperations)
235 if (bFileOpSucceed && !bUserCancelled)
237 bFileOpSucceed = RunOp(m_pMoveOperations.get(), bUserCancelled);
243 if (m_bHasRenameOperations)
245 if (bFileOpSucceed && !bUserCancelled)
247 bFileOpSucceed = RunOp(m_pRenameOperations.get(), bUserCancelled);
253 if (m_bHasDelOperations)
255 if (bFileOpSucceed && !bUserCancelled)
257 bFileOpSucceed = RunOp(m_pDelOperations.get(), bUserCancelled);
263 if (!bFileOpSucceed || bUserCancelled)