void CRemoteTreeView::OnMenuDelete(wxCommandEvent&) { if (!m_pState->IsRemoteIdle()) return; if (!m_contextMenuItem) return; const CServerPath& path = GetPathFromItem(m_contextMenuItem); if (path.empty()) return; if (wxMessageBoxEx(_("Really delete all selected files and/or directories from the server?"), _("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.empty() && (path == currentPath || path.IsParentOf(currentPath, false))) currentPath = startDir; CFilterManager filter; pRecursiveOperation->StartRecursiveOperation(CRecursiveOperation::recursive_delete, startDir, filter.GetActiveFilters(false), !hasParent, currentPath); }
bool CServerPath::operator==(const CServerPath &op) const { if (empty() != op.empty()) return false; else if (m_type != op.m_type) return false; else if (m_data != op.m_data) return false; return true; }
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; }
int CHttpControlSocket::FileTransfer(const wxString localFile, const CServerPath &remotePath, const wxString &remoteFile, bool download, const CFileTransferCommand::t_transferSettings& transferSettings) { LogMessage(Debug_Verbose, _T("CHttpControlSocket::FileTransfer()")); LogMessage(Status, _("Downloading %s"), remotePath.FormatFilename(remoteFile).c_str()); if (!download) { ResetOperation(FZ_REPLY_CRITICALERROR | FZ_REPLY_NOTSUPPORTED); return FZ_REPLY_ERROR; } if (m_pCurOpData) { LogMessage(__TFILE__, __LINE__, this, Debug_Info, _T("deleting nonzero pData")); delete m_pCurOpData; } CHttpFileTransferOpData *pData = new CHttpFileTransferOpData(download, localFile, remoteFile, remotePath); m_pCurOpData = pData; m_pHttpOpData = pData; if (localFile != _T("")) { pData->opState = filetransfer_waitfileexists; int res = CheckOverwriteFile(); if (res != FZ_REPLY_OK) return res; pData->opState = filetransfer_transfer; pData->pFile = new wxFile(); CreateLocalDir(pData->localFile); if (!pData->pFile->Open(pData->localFile, wxFile::write)) { LogMessage(::Error, _("Failed to open \"%s\" for writing"), pData->localFile.c_str()); ResetOperation(FZ_REPLY_ERROR); return FZ_REPLY_ERROR; } } else pData->opState = filetransfer_transfer; int res = InternalConnect(m_pCurrentServer->GetHost(), m_pCurrentServer->GetPort(), m_pCurrentServer->GetProtocol() == HTTPS); if (res != FZ_REPLY_OK) return res; return FileTransferSend(); }
void CRemoteViewHeader::OnSelectionChanged(wxCommandEvent& event) { const wxString& dir = event.GetString(); if (dir == _T("")) return; CServerPath path = m_path; if (!path.SetPath(dir)) { wxBell(); return; } if (!m_pState->m_pCommandQueue->Idle()) { wxBell(); return; } m_pState->ChangeRemoteDir(path); }
void CPathCache::InvalidatePath(tServerCache & serverCache, CServerPath const& path, wxString const& subdir) { CSourcePath sourcePath; sourcePath.source = path; sourcePath.subdir = subdir; CServerPath target; tServerCacheIterator serverIter = serverCache.find(sourcePath); if (serverIter != serverCache.end()) { target = serverIter->second; serverCache.erase(serverIter); } if (target.empty() && !subdir.empty()) { target = path; if (!target.AddSegment(subdir)) return; } if (!target.empty()) { // Unfortunately O(n), don't know of a faster way. for (auto serverIter = serverCache.begin(); serverIter != serverCache.end(); ) { if (serverIter->second == target || target.IsParentOf(serverIter->second, false)) serverCache.erase(serverIter++); else if (serverIter->first.source == target || target.IsParentOf(serverIter->first.source, false)) serverCache.erase(serverIter++); else ++serverIter; } } }
void CPathCache::Store(CServer const& server, CServerPath const& target, CServerPath const& source, wxString const& subdir) { scoped_lock lock(mutex_); wxASSERT(!target.empty() && !source.empty()); tCacheIterator iter = m_cache.find(server); if (iter == m_cache.cend()) #if HAVE_MAP_EMPLACE iter = m_cache.emplace(std::make_pair(server, tServerCache())).first; #else iter = m_cache.insert(std::make_pair(server, tServerCache())).first; #endif tServerCache &serverCache = iter->second; CSourcePath sourcePath; sourcePath.source = source; sourcePath.subdir = subdir; serverCache[sourcePath] = target; }
void CQueueStorage::Impl::ReadRemotePaths() { if (!selectRemotePathQuery_) return; int res; do { res = sqlite3_step(selectRemotePathQuery_); if (res == SQLITE_ROW) { int64_t id = GetColumnInt64(selectRemotePathQuery_, path_table_column_names::id); wxString remotePathRaw = GetColumnText(selectRemotePathQuery_, path_table_column_names::path); CServerPath remotePath; if (id > 0 && !remotePathRaw.empty() && remotePath.SetSafePath(remotePathRaw)) reverseRemotePaths_[id] = remotePath; } } while (res == SQLITE_BUSY || res == SQLITE_ROW); sqlite3_reset(selectRemotePathQuery_); }
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; }
bool CServerPath::IsSubdirOf(const CServerPath &path, bool cmpNoCase) const { if (empty() || path.empty()) return false; if (m_type != path.m_type) return false; if (!HasParent()) return false; if (traits[m_type].prefixmode != 1) { if (cmpNoCase ) { if( m_data->m_prefix && !path.m_data->m_prefix ) { return false; } else if( !m_data->m_prefix && path.m_data->m_prefix ) { return false; } else if( m_data->m_prefix && path.m_data->m_prefix && m_data->m_prefix->CmpNoCase(*path.m_data->m_prefix) ) { return false; } } if (!cmpNoCase && m_data->m_prefix != path.m_data->m_prefix) return false; } // On MVS, dirs like 'FOO.BAR' without trailing dot cannot have // subdirectories if (traits[m_type].prefixmode == 1 && !path.m_data->m_prefix) return false; tConstSegmentIter iter1 = m_data->m_segments.begin(); tConstSegmentIter iter2 = path.m_data->m_segments.begin(); while (iter1 != m_data->m_segments.end()) { if (iter2 == path.m_data->m_segments.end()) return true; if (cmpNoCase) { if (iter1->CmpNoCase(*iter2)) return false; } else if (*iter1 != *iter2) return false; ++iter1; ++iter2; } return false; }
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; }
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].has_date() ? &listing[i].time : 0)) 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 CServerPath::operator<(const CServerPath &op) const { if (empty()) { if (!op.empty()) return false; } else if (op.empty()) return true; if( m_data->m_prefix || op.m_data->m_prefix ) { if( m_data->m_prefix < op.m_data->m_prefix ) { return true; } else if( op.m_data->m_prefix < m_data->m_prefix ) { return false; } } if (m_type > op.m_type) return false; else if (m_type < op.m_type) return true; tConstSegmentIter iter1, iter2; for (iter1 = m_data->m_segments.begin(), iter2 = op.m_data->m_segments.begin(); iter1 != m_data->m_segments.end(); ++iter1, ++iter2) { if (iter2 == op.m_data->m_segments.end()) return false; const int cmp = iter1->Cmp(*iter2); if (cmp < 0) return true; if (cmp > 0) return false; } return iter2 != op.m_data->m_segments.end(); }
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; }
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.empty()); if (path.empty()) return; m_pState->ChangeRemoteDir(path); }
CFolderScanItem::CFolderScanItem(CServerItem* parent, bool queued, bool download, const wxString& localPath, const CServerPath& remotePath) { m_parent = parent; m_download = download; m_localPath = localPath; m_remotePath = remotePath; m_queued = queued; m_remove = false; m_active = false; m_count = 0; t_dirPair pair; pair.localPath = localPath.c_str(); pair.remotePath.SetSafePath(remotePath.GetSafePath().c_str()); m_dirsToCheck.push_back(pair); m_defaultFileExistsAction = CFileExistsNotification::unknown; }
bool CBookmarksDialog::GetBookmark(const wxString &name, wxString &local_dir, CServerPath &remote_dir, bool &sync) { CInterProcessMutex mutex(MUTEX_GLOBALBOOKMARKS); CXmlFile file(wxGetApp().GetSettingsFile(_T("bookmarks"))); TiXmlElement* pDocument = file.Load(); if (!pDocument) { wxMessageBoxEx(file.GetError(), _("Error loading xml file"), wxICON_ERROR); return false; } for (TiXmlElement *pBookmark = pDocument->FirstChildElement("Bookmark"); pBookmark; pBookmark = pBookmark->NextSiblingElement("Bookmark")) { wxString remote_dir_raw; if (name != GetTextElement(pBookmark, "Name")) continue; local_dir = GetTextElement(pBookmark, "LocalDir"); remote_dir_raw = GetTextElement(pBookmark, "RemoteDir"); if (!remote_dir_raw.empty()) { if (!remote_dir.SetSafePath(remote_dir_raw)) return false; } if (local_dir.empty() && remote_dir_raw.empty()) return false; if (local_dir.empty() || remote_dir_raw.empty()) sync = false; else sync = GetTextElementBool(pBookmark, "SyncBrowsing", false); return true; } return false; }
bool CState::Connect(const CServer& server, bool askBreak, const CServerPath& path /*=CServerPath()*/) { if (!m_pEngine) return false; if (m_pEngine->IsConnected() || m_pEngine->IsBusy() || !m_pCommandQueue->Idle()) { if (askBreak) if (wxMessageBox(_("Break current connection?"), _T("FileZilla"), wxYES_NO | wxICON_QUESTION) != wxYES) return false; m_pCommandQueue->Cancel(); } m_pCommandQueue->ProcessCommand(new CConnectCommand(server)); m_pCommandQueue->ProcessCommand(new CListCommand(path)); COptions::Get()->SetLastServer(server); COptions::Get()->SetOption(OPTION_LASTSERVERPATH, path.GetSafePath()); m_pMainFrame->SetTitle(server.FormatServer() + _T(" - FileZilla")); return true; }
int CServerPath::CmpNoCase(const CServerPath &op) const { if (empty() != op.empty()) return 1; else if (m_data->m_prefix != op.m_data->m_prefix) return 1; else if (m_type != op.m_type) return 1; if (m_data->m_segments.size() > op.m_data->m_segments.size()) return 1; else if (m_data->m_segments.size() < op.m_data->m_segments.size()) return -1; tConstSegmentIter iter = m_data->m_segments.begin(); tConstSegmentIter iter2 = op.m_data->m_segments.begin(); while (iter != m_data->m_segments.end()) { int res = iter++->CmpNoCase(*iter2++); if (res) return res; } return 0; }
void CRemoteRecursiveOperation::StartRecursiveOperation(OperationMode mode, ActiveFilters const& filters, CServerPath const& finalDir, bool immediate) { wxCHECK_RET(m_operationMode == recursive_none, _T("StartRecursiveOperation called with m_operationMode != recursive_none")); wxCHECK_RET(m_state.IsRemoteConnected(), _T("StartRecursiveOperation while disconnected")); wxCHECK_RET(!finalDir.empty(), _T("Empty final dir in recursive operation")); if (mode == recursive_chmod && !m_pChmodDlg) { return; } if ((mode == recursive_transfer || mode == recursive_transfer_flatten) && !m_pQueue) { return; } if (recursion_roots_.empty()) { // Nothing to do in this case return; } m_processedFiles = 0; m_processedDirectories = 0; m_immediate = immediate; m_operationMode = mode; if ((mode == CRecursiveOperation::recursive_transfer || mode == CRecursiveOperation::recursive_transfer_flatten) && immediate) { m_actionAfterBlocker = m_pQueue->GetActionAfterBlocker(); } m_state.NotifyHandlers(STATECHANGE_REMOTE_IDLE); m_state.NotifyHandlers(STATECHANGE_REMOTE_RECURSION_STATUS); m_filters = filters; NextOperation(); }
int64_t CQueueStorage::Impl::SaveRemotePath(const CServerPath& path) { wxString const& safePath = path.GetSafePath(); std::unordered_map<wxString, int64_t, wxStringHash>::const_iterator it = remotePaths_.find(safePath); if (it != remotePaths_.end()) return it->second; Bind(insertRemotePathQuery_, path_table_column_names::path, safePath); int res; do { res = sqlite3_step(insertRemotePathQuery_); } while (res == SQLITE_BUSY); sqlite3_reset(insertRemotePathQuery_); if (res == SQLITE_DONE) { int64_t id = sqlite3_last_insert_rowid(db_); remotePaths_[safePath] = id; return id; } return -1; }
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; } } }
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; }
CServerPath CServerPath::GetCommonParent(const CServerPath& path) const { if (*this == path) { return *this; } if (empty() || path.empty()) { return CServerPath(); } if (m_type != path.m_type || (!traits[m_type].prefixmode && m_data->m_prefix != path.m_data->m_prefix)) { return CServerPath(); } if (!HasParent()) { if (path.IsSubdirOf(*this, false)) { return *this; } else { return CServerPath(); } } else if (!path.HasParent()) { if (IsSubdirOf(path, false)) { return path; } else { return CServerPath(); } } CServerPath parent; parent.m_type = m_type; CServerPathData& parentData = parent.m_data.get(); tConstSegmentIter last = m_data->m_segments.end(); tConstSegmentIter last2 = path.m_data->m_segments.end(); if (traits[m_type].prefixmode == 1) { if (!m_data->m_prefix) { --last; } if (!path.m_data->m_prefix) { --last2; } parentData.m_prefix = GetParent().m_data->m_prefix; } else parentData.m_prefix = m_data->m_prefix; tConstSegmentIter iter = m_data->m_segments.begin(); tConstSegmentIter iter2 = path.m_data->m_segments.begin(); while (iter != last && iter2 != last2) { if (*iter != *iter2) { if (!traits[m_type].has_root && parentData.m_segments.empty()) { return CServerPath(); } else { return parent; } } parentData.m_segments.push_back(*iter); ++iter; ++iter2; } return parent; }
bool CServerPath::IsParentOf(const CServerPath &path, bool cmpNoCase) const { return path.IsSubdirOf(*this, cmpNoCase); }
recursion_root::recursion_root(CServerPath const& start_dir, bool allow_parent) : m_remoteStartDir(start_dir) , m_allowParent(allow_parent) { wxASSERT_MSG(!start_dir.empty(), _T("Empty startDir in recursion_root constructor")); }
void CRemoteTreeView::OnBeginDrag(wxTreeEvent& event) { // Drag could result in recursive operation, don't allow at this point if (!m_pState->IsRemoteIdle()) { wxBell(); return; } const wxTreeItemId& item = event.GetItem(); if (!item) return; CServerPath path = GetPathFromItem(item); if (path.empty() || !path.HasParent()) return; const CServerPath& parent = path.GetParent(); const wxString& lastSegment = path.GetLastSegment(); if (lastSegment.empty()) return; wxDataObjectComposite object; CServer const* pServer = m_pState->GetServer(); if (!pServer) return; CServer const server = *pServer; CRemoteDataObject *pRemoteDataObject = new CRemoteDataObject(*pServer, parent); pRemoteDataObject->AddFile(lastSegment, true, -1, false); pRemoteDataObject->Finalize(); object.Add(pRemoteDataObject, true); #if FZ3_USESHELLEXT std::unique_ptr<CShellExtensionInterface> ext = CShellExtensionInterface::CreateInitialized(); if (ext) { const wxString& file = ext->GetDragDirectory(); wxASSERT(!file.empty()); wxFileDataObject *pFileDataObject = new wxFileDataObject; pFileDataObject->AddFile(file); object.Add(pFileDataObject); } #endif CDragDropManager* pDragDropManager = CDragDropManager::Init(); pDragDropManager->pDragSource = this; pDragDropManager->server = *pServer; pDragDropManager->remoteParent = parent; wxDropSource source(this); source.SetData(object); int res = source.DoDragDrop(); pDragDropManager->Release(); if (res != wxDragCopy) { return; } #if FZ3_USESHELLEXT if (ext) { if (!pRemoteDataObject->DidSendData()) { pServer = m_pState->GetServer(); if (!pServer || !m_pState->IsRemoteIdle() || *pServer != server) { wxBell(); return; } CLocalPath target(ext->GetTarget()); if (target.empty()) { ext.reset(); // Release extension before the modal message box wxMessageBoxEx(_("Could not determine the target of the Drag&Drop operation.\nEither the shell extension is not installed properly or you didn't drop the files into an Explorer window.")); return; } m_pState->DownloadDroppedFiles(pRemoteDataObject, target); } } #endif }
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; }
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; }
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.empty()) 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()) { wxMessageBoxEx(_("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())) { wxMessageBoxEx(_("Drag&drop between different servers has not been implemented yet.")); return wxDragNone; } // Make sure path path is valid if (path == m_pRemoteDataObject->GetServerPath()) { wxMessageBoxEx(_("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) return wxDragNone; else if (dir.IsParentOf(path, false)) { wxMessageBoxEx(_("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; }