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