1 // PanelFolderChange.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../Common/StringConvert.h"
6 #include "../../../Common/Wildcard.h"
7
8 #include "../../../Windows/FileName.h"
9 #include "../../../Windows/FileDir.h"
10 #include "../../../Windows/PropVariant.h"
11
12 #include "../../PropID.h"
13
14 #ifdef UNDER_CE
15 #include "FSFolder.h"
16 #else
17 #include "FSDrives.h"
18 #endif
19 #include "LangUtils.h"
20 #include "ListViewDialog.h"
21 #include "Panel.h"
22 #include "RootFolder.h"
23 #include "ViewSettings.h"
24
25 #include "resource.h"
26
27 using namespace NWindows;
28 using namespace NFile;
29 using namespace NFind;
30
ReleaseFolder()31 void CPanel::ReleaseFolder()
32 {
33 DeleteListItems();
34
35 _folder.Release();
36
37 _folderCompare.Release();
38 _folderGetItemName.Release();
39 _folderRawProps.Release();
40 _folderAltStreams.Release();
41 _folderOperations.Release();
42
43 _thereAreDeletedItems = false;
44 }
45
SetNewFolder(IFolderFolder * newFolder)46 void CPanel::SetNewFolder(IFolderFolder *newFolder)
47 {
48 ReleaseFolder();
49 _folder = newFolder;
50 if (_folder)
51 {
52 _folder.QueryInterface(IID_IFolderCompare, &_folderCompare);
53 _folder.QueryInterface(IID_IFolderGetItemName, &_folderGetItemName);
54 _folder.QueryInterface(IID_IArchiveGetRawProps, &_folderRawProps);
55 _folder.QueryInterface(IID_IFolderAltStreams, &_folderAltStreams);
56 _folder.QueryInterface(IID_IFolderOperations, &_folderOperations);
57 }
58 }
59
SetToRootFolder()60 void CPanel::SetToRootFolder()
61 {
62 ReleaseFolder();
63 _library.Free();
64
65 CRootFolder *rootFolderSpec = new CRootFolder;
66 SetNewFolder(rootFolderSpec);
67 rootFolderSpec->Init();
68 }
69
70
DoesNameContainWildcard_SkipRoot(const UString & path)71 static bool DoesNameContainWildcard_SkipRoot(const UString &path)
72 {
73 return DoesNameContainWildcard(path.Ptr(NName::GetRootPrefixSize(path)));
74 }
75
BindToPath(const UString & fullPath,const UString & arcFormat,bool & archiveIsOpened,bool & encrypted)76 HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted)
77 {
78 UString path = fullPath;
79 #ifdef _WIN32
80 path.Replace(L'/', WCHAR_PATH_SEPARATOR);
81 #endif
82
83 archiveIsOpened = false;
84 encrypted = false;
85
86 CDisableTimerProcessing disableTimerProcessing(*this);
87 CDisableNotify disableNotify(*this);
88
89 for (; !_parentFolders.IsEmpty(); CloseOneLevel())
90 {
91 // ---------- we try to use open archive ----------
92
93 const CFolderLink &link = _parentFolders.Back();
94 const UString &virtPath = link.VirtualPath;
95 if (!path.IsPrefixedBy(virtPath))
96 continue;
97 UString relatPath = path.Ptr(virtPath.Len());
98 if (!relatPath.IsEmpty())
99 {
100 if (!IS_PATH_SEPAR(relatPath[0]))
101 continue;
102 else
103 relatPath.Delete(0);
104 }
105
106 UString relatPath2 = relatPath;
107 if (!relatPath2.IsEmpty() && !IS_PATH_SEPAR(relatPath2.Back()))
108 relatPath2.Add_PathSepar();
109
110 for (;;)
111 {
112 const UString foldPath = GetFolderPath(_folder);
113 if (relatPath2 == foldPath)
114 break;
115 if (relatPath.IsPrefixedBy(foldPath))
116 {
117 path = relatPath.Ptr(foldPath.Len());
118 break;
119 }
120 CMyComPtr<IFolderFolder> newFolder;
121 if (_folder->BindToParentFolder(&newFolder) != S_OK)
122 throw 20140918;
123 if (!newFolder) // we exit from loop above if (relatPath.IsPrefixedBy(empty path for root folder)
124 throw 20140918;
125 SetNewFolder(newFolder);
126 }
127 break;
128 }
129
130 if (_parentFolders.IsEmpty())
131 {
132 // ---------- we open file or folder from file system ----------
133
134 CloseOpenFolders();
135 UString sysPath = path;
136
137 unsigned prefixSize = NName::GetRootPrefixSize(sysPath);
138 if (prefixSize == 0 || sysPath[prefixSize] == 0)
139 sysPath.Empty();
140
141 #if defined(_WIN32) && !defined(UNDER_CE)
142 if (!sysPath.IsEmpty() && sysPath.Back() == ':' &&
143 (sysPath.Len() != 2 || !NName::IsDrivePath2(sysPath)))
144 {
145 UString baseFile = sysPath;
146 baseFile.DeleteBack();
147 if (NFind::DoesFileOrDirExist(us2fs(baseFile)))
148 sysPath.Empty();
149 }
150 #endif
151
152 CFileInfo fileInfo;
153
154 while (!sysPath.IsEmpty())
155 {
156 if (fileInfo.Find(us2fs(sysPath)))
157 break;
158 int pos = sysPath.ReverseFind_PathSepar();
159 if (pos < 0)
160 sysPath.Empty();
161 else
162 {
163 /*
164 if (reducedParts.Size() > 0 || pos < (int)sysPath.Len() - 1)
165 reducedParts.Add(sysPath.Ptr(pos + 1));
166 */
167 #if defined(_WIN32) && !defined(UNDER_CE)
168 if (pos == 2 && NName::IsDrivePath2(sysPath) && sysPath.Len() > 3)
169 pos++;
170 #endif
171
172 sysPath.DeleteFrom(pos);
173 }
174 }
175
176 SetToRootFolder();
177
178 CMyComPtr<IFolderFolder> newFolder;
179
180 if (sysPath.IsEmpty())
181 {
182 _folder->BindToFolder(path, &newFolder);
183 }
184 else if (fileInfo.IsDir())
185 {
186 #ifdef _WIN32
187 if (DoesNameContainWildcard_SkipRoot(sysPath))
188 {
189 FString dirPrefix, fileName;
190 NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName);
191 if (DoesNameContainWildcard_SkipRoot(fs2us(dirPrefix)))
192 return E_INVALIDARG;
193 sysPath = fs2us(dirPrefix + fileInfo.Name);
194 }
195 #endif
196
197 NName::NormalizeDirPathPrefix(sysPath);
198 _folder->BindToFolder(sysPath, &newFolder);
199 }
200 else
201 {
202 FString dirPrefix, fileName;
203
204 NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName);
205
206 HRESULT res = S_OK;
207
208 #ifdef _WIN32
209 if (DoesNameContainWildcard_SkipRoot(fs2us(dirPrefix)))
210 return E_INVALIDARG;
211
212 if (DoesNameContainWildcard(fs2us(fileName)))
213 res = S_FALSE;
214 else
215 #endif
216 {
217 CTempFileInfo tfi;
218 tfi.RelPath = fs2us(fileName);
219 tfi.FolderPath = dirPrefix;
220 tfi.FilePath = us2fs(sysPath);
221 res = OpenAsArc(NULL, tfi, sysPath, arcFormat, encrypted);
222 }
223
224 if (res == S_FALSE)
225 _folder->BindToFolder(fs2us(dirPrefix), &newFolder);
226 else
227 {
228 RINOK(res);
229 archiveIsOpened = true;
230 _parentFolders.Back().ParentFolderPath = fs2us(dirPrefix);
231 path.DeleteFrontal(sysPath.Len());
232 if (!path.IsEmpty() && IS_PATH_SEPAR(path[0]))
233 path.Delete(0);
234 }
235 }
236
237 if (newFolder)
238 {
239 SetNewFolder(newFolder);
240 // LoadFullPath();
241 return S_OK;
242 }
243 }
244
245 {
246 // ---------- we open folder remPath in archive and sub archives ----------
247
248 for (unsigned curPos = 0; curPos != path.Len();)
249 {
250 UString s = path.Ptr(curPos);
251 int slashPos = NName::FindSepar(s);
252 unsigned skipLen = s.Len();
253 if (slashPos >= 0)
254 {
255 s.DeleteFrom(slashPos);
256 skipLen = slashPos + 1;
257 }
258
259 CMyComPtr<IFolderFolder> newFolder;
260 _folder->BindToFolder(s, &newFolder);
261 if (newFolder)
262 curPos += skipLen;
263 else if (_folderAltStreams)
264 {
265 int pos = s.Find(L':');
266 if (pos >= 0)
267 {
268 UString baseName = s;
269 baseName.DeleteFrom(pos);
270 if (_folderAltStreams->BindToAltStreams(baseName, &newFolder) == S_OK && newFolder)
271 curPos += pos + 1;
272 }
273 }
274
275 if (!newFolder)
276 break;
277
278 SetNewFolder(newFolder);
279 }
280 }
281
282 return S_OK;
283 }
284
BindToPathAndRefresh(const UString & path)285 HRESULT CPanel::BindToPathAndRefresh(const UString &path)
286 {
287 CDisableTimerProcessing disableTimerProcessing(*this);
288 CDisableNotify disableNotify(*this);
289 bool archiveIsOpened, encrypted;
290 UString s = path;
291
292 #ifdef _WIN32
293 if (!s.IsEmpty() && s[0] == '\"' && s.Back() == '\"')
294 {
295 s.DeleteBack();
296 s.Delete(0);
297 }
298 #endif
299
300 HRESULT res = BindToPath(s, UString(), archiveIsOpened, encrypted);
301 RefreshListCtrl();
302 return res;
303 }
304
SetBookmark(unsigned index)305 void CPanel::SetBookmark(unsigned index)
306 {
307 _appState->FastFolders.SetString(index, _currentFolderPrefix);
308 }
309
OpenBookmark(unsigned index)310 void CPanel::OpenBookmark(unsigned index)
311 {
312 BindToPathAndRefresh(_appState->FastFolders.GetString(index));
313 }
314
GetFolderPath(IFolderFolder * folder)315 UString GetFolderPath(IFolderFolder *folder)
316 {
317 {
318 NCOM::CPropVariant prop;
319 if (folder->GetFolderProperty(kpidPath, &prop) == S_OK)
320 if (prop.vt == VT_BSTR)
321 return (wchar_t *)prop.bstrVal;
322 }
323 return UString();
324 }
325
LoadFullPath()326 void CPanel::LoadFullPath()
327 {
328 _currentFolderPrefix.Empty();
329 FOR_VECTOR (i, _parentFolders)
330 {
331 const CFolderLink &folderLink = _parentFolders[i];
332 _currentFolderPrefix += folderLink.ParentFolderPath;
333 // GetFolderPath(folderLink.ParentFolder);
334 _currentFolderPrefix += folderLink.RelPath;
335 _currentFolderPrefix.Add_PathSepar();
336 }
337 if (_folder)
338 _currentFolderPrefix += GetFolderPath(_folder);
339 }
340
GetRealIconIndex(CFSTR path,DWORD attributes)341 static int GetRealIconIndex(CFSTR path, DWORD attributes)
342 {
343 int index = -1;
344 if (GetRealIconIndex(path, attributes, index) != 0)
345 return index;
346 return -1;
347 }
348
LoadFullPathAndShow()349 void CPanel::LoadFullPathAndShow()
350 {
351 LoadFullPath();
352 _appState->FolderHistory.AddString(_currentFolderPrefix);
353
354 _headerComboBox.SetText(_currentFolderPrefix);
355
356 #ifndef UNDER_CE
357
358 COMBOBOXEXITEM item;
359 item.mask = 0;
360
361 UString path = _currentFolderPrefix;
362 if (path.Len() >
363 #ifdef _WIN32
364 3
365 #else
366 1
367 #endif
368 && IS_PATH_SEPAR(path.Back()))
369 path.DeleteBack();
370
371 DWORD attrib = FILE_ATTRIBUTE_DIRECTORY;
372
373 // GetRealIconIndex is slow for direct DVD/UDF path. So we use dummy path
374 if (path.IsPrefixedBy(L"\\\\.\\"))
375 path = "_TestFolder_";
376 else
377 {
378 CFileInfo fi;
379 if (fi.Find(us2fs(path)))
380 attrib = fi.Attrib;
381 }
382 item.iImage = GetRealIconIndex(us2fs(path), attrib);
383
384 if (item.iImage >= 0)
385 {
386 item.iSelectedImage = item.iImage;
387 item.mask |= (CBEIF_IMAGE | CBEIF_SELECTEDIMAGE);
388 }
389 item.iItem = -1;
390 _headerComboBox.SetItem(&item);
391
392 #endif
393
394 RefreshTitle();
395 }
396
397 #ifndef UNDER_CE
OnNotifyComboBoxEnter(const UString & s)398 LRESULT CPanel::OnNotifyComboBoxEnter(const UString &s)
399 {
400 if (BindToPathAndRefresh(GetUnicodeString(s)) == S_OK)
401 {
402 PostMsg(kSetFocusToListView);
403 return TRUE;
404 }
405 return FALSE;
406 }
407
OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info,LRESULT & result)408 bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result)
409 {
410 if (info->iWhy == CBENF_ESCAPE)
411 {
412 _headerComboBox.SetText(_currentFolderPrefix);
413 PostMsg(kSetFocusToListView);
414 result = FALSE;
415 return true;
416 }
417
418 /*
419 if (info->iWhy == CBENF_DROPDOWN)
420 {
421 result = FALSE;
422 return true;
423 }
424 */
425
426 if (info->iWhy == CBENF_RETURN)
427 {
428 // When we use Edit control and press Enter.
429 UString s;
430 _headerComboBox.GetText(s);
431 result = OnNotifyComboBoxEnter(s);
432 return true;
433 }
434 return false;
435 }
436 #endif
437
438 #ifndef _UNICODE
OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info,LRESULT & result)439 bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result)
440 {
441 if (info->iWhy == CBENF_ESCAPE)
442 {
443 _headerComboBox.SetText(_currentFolderPrefix);
444 PostMsg(kSetFocusToListView);
445 result = FALSE;
446 return true;
447 }
448 /*
449 if (info->iWhy == CBENF_DROPDOWN)
450 {
451 result = FALSE;
452 return true;
453 }
454 */
455
456 if (info->iWhy == CBENF_RETURN)
457 {
458 UString s;
459 _headerComboBox.GetText(s);
460 // GetUnicodeString(info->szText)
461 result = OnNotifyComboBoxEnter(s);
462 return true;
463 }
464 return false;
465 }
466 #endif
467
AddComboBoxItem(const UString & name,int iconIndex,int indent,bool addToList)468 void CPanel::AddComboBoxItem(const UString &name, int iconIndex, int indent, bool addToList)
469 {
470 #ifdef UNDER_CE
471
472 UString s;
473 iconIndex = iconIndex;
474 for (int i = 0; i < indent; i++)
475 s += " ";
476 _headerComboBox.AddString(s + name);
477
478 #else
479
480 COMBOBOXEXITEMW item;
481 item.mask = CBEIF_TEXT | CBEIF_INDENT;
482 item.iSelectedImage = item.iImage = iconIndex;
483 if (iconIndex >= 0)
484 item.mask |= (CBEIF_IMAGE | CBEIF_SELECTEDIMAGE);
485 item.iItem = -1;
486 item.iIndent = indent;
487 item.pszText = (LPWSTR)(LPCWSTR)name;
488 _headerComboBox.InsertItem(&item);
489
490 #endif
491
492 if (addToList)
493 ComboBoxPaths.Add(name);
494 }
495
496 extern UString RootFolder_GetName_Computer(int &iconIndex);
497 extern UString RootFolder_GetName_Network(int &iconIndex);
498 extern UString RootFolder_GetName_Documents(int &iconIndex);
499
OnComboBoxCommand(UINT code,LPARAM,LRESULT & result)500 bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result)
501 {
502 result = FALSE;
503 switch (code)
504 {
505 case CBN_DROPDOWN:
506 {
507 ComboBoxPaths.Clear();
508 _headerComboBox.ResetContent();
509
510 unsigned i;
511 UStringVector pathParts;
512
513 SplitPathToParts(_currentFolderPrefix, pathParts);
514 UString sumPass;
515 if (!pathParts.IsEmpty())
516 pathParts.DeleteBack();
517 for (i = 0; i < pathParts.Size(); i++)
518 {
519 UString name = pathParts[i];
520 sumPass += name;
521 sumPass.Add_PathSepar();
522 CFileInfo info;
523 DWORD attrib = FILE_ATTRIBUTE_DIRECTORY;
524 if (info.Find(us2fs(sumPass)))
525 attrib = info.Attrib;
526 AddComboBoxItem(name.IsEmpty() ? L"\\" : name, GetRealIconIndex(us2fs(sumPass), attrib), i, false);
527 ComboBoxPaths.Add(sumPass);
528 }
529
530 #ifndef UNDER_CE
531
532 int iconIndex;
533 UString name;
534 name = RootFolder_GetName_Documents(iconIndex);
535 AddComboBoxItem(name, iconIndex, 0, true);
536
537 name = RootFolder_GetName_Computer(iconIndex);
538 AddComboBoxItem(name, iconIndex, 0, true);
539
540 FStringVector driveStrings;
541 MyGetLogicalDriveStrings(driveStrings);
542 for (i = 0; i < driveStrings.Size(); i++)
543 {
544 FString s = driveStrings[i];
545 ComboBoxPaths.Add(fs2us(s));
546 int iconIndex2 = GetRealIconIndex(s, 0);
547 if (s.Len() > 0 && s.Back() == FCHAR_PATH_SEPARATOR)
548 s.DeleteBack();
549 AddComboBoxItem(fs2us(s), iconIndex2, 1, false);
550 }
551
552 name = RootFolder_GetName_Network(iconIndex);
553 AddComboBoxItem(name, iconIndex, 0, true);
554
555 #endif
556
557 return false;
558 }
559
560 case CBN_SELENDOK:
561 {
562 code = code;
563 int index = _headerComboBox.GetCurSel();
564 if (index >= 0)
565 {
566 UString pass = ComboBoxPaths[index];
567 _headerComboBox.SetCurSel(-1);
568 // _headerComboBox.SetText(pass); // it's fix for seclecting by mouse.
569 if (BindToPathAndRefresh(pass) == S_OK)
570 {
571 PostMsg(kSetFocusToListView);
572 #ifdef UNDER_CE
573 PostMsg(kRefresh_HeaderComboBox);
574 #endif
575 return true;
576 }
577 }
578 return false;
579 }
580 /*
581 case CBN_CLOSEUP:
582 {
583 LoadFullPathAndShow();
584 true;
585
586 }
587 case CBN_SELCHANGE:
588 {
589 // LoadFullPathAndShow();
590 return true;
591 }
592 */
593 }
594 return false;
595 }
596
OnNotifyComboBox(LPNMHDR NON_CE_VAR (header),LRESULT & NON_CE_VAR (result))597 bool CPanel::OnNotifyComboBox(LPNMHDR NON_CE_VAR(header), LRESULT & NON_CE_VAR(result))
598 {
599 #ifndef UNDER_CE
600 switch (header->code)
601 {
602 case CBEN_BEGINEDIT:
603 {
604 _lastFocusedIsList = false;
605 _panelCallback->PanelWasFocused();
606 break;
607 }
608 #ifndef _UNICODE
609 case CBEN_ENDEDIT:
610 {
611 return OnNotifyComboBoxEndEdit((PNMCBEENDEDIT)header, result);
612 }
613 #endif
614 case CBEN_ENDEDITW:
615 {
616 return OnNotifyComboBoxEndEdit((PNMCBEENDEDITW)header, result);
617 }
618 }
619 #endif
620 return false;
621 }
622
623
FoldersHistory()624 void CPanel::FoldersHistory()
625 {
626 CListViewDialog listViewDialog;
627 listViewDialog.DeleteIsAllowed = true;
628 LangString(IDS_FOLDERS_HISTORY, listViewDialog.Title);
629 _appState->FolderHistory.GetList(listViewDialog.Strings);
630 if (listViewDialog.Create(GetParent()) != IDOK)
631 return;
632 UString selectString;
633 if (listViewDialog.StringsWereChanged)
634 {
635 _appState->FolderHistory.RemoveAll();
636 for (int i = listViewDialog.Strings.Size() - 1; i >= 0; i--)
637 _appState->FolderHistory.AddString(listViewDialog.Strings[i]);
638 if (listViewDialog.FocusedItemIndex >= 0)
639 selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex];
640 }
641 else
642 {
643 if (listViewDialog.FocusedItemIndex >= 0)
644 selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex];
645 }
646 if (listViewDialog.FocusedItemIndex >= 0)
647 BindToPathAndRefresh(selectString);
648 }
649
650
GetParentDirPrefix() const651 UString CPanel::GetParentDirPrefix() const
652 {
653 UString s;
654 if (!_currentFolderPrefix.IsEmpty())
655 {
656 wchar_t c = _currentFolderPrefix.Back();
657 if (IS_PATH_SEPAR(c) || c == ':')
658 {
659 s = _currentFolderPrefix;
660 s.DeleteBack();
661 if (s != L"\\\\." &&
662 s != L"\\\\?")
663 {
664 int pos = s.ReverseFind_PathSepar();
665 if (pos >= 0)
666 s.DeleteFrom(pos + 1);
667 }
668 }
669 }
670 return s;
671 }
672
673
OpenParentFolder()674 void CPanel::OpenParentFolder()
675 {
676 LoadFullPath(); // Maybe we don't need it ??
677
678 UString parentFolderPrefix;
679 UString focusedName;
680
681 if (!_currentFolderPrefix.IsEmpty())
682 {
683 wchar_t c = _currentFolderPrefix.Back();
684 if (IS_PATH_SEPAR(c) || c == ':')
685 {
686 focusedName = _currentFolderPrefix;
687 focusedName.DeleteBack();
688 /*
689 if (c == ':' && !focusedName.IsEmpty() && IS_PATH_SEPAR(focusedName.Back()))
690 {
691 focusedName.DeleteBack();
692 }
693 else
694 */
695 if (focusedName != L"\\\\." &&
696 focusedName != L"\\\\?")
697 {
698 int pos = focusedName.ReverseFind_PathSepar();
699 if (pos >= 0)
700 {
701 parentFolderPrefix = focusedName;
702 parentFolderPrefix.DeleteFrom(pos + 1);
703 focusedName.DeleteFrontal(pos + 1);
704 }
705 }
706 }
707 }
708
709 CDisableTimerProcessing disableTimerProcessing(*this);
710 CDisableNotify disableNotify(*this);
711
712 CMyComPtr<IFolderFolder> newFolder;
713 _folder->BindToParentFolder(&newFolder);
714
715 // newFolder.Release(); // for test
716
717 if (newFolder)
718 SetNewFolder(newFolder);
719 else
720 {
721 bool needSetFolder = true;
722 if (!_parentFolders.IsEmpty())
723 {
724 {
725 const CFolderLink &link = _parentFolders.Back();
726 parentFolderPrefix = link.ParentFolderPath;
727 focusedName = link.RelPath;
728 }
729 CloseOneLevel();
730 needSetFolder = (!_folder);
731 }
732
733 if (needSetFolder)
734 {
735 {
736 bool archiveIsOpened;
737 bool encrypted;
738 BindToPath(parentFolderPrefix, UString(), archiveIsOpened, encrypted);
739 }
740 }
741 }
742
743 CSelectedState state;
744 state.FocusedName = focusedName;
745 state.FocusedName_Defined = true;
746 /*
747 if (!focusedName.IsEmpty())
748 state.SelectedNames.Add(focusedName);
749 */
750 LoadFullPath();
751 // ::SetCurrentDirectory(::_currentFolderPrefix);
752 RefreshListCtrl(state);
753 // _listView.EnsureVisible(_listView.GetFocusedItem(), false);
754 }
755
756
CloseOneLevel()757 void CPanel::CloseOneLevel()
758 {
759 ReleaseFolder();
760 _library.Free();
761 {
762 CFolderLink &link = _parentFolders.Back();
763 if (link.ParentFolder)
764 SetNewFolder(link.ParentFolder);
765 _library.Attach(link.Library.Detach());
766 }
767 if (_parentFolders.Size() > 1)
768 OpenParentArchiveFolder();
769 _parentFolders.DeleteBack();
770 if (_parentFolders.IsEmpty())
771 _flatMode = _flatModeForDisk;
772 }
773
CloseOpenFolders()774 void CPanel::CloseOpenFolders()
775 {
776 while (!_parentFolders.IsEmpty())
777 CloseOneLevel();
778 _flatMode = _flatModeForDisk;
779 ReleaseFolder();
780 _library.Free();
781 }
782
OpenRootFolder()783 void CPanel::OpenRootFolder()
784 {
785 CDisableTimerProcessing disableTimerProcessing(*this);
786 CDisableNotify disableNotify(*this);
787 _parentFolders.Clear();
788 SetToRootFolder();
789 RefreshListCtrl();
790 // ::SetCurrentDirectory(::_currentFolderPrefix);
791 /*
792 BeforeChangeFolder();
793 _currentFolderPrefix.Empty();
794 AfterChangeFolder();
795 SetCurrentPathText();
796 RefreshListCtrl(UString(), 0, UStringVector());
797 _listView.EnsureVisible(_listView.GetFocusedItem(), false);
798 */
799 }
800
OpenDrivesFolder()801 void CPanel::OpenDrivesFolder()
802 {
803 CloseOpenFolders();
804 #ifdef UNDER_CE
805 NFsFolder::CFSFolder *folderSpec = new NFsFolder::CFSFolder;
806 SetNewFolder(folderSpec);
807 folderSpec->InitToRoot();
808 #else
809 CFSDrives *folderSpec = new CFSDrives;
810 SetNewFolder(folderSpec);
811 folderSpec->Init();
812 #endif
813 RefreshListCtrl();
814 }
815
OpenFolder(int index)816 void CPanel::OpenFolder(int index)
817 {
818 if (index == kParentIndex)
819 {
820 OpenParentFolder();
821 return;
822 }
823 CMyComPtr<IFolderFolder> newFolder;
824 _folder->BindToFolder(index, &newFolder);
825 if (!newFolder)
826 return;
827 SetNewFolder(newFolder);
828 LoadFullPath();
829 RefreshListCtrl();
830 // 17.02: fixed : now we don't select first item
831 // _listView.SetItemState_Selected(_listView.GetFocusedItem());
832 _listView.EnsureVisible(_listView.GetFocusedItem(), false);
833 }
834
OpenAltStreams()835 void CPanel::OpenAltStreams()
836 {
837 CRecordVector<UInt32> indices;
838 GetOperatedItemIndices(indices);
839 Int32 realIndex = -1;
840 if (indices.Size() > 1)
841 return;
842 if (indices.Size() == 1)
843 realIndex = indices[0];
844
845 if (_folderAltStreams)
846 {
847 CMyComPtr<IFolderFolder> newFolder;
848 _folderAltStreams->BindToAltStreams(realIndex, &newFolder);
849 if (newFolder)
850 {
851 CDisableTimerProcessing disableTimerProcessing(*this);
852 CDisableNotify disableNotify(*this);
853 SetNewFolder(newFolder);
854 RefreshListCtrl();
855 return;
856 }
857 return;
858 }
859
860 #if defined(_WIN32) && !defined(UNDER_CE)
861 UString path;
862 if (realIndex >= 0)
863 path = GetItemFullPath(realIndex);
864 else
865 {
866 path = GetFsPath();
867 if (!NName::IsDriveRootPath_SuperAllowed(us2fs(path)))
868 if (!path.IsEmpty() && IS_PATH_SEPAR(path.Back()))
869 path.DeleteBack();
870 }
871
872 path += ':';
873 BindToPathAndRefresh(path);
874 #endif
875 }
876