generate wxEVT_COMMAND_TEXT_COPY event in wxHtmlWindow
[wxWidgets.git] / samples / html / test / test.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: test.cpp
3 // Purpose: wxHtml testing example
4 // Author: Vaclav Slavik
5 // Created: 1999-07-07
6 // RCS-ID: $Id$
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:
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:
98 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
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
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
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
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
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
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
292 void MyFrame::OnBack(wxCommandEvent& WXUNUSED(event))
293 {
294 if (!m_Html->HistoryBack())
295 {
296 wxMessageBox(_("You reached prehistory era!"));
297 }
298 }
299
300 void MyFrame::OnForward(wxCommandEvent& WXUNUSED(event))
301 {
302 if (!m_Html->HistoryForward())
303 {
304 wxMessageBox(_("No more items in history!"));
305 }
306 }
307
308 void MyFrame::OnProcessor(wxCommandEvent& WXUNUSED(event))
309 {
310 m_Processor->Enable(!m_Processor->IsEnabled());
311 m_Html->LoadPage(m_Html->GetOpenedPage());
312 }
313
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
323 void MyFrame::OnHtmlCellHover(wxHtmlCellEvent &event)
324 {
325 wxLogMessage(wxT("Mouse moved over cell %d at %d;%d"),
326 event.GetCell(), event.GetPoint().x, event.GetPoint().y);
327 }
328
329 void MyFrame::OnHtmlCellClicked(wxHtmlCellEvent &event)
330 {
331 wxLogMessage(wxT("Click over cell %d 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
338 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
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->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 return;
368 }
369 }
370
371 wxLogStatus(_T("Clipboard: nothing"));
372 }
373 #endif // wxUSE_CLIPBOARD