]> git.saurik.com Git - wxWidgets.git/blame - samples/html/test/test.cpp
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / samples / html / test / test.cpp
CommitLineData
5526e819
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: test.cpp
3// Purpose: wxHtml testing example
3f6bd7c1
DS
4// Author: Vaclav Slavik
5// Created: 1999-07-07
3f6bd7c1
DS
6// Copyright: (c) Vaclav Slavik
7// Licence: wxWindows licence
5526e819
VS
8/////////////////////////////////////////////////////////////////////////////
9
5526e819 10// For compilers that support precompilation, includes "wx/wx.h".
92a19c2e 11#include "wx/wxprec.h"
5526e819
VS
12
13#ifdef __BORLANDC__
14 #pragma hdrstop
15#endif
16
3f6bd7c1 17// For all others, include the necessary headers (this file is usually all you
be5a51fb 18// need because it includes almost all "standard" wxWidgets headers
5526e819 19#ifndef WX_PRECOMP
67547666 20 #include "wx/wx.h"
5526e819
VS
21#endif
22
40091824 23#include "wx/image.h"
bbb8f29b 24#include "wx/sysopt.h"
40091824
VS
25#include "wx/html/htmlwin.h"
26#include "wx/html/htmlproc.h"
27#include "wx/fs_inet.h"
28#include "wx/filedlg.h"
d83c04e6 29#include "wx/utils.h"
0f11c233
VZ
30#include "wx/clipbrd.h"
31#include "wx/dataobj.h"
63b459df 32#include "wx/stopwatch.h"
5526e819 33
18922659
JS
34#include "../../sample.xpm"
35
5526e819
VS
36// ----------------------------------------------------------------------------
37// private classes
38// ----------------------------------------------------------------------------
39
40// Define a new application type, each program should derive a class from wxApp
3e729cbe
VS
41class MyApp : public wxApp
42{
43public:
3f6bd7c1 44 virtual bool OnInit();
3e729cbe 45};
5526e819 46
4bfa3189
WS
47// Define a new html window type: this is a wrapper for handling wxHtmlWindow events
48class MyHtmlWindow : public wxHtmlWindow
49{
50public:
03a187cc
VZ
51 MyHtmlWindow(wxWindow *parent) : wxHtmlWindow( parent )
52 {
53 // no custom background initially to avoid confusing people
54 m_drawCustomBg = false;
55 }
4bfa3189
WS
56
57 virtual wxHtmlOpeningStatus OnOpeningURL(wxHtmlURLType WXUNUSED(type),
58 const wxString& WXUNUSED(url),
59 wxString *WXUNUSED(redirect)) const;
60
03a187cc
VZ
61 // toggle drawing of custom background
62 void DrawCustomBg(bool draw)
63 {
64 m_drawCustomBg = draw;
65 Refresh();
66 }
67
4bfa3189 68private:
03a187cc 69#if wxUSE_CLIPBOARD
0f11c233 70 void OnClipboardEvent(wxClipboardTextEvent& event);
03a187cc
VZ
71#endif // wxUSE_CLIPBOARD
72 void OnEraseBgEvent(wxEraseEvent& event);
73
74 bool m_drawCustomBg;
0f11c233 75
0f11c233 76 DECLARE_EVENT_TABLE()
c0c133e1 77 wxDECLARE_NO_COPY_CLASS(MyHtmlWindow);
4bfa3189
WS
78};
79
5526e819 80// Define a new frame type: this is going to be our main frame
3e729cbe
VS
81class MyFrame : public wxFrame
82{
83public:
3f6bd7c1 84 // ctor(s)
3e729cbe
VS
85 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
86
3f6bd7c1 87 // event handlers (these functions should _not_ be virtual)
3e729cbe
VS
88 void OnQuit(wxCommandEvent& event);
89 void OnPageOpen(wxCommandEvent& event);
17ede0b1
RR
90 void OnDefaultLocalBrowser(wxCommandEvent& event);
91 void OnDefaultWebBrowser(wxCommandEvent& event);
3e729cbe
VS
92 void OnBack(wxCommandEvent& event);
93 void OnForward(wxCommandEvent& event);
94 void OnProcessor(wxCommandEvent& event);
03a187cc 95 void OnDrawCustomBg(wxCommandEvent& event);
3e729cbe 96
a1c3cdc4
VS
97 void OnHtmlLinkClicked(wxHtmlLinkEvent& event);
98 void OnHtmlCellHover(wxHtmlCellEvent &event);
99 void OnHtmlCellClicked(wxHtmlCellEvent &event);
100
3e729cbe 101private:
4bfa3189 102 MyHtmlWindow *m_Html;
3f6bd7c1
DS
103 wxHtmlProcessor *m_Processor;
104
be5a51fb 105 // Any class wishing to process wxWidgets events must use this macro
3f6bd7c1 106 DECLARE_EVENT_TABLE()
3e729cbe
VS
107};
108
109
110class BoldProcessor : public wxHtmlProcessor
111{
3f6bd7c1
DS
112public:
113 virtual wxString Process(const wxString& s) const
114 {
115 wxString r(s);
116 r.Replace(wxT("<b>"), wxEmptyString);
117 r.Replace(wxT("<B>"), wxEmptyString);
118 r.Replace(wxT("</b>"), wxEmptyString);
119 r.Replace(wxT("</B>"), wxEmptyString);
120
121 return r;
122 }
3e729cbe 123};
5526e819
VS
124
125// ----------------------------------------------------------------------------
126// constants
127// ----------------------------------------------------------------------------
128
129// IDs for the controls and the menu commands
3f6bd7c1
DS
130enum
131{
5526e819 132 // menu items
3f6bd7c1 133 ID_PageOpen = wxID_HIGHEST,
17ede0b1
RR
134 ID_DefaultLocalBrowser,
135 ID_DefaultWebBrowser,
3f6bd7c1
DS
136 ID_Back,
137 ID_Forward,
03a187cc
VZ
138 ID_Processor,
139 ID_DrawCustomBg
3f6bd7c1 140};
5526e819
VS
141
142// ----------------------------------------------------------------------------
be5a51fb 143// event tables and other macros for wxWidgets
5526e819
VS
144// ----------------------------------------------------------------------------
145
3f6bd7c1
DS
146BEGIN_EVENT_TABLE(MyFrame, wxFrame)
147 EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
148 EVT_MENU(ID_PageOpen, MyFrame::OnPageOpen)
17ede0b1
RR
149 EVT_MENU(ID_DefaultLocalBrowser, MyFrame::OnDefaultLocalBrowser)
150 EVT_MENU(ID_DefaultWebBrowser, MyFrame::OnDefaultWebBrowser)
3f6bd7c1
DS
151 EVT_MENU(ID_Back, MyFrame::OnBack)
152 EVT_MENU(ID_Forward, MyFrame::OnForward)
153 EVT_MENU(ID_Processor, MyFrame::OnProcessor)
03a187cc 154 EVT_MENU(ID_DrawCustomBg, MyFrame::OnDrawCustomBg)
a1c3cdc4
VS
155
156 EVT_HTML_LINK_CLICKED(wxID_ANY, MyFrame::OnHtmlLinkClicked)
157 EVT_HTML_CELL_HOVER(wxID_ANY, MyFrame::OnHtmlCellHover)
158 EVT_HTML_CELL_CLICKED(wxID_ANY, MyFrame::OnHtmlCellClicked)
3f6bd7c1
DS
159END_EVENT_TABLE()
160
161IMPLEMENT_APP(MyApp)
162
163// ============================================================================
164// implementation
165// ============================================================================
166
167// ----------------------------------------------------------------------------
168// the application class
169// ----------------------------------------------------------------------------
170
171// `Main program' equivalent: the program execution "starts" here
172bool MyApp::OnInit()
173{
45e6e6f8
VZ
174 if ( !wxApp::OnInit() )
175 return false;
176
954cc8d2 177#if wxUSE_SYSTEM_OPTIONS
3f6bd7c1 178 wxSystemOptions::SetOption(wxT("no-maskblt"), 1);
954cc8d2 179#endif
bbb8f29b 180
3f6bd7c1 181 wxInitAllImageHandlers();
954cc8d2 182#if wxUSE_FS_INET && wxUSE_STREAMS && wxUSE_SOCKETS
3f6bd7c1 183 wxFileSystem::AddHandler(new wxInternetFSHandler);
954cc8d2 184#endif
5612e524 185
be5a51fb 186 SetVendorName(wxT("wxWidgets"));
3f6bd7c1
DS
187 SetAppName(wxT("wxHtmlTest"));
188 // the following call to wxConfig::Get will use it to create an object...
5612e524 189
5526e819 190 // Create the main application window
3f6bd7c1
DS
191 MyFrame *frame = new MyFrame(_("wxHtmlWindow testing application"),
192 wxDefaultPosition, wxSize(640, 480));
193
194 frame->Show();
195
196 return true /* continue running */;
197}
5526e819
VS
198
199// ----------------------------------------------------------------------------
200// main frame
201// ----------------------------------------------------------------------------
202
5526e819 203// frame constructor
3f6bd7c1
DS
204MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
205 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size,
206 wxDEFAULT_FRAME_STYLE, wxT("html_test_app"))
207{
5526e819 208 // create a menu bar
3f6bd7c1
DS
209 wxMenu *menuFile = new wxMenu;
210 wxMenu *menuNav = new wxMenu;
211
63b459df 212 menuFile->Append(ID_PageOpen, _("&Open HTML page...\tCtrl-O"));
17ede0b1
RR
213 menuFile->Append(ID_DefaultLocalBrowser, _("&Open current page with default browser"));
214 menuFile->Append(ID_DefaultWebBrowser, _("Open a &web page with default browser"));
3f6bd7c1
DS
215 menuFile->AppendSeparator();
216 menuFile->Append(ID_Processor, _("&Remove bold attribute"),
217 wxEmptyString, wxITEM_CHECK);
03a187cc
VZ
218 menuFile->AppendSeparator();
219 menuFile->AppendCheckItem(ID_DrawCustomBg, "&Draw custom background");
3f6bd7c1
DS
220 menuFile->AppendSeparator();
221 menuFile->Append(wxID_EXIT, _("&Close frame"));
222 menuNav->Append(ID_Back, _("Go &BACK"));
223 menuNav->Append(ID_Forward, _("Go &FORWARD"));
5526e819
VS
224
225 // now append the freshly created menu to the menu bar...
3f6bd7c1
DS
226 wxMenuBar *menuBar = new wxMenuBar;
227 menuBar->Append(menuFile, _("&File"));
228 menuBar->Append(menuNav, _("&Navigate"));
5526e819
VS
229
230 // ... and attach this menu bar to the frame
3f6bd7c1
DS
231 SetMenuBar(menuBar);
232
18922659 233 SetIcon(wxIcon(sample_xpm));
11fdee42 234
3f6bd7c1
DS
235#if wxUSE_ACCEL
236 // Create convenient accelerators for Back and Forward navigation
237 wxAcceleratorEntry entries[2];
238 entries[0].Set(wxACCEL_ALT, WXK_LEFT, ID_Back);
239 entries[1].Set(wxACCEL_ALT, WXK_RIGHT, ID_Forward);
240
241 wxAcceleratorTable accel(WXSIZEOF(entries), entries);
242 SetAcceleratorTable(accel);
243#endif // wxUSE_ACCEL
244
8520f137 245#if wxUSE_STATUSBAR
4bfa3189 246 CreateStatusBar(2);
8520f137 247#endif // wxUSE_STATUSBAR
3f6bd7c1
DS
248
249 m_Processor = new BoldProcessor;
250 m_Processor->Enable(false);
4bfa3189 251 m_Html = new MyHtmlWindow(this);
3f6bd7c1 252 m_Html->SetRelatedFrame(this, _("HTML : %s"));
8520f137 253#if wxUSE_STATUSBAR
63b459df 254 m_Html->SetRelatedStatusBar(1);
8520f137 255#endif // wxUSE_STATUSBAR
3f6bd7c1
DS
256 m_Html->ReadCustomization(wxConfig::Get());
257 m_Html->LoadFile(wxFileName(wxT("test.htm")));
258 m_Html->AddProcessor(m_Processor);
a1c3cdc4 259
9a83f860 260 wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, wxT(""),
a1c3cdc4
VS
261 wxDefaultPosition, wxDefaultSize,
262 wxTE_MULTILINE);
263
264 delete wxLog::SetActiveTarget(new wxLogTextCtrl(text));
265
266 wxSizer *sz = new wxBoxSizer(wxVERTICAL);
267 sz->Add(m_Html, 3, wxGROW);
268 sz->Add(text, 1, wxGROW);
269 SetSizer(sz);
3f6bd7c1 270}
5526e819
VS
271
272
273// event handlers
274
3e729cbe
VS
275void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
276{
3f6bd7c1
DS
277 m_Html->WriteCustomization(wxConfig::Get());
278 delete wxConfig::Set(NULL);
279
280 // true is to force the frame to close
281 Close(true);
3e729cbe
VS
282}
283
284void MyFrame::OnPageOpen(wxCommandEvent& WXUNUSED(event))
285{
71307412 286#if wxUSE_FILEDLG
3f6bd7c1 287 wxString p = wxFileSelector(_("Open HTML document"), wxEmptyString,
43056e6e 288 wxEmptyString, wxEmptyString, wxT("HTML files|*.htm;*.html"));
3f6bd7c1 289
71307412 290 if (!p.empty())
63b459df
VZ
291 {
292#if wxUSE_STOPWATCH
293 wxStopWatch sw;
294#endif
9dbadebe 295 m_Html->LoadFile(wxFileName(p));
63b459df
VZ
296#if wxUSE_STOPWATCH
297 wxLogStatus("Loaded \"%s\" in %lums", p, sw.Time());
298#endif
299 }
71307412 300#endif // wxUSE_FILEDLG
3e729cbe
VS
301}
302
17ede0b1 303void MyFrame::OnDefaultLocalBrowser(wxCommandEvent& WXUNUSED(event))
d83c04e6
WS
304{
305 wxString page = m_Html->GetOpenedPage();
306 if (!page.empty())
307 {
308 wxLaunchDefaultBrowser(page);
309 }
310}
311
17ede0b1
RR
312void MyFrame::OnDefaultWebBrowser(wxCommandEvent& WXUNUSED(event))
313{
314 wxString page = m_Html->GetOpenedPage();
315 if (!page.empty())
316 {
317 wxLaunchDefaultBrowser(wxT("http://www.google.com"));
318 }
319}
320
3e729cbe
VS
321void MyFrame::OnBack(wxCommandEvent& WXUNUSED(event))
322{
3f6bd7c1
DS
323 if (!m_Html->HistoryBack())
324 {
325 wxMessageBox(_("You reached prehistory era!"));
326 }
3e729cbe
VS
327}
328
329void MyFrame::OnForward(wxCommandEvent& WXUNUSED(event))
330{
3f6bd7c1
DS
331 if (!m_Html->HistoryForward())
332 {
333 wxMessageBox(_("No more items in history!"));
334 }
3e729cbe
VS
335}
336
337void MyFrame::OnProcessor(wxCommandEvent& WXUNUSED(event))
338{
339 m_Processor->Enable(!m_Processor->IsEnabled());
340 m_Html->LoadPage(m_Html->GetOpenedPage());
3e729cbe 341}
4bfa3189 342
03a187cc
VZ
343void MyFrame::OnDrawCustomBg(wxCommandEvent& event)
344{
345 m_Html->DrawCustomBg(event.IsChecked());
346}
347
a1c3cdc4
VS
348void MyFrame::OnHtmlLinkClicked(wxHtmlLinkEvent &event)
349{
350 wxLogMessage(wxT("The url '%s' has been clicked!"), event.GetLinkInfo().GetHref().c_str());
351
352 // skipping this event the default behaviour (load the clicked URL)
353 // will happen...
354 event.Skip();
355}
356
357void MyFrame::OnHtmlCellHover(wxHtmlCellEvent &event)
358{
34e20200 359 wxLogMessage(wxT("Mouse moved over cell %p at %d;%d"),
a1c3cdc4
VS
360 event.GetCell(), event.GetPoint().x, event.GetPoint().y);
361}
362
363void MyFrame::OnHtmlCellClicked(wxHtmlCellEvent &event)
364{
34e20200 365 wxLogMessage(wxT("Click over cell %p at %d;%d"),
a1c3cdc4
VS
366 event.GetCell(), event.GetPoint().x, event.GetPoint().y);
367
368 // if we don't skip the event, OnHtmlLinkClicked won't be called!
369 event.Skip();
370}
371
4bfa3189
WS
372wxHtmlOpeningStatus MyHtmlWindow::OnOpeningURL(wxHtmlURLType WXUNUSED(type),
373 const wxString& url,
374 wxString *WXUNUSED(redirect)) const
375{
9a83f860 376 GetRelatedFrame()->SetStatusText(url + wxT(" lately opened"),1);
4bfa3189
WS
377 return wxHTML_OPEN;
378}
0f11c233 379
0f11c233 380BEGIN_EVENT_TABLE(MyHtmlWindow, wxHtmlWindow)
03a187cc 381#if wxUSE_CLIPBOARD
0f11c233 382 EVT_TEXT_COPY(wxID_ANY, MyHtmlWindow::OnClipboardEvent)
03a187cc
VZ
383#endif // wxUSE_CLIPBOARD
384 EVT_ERASE_BACKGROUND(MyHtmlWindow::OnEraseBgEvent)
0f11c233
VZ
385END_EVENT_TABLE()
386
03a187cc 387#if wxUSE_CLIPBOARD
0f11c233
VZ
388void MyHtmlWindow::OnClipboardEvent(wxClipboardTextEvent& WXUNUSED(event))
389{
390 // explicitly call wxHtmlWindow::CopySelection() method
391 // and show the first 100 characters of the text copied in the status bar
392 if ( CopySelection() )
393 {
394 wxTextDataObject data;
3214ac5a 395 if ( wxTheClipboard && wxTheClipboard->Open() && wxTheClipboard->GetData(data) )
0f11c233
VZ
396 {
397 const wxString text = data.GetText();
398 const size_t maxTextLength = 100;
399
9a83f860 400 wxLogStatus(wxString::Format(wxT("Clipboard: '%s%s'"),
0f11c233 401 wxString(text, maxTextLength).c_str(),
9a83f860
VZ
402 (text.length() > maxTextLength) ? wxT("...")
403 : wxT("")));
3214ac5a
JS
404 wxTheClipboard->Close();
405
0f11c233
VZ
406 return;
407 }
408 }
409
9a83f860 410 wxLogStatus(wxT("Clipboard: nothing"));
0f11c233
VZ
411}
412#endif // wxUSE_CLIPBOARD
03a187cc
VZ
413
414void MyHtmlWindow::OnEraseBgEvent(wxEraseEvent& event)
415{
416 if ( !m_drawCustomBg )
417 {
418 event.Skip();
419 return;
420 }
421
422 // draw a background grid to show that this handler is indeed executed
423
424 wxDC& dc = *event.GetDC();
425 dc.SetPen(*wxBLUE_PEN);
426 dc.Clear();
427
428 const wxSize size = GetVirtualSize();
429 for ( int x = 0; x < size.x; x += 15 )
430 {
431 dc.DrawLine(x, 0, x, size.y);
432 }
433
434 for ( int y = 0; y < size.y; y += 15 )
435 {
436 dc.DrawLine(0, y, size.x, y);
437 }
438}
439