1 // This file is part of BOINC.
2 // http://boinc.berkeley.edu
3 // Copyright (C) 2008 University of California
4 //
5 // BOINC is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License
7 // as published by the Free Software Foundation,
8 // either version 3 of the License, or (at your option) any later version.
9 //
10 // BOINC is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 // See the GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with BOINC. If not, see <http://www.gnu.org/licenses/>.
17 //
18 #if defined(__GNUG__) && !defined(__APPLE__)
19 #pragma implementation "DlgDiagnosticLogFlags.cpp"
20 #endif
21
22 #include "stdwx.h"
23 #include "util.h"
24 #include "DlgDiagnosticLogFlags.h"
25 #include "BOINCGUIApp.h"
26 #include "BOINCBaseFrame.h"
27 #include "Events.h"
28 #include "error_numbers.h"
29 #include "gui_rpc_client.h" // For SET_LOCALE
30 #include "SkinManager.h"
31
32
33 #define DLGDIAGNOSTICS_INITIAL_WIDTH ADJUSTFORXDPI(480)
34 #define DLGDIAGNOSTICS_INITIAL_HEIGHT ADJUSTFORYDPI(480)
35 #define DLGDIAGNOSTICS_MIN_WIDTH ADJUSTFORXDPI(400)
36 #define DLGDIAGNOSTICS_MIN_HEIGHT ADJUSTFORYDPI(400)
37
IMPLEMENT_DYNAMIC_CLASS(CDlgDiagnosticLogFlags,wxDialog)38 IMPLEMENT_DYNAMIC_CLASS(CDlgDiagnosticLogFlags, wxDialog)
39
40 BEGIN_EVENT_TABLE(CDlgDiagnosticLogFlags, wxDialog)
41 EVT_SIZE(CDlgDiagnosticLogFlags::OnSize)
42 EVT_BUTTON(wxID_OK,CDlgDiagnosticLogFlags::OnOK)
43 EVT_BUTTON(ID_DEFAULTSBTN,CDlgDiagnosticLogFlags::OnSetDefaults)
44 EVT_BUTTON(wxID_APPLY,CDlgDiagnosticLogFlags::OnApply)
45 EVT_CHECKBOX(wxID_ANY,CDlgDiagnosticLogFlags::OnCheckBox)
46
47 END_EVENT_TABLE()
48
49 /* Constructor */
50 CDlgDiagnosticLogFlags::CDlgDiagnosticLogFlags(wxWindow* parent) :
51 wxDialog( parent, ID_ANYDIALOG, wxEmptyString, wxDefaultPosition,
52 wxSize( DLGDIAGNOSTICS_INITIAL_WIDTH,DLGDIAGNOSTICS_INITIAL_HEIGHT ),
53 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER
54 ) {
55
56 CSkinAdvanced* pSkinAdvanced = wxGetApp().GetSkinManager()->GetAdvanced();
57 CMainDocument* pDoc = wxGetApp().GetDocument();
58
59 wxASSERT(pDoc);
60 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
61
62 wxASSERT(pSkinAdvanced);
63 wxASSERT(wxDynamicCast(pSkinAdvanced, CSkinAdvanced));
64
65 wxString title;
66 title.Printf(
67 _("%s Diagnostic Log Flags"),
68 pSkinAdvanced->GetApplicationShortName().c_str()
69 );
70
71 SetTitle(title);
72
73 // Get cc_config.xml file flags
74 log_flags.init();
75 m_cc_config.defaults();
76 pDoc->rpc.get_cc_config(m_cc_config, log_flags);
77
78 SetSizeHints(DLGDIAGNOSTICS_MIN_WIDTH, DLGDIAGNOSTICS_MIN_HEIGHT);
79 SetExtraStyle( GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY );
80
81 wxBoxSizer* bSizer1 = new wxBoxSizer( wxVERTICAL );
82 m_headingSizer = new wxFlexGridSizer( 1 );
83
84 m_headingText.Printf(
85 _("These flags enable various types of diagnostic messages in the Event Log.")
86 );
87
88 m_heading = new wxStaticText(this, wxID_ANY, m_headingText);
89
90 m_headingSizer->Add(m_heading, 1, wxLEFT | wxRIGHT, 25);
91
92 wxString strURL = pSkinAdvanced->GetOrganizationHelpUrl();
93 wxString helpURL;
94 helpURL.Printf(
95 wxT("%s?target=notice&controlid=log_flags"),
96 strURL.c_str()
97 );
98
99 m_headingSizer->Add(
100 new wxHyperlinkCtrl(
101 this, wxID_ANY, _("More info ..."), helpURL,
102 wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE
103 ),
104 0, wxLEFT | wxRIGHT, 25
105 );
106
107 bSizer1->AddSpacer(7);
108 bSizer1->Add( m_headingSizer, 0, wxEXPAND | wxALL, 5 );
109 bSizer1->AddSpacer(7);
110
111 m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
112 m_scrolledWindow->SetScrollRate( 5, 5 );
113
114 m_checkboxSizer = new wxGridSizer(2, wxSize(0,3));
115 CreateCheckboxes();
116
117 bSizer1->Add( m_scrolledWindow, 1, wxEXPAND | wxALL, 5 );
118
119 wxBoxSizer* buttonSizer = new wxBoxSizer( wxHORIZONTAL );
120
121 wxButton* btnOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 );
122 btnOK->SetToolTip( _("Save all values and close the dialog") );
123 buttonSizer->Add( btnOK, 0, wxALL, 5 );
124
125 wxButton* btnDefaults = new wxButton( this, ID_DEFAULTSBTN, _("Defaults"), wxDefaultPosition, wxDefaultSize, 0 );
126 btnDefaults->SetToolTip( _("Restore default settings") );
127 buttonSizer->Add( btnDefaults, 0, wxALL, 5 );
128
129 wxButton* btnCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
130 btnCancel->SetToolTip( _("Close the dialog without saving") );
131 buttonSizer->Add( btnCancel, 0, wxALL, 5 );
132
133 m_btnApply = new wxButton( this, wxID_APPLY, _("Apply"), wxDefaultPosition, wxDefaultSize, 0 );
134 m_btnApply->SetToolTip( _("Save all values") );
135 m_btnApply->Enable(false);
136 buttonSizer->Add( m_btnApply, 0, wxALL, 5 );
137
138 btnCancel->SetDefault();
139 bSizer1->Add( buttonSizer, 0, wxALIGN_RIGHT | wxALL, 15 );
140
141 SetSizer( bSizer1 );
142
143 RestoreState();
144 Layout();
145 Center( wxBOTH );
146
147 #if defined(__WXMSW__) || defined(__WXGTK__)
148 SetDoubleBuffered(true);
149 #endif
150 }
151
152 // destructor
~CDlgDiagnosticLogFlags()153 CDlgDiagnosticLogFlags::~CDlgDiagnosticLogFlags() {
154 SaveState();
155 }
156
157
CreateCheckboxes()158 void CDlgDiagnosticLogFlags::CreateCheckboxes() {
159 SET_LOCALE sl;
160 char buf[64000];
161 MIOFILE mf;
162 bool val;
163
164 m_checkbox_list.clear();
165
166 mf.init_buf_write(buf, sizeof(buf));
167 m_cc_config.write(mf, log_flags);
168
169 mf.init_buf_read(buf);
170 XML_PARSER xp(&mf);
171
172 while (!xp.get_tag()) {
173 if (!xp.is_tag) {
174 continue;
175 }
176 if (xp.match_tag("log_flags")) break;
177 }
178
179 while (!xp.get_tag()) {
180 if (!xp.is_tag) {
181 continue;
182 }
183 if (xp.match_tag("/log_flags")) break;
184 wxString label = wxString(xp.parsed_tag);
185 xp.parse_bool(xp.parsed_tag, val);
186
187 wxCheckBox* ckbox = new wxCheckBox(m_scrolledWindow, wxID_ANY, label);
188 m_checkboxSizer->Add(ckbox, 0, wxLEFT, 25);
189 m_checkbox_list.push_back(ckbox);
190 ckbox->SetValue(val);
191 }
192
193 m_scrolledWindow->SetSizer( m_checkboxSizer );
194 m_scrolledWindow->Layout();
195 m_checkboxSizer->Fit( m_scrolledWindow );
196 }
197
SaveFlags()198 void CDlgDiagnosticLogFlags::SaveFlags() {
199 SET_LOCALE sl;
200 char buf[64000];
201 MIOFILE mf;
202 bool val;
203 unsigned int i;
204 CMainDocument* pDoc = wxGetApp().GetDocument();
205
206 wxASSERT(pDoc);
207 wxASSERT(wxDynamicCast(pDoc, CMainDocument));
208
209 mf.init_buf_write(buf, sizeof(buf));
210 for (i = 0; i<m_checkbox_list.size(); ++i) {
211 wxCheckBox* ckbox = m_checkbox_list[i];
212 val = ckbox->GetValue();
213 mf.printf(" <%s>%d</%s>\n", (const char*)ckbox->GetLabel().ToAscii(), (int)val, (const char*)ckbox->GetLabel().ToAscii());
214 }
215 mf.printf(" </log_flags>\n");
216
217 XML_PARSER xp(&mf);
218 mf.init_buf_read(buf);
219 log_flags.parse(xp);
220
221 int retval = pDoc->rpc.set_cc_config(m_cc_config, log_flags);
222 if (!retval) {
223 pDoc->rpc.read_cc_config();
224 }
225 }
226
227
228 /* saves dialog size and (on Mac) position */
SaveState()229 bool CDlgDiagnosticLogFlags::SaveState() {
230 wxConfigBase* pConfig = wxConfigBase::Get(FALSE);
231
232 wxASSERT(pConfig);
233 if (!pConfig) return false;
234
235 pConfig->SetPath("/DlgDiagnosticLogFlags/");
236 pConfig->Write(wxT("Width"), GetSize().GetWidth());
237 pConfig->Write(wxT("Height"), GetSize().GetHeight());
238
239 pConfig->Flush();
240
241 return true;
242 }
243
244 /* restores former dialog size and (on Mac) position */
RestoreState()245 bool CDlgDiagnosticLogFlags::RestoreState() {
246 wxConfigBase* pConfig = wxConfigBase::Get(FALSE);
247 int iWidth, iHeight;
248
249 wxASSERT(pConfig);
250 if (!pConfig) return false;
251
252 pConfig->SetPath("/DlgDiagnosticLogFlags/");
253
254 pConfig->Read(wxT("Width"), &iWidth, DLGDIAGNOSTICS_INITIAL_WIDTH);
255 pConfig->Read(wxT("Height"), &iHeight, DLGDIAGNOSTICS_INITIAL_HEIGHT);
256
257 // Guard against a rare situation where registry values are zero
258 if ((iWidth < 50) && (iWidth != wxDefaultCoord)) iWidth = DLGDIAGNOSTICS_INITIAL_WIDTH;
259 if ((iHeight < 50) && (iHeight != wxDefaultCoord)) iHeight = DLGDIAGNOSTICS_INITIAL_HEIGHT;
260
261 // Set size to saved values or defaults if no saved values
262 SetSize(std::max(iWidth, DLGDIAGNOSTICS_MIN_WIDTH), std::max(iHeight, DLGDIAGNOSTICS_MIN_HEIGHT));
263
264 return true;
265 }
266
267
OnSize(wxSizeEvent & event)268 void CDlgDiagnosticLogFlags::OnSize(wxSizeEvent& event) {
269 m_heading->SetLabel(m_headingText);
270 m_heading->Wrap(m_headingSizer->GetSize().GetWidth()-50);
271 m_headingSizer->Fit(m_heading);
272 Layout();
273 SaveState();
274 Refresh();
275
276 event.Skip();
277 }
278
279
OnOK(wxCommandEvent & event)280 void CDlgDiagnosticLogFlags::OnOK(wxCommandEvent& event) {
281 SaveFlags();
282
283 event.Skip();
284 }
285
286
OnSetDefaults(wxCommandEvent &)287 void CDlgDiagnosticLogFlags::OnSetDefaults(wxCommandEvent& ) {
288 log_flags.init();
289
290 m_checkboxSizer->Clear(true);
291 CreateCheckboxes();
292 m_btnApply->Enable();
293 Layout();
294 }
295
OnApply(wxCommandEvent & event)296 void CDlgDiagnosticLogFlags::OnApply(wxCommandEvent & event) {
297 SaveFlags();
298 m_btnApply->Enable(false);
299
300 event.Skip();
301 }
302
OnCheckBox(wxCommandEvent & event)303 void CDlgDiagnosticLogFlags::OnCheckBox(wxCommandEvent & event) {
304 m_btnApply->Enable();
305
306 event.Skip();
307 }
308