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