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