1 #ifndef FILEZILLA_INTERFACE_QUEUE_HEADER
2 #define FILEZILLA_INTERFACE_QUEUE_HEADER
3 
4 #include "aui_notebook_ex.h"
5 #include "listctrlex.h"
6 #include "edithandler.h"
7 #include <libfilezilla/optional.hpp>
8 
9 enum class QueuePriority : unsigned char {
10 	lowest,
11 	low,
12 	normal,
13 	high,
14 	highest,
15 
16 	count
17 };
18 
19 enum class QueueItemType {
20 	Server,
21 	File,
22 	Folder,
23 	Status
24 };
25 
26 enum class TransferDirection
27 {
28 	both,
29 	download,
30 	upload
31 };
32 
33 namespace pugi { class xml_node; }
34 class CQueueItem
35 {
36 public:
37 	virtual ~CQueueItem();
38 
39 	virtual void SetPriority(QueuePriority priority);
40 
41 	virtual void AddChild(CQueueItem* pItem);
42 	virtual unsigned int GetChildrenCount(bool recursive) const;
43 	virtual CQueueItem* GetChild(unsigned int item, bool recursive = true);
GetParent()44 	CQueueItem* GetParent() { return m_parent; }
GetParent()45 	const CQueueItem* GetParent() const { return m_parent; }
SetParent(CQueueItem * parent)46 	void SetParent(CQueueItem* parent) { m_parent = parent; }
47 
48 	virtual bool RemoveChild(CQueueItem* pItem, bool destroy = true, bool forward = true); // Removes a child item with is somewhere in the tree of children.
49 	virtual bool TryRemoveAll() = 0; // Removes a inactive childrens, queues active children for removal. Returns true if item itself can be removed
50 	CQueueItem* GetTopLevelItem();
51 	const CQueueItem* GetTopLevelItem() const;
52 	int GetItemIndex() const; // Return the visible item index relative to the topmost parent item.
SaveItem(pugi::xml_node &)53 	virtual void SaveItem(pugi::xml_node&) const {}
54 
55 	virtual QueueItemType GetType() const = 0;
56 
GetTime()57 	fz::datetime GetTime() const { return m_time; }
UpdateTime()58 	void UpdateTime() { m_time = fz::datetime::now(); }
59 
GetRemovedAtFront()60 	int GetRemovedAtFront() const { return m_removed_at_front; }
61 
62 protected:
63 	CQueueItem(CQueueItem* parent = 0);
64 
65 	CQueueItem* m_parent;
66 
67 	friend class CServerItem;
68 
69 	fz::datetime m_time;
70 
71 private:
72 	std::vector<CQueueItem*> m_children;
73 
74 	// Number of items removed at front of list
75 	// Increased instead of calling slow m_children.erase(0),
76 	// resetted on insert.
77 	int m_removed_at_front{};
78 };
79 
80 class CFileItem;
81 class CServerItem final : public CQueueItem
82 {
83 public:
84 	CServerItem(Site const& site);
85 	virtual ~CServerItem();
GetType()86 	virtual QueueItemType GetType() const override { return QueueItemType::Server; }
87 
GetSite()88 	Site const& GetSite() const { return site_; }
GetCredentials()89 	ProtectedCredentials& GetCredentials() {return site_.credentials; }
90 	wxString GetName() const;
91 
92 	virtual void AddChild(CQueueItem* pItem) override;
93 	virtual unsigned int GetChildrenCount(bool recursive) const override;
94 	virtual CQueueItem* GetChild(unsigned int item, bool recursive = true) override;
95 
96 	CFileItem* GetIdleChild(bool immadiateOnly, TransferDirection direction);
97 
98 	virtual bool RemoveChild(CQueueItem* pItem, bool destroy = true, bool forward = true) override; // Removes a child item with is somewhere in the tree of children
99 	virtual bool TryRemoveAll() override;
100 
101 	int64_t GetTotalSize(int& filesWithUnknownSize, int& queuedFiles) const;
102 
103 	void QueueImmediateFiles();
104 	void QueueImmediateFile(CFileItem* pItem);
105 
106 	virtual void SaveItem(pugi::xml_node& element) const override;
107 
108 	void SetDefaultFileExistsAction(CFileExistsNotification::OverwriteAction action, const TransferDirection direction);
109 
110 	void DetachChildren();
111 
112 	virtual void SetPriority(QueuePriority priority) override;
113 
114 	void SetChildPriority(CFileItem* pItem, QueuePriority oldPriority, QueuePriority newPriority);
115 
116 	int m_activeCount;
117 
GetChildren()118 	const std::vector<CQueueItem*>& GetChildren() const { return m_children; }
119 
120 	void Sort(int col, bool reverse);
121 
122 protected:
123 	void AddFileItemToList(CFileItem* pItem);
124 	void RemoveFileItemFromList(CFileItem* pItem, bool forward);
125 
126 	Site site_;
127 
128 	// array of item lists, sorted by priority. Used by scheduler to find
129 	// next file to transfer
130 	// First index specifies whether the item is queued (0) or immediate (1)
131 	std::deque<CFileItem*> m_fileList[2][static_cast<int>(QueuePriority::count)];
132 
133 	friend class CQueueItem;
134 
135 	int m_visibleOffspring{}; // Visible offspring over all sublevels
136 	int m_maxCachedIndex{-1};
137 
138 	struct t_cacheItem
139 	{
140 		int index;
141 		int child;
142 	};
143 	std::vector<t_cacheItem> m_lookupCache;
144 };
145 
146 struct t_EngineData;
147 
148 namespace queue_flags
149 {
150 	auto constexpr queued = static_cast<transfer_flags>(0x01);
151 	auto constexpr active = static_cast<transfer_flags>(0x02);
152 	auto constexpr made_progess = static_cast<transfer_flags>(0x04);
153 	auto constexpr remove = static_cast<transfer_flags>(0x08);
154 	auto constexpr mask = static_cast<transfer_flags>(0x0f);
155 }
156 
157 class CFileItem : public CQueueItem
158 {
159 public:
160 	CFileItem(CServerItem* parent, transfer_flags const& flags,
161 		std::wstring const& sourceFile, std::wstring const& targetFile,
162 		CLocalPath const& localPath, CServerPath const& remotePath, int64_t size);
163 
164 	virtual ~CFileItem();
165 
166 	virtual void SetPriority(QueuePriority priority) override;
167 	void SetPriorityRaw(QueuePriority priority);
168 	QueuePriority GetPriority() const;
169 
GetLocalFile()170 	std::wstring const& GetLocalFile() const { return !Download() ? GetSourceFile() : (m_targetFile ? *m_targetFile : m_sourceFile); }
GetRemoteFile()171 	std::wstring const& GetRemoteFile() const { return Download() ? GetSourceFile() : (m_targetFile ? *m_targetFile : m_sourceFile); }
GetSourceFile()172 	std::wstring const& GetSourceFile() const { return m_sourceFile; }
GetTargetFile()173 	fz::sparse_optional<std::wstring> const& GetTargetFile() const { return m_targetFile; }
GetLocalPath()174 	CLocalPath const& GetLocalPath() const { return m_localPath; }
GetRemotePath()175 	CServerPath const& GetRemotePath() const { return m_remotePath; }
GetSize()176 	int64_t GetSize() const { return m_size; }
SetSize(int64_t size)177 	void SetSize(int64_t size) { m_size = size; }
Download()178 	inline bool Download() const { return flags_ & transfer_flags::download; }
179 
flags()180 	inline transfer_flags flags() const { return flags_; }
181 
queued()182 	inline bool queued() const { return flags_ & queue_flags::queued; }
set_queued(bool q)183 	inline void set_queued(bool q)
184 	{
185 		if (q) {
186 			flags_ |= queue_flags::queued;
187 		}
188 		else {
189 			flags_ -= queue_flags::queued;
190 		}
191 	}
192 
pending_remove()193 	inline bool pending_remove() const { return flags_ & queue_flags::remove; }
set_pending_remove(bool remove)194 	inline void set_pending_remove(bool remove)
195 	{
196 		if (remove) {
197 			flags_ |= queue_flags::remove;
198 		}
199 		else {
200 			flags_ -= queue_flags::remove;
201 		}
202 	}
203 
GetType()204 	virtual QueueItemType GetType() const override { return QueueItemType::File; }
205 
IsActive()206 	bool IsActive() const { return flags_ & queue_flags::active; }
207 	virtual void SetActive(bool active);
208 
209 	virtual void SaveItem(pugi::xml_node& element) const override;
210 
211 	// Removes inactive children, queues active children for removal.
212 	// Returns true if item can be removed itself
213 	virtual bool TryRemoveAll() override final;
214 
215 	void SetTargetFile(std::wstring const& file);
216 
217 	enum class Status : unsigned char {
218 		none,
219 		incorrect_password,
220 		timeout,
221 		disconnecting,
222 		disconnected,
223 		connecting,
224 		connection_failed,
225 		interrupted,
226 		wait_browsing,
227 		wait_password,
228 		local_file_unwriteable,
229 		could_not_start,
230 		transferring,
231 		creating_dir
232 	};
233 
234 	wxString const& GetStatusMessage() const;
235 	void SetStatusMessage(Status status);
236 
237 	CEditHandler::fileType m_edit{CEditHandler::none};
238 	CFileExistsNotification::OverwriteAction m_defaultFileExistsAction{CFileExistsNotification::unknown};
239 	CFileExistsNotification::OverwriteAction m_onetime_action{CFileExistsNotification::unknown};
240 	QueuePriority m_priority{QueuePriority::normal};
241 
242 protected:
243 
244 	transfer_flags flags_;
245 	Status m_status{};
246 
247 public:
248 	unsigned char m_errorCount{};
249 	t_EngineData* m_pEngineData{};
250 
251 
made_progress()252 	inline bool made_progress() const { return flags_ & queue_flags::made_progess; }
set_made_progress(bool made_progress)253 	inline void set_made_progress(bool made_progress)
254 	{
255 		if (made_progress) {
256 			flags_ |= queue_flags::made_progess;
257 		}
258 		else {
259 			flags_ -= queue_flags::made_progess;
260 		}
261 	}
262 
263 protected:
264 	std::wstring const m_sourceFile;
265 	fz::sparse_optional<std::wstring> m_targetFile;
266 	CLocalPath const m_localPath;
267 	CServerPath const m_remotePath;
268 	int64_t m_size{};
269 };
270 
271 class CFolderItem final : public CFileItem
272 {
273 public:
274 	CFolderItem(CServerItem* parent, bool queued, CLocalPath const& localPath);
275 	CFolderItem(CServerItem* parent, bool queued, CServerPath const& remotePath, std::wstring const& remoteFile);
276 
GetType()277 	virtual QueueItemType GetType() const override { return QueueItemType::Folder; }
278 
279 	virtual void SaveItem(pugi::xml_node& element) const override;
280 
281 	virtual void SetActive(bool active) override;
282 };
283 
284 class CStatusItem final : public CQueueItem
285 {
286 public:
287 	CStatusItem() = default;
288 	virtual ~CStatusItem() = default;
289 
GetType()290 	virtual QueueItemType GetType() const override { return QueueItemType::Status; }
291 
TryRemoveAll()292 	virtual bool TryRemoveAll() override { return true; }
293 };
294 
295 class CQueue;
296 class CQueueViewBase : public wxListCtrlEx
297 {
298 public:
299 
300 	enum ColumnId
301 	{
302 		colLocalName,
303 		colDirection,
304 		colRemoteName,
305 		colSize,
306 		colPriority,
307 		colTime,
308 		colTransferStatus,
309 		colErrorReason
310 	};
311 
312 	CQueueViewBase(CQueue* parent, int index, const wxString& title);
313 	virtual ~CQueueViewBase();
314 
315 	// Gets item for given server or creates new if it doesn't exist
316 	CServerItem* CreateServerItem(Site const& site);
317 
318 	virtual void InsertItem(CServerItem* pServerItem, CQueueItem* pItem);
319 	virtual bool RemoveItem(CQueueItem* pItem, bool destroy, bool updateItemCount = true, bool updateSelections = true, bool forward = true);
320 
321 	// Has to be called after adding or removing items. Also updates
322 	// item count and selections.
323 	virtual void CommitChanges();
324 
GetTitle()325 	wxString GetTitle() const { return m_title; }
326 
GetFileCount()327 	int GetFileCount() const { return m_fileCount; }
328 
329 	void WriteToFile(pugi::xml_node element) const;
330 
331 protected:
332 
333 	void CreateColumns(std::vector<ColumnId> const& extraColumns = std::vector<ColumnId>());
334 	void AddQueueColumn(ColumnId id);
335 
336 	// Gets item for given server
337 	CServerItem* GetServerItem(Site const& site);
338 
339 	// Gets item with given index
340 	CQueueItem* GetQueueItem(unsigned int item) const;
341 
342 	// Get index for given queue item
343 	int GetItemIndex(const CQueueItem* item);
344 
345 	virtual wxString OnGetItemText(long item, long column) const;
346 	virtual wxString OnGetItemText(CQueueItem* pItem, ColumnId column) const;
347 	virtual int OnGetItemImage(long item) const;
348 
349 	void RefreshItem(const CQueueItem* pItem);
350 
351 	void DisplayNumberQueuedFiles();
352 
353 	// Position at which insertions start and number of insertions
354 	int m_insertionStart{-1};
355 	unsigned int m_insertionCount{};
356 
357 	int m_fileCount{};
358 	bool m_fileCountChanged{};
359 
360 	// Selection management.
361 	void UpdateSelections_ItemAdded(int added);
362 	void UpdateSelections_ItemRangeAdded(int added, int count);
363 	void UpdateSelections_ItemRemoved(int removed);
364 	void UpdateSelections_ItemRangeRemoved(int removed, int count);
365 
366 	int m_itemCount{};
367 	bool m_allowBackgroundErase{true};
368 
369 	std::vector<CServerItem*> m_serverList;
370 
371 	CQueue* m_pQueue;
372 
373 	const int m_pageIndex;
374 
375 	const wxString m_title;
376 
377 	wxTimer m_filecount_delay_timer;
378 
379 	std::vector<ColumnId> m_columns;
380 
381 	DECLARE_EVENT_TABLE()
382 	void OnEraseBackground(wxEraseEvent& event);
383 	void OnChar(wxKeyEvent& event);
384 	void OnEndColumnDrag(wxListEvent& event);
385 	void OnTimer(wxTimerEvent& event);
386 	void OnKeyDown(wxKeyEvent& event);
387 	void OnExport(wxCommandEvent&);
388 };
389 
390 class CQueueView;
391 class CQueueViewFailed;
392 class CQueueViewSuccessful;
393 
394 class CMainFrame;
395 class CAsyncRequestQueue;
396 class cert_store;
397 class CQueue final : public wxAuiNotebookEx
398 {
399 public:
400 	CQueue(wxWindow* parent, CMainFrame* pMainFrame, CAsyncRequestQueue* pAsyncRequestQueue, cert_store & certStore);
~CQueue()401 	virtual ~CQueue() {}
402 
GetQueueView()403 	inline CQueueView* GetQueueView() { return m_pQueueView; }
GetQueueView_Failed()404 	inline CQueueViewFailed* GetQueueView_Failed() { return m_pQueueView_Failed; }
GetQueueView_Successful()405 	inline CQueueViewSuccessful* GetQueueView_Successful() { return m_pQueueView_Successful; }
406 
407 	virtual void SetFocus();
408 protected:
409 
410 	CQueueView* m_pQueueView{};
411 	CQueueViewFailed* m_pQueueView_Failed{};
412 	CQueueViewSuccessful* m_pQueueView_Successful{};
413 };
414 
415 #include "QueueView.h"
416 
417 #endif
418