#include "FileZilla.h" #include "LocalTreeView.h" #include "LocalListView.h" #include "RemoteTreeView.h" #include "RemoteListView.h" #include "StatusView.h" #include "queue.h" #include "Mainfrm.h" #include "state.h" #include "Options.h" #include "commandqueue.h" #include "asyncrequestqueue.h" #include "led.h" #include "sitemanager.h" #include "settingsdialog.h" #include "themeprovider.h" #include "filezillaapp.h" #include "view.h" #include "viewheader.h" #include "aboutdialog.h" #include "filter.h" #include "netconfwizard.h" #include "quickconnectbar.h" #include "updatewizard.h" #include "defaultfileexistsdlg.h" #include "loginmanager.h" #include "conditionaldialog.h" #include "clearprivatedata.h" #include "export.h" #include "import.h" #include "recursive_operation.h" #include #if wxUSE_DISPLAY #include #endif #ifdef _DEBUG #define new DEBUG_NEW #endif #define TRANSFERSTATUS_TIMER_ID wxID_HIGHEST + 3 static const int statbarWidths[6] = { #ifdef __WXMSW__ -2, 90, -1, 150, -1, 41 #else -2, 90, -1, 150, -1, 50 #endif }; #ifdef __WXMSW__ DECLARE_EVENT_TYPE(fzEVT_ONSIZE_POST, -1) DEFINE_EVENT_TYPE(fzEVT_ONSIZE_POST) #endif BEGIN_EVENT_TABLE(CMainFrame, wxFrame) EVT_SIZE(CMainFrame::OnSize) #ifdef __WXMSW__ EVT_COMMAND(wxID_ANY, fzEVT_ONSIZE_POST, CMainFrame::OnSizePost) #endif EVT_SPLITTER_SASH_POS_CHANGED(wxID_ANY, CMainFrame::OnViewSplitterPosChanged) EVT_MENU(wxID_ANY, CMainFrame::OnMenuHandler) EVT_FZ_NOTIFICATION(wxID_ANY, CMainFrame::OnEngineEvent) EVT_UPDATE_UI(XRCID("ID_TOOLBAR_DISCONNECT"), CMainFrame::OnUpdateToolbarDisconnect) EVT_TOOL(XRCID("ID_TOOLBAR_DISCONNECT"), CMainFrame::OnDisconnect) EVT_UPDATE_UI(XRCID("ID_MENU_SERVER_DISCONNECT"), CMainFrame::OnUpdateToolbarDisconnect) EVT_MENU(XRCID("ID_MENU_SERVER_DISCONNECT"), CMainFrame::OnDisconnect) EVT_UPDATE_UI(XRCID("ID_TOOLBAR_CANCEL"), CMainFrame::OnUpdateToolbarCancel) EVT_TOOL(XRCID("ID_TOOLBAR_CANCEL"), CMainFrame::OnCancel) EVT_SPLITTER_SASH_POS_CHANGING(wxID_ANY, CMainFrame::OnSplitterSashPosChanging) EVT_SPLITTER_SASH_POS_CHANGED(wxID_ANY, CMainFrame::OnSplitterSashPosChanged) EVT_UPDATE_UI(XRCID("ID_TOOLBAR_RECONNECT"), CMainFrame::OnUpdateToolbarReconnect) EVT_TOOL(XRCID("ID_TOOLBAR_RECONNECT"), CMainFrame::OnReconnect) EVT_UPDATE_UI(XRCID("ID_MENU_SERVER_RECONNECT"), CMainFrame::OnUpdateToolbarReconnect) EVT_TOOL(XRCID("ID_MENU_SERVER_RECONNECT"), CMainFrame::OnReconnect) EVT_TOOL(XRCID("ID_TOOLBAR_REFRESH"), CMainFrame::OnRefresh) EVT_TOOL(XRCID("ID_TOOLBAR_SITEMANAGER"), CMainFrame::OnSiteManager) EVT_CLOSE(CMainFrame::OnClose) EVT_TIMER(wxID_ANY, CMainFrame::OnTimer) EVT_TOOL(XRCID("ID_TOOLBAR_PROCESSQUEUE"), CMainFrame::OnProcessQueue) EVT_UPDATE_UI(XRCID("ID_TOOLBAR_PROCESSQUEUE"), CMainFrame::OnUpdateToolbarProcessQueue) EVT_TOOL(XRCID("ID_TOOLBAR_LOGVIEW"), CMainFrame::OnToggleLogView) EVT_UPDATE_UI(XRCID("ID_TOOLBAR_LOGVIEW"), CMainFrame::OnUpdateToggleLogView) EVT_TOOL(XRCID("ID_TOOLBAR_LOCALTREEVIEW"), CMainFrame::OnToggleLocalTreeView) EVT_UPDATE_UI(XRCID("ID_TOOLBAR_LOCALTREEVIEW"), CMainFrame::OnUpdateToggleLocalTreeView) EVT_TOOL(XRCID("ID_TOOLBAR_REMOTETREEVIEW"), CMainFrame::OnToggleRemoteTreeView) EVT_UPDATE_UI(XRCID("ID_TOOLBAR_REMOTETREEVIEW"), CMainFrame::OnUpdateToggleRemoteTreeView) EVT_TOOL(XRCID("ID_TOOLBAR_QUEUEVIEW"), CMainFrame::OnToggleQueueView) EVT_UPDATE_UI(XRCID("ID_TOOLBAR_QUEUEVIEW"), CMainFrame::OnUpdateToggleQueueView) EVT_MENU(wxID_ABOUT, CMainFrame::OnMenuHelpAbout) EVT_TOOL(XRCID("ID_TOOLBAR_FILTER"), CMainFrame::OnFilter) #if FZ_MANUALUPDATECHECK EVT_MENU(XRCID("ID_CHECKFORUPDATES"), CMainFrame::OnCheckForUpdates) #endif //FZ_MANUALUPDATECHECK EVT_TOOL_RCLICKED(XRCID("ID_TOOLBAR_SITEMANAGER"), CMainFrame::OnSitemanagerDropdown) #ifdef EVT_TOOL_DROPDOWN EVT_TOOL_DROPDOWN(XRCID("ID_TOOLBAR_SITEMANAGER"), CMainFrame::OnSitemanagerDropdown) #endif EVT_UPDATE_UI(XRCID("ID_MENU_SERVER_CMD"), CMainFrame::OnUpdateMenuCustomcommand) EVT_UPDATE_UI(XRCID("ID_MENU_SERVER_VIEWHIDDEN"), CMainFrame::OnUpdateMenuShowHidden) EVT_NAVIGATION_KEY(CMainFrame::OnNavigationKeyEvent) EVT_SET_FOCUS(CMainFrame::OnGetFocus) EVT_CHAR_HOOK(CMainFrame::OnChar) EVT_MENU(XRCID("ID_MENU_EDIT_FILTERS"), CMainFrame::OnFilter) END_EVENT_TABLE() CMainFrame::CMainFrame() : wxFrame(NULL, -1, _T("FileZilla"), wxDefaultPosition, wxSize(900, 750)) { SetSizeHints(250, 250); #ifdef __WXMSW__ SetIcon(wxICON(appicon)); #else SetIcons(CThemeProvider::GetIconBundle(_T("ART_FILEZILLA"))); #endif m_pStatusBar = NULL; m_pMenuBar = NULL; m_pToolBar = 0; m_pQuickconnectBar = NULL; m_pTopSplitter = NULL; m_pBottomSplitter = NULL; m_pViewSplitter = NULL; m_pLocalSplitter = NULL; m_pRemoteSplitter = NULL; m_bInitDone = false; m_bQuit = false; #if FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK m_pUpdateWizard = 0; #endif //FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK m_lastLogViewSplitterPos = 0; m_lastLocalTreeSplitterPos = 0; m_lastRemoteTreeSplitterPos = 0; m_lastQueueSplitterPos = 0; m_lastMaximized = false; #ifdef __WXMSW__ m_windowIsMaximized = false; m_pendingPostSizing = false; #endif m_pThemeProvider = new CThemeProvider(); m_pState = new CState(this); m_pStatusBar = new wxStatusBar(this, wxID_ANY, wxST_SIZEGRIP); if (m_pStatusBar) { m_pStatusBar->SetFieldsCount(6); m_pStatusBar->Connect(wxID_ANY, wxEVT_SIZE, (wxObjectEventFunction)(wxEventFunction)(wxSizeEventFunction)&CMainFrame::OnStatusbarSize, 0, this); int array[6]; for (int i = 1; i < 5; i++) array[i] = wxSB_NORMAL; array[0] = wxSB_FLAT; array[5] = wxSB_FLAT; m_pStatusBar->SetStatusStyles(6, array); m_pStatusBar->SetStatusWidths(6, statbarWidths); m_pRecvLed = new CLed(m_pStatusBar, 1, m_pState); m_pSendLed = new CLed(m_pStatusBar, 0, m_pState); SetStatusBar(m_pStatusBar); } else { m_pRecvLed = 0; m_pSendLed = 0; } m_transferStatusTimer.SetOwner(this, TRANSFERSTATUS_TIMER_ID); CreateMenus(); CreateToolBar(); CreateQuickconnectBar(); m_ViewSplitterSashPos = 0.5; m_pAsyncRequestQueue = new CAsyncRequestQueue(this); if (!m_pState->CreateEngine()) { wxMessageBox(_("Failed to initialize FTP engine")); } #ifdef __WXMSW__ long style = wxSP_NOBORDER | wxSP_LIVE_UPDATE; #else long style = wxSP_3DBORDER | wxSP_LIVE_UPDATE; #endif wxSize clientSize = GetClientSize(); m_pTopSplitter = new wxSplitterWindow(this, -1, wxDefaultPosition, clientSize, style); m_pTopSplitter->SetMinimumPaneSize(50); m_pBottomSplitter = new wxSplitterWindow(m_pTopSplitter, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_LIVE_UPDATE); m_pBottomSplitter->SetMinimumPaneSize(50); m_pBottomSplitter->SetSashGravity(1.0); m_pViewSplitter = new wxSplitterWindow(m_pBottomSplitter, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_LIVE_UPDATE); m_pViewSplitter->SetMinimumPaneSize(50); m_pLocalSplitter = new wxSplitterWindow(m_pViewSplitter, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_LIVE_UPDATE); m_pLocalSplitter->SetMinimumPaneSize(50); m_pRemoteSplitter = new wxSplitterWindow(m_pViewSplitter, -1, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxSP_LIVE_UPDATE); m_pRemoteSplitter->SetMinimumPaneSize(50); m_pStatusView = new CStatusView(m_pTopSplitter, -1); m_pQueuePane = new CQueue(m_pBottomSplitter, this, m_pAsyncRequestQueue); m_pQueueView = m_pQueuePane->GetQueueView(); m_pLocalTreeViewPanel = new CView(m_pLocalSplitter); m_pLocalListViewPanel = new CView(m_pLocalSplitter); m_pLocalTreeView = new CLocalTreeView(m_pLocalTreeViewPanel, -1, m_pState, m_pQueueView); m_pLocalListView = new CLocalListView(m_pLocalListViewPanel, -1, m_pState, m_pQueueView); m_pLocalTreeViewPanel->SetWindow(m_pLocalTreeView); m_pLocalListViewPanel->SetWindow(m_pLocalListView); m_pRemoteTreeViewPanel = new CView(m_pRemoteSplitter); m_pRemoteListViewPanel = new CView(m_pRemoteSplitter); m_pRemoteTreeView = new CRemoteTreeView(m_pRemoteTreeViewPanel, -1, m_pState, m_pQueueView); m_pRemoteListView = new CRemoteListView(m_pRemoteListViewPanel, -1, m_pState, m_pQueueView); m_pRemoteTreeViewPanel->SetWindow(m_pRemoteTreeView); m_pRemoteListViewPanel->SetWindow(m_pRemoteListView); if (COptions::Get()->GetOptionVal(OPTION_SHOW_MESSAGELOG)) m_pTopSplitter->SplitHorizontally(m_pStatusView, m_pBottomSplitter, 100); else { m_pStatusView->Hide(); m_pTopSplitter->Initialize(m_pBottomSplitter); } if (COptions::Get()->GetOptionVal(OPTION_SHOW_QUEUE)) m_pBottomSplitter->SplitHorizontally(m_pViewSplitter, m_pQueuePane); else { m_pQueuePane->Hide(); m_pBottomSplitter->Initialize(m_pViewSplitter); } const int layout = COptions::Get()->GetOptionVal(OPTION_FILEPANE_LAYOUT); const int swap = COptions::Get()->GetOptionVal(OPTION_FILEPANE_SWAP); if (layout == 1) { if (swap) m_pViewSplitter->SplitHorizontally(m_pRemoteSplitter, m_pLocalSplitter); else m_pViewSplitter->SplitHorizontally(m_pLocalSplitter, m_pRemoteSplitter); } else { if (swap) m_pViewSplitter->SplitVertically(m_pRemoteSplitter, m_pLocalSplitter); else m_pViewSplitter->SplitVertically(m_pLocalSplitter, m_pRemoteSplitter); } m_pLocalViewHeader = new CLocalViewHeader(m_pLocalSplitter, m_pState); if (COptions::Get()->GetOptionVal(OPTION_SHOW_TREE_LOCAL)) { m_pLocalTreeViewPanel->SetHeader(m_pLocalViewHeader); if (layout == 3 && swap) m_pLocalSplitter->SplitVertically(m_pLocalListViewPanel, m_pLocalTreeViewPanel); else if (layout) m_pLocalSplitter->SplitVertically(m_pLocalTreeViewPanel, m_pLocalListViewPanel); else m_pLocalSplitter->SplitHorizontally(m_pLocalTreeViewPanel, m_pLocalListViewPanel); } else { m_pLocalTreeViewPanel->Hide(); m_pLocalListViewPanel->SetHeader(m_pLocalViewHeader); m_pLocalSplitter->Initialize(m_pLocalListViewPanel); } m_pRemoteViewHeader = new CRemoteViewHeader(m_pRemoteSplitter, m_pState); if (COptions::Get()->GetOptionVal(OPTION_SHOW_TREE_REMOTE)) { m_pRemoteTreeViewPanel->SetHeader(m_pRemoteViewHeader); if (layout == 3 && !swap) m_pRemoteSplitter->SplitVertically(m_pRemoteListViewPanel, m_pRemoteTreeViewPanel); else if (layout) m_pRemoteSplitter->SplitVertically(m_pRemoteTreeViewPanel, m_pRemoteListViewPanel); else m_pRemoteSplitter->SplitHorizontally(m_pRemoteTreeViewPanel, m_pRemoteListViewPanel); } else { m_pRemoteTreeViewPanel->Hide(); m_pRemoteListViewPanel->SetHeader(m_pRemoteViewHeader); m_pRemoteSplitter->Initialize(m_pRemoteListViewPanel); } wxSize size = m_pBottomSplitter->GetClientSize(); m_pBottomSplitter->SetSashPosition(size.GetHeight() - 170); Layout(); RestoreSizes(); wxString localDir = COptions::Get()->GetOption(OPTION_LASTLOCALDIR); if (!m_pState->SetLocalDir(localDir)) m_pState->SetLocalDir(_T("/")); wxAcceleratorEntry entries[1]; entries[0].Set(wxACCEL_NORMAL, WXK_F5, XRCID("ID_TOOLBAR_REFRESH")); wxAcceleratorTable accel(1, entries); SetAcceleratorTable(accel); #if FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK if (COptions::Get()->GetOptionVal(OPTION_UPDATECHECK)) { m_pUpdateWizard = new CUpdateWizard(this); m_pUpdateWizard->InitAutoUpdateCheck(); } else m_pUpdateWizard = 0; #endif //FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK m_pState->GetRecursiveOperationHandler()->SetQueue(m_pQueueView); ConnectNavigationHandler(m_pStatusView); ConnectNavigationHandler(m_pLocalListView); ConnectNavigationHandler(m_pRemoteListView); ConnectNavigationHandler(m_pLocalTreeView); ConnectNavigationHandler(m_pRemoteTreeView); ConnectNavigationHandler(m_pLocalViewHeader); ConnectNavigationHandler(m_pRemoteViewHeader); ConnectNavigationHandler(m_pQueuePane); wxNavigationKeyEvent evt; evt.SetDirection(true); AddPendingEvent(evt); } CMainFrame::~CMainFrame() { delete m_pState; delete m_pAsyncRequestQueue; #if FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK delete m_pUpdateWizard; #endif //FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK } void CMainFrame::OnSize(wxSizeEvent &event) { if (!m_pBottomSplitter) return; wxFrame::OnSize(event); wxSize clientSize = GetClientSize(); if (m_pQuickconnectBar) { wxSize barSize = m_pQuickconnectBar->GetSize(); m_pQuickconnectBar->SetSize(0, 0, clientSize.GetWidth(), barSize.GetHeight()); } if (m_pTopSplitter) { if (!m_pQuickconnectBar) m_pTopSplitter->SetSize(clientSize.GetWidth(), clientSize.GetHeight()); else { wxSize panelSize = m_pQuickconnectBar->GetSize(); m_pTopSplitter->SetSize(0, panelSize.GetHeight(), clientSize.GetWidth(), clientSize.GetHeight() - panelSize.GetHeight()); } } #ifdef __WXMSW__ if (!m_pendingPostSizing) { m_pendingPostSizing = true; wxCommandEvent evt(fzEVT_ONSIZE_POST); AddPendingEvent(evt); } #else if (m_pViewSplitter) { Layout(); wxSize size = m_pViewSplitter->GetClientSize(); const int layout = COptions::Get()->GetOptionVal(OPTION_FILEPANE_LAYOUT); int pos; if (layout == 1) { pos = static_cast(size.GetHeight() * m_ViewSplitterSashPos); if (pos < 20) pos = 20; else if (pos > size.GetHeight() - 20) pos = size.GetHeight() - 20; } else { pos = static_cast(size.GetWidth() * m_ViewSplitterSashPos); if (pos < 20) pos = 20; else if (pos > size.GetWidth() - 20) pos = size.GetWidth() - 20; } m_pViewSplitter->SetSashPosition(pos); } ApplySplitterConstraints(); #endif if (!IsIconized()) { m_lastMaximized = IsMaximized(); if (!m_lastMaximized) { m_lastWindowPosition = GetPosition(); m_lastWindowSize = GetClientSize(); } } } #ifdef __WXMSW__ void CMainFrame::OnSizePost(wxCommandEvent& event) { m_pendingPostSizing = false; if (m_pViewSplitter) { Layout(); wxSize size = m_pViewSplitter->GetClientSize(); const int layout = COptions::Get()->GetOptionVal(OPTION_FILEPANE_LAYOUT); int pos; if (layout == 1) { pos = static_cast(size.GetHeight() * m_ViewSplitterSashPos); if (pos < 20) pos = 20; else if (pos > size.GetHeight() - 20) pos = size.GetHeight() - 20; } else { pos = static_cast(size.GetWidth() * m_ViewSplitterSashPos); if (pos < 20) pos = 20; else if (pos > size.GetWidth() - 20) pos = size.GetWidth() - 20; } m_pViewSplitter->SetSashPosition(pos); } ApplySplitterConstraints(); } #endif void CMainFrame::OnViewSplitterPosChanged(wxSplitterEvent &event) { if (event.GetEventObject() != m_pViewSplitter) { event.Skip(); return; } #ifdef __WXMSW__ if (m_pendingPostSizing) return; #endif wxSize size = m_pViewSplitter->GetClientSize(); int pos = m_pViewSplitter->GetSashPosition(); const int layout = COptions::Get()->GetOptionVal(OPTION_FILEPANE_LAYOUT); if (layout != 1) m_ViewSplitterSashPos = pos / (float)size.GetWidth(); else m_ViewSplitterSashPos = pos / (float)size.GetHeight(); } bool CMainFrame::CreateMenus() { if (m_pMenuBar) { SetMenuBar(0); delete m_pMenuBar; } m_pMenuBar = wxXmlResource::Get()->LoadMenuBar(_T("ID_MENUBAR")); if (!m_pMenuBar) { wxLogError(_("Cannot load main menu from resource file")); } #if !FZ_MANUALUPDATECHECK wxMenu *helpMenu; wxMenuItem* pUpdateItem = m_pMenuBar->FindItem(XRCID("ID_CHECKFORUPDATES"), &helpMenu); if (pUpdateItem) helpMenu->Delete(pUpdateItem); #endif //!FZ_MANUALUPDATECHECK if (COptions::Get()->GetOptionVal(OPTION_DEBUG_MENU)) { wxMenu* pMenu = wxXmlResource::Get()->LoadMenu(_T("ID_MENU_DEBUG")); if (pMenu) m_pMenuBar->Append(pMenu, _("&Debug")); } SetMenuBar(m_pMenuBar); #if FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK if (m_pUpdateWizard) m_pUpdateWizard->DisplayUpdateAvailability(false, true); #endif //FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK return true; } bool CMainFrame::CreateQuickconnectBar() { if (m_pQuickconnectBar) delete m_pQuickconnectBar; m_pQuickconnectBar = new CQuickconnectBar(); if (!m_pQuickconnectBar->Create(this, m_pState)) { delete m_pQuickconnectBar; m_pQuickconnectBar = 0; } return true; } void CMainFrame::OnMenuHandler(wxCommandEvent &event) { if (event.GetId() == XRCID("wxID_EXIT")) { Close(); } else if (event.GetId() == XRCID("ID_MENU_FILE_SITEMANAGER")) { OnSiteManager(event); } else if (event.GetId() == XRCID("ID_MENU_SERVER_CMD")) { if (!m_pState->m_pEngine || !m_pState->m_pEngine->IsConnected() || !m_pState->m_pCommandQueue->Idle()) return; wxTextEntryDialog dlg(this, _("Please enter raw FTP command.\nUsing raw ftp commands will clear the directory cache."), _("Enter custom command")); if (dlg.ShowModal() != wxID_OK) return; const wxString &command = dlg.GetValue(); if (!command.Left(5).CmpNoCase(_T("quote")) || !command.Left(6).CmpNoCase(_T("quote "))) { CConditionalDialog dlg(this, CConditionalDialog::rawcommand_quote, CConditionalDialog::yesno); dlg.SetTitle(_("Raw FTP command")); dlg.AddText(_("'quote' is usually a local command used by commandline clients to send the arguments following 'quote' to the server. You might want to enter the raw command without the leading 'quote'.")); dlg.AddText(wxString::Format(_("Do you really want to send '%s' to the server?"), command.c_str())); if (!dlg.Run()) return; } m_pState->m_pCommandQueue->ProcessCommand(new CRawCommand(dlg.GetValue())); } else if (event.GetId() == XRCID("wxID_PREFERENCES")) { OnMenuEditSettings(event); } else if (event.GetId() == XRCID("ID_MENU_EDIT_NETCONFWIZARD")) { CNetConfWizard wizard(this, COptions::Get()); wizard.Load(); wizard.Run(); } // Debug menu else if (event.GetId() == XRCID("ID_CRASH")) { // Cause a crash int *x = 0; *x = 0; } else if (event.GetId() == XRCID("ID_CLEARCACHE_LAYOUT")) { CWrapEngine::ClearCache(); } else if (event.GetId() == XRCID("ID_MENU_TRANSFER_FILEEXISTS")) { CDefaultFileExistsDlg dlg; if (!dlg.Load(this, false)) return; dlg.Run(); } else if (event.GetId() == XRCID("ID_MENU_EDIT_CLEARPRIVATEDATA")) { CClearPrivateDataDialog* pDlg = CClearPrivateDataDialog::Create(this); if (!pDlg) return; pDlg->Show(); pDlg->Delete(); } else if (event.GetId() == XRCID("ID_MENU_SERVER_VIEWHIDDEN")) { bool showHidden = COptions::Get()->GetOptionVal(OPTION_VIEW_HIDDEN_FILES) ? 0 : 1; if (showHidden) { CConditionalDialog dlg(this, CConditionalDialog::viewhidden, CConditionalDialog::ok, true); dlg.SetTitle(_("View hidden files")); dlg.AddText(_("Note that this feature is only supported using the FTP protocol.")); dlg.AddText(_("Also, not all servers support this feature and may return incorrect listings if 'View hidden files' is enabled. Although FileZilla performs some tests to see if the server supports this feature, the test may fail.")); dlg.AddText(_("Disable this option if you cannot see your files anymore.")); dlg.Run(); } COptions::Get()->SetOption(OPTION_VIEW_HIDDEN_FILES, showHidden ? 1 : 0); } else if (event.GetId() == XRCID("ID_EXPORT")) { CExportDialog dlg(this, m_pQueueView); dlg.Show(); } else if (event.GetId() == XRCID("ID_IMPORT")) { CImportDialog dlg(this, m_pQueueView); dlg.Show(); } else { CSiteManagerItemData* pData = CSiteManager::GetSiteById(event.GetId()); if (!pData) { event.Skip(); return; } ConnectToSite(pData); delete pData; } } void CMainFrame::OnEngineEvent(wxEvent &event) { if (!m_pState->m_pEngine) return; CNotification *pNotification = m_pState->m_pEngine->GetNextNotification(); while (pNotification) { switch (pNotification->GetID()) { case nId_logmsg: m_pStatusView->AddToLog(reinterpret_cast(pNotification)); delete pNotification; break; case nId_operation: m_pState->m_pCommandQueue->Finish(reinterpret_cast(pNotification)); if (m_bQuit) { Close(); return; } break; case nId_listing: { const CDirectoryListingNotification* const pListingNotification = reinterpret_cast(pNotification); if (pListingNotification->GetPath().IsEmpty()) m_pState->SetRemoteDir(0, false); else { CDirectoryListing* pListing = new CDirectoryListing; if (pListingNotification->Failed() || m_pState->m_pEngine->CacheLookup(pListingNotification->GetPath(), *pListing) != FZ_REPLY_OK) { pListing->path = pListingNotification->GetPath(); pListing->m_failed = true; } m_pState->SetRemoteDir(pListing, pListingNotification->Modified()); } } delete pNotification; break; case nId_asyncrequest: { CAsyncRequestNotification* pAsyncRequest = reinterpret_cast(pNotification); if (pAsyncRequest->GetRequestID() == reqId_fileexists) m_pQueueView->ProcessNotification(pNotification); else m_pAsyncRequestQueue->AddRequest(m_pState->m_pEngine, pAsyncRequest); } break; case nId_active: { CActiveNotification *pActiveNotification = reinterpret_cast(pNotification); if (pActiveNotification->IsRecv()) UpdateRecvLed(); else UpdateSendLed(); delete pNotification; } break; case nId_transferstatus: { m_pQueueView->ProcessNotification(pNotification); /* CTransferStatusNotification *pTransferStatusNotification = reinterpret_cast(pNotification); const CTransferStatus *pStatus = pTransferStatusNotification ? pTransferStatusNotification->GetStatus() : 0; if (pStatus && !m_transferStatusTimer.IsRunning()) m_transferStatusTimer.Start(100); else if (!pStatus && m_transferStatusTimer.IsRunning()) m_transferStatusTimer.Stop(); SetProgress(pStatus); delete pNotification;*/ } break; default: delete pNotification; break; } pNotification = m_pState->m_pEngine->GetNextNotification(); } } bool CMainFrame::CreateToolBar() { if (m_pToolBar) { SetToolBar(0); delete m_pToolBar; } m_pToolBar = wxXmlResource::Get()->LoadToolBar(this, _T("ID_TOOLBAR")); if (!m_pToolBar) { wxLogError(_("Cannot load toolbar from resource file")); return false; } m_pToolBar->SetExtraStyle(wxWS_EX_PROCESS_UI_UPDATES); #if defined(EVT_TOOL_DROPDOWN) && defined(__WXMSW__) wxToolBarToolBase* pOldTool = m_pToolBar->FindById(XRCID("ID_TOOLBAR_SITEMANAGER")); if (pOldTool) { wxToolBarToolBase* pTool = new wxToolBarToolBase(0, XRCID("ID_TOOLBAR_SITEMANAGER"), pOldTool->GetLabel(), pOldTool->GetNormalBitmap(), pOldTool->GetDisabledBitmap(), wxITEM_DROPDOWN, NULL, pOldTool->GetShortHelp(), pOldTool->GetLongHelp()); int pos = m_pToolBar->GetToolPos(XRCID("ID_TOOLBAR_SITEMANAGER")); wxASSERT(pos != wxNOT_FOUND); m_pToolBar->DeleteToolByPos(pos); m_pToolBar->InsertTool(pos, pTool); m_pToolBar->Realize(); } #endif #ifdef __WXMSW__ int majorVersion, minorVersion; wxGetOsVersion(& majorVersion, & minorVersion); if (majorVersion < 6) m_pToolBar->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); #endif CFilterDialog dlg; m_pToolBar->ToggleTool(XRCID("ID_TOOLBAR_FILTER"), dlg.HasActiveFilters()); SetToolBar(m_pToolBar); return true; } void CMainFrame::OnUpdateToolbarDisconnect(wxUpdateUIEvent& event) { event.Enable(m_pState->IsRemoteConnected() && m_pState->IsRemoteIdle()); } void CMainFrame::OnDisconnect(wxCommandEvent& event) { if (!m_pState->IsRemoteConnected()) return; if (!m_pState->IsRemoteIdle()) return; m_pState->m_pCommandQueue->ProcessCommand(new CDisconnectCommand()); } void CMainFrame::OnUpdateToolbarCancel(wxUpdateUIEvent& event) { event.Enable(m_pState && m_pState->m_pCommandQueue && !m_pState->m_pCommandQueue->Idle()); } void CMainFrame::OnCancel(wxCommandEvent& event) { if (m_pState->m_pCommandQueue->Idle()) return; if (wxMessageBox(_("Really cancel current operation?"), _T("FileZilla"), wxYES_NO | wxICON_QUESTION) == wxYES) { m_pState->m_pCommandQueue->Cancel(); m_pState->GetRecursiveOperationHandler()->StopRecursiveOperation(); } } void CMainFrame::OnSplitterSashPosChanging(wxSplitterEvent& event) { if (event.GetEventObject() == m_pBottomSplitter) { if (!m_pRemoteSplitter || !m_pLocalSplitter) return; if (event.GetSashPosition() < 43) event.SetSashPosition(43); } } void CMainFrame::OnSplitterSashPosChanged(wxSplitterEvent& event) { if (event.GetEventObject() == m_pBottomSplitter) { if (!m_pRemoteSplitter || !m_pLocalSplitter) return; if (event.GetSashPosition() < 43) event.SetSashPosition(43); int delta = event.GetSashPosition() - m_pBottomSplitter->GetSashPosition(); int newSize = m_pRemoteSplitter->GetClientSize().GetHeight() - m_pRemoteSplitter->GetSashPosition() + delta; if (newSize < 0) event.Veto(); else if (newSize < 20) m_pRemoteSplitter->SetSashPosition(m_pRemoteSplitter->GetSashPosition() - 20 + newSize); newSize = m_pLocalSplitter->GetClientSize().GetHeight() - m_pLocalSplitter->GetSashPosition() + delta; if (newSize < 0) event.Veto(); else if (newSize < 20) m_pLocalSplitter->SetSashPosition(m_pLocalSplitter->GetSashPosition() - 20 + newSize); } } void CMainFrame::OnClose(wxCloseEvent &event) { if (!m_bQuit) { if (m_pQueueView && m_pQueueView->IsActive()) { CConditionalDialog dlg(this, CConditionalDialog::confirmexit, CConditionalDialog::yesno); dlg.SetTitle(_("Close FileZilla")); dlg.AddText(_("File transfers still in progress.")); dlg.AddText(_("Do you really want to close FileZilla?")); if (!dlg.Run()) { event.Veto(); return; } } RememberSizes(); m_bQuit = true; } Show(false); delete m_pSendLed; delete m_pRecvLed; m_pSendLed = 0; m_pRecvLed = 0; m_transferStatusTimer.Stop(); if (!m_pQueueView->Quit()) { event.Veto(); return; } bool res = true; if (m_pState->m_pCommandQueue) res = m_pState->m_pCommandQueue->Cancel(); if (!res) { event.Veto(); return; } m_pState->DestroyEngine(); CSiteManager::ClearIdMap(); COptions::Get()->SaveColumnWidths(m_pLocalListView, OPTION_LOCALFILELIST_COLUMN_WIDTHS); COptions::Get()->SaveColumnWidths(m_pRemoteListView, OPTION_REMOTEFILELIST_COLUMN_WIDTHS); Destroy(); } void CMainFrame::OnUpdateToolbarReconnect(wxUpdateUIEvent &event) { if (!m_pState->m_pEngine || m_pState->m_pEngine->IsConnected() || !m_pState->m_pCommandQueue->Idle()) { event.Enable(false); return; } CServer server; event.Enable(COptions::Get()->GetLastServer(server)); } void CMainFrame::OnReconnect(wxCommandEvent &event) { if (!m_pState->m_pEngine || m_pState->m_pEngine->IsConnected() || !m_pState->m_pCommandQueue->Idle()) return; CServer server; if (!COptions::Get()->GetLastServer(server)) return; if (server.GetLogonType() == ASK) { if (!CLoginManager::Get().GetPassword(server, false)) return; } CServerPath path; path.SetSafePath(COptions::Get()->GetOption(OPTION_LASTSERVERPATH)); m_pState->Connect(server, false, path); } void CMainFrame::OnRefresh(wxCommandEvent &event) { if (m_pState->m_pEngine && m_pState->m_pEngine->IsConnected() && m_pState->m_pCommandQueue->Idle()) m_pState->m_pCommandQueue->ProcessCommand(new CListCommand(m_pState->GetRemotePath(), _T(""), true)); if (m_pState) m_pState->RefreshLocal(); } void CMainFrame::OnStatusbarSize(wxSizeEvent& event) { if (!m_pStatusBar) return; #ifdef __WXMSW__ if (IsMaximized() && !m_windowIsMaximized) { m_windowIsMaximized = true; int widths[6]; memcpy(widths, statbarWidths, 6 * sizeof(int)); widths[5] = 35; m_pStatusBar->SetStatusWidths(6, widths); m_pStatusBar->Refresh(); } else if (!IsMaximized() && m_windowIsMaximized) { m_windowIsMaximized = false; m_pStatusBar->SetStatusWidths(6, statbarWidths); m_pStatusBar->Refresh(); } #endif if (m_pSendLed) { wxRect rect; m_pStatusBar->GetFieldRect(5, rect); m_pSendLed->SetSize(rect.GetLeft() + 16, rect.GetTop() + (rect.GetHeight() - 11) / 2, -1, -1); } if (m_pRecvLed) { wxRect rect; m_pStatusBar->GetFieldRect(5, rect); m_pRecvLed->SetSize(rect.GetLeft() + 2, rect.GetTop() + (rect.GetHeight() - 11) / 2, -1, -1); } } void CMainFrame::OnTimer(wxTimerEvent& event) { if (event.GetId() == TRANSFERSTATUS_TIMER_ID && m_transferStatusTimer.IsRunning()) { if (!m_pState->m_pEngine) { m_transferStatusTimer.Stop(); return; } bool changed; CTransferStatus status; if (!m_pState->m_pEngine->GetTransferStatus(status, changed)) { SetProgress(0); m_transferStatusTimer.Stop(); } else if (changed) SetProgress(&status); else m_transferStatusTimer.Stop(); } } void CMainFrame::SetProgress(const CTransferStatus *pStatus) { return; /* TODO: If called during primary transfer, relay to queue, else relay to remote file list statusbar. if (!m_pStatusBar) return; if (!pStatus) { m_pStatusBar->SetStatusText(_T(""), 1); m_pStatusBar->SetStatusText(_T(""), 2); m_pStatusBar->SetStatusText(_T(""), 3); return; } wxTimeSpan elapsed = wxDateTime::Now().Subtract(pStatus->started); m_pStatusBar->SetStatusText(elapsed.Format(_("%H:%M:%S elapsed")), 1); int elapsedSeconds = elapsed.GetSeconds().GetLo(); // Assume GetHi is always 0 if (elapsedSeconds) { wxFileOffset rate = (pStatus->currentOffset - pStatus->startOffset) / elapsedSeconds; if (rate > (1000*1000)) m_pStatusBar->SetStatusText(wxString::Format(_("%s bytes (%d.%d MB/s)"), wxLongLong(pStatus->currentOffset).ToString().c_str(), (int)(rate / 1000 / 1000), (int)((rate / 1000 / 100) % 10)), 4); else if (rate > 1000) m_pStatusBar->SetStatusText(wxString::Format(_("%s bytes (%d.%d KB/s)"), wxLongLong(pStatus->currentOffset).ToString().c_str(), (int)(rate / 1000), (int)((rate / 100) % 10)), 4); else m_pStatusBar->SetStatusText(wxString::Format(_("%s bytes (%d B/s)"), wxLongLong(pStatus->currentOffset).ToString().c_str(), (int)rate), 4); if (pStatus->totalSize > 0 && rate > 0) { int left = ((pStatus->totalSize - pStatus->startOffset) / rate) - elapsedSeconds; if (left < 0) left = 0; wxTimeSpan timeLeft(0, 0, left); m_pStatusBar->SetStatusText(timeLeft.Format(_("%H:%M:%S left")), 2); } else { m_pStatusBar->SetStatusText(_("--:--:-- left"), 2); } } else m_pStatusBar->SetStatusText(wxString::Format(_("%s bytes (? B/s)"), wxLongLong(pStatus->currentOffset).ToString().c_str()), 4); */ } void CMainFrame::OnSiteManager(wxCommandEvent& event) { CSiteManager dlg; if (!dlg.Create(this)) return; int res = dlg.ShowModal(); if (res == wxID_YES) { CSiteManagerItemData data; if (!dlg.GetServer(data)) return; ConnectToSite(&data); } } void CMainFrame::UpdateSendLed() { if (m_pSendLed) m_pSendLed->Ping(); } void CMainFrame::UpdateRecvLed() { if (m_pRecvLed) m_pRecvLed->Ping(); } void CMainFrame::AddToRequestQueue(CFileZillaEngine *pEngine, CAsyncRequestNotification *pNotification) { m_pAsyncRequestQueue->AddRequest(pEngine, reinterpret_cast(pNotification)); } void CMainFrame::OnProcessQueue(wxCommandEvent& event) { if (m_pQueueView) m_pQueueView->SetActive(event.IsChecked()); } void CMainFrame::OnUpdateToolbarProcessQueue(wxUpdateUIEvent& event) { event.Check(m_pQueueView->IsActive() != 0); } void CMainFrame::OnMenuEditSettings(wxCommandEvent& event) { CSettingsDialog dlg; if (!dlg.Create(this)) return; COptions* pOptions = COptions::Get(); wxString oldTheme = pOptions->GetOption(OPTION_THEME); int oldLang = wxGetApp().GetCurrentLanguage(); int oldShowDebugMenu = pOptions->GetOptionVal(OPTION_DEBUG_MENU) != 0; int res = dlg.ShowModal(); if (res != wxID_OK) { UpdateLayout(); return; } wxString newTheme = pOptions->GetOption(OPTION_THEME); int newLang = wxGetApp().GetCurrentLanguage(); if (oldTheme != newTheme) { wxArtProvider::Delete(m_pThemeProvider); m_pThemeProvider = new CThemeProvider(); } if (oldTheme != newTheme || oldLang != newLang) CreateToolBar(); if (oldLang != newLang || oldShowDebugMenu != pOptions->GetOptionVal(OPTION_DEBUG_MENU)) { m_pStatusView->InitDefAttr(); CreateMenus(); } if (oldLang != newLang) { CreateQuickconnectBar(); wxGetApp().GetWrapEngine()->CheckLanguage(); } CheckChangedSettings(); } void CMainFrame::OnToggleLogView(wxCommandEvent& event) { if (!m_pTopSplitter) return; if (m_pTopSplitter->IsSplit()) { m_lastLogViewSplitterPos = m_pTopSplitter->GetSashPosition(); m_pTopSplitter->Unsplit(m_pStatusView); } else { // Sometimes m_pQueueView resizes instead of m_bViewSplitter, save original value wxRect rect = m_pBottomSplitter->GetClientSize(); int queueSplitterPos = rect.GetHeight() - m_pBottomSplitter->GetSashPosition(); m_pTopSplitter->SplitHorizontally(m_pStatusView, m_pBottomSplitter, m_lastLogViewSplitterPos); // Restore previous queue size rect = m_pBottomSplitter->GetClientSize(); if (queueSplitterPos != (rect.GetHeight() - m_pBottomSplitter->GetSashPosition())) m_pBottomSplitter->SetSashPosition(rect.GetHeight() - queueSplitterPos); ApplySplitterConstraints(); } COptions::Get()->SetOption(OPTION_SHOW_MESSAGELOG, m_pTopSplitter->IsSplit()); } void CMainFrame::OnUpdateToggleLogView(wxUpdateUIEvent& event) { event.Check(m_pTopSplitter && m_pTopSplitter->IsSplit()); } void CMainFrame::ApplySplitterConstraints() { if (m_pTopSplitter->IsSplit()) { wxSize size = m_pTopSplitter->GetClientSize(); if (size.GetHeight() - m_pTopSplitter->GetSashPosition() < 100) m_pTopSplitter->SetSashPosition(size.GetHeight() - 103); } if (m_pBottomSplitter->GetSashPosition() < 45) m_pBottomSplitter->SetSashPosition(45); if (m_pLocalSplitter->IsSplit() && m_pLocalSplitter->GetSashPosition() < 50) m_pLocalSplitter->SetSashPosition(50); if (m_pRemoteSplitter->IsSplit() && m_pRemoteSplitter->GetSashPosition() < 50) m_pRemoteSplitter->SetSashPosition(50); } void CMainFrame::OnToggleLocalTreeView(wxCommandEvent& event) { if (!m_pTopSplitter) return; if (m_pLocalSplitter->IsSplit()) { m_pLocalListViewPanel->SetHeader(m_pLocalTreeViewPanel->DetachHeader()); m_lastLocalTreeSplitterPos = m_pLocalSplitter->GetSashPosition(); m_pLocalSplitter->Unsplit(m_pLocalTreeViewPanel); } else { m_pLocalTreeViewPanel->SetHeader(m_pLocalListViewPanel->DetachHeader()); wxSize size = m_pLocalSplitter->GetClientSize(); const int layout = COptions::Get()->GetOptionVal(OPTION_FILEPANE_LAYOUT); const int swap = COptions::Get()->GetOptionVal(OPTION_FILEPANE_SWAP); if (layout == 3 && swap) m_pLocalSplitter->SplitVertically(m_pLocalListViewPanel, m_pLocalTreeViewPanel, m_lastLocalTreeSplitterPos); else if (layout) m_pLocalSplitter->SplitVertically(m_pLocalTreeViewPanel, m_pLocalListViewPanel, m_lastLocalTreeSplitterPos); else m_pLocalSplitter->SplitHorizontally(m_pLocalTreeViewPanel, m_pLocalListViewPanel, m_lastLocalTreeSplitterPos); } COptions::Get()->SetOption(OPTION_SHOW_TREE_LOCAL, m_pLocalSplitter->IsSplit()); } void CMainFrame::OnUpdateToggleLocalTreeView(wxUpdateUIEvent& event) { event.Check(m_pLocalSplitter && m_pLocalSplitter->IsSplit()); } void CMainFrame::OnToggleRemoteTreeView(wxCommandEvent& event) { if (!m_pTopSplitter) return; if (m_pRemoteSplitter->IsSplit()) { m_pRemoteListViewPanel->SetHeader(m_pRemoteTreeViewPanel->DetachHeader()); m_lastRemoteTreeSplitterPos = m_pRemoteSplitter->GetSashPosition(); m_pRemoteSplitter->Unsplit(m_pRemoteTreeViewPanel); } else { m_pRemoteTreeViewPanel->SetHeader(m_pRemoteListViewPanel->DetachHeader()); wxSize size = m_pRemoteSplitter->GetClientSize(); const int layout = COptions::Get()->GetOptionVal(OPTION_FILEPANE_LAYOUT); const int swap = COptions::Get()->GetOptionVal(OPTION_FILEPANE_SWAP); if (layout == 3 && !swap) m_pRemoteSplitter->SplitVertically(m_pRemoteListViewPanel, m_pRemoteTreeViewPanel, m_lastRemoteTreeSplitterPos); else if (layout) m_pRemoteSplitter->SplitVertically(m_pRemoteTreeViewPanel, m_pRemoteListViewPanel, m_lastRemoteTreeSplitterPos); else m_pRemoteSplitter->SplitHorizontally(m_pRemoteTreeViewPanel, m_pRemoteListViewPanel, m_lastRemoteTreeSplitterPos); } COptions::Get()->SetOption(OPTION_SHOW_TREE_REMOTE, m_pRemoteSplitter->IsSplit()); } void CMainFrame::OnUpdateToggleRemoteTreeView(wxUpdateUIEvent& event) { event.Check(m_pRemoteSplitter && m_pRemoteSplitter->IsSplit()); } void CMainFrame::OnToggleQueueView(wxCommandEvent& event) { if (!m_pBottomSplitter) return; if (m_pBottomSplitter->IsSplit()) { wxRect rect = m_pBottomSplitter->GetClientSize(); m_lastQueueSplitterPos = rect.GetHeight() - m_pBottomSplitter->GetSashPosition(); m_pBottomSplitter->Unsplit(m_pQueuePane); } else { wxRect rect = m_pBottomSplitter->GetClientSize(); m_pBottomSplitter->SplitHorizontally(m_pViewSplitter, m_pQueuePane, rect.GetHeight() - m_lastQueueSplitterPos); ApplySplitterConstraints(); } COptions::Get()->SetOption(OPTION_SHOW_QUEUE, m_pBottomSplitter->IsSplit()); } void CMainFrame::OnUpdateToggleQueueView(wxUpdateUIEvent& event) { event.Check(m_pBottomSplitter && m_pBottomSplitter->IsSplit()); } void CMainFrame::OnMenuHelpAbout(wxCommandEvent& event) { CAboutDialog dlg; if (!dlg.Create(this)) return; dlg.ShowModal(); } void CMainFrame::OnFilter(wxCommandEvent& event) { CFilterDialog dlg; m_pToolBar->ToggleTool(XRCID("ID_TOOLBAR_FILTER"), dlg.HasActiveFilters()); dlg.Create(this); dlg.ShowModal(); m_pToolBar->ToggleTool(XRCID("ID_TOOLBAR_FILTER"), dlg.HasActiveFilters()); m_pState->ApplyCurrentFilter(); } #if FZ_MANUALUPDATECHECK void CMainFrame::OnCheckForUpdates(wxCommandEvent& event) { wxString version(PACKAGE_VERSION, wxConvLocal); if (version[0] < '0' || version[0] > '9') { wxMessageBox(_("Executable contains no version info, cannot check for updates."), _("Updatecheck failed"), wxICON_ERROR, this); return; } CUpdateWizard dlg(this); if (!dlg.Load()) return; dlg.Run(); } #endif //FZ_MANUALUPDATECHECK void CMainFrame::UpdateLayout(int layout /*=-1*/, int swap /*=-1*/) { if (layout == -1) layout = COptions::Get()->GetOptionVal(OPTION_FILEPANE_LAYOUT); if (swap == -1) swap = COptions::Get()->GetOptionVal(OPTION_FILEPANE_SWAP); int mode; if (!layout || layout == 2 || layout == 3) mode = wxSPLIT_VERTICAL; else mode = wxSPLIT_HORIZONTAL; int isMode = m_pViewSplitter->GetSplitMode(); int isSwap = m_pViewSplitter->GetWindow1() == m_pRemoteSplitter ? 1 : 0; if (mode != isMode || swap != isSwap) { m_pViewSplitter->Unsplit(); if (mode == wxSPLIT_VERTICAL) { if (swap) m_pViewSplitter->SplitVertically(m_pRemoteSplitter, m_pLocalSplitter); else m_pViewSplitter->SplitVertically(m_pLocalSplitter, m_pRemoteSplitter); } else { if (swap) m_pViewSplitter->SplitHorizontally(m_pRemoteSplitter, m_pLocalSplitter); else m_pViewSplitter->SplitHorizontally(m_pLocalSplitter, m_pRemoteSplitter); } } if (m_pLocalSplitter->IsSplit()) { if (!layout) mode = wxSPLIT_HORIZONTAL; else mode = wxSPLIT_VERTICAL; wxWindow* pFirst; wxWindow* pSecond; if (layout == 3 && swap) { pFirst = m_pLocalListViewPanel; pSecond = m_pLocalTreeViewPanel; } else { pFirst = m_pLocalTreeViewPanel; pSecond = m_pLocalListViewPanel; } if (mode != m_pLocalSplitter->GetSplitMode() || pFirst != m_pLocalSplitter->GetWindow1()) { m_pLocalSplitter->Unsplit(); if (mode == wxSPLIT_VERTICAL) m_pLocalSplitter->SplitVertically(pFirst, pSecond, m_lastLocalTreeSplitterPos); else m_pLocalSplitter->SplitHorizontally(pFirst, pSecond, m_lastLocalTreeSplitterPos); } } if (m_pRemoteSplitter->IsSplit()) { if (!layout) mode = wxSPLIT_HORIZONTAL; else mode = wxSPLIT_VERTICAL; wxWindow* pFirst; wxWindow* pSecond; if (layout == 3 && !swap) { pFirst = m_pRemoteListViewPanel; pSecond = m_pRemoteTreeViewPanel; } else { pFirst = m_pRemoteTreeViewPanel; pSecond = m_pRemoteListViewPanel; } if (mode != m_pRemoteSplitter->GetSplitMode() || pFirst != m_pRemoteSplitter->GetWindow1()) { m_pRemoteSplitter->Unsplit(); if (mode == wxSPLIT_VERTICAL) m_pRemoteSplitter->SplitVertically(pFirst, pSecond, m_lastRemoteTreeSplitterPos); else m_pRemoteSplitter->SplitHorizontally(pFirst, pSecond, m_lastRemoteTreeSplitterPos); } } } void CMainFrame::OnSitemanagerDropdown(wxCommandEvent& event) { wxMenu *pMenu = CSiteManager::GetSitesMenu(); #ifdef EVT_TOOL_DROPDOWN if (event.GetEventType() == wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED) { m_pToolBar->SetDropdownMenu(XRCID("ID_TOOLBAR_SITEMANAGER"), pMenu); event.Skip(); } else #endif { if (!pMenu) return; #ifdef __WXMSW__ RECT r; if (::SendMessage((HWND)m_pToolBar->GetHandle(), TB_GETITEMRECT, m_pToolBar->GetToolPos(event.GetId()), (LPARAM)&r)) m_pToolBar->PopupMenu(pMenu, r.left, r.bottom); else #endif m_pToolBar->PopupMenu(pMenu); delete pMenu; } } void CMainFrame::ConnectToSite(CSiteManagerItemData* const pData) { wxASSERT(pData); if (pData->m_server.GetLogonType() == ASK) { if (!CLoginManager::Get().GetPassword(pData->m_server, false, pData->m_name)) return; } m_pState->Connect(pData->m_server, true, pData->m_remoteDir); if (pData->m_localDir != _T("")) m_pState->SetLocalDir(pData->m_localDir); } void CMainFrame::OnUpdateMenuCustomcommand(wxUpdateUIEvent& event) { if (!m_pMenuBar) return; event.Enable(m_pState->m_pEngine && m_pState->m_pEngine->IsConnected() && m_pState->m_pCommandQueue->Idle()); } void CMainFrame::OnUpdateMenuShowHidden(wxUpdateUIEvent& event) { bool enable = true; const CServer* pServer; if (m_pState && (pServer = m_pState->GetServer())) { switch (pServer->GetProtocol()) { case FTP: case FTPS: case FTPES: break; default: enable = false; } } event.Enable(enable); event.Check(COptions::Get()->GetOptionVal(OPTION_VIEW_HIDDEN_FILES) != 0); } void CMainFrame::CheckChangedSettings() { #if FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK if (COptions::Get()->GetOptionVal(OPTION_UPDATECHECK)) { if (!m_pUpdateWizard) { m_pUpdateWizard = new CUpdateWizard(this); m_pUpdateWizard->InitAutoUpdateCheck(); } } else { if (m_pUpdateWizard) { delete m_pUpdateWizard; m_pUpdateWizard = 0; } } #endif //FZ_MANUALUPDATECHECK && FZ_AUTOUPDATECHECK UpdateLayout(); m_pAsyncRequestQueue->RecheckDefaults(); m_pLocalListView->InitDateFormat(); m_pRemoteListView->InitDateFormat(); } void CMainFrame::ConnectNavigationHandler(wxEvtHandler* handler) { if (!handler) return; handler->Connect(wxEVT_NAVIGATION_KEY, wxNavigationKeyEventHandler(CMainFrame::OnNavigationKeyEvent), 0, this); } void CMainFrame::OnNavigationKeyEvent(wxNavigationKeyEvent& event) { std::list windowOrder; windowOrder.push_back(m_pQuickconnectBar); windowOrder.push_back(m_pStatusView); if (COptions::Get()->GetOptionVal(OPTION_FILEPANE_SWAP) == 0) { windowOrder.push_back(m_pLocalViewHeader); windowOrder.push_back(m_pLocalTreeView); windowOrder.push_back(m_pLocalListView); windowOrder.push_back(m_pRemoteViewHeader); windowOrder.push_back(m_pRemoteTreeView); windowOrder.push_back(m_pRemoteListView); } else { windowOrder.push_back(m_pRemoteViewHeader); windowOrder.push_back(m_pRemoteTreeView); windowOrder.push_back(m_pRemoteListView); windowOrder.push_back(m_pLocalViewHeader); windowOrder.push_back(m_pLocalTreeView); windowOrder.push_back(m_pLocalListView); } windowOrder.push_back(m_pQueuePane); std::list::iterator iter; for (iter = windowOrder.begin(); iter != windowOrder.end(); iter++) { if (*iter == event.GetEventObject()) break; } bool skipFirst; if (iter == windowOrder.end()) { iter = windowOrder.begin(); skipFirst = false; } else skipFirst = true; FocusNextEnabled(windowOrder, iter, skipFirst, event.GetDirection()); } void CMainFrame::OnGetFocus(wxFocusEvent& event) { wxNavigationKeyEvent evt; OnNavigationKeyEvent(evt); } void CMainFrame::OnChar(wxKeyEvent& event) { if (event.GetKeyCode() != WXK_F6) { event.Skip(); return; } // Jump between quickconnect bar and view headers std::list windowOrder; windowOrder.push_back(m_pQuickconnectBar); windowOrder.push_back(m_pLocalViewHeader); windowOrder.push_back(m_pRemoteViewHeader); wxWindow* focused = FindFocus(); bool skipFirst = false; std::list::iterator iter; if (!focused) { iter = windowOrder.begin(); skipFirst = false; } else { wxWindow *parent = focused->GetParent(); for (iter = windowOrder.begin(); iter != windowOrder.end(); iter++) { if (*iter == focused || *iter == parent) { skipFirst = true; break; } } if (iter == windowOrder.end()) { iter = windowOrder.begin(); skipFirst = false; } } FocusNextEnabled(windowOrder, iter, skipFirst, !event.ShiftDown()); } void CMainFrame::FocusNextEnabled(std::list& windowOrder, std::list::iterator iter, bool skipFirst, bool forward) { std::list::iterator start = iter; while (skipFirst || !(*iter)->IsShownOnScreen() || !(*iter)->IsEnabled()) { skipFirst = false; if (forward) { iter++; if (iter == windowOrder.end()) iter = windowOrder.begin(); } else { if (iter == windowOrder.begin()) iter = windowOrder.end(); iter--; } if (iter == start) { wxBell(); return; } } (*iter)->SetFocus(); } void CMainFrame::RememberSizes() { if (!m_lastWindowSize.IsFullySpecified()) return; wxString posString; // is_maximized posString += wxString::Format(_T("%d "), m_lastMaximized ? 1 : 0); // pos_x pos_y posString += wxString::Format(_T("%d %d "), m_lastWindowPosition.x, m_lastWindowPosition.y); // pos_width pos_height posString += wxString::Format(_T("%d %d "), m_lastWindowSize.x, m_lastWindowSize.y); // top_pos posString += wxString::Format(_T("%d "), m_pTopSplitter->IsSplit() ? m_pTopSplitter->GetSashPosition() : m_lastLogViewSplitterPos); // bottom_height int x, y; m_pBottomSplitter->GetClientSize(&x, &y); if (m_pBottomSplitter->IsSplit()) y -= m_pBottomSplitter->GetSashPosition(); else y -= m_lastQueueSplitterPos; posString += wxString::Format(_T("%d "), y); // view_pos posString += wxString::Format(_T("%d "), m_pViewSplitter->GetSashPosition()); // view_height_width m_pViewSplitter->GetClientSize(&x, &y); if (COptions::Get()->GetOptionVal(OPTION_FILEPANE_LAYOUT) != 1) posString += wxString::Format(_T("%d "), x); else posString += wxString::Format(_T("%d "), y); // local_pos posString += wxString::Format(_T("%d "), m_pLocalSplitter->IsSplit() ? m_pLocalSplitter->GetSashPosition() : m_lastLocalTreeSplitterPos); // remote_pos posString += wxString::Format(_T("%d"), m_pRemoteSplitter->IsSplit() ? m_pRemoteSplitter->GetSashPosition() : m_lastRemoteTreeSplitterPos); COptions::Get()->SetOption(OPTION_WINDOW_POSITION, posString); } void CMainFrame::RestoreSizes() { if (wxGetKeyState(WXK_SHIFT) && wxGetKeyState(WXK_ALT) && wxGetKeyState(WXK_CONTROL)) return; #if wxUSE_DISPLAY int min_x = 1000000000; int min_y = 1000000000; int max_x = 0; int max_y = 0; for (unsigned int i = 0; i < wxDisplay::GetCount(); i++) { wxDisplay display(i); wxRect rect = display.GetGeometry(); min_x = wxMin(min_x, rect.GetLeft()); min_y = wxMin(min_y, rect.GetTop()); max_x = wxMax(max_x, rect.GetRight()); max_y = wxMax(max_y, rect.GetBottom()); } #else int min_x = 0; int min_y = 0; int max_x = 1000000000; int max_y = 1000000000; #endif // is_maximized win_x win_y win_width win_height top_pos bottom_height view_pos view_height_width local_pos remote_pos wxString posString = COptions::Get()->GetOption(OPTION_WINDOW_POSITION); wxStringTokenizer tokens(posString, _T(" ")); int count = tokens.CountTokens(); if (count == 11) { long * aPosValues = new long[count]; for (int i = 0; i < count; i++) { wxString token = tokens.GetNextToken(); if (!token.ToLong(aPosValues + i)) { delete [] aPosValues; return; } } // Make sure position is (somewhat) sane int pos_x = wxMin(max_x - 30, aPosValues[1]); int pos_y = wxMin(max_y - 30, aPosValues[2]); int client_width = aPosValues[3]; int client_height = aPosValues[4]; if (pos_x + client_width - 30 < min_x) pos_x = min_x; if (pos_y + client_height - 30 < min_y) pos_y = min_y; if (aPosValues[0]) { // We need to move so it appears on the proper display on multi-monitor systems Move(pos_x, pos_y); // We need to call SetClientSize here too. Since window isn't yet shown here, Maximize // doesn't actually resize the window till it is shown // The slight off-size is needed to ensure the client sizes gets changed at least once. // Otherwise all the splitters would have default size still. SetClientSize(client_width + 1, client_height); // A 2nd call is neccessary, for some reason the first call // doesn't fully set the height properly at least under wxMSW SetClientSize(client_width, client_height); Maximize(); } else { Move(pos_x, pos_y); // The slight off-size is needed to ensure the client sizes gets changed at least once. // Otherwise all the splitters would have default size still. SetClientSize(client_width + 1, client_height); // A 2nd call is neccessary, for some reason the first call // doesn't fully set the height properly at least under wxMSW SetClientSize(client_width, client_height); } m_lastLogViewSplitterPos = aPosValues[5]; m_pTopSplitter->SetSashPosition(m_lastLogViewSplitterPos); int x, y; m_pBottomSplitter->GetClientSize(&x, &y); y -= aPosValues[6]; if (y < 100) y = 100; m_lastQueueSplitterPos = y; m_pBottomSplitter->SetSashPosition(m_lastQueueSplitterPos); m_ViewSplitterSashPos = (float)aPosValues[7] / aPosValues[8]; m_pViewSplitter->SetSashPosition(aPosValues[7]); m_lastLocalTreeSplitterPos = aPosValues[9]; m_lastRemoteTreeSplitterPos = aPosValues[10]; m_pLocalSplitter->SetSashPosition(m_lastLocalTreeSplitterPos); m_pRemoteSplitter->SetSashPosition(m_lastRemoteTreeSplitterPos); delete [] aPosValues; } }