// PanelFolderChange.cpp #include "StdAfx.h" #include "../../../Common/StringConvert.h" #include "../../../Common/Wildcard.h" #include "../../../Windows/FileName.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/PropVariant.h" #include "../../PropID.h" #ifdef UNDER_CE #include "FSFolder.h" #else #include "FSDrives.h" #endif #include "LangUtils.h" #include "ListViewDialog.h" #include "Panel.h" #include "RootFolder.h" #include "ViewSettings.h" #include "resource.h" using namespace NWindows; using namespace NFile; using namespace NFind; void CPanel::ReleaseFolder() { DeleteListItems(); _folder.Release(); _folderCompare.Release(); _folderGetItemName.Release(); _folderRawProps.Release(); _folderAltStreams.Release(); _folderOperations.Release(); _thereAreDeletedItems = false; } void CPanel::SetNewFolder(IFolderFolder *newFolder) { ReleaseFolder(); _folder = newFolder; if (_folder) { _folder.QueryInterface(IID_IFolderCompare, &_folderCompare); _folder.QueryInterface(IID_IFolderGetItemName, &_folderGetItemName); _folder.QueryInterface(IID_IArchiveGetRawProps, &_folderRawProps); _folder.QueryInterface(IID_IFolderAltStreams, &_folderAltStreams); _folder.QueryInterface(IID_IFolderOperations, &_folderOperations); } } void CPanel::SetToRootFolder() { ReleaseFolder(); _library.Free(); CRootFolder *rootFolderSpec = new CRootFolder; SetNewFolder(rootFolderSpec); rootFolderSpec->Init(); } static bool DoesNameContainWildcard_SkipRoot(const UString &path) { return DoesNameContainWildcard(path.Ptr(NName::GetRootPrefixSize(path))); } HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, COpenResult &openRes) { UString path = fullPath; #ifdef _WIN32 path.Replace(L'/', WCHAR_PATH_SEPARATOR); #endif openRes.ArchiveIsOpened = false; openRes.Encrypted = false; CDisableTimerProcessing disableTimerProcessing(*this); CDisableNotify disableNotify(*this); for (; !_parentFolders.IsEmpty(); CloseOneLevel()) { // ---------- we try to use open archive ---------- const CFolderLink &link = _parentFolders.Back(); const UString &virtPath = link.VirtualPath; if (!path.IsPrefixedBy(virtPath)) continue; UString relatPath = path.Ptr(virtPath.Len()); if (!relatPath.IsEmpty()) { if (!IS_PATH_SEPAR(relatPath[0])) continue; else relatPath.Delete(0); } UString relatPath2 = relatPath; if (!relatPath2.IsEmpty() && !IS_PATH_SEPAR(relatPath2.Back())) relatPath2.Add_PathSepar(); for (;;) { const UString foldPath = GetFolderPath(_folder); if (relatPath2 == foldPath) break; if (relatPath.IsPrefixedBy(foldPath)) { path = relatPath.Ptr(foldPath.Len()); break; } CMyComPtr newFolder; if (_folder->BindToParentFolder(&newFolder) != S_OK) throw 20140918; if (!newFolder) // we exit from loop above if (relatPath.IsPrefixedBy(empty path for root folder) throw 20140918; SetNewFolder(newFolder); } break; } if (_parentFolders.IsEmpty()) { // ---------- we open file or folder from file system ---------- CloseOpenFolders(); UString sysPath = path; /* we will Empty() sysPath variable, if we need to BindToFolder() directly with (path) variable */ const unsigned prefixSize = NName::GetRootPrefixSize(sysPath); if (prefixSize == 0 || sysPath[prefixSize] == 0) sysPath.Empty(); #if defined(_WIN32) && !defined(UNDER_CE) if (!sysPath.IsEmpty() && sysPath.Back() == ':' && (sysPath.Len() != 2 || !NName::IsDrivePath2(sysPath))) { // if base item for alt streams prefix "base:" exists, we will use it UString baseFile = sysPath; baseFile.DeleteBack(); if (NFind::DoesFileOrDirExist(us2fs(baseFile))) sysPath.Empty(); } #endif CFileInfo fileInfo; while (!sysPath.IsEmpty()) { if (sysPath.Len() <= prefixSize) { path.DeleteFrom(prefixSize); sysPath.Empty(); break; } fileInfo.ClearBase(); if (IsPathSepar(sysPath.Back())) { /* Windows 10 by default doesn't allow look "Local Settings" that is junction to "AppData\Local", but it does allow look "Local Settings\Temp\*" 22.02: at first we try to use paths with slashes "path\" */ CFileInfo fi; // CFindFile findFile; // FString path2 = us2fs(sysPath); // path2 += '*'; // CHAR_ANY_MASK; // if (findFile.FindFirst(path2, fi)) CEnumerator enumerator; enumerator.SetDirPrefix(us2fs(sysPath)); bool found = false; if (enumerator.Next(fi, found)) { // sysPath.DeleteBack(); fileInfo.SetAsDir(); fileInfo.Size = 0; fileInfo.Name.Empty(); break; } sysPath.DeleteBack(); continue; } if (fileInfo.Find(us2fs(sysPath))) break; int pos = sysPath.ReverseFind_PathSepar(); if (pos < 0) { sysPath.Empty(); break; } { if ((unsigned)pos != sysPath.Len() - 1) pos++; sysPath.DeleteFrom((unsigned)pos); } } SetToRootFolder(); CMyComPtr newFolder; if (sysPath.IsEmpty()) { _folder->BindToFolder(path, &newFolder); } else if (fileInfo.IsDir()) { #ifdef _WIN32 if (DoesNameContainWildcard_SkipRoot(sysPath)) { FString dirPrefix, fileName; NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName); if (DoesNameContainWildcard_SkipRoot(fs2us(dirPrefix))) return E_INVALIDARG; sysPath = fs2us(dirPrefix + fileInfo.Name); } #endif NName::NormalizeDirPathPrefix(sysPath); _folder->BindToFolder(sysPath, &newFolder); } else { FString dirPrefix, fileName; NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName); HRESULT res = S_OK; #ifdef _WIN32 if (DoesNameContainWildcard_SkipRoot(fs2us(dirPrefix))) return E_INVALIDARG; if (DoesNameContainWildcard(fs2us(fileName))) res = S_FALSE; else #endif { CTempFileInfo tfi; tfi.RelPath = fs2us(fileName); tfi.FolderPath = dirPrefix; tfi.FilePath = us2fs(sysPath); res = OpenAsArc(NULL, tfi, sysPath, arcFormat, openRes); } if (res == S_FALSE) _folder->BindToFolder(fs2us(dirPrefix), &newFolder); else { RINOK(res) openRes.ArchiveIsOpened = true; _parentFolders.Back().ParentFolderPath = fs2us(dirPrefix); path.DeleteFrontal(sysPath.Len()); if (!path.IsEmpty() && IS_PATH_SEPAR(path[0])) path.Delete(0); } } if (newFolder) { SetNewFolder(newFolder); // LoadFullPath(); return S_OK; } } { // ---------- we open folder remPath in archive and sub archives ---------- for (unsigned curPos = 0; curPos != path.Len();) { UString s = path.Ptr(curPos); const int slashPos = NName::FindSepar(s); unsigned skipLen = s.Len(); if (slashPos >= 0) { s.DeleteFrom((unsigned)slashPos); skipLen = (unsigned)slashPos + 1; } CMyComPtr newFolder; _folder->BindToFolder(s, &newFolder); if (newFolder) curPos += skipLen; else if (_folderAltStreams) { const int pos = s.Find(L':'); if (pos >= 0) { UString baseName = s; baseName.DeleteFrom((unsigned)pos); if (_folderAltStreams->BindToAltStreams(baseName, &newFolder) == S_OK && newFolder) curPos += (unsigned)pos + 1; } } if (!newFolder) break; SetNewFolder(newFolder); } } return S_OK; } HRESULT CPanel::BindToPathAndRefresh(const UString &path) { CDisableTimerProcessing disableTimerProcessing(*this); CDisableNotify disableNotify(*this); COpenResult openRes; UString s = path; #ifdef _WIN32 if (!s.IsEmpty() && s[0] == '\"' && s.Back() == '\"') { s.DeleteBack(); s.Delete(0); } #endif HRESULT res = BindToPath(s, UString(), openRes); RefreshListCtrl(); return res; } void CPanel::SetBookmark(unsigned index) { _appState->FastFolders.SetString(index, _currentFolderPrefix); } void CPanel::OpenBookmark(unsigned index) { BindToPathAndRefresh(_appState->FastFolders.GetString(index)); } UString GetFolderPath(IFolderFolder *folder) { { NCOM::CPropVariant prop; if (folder->GetFolderProperty(kpidPath, &prop) == S_OK) if (prop.vt == VT_BSTR) return (wchar_t *)prop.bstrVal; } return UString(); } void CPanel::LoadFullPath() { _currentFolderPrefix.Empty(); FOR_VECTOR (i, _parentFolders) { const CFolderLink &folderLink = _parentFolders[i]; _currentFolderPrefix += folderLink.ParentFolderPath; // GetFolderPath(folderLink.ParentFolder); _currentFolderPrefix += folderLink.RelPath; _currentFolderPrefix.Add_PathSepar(); } if (_folder) _currentFolderPrefix += GetFolderPath(_folder); } static int GetRealIconIndex_for_DirPath(CFSTR path, DWORD attrib) { attrib |= FILE_ATTRIBUTE_DIRECTORY; // optional int index = -1; if (Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef(path, attrib, index)) if (index >= 0) return index; return g_Ext_to_Icon_Map.GetIconIndex_DIR(attrib); } extern UString RootFolder_GetName_Computer(int &iconIndex); extern UString RootFolder_GetName_Network(int &iconIndex); extern UString RootFolder_GetName_Documents(int &iconIndex); static int Find_FileExtension_DotPos_in_path(const wchar_t *path) { int dotPos = -1; unsigned i; for (i = 0;; i++) { const wchar_t c = path[i]; if (c == 0) return dotPos; if (c == '.') dotPos = (int)i; else if (IS_PATH_SEPAR(c) || c == ':') dotPos = -1; } } void CPanel::LoadFullPathAndShow() { LoadFullPath(); _appState->FolderHistory.AddString(_currentFolderPrefix); _headerComboBox.SetText(_currentFolderPrefix); #ifndef UNDER_CE COMBOBOXEXITEM item; item.mask = 0; item.iImage = -1; UString path = _currentFolderPrefix; // path = "\\\\.\\PhysicalDrive1\\"; // for debug // path = "\\\\.\\y:\\"; // for debug if (!path.IsEmpty()) { const unsigned rootPrefixSize = NName::GetRootPrefixSize(path); if (rootPrefixSize == 0 && path[0] != '\\') { int iconIndex = -1; UString name_Computer = RootFolder_GetName_Computer(iconIndex); name_Computer.Add_PathSepar(); if (path == name_Computer || path == L"\\\\?\\") item.iImage = iconIndex; else { UString name = RootFolder_GetName_Network(iconIndex); name.Add_PathSepar(); if (path == name) item.iImage = iconIndex; } } if (item.iImage < 0) { if (rootPrefixSize == 0 || rootPrefixSize == path.Len()) { DWORD attrib = FILE_ATTRIBUTE_DIRECTORY; CFileInfo info; if (info.Find(us2fs(path))) attrib = info.Attrib; NName::If_IsSuperPath_RemoveSuperPrefix(path); item.iImage = GetRealIconIndex_for_DirPath(us2fs(path), attrib); } else if (rootPrefixSize == NName::kDevicePathPrefixSize && NName::IsDevicePath(us2fs(path.Left(path.Len() - 1)))) { if (path.IsPrefixedBy_Ascii_NoCase("\\\\.\\")) path.DeleteFrontal(4); if (path.Len() > 3) // is not "c:\\" { // PhysicalDrive if (path.Back() == '\\') path.DeleteBack(); } item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path(us2fs(path), FILE_ATTRIBUTE_ARCHIVE); } else { if (path.Back() == '\\') path.DeleteBack(); bool need_Fs_Check = true; bool is_File = false; if (!_parentFolders.IsEmpty()) { const CFolderLink &link = _parentFolders.Back(); if (link.VirtualPath == path) { is_File = true; if (_parentFolders.Size() != 1) need_Fs_Check = false; } else need_Fs_Check = false; } if (need_Fs_Check) { CFileInfo info; const bool finded = info.Find(us2fs(path)); DWORD attrib = FILE_ATTRIBUTE_DIRECTORY; if (finded) attrib = info.Attrib; item.iImage = Shell_GetFileInfo_SysIconIndex_for_Path(us2fs(path), attrib); } if (item.iImage <= 0 && is_File) { int dotPos = Find_FileExtension_DotPos_in_path(path); if (dotPos < 0) dotPos = (int)path.Len(); item.iImage = g_Ext_to_Icon_Map.GetIconIndex(FILE_ATTRIBUTE_ARCHIVE, path.Ptr(dotPos)); } } } } if (item.iImage < 0) item.iImage = g_Ext_to_Icon_Map.GetIconIndex_DIR(); // if (item.iImage < 0) item.iImage = 0; // item.iImage = -1; // for debug if (item.iImage >= 0) { item.iSelectedImage = item.iImage; item.mask |= (CBEIF_IMAGE | CBEIF_SELECTEDIMAGE); } item.iItem = -1; _headerComboBox.SetItem(&item); #endif RefreshTitle(); } #ifndef UNDER_CE LRESULT CPanel::OnNotifyComboBoxEnter(const UString &s) { if (BindToPathAndRefresh(GetUnicodeString(s)) == S_OK) { PostMsg(kSetFocusToListView); return TRUE; } return FALSE; } bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result) { if (info->iWhy == CBENF_ESCAPE) { _headerComboBox.SetText(_currentFolderPrefix); PostMsg(kSetFocusToListView); result = FALSE; return true; } /* if (info->iWhy == CBENF_DROPDOWN) { result = FALSE; return true; } */ if (info->iWhy == CBENF_RETURN) { // When we use Edit control and press Enter. UString s; _headerComboBox.GetText(s); result = OnNotifyComboBoxEnter(s); return true; } return false; } #endif #ifndef _UNICODE bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result) { if (info->iWhy == CBENF_ESCAPE) { _headerComboBox.SetText(_currentFolderPrefix); PostMsg(kSetFocusToListView); result = FALSE; return true; } /* if (info->iWhy == CBENF_DROPDOWN) { result = FALSE; return true; } */ if (info->iWhy == CBENF_RETURN) { UString s; _headerComboBox.GetText(s); // GetUnicodeString(info->szText) result = OnNotifyComboBoxEnter(s); return true; } return false; } #endif void CPanel::AddComboBoxItem(const UString &name, int iconIndex, unsigned indent, bool addToList) { #ifdef UNDER_CE UString s; iconIndex = iconIndex; for (unsigned i = 0; i < indent; i++) s += " "; _headerComboBox.AddString(s + name); #else COMBOBOXEXITEMW item; item.mask = CBEIF_TEXT | CBEIF_INDENT; if (iconIndex < 0) iconIndex = g_Ext_to_Icon_Map.GetIconIndex_DIR(); item.iSelectedImage = item.iImage = iconIndex; if (iconIndex >= 0) item.mask |= (CBEIF_IMAGE | CBEIF_SELECTEDIMAGE); item.iItem = -1; item.iIndent = (int)indent; item.pszText = name.Ptr_non_const(); _headerComboBox.InsertItem(&item); #endif if (addToList) { UString s = name; s.Add_PathSepar(); ComboBoxPaths.Add(s); } } bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result) { result = FALSE; switch (code) { case CBN_DROPDOWN: { ComboBoxPaths.Clear(); _headerComboBox.ResetContent(); UString sumPath; UStringVector pathParts; unsigned indent = 0; { UString path = _currentFolderPrefix; // path = L"\\\\.\\y:\\"; // for debug UString prefix0; if (path.IsPrefixedBy_Ascii_NoCase("\\\\")) { const int separ = FindCharPosInString(path.Ptr(2), '\\'); if (separ > 0 && (separ > 1 || path[2] != '.')) // "\\\\.\\" will be processed later { const UString s = path.Left(2 + separ); prefix0 = s; prefix0.Add_PathSepar(); AddComboBoxItem(s, GetRealIconIndex_for_DirPath(us2fs(prefix0), FILE_ATTRIBUTE_DIRECTORY), indent++, false); // addToList ComboBoxPaths.Add(prefix0); } } unsigned rootPrefixSize = NName::GetRootPrefixSize(path); sumPath = path; if (rootPrefixSize <= prefix0.Len()) { rootPrefixSize = prefix0.Len(); sumPath.DeleteFrom(rootPrefixSize); } else { // rootPrefixSize > prefix0.Len() sumPath.DeleteFrom(rootPrefixSize); CFileInfo info; DWORD attrib = FILE_ATTRIBUTE_DIRECTORY; if (info.Find(us2fs(sumPath)) && info.IsDir()) attrib = info.Attrib; UString s = sumPath.Ptr(prefix0.Len()); if (!s.IsEmpty()) { const wchar_t c = s.Back(); if (IS_PATH_SEPAR(c)) s.DeleteBack(); } UString path_for_icon = sumPath; NName::If_IsSuperPath_RemoveSuperPrefix(path_for_icon); AddComboBoxItem(s, GetRealIconIndex_for_DirPath(us2fs(path_for_icon), attrib), indent++, false); // addToList ComboBoxPaths.Add(sumPath); } path.DeleteFrontal(rootPrefixSize); SplitPathToParts(path, pathParts); } // it's expected that pathParts.Back() is empty, because _currentFolderPrefix has PathSeparator. unsigned next_Arc_index = 0; int iconIndex_Computer; const UString name_Computer = RootFolder_GetName_Computer(iconIndex_Computer); // const bool is_devicePrefix = (sumPath == L"\\\\.\\"); if (pathParts.Size() > 1) if (!sumPath.IsEmpty() || pathParts.Size() != 2 || pathParts[0] != name_Computer) for (unsigned i = 0; i + 1 < pathParts.Size(); i++) { UString name = pathParts[i]; sumPath += name; bool isRootDir_inLink = false; if (next_Arc_index < _parentFolders.Size()) { const CFolderLink &link = _parentFolders[next_Arc_index]; if (link.VirtualPath == sumPath) { isRootDir_inLink = true; next_Arc_index++; } } int iconIndex = -1; DWORD attrib = isRootDir_inLink ? FILE_ATTRIBUTE_ARCHIVE: FILE_ATTRIBUTE_DIRECTORY; if (next_Arc_index == 0 || (next_Arc_index == 1 && isRootDir_inLink)) { if (i == 0 && NName::IsDevicePath(us2fs(sumPath))) { UString path = name; path.Add_PathSepar(); attrib = FILE_ATTRIBUTE_ARCHIVE; // FILE_ATTRIBUTE_DIRECTORY; } else { CFileInfo info; if (info.Find(us2fs(sumPath))) attrib = info.Attrib; } iconIndex = Shell_GetFileInfo_SysIconIndex_for_Path(us2fs(sumPath), attrib); } if (iconIndex < 0) iconIndex = g_Ext_to_Icon_Map.GetIconIndex(attrib, name); // iconIndex = -1; // for debug if (iconIndex < 0 && isRootDir_inLink) iconIndex = 0; // default file sumPath.Add_PathSepar(); ComboBoxPaths.Add(sumPath); if (name.IsEmpty()) name.Add_PathSepar(); AddComboBoxItem(name, iconIndex, indent++, false); // addToList } #ifndef UNDER_CE { int iconIndex; const UString name = RootFolder_GetName_Documents(iconIndex); // iconIndex = -1; // for debug AddComboBoxItem(name, iconIndex, 0, true); } AddComboBoxItem(name_Computer, iconIndex_Computer, 0, true); { FStringVector driveStrings; MyGetLogicalDriveStrings(driveStrings); FOR_VECTOR (i, driveStrings) { FString s = driveStrings[i]; ComboBoxPaths.Add(fs2us(s)); int iconIndex2 = GetRealIconIndex_for_DirPath(s, FILE_ATTRIBUTE_DIRECTORY); if (!s.IsEmpty()) { const FChar c = s.Back(); if (IS_PATH_SEPAR(c)) s.DeleteBack(); } // iconIndex2 = -1; // for debug AddComboBoxItem(fs2us(s), iconIndex2, 1, false); } } { int iconIndex; const UString name = RootFolder_GetName_Network(iconIndex); AddComboBoxItem(name, iconIndex, 0, true); } #endif return false; } case CBN_SELENDOK: { int index = _headerComboBox.GetCurSel(); if (index >= 0) { const UString path = ComboBoxPaths[index]; _headerComboBox.SetCurSel(-1); // _headerComboBox.SetText(pass); // it's fix for selecting by mouse. if (BindToPathAndRefresh(path) == S_OK) { PostMsg(kSetFocusToListView); #ifdef UNDER_CE PostMsg(kRefresh_HeaderComboBox); #endif return true; } } return false; } /* case CBN_CLOSEUP: { LoadFullPathAndShow(); true; } case CBN_SELCHANGE: { // LoadFullPathAndShow(); return true; } */ } return false; } bool CPanel::OnNotifyComboBox(LPNMHDR NON_CE_VAR(header), LRESULT & NON_CE_VAR(result)) { #ifndef UNDER_CE switch (header->code) { case CBEN_BEGINEDIT: { _lastFocusedIsList = false; _panelCallback->PanelWasFocused(); break; } #ifndef _UNICODE case CBEN_ENDEDIT: { return OnNotifyComboBoxEndEdit((PNMCBEENDEDIT)header, result); } #endif case CBEN_ENDEDITW: { return OnNotifyComboBoxEndEdit((PNMCBEENDEDITW)header, result); } } #endif return false; } void CPanel::FoldersHistory() { CListViewDialog listViewDialog; listViewDialog.DeleteIsAllowed = true; listViewDialog.SelectFirst = true; LangString(IDS_FOLDERS_HISTORY, listViewDialog.Title); _appState->FolderHistory.GetList(listViewDialog.Strings); if (listViewDialog.Create(GetParent()) != IDOK) return; UString selectString; if (listViewDialog.StringsWereChanged) { _appState->FolderHistory.RemoveAll(); for (int i = (int)listViewDialog.Strings.Size() - 1; i >= 0; i--) _appState->FolderHistory.AddString(listViewDialog.Strings[i]); if (listViewDialog.FocusedItemIndex >= 0) selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex]; } else { if (listViewDialog.FocusedItemIndex >= 0) selectString = listViewDialog.Strings[listViewDialog.FocusedItemIndex]; } if (listViewDialog.FocusedItemIndex >= 0) BindToPathAndRefresh(selectString); } UString CPanel::GetParentDirPrefix() const { UString s; if (!_currentFolderPrefix.IsEmpty()) { wchar_t c = _currentFolderPrefix.Back(); if (IS_PATH_SEPAR(c) || c == ':') { s = _currentFolderPrefix; s.DeleteBack(); if (s != L"\\\\." && s != L"\\\\?") { int pos = s.ReverseFind_PathSepar(); if (pos >= 0) s.DeleteFrom((unsigned)(pos + 1)); } } } return s; } void CPanel::OpenParentFolder() { LoadFullPath(); // Maybe we don't need it ?? UString parentFolderPrefix; UString focusedName; if (!_currentFolderPrefix.IsEmpty()) { wchar_t c = _currentFolderPrefix.Back(); if (IS_PATH_SEPAR(c) || c == ':') { focusedName = _currentFolderPrefix; focusedName.DeleteBack(); /* if (c == ':' && !focusedName.IsEmpty() && IS_PATH_SEPAR(focusedName.Back())) { focusedName.DeleteBack(); } else */ if (focusedName != L"\\\\." && focusedName != L"\\\\?") { const int pos = focusedName.ReverseFind_PathSepar(); if (pos >= 0) { parentFolderPrefix = focusedName; parentFolderPrefix.DeleteFrom((unsigned)(pos + 1)); focusedName.DeleteFrontal((unsigned)(pos + 1)); } } } } CDisableTimerProcessing disableTimerProcessing(*this); CDisableNotify disableNotify(*this); CMyComPtr newFolder; _folder->BindToParentFolder(&newFolder); // newFolder.Release(); // for test if (newFolder) SetNewFolder(newFolder); else { bool needSetFolder = true; if (!_parentFolders.IsEmpty()) { { const CFolderLink &link = _parentFolders.Back(); parentFolderPrefix = link.ParentFolderPath; focusedName = link.RelPath; } CloseOneLevel(); needSetFolder = (!_folder); } if (needSetFolder) { { COpenResult openRes; BindToPath(parentFolderPrefix, UString(), openRes); } } } CSelectedState state; state.FocusedName = focusedName; state.FocusedName_Defined = true; /* if (!focusedName.IsEmpty()) state.SelectedNames.Add(focusedName); */ LoadFullPath(); // ::SetCurrentDirectory(::_currentFolderPrefix); RefreshListCtrl(state); // _listView.EnsureVisible(_listView.GetFocusedItem(), false); } void CPanel::CloseOneLevel() { ReleaseFolder(); _library.Free(); { CFolderLink &link = _parentFolders.Back(); if (link.ParentFolder) SetNewFolder(link.ParentFolder); _library.Attach(link.Library.Detach()); } if (_parentFolders.Size() > 1) OpenParentArchiveFolder(); _parentFolders.DeleteBack(); if (_parentFolders.IsEmpty()) _flatMode = _flatModeForDisk; } void CPanel::CloseOpenFolders() { while (!_parentFolders.IsEmpty()) CloseOneLevel(); _flatMode = _flatModeForDisk; ReleaseFolder(); _library.Free(); } void CPanel::OpenRootFolder() { CDisableTimerProcessing disableTimerProcessing(*this); CDisableNotify disableNotify(*this); _parentFolders.Clear(); SetToRootFolder(); RefreshListCtrl(); // ::SetCurrentDirectory(::_currentFolderPrefix); /* BeforeChangeFolder(); _currentFolderPrefix.Empty(); AfterChangeFolder(); SetCurrentPathText(); RefreshListCtrl(UString(), 0, UStringVector()); _listView.EnsureVisible(_listView.GetFocusedItem(), false); */ } void CPanel::OpenDrivesFolder() { CloseOpenFolders(); #ifdef UNDER_CE NFsFolder::CFSFolder *folderSpec = new NFsFolder::CFSFolder; SetNewFolder(folderSpec); folderSpec->InitToRoot(); #else CFSDrives *folderSpec = new CFSDrives; SetNewFolder(folderSpec); folderSpec->Init(); #endif RefreshListCtrl(); } void CPanel::OpenFolder(unsigned index) { if (index == kParentIndex) { OpenParentFolder(); return; } CMyComPtr newFolder; const HRESULT res = _folder->BindToFolder((unsigned)index, &newFolder); if (res != 0) { MessageBox_Error_HRESULT(res); return; } if (!newFolder) return; SetNewFolder(newFolder); LoadFullPath(); RefreshListCtrl(); // 17.02: fixed : now we don't select first item // _listView.SetItemState_Selected(_listView.GetFocusedItem()); _listView.EnsureVisible(_listView.GetFocusedItem(), false); } void CPanel::OpenAltStreams() { CRecordVector indices; Get_ItemIndices_Operated(indices); Int32 realIndex = -1; if (indices.Size() > 1) return; if (indices.Size() == 1) realIndex = (Int32)indices[0]; if (_folderAltStreams) { CMyComPtr newFolder; _folderAltStreams->BindToAltStreams((UInt32)realIndex, &newFolder); if (newFolder) { CDisableTimerProcessing disableTimerProcessing(*this); CDisableNotify disableNotify(*this); SetNewFolder(newFolder); RefreshListCtrl(); return; } return; } #if defined(_WIN32) && !defined(UNDER_CE) UString path; if (realIndex >= 0) path = GetItemFullPath((UInt32)realIndex); else { path = GetFsPath(); if (!NName::IsDriveRootPath_SuperAllowed(us2fs(path))) if (!path.IsEmpty() && IS_PATH_SEPAR(path.Back())) path.DeleteBack(); } path.Add_Colon(); BindToPathAndRefresh(path); #endif }