1 #include "filezilla.h"
2 #include "local_recursive_operation.h"
3
4 #include <libfilezilla/local_filesys.hpp>
5
6 #include "QueueView.h"
7
BEGIN_EVENT_TABLE(CLocalRecursiveOperation,wxEvtHandler)8 BEGIN_EVENT_TABLE(CLocalRecursiveOperation, wxEvtHandler)
9 END_EVENT_TABLE()
10
11
12 CLocalRecursiveOperation::CLocalRecursiveOperation(CState& state)
13 : local_recursive_operation(state.pool_)
14 , state_(state)
15 {
16 }
17
~CLocalRecursiveOperation()18 CLocalRecursiveOperation::~CLocalRecursiveOperation()
19 {
20 thread_.join();
21 }
22
StartRecursiveOperation(OperationMode mode,ActiveFilters const & filters,bool immediate,bool ignore_links)23 void CLocalRecursiveOperation::StartRecursiveOperation(OperationMode mode, ActiveFilters const& filters, bool immediate, bool ignore_links)
24 {
25 m_immediate = immediate;
26 start_recursive_operation(mode, filters, ignore_links);
27 }
28
do_start_recursive_operation(OperationMode mode,ActiveFilters const & filters,bool ignore_links)29 bool CLocalRecursiveOperation::do_start_recursive_operation(OperationMode mode, ActiveFilters const& filters, bool ignore_links)
30 {
31 if (!m_pQueue) {
32 return false;
33 }
34
35 Site const& site = state_.GetSite();
36 if (site) {
37 site_ = site;
38 }
39 else {
40 if (mode != OperationMode::recursive_list) {
41 return false;
42 }
43
44 site_ = Site();
45 }
46
47 if (!local_recursive_operation::do_start_recursive_operation(mode, filters, ignore_links)) {
48 return false;
49 }
50
51 if ((mode == recursive_operation::recursive_transfer || mode == recursive_operation::recursive_transfer_flatten) && m_immediate) {
52 m_actionAfterBlocker = m_pQueue->GetActionAfterBlocker();
53 }
54
55 state_.NotifyHandlers(STATECHANGE_LOCAL_RECURSION_STATUS);
56
57 return true;
58 }
59
StopRecursiveOperation()60 void CLocalRecursiveOperation::StopRecursiveOperation()
61 {
62 local_recursive_operation::StopRecursiveOperation();
63
64 state_.NotifyHandlers(STATECHANGE_LOCAL_RECURSION_STATUS);
65 m_actionAfterBlocker.reset();
66 }
67
on_listed_directory()68 void CLocalRecursiveOperation::on_listed_directory() {
69 CallAfter(&CLocalRecursiveOperation::OnListedDirectory);
70 }
71
OnListedDirectory()72 void CLocalRecursiveOperation::OnListedDirectory()
73 {
74 if (m_operationMode == recursive_none) {
75 return;
76 }
77
78 bool const queue = m_operationMode == recursive_transfer || m_operationMode == recursive_transfer_flatten;
79
80 listing d;
81
82 bool stop = false;
83 int64_t processed = 0;
84 while (processed < 5000) {
85 {
86 fz::scoped_lock l(mutex_);
87 if (m_listedDirectories.empty()) {
88 break;
89 }
90
91 d = std::move(m_listedDirectories.front());
92 m_listedDirectories.pop_front();
93 }
94
95 if (d.localPath.empty()) {
96 stop = true;
97 }
98 else {
99 if (queue) {
100 m_pQueue->QueueFiles(!m_immediate, site_, d);
101 }
102 ++m_processedDirectories;
103 processed += d.files.size();
104 state_.NotifyHandlers(STATECHANGE_LOCAL_RECURSION_LISTING, std::wstring(), &d);
105 }
106 }
107
108 if (queue) {
109 m_pQueue->QueueFile_Finish(m_immediate);
110 }
111
112 m_processedFiles += processed;
113 if (stop) {
114 StopRecursiveOperation();
115 }
116 else if (processed) {
117 state_.NotifyHandlers(STATECHANGE_LOCAL_RECURSION_STATUS);
118
119 if (processed >= 5000) {
120 CallAfter(&CLocalRecursiveOperation::OnListedDirectory);
121 }
122 }
123 }
124
SetImmediate(bool immediate)125 void CLocalRecursiveOperation::SetImmediate(bool immediate)
126 {
127 if (m_operationMode == recursive_transfer || m_operationMode == recursive_transfer_flatten) {
128 m_immediate = immediate;
129 if (!immediate) {
130 m_actionAfterBlocker.reset();
131 }
132 }
133 }
134
135