#ifndef __QUEUEVIEW_H__ #define __QUEUEVIEW_H__ #include "dndobjects.h" #include "queue.h" #include #include #include #include #include "queue_storage.h" class CFolderProcessingEntry { public: enum t_type { dir, file }; const enum t_type m_type; CFolderProcessingEntry(enum t_type type) : m_type(type) {} virtual ~CFolderProcessingEntry() {} }; class t_newEntry : public CFolderProcessingEntry { public: t_newEntry() : CFolderProcessingEntry(CFolderProcessingEntry::file) {} wxString name; int64_t size{}; fz::datetime time; int attributes{}; bool dir{}; }; enum ActionAfterState { ActionAfterState_Disabled, ActionAfterState_Close, ActionAfterState_Disconnect, ActionAfterState_RunCommand, ActionAfterState_ShowMessage, ActionAfterState_PlaySound // On Windows and OS X, wx can reboot or shutdown the system as well. #if defined(__WXMSW__) || defined(__WXMAC__) , ActionAfterState_Reboot, ActionAfterState_Shutdown, ActionAfterState_Sleep #endif }; class CStatusLineCtrl; class CFileItem; struct t_EngineData { t_EngineData() : pEngine() , active() , transient() , state(t_EngineData::none) , pItem() , pStatusLineCtrl() , m_idleDisconnectTimer() { } ~t_EngineData() { wxASSERT(!active); if (!transient) delete pEngine; delete m_idleDisconnectTimer; } CFileZillaEngine* pEngine; bool active; bool transient; enum EngineDataState { none, cancel, disconnect, connect, transfer, list, mkdir, askpassword, waitprimary } state; CFileItem* pItem; CServer lastServer; CStatusLineCtrl* pStatusLineCtrl; wxTimer* m_idleDisconnectTimer; }; class CMainFrame; class CStatusLineCtrl; class CFolderProcessingThread; class CAsyncRequestQueue; class CQueue; #if WITH_LIBDBUS class CDesktopNotification; #elif defined(__WXGTK__) || defined(__WXMSW__) class wxNotificationMessage; #endif class CQueueView : public CQueueViewBase, public COptionChangeEventHandler { friend class CFolderProcessingThread; friend class CQueueViewDropTarget; friend class CQueueViewFailed; public: CQueueView(CQueue* parent, int index, CMainFrame* pMainFrame, CAsyncRequestQueue* pAsyncRequestQueue); virtual ~CQueueView(); bool QueueFile(const bool queueOnly, const bool download, const wxString& localFile, const wxString& remoteFile, const CLocalPath& localPath, const CServerPath& remotePath, const CServer& server, int64_t size, enum CEditHandler::fileType edit = CEditHandler::none, QueuePriority priority = QueuePriority::normal); void QueueFile_Finish(const bool start); // Need to be called after QueueFile bool QueueFiles(const bool queueOnly, const CLocalPath& localPath, const CRemoteDataObject& dataObject); int QueueFiles(const std::list &entryList, bool queueOnly, bool download, CServerItem* pServerItem, const CFileExistsNotification::OverwriteAction defaultFileExistsAction); bool QueueFolder(bool queueOnly, bool download, const CLocalPath& localPath, const CServerPath& remotePath, const CServer& server); bool empty() const; int IsActive() const { return m_activeMode; } bool SetActive(bool active = true); bool Quit(); // This sets the default file exists action for all files currently in queue. // This includes queued folders which are yet to be processed void SetDefaultFileExistsAction(CFileExistsNotification::OverwriteAction action, const TransferDirection direction); void UpdateItemSize(CFileItem* pItem, int64_t size); void RemoveAll(); void LoadQueue(); void LoadQueueFromXML(); void ImportQueue(pugi::xml_node element, bool updateSelections); virtual void InsertItem(CServerItem* pServerItem, CQueueItem* pItem); virtual void CommitChanges(); void ProcessNotification(CFileZillaEngine* pEngine, std::unique_ptr&& pNotification); void RenameFileInTransfer(CFileZillaEngine *pEngine, const wxString& newName, bool local); static wxString ReplaceInvalidCharacters(const wxString& filename); // Get the current download speed as the sum of all active downloads. // Unit is byte/s. wxFileOffset GetCurrentDownloadSpeed(); // Get the current upload speed as the sum of all active uploads. // Unit is byte/s. wxFileOffset GetCurrentUploadSpeed(); protected: #ifdef __WXMSW__ WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); #endif virtual void OnOptionsChanged(changed_options_t const& options); void AdvanceQueue(bool refresh = true); bool TryStartNextTransfer(); // Called from TryStartNextTransfer(), checks // whether it is allowed to start another transfer on that server item bool CanStartTransfer(const CServerItem& server_item, struct t_EngineData *&pEngineData); bool ProcessFolderItems(int type = -1); void ProcessUploadFolderItems(); void ProcessReply(t_EngineData* pEngineData, COperationNotification const& notification); void SendNextCommand(t_EngineData& engineData); enum ResetReason { success, failure, reset, retry, remove }; enum ActionAfterState GetActionAfterState() const; void ResetEngine(t_EngineData& data, const enum ResetReason reason); void DeleteEngines(); virtual bool RemoveItem(CQueueItem* item, bool destroy, bool updateItemCount = true, bool updateSelections = true, bool forward = true); // Stops processing of given item // Returns true on success, false if it would block bool StopItem(CFileItem* item); bool StopItem(CServerItem* pServerItem, bool updateSelections); void CheckQueueState(); bool IncreaseErrorCount(t_EngineData& engineData); void UpdateStatusLinePositions(); void CalculateQueueSize(); void DisplayQueueSize(); void SaveQueue(); bool IsActionAfter(enum ActionAfterState); void ActionAfter(bool warned = false); #if defined(__WXMSW__) || defined(__WXMAC__) void ActionAfterWarnUser(ActionAfterState s); #endif void ProcessNotification(t_EngineData* pEngineData, std::unique_ptr && pNotification); // Tries to refresh the current remote directory listing // if there's an idle engine connected to the current server of // the primary connection. void TryRefreshListings(); CServer m_last_refresh_server; CServerPath m_last_refresh_path; fz::monotonic_clock m_last_refresh_listing_time; // Called from Process Reply. // After a disconnect, check if there's another idle engine that // is already connected. bool SwitchEngine(t_EngineData** ppEngineData); bool IsOtherEngineConnected(t_EngineData* pEngineData); t_EngineData* GetIdleEngine(const CServer* pServer = 0, bool allowTransient = false); t_EngineData* GetEngineData(const CFileZillaEngine* pEngine); std::vector m_engineData; std::list m_statusLineList; /* * List of queued folders used to populate the queue. * Index 0 for downloads, index 1 for uploads. * For each type, only the first one can be active at any given time. */ std::list m_queuedFolders[2]; void RemoveQueuedFolderItem(CFolderScanItem* pFolder); CFolderProcessingThread *m_pFolderProcessingThread{}; /* * Don't update status line positions if m_waitStatusLineUpdate is true. * This assures we are updating the status line positions only once, * and not multiple times (for example inside a loop). */ bool m_waitStatusLineUpdate; // Remember last top item in UpdateStatusLinePositions() int m_lastTopItem; int m_activeCount; int m_activeCountDown; int m_activeCountUp; int m_activeMode; // 0 inactive, 1 only immediate transfers, 2 all int m_quit; enum ActionAfterState m_actionAfterState; wxString m_actionAfterRunCommand; #if defined(__WXMSW__) || defined(__WXMAC__) wxTimer* m_actionAfterTimer{}; wxProgressDialog* m_actionAfterWarnDialog{}; int m_actionAfterTimerCount{}; int m_actionAfterTimerId{-1}; #endif int64_t m_totalQueueSize; int m_filesWithUnknownSize; CMainFrame* m_pMainFrame; CAsyncRequestQueue* m_pAsyncRequestQueue; std::list m_waitingForPassword; virtual void OnPostScroll(); wxTimer m_folderscan_item_refresh_timer; int GetLineHeight(); int m_line_height; #ifdef __WXMSW__ int m_header_height; #endif wxTimer m_resize_timer; void ReleaseExclusiveEngineLock(CFileZillaEngine* pEngine); #if WITH_LIBDBUS std::unique_ptr m_desktop_notification; #elif defined(__WXGTK__) || defined(__WXMSW__) std::unique_ptr m_desktop_notification; #endif CQueueStorage m_queue_storage; // Get the current transfer speed. // Unit is byte/s. wxFileOffset GetCurrentSpeed(bool countDownload, bool countUpload); DECLARE_EVENT_TABLE() void OnEngineEvent(wxFzEvent &event); void OnFolderThreadComplete(wxCommandEvent& event); void OnFolderThreadFiles(wxCommandEvent& event); void OnChar(wxKeyEvent& event); // Context menu handlers void OnContextMenu(wxContextMenuEvent& event); void OnProcessQueue(wxCommandEvent& event); void OnStopAndClear(wxCommandEvent& event); void OnRemoveSelected(wxCommandEvent& event); void OnSetDefaultFileExistsAction(wxCommandEvent& event); void OnAskPassword(wxCommandEvent& event); void OnTimer(wxTimerEvent& evnet); void OnSetPriority(wxCommandEvent& event); void OnExclusiveEngineRequestGranted(wxCommandEvent& event); void OnActionAfter(wxCommandEvent& event); void OnActionAfterTimerTick(); void OnSize(wxSizeEvent& event); }; #endif