xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/BrowseDialog.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // BrowseDialog.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/MyWindows.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
10*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/CommonDialog.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/Shell.h"
12*f6dc9357SAndroid Build Coastguard Worker #endif
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileFind.h"
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker #ifdef UNDER_CE
18*f6dc9357SAndroid Build Coastguard Worker #include <commdlg.h>
19*f6dc9357SAndroid Build Coastguard Worker #endif
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker #include "BrowseDialog.h"
22*f6dc9357SAndroid Build Coastguard Worker 
23*f6dc9357SAndroid Build Coastguard Worker #define USE_MY_BROWSE_DIALOG
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MY_BROWSE_DIALOG
26*f6dc9357SAndroid Build Coastguard Worker 
27*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Defs.h"
28*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/Wildcard.h"
29*f6dc9357SAndroid Build Coastguard Worker 
30*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
31*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariantConv.h"
32*f6dc9357SAndroid Build Coastguard Worker 
33*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/Control/ComboBox.h"
34*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/Control/Dialog.h"
35*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/Control/Edit.h"
36*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/Control/ListView.h"
37*f6dc9357SAndroid Build Coastguard Worker 
38*f6dc9357SAndroid Build Coastguard Worker #include "BrowseDialogRes.h"
39*f6dc9357SAndroid Build Coastguard Worker #include "PropertyNameRes.h"
40*f6dc9357SAndroid Build Coastguard Worker #include "SysIconUtils.h"
41*f6dc9357SAndroid Build Coastguard Worker 
42*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
43*f6dc9357SAndroid Build Coastguard Worker #include "RegistryUtils.h"
44*f6dc9357SAndroid Build Coastguard Worker #endif
45*f6dc9357SAndroid Build Coastguard Worker 
46*f6dc9357SAndroid Build Coastguard Worker #endif // USE_MY_BROWSE_DIALOG
47*f6dc9357SAndroid Build Coastguard Worker 
48*f6dc9357SAndroid Build Coastguard Worker #include "ComboDialog.h"
49*f6dc9357SAndroid Build Coastguard Worker #include "LangUtils.h"
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker #include "resource.h"
52*f6dc9357SAndroid Build Coastguard Worker 
53*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
54*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
55*f6dc9357SAndroid Build Coastguard Worker using namespace NName;
56*f6dc9357SAndroid Build Coastguard Worker using namespace NFind;
57*f6dc9357SAndroid Build Coastguard Worker 
MessageBox_Error_Global(HWND wnd,const wchar_t * message)58*f6dc9357SAndroid Build Coastguard Worker static void MessageBox_Error_Global(HWND wnd, const wchar_t *message)
59*f6dc9357SAndroid Build Coastguard Worker {
60*f6dc9357SAndroid Build Coastguard Worker   ::MessageBoxW(wnd, message, L"7-Zip", MB_ICONERROR);
61*f6dc9357SAndroid Build Coastguard Worker }
62*f6dc9357SAndroid Build Coastguard Worker 
63*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MY_BROWSE_DIALOG
64*f6dc9357SAndroid Build Coastguard Worker 
65*f6dc9357SAndroid Build Coastguard Worker #if 0
66*f6dc9357SAndroid Build Coastguard Worker extern HINSTANCE g_hInstance;
67*f6dc9357SAndroid Build Coastguard Worker #endif
68*f6dc9357SAndroid Build Coastguard Worker extern bool g_LVN_ITEMACTIVATE_Support;
69*f6dc9357SAndroid Build Coastguard Worker 
70*f6dc9357SAndroid Build Coastguard Worker static const int kParentIndex = -1;
71*f6dc9357SAndroid Build Coastguard Worker static const UINT k_Message_RefreshPathEdit = WM_APP + 1;
72*f6dc9357SAndroid Build Coastguard Worker 
73*f6dc9357SAndroid Build Coastguard Worker extern UString HResultToMessage(HRESULT errorCode);
74*f6dc9357SAndroid Build Coastguard Worker 
MessageBox_HResError(HWND wnd,HRESULT errorCode,const wchar_t * name)75*f6dc9357SAndroid Build Coastguard Worker static void MessageBox_HResError(HWND wnd, HRESULT errorCode, const wchar_t *name)
76*f6dc9357SAndroid Build Coastguard Worker {
77*f6dc9357SAndroid Build Coastguard Worker   UString s = HResultToMessage(errorCode);
78*f6dc9357SAndroid Build Coastguard Worker   if (name)
79*f6dc9357SAndroid Build Coastguard Worker   {
80*f6dc9357SAndroid Build Coastguard Worker     s.Add_LF();
81*f6dc9357SAndroid Build Coastguard Worker     s += name;
82*f6dc9357SAndroid Build Coastguard Worker   }
83*f6dc9357SAndroid Build Coastguard Worker   MessageBox_Error_Global(wnd, s);
84*f6dc9357SAndroid Build Coastguard Worker }
85*f6dc9357SAndroid Build Coastguard Worker 
86*f6dc9357SAndroid Build Coastguard Worker class CBrowseDialog: public NControl::CModalDialog
87*f6dc9357SAndroid Build Coastguard Worker {
88*f6dc9357SAndroid Build Coastguard Worker   NControl::CListView _list;
89*f6dc9357SAndroid Build Coastguard Worker   NControl::CEdit _pathEdit;
90*f6dc9357SAndroid Build Coastguard Worker   NControl::CComboBox _filterCombo;
91*f6dc9357SAndroid Build Coastguard Worker 
92*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CFileInfo> _files;
93*f6dc9357SAndroid Build Coastguard Worker 
94*f6dc9357SAndroid Build Coastguard Worker   CExtToIconMap _extToIconMap;
95*f6dc9357SAndroid Build Coastguard Worker   int _sortIndex;
96*f6dc9357SAndroid Build Coastguard Worker   bool _ascending;
97*f6dc9357SAndroid Build Coastguard Worker  #ifndef Z7_SFX
98*f6dc9357SAndroid Build Coastguard Worker   bool _showDots;
99*f6dc9357SAndroid Build Coastguard Worker  #endif
100*f6dc9357SAndroid Build Coastguard Worker   UString _topDirPrefix; // we don't open parent of that folder
101*f6dc9357SAndroid Build Coastguard Worker   UString DirPrefix;
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker   virtual bool OnInit() Z7_override;
104*f6dc9357SAndroid Build Coastguard Worker   virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override;
105*f6dc9357SAndroid Build Coastguard Worker   virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override;
106*f6dc9357SAndroid Build Coastguard Worker   virtual bool OnNotify(UINT controlID, LPNMHDR header) Z7_override;
107*f6dc9357SAndroid Build Coastguard Worker   virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override;
108*f6dc9357SAndroid Build Coastguard Worker   virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override;
109*f6dc9357SAndroid Build Coastguard Worker   virtual void OnOK() Z7_override;
110*f6dc9357SAndroid Build Coastguard Worker 
111*f6dc9357SAndroid Build Coastguard Worker   bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo);
112*f6dc9357SAndroid Build Coastguard Worker 
Post_RefreshPathEdit()113*f6dc9357SAndroid Build Coastguard Worker   void Post_RefreshPathEdit() { PostMsg(k_Message_RefreshPathEdit); }
114*f6dc9357SAndroid Build Coastguard Worker 
115*f6dc9357SAndroid Build Coastguard Worker   bool GetParentPath(const UString &path, UString &parentPrefix, UString &name);
116*f6dc9357SAndroid Build Coastguard Worker   // Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter
117*f6dc9357SAndroid Build Coastguard Worker   HRESULT Reload(const UString &pathPrefix, const UString &selectedName);
118*f6dc9357SAndroid Build Coastguard Worker   HRESULT Reload();
119*f6dc9357SAndroid Build Coastguard Worker 
120*f6dc9357SAndroid Build Coastguard Worker   void OpenParentFolder();
121*f6dc9357SAndroid Build Coastguard Worker   void SetPathEditText();
122*f6dc9357SAndroid Build Coastguard Worker   void OnCreateDir();
123*f6dc9357SAndroid Build Coastguard Worker   void OnItemEnter();
124*f6dc9357SAndroid Build Coastguard Worker   void FinishOnOK();
125*f6dc9357SAndroid Build Coastguard Worker 
GetRealItemIndex(int indexInListView) const126*f6dc9357SAndroid Build Coastguard Worker   int GetRealItemIndex(int indexInListView) const
127*f6dc9357SAndroid Build Coastguard Worker   {
128*f6dc9357SAndroid Build Coastguard Worker     LPARAM param;
129*f6dc9357SAndroid Build Coastguard Worker     if (!_list.GetItemParam((unsigned)indexInListView, param))
130*f6dc9357SAndroid Build Coastguard Worker       return (int)-1;
131*f6dc9357SAndroid Build Coastguard Worker     return (int)param;
132*f6dc9357SAndroid Build Coastguard Worker   }
133*f6dc9357SAndroid Build Coastguard Worker 
134*f6dc9357SAndroid Build Coastguard Worker public:
135*f6dc9357SAndroid Build Coastguard Worker 
136*f6dc9357SAndroid Build Coastguard Worker   bool SaveMode;
137*f6dc9357SAndroid Build Coastguard Worker   bool FolderMode;
138*f6dc9357SAndroid Build Coastguard Worker   int FilterIndex;  // [in / out]
139*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CBrowseFilterInfo> Filters;
140*f6dc9357SAndroid Build Coastguard Worker 
141*f6dc9357SAndroid Build Coastguard Worker   UString FilePath;   // [in / out]
142*f6dc9357SAndroid Build Coastguard Worker   UString Title;
143*f6dc9357SAndroid Build Coastguard Worker 
CBrowseDialog()144*f6dc9357SAndroid Build Coastguard Worker   CBrowseDialog():
145*f6dc9357SAndroid Build Coastguard Worker    #ifndef Z7_SFX
146*f6dc9357SAndroid Build Coastguard Worker       _showDots(false),
147*f6dc9357SAndroid Build Coastguard Worker    #endif
148*f6dc9357SAndroid Build Coastguard Worker       SaveMode(false)
149*f6dc9357SAndroid Build Coastguard Worker       , FolderMode(false)
150*f6dc9357SAndroid Build Coastguard Worker       , FilterIndex(-1)
151*f6dc9357SAndroid Build Coastguard Worker     {}
Create(HWND parent=NULL)152*f6dc9357SAndroid Build Coastguard Worker   INT_PTR Create(HWND parent = NULL) { return CModalDialog::Create(IDD_BROWSE, parent); }
153*f6dc9357SAndroid Build Coastguard Worker   int CompareItems(LPARAM lParam1, LPARAM lParam2) const;
154*f6dc9357SAndroid Build Coastguard Worker };
155*f6dc9357SAndroid Build Coastguard Worker 
156*f6dc9357SAndroid Build Coastguard Worker 
OnInit()157*f6dc9357SAndroid Build Coastguard Worker bool CBrowseDialog::OnInit()
158*f6dc9357SAndroid Build Coastguard Worker {
159*f6dc9357SAndroid Build Coastguard Worker   #ifdef Z7_LANG
160*f6dc9357SAndroid Build Coastguard Worker   LangSetDlgItems(*this, NULL, 0);
161*f6dc9357SAndroid Build Coastguard Worker   #endif
162*f6dc9357SAndroid Build Coastguard Worker   if (!Title.IsEmpty())
163*f6dc9357SAndroid Build Coastguard Worker     SetText(Title);
164*f6dc9357SAndroid Build Coastguard Worker   _list.Attach(GetItem(IDL_BROWSE));
165*f6dc9357SAndroid Build Coastguard Worker   _filterCombo.Attach(GetItem(IDC_BROWSE_FILTER));
166*f6dc9357SAndroid Build Coastguard Worker   _pathEdit.Attach(GetItem(IDE_BROWSE_PATH));
167*f6dc9357SAndroid Build Coastguard Worker 
168*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
169*f6dc9357SAndroid Build Coastguard Worker   _list.SetUnicodeFormat();
170*f6dc9357SAndroid Build Coastguard Worker   #endif
171*f6dc9357SAndroid Build Coastguard Worker 
172*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_SFX
173*f6dc9357SAndroid Build Coastguard Worker   CFmSettings st;
174*f6dc9357SAndroid Build Coastguard Worker   st.Load();
175*f6dc9357SAndroid Build Coastguard Worker   if (st.SingleClick)
176*f6dc9357SAndroid Build Coastguard Worker     _list.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT);
177*f6dc9357SAndroid Build Coastguard Worker   _showDots = st.ShowDots;
178*f6dc9357SAndroid Build Coastguard Worker   #endif
179*f6dc9357SAndroid Build Coastguard Worker 
180*f6dc9357SAndroid Build Coastguard Worker   {
181*f6dc9357SAndroid Build Coastguard Worker     /*
182*f6dc9357SAndroid Build Coastguard Worker     Filters.Clear(); // for debug
183*f6dc9357SAndroid Build Coastguard Worker     if (Filters.IsEmpty() && !FolderMode)
184*f6dc9357SAndroid Build Coastguard Worker     {
185*f6dc9357SAndroid Build Coastguard Worker       CBrowseFilterInfo &f = Filters.AddNew();
186*f6dc9357SAndroid Build Coastguard Worker       const UString mask("*.*");
187*f6dc9357SAndroid Build Coastguard Worker       f.Masks.Add(mask);
188*f6dc9357SAndroid Build Coastguard Worker       // f.Description = "(";
189*f6dc9357SAndroid Build Coastguard Worker       f.Description += mask;
190*f6dc9357SAndroid Build Coastguard Worker       // f.Description += ")";
191*f6dc9357SAndroid Build Coastguard Worker     }
192*f6dc9357SAndroid Build Coastguard Worker     */
193*f6dc9357SAndroid Build Coastguard Worker 
194*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, Filters)
195*f6dc9357SAndroid Build Coastguard Worker     {
196*f6dc9357SAndroid Build Coastguard Worker       _filterCombo.AddString(Filters[i].Description);
197*f6dc9357SAndroid Build Coastguard Worker     }
198*f6dc9357SAndroid Build Coastguard Worker 
199*f6dc9357SAndroid Build Coastguard Worker     if (Filters.Size() <= 1)
200*f6dc9357SAndroid Build Coastguard Worker     {
201*f6dc9357SAndroid Build Coastguard Worker       if (FolderMode)
202*f6dc9357SAndroid Build Coastguard Worker         HideItem(IDC_BROWSE_FILTER);
203*f6dc9357SAndroid Build Coastguard Worker       else
204*f6dc9357SAndroid Build Coastguard Worker         EnableItem(IDC_BROWSE_FILTER, false);
205*f6dc9357SAndroid Build Coastguard Worker     }
206*f6dc9357SAndroid Build Coastguard Worker 
207*f6dc9357SAndroid Build Coastguard Worker     if (/* FilterIndex >= 0 && */ (unsigned)FilterIndex < Filters.Size())
208*f6dc9357SAndroid Build Coastguard Worker       _filterCombo.SetCurSel(FilterIndex);
209*f6dc9357SAndroid Build Coastguard Worker   }
210*f6dc9357SAndroid Build Coastguard Worker 
211*f6dc9357SAndroid Build Coastguard Worker   _list.SetImageList(Shell_Get_SysImageList_smallIcons(true), LVSIL_SMALL);
212*f6dc9357SAndroid Build Coastguard Worker   _list.SetImageList(Shell_Get_SysImageList_smallIcons(false), LVSIL_NORMAL);
213*f6dc9357SAndroid Build Coastguard Worker 
214*f6dc9357SAndroid Build Coastguard Worker   _list.InsertColumn(0, LangString(IDS_PROP_NAME), 100);
215*f6dc9357SAndroid Build Coastguard Worker   _list.InsertColumn(1, LangString(IDS_PROP_MTIME), 100);
216*f6dc9357SAndroid Build Coastguard Worker   {
217*f6dc9357SAndroid Build Coastguard Worker     LV_COLUMNW column;
218*f6dc9357SAndroid Build Coastguard Worker     column.iSubItem = 2;
219*f6dc9357SAndroid Build Coastguard Worker     column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
220*f6dc9357SAndroid Build Coastguard Worker     column.fmt = LVCFMT_RIGHT;
221*f6dc9357SAndroid Build Coastguard Worker     column.cx = 100;
222*f6dc9357SAndroid Build Coastguard Worker     const UString s = LangString(IDS_PROP_SIZE);
223*f6dc9357SAndroid Build Coastguard Worker     column.pszText = s.Ptr_non_const();
224*f6dc9357SAndroid Build Coastguard Worker     _list.InsertColumn(2, &column);
225*f6dc9357SAndroid Build Coastguard Worker   }
226*f6dc9357SAndroid Build Coastguard Worker 
227*f6dc9357SAndroid Build Coastguard Worker   _list.InsertItem(0, L"12345678901234567"
228*f6dc9357SAndroid Build Coastguard Worker       #ifndef UNDER_CE
229*f6dc9357SAndroid Build Coastguard Worker       L"1234567890"
230*f6dc9357SAndroid Build Coastguard Worker       #endif
231*f6dc9357SAndroid Build Coastguard Worker       );
232*f6dc9357SAndroid Build Coastguard Worker   _list.SetSubItem(0, 1, L"2009-09-09"
233*f6dc9357SAndroid Build Coastguard Worker       #ifndef UNDER_CE
234*f6dc9357SAndroid Build Coastguard Worker       L" 09:09"
235*f6dc9357SAndroid Build Coastguard Worker       #endif
236*f6dc9357SAndroid Build Coastguard Worker       );
237*f6dc9357SAndroid Build Coastguard Worker   _list.SetSubItem(0, 2, L"9999 MB");
238*f6dc9357SAndroid Build Coastguard Worker   for (int i = 0; i < 3; i++)
239*f6dc9357SAndroid Build Coastguard Worker     _list.SetColumnWidthAuto(i);
240*f6dc9357SAndroid Build Coastguard Worker   _list.DeleteAllItems();
241*f6dc9357SAndroid Build Coastguard Worker 
242*f6dc9357SAndroid Build Coastguard Worker   _ascending = true;
243*f6dc9357SAndroid Build Coastguard Worker   _sortIndex = 0;
244*f6dc9357SAndroid Build Coastguard Worker 
245*f6dc9357SAndroid Build Coastguard Worker   NormalizeSize();
246*f6dc9357SAndroid Build Coastguard Worker 
247*f6dc9357SAndroid Build Coastguard Worker   _topDirPrefix.Empty();
248*f6dc9357SAndroid Build Coastguard Worker   {
249*f6dc9357SAndroid Build Coastguard Worker     unsigned rootSize = GetRootPrefixSize(FilePath);
250*f6dc9357SAndroid Build Coastguard Worker     #if defined(_WIN32) && !defined(UNDER_CE)
251*f6dc9357SAndroid Build Coastguard Worker     // We can go up from root folder to drives list
252*f6dc9357SAndroid Build Coastguard Worker     if (IsDrivePath(FilePath))
253*f6dc9357SAndroid Build Coastguard Worker       rootSize = 0;
254*f6dc9357SAndroid Build Coastguard Worker     else if (IsSuperPath(FilePath))
255*f6dc9357SAndroid Build Coastguard Worker     {
256*f6dc9357SAndroid Build Coastguard Worker       if (IsDrivePath(FilePath.Ptr(kSuperPathPrefixSize)))
257*f6dc9357SAndroid Build Coastguard Worker         rootSize = kSuperPathPrefixSize;
258*f6dc9357SAndroid Build Coastguard Worker     }
259*f6dc9357SAndroid Build Coastguard Worker     #endif
260*f6dc9357SAndroid Build Coastguard Worker     _topDirPrefix.SetFrom(FilePath, rootSize);
261*f6dc9357SAndroid Build Coastguard Worker   }
262*f6dc9357SAndroid Build Coastguard Worker 
263*f6dc9357SAndroid Build Coastguard Worker   UString name;
264*f6dc9357SAndroid Build Coastguard Worker   if (!GetParentPath(FilePath, DirPrefix, name))
265*f6dc9357SAndroid Build Coastguard Worker     DirPrefix = _topDirPrefix;
266*f6dc9357SAndroid Build Coastguard Worker 
267*f6dc9357SAndroid Build Coastguard Worker   for (;;)
268*f6dc9357SAndroid Build Coastguard Worker   {
269*f6dc9357SAndroid Build Coastguard Worker     UString baseFolder = DirPrefix;
270*f6dc9357SAndroid Build Coastguard Worker     if (Reload(baseFolder, name) == S_OK)
271*f6dc9357SAndroid Build Coastguard Worker       break;
272*f6dc9357SAndroid Build Coastguard Worker     name.Empty();
273*f6dc9357SAndroid Build Coastguard Worker     if (DirPrefix.IsEmpty())
274*f6dc9357SAndroid Build Coastguard Worker       break;
275*f6dc9357SAndroid Build Coastguard Worker     UString parent, name2;
276*f6dc9357SAndroid Build Coastguard Worker     GetParentPath(DirPrefix, parent, name2);
277*f6dc9357SAndroid Build Coastguard Worker     DirPrefix = parent;
278*f6dc9357SAndroid Build Coastguard Worker   }
279*f6dc9357SAndroid Build Coastguard Worker 
280*f6dc9357SAndroid Build Coastguard Worker   if (name.IsEmpty())
281*f6dc9357SAndroid Build Coastguard Worker     name = FilePath;
282*f6dc9357SAndroid Build Coastguard Worker   if (FolderMode)
283*f6dc9357SAndroid Build Coastguard Worker     NormalizeDirPathPrefix(name);
284*f6dc9357SAndroid Build Coastguard Worker   _pathEdit.SetText(name);
285*f6dc9357SAndroid Build Coastguard Worker 
286*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
287*f6dc9357SAndroid Build Coastguard Worker   /* If we clear UISF_HIDEFOCUS, the focus rectangle in ListView will be visible,
288*f6dc9357SAndroid Build Coastguard Worker      even if we use mouse for pressing the button to open this dialog. */
289*f6dc9357SAndroid Build Coastguard Worker   PostMsg(Z7_WIN_WM_UPDATEUISTATE, MAKEWPARAM(Z7_WIN_UIS_CLEAR, Z7_WIN_UISF_HIDEFOCUS));
290*f6dc9357SAndroid Build Coastguard Worker   #endif
291*f6dc9357SAndroid Build Coastguard Worker 
292*f6dc9357SAndroid Build Coastguard Worker #if 0
293*f6dc9357SAndroid Build Coastguard Worker   {
294*f6dc9357SAndroid Build Coastguard Worker     const HWND hwndTool = GetItem(IDB_BROWSE_CREATE_DIR);
295*f6dc9357SAndroid Build Coastguard Worker     if (hwndTool)
296*f6dc9357SAndroid Build Coastguard Worker     {
297*f6dc9357SAndroid Build Coastguard Worker       // Create the tooltip:
298*f6dc9357SAndroid Build Coastguard Worker       const HWND hwndTip = CreateWindowEx(0, TOOLTIPS_CLASS, NULL,
299*f6dc9357SAndroid Build Coastguard Worker           WS_POPUP | TTS_ALWAYSTIP
300*f6dc9357SAndroid Build Coastguard Worker           // | TTS_BALLOON
301*f6dc9357SAndroid Build Coastguard Worker           , CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
302*f6dc9357SAndroid Build Coastguard Worker           *this, NULL, g_hInstance, NULL);
303*f6dc9357SAndroid Build Coastguard Worker       if (hwndTip)
304*f6dc9357SAndroid Build Coastguard Worker       {
305*f6dc9357SAndroid Build Coastguard Worker         // Associate the tooltip with the tool:
306*f6dc9357SAndroid Build Coastguard Worker         TOOLINFOW toolInfo;
307*f6dc9357SAndroid Build Coastguard Worker         memset(&toolInfo, 0, sizeof(toolInfo));
308*f6dc9357SAndroid Build Coastguard Worker         toolInfo.cbSize = sizeof(toolInfo);
309*f6dc9357SAndroid Build Coastguard Worker         toolInfo.hwnd = *this;
310*f6dc9357SAndroid Build Coastguard Worker         toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
311*f6dc9357SAndroid Build Coastguard Worker         toolInfo.uId = (UINT_PTR)hwndTool;
312*f6dc9357SAndroid Build Coastguard Worker         UString s;
313*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LANG
314*f6dc9357SAndroid Build Coastguard Worker         LangString_OnlyFromLangFile(IDM_CREATE_FOLDER, s);
315*f6dc9357SAndroid Build Coastguard Worker         s.RemoveChar(L'&');
316*f6dc9357SAndroid Build Coastguard Worker         if (s.IsEmpty())
317*f6dc9357SAndroid Build Coastguard Worker #endif
318*f6dc9357SAndroid Build Coastguard Worker           s = "Create Folder";
319*f6dc9357SAndroid Build Coastguard Worker         toolInfo.lpszText = s.Ptr_non_const();
320*f6dc9357SAndroid Build Coastguard Worker         SendMessage(hwndTip, TTM_ADDTOOLW, 0, (LPARAM)&toolInfo);
321*f6dc9357SAndroid Build Coastguard Worker       }
322*f6dc9357SAndroid Build Coastguard Worker     }
323*f6dc9357SAndroid Build Coastguard Worker   }
324*f6dc9357SAndroid Build Coastguard Worker #endif
325*f6dc9357SAndroid Build Coastguard Worker   return CModalDialog::OnInit();
326*f6dc9357SAndroid Build Coastguard Worker }
327*f6dc9357SAndroid Build Coastguard Worker 
OnSize(WPARAM,int xSize,int ySize)328*f6dc9357SAndroid Build Coastguard Worker bool CBrowseDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
329*f6dc9357SAndroid Build Coastguard Worker {
330*f6dc9357SAndroid Build Coastguard Worker   int mx, my;
331*f6dc9357SAndroid Build Coastguard Worker   {
332*f6dc9357SAndroid Build Coastguard Worker     RECT r;
333*f6dc9357SAndroid Build Coastguard Worker     GetClientRectOfItem(IDB_BROWSE_PARENT, r);
334*f6dc9357SAndroid Build Coastguard Worker     mx = r.left;
335*f6dc9357SAndroid Build Coastguard Worker     my = r.top;
336*f6dc9357SAndroid Build Coastguard Worker   }
337*f6dc9357SAndroid Build Coastguard Worker   InvalidateRect(NULL);
338*f6dc9357SAndroid Build Coastguard Worker 
339*f6dc9357SAndroid Build Coastguard Worker   int xLim = xSize - mx;
340*f6dc9357SAndroid Build Coastguard Worker   {
341*f6dc9357SAndroid Build Coastguard Worker     RECT r;
342*f6dc9357SAndroid Build Coastguard Worker     GetClientRectOfItem(IDT_BROWSE_FOLDER, r);
343*f6dc9357SAndroid Build Coastguard Worker     MoveItem(IDT_BROWSE_FOLDER, r.left, r.top, xLim - r.left, RECT_SIZE_Y(r));
344*f6dc9357SAndroid Build Coastguard Worker   }
345*f6dc9357SAndroid Build Coastguard Worker 
346*f6dc9357SAndroid Build Coastguard Worker   int bx1, bx2, by;
347*f6dc9357SAndroid Build Coastguard Worker   GetItemSizes(IDCANCEL, bx1, by);
348*f6dc9357SAndroid Build Coastguard Worker   GetItemSizes(IDOK, bx2, by);
349*f6dc9357SAndroid Build Coastguard Worker   int y = ySize - my - by;
350*f6dc9357SAndroid Build Coastguard Worker   int x = xLim - bx1;
351*f6dc9357SAndroid Build Coastguard Worker   MoveItem(IDCANCEL, x, y, bx1, by);
352*f6dc9357SAndroid Build Coastguard Worker   MoveItem(IDOK, x - mx - bx2, y, bx2, by);
353*f6dc9357SAndroid Build Coastguard Worker 
354*f6dc9357SAndroid Build Coastguard Worker   // Y_Size of ComboBox is tricky. So we use Y_Size of _pathEdit instead
355*f6dc9357SAndroid Build Coastguard Worker 
356*f6dc9357SAndroid Build Coastguard Worker   int yPathSize;
357*f6dc9357SAndroid Build Coastguard Worker   {
358*f6dc9357SAndroid Build Coastguard Worker     RECT r;
359*f6dc9357SAndroid Build Coastguard Worker     GetClientRectOfItem(IDE_BROWSE_PATH, r);
360*f6dc9357SAndroid Build Coastguard Worker     yPathSize = RECT_SIZE_Y(r);
361*f6dc9357SAndroid Build Coastguard Worker     _pathEdit.Move(r.left, y - my - yPathSize - my - yPathSize, xLim - r.left, yPathSize);
362*f6dc9357SAndroid Build Coastguard Worker   }
363*f6dc9357SAndroid Build Coastguard Worker 
364*f6dc9357SAndroid Build Coastguard Worker   {
365*f6dc9357SAndroid Build Coastguard Worker     RECT r;
366*f6dc9357SAndroid Build Coastguard Worker     GetClientRectOfItem(IDC_BROWSE_FILTER, r);
367*f6dc9357SAndroid Build Coastguard Worker     _filterCombo.Move(r.left, y - my - yPathSize, xLim - r.left, RECT_SIZE_Y(r));
368*f6dc9357SAndroid Build Coastguard Worker   }
369*f6dc9357SAndroid Build Coastguard Worker 
370*f6dc9357SAndroid Build Coastguard Worker   {
371*f6dc9357SAndroid Build Coastguard Worker     RECT r;
372*f6dc9357SAndroid Build Coastguard Worker     GetClientRectOfItem(IDL_BROWSE, r);
373*f6dc9357SAndroid Build Coastguard Worker     _list.Move(r.left, r.top, xLim - r.left, y - my - yPathSize - my - yPathSize - my - r.top);
374*f6dc9357SAndroid Build Coastguard Worker   }
375*f6dc9357SAndroid Build Coastguard Worker 
376*f6dc9357SAndroid Build Coastguard Worker   return false;
377*f6dc9357SAndroid Build Coastguard Worker }
378*f6dc9357SAndroid Build Coastguard Worker 
OnMessage(UINT message,WPARAM wParam,LPARAM lParam)379*f6dc9357SAndroid Build Coastguard Worker bool CBrowseDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
380*f6dc9357SAndroid Build Coastguard Worker {
381*f6dc9357SAndroid Build Coastguard Worker   if (message == k_Message_RefreshPathEdit)
382*f6dc9357SAndroid Build Coastguard Worker   {
383*f6dc9357SAndroid Build Coastguard Worker     SetPathEditText();
384*f6dc9357SAndroid Build Coastguard Worker     return true;
385*f6dc9357SAndroid Build Coastguard Worker   }
386*f6dc9357SAndroid Build Coastguard Worker   return CModalDialog::OnMessage(message, wParam, lParam);
387*f6dc9357SAndroid Build Coastguard Worker }
388*f6dc9357SAndroid Build Coastguard Worker 
389*f6dc9357SAndroid Build Coastguard Worker 
OnCommand(unsigned code,unsigned itemID,LPARAM lParam)390*f6dc9357SAndroid Build Coastguard Worker bool CBrowseDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam)
391*f6dc9357SAndroid Build Coastguard Worker {
392*f6dc9357SAndroid Build Coastguard Worker   if (code == CBN_SELCHANGE)
393*f6dc9357SAndroid Build Coastguard Worker   {
394*f6dc9357SAndroid Build Coastguard Worker     switch (itemID)
395*f6dc9357SAndroid Build Coastguard Worker     {
396*f6dc9357SAndroid Build Coastguard Worker       case IDC_BROWSE_FILTER:
397*f6dc9357SAndroid Build Coastguard Worker       {
398*f6dc9357SAndroid Build Coastguard Worker         Reload();
399*f6dc9357SAndroid Build Coastguard Worker         return true;
400*f6dc9357SAndroid Build Coastguard Worker       }
401*f6dc9357SAndroid Build Coastguard Worker     }
402*f6dc9357SAndroid Build Coastguard Worker   }
403*f6dc9357SAndroid Build Coastguard Worker   return CModalDialog::OnCommand(code, itemID, lParam);
404*f6dc9357SAndroid Build Coastguard Worker }
405*f6dc9357SAndroid Build Coastguard Worker 
406*f6dc9357SAndroid Build Coastguard Worker 
OnNotify(UINT,LPNMHDR header)407*f6dc9357SAndroid Build Coastguard Worker bool CBrowseDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
408*f6dc9357SAndroid Build Coastguard Worker {
409*f6dc9357SAndroid Build Coastguard Worker   if (header->hwndFrom != _list)
410*f6dc9357SAndroid Build Coastguard Worker     return false;
411*f6dc9357SAndroid Build Coastguard Worker   switch (header->code)
412*f6dc9357SAndroid Build Coastguard Worker   {
413*f6dc9357SAndroid Build Coastguard Worker     case LVN_ITEMACTIVATE:
414*f6dc9357SAndroid Build Coastguard Worker       if (g_LVN_ITEMACTIVATE_Support)
415*f6dc9357SAndroid Build Coastguard Worker         OnItemEnter();
416*f6dc9357SAndroid Build Coastguard Worker       break;
417*f6dc9357SAndroid Build Coastguard Worker     case NM_DBLCLK:
418*f6dc9357SAndroid Build Coastguard Worker     case NM_RETURN: // probably it's unused
419*f6dc9357SAndroid Build Coastguard Worker       if (!g_LVN_ITEMACTIVATE_Support)
420*f6dc9357SAndroid Build Coastguard Worker         OnItemEnter();
421*f6dc9357SAndroid Build Coastguard Worker       break;
422*f6dc9357SAndroid Build Coastguard Worker     case LVN_COLUMNCLICK:
423*f6dc9357SAndroid Build Coastguard Worker     {
424*f6dc9357SAndroid Build Coastguard Worker       const int index = LPNMLISTVIEW(header)->iSubItem;
425*f6dc9357SAndroid Build Coastguard Worker       if (index == _sortIndex)
426*f6dc9357SAndroid Build Coastguard Worker         _ascending = !_ascending;
427*f6dc9357SAndroid Build Coastguard Worker       else
428*f6dc9357SAndroid Build Coastguard Worker       {
429*f6dc9357SAndroid Build Coastguard Worker         _ascending = (index == 0);
430*f6dc9357SAndroid Build Coastguard Worker         _sortIndex = index;
431*f6dc9357SAndroid Build Coastguard Worker       }
432*f6dc9357SAndroid Build Coastguard Worker       Reload();
433*f6dc9357SAndroid Build Coastguard Worker       return false;
434*f6dc9357SAndroid Build Coastguard Worker     }
435*f6dc9357SAndroid Build Coastguard Worker     case LVN_KEYDOWN:
436*f6dc9357SAndroid Build Coastguard Worker     {
437*f6dc9357SAndroid Build Coastguard Worker       bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header));
438*f6dc9357SAndroid Build Coastguard Worker       Post_RefreshPathEdit();
439*f6dc9357SAndroid Build Coastguard Worker       return boolResult;
440*f6dc9357SAndroid Build Coastguard Worker     }
441*f6dc9357SAndroid Build Coastguard Worker     case NM_RCLICK:
442*f6dc9357SAndroid Build Coastguard Worker     case NM_CLICK:
443*f6dc9357SAndroid Build Coastguard Worker     case LVN_BEGINDRAG:
444*f6dc9357SAndroid Build Coastguard Worker       Post_RefreshPathEdit();
445*f6dc9357SAndroid Build Coastguard Worker       break;
446*f6dc9357SAndroid Build Coastguard Worker   }
447*f6dc9357SAndroid Build Coastguard Worker   return false;
448*f6dc9357SAndroid Build Coastguard Worker }
449*f6dc9357SAndroid Build Coastguard Worker 
OnKeyDown(LPNMLVKEYDOWN keyDownInfo)450*f6dc9357SAndroid Build Coastguard Worker bool CBrowseDialog::OnKeyDown(LPNMLVKEYDOWN keyDownInfo)
451*f6dc9357SAndroid Build Coastguard Worker {
452*f6dc9357SAndroid Build Coastguard Worker   const bool ctrl = IsKeyDown(VK_CONTROL);
453*f6dc9357SAndroid Build Coastguard Worker 
454*f6dc9357SAndroid Build Coastguard Worker   switch (keyDownInfo->wVKey)
455*f6dc9357SAndroid Build Coastguard Worker   {
456*f6dc9357SAndroid Build Coastguard Worker     case VK_BACK:
457*f6dc9357SAndroid Build Coastguard Worker       OpenParentFolder();
458*f6dc9357SAndroid Build Coastguard Worker       return true;
459*f6dc9357SAndroid Build Coastguard Worker     case 'R':
460*f6dc9357SAndroid Build Coastguard Worker       if (ctrl)
461*f6dc9357SAndroid Build Coastguard Worker       {
462*f6dc9357SAndroid Build Coastguard Worker         Reload();
463*f6dc9357SAndroid Build Coastguard Worker         return true;
464*f6dc9357SAndroid Build Coastguard Worker       }
465*f6dc9357SAndroid Build Coastguard Worker       return false;
466*f6dc9357SAndroid Build Coastguard Worker     case VK_F7:
467*f6dc9357SAndroid Build Coastguard Worker       OnCreateDir();
468*f6dc9357SAndroid Build Coastguard Worker       return true;
469*f6dc9357SAndroid Build Coastguard Worker   }
470*f6dc9357SAndroid Build Coastguard Worker   return false;
471*f6dc9357SAndroid Build Coastguard Worker }
472*f6dc9357SAndroid Build Coastguard Worker 
473*f6dc9357SAndroid Build Coastguard Worker 
OnButtonClicked(unsigned buttonID,HWND buttonHWND)474*f6dc9357SAndroid Build Coastguard Worker bool CBrowseDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND)
475*f6dc9357SAndroid Build Coastguard Worker {
476*f6dc9357SAndroid Build Coastguard Worker   switch (buttonID)
477*f6dc9357SAndroid Build Coastguard Worker   {
478*f6dc9357SAndroid Build Coastguard Worker     case IDB_BROWSE_PARENT: OpenParentFolder(); break;
479*f6dc9357SAndroid Build Coastguard Worker     case IDB_BROWSE_CREATE_DIR: OnCreateDir(); break;
480*f6dc9357SAndroid Build Coastguard Worker     default: return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
481*f6dc9357SAndroid Build Coastguard Worker   }
482*f6dc9357SAndroid Build Coastguard Worker   _list.SetFocus();
483*f6dc9357SAndroid Build Coastguard Worker   return true;
484*f6dc9357SAndroid Build Coastguard Worker }
485*f6dc9357SAndroid Build Coastguard Worker 
OnOK()486*f6dc9357SAndroid Build Coastguard Worker void CBrowseDialog::OnOK()
487*f6dc9357SAndroid Build Coastguard Worker {
488*f6dc9357SAndroid Build Coastguard Worker   /* When we press "Enter" in listview, Windows sends message to first Button.
489*f6dc9357SAndroid Build Coastguard Worker      We check that message was from ListView; */
490*f6dc9357SAndroid Build Coastguard Worker   if (GetFocus() == _list)
491*f6dc9357SAndroid Build Coastguard Worker   {
492*f6dc9357SAndroid Build Coastguard Worker     OnItemEnter();
493*f6dc9357SAndroid Build Coastguard Worker     return;
494*f6dc9357SAndroid Build Coastguard Worker   }
495*f6dc9357SAndroid Build Coastguard Worker   FinishOnOK();
496*f6dc9357SAndroid Build Coastguard Worker }
497*f6dc9357SAndroid Build Coastguard Worker 
498*f6dc9357SAndroid Build Coastguard Worker 
GetParentPath(const UString & path,UString & parentPrefix,UString & name)499*f6dc9357SAndroid Build Coastguard Worker bool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, UString &name)
500*f6dc9357SAndroid Build Coastguard Worker {
501*f6dc9357SAndroid Build Coastguard Worker   parentPrefix.Empty();
502*f6dc9357SAndroid Build Coastguard Worker   name.Empty();
503*f6dc9357SAndroid Build Coastguard Worker   if (path.IsEmpty())
504*f6dc9357SAndroid Build Coastguard Worker     return false;
505*f6dc9357SAndroid Build Coastguard Worker   if (_topDirPrefix == path)
506*f6dc9357SAndroid Build Coastguard Worker     return false;
507*f6dc9357SAndroid Build Coastguard Worker   UString s = path;
508*f6dc9357SAndroid Build Coastguard Worker   if (IS_PATH_SEPAR(s.Back()))
509*f6dc9357SAndroid Build Coastguard Worker     s.DeleteBack();
510*f6dc9357SAndroid Build Coastguard Worker   if (s.IsEmpty())
511*f6dc9357SAndroid Build Coastguard Worker     return false;
512*f6dc9357SAndroid Build Coastguard Worker   if (IS_PATH_SEPAR(s.Back()))
513*f6dc9357SAndroid Build Coastguard Worker     return false;
514*f6dc9357SAndroid Build Coastguard Worker   const unsigned pos1 = (unsigned)(s.ReverseFind_PathSepar() + 1);
515*f6dc9357SAndroid Build Coastguard Worker   parentPrefix.SetFrom(s, pos1);
516*f6dc9357SAndroid Build Coastguard Worker   name = s.Ptr(pos1);
517*f6dc9357SAndroid Build Coastguard Worker   return true;
518*f6dc9357SAndroid Build Coastguard Worker }
519*f6dc9357SAndroid Build Coastguard Worker 
CompareItems(LPARAM lParam1,LPARAM lParam2) const520*f6dc9357SAndroid Build Coastguard Worker int CBrowseDialog::CompareItems(LPARAM lParam1, LPARAM lParam2) const
521*f6dc9357SAndroid Build Coastguard Worker {
522*f6dc9357SAndroid Build Coastguard Worker   if (lParam1 == lParam2)      return 0;
523*f6dc9357SAndroid Build Coastguard Worker   if (lParam1 == kParentIndex) return -1;
524*f6dc9357SAndroid Build Coastguard Worker   if (lParam2 == kParentIndex) return 1;
525*f6dc9357SAndroid Build Coastguard Worker 
526*f6dc9357SAndroid Build Coastguard Worker   const CFileInfo &f1 = _files[(int)lParam1];
527*f6dc9357SAndroid Build Coastguard Worker   const CFileInfo &f2 = _files[(int)lParam2];
528*f6dc9357SAndroid Build Coastguard Worker 
529*f6dc9357SAndroid Build Coastguard Worker   const bool isDir2 = f2.IsDir();
530*f6dc9357SAndroid Build Coastguard Worker   if (f1.IsDir())
531*f6dc9357SAndroid Build Coastguard Worker   {
532*f6dc9357SAndroid Build Coastguard Worker     if (!isDir2) return -1;
533*f6dc9357SAndroid Build Coastguard Worker   }
534*f6dc9357SAndroid Build Coastguard Worker   else if (isDir2) return 1;
535*f6dc9357SAndroid Build Coastguard Worker 
536*f6dc9357SAndroid Build Coastguard Worker   int res = 0;
537*f6dc9357SAndroid Build Coastguard Worker   switch (_sortIndex)
538*f6dc9357SAndroid Build Coastguard Worker   {
539*f6dc9357SAndroid Build Coastguard Worker     case 0: res = CompareFileNames(fs2us(f1.Name), fs2us(f2.Name)); break;
540*f6dc9357SAndroid Build Coastguard Worker     case 1: res = CompareFileTime(&f1.MTime, &f2.MTime); break;
541*f6dc9357SAndroid Build Coastguard Worker     case 2: res = MyCompare(f1.Size, f2.Size); break;
542*f6dc9357SAndroid Build Coastguard Worker   }
543*f6dc9357SAndroid Build Coastguard Worker   return _ascending ? res: -res;
544*f6dc9357SAndroid Build Coastguard Worker }
545*f6dc9357SAndroid Build Coastguard Worker 
CompareItems2(LPARAM lParam1,LPARAM lParam2,LPARAM lpData)546*f6dc9357SAndroid Build Coastguard Worker static int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
547*f6dc9357SAndroid Build Coastguard Worker {
548*f6dc9357SAndroid Build Coastguard Worker   return ((CBrowseDialog *)lpData)->CompareItems(lParam1, lParam2);
549*f6dc9357SAndroid Build Coastguard Worker }
550*f6dc9357SAndroid Build Coastguard Worker 
551*f6dc9357SAndroid Build Coastguard Worker wchar_t *Browse_ConvertSizeToString(UInt64 v, wchar_t *s);
Browse_ConvertSizeToString(UInt64 v,wchar_t * s)552*f6dc9357SAndroid Build Coastguard Worker wchar_t *Browse_ConvertSizeToString(UInt64 v, wchar_t *s)
553*f6dc9357SAndroid Build Coastguard Worker {
554*f6dc9357SAndroid Build Coastguard Worker   char c = 0;
555*f6dc9357SAndroid Build Coastguard Worker        if (v >= ((UInt64)10000 << 20)) { v >>= 30; c = 'G'; }
556*f6dc9357SAndroid Build Coastguard Worker   else if (v >= ((UInt64)10000 << 10)) { v >>= 20; c = 'M'; }
557*f6dc9357SAndroid Build Coastguard Worker   else if (v >= ((UInt64)10000 <<  0)) { v >>= 10; c = 'K'; }
558*f6dc9357SAndroid Build Coastguard Worker   s = ConvertUInt64ToString(v, s);
559*f6dc9357SAndroid Build Coastguard Worker   if (c != 0)
560*f6dc9357SAndroid Build Coastguard Worker   {
561*f6dc9357SAndroid Build Coastguard Worker     *s++ = ' ';
562*f6dc9357SAndroid Build Coastguard Worker     *s++ = (wchar_t)c;
563*f6dc9357SAndroid Build Coastguard Worker     *s++ = 'B';
564*f6dc9357SAndroid Build Coastguard Worker     *s = 0;
565*f6dc9357SAndroid Build Coastguard Worker   }
566*f6dc9357SAndroid Build Coastguard Worker   return s;
567*f6dc9357SAndroid Build Coastguard Worker }
568*f6dc9357SAndroid Build Coastguard Worker 
569*f6dc9357SAndroid Build Coastguard Worker // Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter
570*f6dc9357SAndroid Build Coastguard Worker 
Reload(const UString & pathPrefix,const UString & selectedName)571*f6dc9357SAndroid Build Coastguard Worker HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selectedName)
572*f6dc9357SAndroid Build Coastguard Worker {
573*f6dc9357SAndroid Build Coastguard Worker   CObjectVector<CFileInfo> files;
574*f6dc9357SAndroid Build Coastguard Worker 
575*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
576*f6dc9357SAndroid Build Coastguard Worker   bool isDrive = false;
577*f6dc9357SAndroid Build Coastguard Worker   if (pathPrefix.IsEmpty() || pathPrefix.IsEqualTo(kSuperPathPrefix))
578*f6dc9357SAndroid Build Coastguard Worker   {
579*f6dc9357SAndroid Build Coastguard Worker     isDrive = true;
580*f6dc9357SAndroid Build Coastguard Worker     FStringVector drives;
581*f6dc9357SAndroid Build Coastguard Worker     if (!MyGetLogicalDriveStrings(drives))
582*f6dc9357SAndroid Build Coastguard Worker       return GetLastError_noZero_HRESULT();
583*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, drives)
584*f6dc9357SAndroid Build Coastguard Worker     {
585*f6dc9357SAndroid Build Coastguard Worker       const FString &d = drives[i];
586*f6dc9357SAndroid Build Coastguard Worker       if (d.Len() < 2 || d.Back() != '\\')
587*f6dc9357SAndroid Build Coastguard Worker         return E_FAIL;
588*f6dc9357SAndroid Build Coastguard Worker       CFileInfo &fi = files.AddNew();
589*f6dc9357SAndroid Build Coastguard Worker       fi.SetAsDir();
590*f6dc9357SAndroid Build Coastguard Worker       fi.Name = d;
591*f6dc9357SAndroid Build Coastguard Worker       fi.Name.DeleteBack();
592*f6dc9357SAndroid Build Coastguard Worker     }
593*f6dc9357SAndroid Build Coastguard Worker   }
594*f6dc9357SAndroid Build Coastguard Worker   else
595*f6dc9357SAndroid Build Coastguard Worker   #endif
596*f6dc9357SAndroid Build Coastguard Worker   {
597*f6dc9357SAndroid Build Coastguard Worker     const UStringVector *masks = NULL;
598*f6dc9357SAndroid Build Coastguard Worker     if (!Filters.IsEmpty() && _filterCombo.GetCount() > 0)
599*f6dc9357SAndroid Build Coastguard Worker     {
600*f6dc9357SAndroid Build Coastguard Worker       const int selected = _filterCombo.GetCurSel();
601*f6dc9357SAndroid Build Coastguard Worker             // GetItemData_of_CurSel(); // we don't use data field
602*f6dc9357SAndroid Build Coastguard Worker       if (/* selected >= 0 && */ (unsigned)selected < Filters.Size())
603*f6dc9357SAndroid Build Coastguard Worker       {
604*f6dc9357SAndroid Build Coastguard Worker         const UStringVector &m = Filters[selected].Masks;
605*f6dc9357SAndroid Build Coastguard Worker         if (m.Size() > 1 || (m.Size() == 1
606*f6dc9357SAndroid Build Coastguard Worker               && !m[0].IsEqualTo("*.*")
607*f6dc9357SAndroid Build Coastguard Worker               && !m[0].IsEqualTo("*")))
608*f6dc9357SAndroid Build Coastguard Worker           masks = &m;
609*f6dc9357SAndroid Build Coastguard Worker       }
610*f6dc9357SAndroid Build Coastguard Worker     }
611*f6dc9357SAndroid Build Coastguard Worker     CEnumerator enumerator;
612*f6dc9357SAndroid Build Coastguard Worker     enumerator.SetDirPrefix(us2fs(pathPrefix));
613*f6dc9357SAndroid Build Coastguard Worker     CFileInfo fi;
614*f6dc9357SAndroid Build Coastguard Worker     for (;;)
615*f6dc9357SAndroid Build Coastguard Worker     {
616*f6dc9357SAndroid Build Coastguard Worker       bool found;
617*f6dc9357SAndroid Build Coastguard Worker       if (!enumerator.Next(fi, found))
618*f6dc9357SAndroid Build Coastguard Worker         return GetLastError_noZero_HRESULT();
619*f6dc9357SAndroid Build Coastguard Worker       if (!found)
620*f6dc9357SAndroid Build Coastguard Worker         break;
621*f6dc9357SAndroid Build Coastguard Worker       if (!fi.IsDir())
622*f6dc9357SAndroid Build Coastguard Worker       {
623*f6dc9357SAndroid Build Coastguard Worker         if (FolderMode)
624*f6dc9357SAndroid Build Coastguard Worker           continue;
625*f6dc9357SAndroid Build Coastguard Worker         if (masks)
626*f6dc9357SAndroid Build Coastguard Worker         {
627*f6dc9357SAndroid Build Coastguard Worker           unsigned i;
628*f6dc9357SAndroid Build Coastguard Worker           const unsigned numMasks = masks->Size();
629*f6dc9357SAndroid Build Coastguard Worker           for (i = 0; i < numMasks; i++)
630*f6dc9357SAndroid Build Coastguard Worker             if (DoesWildcardMatchName((*masks)[i], fs2us(fi.Name)))
631*f6dc9357SAndroid Build Coastguard Worker               break;
632*f6dc9357SAndroid Build Coastguard Worker           if (i == numMasks)
633*f6dc9357SAndroid Build Coastguard Worker             continue;
634*f6dc9357SAndroid Build Coastguard Worker         }
635*f6dc9357SAndroid Build Coastguard Worker       }
636*f6dc9357SAndroid Build Coastguard Worker       files.Add(fi);
637*f6dc9357SAndroid Build Coastguard Worker     }
638*f6dc9357SAndroid Build Coastguard Worker   }
639*f6dc9357SAndroid Build Coastguard Worker 
640*f6dc9357SAndroid Build Coastguard Worker   DirPrefix = pathPrefix;
641*f6dc9357SAndroid Build Coastguard Worker 
642*f6dc9357SAndroid Build Coastguard Worker   _files = files;
643*f6dc9357SAndroid Build Coastguard Worker 
644*f6dc9357SAndroid Build Coastguard Worker   SetItemText(IDT_BROWSE_FOLDER, DirPrefix);
645*f6dc9357SAndroid Build Coastguard Worker 
646*f6dc9357SAndroid Build Coastguard Worker   _list.SetRedraw(false);
647*f6dc9357SAndroid Build Coastguard Worker   _list.DeleteAllItems();
648*f6dc9357SAndroid Build Coastguard Worker 
649*f6dc9357SAndroid Build Coastguard Worker   LVITEMW item;
650*f6dc9357SAndroid Build Coastguard Worker 
651*f6dc9357SAndroid Build Coastguard Worker   unsigned index = 0;
652*f6dc9357SAndroid Build Coastguard Worker   int cursorIndex = -1;
653*f6dc9357SAndroid Build Coastguard Worker 
654*f6dc9357SAndroid Build Coastguard Worker   #ifndef Z7_SFX
655*f6dc9357SAndroid Build Coastguard Worker   if (_showDots && _topDirPrefix != DirPrefix)
656*f6dc9357SAndroid Build Coastguard Worker   {
657*f6dc9357SAndroid Build Coastguard Worker     item.iItem = (int)index;
658*f6dc9357SAndroid Build Coastguard Worker     const UString itemName ("..");
659*f6dc9357SAndroid Build Coastguard Worker     if (selectedName.IsEmpty())
660*f6dc9357SAndroid Build Coastguard Worker       cursorIndex = (int)index;
661*f6dc9357SAndroid Build Coastguard Worker     item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
662*f6dc9357SAndroid Build Coastguard Worker     unsigned subItem = 0;
663*f6dc9357SAndroid Build Coastguard Worker     item.iSubItem = (int)(subItem++);
664*f6dc9357SAndroid Build Coastguard Worker     item.lParam = kParentIndex;
665*f6dc9357SAndroid Build Coastguard Worker     item.pszText = itemName.Ptr_non_const();
666*f6dc9357SAndroid Build Coastguard Worker     item.iImage = _extToIconMap.GetIconIndex(FILE_ATTRIBUTE_DIRECTORY, DirPrefix);
667*f6dc9357SAndroid Build Coastguard Worker     if (item.iImage < 0)
668*f6dc9357SAndroid Build Coastguard Worker       item.iImage = 0;
669*f6dc9357SAndroid Build Coastguard Worker     _list.InsertItem(&item);
670*f6dc9357SAndroid Build Coastguard Worker     _list.SetSubItem(index, subItem++, L"");
671*f6dc9357SAndroid Build Coastguard Worker     _list.SetSubItem(index, subItem++, L"");
672*f6dc9357SAndroid Build Coastguard Worker     index++;
673*f6dc9357SAndroid Build Coastguard Worker   }
674*f6dc9357SAndroid Build Coastguard Worker   #endif
675*f6dc9357SAndroid Build Coastguard Worker 
676*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < _files.Size(); i++, index++)
677*f6dc9357SAndroid Build Coastguard Worker   {
678*f6dc9357SAndroid Build Coastguard Worker     item.iItem = (int)index;
679*f6dc9357SAndroid Build Coastguard Worker     const CFileInfo &fi = _files[i];
680*f6dc9357SAndroid Build Coastguard Worker     const UString name = fs2us(fi.Name);
681*f6dc9357SAndroid Build Coastguard Worker     if (!selectedName.IsEmpty() && CompareFileNames(name, selectedName) == 0)
682*f6dc9357SAndroid Build Coastguard Worker       cursorIndex = (int)index;
683*f6dc9357SAndroid Build Coastguard Worker     item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
684*f6dc9357SAndroid Build Coastguard Worker     unsigned subItem = 0;
685*f6dc9357SAndroid Build Coastguard Worker     item.iSubItem = (int)(subItem++);
686*f6dc9357SAndroid Build Coastguard Worker     item.lParam = (LPARAM)i;
687*f6dc9357SAndroid Build Coastguard Worker     item.pszText = name.Ptr_non_const();
688*f6dc9357SAndroid Build Coastguard Worker 
689*f6dc9357SAndroid Build Coastguard Worker     const UString fullPath = DirPrefix + name;
690*f6dc9357SAndroid Build Coastguard Worker     #ifndef UNDER_CE
691*f6dc9357SAndroid Build Coastguard Worker     if (isDrive)
692*f6dc9357SAndroid Build Coastguard Worker     {
693*f6dc9357SAndroid Build Coastguard Worker       item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path(
694*f6dc9357SAndroid Build Coastguard Worker           fi.Name + FCHAR_PATH_SEPARATOR,
695*f6dc9357SAndroid Build Coastguard Worker           FILE_ATTRIBUTE_DIRECTORY);
696*f6dc9357SAndroid Build Coastguard Worker     }
697*f6dc9357SAndroid Build Coastguard Worker     else
698*f6dc9357SAndroid Build Coastguard Worker     #endif
699*f6dc9357SAndroid Build Coastguard Worker       item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, fullPath);
700*f6dc9357SAndroid Build Coastguard Worker     if (item.iImage < 0)
701*f6dc9357SAndroid Build Coastguard Worker         item.iImage = 0;
702*f6dc9357SAndroid Build Coastguard Worker     _list.InsertItem(&item);
703*f6dc9357SAndroid Build Coastguard Worker     wchar_t s[64];
704*f6dc9357SAndroid Build Coastguard Worker     {
705*f6dc9357SAndroid Build Coastguard Worker       s[0] = 0;
706*f6dc9357SAndroid Build Coastguard Worker       if (!FILETIME_IsZero(fi.MTime))
707*f6dc9357SAndroid Build Coastguard Worker         ConvertUtcFileTimeToString(fi.MTime, s,
708*f6dc9357SAndroid Build Coastguard Worker             #ifndef UNDER_CE
709*f6dc9357SAndroid Build Coastguard Worker               kTimestampPrintLevel_MIN
710*f6dc9357SAndroid Build Coastguard Worker             #else
711*f6dc9357SAndroid Build Coastguard Worker               kTimestampPrintLevel_DAY
712*f6dc9357SAndroid Build Coastguard Worker             #endif
713*f6dc9357SAndroid Build Coastguard Worker               );
714*f6dc9357SAndroid Build Coastguard Worker       _list.SetSubItem(index, subItem++, s);
715*f6dc9357SAndroid Build Coastguard Worker     }
716*f6dc9357SAndroid Build Coastguard Worker     {
717*f6dc9357SAndroid Build Coastguard Worker       s[0] = 0;
718*f6dc9357SAndroid Build Coastguard Worker       if (!fi.IsDir())
719*f6dc9357SAndroid Build Coastguard Worker         Browse_ConvertSizeToString(fi.Size, s);
720*f6dc9357SAndroid Build Coastguard Worker       _list.SetSubItem(index, subItem++, s);
721*f6dc9357SAndroid Build Coastguard Worker     }
722*f6dc9357SAndroid Build Coastguard Worker   }
723*f6dc9357SAndroid Build Coastguard Worker 
724*f6dc9357SAndroid Build Coastguard Worker   if (_list.GetItemCount() > 0 && cursorIndex >= 0)
725*f6dc9357SAndroid Build Coastguard Worker     _list.SetItemState_FocusedSelected(cursorIndex);
726*f6dc9357SAndroid Build Coastguard Worker   _list.SortItems(CompareItems2, (LPARAM)this);
727*f6dc9357SAndroid Build Coastguard Worker   if (_list.GetItemCount() > 0 && cursorIndex < 0)
728*f6dc9357SAndroid Build Coastguard Worker     _list.SetItemState(0, LVIS_FOCUSED, LVIS_FOCUSED);
729*f6dc9357SAndroid Build Coastguard Worker   _list.EnsureVisible(_list.GetFocusedItem(), false);
730*f6dc9357SAndroid Build Coastguard Worker   _list.SetRedraw(true);
731*f6dc9357SAndroid Build Coastguard Worker   _list.InvalidateRect(NULL, true);
732*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
733*f6dc9357SAndroid Build Coastguard Worker }
734*f6dc9357SAndroid Build Coastguard Worker 
Reload()735*f6dc9357SAndroid Build Coastguard Worker HRESULT CBrowseDialog::Reload()
736*f6dc9357SAndroid Build Coastguard Worker {
737*f6dc9357SAndroid Build Coastguard Worker   UString selected;
738*f6dc9357SAndroid Build Coastguard Worker   const int index = _list.GetNextSelectedItem(-1);
739*f6dc9357SAndroid Build Coastguard Worker   if (index >= 0)
740*f6dc9357SAndroid Build Coastguard Worker   {
741*f6dc9357SAndroid Build Coastguard Worker     const int fileIndex = GetRealItemIndex(index);
742*f6dc9357SAndroid Build Coastguard Worker     if (fileIndex != kParentIndex)
743*f6dc9357SAndroid Build Coastguard Worker       selected = fs2us(_files[fileIndex].Name);
744*f6dc9357SAndroid Build Coastguard Worker   }
745*f6dc9357SAndroid Build Coastguard Worker   const UString dirPathTemp = DirPrefix;
746*f6dc9357SAndroid Build Coastguard Worker   return Reload(dirPathTemp, selected);
747*f6dc9357SAndroid Build Coastguard Worker }
748*f6dc9357SAndroid Build Coastguard Worker 
OpenParentFolder()749*f6dc9357SAndroid Build Coastguard Worker void CBrowseDialog::OpenParentFolder()
750*f6dc9357SAndroid Build Coastguard Worker {
751*f6dc9357SAndroid Build Coastguard Worker   UString parent, selected;
752*f6dc9357SAndroid Build Coastguard Worker   if (GetParentPath(DirPrefix, parent, selected))
753*f6dc9357SAndroid Build Coastguard Worker   {
754*f6dc9357SAndroid Build Coastguard Worker     Reload(parent, selected);
755*f6dc9357SAndroid Build Coastguard Worker     SetPathEditText();
756*f6dc9357SAndroid Build Coastguard Worker   }
757*f6dc9357SAndroid Build Coastguard Worker }
758*f6dc9357SAndroid Build Coastguard Worker 
SetPathEditText()759*f6dc9357SAndroid Build Coastguard Worker void CBrowseDialog::SetPathEditText()
760*f6dc9357SAndroid Build Coastguard Worker {
761*f6dc9357SAndroid Build Coastguard Worker   const int index = _list.GetNextSelectedItem(-1);
762*f6dc9357SAndroid Build Coastguard Worker   if (index < 0)
763*f6dc9357SAndroid Build Coastguard Worker   {
764*f6dc9357SAndroid Build Coastguard Worker     if (FolderMode)
765*f6dc9357SAndroid Build Coastguard Worker       _pathEdit.SetText(DirPrefix);
766*f6dc9357SAndroid Build Coastguard Worker     return;
767*f6dc9357SAndroid Build Coastguard Worker   }
768*f6dc9357SAndroid Build Coastguard Worker   const int fileIndex = GetRealItemIndex(index);
769*f6dc9357SAndroid Build Coastguard Worker   if (fileIndex == kParentIndex)
770*f6dc9357SAndroid Build Coastguard Worker   {
771*f6dc9357SAndroid Build Coastguard Worker     if (FolderMode)
772*f6dc9357SAndroid Build Coastguard Worker       _pathEdit.SetText(L".." WSTRING_PATH_SEPARATOR);
773*f6dc9357SAndroid Build Coastguard Worker     return;
774*f6dc9357SAndroid Build Coastguard Worker   }
775*f6dc9357SAndroid Build Coastguard Worker   const CFileInfo &file = _files[fileIndex];
776*f6dc9357SAndroid Build Coastguard Worker   if (file.IsDir())
777*f6dc9357SAndroid Build Coastguard Worker   {
778*f6dc9357SAndroid Build Coastguard Worker     if (!FolderMode)
779*f6dc9357SAndroid Build Coastguard Worker       return;
780*f6dc9357SAndroid Build Coastguard Worker     _pathEdit.SetText(fs2us(file.Name) + WCHAR_PATH_SEPARATOR);
781*f6dc9357SAndroid Build Coastguard Worker   }
782*f6dc9357SAndroid Build Coastguard Worker   else
783*f6dc9357SAndroid Build Coastguard Worker     _pathEdit.SetText(fs2us(file.Name));
784*f6dc9357SAndroid Build Coastguard Worker }
785*f6dc9357SAndroid Build Coastguard Worker 
OnCreateDir()786*f6dc9357SAndroid Build Coastguard Worker void CBrowseDialog::OnCreateDir()
787*f6dc9357SAndroid Build Coastguard Worker {
788*f6dc9357SAndroid Build Coastguard Worker   UString name;
789*f6dc9357SAndroid Build Coastguard Worker   {
790*f6dc9357SAndroid Build Coastguard Worker     UString enteredName;
791*f6dc9357SAndroid Build Coastguard Worker     Dlg_CreateFolder((HWND)*this, enteredName);
792*f6dc9357SAndroid Build Coastguard Worker     if (enteredName.IsEmpty())
793*f6dc9357SAndroid Build Coastguard Worker       return;
794*f6dc9357SAndroid Build Coastguard Worker     if (!CorrectFsPath(DirPrefix, enteredName, name))
795*f6dc9357SAndroid Build Coastguard Worker     {
796*f6dc9357SAndroid Build Coastguard Worker       MessageBox_HResError((HWND)*this, ERROR_INVALID_NAME, name);
797*f6dc9357SAndroid Build Coastguard Worker       return;
798*f6dc9357SAndroid Build Coastguard Worker     }
799*f6dc9357SAndroid Build Coastguard Worker   }
800*f6dc9357SAndroid Build Coastguard Worker   if (name.IsEmpty())
801*f6dc9357SAndroid Build Coastguard Worker     return;
802*f6dc9357SAndroid Build Coastguard Worker 
803*f6dc9357SAndroid Build Coastguard Worker   FString destPath;
804*f6dc9357SAndroid Build Coastguard Worker   if (GetFullPath(us2fs(DirPrefix), us2fs(name), destPath))
805*f6dc9357SAndroid Build Coastguard Worker   {
806*f6dc9357SAndroid Build Coastguard Worker     if (!NDir::CreateComplexDir(destPath))
807*f6dc9357SAndroid Build Coastguard Worker     {
808*f6dc9357SAndroid Build Coastguard Worker       MessageBox_HResError((HWND)*this, GetLastError_noZero_HRESULT(), fs2us(destPath));
809*f6dc9357SAndroid Build Coastguard Worker     }
810*f6dc9357SAndroid Build Coastguard Worker     else
811*f6dc9357SAndroid Build Coastguard Worker     {
812*f6dc9357SAndroid Build Coastguard Worker       UString tempPath = DirPrefix;
813*f6dc9357SAndroid Build Coastguard Worker       Reload(tempPath, name);
814*f6dc9357SAndroid Build Coastguard Worker       SetPathEditText();
815*f6dc9357SAndroid Build Coastguard Worker     }
816*f6dc9357SAndroid Build Coastguard Worker     _list.SetFocus();
817*f6dc9357SAndroid Build Coastguard Worker   }
818*f6dc9357SAndroid Build Coastguard Worker }
819*f6dc9357SAndroid Build Coastguard Worker 
OnItemEnter()820*f6dc9357SAndroid Build Coastguard Worker void CBrowseDialog::OnItemEnter()
821*f6dc9357SAndroid Build Coastguard Worker {
822*f6dc9357SAndroid Build Coastguard Worker   const int index = _list.GetNextSelectedItem(-1);
823*f6dc9357SAndroid Build Coastguard Worker   if (index < 0)
824*f6dc9357SAndroid Build Coastguard Worker     return;
825*f6dc9357SAndroid Build Coastguard Worker   const int fileIndex = GetRealItemIndex(index);
826*f6dc9357SAndroid Build Coastguard Worker   if (fileIndex == kParentIndex)
827*f6dc9357SAndroid Build Coastguard Worker     OpenParentFolder();
828*f6dc9357SAndroid Build Coastguard Worker   else
829*f6dc9357SAndroid Build Coastguard Worker   {
830*f6dc9357SAndroid Build Coastguard Worker     const CFileInfo &file = _files[fileIndex];
831*f6dc9357SAndroid Build Coastguard Worker     if (!file.IsDir())
832*f6dc9357SAndroid Build Coastguard Worker     {
833*f6dc9357SAndroid Build Coastguard Worker       if (!FolderMode)
834*f6dc9357SAndroid Build Coastguard Worker         FinishOnOK();
835*f6dc9357SAndroid Build Coastguard Worker       /*
836*f6dc9357SAndroid Build Coastguard Worker       MessageBox_Error_Global(*this, FolderMode ?
837*f6dc9357SAndroid Build Coastguard Worker             L"You must select some folder":
838*f6dc9357SAndroid Build Coastguard Worker             L"You must select some file");
839*f6dc9357SAndroid Build Coastguard Worker       */
840*f6dc9357SAndroid Build Coastguard Worker       return;
841*f6dc9357SAndroid Build Coastguard Worker     }
842*f6dc9357SAndroid Build Coastguard Worker     UString s = DirPrefix;
843*f6dc9357SAndroid Build Coastguard Worker     s += fs2us(file.Name);
844*f6dc9357SAndroid Build Coastguard Worker     s.Add_PathSepar();
845*f6dc9357SAndroid Build Coastguard Worker     const HRESULT res = Reload(s, UString());
846*f6dc9357SAndroid Build Coastguard Worker     if (res != S_OK)
847*f6dc9357SAndroid Build Coastguard Worker       MessageBox_HResError(*this, res, s);
848*f6dc9357SAndroid Build Coastguard Worker     SetPathEditText();
849*f6dc9357SAndroid Build Coastguard Worker   }
850*f6dc9357SAndroid Build Coastguard Worker }
851*f6dc9357SAndroid Build Coastguard Worker 
FinishOnOK()852*f6dc9357SAndroid Build Coastguard Worker void CBrowseDialog::FinishOnOK()
853*f6dc9357SAndroid Build Coastguard Worker {
854*f6dc9357SAndroid Build Coastguard Worker   UString s;
855*f6dc9357SAndroid Build Coastguard Worker   _pathEdit.GetText(s);
856*f6dc9357SAndroid Build Coastguard Worker   FString destPath;
857*f6dc9357SAndroid Build Coastguard Worker   if (!GetFullPath(us2fs(DirPrefix), us2fs(s), destPath))
858*f6dc9357SAndroid Build Coastguard Worker   {
859*f6dc9357SAndroid Build Coastguard Worker     MessageBox_HResError((HWND)*this, ERROR_INVALID_NAME, s);
860*f6dc9357SAndroid Build Coastguard Worker     return;
861*f6dc9357SAndroid Build Coastguard Worker   }
862*f6dc9357SAndroid Build Coastguard Worker   FilePath = fs2us(destPath);
863*f6dc9357SAndroid Build Coastguard Worker   if (FolderMode)
864*f6dc9357SAndroid Build Coastguard Worker     NormalizeDirPathPrefix(FilePath);
865*f6dc9357SAndroid Build Coastguard Worker   FilterIndex = _filterCombo.GetCurSel();
866*f6dc9357SAndroid Build Coastguard Worker   End(IDOK);
867*f6dc9357SAndroid Build Coastguard Worker }
868*f6dc9357SAndroid Build Coastguard Worker 
869*f6dc9357SAndroid Build Coastguard Worker #endif // USE_MY_BROWSE_DIALOG
870*f6dc9357SAndroid Build Coastguard Worker 
871*f6dc9357SAndroid Build Coastguard Worker 
872*f6dc9357SAndroid Build Coastguard Worker 
MyBrowseForFolder(HWND owner,LPCWSTR title,LPCWSTR path,UString & resultPath)873*f6dc9357SAndroid Build Coastguard Worker bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath)
874*f6dc9357SAndroid Build Coastguard Worker {
875*f6dc9357SAndroid Build Coastguard Worker   resultPath.Empty();
876*f6dc9357SAndroid Build Coastguard Worker 
877*f6dc9357SAndroid Build Coastguard Worker   #ifndef UNDER_CE
878*f6dc9357SAndroid Build Coastguard Worker 
879*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MY_BROWSE_DIALOG
880*f6dc9357SAndroid Build Coastguard Worker   if (!IsSuperOrDevicePath(path))
881*f6dc9357SAndroid Build Coastguard Worker   if (MyStringLen(path) < MAX_PATH)
882*f6dc9357SAndroid Build Coastguard Worker #endif
883*f6dc9357SAndroid Build Coastguard Worker     return NShell::BrowseForFolder(owner, title, path, resultPath);
884*f6dc9357SAndroid Build Coastguard Worker 
885*f6dc9357SAndroid Build Coastguard Worker   #endif //  UNDER_CE
886*f6dc9357SAndroid Build Coastguard Worker 
887*f6dc9357SAndroid Build Coastguard Worker   #ifdef USE_MY_BROWSE_DIALOG
888*f6dc9357SAndroid Build Coastguard Worker 
889*f6dc9357SAndroid Build Coastguard Worker   CBrowseDialog dialog;
890*f6dc9357SAndroid Build Coastguard Worker   dialog.FolderMode = true;
891*f6dc9357SAndroid Build Coastguard Worker   if (title)
892*f6dc9357SAndroid Build Coastguard Worker     dialog.Title = title;
893*f6dc9357SAndroid Build Coastguard Worker   if (path)
894*f6dc9357SAndroid Build Coastguard Worker     dialog.FilePath = path;
895*f6dc9357SAndroid Build Coastguard Worker   if (dialog.Create(owner) != IDOK)
896*f6dc9357SAndroid Build Coastguard Worker     return false;
897*f6dc9357SAndroid Build Coastguard Worker   resultPath = dialog.FilePath;
898*f6dc9357SAndroid Build Coastguard Worker   return true;
899*f6dc9357SAndroid Build Coastguard Worker 
900*f6dc9357SAndroid Build Coastguard Worker   #endif
901*f6dc9357SAndroid Build Coastguard Worker }
902*f6dc9357SAndroid Build Coastguard Worker 
903*f6dc9357SAndroid Build Coastguard Worker 
904*f6dc9357SAndroid Build Coastguard Worker // LPCWSTR filterDescription, LPCWSTR filter,
905*f6dc9357SAndroid Build Coastguard Worker 
BrowseForFile(const CObjectVector<CBrowseFilterInfo> & filters)906*f6dc9357SAndroid Build Coastguard Worker bool CBrowseInfo::BrowseForFile(const CObjectVector<CBrowseFilterInfo> &filters)
907*f6dc9357SAndroid Build Coastguard Worker {
908*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
909*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MY_BROWSE_DIALOG
910*f6dc9357SAndroid Build Coastguard Worker   /* win10:
911*f6dc9357SAndroid Build Coastguard Worker      GetOpenFileName() for FilePath doesn't support super prefix "\\\\?\\"
912*f6dc9357SAndroid Build Coastguard Worker      GetOpenFileName() for FilePath doesn't support long path
913*f6dc9357SAndroid Build Coastguard Worker   */
914*f6dc9357SAndroid Build Coastguard Worker   if (!IsSuperOrDevicePath(FilePath))
915*f6dc9357SAndroid Build Coastguard Worker   // if (filters.Size() > 100) // for debug
916*f6dc9357SAndroid Build Coastguard Worker #endif
917*f6dc9357SAndroid Build Coastguard Worker   {
918*f6dc9357SAndroid Build Coastguard Worker     const UString filePath_Store = FilePath;
919*f6dc9357SAndroid Build Coastguard Worker     UString dirPrefix;
920*f6dc9357SAndroid Build Coastguard Worker     {
921*f6dc9357SAndroid Build Coastguard Worker       FString prefix, name;
922*f6dc9357SAndroid Build Coastguard Worker       if (NDir::GetFullPathAndSplit(us2fs(FilePath), prefix, name))
923*f6dc9357SAndroid Build Coastguard Worker       {
924*f6dc9357SAndroid Build Coastguard Worker         dirPrefix = fs2us(prefix);
925*f6dc9357SAndroid Build Coastguard Worker         FilePath = fs2us(name);
926*f6dc9357SAndroid Build Coastguard Worker       }
927*f6dc9357SAndroid Build Coastguard Worker     }
928*f6dc9357SAndroid Build Coastguard Worker     UStringVector filters2;
929*f6dc9357SAndroid Build Coastguard Worker     FOR_VECTOR (i, filters)
930*f6dc9357SAndroid Build Coastguard Worker     {
931*f6dc9357SAndroid Build Coastguard Worker       const CBrowseFilterInfo &fi = filters[i];
932*f6dc9357SAndroid Build Coastguard Worker       filters2.Add(fi.Description);
933*f6dc9357SAndroid Build Coastguard Worker       UString s;
934*f6dc9357SAndroid Build Coastguard Worker       FOR_VECTOR (k, fi.Masks)
935*f6dc9357SAndroid Build Coastguard Worker       {
936*f6dc9357SAndroid Build Coastguard Worker         if (k != 0)
937*f6dc9357SAndroid Build Coastguard Worker           s += ";";
938*f6dc9357SAndroid Build Coastguard Worker         s += fi.Masks[k];
939*f6dc9357SAndroid Build Coastguard Worker       }
940*f6dc9357SAndroid Build Coastguard Worker       filters2.Add(s);
941*f6dc9357SAndroid Build Coastguard Worker     }
942*f6dc9357SAndroid Build Coastguard Worker     if (CommonDlg_BrowseForFile(!dirPrefix.IsEmpty() ? dirPrefix.Ptr(): NULL, filters2))
943*f6dc9357SAndroid Build Coastguard Worker       return true;
944*f6dc9357SAndroid Build Coastguard Worker     FilePath = filePath_Store;
945*f6dc9357SAndroid Build Coastguard Worker 
946*f6dc9357SAndroid Build Coastguard Worker   #ifdef UNDER_CE
947*f6dc9357SAndroid Build Coastguard Worker     return false;
948*f6dc9357SAndroid Build Coastguard Worker   #else
949*f6dc9357SAndroid Build Coastguard Worker     // maybe we must use GetLastError in WinCE.
950*f6dc9357SAndroid Build Coastguard Worker     const DWORD errorCode = CommDlgExtendedError();
951*f6dc9357SAndroid Build Coastguard Worker   #ifdef USE_MY_BROWSE_DIALOG
952*f6dc9357SAndroid Build Coastguard Worker     // FNERR_INVALIDFILENAME is expected error, if long path was used
953*f6dc9357SAndroid Build Coastguard Worker     if (errorCode != FNERR_INVALIDFILENAME
954*f6dc9357SAndroid Build Coastguard Worker         || FilePath.Len() < MAX_PATH)
955*f6dc9357SAndroid Build Coastguard Worker   #endif
956*f6dc9357SAndroid Build Coastguard Worker     {
957*f6dc9357SAndroid Build Coastguard Worker       if (errorCode == 0)  // cancel or close on dialog
958*f6dc9357SAndroid Build Coastguard Worker         return false;
959*f6dc9357SAndroid Build Coastguard Worker       const char *message = NULL;
960*f6dc9357SAndroid Build Coastguard Worker       if (errorCode == FNERR_INVALIDFILENAME)
961*f6dc9357SAndroid Build Coastguard Worker         message = "Invalid file name";
962*f6dc9357SAndroid Build Coastguard Worker       UString s ("Open Dialog Error:");
963*f6dc9357SAndroid Build Coastguard Worker       s.Add_LF();
964*f6dc9357SAndroid Build Coastguard Worker       if (message)
965*f6dc9357SAndroid Build Coastguard Worker         s += message;
966*f6dc9357SAndroid Build Coastguard Worker       else
967*f6dc9357SAndroid Build Coastguard Worker       {
968*f6dc9357SAndroid Build Coastguard Worker         char temp[16];
969*f6dc9357SAndroid Build Coastguard Worker         ConvertUInt32ToHex8Digits(errorCode, temp);
970*f6dc9357SAndroid Build Coastguard Worker         s += "Error #";
971*f6dc9357SAndroid Build Coastguard Worker         s += temp;
972*f6dc9357SAndroid Build Coastguard Worker       }
973*f6dc9357SAndroid Build Coastguard Worker       s.Add_LF();
974*f6dc9357SAndroid Build Coastguard Worker       s += FilePath;
975*f6dc9357SAndroid Build Coastguard Worker       MessageBox_Error_Global(hwndOwner, s);
976*f6dc9357SAndroid Build Coastguard Worker     }
977*f6dc9357SAndroid Build Coastguard Worker   #endif // UNDER_CE
978*f6dc9357SAndroid Build Coastguard Worker   }
979*f6dc9357SAndroid Build Coastguard Worker 
980*f6dc9357SAndroid Build Coastguard Worker #endif // UNDER_CE
981*f6dc9357SAndroid Build Coastguard Worker 
982*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_MY_BROWSE_DIALOG
983*f6dc9357SAndroid Build Coastguard Worker 
984*f6dc9357SAndroid Build Coastguard Worker   CBrowseDialog dialog;
985*f6dc9357SAndroid Build Coastguard Worker 
986*f6dc9357SAndroid Build Coastguard Worker   dialog.FolderMode = false;
987*f6dc9357SAndroid Build Coastguard Worker   dialog.SaveMode = SaveMode;
988*f6dc9357SAndroid Build Coastguard Worker   dialog.FilterIndex = FilterIndex;
989*f6dc9357SAndroid Build Coastguard Worker   dialog.Filters = filters;
990*f6dc9357SAndroid Build Coastguard Worker 
991*f6dc9357SAndroid Build Coastguard Worker   if (lpstrTitle)
992*f6dc9357SAndroid Build Coastguard Worker     dialog.Title = lpstrTitle;
993*f6dc9357SAndroid Build Coastguard Worker   dialog.FilePath = FilePath;
994*f6dc9357SAndroid Build Coastguard Worker   if (dialog.Create(hwndOwner) != IDOK)
995*f6dc9357SAndroid Build Coastguard Worker     return false;
996*f6dc9357SAndroid Build Coastguard Worker   FilePath = dialog.FilePath;
997*f6dc9357SAndroid Build Coastguard Worker   FilterIndex = dialog.FilterIndex;
998*f6dc9357SAndroid Build Coastguard Worker #endif
999*f6dc9357SAndroid Build Coastguard Worker 
1000*f6dc9357SAndroid Build Coastguard Worker   return true;
1001*f6dc9357SAndroid Build Coastguard Worker }
1002*f6dc9357SAndroid Build Coastguard Worker 
1003*f6dc9357SAndroid Build Coastguard Worker 
1004*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
1005*f6dc9357SAndroid Build Coastguard Worker 
RemoveDotsAndSpaces(UString & path)1006*f6dc9357SAndroid Build Coastguard Worker static void RemoveDotsAndSpaces(UString &path)
1007*f6dc9357SAndroid Build Coastguard Worker {
1008*f6dc9357SAndroid Build Coastguard Worker   while (!path.IsEmpty())
1009*f6dc9357SAndroid Build Coastguard Worker   {
1010*f6dc9357SAndroid Build Coastguard Worker     wchar_t c = path.Back();
1011*f6dc9357SAndroid Build Coastguard Worker     if (c != ' ' && c != '.')
1012*f6dc9357SAndroid Build Coastguard Worker       return;
1013*f6dc9357SAndroid Build Coastguard Worker     path.DeleteBack();
1014*f6dc9357SAndroid Build Coastguard Worker   }
1015*f6dc9357SAndroid Build Coastguard Worker }
1016*f6dc9357SAndroid Build Coastguard Worker 
1017*f6dc9357SAndroid Build Coastguard Worker 
CorrectFsPath(const UString & relBase,const UString & path2,UString & result)1018*f6dc9357SAndroid Build Coastguard Worker bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result)
1019*f6dc9357SAndroid Build Coastguard Worker {
1020*f6dc9357SAndroid Build Coastguard Worker   result.Empty();
1021*f6dc9357SAndroid Build Coastguard Worker 
1022*f6dc9357SAndroid Build Coastguard Worker   UString path = path2;
1023*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
1024*f6dc9357SAndroid Build Coastguard Worker   path.Replace(L'/', WCHAR_PATH_SEPARATOR);
1025*f6dc9357SAndroid Build Coastguard Worker   #endif
1026*f6dc9357SAndroid Build Coastguard Worker   unsigned start = 0;
1027*f6dc9357SAndroid Build Coastguard Worker   UString base;
1028*f6dc9357SAndroid Build Coastguard Worker 
1029*f6dc9357SAndroid Build Coastguard Worker   if (IsAbsolutePath(path))
1030*f6dc9357SAndroid Build Coastguard Worker   {
1031*f6dc9357SAndroid Build Coastguard Worker     #if defined(_WIN32) && !defined(UNDER_CE)
1032*f6dc9357SAndroid Build Coastguard Worker     if (IsSuperOrDevicePath(path))
1033*f6dc9357SAndroid Build Coastguard Worker     {
1034*f6dc9357SAndroid Build Coastguard Worker       result = path;
1035*f6dc9357SAndroid Build Coastguard Worker       return true;
1036*f6dc9357SAndroid Build Coastguard Worker     }
1037*f6dc9357SAndroid Build Coastguard Worker     #endif
1038*f6dc9357SAndroid Build Coastguard Worker     start = GetRootPrefixSize(path);
1039*f6dc9357SAndroid Build Coastguard Worker   }
1040*f6dc9357SAndroid Build Coastguard Worker   else
1041*f6dc9357SAndroid Build Coastguard Worker   {
1042*f6dc9357SAndroid Build Coastguard Worker     #if defined(_WIN32) && !defined(UNDER_CE)
1043*f6dc9357SAndroid Build Coastguard Worker     if (IsSuperOrDevicePath(relBase))
1044*f6dc9357SAndroid Build Coastguard Worker     {
1045*f6dc9357SAndroid Build Coastguard Worker       result = path;
1046*f6dc9357SAndroid Build Coastguard Worker       return true;
1047*f6dc9357SAndroid Build Coastguard Worker     }
1048*f6dc9357SAndroid Build Coastguard Worker     #endif
1049*f6dc9357SAndroid Build Coastguard Worker     base = relBase;
1050*f6dc9357SAndroid Build Coastguard Worker   }
1051*f6dc9357SAndroid Build Coastguard Worker 
1052*f6dc9357SAndroid Build Coastguard Worker   /* We can't use backward, since we must change only disk paths */
1053*f6dc9357SAndroid Build Coastguard Worker   /*
1054*f6dc9357SAndroid Build Coastguard Worker   for (;;)
1055*f6dc9357SAndroid Build Coastguard Worker   {
1056*f6dc9357SAndroid Build Coastguard Worker     if (path.Len() <= start)
1057*f6dc9357SAndroid Build Coastguard Worker       break;
1058*f6dc9357SAndroid Build Coastguard Worker     if (DoesFileOrDirExist(us2fs(path)))
1059*f6dc9357SAndroid Build Coastguard Worker       break;
1060*f6dc9357SAndroid Build Coastguard Worker     if (path.Back() == WCHAR_PATH_SEPARATOR)
1061*f6dc9357SAndroid Build Coastguard Worker     {
1062*f6dc9357SAndroid Build Coastguard Worker       path.DeleteBack();
1063*f6dc9357SAndroid Build Coastguard Worker       result.Insert(0, WCHAR_PATH_SEPARATOR);
1064*f6dc9357SAndroid Build Coastguard Worker     }
1065*f6dc9357SAndroid Build Coastguard Worker     int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR) + 1;
1066*f6dc9357SAndroid Build Coastguard Worker     UString cur = path.Ptr(pos);
1067*f6dc9357SAndroid Build Coastguard Worker     RemoveDotsAndSpaces(cur);
1068*f6dc9357SAndroid Build Coastguard Worker     result.Insert(0, cur);
1069*f6dc9357SAndroid Build Coastguard Worker     path.DeleteFrom(pos);
1070*f6dc9357SAndroid Build Coastguard Worker   }
1071*f6dc9357SAndroid Build Coastguard Worker   result.Insert(0, path);
1072*f6dc9357SAndroid Build Coastguard Worker   return true;
1073*f6dc9357SAndroid Build Coastguard Worker   */
1074*f6dc9357SAndroid Build Coastguard Worker 
1075*f6dc9357SAndroid Build Coastguard Worker   result += path.Left(start);
1076*f6dc9357SAndroid Build Coastguard Worker   bool checkExist = true;
1077*f6dc9357SAndroid Build Coastguard Worker   UString cur;
1078*f6dc9357SAndroid Build Coastguard Worker 
1079*f6dc9357SAndroid Build Coastguard Worker   for (;;)
1080*f6dc9357SAndroid Build Coastguard Worker   {
1081*f6dc9357SAndroid Build Coastguard Worker     if (start == path.Len())
1082*f6dc9357SAndroid Build Coastguard Worker       break;
1083*f6dc9357SAndroid Build Coastguard Worker     const int slashPos = path.Find(WCHAR_PATH_SEPARATOR, start);
1084*f6dc9357SAndroid Build Coastguard Worker     cur.SetFrom(path.Ptr(start), (slashPos < 0 ? path.Len() : (unsigned)slashPos) - start);
1085*f6dc9357SAndroid Build Coastguard Worker     if (checkExist)
1086*f6dc9357SAndroid Build Coastguard Worker     {
1087*f6dc9357SAndroid Build Coastguard Worker       CFileInfo fi;
1088*f6dc9357SAndroid Build Coastguard Worker       if (fi.Find(us2fs(base + result + cur)))
1089*f6dc9357SAndroid Build Coastguard Worker       {
1090*f6dc9357SAndroid Build Coastguard Worker         if (!fi.IsDir())
1091*f6dc9357SAndroid Build Coastguard Worker         {
1092*f6dc9357SAndroid Build Coastguard Worker           result = path;
1093*f6dc9357SAndroid Build Coastguard Worker           break;
1094*f6dc9357SAndroid Build Coastguard Worker         }
1095*f6dc9357SAndroid Build Coastguard Worker       }
1096*f6dc9357SAndroid Build Coastguard Worker       else
1097*f6dc9357SAndroid Build Coastguard Worker         checkExist = false;
1098*f6dc9357SAndroid Build Coastguard Worker     }
1099*f6dc9357SAndroid Build Coastguard Worker     if (!checkExist)
1100*f6dc9357SAndroid Build Coastguard Worker       RemoveDotsAndSpaces(cur);
1101*f6dc9357SAndroid Build Coastguard Worker     result += cur;
1102*f6dc9357SAndroid Build Coastguard Worker     if (slashPos < 0)
1103*f6dc9357SAndroid Build Coastguard Worker       break;
1104*f6dc9357SAndroid Build Coastguard Worker     start = (unsigned)(slashPos + 1);
1105*f6dc9357SAndroid Build Coastguard Worker     result.Add_PathSepar();
1106*f6dc9357SAndroid Build Coastguard Worker   }
1107*f6dc9357SAndroid Build Coastguard Worker 
1108*f6dc9357SAndroid Build Coastguard Worker   return true;
1109*f6dc9357SAndroid Build Coastguard Worker }
1110*f6dc9357SAndroid Build Coastguard Worker 
1111*f6dc9357SAndroid Build Coastguard Worker #else
1112*f6dc9357SAndroid Build Coastguard Worker 
CorrectFsPath(const UString &,const UString & path,UString & result)1113*f6dc9357SAndroid Build Coastguard Worker bool CorrectFsPath(const UString & /* relBase */, const UString &path, UString &result)
1114*f6dc9357SAndroid Build Coastguard Worker {
1115*f6dc9357SAndroid Build Coastguard Worker   result = path;
1116*f6dc9357SAndroid Build Coastguard Worker   return true;
1117*f6dc9357SAndroid Build Coastguard Worker }
1118*f6dc9357SAndroid Build Coastguard Worker 
1119*f6dc9357SAndroid Build Coastguard Worker #endif
1120*f6dc9357SAndroid Build Coastguard Worker 
Dlg_CreateFolder(HWND wnd,UString & destName)1121*f6dc9357SAndroid Build Coastguard Worker bool Dlg_CreateFolder(HWND wnd, UString &destName)
1122*f6dc9357SAndroid Build Coastguard Worker {
1123*f6dc9357SAndroid Build Coastguard Worker   destName.Empty();
1124*f6dc9357SAndroid Build Coastguard Worker   CComboDialog dlg;
1125*f6dc9357SAndroid Build Coastguard Worker   LangString(IDS_CREATE_FOLDER, dlg.Title);
1126*f6dc9357SAndroid Build Coastguard Worker   LangString(IDS_CREATE_FOLDER_NAME, dlg.Static);
1127*f6dc9357SAndroid Build Coastguard Worker   LangString(IDS_CREATE_FOLDER_DEFAULT_NAME, dlg.Value);
1128*f6dc9357SAndroid Build Coastguard Worker   if (dlg.Create(wnd) != IDOK)
1129*f6dc9357SAndroid Build Coastguard Worker     return false;
1130*f6dc9357SAndroid Build Coastguard Worker   destName = dlg.Value;
1131*f6dc9357SAndroid Build Coastguard Worker   return true;
1132*f6dc9357SAndroid Build Coastguard Worker }
1133