// PanelFolderChange.cpp #include "StdAfx.h" #include "Common/StringConvert.h" #include "Common/Wildcard.h" #include "Windows/FileDir.h" #include "../../PropID.h" #include "Panel.h" #include "ListViewDialog.h" #include "RootFolder.h" #include "ViewSettings.h" #include "FSDrives.h" #include "LangUtils.h" #include "resource.h" using namespace NWindows; using namespace NFile; using namespace NFind; void CPanel::SetToRootFolder() { _folder.Release(); _library.Free(); CRootFolder *rootFolderSpec = new CRootFolder; _folder = rootFolderSpec; rootFolderSpec->Init(); } HRESULT CPanel::BindToPath(const UString &fullPath, bool &archiveIsOpened, bool &encrypted) { archiveIsOpened = false; encrypted = false; CDisableTimerProcessing disableTimerProcessing1(*this); CloseOpenFolders(); UString sysPath = fullPath; CFileInfoW fileInfo; UStringVector reducedParts; while(!sysPath.IsEmpty()) { if (FindFile(sysPath, fileInfo)) break; int pos = sysPath.ReverseFind(L'\\'); if (pos < 0) sysPath.Empty(); else { if (reducedParts.Size() > 0 || pos < sysPath.Length() - 1) reducedParts.Add(sysPath.Mid(pos + 1)); sysPath = sysPath.Left(pos); } } SetToRootFolder(); CMyComPtr newFolder; if (sysPath.IsEmpty()) { if (_folder->BindToFolder(fullPath, &newFolder) == S_OK) _folder = newFolder; } else if (fileInfo.IsDirectory()) { NName::NormalizeDirPathPrefix(sysPath); if (_folder->BindToFolder(sysPath, &newFolder) == S_OK) _folder = newFolder; } else { UString dirPrefix; if (!NDirectory::GetOnlyDirPrefix(sysPath, dirPrefix)) dirPrefix.Empty(); if (_folder->BindToFolder(dirPrefix, &newFolder) == S_OK) { _folder = newFolder; LoadFullPath(); UString fileName; if (NDirectory::GetOnlyName(sysPath, fileName)) { if (OpenItemAsArchive(fileName, _currentFolderPrefix, _currentFolderPrefix + fileName, encrypted) == S_OK) { archiveIsOpened = true; for (int i = reducedParts.Size() - 1; i >= 0; i--) { CMyComPtr newFolder; _folder->BindToFolder(reducedParts[i], &newFolder); if (!newFolder) break; _folder = newFolder; } } } } } return S_OK; } HRESULT CPanel::BindToPathAndRefresh(const UString &path) { CDisableTimerProcessing disableTimerProcessing1(*this); bool archiveIsOpened, encrypted; RINOK(BindToPath(path, archiveIsOpened, encrypted)); RefreshListCtrl(UString(), -1, true, UStringVector()); return S_OK; } void CPanel::SetBookmark(int index) { _appState->FastFolders.SetString(index, _currentFolderPrefix); } void CPanel::OpenBookmark(int 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 (int i = 0; i < _parentFolders.Size(); i++) { const CFolderLink &folderLink = _parentFolders[i]; _currentFolderPrefix += GetFolderPath(folderLink.ParentFolder); _currentFolderPrefix += folderLink.ItemName; _currentFolderPrefix += L'\\'; } if (_folder) _currentFolderPrefix += GetFolderPath(_folder); } void CPanel::LoadFullPathAndShow() { LoadFullPath(); _appState->FolderHistory.AddString(_currentFolderPrefix); // _headerComboBox.SendMessage(CB_RESETCONTENT, 0, 0); _headerComboBox.SetText(_currentFolderPrefix); RefreshTitle(); /* for (int i = 0; i < g_Folders.m_Strings.Size(); i++) { UString string = g_Folders.m_Strings[i]; COMBOBOXEXITEM item; item.mask = CBEIF_TEXT; item.iItem = i; item.pszText = (LPTSTR)(LPCTSTR)string; _headerComboBox.InsertItem(&item); } */ } bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDITW info, LRESULT &result) { if (info->iWhy == CBENF_ESCAPE) { _headerComboBox.SetText(_currentFolderPrefix); PostMessage(kSetFocusToListView); result = FALSE; return true; } if (info->iWhy == CBENF_DROPDOWN) { result = FALSE; return true; } if (info->iWhy == CBENF_RETURN) { UString s; _headerComboBox.GetText(s); // length of NMCBEENDEDITW.szText is limited by MAX_PATH // if (BindToPathAndRefresh(info->szText) != S_OK) if (BindToPathAndRefresh(s) != S_OK) { result = TRUE; return true; } result = FALSE; PostMessage(kSetFocusToListView); return true; } return false; } #ifndef _UNICODE bool CPanel::OnNotifyComboBoxEndEdit(PNMCBEENDEDIT info, LRESULT &result) { if (info->iWhy == CBENF_ESCAPE) { _headerComboBox.SetText(_currentFolderPrefix); PostMessage(kSetFocusToListView); result = FALSE; return true; } if (info->iWhy == CBENF_DROPDOWN) { result = FALSE; return true; } if (info->iWhy == CBENF_RETURN) { if (BindToPathAndRefresh(GetUnicodeString(info->szText)) != S_OK) { result = TRUE; return true; } result = FALSE; PostMessage(kSetFocusToListView); return true; } return false; } #endif void CPanel::OnComboBoxCommand(UINT /* code */, LPARAM & /* param */) { /* if (code == CBN_SELENDOK) { UString path; if (!_headerComboBox.GetText(path)) return; CRootFolder *rootFolderSpec = new CRootFolder; CMyComPtr rootFolder = rootFolderSpec; rootFolderSpec->Init(); CMyComPtr newFolder; if (rootFolder->BindToFolder(path, &newFolder) != S_OK) return; _folder = newFolder; SetCurrentPathText(); RefreshListCtrl(UString(), -1, UStringVector()); PostMessage(kSetFocusToListView); } */ } bool CPanel::OnNotifyComboBox(LPNMHDR header, LRESULT &result) { switch(header->code) { case CBEN_BEGINEDIT: { _lastFocusedIsList = false; _panelCallback->PanelWasFocused(); } #ifndef _UNICODE case CBEN_ENDEDIT: { return OnNotifyComboBoxEndEdit((PNMCBEENDEDIT)header, result); } #endif case CBEN_ENDEDITW: { return OnNotifyComboBoxEndEdit((PNMCBEENDEDITW)header, result); } } return false; } void CPanel::FoldersHistory() { CListViewDialog listViewDialog; listViewDialog.DeleteIsAllowed = true; listViewDialog.Title = LangString(IDS_FOLDERS_HISTORY, 0x03020260); _appState->FolderHistory.GetList(listViewDialog.Strings); if (listViewDialog.Create(GetParent()) == IDCANCEL) return; UString selectString; if (listViewDialog.StringsWereChanged) { _appState->FolderHistory.RemoveAll(); for (int i = 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); } void CPanel::OpenParentFolder() { LoadFullPath(); // Maybe we don't need it ?? UString focucedName; if (!_currentFolderPrefix.IsEmpty()) { UString string = _currentFolderPrefix; string.Delete(string.Length() - 1); int pos = string.ReverseFind(L'\\'); if (pos < 0) pos = 0; else pos++; focucedName = string.Mid(pos); } CDisableTimerProcessing disableTimerProcessing1(*this); CMyComPtr newFolder; _folder->BindToParentFolder(&newFolder); if (newFolder) _folder = newFolder; else { if (_parentFolders.IsEmpty()) { SetToRootFolder(); if (focucedName.IsEmpty()) focucedName = GetItemName(0); } else { _folder.Release(); _library.Free(); CFolderLink &link = _parentFolders.Back(); _folder = link.ParentFolder; _library.Attach(link.Library.Detach()); focucedName = link.ItemName; if (_parentFolders.Size () > 1) OpenParentArchiveFolder(); _parentFolders.DeleteBack(); } } UStringVector selectedItems; /* if (!focucedName.IsEmpty()) selectedItems.Add(focucedName); */ LoadFullPath(); // ::SetCurrentDirectory(::_currentFolderPrefix); RefreshListCtrl(focucedName, -1, true, selectedItems); _listView.EnsureVisible(_listView.GetFocusedItem(), false); RefreshStatusBar(); } void CPanel::CloseOpenFolders() { while(_parentFolders.Size() > 0) { _folder.Release(); _library.Free(); _folder = _parentFolders.Back().ParentFolder; _library.Attach(_parentFolders.Back().Library.Detach()); if (_parentFolders.Size () > 1) OpenParentArchiveFolder(); _parentFolders.DeleteBack(); } _folder.Release(); _library.Free(); } void CPanel::OpenRootFolder() { CDisableTimerProcessing disableTimerProcessing1(*this); _parentFolders.Clear(); SetToRootFolder(); RefreshListCtrl(UString(), -1, true, UStringVector()); // ::SetCurrentDirectory(::_currentFolderPrefix); /* BeforeChangeFolder(); _currentFolderPrefix.Empty(); AfterChangeFolder(); SetCurrentPathText(); RefreshListCtrl(UString(), 0, UStringVector()); _listView.EnsureVisible(_listView.GetFocusedItem(), false); */ } void CPanel::OpenDrivesFolder() { CloseOpenFolders(); CFSDrives *fsFolderSpec = new CFSDrives; _folder = fsFolderSpec; fsFolderSpec->Init(); RefreshListCtrl(); } void CPanel::OpenFolder(int index) { if (index == kParentIndex) { OpenParentFolder(); return; } CMyComPtr newFolder; _folder->BindToFolder(index, &newFolder); if (!newFolder) return; _folder = newFolder; LoadFullPath(); // ::SetCurrentDirectory(::_currentFolderPrefix); RefreshListCtrl(); UINT state = LVIS_SELECTED; _listView.SetItemState(_listView.GetFocusedItem(), state, state); _listView.EnsureVisible(_listView.GetFocusedItem(), false); }