Imported Upstream version 9.20
[platform/upstream/7zip.git] / CPP / 7zip / UI / FileManager / PanelCopy.cpp
1 // PanelExtract.cpp\r
2 \r
3 #include "StdAfx.h"\r
4 \r
5 #include "Panel.h"\r
6 #include "resource.h"\r
7 #include "LangUtils.h"\r
8 #include "ExtractCallback.h"\r
9 #include "Windows/Thread.h"\r
10 ////////////////////////////////////////////////////////////////\r
11 \r
12 #include "UpdateCallback100.h"\r
13 \r
14 using namespace NWindows;\r
15 \r
16 class CPanelCopyThread: public CProgressThreadVirt\r
17 {\r
18   HRESULT ProcessVirt();\r
19 public:\r
20   CMyComPtr<IFolderOperations> FolderOperations;\r
21   CRecordVector<UInt32> Indices;\r
22   UString DestPath;\r
23   CExtractCallbackImp *ExtractCallbackSpec;\r
24   CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback;\r
25   HRESULT Result;\r
26   bool MoveMode;\r
27 \r
28   CPanelCopyThread(): MoveMode(false), Result(E_FAIL) {}\r
29 };\r
30   \r
31 HRESULT CPanelCopyThread::ProcessVirt()\r
32 {\r
33   if (MoveMode)\r
34     Result = FolderOperations->MoveTo(&Indices.Front(), Indices.Size(), DestPath, ExtractCallback);\r
35   else\r
36     Result = FolderOperations->CopyTo(&Indices.Front(), Indices.Size(), DestPath, ExtractCallback);\r
37   return Result;\r
38 }\r
39 \r
40 HRESULT CPanel::CopyTo(const CRecordVector<UInt32> &indices, const UString &folder,\r
41     bool moveMode, bool showErrorMessages, UStringVector *messages,\r
42     bool &usePassword, UString &password)\r
43 {\r
44   CMyComPtr<IFolderOperations> folderOperations;\r
45   if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)\r
46   {\r
47     UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);\r
48     if (showErrorMessages)\r
49       MessageBox(errorMessage);\r
50     else if (messages != 0)\r
51       messages->Add(errorMessage);\r
52     return E_FAIL;\r
53   }\r
54 \r
55   HRESULT res;\r
56   {\r
57   CPanelCopyThread extracter;\r
58 \r
59   \r
60   extracter.ExtractCallbackSpec = new CExtractCallbackImp;\r
61   extracter.ExtractCallback = extracter.ExtractCallbackSpec;\r
62   extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog;\r
63   extracter.ProgressDialog.CompressingMode = false;\r
64   \r
65   UString title = moveMode ?\r
66       LangString(IDS_MOVING, 0x03020206):\r
67       LangString(IDS_COPYING, 0x03020205);\r
68   UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000);\r
69   \r
70   extracter.ProgressDialog.MainWindow = GetParent();\r
71   extracter.ProgressDialog.MainTitle = progressWindowTitle;\r
72   extracter.ProgressDialog.MainAddTitle = title + L" ";\r
73     \r
74   extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAskBefore;\r
75   extracter.ExtractCallbackSpec->Init();\r
76   extracter.Indices = indices;\r
77   extracter.DestPath = folder;\r
78   extracter.FolderOperations = folderOperations;\r
79   extracter.MoveMode = moveMode;\r
80 \r
81   extracter.ExtractCallbackSpec->PasswordIsDefined = usePassword;\r
82   extracter.ExtractCallbackSpec->Password = password;\r
83   \r
84   RINOK(extracter.Create(title, GetParent()));\r
85   \r
86   if (messages != 0)\r
87     *messages = extracter.ProgressDialog.Sync.Messages;\r
88   res = extracter.Result;\r
89 \r
90   if (res == S_OK && extracter.ExtractCallbackSpec->IsOK())\r
91   {\r
92     usePassword = extracter.ExtractCallbackSpec->PasswordIsDefined;\r
93     password = extracter.ExtractCallbackSpec->Password;\r
94   }\r
95   }\r
96   RefreshTitleAlways();\r
97   return res;\r
98 }\r
99 \r
100 \r
101 struct CThreadUpdate\r
102 {\r
103   CMyComPtr<IFolderOperations> FolderOperations;\r
104   UString FolderPrefix;\r
105   UStringVector FileNames;\r
106   CRecordVector<const wchar_t *> FileNamePointers;\r
107   CProgressDialog ProgressDialog;\r
108   CMyComPtr<IFolderArchiveUpdateCallback> UpdateCallback;\r
109   CUpdateCallback100Imp *UpdateCallbackSpec;\r
110   HRESULT Result;\r
111   \r
112   void Process()\r
113   {\r
114     try\r
115     {\r
116       CProgressCloser closer(ProgressDialog);\r
117       Result = FolderOperations->CopyFrom(\r
118         FolderPrefix,\r
119         &FileNamePointers.Front(),\r
120         FileNamePointers.Size(),\r
121         UpdateCallback);\r
122     }\r
123     catch(...) { Result = E_FAIL; }\r
124   }\r
125   static THREAD_FUNC_DECL MyThreadFunction(void *param)\r
126   {\r
127     ((CThreadUpdate *)param)->Process();\r
128     return 0;\r
129   }\r
130 };\r
131 \r
132 HRESULT CPanel::CopyFrom(const UString &folderPrefix, const UStringVector &filePaths,\r
133     bool showErrorMessages, UStringVector *messages)\r
134 {\r
135   CMyComPtr<IFolderOperations> folderOperations;\r
136   _folder.QueryInterface(IID_IFolderOperations, &folderOperations);\r
137   HRESULT res;\r
138   if (!folderOperations)\r
139     res = E_NOINTERFACE;\r
140   else\r
141   {\r
142   CThreadUpdate updater;\r
143   updater.UpdateCallbackSpec = new CUpdateCallback100Imp;\r
144   updater.UpdateCallback = updater.UpdateCallbackSpec;\r
145 \r
146   updater.UpdateCallbackSpec->ProgressDialog = &updater.ProgressDialog;\r
147 \r
148   UString title = LangString(IDS_COPYING, 0x03020205);\r
149   UString progressWindowTitle = LangString(IDS_APP_TITLE, 0x03000000);\r
150 \r
151   updater.ProgressDialog.MainWindow = GetParent();\r
152   updater.ProgressDialog.MainTitle = progressWindowTitle;\r
153   updater.ProgressDialog.MainAddTitle = title + UString(L" ");\r
154   \r
155   updater.UpdateCallbackSpec->Init(false, L"");\r
156   updater.FolderOperations = folderOperations;\r
157   updater.FolderPrefix = folderPrefix;\r
158   updater.FileNames.Reserve(filePaths.Size());\r
159   int i;\r
160   for(i = 0; i < filePaths.Size(); i++)\r
161     updater.FileNames.Add(filePaths[i]);\r
162   updater.FileNamePointers.Reserve(updater.FileNames.Size());\r
163   for(i = 0; i < updater.FileNames.Size(); i++)\r
164     updater.FileNamePointers.Add(updater.FileNames[i]);\r
165 \r
166   NWindows::CThread thread;\r
167   RINOK(thread.Create(CThreadUpdate::MyThreadFunction, &updater));\r
168   updater.ProgressDialog.Create(title, thread, GetParent());\r
169   \r
170   if (messages != 0)\r
171     *messages = updater.ProgressDialog.Sync.Messages;\r
172 \r
173   res = updater.Result;\r
174   }\r
175 \r
176   if (res == E_NOINTERFACE)\r
177   {\r
178     UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);\r
179     if (showErrorMessages)\r
180       MessageBox(errorMessage);\r
181     else if (messages != 0)\r
182       messages->Add(errorMessage);\r
183     return E_ABORT;\r
184   }\r
185 \r
186   RefreshTitleAlways();\r
187   return res;\r
188 }\r
189 \r
190 void CPanel::CopyFromNoAsk(const UStringVector &filePaths)\r
191 {\r
192   CDisableTimerProcessing disableTimerProcessing(*this);\r
193 \r
194   CSelectedState srcSelState;\r
195   SaveSelectedState(srcSelState);\r
196 \r
197   HRESULT result = CopyFrom(L"", filePaths, true, 0);\r
198 \r
199   if (result != S_OK)\r
200   {\r
201     disableTimerProcessing.Restore();\r
202     // For Password:\r
203     SetFocusToList();\r
204     if (result != E_ABORT)\r
205       MessageBoxError(result);\r
206     return;\r
207   }\r
208 \r
209   RefreshListCtrl(srcSelState);\r
210 \r
211   disableTimerProcessing.Restore();\r
212   SetFocusToList();\r
213 }\r
214 \r
215 void CPanel::CopyFromAsk(const UStringVector &filePaths)\r
216 {\r
217   UString title = LangString(IDS_CONFIRM_FILE_COPY, 0x03020222);\r
218   UString message = LangString(IDS_WANT_TO_COPY_FILES, 0x03020223);\r
219   message += L"\n\'";\r
220   message += _currentFolderPrefix;\r
221   message += L"\' ?";\r
222   int res = ::MessageBoxW(*(this), message, title, MB_YESNOCANCEL | MB_ICONQUESTION);\r
223   if (res != IDYES)\r
224     return;\r
225 \r
226   CopyFromNoAsk(filePaths);\r
227 }\r