1 #ifndef FILEZILLA_INTERFACE_QUEUEVIEW_HEADER
2 #define FILEZILLA_INTERFACE_QUEUEVIEW_HEADER
3 
4 #include "dndobjects.h"
5 #include "local_recursive_operation.h"
6 #include "option_change_event_handler.h"
7 #include "queue.h"
8 #include "queue_storage.h"
9 #include "state.h"
10 
11 #include "../include/libfilezilla_engine.h"
12 #include "../include/notification.h"
13 
14 #include <wx/progdlg.h>
15 
16 #include <list>
17 #include <set>
18 
19 namespace ActionAfterState {
20 enum type {
21 	None,
22 	ShowNotification,
23 	RequestAttention,
24 	Close,
25 	RunCommand,
26 	PlaySound,
27 
28 	// On Windows and OS X, wx can reboot or shutdown the system as well.
29 	Reboot,
30 	Shutdown,
31 	Sleep,
32 	CloseOnce,
33 
34 	Count
35 };
36 }
37 
38 class CStatusLineCtrl;
39 class CFileItem;
40 struct t_EngineData final
41 {
t_EngineDatafinal42 	t_EngineData()
43 		: pEngine()
44 		, active()
45 		, transient()
46 		, state(t_EngineData::none)
47 		, pItem()
48 		, pStatusLineCtrl()
49 		, m_idleDisconnectTimer()
50 	{
51 	}
52 
~t_EngineDatafinal53 	~t_EngineData()
54 	{
55 		wxASSERT(!active);
56 		if (!transient)
57 			delete pEngine;
58 		delete m_idleDisconnectTimer;
59 	}
60 
61 	CFileZillaEngine* pEngine;
62 	bool active;
63 	bool transient;
64 
65 	enum EngineDataState
66 	{
67 		none,
68 		cancel,
69 		disconnect,
70 		connect,
71 		transfer,
72 		list,
73 		mkdir,
74 		askpassword,
75 		waitprimary
76 	} state;
77 
78 	CFileItem* pItem;
79 	Site lastSite;
80 	CStatusLineCtrl* pStatusLineCtrl;
81 	wxTimer* m_idleDisconnectTimer;
82 };
83 
84 class CMainFrame;
85 class CStatusLineCtrl;
86 class CAsyncRequestQueue;
87 class CQueue;
88 #if WITH_LIBDBUS
89 class CDesktopNotification;
90 #elif defined(__WXGTK__) || defined(__WXMSW__)
91 class wxNotificationMessage;
92 #endif
93 
94 class CActionAfterBlocker final
95 {
96 public:
CActionAfterBlocker(CQueueView & queueView)97 	CActionAfterBlocker(CQueueView& queueView)
98 		: queueView_(queueView)
99 	{
100 	}
101 
102 	~CActionAfterBlocker();
103 
104 private:
105 	friend class CQueueView;
106 	CQueueView& queueView_;
107 	bool trigger_{};
108 };
109 
110 class CQueueView final : public CQueueViewBase, public COptionChangeEventHandler, public CGlobalStateEventHandler
111 {
112 	friend class CQueueViewDropTarget;
113 	friend class CQueueViewFailed;
114 	friend class CActionAfterBlocker;
115 
116 public:
117 	CQueueView(CQueue* parent, int index, CMainFrame* pMainFrame, CAsyncRequestQueue* pAsyncRequestQueue, cert_store & certStore);
118 	virtual ~CQueueView();
119 
120 	bool QueueFile(bool const queueOnly, bool const download,
121 		std::wstring const& sourceFile, std::wstring const& targetFile,
122 		CLocalPath const& localPath, CServerPath const& remotePath,
123 		Site const& site, int64_t size, CEditHandler::fileType edit = CEditHandler::none,
124 		QueuePriority priority = QueuePriority::normal);
125 
126 	void QueueFile_Finish(const bool start); // Need to be called after QueueFile
127 	bool QueueFiles(const bool queueOnly, CLocalPath const& localPath, const CRemoteDataObject& dataObject);
128 	bool QueueFiles(const bool queueOnly, Site const& site, CLocalRecursiveOperation::listing const& listing);
129 
130 	bool empty() const;
IsActive()131 	int IsActive() const { return m_activeMode; }
132 	bool SetActive(bool active = true);
133 	bool Quit();
134 
135 	// This sets the default file exists action for all files currently in queue.
136 	void SetDefaultFileExistsAction(CFileExistsNotification::OverwriteAction action, const TransferDirection direction);
137 
138 	void UpdateItemSize(CFileItem* pItem, int64_t size);
139 
140 	void RemoveAll();
141 
142 	void LoadQueue();
143 	void ImportQueue(pugi::xml_node element, bool updateSelections);
144 
145 	virtual void InsertItem(CServerItem* pServerItem, CQueueItem* pItem) override;
146 
147 	virtual void CommitChanges() override;
148 
149 	void ProcessNotification(CFileZillaEngine* pEngine, std::unique_ptr<CNotification>&& pNotification);
150 
151 	void RenameFileInTransfer(CFileZillaEngine *pEngine, std::wstring const& newName, bool local, writer_factory_holder & new_writer);
152 
153 	static std::wstring ReplaceInvalidCharacters(std::wstring const& filename, bool includeQuotesAndBreaks = false);
154 
155 	std::shared_ptr<CActionAfterBlocker> GetActionAfterBlocker();
156 
157 protected:
158 
159 #ifdef __WXMSW__
160 	WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
161 #endif
162 
163 	virtual void OnOptionsChanged(watched_options const& options) override;
164 
165 	void AdvanceQueue(bool refresh = true);
166 	bool TryStartNextTransfer();
167 
168 	// Called from TryStartNextTransfer(), checks
169 	// whether it is allowed to start another transfer on that server item
170 	bool CanStartTransfer(const CServerItem& server_item, t_EngineData *&pEngineData);
171 
172 	void ProcessReply(t_EngineData* pEngineData, COperationNotification const& notification);
173 	void SendNextCommand(t_EngineData& engineData);
174 
175 	enum class ResetReason
176 	{
177 		success,
178 		failure,
179 		reset,
180 		retry,
181 		remove
182 	};
183 
184 	void ResetEngine(t_EngineData& data, const ResetReason reason);
185 	void DeleteEngines();
186 
187 	virtual bool RemoveItem(CQueueItem* item, bool destroy, bool updateItemCount = true, bool updateSelections = true, bool forward = true) override;
188 
189 	// Stops processing of given item
190 	// Returns true on success, false if it would block
191 	bool StopItem(CFileItem* item);
192 	bool StopItem(CServerItem* pServerItem, bool updateSelections);
193 
194 	void CheckQueueState();
195 	bool IncreaseErrorCount(t_EngineData& engineData);
196 	void UpdateStatusLinePositions();
197 	void CalculateQueueSize();
198 	void DisplayQueueSize();
199 	void SaveQueue(bool silent = false);
200 
201 	bool IsActionAfter(ActionAfterState::type);
202 	void ActionAfter(bool warned = false);
203 #if defined(__WXMSW__) || defined(__WXMAC__)
204 	void ActionAfterWarnUser(ActionAfterState::type s);
205 #endif
206 
207 	void ProcessNotification(t_EngineData* pEngineData, std::unique_ptr<CNotification> && pNotification);
208 
209 	// Tries to refresh the current remote directory listing
210 	// if there's an idle engine connected to the current server of
211 	// the primary connection.
212 	void TryRefreshListings();
213 	CServer m_last_refresh_server;
214 	CServerPath m_last_refresh_path;
215 	fz::monotonic_clock m_last_refresh_listing_time;
216 
217 	bool IsOtherEngineConnected(t_EngineData* pEngineData);
218 
219 	t_EngineData* GetIdleEngine(Site const& site = Site(), bool allowTransient = false);
220 	t_EngineData* GetEngineData(const CFileZillaEngine* pEngine);
221 
222 	std::vector<t_EngineData*> m_engineData;
223 	std::list<CStatusLineCtrl*> m_statusLineList;
224 
225 	/*
226 	 * Don't update status line positions if m_waitStatusLineUpdate is true.
227 	 * This assures we are updating the status line positions only once,
228 	 * and not multiple times (for example inside a loop).
229 	 */
230 	bool m_waitStatusLineUpdate{};
231 
232 	// Remember last top item in UpdateStatusLinePositions()
233 	int m_lastTopItem{-1};
234 
235 	int m_activeCount{};
236 	int m_activeCountDown{};
237 	int m_activeCountUp{};
238 	int m_activeMode{}; // 0 inactive, 1 only immediate transfers, 2 all
239 	int m_quit{};
240 
241 	ActionAfterState::type m_actionAfterState;
242 #if defined(__WXMSW__) || defined(__WXMAC__)
243 	wxTimer* m_actionAfterTimer{};
244 	wxProgressDialog* m_actionAfterWarnDialog{};
245 	int m_actionAfterTimerCount{};
246 	int m_actionAfterTimerId{-1};
247 #endif
248 
249 	int64_t m_totalQueueSize{};
250 	int m_filesWithUnknownSize{};
251 
252 	CMainFrame* m_pMainFrame;
253 	CAsyncRequestQueue* m_pAsyncRequestQueue;
254 	cert_store & cert_store_;
255 
256 	std::list<CFileZillaEngine*> m_waitingForPassword;
257 
258 	virtual void OnPostScroll() override;
259 
260 	int GetLineHeight();
261 	int m_line_height;
262 #ifdef __WXMSW__
263 	int m_header_height;
264 #endif
265 
266 	wxTimer m_resize_timer;
267 
268 	void ReleaseExclusiveEngineLock(CFileZillaEngine* pEngine);
269 
270 #if WITH_LIBDBUS
271 	std::unique_ptr<CDesktopNotification> m_desktop_notification;
272 #elif defined(__WXGTK__) || defined(__WXMSW__)
273 	std::unique_ptr<wxNotificationMessage> m_desktop_notification;
274 #endif
275 
276 	CQueueStorage m_queue_storage;
277 
278 	void OnEngineEvent(CFileZillaEngine* engine);
279 
280 	void OnAskPassword();
281 
282 	std::weak_ptr<CActionAfterBlocker> m_actionAfterBlocker;
283 
284 	virtual void OnStateChange(CState* pState, t_statechange_notifications notification, std::wstring const& data, const void* data2) override;
285 
286 	DECLARE_EVENT_TABLE()
287 	void OnChar(wxKeyEvent& event);
288 
289 	// Context menu handlers
290 	void OnContextMenu(wxContextMenuEvent& event);
291 	void OnProcessQueue(wxCommandEvent& event);
292 	void OnStopAndClear(wxCommandEvent& event);
293 	void OnRemoveSelected(wxCommandEvent& event);
294 	void OnSetDefaultFileExistsAction(wxCommandEvent& event);
295 
296 	void OnTimer(wxTimerEvent& evnet);
297 
298 	void OnSetPriority(wxCommandEvent& event);
299 
300 	void OnExclusiveEngineRequestGranted(wxCommandEvent& event);
301 
302 	void OnActionAfter(wxCommandEvent& event);
303 	void OnActionAfterTimerTick();
304 
305 	void OnSize(wxSizeEvent& event);
306 
307 	void OnColumnClicked(wxListEvent &event);
308 };
309 
310 #endif
311