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