]> git.saurik.com Git - wxWidgets.git/blame - samples/web/web.cpp
Add support for new window events in gtk
[wxWidgets.git] / samples / web / web.cpp
CommitLineData
61b98a2d 1/////////////////////////////////////////////////////////////////////////////
ec4ac0f7
SL
2// Name: web.cpp
3// Purpose: wxWebView sample
61b98a2d
SL
4// Author: Marianne Gagnon
5// Id: $Id$
ec4ac0f7 6// Copyright: (c) 2010 Marianne Gagnon, Steven Lamerton
61b98a2d
SL
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
ec4ac0f7
SL
10// ----------------------------------------------------------------------------
11// headers
12// ----------------------------------------------------------------------------
13
14// For compilers that support precompilation, includes "wx/wx.h".
15#include "wx/wxprec.h"
16
17#ifdef __BORLANDC__
18 #pragma hdrstop
19#endif
20
21#ifndef WX_PRECOMP
22 #include "wx/wx.h"
23#endif
24
61b98a2d
SL
25#include <wx/artprov.h>
26#include <wx/notifmsg.h>
27#include <wx/settings.h>
ec4ac0f7
SL
28#include <wx/webview.h>
29#include <wx/infobar.h>
30
31#if !defined(__WXMSW__) && !defined(__WXPM__)
32 #include "../sample.xpm"
33#endif
61b98a2d
SL
34
35#if wxUSE_STC
36#include <wx/stc/stc.h>
37#else
38#error "wxStyledTextControl is needed by this sample"
39#endif
40
61b98a2d
SL
41#include "wxlogo.xpm"
42#include "back.xpm"
43#include "forward.xpm"
44#include "stop.xpm"
45#include "refresh.xpm"
46
61b98a2d 47
ec4ac0f7 48class WebApp : public wxApp
61b98a2d
SL
49{
50public:
ec4ac0f7 51 virtual bool OnInit();
61b98a2d
SL
52};
53
ec4ac0f7 54class WebFrame : public wxFrame
61b98a2d 55{
ec4ac0f7
SL
56public:
57 WebFrame();
58
59 void OnAnimationTimer(wxTimerEvent& evt);
60 void UpdateState();
61 void OnUrl(wxCommandEvent& evt);
62 void OnBack(wxCommandEvent& evt);
63 void OnForward(wxCommandEvent& evt);
64 void OnStop(wxCommandEvent& evt);
65 void OnReload(wxCommandEvent& evt);
66 void OnNavigationRequest(wxWebNavigationEvent& evt);
67 void OnNavigationComplete(wxWebNavigationEvent& evt);
68 void OnDocumentLoaded(wxWebNavigationEvent& evt);
69 void OnNewWindow(wxWebNavigationEvent& evt);
70 void OnViewSourceRequest(wxCommandEvent& evt);
71 void OnToolsClicked(wxCommandEvent& evt);
72 void OnSetZoom(wxCommandEvent& evt);
73 void OnError(wxWebNavigationEvent& evt);
74 void OnPrint(wxCommandEvent& evt);
75
76private:
77 wxTextCtrl* m_url;
78 wxWebView* m_browser;
79
61b98a2d 80 wxToolBar* m_toolbar;
ec4ac0f7
SL
81 wxToolBarToolBase* m_toolbar_back;
82 wxToolBarToolBase* m_toolbar_forward;
83 wxToolBarToolBase* m_toolbar_stop;
84 wxToolBarToolBase* m_toolbar_reload;
85 wxToolBarToolBase* m_toolbar_tools;
86
87 wxMenu* m_tools_menu;
88 wxMenuItem* m_tools_tiny;
89 wxMenuItem* m_tools_small;
90 wxMenuItem* m_tools_medium;
91 wxMenuItem* m_tools_large;
92 wxMenuItem* m_tools_largest;
93
61b98a2d
SL
94 wxTimer* m_timer;
95 int m_animation_angle;
ec4ac0f7
SL
96
97
98 wxInfoBar *m_info;
99 wxStaticText* m_info_text;
100};
101
102class SourceViewDialog : public wxDialog
103{
61b98a2d 104public:
ec4ac0f7
SL
105 SourceViewDialog(wxWindow* parent, wxString source);
106};
107
108IMPLEMENT_APP(WebApp)
109
110// ============================================================================
111// implementation
112// ============================================================================
113
114bool WebApp::OnInit()
115{
116 if ( !wxApp::OnInit() )
117 return false;
118
119 WebFrame *frame = new WebFrame();
120 frame->Show();
121
122 return true;
123}
124
125WebFrame::WebFrame() : wxFrame(NULL, wxID_ANY, "wxWebView Sample")
126{
127 // set the frame icon
128 SetIcon(wxICON(sample));
129 SetTitle("wxWebView Sample");
130
131 m_timer = NULL;
132 m_animation_angle = 0;
133
134
135 wxBoxSizer* topsizer = new wxBoxSizer(wxVERTICAL);
136
137 // Create the toolbar
138 m_toolbar = CreateToolBar(wxTB_TEXT);
139 m_toolbar->SetToolBitmapSize(wxSize(32, 32));
140
141 m_toolbar_back = m_toolbar->AddTool(wxID_ANY, _("Back"), wxBitmap(back_xpm));
142 m_toolbar_forward = m_toolbar->AddTool(wxID_ANY, _("Forward"), wxBitmap(forward_xpm));
143 m_toolbar_stop = m_toolbar->AddTool(wxID_ANY, _("Stop"), wxBitmap(stop_xpm));
144 m_toolbar_reload = m_toolbar->AddTool(wxID_ANY, _("Reload"), wxBitmap(refresh_xpm));
145 m_url = new wxTextCtrl(m_toolbar, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(400, -1), wxTE_PROCESS_ENTER );
146 m_toolbar->AddControl(m_url, _("URL"));
147 m_toolbar_tools = m_toolbar->AddTool(wxID_ANY, _("Menu"), wxBitmap(wxlogo_xpm));
148
149 m_toolbar->Realize();
150
151 // Create the info panel
152 m_info = new wxInfoBar(this);
153 topsizer->Add(m_info, wxSizerFlags().Expand());
154
155 // Create the webview
156 m_browser = wxWebView::New(this, wxID_ANY);
157 m_browser->LoadUrl("http://www.wxwidgets.org");
158 topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1));
159
160 SetSizer(topsizer);
161
162 // Create a log window
163 new wxLogWindow(this, _("Logging"));
164
165 // Create the Tools menu
166 m_tools_menu = new wxMenu();
167 wxMenuItem* print = m_tools_menu->Append(wxID_ANY , _("Print"));
168 wxMenuItem* viewSource = m_tools_menu->Append(wxID_ANY , _("View Source"));
169 m_tools_menu->AppendSeparator();
170 m_tools_tiny = m_tools_menu->AppendCheckItem(wxID_ANY, _("Tiny"));
171 m_tools_small = m_tools_menu->AppendCheckItem(wxID_ANY, _("Small"));
172 m_tools_medium = m_tools_menu->AppendCheckItem(wxID_ANY, _("Medium"));
173 m_tools_large = m_tools_menu->AppendCheckItem(wxID_ANY, _("Large"));
174 m_tools_largest = m_tools_menu->AppendCheckItem(wxID_ANY, _("Largest"));
175
176
177 // Connect the toolbar events
178 Connect(m_toolbar_back->GetId(), wxEVT_COMMAND_TOOL_CLICKED,
179 wxCommandEventHandler(WebFrame::OnBack), NULL, this );
180 Connect(m_toolbar_forward->GetId(), wxEVT_COMMAND_TOOL_CLICKED,
181 wxCommandEventHandler(WebFrame::OnForward), NULL, this );
182 Connect(m_toolbar_stop->GetId(), wxEVT_COMMAND_TOOL_CLICKED,
183 wxCommandEventHandler(WebFrame::OnStop), NULL, this );
184 Connect(m_toolbar_reload->GetId(), wxEVT_COMMAND_TOOL_CLICKED,
185 wxCommandEventHandler(WebFrame::OnReload),NULL, this );
186 Connect(m_toolbar_tools->GetId(), wxEVT_COMMAND_TOOL_CLICKED,
187 wxCommandEventHandler(WebFrame::OnToolsClicked), NULL, this );
188
189 Connect(m_url->GetId(), wxEVT_COMMAND_TEXT_ENTER,
190 wxCommandEventHandler(WebFrame::OnUrl), NULL, this );
191
192 // Connect the webview events
193 Connect(m_browser->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATING,
194 wxWebNavigationEventHandler(WebFrame::OnNavigationRequest), NULL, this);
195 Connect(m_browser->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATED,
196 wxWebNavigationEventHandler(WebFrame::OnNavigationComplete), NULL, this);
197 Connect(m_browser->GetId(), wxEVT_COMMAND_WEB_VIEW_LOADED,
198 wxWebNavigationEventHandler(WebFrame::OnDocumentLoaded), NULL, this);
199 Connect(m_browser->GetId(), wxEVT_COMMAND_WEB_VIEW_ERROR,
200 wxWebNavigationEventHandler(WebFrame::OnError), NULL, this);
201 Connect(m_browser->GetId(), wxEVT_COMMAND_WEB_VIEW_NEWWINDOW,
202 wxWebNavigationEventHandler(WebFrame::OnNewWindow), NULL, this);
203
204 // Connect the menu events
205 Connect(viewSource->GetId(), wxEVT_COMMAND_MENU_SELECTED,
206 wxCommandEventHandler(WebFrame::OnViewSourceRequest), NULL, this );
207 Connect(print->GetId(), wxEVT_COMMAND_MENU_SELECTED,
208 wxCommandEventHandler(WebFrame::OnPrint), NULL, this );
209 Connect(m_tools_tiny->GetId(), wxEVT_COMMAND_MENU_SELECTED,
210 wxCommandEventHandler(WebFrame::OnSetZoom), NULL, this );
211 Connect(m_tools_small->GetId(), wxEVT_COMMAND_MENU_SELECTED,
212 wxCommandEventHandler(WebFrame::OnSetZoom), NULL, this );
213 Connect(m_tools_medium->GetId(), wxEVT_COMMAND_MENU_SELECTED,
214 wxCommandEventHandler(WebFrame::OnSetZoom), NULL, this );
215 Connect(m_tools_large->GetId(), wxEVT_COMMAND_MENU_SELECTED,
216 wxCommandEventHandler(WebFrame::OnSetZoom), NULL, this );
217 Connect(m_tools_largest->GetId(), wxEVT_COMMAND_MENU_SELECTED,
218 wxCommandEventHandler(WebFrame::OnSetZoom), NULL, this );
219}
220
221void WebFrame::OnAnimationTimer(wxTimerEvent& evt)
222{
223 m_animation_angle += 15;
224 if (m_animation_angle > 360) m_animation_angle -= 360;
61b98a2d 225
ec4ac0f7 226 wxBitmap image(32, 32);
61b98a2d 227 {
61b98a2d
SL
228 wxMemoryDC dc;
229 dc.SelectObject(image);
230 dc.SetBackground(wxBrush(wxColour(255,0,255)));
231 dc.Clear();
232
233 if (m_animation_angle >= 0 && m_animation_angle <= 180)
234 {
235 dc.SetBrush(*wxYELLOW_BRUSH);
236 dc.SetPen(*wxYELLOW_PEN);
237 dc.DrawCircle(16 - int(sin(m_animation_angle*0.01745f /* convert to radians */)*14.0f),
ec4ac0f7 238 16 + int(cos(m_animation_angle*0.01745f /* convert to radians */)*14.0f), 3 );
61b98a2d
SL
239 }
240
241 dc.DrawBitmap(wxBitmap(wxlogo_xpm), 0, 0, true);
242
243 if (m_animation_angle > 180)
244 {
245 dc.SetBrush(*wxYELLOW_BRUSH);
246 dc.SetPen(*wxYELLOW_PEN);
247 dc.DrawCircle(16 - int(sin(m_animation_angle*0.01745f /* convert to radians */)*14.0f),
ec4ac0f7 248 16 + int(cos(m_animation_angle*0.01745f /* convert to radians */)*14.0f), 3 );
61b98a2d 249 }
ec4ac0f7
SL
250 }
251 image.SetMask(new wxMask(image, wxColour(255,0,255)));
252 m_toolbar->SetToolNormalBitmap(m_toolbar_tools->GetId(), image);
253}
254
255/**
256 * Method that retrieves the current state from the web control and updates the GUI
257 * the reflect this current state.
258 */
259void WebFrame::UpdateState()
260{
261 m_toolbar->EnableTool( m_toolbar_back->GetId(), m_browser->CanGoBack() );
262 m_toolbar->EnableTool( m_toolbar_forward->GetId(), m_browser->CanGoForward() );
61b98a2d 263
ec4ac0f7 264 if (m_browser->IsBusy())
61b98a2d 265 {
ec4ac0f7 266 if (m_timer == NULL)
61b98a2d 267 {
ec4ac0f7
SL
268 m_timer = new wxTimer(this);
269 this->Connect(wxEVT_TIMER, wxTimerEventHandler(WebFrame::OnAnimationTimer), NULL, this);
61b98a2d 270 }
ec4ac0f7 271 m_timer->Start(100); // start animation timer
61b98a2d 272
ec4ac0f7 273 m_toolbar->EnableTool( m_toolbar_stop->GetId(), true );
61b98a2d 274 }
ec4ac0f7 275 else
61b98a2d 276 {
ec4ac0f7
SL
277 if (m_timer != NULL) m_timer->Stop(); // stop animation timer
278 m_toolbar->SetToolNormalBitmap(m_toolbar_tools->GetId(), wxBitmap(wxlogo_xpm));
279 m_toolbar->EnableTool( m_toolbar_stop->GetId(), false );
61b98a2d
SL
280 }
281
ec4ac0f7
SL
282 SetTitle( m_browser->GetCurrentTitle() );
283 m_url->SetValue( m_browser->GetCurrentURL() );
284}
285
286/**
287 * Callback invoked when user entered an URL and pressed enter
288 */
289void WebFrame::OnUrl(wxCommandEvent& evt)
290{
291 m_browser->LoadUrl( m_url->GetValue() );
292 UpdateState();
293}
294
295/**
296 * Callback invoked when user pressed the "back" button
297 */
298void WebFrame::OnBack(wxCommandEvent& evt)
299{
300 m_browser->GoBack();
301 UpdateState();
302}
303
304/**
305 * Callback invoked when user pressed the "forward" button
306 */
307void WebFrame::OnForward(wxCommandEvent& evt)
308{
309 m_browser->GoForward();
310 UpdateState();
311}
312
313/**
314 * Callback invoked when user pressed the "stop" button
315 */
316void WebFrame::OnStop(wxCommandEvent& evt)
317{
318 m_browser->Stop();
319 UpdateState();
320}
321
322/**
323 * Callback invoked when user pressed the "reload" button
324 */
325void WebFrame::OnReload(wxCommandEvent& evt)
326{
327 m_browser->Reload();
328 UpdateState();
329}
330
331/**
332 * Callback invoked when there is a request to load a new page (for instance
333 * when the user clicks a link)
334 */
335void WebFrame::OnNavigationRequest(wxWebNavigationEvent& evt)
336{
337 wxLogMessage("%s", "Navigation request to '" + evt.GetHref() + "' (target='" +
338 evt.GetTarget() + "')");
339
340 wxASSERT(m_browser->IsBusy());
341
342 // Uncomment this to see how to block navigation requests
343 //int answer = wxMessageBox("Proceed with navigation to '" + evt.GetHref() + "'?",
344 // "Proceed with navigation?", wxYES_NO );
345 //if (answer != wxYES)
346 //{
347 // evt.Veto();
348 //}
349 UpdateState();
350}
351
352/**
353 * Callback invoked when a navigation request was accepted
354 */
355void WebFrame::OnNavigationComplete(wxWebNavigationEvent& evt)
356{
357 wxLogMessage("%s", "Navigation complete; url='" + evt.GetHref() + "'");
358 UpdateState();
359}
360
361/**
362 * Callback invoked when a page is finished loading
363 */
364void WebFrame::OnDocumentLoaded(wxWebNavigationEvent& evt)
365{
366 wxLogMessage("%s", "Document loaded; url='" + evt.GetHref() + "'");
367 UpdateState();
368}
369
370/**
371 * On new window, we veto to stop extra windows appearing
372 */
373void WebFrame::OnNewWindow(wxWebNavigationEvent& evt)
374{
375 wxLogMessage("%s", "New window; url='" + evt.GetHref() + "'");
376 evt.Veto();
377
378 UpdateState();
379}
380
381/**
382 * Invoked when user selects the "View Source" menu item
383 */
384void WebFrame::OnViewSourceRequest(wxCommandEvent& evt)
385{
386 SourceViewDialog dlg(this, m_browser->GetPageSource());
387 dlg.ShowModal();
388}
389
390/**
391 * Invoked when user selects the "Menu" item
392 */
393void WebFrame::OnToolsClicked(wxCommandEvent& evt)
394{
395 if(m_browser->GetCurrentURL() == "")
396 return;
397
398 m_tools_tiny->Check(false);
399 m_tools_small->Check(false);
400 m_tools_medium->Check(false);
401 m_tools_large->Check(false);
402 m_tools_largest->Check(false);
403
404 wxWebViewZoom zoom = m_browser->GetZoom();
405 switch (zoom)
61b98a2d 406 {
ec4ac0f7
SL
407 case wxWEB_VIEW_ZOOM_TINY:
408 m_tools_tiny->Check();
409 break;
410 case wxWEB_VIEW_ZOOM_SMALL:
411 m_tools_small->Check();
412 break;
413 case wxWEB_VIEW_ZOOM_MEDIUM:
414 m_tools_medium->Check();
415 break;
416 case wxWEB_VIEW_ZOOM_LARGE:
417 m_tools_large->Check();
418 break;
419 case wxWEB_VIEW_ZOOM_LARGEST:
420 m_tools_largest->Check();
421 break;
61b98a2d
SL
422 }
423
ec4ac0f7
SL
424 wxPoint position = ScreenToClient( wxGetMousePosition() );
425 PopupMenu(m_tools_menu, position.x, position.y);
426}
427
428/**
429 * Invoked when user selects the zoom size in the menu
430 */
431void WebFrame::OnSetZoom(wxCommandEvent& evt)
432{
433 if (evt.GetId() == m_tools_tiny->GetId())
61b98a2d 434 {
ec4ac0f7 435 m_browser->SetZoom(wxWEB_VIEW_ZOOM_TINY);
61b98a2d 436 }
ec4ac0f7 437 else if (evt.GetId() == m_tools_small->GetId())
61b98a2d 438 {
ec4ac0f7 439 m_browser->SetZoom(wxWEB_VIEW_ZOOM_SMALL);
61b98a2d 440 }
ec4ac0f7 441 else if (evt.GetId() == m_tools_medium->GetId())
61b98a2d 442 {
ec4ac0f7 443 m_browser->SetZoom(wxWEB_VIEW_ZOOM_MEDIUM);
61b98a2d 444 }
ec4ac0f7 445 else if (evt.GetId() == m_tools_large->GetId())
61b98a2d 446 {
ec4ac0f7 447 m_browser->SetZoom(wxWEB_VIEW_ZOOM_LARGE);
61b98a2d 448 }
ec4ac0f7 449 else if (evt.GetId() == m_tools_largest->GetId())
61b98a2d 450 {
ec4ac0f7 451 m_browser->SetZoom(wxWEB_VIEW_ZOOM_LARGEST);
61b98a2d 452 }
ec4ac0f7 453 else
61b98a2d 454 {
ec4ac0f7 455 wxFAIL;
61b98a2d 456 }
ec4ac0f7 457}
853b6cd0 458
ec4ac0f7
SL
459/**
460 * Callback invoked when a loading error occurs
461 */
462void WebFrame::OnError(wxWebNavigationEvent& evt)
463{
464 wxString errorCategory;
465 switch (evt.GetInt())
61b98a2d 466 {
ec4ac0f7
SL
467 case wxWEB_NAV_ERR_CONNECTION:
468 errorCategory = "wxWEB_NAV_ERR_CONNECTION";
469 break;
61b98a2d 470
ec4ac0f7
SL
471 case wxWEB_NAV_ERR_CERTIFICATE:
472 errorCategory = "wxWEB_NAV_ERR_CERTIFICATE";
473 break;
61b98a2d 474
ec4ac0f7
SL
475 case wxWEB_NAV_ERR_AUTH:
476 errorCategory = "wxWEB_NAV_ERR_AUTH";
477 break;
61b98a2d 478
ec4ac0f7
SL
479 case wxWEB_NAV_ERR_SECURITY:
480 errorCategory = "wxWEB_NAV_ERR_SECURITY";
481 break;
61b98a2d 482
ec4ac0f7
SL
483 case wxWEB_NAV_ERR_NOT_FOUND:
484 errorCategory = "wxWEB_NAV_ERR_NOT_FOUND";
485 break;
61b98a2d 486
ec4ac0f7
SL
487 case wxWEB_NAV_ERR_REQUEST:
488 errorCategory = "wxWEB_NAV_ERR_REQUEST";
489 break;
490
491 case wxWEB_NAV_ERR_USER_CANCELLED:
492 errorCategory = "wxWEB_NAV_ERR_USER_CANCELLED";
493 break;
494
495 case wxWEB_NAV_ERR_OTHER:
496 errorCategory = "wxWEB_NAV_ERR_OTHER";
497 break;
61b98a2d
SL
498 }
499
ec4ac0f7 500 wxLogMessage("Error; url='" + evt.GetHref() + "', error='" + errorCategory + "' (" + evt.GetString() + ")");
61b98a2d 501
ec4ac0f7
SL
502 //Show the info bar with an error
503 m_info->ShowMessage(_("An error occurred loading ") + evt.GetHref() + "\n" +
504 "'" + errorCategory + "' (" + evt.GetString() + ")", wxICON_ERROR);
61b98a2d 505
ec4ac0f7
SL
506 UpdateState();
507}
61b98a2d 508
ec4ac0f7
SL
509/**
510 * Invoked when user selects "Print" from the menu
511 */
512void WebFrame::OnPrint(wxCommandEvent& evt)
61b98a2d 513{
ec4ac0f7
SL
514 m_browser->Print();
515}
61b98a2d 516
ec4ac0f7
SL
517SourceViewDialog::SourceViewDialog(wxWindow* parent, wxString source) :
518 wxDialog(parent, wxID_ANY, "Source Code",
519 wxDefaultPosition, wxSize(700,500),
520 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
521{
522 wxStyledTextCtrl* text = new wxStyledTextCtrl(this, wxID_ANY);
523 text->SetMarginWidth(1, 30);
524 text->SetMarginType(1, wxSTC_MARGIN_NUMBER);
525 text->SetText(source);
61b98a2d 526
ec4ac0f7
SL
527 text->StyleClearAll();
528 text->SetLexer(wxSTC_LEX_HTML);
529 text->StyleSetForeground(wxSTC_H_DOUBLESTRING, wxColour(255,0,0));
530 text->StyleSetForeground(wxSTC_H_SINGLESTRING, wxColour(255,0,0));
531 text->StyleSetForeground(wxSTC_H_ENTITY, wxColour(255,0,0));
532 text->StyleSetForeground(wxSTC_H_TAG, wxColour(0,150,0));
533 text->StyleSetForeground(wxSTC_H_TAGUNKNOWN, wxColour(0,150,0));
534 text->StyleSetForeground(wxSTC_H_ATTRIBUTE, wxColour(0,0,150));
535 text->StyleSetForeground(wxSTC_H_ATTRIBUTEUNKNOWN, wxColour(0,0,150));
536 text->StyleSetForeground(wxSTC_H_COMMENT, wxColour(150,150,150));
61b98a2d 537
61b98a2d 538 wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
ec4ac0f7
SL
539 sizer->Add(text, 1, wxEXPAND);
540 SetSizer(sizer);
61b98a2d 541}