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