1 #include "../filezilla.h"
2 
3 #include "../Options.h"
4 #include "settingsdialog.h"
5 #include "optionspage.h"
6 #include "optionspage_ftpproxy.h"
7 #include "../textctrlex.h"
8 
9 #include <wx/statbox.h>
10 
11 struct COptionsPageFtpProxy::impl final
12 {
13 	wxRadioButton* none_{};
14 	wxRadioButton* userhost_{};
15 	wxRadioButton* site_{};
16 	wxRadioButton* open_{};
17 	wxRadioButton* custom_{};
18 
19 	wxTextCtrlEx* sequence_{};
20 
21 	wxTextCtrlEx* host_{};
22 	wxTextCtrlEx* user_{};
23 	wxTextCtrlEx* pass_{};
24 };
25 
COptionsPageFtpProxy()26 COptionsPageFtpProxy::COptionsPageFtpProxy()
27 	: impl_(std::make_unique<impl>())
28 {
29 }
30 
31 COptionsPageFtpProxy::~COptionsPageFtpProxy() = default;
32 
CreateControls(wxWindow * parent)33 bool COptionsPageFtpProxy::CreateControls(wxWindow* parent)
34 {
35 	auto const& lay = m_pOwner->layout();
36 
37 	Create(parent);
38 	auto main = lay.createFlex(1);
39 	main->AddGrowableCol(0);
40 	main->AddGrowableRow(0);
41 	SetSizer(main);
42 
43 	{
44 		auto [box, inner] = lay.createStatBox(main, _("FTP Proxy"), 1);
45 		inner->AddGrowableCol(0);
46 		inner->AddGrowableRow(6);
47 
48 		inner->Add(new wxStaticText(box, nullID, _("Type of FTP Proxy:")));
49 		impl_->none_ = new wxRadioButton(box, nullID, _("&None"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
50 		inner->Add(impl_->none_);
51 		impl_->userhost_ = new wxRadioButton(box, nullID, _("USER@&HOST"));
52 		inner->Add(impl_->userhost_);
53 		impl_->site_ = new wxRadioButton(box, nullID, _("&SITE"));
54 		inner->Add(impl_->site_);
55 		impl_->open_ = new wxRadioButton(box, nullID, _("&OPEN"));
56 		inner->Add(impl_->open_);
57 		impl_->custom_ = new wxRadioButton(box, nullID, _("Cus&tom"));
58 		inner->Add(impl_->custom_);
59 
60 		auto flex = lay.createFlex(1);
61 		flex->AddGrowableCol(0);
62 		flex->AddGrowableRow(0);
63 		inner->Add(flex, 0, wxGROW|wxLEFT, lay.indent);
64 		impl_->sequence_ = new wxTextCtrlEx(box, nullID, wxString(), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
65 		flex->Add(impl_->sequence_, lay.grow);
66 		flex->Add(new wxStaticText(box, nullID, _("Format specifications:")));
67 		auto row = lay.createFlex(3);
68 		flex->Add(row);
69 		row->SetHGap(lay.gap * 3);
70 		row->Add(new wxStaticText(box, nullID, _("%h - Host")), lay.valign);
71 		row->Add(new wxStaticText(box, nullID, _("%u - Username")), lay.valign);
72 		row->Add(new wxStaticText(box, nullID, _("%p - Password")), lay.valign);
73 		flex->Add(new wxStaticText(box, nullID, _("%a - Account (Lines containing this will be omitted if not using Account logontype)")));
74 		row = lay.createFlex(2);
75 		flex->Add(row);
76 		row->SetHGap(lay.gap * 3);
77 		row->Add(new wxStaticText(box, nullID, _("%s - Proxy user")), lay.valign);
78 		row->Add(new wxStaticText(box, nullID, _("%w - Proxy password")), lay.valign);
79 
80 		flex = lay.createFlex(4);
81 		inner->Add(flex);
82 		flex->Add(new wxStaticText(box, nullID, _("P&roxy host:")), lay.valign);
83 		impl_->host_ = new wxTextCtrlEx(box, nullID);
84 		flex->Add(impl_->host_, lay.valign);
85 		flex->Add(new wxStaticText(box, nullID, _("Proxy &user:")), lay.valign);
86 		impl_->user_ = new wxTextCtrlEx(box, nullID);
87 		flex->Add(impl_->user_, lay.valign);
88 		flex->Add(new wxStaticText(box, nullID, _("Pro&xy password:")), lay.valign);
89 		impl_->pass_ = new wxTextCtrlEx(box, nullID);
90 		flex->Add(impl_->pass_, lay.valign);
91 		inner->Add(new wxStaticText(box, nullID, _("Note: This only works with plain, unencrytped FTP connections.")));
92 
93 		impl_->none_->Bind(wxEVT_RADIOBUTTON, &COptionsPageFtpProxy::OnProxyTypeChanged, this);
94 		impl_->userhost_->Bind(wxEVT_RADIOBUTTON, &COptionsPageFtpProxy::OnProxyTypeChanged, this);
95 		impl_->site_->Bind(wxEVT_RADIOBUTTON, &COptionsPageFtpProxy::OnProxyTypeChanged, this);
96 		impl_->open_->Bind(wxEVT_RADIOBUTTON, &COptionsPageFtpProxy::OnProxyTypeChanged, this);
97 		impl_->custom_->Bind(wxEVT_RADIOBUTTON, &COptionsPageFtpProxy::OnProxyTypeChanged, this);
98 		impl_->sequence_->Bind(wxEVT_TEXT, &COptionsPageFtpProxy::OnLoginSequenceChanged, this);
99 	}
100 
101 	return true;
102 }
103 
LoadPage()104 bool COptionsPageFtpProxy::LoadPage()
105 {
106 	int type = m_pOptions->get_int(OPTION_FTP_PROXY_TYPE);
107 	switch (type)
108 	{
109 	default:
110 	case 0:
111 		impl_->none_->SetValue(true);
112 		break;
113 	case 1:
114 		impl_->userhost_->SetValue(true);
115 		break;
116 	case 2:
117 		impl_->site_->SetValue(true);
118 		break;
119 	case 3:
120 		impl_->open_->SetValue(true);
121 		break;
122 	case 4:
123 		impl_->custom_->SetValue(true);
124 		impl_->sequence_->ChangeValue(m_pOptions->get_string(OPTION_FTP_PROXY_CUSTOMLOGINSEQUENCE));
125 		break;
126 	}
127 
128 	impl_->host_->ChangeValue(m_pOptions->get_string(OPTION_FTP_PROXY_HOST));
129 	impl_->user_->ChangeValue(m_pOptions->get_string(OPTION_FTP_PROXY_USER));
130 	impl_->pass_->ChangeValue(m_pOptions->get_string(OPTION_FTP_PROXY_PASS));
131 
132 	SetCtrlState();
133 
134 	return true;
135 }
136 
SavePage()137 bool COptionsPageFtpProxy::SavePage()
138 {
139 	int type{};
140 	if (impl_->userhost_->GetValue()) {
141 		type = 1;
142 	}
143 	if (impl_->site_->GetValue()) {
144 		type = 2;
145 	}
146 	if (impl_->open_->GetValue()) {
147 		type = 3;
148 	}
149 	if (impl_->custom_->GetValue()) {
150 		type = 4;
151 		m_pOptions->set(OPTION_FTP_PROXY_CUSTOMLOGINSEQUENCE, impl_->sequence_->GetValue().ToStdWstring());
152 	}
153 	m_pOptions->set(OPTION_FTP_PROXY_TYPE, type);
154 
155 	m_pOptions->set(OPTION_FTP_PROXY_HOST, impl_->host_->GetValue().ToStdWstring());
156 	m_pOptions->set(OPTION_FTP_PROXY_USER, impl_->user_->GetValue().ToStdWstring());
157 	m_pOptions->set(OPTION_FTP_PROXY_PASS, impl_->pass_->GetValue().ToStdWstring());
158 
159 	return true;
160 }
161 
Validate()162 bool COptionsPageFtpProxy::Validate()
163 {
164 	if (!impl_->none_->GetValue()) {
165 		if (impl_->host_->GetValue().empty()) {
166 			return DisplayError(impl_->host_, _("You need to enter a proxy host."));
167 		}
168 	}
169 
170 	if (impl_->custom_->GetValue()) {
171 		if (impl_->sequence_->GetValue().empty()) {
172 			return DisplayError(impl_->sequence_, _("The custom login sequence cannot be empty."));
173 		}
174 	}
175 
176 	return true;
177 }
178 
SetCtrlState()179 void COptionsPageFtpProxy::SetCtrlState()
180 {
181 	bool const none = impl_->none_->GetValue();
182 
183 	impl_->host_->Enable(!none);
184 	impl_->user_->Enable(!none);
185 	impl_->pass_->Enable(!none);
186 	impl_->sequence_->Enable(!none);
187 	impl_->sequence_->SetEditable(!none);
188 
189 	if (none) {
190 		impl_->sequence_->ChangeValue(wxString());
191 #ifdef __WXMSW__
192 		impl_->sequence_->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
193 #endif
194 		return;
195 	}
196 
197 #ifdef __WXMSW__
198 	impl_->sequence_->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
199 #endif
200 
201 	if (impl_->custom_->GetValue()) {
202 		return;
203 	}
204 
205 	wxString loginSequence = L"USER %s\nPASS %w\n";
206 
207 	if (impl_->userhost_->GetValue()) {
208 		loginSequence += L"USER %u@%h\n";
209 	}
210 	else {
211 		if (impl_->site_->GetValue()) {
212 			loginSequence += L"SITE %h\n";
213 		}
214 		else {
215 			loginSequence += L"OPEN %h\n";
216 		}
217 		loginSequence += L"USER %u\n";
218 	}
219 
220 	loginSequence += L"PASS %p\nACCT %a";
221 
222 	impl_->sequence_->ChangeValue(loginSequence);
223 }
224 
OnProxyTypeChanged(wxCommandEvent &)225 void COptionsPageFtpProxy::OnProxyTypeChanged(wxCommandEvent&)
226 {
227 	SetCtrlState();
228 }
229 
OnLoginSequenceChanged(wxCommandEvent &)230 void COptionsPageFtpProxy::OnLoginSequenceChanged(wxCommandEvent&)
231 {
232 	impl_->custom_->SetValue(true);
233 }
234