1 #include "../filezilla.h"
2 #include "../Options.h"
3 #include "settingsdialog.h"
4 #include "optionspage.h"
5 #include "optionspage_logging.h"
6 #include "../textctrlex.h"
7
8 #include <wx/filedlg.h>
9 #include <wx/statbox.h>
10
11 struct COptionsPageLogging::impl final
12 {
13 wxCheckBox* timestamps_{};
14 wxCheckBox* log_{};
15 wxTextCtrlEx* file_{};
16 wxButton* browse_{};
17 wxCheckBox* do_limit_{};
18 wxTextCtrlEx* limit_{};
19 };
20
COptionsPageLogging()21 COptionsPageLogging::COptionsPageLogging()
22 : impl_(std::make_unique<impl>())
23 {}
24
~COptionsPageLogging()25 COptionsPageLogging::~COptionsPageLogging()
26 {
27 }
28
CreateControls(wxWindow * parent)29 bool COptionsPageLogging::CreateControls(wxWindow* parent)
30 {
31 auto const& lay = m_pOwner->layout();
32
33 Create(parent);
34 auto main = lay.createFlex(1);
35 main->AddGrowableCol(0);
36 main->AddGrowableRow(0);
37 SetSizer(main);
38
39 {
40 auto [box, inner] = lay.createStatBox(main, _("Logging"), 1);
41
42 impl_->timestamps_ = new wxCheckBox(box, nullID, _("&Show timestamps in message log"));
43 inner->Add(impl_->timestamps_);
44
45 impl_->log_ = new wxCheckBox(box, nullID, _("&Log to file"));
46 inner->Add(impl_->log_);
47 auto row = lay.createFlex(3);
48 row->AddGrowableCol(1);
49 inner->Add(row, 0, wxLEFT|wxGROW, lay.indent);
50 row->Add(new wxStaticText(box, nullID, _("Filename:")), lay.valign);
51 impl_->file_ = new wxTextCtrlEx(box, nullID, wxString());
52 row->Add(impl_->file_, lay.valigng);
53 impl_->browse_ = new wxButton(box, nullID, _("&Browse"));
54 row->Add(impl_->browse_, lay.valign);
55 impl_->browse_->Bind(wxEVT_BUTTON, &COptionsPageLogging::OnBrowse, this);
56
57 impl_->do_limit_ = new wxCheckBox(box, nullID, _("Limit size of logfile"));
58 inner->Add(impl_->do_limit_, 0, wxLEFT, lay.indent);
59 row = lay.createFlex(3);
60 inner->Add(row, 0, wxLEFT, lay.indent * 2);
61 row->Add(new wxStaticText(box, nullID, _("Limit:")), lay.valign);
62 impl_->limit_ = new wxTextCtrlEx(box, nullID, wxString());
63 row->Add(impl_->limit_, lay.valign)->SetMinSize(lay.dlgUnits(20), -1);
64 impl_->limit_->SetMaxLength(4);
65 row->Add(new wxStaticText(box, nullID, _("MiB")), lay.valign);
66
67 inner->Add(new wxStaticText(box, nullID, _("If the size of the logfile reaches the limit, it gets renamed by adding \".1\" to the end of the filename (possibly overwriting older logfiles) and a new file gets created.")), 0, wxLEFT, lay.indent * 2);
68 inner->Add(new wxStaticText(box, nullID, _("Changing logfile settings requires restart of FileZilla.")), 0, wxLEFT, lay.indent);
69
70 impl_->do_limit_->Bind(wxEVT_CHECKBOX, &COptionsPageLogging::OnCheck, this);
71 impl_->log_->Bind(wxEVT_CHECKBOX, &COptionsPageLogging::OnCheck, this);
72 }
73
74 return true;
75 }
LoadPage()76 bool COptionsPageLogging::LoadPage()
77 {
78 impl_->timestamps_->SetValue(m_pOptions->get_bool(OPTION_MESSAGELOG_TIMESTAMP));
79
80 std::wstring const filename = m_pOptions->get_string(OPTION_LOGGING_FILE);
81 impl_->log_->SetValue(!filename.empty());
82 impl_->file_->ChangeValue(filename);
83
84 int const limit = m_pOptions->get_int(OPTION_LOGGING_FILE_SIZELIMIT);
85 impl_->do_limit_->SetValue(limit > 0);
86 impl_->limit_->ChangeValue(fz::to_wstring(limit));
87
88 SetCtrlState();
89
90 return true;
91 }
92
SavePage()93 bool COptionsPageLogging::SavePage()
94 {
95 m_pOptions->set(OPTION_MESSAGELOG_TIMESTAMP, impl_->timestamps_->GetValue());
96
97 std::wstring file;
98 if (impl_->log_->GetValue()) {
99 file = impl_->file_->GetValue().ToStdWstring();
100 }
101 m_pOptions->set(OPTION_LOGGING_FILE, file);
102
103 if (impl_->do_limit_->GetValue()) {
104 m_pOptions->set(OPTION_LOGGING_FILE_SIZELIMIT, fz::to_integral<int>(impl_->limit_->GetValue().ToStdWstring()));
105 }
106 else {
107 m_pOptions->set(OPTION_LOGGING_FILE_SIZELIMIT, 0);
108 }
109
110 return true;
111 }
112
Validate()113 bool COptionsPageLogging::Validate()
114 {
115 if (impl_->log_->GetValue()) {
116 wxString file = impl_->file_->GetValue();
117 if (file.empty()) {
118 return DisplayError(impl_->file_, _("You need to enter a name for the log file."));
119 }
120
121 wxFileName fn(file);
122 if (!fn.IsOk() || !fn.DirExists()) {
123 return DisplayError(impl_->file_, _("Directory containing the logfile does not exist or filename is invalid."));
124 }
125
126 if (impl_->do_limit_->GetValue()) {
127 auto v = fz::to_integral<int>(impl_->limit_->GetValue().ToStdWstring());
128 if (v < 1 || v > 2000) {
129 return DisplayError(impl_->limit_, _("The limit needs to be between 1 and 2000 MiB"));
130 }
131 }
132 }
133 return true;
134 }
135
SetCtrlState()136 void COptionsPageLogging::SetCtrlState()
137 {
138 bool const log_to_file = impl_->log_->GetValue();
139 bool const limit = impl_->do_limit_->GetValue();
140
141 impl_->file_->Enable(log_to_file);
142 impl_->browse_->Enable(log_to_file);
143 impl_->do_limit_->Enable(log_to_file);
144 impl_->limit_->Enable(log_to_file && limit);
145 }
146
OnBrowse(wxCommandEvent &)147 void COptionsPageLogging::OnBrowse(wxCommandEvent&)
148 {
149 wxFileDialog dlg(this, _("Log file"), wxString(), _T("filezilla.log"), _T("Log files (*.log)|*.log"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
150
151 if (dlg.ShowModal() != wxID_OK) {
152 return;
153 }
154
155 impl_->file_->ChangeValue(dlg.GetPath());
156 }
157
OnCheck(wxCommandEvent &)158 void COptionsPageLogging::OnCheck(wxCommandEvent&)
159 {
160 SetCtrlState();
161 }
162