]> git.saurik.com Git - wxWidgets.git/blob - samples/web/web.cpp
eb18e11abf846f367fd2c711b83bab83a43c554b
[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);
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
221 void WebFrame::OnAnimationTimer(wxTimerEvent& evt)
222 {
223 m_animation_angle += 15;
224 if (m_animation_angle > 360) m_animation_angle -= 360;
225
226 wxBitmap image(32, 32);
227 {
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),
238 16 + int(cos(m_animation_angle*0.01745f /* convert to radians */)*14.0f), 3 );
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),
248 16 + int(cos(m_animation_angle*0.01745f /* convert to radians */)*14.0f), 3 );
249 }
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 */
259 void 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() );
263
264 if (m_browser->IsBusy())
265 {
266 if (m_timer == NULL)
267 {
268 m_timer = new wxTimer(this);
269 this->Connect(wxEVT_TIMER, wxTimerEventHandler(WebFrame::OnAnimationTimer), NULL, this);
270 }
271 m_timer->Start(100); // start animation timer
272
273 m_toolbar->EnableTool( m_toolbar_stop->GetId(), true );
274 }
275 else
276 {
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 );
280 }
281
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 */
289 void 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 */
298 void WebFrame::OnBack(wxCommandEvent& evt)
299 {
300 m_browser->GoBack();
301 UpdateState();
302 }
303
304 /**
305 * Callback invoked when user pressed the "forward" button
306 */
307 void WebFrame::OnForward(wxCommandEvent& evt)
308 {
309 m_browser->GoForward();
310 UpdateState();
311 }
312
313 /**
314 * Callback invoked when user pressed the "stop" button
315 */
316 void WebFrame::OnStop(wxCommandEvent& evt)
317 {
318 m_browser->Stop();
319 UpdateState();
320 }
321
322 /**
323 * Callback invoked when user pressed the "reload" button
324 */
325 void 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 */
335 void 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 */
355 void 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 */
364 void 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 */
373 void 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 */
384 void 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 */
393 void 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)
406 {
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;
422 }
423
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 */
431 void WebFrame::OnSetZoom(wxCommandEvent& evt)
432 {
433 if (evt.GetId() == m_tools_tiny->GetId())
434 {
435 m_browser->SetZoom(wxWEB_VIEW_ZOOM_TINY);
436 }
437 else if (evt.GetId() == m_tools_small->GetId())
438 {
439 m_browser->SetZoom(wxWEB_VIEW_ZOOM_SMALL);
440 }
441 else if (evt.GetId() == m_tools_medium->GetId())
442 {
443 m_browser->SetZoom(wxWEB_VIEW_ZOOM_MEDIUM);
444 }
445 else if (evt.GetId() == m_tools_large->GetId())
446 {
447 m_browser->SetZoom(wxWEB_VIEW_ZOOM_LARGE);
448 }
449 else if (evt.GetId() == m_tools_largest->GetId())
450 {
451 m_browser->SetZoom(wxWEB_VIEW_ZOOM_LARGEST);
452 }
453 else
454 {
455 wxFAIL;
456 }
457 }
458
459 /**
460 * Callback invoked when a loading error occurs
461 */
462 void WebFrame::OnError(wxWebNavigationEvent& evt)
463 {
464 wxString errorCategory;
465 switch (evt.GetInt())
466 {
467 case wxWEB_NAV_ERR_CONNECTION:
468 errorCategory = "wxWEB_NAV_ERR_CONNECTION";
469 break;
470
471 case wxWEB_NAV_ERR_CERTIFICATE:
472 errorCategory = "wxWEB_NAV_ERR_CERTIFICATE";
473 break;
474
475 case wxWEB_NAV_ERR_AUTH:
476 errorCategory = "wxWEB_NAV_ERR_AUTH";
477 break;
478
479 case wxWEB_NAV_ERR_SECURITY:
480 errorCategory = "wxWEB_NAV_ERR_SECURITY";
481 break;
482
483 case wxWEB_NAV_ERR_NOT_FOUND:
484 errorCategory = "wxWEB_NAV_ERR_NOT_FOUND";
485 break;
486
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;
498 }
499
500 wxLogMessage("Error; url='" + evt.GetHref() + "', error='" + errorCategory + "' (" + evt.GetString() + ")");
501
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);
505
506 UpdateState();
507 }
508
509 /**
510 * Invoked when user selects "Print" from the menu
511 */
512 void WebFrame::OnPrint(wxCommandEvent& evt)
513 {
514 m_browser->Print();
515 }
516
517 SourceViewDialog::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);
526
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));
537
538 wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
539 sizer->Add(text, 1, wxEXPAND);
540 SetSizer(sizer);
541 }