1370b324cSopenharmony_ci// BrowseDialog.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../../Common/MyWindows.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "../../../Common/IntToString.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_ci#ifndef UNDER_CE
10370b324cSopenharmony_ci#include "../../../Windows/CommonDialog.h"
11370b324cSopenharmony_ci#include "../../../Windows/Shell.h"
12370b324cSopenharmony_ci#endif
13370b324cSopenharmony_ci
14370b324cSopenharmony_ci#include "../../../Windows/FileName.h"
15370b324cSopenharmony_ci#include "../../../Windows/FileFind.h"
16370b324cSopenharmony_ci
17370b324cSopenharmony_ci#ifdef UNDER_CE
18370b324cSopenharmony_ci#include <commdlg.h>
19370b324cSopenharmony_ci#endif
20370b324cSopenharmony_ci
21370b324cSopenharmony_ci#include "BrowseDialog.h"
22370b324cSopenharmony_ci
23370b324cSopenharmony_ci#define USE_MY_BROWSE_DIALOG
24370b324cSopenharmony_ci
25370b324cSopenharmony_ci#ifdef USE_MY_BROWSE_DIALOG
26370b324cSopenharmony_ci
27370b324cSopenharmony_ci#include "../../../Common/Defs.h"
28370b324cSopenharmony_ci#include "../../../Common/Wildcard.h"
29370b324cSopenharmony_ci
30370b324cSopenharmony_ci#include "../../../Windows/FileDir.h"
31370b324cSopenharmony_ci#include "../../../Windows/PropVariantConv.h"
32370b324cSopenharmony_ci
33370b324cSopenharmony_ci#include "../../../Windows/Control/ComboBox.h"
34370b324cSopenharmony_ci#include "../../../Windows/Control/Dialog.h"
35370b324cSopenharmony_ci#include "../../../Windows/Control/Edit.h"
36370b324cSopenharmony_ci#include "../../../Windows/Control/ListView.h"
37370b324cSopenharmony_ci
38370b324cSopenharmony_ci#include "BrowseDialogRes.h"
39370b324cSopenharmony_ci#include "PropertyNameRes.h"
40370b324cSopenharmony_ci#include "SysIconUtils.h"
41370b324cSopenharmony_ci
42370b324cSopenharmony_ci#ifndef Z7_SFX
43370b324cSopenharmony_ci#include "RegistryUtils.h"
44370b324cSopenharmony_ci#endif
45370b324cSopenharmony_ci
46370b324cSopenharmony_ci#endif // USE_MY_BROWSE_DIALOG
47370b324cSopenharmony_ci
48370b324cSopenharmony_ci#include "ComboDialog.h"
49370b324cSopenharmony_ci#include "LangUtils.h"
50370b324cSopenharmony_ci
51370b324cSopenharmony_ci#include "resource.h"
52370b324cSopenharmony_ci
53370b324cSopenharmony_ciusing namespace NWindows;
54370b324cSopenharmony_ciusing namespace NFile;
55370b324cSopenharmony_ciusing namespace NName;
56370b324cSopenharmony_ciusing namespace NFind;
57370b324cSopenharmony_ci
58370b324cSopenharmony_cistatic void MessageBox_Error_Global(HWND wnd, const wchar_t *message)
59370b324cSopenharmony_ci{
60370b324cSopenharmony_ci  ::MessageBoxW(wnd, message, L"7-Zip", MB_ICONERROR);
61370b324cSopenharmony_ci}
62370b324cSopenharmony_ci
63370b324cSopenharmony_ci#ifdef USE_MY_BROWSE_DIALOG
64370b324cSopenharmony_ci
65370b324cSopenharmony_ciextern bool g_LVN_ITEMACTIVATE_Support;
66370b324cSopenharmony_ci
67370b324cSopenharmony_cistatic const int kParentIndex = -1;
68370b324cSopenharmony_cistatic const UINT k_Message_RefreshPathEdit = WM_APP + 1;
69370b324cSopenharmony_ci
70370b324cSopenharmony_ciextern UString HResultToMessage(HRESULT errorCode);
71370b324cSopenharmony_ci
72370b324cSopenharmony_cistatic void MessageBox_HResError(HWND wnd, HRESULT errorCode, const wchar_t *name)
73370b324cSopenharmony_ci{
74370b324cSopenharmony_ci  UString s = HResultToMessage(errorCode);
75370b324cSopenharmony_ci  if (name)
76370b324cSopenharmony_ci  {
77370b324cSopenharmony_ci    s.Add_LF();
78370b324cSopenharmony_ci    s += name;
79370b324cSopenharmony_ci  }
80370b324cSopenharmony_ci  MessageBox_Error_Global(wnd, s);
81370b324cSopenharmony_ci}
82370b324cSopenharmony_ci
83370b324cSopenharmony_ciclass CBrowseDialog: public NControl::CModalDialog
84370b324cSopenharmony_ci{
85370b324cSopenharmony_ci  NControl::CListView _list;
86370b324cSopenharmony_ci  NControl::CEdit _pathEdit;
87370b324cSopenharmony_ci  NControl::CComboBox _filterCombo;
88370b324cSopenharmony_ci
89370b324cSopenharmony_ci  CObjectVector<CFileInfo> _files;
90370b324cSopenharmony_ci
91370b324cSopenharmony_ci  CExtToIconMap _extToIconMap;
92370b324cSopenharmony_ci  int _sortIndex;
93370b324cSopenharmony_ci  bool _ascending;
94370b324cSopenharmony_ci #ifndef Z7_SFX
95370b324cSopenharmony_ci  bool _showDots;
96370b324cSopenharmony_ci #endif
97370b324cSopenharmony_ci  UString _topDirPrefix; // we don't open parent of that folder
98370b324cSopenharmony_ci  UString DirPrefix;
99370b324cSopenharmony_ci
100370b324cSopenharmony_ci  virtual bool OnInit() Z7_override;
101370b324cSopenharmony_ci  virtual bool OnSize(WPARAM wParam, int xSize, int ySize) Z7_override;
102370b324cSopenharmony_ci  virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam) Z7_override;
103370b324cSopenharmony_ci  virtual bool OnNotify(UINT controlID, LPNMHDR header) Z7_override;
104370b324cSopenharmony_ci  virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam) Z7_override;
105370b324cSopenharmony_ci  virtual bool OnButtonClicked(unsigned buttonID, HWND buttonHWND) Z7_override;
106370b324cSopenharmony_ci  virtual void OnOK() Z7_override;
107370b324cSopenharmony_ci
108370b324cSopenharmony_ci  bool OnKeyDown(LPNMLVKEYDOWN keyDownInfo);
109370b324cSopenharmony_ci
110370b324cSopenharmony_ci  void Post_RefreshPathEdit() { PostMsg(k_Message_RefreshPathEdit); }
111370b324cSopenharmony_ci
112370b324cSopenharmony_ci  bool GetParentPath(const UString &path, UString &parentPrefix, UString &name);
113370b324cSopenharmony_ci  // Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter
114370b324cSopenharmony_ci  HRESULT Reload(const UString &pathPrefix, const UString &selectedName);
115370b324cSopenharmony_ci  HRESULT Reload();
116370b324cSopenharmony_ci
117370b324cSopenharmony_ci  void OpenParentFolder();
118370b324cSopenharmony_ci  void SetPathEditText();
119370b324cSopenharmony_ci  void OnCreateDir();
120370b324cSopenharmony_ci  void OnItemEnter();
121370b324cSopenharmony_ci  void FinishOnOK();
122370b324cSopenharmony_ci
123370b324cSopenharmony_ci  int GetRealItemIndex(int indexInListView) const
124370b324cSopenharmony_ci  {
125370b324cSopenharmony_ci    LPARAM param;
126370b324cSopenharmony_ci    if (!_list.GetItemParam((unsigned)indexInListView, param))
127370b324cSopenharmony_ci      return (int)-1;
128370b324cSopenharmony_ci    return (int)param;
129370b324cSopenharmony_ci  }
130370b324cSopenharmony_ci
131370b324cSopenharmony_cipublic:
132370b324cSopenharmony_ci
133370b324cSopenharmony_ci  bool SaveMode;
134370b324cSopenharmony_ci  bool FolderMode;
135370b324cSopenharmony_ci  int FilterIndex;  // [in / out]
136370b324cSopenharmony_ci  CObjectVector<CBrowseFilterInfo> Filters;
137370b324cSopenharmony_ci
138370b324cSopenharmony_ci  UString FilePath;   // [in / out]
139370b324cSopenharmony_ci  UString Title;
140370b324cSopenharmony_ci
141370b324cSopenharmony_ci  CBrowseDialog():
142370b324cSopenharmony_ci   #ifndef Z7_SFX
143370b324cSopenharmony_ci      _showDots(false),
144370b324cSopenharmony_ci   #endif
145370b324cSopenharmony_ci      SaveMode(false)
146370b324cSopenharmony_ci      , FolderMode(false)
147370b324cSopenharmony_ci      , FilterIndex(-1)
148370b324cSopenharmony_ci    {}
149370b324cSopenharmony_ci  INT_PTR Create(HWND parent = NULL) { return CModalDialog::Create(IDD_BROWSE, parent); }
150370b324cSopenharmony_ci  int CompareItems(LPARAM lParam1, LPARAM lParam2) const;
151370b324cSopenharmony_ci};
152370b324cSopenharmony_ci
153370b324cSopenharmony_ci
154370b324cSopenharmony_cibool CBrowseDialog::OnInit()
155370b324cSopenharmony_ci{
156370b324cSopenharmony_ci  #ifdef Z7_LANG
157370b324cSopenharmony_ci  LangSetDlgItems(*this, NULL, 0);
158370b324cSopenharmony_ci  #endif
159370b324cSopenharmony_ci  if (!Title.IsEmpty())
160370b324cSopenharmony_ci    SetText(Title);
161370b324cSopenharmony_ci  _list.Attach(GetItem(IDL_BROWSE));
162370b324cSopenharmony_ci  _filterCombo.Attach(GetItem(IDC_BROWSE_FILTER));
163370b324cSopenharmony_ci  _pathEdit.Attach(GetItem(IDE_BROWSE_PATH));
164370b324cSopenharmony_ci
165370b324cSopenharmony_ci  #ifndef UNDER_CE
166370b324cSopenharmony_ci  _list.SetUnicodeFormat();
167370b324cSopenharmony_ci  #endif
168370b324cSopenharmony_ci
169370b324cSopenharmony_ci  #ifndef Z7_SFX
170370b324cSopenharmony_ci  CFmSettings st;
171370b324cSopenharmony_ci  st.Load();
172370b324cSopenharmony_ci  if (st.SingleClick)
173370b324cSopenharmony_ci    _list.SetExtendedListViewStyle(LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT);
174370b324cSopenharmony_ci  _showDots = st.ShowDots;
175370b324cSopenharmony_ci  #endif
176370b324cSopenharmony_ci
177370b324cSopenharmony_ci  {
178370b324cSopenharmony_ci    /*
179370b324cSopenharmony_ci    Filters.Clear(); // for debug
180370b324cSopenharmony_ci    if (Filters.IsEmpty() && !FolderMode)
181370b324cSopenharmony_ci    {
182370b324cSopenharmony_ci      CBrowseFilterInfo &f = Filters.AddNew();
183370b324cSopenharmony_ci      const UString mask("*.*");
184370b324cSopenharmony_ci      f.Masks.Add(mask);
185370b324cSopenharmony_ci      // f.Description = "(";
186370b324cSopenharmony_ci      f.Description += mask;
187370b324cSopenharmony_ci      // f.Description += ")";
188370b324cSopenharmony_ci    }
189370b324cSopenharmony_ci    */
190370b324cSopenharmony_ci
191370b324cSopenharmony_ci    FOR_VECTOR (i, Filters)
192370b324cSopenharmony_ci    {
193370b324cSopenharmony_ci      _filterCombo.AddString(Filters[i].Description);
194370b324cSopenharmony_ci    }
195370b324cSopenharmony_ci
196370b324cSopenharmony_ci    if (Filters.Size() <= 1)
197370b324cSopenharmony_ci    {
198370b324cSopenharmony_ci      if (FolderMode)
199370b324cSopenharmony_ci        HideItem(IDC_BROWSE_FILTER);
200370b324cSopenharmony_ci      else
201370b324cSopenharmony_ci        EnableItem(IDC_BROWSE_FILTER, false);
202370b324cSopenharmony_ci    }
203370b324cSopenharmony_ci
204370b324cSopenharmony_ci    if (/* FilterIndex >= 0 && */ (unsigned)FilterIndex < Filters.Size())
205370b324cSopenharmony_ci      _filterCombo.SetCurSel(FilterIndex);
206370b324cSopenharmony_ci  }
207370b324cSopenharmony_ci
208370b324cSopenharmony_ci  _list.SetImageList(GetSysImageList(true), LVSIL_SMALL);
209370b324cSopenharmony_ci  _list.SetImageList(GetSysImageList(false), LVSIL_NORMAL);
210370b324cSopenharmony_ci
211370b324cSopenharmony_ci  _list.InsertColumn(0, LangString(IDS_PROP_NAME), 100);
212370b324cSopenharmony_ci  _list.InsertColumn(1, LangString(IDS_PROP_MTIME), 100);
213370b324cSopenharmony_ci  {
214370b324cSopenharmony_ci    LV_COLUMNW column;
215370b324cSopenharmony_ci    column.iSubItem = 2;
216370b324cSopenharmony_ci    column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
217370b324cSopenharmony_ci    column.fmt = LVCFMT_RIGHT;
218370b324cSopenharmony_ci    column.cx = 100;
219370b324cSopenharmony_ci    const UString s = LangString(IDS_PROP_SIZE);
220370b324cSopenharmony_ci    column.pszText = s.Ptr_non_const();
221370b324cSopenharmony_ci    _list.InsertColumn(2, &column);
222370b324cSopenharmony_ci  }
223370b324cSopenharmony_ci
224370b324cSopenharmony_ci  _list.InsertItem(0, L"12345678901234567"
225370b324cSopenharmony_ci      #ifndef UNDER_CE
226370b324cSopenharmony_ci      L"1234567890"
227370b324cSopenharmony_ci      #endif
228370b324cSopenharmony_ci      );
229370b324cSopenharmony_ci  _list.SetSubItem(0, 1, L"2009-09-09"
230370b324cSopenharmony_ci      #ifndef UNDER_CE
231370b324cSopenharmony_ci      L" 09:09"
232370b324cSopenharmony_ci      #endif
233370b324cSopenharmony_ci      );
234370b324cSopenharmony_ci  _list.SetSubItem(0, 2, L"9999 MB");
235370b324cSopenharmony_ci  for (int i = 0; i < 3; i++)
236370b324cSopenharmony_ci    _list.SetColumnWidthAuto(i);
237370b324cSopenharmony_ci  _list.DeleteAllItems();
238370b324cSopenharmony_ci
239370b324cSopenharmony_ci  _ascending = true;
240370b324cSopenharmony_ci  _sortIndex = 0;
241370b324cSopenharmony_ci
242370b324cSopenharmony_ci  NormalizeSize();
243370b324cSopenharmony_ci
244370b324cSopenharmony_ci  _topDirPrefix.Empty();
245370b324cSopenharmony_ci  {
246370b324cSopenharmony_ci    unsigned rootSize = GetRootPrefixSize(FilePath);
247370b324cSopenharmony_ci    #if defined(_WIN32) && !defined(UNDER_CE)
248370b324cSopenharmony_ci    // We can go up from root folder to drives list
249370b324cSopenharmony_ci    if (IsDrivePath(FilePath))
250370b324cSopenharmony_ci      rootSize = 0;
251370b324cSopenharmony_ci    else if (IsSuperPath(FilePath))
252370b324cSopenharmony_ci    {
253370b324cSopenharmony_ci      if (IsDrivePath(FilePath.Ptr(kSuperPathPrefixSize)))
254370b324cSopenharmony_ci        rootSize = kSuperPathPrefixSize;
255370b324cSopenharmony_ci    }
256370b324cSopenharmony_ci    #endif
257370b324cSopenharmony_ci    _topDirPrefix.SetFrom(FilePath, rootSize);
258370b324cSopenharmony_ci  }
259370b324cSopenharmony_ci
260370b324cSopenharmony_ci  UString name;
261370b324cSopenharmony_ci  if (!GetParentPath(FilePath, DirPrefix, name))
262370b324cSopenharmony_ci    DirPrefix = _topDirPrefix;
263370b324cSopenharmony_ci
264370b324cSopenharmony_ci  for (;;)
265370b324cSopenharmony_ci  {
266370b324cSopenharmony_ci    UString baseFolder = DirPrefix;
267370b324cSopenharmony_ci    if (Reload(baseFolder, name) == S_OK)
268370b324cSopenharmony_ci      break;
269370b324cSopenharmony_ci    name.Empty();
270370b324cSopenharmony_ci    if (DirPrefix.IsEmpty())
271370b324cSopenharmony_ci      break;
272370b324cSopenharmony_ci    UString parent, name2;
273370b324cSopenharmony_ci    GetParentPath(DirPrefix, parent, name2);
274370b324cSopenharmony_ci    DirPrefix = parent;
275370b324cSopenharmony_ci  }
276370b324cSopenharmony_ci
277370b324cSopenharmony_ci  if (name.IsEmpty())
278370b324cSopenharmony_ci    name = FilePath;
279370b324cSopenharmony_ci  if (FolderMode)
280370b324cSopenharmony_ci    NormalizeDirPathPrefix(name);
281370b324cSopenharmony_ci  _pathEdit.SetText(name);
282370b324cSopenharmony_ci
283370b324cSopenharmony_ci  #ifndef UNDER_CE
284370b324cSopenharmony_ci  /* If we clear UISF_HIDEFOCUS, the focus rectangle in ListView will be visible,
285370b324cSopenharmony_ci     even if we use mouse for pressing the button to open this dialog. */
286370b324cSopenharmony_ci  PostMsg(Z7_WIN_WM_UPDATEUISTATE, MAKEWPARAM(Z7_WIN_UIS_CLEAR, Z7_WIN_UISF_HIDEFOCUS));
287370b324cSopenharmony_ci  #endif
288370b324cSopenharmony_ci
289370b324cSopenharmony_ci  return CModalDialog::OnInit();
290370b324cSopenharmony_ci}
291370b324cSopenharmony_ci
292370b324cSopenharmony_cibool CBrowseDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
293370b324cSopenharmony_ci{
294370b324cSopenharmony_ci  int mx, my;
295370b324cSopenharmony_ci  {
296370b324cSopenharmony_ci    RECT r;
297370b324cSopenharmony_ci    GetClientRectOfItem(IDB_BROWSE_PARENT, r);
298370b324cSopenharmony_ci    mx = r.left;
299370b324cSopenharmony_ci    my = r.top;
300370b324cSopenharmony_ci  }
301370b324cSopenharmony_ci  InvalidateRect(NULL);
302370b324cSopenharmony_ci
303370b324cSopenharmony_ci  int xLim = xSize - mx;
304370b324cSopenharmony_ci  {
305370b324cSopenharmony_ci    RECT r;
306370b324cSopenharmony_ci    GetClientRectOfItem(IDT_BROWSE_FOLDER, r);
307370b324cSopenharmony_ci    MoveItem(IDT_BROWSE_FOLDER, r.left, r.top, xLim - r.left, RECT_SIZE_Y(r));
308370b324cSopenharmony_ci  }
309370b324cSopenharmony_ci
310370b324cSopenharmony_ci  int bx1, bx2, by;
311370b324cSopenharmony_ci  GetItemSizes(IDCANCEL, bx1, by);
312370b324cSopenharmony_ci  GetItemSizes(IDOK, bx2, by);
313370b324cSopenharmony_ci  int y = ySize - my - by;
314370b324cSopenharmony_ci  int x = xLim - bx1;
315370b324cSopenharmony_ci  MoveItem(IDCANCEL, x, y, bx1, by);
316370b324cSopenharmony_ci  MoveItem(IDOK, x - mx - bx2, y, bx2, by);
317370b324cSopenharmony_ci
318370b324cSopenharmony_ci  // Y_Size of ComboBox is tricky. So we use Y_Size of _pathEdit instead
319370b324cSopenharmony_ci
320370b324cSopenharmony_ci  int yPathSize;
321370b324cSopenharmony_ci  {
322370b324cSopenharmony_ci    RECT r;
323370b324cSopenharmony_ci    GetClientRectOfItem(IDE_BROWSE_PATH, r);
324370b324cSopenharmony_ci    yPathSize = RECT_SIZE_Y(r);
325370b324cSopenharmony_ci    _pathEdit.Move(r.left, y - my - yPathSize - my - yPathSize, xLim - r.left, yPathSize);
326370b324cSopenharmony_ci  }
327370b324cSopenharmony_ci
328370b324cSopenharmony_ci  {
329370b324cSopenharmony_ci    RECT r;
330370b324cSopenharmony_ci    GetClientRectOfItem(IDC_BROWSE_FILTER, r);
331370b324cSopenharmony_ci    _filterCombo.Move(r.left, y - my - yPathSize, xLim - r.left, RECT_SIZE_Y(r));
332370b324cSopenharmony_ci  }
333370b324cSopenharmony_ci
334370b324cSopenharmony_ci  {
335370b324cSopenharmony_ci    RECT r;
336370b324cSopenharmony_ci    GetClientRectOfItem(IDL_BROWSE, r);
337370b324cSopenharmony_ci    _list.Move(r.left, r.top, xLim - r.left, y - my - yPathSize - my - yPathSize - my - r.top);
338370b324cSopenharmony_ci  }
339370b324cSopenharmony_ci
340370b324cSopenharmony_ci  return false;
341370b324cSopenharmony_ci}
342370b324cSopenharmony_ci
343370b324cSopenharmony_cibool CBrowseDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
344370b324cSopenharmony_ci{
345370b324cSopenharmony_ci  if (message == k_Message_RefreshPathEdit)
346370b324cSopenharmony_ci  {
347370b324cSopenharmony_ci    SetPathEditText();
348370b324cSopenharmony_ci    return true;
349370b324cSopenharmony_ci  }
350370b324cSopenharmony_ci  return CModalDialog::OnMessage(message, wParam, lParam);
351370b324cSopenharmony_ci}
352370b324cSopenharmony_ci
353370b324cSopenharmony_ci
354370b324cSopenharmony_cibool CBrowseDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam)
355370b324cSopenharmony_ci{
356370b324cSopenharmony_ci  if (code == CBN_SELCHANGE)
357370b324cSopenharmony_ci  {
358370b324cSopenharmony_ci    switch (itemID)
359370b324cSopenharmony_ci    {
360370b324cSopenharmony_ci      case IDC_BROWSE_FILTER:
361370b324cSopenharmony_ci      {
362370b324cSopenharmony_ci        Reload();
363370b324cSopenharmony_ci        return true;
364370b324cSopenharmony_ci      }
365370b324cSopenharmony_ci    }
366370b324cSopenharmony_ci  }
367370b324cSopenharmony_ci  return CModalDialog::OnCommand(code, itemID, lParam);
368370b324cSopenharmony_ci}
369370b324cSopenharmony_ci
370370b324cSopenharmony_ci
371370b324cSopenharmony_cibool CBrowseDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
372370b324cSopenharmony_ci{
373370b324cSopenharmony_ci  if (header->hwndFrom != _list)
374370b324cSopenharmony_ci    return false;
375370b324cSopenharmony_ci  switch (header->code)
376370b324cSopenharmony_ci  {
377370b324cSopenharmony_ci    case LVN_ITEMACTIVATE:
378370b324cSopenharmony_ci      if (g_LVN_ITEMACTIVATE_Support)
379370b324cSopenharmony_ci        OnItemEnter();
380370b324cSopenharmony_ci      break;
381370b324cSopenharmony_ci    case NM_DBLCLK:
382370b324cSopenharmony_ci    case NM_RETURN: // probabably it's unused
383370b324cSopenharmony_ci      if (!g_LVN_ITEMACTIVATE_Support)
384370b324cSopenharmony_ci        OnItemEnter();
385370b324cSopenharmony_ci      break;
386370b324cSopenharmony_ci    case LVN_COLUMNCLICK:
387370b324cSopenharmony_ci    {
388370b324cSopenharmony_ci      const int index = LPNMLISTVIEW(header)->iSubItem;
389370b324cSopenharmony_ci      if (index == _sortIndex)
390370b324cSopenharmony_ci        _ascending = !_ascending;
391370b324cSopenharmony_ci      else
392370b324cSopenharmony_ci      {
393370b324cSopenharmony_ci        _ascending = (index == 0);
394370b324cSopenharmony_ci        _sortIndex = index;
395370b324cSopenharmony_ci      }
396370b324cSopenharmony_ci      Reload();
397370b324cSopenharmony_ci      return false;
398370b324cSopenharmony_ci    }
399370b324cSopenharmony_ci    case LVN_KEYDOWN:
400370b324cSopenharmony_ci    {
401370b324cSopenharmony_ci      bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header));
402370b324cSopenharmony_ci      Post_RefreshPathEdit();
403370b324cSopenharmony_ci      return boolResult;
404370b324cSopenharmony_ci    }
405370b324cSopenharmony_ci    case NM_RCLICK:
406370b324cSopenharmony_ci    case NM_CLICK:
407370b324cSopenharmony_ci    case LVN_BEGINDRAG:
408370b324cSopenharmony_ci      Post_RefreshPathEdit();
409370b324cSopenharmony_ci      break;
410370b324cSopenharmony_ci  }
411370b324cSopenharmony_ci  return false;
412370b324cSopenharmony_ci}
413370b324cSopenharmony_ci
414370b324cSopenharmony_cibool CBrowseDialog::OnKeyDown(LPNMLVKEYDOWN keyDownInfo)
415370b324cSopenharmony_ci{
416370b324cSopenharmony_ci  const bool ctrl = IsKeyDown(VK_CONTROL);
417370b324cSopenharmony_ci
418370b324cSopenharmony_ci  switch (keyDownInfo->wVKey)
419370b324cSopenharmony_ci  {
420370b324cSopenharmony_ci    case VK_BACK:
421370b324cSopenharmony_ci      OpenParentFolder();
422370b324cSopenharmony_ci      return true;
423370b324cSopenharmony_ci    case 'R':
424370b324cSopenharmony_ci      if (ctrl)
425370b324cSopenharmony_ci      {
426370b324cSopenharmony_ci        Reload();
427370b324cSopenharmony_ci        return true;
428370b324cSopenharmony_ci      }
429370b324cSopenharmony_ci      return false;
430370b324cSopenharmony_ci    case VK_F7:
431370b324cSopenharmony_ci      OnCreateDir();
432370b324cSopenharmony_ci      return true;
433370b324cSopenharmony_ci  }
434370b324cSopenharmony_ci  return false;
435370b324cSopenharmony_ci}
436370b324cSopenharmony_ci
437370b324cSopenharmony_ci
438370b324cSopenharmony_cibool CBrowseDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND)
439370b324cSopenharmony_ci{
440370b324cSopenharmony_ci  switch (buttonID)
441370b324cSopenharmony_ci  {
442370b324cSopenharmony_ci    case IDB_BROWSE_PARENT: OpenParentFolder(); break;
443370b324cSopenharmony_ci    case IDB_BROWSE_CREATE_DIR: OnCreateDir(); break;
444370b324cSopenharmony_ci    default: return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
445370b324cSopenharmony_ci  }
446370b324cSopenharmony_ci  _list.SetFocus();
447370b324cSopenharmony_ci  return true;
448370b324cSopenharmony_ci}
449370b324cSopenharmony_ci
450370b324cSopenharmony_civoid CBrowseDialog::OnOK()
451370b324cSopenharmony_ci{
452370b324cSopenharmony_ci  /* When we press "Enter" in listview, Windows sends message to first Button.
453370b324cSopenharmony_ci     We check that message was from ListView; */
454370b324cSopenharmony_ci  if (GetFocus() == _list)
455370b324cSopenharmony_ci  {
456370b324cSopenharmony_ci    OnItemEnter();
457370b324cSopenharmony_ci    return;
458370b324cSopenharmony_ci  }
459370b324cSopenharmony_ci  FinishOnOK();
460370b324cSopenharmony_ci}
461370b324cSopenharmony_ci
462370b324cSopenharmony_ci
463370b324cSopenharmony_cibool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, UString &name)
464370b324cSopenharmony_ci{
465370b324cSopenharmony_ci  parentPrefix.Empty();
466370b324cSopenharmony_ci  name.Empty();
467370b324cSopenharmony_ci  if (path.IsEmpty())
468370b324cSopenharmony_ci    return false;
469370b324cSopenharmony_ci  if (_topDirPrefix == path)
470370b324cSopenharmony_ci    return false;
471370b324cSopenharmony_ci  UString s = path;
472370b324cSopenharmony_ci  if (IS_PATH_SEPAR(s.Back()))
473370b324cSopenharmony_ci    s.DeleteBack();
474370b324cSopenharmony_ci  if (s.IsEmpty())
475370b324cSopenharmony_ci    return false;
476370b324cSopenharmony_ci  if (IS_PATH_SEPAR(s.Back()))
477370b324cSopenharmony_ci    return false;
478370b324cSopenharmony_ci  const unsigned pos1 = (unsigned)(s.ReverseFind_PathSepar() + 1);
479370b324cSopenharmony_ci  parentPrefix.SetFrom(s, pos1);
480370b324cSopenharmony_ci  name = s.Ptr(pos1);
481370b324cSopenharmony_ci  return true;
482370b324cSopenharmony_ci}
483370b324cSopenharmony_ci
484370b324cSopenharmony_ciint CBrowseDialog::CompareItems(LPARAM lParam1, LPARAM lParam2) const
485370b324cSopenharmony_ci{
486370b324cSopenharmony_ci  if (lParam1 == kParentIndex) return -1;
487370b324cSopenharmony_ci  if (lParam2 == kParentIndex) return 1;
488370b324cSopenharmony_ci  const CFileInfo &f1 = _files[(int)lParam1];
489370b324cSopenharmony_ci  const CFileInfo &f2 = _files[(int)lParam2];
490370b324cSopenharmony_ci
491370b324cSopenharmony_ci  const bool isDir1 = f1.IsDir();
492370b324cSopenharmony_ci  const bool isDir2 = f2.IsDir();
493370b324cSopenharmony_ci  if (isDir1 && !isDir2) return -1;
494370b324cSopenharmony_ci  if (isDir2 && !isDir1) return 1;
495370b324cSopenharmony_ci
496370b324cSopenharmony_ci  int res = 0;
497370b324cSopenharmony_ci  switch (_sortIndex)
498370b324cSopenharmony_ci  {
499370b324cSopenharmony_ci    case 0: res = CompareFileNames(fs2us(f1.Name), fs2us(f2.Name)); break;
500370b324cSopenharmony_ci    case 1: res = CompareFileTime(&f1.MTime, &f2.MTime); break;
501370b324cSopenharmony_ci    case 2: res = MyCompare(f1.Size, f2.Size); break;
502370b324cSopenharmony_ci  }
503370b324cSopenharmony_ci  return _ascending ? res: -res;
504370b324cSopenharmony_ci}
505370b324cSopenharmony_ci
506370b324cSopenharmony_cistatic int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
507370b324cSopenharmony_ci{
508370b324cSopenharmony_ci  return ((CBrowseDialog *)lpData)->CompareItems(lParam1, lParam2);
509370b324cSopenharmony_ci}
510370b324cSopenharmony_ci
511370b324cSopenharmony_cistatic void ConvertSizeToString(UInt64 v, wchar_t *s)
512370b324cSopenharmony_ci{
513370b324cSopenharmony_ci  char c = 0;
514370b324cSopenharmony_ci       if (v >= ((UInt64)10000 << 20)) { v >>= 30; c = 'G'; }
515370b324cSopenharmony_ci  else if (v >= ((UInt64)10000 << 10)) { v >>= 20; c = 'M'; }
516370b324cSopenharmony_ci  else if (v >= ((UInt64)10000 <<  0)) { v >>= 10; c = 'K'; }
517370b324cSopenharmony_ci  s = ConvertUInt64ToString(v, s);
518370b324cSopenharmony_ci  if (c != 0)
519370b324cSopenharmony_ci  {
520370b324cSopenharmony_ci    *s++ = ' ';
521370b324cSopenharmony_ci    *s++ = (wchar_t)c;
522370b324cSopenharmony_ci    *s++ = 'B';
523370b324cSopenharmony_ci    *s++ = 0;
524370b324cSopenharmony_ci  }
525370b324cSopenharmony_ci}
526370b324cSopenharmony_ci
527370b324cSopenharmony_ci// Reload changes DirPrefix. Don't send DirPrefix in pathPrefix parameter
528370b324cSopenharmony_ci
529370b324cSopenharmony_ciHRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selectedName)
530370b324cSopenharmony_ci{
531370b324cSopenharmony_ci  CObjectVector<CFileInfo> files;
532370b324cSopenharmony_ci
533370b324cSopenharmony_ci  #ifndef UNDER_CE
534370b324cSopenharmony_ci  bool isDrive = false;
535370b324cSopenharmony_ci  if (pathPrefix.IsEmpty() || pathPrefix.IsEqualTo(kSuperPathPrefix))
536370b324cSopenharmony_ci  {
537370b324cSopenharmony_ci    isDrive = true;
538370b324cSopenharmony_ci    FStringVector drives;
539370b324cSopenharmony_ci    if (!MyGetLogicalDriveStrings(drives))
540370b324cSopenharmony_ci      return GetLastError_noZero_HRESULT();
541370b324cSopenharmony_ci    FOR_VECTOR (i, drives)
542370b324cSopenharmony_ci    {
543370b324cSopenharmony_ci      const FString &d = drives[i];
544370b324cSopenharmony_ci      if (d.Len() < 2 || d.Back() != '\\')
545370b324cSopenharmony_ci        return E_FAIL;
546370b324cSopenharmony_ci      CFileInfo &fi = files.AddNew();
547370b324cSopenharmony_ci      fi.SetAsDir();
548370b324cSopenharmony_ci      fi.Name = d;
549370b324cSopenharmony_ci      fi.Name.DeleteBack();
550370b324cSopenharmony_ci    }
551370b324cSopenharmony_ci  }
552370b324cSopenharmony_ci  else
553370b324cSopenharmony_ci  #endif
554370b324cSopenharmony_ci  {
555370b324cSopenharmony_ci    const UStringVector *masks = NULL;
556370b324cSopenharmony_ci    if (!Filters.IsEmpty() && _filterCombo.GetCount() > 0)
557370b324cSopenharmony_ci    {
558370b324cSopenharmony_ci      const int selected = _filterCombo.GetCurSel();
559370b324cSopenharmony_ci            // GetItemData_of_CurSel(); // we don't use data field
560370b324cSopenharmony_ci      if (/* selected >= 0 && */ (unsigned)selected < Filters.Size())
561370b324cSopenharmony_ci      {
562370b324cSopenharmony_ci        const UStringVector &m = Filters[selected].Masks;
563370b324cSopenharmony_ci        if (m.Size() > 1 || (m.Size() == 1
564370b324cSopenharmony_ci              && !m[0].IsEqualTo("*.*")
565370b324cSopenharmony_ci              && !m[0].IsEqualTo("*")))
566370b324cSopenharmony_ci          masks = &m;
567370b324cSopenharmony_ci      }
568370b324cSopenharmony_ci    }
569370b324cSopenharmony_ci    CEnumerator enumerator;
570370b324cSopenharmony_ci    enumerator.SetDirPrefix(us2fs(pathPrefix));
571370b324cSopenharmony_ci    CFileInfo fi;
572370b324cSopenharmony_ci    for (;;)
573370b324cSopenharmony_ci    {
574370b324cSopenharmony_ci      bool found;
575370b324cSopenharmony_ci      if (!enumerator.Next(fi, found))
576370b324cSopenharmony_ci        return GetLastError_noZero_HRESULT();
577370b324cSopenharmony_ci      if (!found)
578370b324cSopenharmony_ci        break;
579370b324cSopenharmony_ci      if (!fi.IsDir())
580370b324cSopenharmony_ci      {
581370b324cSopenharmony_ci        if (FolderMode)
582370b324cSopenharmony_ci          continue;
583370b324cSopenharmony_ci        if (masks)
584370b324cSopenharmony_ci        {
585370b324cSopenharmony_ci          unsigned i;
586370b324cSopenharmony_ci          const unsigned numMasks = masks->Size();
587370b324cSopenharmony_ci          for (i = 0; i < numMasks; i++)
588370b324cSopenharmony_ci            if (DoesWildcardMatchName((*masks)[i], fs2us(fi.Name)))
589370b324cSopenharmony_ci              break;
590370b324cSopenharmony_ci          if (i == numMasks)
591370b324cSopenharmony_ci            continue;
592370b324cSopenharmony_ci        }
593370b324cSopenharmony_ci      }
594370b324cSopenharmony_ci      files.Add(fi);
595370b324cSopenharmony_ci    }
596370b324cSopenharmony_ci  }
597370b324cSopenharmony_ci
598370b324cSopenharmony_ci  DirPrefix = pathPrefix;
599370b324cSopenharmony_ci
600370b324cSopenharmony_ci  _files = files;
601370b324cSopenharmony_ci
602370b324cSopenharmony_ci  SetItemText(IDT_BROWSE_FOLDER, DirPrefix);
603370b324cSopenharmony_ci
604370b324cSopenharmony_ci  _list.SetRedraw(false);
605370b324cSopenharmony_ci  _list.DeleteAllItems();
606370b324cSopenharmony_ci
607370b324cSopenharmony_ci  LVITEMW item;
608370b324cSopenharmony_ci
609370b324cSopenharmony_ci  unsigned index = 0;
610370b324cSopenharmony_ci  int cursorIndex = -1;
611370b324cSopenharmony_ci
612370b324cSopenharmony_ci  #ifndef Z7_SFX
613370b324cSopenharmony_ci  if (_showDots && _topDirPrefix != DirPrefix)
614370b324cSopenharmony_ci  {
615370b324cSopenharmony_ci    item.iItem = (int)index;
616370b324cSopenharmony_ci    const UString itemName ("..");
617370b324cSopenharmony_ci    if (selectedName.IsEmpty())
618370b324cSopenharmony_ci      cursorIndex = (int)index;
619370b324cSopenharmony_ci    item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
620370b324cSopenharmony_ci    unsigned subItem = 0;
621370b324cSopenharmony_ci    item.iSubItem = (int)(subItem++);
622370b324cSopenharmony_ci    item.lParam = kParentIndex;
623370b324cSopenharmony_ci    item.pszText = itemName.Ptr_non_const();
624370b324cSopenharmony_ci    item.iImage = _extToIconMap.GetIconIndex(FILE_ATTRIBUTE_DIRECTORY, DirPrefix);
625370b324cSopenharmony_ci    if (item.iImage < 0)
626370b324cSopenharmony_ci      item.iImage = 0;
627370b324cSopenharmony_ci    _list.InsertItem(&item);
628370b324cSopenharmony_ci    _list.SetSubItem(index, subItem++, L"");
629370b324cSopenharmony_ci    _list.SetSubItem(index, subItem++, L"");
630370b324cSopenharmony_ci    index++;
631370b324cSopenharmony_ci  }
632370b324cSopenharmony_ci  #endif
633370b324cSopenharmony_ci
634370b324cSopenharmony_ci  for (unsigned i = 0; i < _files.Size(); i++, index++)
635370b324cSopenharmony_ci  {
636370b324cSopenharmony_ci    item.iItem = (int)index;
637370b324cSopenharmony_ci    const CFileInfo &fi = _files[i];
638370b324cSopenharmony_ci    const UString name = fs2us(fi.Name);
639370b324cSopenharmony_ci    if (!selectedName.IsEmpty() && CompareFileNames(name, selectedName) == 0)
640370b324cSopenharmony_ci      cursorIndex = (int)index;
641370b324cSopenharmony_ci    item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
642370b324cSopenharmony_ci    unsigned subItem = 0;
643370b324cSopenharmony_ci    item.iSubItem = (int)(subItem++);
644370b324cSopenharmony_ci    item.lParam = (LPARAM)i;
645370b324cSopenharmony_ci    item.pszText = name.Ptr_non_const();
646370b324cSopenharmony_ci
647370b324cSopenharmony_ci    const UString fullPath = DirPrefix + name;
648370b324cSopenharmony_ci    #ifndef UNDER_CE
649370b324cSopenharmony_ci    if (isDrive)
650370b324cSopenharmony_ci    {
651370b324cSopenharmony_ci      if (GetRealIconIndex(fi.Name + FCHAR_PATH_SEPARATOR, FILE_ATTRIBUTE_DIRECTORY, item.iImage) == 0)
652370b324cSopenharmony_ci        item.iImage = 0;
653370b324cSopenharmony_ci    }
654370b324cSopenharmony_ci    else
655370b324cSopenharmony_ci    #endif
656370b324cSopenharmony_ci      item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, fullPath);
657370b324cSopenharmony_ci    if (item.iImage < 0)
658370b324cSopenharmony_ci      item.iImage = 0;
659370b324cSopenharmony_ci    _list.InsertItem(&item);
660370b324cSopenharmony_ci    wchar_t s[32];
661370b324cSopenharmony_ci    {
662370b324cSopenharmony_ci      s[0] = 0;
663370b324cSopenharmony_ci      ConvertUtcFileTimeToString(fi.MTime, s,
664370b324cSopenharmony_ci            #ifndef UNDER_CE
665370b324cSopenharmony_ci              kTimestampPrintLevel_MIN
666370b324cSopenharmony_ci            #else
667370b324cSopenharmony_ci              kTimestampPrintLevel_DAY
668370b324cSopenharmony_ci            #endif
669370b324cSopenharmony_ci              );
670370b324cSopenharmony_ci      _list.SetSubItem(index, subItem++, s);
671370b324cSopenharmony_ci    }
672370b324cSopenharmony_ci    {
673370b324cSopenharmony_ci      s[0] = 0;
674370b324cSopenharmony_ci      if (!fi.IsDir())
675370b324cSopenharmony_ci        ConvertSizeToString(fi.Size, s);
676370b324cSopenharmony_ci      _list.SetSubItem(index, subItem++, s);
677370b324cSopenharmony_ci    }
678370b324cSopenharmony_ci  }
679370b324cSopenharmony_ci
680370b324cSopenharmony_ci  if (_list.GetItemCount() > 0 && cursorIndex >= 0)
681370b324cSopenharmony_ci    _list.SetItemState_FocusedSelected(cursorIndex);
682370b324cSopenharmony_ci  _list.SortItems(CompareItems2, (LPARAM)this);
683370b324cSopenharmony_ci  if (_list.GetItemCount() > 0 && cursorIndex < 0)
684370b324cSopenharmony_ci    _list.SetItemState(0, LVIS_FOCUSED, LVIS_FOCUSED);
685370b324cSopenharmony_ci  _list.EnsureVisible(_list.GetFocusedItem(), false);
686370b324cSopenharmony_ci  _list.SetRedraw(true);
687370b324cSopenharmony_ci  _list.InvalidateRect(NULL, true);
688370b324cSopenharmony_ci  return S_OK;
689370b324cSopenharmony_ci}
690370b324cSopenharmony_ci
691370b324cSopenharmony_ciHRESULT CBrowseDialog::Reload()
692370b324cSopenharmony_ci{
693370b324cSopenharmony_ci  UString selected;
694370b324cSopenharmony_ci  const int index = _list.GetNextSelectedItem(-1);
695370b324cSopenharmony_ci  if (index >= 0)
696370b324cSopenharmony_ci  {
697370b324cSopenharmony_ci    const int fileIndex = GetRealItemIndex(index);
698370b324cSopenharmony_ci    if (fileIndex != kParentIndex)
699370b324cSopenharmony_ci      selected = fs2us(_files[fileIndex].Name);
700370b324cSopenharmony_ci  }
701370b324cSopenharmony_ci  const UString dirPathTemp = DirPrefix;
702370b324cSopenharmony_ci  return Reload(dirPathTemp, selected);
703370b324cSopenharmony_ci}
704370b324cSopenharmony_ci
705370b324cSopenharmony_civoid CBrowseDialog::OpenParentFolder()
706370b324cSopenharmony_ci{
707370b324cSopenharmony_ci  UString parent, selected;
708370b324cSopenharmony_ci  if (GetParentPath(DirPrefix, parent, selected))
709370b324cSopenharmony_ci  {
710370b324cSopenharmony_ci    Reload(parent, selected);
711370b324cSopenharmony_ci    SetPathEditText();
712370b324cSopenharmony_ci  }
713370b324cSopenharmony_ci}
714370b324cSopenharmony_ci
715370b324cSopenharmony_civoid CBrowseDialog::SetPathEditText()
716370b324cSopenharmony_ci{
717370b324cSopenharmony_ci  const int index = _list.GetNextSelectedItem(-1);
718370b324cSopenharmony_ci  if (index < 0)
719370b324cSopenharmony_ci  {
720370b324cSopenharmony_ci    if (FolderMode)
721370b324cSopenharmony_ci      _pathEdit.SetText(DirPrefix);
722370b324cSopenharmony_ci    return;
723370b324cSopenharmony_ci  }
724370b324cSopenharmony_ci  const int fileIndex = GetRealItemIndex(index);
725370b324cSopenharmony_ci  if (fileIndex == kParentIndex)
726370b324cSopenharmony_ci  {
727370b324cSopenharmony_ci    if (FolderMode)
728370b324cSopenharmony_ci      _pathEdit.SetText(L".." WSTRING_PATH_SEPARATOR);
729370b324cSopenharmony_ci    return;
730370b324cSopenharmony_ci  }
731370b324cSopenharmony_ci  const CFileInfo &file = _files[fileIndex];
732370b324cSopenharmony_ci  if (file.IsDir())
733370b324cSopenharmony_ci  {
734370b324cSopenharmony_ci    if (!FolderMode)
735370b324cSopenharmony_ci      return;
736370b324cSopenharmony_ci    _pathEdit.SetText(fs2us(file.Name) + WCHAR_PATH_SEPARATOR);
737370b324cSopenharmony_ci  }
738370b324cSopenharmony_ci  else
739370b324cSopenharmony_ci    _pathEdit.SetText(fs2us(file.Name));
740370b324cSopenharmony_ci}
741370b324cSopenharmony_ci
742370b324cSopenharmony_civoid CBrowseDialog::OnCreateDir()
743370b324cSopenharmony_ci{
744370b324cSopenharmony_ci  UString name;
745370b324cSopenharmony_ci  {
746370b324cSopenharmony_ci    UString enteredName;
747370b324cSopenharmony_ci    Dlg_CreateFolder((HWND)*this, enteredName);
748370b324cSopenharmony_ci    if (enteredName.IsEmpty())
749370b324cSopenharmony_ci      return;
750370b324cSopenharmony_ci    if (!CorrectFsPath(DirPrefix, enteredName, name))
751370b324cSopenharmony_ci    {
752370b324cSopenharmony_ci      MessageBox_HResError((HWND)*this, ERROR_INVALID_NAME, name);
753370b324cSopenharmony_ci      return;
754370b324cSopenharmony_ci    }
755370b324cSopenharmony_ci  }
756370b324cSopenharmony_ci  if (name.IsEmpty())
757370b324cSopenharmony_ci    return;
758370b324cSopenharmony_ci
759370b324cSopenharmony_ci  FString destPath;
760370b324cSopenharmony_ci  if (GetFullPath(us2fs(DirPrefix), us2fs(name), destPath))
761370b324cSopenharmony_ci  {
762370b324cSopenharmony_ci    if (!NDir::CreateComplexDir(destPath))
763370b324cSopenharmony_ci    {
764370b324cSopenharmony_ci      MessageBox_HResError((HWND)*this, GetLastError_noZero_HRESULT(), fs2us(destPath));
765370b324cSopenharmony_ci    }
766370b324cSopenharmony_ci    else
767370b324cSopenharmony_ci    {
768370b324cSopenharmony_ci      UString tempPath = DirPrefix;
769370b324cSopenharmony_ci      Reload(tempPath, name);
770370b324cSopenharmony_ci      SetPathEditText();
771370b324cSopenharmony_ci    }
772370b324cSopenharmony_ci    _list.SetFocus();
773370b324cSopenharmony_ci  }
774370b324cSopenharmony_ci}
775370b324cSopenharmony_ci
776370b324cSopenharmony_civoid CBrowseDialog::OnItemEnter()
777370b324cSopenharmony_ci{
778370b324cSopenharmony_ci  const int index = _list.GetNextSelectedItem(-1);
779370b324cSopenharmony_ci  if (index < 0)
780370b324cSopenharmony_ci    return;
781370b324cSopenharmony_ci  const int fileIndex = GetRealItemIndex(index);
782370b324cSopenharmony_ci  if (fileIndex == kParentIndex)
783370b324cSopenharmony_ci    OpenParentFolder();
784370b324cSopenharmony_ci  else
785370b324cSopenharmony_ci  {
786370b324cSopenharmony_ci    const CFileInfo &file = _files[fileIndex];
787370b324cSopenharmony_ci    if (!file.IsDir())
788370b324cSopenharmony_ci    {
789370b324cSopenharmony_ci      if (!FolderMode)
790370b324cSopenharmony_ci        FinishOnOK();
791370b324cSopenharmony_ci      /*
792370b324cSopenharmony_ci      MessageBox_Error_Global(*this, FolderMode ?
793370b324cSopenharmony_ci            L"You must select some folder":
794370b324cSopenharmony_ci            L"You must select some file");
795370b324cSopenharmony_ci      */
796370b324cSopenharmony_ci      return;
797370b324cSopenharmony_ci    }
798370b324cSopenharmony_ci    UString s = DirPrefix;
799370b324cSopenharmony_ci    s += fs2us(file.Name);
800370b324cSopenharmony_ci    s.Add_PathSepar();
801370b324cSopenharmony_ci    const HRESULT res = Reload(s, UString());
802370b324cSopenharmony_ci    if (res != S_OK)
803370b324cSopenharmony_ci      MessageBox_HResError(*this, res, s);
804370b324cSopenharmony_ci    SetPathEditText();
805370b324cSopenharmony_ci  }
806370b324cSopenharmony_ci}
807370b324cSopenharmony_ci
808370b324cSopenharmony_civoid CBrowseDialog::FinishOnOK()
809370b324cSopenharmony_ci{
810370b324cSopenharmony_ci  UString s;
811370b324cSopenharmony_ci  _pathEdit.GetText(s);
812370b324cSopenharmony_ci  FString destPath;
813370b324cSopenharmony_ci  if (!GetFullPath(us2fs(DirPrefix), us2fs(s), destPath))
814370b324cSopenharmony_ci  {
815370b324cSopenharmony_ci    MessageBox_HResError((HWND)*this, ERROR_INVALID_NAME, s);
816370b324cSopenharmony_ci    return;
817370b324cSopenharmony_ci  }
818370b324cSopenharmony_ci  FilePath = fs2us(destPath);
819370b324cSopenharmony_ci  if (FolderMode)
820370b324cSopenharmony_ci    NormalizeDirPathPrefix(FilePath);
821370b324cSopenharmony_ci  FilterIndex = _filterCombo.GetCurSel();
822370b324cSopenharmony_ci  End(IDOK);
823370b324cSopenharmony_ci}
824370b324cSopenharmony_ci
825370b324cSopenharmony_ci#endif // USE_MY_BROWSE_DIALOG
826370b324cSopenharmony_ci
827370b324cSopenharmony_ci
828370b324cSopenharmony_ci
829370b324cSopenharmony_cibool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultPath)
830370b324cSopenharmony_ci{
831370b324cSopenharmony_ci  resultPath.Empty();
832370b324cSopenharmony_ci
833370b324cSopenharmony_ci  #ifndef UNDER_CE
834370b324cSopenharmony_ci
835370b324cSopenharmony_ci#ifdef USE_MY_BROWSE_DIALOG
836370b324cSopenharmony_ci  if (!IsSuperOrDevicePath(path))
837370b324cSopenharmony_ci  if (MyStringLen(path) < MAX_PATH)
838370b324cSopenharmony_ci#endif
839370b324cSopenharmony_ci    return NShell::BrowseForFolder(owner, title, path, resultPath);
840370b324cSopenharmony_ci
841370b324cSopenharmony_ci  #endif //  UNDER_CE
842370b324cSopenharmony_ci
843370b324cSopenharmony_ci  #ifdef USE_MY_BROWSE_DIALOG
844370b324cSopenharmony_ci
845370b324cSopenharmony_ci  CBrowseDialog dialog;
846370b324cSopenharmony_ci  dialog.FolderMode = true;
847370b324cSopenharmony_ci  if (title)
848370b324cSopenharmony_ci    dialog.Title = title;
849370b324cSopenharmony_ci  if (path)
850370b324cSopenharmony_ci    dialog.FilePath = path;
851370b324cSopenharmony_ci  if (dialog.Create(owner) != IDOK)
852370b324cSopenharmony_ci    return false;
853370b324cSopenharmony_ci  resultPath = dialog.FilePath;
854370b324cSopenharmony_ci  return true;
855370b324cSopenharmony_ci
856370b324cSopenharmony_ci  #endif
857370b324cSopenharmony_ci}
858370b324cSopenharmony_ci
859370b324cSopenharmony_ci
860370b324cSopenharmony_ci// LPCWSTR filterDescription, LPCWSTR filter,
861370b324cSopenharmony_ci
862370b324cSopenharmony_cibool CBrowseInfo::BrowseForFile(const CObjectVector<CBrowseFilterInfo> &filters)
863370b324cSopenharmony_ci{
864370b324cSopenharmony_ci#ifndef UNDER_CE
865370b324cSopenharmony_ci#ifdef USE_MY_BROWSE_DIALOG
866370b324cSopenharmony_ci  /* win10:
867370b324cSopenharmony_ci     GetOpenFileName() for FilePath doesn't support super prefix "\\\\?\\"
868370b324cSopenharmony_ci     GetOpenFileName() for FilePath doesn't support long path
869370b324cSopenharmony_ci  */
870370b324cSopenharmony_ci  if (!IsSuperOrDevicePath(FilePath))
871370b324cSopenharmony_ci  // if (filters.Size() > 100) // for debug
872370b324cSopenharmony_ci#endif
873370b324cSopenharmony_ci  {
874370b324cSopenharmony_ci    const UString filePath_Store = FilePath;
875370b324cSopenharmony_ci    UString dirPrefix;
876370b324cSopenharmony_ci    {
877370b324cSopenharmony_ci      FString prefix, name;
878370b324cSopenharmony_ci      if (NDir::GetFullPathAndSplit(us2fs(FilePath), prefix, name))
879370b324cSopenharmony_ci      {
880370b324cSopenharmony_ci        dirPrefix = fs2us(prefix);
881370b324cSopenharmony_ci        FilePath = fs2us(name);
882370b324cSopenharmony_ci      }
883370b324cSopenharmony_ci    }
884370b324cSopenharmony_ci    UStringVector filters2;
885370b324cSopenharmony_ci    FOR_VECTOR (i, filters)
886370b324cSopenharmony_ci    {
887370b324cSopenharmony_ci      const CBrowseFilterInfo &fi = filters[i];
888370b324cSopenharmony_ci      filters2.Add(fi.Description);
889370b324cSopenharmony_ci      UString s;
890370b324cSopenharmony_ci      FOR_VECTOR (k, fi.Masks)
891370b324cSopenharmony_ci      {
892370b324cSopenharmony_ci        if (k != 0)
893370b324cSopenharmony_ci          s += ";";
894370b324cSopenharmony_ci        s += fi.Masks[k];
895370b324cSopenharmony_ci      }
896370b324cSopenharmony_ci      filters2.Add(s);
897370b324cSopenharmony_ci    }
898370b324cSopenharmony_ci    if (CommonDlg_BrowseForFile(!dirPrefix.IsEmpty() ? dirPrefix.Ptr(): NULL, filters2))
899370b324cSopenharmony_ci      return true;
900370b324cSopenharmony_ci    FilePath = filePath_Store;
901370b324cSopenharmony_ci
902370b324cSopenharmony_ci  #ifdef UNDER_CE
903370b324cSopenharmony_ci    return false;
904370b324cSopenharmony_ci  #else
905370b324cSopenharmony_ci    // maybe we must use GetLastError in WinCE.
906370b324cSopenharmony_ci    const DWORD errorCode = CommDlgExtendedError();
907370b324cSopenharmony_ci  #ifdef USE_MY_BROWSE_DIALOG
908370b324cSopenharmony_ci    // FNERR_INVALIDFILENAME is expected error, if long path was used
909370b324cSopenharmony_ci    if (errorCode != FNERR_INVALIDFILENAME
910370b324cSopenharmony_ci        || FilePath.Len() < MAX_PATH)
911370b324cSopenharmony_ci  #endif
912370b324cSopenharmony_ci    {
913370b324cSopenharmony_ci      if (errorCode == 0)  // cancel or close on dialog
914370b324cSopenharmony_ci        return false;
915370b324cSopenharmony_ci      const char *message = NULL;
916370b324cSopenharmony_ci      if (errorCode == FNERR_INVALIDFILENAME)
917370b324cSopenharmony_ci        message = "Invalid file name";
918370b324cSopenharmony_ci      UString s ("Open Dialog Error:");
919370b324cSopenharmony_ci      s.Add_LF();
920370b324cSopenharmony_ci      if (message)
921370b324cSopenharmony_ci        s += message;
922370b324cSopenharmony_ci      else
923370b324cSopenharmony_ci      {
924370b324cSopenharmony_ci        char temp[16];
925370b324cSopenharmony_ci        ConvertUInt32ToHex8Digits(errorCode, temp);
926370b324cSopenharmony_ci        s += "Error #";
927370b324cSopenharmony_ci        s += temp;
928370b324cSopenharmony_ci      }
929370b324cSopenharmony_ci      s.Add_LF();
930370b324cSopenharmony_ci      s += FilePath;
931370b324cSopenharmony_ci      MessageBox_Error_Global(hwndOwner, s);
932370b324cSopenharmony_ci    }
933370b324cSopenharmony_ci  #endif // UNDER_CE
934370b324cSopenharmony_ci  }
935370b324cSopenharmony_ci
936370b324cSopenharmony_ci#endif // UNDER_CE
937370b324cSopenharmony_ci
938370b324cSopenharmony_ci#ifdef USE_MY_BROWSE_DIALOG
939370b324cSopenharmony_ci
940370b324cSopenharmony_ci  CBrowseDialog dialog;
941370b324cSopenharmony_ci
942370b324cSopenharmony_ci  dialog.FolderMode = false;
943370b324cSopenharmony_ci  dialog.SaveMode = SaveMode;
944370b324cSopenharmony_ci  dialog.FilterIndex = FilterIndex;
945370b324cSopenharmony_ci  dialog.Filters = filters;
946370b324cSopenharmony_ci
947370b324cSopenharmony_ci  if (lpstrTitle)
948370b324cSopenharmony_ci    dialog.Title = lpstrTitle;
949370b324cSopenharmony_ci  dialog.FilePath = FilePath;
950370b324cSopenharmony_ci  if (dialog.Create(hwndOwner) != IDOK)
951370b324cSopenharmony_ci    return false;
952370b324cSopenharmony_ci  FilePath = dialog.FilePath;
953370b324cSopenharmony_ci  FilterIndex = dialog.FilterIndex;
954370b324cSopenharmony_ci#endif
955370b324cSopenharmony_ci
956370b324cSopenharmony_ci  return true;
957370b324cSopenharmony_ci}
958370b324cSopenharmony_ci
959370b324cSopenharmony_ci
960370b324cSopenharmony_ci#ifdef _WIN32
961370b324cSopenharmony_ci
962370b324cSopenharmony_cistatic void RemoveDotsAndSpaces(UString &path)
963370b324cSopenharmony_ci{
964370b324cSopenharmony_ci  while (!path.IsEmpty())
965370b324cSopenharmony_ci  {
966370b324cSopenharmony_ci    wchar_t c = path.Back();
967370b324cSopenharmony_ci    if (c != ' ' && c != '.')
968370b324cSopenharmony_ci      return;
969370b324cSopenharmony_ci    path.DeleteBack();
970370b324cSopenharmony_ci  }
971370b324cSopenharmony_ci}
972370b324cSopenharmony_ci
973370b324cSopenharmony_ci
974370b324cSopenharmony_cibool CorrectFsPath(const UString &relBase, const UString &path2, UString &result)
975370b324cSopenharmony_ci{
976370b324cSopenharmony_ci  result.Empty();
977370b324cSopenharmony_ci
978370b324cSopenharmony_ci  UString path = path2;
979370b324cSopenharmony_ci  #ifdef _WIN32
980370b324cSopenharmony_ci  path.Replace(L'/', WCHAR_PATH_SEPARATOR);
981370b324cSopenharmony_ci  #endif
982370b324cSopenharmony_ci  unsigned start = 0;
983370b324cSopenharmony_ci  UString base;
984370b324cSopenharmony_ci
985370b324cSopenharmony_ci  if (IsAbsolutePath(path))
986370b324cSopenharmony_ci  {
987370b324cSopenharmony_ci    #if defined(_WIN32) && !defined(UNDER_CE)
988370b324cSopenharmony_ci    if (IsSuperOrDevicePath(path))
989370b324cSopenharmony_ci    {
990370b324cSopenharmony_ci      result = path;
991370b324cSopenharmony_ci      return true;
992370b324cSopenharmony_ci    }
993370b324cSopenharmony_ci    #endif
994370b324cSopenharmony_ci    start = GetRootPrefixSize(path);
995370b324cSopenharmony_ci  }
996370b324cSopenharmony_ci  else
997370b324cSopenharmony_ci  {
998370b324cSopenharmony_ci    #if defined(_WIN32) && !defined(UNDER_CE)
999370b324cSopenharmony_ci    if (IsSuperOrDevicePath(relBase))
1000370b324cSopenharmony_ci    {
1001370b324cSopenharmony_ci      result = path;
1002370b324cSopenharmony_ci      return true;
1003370b324cSopenharmony_ci    }
1004370b324cSopenharmony_ci    #endif
1005370b324cSopenharmony_ci    base = relBase;
1006370b324cSopenharmony_ci  }
1007370b324cSopenharmony_ci
1008370b324cSopenharmony_ci  /* We can't use backward, since we must change only disk paths */
1009370b324cSopenharmony_ci  /*
1010370b324cSopenharmony_ci  for (;;)
1011370b324cSopenharmony_ci  {
1012370b324cSopenharmony_ci    if (path.Len() <= start)
1013370b324cSopenharmony_ci      break;
1014370b324cSopenharmony_ci    if (DoesFileOrDirExist(us2fs(path)))
1015370b324cSopenharmony_ci      break;
1016370b324cSopenharmony_ci    if (path.Back() == WCHAR_PATH_SEPARATOR)
1017370b324cSopenharmony_ci    {
1018370b324cSopenharmony_ci      path.DeleteBack();
1019370b324cSopenharmony_ci      result.Insert(0, WCHAR_PATH_SEPARATOR);
1020370b324cSopenharmony_ci    }
1021370b324cSopenharmony_ci    int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR) + 1;
1022370b324cSopenharmony_ci    UString cur = path.Ptr(pos);
1023370b324cSopenharmony_ci    RemoveDotsAndSpaces(cur);
1024370b324cSopenharmony_ci    result.Insert(0, cur);
1025370b324cSopenharmony_ci    path.DeleteFrom(pos);
1026370b324cSopenharmony_ci  }
1027370b324cSopenharmony_ci  result.Insert(0, path);
1028370b324cSopenharmony_ci  return true;
1029370b324cSopenharmony_ci  */
1030370b324cSopenharmony_ci
1031370b324cSopenharmony_ci  result += path.Left(start);
1032370b324cSopenharmony_ci  bool checkExist = true;
1033370b324cSopenharmony_ci  UString cur;
1034370b324cSopenharmony_ci
1035370b324cSopenharmony_ci  for (;;)
1036370b324cSopenharmony_ci  {
1037370b324cSopenharmony_ci    if (start == path.Len())
1038370b324cSopenharmony_ci      break;
1039370b324cSopenharmony_ci    const int slashPos = path.Find(WCHAR_PATH_SEPARATOR, start);
1040370b324cSopenharmony_ci    cur.SetFrom(path.Ptr(start), (slashPos < 0 ? path.Len() : (unsigned)slashPos) - start);
1041370b324cSopenharmony_ci    if (checkExist)
1042370b324cSopenharmony_ci    {
1043370b324cSopenharmony_ci      CFileInfo fi;
1044370b324cSopenharmony_ci      if (fi.Find(us2fs(base + result + cur)))
1045370b324cSopenharmony_ci      {
1046370b324cSopenharmony_ci        if (!fi.IsDir())
1047370b324cSopenharmony_ci        {
1048370b324cSopenharmony_ci          result = path;
1049370b324cSopenharmony_ci          break;
1050370b324cSopenharmony_ci        }
1051370b324cSopenharmony_ci      }
1052370b324cSopenharmony_ci      else
1053370b324cSopenharmony_ci        checkExist = false;
1054370b324cSopenharmony_ci    }
1055370b324cSopenharmony_ci    if (!checkExist)
1056370b324cSopenharmony_ci      RemoveDotsAndSpaces(cur);
1057370b324cSopenharmony_ci    result += cur;
1058370b324cSopenharmony_ci    if (slashPos < 0)
1059370b324cSopenharmony_ci      break;
1060370b324cSopenharmony_ci    start = (unsigned)(slashPos + 1);
1061370b324cSopenharmony_ci    result.Add_PathSepar();
1062370b324cSopenharmony_ci  }
1063370b324cSopenharmony_ci
1064370b324cSopenharmony_ci  return true;
1065370b324cSopenharmony_ci}
1066370b324cSopenharmony_ci
1067370b324cSopenharmony_ci#else
1068370b324cSopenharmony_ci
1069370b324cSopenharmony_cibool CorrectFsPath(const UString & /* relBase */, const UString &path, UString &result)
1070370b324cSopenharmony_ci{
1071370b324cSopenharmony_ci  result = path;
1072370b324cSopenharmony_ci  return true;
1073370b324cSopenharmony_ci}
1074370b324cSopenharmony_ci
1075370b324cSopenharmony_ci#endif
1076370b324cSopenharmony_ci
1077370b324cSopenharmony_cibool Dlg_CreateFolder(HWND wnd, UString &destName)
1078370b324cSopenharmony_ci{
1079370b324cSopenharmony_ci  destName.Empty();
1080370b324cSopenharmony_ci  CComboDialog dlg;
1081370b324cSopenharmony_ci  LangString(IDS_CREATE_FOLDER, dlg.Title);
1082370b324cSopenharmony_ci  LangString(IDS_CREATE_FOLDER_NAME, dlg.Static);
1083370b324cSopenharmony_ci  LangString(IDS_CREATE_FOLDER_DEFAULT_NAME, dlg.Value);
1084370b324cSopenharmony_ci  if (dlg.Create(wnd) != IDOK)
1085370b324cSopenharmony_ci    return false;
1086370b324cSopenharmony_ci  destName = dlg.Value;
1087370b324cSopenharmony_ci  return true;
1088370b324cSopenharmony_ci}
1089