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