WinCE doesn't have wxCheckListBox, and doesn't like wxRmDir
[wxWidgets.git] / src / generic / dbgrptg.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/dbgrptg.cpp
3 // Purpose: implementation of wxDebugReportPreviewStd
4 // Author: Vadim Zeitlin, Andrej Putrin
5 // Modified by:
6 // Created: 2005-01-21
7 // RCS-ID: $Id$
8 // Copyright: (c) 2005 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // License: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #include "wx/sizer.h"
28 #include "wx/checklst.h"
29 #include "wx/textctrl.h"
30 #endif // WX_PRECOMP
31
32 #if wxUSE_DEBUGREPORT && wxUSE_CHECKLISTBOX
33
34 #include "wx/debugrpt.h"
35
36 #include "wx/intl.h"
37 #include "wx/filename.h"
38 #include "wx/ffile.h"
39 #include "wx/mimetype.h"
40
41 #include "wx/statline.h"
42 #include "wx/stattext.h"
43 #include "wx/filedlg.h"
44 #include "wx/valtext.h"
45
46 // ----------------------------------------------------------------------------
47 // wxDumpPreviewDlg: simple class for showing ASCII preview of dump files
48 // ----------------------------------------------------------------------------
49
50 class wxDumpPreviewDlg : public wxDialog
51 {
52 public:
53 wxDumpPreviewDlg(wxWindow *parent,
54 const wxString& title,
55 const wxString& text);
56
57 private:
58 // the text we show
59 wxTextCtrl *m_text;
60
61 DECLARE_NO_COPY_CLASS(wxDumpPreviewDlg)
62 };
63
64 wxDumpPreviewDlg::wxDumpPreviewDlg(wxWindow *parent,
65 const wxString& title,
66 const wxString& text)
67 : wxDialog(parent, wxID_ANY, title,
68 wxDefaultPosition, wxDefaultSize,
69 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
70 {
71 // create controls
72 // ---------------
73
74 // use wxTE_RICH2 style to avoid 64kB limit under MSW and display big files
75 // faster than with wxTE_RICH
76 m_text = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
77 wxPoint(0, 0), wxDefaultSize,
78 wxTE_MULTILINE |
79 wxTE_READONLY |
80 wxTE_NOHIDESEL |
81 wxTE_RICH2);
82 m_text->SetValue(text);
83
84 // use fixed-width font
85 m_text->SetFont(wxFont(12, wxFONTFAMILY_TELETYPE,
86 wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
87
88 wxButton *btnClose = new wxButton(this, wxID_CANCEL, _("Close"));
89
90
91 // layout them
92 // -----------
93
94 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL),
95 *sizerBtns = new wxBoxSizer(wxHORIZONTAL);
96
97 sizerBtns->Add(btnClose, 0, 0, 1);
98
99 sizerTop->Add(m_text, 1, wxEXPAND);
100 sizerTop->Add(sizerBtns, 0, wxALIGN_RIGHT | wxTOP | wxBOTTOM | wxRIGHT, 1);
101
102 // set the sizer &c
103 // ----------------
104
105 // make the text window bigger to show more contents of the file
106 sizerTop->SetItemMinSize(m_text, 600, 300);
107 SetSizer(sizerTop);
108
109 Layout();
110 Fit();
111
112 m_text->SetFocus();
113 }
114
115 // ----------------------------------------------------------------------------
116 // wxDumpOpenExternalDlg: choose a command for opening the given file
117 // ----------------------------------------------------------------------------
118
119 class wxDumpOpenExternalDlg : public wxDialog
120 {
121 public:
122 wxDumpOpenExternalDlg(wxWindow *parent, const wxFileName& filename);
123
124 // return the command chosed by user to open this file
125 const wxString& GetCommand() const { return m_command; }
126
127 wxString m_command;
128
129 private:
130 void OnBrowse(wxCommandEvent& event);
131
132 DECLARE_EVENT_TABLE()
133 DECLARE_NO_COPY_CLASS(wxDumpOpenExternalDlg)
134 };
135
136 BEGIN_EVENT_TABLE(wxDumpOpenExternalDlg, wxDialog)
137 EVT_BUTTON(wxID_MORE, wxDumpOpenExternalDlg::OnBrowse)
138 END_EVENT_TABLE()
139
140
141 wxDumpOpenExternalDlg::wxDumpOpenExternalDlg(wxWindow *parent,
142 const wxFileName& filename)
143 : wxDialog(parent,
144 wxID_ANY,
145 wxString::Format
146 (
147 _("Open file \"%s\""),
148 filename.GetFullPath().c_str()
149 ))
150 {
151 // create controls
152 // ---------------
153
154 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
155 sizerTop->Add(new wxStaticText(this, wxID_ANY,
156 wxString::Format
157 (
158 _("Enter command to open file \"%s\":"),
159 filename.GetFullName().c_str()
160 )),
161 wxSizerFlags().Border());
162
163 wxSizer *sizerH = new wxBoxSizer(wxHORIZONTAL);
164
165 wxTextCtrl *command = new wxTextCtrl
166 (
167 this,
168 wxID_ANY,
169 wxEmptyString,
170 wxDefaultPosition,
171 wxSize(250, -1),
172 0,
173 wxTextValidator(wxFILTER_NONE, &m_command)
174 );
175 sizerH->Add(command,
176 wxSizerFlags(1).Align(wxALIGN_CENTER_VERTICAL));
177 wxButton *browse = new wxButton(this, wxID_MORE, wxT(">>"),
178 wxDefaultPosition, wxDefaultSize,
179 wxBU_EXACTFIT);
180 sizerH->Add(browse,
181 wxSizerFlags(0).Align(wxALIGN_CENTER_VERTICAL). Border(wxLEFT));
182
183 sizerTop->Add(sizerH, wxSizerFlags(0).Expand().Border());
184
185 sizerTop->Add(new wxStaticLine(this), wxSizerFlags().Expand().Border());
186
187 sizerTop->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL),
188 wxSizerFlags().Align(wxALIGN_RIGHT).Border());
189
190 // set the sizer &c
191 // ----------------
192
193 SetSizer(sizerTop);
194
195 Layout();
196 Fit();
197
198 command->SetFocus();
199 }
200
201 void wxDumpOpenExternalDlg::OnBrowse(wxCommandEvent& )
202 {
203 wxFileName fname(m_command);
204 wxFileDialog dlg(this,
205 wxFileSelectorPromptStr,
206 fname.GetPathWithSep(),
207 fname.GetFullName()
208 #ifdef __WXMSW__
209 , _("Executable files (*.exe)|*.exe|All files (*.*)|*.*||")
210 #endif // __WXMSW__
211 );
212 if ( dlg.ShowModal() == wxID_OK )
213 {
214 m_command = dlg.GetPath();
215 TransferDataToWindow();
216 }
217 }
218
219
220 // ----------------------------------------------------------------------------
221 // wxDebugReportDialog: class showing debug report to the user
222 // ----------------------------------------------------------------------------
223
224 class wxDebugReportDialog : public wxDialog
225 {
226 public:
227 wxDebugReportDialog(wxDebugReport& dbgrpt);
228
229 virtual bool TransferDataToWindow();
230 virtual bool TransferDataFromWindow();
231
232 private:
233 void OnView(wxCommandEvent& );
234 void OnViewUpdate(wxUpdateUIEvent& );
235 void OnOpen(wxCommandEvent& );
236
237
238 // small helper: add wxEXPAND and wxALL flags
239 static wxSizerFlags SizerFlags(int proportion)
240 {
241 return wxSizerFlags(proportion).Expand().Border();
242 }
243
244
245 wxDebugReport& m_dbgrpt;
246
247 wxCheckListBox *m_checklst;
248 wxTextCtrl *m_notes;
249
250 wxArrayString m_files;
251
252 DECLARE_EVENT_TABLE()
253 DECLARE_NO_COPY_CLASS(wxDebugReportDialog)
254 };
255
256 // ============================================================================
257 // wxDebugReportDialog implementation
258 // ============================================================================
259
260 BEGIN_EVENT_TABLE(wxDebugReportDialog, wxDialog)
261 EVT_BUTTON(wxID_VIEW_DETAILS, wxDebugReportDialog::OnView)
262 EVT_UPDATE_UI(wxID_VIEW_DETAILS, wxDebugReportDialog::OnViewUpdate)
263 EVT_BUTTON(wxID_OPEN, wxDebugReportDialog::OnOpen)
264 EVT_UPDATE_UI(wxID_OPEN, wxDebugReportDialog::OnViewUpdate)
265 END_EVENT_TABLE()
266
267
268 // ----------------------------------------------------------------------------
269 // construction
270 // ----------------------------------------------------------------------------
271
272 wxDebugReportDialog::wxDebugReportDialog(wxDebugReport& dbgrpt)
273 : wxDialog(NULL, wxID_ANY,
274 wxString::Format(_("Debug report \"%s\""),
275 dbgrpt.GetReportName().c_str()),
276 wxDefaultPosition,
277 wxDefaultSize,
278 wxDEFAULT_DIALOG_STYLE | wxTHICK_FRAME),
279 m_dbgrpt(dbgrpt)
280 {
281 // upper part of the dialog: explanatory message
282 wxString msg;
283 msg << _("A debug report has been generated in the directory\n")
284 << _T('\n')
285 << _T(" \"") << dbgrpt.GetDirectory() << _T("\"\n")
286 << _T('\n')
287 << _("The report contains the files listed below. If any of these ")
288 << _("files contain private information,\n")
289 << _("please uncheck them and they will be removed from the report.\n")
290 << _T('\n')
291 << _("If you wish to suppress this debug report completely, please ")
292 << _("choose the \"Cancel\" button,\n")
293 << _("but be warned that it may hinder improving the program, so if\n")
294 << _("at all possible please do continue with the report generation.\n")
295 << _T('\n')
296 << _(" Thank you and we're sorry for the inconvenience!\n")
297 << _T("\n\n"); // just some white space to separate from other stuff
298
299 const wxSizerFlags flagsFixed(SizerFlags(0));
300 const wxSizerFlags flagsExpand(SizerFlags(1));
301 const wxSizerFlags flagsExpand2(SizerFlags(2));
302
303 wxSizer *sizerPreview =
304 new wxStaticBoxSizer(wxVERTICAL, this, _("&Debug report preview:"));
305 sizerPreview->Add(CreateTextSizer(msg), SizerFlags(0).Centre());
306
307 // ... and the list of files in this debug report with buttons to view them
308 wxSizer *sizerFileBtns = new wxBoxSizer(wxVERTICAL);
309 sizerFileBtns->AddStretchSpacer(1);
310 sizerFileBtns->Add(new wxButton(this, wxID_VIEW_DETAILS, _T("&View...")),
311 wxSizerFlags().Border(wxBOTTOM));
312 sizerFileBtns->Add(new wxButton(this, wxID_OPEN, _T("&Open...")),
313 wxSizerFlags().Border(wxTOP));
314 sizerFileBtns->AddStretchSpacer(1);
315
316 m_checklst = new wxCheckListBox(this, wxID_ANY);
317
318 wxSizer *sizerFiles = new wxBoxSizer(wxHORIZONTAL);
319 sizerFiles->Add(m_checklst, flagsExpand);
320 sizerFiles->Add(sizerFileBtns, flagsFixed);
321
322 sizerPreview->Add(sizerFiles, flagsExpand2);
323
324
325 // lower part of the dialog: notes field
326 wxSizer *sizerNotes = new wxStaticBoxSizer(wxVERTICAL, this, _("&Notes:"));
327
328 msg = _("If you have any additional information pertaining to this bug\n");
329 msg << _("report, please enter it here and it will be joined to it:");
330
331 m_notes = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
332 wxDefaultPosition, wxDefaultSize,
333 wxTE_MULTILINE);
334
335 sizerNotes->Add(CreateTextSizer(msg), flagsFixed);
336 sizerNotes->Add(m_notes, flagsExpand);
337
338
339 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
340 sizerTop->Add(sizerPreview, flagsExpand2);
341 sizerTop->AddSpacer(5);
342 sizerTop->Add(sizerNotes, flagsExpand);
343 sizerTop->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), flagsFixed);
344
345 SetSizerAndFit(sizerTop);
346 Layout();
347 CentreOnScreen();
348 }
349
350 // ----------------------------------------------------------------------------
351 // data exchange
352 // ----------------------------------------------------------------------------
353
354 bool wxDebugReportDialog::TransferDataToWindow()
355 {
356 // all files are included in the report by default
357 const size_t count = m_dbgrpt.GetFilesCount();
358 for ( size_t n = 0; n < count; n++ )
359 {
360 wxString name,
361 desc;
362 if ( m_dbgrpt.GetFile(n, &name, &desc) )
363 {
364 m_checklst->Append(name + _T(" (") + desc + _T(')'));
365 m_checklst->Check(n);
366
367 m_files.Add(name);
368 }
369 }
370
371 return true;
372 }
373
374 bool wxDebugReportDialog::TransferDataFromWindow()
375 {
376 // any unchecked files should be removed from the report
377 const size_t count = m_checklst->GetCount();
378 for ( size_t n = 0; n < count; n++ )
379 {
380 if ( !m_checklst->IsChecked(n) )
381 {
382 m_dbgrpt.RemoveFile(m_files[n]);
383 }
384 }
385
386 // if the user entered any notes, add them to the report
387 const wxString notes = m_notes->GetValue();
388 if ( !notes.empty() )
389 {
390 // for now it's fixed, could make it configurable in the future...
391 const wxChar *NOTES_FILE_NAME = _T("notes.txt");
392 wxFileName fn(m_dbgrpt.GetDirectory(), NOTES_FILE_NAME);
393 wxFFile file(fn.GetFullPath(), _T("w"));
394 if ( file.IsOpened() && file.Write(notes) )
395 {
396 m_dbgrpt.AddFile(NOTES_FILE_NAME, _T("user notes"));
397 }
398 }
399
400 return true;
401 }
402
403 // ----------------------------------------------------------------------------
404 // event handlers
405 // ----------------------------------------------------------------------------
406
407 void wxDebugReportDialog::OnView(wxCommandEvent& )
408 {
409 const int sel = m_checklst->GetSelection();
410 wxCHECK_RET( sel != -1, _T("invalid selection in OnView()") );
411
412 wxFileName fn(m_dbgrpt.GetDirectory(), m_files[sel]);
413 wxString str;
414
415 wxFFile file(fn.GetFullPath());
416 if ( file.IsOpened() && file.ReadAll(&str) )
417 {
418 wxDumpPreviewDlg dlg(this, m_files[sel], str);
419 dlg.ShowModal();
420 }
421 }
422
423 void wxDebugReportDialog::OnOpen(wxCommandEvent& )
424 {
425 const int sel = m_checklst->GetSelection();
426 wxCHECK_RET( sel != -1, _T("invalid selection in OnOpen()") );
427
428 wxFileName fn(m_dbgrpt.GetDirectory(), m_files[sel]);
429
430 // try to get the command to open this kind of files ourselves
431 wxString command;
432 wxFileType *
433 ft = wxTheMimeTypesManager->GetFileTypeFromExtension(fn.GetExt());
434 if ( ft )
435 {
436 command = ft->GetOpenCommand(fn.GetFullPath());
437 }
438
439 // if we couldn't, ask the user
440 if ( command.empty() )
441 {
442 wxDumpOpenExternalDlg dlg(this, fn);
443 if ( dlg.ShowModal() == wxID_OK )
444 {
445 // get the command chosen by the user and append file name to it
446
447 // if we don't have place marker for file name in the command...
448 wxString cmd = dlg.GetCommand();
449 if ( cmd.find(_T('%')) == wxString::npos )
450 {
451 // ...add it
452 cmd += _T(" \"%s\"");
453 }
454
455 command = wxFileType::ExpandCommand(cmd, fn.GetFullPath());
456 }
457 }
458
459 if ( !command.empty() )
460 ::wxExecute(command);
461 }
462
463 void wxDebugReportDialog::OnViewUpdate(wxUpdateUIEvent& event)
464 {
465 int sel = m_checklst->GetSelection();
466 if (sel >= 0)
467 {
468 wxFileName fn(m_dbgrpt.GetDirectory(), m_files[sel]);
469 event.Enable(fn.FileExists());
470 }
471 else
472 event.Enable(false);
473 }
474
475
476 // ============================================================================
477 // wxDebugReportPreviewStd implementation
478 // ============================================================================
479
480 bool wxDebugReportPreviewStd::Show(wxDebugReport& dbgrpt) const
481 {
482 if ( !dbgrpt.GetFilesCount() )
483 return false;
484
485 wxDebugReportDialog dlg(dbgrpt);
486
487 return dlg.ShowModal() == wxID_OK && dbgrpt.GetFilesCount() != 0;
488 }
489
490 #endif // wxUSE_DEBUGREPORT
491