1 #ifndef FILEZILLA_INTERFACE_STATE_HEADER
2 #define FILEZILLA_INTERFACE_STATE_HEADER
3 
4 #include "filter_manager.h"
5 #include "sitemanager.h"
6 #include "sitemanager_dialog.h"
7 
8 #include "../include/local_path.h"
9 
10 #include <memory>
11 
12 enum t_statechange_notifications
13 {
14 	STATECHANGE_NONE, // Used to unregister all notifications
15 
16 	STATECHANGE_REMOTE_DIR,
17 	STATECHANGE_REMOTE_DIR_OTHER,
18 	STATECHANGE_REMOTE_RECV,
19 	STATECHANGE_REMOTE_SEND,
20 	STATECHANGE_REMOTE_LINKNOTDIR,
21 	STATECHANGE_LOCAL_DIR,
22 
23 	// data contains name (excluding path) of file to refresh
24 	STATECHANGE_LOCAL_REFRESH_FILE,
25 
26 	STATECHANGE_APPLYFILTER,
27 
28 	STATECHANGE_REMOTE_IDLE,
29 	STATECHANGE_SERVER,
30 	STATECHANGE_ENCRYPTION,
31 
32 	STATECHANGE_SYNC_BROWSE,
33 	STATECHANGE_COMPARISON,
34 
35 	STATECHANGE_REMOTE_RECURSION_STATUS,
36 	STATECHANGE_LOCAL_RECURSION_STATUS,
37 
38 	STATECHANGE_LOCAL_RECURSION_LISTING,
39 
40 	/* Global notifications */
41 	STATECHANGE_QUEUEPROCESSING,
42 	STATECHANGE_NEWCONTEXT, /* New context created */
43 	STATECHANGE_CHANGEDCONTEXT, /* Currently active context changed */
44 	STATECHANGE_REMOVECONTEXT, /* Right before deleting a context */
45 	STATECHANGE_GLOBALBOOKMARKS,
46 	STATECHANGE_REWRITE_CREDENTIALS,
47 
48 	STATECHANGE_QUITNOW,
49 
50 	STATECHANGE_MAX
51 };
52 
53 class CDirectoryListing;
54 class CFileZillaEngine;
55 class CCommandQueue;
56 class CLocalDataObject;
57 class CLocalRecursiveOperation;
58 class CMainFrame;
59 class CGlobalStateEventHandler;
60 class CStateEventHandler;
61 class CRemoteDataObject;
62 class CRemoteRecursiveOperation;
63 class CComparisonManager;
64 
65 class CStateFilterManager final : public CFilterManager
66 {
67 public:
68 	virtual bool FilenameFiltered(std::wstring const& name, std::wstring const& path, bool dir, int64_t size, bool local, int attributes, fz::datetime const& date) const override;
69 
GetLocalFilter()70 	CFilter const& GetLocalFilter() const { return m_localFilter; }
SetLocalFilter(CFilter const & filter)71 	void SetLocalFilter(CFilter const& filter) { m_localFilter = filter; }
72 
GetRemoteFilter()73 	CFilter const& GetRemoteFilter() const { return m_remoteFilter; }
SetRemoteFilter(CFilter const & filter)74 	void SetRemoteFilter(CFilter const& filter) { m_remoteFilter = filter; }
75 
76 private:
77 	CFilter m_localFilter;
78 	CFilter m_remoteFilter;
79 };
80 
81 class CState;
82 class CContextManager final
83 {
84 	friend class CState;
85 public:
86 	// If current_only is set, only notifications from the current (at the time
87 	// of notification emission) context is dispatched to the handler.
88 	void RegisterHandler(CGlobalStateEventHandler* pHandler, t_statechange_notifications notification, bool current_only);
89 	void UnregisterHandler(CGlobalStateEventHandler* pHandler, t_statechange_notifications notification);
90 
91 	size_t HandlerCount(t_statechange_notifications notification) const;
92 
93 	CState* CreateState(CMainFrame &mainFrame);
94 	void DestroyState(CState* pState);
95 	void DestroyAllStates();
96 
97 	CState* GetCurrentContext();
GetAllStates()98 	const std::vector<CState*>* GetAllStates() { return &m_contexts; }
99 
100 	static CContextManager* Get();
101 
102 	void NotifyAllHandlers(t_statechange_notifications notification, std::wstring const& data = std::wstring(), void const* data2 = 0);
103 	void NotifyGlobalHandlers(t_statechange_notifications notification, std::wstring const& data = std::wstring(), void const* data2 = 0);
104 
105 	void SetCurrentContext(CState* pState);
106 
107 	void ProcessDirectoryListing(CServer const& server, std::shared_ptr<CDirectoryListing> const& listing, CState const* exempt);
108 
109 protected:
110 	CContextManager();
111 
112 	std::vector<CState*> m_contexts;
113 	int m_current_context;
114 
115 	struct t_handler
116 	{
117 		CGlobalStateEventHandler* pHandler;
118 		bool current_only;
119 	};
120 	std::vector<t_handler> m_handlers[STATECHANGE_MAX];
121 
122 	void NotifyHandlers(CState* pState, t_statechange_notifications notification, std::wstring const& data, void const* data2);
123 
124 	static CContextManager m_the_context_manager;
125 };
126 
127 class CState final
128 {
129 	friend class CCommandQueue;
130 public:
131 	CState(CMainFrame& mainFrame);
132 	~CState();
133 
134 	CState(CState const&) = delete;
135 	CState& operator=(CState const&) = delete;
136 
137 	bool CreateEngine();
138 	void DestroyEngine();
139 
140 	CLocalPath GetLocalDir() const;
141 	bool SetLocalDir(CLocalPath const& dir, std::wstring *error = 0, bool rememberPreviousSubdir = true);
142 	bool SetLocalDir(std::wstring const& dir, std::wstring *error = 0, bool rememberPreviousSubdir = true);
143 
144 	bool Connect(Site const& site, CServerPath const& path = CServerPath(), bool compare = false);
145 	bool Disconnect();
146 
147 	bool ChangeRemoteDir(CServerPath const& path, std::wstring const& subdir = std::wstring(), int flags = 0, bool ignore_busy = false, bool compare = false);
148 	bool SetRemoteDir(std::shared_ptr<CDirectoryListing> const& pDirectoryListing, bool primary);
149 	std::shared_ptr<CDirectoryListing> GetRemoteDir() const;
150 	const CServerPath GetRemotePath() const;
151 
152 	Site const& GetSite() const;
153 	wxString GetTitle() const;
154 
155 	void RefreshLocal();
156 	void RefreshLocalFile(std::wstring const& file);
157 	void LocalDirCreated(CLocalPath const& path);
158 
159 	bool RefreshRemote(bool clear_cache = false);
160 
161 	void RegisterHandler(CStateEventHandler* pHandler, t_statechange_notifications notification, CStateEventHandler* insertBefore = 0);
162 	void UnregisterHandler(CStateEventHandler* pHandler, t_statechange_notifications notification);
163 
164 	std::unique_ptr<CFileZillaEngine> engine_;
165 	CCommandQueue* m_pCommandQueue{};
GetComparisonManager()166 	CComparisonManager* GetComparisonManager() { return m_pComparisonManager; }
167 
168 	void UploadDroppedFiles(CLocalDataObject const* pLocalDataObject, std::wstring const& subdir, bool queueOnly);
169 	void UploadDroppedFiles(wxFileDataObject const* pFileDataObject, std::wstring const& subdir, bool queueOnly);
170 	void UploadDroppedFiles(CLocalDataObject const* pLocalDataObject, CServerPath const& path, bool queueOnly);
171 	void UploadDroppedFiles(wxFileDataObject const* pFileDataObject, CServerPath const& path, bool queueOnly);
172 	void HandleDroppedFiles(CLocalDataObject const* pLocalDataObject, CLocalPath const& path, bool copy);
173 	void HandleDroppedFiles(wxFileDataObject const* pFileDataObject, CLocalPath const& path, bool copy);
174 	bool DownloadDroppedFiles(CRemoteDataObject const* pRemoteDataObject, CLocalPath const& path, bool queueOnly = false);
175 
176 	static bool RecursiveCopy(CLocalPath source, CLocalPath const& targte);
177 
178 	bool IsRemoteConnected() const;
179 	bool IsRemoteIdle(bool ignore_recursive = false) const;
180 	bool IsLocalIdle(bool ignore_recursive = false) const;
181 
GetLocalRecursiveOperation()182 	CLocalRecursiveOperation* GetLocalRecursiveOperation() { return m_pLocalRecursiveOperation; }
GetRemoteRecursiveOperation()183 	CRemoteRecursiveOperation* GetRemoteRecursiveOperation() { return m_pRemoteRecursiveOperation; }
184 
185 	void NotifyHandlers(t_statechange_notifications notification, std::wstring const& data = std::wstring(), void const* data2 = 0);
186 
SuccessfulConnect()187 	bool SuccessfulConnect() const { return m_successful_connect; }
SetSuccessfulConnect()188 	void SetSuccessfulConnect() { m_successful_connect = true; }
189 
190 	void ListingFailed(int error);
191 	void LinkIsNotDir(CServerPath const& path, std::wstring const& subdir);
192 
193 	bool SetSyncBrowse(bool enable, CServerPath const& assumed_remote_root = CServerPath());
GetSyncBrowse()194 	bool GetSyncBrowse() const { return !m_sync_browse.local_root.empty(); }
195 
GetLastSite()196 	Site const& GetLastSite() const { return m_last_site; }
GetLastServerPath()197 	CServerPath GetLastServerPath() const { return m_last_path; }
SetLastSite(Site const & server,CServerPath const & path)198 	void SetLastSite(Site const& server, CServerPath const& path)
199 		{ m_last_site = server; m_last_path = path; }
200 
201 	bool GetSecurityInfo(CCertificateNotification *& pInfo);
202 	bool GetSecurityInfo(CSftpEncryptionNotification *& pInfo);
203 	void SetSecurityInfo(CCertificateNotification const& info);
204 	void SetSecurityInfo(CSftpEncryptionNotification const& info);
205 
206 	// If the previously selected directory was a direct child of the current directory, this
207 	// returns the relative name of the subdirectory.
GetPreviouslyVisitedLocalSubdir()208 	std::wstring GetPreviouslyVisitedLocalSubdir() const { return m_previouslyVisitedLocalSubdir; }
GetPreviouslyVisitedRemoteSubdir()209 	std::wstring GetPreviouslyVisitedRemoteSubdir() const { return m_previouslyVisitedRemoteSubdir; }
ClearPreviouslyVisitedLocalSubdir()210 	void ClearPreviouslyVisitedLocalSubdir() { m_previouslyVisitedLocalSubdir.clear(); }
ClearPreviouslyVisitedRemoteSubdir()211 	void ClearPreviouslyVisitedRemoteSubdir() { m_previouslyVisitedRemoteSubdir.clear(); }
212 
213 	void UpdateKnownSites(std::vector<CSiteManagerDialog::_connected_site> const& active_sites);
214 	void UpdateSite(std::wstring const& oldPath, Site const& newSite);
215 
GetStateFilterManager()216 	CStateFilterManager& GetStateFilterManager() { return m_stateFilterManager; }
217 
218 	void ChangeServer(CServer const& newServer);
219 
220 	fz::thread_pool & pool_;
221 
222 protected:
223 	void SetSite(Site const& site, CServerPath const& path = CServerPath());
224 
225 	void UpdateTitle();
226 
227 	CLocalPath m_localDir;
228 	std::shared_ptr<CDirectoryListing> m_pDirectoryListing;
229 
230 	Site m_site;
231 
232 	wxString m_title;
233 	bool m_successful_connect{};
234 
235 	Site m_last_site;
236 	CServerPath m_last_path;
237 
238 	CMainFrame& m_mainFrame;
239 
240 	CLocalRecursiveOperation* m_pLocalRecursiveOperation;
241 	CRemoteRecursiveOperation* m_pRemoteRecursiveOperation;
242 
243 	CComparisonManager* m_pComparisonManager;
244 
245 	CStateFilterManager m_stateFilterManager;
246 
247 	struct t_handlersForNotification
248 	{
249 		std::vector<CStateEventHandler*> handlers;
250 		bool compact_{};
251 		bool inNotify_{};
252 	};
253 
254 	t_handlersForNotification m_handlers[STATECHANGE_MAX];
255 
256 	CLocalPath GetSynchronizedDirectory(CServerPath remote_path);
257 	CServerPath GetSynchronizedDirectory(CLocalPath local_path);
258 
259 	struct _sync_browse
260 	{
261 		CLocalPath local_root;
262 		CServerPath remote_root;
263 
264 		// The target path when changing remote directory
265 		CServerPath target_path;
266 	} m_sync_browse;
267 
268 	struct _post_setdir
269 	{
270 		bool compare{};
271 		bool syncbrowse{};
272 	} m_changeDirFlags;
273 
274 	std::unique_ptr<CCertificateNotification> m_pCertificate;
275 	std::unique_ptr<CSftpEncryptionNotification> m_pSftpEncryptionInfo;
276 
277 	std::wstring m_previouslyVisitedLocalSubdir;
278 	std::wstring m_previouslyVisitedRemoteSubdir;
279 };
280 
281 class CGlobalStateEventHandler
282 {
283 public:
284 	CGlobalStateEventHandler() = default;
285 	virtual ~CGlobalStateEventHandler();
286 
287 	virtual void OnStateChange(CState* pState, t_statechange_notifications notification, std::wstring const& data, const void* data2) = 0;
288 };
289 
290 class CStateEventHandler
291 {
292 public:
293 	CStateEventHandler(CState& state);
294 	virtual ~CStateEventHandler();
295 
296 	CState& m_state;
297 
298 	virtual void OnStateChange(t_statechange_notifications notification, std::wstring const& data, const void* data2) = 0;
299 };
300 
301 #endif
302