void CRemoteTreeView::DisplayItem(wxTreeItemId parent, const CDirectoryListing& listing) { DeleteChildren(parent); const wxString path = listing.path.GetPath(); CFilterDialog filter; for (unsigned int i = 0; i < listing.GetCount(); i++) { if (!listing[i].is_dir()) continue; if (filter.FilenameFiltered(listing[i].name, path, true, -1, false, 0, listing[i].time)) continue; const wxString& name = listing[i].name; CServerPath subdir = listing.path; subdir.AddSegment(name); CDirectoryListing subListing; if (m_pState->m_pEngine->CacheLookup(subdir, subListing) == FZ_REPLY_OK) { wxTreeItemId child = AppendItem(parent, name, 0, 2, 0); SetItemImages(child, false); if (HasSubdirs(subListing, filter)) AppendItem(child, _T(""), -1, -1); } else { wxTreeItemId child = AppendItem(parent, name, 1, 3, 0); SetItemImages(child, true); } } SortChildren(parent); }
bool CRemoteTreeView::ListExpand(wxTreeItemId item) { const CServerPath path = GetPathFromItem(item); wxASSERT(!path.empty()); if (path.empty()) return false; CDirectoryListing listing; if (m_pState->m_pEngine->CacheLookup(path, listing) == FZ_REPLY_OK) RefreshItem(item, listing, false); else { SetItemImages(item, true); wxTreeItemId child = GetLastChild(item); if (!child || GetItemText(child).empty()) return false; } return true; }
void CRemoteTreeView::RefreshItem(wxTreeItemId parent, const CDirectoryListing& listing, bool will_select_parent) { SetItemImages(parent, false); wxTreeItemIdValue cookie; wxTreeItemId child = GetFirstChild(parent, cookie); if (!child || GetItemText(child).empty()) { DisplayItem(parent, listing); return; } CFilterManager filter; wxString const path = listing.path.GetPath(); wxArrayString dirs; for (unsigned int i = 0; i < listing.GetCount(); ++i) { if (!listing[i].is_dir()) continue; if (!filter.FilenameFiltered(listing[i].name, path, true, -1, false, 0, listing[i].time)) dirs.push_back(listing[i].name); } auto const& sortFunc = CFileListCtrlSortBase::GetCmpFunction(m_nameSortMode); dirs.Sort(sortFunc); bool inserted = false; child = GetLastChild(parent); wxArrayString::reverse_iterator iter = dirs.rbegin(); while (child && iter != dirs.rend()) { int cmp = sortFunc(GetItemText(child), *iter); if (!cmp) { CServerPath childPath = listing.path; childPath.AddSegment(*iter); CDirectoryListing subListing; if (m_pState->m_pEngine->CacheLookup(childPath, subListing) == FZ_REPLY_OK) { if (!GetLastChild(child) && HasSubdirs(subListing, filter)) AppendItem(child, _T(""), -1, -1); SetItemImages(child, false); } else SetItemImages(child, true); child = GetPrevSibling(child); ++iter; } else if (cmp > 0) { // Child no longer exists wxTreeItemId sel = GetSelection(); while (sel && sel != child) sel = GetItemParent(sel); wxTreeItemId prev = GetPrevSibling(child); if (!sel || will_select_parent) Delete(child); child = prev; } else if (cmp < 0) { // New directory CServerPath childPath = listing.path; childPath.AddSegment(*iter); CDirectoryListing subListing; if (m_pState->m_pEngine->CacheLookup(childPath, subListing) == FZ_REPLY_OK) { wxTreeItemId childItem = AppendItem(parent, *iter, 0, 2, 0); if (childItem) { SetItemImages(childItem, false); if (HasSubdirs(subListing, filter)) { AppendItem(childItem, _T(""), -1, -1); } } } else { wxTreeItemId childItem = AppendItem(parent, *iter, 1, 3, 0); if (childItem) { SetItemImages(childItem, true); } } ++iter; inserted = true; } } while (child) { // Child no longer exists wxTreeItemId sel = GetSelection(); while (sel && sel != child) sel = GetItemParent(sel); wxTreeItemId prev = GetPrevSibling(child); if (!sel || will_select_parent) Delete(child); child = prev; } while (iter != dirs.rend()) { CServerPath childPath = listing.path; childPath.AddSegment(*iter); CDirectoryListing subListing; if (m_pState->m_pEngine->CacheLookup(childPath, subListing) == FZ_REPLY_OK) { wxTreeItemId childItem = AppendItem(parent, *iter, 0, 2, 0); if (childItem) { SetItemImages(childItem, false); if (HasSubdirs(subListing, filter)) { AppendItem(childItem, _T(""), -1, -1); } } } else { wxTreeItemId childItem = AppendItem(parent, *iter, 1, 3, 0); if (childItem) { SetItemImages(childItem, true); } } ++iter; inserted = true; } if (inserted) SortChildren(parent); }
wxTreeItemId CRemoteTreeView::MakeParent(CServerPath path, bool select) { std::vector<wxString> pieces; pieces.reserve(path.SegmentCount() + 1); while (path.HasParent()) { pieces.push_back(path.GetLastSegment()); path = path.GetParent(); } wxASSERT(!path.GetPath().empty()); pieces.push_back(path.GetPath()); const wxTreeItemId root = GetRootItem(); wxTreeItemId parent = root; for (std::vector<wxString>::const_reverse_iterator iter = pieces.rbegin(); iter != pieces.rend(); ++iter) { if (iter != pieces.rbegin()) path.AddSegment(*iter); wxTreeItemIdValue cookie; wxTreeItemId child = GetFirstChild(parent, cookie); if (child && GetItemText(child).empty()) { Delete(child); child = wxTreeItemId(); if (parent != root) ListExpand(parent); } for (child = GetFirstChild(parent, cookie); child; child = GetNextSibling(child)) { const wxString& text = GetItemText(child); if (text == *iter) break; } if (!child) { CDirectoryListing listing; if (m_pState->m_pEngine->CacheLookup(path, listing) == FZ_REPLY_OK) { child = AppendItem(parent, *iter, 0, 2, path.HasParent() ? 0 : new CItemData(path)); SetItemImages(child, false); } else { child = AppendItem(parent, *iter, 1, 3, path.HasParent() ? 0 : new CItemData(path)); SetItemImages(child, true); } SortChildren(parent); auto nextIter = iter; ++nextIter; if (nextIter != pieces.rend()) DisplayItem(child, listing); } if (select && iter != pieces.rbegin()) { #ifndef __WXMSW__ // Prevent CalculatePositions from being called wxGenericTreeItem *anchor = m_anchor; m_anchor = 0; #endif Expand(parent); #ifndef __WXMSW__ m_anchor = anchor; #endif } parent = child; } return parent; }
void CRemoteTreeView::SetDirectoryListing(std::shared_ptr<CDirectoryListing> const& pListing, bool modified) { m_busy = true; if (!pListing) { m_ExpandAfterList = wxTreeItemId(); DeleteAllItems(); AddRoot(_T("")); m_busy = false; if (FindFocus() == this) { wxNavigationKeyEvent *evt = new wxNavigationKeyEvent(); evt->SetFromTab(true); evt->SetEventObject(this); evt->SetDirection(true); QueueEvent(evt); } Enable(false); m_contextMenuItem = wxTreeItemId(); return; } Enable(true); #ifdef __WXGTK__ GetParent()->m_dirtyTabOrder = true; #endif if (pListing->get_unsure_flags() && !(pListing->get_unsure_flags() & ~(CDirectoryListing::unsure_unknown | CDirectoryListing::unsure_file_mask))) { // Just files changed, does not affect directory tree m_busy = false; return; } #ifndef __WXMSW__ Freeze(); #endif wxTreeItemId parent = MakeParent(pListing->path, !modified); if (!parent) { m_busy = false; #ifndef __WXMSW__ Thaw(); #endif return; } if (!IsExpanded(parent) && parent != m_ExpandAfterList) { DeleteChildren(parent); CFilterManager filter; if (HasSubdirs(*pListing, filter)) AppendItem(parent, _T(""), -1, -1); } else { RefreshItem(parent, *pListing, !modified); if (m_ExpandAfterList == parent) { #ifndef __WXMSW__ // Prevent CalculatePositions from being called wxGenericTreeItem *anchor = m_anchor; m_anchor = 0; #endif Expand(parent); #ifndef __WXMSW__ m_anchor = anchor; #endif } } m_ExpandAfterList = wxTreeItemId(); SetItemImages(parent, false); #ifndef __WXMSW__ Thaw(); #endif if (!modified) SafeSelectItem(parent); #ifndef __WXMSW__ else Refresh(); #endif m_busy = false; }
void CRemoteTreeView::RefreshItem(wxTreeItemId parent, const CDirectoryListing& listing, bool will_select_parent) { SetItemImages(parent, false); wxTreeItemIdValue cookie; wxTreeItemId child = GetFirstChild(parent, cookie); if (!child || GetItemText(child) == _T("")) { DisplayItem(parent, listing); return; } CFilterManager filter; const wxString path = listing.path.GetPath(); std::list<wxString> dirs; for (unsigned int i = 0; i < listing.GetCount(); i++) { if (!listing[i].is_dir()) continue; if (!filter.FilenameFiltered(listing[i].name, path, true, -1, false, 0, listing[i].has_date() ? &listing[i].time : 0)) dirs.push_back(listing[i].name); } dirs.sort(sortfunc); bool inserted = false; child = GetLastChild(parent); std::list<wxString>::reverse_iterator iter = dirs.rbegin(); while (child && iter != dirs.rend()) { int cmp = GetItemText(child).CmpNoCase(*iter); if (!cmp) cmp = GetItemText(child).Cmp(*iter); if (!cmp) { CServerPath path = listing.path; path.AddSegment(*iter); CDirectoryListing subListing; if (m_pState->m_pEngine->CacheLookup(path, subListing) == FZ_REPLY_OK) { if (!GetLastChild(child) && HasSubdirs(subListing, filter)) AppendItem(child, _T(""), -1, -1); SetItemImages(child, false); } else SetItemImages(child, true); child = GetPrevSibling(child); iter++; } else if (cmp > 0) { // Child no longer exists wxTreeItemId sel = GetSelection(); while (sel && sel != child) sel = GetItemParent(sel); wxTreeItemId prev = GetPrevSibling(child); if (!sel || will_select_parent) Delete(child); child = prev; } else if (cmp < 0) { // New directory CServerPath path = listing.path; path.AddSegment(*iter); CDirectoryListing subListing; if (m_pState->m_pEngine->CacheLookup(path, subListing) == FZ_REPLY_OK) { wxTreeItemId child = AppendItem(parent, *iter, 0, 2, 0); SetItemImages(child, false); if (HasSubdirs(subListing, filter)) AppendItem(child, _T(""), -1, -1); } else { wxTreeItemId child = AppendItem(parent, *iter, 1, 3, 0); if (child) SetItemImages(child, true); } iter++; inserted = true; } } while (child) { // Child no longer exists wxTreeItemId sel = GetSelection(); while (sel && sel != child) sel = GetItemParent(sel); wxTreeItemId prev = GetPrevSibling(child); if (!sel || will_select_parent) Delete(child); child = prev; } while (iter != dirs.rend()) { CServerPath path = listing.path; path.AddSegment(*iter); CDirectoryListing subListing; if (m_pState->m_pEngine->CacheLookup(path, subListing) == FZ_REPLY_OK) { wxTreeItemId child = AppendItem(parent, *iter, 0, 2, 0); SetItemImages(child, false); if (HasSubdirs(subListing, filter)) AppendItem(child, _T(""), -1, -1); } else { wxTreeItemId child = AppendItem(parent, *iter, 1, 3, 0); SetItemImages(child, true); } iter++; inserted = true; } if (inserted) SortChildren(parent); }