1 #include "filezilla.h"
2 #include "sitemanager_site.h"
3
4 #include "filezillaapp.h"
5 #include "Options.h"
6 #include "sitemanager_controls.h"
7 #include "sitemanager_dialog.h"
8 #include "textctrlex.h"
9 #include "xrc_helper.h"
10
11 #include "../include/s3sse.h"
12
13 #include <libfilezilla/translate.hpp>
14
15 #include <wx/dcclient.h>
16 #include <wx/gbsizer.h>
17 #include <wx/statline.h>
18 #include <wx/wupdlock.h>
19
20 #ifdef __WXMSW__
21 #include "commctrl.h"
22 #endif
23
CSiteManagerSite(CSiteManagerDialog & sitemanager)24 CSiteManagerSite::CSiteManagerSite(CSiteManagerDialog &sitemanager)
25 : sitemanager_(sitemanager)
26 {
27 }
28
Load(wxWindow * parent)29 bool CSiteManagerSite::Load(wxWindow* parent)
30 {
31 Create(parent, -1);
32
33 DialogLayout lay(static_cast<wxTopLevelWindow*>(wxGetTopLevelParent(parent)));
34
35 {
36 auto onChange = [this](ServerProtocol protocol, LogonType type) {
37 wxWindowUpdateLocker l(this);
38 SetControlVisibility(protocol, type);
39 for (auto & controls : controls_) {
40 controls->SetControlState();
41 }
42 GetContainingSizer()->Layout();
43 };
44
45 generalPage_ = new wxPanel(this);
46 AddPage(generalPage_, _("General"));
47
48 auto* main = lay.createMain(generalPage_, 1);
49 controls_.emplace_back(std::make_unique<GeneralSiteControls>(*generalPage_, lay, *main, onChange));
50
51 main->Add(new wxStaticLine(generalPage_), lay.grow);
52
53 auto row = lay.createFlex(0, 1);
54 main->Add(row);
55 row->Add(new wxStaticText(generalPage_, -1, _("&Background color:")), lay.valign);
56 auto colors = new wxChoice(generalPage_, XRCID("ID_COLOR"));
57 row->Add(colors, lay.valign);
58
59 main->Add(new wxStaticText(generalPage_, -1, _("Co&mments:")));
60 main->Add(new wxTextCtrlEx(generalPage_, XRCID("ID_COMMENTS"), L"", wxDefaultPosition, wxSize(-1, lay.dlgUnits(43)), wxTE_MULTILINE), 1, wxGROW);
61 main->AddGrowableRow(main->GetEffectiveRowsCount() - 1);
62
63 for (int i = 0; ; ++i) {
64 wxString name = CSiteManager::GetColourName(i);
65 if (name.empty()) {
66 break;
67 }
68 colors->AppendString(wxGetTranslation(name));
69 }
70 }
71
72 {
73 advancedPage_ = new wxPanel(this);
74 AddPage(advancedPage_, _("Advanced"));
75 auto * main = lay.createMain(advancedPage_, 1);
76 controls_.emplace_back(std::make_unique<AdvancedSiteControls>(*advancedPage_, lay, *main));
77 }
78
79 {
80 transferPage_ = new wxPanel(this);
81 AddPage(transferPage_, _("Transfer Settings"));
82 auto * main = lay.createMain(transferPage_, 1);
83 controls_.emplace_back(std::make_unique<TransferSettingsSiteControls>(*transferPage_, lay, *main));
84 }
85
86 {
87 charsetPage_ = new wxPanel(this);
88 AddPage(charsetPage_, _("Charset"));
89 auto * main = lay.createMain(charsetPage_, 1);
90 controls_.emplace_back(std::make_unique<CharsetSiteControls>(*charsetPage_, lay, *main));
91
92 int const charsetPageIndex = FindPage(charsetPage_);
93 m_charsetPageText = GetPageText(charsetPageIndex);
94 wxGetApp().GetWrapEngine()->WrapRecursive(charsetPage_, 1.3);
95 }
96
97 {
98 s3Page_ = new wxPanel(this);
99 AddPage(s3Page_, L"S3");
100 auto * main = lay.createMain(s3Page_, 1);
101 controls_.emplace_back(std::make_unique<S3SiteControls>(*s3Page_, lay, *main));
102 }
103
104 {
105 dropboxPage_ = new wxPanel(this);
106 AddPage(dropboxPage_, L"Dropbox");
107 auto * main = lay.createMain(dropboxPage_, 1);
108 controls_.emplace_back(std::make_unique<DropboxSiteControls>(*dropboxPage_, lay, *main));
109 }
110
111 {
112 swiftPage_ = new wxPanel(this);
113 AddPage(swiftPage_, L"Swift");
114 auto * main = lay.createMain(swiftPage_, 1);
115 controls_.emplace_back(std::make_unique<SwiftSiteControls>(*swiftPage_, lay, *main));
116 }
117
118 m_totalPages = GetPageCount();
119
120 GetPage(0)->GetSizer()->Fit(GetPage(0));
121
122 #ifdef __WXMSW__
123 // Make pages at least wide enough to fit all tabs
124 HWND hWnd = (HWND)GetHandle();
125
126 int width = 4;
127 for (unsigned int i = 0; i < GetPageCount(); ++i) {
128 RECT tab_rect{};
129 if (TabCtrl_GetItemRect(hWnd, i, &tab_rect)) {
130 width += tab_rect.right - tab_rect.left;
131 }
132 }
133 #else
134 // Make pages at least wide enough to fit all tabs
135 int width = 10; // Guessed
136 wxClientDC dc(this);
137 for (unsigned int i = 0; i < GetPageCount(); ++i) {
138 wxCoord w, h;
139 dc.GetTextExtent(GetPageText(i), &w, &h);
140
141 width += w;
142 #ifdef __WXMAC__
143 width += 20; // Guessed
144 #else
145 width += 20;
146 #endif
147 }
148 #endif
149
150 wxSize const descSize = XRCCTRL(*this, "ID_ENCRYPTION_DESC", wxWindow)->GetSize();
151 wxSize const encSize = XRCCTRL(*this, "ID_ENCRYPTION", wxWindow)->GetSize();
152
153 int dataWidth = std::max(encSize.GetWidth(), XRCCTRL(*this, "ID_PROTOCOL", wxWindow)->GetSize().GetWidth());
154
155 auto generalSizer = static_cast<wxGridBagSizer*>(xrc_call(*this, "ID_PROTOCOL", &wxWindow::GetContainingSizer));
156 width = std::max(width, static_cast<int>(descSize.GetWidth() * 2 + dataWidth + generalSizer->GetHGap() * 3));
157
158 wxSize page_min_size = GetPage(0)->GetSizer()->GetMinSize();
159 if (page_min_size.x < width) {
160 page_min_size.x = width;
161 GetPage(0)->GetSizer()->SetMinSize(page_min_size);
162 }
163
164 // Set min height of general page sizer
165 generalSizer->SetMinSize(generalSizer->GetMinSize());
166
167 // Set min height of encryption row
168 auto encSizer = xrc_call(*this, "ID_ENCRYPTION", &wxWindow::GetContainingSizer);
169 encSizer->GetItem(encSizer->GetItemCount() - 1)->SetMinSize(0, std::max(descSize.GetHeight(), encSize.GetHeight()));
170
171 return true;
172 }
173
SetControlVisibility(ServerProtocol protocol,LogonType type)174 void CSiteManagerSite::SetControlVisibility(ServerProtocol protocol, LogonType type)
175 {
176 for (auto & controls : controls_) {
177 controls->SetPredefined(predefined_);
178 controls->SetControlVisibility(protocol, type);
179 }
180
181 if (charsetPage_) {
182 if (CServer::ProtocolHasFeature(protocol, ProtocolFeature::Charset)) {
183 if (FindPage(charsetPage_) == wxNOT_FOUND) {
184 AddPage(charsetPage_, m_charsetPageText);
185 }
186 }
187 else {
188 int const charsetPageIndex = FindPage(charsetPage_);
189 if (charsetPageIndex != wxNOT_FOUND) {
190 RemovePage(charsetPageIndex);
191 }
192 }
193 }
194
195 if (s3Page_) {
196 if (protocol == S3) {
197 if (FindPage(s3Page_) == wxNOT_FOUND) {
198 AddPage(s3Page_, L"S3");
199 }
200 }
201 else {
202 int const s3PageIndex = FindPage(s3Page_);
203 if (s3PageIndex != wxNOT_FOUND) {
204 RemovePage(s3PageIndex);
205 }
206 }
207 }
208
209 if (swiftPage_) {
210 if (protocol == SWIFT) {
211 if (FindPage(swiftPage_) == wxNOT_FOUND) {
212 AddPage(swiftPage_, L"Swift");
213 }
214 }
215 else {
216 int const swiftPageIndex = FindPage(swiftPage_);
217 if (swiftPageIndex != wxNOT_FOUND) {
218 RemovePage(swiftPageIndex);
219 }
220 }
221 }
222
223 if (dropboxPage_) {
224 if (protocol == DROPBOX) {
225 if (FindPage(dropboxPage_) == wxNOT_FOUND) {
226 AddPage(dropboxPage_, L"Dropbox");
227 }
228 }
229 else {
230 int const dropboxPageIndex = FindPage(dropboxPage_);
231 if (dropboxPageIndex != wxNOT_FOUND) {
232 RemovePage(dropboxPageIndex);
233 }
234 }
235 }
236
237 GetPage(0)->GetSizer()->Fit(GetPage(0));
238 }
239
UpdateSite(Site & site,bool silent)240 bool CSiteManagerSite::UpdateSite(Site &site, bool silent)
241 {
242 for (auto & controls : controls_) {
243 if (!controls->UpdateSite(site, silent)) {
244 return false;
245 }
246 }
247
248 site.comments_ = xrc_call(*this, "ID_COMMENTS", &wxTextCtrl::GetValue).ToStdWstring();
249 site.m_colour = CSiteManager::GetColourFromIndex(xrc_call(*this, "ID_COLOR", &wxChoice::GetSelection));
250
251 return true;
252 }
253
SetSite(Site const & site,bool predefined)254 void CSiteManagerSite::SetSite(Site const& site, bool predefined)
255 {
256 predefined_ = predefined;
257
258 if (site) {
259 SetControlVisibility(site.server.GetProtocol(), site.credentials.logonType_);
260 }
261 else {
262 bool const kiosk_mode = COptions::Get()->get_int(OPTION_DEFAULT_KIOSKMODE) != 0;
263 auto const logonType = kiosk_mode ? LogonType::ask : LogonType::normal;
264 SetControlVisibility(FTP, logonType);
265 }
266
267 xrc_call(*this, "ID_COLOR", &wxWindow::Enable, !predefined);
268 xrc_call(*this, "ID_COMMENTS", &wxWindow::Enable, !predefined);
269
270 for (auto & controls : controls_) {
271 controls->SetSite(site);
272 controls->SetControlState();
273 }
274
275 if (!site) {
276 xrc_call(*this, "ID_COMMENTS", &wxTextCtrl::ChangeValue, wxString());
277 xrc_call(*this, "ID_COLOR", &wxChoice::Select, 0);
278 }
279 else {
280 xrc_call(*this, "ID_COMMENTS", &wxTextCtrl::ChangeValue, site.comments_);
281 xrc_call(*this, "ID_COLOR", &wxChoice::Select, CSiteManager::GetColourIndex(site_colour_to_wx(site.m_colour)));
282 }
283 }
284