1*f6dc9357SAndroid Build Coastguard Worker // PanelOperations.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/DynamicBuffer.h"
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/COM.h"
10*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariant.h"
12*f6dc9357SAndroid Build Coastguard Worker
13*f6dc9357SAndroid Build Coastguard Worker #include "ComboDialog.h"
14*f6dc9357SAndroid Build Coastguard Worker
15*f6dc9357SAndroid Build Coastguard Worker #include "FSFolder.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "FormatUtils.h"
17*f6dc9357SAndroid Build Coastguard Worker #include "LangUtils.h"
18*f6dc9357SAndroid Build Coastguard Worker #include "Panel.h"
19*f6dc9357SAndroid Build Coastguard Worker #include "UpdateCallback100.h"
20*f6dc9357SAndroid Build Coastguard Worker
21*f6dc9357SAndroid Build Coastguard Worker #include "resource.h"
22*f6dc9357SAndroid Build Coastguard Worker
23*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
24*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
25*f6dc9357SAndroid Build Coastguard Worker using namespace NName;
26*f6dc9357SAndroid Build Coastguard Worker
27*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
28*f6dc9357SAndroid Build Coastguard Worker extern bool g_IsNT;
29*f6dc9357SAndroid Build Coastguard Worker #endif
30*f6dc9357SAndroid Build Coastguard Worker
31*f6dc9357SAndroid Build Coastguard Worker enum EFolderOpType
32*f6dc9357SAndroid Build Coastguard Worker {
33*f6dc9357SAndroid Build Coastguard Worker FOLDER_TYPE_CREATE_FOLDER = 0,
34*f6dc9357SAndroid Build Coastguard Worker FOLDER_TYPE_DELETE = 1,
35*f6dc9357SAndroid Build Coastguard Worker FOLDER_TYPE_RENAME = 2
36*f6dc9357SAndroid Build Coastguard Worker };
37*f6dc9357SAndroid Build Coastguard Worker
38*f6dc9357SAndroid Build Coastguard Worker class CThreadFolderOperations: public CProgressThreadVirt
39*f6dc9357SAndroid Build Coastguard Worker {
40*f6dc9357SAndroid Build Coastguard Worker HRESULT ProcessVirt() Z7_override;
41*f6dc9357SAndroid Build Coastguard Worker public:
42*f6dc9357SAndroid Build Coastguard Worker EFolderOpType OpType;
43*f6dc9357SAndroid Build Coastguard Worker UString Name;
44*f6dc9357SAndroid Build Coastguard Worker UInt32 Index;
45*f6dc9357SAndroid Build Coastguard Worker CRecordVector<UInt32> Indices;
46*f6dc9357SAndroid Build Coastguard Worker
47*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IFolderOperations> FolderOperations;
48*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IProgress> UpdateCallback;
49*f6dc9357SAndroid Build Coastguard Worker CUpdateCallback100Imp *UpdateCallbackSpec;
50*f6dc9357SAndroid Build Coastguard Worker
CThreadFolderOperations(EFolderOpType opType)51*f6dc9357SAndroid Build Coastguard Worker CThreadFolderOperations(EFolderOpType opType): OpType(opType) {}
52*f6dc9357SAndroid Build Coastguard Worker HRESULT DoOperation(CPanel &panel, const UString &progressTitle, const UString &titleError);
53*f6dc9357SAndroid Build Coastguard Worker };
54*f6dc9357SAndroid Build Coastguard Worker
ProcessVirt()55*f6dc9357SAndroid Build Coastguard Worker HRESULT CThreadFolderOperations::ProcessVirt()
56*f6dc9357SAndroid Build Coastguard Worker {
57*f6dc9357SAndroid Build Coastguard Worker NCOM::CComInitializer comInitializer;
58*f6dc9357SAndroid Build Coastguard Worker switch ((int)OpType)
59*f6dc9357SAndroid Build Coastguard Worker {
60*f6dc9357SAndroid Build Coastguard Worker case FOLDER_TYPE_CREATE_FOLDER:
61*f6dc9357SAndroid Build Coastguard Worker return FolderOperations->CreateFolder(Name, UpdateCallback);
62*f6dc9357SAndroid Build Coastguard Worker case FOLDER_TYPE_DELETE:
63*f6dc9357SAndroid Build Coastguard Worker return FolderOperations->Delete(Indices.ConstData(), Indices.Size(), UpdateCallback);
64*f6dc9357SAndroid Build Coastguard Worker case FOLDER_TYPE_RENAME:
65*f6dc9357SAndroid Build Coastguard Worker return FolderOperations->Rename(Index, Name, UpdateCallback);
66*f6dc9357SAndroid Build Coastguard Worker default:
67*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
68*f6dc9357SAndroid Build Coastguard Worker }
69*f6dc9357SAndroid Build Coastguard Worker }
70*f6dc9357SAndroid Build Coastguard Worker
71*f6dc9357SAndroid Build Coastguard Worker
DoOperation(CPanel & panel,const UString & progressTitle,const UString & titleError)72*f6dc9357SAndroid Build Coastguard Worker HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progressTitle, const UString &titleError)
73*f6dc9357SAndroid Build Coastguard Worker {
74*f6dc9357SAndroid Build Coastguard Worker UpdateCallbackSpec = new CUpdateCallback100Imp;
75*f6dc9357SAndroid Build Coastguard Worker UpdateCallback = UpdateCallbackSpec;
76*f6dc9357SAndroid Build Coastguard Worker UpdateCallbackSpec->ProgressDialog = this;
77*f6dc9357SAndroid Build Coastguard Worker
78*f6dc9357SAndroid Build Coastguard Worker WaitMode = true;
79*f6dc9357SAndroid Build Coastguard Worker Sync.FinalMessage.ErrorMessage.Title = titleError;
80*f6dc9357SAndroid Build Coastguard Worker
81*f6dc9357SAndroid Build Coastguard Worker UpdateCallbackSpec->Init();
82*f6dc9357SAndroid Build Coastguard Worker
83*f6dc9357SAndroid Build Coastguard Worker if (!panel._parentFolders.IsEmpty())
84*f6dc9357SAndroid Build Coastguard Worker {
85*f6dc9357SAndroid Build Coastguard Worker const CFolderLink &fl = panel._parentFolders.Back();
86*f6dc9357SAndroid Build Coastguard Worker UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword;
87*f6dc9357SAndroid Build Coastguard Worker UpdateCallbackSpec->Password = fl.Password;
88*f6dc9357SAndroid Build Coastguard Worker }
89*f6dc9357SAndroid Build Coastguard Worker
90*f6dc9357SAndroid Build Coastguard Worker MainWindow = panel._mainWindow; // panel.GetParent()
91*f6dc9357SAndroid Build Coastguard Worker MainTitle = "7-Zip"; // LangString(IDS_APP_TITLE);
92*f6dc9357SAndroid Build Coastguard Worker MainAddTitle = progressTitle + L' ';
93*f6dc9357SAndroid Build Coastguard Worker
94*f6dc9357SAndroid Build Coastguard Worker RINOK(Create(progressTitle, MainWindow))
95*f6dc9357SAndroid Build Coastguard Worker return Result;
96*f6dc9357SAndroid Build Coastguard Worker }
97*f6dc9357SAndroid Build Coastguard Worker
98*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
99*f6dc9357SAndroid Build Coastguard Worker typedef int (WINAPI * Func_SHFileOperationW)(LPSHFILEOPSTRUCTW lpFileOp);
100*f6dc9357SAndroid Build Coastguard Worker #endif
101*f6dc9357SAndroid Build Coastguard Worker
102*f6dc9357SAndroid Build Coastguard Worker /*
103*f6dc9357SAndroid Build Coastguard Worker void CPanel::MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID)
104*f6dc9357SAndroid Build Coastguard Worker {
105*f6dc9357SAndroid Build Coastguard Worker if (errorCode == E_NOINTERFACE)
106*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_UnsupportOperation();
107*f6dc9357SAndroid Build Coastguard Worker else
108*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_HRESULT_Caption(errorCode, LangString(resourceID));
109*f6dc9357SAndroid Build Coastguard Worker }
110*f6dc9357SAndroid Build Coastguard Worker */
111*f6dc9357SAndroid Build Coastguard Worker
DeleteItems(bool NON_CE_VAR (toRecycleBin))112*f6dc9357SAndroid Build Coastguard Worker void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
113*f6dc9357SAndroid Build Coastguard Worker {
114*f6dc9357SAndroid Build Coastguard Worker CDisableTimerProcessing disableTimerProcessing(*this);
115*f6dc9357SAndroid Build Coastguard Worker CRecordVector<UInt32> indices;
116*f6dc9357SAndroid Build Coastguard Worker Get_ItemIndices_Operated(indices);
117*f6dc9357SAndroid Build Coastguard Worker if (indices.IsEmpty())
118*f6dc9357SAndroid Build Coastguard Worker return;
119*f6dc9357SAndroid Build Coastguard Worker CSelectedState state;
120*f6dc9357SAndroid Build Coastguard Worker SaveSelectedState(state);
121*f6dc9357SAndroid Build Coastguard Worker
122*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
123*f6dc9357SAndroid Build Coastguard Worker // WM6 / SHFileOperationW doesn't ask user! So we use internal delete
124*f6dc9357SAndroid Build Coastguard Worker if (IsFSFolder() && toRecycleBin)
125*f6dc9357SAndroid Build Coastguard Worker {
126*f6dc9357SAndroid Build Coastguard Worker bool useInternalDelete = false;
127*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
128*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
129*f6dc9357SAndroid Build Coastguard Worker {
130*f6dc9357SAndroid Build Coastguard Worker CDynamicBuffer<CHAR> buffer;
131*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, indices)
132*f6dc9357SAndroid Build Coastguard Worker {
133*f6dc9357SAndroid Build Coastguard Worker const AString path (GetSystemString(GetItemFullPath(indices[i])));
134*f6dc9357SAndroid Build Coastguard Worker buffer.AddData(path, path.Len() + 1);
135*f6dc9357SAndroid Build Coastguard Worker }
136*f6dc9357SAndroid Build Coastguard Worker *buffer.GetCurPtrAndGrow(1) = 0;
137*f6dc9357SAndroid Build Coastguard Worker SHFILEOPSTRUCTA fo;
138*f6dc9357SAndroid Build Coastguard Worker fo.hwnd = GetParent();
139*f6dc9357SAndroid Build Coastguard Worker fo.wFunc = FO_DELETE;
140*f6dc9357SAndroid Build Coastguard Worker fo.pFrom = (const CHAR *)buffer;
141*f6dc9357SAndroid Build Coastguard Worker fo.pTo = NULL;
142*f6dc9357SAndroid Build Coastguard Worker fo.fFlags = 0;
143*f6dc9357SAndroid Build Coastguard Worker if (toRecycleBin)
144*f6dc9357SAndroid Build Coastguard Worker fo.fFlags |= FOF_ALLOWUNDO;
145*f6dc9357SAndroid Build Coastguard Worker // fo.fFlags |= FOF_NOCONFIRMATION;
146*f6dc9357SAndroid Build Coastguard Worker // fo.fFlags |= FOF_NOERRORUI;
147*f6dc9357SAndroid Build Coastguard Worker // fo.fFlags |= FOF_SILENT;
148*f6dc9357SAndroid Build Coastguard Worker // fo.fFlags |= FOF_WANTNUKEWARNING;
149*f6dc9357SAndroid Build Coastguard Worker fo.fAnyOperationsAborted = FALSE;
150*f6dc9357SAndroid Build Coastguard Worker fo.hNameMappings = NULL;
151*f6dc9357SAndroid Build Coastguard Worker fo.lpszProgressTitle = NULL;
152*f6dc9357SAndroid Build Coastguard Worker /* int res = */ ::SHFileOperationA(&fo);
153*f6dc9357SAndroid Build Coastguard Worker }
154*f6dc9357SAndroid Build Coastguard Worker else
155*f6dc9357SAndroid Build Coastguard Worker #endif
156*f6dc9357SAndroid Build Coastguard Worker {
157*f6dc9357SAndroid Build Coastguard Worker CDynamicBuffer<WCHAR> buffer;
158*f6dc9357SAndroid Build Coastguard Worker unsigned maxLen = 0;
159*f6dc9357SAndroid Build Coastguard Worker const UString prefix = GetFsPath();
160*f6dc9357SAndroid Build Coastguard Worker FOR_VECTOR (i, indices)
161*f6dc9357SAndroid Build Coastguard Worker {
162*f6dc9357SAndroid Build Coastguard Worker // L"\\\\?\\") doesn't work here.
163*f6dc9357SAndroid Build Coastguard Worker const UString path = prefix + GetItemRelPath2(indices[i]);
164*f6dc9357SAndroid Build Coastguard Worker if (path.Len() > maxLen)
165*f6dc9357SAndroid Build Coastguard Worker maxLen = path.Len();
166*f6dc9357SAndroid Build Coastguard Worker buffer.AddData(path, path.Len() + 1);
167*f6dc9357SAndroid Build Coastguard Worker }
168*f6dc9357SAndroid Build Coastguard Worker *buffer.GetCurPtrAndGrow(1) = 0;
169*f6dc9357SAndroid Build Coastguard Worker if (maxLen >= MAX_PATH)
170*f6dc9357SAndroid Build Coastguard Worker {
171*f6dc9357SAndroid Build Coastguard Worker if (toRecycleBin)
172*f6dc9357SAndroid Build Coastguard Worker {
173*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_LangID(IDS_ERROR_LONG_PATH_TO_RECYCLE);
174*f6dc9357SAndroid Build Coastguard Worker return;
175*f6dc9357SAndroid Build Coastguard Worker }
176*f6dc9357SAndroid Build Coastguard Worker useInternalDelete = true;
177*f6dc9357SAndroid Build Coastguard Worker }
178*f6dc9357SAndroid Build Coastguard Worker else
179*f6dc9357SAndroid Build Coastguard Worker {
180*f6dc9357SAndroid Build Coastguard Worker SHFILEOPSTRUCTW fo;
181*f6dc9357SAndroid Build Coastguard Worker fo.hwnd = GetParent();
182*f6dc9357SAndroid Build Coastguard Worker fo.wFunc = FO_DELETE;
183*f6dc9357SAndroid Build Coastguard Worker fo.pFrom = (const WCHAR *)buffer;
184*f6dc9357SAndroid Build Coastguard Worker fo.pTo = NULL;
185*f6dc9357SAndroid Build Coastguard Worker fo.fFlags = 0;
186*f6dc9357SAndroid Build Coastguard Worker if (toRecycleBin)
187*f6dc9357SAndroid Build Coastguard Worker fo.fFlags |= FOF_ALLOWUNDO;
188*f6dc9357SAndroid Build Coastguard Worker fo.fAnyOperationsAborted = FALSE;
189*f6dc9357SAndroid Build Coastguard Worker fo.hNameMappings = NULL;
190*f6dc9357SAndroid Build Coastguard Worker fo.lpszProgressTitle = NULL;
191*f6dc9357SAndroid Build Coastguard Worker // int res;
192*f6dc9357SAndroid Build Coastguard Worker #ifdef _UNICODE
193*f6dc9357SAndroid Build Coastguard Worker /* res = */ ::SHFileOperationW(&fo);
194*f6dc9357SAndroid Build Coastguard Worker #else
195*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
196*f6dc9357SAndroid Build Coastguard Worker const
197*f6dc9357SAndroid Build Coastguard Worker Func_SHFileOperationW
198*f6dc9357SAndroid Build Coastguard Worker f_SHFileOperationW = Z7_GET_PROC_ADDRESS(
199*f6dc9357SAndroid Build Coastguard Worker Func_SHFileOperationW, ::GetModuleHandleW(L"shell32.dll"),
200*f6dc9357SAndroid Build Coastguard Worker "SHFileOperationW");
201*f6dc9357SAndroid Build Coastguard Worker if (!f_SHFileOperationW)
202*f6dc9357SAndroid Build Coastguard Worker return;
203*f6dc9357SAndroid Build Coastguard Worker /* res = */ f_SHFileOperationW(&fo);
204*f6dc9357SAndroid Build Coastguard Worker #endif
205*f6dc9357SAndroid Build Coastguard Worker }
206*f6dc9357SAndroid Build Coastguard Worker }
207*f6dc9357SAndroid Build Coastguard Worker /*
208*f6dc9357SAndroid Build Coastguard Worker if (fo.fAnyOperationsAborted)
209*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_HRESULT_Caption(result, LangString(IDS_ERROR_DELETING));
210*f6dc9357SAndroid Build Coastguard Worker */
211*f6dc9357SAndroid Build Coastguard Worker if (!useInternalDelete)
212*f6dc9357SAndroid Build Coastguard Worker {
213*f6dc9357SAndroid Build Coastguard Worker RefreshListCtrl(state);
214*f6dc9357SAndroid Build Coastguard Worker return;
215*f6dc9357SAndroid Build Coastguard Worker }
216*f6dc9357SAndroid Build Coastguard Worker }
217*f6dc9357SAndroid Build Coastguard Worker #endif
218*f6dc9357SAndroid Build Coastguard Worker
219*f6dc9357SAndroid Build Coastguard Worker // DeleteItemsInternal
220*f6dc9357SAndroid Build Coastguard Worker
221*f6dc9357SAndroid Build Coastguard Worker if (!CheckBeforeUpdate(IDS_ERROR_DELETING))
222*f6dc9357SAndroid Build Coastguard Worker return;
223*f6dc9357SAndroid Build Coastguard Worker
224*f6dc9357SAndroid Build Coastguard Worker UInt32 titleID, messageID;
225*f6dc9357SAndroid Build Coastguard Worker UString messageParam;
226*f6dc9357SAndroid Build Coastguard Worker if (indices.Size() == 1)
227*f6dc9357SAndroid Build Coastguard Worker {
228*f6dc9357SAndroid Build Coastguard Worker const unsigned index = indices[0];
229*f6dc9357SAndroid Build Coastguard Worker messageParam = GetItemRelPath2(index);
230*f6dc9357SAndroid Build Coastguard Worker if (IsItem_Folder(index))
231*f6dc9357SAndroid Build Coastguard Worker {
232*f6dc9357SAndroid Build Coastguard Worker titleID = IDS_CONFIRM_FOLDER_DELETE;
233*f6dc9357SAndroid Build Coastguard Worker messageID = IDS_WANT_TO_DELETE_FOLDER;
234*f6dc9357SAndroid Build Coastguard Worker }
235*f6dc9357SAndroid Build Coastguard Worker else
236*f6dc9357SAndroid Build Coastguard Worker {
237*f6dc9357SAndroid Build Coastguard Worker titleID = IDS_CONFIRM_FILE_DELETE;
238*f6dc9357SAndroid Build Coastguard Worker messageID = IDS_WANT_TO_DELETE_FILE;
239*f6dc9357SAndroid Build Coastguard Worker }
240*f6dc9357SAndroid Build Coastguard Worker }
241*f6dc9357SAndroid Build Coastguard Worker else
242*f6dc9357SAndroid Build Coastguard Worker {
243*f6dc9357SAndroid Build Coastguard Worker titleID = IDS_CONFIRM_ITEMS_DELETE;
244*f6dc9357SAndroid Build Coastguard Worker messageID = IDS_WANT_TO_DELETE_ITEMS;
245*f6dc9357SAndroid Build Coastguard Worker messageParam = NumberToString(indices.Size());
246*f6dc9357SAndroid Build Coastguard Worker }
247*f6dc9357SAndroid Build Coastguard Worker if (::MessageBoxW(GetParent(), MyFormatNew(messageID, messageParam), LangString(titleID),
248*f6dc9357SAndroid Build Coastguard Worker MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES)
249*f6dc9357SAndroid Build Coastguard Worker return;
250*f6dc9357SAndroid Build Coastguard Worker
251*f6dc9357SAndroid Build Coastguard Worker CDisableNotify disableNotify(*this);
252*f6dc9357SAndroid Build Coastguard Worker {
253*f6dc9357SAndroid Build Coastguard Worker CThreadFolderOperations op(FOLDER_TYPE_DELETE);
254*f6dc9357SAndroid Build Coastguard Worker op.FolderOperations = _folderOperations;
255*f6dc9357SAndroid Build Coastguard Worker op.Indices = indices;
256*f6dc9357SAndroid Build Coastguard Worker op.DoOperation(*this,
257*f6dc9357SAndroid Build Coastguard Worker LangString(IDS_DELETING),
258*f6dc9357SAndroid Build Coastguard Worker LangString(IDS_ERROR_DELETING));
259*f6dc9357SAndroid Build Coastguard Worker }
260*f6dc9357SAndroid Build Coastguard Worker RefreshTitleAlways();
261*f6dc9357SAndroid Build Coastguard Worker RefreshListCtrl(state);
262*f6dc9357SAndroid Build Coastguard Worker }
263*f6dc9357SAndroid Build Coastguard Worker
OnBeginLabelEdit(LV_DISPINFOW * lpnmh)264*f6dc9357SAndroid Build Coastguard Worker BOOL CPanel::OnBeginLabelEdit(LV_DISPINFOW * lpnmh)
265*f6dc9357SAndroid Build Coastguard Worker {
266*f6dc9357SAndroid Build Coastguard Worker const unsigned realIndex = GetRealIndex(lpnmh->item);
267*f6dc9357SAndroid Build Coastguard Worker if (realIndex == kParentIndex)
268*f6dc9357SAndroid Build Coastguard Worker return TRUE;
269*f6dc9357SAndroid Build Coastguard Worker if (IsThereReadOnlyFolder())
270*f6dc9357SAndroid Build Coastguard Worker return TRUE;
271*f6dc9357SAndroid Build Coastguard Worker return FALSE;
272*f6dc9357SAndroid Build Coastguard Worker }
273*f6dc9357SAndroid Build Coastguard Worker
IsCorrectFsName(const UString & name)274*f6dc9357SAndroid Build Coastguard Worker static bool IsCorrectFsName(const UString &name)
275*f6dc9357SAndroid Build Coastguard Worker {
276*f6dc9357SAndroid Build Coastguard Worker const UString lastPart = name.Ptr((unsigned)(name.ReverseFind_PathSepar() + 1));
277*f6dc9357SAndroid Build Coastguard Worker return
278*f6dc9357SAndroid Build Coastguard Worker lastPart != L"." &&
279*f6dc9357SAndroid Build Coastguard Worker lastPart != L"..";
280*f6dc9357SAndroid Build Coastguard Worker }
281*f6dc9357SAndroid Build Coastguard Worker
282*f6dc9357SAndroid Build Coastguard Worker bool CorrectFsPath(const UString &relBase, const UString &path, UString &result);
283*f6dc9357SAndroid Build Coastguard Worker
CorrectFsPath(const UString & path2,UString & result)284*f6dc9357SAndroid Build Coastguard Worker bool CPanel::CorrectFsPath(const UString &path2, UString &result)
285*f6dc9357SAndroid Build Coastguard Worker {
286*f6dc9357SAndroid Build Coastguard Worker return ::CorrectFsPath(GetFsPath(), path2, result);
287*f6dc9357SAndroid Build Coastguard Worker }
288*f6dc9357SAndroid Build Coastguard Worker
OnEndLabelEdit(LV_DISPINFOW * lpnmh)289*f6dc9357SAndroid Build Coastguard Worker BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
290*f6dc9357SAndroid Build Coastguard Worker {
291*f6dc9357SAndroid Build Coastguard Worker if (lpnmh->item.pszText == NULL)
292*f6dc9357SAndroid Build Coastguard Worker return FALSE;
293*f6dc9357SAndroid Build Coastguard Worker CDisableTimerProcessing disableTimerProcessing2(*this);
294*f6dc9357SAndroid Build Coastguard Worker
295*f6dc9357SAndroid Build Coastguard Worker if (!CheckBeforeUpdate(IDS_ERROR_RENAMING))
296*f6dc9357SAndroid Build Coastguard Worker return FALSE;
297*f6dc9357SAndroid Build Coastguard Worker
298*f6dc9357SAndroid Build Coastguard Worker UString newName = lpnmh->item.pszText;
299*f6dc9357SAndroid Build Coastguard Worker if (!IsCorrectFsName(newName))
300*f6dc9357SAndroid Build Coastguard Worker {
301*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_HRESULT(E_INVALIDARG);
302*f6dc9357SAndroid Build Coastguard Worker return FALSE;
303*f6dc9357SAndroid Build Coastguard Worker }
304*f6dc9357SAndroid Build Coastguard Worker
305*f6dc9357SAndroid Build Coastguard Worker if (IsFSFolder())
306*f6dc9357SAndroid Build Coastguard Worker {
307*f6dc9357SAndroid Build Coastguard Worker UString correctName;
308*f6dc9357SAndroid Build Coastguard Worker if (!CorrectFsPath(newName, correctName))
309*f6dc9357SAndroid Build Coastguard Worker {
310*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_HRESULT(E_INVALIDARG);
311*f6dc9357SAndroid Build Coastguard Worker return FALSE;
312*f6dc9357SAndroid Build Coastguard Worker }
313*f6dc9357SAndroid Build Coastguard Worker newName = correctName;
314*f6dc9357SAndroid Build Coastguard Worker }
315*f6dc9357SAndroid Build Coastguard Worker
316*f6dc9357SAndroid Build Coastguard Worker SaveSelectedState(_selectedState);
317*f6dc9357SAndroid Build Coastguard Worker
318*f6dc9357SAndroid Build Coastguard Worker const unsigned realIndex = GetRealIndex(lpnmh->item);
319*f6dc9357SAndroid Build Coastguard Worker if (realIndex == kParentIndex)
320*f6dc9357SAndroid Build Coastguard Worker return FALSE;
321*f6dc9357SAndroid Build Coastguard Worker const UString prefix = GetItemPrefix(realIndex);
322*f6dc9357SAndroid Build Coastguard Worker const UString oldName = GetItemName(realIndex);
323*f6dc9357SAndroid Build Coastguard Worker
324*f6dc9357SAndroid Build Coastguard Worker CDisableNotify disableNotify(*this);
325*f6dc9357SAndroid Build Coastguard Worker {
326*f6dc9357SAndroid Build Coastguard Worker CThreadFolderOperations op(FOLDER_TYPE_RENAME);
327*f6dc9357SAndroid Build Coastguard Worker op.FolderOperations = _folderOperations;
328*f6dc9357SAndroid Build Coastguard Worker op.Index = realIndex;
329*f6dc9357SAndroid Build Coastguard Worker op.Name = newName;
330*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = op.DoOperation(*this,
331*f6dc9357SAndroid Build Coastguard Worker LangString(IDS_RENAMING),
332*f6dc9357SAndroid Build Coastguard Worker LangString(IDS_ERROR_RENAMING));
333*f6dc9357SAndroid Build Coastguard Worker // fixed in 9.26: we refresh list even after errors
334*f6dc9357SAndroid Build Coastguard Worker // (it's more safe, since error can be at different stages, so list can be incorrect).
335*f6dc9357SAndroid Build Coastguard Worker if (res == S_OK)
336*f6dc9357SAndroid Build Coastguard Worker _selectedState.FocusedName = prefix + newName;
337*f6dc9357SAndroid Build Coastguard Worker else
338*f6dc9357SAndroid Build Coastguard Worker {
339*f6dc9357SAndroid Build Coastguard Worker _selectedState.FocusedName = prefix + oldName;
340*f6dc9357SAndroid Build Coastguard Worker // return FALSE;
341*f6dc9357SAndroid Build Coastguard Worker }
342*f6dc9357SAndroid Build Coastguard Worker }
343*f6dc9357SAndroid Build Coastguard Worker
344*f6dc9357SAndroid Build Coastguard Worker // Can't use RefreshListCtrl here.
345*f6dc9357SAndroid Build Coastguard Worker // RefreshListCtrlSaveFocused();
346*f6dc9357SAndroid Build Coastguard Worker _selectedState.FocusedName_Defined = true;
347*f6dc9357SAndroid Build Coastguard Worker _selectedState.SelectFocused = true;
348*f6dc9357SAndroid Build Coastguard Worker
349*f6dc9357SAndroid Build Coastguard Worker // We need clear all items to disable GetText before Reload:
350*f6dc9357SAndroid Build Coastguard Worker // number of items can change.
351*f6dc9357SAndroid Build Coastguard Worker // DeleteListItems();
352*f6dc9357SAndroid Build Coastguard Worker // But seems it can still call GetText (maybe for current item)
353*f6dc9357SAndroid Build Coastguard Worker // so we can't delete items.
354*f6dc9357SAndroid Build Coastguard Worker
355*f6dc9357SAndroid Build Coastguard Worker _dontShowMode = true;
356*f6dc9357SAndroid Build Coastguard Worker
357*f6dc9357SAndroid Build Coastguard Worker PostMsg(kReLoadMessage);
358*f6dc9357SAndroid Build Coastguard Worker return TRUE;
359*f6dc9357SAndroid Build Coastguard Worker }
360*f6dc9357SAndroid Build Coastguard Worker
361*f6dc9357SAndroid Build Coastguard Worker bool Dlg_CreateFolder(HWND wnd, UString &destName);
362*f6dc9357SAndroid Build Coastguard Worker
CreateFolder()363*f6dc9357SAndroid Build Coastguard Worker void CPanel::CreateFolder()
364*f6dc9357SAndroid Build Coastguard Worker {
365*f6dc9357SAndroid Build Coastguard Worker if (IsHashFolder())
366*f6dc9357SAndroid Build Coastguard Worker return;
367*f6dc9357SAndroid Build Coastguard Worker
368*f6dc9357SAndroid Build Coastguard Worker if (!CheckBeforeUpdate(IDS_CREATE_FOLDER_ERROR))
369*f6dc9357SAndroid Build Coastguard Worker return;
370*f6dc9357SAndroid Build Coastguard Worker
371*f6dc9357SAndroid Build Coastguard Worker CDisableTimerProcessing disableTimerProcessing2(*this);
372*f6dc9357SAndroid Build Coastguard Worker CSelectedState state;
373*f6dc9357SAndroid Build Coastguard Worker SaveSelectedState(state);
374*f6dc9357SAndroid Build Coastguard Worker
375*f6dc9357SAndroid Build Coastguard Worker UString newName;
376*f6dc9357SAndroid Build Coastguard Worker if (!Dlg_CreateFolder(GetParent(), newName))
377*f6dc9357SAndroid Build Coastguard Worker return;
378*f6dc9357SAndroid Build Coastguard Worker
379*f6dc9357SAndroid Build Coastguard Worker if (!IsCorrectFsName(newName))
380*f6dc9357SAndroid Build Coastguard Worker {
381*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_HRESULT(E_INVALIDARG);
382*f6dc9357SAndroid Build Coastguard Worker return;
383*f6dc9357SAndroid Build Coastguard Worker }
384*f6dc9357SAndroid Build Coastguard Worker
385*f6dc9357SAndroid Build Coastguard Worker if (IsFSFolder())
386*f6dc9357SAndroid Build Coastguard Worker {
387*f6dc9357SAndroid Build Coastguard Worker UString correctName;
388*f6dc9357SAndroid Build Coastguard Worker if (!CorrectFsPath(newName, correctName))
389*f6dc9357SAndroid Build Coastguard Worker {
390*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_HRESULT(E_INVALIDARG);
391*f6dc9357SAndroid Build Coastguard Worker return;
392*f6dc9357SAndroid Build Coastguard Worker }
393*f6dc9357SAndroid Build Coastguard Worker newName = correctName;
394*f6dc9357SAndroid Build Coastguard Worker }
395*f6dc9357SAndroid Build Coastguard Worker
396*f6dc9357SAndroid Build Coastguard Worker HRESULT res;
397*f6dc9357SAndroid Build Coastguard Worker CDisableNotify disableNotify(*this);
398*f6dc9357SAndroid Build Coastguard Worker {
399*f6dc9357SAndroid Build Coastguard Worker CThreadFolderOperations op(FOLDER_TYPE_CREATE_FOLDER);
400*f6dc9357SAndroid Build Coastguard Worker op.FolderOperations = _folderOperations;
401*f6dc9357SAndroid Build Coastguard Worker op.Name = newName;
402*f6dc9357SAndroid Build Coastguard Worker res = op.DoOperation(*this,
403*f6dc9357SAndroid Build Coastguard Worker LangString(IDS_CREATE_FOLDER),
404*f6dc9357SAndroid Build Coastguard Worker LangString(IDS_CREATE_FOLDER_ERROR));
405*f6dc9357SAndroid Build Coastguard Worker /*
406*f6dc9357SAndroid Build Coastguard Worker // fixed for 9.26: we must refresh always
407*f6dc9357SAndroid Build Coastguard Worker if (res != S_OK)
408*f6dc9357SAndroid Build Coastguard Worker return;
409*f6dc9357SAndroid Build Coastguard Worker */
410*f6dc9357SAndroid Build Coastguard Worker }
411*f6dc9357SAndroid Build Coastguard Worker if (res == S_OK)
412*f6dc9357SAndroid Build Coastguard Worker {
413*f6dc9357SAndroid Build Coastguard Worker int pos = newName.Find(WCHAR_PATH_SEPARATOR);
414*f6dc9357SAndroid Build Coastguard Worker if (pos >= 0)
415*f6dc9357SAndroid Build Coastguard Worker newName.DeleteFrom((unsigned)(pos));
416*f6dc9357SAndroid Build Coastguard Worker if (!_mySelectMode)
417*f6dc9357SAndroid Build Coastguard Worker state.SelectedNames.Clear();
418*f6dc9357SAndroid Build Coastguard Worker state.FocusedName = newName;
419*f6dc9357SAndroid Build Coastguard Worker state.FocusedName_Defined = true;
420*f6dc9357SAndroid Build Coastguard Worker state.SelectFocused = true;
421*f6dc9357SAndroid Build Coastguard Worker }
422*f6dc9357SAndroid Build Coastguard Worker RefreshTitleAlways();
423*f6dc9357SAndroid Build Coastguard Worker RefreshListCtrl(state);
424*f6dc9357SAndroid Build Coastguard Worker }
425*f6dc9357SAndroid Build Coastguard Worker
CreateFile()426*f6dc9357SAndroid Build Coastguard Worker void CPanel::CreateFile()
427*f6dc9357SAndroid Build Coastguard Worker {
428*f6dc9357SAndroid Build Coastguard Worker if (IsHashFolder())
429*f6dc9357SAndroid Build Coastguard Worker return;
430*f6dc9357SAndroid Build Coastguard Worker
431*f6dc9357SAndroid Build Coastguard Worker if (!CheckBeforeUpdate(IDS_CREATE_FILE_ERROR))
432*f6dc9357SAndroid Build Coastguard Worker return;
433*f6dc9357SAndroid Build Coastguard Worker
434*f6dc9357SAndroid Build Coastguard Worker CDisableTimerProcessing disableTimerProcessing2(*this);
435*f6dc9357SAndroid Build Coastguard Worker CSelectedState state;
436*f6dc9357SAndroid Build Coastguard Worker SaveSelectedState(state);
437*f6dc9357SAndroid Build Coastguard Worker CComboDialog dlg;
438*f6dc9357SAndroid Build Coastguard Worker LangString(IDS_CREATE_FILE, dlg.Title);
439*f6dc9357SAndroid Build Coastguard Worker LangString(IDS_CREATE_FILE_NAME, dlg.Static);
440*f6dc9357SAndroid Build Coastguard Worker LangString(IDS_CREATE_FILE_DEFAULT_NAME, dlg.Value);
441*f6dc9357SAndroid Build Coastguard Worker
442*f6dc9357SAndroid Build Coastguard Worker if (dlg.Create(GetParent()) != IDOK)
443*f6dc9357SAndroid Build Coastguard Worker return;
444*f6dc9357SAndroid Build Coastguard Worker
445*f6dc9357SAndroid Build Coastguard Worker CDisableNotify disableNotify(*this);
446*f6dc9357SAndroid Build Coastguard Worker
447*f6dc9357SAndroid Build Coastguard Worker UString newName = dlg.Value;
448*f6dc9357SAndroid Build Coastguard Worker
449*f6dc9357SAndroid Build Coastguard Worker if (IsFSFolder())
450*f6dc9357SAndroid Build Coastguard Worker {
451*f6dc9357SAndroid Build Coastguard Worker UString correctName;
452*f6dc9357SAndroid Build Coastguard Worker if (!CorrectFsPath(newName, correctName))
453*f6dc9357SAndroid Build Coastguard Worker {
454*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_HRESULT(E_INVALIDARG);
455*f6dc9357SAndroid Build Coastguard Worker return;
456*f6dc9357SAndroid Build Coastguard Worker }
457*f6dc9357SAndroid Build Coastguard Worker newName = correctName;
458*f6dc9357SAndroid Build Coastguard Worker }
459*f6dc9357SAndroid Build Coastguard Worker
460*f6dc9357SAndroid Build Coastguard Worker const HRESULT result = _folderOperations->CreateFile(newName, NULL);
461*f6dc9357SAndroid Build Coastguard Worker if (result != S_OK)
462*f6dc9357SAndroid Build Coastguard Worker {
463*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_HRESULT_Caption(result, LangString(IDS_CREATE_FILE_ERROR));
464*f6dc9357SAndroid Build Coastguard Worker // MessageBoxErrorForUpdate(result, IDS_CREATE_FILE_ERROR);
465*f6dc9357SAndroid Build Coastguard Worker return;
466*f6dc9357SAndroid Build Coastguard Worker }
467*f6dc9357SAndroid Build Coastguard Worker const int pos = newName.Find(WCHAR_PATH_SEPARATOR);
468*f6dc9357SAndroid Build Coastguard Worker if (pos >= 0)
469*f6dc9357SAndroid Build Coastguard Worker newName.DeleteFrom((unsigned)pos);
470*f6dc9357SAndroid Build Coastguard Worker if (!_mySelectMode)
471*f6dc9357SAndroid Build Coastguard Worker state.SelectedNames.Clear();
472*f6dc9357SAndroid Build Coastguard Worker state.FocusedName = newName;
473*f6dc9357SAndroid Build Coastguard Worker state.FocusedName_Defined = true;
474*f6dc9357SAndroid Build Coastguard Worker state.SelectFocused = true;
475*f6dc9357SAndroid Build Coastguard Worker RefreshListCtrl(state);
476*f6dc9357SAndroid Build Coastguard Worker }
477*f6dc9357SAndroid Build Coastguard Worker
RenameFile()478*f6dc9357SAndroid Build Coastguard Worker void CPanel::RenameFile()
479*f6dc9357SAndroid Build Coastguard Worker {
480*f6dc9357SAndroid Build Coastguard Worker if (!CheckBeforeUpdate(IDS_ERROR_RENAMING))
481*f6dc9357SAndroid Build Coastguard Worker return;
482*f6dc9357SAndroid Build Coastguard Worker int index = _listView.GetFocusedItem();
483*f6dc9357SAndroid Build Coastguard Worker if (index >= 0)
484*f6dc9357SAndroid Build Coastguard Worker _listView.EditLabel(index);
485*f6dc9357SAndroid Build Coastguard Worker }
486*f6dc9357SAndroid Build Coastguard Worker
ChangeComment()487*f6dc9357SAndroid Build Coastguard Worker void CPanel::ChangeComment()
488*f6dc9357SAndroid Build Coastguard Worker {
489*f6dc9357SAndroid Build Coastguard Worker if (IsHashFolder())
490*f6dc9357SAndroid Build Coastguard Worker return;
491*f6dc9357SAndroid Build Coastguard Worker if (!CheckBeforeUpdate(IDS_COMMENT))
492*f6dc9357SAndroid Build Coastguard Worker return;
493*f6dc9357SAndroid Build Coastguard Worker CDisableTimerProcessing disableTimerProcessing2(*this);
494*f6dc9357SAndroid Build Coastguard Worker const int index = _listView.GetFocusedItem();
495*f6dc9357SAndroid Build Coastguard Worker if (index < 0)
496*f6dc9357SAndroid Build Coastguard Worker return;
497*f6dc9357SAndroid Build Coastguard Worker const unsigned realIndex = GetRealItemIndex(index);
498*f6dc9357SAndroid Build Coastguard Worker if (realIndex == kParentIndex)
499*f6dc9357SAndroid Build Coastguard Worker return;
500*f6dc9357SAndroid Build Coastguard Worker CSelectedState state;
501*f6dc9357SAndroid Build Coastguard Worker SaveSelectedState(state);
502*f6dc9357SAndroid Build Coastguard Worker UString comment;
503*f6dc9357SAndroid Build Coastguard Worker {
504*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant propVariant;
505*f6dc9357SAndroid Build Coastguard Worker if (_folder->GetProperty(realIndex, kpidComment, &propVariant) != S_OK)
506*f6dc9357SAndroid Build Coastguard Worker return;
507*f6dc9357SAndroid Build Coastguard Worker if (propVariant.vt == VT_BSTR)
508*f6dc9357SAndroid Build Coastguard Worker comment = propVariant.bstrVal;
509*f6dc9357SAndroid Build Coastguard Worker else if (propVariant.vt != VT_EMPTY)
510*f6dc9357SAndroid Build Coastguard Worker return;
511*f6dc9357SAndroid Build Coastguard Worker }
512*f6dc9357SAndroid Build Coastguard Worker const UString name = GetItemRelPath2(realIndex);
513*f6dc9357SAndroid Build Coastguard Worker CComboDialog dlg;
514*f6dc9357SAndroid Build Coastguard Worker dlg.Title = name;
515*f6dc9357SAndroid Build Coastguard Worker dlg.Title += " : ";
516*f6dc9357SAndroid Build Coastguard Worker AddLangString(dlg.Title, IDS_COMMENT);
517*f6dc9357SAndroid Build Coastguard Worker dlg.Value = comment;
518*f6dc9357SAndroid Build Coastguard Worker LangString(IDS_COMMENT2, dlg.Static);
519*f6dc9357SAndroid Build Coastguard Worker if (dlg.Create(GetParent()) != IDOK)
520*f6dc9357SAndroid Build Coastguard Worker return;
521*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant propVariant (dlg.Value);
522*f6dc9357SAndroid Build Coastguard Worker
523*f6dc9357SAndroid Build Coastguard Worker CDisableNotify disableNotify(*this);
524*f6dc9357SAndroid Build Coastguard Worker const HRESULT result = _folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL);
525*f6dc9357SAndroid Build Coastguard Worker if (result != S_OK)
526*f6dc9357SAndroid Build Coastguard Worker {
527*f6dc9357SAndroid Build Coastguard Worker if (result == E_NOINTERFACE)
528*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_UnsupportOperation();
529*f6dc9357SAndroid Build Coastguard Worker else
530*f6dc9357SAndroid Build Coastguard Worker MessageBox_Error_HRESULT_Caption(result, L"Set Comment Error");
531*f6dc9357SAndroid Build Coastguard Worker }
532*f6dc9357SAndroid Build Coastguard Worker RefreshListCtrl(state);
533*f6dc9357SAndroid Build Coastguard Worker }
534