bool CState::SetSyncBrowse(bool enable, const CServerPath& assumed_remote_root /*=CServerPath()*/) { if (enable != m_sync_browse.local_root.empty()) return enable; if (!enable) { wxASSERT(assumed_remote_root.IsEmpty()); m_sync_browse.local_root.clear(); m_sync_browse.remote_root.Clear(); m_sync_browse.is_changing = false; NotifyHandlers(STATECHANGE_SYNC_BROWSE); return false; } if (!m_pDirectoryListing && assumed_remote_root.IsEmpty()) { NotifyHandlers(STATECHANGE_SYNC_BROWSE); return false; } m_sync_browse.is_changing = false; m_sync_browse.local_root = m_localDir; if (assumed_remote_root.IsEmpty()) m_sync_browse.remote_root = m_pDirectoryListing->path; else { m_sync_browse.remote_root = assumed_remote_root; m_sync_browse.is_changing = true; m_sync_browse.compare = false; } while (m_sync_browse.local_root.HasParent() && m_sync_browse.remote_root.HasParent() && m_sync_browse.local_root.GetLastSegment() == m_sync_browse.remote_root.GetLastSegment()) { m_sync_browse.local_root.MakeParent(); m_sync_browse.remote_root = m_sync_browse.remote_root.GetParent(); } NotifyHandlers(STATECHANGE_SYNC_BROWSE); return true; }
void CSearchDialog::OnSearch(wxCommandEvent& event) { if (!m_pState->IsRemoteIdle()) { wxBell(); return; } CServerPath path; const CServer* pServer = m_pState->GetServer(); if (!pServer) { wxMessageBox(_("Connection to server lost."), _("Remote file search"), wxICON_EXCLAMATION); return; } path.SetType(pServer->GetType()); if (!path.SetPath(XRCCTRL(*this, "ID_PATH", wxTextCtrl)->GetValue()) || path.IsEmpty()) { wxMessageBox(_("Need to enter valid remote path"), _("Remote file search"), wxICON_EXCLAMATION); return; } m_search_root = path; // Prepare filter wxString error; if (!ValidateFilter(error, true)) { wxMessageBox(wxString::Format(_("Invalid search conditions: %s"), error.c_str()), _("Remote file search"), wxICON_EXCLAMATION); return; } m_search_filter = GetFilter(); if (!CFilterManager::CompileRegexes(m_search_filter)) { wxMessageBox(_("Invalid regular expression in search conditions."), _("Remote file search"), wxICON_EXCLAMATION); return; } m_search_filter.matchCase = XRCCTRL(*this, "ID_CASE", wxCheckBox)->GetValue(); // Delete old results m_results->ClearSelection(); m_results->m_indexMapping.clear(); m_results->m_fileData.clear(); m_results->SetItemCount(0); m_visited.clear(); m_results->RefreshListOnly(true); m_results->GetFilelistStatusBar()->Clear(); // Start m_searching = true; m_pState->GetRecursiveOperationHandler()->AddDirectoryToVisitRestricted(path, _T(""), true); std::list<CFilter> filters; // Empty, recurse into everything m_pState->GetRecursiveOperationHandler()->StartRecursiveOperation(CRecursiveOperation::recursive_list, path, filters, true); }
bool CControlSocket::ParsePwdReply(wxString reply, bool unquoted /*=false*/, const CServerPath& defaultPath /*=CServerPath()*/) { if (!unquoted) { int pos1 = reply.Find('"'); int pos2 = reply.Find('"', true); if (pos1 == -1 || pos1 >= pos2) { pos1 = reply.Find('\''); pos2 = reply.Find('\'', true); if (pos1 != -1 && pos1 < pos2) LogMessage(__TFILE__, __LINE__, this, Debug_Info, _T("Broken server sending single-quoted path instead of double-quoted path.")); } if (pos1 == -1 || pos1 >= pos2) { LogMessage(__TFILE__, __LINE__, this, Debug_Info, _T("Broken server, no quoted path found in pwd reply, trying first token as path")); pos1 = reply.Find(' '); if (pos1 != -1) { reply = reply.Mid(pos1 + 1); pos2 = reply.Find(' '); if (pos2 != -1) reply = reply.Left(pos2); } else reply = _T(""); } else { reply = reply.Mid(pos1 + 1, pos2 - pos1 - 1); reply.Replace(_T("\"\""), _T("\"")); } } m_CurrentPath.SetType(m_pCurrentServer->GetType()); if (reply == _T("") || !m_CurrentPath.SetPath(reply)) { if (reply != _T("")) LogMessage(::Error, _("Failed to parse returned path.")); else LogMessage(::Error, _("Server returned empty path.")); if (!defaultPath.IsEmpty()) { LogMessage(Debug_Warning, _T("Assuming path is '%s'."), defaultPath.GetPath().c_str()); m_CurrentPath = defaultPath; return true; } return false; } return true; }
void CLocalListView::OnMenuUpload(wxCommandEvent& event) { const CServer* pServer = m_pState->GetServer(); if (!pServer) { wxBell(); return; } bool added = false; bool queue_only = event.GetId() == XRCID("ID_ADDTOQUEUE"); long item = -1; for (;;) { item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (!item && m_hasParent) continue; if (item == -1) break; const CLocalFileData *data = GetData(item); if (!data) break; if (data->flags == fill) continue; CServerPath path = m_pState->GetRemotePath(); if (path.IsEmpty()) { wxBell(); break; } if (data->dir) { path.ChangePath(data->name); CLocalPath localPath(m_dir); localPath.AddSegment(data->name); m_pQueue->QueueFolder(event.GetId() == XRCID("ID_ADDTOQUEUE"), false, localPath, path, *pServer); } else { m_pQueue->QueueFile(queue_only, false, data->name, wxEmptyString, CLocalPath(m_dir), path, *pServer, data->size); added = true; } } if (added) m_pQueue->QueueFile_Finish(!queue_only); }
bool CRemoteTreeView::ListExpand(wxTreeItemId item) { const CServerPath path = GetPathFromItem(item); wxASSERT(!path.IsEmpty()); if (path.IsEmpty()) 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) == _T("")) return false; } return true; }
void CPathCache::InvalidatePath(const CServer& server, const CServerPath& path, const wxString& subdir /*=_T("")*/) { tCacheIterator iter = m_cache.find(server); if (iter == m_cache.end()) return; CSourcePath sourcePath; sourcePath.source = path; sourcePath.subdir = subdir; CServerPath target; tServerCacheIterator serverIter = iter->second->find(sourcePath); if (serverIter != iter->second->end()) { target = serverIter->second; iter->second->erase(serverIter); } if (target.IsEmpty() && subdir != _T("")) { target = path; if (!target.AddSegment(subdir)) return; } if (!target.IsEmpty()) { // Unfortunately O(n), don't know of a faster way. for (std::map<CSourcePath, CServerPath>::iterator serverIter = iter->second->begin(); serverIter != iter->second->end();) { if (serverIter->second == target || target.IsParentOf(serverIter->second, false)) iter->second->erase(serverIter++); else if (serverIter->first.source == target || target.IsParentOf(serverIter->first.source, false)) iter->second->erase(serverIter++); else ++serverIter; } } }
void CPathCache::Store(const CServer& server, const CServerPath& target, const CServerPath& source, const wxString subdir/*=_T("")*/) { wxASSERT(!target.IsEmpty() && !source.IsEmpty()); tServerCache *pServerCache; tCacheIterator iter = m_cache.find(server); if (iter != m_cache.end()) pServerCache = iter->second; else { pServerCache = new tServerCache; m_cache[server] = pServerCache; } tServerCache &serverCache = *pServerCache; CSourcePath sourcePath; sourcePath.source = source; sourcePath.subdir = subdir; serverCache[sourcePath] = target; }
void CControlSocket::InvalidateCurrentWorkingDir(const CServerPath& path) { wxASSERT(!path.IsEmpty()); if (m_CurrentPath.IsEmpty()) return; if (m_CurrentPath == path || path.IsParentOf(m_CurrentPath, false)) { if (m_pCurOpData) m_invalidateCurrentPath = true; else m_CurrentPath.Clear(); } }
void CRemoteTreeView::OnSelectionChanged(wxTreeEvent& event) { if (event.GetItem() != m_ExpandAfterList) m_ExpandAfterList = wxTreeItemId(); if (m_busy) return; if (!m_pState->IsRemoteIdle()) { wxBell(); return; } wxTreeItemId item = event.GetItem(); if (!item) return; const CServerPath path = GetPathFromItem(item); wxASSERT(!path.IsEmpty()); if (path.IsEmpty()) return; m_pState->ChangeRemoteDir(path); }
CServerPath CPathCache::Lookup(const CServer& server, const CServerPath& source, const wxString subdir /*=_T("")*/) { const tCacheConstIterator iter = m_cache.find(server); if (iter == m_cache.end()) return CServerPath(); CServerPath result = Lookup(*iter->second, source, subdir); if (result.IsEmpty()) m_misses++; else m_hits++; return result; }
void CRemoteTreeView::OnMenuDelete(wxCommandEvent& event) { if (!m_pState->IsRemoteIdle()) return; if (!m_contextMenuItem) return; const CServerPath& path = GetPathFromItem(m_contextMenuItem); if (path.IsEmpty()) return; if (wxMessageBox(_("Really delete all selected files and/or directories?"), _("Confirmation needed"), wxICON_QUESTION | wxYES_NO, this) != wxYES) return; const bool hasParent = path.HasParent(); CRecursiveOperation* pRecursiveOperation = m_pState->GetRecursiveOperationHandler(); CServerPath startDir; if (hasParent) { const wxString& name = GetItemText(m_contextMenuItem); startDir = path.GetParent(); pRecursiveOperation->AddDirectoryToVisit(startDir, name); } else { startDir = path; pRecursiveOperation->AddDirectoryToVisit(startDir, _T("")); } CServerPath currentPath; const wxTreeItemId selected = GetSelection(); if (selected) currentPath = GetPathFromItem(selected); if (!currentPath.IsEmpty() && (path == currentPath || path.IsParentOf(currentPath, false))) currentPath = startDir; CFilterManager filter; pRecursiveOperation->StartRecursiveOperation(CRecursiveOperation::recursive_delete, startDir, filter.GetActiveFilters(false), !hasParent, currentPath); }
int CFileZillaApi::MakeDir(const CServerPath &path) { //Check if call allowed if (!m_bInitialized) return FZ_REPLY_NOTINITIALIZED; if (IsConnected()==FZ_REPLY_NOTCONNECTED) return FZ_REPLY_NOTCONNECTED; if (IsBusy()==FZ_REPLY_BUSY) return FZ_REPLY_BUSY; if (path.IsEmpty() || !path.HasParent()) return FZ_REPLY_INVALIDPARAM; t_command command; command.id=FZ_COMMAND_MAKEDIR; command.path=path; m_pMainThread->Command(command); if (m_hOwnerWnd) return FZ_REPLY_WOULDBLOCK; else return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR; return FZ_REPLY_ERROR; }
bool CSearchDialog::Load() { if (!wxDialogEx::Load(m_parent, _T("ID_SEARCH"))) return false; /* XRCed complains if adding a status bar to a dialog, so do it here instead */ CFilelistStatusBar* pStatusBar = new CFilelistStatusBar(this); pStatusBar->SetEmptyString(_("No search results")); GetSizer()->Add(pStatusBar, 0, wxGROW); if (!CreateListControl(filter_name | filter_size | filter_path | filter_date)) return false; m_results = new CSearchDialogFileList(this, m_pState, 0); ReplaceControl(XRCCTRL(*this, "ID_RESULTS", wxWindow), m_results); m_results->SetFilelistStatusBar(pStatusBar); const CServerPath path = m_pState->GetRemotePath(); if (!path.IsEmpty()) XRCCTRL(*this, "ID_PATH", wxTextCtrl)->ChangeValue(path.GetPath()); SetCtrlState(); m_pWindowStateManager = new CWindowStateManager(this); m_pWindowStateManager->Restore(OPTION_SEARCH_SIZE, wxSize(750, 500)); Layout(); LoadConditions(); EditFilter(m_search_filter); XRCCTRL(*this, "ID_CASE", wxCheckBox)->SetValue(m_search_filter.matchCase); return true; }
bool CSiteManager::AddBookmark(wxString sitePath, const wxString& name, const wxString &local_dir, const CServerPath &remote_dir, bool sync) { if (local_dir.empty() && remote_dir.IsEmpty()) return false; if (sitePath[0] != '0') return false; sitePath = sitePath.Mid(1); // We have to synchronize access to sitemanager.xml so that multiple processed don't write // to the same file or one is reading while the other one writes. CInterProcessMutex mutex(MUTEX_SITEMANAGER); CXmlFile file; TiXmlElement* pDocument = file.Load(_T("sitemanager")); if (!pDocument) { wxString msg = file.GetError() + _T("\n") + _("The bookmark could not be added."); wxMessageBox(msg, _("Error loading xml file"), wxICON_ERROR); return false; } TiXmlElement* pElement = pDocument->FirstChildElement("Servers"); if (!pElement) return false; std::list<wxString> segments; if (!UnescapeSitePath(sitePath, segments)) { wxMessageBox(_("Site path is malformed."), _("Invalid site path")); return 0; } TiXmlElement* pChild = GetElementByPath(pElement, segments); if (!pChild || strcmp(pChild->Value(), "Server")) { wxMessageBox(_("Site does not exist."), _("Invalid site path")); return 0; } // Bookmarks TiXmlElement *pInsertBefore = 0; TiXmlElement* pBookmark; for (pBookmark = pChild->FirstChildElement("Bookmark"); pBookmark; pBookmark = pBookmark->NextSiblingElement("Bookmark")) { TiXmlHandle handle(pBookmark); wxString old_name = GetTextElement_Trimmed(pBookmark, "Name"); if (old_name.empty()) continue; if (name == old_name) { wxMessageBox(_("Name of bookmark already exists."), _("New bookmark"), wxICON_EXCLAMATION); return false; } if (name < old_name && !pInsertBefore) pInsertBefore = pBookmark; } if (pInsertBefore) pBookmark = pChild->InsertBeforeChild(pInsertBefore, TiXmlElement("Bookmark"))->ToElement(); else pBookmark = pChild->LinkEndChild(new TiXmlElement("Bookmark"))->ToElement(); AddTextElement(pBookmark, "Name", name); if (!local_dir.empty()) AddTextElement(pBookmark, "LocalDir", local_dir); if (!remote_dir.IsEmpty()) AddTextElement(pBookmark, "RemoteDir", remote_dir.GetSafePath()); if (sync) AddTextElementRaw(pBookmark, "SyncBrowsing", "1"); wxString error; if (!file.Save(&error)) { if (COptions::Get()->GetOptionVal(OPTION_DEFAULT_KIOSKMODE) == 2) return true; wxString msg = wxString::Format(_("Could not write \"%s\", the selected sites could not be exported: %s"), file.GetFileName().GetFullPath().c_str(), error.c_str()); wxMessageBox(msg, _("Error writing xml file"), wxICON_ERROR); } return true; }
bool CSiteManager::GetBookmarks(wxString sitePath, std::list<wxString> &bookmarks) { wxChar c = sitePath[0]; if (c != '0' && c != '1') return false; sitePath = sitePath.Mid(1); // We have to synchronize access to sitemanager.xml so that multiple processed don't write // to the same file or one is reading while the other one writes. CInterProcessMutex mutex(MUTEX_SITEMANAGER); CXmlFile file; TiXmlElement* pDocument = 0; if (c == '0') pDocument = file.Load(_T("sitemanager")); else { const wxString& defaultsDir = wxGetApp().GetDefaultsDir(); if (defaultsDir == _T("")) return false; pDocument = file.Load(wxFileName(defaultsDir, _T("fzdefaults.xml"))); } if (!pDocument) { wxMessageBox(file.GetError(), _("Error loading xml file"), wxICON_ERROR); return false; } TiXmlElement* pElement = pDocument->FirstChildElement("Servers"); if (!pElement) return false; std::list<wxString> segments; if (!UnescapeSitePath(sitePath, segments)) { wxMessageBox(_("Site path is malformed."), _("Invalid site path")); return 0; } TiXmlElement* pChild = GetElementByPath(pElement, segments); if (pChild && !strcmp(pChild->Value(), "Bookmark")) pChild = pChild->Parent()->ToElement(); if (!pChild || strcmp(pChild->Value(), "Server")) return 0; // Bookmarks for (TiXmlElement* pBookmark = pChild->FirstChildElement("Bookmark"); pBookmark; pBookmark = pBookmark->NextSiblingElement("Bookmark")) { TiXmlHandle handle(pBookmark); wxString name = GetTextElement_Trimmed(pBookmark, "Name"); if (name.empty()) continue; wxString localPath; CServerPath remotePath; TiXmlText* localDir = handle.FirstChildElement("LocalDir").FirstChild().Text(); if (localDir) localPath = ConvLocal(localDir->Value()); TiXmlText* remoteDir = handle.FirstChildElement("RemoteDir").FirstChild().Text(); if (remoteDir) remotePath.SetSafePath(ConvLocal(remoteDir->Value())); if (localPath.empty() && remotePath.IsEmpty()) continue; bookmarks.push_back(name); } return true; }
CSiteManagerItemData_Site* CSiteManager::GetSiteByPath(wxString sitePath) { wxChar c = sitePath[0]; if (c != '0' && c != '1') { wxMessageBox(_("Site path has to begin with 0 or 1."), _("Invalid site path")); return 0; } sitePath = sitePath.Mid(1); // We have to synchronize access to sitemanager.xml so that multiple processed don't write // to the same file or one is reading while the other one writes. CInterProcessMutex mutex(MUTEX_SITEMANAGER); CXmlFile file; TiXmlElement* pDocument = 0; if (c == '0') pDocument = file.Load(_T("sitemanager")); else { const wxString& defaultsDir = wxGetApp().GetDefaultsDir(); if (defaultsDir == _T("")) { wxMessageBox(_("Site does not exist."), _("Invalid site path")); return 0; } wxFileName name(defaultsDir, _T("fzdefaults.xml")); pDocument = file.Load(name); } if (!pDocument) { wxMessageBox(file.GetError(), _("Error loading xml file"), wxICON_ERROR); return 0; } TiXmlElement* pElement = pDocument->FirstChildElement("Servers"); if (!pElement) { wxMessageBox(_("Site does not exist."), _("Invalid site path")); return 0; } std::list<wxString> segments; if (!UnescapeSitePath(sitePath, segments) || segments.empty()) { wxMessageBox(_("Site path is malformed."), _("Invalid site path")); return 0; } TiXmlElement* pChild = GetElementByPath(pElement, segments); if (!pChild) { wxMessageBox(_("Site does not exist."), _("Invalid site path")); return 0; } TiXmlElement* pBookmark; if (!strcmp(pChild->Value(), "Bookmark")) { pBookmark = pChild; pChild = pChild->Parent()->ToElement(); segments.pop_back(); } else pBookmark = 0; CSiteManagerItemData_Site* data = ReadServerElement(pChild); if (!data) { wxMessageBox(_("Could not read server item."), _("Invalid site path")); return 0; } if (pBookmark) { TiXmlHandle handle(pBookmark); wxString localPath; CServerPath remotePath; TiXmlText* localDir = handle.FirstChildElement("LocalDir").FirstChild().Text(); if (localDir) localPath = ConvLocal(localDir->Value()); TiXmlText* remoteDir = handle.FirstChildElement("RemoteDir").FirstChild().Text(); if (remoteDir) remotePath.SetSafePath(ConvLocal(remoteDir->Value())); if (!localPath.empty() && !remotePath.IsEmpty()) { data->m_sync = GetTextElementBool(pBookmark, "SyncBrowsing", false); } else data->m_sync = false; data->m_localDir = localPath; data->m_remoteDir = remotePath; } data->m_path = BuildPath( c, segments ); return data; }
BOOL CServerPath::ChangePath(CString &subdir, BOOL bIsFile /*=FALSE*/) { CServerPath newpath = *this; CString dir = subdir; if (!(newpath.m_nServerType&FZ_SERVERTYPE_HIGHMASK)) newpath.m_nServerType = FZ_SERVERTYPE_FTP; dir.TrimLeft(_T(" ")); dir.TrimRight(_T(" ")); if ( dir==_T("") ) { if (newpath.IsEmpty() || bIsFile) return FALSE; else { *this=newpath; return TRUE; } } switch (newpath.m_nServerType&FZ_SERVERTYPE_HIGHMASK) { case FZ_SERVERTYPE_FTP: switch(newpath.m_nServerType&FZ_SERVERTYPE_SUBMASK) { case FZ_SERVERTYPE_SUB_FTP_MVS: case FZ_SERVERTYPE_SUB_FTP_BS2000: subdir.TrimLeft(FTP_MVS_DOUBLE_QUOTA); subdir.TrimRight(FTP_MVS_DOUBLE_QUOTA); if (subdir.Left(1) == _MPT("'")) { if (subdir.Right(1) != _MPT("'")) return FALSE; if (!newpath.SetPath(subdir, bIsFile)) return FALSE; } else if (subdir.Right(1) == _MPT("'")) return FALSE; else if (!newpath.IsEmpty()) { if (m_Prefix != _T(".")) return FALSE; subdir.TrimLeft(_MPT('.')); while (subdir.Replace(_T(".."), _T("."))); int pos = subdir.Find(_MPT('.')); while (pos != -1) { newpath.m_Segments.push_back(subdir.Left(pos)); subdir = subdir.Mid(pos + 1); } if (subdir != _T("")) { newpath.m_Segments.push_back(subdir); newpath.m_Prefix = _T(""); } else newpath.m_Prefix = _T("."); if (bIsFile) { if (newpath.m_Prefix == _T(".")) return false; if (newpath.m_Segments.empty()) return false; subdir = newpath.m_Segments.back(); newpath.m_Segments.pop_back(); int pos = subdir.Find(_MPT('(')); int pos2 = subdir.Find(_MPT(')')); if (pos != -1) { if (!pos || pos2 != subdir.GetLength() - 2) return false; newpath.m_Segments.push_back(subdir.Left(pos)); subdir = subdir.Mid(pos + 1, pos2 - pos - 1); } else if (pos2 != -1) return false; else newpath.m_Prefix = _T("."); } } else if (!newpath.SetPath(subdir, bIsFile)) return FALSE; break; case FZ_SERVERTYPE_SUB_FTP_VMS: { int pos1=dir.Find( _T("[") ); if (pos1==-1) { int pos2=dir.ReverseFind(_MPT(']')); if (pos2!=-1) return FALSE; if (bIsFile) { if (newpath.IsEmpty()) return FALSE; subdir=dir; *this=newpath; return TRUE; } while ( dir.Replace( _T(".."), _T(".") ) ); } else { int pos2=dir.ReverseFind(_MPT(']')); if (pos2==-1) return FALSE; if (bIsFile && pos2==(dir.GetLength()-1)) return FALSE; if (!bIsFile && pos2!=(dir.GetLength()-1)) return FALSE; if (pos2<=pos1) return FALSE; if (bIsFile) subdir=dir.Mid(pos2+2); dir=dir.Left(pos2); if (pos1) newpath.m_Prefix=dir.Left(pos1); else newpath.m_Prefix=_MPT(""); newpath.m_Segments.clear(); dir=dir.Mid(pos1+1); pos1=dir.Find( _T("[") ); pos2=dir.Find( _T("]") ); if (pos1!=-1 || pos2!=-1) return FALSE; } int pos=dir.Find( _T(".") ); while(pos!=-1) { newpath.m_Segments.push_back(dir.Left(pos)); dir=dir.Mid(pos+1); pos=dir.Find( _T(".") ); } if (dir!=_MPT("")) newpath.m_Segments.push_back(dir); } break; case FZ_SERVERTYPE_SUB_FTP_WINDOWS: { dir.Replace( _T("\\"), _T("/") ); while(dir.Replace( _T("//"), _T("/") )); if (dir.GetLength() >= 2 && dir[1] == _MPT(':')) newpath.m_Segments.clear(); else if (dir[0]==_MPT('/')) { CString firstSegment; if (newpath.m_Segments.empty()) firstSegment = _MPT("C:"); else firstSegment = newpath.m_Segments.front(); newpath.m_Segments.clear(); newpath.m_Segments.push_back(firstSegment); dir.TrimLeft( _T("/") ); } if (newpath.IsEmpty()) return FALSE; if (dir.Right(1)==_T("/") && bIsFile) return FALSE; dir.TrimRight( _T("/") ); int pos=dir.ReverseFind(_MPT('/')); if (bIsFile) if (pos==-1) { subdir=dir; newpath.m_bEmpty=FALSE; *this=newpath; return TRUE; } else { subdir=dir.Mid(pos+1); dir=dir.Left(pos); dir.TrimRight( _T("/") ); } pos=dir.Find( _T("/") ); while(pos!=-1) { newpath.m_Segments.push_back(dir.Left(pos)); dir=dir.Mid(pos+1); pos=dir.Find( _T("/") ); } if (dir!=_MPT("")) newpath.m_Segments.push_back(dir); break; } case FZ_SERVERTYPE_SUB_FTP_UNKNOWN: dir.Replace(_MPT('.'), _MPT('/')); dir = _T("/") + dir; default: dir.Replace( _T("\\"), _T("/") ); while(dir.Replace( _T("//"), _T("/") )); if (dir[0]==_MPT('/')) { newpath.m_Segments.clear(); if (dir!="/") dir.TrimLeft( _T("/") ); } else if (newpath.IsEmpty()) return FALSE; if (dir.Right(1)==_T("/") && bIsFile) return FALSE; dir.TrimRight( _T("/") ); int pos=dir.ReverseFind(_MPT('/')); if (bIsFile) if (pos==-1) { subdir=dir; newpath.m_bEmpty=FALSE; *this=newpath; return TRUE; } else { subdir=dir.Mid(pos+1); dir=dir.Left(pos); dir.TrimRight( _T("/") ); } pos=dir.Find( _T("/") ); while(pos!=-1) { newpath.m_Segments.push_back(dir.Left(pos)); dir=dir.Mid(pos+1); pos=dir.Find( _T("/") ); } if (dir!=_MPT("")) newpath.m_Segments.push_back(dir); break; } break; case FZ_SERVERTYPE_LOCAL: { if (dir.Right(1)==_T("\\") && bIsFile) return FALSE; dir.TrimRight( _T("\\") ); while (dir.Replace( _T("\\\\"), _T("\\") )); if ( dir.Left(1) == _T("\\") ) newpath.m_Segments.clear(); else if (newpath.IsEmpty()) return FALSE; dir.TrimLeft( _T("\\") ); if (bIsFile) { int pos=dir.ReverseFind(_MPT('\\')); if (pos==-1) { if (dir.Find( _T(":") )!=-1) return FALSE; subdir=dir; newpath.m_bEmpty=FALSE; *this=newpath; return TRUE; } else { if (dir.Find( _T(":"), pos+1)!=-1) return FALSE; subdir=dir.Mid(pos+1); dir=dir.Left(pos); } } int pos=dir.Find( _T(":") ); if (pos==1) //dir is absolute path { newpath.m_Segments.clear(); newpath.m_Prefix=dir.Left(pos+1); dir=dir.Mid(pos+1); dir.TrimLeft( _T("\\") ); if (dir.Find( _T(":") )!=-1) return FALSE; } if (pos==-1 || pos==1) { pos=dir.Find( _T("\\") ); while (pos!=-1) { newpath.m_Segments.push_back(dir.Left(pos)); dir=dir.Mid(pos+1); pos=dir.Find( _T("\\") ); } if (dir!=_MPT("")) newpath.m_Segments.push_back(dir); } else return FALSE; } break; default: return FALSE; } newpath.m_bEmpty=FALSE; *this=newpath; return TRUE; }
void CLocalListView::OnItemActivated(wxListEvent &event) { int count = 0; bool back = false; int item = -1; while (true) { item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (item == -1) break; count++; if (!item && m_hasParent) back = true; } if (count > 1) { if (back) { wxBell(); return; } wxCommandEvent cmdEvent; OnMenuUpload(cmdEvent); return; } item = event.GetIndex(); t_fileData *data = GetData(item); if (!data) return; if (data->dir) { wxString error; if (!m_pState->SetLocalDir(data->name, &error)) { if (error != _T("")) wxMessageBox(error, _("Failed to change directory"), wxICON_INFORMATION); else wxBell(); } return; } const CServer* pServer = m_pState->GetServer(); if (!pServer) { wxBell(); return; } CServerPath path = m_pState->GetRemotePath(); if (path.IsEmpty()) { wxBell(); return; } wxFileName fn(m_dir, data->name); m_pQueue->QueueFile(false, false, fn.GetFullPath(), data->name, path, *pServer, data->size); }
int CFileZillaApi::List(const CServerPath& parent, CString dirname, int nListMode /*=FZ_LIST_USECACHE*/) { //Check if call allowed if (!m_bInitialized) return FZ_REPLY_NOTINITIALIZED; if (IsConnected()==FZ_REPLY_NOTCONNECTED) return FZ_REPLY_NOTCONNECTED; #ifndef MPEXT_NO_CACHE if ( (nListMode&(FZ_LIST_FORCECACHE|FZ_LIST_REALCHANGE))==(FZ_LIST_FORCECACHE|FZ_LIST_REALCHANGE) ) return FZ_REPLY_INVALIDPARAM; if (nListMode&FZ_LIST_FORCECACHE) nListMode|=FZ_LIST_USECACHE; #endif if (dirname==_MPT("") || parent.IsEmpty()) return FZ_REPLY_INVALIDPARAM; #ifndef MPEXT_NO_CACHE //Check if current dir is cached if (nListMode&FZ_LIST_USECACHE && !(nListMode&FZ_LIST_REALCHANGE)) { t_server server; BOOL res=m_pMainThread->GetCurrentServer(server); if (res) { t_directory *directory=new t_directory; CDirectoryCache cache; res=cache.Lookup(parent,dirname,server,*directory); if (res) { BOOL bExact=TRUE; if (nListMode & FZ_LIST_EXACT) for (int i=0;i<directory->num;i++) if (directory->direntry[i].bUnsure || (directory->direntry[i].size==-1 && !directory->direntry[i].dir)) { bExact=FALSE; break; } if (bExact) { m_pMainThread->SetWorkingDir(directory); delete directory; return FZ_REPLY_OK; } } delete directory; } } #endif if (m_pMainThread->IsBusy()) return FZ_REPLY_BUSY; #ifndef MPEXT_NO_CACHE if (nListMode&FZ_LIST_FORCECACHE) return FZ_REPLY_ERROR; #endif t_command command; command.id=FZ_COMMAND_LIST; command.path=parent; command.param1=dirname; command.param4=nListMode; m_pMainThread->Command(command); if (m_hOwnerWnd) return FZ_REPLY_WOULDBLOCK; else return m_pMainThread->LastOperationSuccessful()?FZ_REPLY_OK:FZ_REPLY_ERROR; }
void CLocalListView::OnItemActivated(wxListEvent &event) { int count = 0; bool back = false; int item = -1; for (;;) { item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (item == -1) break; count++; if (!item && m_hasParent) back = true; } if (count > 1) { if (back) { wxBell(); return; } wxCommandEvent cmdEvent; OnMenuUpload(cmdEvent); return; } item = event.GetIndex(); CLocalFileData *data = GetData(item); if (!data) return; if (data->dir) { const int action = COptions::Get()->GetOptionVal(OPTION_DOUBLECLICK_ACTION_DIRECTORY); if (action == 3) { // No action wxBell(); return; } if (!action || data->name == _T("..")) { // Enter action wxString error; if (!m_pState->SetLocalDir(data->name, &error)) { if (error != _T("")) wxMessageBoxEx(error, _("Failed to change directory"), wxICON_INFORMATION); else wxBell(); } return; } wxCommandEvent evt(0, action == 1 ? XRCID("ID_UPLOAD") : XRCID("ID_ADDTOQUEUE")); OnMenuUpload(evt); return; } if (data->flags == fill) { wxBell(); return; } const int action = COptions::Get()->GetOptionVal(OPTION_DOUBLECLICK_ACTION_FILE); if (action == 3) { // No action wxBell(); return; } if (action == 2) { // View / Edit action wxCommandEvent evt; OnMenuEdit(evt); return; } const CServer* pServer = m_pState->GetServer(); if (!pServer) { wxBell(); return; } CServerPath path = m_pState->GetRemotePath(); if (path.IsEmpty()) { wxBell(); return; } const bool queue_only = action == 1; m_pQueue->QueueFile(queue_only, false, data->name, wxEmptyString, CLocalPath(m_dir), path, *pServer, data->size); m_pQueue->QueueFile_Finish(true); }
void CLocalListView::OnMenuEdit(wxCommandEvent& event) { CServer server; CServerPath path; if (!m_pState->GetServer()) { if (COptions::Get()->GetOptionVal(OPTION_EDIT_TRACK_LOCAL)) { wxMessageBoxEx(_("Cannot edit file, not connected to any server."), _("Editing failed"), wxICON_EXCLAMATION); return; } } else { server = *m_pState->GetServer(); path = m_pState->GetRemotePath(); if (path.IsEmpty()) { wxMessageBoxEx(_("Cannot edit file, remote path unknown."), _("Editing failed"), wxICON_EXCLAMATION); return; } } std::list<CLocalFileData> selected_item_list; long item = -1; while ((item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != -1) { if (!item && m_hasParent) { wxBell(); return; } const CLocalFileData *data = GetData(item); if (!data) continue; if (data->dir) { wxBell(); return; } if (data->flags == fill) continue; selected_item_list.push_back(*data); } CEditHandler* pEditHandler = CEditHandler::Get(); if (selected_item_list.empty()) { wxBell(); return; } if (selected_item_list.size() > 10) { CConditionalDialog dlg(this, CConditionalDialog::many_selected_for_edit, CConditionalDialog::yesno); dlg.SetTitle(_("Confirmation needed")); dlg.AddText(_("You have selected more than 10 files for editing, do you really want to continue?")); if (!dlg.Run()) return; } for (std::list<CLocalFileData>::const_iterator data = selected_item_list.begin(); data != selected_item_list.end(); ++data) { wxFileName fn(m_dir, data->name); bool dangerous = false; bool program_exists = false; wxString cmd = pEditHandler->CanOpen(CEditHandler::local, fn.GetFullPath(), dangerous, program_exists); if (cmd.empty()) { CNewAssociationDialog dlg(this); if (!dlg.Show(fn.GetFullName())) continue; cmd = pEditHandler->CanOpen(CEditHandler::local, fn.GetFullPath(), dangerous, program_exists); if (cmd.empty()) { wxMessageBoxEx(wxString::Format(_("The file '%s' could not be opened:\nNo program has been associated on your system with this file type."), fn.GetFullPath().c_str()), _("Opening failed"), wxICON_EXCLAMATION); continue; } } if (!program_exists) { wxString msg = wxString::Format(_("The file '%s' cannot be opened:\nThe associated program (%s) could not be found.\nPlease check your filetype associations."), fn.GetFullPath().c_str(), cmd.c_str()); wxMessageBoxEx(msg, _("Cannot edit file"), wxICON_EXCLAMATION); continue; } if (dangerous) { int res = wxMessageBoxEx(_("The selected file would be executed directly.\nThis can be dangerous and damage your system.\nDo you really want to continue?"), _("Dangerous filetype"), wxICON_EXCLAMATION | wxYES_NO); if (res != wxYES) { wxBell(); continue; } } CEditHandler::fileState state = pEditHandler->GetFileState(fn.GetFullPath()); switch (state) { case CEditHandler::upload: case CEditHandler::upload_and_remove: wxMessageBoxEx(_("A file with that name is already being transferred."), _("Cannot view/edit selected file"), wxICON_EXCLAMATION); continue; case CEditHandler::edit: { int res = wxMessageBoxEx(wxString::Format(_("A file with that name is already being edited. Do you want to reopen '%s'?"), fn.GetFullPath().c_str()), _("Selected file already being edited"), wxICON_QUESTION | wxYES_NO); if (res != wxYES) { wxBell(); continue; } pEditHandler->StartEditing(fn.GetFullPath()); continue; } default: break; } wxString file = fn.GetFullPath(); if (!pEditHandler->AddFile(CEditHandler::local, file, path, server)) { wxMessageBoxEx(wxString::Format(_("The file '%s' could not be opened:\nThe associated command failed"), fn.GetFullPath().c_str()), _("Opening failed"), wxICON_EXCLAMATION); continue; } } }
void CSearchDialog::ProcessSelection(std::list<int> &selected_files, std::list<CServerPath> &selected_dirs) { int sel = -1; while ((sel = m_results->GetNextItem(sel, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) != -1) { if (sel > (int)m_results->m_indexMapping.size()) continue; int index = m_results->m_indexMapping[sel]; if (m_results->m_fileData[index].entry.is_dir()) { CServerPath path = m_results->m_fileData[index].path; path.ChangePath(m_results->m_fileData[index].entry.name); if (path.IsEmpty()) continue; bool replaced = false; std::list<CServerPath>::iterator iter = selected_dirs.begin(); std::list<CServerPath>::iterator prev; // Make sure that selected_dirs does not contain // any directories that are in a parent-child relationship // Resolve by only keeping topmost parents while (iter != selected_dirs.end()) { if (*iter == path) { replaced = true; break; } if (iter->IsParentOf(path, false)) { replaced = true; break; } if (iter->IsSubdirOf(path, false)) { if (!replaced) { *iter = path; replaced = true; } else { prev = iter++; selected_dirs.erase(prev); continue; } } ++iter; } if (!replaced) selected_dirs.push_back(path); } else selected_files.push_back(index); } // Now in a second phase filter out all files that are also in a directory std::list<int> selected_files_new; for (std::list<int>::const_iterator iter = selected_files.begin(); iter != selected_files.end(); ++iter) { CServerPath path = m_results->m_fileData[*iter].path; std::list<CServerPath>::const_iterator path_iter; for (path_iter = selected_dirs.begin(); path_iter != selected_dirs.end(); ++path_iter) { if (*path_iter == path || path_iter->IsParentOf(path, false)) break; } if (path_iter == selected_dirs.end()) selected_files_new.push_back(*iter); } selected_files.swap(selected_files_new); // At this point selected_dirs contains uncomparable // paths and selected_files contains only files not // covered by any of those directories. }
virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def) { if (def == wxDragError || def == wxDragNone || def == wxDragCancel) return def; wxTreeItemId hit = GetHit(wxPoint(x, y)); if (!hit) return wxDragNone; CServerPath path = m_pRemoteTreeView->GetPathFromItem(hit); if (path.IsEmpty()) return wxDragNone; if (!GetData()) return wxDragError; CDragDropManager* pDragDropManager = CDragDropManager::Get(); if (pDragDropManager) pDragDropManager->pDropTarget = m_pRemoteTreeView; if (m_pDataObject->GetReceivedFormat() == m_pFileDataObject->GetFormat()) m_pRemoteTreeView->m_pState->UploadDroppedFiles(m_pFileDataObject, path, false); else { if (m_pRemoteDataObject->GetProcessId() != (int)wxGetProcessId()) { wxMessageBox(_("Drag&drop between different instances of FileZilla has not been implemented yet.")); return wxDragNone; } if (!m_pRemoteTreeView->m_pState->GetServer() || !m_pRemoteDataObject->GetServer().EqualsNoPass(*m_pRemoteTreeView->m_pState->GetServer())) { wxMessageBox(_("Drag&drop between different servers has not been implemented yet.")); return wxDragNone; } // Make sure path path is valid if (path == m_pRemoteDataObject->GetServerPath()) { wxMessageBox(_("Source and path of the drop operation are identical")); return wxDragNone; } const std::list<CRemoteDataObject::t_fileInfo>& files = m_pRemoteDataObject->GetFiles(); for (std::list<CRemoteDataObject::t_fileInfo>::const_iterator iter = files.begin(); iter != files.end(); iter++) { const CRemoteDataObject::t_fileInfo& info = *iter; if (info.dir) { CServerPath dir = m_pRemoteDataObject->GetServerPath(); dir.AddSegment(info.name); if (dir == path || dir.IsParentOf(path, false)) { wxMessageBox(_("A directory cannot be dragged into one of its subdirectories.")); return wxDragNone; } } } for (std::list<CRemoteDataObject::t_fileInfo>::const_iterator iter = files.begin(); iter != files.end(); iter++) { const CRemoteDataObject::t_fileInfo& info = *iter; m_pRemoteTreeView->m_pState->m_pCommandQueue->ProcessCommand( new CRenameCommand(m_pRemoteDataObject->GetServerPath(), info.name, path, info.name) ); } return wxDragNone; } return def; }
void CRemoteTreeView::ApplyFilters() { std::list<struct _parents> parents; const wxTreeItemId root = GetRootItem(); wxTreeItemIdValue cookie; for (wxTreeItemId child = GetFirstChild(root, cookie); child; child = GetNextSibling(child)) { CServerPath path = GetPathFromItem(child); if (path.IsEmpty()) continue; struct _parents dir; dir.item = child; dir.path = path; parents.push_back(dir); } CFilterManager filter; while (!parents.empty()) { struct _parents parent = parents.back(); parents.pop_back(); CDirectoryListing listing; if (m_pState->m_pEngine->CacheLookup(parent.path, listing) == FZ_REPLY_OK) RefreshItem(parent.item, listing, false); else if (filter.HasActiveFilters()) { for (wxTreeItemId child = GetFirstChild(parent.item, cookie); child; child = GetNextSibling(child)) { CServerPath path = GetPathFromItem(child); if (path.IsEmpty()) continue; if (filter.FilenameFiltered(GetItemText(child), path.GetPath(), true, -1, false, 0, 0)) { wxTreeItemId sel = GetSelection(); while (sel && sel != child) sel = GetItemParent(sel); if (!sel) { Delete(child); continue; } } struct _parents dir; dir.item = child; dir.path = path; parents.push_back(dir); } // The stuff below has already been done above in this one case continue; } for (wxTreeItemId child = GetFirstChild(parent.item, cookie); child; child = GetNextSibling(child)) { CServerPath path = GetPathFromItem(child); if (path.IsEmpty()) continue; struct _parents dir; dir.item = child; dir.path = path; parents.push_back(dir); } } }
void CRemoteTreeView::OnEndLabelEdit(wxTreeEvent& event) { if (event.IsEditCancelled()) { event.Veto(); return; } if (!m_pState->IsRemoteIdle()) { event.Veto(); return; } CItemData* const pData = (CItemData*)GetItemData(event.GetItem()); if (pData) { event.Veto(); return; } CServerPath old_path = GetPathFromItem(event.GetItem()); CServerPath parent = old_path.GetParent(); const wxString& oldName = GetItemText(event.GetItem()); const wxString& newName = event.GetLabel(); if (oldName == newName) { event.Veto(); return; } m_pState->m_pCommandQueue->ProcessCommand(new CRenameCommand(parent, oldName, parent, newName)); m_pState->ChangeRemoteDir(parent); CServerPath currentPath; const wxTreeItemId selected = GetSelection(); if (selected) currentPath = GetPathFromItem(selected); if (currentPath.IsEmpty()) return; if (currentPath == old_path || currentPath.IsSubdirOf(old_path, false)) { // Previously selected path was below renamed one, list the new one std::list<wxString> subdirs; while (currentPath != old_path) { if (!currentPath.HasParent()) { // Abort just in case return; } subdirs.push_front(currentPath.GetLastSegment()); currentPath = currentPath.GetParent(); } currentPath = parent; currentPath.AddSegment(newName); for (std::list<wxString>::const_iterator iter = subdirs.begin(); iter != subdirs.end(); iter++) currentPath.AddSegment(*iter); m_pState->ChangeRemoteDir(currentPath); } else if (currentPath != parent) m_pState->ChangeRemoteDir(currentPath); }