Fix wxWebView compilation in STL build with wxGTK.
[wxWidgets.git] / src / gtk / webview_webkit.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/webview_webkit.cpp
3 // Purpose: GTK WebKit backend for web view component
4 // Author: Marianne Gagnon, Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 2010 Marianne Gagnon, 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #if wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT
14
15 #include "wx/stockitem.h"
16 #include "wx/gtk/webview_webkit.h"
17 #include "wx/gtk/control.h"
18 #include "wx/gtk/private.h"
19 #include "wx/filesys.h"
20 #include "wx/base64.h"
21 #include <webkit/webkit.h>
22
23 // ----------------------------------------------------------------------------
24 // GTK callbacks
25 // ----------------------------------------------------------------------------
26
27 extern "C"
28 {
29
30 static void
31 wxgtk_webview_webkit_load_status(GtkWidget* widget,
32 GParamSpec*,
33 wxWebViewWebKit *webKitCtrl)
34 {
35 if (!webKitCtrl->m_ready) return;
36
37 wxString url = webKitCtrl->GetCurrentURL();
38
39 WebKitLoadStatus status;
40 g_object_get(G_OBJECT(widget), "load-status", &status, NULL);
41
42 wxString target; // TODO: get target (if possible)
43
44 if (status == WEBKIT_LOAD_FINISHED)
45 {
46 WebKitWebBackForwardList* hist = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(widget));
47 WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_current_item(hist);
48 //We have to check if we are actually storing history
49 //If the item isn't added we add it ourselves, it isn't added otherwise
50 //with a custom scheme.
51 if(WEBKIT_IS_WEB_HISTORY_ITEM(item) && webkit_web_history_item_get_uri(item) != url)
52 {
53 WebKitWebHistoryItem*
54 newitem = webkit_web_history_item_new_with_data
55 (
56 url.utf8_str(),
57 webKitCtrl->GetCurrentTitle().utf8_str()
58 );
59 webkit_web_back_forward_list_add_item(hist, newitem);
60 }
61
62 webKitCtrl->m_busy = false;
63 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_LOADED,
64 webKitCtrl->GetId(),
65 url, target);
66
67 if (webKitCtrl && webKitCtrl->GetEventHandler())
68 webKitCtrl->GetEventHandler()->ProcessEvent(event);
69 }
70 else if (status == WEBKIT_LOAD_COMMITTED)
71 {
72 webKitCtrl->m_busy = true;
73 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,
74 webKitCtrl->GetId(),
75 url, target);
76
77 if (webKitCtrl && webKitCtrl->GetEventHandler())
78 webKitCtrl->GetEventHandler()->ProcessEvent(event);
79 }
80 }
81
82 static gboolean
83 wxgtk_webview_webkit_navigation(WebKitWebView *,
84 WebKitWebFrame *frame,
85 WebKitNetworkRequest *request,
86 WebKitWebNavigationAction *,
87 WebKitWebPolicyDecision *policy_decision,
88 wxWebViewWebKit *webKitCtrl)
89 {
90 if(webKitCtrl->m_guard)
91 {
92 webKitCtrl->m_guard = false;
93 //We set this to make sure that we don't try to load the page again from
94 //the resource request callback
95 webKitCtrl->m_vfsurl = webkit_network_request_get_uri(request);
96 webkit_web_policy_decision_use(policy_decision);
97 return FALSE;
98 }
99
100 webKitCtrl->m_busy = true;
101
102 const gchar* uri = webkit_network_request_get_uri(request);
103
104 wxString target = webkit_web_frame_get_name (frame);
105 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING,
106 webKitCtrl->GetId(),
107 wxString( uri, wxConvUTF8 ),
108 target);
109
110 if (webKitCtrl && webKitCtrl->GetEventHandler())
111 webKitCtrl->GetEventHandler()->ProcessEvent(event);
112
113 if (!event.IsAllowed())
114 {
115 webKitCtrl->m_busy = false;
116 webkit_web_policy_decision_ignore(policy_decision);
117 return TRUE;
118 }
119 else
120 {
121 wxString wxuri = uri;
122 wxSharedPtr<wxWebViewHandler> handler;
123 wxVector<wxSharedPtr<wxWebViewHandler> > hanlders = webKitCtrl->GetHandlers();
124 //We are not vetoed so see if we match one of the additional handlers
125 for(wxVector<wxSharedPtr<wxWebViewHandler> >::iterator it = hanlders.begin();
126 it != hanlders.end(); ++it)
127 {
128 if(wxuri.substr(0, (*it)->GetName().length()) == (*it)->GetName())
129 {
130 handler = (*it);
131 }
132 }
133 //If we found a handler we can then use it to load the file directly
134 //ourselves
135 if(handler)
136 {
137 webKitCtrl->m_guard = true;
138 wxFSFile* file = handler->GetFile(wxuri);
139 if(file)
140 {
141 webKitCtrl->SetPage(*file->GetStream(), wxuri);
142 }
143 //We need to throw some sort of error here if file is NULL
144 webkit_web_policy_decision_ignore(policy_decision);
145 return TRUE;
146 }
147 return FALSE;
148 }
149 }
150
151 static gboolean
152 wxgtk_webview_webkit_error(WebKitWebView*,
153 WebKitWebFrame*,
154 gchar *uri,
155 gpointer web_error,
156 wxWebViewWebKit* webKitWindow)
157 {
158 webKitWindow->m_busy = false;
159 wxWebViewNavigationError type = wxWEB_NAV_ERR_OTHER;
160
161 GError* error = (GError*)web_error;
162 wxString description(error->message, wxConvUTF8);
163
164 if (strcmp(g_quark_to_string(error->domain), "soup_http_error_quark") == 0)
165 {
166 switch (error->code)
167 {
168 case SOUP_STATUS_CANCELLED:
169 type = wxWEB_NAV_ERR_USER_CANCELLED;
170 break;
171
172 case SOUP_STATUS_CANT_RESOLVE:
173 case SOUP_STATUS_NOT_FOUND:
174 type = wxWEB_NAV_ERR_NOT_FOUND;
175 break;
176
177 case SOUP_STATUS_CANT_RESOLVE_PROXY:
178 case SOUP_STATUS_CANT_CONNECT:
179 case SOUP_STATUS_CANT_CONNECT_PROXY:
180 case SOUP_STATUS_SSL_FAILED:
181 case SOUP_STATUS_IO_ERROR:
182 type = wxWEB_NAV_ERR_CONNECTION;
183 break;
184
185 case SOUP_STATUS_MALFORMED:
186 //case SOUP_STATUS_TOO_MANY_REDIRECTS:
187 type = wxWEB_NAV_ERR_REQUEST;
188 break;
189
190 //case SOUP_STATUS_NO_CONTENT:
191 //case SOUP_STATUS_RESET_CONTENT:
192
193 case SOUP_STATUS_BAD_REQUEST:
194 type = wxWEB_NAV_ERR_REQUEST;
195 break;
196
197 case SOUP_STATUS_UNAUTHORIZED:
198 case SOUP_STATUS_FORBIDDEN:
199 type = wxWEB_NAV_ERR_AUTH;
200 break;
201
202 case SOUP_STATUS_METHOD_NOT_ALLOWED:
203 case SOUP_STATUS_NOT_ACCEPTABLE:
204 type = wxWEB_NAV_ERR_SECURITY;
205 break;
206
207 case SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED:
208 type = wxWEB_NAV_ERR_AUTH;
209 break;
210
211 case SOUP_STATUS_REQUEST_TIMEOUT:
212 type = wxWEB_NAV_ERR_CONNECTION;
213 break;
214
215 //case SOUP_STATUS_PAYMENT_REQUIRED:
216 case SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE:
217 case SOUP_STATUS_REQUEST_URI_TOO_LONG:
218 case SOUP_STATUS_UNSUPPORTED_MEDIA_TYPE:
219 type = wxWEB_NAV_ERR_REQUEST;
220 break;
221
222 case SOUP_STATUS_BAD_GATEWAY:
223 case SOUP_STATUS_SERVICE_UNAVAILABLE:
224 case SOUP_STATUS_GATEWAY_TIMEOUT:
225 type = wxWEB_NAV_ERR_CONNECTION;
226 break;
227
228 case SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED:
229 type = wxWEB_NAV_ERR_REQUEST;
230 break;
231 //case SOUP_STATUS_INSUFFICIENT_STORAGE:
232 //case SOUP_STATUS_NOT_EXTENDED:
233 }
234 }
235 else if (strcmp(g_quark_to_string(error->domain),
236 "webkit-network-error-quark") == 0)
237 {
238 switch (error->code)
239 {
240 //WEBKIT_NETWORK_ERROR_FAILED:
241 //WEBKIT_NETWORK_ERROR_TRANSPORT:
242
243 case WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL:
244 type = wxWEB_NAV_ERR_REQUEST;
245 break;
246
247 case WEBKIT_NETWORK_ERROR_CANCELLED:
248 type = wxWEB_NAV_ERR_USER_CANCELLED;
249 break;
250
251 case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST:
252 type = wxWEB_NAV_ERR_NOT_FOUND;
253 break;
254 }
255 }
256 else if (strcmp(g_quark_to_string(error->domain),
257 "webkit-policy-error-quark") == 0)
258 {
259 switch (error->code)
260 {
261 //case WEBKIT_POLICY_ERROR_FAILED:
262 //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE:
263 //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URL:
264 //case WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE:
265 case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT:
266 type = wxWEB_NAV_ERR_SECURITY;
267 break;
268 }
269 }
270 /*
271 webkit_plugin_error_quark
272 else
273 {
274 printf("Error domain %s\n", g_quark_to_string(error->domain));
275 }
276 */
277
278 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_ERROR,
279 webKitWindow->GetId(),
280 uri, "");
281 event.SetString(description);
282 event.SetInt(type);
283
284 if (webKitWindow && webKitWindow->GetEventHandler())
285 {
286 webKitWindow->GetEventHandler()->ProcessEvent(event);
287 }
288
289 return FALSE;
290 }
291
292 static gboolean
293 wxgtk_webview_webkit_new_window(WebKitWebView*,
294 WebKitWebFrame *frame,
295 WebKitNetworkRequest *request,
296 WebKitWebNavigationAction*,
297 WebKitWebPolicyDecision *policy_decision,
298 wxWebViewWebKit *webKitCtrl)
299 {
300 const gchar* uri = webkit_network_request_get_uri(request);
301
302 wxString target = webkit_web_frame_get_name (frame);
303 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW,
304 webKitCtrl->GetId(),
305 wxString( uri, wxConvUTF8 ),
306 target);
307
308 if (webKitCtrl && webKitCtrl->GetEventHandler())
309 webKitCtrl->GetEventHandler()->ProcessEvent(event);
310
311 //We always want the user to handle this themselves
312 webkit_web_policy_decision_ignore(policy_decision);
313 return TRUE;
314 }
315
316 static void
317 wxgtk_webview_webkit_title_changed(WebKitWebView*,
318 WebKitWebFrame*,
319 gchar *title,
320 wxWebViewWebKit *webKitCtrl)
321 {
322 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED,
323 webKitCtrl->GetId(),
324 webKitCtrl->GetCurrentURL(),
325 "");
326 event.SetString(wxString(title, wxConvUTF8));
327
328 if (webKitCtrl && webKitCtrl->GetEventHandler())
329 webKitCtrl->GetEventHandler()->ProcessEvent(event);
330
331 }
332
333 static void
334 wxgtk_webview_webkit_resource_req(WebKitWebView *,
335 WebKitWebFrame *,
336 WebKitWebResource *,
337 WebKitNetworkRequest *request,
338 WebKitNetworkResponse *,
339 wxWebViewWebKit *webKitCtrl)
340 {
341 wxString uri = webkit_network_request_get_uri(request);
342
343 wxSharedPtr<wxWebViewHandler> handler;
344 wxVector<wxSharedPtr<wxWebViewHandler> > hanlders = webKitCtrl->GetHandlers();
345
346 //We are not vetoed so see if we match one of the additional handlers
347 for(wxVector<wxSharedPtr<wxWebViewHandler> >::iterator it = hanlders.begin();
348 it != hanlders.end(); ++it)
349 {
350 if(uri.substr(0, (*it)->GetName().length()) == (*it)->GetName())
351 {
352 handler = (*it);
353 }
354 }
355 //If we found a handler we can then use it to load the file directly
356 //ourselves
357 if(handler)
358 {
359 //If it is requsting the page itself then return as we have already
360 //loaded it from the archive
361 if(webKitCtrl->m_vfsurl == uri)
362 return;
363
364 wxFSFile* file = handler->GetFile(uri);
365 if(file)
366 {
367 //We load the data into a data url to save it being written out again
368 size_t size = file->GetStream()->GetLength();
369 char *buffer = new char[size];
370 file->GetStream()->Read(buffer, size);
371 wxString data = wxBase64Encode(buffer, size);
372 delete[] buffer;
373 wxString mime = file->GetMimeType();
374 wxString path = "data:" + mime + ";base64," + data;
375 //Then we can redirect the call
376 webkit_network_request_set_uri(request, path.utf8_str());
377 }
378
379 }
380 }
381
382 } // extern "C"
383
384 //-----------------------------------------------------------------------------
385 // wxWebViewWebKit
386 //-----------------------------------------------------------------------------
387
388 wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit, wxWebView);
389
390 bool wxWebViewWebKit::Create(wxWindow *parent,
391 wxWindowID id,
392 const wxString &url,
393 const wxPoint& pos,
394 const wxSize& size,
395 long style,
396 const wxString& name)
397 {
398 m_ready = false;
399 m_busy = false;
400 m_guard = false;
401
402 if (!PreCreation( parent, pos, size ) ||
403 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
404 {
405 wxFAIL_MSG( wxT("wxWebViewWebKit creation failed") );
406 return false;
407 }
408
409 GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
410 web_view = webkit_web_view_new ();
411 g_object_ref(web_view); // TODO: check memory management
412
413 m_widget = scrolled_window;
414 g_object_ref(m_widget); // TODO: check memory management
415
416 /* Place the WebKitWebView in the GtkScrolledWindow */
417 gtk_container_add (GTK_CONTAINER (scrolled_window), web_view);
418 gtk_widget_show(m_widget);
419 gtk_widget_show(web_view);
420
421 g_signal_connect_after(web_view, "notify::load-status",
422 G_CALLBACK(wxgtk_webview_webkit_load_status),
423 this);
424 g_signal_connect_after(web_view, "navigation-policy-decision-requested",
425 G_CALLBACK(wxgtk_webview_webkit_navigation),
426 this);
427 g_signal_connect_after(web_view, "load-error",
428 G_CALLBACK(wxgtk_webview_webkit_error),
429 this);
430
431 g_signal_connect_after(web_view, "new-window-policy-decision-requested",
432 G_CALLBACK(wxgtk_webview_webkit_new_window), this);
433
434 g_signal_connect_after(web_view, "title-changed",
435 G_CALLBACK(wxgtk_webview_webkit_title_changed), this);
436
437 g_signal_connect_after(web_view, "resource-request-starting",
438 G_CALLBACK(wxgtk_webview_webkit_resource_req), this);
439
440 m_parent->DoAddChild( this );
441
442 PostCreation(size);
443
444 /* Open a webpage */
445 webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), url.utf8_str());
446
447 //Get the initial history limit so we can enable and disable it later
448 WebKitWebBackForwardList* history;
449 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
450 m_historyLimit = webkit_web_back_forward_list_get_limit(history);
451
452 m_ready = true;
453
454 return true;
455 }
456
457 bool wxWebViewWebKit::Enable( bool enable )
458 {
459 if (!wxControl::Enable(enable))
460 return false;
461
462 gtk_widget_set_sensitive(GTK_BIN(m_widget)->child, enable);
463
464 //if (enable)
465 // GTKFixSensitivity();
466
467 return true;
468 }
469
470 GdkWindow*
471 wxWebViewWebKit::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
472 {
473 GdkWindow* window = gtk_widget_get_parent_window(m_widget);
474 return window;
475 }
476
477 void wxWebViewWebKit::ZoomIn()
478 {
479 webkit_web_view_zoom_in (WEBKIT_WEB_VIEW(web_view));
480 }
481
482 void wxWebViewWebKit::ZoomOut()
483 {
484 webkit_web_view_zoom_out (WEBKIT_WEB_VIEW(web_view));
485 }
486
487 void wxWebViewWebKit::SetWebkitZoom(float level)
488 {
489 webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW(web_view), level);
490 }
491
492 float wxWebViewWebKit::GetWebkitZoom() const
493 {
494 return webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW(web_view));
495 }
496
497 void wxWebViewWebKit::Stop()
498 {
499 webkit_web_view_stop_loading (WEBKIT_WEB_VIEW(web_view));
500 }
501
502 void wxWebViewWebKit::Reload(wxWebViewReloadFlags flags)
503 {
504 if (flags & wxWEB_VIEW_RELOAD_NO_CACHE)
505 {
506 webkit_web_view_reload_bypass_cache (WEBKIT_WEB_VIEW(web_view));
507 }
508 else
509 {
510 webkit_web_view_reload (WEBKIT_WEB_VIEW(web_view));
511 }
512 }
513
514 void wxWebViewWebKit::LoadURL(const wxString& url)
515 {
516 webkit_web_view_load_uri(WEBKIT_WEB_VIEW(web_view), wxGTK_CONV(url));
517 }
518
519
520 void wxWebViewWebKit::GoBack()
521 {
522 webkit_web_view_go_back (WEBKIT_WEB_VIEW(web_view));
523 }
524
525 void wxWebViewWebKit::GoForward()
526 {
527 webkit_web_view_go_forward (WEBKIT_WEB_VIEW(web_view));
528 }
529
530
531 bool wxWebViewWebKit::CanGoBack() const
532 {
533 return webkit_web_view_can_go_back (WEBKIT_WEB_VIEW(web_view));
534 }
535
536
537 bool wxWebViewWebKit::CanGoForward() const
538 {
539 return webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW(web_view));
540 }
541
542 void wxWebViewWebKit::ClearHistory()
543 {
544 WebKitWebBackForwardList* history;
545 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
546 webkit_web_back_forward_list_clear(history);
547 }
548
549 void wxWebViewWebKit::EnableHistory(bool enable)
550 {
551 WebKitWebBackForwardList* history;
552 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
553 if(enable)
554 {
555 webkit_web_back_forward_list_set_limit(history, m_historyLimit);
556 }
557 else
558 {
559 webkit_web_back_forward_list_set_limit(history, 0);
560 }
561 }
562
563 wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewWebKit::GetBackwardHistory()
564 {
565 wxVector<wxSharedPtr<wxWebViewHistoryItem> > backhist;
566 WebKitWebBackForwardList* history;
567 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
568 GList* list = webkit_web_back_forward_list_get_back_list_with_limit(history,
569 m_historyLimit);
570 //We need to iterate in reverse to get the order we desire
571 for(int i = g_list_length(list) - 1; i >= 0 ; i--)
572 {
573 WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)g_list_nth_data(list, i);
574 wxWebViewHistoryItem* wxitem = new wxWebViewHistoryItem(
575 webkit_web_history_item_get_uri(gtkitem),
576 webkit_web_history_item_get_title(gtkitem));
577 wxitem->m_histItem = gtkitem;
578 wxSharedPtr<wxWebViewHistoryItem> item(wxitem);
579 backhist.push_back(item);
580 }
581 return backhist;
582 }
583
584 wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewWebKit::GetForwardHistory()
585 {
586 wxVector<wxSharedPtr<wxWebViewHistoryItem> > forwardhist;
587 WebKitWebBackForwardList* history;
588 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
589 GList* list = webkit_web_back_forward_list_get_forward_list_with_limit(history,
590 m_historyLimit);
591 for(guint i = 0; i < g_list_length(list); i++)
592 {
593 WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)g_list_nth_data(list, i);
594 wxWebViewHistoryItem* wxitem = new wxWebViewHistoryItem(
595 webkit_web_history_item_get_uri(gtkitem),
596 webkit_web_history_item_get_title(gtkitem));
597 wxitem->m_histItem = gtkitem;
598 wxSharedPtr<wxWebViewHistoryItem> item(wxitem);
599 forwardhist.push_back(item);
600 }
601 return forwardhist;
602 }
603
604 void wxWebViewWebKit::LoadHistoryItem(wxSharedPtr<wxWebViewHistoryItem> item)
605 {
606 WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)item->m_histItem;
607 if(gtkitem)
608 {
609 WebKitWebBackForwardList* history;
610 history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view));
611 webkit_web_view_go_to_back_forward_item(WEBKIT_WEB_VIEW(web_view),
612 WEBKIT_WEB_HISTORY_ITEM(gtkitem));
613 }
614 }
615
616 bool wxWebViewWebKit::CanCut() const
617 {
618 return webkit_web_view_can_cut_clipboard(WEBKIT_WEB_VIEW(web_view));
619 }
620
621 bool wxWebViewWebKit::CanCopy() const
622 {
623 return webkit_web_view_can_copy_clipboard(WEBKIT_WEB_VIEW(web_view));
624 }
625
626 bool wxWebViewWebKit::CanPaste() const
627 {
628 return webkit_web_view_can_paste_clipboard(WEBKIT_WEB_VIEW(web_view));
629 }
630
631 void wxWebViewWebKit::Cut()
632 {
633 webkit_web_view_cut_clipboard(WEBKIT_WEB_VIEW(web_view));
634 }
635
636 void wxWebViewWebKit::Copy()
637 {
638 webkit_web_view_copy_clipboard(WEBKIT_WEB_VIEW(web_view));
639 }
640
641 void wxWebViewWebKit::Paste()
642 {
643 webkit_web_view_paste_clipboard(WEBKIT_WEB_VIEW(web_view));
644 }
645
646 bool wxWebViewWebKit::CanUndo() const
647 {
648 return webkit_web_view_can_undo(WEBKIT_WEB_VIEW(web_view));
649 }
650
651 bool wxWebViewWebKit::CanRedo() const
652 {
653 return webkit_web_view_can_redo(WEBKIT_WEB_VIEW(web_view));
654 }
655
656 void wxWebViewWebKit::Undo()
657 {
658 webkit_web_view_undo(WEBKIT_WEB_VIEW(web_view));
659 }
660
661 void wxWebViewWebKit::Redo()
662 {
663 webkit_web_view_redo(WEBKIT_WEB_VIEW(web_view));
664 }
665
666 wxString wxWebViewWebKit::GetCurrentURL() const
667 {
668 // FIXME: check which encoding the web kit control uses instead of
669 // assuming UTF8 (here and elsewhere too)
670 return wxString::FromUTF8(webkit_web_view_get_uri(
671 WEBKIT_WEB_VIEW(web_view)));
672 }
673
674
675 wxString wxWebViewWebKit::GetCurrentTitle() const
676 {
677 return wxString::FromUTF8(webkit_web_view_get_title(
678 WEBKIT_WEB_VIEW(web_view)));
679 }
680
681
682 wxString wxWebViewWebKit::GetPageSource() const
683 {
684 WebKitWebFrame* frame = webkit_web_view_get_main_frame(
685 WEBKIT_WEB_VIEW(web_view));
686 WebKitWebDataSource* src = webkit_web_frame_get_data_source (frame);
687
688 // TODO: check encoding with
689 // const gchar*
690 // webkit_web_data_source_get_encoding(WebKitWebDataSource *data_source);
691 return wxString(webkit_web_data_source_get_data (src)->str, wxConvUTF8);
692 }
693
694
695 wxWebViewZoom wxWebViewWebKit::GetZoom() const
696 {
697 float zoom = GetWebkitZoom();
698
699 // arbitrary way to map float zoom to our common zoom enum
700 if (zoom <= 0.65)
701 {
702 return wxWEB_VIEW_ZOOM_TINY;
703 }
704 else if (zoom > 0.65 && zoom <= 0.90)
705 {
706 return wxWEB_VIEW_ZOOM_SMALL;
707 }
708 else if (zoom > 0.90 && zoom <= 1.15)
709 {
710 return wxWEB_VIEW_ZOOM_MEDIUM;
711 }
712 else if (zoom > 1.15 && zoom <= 1.45)
713 {
714 return wxWEB_VIEW_ZOOM_LARGE;
715 }
716 else if (zoom > 1.45)
717 {
718 return wxWEB_VIEW_ZOOM_LARGEST;
719 }
720
721 // to shut up compilers, this can never be reached logically
722 wxASSERT(false);
723 return wxWEB_VIEW_ZOOM_MEDIUM;
724 }
725
726
727 void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom)
728 {
729 // arbitrary way to map our common zoom enum to float zoom
730 switch (zoom)
731 {
732 case wxWEB_VIEW_ZOOM_TINY:
733 SetWebkitZoom(0.6f);
734 break;
735
736 case wxWEB_VIEW_ZOOM_SMALL:
737 SetWebkitZoom(0.8f);
738 break;
739
740 case wxWEB_VIEW_ZOOM_MEDIUM:
741 SetWebkitZoom(1.0f);
742 break;
743
744 case wxWEB_VIEW_ZOOM_LARGE:
745 SetWebkitZoom(1.3);
746 break;
747
748 case wxWEB_VIEW_ZOOM_LARGEST:
749 SetWebkitZoom(1.6);
750 break;
751
752 default:
753 wxASSERT(false);
754 }
755 }
756
757 void wxWebViewWebKit::SetZoomType(wxWebViewZoomType type)
758 {
759 webkit_web_view_set_full_content_zoom(WEBKIT_WEB_VIEW(web_view),
760 (type == wxWEB_VIEW_ZOOM_TYPE_LAYOUT ?
761 TRUE : FALSE));
762 }
763
764 wxWebViewZoomType wxWebViewWebKit::GetZoomType() const
765 {
766 gboolean fczoom = webkit_web_view_get_full_content_zoom(
767 WEBKIT_WEB_VIEW(web_view));
768
769 if (fczoom) return wxWEB_VIEW_ZOOM_TYPE_LAYOUT;
770 else return wxWEB_VIEW_ZOOM_TYPE_TEXT;
771 }
772
773 bool wxWebViewWebKit::CanSetZoomType(wxWebViewZoomType) const
774 {
775 // this port supports all zoom types
776 return true;
777 }
778
779 void wxWebViewWebKit::SetPage(const wxString& html, const wxString& baseUri)
780 {
781 webkit_web_view_load_string (WEBKIT_WEB_VIEW(web_view),
782 html.mb_str(wxConvUTF8),
783 "text/html",
784 "UTF-8",
785 baseUri.mb_str(wxConvUTF8));
786 }
787
788 void wxWebViewWebKit::Print()
789 {
790 WebKitWebFrame* frame = webkit_web_view_get_main_frame(
791 WEBKIT_WEB_VIEW(web_view));
792 webkit_web_frame_print (frame);
793
794 // GtkPrintOperationResult webkit_web_frame_print_full
795 // (WebKitWebFrame *frame,
796 // GtkPrintOperation *operation,
797 // GtkPrintOperationAction action,
798 // GError **error);
799
800 }
801
802
803 bool wxWebViewWebKit::IsBusy() const
804 {
805 return m_busy;
806
807 // This code looks nice but returns true after a page was cancelled
808 /*
809 WebKitLoadStatus status = webkit_web_view_get_load_status
810 (WEBKIT_WEB_VIEW(web_view));
811
812
813 #if WEBKIT_CHECK_VERSION(1,1,16)
814 // WEBKIT_LOAD_FAILED is new in webkit 1.1.16
815 if (status == WEBKIT_LOAD_FAILED)
816 {
817 return false;
818 }
819 #endif
820 if (status == WEBKIT_LOAD_FINISHED)
821 {
822 return false;
823 }
824
825 return true;
826 */
827 }
828
829 void wxWebViewWebKit::SetEditable(bool enable)
830 {
831 webkit_web_view_set_editable(WEBKIT_WEB_VIEW(web_view), enable);
832 }
833
834 bool wxWebViewWebKit::IsEditable() const
835 {
836 return webkit_web_view_get_editable(WEBKIT_WEB_VIEW(web_view));
837 }
838
839 void wxWebViewWebKit::DeleteSelection()
840 {
841 webkit_web_view_delete_selection(WEBKIT_WEB_VIEW(web_view));
842 }
843
844 bool wxWebViewWebKit::HasSelection() const
845 {
846 return webkit_web_view_has_selection(WEBKIT_WEB_VIEW(web_view));
847 }
848
849 void wxWebViewWebKit::SelectAll()
850 {
851 webkit_web_view_select_all(WEBKIT_WEB_VIEW(web_view));
852 }
853
854 wxString wxWebViewWebKit::GetSelectedText() const
855 {
856 WebKitDOMDocument* doc;
857 WebKitDOMDOMWindow* win;
858 WebKitDOMDOMSelection* sel;
859 WebKitDOMRange* range;
860
861 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
862 win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc));
863 sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win));
864 range = webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel),
865 0, NULL);
866 return wxString(webkit_dom_range_get_text(WEBKIT_DOM_RANGE(range)),
867 wxConvUTF8);
868 }
869
870 wxString wxWebViewWebKit::GetSelectedSource() const
871 {
872 WebKitDOMDocument* doc;
873 WebKitDOMDOMWindow* win;
874 WebKitDOMDOMSelection* sel;
875 WebKitDOMRange* range;
876 WebKitDOMElement* div;
877 WebKitDOMDocumentFragment* clone;
878 WebKitDOMHTMLElement* html;
879
880 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
881 win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc));
882 sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win));
883 range = webkit_dom_dom_selection_get_range_at(WEBKIT_DOM_DOM_SELECTION(sel),
884 0, NULL);
885 div = webkit_dom_document_create_element(WEBKIT_DOM_DOCUMENT(doc), "div", NULL);
886
887 clone = webkit_dom_range_clone_contents(WEBKIT_DOM_RANGE(range), NULL);
888 webkit_dom_node_append_child(&div->parent_instance, &clone->parent_instance, NULL);
889 html = (WebKitDOMHTMLElement*)div;
890
891 return wxString(webkit_dom_html_element_get_inner_html(WEBKIT_DOM_HTML_ELEMENT(html)),
892 wxConvUTF8);
893 }
894
895 void wxWebViewWebKit::ClearSelection()
896 {
897 WebKitDOMDocument* doc;
898 WebKitDOMDOMWindow* win;
899 WebKitDOMDOMSelection* sel;
900
901 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
902 win = webkit_dom_document_get_default_view(WEBKIT_DOM_DOCUMENT(doc));
903 sel = webkit_dom_dom_window_get_selection(WEBKIT_DOM_DOM_WINDOW(win));
904 webkit_dom_dom_selection_remove_all_ranges(WEBKIT_DOM_DOM_SELECTION(sel));
905
906 }
907
908 wxString wxWebViewWebKit::GetPageText() const
909 {
910 WebKitDOMDocument* doc;
911 WebKitDOMHTMLElement* body;
912
913 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(web_view));
914 body = webkit_dom_document_get_body(WEBKIT_DOM_DOCUMENT(doc));
915 return wxString(webkit_dom_html_element_get_inner_text(WEBKIT_DOM_HTML_ELEMENT(body)),
916 wxConvUTF8);
917 }
918
919 void wxWebViewWebKit::RunScript(const wxString& javascript)
920 {
921 webkit_web_view_execute_script(WEBKIT_WEB_VIEW(web_view),
922 javascript.mb_str(wxConvUTF8));
923 }
924
925 void wxWebViewWebKit::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
926 {
927 m_handlerList.push_back(handler);
928 }
929
930 // static
931 wxVisualAttributes
932 wxWebViewWebKit::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
933 {
934 return GetDefaultAttributesFromGTKWidget(webkit_web_view_new);
935 }
936
937
938 #endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT