]> git.saurik.com Git - wxWidgets.git/blame - src/generic/dbgrptg.cpp
Add comments explaining the workaround for mingw 3.2.3
[wxWidgets.git] / src / generic / dbgrptg.cpp
CommitLineData
ce4fd7b5
VZ
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
ef826e24 32#if wxUSE_DEBUGREPORT
ce4fd7b5
VZ
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"
5b89b4dc
RR
42#include "wx/stattext.h"
43#include "wx/filedlg.h"
44#include "wx/valtext.h"
ce4fd7b5
VZ
45
46// ----------------------------------------------------------------------------
47// wxDumpPreviewDlg: simple class for showing ASCII preview of dump files
48// ----------------------------------------------------------------------------
49
50class wxDumpPreviewDlg : public wxDialog
51{
52public:
53 wxDumpPreviewDlg(wxWindow *parent,
54 const wxString& title,
55 const wxString& text);
56
57private:
58 // the text we show
59 wxTextCtrl *m_text;
60
61 DECLARE_NO_COPY_CLASS(wxDumpPreviewDlg)
62};
63
64wxDumpPreviewDlg::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
119class wxDumpOpenExternalDlg : public wxDialog
120{
121public:
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
129private:
130 void OnBrowse(wxCommandEvent& event);
131
132 DECLARE_EVENT_TABLE()
133 DECLARE_NO_COPY_CLASS(wxDumpOpenExternalDlg)
134};
135
136BEGIN_EVENT_TABLE(wxDumpOpenExternalDlg, wxDialog)
137 EVT_BUTTON(wxID_MORE, wxDumpOpenExternalDlg::OnBrowse)
138END_EVENT_TABLE()
139
140
141wxDumpOpenExternalDlg::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,
f5c479cc
WS
171 wxSize(250, wxDefaultCoord),
172 0
173#if wxUSE_VALIDATORS
174 ,wxTextValidator(wxFILTER_NONE, &m_command)
175#endif
ce4fd7b5
VZ
176 );
177 sizerH->Add(command,
178 wxSizerFlags(1).Align(wxALIGN_CENTER_VERTICAL));
179 wxButton *browse = new wxButton(this, wxID_MORE, wxT(">>"),
180 wxDefaultPosition, wxDefaultSize,
181 wxBU_EXACTFIT);
182 sizerH->Add(browse,
183 wxSizerFlags(0).Align(wxALIGN_CENTER_VERTICAL). Border(wxLEFT));
184
185 sizerTop->Add(sizerH, wxSizerFlags(0).Expand().Border());
186
187 sizerTop->Add(new wxStaticLine(this), wxSizerFlags().Expand().Border());
188
189 sizerTop->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL),
190 wxSizerFlags().Align(wxALIGN_RIGHT).Border());
191
192 // set the sizer &c
193 // ----------------
194
195 SetSizer(sizerTop);
196
197 Layout();
198 Fit();
199
200 command->SetFocus();
201}
202
203void wxDumpOpenExternalDlg::OnBrowse(wxCommandEvent& )
204{
205 wxFileName fname(m_command);
206 wxFileDialog dlg(this,
207 wxFileSelectorPromptStr,
208 fname.GetPathWithSep(),
209 fname.GetFullName()
210#ifdef __WXMSW__
211 , _("Executable files (*.exe)|*.exe|All files (*.*)|*.*||")
212#endif // __WXMSW__
213 );
214 if ( dlg.ShowModal() == wxID_OK )
215 {
216 m_command = dlg.GetPath();
217 TransferDataToWindow();
218 }
219}
220
221
222// ----------------------------------------------------------------------------
223// wxDebugReportDialog: class showing debug report to the user
224// ----------------------------------------------------------------------------
225
226class wxDebugReportDialog : public wxDialog
227{
228public:
229 wxDebugReportDialog(wxDebugReport& dbgrpt);
230
231 virtual bool TransferDataToWindow();
232 virtual bool TransferDataFromWindow();
233
234private:
235 void OnView(wxCommandEvent& );
236 void OnViewUpdate(wxUpdateUIEvent& );
237 void OnOpen(wxCommandEvent& );
238
239
240 // small helper: add wxEXPAND and wxALL flags
241 static wxSizerFlags SizerFlags(int proportion)
242 {
243 return wxSizerFlags(proportion).Expand().Border();
244 }
245
246
247 wxDebugReport& m_dbgrpt;
248
249 wxCheckListBox *m_checklst;
250 wxTextCtrl *m_notes;
251
252 wxArrayString m_files;
253
254 DECLARE_EVENT_TABLE()
255 DECLARE_NO_COPY_CLASS(wxDebugReportDialog)
256};
257
258// ============================================================================
259// wxDebugReportDialog implementation
260// ============================================================================
261
262BEGIN_EVENT_TABLE(wxDebugReportDialog, wxDialog)
263 EVT_BUTTON(wxID_VIEW_DETAILS, wxDebugReportDialog::OnView)
264 EVT_UPDATE_UI(wxID_VIEW_DETAILS, wxDebugReportDialog::OnViewUpdate)
265 EVT_BUTTON(wxID_OPEN, wxDebugReportDialog::OnOpen)
266 EVT_UPDATE_UI(wxID_OPEN, wxDebugReportDialog::OnViewUpdate)
267END_EVENT_TABLE()
268
269
270// ----------------------------------------------------------------------------
271// construction
272// ----------------------------------------------------------------------------
273
274wxDebugReportDialog::wxDebugReportDialog(wxDebugReport& dbgrpt)
275 : wxDialog(NULL, wxID_ANY,
276 wxString::Format(_("Debug report \"%s\""),
277 dbgrpt.GetReportName().c_str()),
278 wxDefaultPosition,
279 wxDefaultSize,
280 wxDEFAULT_DIALOG_STYLE | wxTHICK_FRAME),
281 m_dbgrpt(dbgrpt)
282{
283 // upper part of the dialog: explanatory message
284 wxString msg;
285 msg << _("A debug report has been generated in the directory\n")
286 << _T('\n')
287 << _T(" \"") << dbgrpt.GetDirectory() << _T("\"\n")
288 << _T('\n')
289 << _("The report contains the files listed below. If any of these ")
290 << _("files contain private information,\n")
291 << _("please uncheck them and they will be removed from the report.\n")
292 << _T('\n')
293 << _("If you wish to suppress this debug report completely, please ")
294 << _("choose the \"Cancel\" button,\n")
295 << _("but be warned that it may hinder improving the program, so if\n")
296 << _("at all possible please do continue with the report generation.\n")
297 << _T('\n')
298 << _(" Thank you and we're sorry for the inconvenience!\n")
299 << _T("\n\n"); // just some white space to separate from other stuff
300
301 const wxSizerFlags flagsFixed(SizerFlags(0));
302 const wxSizerFlags flagsExpand(SizerFlags(1));
303 const wxSizerFlags flagsExpand2(SizerFlags(2));
304
305 wxSizer *sizerPreview =
306 new wxStaticBoxSizer(wxVERTICAL, this, _("&Debug report preview:"));
307 sizerPreview->Add(CreateTextSizer(msg), SizerFlags(0).Centre());
308
309 // ... and the list of files in this debug report with buttons to view them
310 wxSizer *sizerFileBtns = new wxBoxSizer(wxVERTICAL);
311 sizerFileBtns->AddStretchSpacer(1);
312 sizerFileBtns->Add(new wxButton(this, wxID_VIEW_DETAILS, _T("&View...")),
313 wxSizerFlags().Border(wxBOTTOM));
314 sizerFileBtns->Add(new wxButton(this, wxID_OPEN, _T("&Open...")),
315 wxSizerFlags().Border(wxTOP));
316 sizerFileBtns->AddStretchSpacer(1);
317
318 m_checklst = new wxCheckListBox(this, wxID_ANY);
319
320 wxSizer *sizerFiles = new wxBoxSizer(wxHORIZONTAL);
321 sizerFiles->Add(m_checklst, flagsExpand);
322 sizerFiles->Add(sizerFileBtns, flagsFixed);
323
324 sizerPreview->Add(sizerFiles, flagsExpand2);
325
326
327 // lower part of the dialog: notes field
328 wxSizer *sizerNotes = new wxStaticBoxSizer(wxVERTICAL, this, _("&Notes:"));
329
330 msg = _("If you have any additional information pertaining to this bug\n");
331 msg << _("report, please enter it here and it will be joined to it:");
332
333 m_notes = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
334 wxDefaultPosition, wxDefaultSize,
335 wxTE_MULTILINE);
336
337 sizerNotes->Add(CreateTextSizer(msg), flagsFixed);
338 sizerNotes->Add(m_notes, flagsExpand);
339
340
341 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
342 sizerTop->Add(sizerPreview, flagsExpand2);
343 sizerTop->AddSpacer(5);
344 sizerTop->Add(sizerNotes, flagsExpand);
345 sizerTop->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), flagsFixed);
346
347 SetSizerAndFit(sizerTop);
348 Layout();
349 CentreOnScreen();
350}
351
352// ----------------------------------------------------------------------------
353// data exchange
354// ----------------------------------------------------------------------------
355
356bool wxDebugReportDialog::TransferDataToWindow()
357{
358 // all files are included in the report by default
359 const size_t count = m_dbgrpt.GetFilesCount();
360 for ( size_t n = 0; n < count; n++ )
361 {
362 wxString name,
363 desc;
364 if ( m_dbgrpt.GetFile(n, &name, &desc) )
365 {
366 m_checklst->Append(name + _T(" (") + desc + _T(')'));
367 m_checklst->Check(n);
368
369 m_files.Add(name);
370 }
371 }
372
373 return true;
374}
375
376bool wxDebugReportDialog::TransferDataFromWindow()
377{
378 // any unchecked files should be removed from the report
379 const size_t count = m_checklst->GetCount();
380 for ( size_t n = 0; n < count; n++ )
381 {
382 if ( !m_checklst->IsChecked(n) )
383 {
384 m_dbgrpt.RemoveFile(m_files[n]);
385 }
386 }
387
388 // if the user entered any notes, add them to the report
389 const wxString notes = m_notes->GetValue();
390 if ( !notes.empty() )
391 {
392 // for now it's fixed, could make it configurable in the future...
393 const wxChar *NOTES_FILE_NAME = _T("notes.txt");
394 wxFileName fn(m_dbgrpt.GetDirectory(), NOTES_FILE_NAME);
395 wxFFile file(fn.GetFullPath(), _T("w"));
396 if ( file.IsOpened() && file.Write(notes) )
397 {
398 m_dbgrpt.AddFile(NOTES_FILE_NAME, _T("user notes"));
399 }
400 }
401
402 return true;
403}
404
405// ----------------------------------------------------------------------------
406// event handlers
407// ----------------------------------------------------------------------------
408
409void wxDebugReportDialog::OnView(wxCommandEvent& )
410{
411 const int sel = m_checklst->GetSelection();
412 wxCHECK_RET( sel != -1, _T("invalid selection in OnView()") );
413
414 wxFileName fn(m_dbgrpt.GetDirectory(), m_files[sel]);
415 wxString str;
416
417 wxFFile file(fn.GetFullPath());
418 if ( file.IsOpened() && file.ReadAll(&str) )
419 {
420 wxDumpPreviewDlg dlg(this, m_files[sel], str);
421 dlg.ShowModal();
422 }
423}
424
425void wxDebugReportDialog::OnOpen(wxCommandEvent& )
426{
427 const int sel = m_checklst->GetSelection();
428 wxCHECK_RET( sel != -1, _T("invalid selection in OnOpen()") );
429
430 wxFileName fn(m_dbgrpt.GetDirectory(), m_files[sel]);
431
432 // try to get the command to open this kind of files ourselves
433 wxString command;
434 wxFileType *
435 ft = wxTheMimeTypesManager->GetFileTypeFromExtension(fn.GetExt());
436 if ( ft )
437 {
438 command = ft->GetOpenCommand(fn.GetFullPath());
439 }
440
441 // if we couldn't, ask the user
442 if ( command.empty() )
443 {
444 wxDumpOpenExternalDlg dlg(this, fn);
445 if ( dlg.ShowModal() == wxID_OK )
446 {
447 // get the command chosen by the user and append file name to it
448
449 // if we don't have place marker for file name in the command...
450 wxString cmd = dlg.GetCommand();
451 if ( cmd.find(_T('%')) == wxString::npos )
452 {
453 // ...add it
454 cmd += _T(" \"%s\"");
455 }
456
457 command = wxFileType::ExpandCommand(cmd, fn.GetFullPath());
458 }
459 }
460
461 if ( !command.empty() )
462 ::wxExecute(command);
463}
464
465void wxDebugReportDialog::OnViewUpdate(wxUpdateUIEvent& event)
466{
467 int sel = m_checklst->GetSelection();
468 if (sel >= 0)
469 {
470 wxFileName fn(m_dbgrpt.GetDirectory(), m_files[sel]);
471 event.Enable(fn.FileExists());
472 }
473 else
474 event.Enable(false);
475}
476
477
478// ============================================================================
479// wxDebugReportPreviewStd implementation
480// ============================================================================
481
482bool wxDebugReportPreviewStd::Show(wxDebugReport& dbgrpt) const
483{
484 if ( !dbgrpt.GetFilesCount() )
485 return false;
486
487 wxDebugReportDialog dlg(dbgrpt);
488
489 return dlg.ShowModal() == wxID_OK && dbgrpt.GetFilesCount() != 0;
490}
491
492#endif // wxUSE_DEBUGREPORT
493