#ifndef __STATE_H__ #define __STATE_H__ #include "local_path.h" #include enum t_statechange_notifications { STATECHANGE_NONE, // Used to unregister all notifications STATECHANGE_REMOTE_DIR, STATECHANGE_REMOTE_DIR_OTHER, STATECHANGE_REMOTE_RECV, STATECHANGE_REMOTE_SEND, STATECHANGE_REMOTE_LINKNOTDIR, STATECHANGE_LOCAL_DIR, // data contains name (excluding path) of file to refresh STATECHANGE_LOCAL_REFRESH_FILE, STATECHANGE_APPLYFILTER, STATECHANGE_REMOTE_IDLE, STATECHANGE_SERVER, STATECHANGE_ENCRYPTION, STATECHANGE_SYNC_BROWSE, STATECHANGE_COMPARISON, STATECHANGE_RECURSION_STATUS, /* Global notifications */ STATECHANGE_QUEUEPROCESSING, STATECHANGE_NEWCONTEXT, /* New context created */ STATECHANGE_CHANGEDCONTEXT, /* Currently active context changed */ STATECHANGE_REMOVECONTEXT, /* Right before deleting a context */ STATECHANGE_MAX }; class CDirectoryListing; class CFileZillaEngine; class CCommandQueue; class CMainFrame; class CStateEventHandler; class CRemoteDataObject; class CRecursiveOperation; class CComparisonManager; class CState; class CContextManager final { friend class CState; public: // If current_only is set, only notifications from the current (at the time // of notification emission) context is dispatched to the handler. void RegisterHandler(CStateEventHandler* pHandler, enum t_statechange_notifications notification, bool current_only); void UnregisterHandler(CStateEventHandler* pHandler, enum t_statechange_notifications notification); size_t HandlerCount(enum t_statechange_notifications notification) const; CState* CreateState(CMainFrame &mainFrame); void DestroyState(CState* pState); void DestroyAllStates(); CState* GetCurrentContext(); const std::vector* GetAllStates() { return &m_contexts; } static CContextManager* Get(); void NotifyAllHandlers(enum t_statechange_notifications notification, const wxString& data = _T(""), const void* data2 = 0); void NotifyGlobalHandlers(enum t_statechange_notifications notification, const wxString& data = _T(""), const void* data2 = 0); void SetCurrentContext(CState* pState); protected: CContextManager(); std::vector m_contexts; int m_current_context; struct t_handler { CStateEventHandler* pHandler; bool current_only; }; std::vector m_handlers[STATECHANGE_MAX]; void NotifyHandlers(CState* pState, enum t_statechange_notifications notification, const wxString& data, const void* data2); static CContextManager m_the_context_manager; }; class CState final { friend class CCommandQueue; public: CState(CMainFrame& mainFrame); ~CState(); CState(CState const&) = delete; CState& operator=(CState const&) = delete; bool CreateEngine(); void DestroyEngine(); CLocalPath GetLocalDir() const; bool SetLocalDir(CLocalPath const& dir, wxString *error = 0, bool rememberPreviousSubdir = true); bool SetLocalDir(const wxString& dir, wxString *error = 0, bool rememberPreviousSubdir = true); bool Connect(const CServer& server, const CServerPath& path = CServerPath()); bool Disconnect(); bool ChangeRemoteDir(const CServerPath& path, const wxString& subdir = _T(""), int flags = 0, bool ignore_busy = false); bool SetRemoteDir(std::shared_ptr const& pDirectoryListing, bool modified = false); std::shared_ptr GetRemoteDir() const; const CServerPath GetRemotePath() const; const CServer* GetServer() const; wxString GetTitle() const; void RefreshLocal(); void RefreshLocalFile(wxString file); void LocalDirCreated(const CLocalPath& path); bool RefreshRemote(); void RegisterHandler(CStateEventHandler* pHandler, enum t_statechange_notifications notification, CStateEventHandler* insertBefore = 0); void UnregisterHandler(CStateEventHandler* pHandler, enum t_statechange_notifications notification); CFileZillaEngine* m_pEngine{}; CCommandQueue* m_pCommandQueue{}; CComparisonManager* GetComparisonManager() { return m_pComparisonManager; } void UploadDroppedFiles(const wxFileDataObject* pFileDataObject, const wxString& subdir, bool queueOnly); void UploadDroppedFiles(const wxFileDataObject* pFileDataObject, const CServerPath& path, bool queueOnly); void HandleDroppedFiles(const wxFileDataObject* pFileDataObject, const CLocalPath& path, bool copy); bool DownloadDroppedFiles(const CRemoteDataObject* pRemoteDataObject, const CLocalPath& path, bool queueOnly = false); static bool RecursiveCopy(CLocalPath source, const CLocalPath& targte); bool IsRemoteConnected() const; bool IsRemoteIdle(bool ignore_recursive = false) const; CRecursiveOperation* GetRecursiveOperationHandler() { return m_pRecursiveOperation; } void NotifyHandlers(enum t_statechange_notifications notification, wxString const& data = wxString(), const void* data2 = 0); bool SuccessfulConnect() const { return m_successful_connect; } void SetSuccessfulConnect() { m_successful_connect = true; } void ListingFailed(int error); void LinkIsNotDir(const CServerPath& path, const wxString& subdir); bool SetSyncBrowse(bool enable, const CServerPath& assumed_remote_root = CServerPath()); bool GetSyncBrowse() const { return !m_sync_browse.local_root.empty(); } CServer GetLastServer() const { return m_last_server; } CServerPath GetLastServerPath() const { return m_last_path; } void SetLastServer(const CServer& server, const CServerPath& path) { m_last_server = server; m_last_path = path; } bool GetSecurityInfo(CCertificateNotification *& pInfo); bool GetSecurityInfo(CSftpEncryptionNotification *& pInfo); void SetSecurityInfo(CCertificateNotification const& info); void SetSecurityInfo(CSftpEncryptionNotification const& info); // If the previously selected directory was a direct child of the current directory, this // returns the relative name of the subdirectory. wxString GetPreviouslyVisitedLocalSubdir() const { return m_previouslyVisitedLocalSubdir; } wxString GetPreviouslyVisitedRemoteSubdir() const { return m_previouslyVisitedRemoteSubdir; } void ClearPreviouslyVisitedLocalSubdir() { m_previouslyVisitedLocalSubdir = _T(""); } void ClearPreviouslyVisitedRemoteSubdir() { m_previouslyVisitedRemoteSubdir = _T(""); } protected: void SetServer(const CServer* server, CServerPath const& path = CServerPath()); CLocalPath m_localDir; std::shared_ptr m_pDirectoryListing; CServer* m_pServer{}; wxString m_title; bool m_successful_connect{}; CServer m_last_server; CServerPath m_last_path; CMainFrame& m_mainFrame; CRecursiveOperation* m_pRecursiveOperation; CComparisonManager* m_pComparisonManager; struct t_handler { CStateEventHandler* pHandler; }; std::vector m_handlers[STATECHANGE_MAX]; CLocalPath GetSynchronizedDirectory(CServerPath remote_path); CServerPath GetSynchronizedDirectory(CLocalPath local_path); struct _sync_browse { CLocalPath local_root; CServerPath remote_root; bool is_changing; bool compare; // The target path when changing remote directory CServerPath target_path; } m_sync_browse; std::unique_ptr m_pCertificate; std::unique_ptr m_pSftpEncryptionInfo; wxString m_previouslyVisitedLocalSubdir; wxString m_previouslyVisitedRemoteSubdir; }; class CStateEventHandler { public: CStateEventHandler(CState* pState); virtual ~CStateEventHandler(); CState* m_pState; virtual void OnStateChange(CState* pState, enum t_statechange_notifications notification, const wxString& data, const void* data2) = 0; }; #endif