]> git.saurik.com Git - wxWidgets.git/commitdiff
Application of the most recent wxWebView patch, the only changes were so tab to space...
authorSteve Lamerton <steve.lamerton@gmail.com>
Wed, 4 May 2011 15:40:00 +0000 (15:40 +0000)
committerSteve Lamerton <steve.lamerton@gmail.com>
Wed, 4 May 2011 15:40:00 +0000 (15:40 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/SOC2011_WEBVIEW@67698 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

23 files changed:
build/bakefiles/build_cfg.bkl
build/bakefiles/common.bkl
build/bakefiles/config.bkl
build/bakefiles/files.bkl
build/bakefiles/monolithic.bkl
build/bakefiles/multilib.bkl
build/bakefiles/wxpresets/presets/wx.bkl
build/bakefiles/wxwin.py
include/wx/gtk/webview.h [new file with mode: 0644]
include/wx/msw/webviewie.h [new file with mode: 0644]
include/wx/osx/webview.h [new file with mode: 0644]
include/wx/webview.h [new file with mode: 0644]
samples/samples.bkl
samples/web/forward.xpm [new file with mode: 0644]
samples/web/refresh.xpm [new file with mode: 0644]
samples/web/stop.xpm [new file with mode: 0644]
samples/web/web.bkl [new file with mode: 0644]
samples/web/web.cpp [new file with mode: 0644]
samples/web/wxlogo.xpm [new file with mode: 0644]
src/common/webview.cpp [new file with mode: 0644]
src/gtk/webview.cpp [new file with mode: 0644]
src/msw/webviewie.cpp [new file with mode: 0644]
src/osx/webview.mm [new file with mode: 0644]

index 00b2d33f5cd5677e452ac894eccbab10ed5cf020..b9e973b09ea69b14dc64b62a512dbeeff808b22f 100644 (file)
@@ -39,6 +39,7 @@
                 @echo USE_THREADS=$(USE_THREADS) >>$(BUILD_CFG_FILE)
                 @echo USE_GUI=$(USE_GUI) >>$(BUILD_CFG_FILE)
                 @echo USE_HTML=$(USE_HTML) >>$(BUILD_CFG_FILE)
+                @echo USE_WEB=$(USE_WEB) >>$(BUILD_CFG_FILE)
                 @echo USE_MEDIA=$(USE_MEDIA) >>$(BUILD_CFG_FILE)
                 @echo USE_OPENGL=$(USE_OPENGL) >>$(BUILD_CFG_FILE)
                 @echo USE_QA=$(USE_QA) >>$(BUILD_CFG_FILE)
index 8948042f2bdb687f87da1a303f0952a89965c46b..8de09ff2a74f0843af42892043e4b17ec9fd0750 100644 (file)
     <set var="WXLIB_STC">
         <if cond="MONOLITHIC=='0'">$(mk.evalExpr(wxwin.mkLibName('stc')))</if>
     </set>
-
+    <set var="WXLIB_WEB">
+        <if cond="MONOLITHIC=='0'">$(mk.evalExpr(wxwin.mkLibName('web')))</if>
+    </set>
     <set var="WXLIB_MONO">
         <if cond="MONOLITHIC=='1'">$(mk.evalExpr(wxwin.mkLibName('mono')))</if>
     </set>
index ee14b32871d42795f06272bb34c1a0484e64e15f..4d57319cceb0f0957bf1e77c48510d76cb7f10c3 100644 (file)
@@ -200,6 +200,14 @@ Default is to use debug CRT if and only if BUILD==debug.
         </description>
     </option>
 
+    <option name="USE_WEB">
+        <values>0,1</values>
+        <default-value>1</default-value>
+        <description>
+            Build wxWeb library (USE_GUI must be 1)?
+        </description>
+    </option>
+    
     <option name="USE_MEDIA">
         <values>0,1</values>
         <default-value>1</default-value>
@@ -372,6 +380,7 @@ to run the tests, include CppUnit library here.
         <option name="EXTRALIBS"/>
         <option name="EXTRALIBS_XML"/>
         <option name="EXTRALIBS_HTML"/>
+        <option name="EXTRALIBS_WEB"/>
         <option name="EXTRALIBS_MEDIA"/>
         <option name="EXTRALIBS_GUI"/>
         <option name="EXTRALIBS_OPENGL"/>
@@ -432,6 +441,7 @@ it if SHARED=1 unless you know what you are doing.
         <set var="EXTRALIBS"/>
         <set var="EXTRALIBS_XML"/>
         <set var="EXTRALIBS_HTML"/>
+        <set var="EXTRALIBS_WEB"/>
         <set var="EXTRALIBS_MEDIA"/>
         <set var="EXTRALIBS_GUI"/>
         <set var="EXTRALIBS_OPENGL">
@@ -480,6 +490,7 @@ Set the version of your Mingw installation here.
         <set var="USE_RICHTEXT">1</set>
         <set var="USE_STC">1</set>
         <set var="USE_HTML">1</set>
+        <set var="USE_WEB">1</set>
         <set var="USE_MEDIA">1</set>
         <set var="USE_XRC">1</set>
         <set var="USE_OPENGL">1</set>
index 3c575fa16cdce1fdc87bcf500f255c6e9b530f2c..bfda5997fe64e2538801414a61a7194d1710440d 100644 (file)
@@ -3309,6 +3309,21 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
     <!-- wxHTML users: -->
     src/generic/htmllbox.cpp
 </set>
+<set var="WEB_SRC_PLATFORM">
+    <if cond="TOOLKIT=='MSW'">
+        src/msw/webview.cpp
+    </if>
+    <if cond="PLATFORM_UNIX=='1'">
+        src/gtk/webview.cpp
+    </if>
+    <if cond="PLATFORM_MACOSX=='1'">
+        src/osx/webview.mm
+    </if>
+</set>
+<set var="WEB_SRC" hints="files">
+    $(WEB_SRC_PLATFORM)
+    src/common/webview.cpp
+</set>
 <set var="MSW_HTML_HDR" hints="files">
     <if cond="TOOLKIT=='MSW'">wx/msw/helpbest.h</if>
 </set>
@@ -3334,7 +3349,21 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
     wx/htmllbox.h
     $(MSW_HTML_HDR)
 </set>
-
+<set var="PLATFORM_WEB_HDR" hints="files">
+    <if cond="TOOLKIT=='MSW'">
+        wx/msw/webviewie.h
+    </if>
+    <if cond="PLATFORM_UNIX=='1'">
+        wx/gtk/webview.h
+    </if>
+    <if cond="PLATFORM_MACOSX=='1'">
+        wx/osx/webview.h
+    </if>
+</set>
+<set var="WEB_HDR" hints="files">
+    $(PLATFORM_WEB_HDR)
+    wx/webview.h
+</set>
 
 
 <!-- ====================================================================== -->
index 1ad6d4af0247504f858b61d2b918b3fb4eca0b9e..f02411eab1947bbbc833e6595a62892a924c4bc6 100644 (file)
@@ -4,7 +4,7 @@
 
     <set var="MONOLIB_GUI_SRC">
         <if cond="USE_GUI=='1'">
-            $(CORE_SRC) $(ADVANCED_SRC) $(MEDIA_SRC) $(HTML_SRC) $(QA_SRC)
+            $(CORE_SRC) $(ADVANCED_SRC) $(MEDIA_SRC) $(HTML_SRC) $(WEB_SRC) $(QA_SRC)
             $(XRC_SRC) $(AUI_SRC) $(PROPGRID_SRC) $(RIBBON_SRC) $(RICHTEXT_SRC)
             $(STC_SRC)
         </if>
@@ -25,6 +25,7 @@
         <define>WXMAKINGDLL</define>
         <ldlibs>$(EXTRALIBS_XML)</ldlibs>
         <ldlibs>$(EXTRALIBS_HTML)</ldlibs>
+        <ldlibs>$(EXTRALIBS_WEB)</ldlibs>
         <ldlibs>$(EXTRALIBS_MEDIA)</ldlibs>
         <ldlibs>$(PLUGIN_MONOLIB_EXTRALIBS)</ldlibs>
         <library>$(wxscintilla_library_link)</library>
index 2217008017f15536611ce72967e0f32246559d67..6c5ffd7c7f360c722fa0b829853ca444b2409495 100644 (file)
 
     <set var="MSVC6PRJ_MERGED_TARGETS_MULTILIB" append="1">html=htmllib+htmldll</set>
 
+    <!-- ================================================================ -->
+    <!--                               wxWEB                              -->
+    <!-- ================================================================ -->
+
+    <dll id="webdll" template="wx_dll"
+         cond="SHARED=='1' and USE_GUI=='1' and USE_WEB=='1' and MONOLITHIC=='0'">
+        <define>WXUSINGDLL</define>
+        <define>WXMAKINGDLL_WEB</define>
+        <sources>$(WEB_SRC)</sources>
+        <library>coredll</library>
+        <library>basedll</library>
+        <ldlibs>$(EXTRALIBS_WEB)</ldlibs>
+        <msvc-headers>$(WEB_HDR)</msvc-headers>
+    </dll>
+
+    <!-- use this to conditonally link against htmldll with <library>: -->
+    <set var="webdll_library_link">
+        <if cond="SHARED=='1' and USE_GUI=='1' and USE_WEB=='1' and MONOLITHIC=='0'">webdll</if>
+    </set>
+
+    <lib id="weblib" template="wx_lib"
+         cond="SHARED=='0' and USE_GUI=='1' and USE_WEB=='1' and MONOLITHIC=='0'">
+        <sources>$(WEB_SRC)</sources>
+        <msvc-headers>$(WEB_HDR)</msvc-headers>
+    </lib>
+
+    <wxshortcut id="wxweb" cond="MONOLITHIC=='0' and USE_WEB=='1'"/>
+
+    <set var="MSVC6PRJ_MERGED_TARGETS_MULTILIB" append="1">web=weblib+webdll</set>
+
     <!-- ================================================================ -->
     <!--                             OpenGL                               -->
     <!-- ================================================================ -->
index ec262c9e096e1843d20a7c56a83940f0f3a768d8..ca51a0deeb28c7ba70b204c2cfdc56e55dc990b6 100644 (file)
         <wx-lib>xml</wx-lib>
         <wx-lib>core</wx-lib>
         <wx-lib>base</wx-lib>
+        <wx-lib>web</wx-lib>
 
 -->
 
                          tag definitions.
     -->
     <set var="WX_LIB_LIST">
-        base core net xml xrc html adv media gl qa aui ribbon propgrid richtext stc
+        base core net xml xrc html adv media gl qa aui ribbon propgrid richtext stc web
     </set>
 
     <!-- if you define this variable to 0 before including wx presets, the
index 8f5cb31f8a7393ee432474f7a19671e6c8b29ccd..d04413352d3701c687482a9df420e01697c40ea1 100644 (file)
@@ -39,12 +39,12 @@ def mk_wxid(id):
 
 
 # All libs that are part of the main library:
-MAIN_LIBS = ['mono', 'base', 'core', 'adv', 'html', 'xml', 'net',
+MAIN_LIBS = ['mono', 'base', 'core', 'adv', 'html', 'xml', 'net', 'web',
              'media', 'qa', 'xrc', 'aui', 'ribbon', 'propgrid', 'richtext', 'stc']
 # List of library names/ids for categories with different names:
 LIBS_NOGUI = ['xml', 'net']
 LIBS_GUI   = ['core', 'adv', 'html', 'gl', 'qa', 'xrc', 'media',
-              'aui', 'propgrid', 'richtext', 'stc', 'ribbon']
+              'aui', 'propgrid', 'richtext', 'stc', 'ribbon', 'web']
 # Additional libraries that must be linked in:
 EXTRALIBS = {
     'gl' : '$(EXTRALIBS_OPENGL)',
@@ -52,6 +52,7 @@ EXTRALIBS = {
     'html' : '$(EXTRALIBS_HTML)',
     'adv' : '$(PLUGIN_ADV_EXTRALIBS)',
     'media' : '$(EXTRALIBS_MEDIA)',
+    'web' : '$(EXTRALIBS_WEB)',
 }
 
 def mkLibName(wxid):
diff --git a/include/wx/gtk/webview.h b/include/wx/gtk/webview.h
new file mode 100644 (file)
index 0000000..88b53e8
--- /dev/null
@@ -0,0 +1,116 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Name:        include/gtk/wx/webview.h\r
+// Purpose:     GTK webkit backend for web view component\r
+// Author:      Robert Roebling, Marianne Gagnon\r
+// Id:          $Id$\r
+// Copyright:   (c) 200 Marianne Gagnon, 1998 Robert Roebling\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef _WX_GTK_WEBKITCTRL_H_\r
+#define _WX_GTK_WEBKITCTRL_H_\r
+\r
+#include "wx/setup.h"\r
+\r
+#if wxHAVE_WEB_BACKEND_GTK_WEBKIT\r
+\r
+#include "wx/webview.h"\r
+\r
+//-----------------------------------------------------------------------------\r
+// wxWebViewGTKWebKit\r
+//-----------------------------------------------------------------------------\r
+\r
+class WXDLLIMPEXP_CORE wxWebViewGTKWebKit : public wxWebView\r
+{\r
+public:\r
+    wxWebViewGTKWebKit() { Init(); }\r
+\r
+    wxWebViewGTKWebKit(wxWindow *parent,\r
+           wxWindowID id = wxID_ANY,\r
+           const wxString& url = wxWebViewDefaultURLStr,\r
+           const wxPoint& pos = wxDefaultPosition,\r
+           const wxSize& size = wxDefaultSize, long style = 0,\r
+           const wxString& name = wxWebViewNameStr)\r
+    {\r
+        Init();\r
+\r
+        Create(parent, id, url, pos, size, style, name);\r
+    }\r
+\r
+    virtual bool Create(wxWindow *parent,\r
+           wxWindowID id = wxID_ANY,\r
+           const wxString& url = wxWebViewDefaultURLStr,\r
+           const wxPoint& pos = wxDefaultPosition,\r
+           const wxSize& size = wxDefaultSize, long style = 0,\r
+           const wxString& name = wxWebViewNameStr);\r
+\r
+    virtual bool Enable( bool enable = true );\r
+\r
+    // implementation\r
+    // --------------\r
+\r
+    static wxVisualAttributes\r
+    GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);\r
+\r
+    // helper to allow access to protected member from GTK callback\r
+    void MoveWindow(int x, int y, int width, int height)\r
+    {\r
+        DoMoveWindow(x, y, width, height);\r
+    }\r
+\r
+    void ZoomIn();\r
+    void ZoomOut();\r
+    void SetWebkitZoom(float level);\r
+    float GetWebkitZoom();\r
+\r
+    virtual void Stop();\r
+    virtual void LoadUrl(const wxString& url);\r
+    virtual void GoBack();\r
+    virtual void GoForward();\r
+    virtual void Reload(wxWebViewReloadFlags flags = 0);\r
+    virtual bool CanGoBack();\r
+    virtual bool CanGoForward();\r
+    virtual wxString GetCurrentURL();\r
+    virtual wxString GetCurrentTitle();\r
+    virtual wxString GetPageSource();\r
+    virtual void SetPage(const wxString& html, const wxString& baseUrl);\r
+    virtual void Print();\r
+    virtual bool IsBusy();\r
+\r
+    void SetZoomType(wxWebViewZoomType);\r
+    wxWebViewZoomType GetZoomType() const;\r
+    bool CanSetZoomType(wxWebViewZoomType) const;\r
+    virtual wxWebViewZoom GetZoom();\r
+    virtual void SetZoom(wxWebViewZoom);\r
+\r
+\r
+\r
+    /** FIXME: hack to work around signals being received too early */\r
+    bool m_ready;\r
+\r
+\r
+    /** TODO: check if this can be made private\r
+     * The native control has a getter to check for busy state, but except in\r
+     * very recent versions of webkit this getter doesn't say everything we need\r
+     * (namely it seems to stay indefinitely busy when loading is cancelled by\r
+     * user)\r
+     */\r
+    bool m_busy;\r
+\r
+protected:\r
+\r
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;\r
+\r
+private:\r
+\r
+    // focus event handler: calls GTKUpdateBitmap()\r
+    void GTKOnFocus(wxFocusEvent& event);\r
+\r
+    GtkWidget *web_view;\r
+\r
+    // FIXME: try to get DECLARE_DYNAMIC_CLASS macros & stuff right\r
+    //DECLARE_DYNAMIC_CLASS(wxWebViewGTKWebKit)\r
+};\r
+\r
+#endif // if wxHAVE_WEB_BACKEND_GTK_WEBKIT\r
+\r
diff --git a/include/wx/msw/webviewie.h b/include/wx/msw/webviewie.h
new file mode 100644 (file)
index 0000000..93f77d2
--- /dev/null
@@ -0,0 +1,126 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Name:        include/wx/msw/webviewie.h\r
+// Purpose:     wxMSW IE wxWebView backend\r
+// Author:      Marianne Gagnon\r
+// Id:          $Id$\r
+// Copyright:   (c) 2010 Marianne Gagnon\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef wxWebViewIE_H\r
+#define wxWebViewIE_H\r
+\r
+#include "wx/setup.h"\r
+\r
+#if wxHAVE_WEB_BACKEND_IE\r
+\r
+#include "wx/control.h"\r
+#include "wx/webview.h"\r
+#include "wx/msw/ole/automtn.h"\r
+#include "wx/msw/ole/activex.h"\r
+\r
+// TODO: move this to wx/msw/chkconf.h\r
+#if wxUSE_ACTIVEX != 1\r
+#error "wxUSE_ACTIVEX must be activated for this to work"\r
+#endif\r
+\r
+#if wxUSE_OLE_AUTOMATION != 1\r
+#error "wxUSE_OLE_AUTOMATION must be activated for this to work"\r
+#endif\r
+\r
+// FIXME: get those DLL export macros right...\r
+\r
+class wxWebViewIE : public wxWebView\r
+{\r
+public:\r
+\r
+    wxWebViewIE() {}\r
+\r
+    wxWebViewIE(wxWindow* parent,\r
+           wxWindowID id,\r
+           const wxString& url = wxWebViewDefaultURLStr,\r
+           const wxPoint& pos = wxDefaultPosition,\r
+           const wxSize& size = wxDefaultSize,\r
+           long style = 0,\r
+           const wxString& name = wxWebViewNameStr)\r
+   {\r
+       Create(parent, id, url, pos, size, style, name);\r
+   }\r
+\r
+    bool Create(wxWindow* parent,\r
+           wxWindowID id,\r
+           const wxString& url = wxWebViewDefaultURLStr,\r
+           const wxPoint& pos = wxDefaultPosition,\r
+           const wxSize& size = wxDefaultSize,\r
+           long style = 0,\r
+           const wxString& name = wxWebViewNameStr);\r
+\r
+    virtual void LoadUrl(const wxString& url);\r
+\r
+    virtual bool CanGoForward() { return m_canNavigateForward; }\r
+    virtual bool CanGoBack() { return m_canNavigateBack; }\r
+    virtual void GoBack();\r
+    virtual void GoForward();\r
+    virtual void Stop();\r
+    virtual void Reload(wxWebViewReloadFlags flags=0);\r
+\r
+    virtual wxString GetPageSource();\r
+\r
+    virtual bool IsBusy();\r
+    virtual wxString GetCurrentURL();\r
+    virtual wxString GetCurrentTitle();\r
+\r
+    virtual void SetZoomType(wxWebViewZoomType);\r
+    virtual wxWebViewZoomType GetZoomType() const;\r
+    virtual bool CanSetZoomType(wxWebViewZoomType) const;\r
+\r
+    virtual void Print();\r
+\r
+    virtual void SetPage(const wxString& html, const wxString& baseUrl);\r
+\r
+    virtual wxWebViewZoom GetZoom();\r
+    virtual void SetZoom(wxWebViewZoom zoom);\r
+\r
+    // ---- IE-specific methods\r
+\r
+    // FIXME: I seem to be able to access remote webpages even in offline mode...\r
+    bool IsOfflineMode();\r
+    void SetOfflineMode(bool offline);\r
+\r
+    /**\r
+     * Get text zoom\r
+     * @return text zoom from 0 to 4\r
+     */\r
+    int GetIETextZoom();\r
+\r
+    /**\r
+     *  @param level 0 to 4\r
+     */\r
+    void SetIETextZoom(int level);\r
+\r
+    void SetIEOpticalZoom(float zoom);\r
+    float GetIEOpticalZoom();\r
+\r
+    void onActiveXEvent(wxActiveXEvent& evt);\r
+    void onEraseBg(wxEraseEvent& evt) {}\r
+\r
+    DECLARE_EVENT_TABLE();\r
+\r
+private:\r
+    wxActiveXContainer* m_container;\r
+    wxAutomationObject m_ie;\r
+    IWebBrowser2* m_webBrowser;\r
+    DWORD m_dwCookie;\r
+    bool m_canNavigateBack;\r
+    bool m_canNavigateForward;\r
+\r
+    /** The "Busy" property of IWebBrowser2 does not always return busy when\r
+     *  we'd want it to; this variable may be set to true in cases where the\r
+     *  Busy property is false but should be true.\r
+     */\r
+    bool m_isBusy;\r
+};\r
+\r
+#endif // wxHAVE_WEB_BACKEND_IE\r
+\r
+#endif // wxWebViewIE_H\r
diff --git a/include/wx/osx/webview.h b/include/wx/osx/webview.h
new file mode 100644 (file)
index 0000000..47a17e8
--- /dev/null
@@ -0,0 +1,142 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Name:        include/wx/osx/webkit.h\r
+// Purpose:     wxOSXWebKitCtrl - embeddable web kit control,\r
+//                             OS X implementation of web view component\r
+// Author:      Jethro Grassie / Kevin Ollivier / Marianne Gagnon\r
+// Modified by:\r
+// Created:     2004-4-16\r
+// RCS-ID:      $Id$\r
+// Copyright:   (c) Jethro Grassie / Kevin Ollivier / Marianne Gagnon\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef _WX_WEBKIT_H\r
+#define _WX_WEBKIT_H\r
+\r
+#include "wx/setup.h"\r
+\r
+#if wxUSE_WEBKIT && (defined(__WXMAC__) || defined(__WXCOCOA__))\r
+\r
+// TODO: define this in setup.h ?\r
+#define wxHAVE_WEB_BACKEND_OSX_WEBKIT 1\r
+\r
+#include "wx/control.h"\r
+#include "wx/webview.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+// Web Kit Control\r
+// ----------------------------------------------------------------------------\r
+\r
+class WXDLLIMPEXP_CORE wxOSXWebKitCtrl : public wxWebView\r
+{\r
+public:\r
+    wxDECLARE_DYNAMIC_CLASS(wxOSXWebKitCtrl);\r
+\r
+    wxOSXWebKitCtrl() {}\r
+    wxOSXWebKitCtrl(wxWindow *parent,\r
+                    wxWindowID winID = wxID_ANY,\r
+                    const wxString& strURL = wxWebViewDefaultURLStr,\r
+                    const wxPoint& pos = wxDefaultPosition,\r
+                    const wxSize& size = wxDefaultSize, long style = 0,\r
+                    const wxString& name = wxWebViewNameStr)\r
+    {\r
+        Create(parent, winID, strURL, pos, size, style, name);\r
+    }\r
+    bool Create(wxWindow *parent,\r
+                wxWindowID winID = wxID_ANY,\r
+                const wxString& strURL = wxWebViewDefaultURLStr,\r
+                const wxPoint& pos = wxDefaultPosition,\r
+                const wxSize& size = wxDefaultSize, long style = 0,\r
+                const wxString& name = wxWebViewNameStr);\r
+    virtual ~wxOSXWebKitCtrl();\r
+\r
+    void InternalLoadURL(const wxString &url);\r
+\r
+    virtual bool CanGoBack();\r
+    virtual bool CanGoForward();\r
+    virtual void GoBack();\r
+    virtual void GoForward();\r
+    virtual void Reload(wxWebViewReloadFlags flags = 0);\r
+    virtual void Stop();\r
+    virtual wxString GetPageSource();\r
+    virtual void SetPageTitle(const wxString& title) { m_pageTitle = title; }\r
+    virtual wxString GetPageTitle(){ return m_pageTitle; }\r
+\r
+    virtual void SetPage(const wxString& html, const wxString& baseUrl);\r
+\r
+    virtual void Print();\r
+\r
+    virtual void LoadUrl(const wxString& url);\r
+    virtual wxString GetCurrentURL();\r
+    virtual wxString GetCurrentTitle();\r
+    virtual wxWebViewZoom GetZoom();\r
+    virtual void SetZoom(wxWebViewZoom zoom);\r
+\r
+    virtual void SetZoomType(wxWebViewZoomType zoomType);\r
+    virtual wxWebViewZoomType GetZoomType() const;\r
+    virtual bool CanSetZoomType(wxWebViewZoomType type) const;\r
+\r
+    virtual bool IsBusy() { return m_busy; }\r
+\r
+    // ---- methods not from the parent (common) interface\r
+    wxString GetSelectedText();\r
+\r
+    wxString RunScript(const wxString& javascript);\r
+\r
+    bool  CanGetPageSource();\r
+\r
+    void  SetScrollPos(int pos);\r
+    int   GetScrollPos();\r
+\r
+    void  MakeEditable(bool enable = true);\r
+    bool  IsEditable();\r
+\r
+    wxString GetSelection();\r
+\r
+    bool  CanIncreaseTextSize();\r
+    void  IncreaseTextSize();\r
+    bool  CanDecreaseTextSize();\r
+    void  DecreaseTextSize();\r
+\r
+    float GetWebkitZoom();\r
+    void  SetWebkitZoom(float zoom);\r
+\r
+    // don't hide base class virtuals\r
+    virtual void SetScrollPos( int orient, int pos, bool refresh = true )\r
+        { return wxControl::SetScrollPos(orient, pos, refresh); }\r
+    virtual int GetScrollPos( int orient ) const\r
+        { return wxControl::GetScrollPos(orient); }\r
+\r
+    //we need to resize the webview when the control size changes\r
+    void OnSize(wxSizeEvent &event);\r
+    void OnMove(wxMoveEvent &event);\r
+    void OnMouseEvents(wxMouseEvent &event);\r
+\r
+    bool m_busy;\r
+\r
+protected:\r
+    DECLARE_EVENT_TABLE()\r
+    void MacVisibilityChanged();\r
+\r
+private:\r
+    wxWindow *m_parent;\r
+    wxWindowID m_windowID;\r
+    wxString m_pageTitle;\r
+\r
+    struct objc_object *m_webView;\r
+\r
+    // we may use this later to setup our own mouse events,\r
+    // so leave it in for now.\r
+    void* m_webKitCtrlEventHandler;\r
+    //It should be WebView*, but WebView is an Objective-C class\r
+    //TODO: look into using DECLARE_WXCOCOA_OBJC_CLASS rather than this.\r
+};\r
+\r
+\r
+#else\r
+// TODO: define this in setup.h ?\r
+#define wxHAVE_WEB_BACKEND_OSX_WEBKIT 0\r
+\r
+#endif // wxUSE_WEBKIT\r
+\r
+#endif // _WX_WEBKIT_H_\r
diff --git a/include/wx/webview.h b/include/wx/webview.h
new file mode 100644 (file)
index 0000000..bd60cd8
--- /dev/null
@@ -0,0 +1,429 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Name:        webview.h\r
+// Purpose:     Common interface and events for web view component\r
+// Author:      Marianne Gagnon\r
+// Id:          $Id$\r
+// Copyright:   (c) 2010 Marianne Gagnon\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef _WX_WEB_VIEW_H_\r
+#define _WX_WEB_VIEW_H_\r
+\r
+#include <wx/control.h>\r
+#include <wx/event.h>\r
+#include <wx/sstream.h>\r
+\r
+/**\r
+ * Zoom level in web view component\r
+ */\r
+enum wxWebViewZoom\r
+{\r
+    wxWEB_VIEW_ZOOM_TINY,\r
+    wxWEB_VIEW_ZOOM_SMALL,\r
+    wxWEB_VIEW_ZOOM_MEDIUM,\r
+    wxWEB_VIEW_ZOOM_LARGE,\r
+    wxWEB_VIEW_ZOOM_LARGEST\r
+};\r
+\r
+/**\r
+ * The type of zooming that the web view control can perform\r
+ */\r
+enum wxWebViewZoomType\r
+{\r
+    /** The entire layout scales when zooming, including images */\r
+    wxWEB_VIEW_ZOOM_TYPE_LAYOUT,\r
+    /** Only the text changes in size when zooming, images and other layout\r
+      * elements retain their initial size */\r
+    wxWEB_VIEW_ZOOM_TYPE_TEXT\r
+};\r
+\r
+/** Types of errors that can cause navigation to fail */\r
+enum wxWebNavigationError\r
+{\r
+    /** Connection error (timeout, etc.) */\r
+    wxWEB_NAV_ERR_CONNECTION = 1,\r
+    /** Invalid certificate */\r
+    wxWEB_NAV_ERR_CERTIFICATE = 2,\r
+    /** Authentication required */\r
+    wxWEB_NAV_ERR_AUTH = 3,\r
+    /** Other security error */\r
+    wxWEB_NAV_ERR_SECURITY = 4,\r
+    /** Requested resource not found */\r
+    wxWEB_NAV_ERR_NOT_FOUND = 5,\r
+    /** Invalid request/parameters (e.g. bad URL, bad protocol,\r
+      * unsupported resource type) */\r
+    wxWEB_NAV_ERR_REQUEST = 6,\r
+    /** The user cancelled (e.g. in a dialog) */\r
+    wxWEB_NAV_ERR_USER_CANCELLED = 7,\r
+    /** Another (exotic) type of error that didn't fit in other categories*/\r
+    wxWEB_NAV_ERR_OTHER = 8\r
+};\r
+\r
+/** Type of refresh */\r
+enum wxWebViewReloadFlags\r
+{\r
+  /** Reload the current view without accessing the cache */\r
+  wxWEB_VIEW_RELOAD_NO_CACHE = 1\r
+};\r
+\r
+\r
+/**\r
+ * List of available backends for wxWebView\r
+ */\r
+enum wxWebViewBackend\r
+{\r
+    /** Value that may be passed to wxWebView to let it pick an appropriate\r
+     * engine for the current platform*/\r
+    wxWEB_VIEW_BACKEND_DEFAULT,\r
+\r
+    /** The OSX-native WebKit web engine */\r
+    wxWEB_VIEW_BACKEND_OSX_WEBKIT,\r
+\r
+    /** The GTK port of the WebKit engine */\r
+    wxWEB_VIEW_BACKEND_GTK_WEBKIT,\r
+\r
+    /** Use Microsoft Internet Explorer as web engine */\r
+    wxWEB_VIEW_BACKEND_IE\r
+};\r
+\r
+extern WXDLLIMPEXP_DATA_CORE(const char) wxWebViewNameStr[];\r
+extern WXDLLIMPEXP_DATA_CORE(const char) wxWebViewDefaultURLStr[];\r
+\r
+/**\r
+  * @class wxWebView\r
+  *\r
+  * This control may be used to render web (HTML / CSS / javascript) documents.\r
+  * Capabilities of the HTML renderer will depend upon the backed.\r
+  * TODO: describe each backend and its capabilities here\r
+  *\r
+  * Note that errors are generally reported asynchronously though the\r
+  * wxEVT_COMMAND_WEB_VIEW_ERROR event described below.\r
+  *\r
+  * @beginEventEmissionTable{wxWebNavigationEvent}\r
+  * @event{EVT_BUTTON(id, func)}\r
+  *\r
+  * @event{EVT_WEB_VIEW_NAVIGATING(id, func)}\r
+  * Process a wxEVT_COMMAND_WEB_VIEW_NAVIGATING event, generated before trying\r
+  * to get a resource. This event may be vetoed to prevent navigating to this\r
+  * resource. Note that if the displayed HTML document has several frames, one\r
+  * such event will be generated per frame.\r
+  *\r
+  * @event{EVT_WEB_VIEW_NAVIGATED(id, func)}\r
+  * Process a wxEVT_COMMAND_WEB_VIEW_NAVIGATED event generated after it was\r
+  * confirmed that a resource would be requested. This event may not be vetoed.\r
+  * Note that if the displayed HTML document has several frames, one such event\r
+  * will be generated per frame.\r
+  *\r
+  * @event{EVT_WEB_VIEW_LOADED(id, func)}\r
+  * Process a wxEVT_COMMAND_WEB_VIEW_LOADED event generated when the document\r
+  * is fully loaded and displayed.\r
+  *\r
+  * @event{EVT_WEB_VIEW_ERRROR(id, func)}\r
+  * Process a wxEVT_COMMAND_WEB_VIEW_ERROR event generated when a navigation\r
+  * error occurs.\r
+  * The integer associated with this event will be a wxWebNavigationError item.\r
+  * The string associated with this event may contain a backend-specific more\r
+  * precise error message/code.\r
+  *\r
+  * @endEventTable\r
+  */\r
+class wxWebView : public wxControl\r
+{\r
+public:\r
+\r
+    /**\r
+     *  Creation function for two-step creation.\r
+     */\r
+    virtual bool Create(wxWindow* parent,\r
+           wxWindowID id,\r
+           const wxString& url,\r
+           const wxPoint& pos,\r
+           const wxSize& size,\r
+           long style,\r
+           const wxString& name) = 0;\r
+\r
+    /**\r
+     * Factory function to create a new wxWebView for two-step creation\r
+     * (you need to call wxWebView::Create on the returned object)\r
+     * @param backend which web engine to use as backend for wxWebView\r
+     * @return the created wxWebView, or NULL if the requested backend is\r
+     *         not available\r
+     */\r
+    static wxWebView* New(wxWebViewBackend backend = wxWEB_VIEW_BACKEND_DEFAULT);\r
+\r
+    // TODO: clarify what styles can do, or remove this flag\r
+    /**\r
+     * Factory function to create a new wxWebView\r
+     * @param parent parent window to create this view in\r
+     * @param id ID of this control\r
+     * @param url URL to load by default in the web view\r
+     * @param pos position to create this control at\r
+     *            (you may use wxDefaultPosition if you use sizers)\r
+     * @param size size to create this control with\r
+     *             (you may use wxDefaultSize if you use sizers)\r
+     * @param backend which web engine to use as backend for wxWebView\r
+     * @return the created wxWebView, or NULL if the requested backend\r
+     *         is not available\r
+     */\r
+    static wxWebView* New(wxWindow* parent,\r
+           wxWindowID id,\r
+           const wxString& url = wxWebViewDefaultURLStr,\r
+           const wxPoint& pos = wxDefaultPosition,\r
+           const wxSize& size = wxDefaultSize,\r
+           wxWebViewBackend backend = wxWEB_VIEW_BACKEND_DEFAULT,\r
+           long style = 0,\r
+           const wxString& name = wxWebViewNameStr);\r
+\r
+\r
+    /** Get whether it is possible to navigate back in the history of\r
+      * visited pages\r
+      */\r
+    virtual bool CanGoBack() = 0;\r
+\r
+    /** Get whether it is possible to navigate forward in the history of\r
+      * visited pages\r
+      */\r
+    virtual bool CanGoForward() = 0;\r
+\r
+    /** Navigate back in the history of visited pages.\r
+      * Only valid if CanGoBack() returned true.\r
+      */\r
+    virtual void GoBack() = 0;\r
+\r
+    /** Navigate forwardin the history of visited pages.\r
+      * Only valid if CanGoForward() returned true.\r
+      */\r
+    virtual void GoForward() = 0;\r
+\r
+    /**\r
+     * Load a HTMl document (web page) from a URL\r
+     * @param url the URL where the HTML document to display can be found\r
+     * @note web engines generally report errors asynchronously, so if you wish\r
+     *       to know whether loading the URL was successful, register to receive\r
+     *       navigation error events\r
+     */\r
+    virtual void LoadUrl(const wxString& url) = 0;\r
+\r
+    /**\r
+     * Stop the current page loading process, if any.\r
+     * May trigger an error event of type wxWEB_NAV_ERR_USER_CANCELLED.\r
+     * TODO: make wxWEB_NAV_ERR_USER_CANCELLED errors uniform across ports.\r
+     */\r
+    virtual void Stop() = 0;\r
+\r
+    /**\r
+     * Reload the currently displayed URL.\r
+     * @param flags A bit array that may optionnally contain reload options\r
+     */\r
+    virtual void Reload(wxWebViewReloadFlags flags=0) = 0;\r
+\r
+\r
+    /**\r
+     * Get the URL of the currently displayed document\r
+     */\r
+    virtual wxString GetCurrentURL() = 0;\r
+\r
+    /**\r
+     * Get the title of the current web page, or its URL/path if title is not\r
+     * available\r
+     */\r
+    virtual wxString GetCurrentTitle() = 0;\r
+\r
+    // TODO: handle choosing a frame when calling GetPageSource()?\r
+    /**\r
+     * Get the HTML source code of the currently displayed document\r
+     * @return the HTML source code, or an empty string if no page is currently\r
+     *         shown\r
+     */\r
+    virtual wxString GetPageSource() = 0;\r
+\r
+   /**\r
+     * Get the zoom factor of the page\r
+     * @return How much the HTML document is zoomed (scaleed)\r
+     */\r
+    virtual wxWebViewZoom GetZoom() = 0;\r
+\r
+    /**\r
+     * Set the zoom factor of the page\r
+     * @param zoom How much to zoom (scale) the HTML document\r
+     */\r
+    virtual void SetZoom(wxWebViewZoom zoom) = 0;\r
+\r
+    /**\r
+     * Set how to interpret the zoom factor\r
+     * @param zoomType how the zoom factor should be interpreted by the\r
+     *                 HTML engine\r
+     * @note invoke    canSetZoomType() first, some HTML renderers may not\r
+     *                 support all zoom types\r
+     */\r
+    virtual void SetZoomType(wxWebViewZoomType zoomType) = 0;\r
+\r
+    /**\r
+     * Get how the zoom factor is currently interpreted\r
+     * @return how the zoom factor is currently interpreted by the HTML engine\r
+     */\r
+    virtual wxWebViewZoomType GetZoomType() const = 0;\r
+\r
+    /**\r
+     * Retrieve whether the current HTML engine supports a type of zoom\r
+     * @param type the type of zoom to test\r
+     * @return whether this type of zoom is supported by this HTML engine\r
+     *         (and thus can be set through setZoomType())\r
+     */\r
+    virtual bool CanSetZoomType(wxWebViewZoomType type) const = 0;\r
+\r
+    // TODO: allow 'SetPage' to find files (e.g. images) from a virtual file\r
+    // system if possible\r
+    /**\r
+     * Set the displayed page source to the contents of the given string\r
+     * @param html    the string that contains the HTML data to display\r
+     * @param baseUrl URL assigned to the HTML data, to be used to resolve\r
+     *                relative paths, for instance\r
+     */\r
+    virtual void SetPage(const wxString& html, const wxString& baseUrl) = 0;\r
+\r
+    /**\r
+     * Set the displayed page source to the contents of the given stream\r
+     * @param html    the stream to read HTML data from\r
+     * @param baseUrl URL assigned to the HTML data, to be used to resolve\r
+     *                relative paths, for instance\r
+     */\r
+    virtual void SetPage(wxInputStream& html, wxString baseUrl)\r
+    {\r
+        wxStringOutputStream stream;\r
+        stream.Write(html);\r
+        SetPage(stream.GetString(), baseUrl);\r
+    }\r
+\r
+    // TODO:\r
+    //     wxString GetSelection();                         // maybe?\r
+    //     void SetSelection(...);                          // maybe?\r
+\r
+    //     void MakeEditable(bool enable = true);           // maybe?\r
+    //     bool IsEditable();                               // maybe?\r
+\r
+    //     void EnableJavascript(bool enabled);             // maybe?\r
+    //     wxString RunScript(const wxString& javascript);  // maybe?\r
+\r
+    //     void SetScrollPos(int pos);                      // maybe?\r
+    //     int GetScrollPos();                              // maybe?\r
+\r
+    //     wxString GetStatusText();                        // maybe?\r
+    //     void SetStatusText(wxString text);               // maybe?\r
+    //     * status text changed event?\r
+    //     * title changed event?\r
+\r
+    //    virtual bool IsOfflineMode() = 0;                 // maybe?\r
+    //     virtual void SetOfflineMode(bool offline) = 0;   // maybe?\r
+\r
+    // TODO: offer API to control the opening of new frames\r
+    //       (through <a target="..."> as well as through javascript), OR\r
+    //       provide a behavior consistent across ports.\r
+    // - OSX : I receive an event for new frames opened with HTML target, and\r
+    //           currently block them all.\r
+    // - IE  : The DISPID_NEWWINDOW2 event looks like it should work, but I\r
+    //           receive way too many of them. A new IE instance opens.\r
+    // - GTK : All frame open requests are blocked. A slot exists that I could\r
+    //           connect to to be notified if ever needed\r
+\r
+    /**\r
+     * Opens a print dialog so that the user may print the currently\r
+     * displayed page.\r
+     */\r
+    virtual void Print() = 0;\r
+\r
+    /**\r
+     * Returns whether the web control is currently busy (e.g. loading a page)\r
+     */\r
+    virtual bool IsBusy() = 0;\r
+};\r
+\r
+//class WXDLLIMPEXP_FWD_HTML wxWebNavigationEvent;\r
+\r
+// FIXME: get those WXDLLIMPEXP_HTML & DECLARE_DYNAMIC_CLASS right...\r
+//wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_HTML, wxEVT_COMMAND_WEB_VIEW_NAVIGATE,\r
+//                         wxWebNavigationEvent );\r
+\r
+\r
+// FIXME: get those WXDLLIMPEXP_HTML & DECLARE_DYNAMIC_CLASS right...\r
+class wxWebNavigationEvent : public wxCommandEvent\r
+{\r
+public:\r
+    wxWebNavigationEvent() {}\r
+    wxWebNavigationEvent(wxEventType type, int id, const wxString href,\r
+                         const wxString target, bool canVeto)\r
+        : wxCommandEvent(type, id)\r
+    {\r
+        m_href = href;\r
+        m_target = target;\r
+        m_vetoed = false;\r
+        m_canVeto = canVeto;\r
+    }\r
+\r
+    /**\r
+     *  Get the URL being visited\r
+     */\r
+    const wxString& GetHref() const { return m_href; }\r
+\r
+    /**\r
+     * Get the target (frame or window) in which the URL that caused this event\r
+     * is viewed, or an empty string if not available.\r
+     */\r
+    const wxString& GetTarget() const { return m_target; }\r
+\r
+    // default copy ctor, assignment operator and dtor are ok\r
+    virtual wxEvent* Clone() const { return new wxWebNavigationEvent(*this); }\r
+\r
+    /** Get whether this event may be vetoed (stopped/prevented). Only\r
+      *  meaningful for events fired before navigation takes place.\r
+      */\r
+    bool CanVeto() const { return m_canVeto; }\r
+\r
+    /** Whether this event was vetoed (stopped/prevented). Only meaningful for\r
+     *  events fired before navigation takes place.\r
+     */\r
+    bool IsVetoed() const { return m_vetoed; }\r
+\r
+    /** Veto (prevent/stop) this event. Only meaningful for events fired\r
+     *  before navigation takes place. Only valid if CanVeto() returned true.\r
+     */\r
+    void Veto() { wxASSERT(m_canVeto); m_vetoed = true; }\r
+\r
+private:\r
+    wxString m_href;\r
+    wxString m_target;\r
+    bool m_canVeto;\r
+    bool m_vetoed;\r
+\r
+    wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxWebNavigationEvent);\r
+};\r
+\r
+wxDECLARE_EVENT( wxEVT_COMMAND_WEB_VIEW_NAVIGATING, wxWebNavigationEvent );\r
+wxDECLARE_EVENT( wxEVT_COMMAND_WEB_VIEW_NAVIGATED, wxWebNavigationEvent );\r
+wxDECLARE_EVENT( wxEVT_COMMAND_WEB_VIEW_LOADED, wxWebNavigationEvent );\r
+wxDECLARE_EVENT( wxEVT_COMMAND_WEB_VIEW_ERROR, wxWebNavigationEvent );\r
+\r
+typedef void (wxEvtHandler::*wxWebNavigationEventFunction)\r
+             (wxWebNavigationEvent&);\r
+\r
+#define wxWebNavigationEventHandler(func) \\r
+    wxEVENT_HANDLER_CAST(wxWebNavigationEventFunction, func)\r
+\r
+#define EVT_WEB_VIEW_NAVIGATING(id, fn) \\r
+    wx__DECLARE_EVT1(wxEVT_COMMAND_WEB_VIEW_NAVIGATING, id,\r
+                     wxHtmlNavigatingEventHandler(fn))\r
+\r
+#define EVT_WEB_VIEW_NAVIGATED(id, fn) \\r
+    wx__DECLARE_EVT1(wxEVT_COMMAND_WEB_VIEW_NAVIGATED, id,\r
+                     wxHtmlNavigatingEventHandler(fn))\r
+\r
+#define EVT_WEB_VIEW_LOADED(id, fn) \\r
+    wx__DECLARE_EVT1(wxEVT_COMMAND_WEB_VIEW_LOADED, id,\r
+                     wxHtmlNavigatingEventHandler(fn))\r
+\r
+#define EVT_WEB_VIEW_ERRROR(id, fn) \\r
+    wx__DECLARE_EVT1(wxEVT_COMMAND_WEB_VIEW_ERROR, id,\r
+                     wxHtmlNavigatingEventHandler(fn))\r
+\r
+#endif\r
index 5073244c206199e7055ea096ee415b5c6e0ded59..88e97bdef82caa8db48cf193cc297498ecf7ed8e 100644 (file)
@@ -87,6 +87,7 @@
     <subproject id="uiaction" template="sub"/>
     <subproject id="validate" template="sub"/>
     <subproject id="vscroll" template="sub"/>
+    <subproject id="web" template="sub"/>
     <subproject id="widgets" template="sub"/>
     <subproject id="wizard" template="sub"/>
     <subproject id="wrapsizer" template="sub"/>
diff --git a/samples/web/forward.xpm b/samples/web/forward.xpm
new file mode 100644 (file)
index 0000000..079de7b
--- /dev/null
@@ -0,0 +1,260 @@
+/* XPM */\r
+static const char * forward_xpm[] = {\r
+"32 32 225 2",\r
+"      c None",\r
+".     c #3A7304",\r
+"+     c #5B8B2C",\r
+"@     c #3C7404",\r
+"#     c #CBE0B7",\r
+"$     c #77A24E",\r
+"%     c #3B7504",\r
+"&     c #CDE2B8",\r
+"*     c #C7DEB0",\r
+"=     c #8EB469",\r
+"-     c #3C7605",\r
+";     c #C7DFB1",\r
+">     c #9EC776",\r
+",     c #BBD8A0",\r
+"'     c #9FC280",\r
+")     c #42790D",\r
+"!     c #C5DDAD",\r
+"~     c #96C36A",\r
+"{     c #92C065",\r
+"]     c #AFD18E",\r
+"^     c #AECD91",\r
+"/     c #4D821B",\r
+"(     c #3A7404",\r
+"_     c #C2DCA9",\r
+":     c #92C064",\r
+"<     c #8CBD5D",\r
+"[     c #8BBC5B",\r
+"}     c #A0C979",\r
+"|     c #B5D299",\r
+"1     c #5D8D2E",\r
+"2     c #3B7503",\r
+"3     c #B8D59B",\r
+"4     c #BDD8A2",\r
+"5     c #BED9A3",\r
+"6     c #BFD9A4",\r
+"7     c #BFDAA5",\r
+"8     c #C0DAA6",\r
+"9     c #C0DBA6",\r
+"0     c #C2DCAA",\r
+"a     c #8DBD5E",\r
+"b     c #88BB57",\r
+"c     c #86B954",\r
+"d     c #85B952",\r
+"e     c #92C066",\r
+"f     c #B5D498",\r
+"g     c #729E46",\r
+"h     c #B8D69A",\r
+"i     c #7DB447",\r
+"j     c #7FB54A",\r
+"k     c #81B64D",\r
+"l     c #83B750",\r
+"m     c #84B851",\r
+"n     c #86B953",\r
+"o     c #86BA53",\r
+"p     c #86BA52",\r
+"q     c #84B850",\r
+"r     c #82B74F",\r
+"s     c #80B64C",\r
+"t     c #7EB549",\r
+"u     c #85B853",\r
+"v     c #B0D18F",\r
+"w     c #85AF5D",\r
+"x     c #3C7505",\r
+"y     c #B5D597",\r
+"z     c #78B141",\r
+"A     c #7AB344",\r
+"B     c #7FB54B",\r
+"C     c #81B74C",\r
+"D     c #82B94D",\r
+"E     c #83BA4D",\r
+"F     c #84BA4D",\r
+"G     c #83BA4C",\r
+"H     c #81B94A",\r
+"I     c #7FB848",\r
+"J     c #7DB646",\r
+"K     c #7AB343",\r
+"L     c #78B140",\r
+"M     c #7AB242",\r
+"N     c #A3CB7E",\r
+"O     c #97BD70",\r
+"P     c #427A0E",\r
+"Q     c #B4D495",\r
+"R     c #74AF3B",\r
+"S     c #76B03E",\r
+"T     c #79B342",\r
+"U     c #7CB644",\r
+"V     c #7EB745",\r
+"W     c #7FB946",\r
+"X     c #80BB48",\r
+"Y     c #80BB47",\r
+"Z     c #7FBA45",\r
+"`     c #7CB841",\r
+" .    c #71B132",\r
+"..    c #68AB27",\r
+"+.    c #62A61F",\r
+"@.    c #61A41F",\r
+"#.    c #65A625",\r
+"$.    c #91C064",\r
+"%.    c #A1C67D",\r
+"&.    c #4C821A",\r
+"*.    c #B2D292",\r
+"=.    c #70AD35",\r
+"-.    c #71AD37",\r
+";.    c #73AF39",\r
+">.    c #77B23C",\r
+",.    c #79B63E",\r
+"'.    c #7CB940",\r
+").    c #7CBA40",\r
+"!.    c #7EBC41",\r
+"~.    c #7BBB3D",\r
+"{.    c #70B52C",\r
+"].    c #62AD18",\r
+"^.    c #58A80B",\r
+"/.    c #56A508",\r
+"(.    c #54A207",\r
+"_.    c #529F06",\r
+":.    c #509C05",\r
+"<.    c #4E9905",\r
+"[.    c #A8CB85",\r
+"}.    c #598C29",\r
+"|.    c #3B7404",\r
+"1.    c #ADD08B",\r
+"2.    c #66A727",\r
+"3.    c #69A92B",\r
+"4.    c #6EAE30",\r
+"5.    c #6FB02F",\r
+"6.    c #6EB22C",\r
+"7.    c #6DB328",\r
+"8.    c #69B221",\r
+"9.    c #62B015",\r
+"0.    c #5CAD0B",\r
+"a.    c #5BAE0B",\r
+"b.    c #5BAD0A",\r
+"c.    c #5AAC0A",\r
+"d.    c #59A909",\r
+"e.    c #57A608",\r
+"f.    c #54A308",\r
+"g.    c #4F9B05",\r
+"h.    c #A2C97E",\r
+"i.    c #578B25",\r
+"j.    c #A3CA7E",\r
+"k.    c #52A007",\r
+"l.    c #55A408",\r
+"m.    c #58A809",\r
+"n.    c #5CAF0B",\r
+"o.    c #5EB10B",\r
+"p.    c #5EB20C",\r
+"q.    c #5FB20C",\r
+"r.    c #5DB00B",\r
+"s.    c #59AA0A",\r
+"t.    c #57A709",\r
+"u.    c #529E07",\r
+"v.    c #94BE6B",\r
+"w.    c #4B8116",\r
+"x.    c #519E06",\r
+"y.    c #54A307",\r
+"z.    c #5DAF0B",\r
+"A.    c #5FB30C",\r
+"B.    c #61B50D",\r
+"C.    c #62B70D",\r
+"D.    c #61B60D",\r
+"E.    c #60B40C",\r
+"F.    c #5EB10C",\r
+"G.    c #5CAE0B",\r
+"H.    c #59AA09",\r
+"I.    c #5BA810",\r
+"J.    c #8FC25E",\r
+"K.    c #8AB65C",\r
+"L.    c #41790C",\r
+"M.    c #53A007",\r
+"N.    c #61B70D",\r
+"O.    c #63BA0E",\r
+"P.    c #65BC0F",\r
+"Q.    c #64BB0E",\r
+"R.    c #63B90E",\r
+"S.    c #60B50D",\r
+"T.    c #67B31B",\r
+"U.    c #9CCB6D",\r
+"V.    c #7AAA4A",\r
+"W.    c #3B7405",\r
+"X.    c #A4CC7E",\r
+"Y.    c #A6CF7F",\r
+"Z.    c #A8D180",\r
+"`.    c #AAD480",\r
+" +    c #ACD781",\r
+".+    c #ADD982",\r
+"++    c #AFDB82",\r
+"@+    c #B0DD83",\r
+"#+    c #B1DE83",\r
+"$+    c #6CC317",\r
+"%+    c #67BF10",\r
+"&+    c #75BE2B",\r
+"*+    c #A3D075",\r
+"=+    c #689C37",\r
+"-+    c #3A7204",\r
+";+    c #AEDE7D",\r
+">+    c #6FC818",\r
+",+    c #6AC411",\r
+"'+    c #68C010",\r
+")+    c #84C93E",\r
+"!+    c #A4D275",\r
+"~+    c #578B23",\r
+"{+    c #376E03",\r
+"]+    c #AEDF7D",\r
+"^+    c #72CB19",\r
+"/+    c #6DC714",\r
+"(+    c #94D455",\r
+"_+    c #9DCD6E",\r
+":+    c #488016",\r
+"<+    c #336204",\r
+"[+    c #AEE07E",\r
+"}+    c #7AD223",\r
+"|+    c #A2DD67",\r
+"1+    c #91C35E",\r
+"2+    c #41790B",\r
+"3+    c #B2E184",\r
+"4+    c #AFE37C",\r
+"5+    c #7EB24A",\r
+"6+    c #3D7506",\r
+"7+    c #3C7504",\r
+"8+    c #AFDC84",\r
+"9+    c #6A9D39",\r
+"0+    c #3A7305",\r
+"a+    c #50851D",\r
+"b+    c #386F03",\r
+"                                                                ",\r
+"                                                                ",\r
+"                                                                ",\r
+"                                                                ",\r
+"                            .                                   ",\r
+"                            . + @                               ",\r
+"                            . # $ %                             ",\r
+"                            . & * = -                           ",\r
+"                            . ; > , ' )                         ",\r
+"                            . ! ~ { ] ^ /                       ",\r
+"          . ( ( ( ( ( ( ( ( . _ : < [ } | 1 2                   ",\r
+"          . 3 , 4 5 6 7 8 8 9 0 a b c d e f g %                 ",\r
+"          . h i j k l m d n o o p q r s t u v w x               ",\r
+"          . y z A i t B C D E F G H I J K L M N O P             ",\r
+"          . Q R S L T U V W X Y Y Z `  ...+.@.#.$.%.&.          ",\r
+"          . *.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.<.R [.}.|.      ",\r
+"          . 1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f._.g.<.=.h.i.|.      ",\r
+"          . j.<.g.k.l.m.c.n.o.p.q.p.r.b.s.t.(.u.t v.w.@         ",\r
+"          . j.<.x.y.t.c.z.A.B.C.C.D.E.F.G.H.I.J.K.L.            ",\r
+"          . j.g.M./.s.n.A.N.O.P.P.Q.R.S.F.T.U.V.W.              ",\r
+"          . j.X.Y.Z.`. +.+++@+#+$+%+P.R.&+*+=+-+                ",\r
+"          . . . . . . . . . . ;+>+,+'+)+!+~+{+                  ",\r
+"                            @ ]+^+/+(+_+:+<+                    ",\r
+"                            @ [+}+|+1+2+                        ",\r
+"                            @ 3+4+5+6+                          ",\r
+"                            7+8+9+0+                            ",\r
+"                            . a+b+                              ",\r
+"                            .                                   ",\r
+"                                                                ",\r
+"                                                                ",\r
+"                                                                ",\r
+"                                                                "};\r
diff --git a/samples/web/refresh.xpm b/samples/web/refresh.xpm
new file mode 100644 (file)
index 0000000..e68629f
--- /dev/null
@@ -0,0 +1,322 @@
+/* XPM */\r
+static const char * refresh_xpm[] = {\r
+"32 32 287 2",\r
+"      c None",\r
+".     c #396AA9",\r
+"+     c #3D6CA9",\r
+"@     c #3968A8",\r
+"#     c #3565A5",\r
+"$     c #3767A6",\r
+"%     c #3867A7",\r
+"&     c #3A6AA8",\r
+"*     c #3567A6",\r
+"=     c #3C6BA8",\r
+"-     c #4B77B0",\r
+";     c #87A6CE",\r
+">     c #A5BFDE",\r
+",     c #B3CAE4",\r
+"'     c #BAD0E8",\r
+")     c #B6CEE6",\r
+"!     c #AFC6E1",\r
+"~     c #9CB8D9",\r
+"{     c #82A3CB",\r
+"]     c #537EB5",\r
+"^     c #3767A7",\r
+"/     c #3869A6",\r
+"(     c #3364A4",\r
+"_     c #3E6CA9",\r
+":     c #94B1D4",\r
+"<     c #BCD2E8",\r
+"[     c #BBD1E8",\r
+"}     c #B9D0E7",\r
+"|     c #B8CEE6",\r
+"1     c #B5CDE5",\r
+"2     c #B3CBE5",\r
+"3     c #B2CBE5",\r
+"4     c #B4CCE5",\r
+"5     c #AAC4E1",\r
+"6     c #799EC9",\r
+"7     c #3B69A9",\r
+"8     c #3768A6",\r
+"9     c #3F6EAA",\r
+"0     c #AEC5E1",\r
+"a     c #BED3E9",\r
+"b     c #B8CEE7",\r
+"c     c #B6CDE6",\r
+"d     c #B1CAE4",\r
+"e     c #AFC8E3",\r
+"f     c #ADC7E3",\r
+"g     c #ABC6E3",\r
+"h     c #769AC6",\r
+"i     c #3867A6",\r
+"j     c #3868A7",\r
+"k     c #87AAD2",\r
+"l     c #A6BFDD",\r
+"m     c #C0D4E9",\r
+"n     c #BDD3E8",\r
+"o     c #B4CCE4",\r
+"p     c #A2BCDB",\r
+"q     c #9AB6D7",\r
+"r     c #9EB9DA",\r
+"s     c #ABC4E0",\r
+"t     c #BAD0E7",\r
+"u     c #B9CFE7",\r
+"v     c #AEC8E3",\r
+"w     c #AAC5E2",\r
+"x     c #A8C4E1",\r
+"y     c #A6C2E0",\r
+"z     c #A9C4E1",\r
+"A     c #B3CBE6",\r
+"B     c #9DBADB",\r
+"C     c #4574AD",\r
+"D     c #3465A4",\r
+"E     c #89AAD1",\r
+"F     c #A5C2E0",\r
+"G     c #6E94C1",\r
+"H     c #BFD4EA",\r
+"I     c #93B1D4",\r
+"J     c #4E79B2",\r
+"K     c #3969A8",\r
+"L     c #3969A7",\r
+"M     c #3868A6",\r
+"N     c #3B6AA7",\r
+"O     c #5C84B8",\r
+"P     c #8CACD2",\r
+"Q     c #B3CCE5",\r
+"R     c #9EBDDE",\r
+"S     c #8FB3D8",\r
+"T     c #81A9D3",\r
+"U     c #8CB0D7",\r
+"V     c #9FBDDD",\r
+"W     c #96B5D8",\r
+"X     c #9CBCDD",\r
+"Y     c #A2C0DF",\r
+"Z     c #A5BFDC",\r
+"`     c #5D86B8",\r
+" .    c #3B6AA8",\r
+"..    c #3768A7",\r
+"+.    c #3A6AA9",\r
+"@.    c #3464A5",\r
+"#.    c #3969A5",\r
+"$.    c #6B90C0",\r
+"%.    c #98B7D9",\r
+"&.    c #98B9DC",\r
+"*.    c #84ABD5",\r
+"=.    c #7EA7D3",\r
+"-.    c #7BA5D2",\r
+";.    c #80A9D4",\r
+">.    c #97B8DB",\r
+",.    c #79A4D1",\r
+"'.    c #A3C0DF",\r
+").    c #3C6AA9",\r
+"!.    c #6B91C0",\r
+"~.    c #4A77B3",\r
+"{.    c #4E7BB5",\r
+"].    c #3667A5",\r
+"^.    c #7197C5",\r
+"/.    c #A0BEDE",\r
+"(.    c #8BAFD7",\r
+"_.    c #7AA5D2",\r
+":.    c #78A3D1",\r
+"<.    c #75A1D0",\r
+"[.    c #3364A5",\r
+"}.    c #5884BB",\r
+"|.    c #5D88BE",\r
+"1.    c #517EB8",\r
+"2.    c #3666A6",\r
+"3.    c #406EAA",\r
+"4.    c #9EBBDB",\r
+"5.    c #77A2D0",\r
+"6.    c #74A0CF",\r
+"7.    c #ABC6E2",\r
+"8.    c #4172AF",\r
+"9.    c #648DC3",\r
+"0.    c #678FC5",\r
+"a.    c #4D7AB4",\r
+"b.    c #3565A3",\r
+"c.    c #4472AC",\r
+"d.    c #A2BFDF",\r
+"e.    c #87ADD6",\r
+"f.    c #76A1D0",\r
+"g.    c #739FCF",\r
+"h.    c #76A2D0",\r
+"i.    c #5783BB",\r
+"j.    c #4571AC",\r
+"k.    c #9EBCDC",\r
+"l.    c #8BB0D7",\r
+"m.    c #74A1D0",\r
+"n.    c #729FCF",\r
+"o.    c #AFC9E4",\r
+"p.    c #3F6EAB",\r
+"q.    c #A3BEDD",\r
+"r.    c #A9C4E2",\r
+"s.    c #A9C5E1",\r
+"t.    c #AFC8E4",\r
+"u.    c #B2CAE4",\r
+"v.    c #3565A4",\r
+"w.    c #3666A5",\r
+"x.    c #CADBED",\r
+"y.    c #C9DAED",\r
+"z.    c #C7D9EC",\r
+"A.    c #C2D6EA",\r
+"B.    c #C0D4EA",\r
+"C.    c #C1D5EA",\r
+"D.    c #A0BCDB",\r
+"E.    c #3769A6",\r
+"F.    c #C8DAEC",\r
+"G.    c #9BBBDD",\r
+"H.    c #3C6CA8",\r
+"I.    c #B3CBE4",\r
+"J.    c #416EAA",\r
+"K.    c #C8D9EC",\r
+"L.    c #99BADC",\r
+"M.    c #BDD2E8",\r
+"N.    c #A9C2DF",\r
+"O.    c #416EA9",\r
+"P.    c #82A9D8",\r
+"Q.    c #3869A7",\r
+"R.    c #C6D8EC",\r
+"S.    c #98B9DB",\r
+"T.    c #A7C4E1",\r
+"U.    c #B2CBE4",\r
+"V.    c #7399C5",\r
+"W.    c #3668A6",\r
+"X.    c #87ADD9",\r
+"Y.    c #C4D6E9",\r
+"Z.    c #B1CAE2",\r
+"`.    c #3F70AD",\r
+" +    c #4577B4",\r
+".+    c #3667A6",\r
+"++    c #C4D7EB",\r
+"@+    c #9DBCDE",\r
+"#+    c #B5CDE6",\r
+"$+    c #96B8DB",\r
+"%+    c #95B7DB",\r
+"&+    c #95B6DA",\r
+"*+    c #85AAD2",\r
+"=+    c #5682B9",\r
+"-+    c #4982C6",\r
+";+    c #B3CDE5",\r
+">+    c #769CCC",\r
+",+    c #3A6CAB",\r
+"'+    c #4476B3",\r
+")+    c #4D81BC",\r
+"!+    c #A9C2DE",\r
+"~+    c #B7CEE7",\r
+"{+    c #9FBEDE",\r
+"]+    c #6D9BCE",\r
+"^+    c #6A99CC",\r
+"/+    c #719ECF",\r
+"(+    c #82A9D4",\r
+"_+    c #80A7D3",\r
+":+    c #618DC1",\r
+"<+    c #4573AF",\r
+"[+    c #3466A5",\r
+"}+    c #3769A9",\r
+"|+    c #386BAD",\r
+"1+    c #376CAE",\r
+"2+    c #3667A9",\r
+"3+    c #4072B0",\r
+"4+    c #5183BE",\r
+"5+    c #588DC7",\r
+"6+    c #3B6EAD",\r
+"7+    c #94B3D7",\r
+"8+    c #5882B7",\r
+"9+    c #A1BEDC",\r
+"0+    c #88AED7",\r
+"a+    c #6E9CCD",\r
+"b+    c #6999CC",\r
+"c+    c #6797CB",\r
+"d+    c #6696CB",\r
+"e+    c #729ECF",\r
+"f+    c #76A0D0",\r
+"g+    c #6995C8",\r
+"h+    c #5E8DC3",\r
+"i+    c #5A8AC2",\r
+"j+    c #5C8CC3",\r
+"k+    c #5E90C9",\r
+"l+    c #5B8FC7",\r
+"m+    c #578CC7",\r
+"n+    c #4A7EBC",\r
+"o+    c #3566A5",\r
+"p+    c #9FBCDA",\r
+"q+    c #3768A5",\r
+"r+    c #6990C1",\r
+"s+    c #7CA5D2",\r
+"t+    c #6A9ACC",\r
+"u+    c #6596CB",\r
+"v+    c #6395CA",\r
+"w+    c #6294CA",\r
+"x+    c #6093C9",\r
+"y+    c #6093CA",\r
+"z+    c #5D91C8",\r
+"A+    c #5B8FC8",\r
+"B+    c #588DC6",\r
+"C+    c #588CC7",\r
+"D+    c #4D82BE",\r
+"E+    c #315F98",\r
+"F+    c #3A69A6",\r
+"G+    c #648EC0",\r
+"H+    c #7EA5D2",\r
+"I+    c #7AA4D2",\r
+"J+    c #6F9DCE",\r
+"K+    c #6193CA",\r
+"L+    c #5F91C8",\r
+"M+    c #5D90C8",\r
+"N+    c #5C90C7",\r
+"O+    c #5C90C8",\r
+"P+    c #588EC6",\r
+"Q+    c #477AB7",\r
+"R+    c #3465A5",\r
+"S+    c #2E578E",\r
+"T+    c #3666A2",\r
+"U+    c #4674AD",\r
+"V+    c #5A88BE",\r
+"W+    c #6592C6",\r
+"X+    c #6B98CB",\r
+"Y+    c #6B99CC",\r
+"Z+    c #6797CC",\r
+"`+    c #6090C7",\r
+" @    c #5588C1",\r
+".@    c #4679B6",\r
+"+@    c #32609C",\r
+"@@    c #1B3558",\r
+"#@    c #2B5185",\r
+"$@    c #325E9A",\r
+"%@    c #3464A1",\r
+"&@    c #3463A3",\r
+"*@    c #3464A2",\r
+"=@    c #32609B",\r
+"-@    c #2A4F83",\r
+"                                                                ",\r
+"                    . + @ # $ % & *                             ",\r
+"                = - ; > , ' ) ! ~ { ] ^ /               (       ",\r
+"              _ : < [ } | 1 2 2 3 4 | 5 6 7 8         % (       ",\r
+"            9 0 a < ' } b c 3 d e f g f 4 d h i     j k (       ",\r
+"          j l m n o p q r s t u 4 v w x y z A B C D E F (       ",\r
+"          G H I J K & L L M N O P Q c g R S T U V W X Y (       ",\r
+"        = Z `  ...+.@.          L #.$.%.&.*.=.-.;.>.,.'.(       ",\r
+"        ).!.K ~.{.].                  @ ^./.(._.:.<.<.z [.      ",\r
+"         .N }.|.1.2.                    8 3.4.&.5.6.<.7.#       ",\r
+"        ( 8.9.0.a.b.                      c.d.e.f.g.h.f #       ",\r
+"        ( i.                            j.k.l.5.m.n.h.o.#       ",\r
+"        (                             p.q.w r.z s.w t.u.v.      ",\r
+"                                    ( ( ( ( ( ( ( ( ( ( (       ",\r
+"        ( w.w.w.D ( ( ( ( ( (                                   ",\r
+"        ( x.x.y.z.A.B.C.D.E.                            (       ",\r
+"        ( F.G.&.&.&.v s H.                              (       ",\r
+"        ( F.G.&.&.w I.J.                              . (       ",\r
+"        ( K.G.&.L.M.N.O.^                     P.      Q.D       ",\r
+"        ( R.G.&.&.S.T.U.V.W.                  X.Y.Z.`. +.+      ",\r
+"        ( ++@+#+G.$+%+%+&+*+=+]..+          -+;+>+,+'+)+*       ",\r
+"        ( A.} !+~+{+*.]+^+/+(+_+:+<+[+}+|+1+|+2+3+4+5+6+        ",\r
+"        ( C.7+( 8+9+0+a+b+c+d+b+e+5.f+g+h+i+j+k+l+m+n+o+        ",\r
+"        ( p+M     q+r+l.s+t+u+v+w+x+x+x+y+z+A+B+C+D+o+          ",\r
+"        D  .        E+F+G+H+I+J+c+K+L+M+N+O+l+P+Q+R+            ",\r
+"        (               S+T+U+V+W+X+Y+Z+`+ @.@$ +@              ",\r
+"                            @@#@$@%@&@( *@=@-@                  ",\r
+"                                                                ",\r
+"                                                                ",\r
+"                                                                ",\r
+"                                                                ",\r
+"                                                                "};\r
diff --git a/samples/web/stop.xpm b/samples/web/stop.xpm
new file mode 100644 (file)
index 0000000..678a4d6
--- /dev/null
@@ -0,0 +1,401 @@
+/* XPM */\r
+static const char * stop_xpm[] = {\r
+"32 32 366 2",\r
+"      c None",\r
+".     c #860000",\r
+"+     c #890000",\r
+"@     c #991414",\r
+"#     c #F38989",\r
+"$     c #F79393",\r
+"%     c #F79292",\r
+"&     c #F79090",\r
+"*     c #F78F8F",\r
+"=     c #F68C8C",\r
+"-     c #F68A8A",\r
+";     c #F58787",\r
+">     c #A61F1F",\r
+",     c #8A0000",\r
+"'     c #991515",\r
+")     c #F18383",\r
+"!     c #E76565",\r
+"~     c #D94040",\r
+"{     c #D93F3F",\r
+"]     c #D83E3E",\r
+"^     c #D83D3D",\r
+"/     c #D83C3C",\r
+"(     c #D83B3B",\r
+"_     c #E15252",\r
+":     c #F17C7C",\r
+"<     c #A51C1C",\r
+"[     c #880000",\r
+"}     c #9B1616",\r
+"|     c #F18484",\r
+"1     c #E76666",\r
+"2     c #D94242",\r
+"3     c #D94141",\r
+"4     c #E05252",\r
+"5     c #F07878",\r
+"6     c #A41A1A",\r
+"7     c #F28585",\r
+"8     c #E66565",\r
+"9     c #D94343",\r
+"0     c #DA4444",\r
+"a     c #E15151",\r
+"b     c #EF7474",\r
+"c     c #A21818",\r
+"d     c #9D1818",\r
+"e     c #DA4545",\r
+"f     c #D83A3A",\r
+"g     c #E05050",\r
+"h     c #EE7070",\r
+"i     c #9F1616",\r
+"j     c #9E1818",\r
+"k     c #E56363",\r
+"l     c #DA4646",\r
+"m     c #DA4747",\r
+"n     c #D73A3A",\r
+"o     c #D63939",\r
+"p     c #DF4F4F",\r
+"q     c #EE6C6C",\r
+"r     c #9E1414",\r
+"s     c #A01919",\r
+"t     c #E56262",\r
+"u     c #E54B4B",\r
+"v     c #FA4F4F",\r
+"w     c #DD4848",\r
+"x     c #EB4444",\r
+"y     c #F64545",\r
+"z     c #D63A3A",\r
+"A     c #D53939",\r
+"B     c #D43838",\r
+"C     c #EC6868",\r
+"D     c #9D1212",\r
+"E     c #A01A1A",\r
+"F     c #E45F5F",\r
+"G     c #E54A4A",\r
+"H     c #F96161",\r
+"I     c #EFA9A9",\r
+"J     c #F75454",\r
+"K     c #DC4747",\r
+"L     c #EA4646",\r
+"M     c #F56B6B",\r
+"N     c #F08E8E",\r
+"O     c #F24747",\r
+"P     c #D43939",\r
+"Q     c #D33838",\r
+"R     c #D23737",\r
+"S     c #DD4C4C",\r
+"T     c #E96363",\r
+"U     c #9A0F0F",\r
+"V     c #F68E8E",\r
+"W     c #E45D5D",\r
+"X     c #E54848",\r
+"Y     c #F85F5F",\r
+"Z     c #E6DBDB",\r
+"`     c #E5E5E5",\r
+" .    c #EEB2B2",\r
+"..    c #F75252",\r
+"+.    c #DC4545",\r
+"@.    c #EB4848",\r
+"#.    c #F66C6C",\r
+"$.    c #E5E1E1",\r
+"%.    c #E4E4E4",\r
+"&.    c #EF9292",\r
+"*.    c #F24848",\r
+"=.    c #CF3535",\r
+"-.    c #DC4B4B",\r
+";.    c #ED6666",\r
+">.    c #FC4848",\r
+",.    c #EEAAAA",\r
+"'.    c #E6E6E6",\r
+").    c #E7E7E7",\r
+"!.    c #EFB3B3",\r
+"~.    c #DC4343",\r
+"{.    c #EB4B4B",\r
+"].    c #F67171",\r
+"^.    c #E8E4E4",\r
+"/.    c #E6D9D9",\r
+"(.    c #FF4848",\r
+"_.    c #DB3C3C",\r
+":.    c #D13838",\r
+"<.    c #D03636",\r
+"[.    c #CE3434",\r
+"}.    c #EF6B6B",\r
+"|.    c #F85353",\r
+"1.    c #EEB6B6",\r
+"2.    c #E8E8E8",\r
+"3.    c #E9E9E9",\r
+"4.    c #EAEAEA",\r
+"5.    c #F0B7B7",\r
+"6.    c #F75858",\r
+"7.    c #EC4E4E",\r
+"8.    c #F77777",\r
+"9.    c #EBE7E7",\r
+"0.    c #E9DDDD",\r
+"a.    c #F86565",\r
+"b.    c #DF4242",\r
+"c.    c #D03737",\r
+"d.    c #CF3636",\r
+"e.    c #CE3535",\r
+"f.    c #CD3333",\r
+"g.    c #EF6969",\r
+"h.    c #DB4343",\r
+"i.    c #F85A5A",\r
+"j.    c #F0BABA",\r
+"k.    c #EBEBEB",\r
+"l.    c #ECECEC",\r
+"m.    c #F2BABA",\r
+"n.    c #F97878",\r
+"o.    c #ECE9E9",\r
+"p.    c #ECE0E0",\r
+"q.    c #F96C6C",\r
+"r.    c #DF4646",\r
+"s.    c #D13939",\r
+"t.    c #D03838",\r
+"u.    c #CF3737",\r
+"v.    c #CD3434",\r
+"w.    c #CC3333",\r
+"x.    c #EE6767",\r
+"y.    c #F79191",\r
+"z.    c #DB4141",\r
+"A.    c #F86161",\r
+"B.    c #F2BFBF",\r
+"C.    c #EDEDED",\r
+"D.    c #EEEEEE",\r
+"E.    c #EEE3E3",\r
+"F.    c #F97272",\r
+"G.    c #DF4949",\r
+"H.    c #CE3636",\r
+"I.    c #CD3535",\r
+"J.    c #CC3434",\r
+"K.    c #CB3232",\r
+"L.    c #EE6565",\r
+"M.    c #F76868",\r
+"N.    c #F4C0C0",\r
+"O.    c #EFEFEF",\r
+"P.    c #F0F0F0",\r
+"Q.    c #F0E7E7",\r
+"R.    c #FA7979",\r
+"S.    c #DF4A4A",\r
+"T.    c #CC3131",\r
+"U.    c #CA2D2D",\r
+"V.    c #C82929",\r
+"W.    c #C72828",\r
+"X.    c #ED5F5F",\r
+"Y.    c #D73939",\r
+"Z.    c #ED5A5A",\r
+"`.    c #FA8686",\r
+" +    c #F1F1F1",\r
+".+    c #F2F2F2",\r
+"++    c #F5CFCF",\r
+"@+    c #FD7171",\r
+"#+    c #D33939",\r
+"$+    c #CB2424",\r
+"%+    c #C71616",\r
+"&+    c #C40B0B",\r
+"*+    c #C00202",\r
+"=+    c #BF0000",\r
+"-+    c #BE0000",\r
+";+    c #BD0000",\r
+">+    c #BC0000",\r
+",+    c #E93D3D",\r
+"'+    c #D73838",\r
+")+    c #EA5B5B",\r
+"!+    c #F99191",\r
+"~+    c #F2EFEF",\r
+"{+    c #F3F3F3",\r
+"]+    c #F4F4F4",\r
+"^+    c #F45353",\r
+"/+    c #C60505",\r
+"(+    c #C10000",\r
+"_+    c #C00000",\r
+":+    c #BA0000",\r
+"<+    c #E93B3B",\r
+"[+    c #F68D8D",\r
+"}+    c #D73737",\r
+"|+    c #EA5E5E",\r
+"1+    c #F99595",\r
+"2+    c #F3F0F0",\r
+"3+    c #F5F5F5",\r
+"4+    c #F6EEEE",\r
+"5+    c #F7DDDD",\r
+"6+    c #F3BFBF",\r
+"7+    c #F45C5C",\r
+"8+    c #C40606",\r
+"9+    c #BB0000",\r
+"0+    c #B90000",\r
+"a+    c #E83939",\r
+"b+    c #F68B8B",\r
+"c+    c #D73535",\r
+"d+    c #D73636",\r
+"e+    c #F99A9A",\r
+"f+    c #F7EFEF",\r
+"g+    c #FA8181",\r
+"h+    c #FD6767",\r
+"i+    c #F8C7C7",\r
+"j+    c #F3C3C3",\r
+"k+    c #F36666",\r
+"l+    c #C20707",\r
+"m+    c #B80000",\r
+"n+    c #E73838",\r
+"o+    c #F68989",\r
+"p+    c #D63434",\r
+"q+    c #EB6363",\r
+"r+    c #F89D9D",\r
+"s+    c #F1EFEF",\r
+"t+    c #F7EEEE",\r
+"u+    c #F97F7F",\r
+"v+    c #D62424",\r
+"w+    c #C80707",\r
+"x+    c #F56C6C",\r
+"y+    c #F9CCCC",\r
+"z+    c #F2C6C6",\r
+"A+    c #F47272",\r
+"B+    c #BF0707",\r
+"C+    c #B70000",\r
+"D+    c #E73636",\r
+"E+    c #F48686",\r
+"F+    c #E14E4E",\r
+"G+    c #D63333",\r
+"H+    c #F78383",\r
+"I+    c #F5BCBC",\r
+"J+    c #F5ECEC",\r
+"K+    c #F98484",\r
+"L+    c #D62727",\r
+"M+    c #C40000",\r
+"N+    c #C30000",\r
+"O+    c #C60808",\r
+"P+    c #F57676",\r
+"Q+    c #F8CFCF",\r
+"R+    c #F0DFDF",\r
+"S+    c #FE8A8A",\r
+"T+    c #C41515",\r
+"U+    c #B80202",\r
+"V+    c #E63434",\r
+"W+    c #A82323",\r
+"X+    c #F07A7A",\r
+"Y+    c #E04C4C",\r
+"Z+    c #D63232",\r
+"`+    c #D53333",\r
+" @    c #D53535",\r
+".@    c #F27E7E",\r
+"+@    c #F5BBBB",\r
+"@@    c #F1E9E9",\r
+"#@    c #F98B8B",\r
+"$@    c #D62A2A",\r
+"%@    c #C20000",\r
+"&@    c #C40909",\r
+"*@    c #F48080",\r
+"=@    c #F6D2D2",\r
+"-@    c #F3E4E4",\r
+";@    c #C61B1B",\r
+">@    c #D92626",\r
+",@    c #CD2020",\r
+"'@    c #8B0000",\r
+")@    c #A72222",\r
+"!@    c #EF6E6E",\r
+"~@    c #DE3C3C",\r
+"{@    c #D11B1B",\r
+"]@    c #CE1313",\r
+"^@    c #CA0707",\r
+"/@    c #C90303",\r
+"(@    c #FF8F8F",\r
+"_@    c #D62D2D",\r
+":@    c #C10A0A",\r
+"<@    c #F58B8B",\r
+"[@    c #FD9898",\r
+"}@    c #C61C1C",\r
+"|@    c #B90303",\r
+"1@    c #DB2828",\r
+"2@    c #CA1F1F",\r
+"3@    c #890101",\r
+"4@    c #A01313",\r
+"5@    c #EC5555",\r
+"6@    c #D61F1F",\r
+"7@    c #C90000",\r
+"8@    c #C80000",\r
+"9@    c #C70000",\r
+"0@    c #C70303",\r
+"a@    c #CD1616",\r
+"b@    c #BF0909",\r
+"c@    c #C11010",\r
+"d@    c #B90404",\r
+"e@    c #DC2929",\r
+"f@    c #C71E1E",\r
+"g@    c #A01111",\r
+"h@    c #EA5252",\r
+"i@    c #D51E1E",\r
+"j@    c #C60000",\r
+"k@    c #C50000",\r
+"l@    c #BA0404",\r
+"m@    c #DC2A2A",\r
+"n@    c #C31C1C",\r
+"o@    c #9E1010",\r
+"p@    c #EA4E4E",\r
+"q@    c #D51D1D",\r
+"r@    c #BB0505",\r
+"s@    c #DE2B2B",\r
+"t@    c #BF1A1A",\r
+"u@    c #840000",\r
+"v@    c #9E0F0F",\r
+"w@    c #E94A4A",\r
+"x@    c #D31C1C",\r
+"y@    c #BC0606",\r
+"z@    c #DF2D2D",\r
+"A@    c #BA1818",\r
+"B@    c #870000",\r
+"C@    c #790000",\r
+"D@    c #9C0D0D",\r
+"E@    c #E84646",\r
+"F@    c #D01B1B",\r
+"G@    c #BC0707",\r
+"H@    c #E02E2E",\r
+"I@    c #B61717",\r
+"J@    c #810000",\r
+"K@    c #730000",\r
+"L@    c #9A0C0C",\r
+"M@    c #EC4949",\r
+"N@    c #EB4747",\r
+"O@    c #EB4545",\r
+"P@    c #E94343",\r
+"Q@    c #E94141",\r
+"R@    c #E93F3F",\r
+"S@    c #E73939",\r
+"T@    c #E73737",\r
+"U@    c #E63535",\r
+"V@    c #B31515",\r
+"W@    c #7D0000",\r
+"X@    c #720000",\r
+"Y@    c #7C0000",\r
+"                    . . . . . . . . . . . . +                   ",\r
+"                  @ # $ $ $ $ $ % & * = - ; > ,                 ",\r
+"                ' ) ! ~ ~ ~ ~ { { ] ^ / ( _ : < [               ",\r
+"              } | 1 2 2 2 2 3 3 ~ { ] ^ / ( 4 5 6 [             ",\r
+"            } 7 8 9 9 0 0 9 9 2 3 ~ { ] ^ / ( a b c             ",\r
+"          d 7 8 0 0 e e e e 0 9 2 3 ~ { ] / ( f g h i           ",\r
+"        j 7 k 0 e l m m m l e 0 9 2 3 { ] ^ / n o p q r         ",\r
+"      s 7 t 9 0 e m u v w m l e 9 2 3 ~ x y / z A B p C D       ",\r
+"    E 7 F 2 9 0 e G H I J K l e 9 2 3 L M N O z P Q R S T U     ",\r
+"  . V W ~ 3 2 0 X Y Z `  ...+.0 9 2 @.#.$.%.&.*.P Q R =.-.;..   ",\r
+"  . % ] { 3 2 9 >.,.` '.).!...~.2 {.].^.).'./.(._.:.<.=.[.}..   ",\r
+"  . % ] { ~ 3 2 ~.|.1.2.3.4.5.6.7.8.9.3.2.0.a.b.:.c.d.e.f.g..   ",\r
+"  . % ^ ] { ~ ~ 3 h.i.j.4.k.l.m.n.o.k.k.p.q.r.s.t.u.e.v.w.x..   ",\r
+"  . y./ ^ ] ] { ~ ~ z.A.B.C.D.D.D.D.D.E.F.G.s.t.u.H.I.J.K.L..   ",\r
+"  . y.( ( / ^ ] ] { { z.M.N.O.P.P.P.Q.R.S.s.t.u.H.T.U.V.W.X..   ",\r
+"  . & Y.f ( / / ^ ^ ^ ^ Z.`. +.+.+.+++@+#+$+%+&+*+=+-+;+>+,+.   ",\r
+"  . * '+Y.f f ( ( ( / )+!+~+{+{+]+]+{+N.^+/+(+_+=+-+;+>+:+<+.   ",\r
+"  . [+}+}+'+Y.Y.Y.f |+1+2+{+3+4+5+]+.+ +6+7+8+=+-+;+9+:+0+a+.   ",\r
+"  . b+c+d+}+}+'+'+|+e+~+{+3+f+g+h+i+3+{+ +j+k+l+;+9+:+0+m+n+.   ",\r
+"  . o+p+c+c+d+d+q+r+s+.+3+t+u+v+w+x+y+3+{+P.z+A+B+:+0+m+C+D+.   ",\r
+"  . E+F+G+p+p+p+H+I+ +{+J+K+L+M+N+O+P+Q+]+ +R+S+T+0+m+C+U+V+.   ",\r
+"  [ W+X+Y+Z+Z+`+ @.@+@@@#@$@M+N+%@(+&@*@=@-@& ;@0+m+C+U+>@,@.   ",\r
+"    '@)@!@~@{@]@^@/@!@(@_@M+N+%@(+_+-+:@<@[@}@0+m+C+|@1@2@3@    ",\r
+"      + 4@5@6@7@8@9@0@a@M+N+%@(+=+-+;+>+b@c@0+m+C+d@e@f@+       ",\r
+"        + g@h@i@9@j@k@M+N+%@(+=+-+;+>+9+:+0+m+C+l@m@n@,         ",\r
+"          , o@p@q@k@M+N+%@_+=+-+;+>+9+:+0+m+C+r@s@t@+           ",\r
+"            u@v@w@x@N+%@_+=+-+;+>+9+:+0+m+C+y@z@A@B@            ",\r
+"              C@D@E@F@_+=+-+;+>+9+:+0+m+C+G@H@I@J@              ",\r
+"                K@L@{.M@N@O@P@Q@R@,+<+S@T@U@V@W@                ",\r
+"                  X@. . . . . . . . . . . . Y@                  ",\r
+"                                                                ",\r
+"                                                                "};\r
diff --git a/samples/web/web.bkl b/samples/web/web.bkl
new file mode 100644 (file)
index 0000000..02b5bce
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>\r
+<!-- $Id: widgets.bkl 59311 2009-03-04 11:47:32Z FM $ -->\r
+<makefile>\r
+\r
+    <include file="../../build/bakefiles/common_samples.bkl"/>\r
+\r
+    <exe id="web" template="wx_sample" template_append="wx_append">\r
+        <sources>\r
+            web.cpp\r
+        </sources>\r
+        <headers></headers>\r
+        <wx-lib>core</wx-lib>\r
+        <wx-lib>base</wx-lib>\r
+        <wx-lib>web</wx-lib>\r
+        <wx-lib>stc</wx-lib>\r
+        <win32-res>../sample.rc</win32-res>\r
+    </exe>\r
+\r
+</makefile>\r
diff --git a/samples/web/web.cpp b/samples/web/web.cpp
new file mode 100644 (file)
index 0000000..befae13
--- /dev/null
@@ -0,0 +1,640 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Name:        wxiepanel.cpp\r
+// Purpose:     wxBetterHTMLControl test\r
+// Author:      Marianne Gagnon\r
+// Id:          $Id$\r
+// Copyright:   (c) 2010 Marianne Gagnon\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
\r
+#include <wx/wx.h>\r
+#include <wx/artprov.h>\r
+#include <wx/notifmsg.h>\r
+#include <wx/settings.h>\r
+\r
+#if wxUSE_STC\r
+#include <wx/stc/stc.h> \r
+#else\r
+#error "wxStyledTextControl is needed by this sample"\r
+#endif\r
+\r
+#include "wx/webview.h"\r
+#include "wxlogo.xpm"\r
+#include "back.xpm"\r
+#include "forward.xpm"\r
+#include "stop.xpm"\r
+#include "refresh.xpm"\r
+\r
+// --------------------------------------------------------------------------------------------------\r
+//                                          SOURCE VIEW FRAME\r
+// --------------------------------------------------------------------------------------------------\r
+enum\r
+{\r
+    MARGIN_LINE_NUMBERS,\r
+    //MARGIN_DIVIDER,\r
+    //MARGIN_FOLDING\r
+};\r
+\r
+class SourceViewDialog : public wxDialog\r
+{\r
+public:\r
+\r
+    void onClose(wxCloseEvent& evt)\r
+    {\r
+        EndModal( GetReturnCode() );\r
+    }\r
+\r
+    SourceViewDialog(wxWindow* parent, wxString source) :\r
+        wxDialog(parent, wxID_ANY, "Source Code",\r
+                 wxDefaultPosition, wxSize(700,500),\r
+                 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)\r
+    {\r
+        wxStyledTextCtrl* text = new wxStyledTextCtrl(this, wxID_ANY);\r
+\r
+        //text->SetLexer(wxSTC_LEX_HTML);\r
+        text->SetMarginWidth (MARGIN_LINE_NUMBERS, 50);\r
+        text->StyleSetForeground (wxSTC_STYLE_LINENUMBER, wxColour (75, 75, 75) );\r
+        text->StyleSetBackground (wxSTC_STYLE_LINENUMBER, wxColour (220, 220, 220));\r
+        text->SetMarginType (MARGIN_LINE_NUMBERS, wxSTC_MARGIN_NUMBER);\r
+        \r
+        text->SetWrapMode (wxSTC_WRAP_WORD);\r
+        \r
+        text->SetText(source);\r
+        \r
+        text->StyleClearAll();\r
+        text->SetLexer(wxSTC_LEX_HTML);\r
+        text->StyleSetForeground (wxSTC_H_DOUBLESTRING,     wxColour(255,0,0));\r
+        text->StyleSetForeground (wxSTC_H_SINGLESTRING,     wxColour(255,0,0));\r
+        text->StyleSetForeground (wxSTC_H_ENTITY,           wxColour(255,0,0));\r
+        text->StyleSetForeground (wxSTC_H_TAG,              wxColour(0,150,0));\r
+        text->StyleSetForeground (wxSTC_H_TAGUNKNOWN,       wxColour(0,150,0));\r
+        text->StyleSetForeground (wxSTC_H_ATTRIBUTE,        wxColour(0,0,150));\r
+        text->StyleSetForeground (wxSTC_H_ATTRIBUTEUNKNOWN, wxColour(0,0,150));\r
+        text->StyleSetForeground (wxSTC_H_COMMENT,          wxColour(150,150,150));\r
+\r
+\r
+        wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);\r
+        sizer->Add(text, 1, wxEXPAND);\r
+        SetSizer(sizer);\r
+        \r
+        Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(SourceViewDialog::onClose), NULL, this);\r
+    }\r
+    \r
+    \r
+};\r
+\r
+// --------------------------------------------------------------------------------------------------\r
+//                                           MAIN BROWSER CLASS\r
+// --------------------------------------------------------------------------------------------------\r
+class wxMiniApp : public wxApp\r
+{\r
+    wxTextCtrl* url;\r
+    wxWebView* m_browser_ctrl;\r
+    wxFrame* frame;\r
+     \r
+    wxToolBarToolBase* back;\r
+    wxToolBarToolBase* forward;\r
+    wxToolBarToolBase* stop;\r
+    wxToolBarToolBase* reload;\r
+    wxToolBarToolBase* tools;\r
+    \r
+    wxMenu* toolsMenu;\r
+    wxMenuItem* tinySize;\r
+    wxMenuItem* smallSize;\r
+    wxMenuItem* mediumSize;\r
+    wxMenuItem* largeSize;\r
+    wxMenuItem* largestSize;\r
+    \r
+    //wxMenuItem* offlineMode;\r
+    //wxMenuItem* onlineMode;\r
+    \r
+    wxLogWindow* logging;\r
+    wxToolBar* m_toolbar;\r
+    \r
+    wxTimer* m_timer;\r
+    int m_animation_angle;\r
+    \r
+    wxPanel* m_notification_panel;\r
+    wxStaticText* m_notification_text;\r
+    \r
+public:\r
+    // function called at the application initialization\r
+    virtual bool OnInit();\r
+    \r
+    /** \r
+      * Implement timer to display the loading animation (OK, I admit this is totally irrelevant to\r
+      * the HTML control being demonstrated here, but it's fun ;)\r
+      */\r
+    void onAnimationTimer(wxTimerEvent& evt)\r
+    {\r
+        m_animation_angle += 15;\r
+        if (m_animation_angle > 360) m_animation_angle -= 360;\r
+        \r
+        wxBitmap image(32, 32);\r
+        \r
+        {\r
+        wxMemoryDC dc;\r
+        dc.SelectObject(image);\r
+        dc.SetBackground(wxBrush(wxColour(255,0,255)));\r
+        dc.Clear();\r
+        \r
+        if (m_animation_angle >= 0 && m_animation_angle <= 180)\r
+        {\r
+            dc.SetBrush(*wxYELLOW_BRUSH);\r
+            dc.SetPen(*wxYELLOW_PEN);\r
+            dc.DrawCircle(16 - int(sin(m_animation_angle*0.01745f /* convert to radians */)*14.0f),\r
+                          16 + int(cos(m_animation_angle*0.01745f /* convert to radians */)*14.0f), 3 );\r
+        }\r
+        \r
+        dc.DrawBitmap(wxBitmap(wxlogo_xpm), 0, 0, true);\r
+        \r
+        if (m_animation_angle > 180)\r
+        {\r
+            dc.SetBrush(*wxYELLOW_BRUSH);\r
+            dc.SetPen(*wxYELLOW_PEN);\r
+            dc.DrawCircle(16 - int(sin(m_animation_angle*0.01745f /* convert to radians */)*14.0f),\r
+                          16 + int(cos(m_animation_angle*0.01745f /* convert to radians */)*14.0f), 3 );\r
+        }\r
+        }\r
+        \r
+        image.SetMask(new wxMask(image, wxColour(255,0,255)));\r
+        m_toolbar->SetToolNormalBitmap(tools->GetId(), image);\r
+    }\r
+    \r
+    /**\r
+     * Method that retrieves the current state from the web control and updates the GUI\r
+     * the reflect this current state.\r
+     */\r
+    void updateState()\r
+    {\r
+        m_toolbar->EnableTool( back->GetId(), m_browser_ctrl->CanGoBack() );\r
+        m_toolbar->EnableTool( forward->GetId(), m_browser_ctrl->CanGoForward() );\r
+        \r
+        if (m_browser_ctrl->IsBusy())\r
+        {\r
+            //tools->SetLabel(_("Loading..."));\r
+            \r
+            if (m_timer == NULL)\r
+            {\r
+                m_timer = new wxTimer(this);\r
+                this->Connect(wxEVT_TIMER, wxTimerEventHandler(wxMiniApp::onAnimationTimer), NULL, this);\r
+            }\r
+            m_timer->Start(100); // start animation timer\r
+            \r
+            m_toolbar->EnableTool( stop->GetId(), true );    \r
+        }\r
+        else\r
+        {\r
+            if (m_timer != NULL) m_timer->Stop(); // stop animation timer\r
+            \r
+            //tools->SetLabel(_("Tools"));\r
+            m_toolbar->SetToolNormalBitmap(tools->GetId(), wxBitmap(wxlogo_xpm));\r
+            m_toolbar->EnableTool( stop->GetId(), false );            \r
+        }\r
+        \r
+        frame->SetTitle( m_browser_ctrl->GetCurrentTitle() );\r
+        url->SetValue( m_browser_ctrl->GetCurrentURL() );\r
+    }\r
+    \r
+    /**\r
+     * Callback invoked when user entered an URL and pressed enter\r
+     */\r
+    void onUrl(wxCommandEvent& evt)\r
+    {\r
+        if (m_notification_panel->IsShown())\r
+        {\r
+            m_notification_panel->Hide();\r
+            frame->Layout();\r
+        }\r
+        \r
+        m_browser_ctrl->LoadUrl( url->GetValue() );\r
+        updateState();\r
+    }\r
+    \r
+    /**\r
+     * Callback invoked when user pressed the "back" button\r
+     */\r
+    void onBack(wxCommandEvent& evt)\r
+    {\r
+        // First, hide notification panel if it was shown\r
+        if (m_notification_panel->IsShown())\r
+        {\r
+            m_notification_panel->Hide();\r
+            frame->Layout();\r
+        }\r
+        \r
+        m_browser_ctrl->GoBack();\r
+        updateState();\r
+    }\r
+    \r
+    /**\r
+     * Callback invoked when user pressed the "forward" button\r
+     */\r
+    void onForward(wxCommandEvent& evt)\r
+    {\r
+        // First, hide notification panel if it was shown\r
+        if (m_notification_panel->IsShown())\r
+        {\r
+            m_notification_panel->Hide();\r
+            frame->Layout();\r
+        }\r
+        \r
+        m_browser_ctrl->GoForward();\r
+        updateState();\r
+    }\r
+    \r
+    /**\r
+     * Callback invoked when user pressed the "stop" button\r
+     */\r
+    void onStop(wxCommandEvent& evt)\r
+    {\r
+        m_browser_ctrl->Stop();\r
+        updateState();\r
+    }\r
+    \r
+    /**\r
+     * Callback invoked when user pressed the "reload" button\r
+     */\r
+    void onReload(wxCommandEvent& evt)\r
+    {\r
+        // First, hide notification panel if it was shown\r
+        if (m_notification_panel->IsShown())\r
+        {\r
+            m_notification_panel->Hide();\r
+            frame->Layout();\r
+        }\r
+        \r
+        m_browser_ctrl->Reload();\r
+        updateState();\r
+    }\r
+    \r
+    /**\r
+     * Callback invoked when there is a request to load a new page (for instance\r
+     * when the user clicks a link)\r
+     */\r
+    void onNavigationRequest(wxWebNavigationEvent& evt)\r
+    {\r
+        // First, hide notification panel if it was shown\r
+        if (m_notification_panel->IsShown())\r
+        {\r
+            m_notification_panel->Hide();\r
+            frame->Layout();\r
+        }\r
+        \r
+        wxLogMessage("Navigation request to '" + evt.GetHref() + "' (target='" +\r
+                   evt.GetTarget() + "')");\r
+        \r
+        wxASSERT(m_browser_ctrl->IsBusy());\r
+        \r
+        // Uncomment this to see how to block navigation requests\r
+        //int answer = wxMessageBox("Proceed with navigation to '" + evt.GetHref() + "'?",\r
+        //                          "Proceed with navigation?", wxYES_NO );\r
+        //if (answer != wxYES)\r
+        //{\r
+        //    evt.Veto();\r
+        //}\r
+        updateState();\r
+    }\r
+    \r
+    /**\r
+     * Callback invoked when a navigation request was accepted\r
+     */\r
+    void onNavigationComplete(wxWebNavigationEvent& evt)\r
+    {\r
+        wxLogMessage("Navigation complete; url='" + evt.GetHref() + "'");\r
+        updateState();\r
+    }\r
+    \r
+    /**\r
+     * Callback invoked when a page is finished loading\r
+     */\r
+    void onDocumentLoaded(wxWebNavigationEvent& evt)\r
+    {\r
+        wxLogMessage("Document loaded; url='" + evt.GetHref() + "'");\r
+        updateState();\r
+        \r
+        m_browser_ctrl->GetZoom();\r
+    }\r
+    \r
+    /**\r
+     * Invoked when user selects the "View Source" menu item\r
+     */\r
+    void onViewSourceRequest(wxCommandEvent& evt)\r
+    {\r
+        SourceViewDialog dlg(frame, m_browser_ctrl->GetPageSource());\r
+        dlg.Center();\r
+        dlg.ShowModal();\r
+    }\r
+    \r
+    /**\r
+     * Invoked when user selects the "Menu" item\r
+     */\r
+    void onToolsClicked(wxCommandEvent& evt)\r
+    {\r
+        tinySize->Check(false);\r
+        smallSize->Check(false); \r
+        mediumSize->Check(false);\r
+        largeSize->Check(false);\r
+        largestSize->Check(false);\r
+        \r
+        wxWebViewZoom zoom = m_browser_ctrl->GetZoom();\r
+        switch (zoom)\r
+        {\r
+            case wxWEB_VIEW_ZOOM_TINY:\r
+                tinySize->Check();\r
+                break;\r
+            case wxWEB_VIEW_ZOOM_SMALL:\r
+                smallSize->Check();\r
+                break;\r
+            case wxWEB_VIEW_ZOOM_MEDIUM:\r
+                mediumSize->Check();\r
+                break;\r
+            case wxWEB_VIEW_ZOOM_LARGE:\r
+                largeSize->Check();\r
+                break;\r
+            case wxWEB_VIEW_ZOOM_LARGEST:\r
+                largestSize->Check();\r
+                break;\r
+        }\r
+        \r
+        //    bool IsOfflineMode();\r
+        //    void SetOfflineMode(bool offline);\r
+        \r
+        //offlineMode->Check(false);\r
+        //onlineMode->Check(false);\r
+        //const bool offline = m_browser_ctrl->IsOfflineMode();\r
+        //if (offline) offlineMode->Check();\r
+        //else         onlineMode->Check();\r
+        \r
+        wxPoint position = frame->ScreenToClient( wxGetMousePosition() );\r
+        frame->PopupMenu(toolsMenu, position.x, position.y);\r
+    }\r
+    \r
+    /**\r
+     * Invoked when user selects the zoom size in the menu\r
+     */\r
+    void onSetZoom(wxCommandEvent& evt)\r
+    {\r
+        if (evt.GetId() == tinySize->GetId())\r
+        {\r
+            m_browser_ctrl->SetZoom(wxWEB_VIEW_ZOOM_TINY);\r
+        }\r
+        else if (evt.GetId() == smallSize->GetId())\r
+        {\r
+            m_browser_ctrl->SetZoom(wxWEB_VIEW_ZOOM_SMALL);\r
+        }\r
+        else if (evt.GetId() == mediumSize->GetId())\r
+        {\r
+            m_browser_ctrl->SetZoom(wxWEB_VIEW_ZOOM_MEDIUM);\r
+        }\r
+        else if (evt.GetId() == largeSize->GetId())\r
+        {\r
+            m_browser_ctrl->SetZoom(wxWEB_VIEW_ZOOM_LARGE);\r
+        }\r
+        else if (evt.GetId() == largestSize->GetId())\r
+        {\r
+            m_browser_ctrl->SetZoom(wxWEB_VIEW_ZOOM_LARGEST);\r
+        }\r
+        else\r
+        {\r
+            wxASSERT(false);\r
+        }\r
+    }\r
+    \r
+    /*\r
+    void onChangeOnlineMode(wxCommandEvent& evt)\r
+    {\r
+        if (evt.GetId() == offlineMode->GetId())\r
+        {\r
+            m_browser_ctrl->SetOfflineMode(true);\r
+            m_browser_ctrl->SetPage("<html><body><h1>You are now in offline mode.</h1></body></html>");\r
+        }\r
+        else if (evt.GetId() == onlineMode->GetId())\r
+        {\r
+            m_browser_ctrl->SetOfflineMode(false);\r
+        }\r
+        else\r
+        {\r
+            wxASSERT(false);\r
+        }\r
+    }\r
+    */\r
+    \r
+    /**\r
+     * Callback invoked when a loading error occurs\r
+     */\r
+    void onError(wxWebNavigationEvent& evt)\r
+    {\r
+        wxString errorCategory;\r
+        switch (evt.GetInt())\r
+        {\r
+            case  wxWEB_NAV_ERR_CONNECTION:\r
+            errorCategory = "wxWEB_NAV_ERR_CONNECTION";\r
+            break;\r
+            \r
+            case wxWEB_NAV_ERR_CERTIFICATE:\r
+            errorCategory = "wxWEB_NAV_ERR_CERTIFICATE";\r
+            break;\r
+            \r
+            case wxWEB_NAV_ERR_AUTH:\r
+            errorCategory = "wxWEB_NAV_ERR_AUTH";\r
+            break;\r
+            \r
+            case wxWEB_NAV_ERR_SECURITY:\r
+            errorCategory = "wxWEB_NAV_ERR_SECURITY";\r
+            break;\r
+            \r
+            case wxWEB_NAV_ERR_NOT_FOUND:\r
+            errorCategory = "wxWEB_NAV_ERR_NOT_FOUND";\r
+            break;\r
+            \r
+            case wxWEB_NAV_ERR_REQUEST:\r
+            errorCategory = "wxWEB_NAV_ERR_REQUEST";\r
+            break;\r
+            \r
+            case wxWEB_NAV_ERR_USER_CANCELLED:\r
+            errorCategory = "wxWEB_NAV_ERR_USER_CANCELLED";\r
+            break;\r
+            \r
+            case wxWEB_NAV_ERR_OTHER:\r
+            errorCategory = "wxWEB_NAV_ERR_OTHER";\r
+            break;\r
+        }\r
+        \r
+        wxLogMessage("Error; url='" + evt.GetHref() + "', error='" + errorCategory + "' (" + evt.GetString() + ")");\r
+        \r
+        // show the notification panel\r
+        m_notification_text->SetLabel(_("An error occurred loading ") + evt.GetHref() + "\n" +\r
+                                      "'" + errorCategory + "' (" + evt.GetString() + ")");\r
+        m_notification_panel->Layout();\r
+        m_notification_panel->GetSizer()->SetSizeHints(m_notification_panel);\r
+        m_notification_panel->Show();\r
+        frame->Layout();\r
+    \r
+        updateState();\r
+    }\r
+    \r
+    /**\r
+     * Invoked when user clicks "Hide" in the notification panel\r
+     */\r
+    void onHideNotifBar(wxCommandEvent& evt)\r
+    {\r
+        m_notification_panel->Hide();\r
+        frame->Layout();\r
+    }\r
+    \r
+    void onClose(wxCloseEvent& evt)\r
+    {\r
+        frame->Destroy();\r
+    }\r
+    \r
+    void onQuitMenu(wxCommandEvent& evt)\r
+    {\r
+        frame->Destroy();\r
+    }\r
+    \r
+    /**\r
+     * Invoked when user selects "Print" from the menu\r
+     */\r
+    void onPrint(wxCommandEvent& evt)\r
+    {\r
+        m_browser_ctrl->Print();\r
+    }\r
+};\r
+\r
+IMPLEMENT_APP(wxMiniApp);\r
+\r
+bool wxMiniApp::OnInit()\r
+{\r
+    m_timer = NULL;\r
+    m_animation_angle = 0;\r
+    \r
+    frame = new wxFrame( NULL, -1, _("wxBetterHTMLControl Browser Example"), wxDefaultPosition, wxSize(800, 600) );\r
+    \r
+    // wx has a default mechanism to expand the only control of a frame; but since this mechanism\r
+    // does not involve sizers, invoking ->Layout on the frame does not udpate the layout which is\r
+    // not good.\r
+    wxBoxSizer* expandSizer = new wxBoxSizer(wxHORIZONTAL);\r
+    wxPanel* mainpane = new wxPanel(frame, wxID_ANY);\r
+    expandSizer->Add(mainpane, 1, wxEXPAND);\r
+    frame->SetSizer(expandSizer);\r
+\r
+    wxLog::SetLogLevel(wxLOG_Max);\r
+    logging = new wxLogWindow(frame, _("Logging"));\r
+    wxLog::SetLogLevel(wxLOG_Max);\r
+    \r
+    // ---- Create the Tools menu\r
+    toolsMenu = new wxMenu();\r
+    wxMenuItem* print = toolsMenu->Append(wxID_ANY , _("Print"));\r
+    wxMenuItem* viewSource = toolsMenu->Append(wxID_ANY , _("View Source"));\r
+    toolsMenu->AppendSeparator();\r
+    tinySize    = toolsMenu->AppendCheckItem(wxID_ANY, _("Tiny"));\r
+    smallSize   = toolsMenu->AppendCheckItem(wxID_ANY, _("Small"));\r
+    mediumSize  = toolsMenu->AppendCheckItem(wxID_ANY, _("Medium"));\r
+    largeSize   = toolsMenu->AppendCheckItem(wxID_ANY, _("Large"));\r
+    largestSize = toolsMenu->AppendCheckItem(wxID_ANY, _("Largest"));\r
+    //toolsMenu->AppendSeparator();\r
+    //offlineMode = toolsMenu->AppendCheckItem(wxID_ANY, _("Offline Mode"));\r
+    //onlineMode  = toolsMenu->AppendCheckItem(wxID_ANY, _("Online Mode"));\r
+\r
+    // ---- Create the Toolbar\r
+    m_toolbar = frame->CreateToolBar(/*wxNO_BORDER |*/ wxTB_TEXT);\r
+    m_toolbar->SetToolBitmapSize(wxSize(32, 32));\r
+    \r
+    back    = m_toolbar->AddTool(wxID_ANY, _("Back"),    wxBitmap(back_xpm));\r
+    forward = m_toolbar->AddTool(wxID_ANY, _("Forward"), wxBitmap(forward_xpm));\r
+    stop    = m_toolbar->AddTool(wxID_ANY, _("Stop"),    wxBitmap(stop_xpm));\r
+    reload  = m_toolbar->AddTool(wxID_ANY, _("Reload"),  wxBitmap(refresh_xpm));\r
+    \r
+    url = new wxTextCtrl(m_toolbar, wxID_ANY, wxT("http://www.google.com"), \r
+                         wxDefaultPosition, wxSize(400, -1), wxTE_PROCESS_ENTER );\r
+    m_toolbar->AddControl(url, _("URL"));    \r
+    tools   = m_toolbar->AddTool(wxID_ANY, _("Menu"), wxBitmap(wxlogo_xpm));\r
+    //m_toolbar->SetDropdownMenu(tools->GetId(), toolsMenu);\r
+\r
+    m_toolbar->Realize();\r
+\r
+    m_toolbar->Connect(back->GetId(),    wxEVT_COMMAND_TOOL_CLICKED,\r
+                                         wxCommandEventHandler(wxMiniApp::onBack),    NULL, this );\r
+    m_toolbar->Connect(forward->GetId(), wxEVT_COMMAND_TOOL_CLICKED,\r
+                                         wxCommandEventHandler(wxMiniApp::onForward), NULL, this );\r
+    m_toolbar->Connect(stop->GetId(),    wxEVT_COMMAND_TOOL_CLICKED,\r
+                                         wxCommandEventHandler(wxMiniApp::onStop),    NULL, this );\r
+    m_toolbar->Connect(reload->GetId(),  wxEVT_COMMAND_TOOL_CLICKED,\r
+                                         wxCommandEventHandler(wxMiniApp::onReload),  NULL, this );\r
+    m_toolbar->Connect(tools->GetId(),   wxEVT_COMMAND_TOOL_CLICKED,\r
+                                         wxCommandEventHandler(wxMiniApp::onToolsClicked),  NULL, this );\r
+\r
+    url->Connect(url->GetId(), wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(wxMiniApp::onUrl), NULL, this );\r
+\r
+\r
+    frame->Connect(viewSource->GetId(), wxEVT_COMMAND_MENU_SELECTED,\r
+                   wxCommandEventHandler(wxMiniApp::onViewSourceRequest),  NULL, this );\r
+    frame->Connect(print->GetId(), wxEVT_COMMAND_MENU_SELECTED,\r
+                   wxCommandEventHandler(wxMiniApp::onPrint),  NULL, this );\r
+    \r
+    frame->Connect(tinySize->GetId(), wxEVT_COMMAND_MENU_SELECTED,\r
+                   wxCommandEventHandler(wxMiniApp::onSetZoom),  NULL, this );\r
+    frame->Connect(smallSize->GetId(), wxEVT_COMMAND_MENU_SELECTED,\r
+                   wxCommandEventHandler(wxMiniApp::onSetZoom),  NULL, this );\r
+    frame->Connect(mediumSize->GetId(), wxEVT_COMMAND_MENU_SELECTED,\r
+                   wxCommandEventHandler(wxMiniApp::onSetZoom),  NULL, this );\r
+    frame->Connect(largeSize->GetId(), wxEVT_COMMAND_MENU_SELECTED,\r
+                   wxCommandEventHandler(wxMiniApp::onSetZoom),  NULL, this );\r
+    frame->Connect(largestSize->GetId(), wxEVT_COMMAND_MENU_SELECTED,\r
+                   wxCommandEventHandler(wxMiniApp::onSetZoom),  NULL, this );\r
+\r
+    // ---- Create the web view\r
+    m_browser_ctrl = wxWebView::GetNew(mainpane, wxID_ANY);\r
+    \r
+    // ---- Create the notification panel\r
+    {\r
+    wxBoxSizer* notification_sizer = new wxBoxSizer(wxHORIZONTAL);        \r
+    m_notification_panel = new wxPanel(mainpane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE);\r
+    m_notification_text = new wxStaticText(m_notification_panel, wxID_ANY, "[No message]");\r
+    notification_sizer->Add( new wxStaticBitmap(m_notification_panel, wxID_ANY,\r
+                                                    wxArtProvider::GetBitmap(wxART_WARNING, wxART_OTHER , wxSize(48, 48))),\r
+                                                    0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );    \r
+    notification_sizer->Add(m_notification_text, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL | wxALL, 5);\r
+    wxButton* hideNotif = new wxButton(m_notification_panel, wxID_ANY, _("Hide"));\r
+    notification_sizer->Add(hideNotif, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);\r
+    m_notification_panel->SetSizer(notification_sizer);\r
+    m_notification_panel->SetBackgroundColour(wxColor(255,225,110));\r
+    m_notification_panel->Hide();\r
+    hideNotif->Connect(hideNotif->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,\r
+                       wxCommandEventHandler(wxMiniApp::onHideNotifBar), NULL, this);\r
+    }\r
+    \r
+    wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);\r
+    sizer->Add(m_notification_panel, 0,  wxEXPAND | wxALL, 5);\r
+    sizer->Add(m_browser_ctrl, 1, wxEXPAND | wxALL, 5);\r
+    \r
+    mainpane->SetSizer(sizer);\r
+    frame->Layout();\r
+    frame->Center();\r
+    frame->Show();\r
+    \r
+    m_browser_ctrl->Connect(m_browser_ctrl->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATING,\r
+                      wxWebNavigationEventHandler(wxMiniApp::onNavigationRequest), NULL, this);\r
+    \r
+    m_browser_ctrl->Connect(m_browser_ctrl->GetId(), wxEVT_COMMAND_WEB_VIEW_NAVIGATED,\r
+                      wxWebNavigationEventHandler(wxMiniApp::onNavigationComplete), NULL, this);\r
+    \r
+    m_browser_ctrl->Connect(m_browser_ctrl->GetId(), wxEVT_COMMAND_WEB_VIEW_LOADED,\r
+                      wxWebNavigationEventHandler(wxMiniApp::onDocumentLoaded), NULL, this);\r
+            \r
+    m_browser_ctrl->Connect(m_browser_ctrl->GetId(), wxEVT_COMMAND_WEB_VIEW_ERROR,\r
+                      wxWebNavigationEventHandler(wxMiniApp::onError), NULL, this);\r
+\r
+    frame->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(wxMiniApp::onClose), NULL, this);\r
+    Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxMiniApp::onQuitMenu), NULL, this);\r
+\r
+    // You can test different zoom types (if supported by the backend)\r
+    // if (m_browser_ctrl->CanSetZoomType(wxWEB_VIEW_ZOOM_TYPE_LAYOUT))\r
+    //     m_browser_ctrl->SetZoomType(wxWEB_VIEW_ZOOM_TYPE_LAYOUT);\r
+\r
+    SetTopWindow(frame);\r
+    frame->Layout();\r
+\r
+    return true;\r
+}\r
diff --git a/samples/web/wxlogo.xpm b/samples/web/wxlogo.xpm
new file mode 100644 (file)
index 0000000..2435130
--- /dev/null
@@ -0,0 +1,44 @@
+/* XPM */\r
+static const char *const wxlogo_xpm[] = {\r
+/* columns rows colors chars-per-pixel */\r
+"32 32 6 1",\r
+"  c black",\r
+". c navy",\r
+"X c red",\r
+"o c yellow",\r
+"O c gray100",\r
+"+ c None",\r
+/* pixels */\r
+"++++++++++++++++++++++++++++++++",\r
+"++++++++++++++++++++++++++++++++",\r
+"++++++++++++++++++++++++++++++++",\r
+"++++++++++++++++++++++++++++++++",\r
+"++++++++++++++++++++++++++++++++",\r
+"++++++++              ++++++++++",\r
+"++++++++ ............ ++++++++++",\r
+"++++++++ ............ ++++++++++",\r
+"++++++++ .OO......... ++++++++++",\r
+"++++++++ .OO......... ++++++++++",\r
+"++++++++ .OO......... ++++++++++",\r
+"++++++++ .OO......              ",\r
+"++++++++ .OO...... oooooooooooo ",\r
+"         .OO...... oooooooooooo ",\r
+" XXXXXXX .OO...... oOOooooooooo ",\r
+" XXXXXXX .OO...... oOOooooooooo ",\r
+" XOOXXXX ......... oOOooooooooo ",\r
+" XOOXXXX ......... oOOooooooooo ",\r
+" XOOXXXX           oOOooooooooo ",\r
+" XOOXXXXXXXXX ++++ oOOooooooooo ",\r
+" XOOXXXXXXXXX ++++ oOOooooooooo ",\r
+" XOOXXXXXXXXX ++++ oOOooooooooo ",\r
+" XOOXXXXXXXXX ++++ oooooooooooo ",\r
+" XOOXXXXXXXXX ++++ oooooooooooo ",\r
+" XXXXXXXXXXXX ++++              ",\r
+" XXXXXXXXXXXX ++++++++++++++++++",\r
+"              ++++++++++++++++++",\r
+"++++++++++++++++++++++++++++++++",\r
+"++++++++++++++++++++++++++++++++",\r
+"++++++++++++++++++++++++++++++++",\r
+"++++++++++++++++++++++++++++++++",\r
+"++++++++++++++++++++++++++++++++"\r
+};\r
diff --git a/src/common/webview.cpp b/src/common/webview.cpp
new file mode 100644 (file)
index 0000000..91ce54f
--- /dev/null
@@ -0,0 +1,113 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Name:        webview.cpp\r
+// Purpose:     Common interface and events for web view component\r
+// Author:      Marianne Gagnon\r
+// Id:          $Id$\r
+// Copyright:   (c) 2010 Marianne Gagnon\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "wx/webview.h"\r
+\r
+#include "wx/osx/webkit.h"\r
+#include "wx/gtk/webkit.h"\r
+#include "wx/msw/webkitie.h"\r
+\r
+extern WXDLLEXPORT_DATA(const char) wxWebViewNameStr[] = "wxWebView";\r
+extern WXDLLEXPORT_DATA(const char) wxWebViewDefaultURLStr[] = "about:blank";\r
+\r
+IMPLEMENT_DYNAMIC_CLASS(wxWebNavigationEvent, wxCommandEvent)\r
+\r
+wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_NAVIGATING, wxWebNavigationEvent );\r
+wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_NAVIGATED, wxWebNavigationEvent );\r
+wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_LOADED, wxWebNavigationEvent );\r
+wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_ERROR, wxWebNavigationEvent );\r
+\r
+// static\r
+wxWebView* wxWebView::New(wxWebViewBackend backend)\r
+{\r
+    switch (backend)\r
+    {\r
+        #if wxHAVE_WEB_BACKEND_OSX_WEBKIT\r
+            case wxWEB_VIEW_BACKEND_OSX_WEBKIT:\r
+                return new wxOSXWebKitCtrl();\r
+        #endif\r
+\r
+        #if wxHAVE_WEB_BACKEND_GTK_WEBKIT\r
+            case wxWEB_VIEW_BACKEND_GTK_WEBKIT:\r
+                return new wxGtkWebKitCtrl();\r
+        #endif\r
+\r
+        #if wxHAVE_WEB_BACKEND_IE\r
+            case wxWEB_VIEW_BACKEND_IE:\r
+                return new wxIEPanel();\r
+        #endif\r
+\r
+        case wxWEB_VIEW_BACKEND_DEFAULT:\r
+\r
+            #if wxHAVE_WEB_BACKEND_OSX_WEBKIT\r
+            return new wxOSXWebKitCtrl();\r
+            #endif\r
+\r
+            #if wxHAVE_WEB_BACKEND_GTK_WEBKIT\r
+            return new wxGtkWebKitCtrl();\r
+            #endif\r
+\r
+            #if wxHAVE_WEB_BACKEND_IE\r
+            return new wxIEPanel();\r
+            #endif\r
+\r
+        // fall-through intended\r
+        default:\r
+            return NULL;\r
+    }\r
+}\r
+\r
+// static\r
+wxWebView* wxWebView::New(wxWindow* parent,\r
+       wxWindowID id,\r
+       const wxString& url,\r
+       const wxPoint& pos,\r
+       const wxSize& size,\r
+       wxWebViewBackend backend,\r
+       long style,\r
+       const wxString& name)\r
+{\r
+    switch (backend)\r
+    {\r
+        #if wxHAVE_WEB_BACKEND_OSX_WEBKIT\r
+            case wxWEB_VIEW_BACKEND_OSX_WEBKIT:\r
+                return new wxOSXWebKitCtrl(parent, id, url, pos, size, style,\r
+                                           name);\r
+        #endif\r
+\r
+        #if wxHAVE_WEB_BACKEND_GTK_WEBKIT\r
+            case wxWEB_VIEW_BACKEND_GTK_WEBKIT:\r
+                return new wxGtkWebKitCtrl(parent, id, url, pos, size, style,\r
+                                           name);\r
+        #endif\r
+\r
+        #if wxHAVE_WEB_BACKEND_IE\r
+            case wxWEB_VIEW_BACKEND_IE:\r
+                return new wxIEPanel(parent, id, url, pos, size, style, name);\r
+        #endif\r
+\r
+        case wxWEB_VIEW_BACKEND_DEFAULT:\r
+\r
+            #if wxHAVE_WEB_BACKEND_OSX_WEBKIT\r
+            return new wxOSXWebKitCtrl(parent, id, url, pos, size, style, name);\r
+            #endif\r
+\r
+            #if wxHAVE_WEB_BACKEND_GTK_WEBKIT\r
+            return new wxGtkWebKitCtrl(parent, id, url, pos, size, style, name);\r
+            #endif\r
+\r
+            #if wxHAVE_WEB_BACKEND_IE\r
+            return new wxIEPanel(parent, id, url, pos, size, style, name);\r
+            #endif\r
+\r
+        // fall-through intended\r
+        default:\r
+            return NULL;\r
+    }\r
+}\r
diff --git a/src/gtk/webview.cpp b/src/gtk/webview.cpp
new file mode 100644 (file)
index 0000000..2aac270
--- /dev/null
@@ -0,0 +1,560 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Name:        src/gtk/webview.cpp\r
+// Purpose:     GTK WebKit backend for web view component\r
+// Author:      Marianne Gagnon, Robert Roebling\r
+// Id:          $Id$\r
+// Copyright:   (c) 2010 Marianne Gagnon, 1998 Robert Roebling\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+// For compilers that support precompilation, includes "wx.h".\r
+#include "wx/wxprec.h"\r
+\r
+\r
+#if wxHAVE_WEB_BACKEND_GTK_WEBKIT\r
+\r
+#include "wx/stockitem.h"\r
+#include "wx/gtk/webview.h"\r
+#include "wx/gtk/control.h"\r
+#include "wx/gtk/private.h"\r
+#include "webkit/webkit.h"\r
+\r
+// ----------------------------------------------------------------------------\r
+// GTK callbacks\r
+// ----------------------------------------------------------------------------\r
+\r
+extern "C"\r
+{\r
+\r
+static void\r
+wxgtk_webkitctrl_load_status_callback(GtkWidget* widget, GParamSpec* arg1,\r
+                                      wxWebViewGTKWebKit *webKitCtrl)\r
+{\r
+    if (!webKitCtrl->m_ready) return;\r
+\r
+    wxString url = webKitCtrl->GetCurrentURL();\r
+\r
+    WebKitLoadStatus status;\r
+    g_object_get(G_OBJECT(widget), "load-status", &status, NULL);\r
+\r
+    wxString target; // TODO: get target (if possible)\r
+\r
+    if (status == WEBKIT_LOAD_FINISHED)\r
+    {\r
+        webKitCtrl->m_busy = false;\r
+        wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_LOADED,\r
+                                       webKitCtrl->GetId(),\r
+                                       url, target, false);\r
+\r
+        if (webKitCtrl && webKitCtrl->GetEventHandler())\r
+            webKitCtrl->GetEventHandler()->ProcessEvent(thisEvent);\r
+    }\r
+    else if (status ==  WEBKIT_LOAD_COMMITTED)\r
+    {\r
+        webKitCtrl->m_busy = true;\r
+        wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,\r
+                                       webKitCtrl->GetId(),\r
+                                       url, target, false);\r
+\r
+        if (webKitCtrl && webKitCtrl->GetEventHandler())\r
+            webKitCtrl->GetEventHandler()->ProcessEvent(thisEvent);\r
+    }\r
+}\r
+\r
+static WebKitNavigationResponse\r
+wxgtk_webkitctrl_navigation_requ_callback(WebKitWebView        *web_view,\r
+                                          WebKitWebFrame       *frame,\r
+                                          WebKitNetworkRequest *request,\r
+                                          wxWebViewGTKWebKit      *webKitCtrl)\r
+{\r
+    webKitCtrl->m_busy = true;\r
+\r
+    const gchar* uri = webkit_network_request_get_uri(request);\r
+\r
+    wxString target = webkit_web_frame_get_name (frame);\r
+    wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_NAVIGATING,\r
+                                   webKitCtrl->GetId(),\r
+                                   wxString( uri, wxConvUTF8 ),\r
+                                   target,\r
+                                   true);\r
+\r
+    if (webKitCtrl && webKitCtrl->GetEventHandler())\r
+        webKitCtrl->GetEventHandler()->ProcessEvent(thisEvent);\r
+\r
+    if (thisEvent.IsVetoed())\r
+    {\r
+        webKitCtrl->m_busy = false;\r
+        return WEBKIT_NAVIGATION_RESPONSE_IGNORE;\r
+    }\r
+    else\r
+    {\r
+        return  WEBKIT_NAVIGATION_RESPONSE_ACCEPT;\r
+    }\r
+}\r
+\r
+static gboolean\r
+wxgtk_webkitctrl_error (WebKitWebView  *web_view,\r
+                        WebKitWebFrame *web_frame,\r
+                        gchar          *uri,\r
+                        gpointer        web_error,\r
+                        wxWebViewGTKWebKit* webKitWindow)\r
+{\r
+    webKitWindow->m_busy = false;\r
+    wxWebNavigationError type = wxWEB_NAV_ERR_OTHER;\r
+\r
+    GError* error = (GError*)web_error;\r
+    wxString description(error->message, wxConvUTF8);\r
+\r
+    if (strcmp(g_quark_to_string(error->domain), "soup_http_error_quark") == 0)\r
+    {\r
+        switch (error->code)\r
+        {\r
+            case SOUP_STATUS_CANCELLED:\r
+                type = wxWEB_NAV_ERR_USER_CANCELLED;\r
+                break;\r
+\r
+            case SOUP_STATUS_CANT_RESOLVE:\r
+            case SOUP_STATUS_NOT_FOUND:\r
+                type = wxWEB_NAV_ERR_NOT_FOUND;\r
+                break;\r
+\r
+            case SOUP_STATUS_CANT_RESOLVE_PROXY:\r
+            case SOUP_STATUS_CANT_CONNECT:\r
+            case SOUP_STATUS_CANT_CONNECT_PROXY:\r
+            case SOUP_STATUS_SSL_FAILED:\r
+            case SOUP_STATUS_IO_ERROR:\r
+                type = wxWEB_NAV_ERR_CONNECTION;\r
+                break;\r
+\r
+            case SOUP_STATUS_MALFORMED:\r
+            //case SOUP_STATUS_TOO_MANY_REDIRECTS:\r
+                type = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+\r
+            //case SOUP_STATUS_NO_CONTENT:\r
+            //case SOUP_STATUS_RESET_CONTENT:\r
+\r
+            case SOUP_STATUS_BAD_REQUEST:\r
+                type = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+\r
+            case SOUP_STATUS_UNAUTHORIZED:\r
+            case SOUP_STATUS_FORBIDDEN:\r
+                type = wxWEB_NAV_ERR_AUTH;\r
+                break;\r
+\r
+            case SOUP_STATUS_METHOD_NOT_ALLOWED:\r
+            case SOUP_STATUS_NOT_ACCEPTABLE:\r
+                type = wxWEB_NAV_ERR_SECURITY;\r
+                break;\r
+\r
+            case SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED:\r
+                type = wxWEB_NAV_ERR_AUTH;\r
+                break;\r
+\r
+            case SOUP_STATUS_REQUEST_TIMEOUT:\r
+                type = wxWEB_NAV_ERR_CONNECTION;\r
+                break;\r
+\r
+            //case SOUP_STATUS_PAYMENT_REQUIRED:\r
+            case SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE:\r
+            case SOUP_STATUS_REQUEST_URI_TOO_LONG:\r
+            case SOUP_STATUS_UNSUPPORTED_MEDIA_TYPE:\r
+                type = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+\r
+            case SOUP_STATUS_BAD_GATEWAY:\r
+            case SOUP_STATUS_SERVICE_UNAVAILABLE:\r
+            case SOUP_STATUS_GATEWAY_TIMEOUT:\r
+                type = wxWEB_NAV_ERR_CONNECTION;\r
+                break;\r
+\r
+            case SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED:\r
+                type = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+            //case SOUP_STATUS_INSUFFICIENT_STORAGE:\r
+            //case SOUP_STATUS_NOT_EXTENDED:\r
+        }\r
+    }\r
+    else if (strcmp(g_quark_to_string(error->domain),\r
+                    "webkit-network-error-quark") == 0)\r
+    {\r
+        switch (error->code)\r
+        {\r
+            //WEBKIT_NETWORK_ERROR_FAILED:\r
+            //WEBKIT_NETWORK_ERROR_TRANSPORT:\r
+\r
+            case WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL:\r
+                type = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+\r
+            case WEBKIT_NETWORK_ERROR_CANCELLED:\r
+                type = wxWEB_NAV_ERR_USER_CANCELLED;\r
+                break;\r
+\r
+            case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST:\r
+                type = wxWEB_NAV_ERR_NOT_FOUND;\r
+                break;\r
+        }\r
+    }\r
+    else if (strcmp(g_quark_to_string(error->domain),\r
+                    "webkit-policy-error-quark") == 0)\r
+    {\r
+        switch (error->code)\r
+        {\r
+            //case WEBKIT_POLICY_ERROR_FAILED:\r
+            //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE:\r
+            //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URL:\r
+            //case WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE:\r
+            case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT:\r
+                type = wxWEB_NAV_ERR_SECURITY;\r
+                break;\r
+        }\r
+    }\r
+    /*\r
+    webkit_plugin_error_quark\r
+    else\r
+    {\r
+        printf("Error domain %s\n", g_quark_to_string(error->domain));\r
+    }\r
+    */\r
+\r
+    wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_ERROR,\r
+                                   webKitWindow->GetId(),\r
+                                   uri,\r
+                                   wxEmptyString,\r
+                                   false);\r
+    thisEvent.SetString(description);\r
+    thisEvent.SetInt(type);\r
+\r
+    if (webKitWindow && webKitWindow->GetEventHandler())\r
+    {\r
+        webKitWindow->GetEventHandler()->ProcessEvent(thisEvent);\r
+    }\r
+\r
+    return FALSE;\r
+}\r
+\r
+\r
+} // extern "C"\r
+\r
+//-----------------------------------------------------------------------------\r
+// wxWebViewGTKWebKit\r
+//-----------------------------------------------------------------------------\r
+\r
+//IMPLEMENT_DYNAMIC_CLASS(wxWebViewGTKWebKit, wxControl)\r
+\r
+bool wxWebViewGTKWebKit::Create(wxWindow *parent,\r
+                      wxWindowID id,\r
+                      const wxString &url,\r
+                      const wxPoint& pos,\r
+                      const wxSize& size,\r
+                      long style,\r
+                      const wxString& name)\r
+{\r
+    m_ready = false;\r
+    m_busy = false;\r
+\r
+    if (!PreCreation( parent, pos, size ) ||\r
+        !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))\r
+    {\r
+        wxFAIL_MSG( wxT("wxWebViewGTKWebKit creation failed") );\r
+        return false;\r
+    }\r
+\r
+    GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);\r
+    web_view = webkit_web_view_new ();\r
+    g_object_ref(web_view); // TODO: check memory management\r
+\r
+    m_widget = scrolled_window;\r
+    g_object_ref(m_widget); // TODO: check memory management\r
+\r
+    /* Place the WebKitWebView in the GtkScrolledWindow */\r
+    gtk_container_add (GTK_CONTAINER (scrolled_window), web_view);\r
+    gtk_widget_show(m_widget);\r
+    gtk_widget_show(web_view);\r
+\r
+    g_signal_connect_after(web_view, "notify::load-status",\r
+                           G_CALLBACK(wxgtk_webkitctrl_load_status_callback),\r
+                           this);\r
+    g_signal_connect_after(web_view, "navigation-requested",\r
+                           G_CALLBACK(wxgtk_webkitctrl_navigation_requ_callback),\r
+                           this);\r
+    g_signal_connect_after(web_view, "load-error", \r
+                           G_CALLBACK(wxgtk_webkitctrl_error),\r
+                           this);\r
+\r
+    // this signal can be added if we care about new frames open requests\r
+    //g_signal_connect_after(web_view, "new-window-policy-decision-requested",\r
+    //                       G_CALLBACK(...), this);\r
+\r
+    m_parent->DoAddChild( this );\r
+\r
+    PostCreation(size);\r
+\r
+    /* Open a webpage */\r
+    webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), url);\r
+\r
+    m_ready = true;\r
+\r
+    return true;\r
+}\r
+\r
+bool wxWebViewGTKWebKit::Enable( bool enable )\r
+{\r
+    if (!wxControl::Enable(enable))\r
+        return false;\r
+\r
+    gtk_widget_set_sensitive(GTK_BIN(m_widget)->child, enable);\r
+\r
+    //if (enable)\r
+    //    GTKFixSensitivity();\r
+\r
+    return true;\r
+}\r
+\r
+GdkWindow*\r
+wxWebViewGTKWebKit::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const\r
+{\r
+    GdkWindow* window = gtk_widget_get_parent_window(m_widget);\r
+    return window;\r
+}\r
+\r
+void wxWebViewGTKWebKit::ZoomIn()\r
+{\r
+    webkit_web_view_zoom_in (WEBKIT_WEB_VIEW(web_view));\r
+}\r
+\r
+void wxWebViewGTKWebKit::ZoomOut()\r
+{\r
+    webkit_web_view_zoom_out (WEBKIT_WEB_VIEW(web_view));\r
+}\r
+\r
+void wxWebViewGTKWebKit::SetWebkitZoom(float level)\r
+{\r
+    webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW(web_view), level);\r
+}\r
+\r
+float wxWebViewGTKWebKit::GetWebkitZoom()\r
+{\r
+    return webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW(web_view));\r
+}\r
+\r
+void wxWebViewGTKWebKit::Stop()\r
+{\r
+     webkit_web_view_stop_loading (WEBKIT_WEB_VIEW(web_view));\r
+}\r
+\r
+void wxWebViewGTKWebKit::Reload(wxWebViewReloadFlags flags)\r
+{\r
+    if (flags & wxWEB_VIEW_RELOAD_NO_CACHE)\r
+    {\r
+        webkit_web_view_reload_bypass_cache (WEBKIT_WEB_VIEW(web_view));\r
+    }\r
+    else\r
+    {\r
+        webkit_web_view_reload (WEBKIT_WEB_VIEW(web_view));\r
+    }\r
+}\r
+\r
+void wxWebViewGTKWebKit::LoadUrl(const wxString& url)\r
+{\r
+    webkit_web_view_open(WEBKIT_WEB_VIEW(web_view), wxGTK_CONV(loc));\r
+}\r
+\r
+\r
+void wxWebViewGTKWebKit::GoBack()\r
+{\r
+    webkit_web_view_go_back (WEBKIT_WEB_VIEW(web_view));\r
+}\r
+\r
+void wxWebViewGTKWebKit::GoForward()\r
+{\r
+    webkit_web_view_go_forward (WEBKIT_WEB_VIEW(web_view));\r
+}\r
+\r
+\r
+bool wxWebViewGTKWebKit::CanGoBack()\r
+{\r
+    return webkit_web_view_can_go_back (WEBKIT_WEB_VIEW(web_view));\r
+}\r
+\r
+\r
+bool wxWebViewGTKWebKit::CanGoForward()\r
+{\r
+    return webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW(web_view));\r
+}\r
+\r
+\r
+wxString wxWebViewGTKWebKit::GetCurrentURL()\r
+{\r
+    // FIXME: check which encoding the web kit control uses instead of\r
+    // assuming UTF8 (here and elsewhere too)\r
+    return wxString::FromUTF8(webkit_web_view_get_uri(\r
+                                WEBKIT_WEB_VIEW(web_view)));\r
+}\r
+\r
+\r
+wxString wxWebViewGTKWebKit::GetCurrentTitle()\r
+{\r
+    return wxString::FromUTF8(webkit_web_view_get_title(\r
+                                WEBKIT_WEB_VIEW(web_view)));\r
+}\r
+\r
+\r
+wxString wxWebViewGTKWebKit::GetPageSource()\r
+{\r
+    WebKitWebFrame* frame = webkit_web_view_get_main_frame(\r
+        WEBKIT_WEB_VIEW(web_view));\r
+    WebKitWebDataSource* src = webkit_web_frame_get_data_source (frame);\r
+\r
+    // TODO: check encoding with\r
+    // const gchar*\r
+    // webkit_web_data_source_get_encoding(WebKitWebDataSource *data_source);\r
+    return wxString(webkit_web_data_source_get_data (src)->str, wxConvUTF8);\r
+}\r
+\r
+\r
+wxWebViewZoom wxWebViewGTKWebKit::GetZoom()\r
+{\r
+    float zoom = GetWebkitZoom();\r
+\r
+    // arbitrary way to map float zoom to our common zoom enum\r
+    if (zoom <= 0.65)\r
+    {\r
+        return wxWEB_VIEW_ZOOM_TINY;\r
+    }\r
+    else if (zoom > 0.65 && zoom <= 0.90)\r
+    {\r
+        return wxWEB_VIEW_ZOOM_SMALL;\r
+    }\r
+    else if (zoom > 0.90 && zoom <= 1.15)\r
+    {\r
+        return wxWEB_VIEW_ZOOM_MEDIUM;\r
+    }\r
+    else if (zoom > 1.15 && zoom <= 1.45)\r
+    {\r
+        return wxWEB_VIEW_ZOOM_LARGE;\r
+    }\r
+    else if (zoom > 1.45)\r
+    {\r
+        return wxWEB_VIEW_ZOOM_LARGEST;\r
+    }\r
+\r
+    // to shut up compilers, this can never be reached logically\r
+    wxASSERT(false);\r
+    return wxWEB_VIEW_ZOOM_MEDIUM;\r
+}\r
+\r
+\r
+void wxWebViewGTKWebKit::SetZoom(wxWebViewZoom zoom)\r
+{\r
+    // arbitrary way to map our common zoom enum to float zoom\r
+    switch (zoom)\r
+    {\r
+        case wxWEB_VIEW_ZOOM_TINY:\r
+            SetWebkitZoom(0.6f);\r
+            break;\r
+\r
+        case wxWEB_VIEW_ZOOM_SMALL:\r
+            SetWebkitZoom(0.8f);\r
+            break;\r
+\r
+        case wxWEB_VIEW_ZOOM_MEDIUM:\r
+            SetWebkitZoom(1.0f);\r
+            break;\r
+\r
+        case wxWEB_VIEW_ZOOM_LARGE:\r
+            SetWebkitZoom(1.3);\r
+            break;\r
+\r
+        case wxWEB_VIEW_ZOOM_LARGEST:\r
+            SetWebkitZoom(1.6);\r
+            break;\r
+\r
+        default:\r
+            wxASSERT(false);\r
+    }\r
+}\r
+\r
+void wxWebViewGTKWebKit::SetZoomType(wxWebViewZoomType type)\r
+{\r
+    webkit_web_view_set_full_content_zoom(WEBKIT_WEB_VIEW(web_view),\r
+                                          (type == wxWEB_VIEW_ZOOM_TYPE_LAYOUT ?\r
+                                          TRUE : FALSE));\r
+}\r
+\r
+wxWebViewZoomType wxWebViewGTKWebKit::GetZoomType() const\r
+{\r
+    gboolean fczoom = webkit_web_view_get_full_content_zoom(\r
+            WEBKIT_WEB_VIEW(web_view));\r
+\r
+    if (fczoom) return wxWEB_VIEW_ZOOM_TYPE_LAYOUT;\r
+    else        return wxWEB_VIEW_ZOOM_TYPE_TEXT;\r
+}\r
+\r
+bool wxWebViewGTKWebKit::CanSetZoomType(wxWebViewZoomType) const\r
+{\r
+    // this port supports all zoom types\r
+    return true;\r
+}\r
+\r
+void wxWebViewGTKWebKit::SetPage(const wxString& html, const wxString& baseUri)\r
+{\r
+    webkit_web_view_load_string (WEBKIT_WEB_VIEW(web_view),\r
+                                 html.mb_str(wxConvUTF8),\r
+                                 "text/html",\r
+                                 "UTF-8",\r
+                                 baseUri.mb_str(wxConvUTF8));\r
+}\r
+\r
+void wxWebViewGTKWebKit::Print()\r
+{\r
+    WebKitWebFrame* frame = webkit_web_view_get_main_frame(\r
+            WEBKIT_WEB_VIEW(web_view));\r
+    webkit_web_frame_print (frame);\r
+\r
+    // GtkPrintOperationResult  webkit_web_frame_print_full\r
+    //      (WebKitWebFrame *frame,\r
+    //       GtkPrintOperation *operation,\r
+    //       GtkPrintOperationAction action,\r
+    //       GError **error);\r
+\r
+}\r
+\r
+\r
+bool wxWebViewGTKWebKit::IsBusy()\r
+{\r
+    return m_busy;\r
+\r
+    // This code looks nice but returns true after a page was cancelled\r
+    /*\r
+    WebKitLoadStatus status = webkit_web_view_get_load_status\r
+            (WEBKIT_WEB_VIEW(web_view));\r
+\r
+\r
+#if WEBKIT_CHECK_VERSION(1,1,16)\r
+    // WEBKIT_LOAD_FAILED is new in webkit 1.1.16\r
+    if (status == WEBKIT_LOAD_FAILED)\r
+    {\r
+        return false;\r
+    }\r
+#endif\r
+    if (status == WEBKIT_LOAD_FINISHED)\r
+    {\r
+        return false;\r
+    }\r
+\r
+    return true;\r
+     */\r
+}\r
+\r
+// static\r
+wxVisualAttributes\r
+wxWebViewGTKWebKit::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))\r
+{\r
+     return GetDefaultAttributesFromGTKWidget(webkit_web_view_new);\r
+}\r
+\r
+\r
+#endif // wxHAVE_WEB_BACKEND_GTK_WEBKIT\r
diff --git a/src/msw/webviewie.cpp b/src/msw/webviewie.cpp
new file mode 100644 (file)
index 0000000..e6f1246
--- /dev/null
@@ -0,0 +1,667 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Name:        src/msw/webviewie.cpp\r
+// Purpose:     wxMSW wxWebViewIE class implementation for web view component\r
+// Author:      Marianne Gagnon\r
+// Id:          $Id$\r
+// Copyright:   (c) 2010 Marianne Gagnon\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "wx/msw/webview.h"\r
+\r
+#if wxHAVE_WEB_BACKEND_IE\r
+\r
+#include <olectl.h>\r
+#include <oleidl.h>\r
+#include <exdispid.h>\r
+#include <exdisp.h>\r
+#include <mshtml.h>\r
+\r
+// FIXME: Seems like MINGW does not have these, how to handle cleanly?\r
+#define DISPID_COMMANDSTATECHANGE   105\r
+typedef enum CommandStateChangeConstants {\r
+    CSC_UPDATECOMMANDS = (int) 0xFFFFFFFF,\r
+    CSC_NAVIGATEFORWARD = 0x1,\r
+    CSC_NAVIGATEBACK = 0x2\r
+} CommandStateChangeConstants;\r
+\r
+\r
+// FIXME: Seems like MINGW does not have these, how to handle cleanly?\r
+#define DISPID_NAVIGATECOMPLETE2    252\r
+#define DISPID_NAVIGATEERROR        271\r
+#define OLECMDID_OPTICAL_ZOOM  63\r
+#define INET_E_ERROR_FIRST 0x800C0002L\r
+#define INET_E_INVALID_URL 0x800C0002L\r
+#define INET_E_NO_SESSION 0x800C0003L\r
+#define INET_E_CANNOT_CONNECT 0x800C0004L\r
+#define INET_E_RESOURCE_NOT_FOUND 0x800C0005L\r
+#define INET_E_OBJECT_NOT_FOUND 0x800C0006L\r
+#define INET_E_DATA_NOT_AVAILABLE 0x800C0007L\r
+#define INET_E_DOWNLOAD_FAILURE 0x800C0008L\r
+#define INET_E_AUTHENTICATION_REQUIRED 0x800C0009L\r
+#define INET_E_NO_VALID_MEDIA 0x800C000AL\r
+#define INET_E_CONNECTION_TIMEOUT 0x800C000BL\r
+#define INET_E_INVALID_REQUEST 0x800C000CL\r
+#define INET_E_UNKNOWN_PROTOCOL 0x800C000DL\r
+#define INET_E_SECURITY_PROBLEM 0x800C000EL\r
+#define INET_E_CANNOT_LOAD_DATA 0x800C000FL\r
+#define INET_E_CANNOT_INSTANTIATE_OBJECT 0x800C0010L\r
+#define INET_E_QUERYOPTION_UNKNOWN 0x800C0013L\r
+#define INET_E_REDIRECT_FAILED 0x800C0014L\r
+#define INET_E_REDIRECT_TO_DIR 0x800C0015L\r
+#define INET_E_CANNOT_LOCK_REQUEST 0x800C0016L\r
+#define INET_E_USE_EXTEND_BINDING 0x800C0017L\r
+#define INET_E_TERMINATED_BIND 0x800C0018L\r
+#define INET_E_INVALID_CERTIFICATE 0x800C0019L\r
+#define INET_E_CODE_DOWNLOAD_DECLINED 0x800C0100L\r
+#define INET_E_RESULT_DISPATCHED 0x800C0200L\r
+#define INET_E_CANNOT_REPLACE_SFP_FILE 0x800C0300L\r
+#define INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY 0x800C0500L\r
+#define INET_E_CODE_INSTALL_SUPPRESSED 0x800C0400L\r
+\r
+#define REFRESH_COMPLETELY 3\r
+\r
+BEGIN_EVENT_TABLE(wxWebViewIE, wxControl)\r
+EVT_ACTIVEX(wxID_ANY, wxWebViewIE::onActiveXEvent)\r
+EVT_ERASE_BACKGROUND(wxWebViewIE::onEraseBg)\r
+END_EVENT_TABLE()\r
+\r
+bool wxWebViewIE::Create(wxWindow* parent,\r
+           wxWindowID id,\r
+           const wxString& url,\r
+           const wxPoint& pos,\r
+           const wxSize& size,\r
+           long style,\r
+           const wxString& name)\r
+{\r
+    if (!wxControl::Create(parent, id, pos, size, style,\r
+                           wxDefaultValidator, name))\r
+    {\r
+        return false;\r
+    }\r
+\r
+    m_webBrowser = NULL;\r
+    m_canNavigateBack = false;\r
+    m_canNavigateForward = false;\r
+    m_isBusy = false;\r
+\r
+    if (::CoCreateInstance(CLSID_WebBrowser, NULL,\r
+                           CLSCTX_INPROC_SERVER, // CLSCTX_INPROC,\r
+                           IID_IWebBrowser2 , (void**)&m_webBrowser) != 0)\r
+    {\r
+        wxLogError("Failed to initialize IE, CoCreateInstance returned an error");\r
+        return false;\r
+    }\r
+\r
+    m_ie.SetDispatchPtr(m_webBrowser); // wxAutomationObject will release itself\r
+\r
+    m_webBrowser->put_RegisterAsBrowser(VARIANT_TRUE);\r
+    m_webBrowser->put_RegisterAsDropTarget(VARIANT_TRUE);\r
+    //m_webBrowser->put_Silent(VARIANT_FALSE);\r
+\r
+    m_container = new wxActiveXContainer(this, IID_IWebBrowser2, m_webBrowser);\r
+\r
+    SetBackgroundStyle(wxBG_STYLE_PAINT);\r
+    SetDoubleBuffered(true);\r
+    return true;\r
+}\r
+\r
+\r
+void wxWebViewIE::LoadUrl(const wxString& url)\r
+{\r
+    wxVariant out = m_ie.CallMethod("Navigate", (BSTR) url.wc_str(),\r
+                                    NULL, NULL, NULL, NULL);\r
+\r
+    // FIXME: why is out value null??\r
+    //(HRESULT)(out.GetLong()) == S_OK;\r
+}\r
+\r
+void wxWebViewIE::SetPage(const wxString& html, const wxString& baseUrl)\r
+{\r
+    LoadUrl("about:blank");\r
+\r
+    // Let the wx events generated for navigation events be processed, so\r
+    // that the underlying IE component completes its Document object.\r
+    // FIXME: calling wxYield is not elegant nor very reliable probably\r
+    wxYield();\r
+\r
+    wxVariant documentVariant = m_ie.GetProperty("Document");\r
+    void* documentPtr = documentVariant.GetVoidPtr();\r
+\r
+    wxASSERT (documentPtr != NULL);\r
+\r
+    // TODO: consider the "baseUrl" parameter if possible\r
+    // TODO: consider encoding\r
+    BSTR bstr = SysAllocString(html.wc_str());\r
+\r
+    // Creates a new one-dimensional array\r
+    SAFEARRAY *psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);\r
+    if (psaStrings != NULL)\r
+    {\r
+        VARIANT *param;\r
+        HRESULT hr = SafeArrayAccessData(psaStrings, (LPVOID*)&param);\r
+        param->vt = VT_BSTR;\r
+        param->bstrVal = bstr;\r
+\r
+        hr = SafeArrayUnaccessData(psaStrings);\r
+\r
+        IHTMLDocument2* document = (IHTMLDocument2*)documentPtr;\r
+        document->write(psaStrings);\r
+\r
+        // SafeArrayDestroy calls SysFreeString for each BSTR\r
+        SafeArrayDestroy(psaStrings);\r
+    }\r
+    else\r
+    {\r
+        wxLogError("wxWebViewIE::SetPage() : psaStrings is NULL");\r
+    }\r
+\r
+}\r
+\r
+wxString wxWebViewIE::GetPageSource()\r
+{\r
+    wxVariant documentVariant = m_ie.GetProperty("Document");\r
+    void* documentPtr = documentVariant.GetVoidPtr();\r
+\r
+    if (documentPtr == NULL)\r
+    {\r
+        return wxEmptyString;\r
+    }\r
+\r
+    IHTMLDocument2* document = (IHTMLDocument2*)documentPtr;\r
+\r
+    IHTMLElement *bodyTag = NULL;\r
+    IHTMLElement *htmlTag = NULL;\r
+    document->get_body(&bodyTag);\r
+    wxASSERT(bodyTag != NULL);\r
+\r
+    document->Release();\r
+    bodyTag->get_parentElement(&htmlTag);\r
+    wxASSERT(htmlTag != NULL);\r
+\r
+    BSTR    bstr;\r
+    htmlTag->get_outerHTML(&bstr);\r
+\r
+    bodyTag->Release();\r
+    htmlTag->Release();\r
+\r
+    //wxMessageBox(wxString(bstr));\r
+\r
+    // TODO: check encoding\r
+    return wxString(bstr);\r
+}\r
+\r
+// FIXME? retrieve OLECMDID_GETZOOMRANGE instead of hardcoding range 0-4\r
+wxWebViewZoom wxWebViewIE::GetZoom()\r
+{\r
+    const int zoom = GetIETextZoom();\r
+\r
+    switch (zoom)\r
+    {\r
+        case 0:\r
+            return wxWEB_VIEW_ZOOM_TINY;\r
+            break;\r
+        case 1:\r
+            return wxWEB_VIEW_ZOOM_SMALL;\r
+            break;\r
+        case 2:\r
+            return wxWEB_VIEW_ZOOM_MEDIUM;\r
+            break;\r
+        case 3:\r
+            return wxWEB_VIEW_ZOOM_LARGE;\r
+            break;\r
+        case 4:\r
+            return wxWEB_VIEW_ZOOM_LARGEST;\r
+            break;\r
+        default:\r
+            wxASSERT(false);\r
+            return wxWEB_VIEW_ZOOM_MEDIUM;\r
+    }\r
+}\r
+void wxWebViewIE::SetZoom(wxWebViewZoom zoom)\r
+{\r
+    // I know I could cast from enum to int since wxWebViewZoom happens to\r
+    // match with IE's zoom levels, but I don't like doing that, what if enum\r
+    // values change...\r
+    switch (zoom)\r
+    {\r
+        case wxWEB_VIEW_ZOOM_TINY:\r
+            SetIETextZoom(0);\r
+            break;\r
+        case wxWEB_VIEW_ZOOM_SMALL:\r
+            SetIETextZoom(1);\r
+            break;\r
+        case wxWEB_VIEW_ZOOM_MEDIUM:\r
+            SetIETextZoom(2);\r
+            break;\r
+        case wxWEB_VIEW_ZOOM_LARGE:\r
+            SetIETextZoom(3);\r
+            break;\r
+        case wxWEB_VIEW_ZOOM_LARGEST:\r
+            SetIETextZoom(4);\r
+            break;\r
+        default:\r
+            wxASSERT(false);\r
+    }\r
+}\r
+\r
+void wxWebViewIE::SetIETextZoom(int level)\r
+{\r
+    VARIANT zoomVariant;\r
+    VariantInit (&zoomVariant);\r
+    V_VT(&zoomVariant) = VT_I4;\r
+    V_I4(&zoomVariant) = level;\r
+\r
+    HRESULT result = m_webBrowser->ExecWB(OLECMDID_ZOOM,\r
+                                          OLECMDEXECOPT_DONTPROMPTUSER,\r
+                                          &zoomVariant, NULL);\r
+    wxASSERT (result == S_OK);\r
+\r
+    VariantClear (&zoomVariant);\r
+}\r
+\r
+int wxWebViewIE::GetIETextZoom()\r
+{\r
+    VARIANT zoomVariant;\r
+    VariantInit (&zoomVariant);\r
+    V_VT(&zoomVariant) = VT_I4;\r
+    V_I4(&zoomVariant) = 4;\r
+\r
+    HRESULT result = m_webBrowser->ExecWB(OLECMDID_ZOOM,\r
+                                          OLECMDEXECOPT_DONTPROMPTUSER,\r
+                                          NULL, &zoomVariant);\r
+    wxASSERT (result == S_OK);\r
+\r
+    int zoom = V_I4(&zoomVariant);\r
+   // wxMessageBox(wxString::Format("Zoom : %i", zoom));\r
+    VariantClear (&zoomVariant);\r
+\r
+    return zoom;\r
+}\r
+\r
+void wxWebViewIE::SetIEOpticalZoom(float zoom)\r
+{\r
+    // TODO: add support for optical zoom (IE7+ only)\r
+\r
+    // TODO: get range from OLECMDID_OPTICAL_GETZOOMRANGE instead of hardcoding?\r
+    wxASSERT(zoom >= 10.0f);\r
+    wxASSERT(zoom <= 1000.0f);\r
+\r
+    VARIANT zoomVariant;\r
+    VariantInit (&zoomVariant);\r
+    V_VT(&zoomVariant) = VT_I4;\r
+    V_I4(&zoomVariant) = (zoom * 100.0f);\r
+\r
+    HRESULT result = m_webBrowser->ExecWB((OLECMDID)OLECMDID_OPTICAL_ZOOM,\r
+                                          OLECMDEXECOPT_DODEFAULT,\r
+                                          &zoomVariant,\r
+                                          NULL);\r
+    wxASSERT (result == S_OK);\r
+}\r
+\r
+float wxWebViewIE::GetIEOpticalZoom()\r
+{\r
+    // TODO: add support for optical zoom (IE7+ only)\r
+\r
+    VARIANT zoomVariant;\r
+    VariantInit (&zoomVariant);\r
+    V_VT(&zoomVariant) = VT_I4;\r
+    V_I4(&zoomVariant) = -1;\r
+\r
+    HRESULT result = m_webBrowser->ExecWB((OLECMDID)OLECMDID_OPTICAL_ZOOM,\r
+                                          OLECMDEXECOPT_DODEFAULT, NULL,\r
+                                          &zoomVariant);\r
+    wxASSERT (result == S_OK);\r
+\r
+    const int zoom = V_I4(&zoomVariant);\r
+    VariantClear (&zoomVariant);\r
+\r
+    return zoom / 100.0f;\r
+}\r
+\r
+void wxWebViewIE::SetZoomType(wxWebViewZoomType)\r
+{\r
+    // TODO: add support for optical zoom (IE7+ only)\r
+    wxASSERT(false);\r
+}\r
+\r
+wxWebViewZoomType wxWebViewIE::GetZoomType() const\r
+{\r
+    // TODO: add support for optical zoom (IE7+ only)\r
+    return wxWEB_VIEW_ZOOM_TYPE_TEXT;\r
+}\r
+\r
+bool wxWebViewIE::CanSetZoomType(wxWebViewZoomType) const\r
+{\r
+    // both are supported\r
+    // TODO: IE6 only supports text zoom, check if it's IE6 first\r
+    return true;\r
+}\r
+\r
+void wxWebViewIE::Print()\r
+{\r
+    m_webBrowser->ExecWB(OLECMDID_PRINTPREVIEW,\r
+                         OLECMDEXECOPT_DODEFAULT, NULL, NULL);\r
+}\r
+\r
+void wxWebViewIE::GoBack()\r
+{\r
+    wxVariant out = m_ie.CallMethod("GoBack");\r
+\r
+    // FIXME: why is out value null??\r
+    //return (HRESULT)(out.GetLong()) == S_OK;\r
+}\r
+\r
+void wxWebViewIE::GoForward()\r
+{\r
+    wxVariant out = m_ie.CallMethod("GoForward");\r
+\r
+    // FIXME: why is out value null??\r
+    //return (HRESULT)(out.GetLong()) == S_OK;\r
+}\r
+\r
+void wxWebViewIE::Stop()\r
+{\r
+    wxVariant out = m_ie.CallMethod("Stop");\r
+\r
+    // FIXME: why is out value null??\r
+    //return (HRESULT)(out.GetLong()) == S_OK;\r
+}\r
+\r
+\r
+void wxWebViewIE::Reload(wxWebViewReloadFlags flags)\r
+{\r
+    wxVariant out;\r
+\r
+    if (flags & wxWEB_VIEW_RELOAD_NO_CACHE)\r
+    {\r
+        VARIANTARG level;\r
+        level.vt = VT_I2;\r
+        level.iVal = 3;\r
+        out = m_ie.CallMethod("Refresh2", &level);\r
+    }\r
+    else\r
+    {\r
+        out = m_ie.CallMethod("Refresh");\r
+    }\r
+\r
+    if (out.GetType() != "null")\r
+    {\r
+        wxMessageBox("Non-null return message : " + out.GetType());\r
+    }\r
+}\r
+\r
+bool wxWebViewIE::IsOfflineMode()\r
+{\r
+    wxVariant out = m_ie.GetProperty("Offline");\r
+\r
+    wxASSERT(out.GetType() == "bool");\r
+\r
+    return out.GetBool();\r
+}\r
+\r
+void wxWebViewIE::SetOfflineMode(bool offline)\r
+{\r
+    // FIXME: the wxWidgets docs do not really document what the return\r
+    //        parameter of PutProperty is\r
+    const bool success = m_ie.PutProperty("Offline", (offline ?\r
+                                                      VARIANT_TRUE :\r
+                                                      VARIANT_FALSE));\r
+    wxASSERT(success);\r
+}\r
+\r
+bool wxWebViewIE::IsBusy()\r
+{\r
+    if (m_isBusy) return true;\r
+\r
+    wxVariant out = m_ie.GetProperty("Busy");\r
+\r
+    wxASSERT(out.GetType() == "bool");\r
+\r
+    return out.GetBool();\r
+}\r
+\r
+wxString wxWebViewIE::GetCurrentURL()\r
+{\r
+    wxVariant out = m_ie.GetProperty("LocationURL");\r
+\r
+    wxASSERT(out.GetType() == "string");\r
+    return out.GetString();\r
+}\r
+\r
+wxString wxWebViewIE::GetCurrentTitle()\r
+{\r
+    wxVariant out = m_ie.GetProperty("LocationName");\r
+\r
+    wxASSERT(out.GetType() == "string");\r
+    return out.GetString();\r
+}\r
+\r
+void wxWebViewIE::onActiveXEvent(wxActiveXEvent& evt)\r
+{\r
+    if (m_webBrowser == NULL) return;\r
+\r
+    switch (evt.GetDispatchId())\r
+    {\r
+        case DISPID_BEFORENAVIGATE2:\r
+        {\r
+            m_isBusy = true;\r
+\r
+            wxString url = evt[1].GetString();\r
+            wxString target = evt[3].GetString();\r
+\r
+            wxWebNavigationEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING,\r
+                                       GetId(), url, target, true);\r
+            event.SetEventObject(this);\r
+            HandleWindowEvent(event);\r
+\r
+            if (event.IsVetoed())\r
+            {\r
+                wxActiveXEventNativeMSW* nativeParams =\r
+                    evt.GetNativeParameters();\r
+                *V_BOOLREF(&nativeParams->pDispParams->rgvarg[0]) = VARIANT_TRUE;\r
+            }\r
+\r
+            // at this point, either the navigation event has been cancelled\r
+            // and we're not busy, either it was accepted and IWebBrowser2's\r
+            // Busy property will be true; so we don't need our override\r
+            // flag anymore.\r
+            m_isBusy = false;\r
+\r
+            break;\r
+        }\r
+\r
+        case DISPID_NAVIGATECOMPLETE2:\r
+        {\r
+            wxString url = evt[1].GetString();\r
+            // TODO: set target parameter if possible\r
+            wxString target = wxEmptyString;\r
+            wxWebNavigationEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,\r
+                                       GetId(), url, target, false);\r
+            event.SetEventObject(this);\r
+            HandleWindowEvent(event);\r
+            break;\r
+        }\r
+\r
+        case DISPID_PROGRESSCHANGE:\r
+        {\r
+            // download progress\r
+            break;\r
+        }\r
+\r
+        case DISPID_DOCUMENTCOMPLETE:\r
+        {\r
+            wxString url = evt[1].GetString();\r
+            // TODO: set target parameter if possible\r
+            wxString target = wxEmptyString;\r
+            wxWebNavigationEvent event(wxEVT_COMMAND_WEB_VIEW_LOADED, GetId(),\r
+                                       url, target, false);\r
+            event.SetEventObject(this);\r
+            HandleWindowEvent(event);\r
+            break;\r
+        }\r
+\r
+        case DISPID_STATUSTEXTCHANGE:\r
+        {\r
+            break;\r
+        }\r
+\r
+        case DISPID_TITLECHANGE:\r
+        {\r
+            break;\r
+        }\r
+\r
+        case DISPID_NAVIGATEERROR:\r
+        {\r
+            wxWebNavigationError errorType = wxWEB_NAV_ERR_OTHER;\r
+            wxString errorCode = "?";\r
+            switch (evt[3].GetLong())\r
+            {\r
+            case INET_E_INVALID_URL: // (0x800C0002L or -2146697214)\r
+                errorCode = "INET_E_INVALID_URL";\r
+                errorType = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+            case INET_E_NO_SESSION: // (0x800C0003L or -2146697213)\r
+                errorCode = "INET_E_NO_SESSION";\r
+                errorType = wxWEB_NAV_ERR_CONNECTION;\r
+                break;\r
+            case INET_E_CANNOT_CONNECT: // (0x800C0004L or -2146697212)\r
+                errorCode = "INET_E_CANNOT_CONNECT";\r
+                errorType = wxWEB_NAV_ERR_CONNECTION;\r
+                break;\r
+            case INET_E_RESOURCE_NOT_FOUND: // (0x800C0005L or -2146697211)\r
+                errorCode = "INET_E_RESOURCE_NOT_FOUND";\r
+                errorType = wxWEB_NAV_ERR_NOT_FOUND;\r
+                break;\r
+            case INET_E_OBJECT_NOT_FOUND: // (0x800C0006L or -2146697210)\r
+                errorCode = "INET_E_OBJECT_NOT_FOUND";\r
+                errorType = wxWEB_NAV_ERR_NOT_FOUND;\r
+                break;\r
+            case INET_E_DATA_NOT_AVAILABLE: // (0x800C0007L or -2146697209)\r
+                errorCode = "INET_E_DATA_NOT_AVAILABLE";\r
+                errorType = wxWEB_NAV_ERR_NOT_FOUND;\r
+                break;\r
+            case INET_E_DOWNLOAD_FAILURE: // (0x800C0008L or -2146697208)\r
+                errorCode = "INET_E_DOWNLOAD_FAILURE";\r
+                errorType = wxWEB_NAV_ERR_CONNECTION;\r
+                break;\r
+            case INET_E_AUTHENTICATION_REQUIRED: // (0x800C0009L or -2146697207)\r
+                errorCode = "INET_E_AUTHENTICATION_REQUIRED";\r
+                errorType = wxWEB_NAV_ERR_AUTH;\r
+                break;\r
+            case INET_E_NO_VALID_MEDIA: // (0x800C000AL or -2146697206)\r
+                errorCode = "INET_E_NO_VALID_MEDIA";\r
+                errorType = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+            case INET_E_CONNECTION_TIMEOUT: // (0x800C000BL or -2146697205)\r
+                errorCode = "INET_E_CONNECTION_TIMEOUT";\r
+                errorType = wxWEB_NAV_ERR_CONNECTION;\r
+                break;\r
+            case INET_E_INVALID_REQUEST: // (0x800C000CL or -2146697204)\r
+                errorCode = "INET_E_INVALID_REQUEST";\r
+                errorType = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+            case INET_E_UNKNOWN_PROTOCOL: // (0x800C000DL or -2146697203)\r
+                errorCode = "INET_E_UNKNOWN_PROTOCOL";\r
+                errorType = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+            case INET_E_SECURITY_PROBLEM: // (0x800C000EL or -2146697202)\r
+                errorCode = "INET_E_SECURITY_PROBLEM";\r
+                errorType = wxWEB_NAV_ERR_SECURITY;\r
+                break;\r
+            case INET_E_CANNOT_LOAD_DATA: // (0x800C000FL or -2146697201)\r
+                errorCode = "INET_E_CANNOT_LOAD_DATA";\r
+                errorType = wxWEB_NAV_ERR_OTHER;\r
+                break;\r
+            case INET_E_CANNOT_INSTANTIATE_OBJECT:\r
+                // CoCreateInstance will return an error code if this happens,\r
+                // we'll handle this above.\r
+                return;\r
+                break;\r
+            case INET_E_REDIRECT_FAILED: // (0x800C0014L or -2146697196)\r
+                errorCode = "INET_E_REDIRECT_FAILED";\r
+                errorType = wxWEB_NAV_ERR_OTHER;\r
+                break;\r
+            case INET_E_REDIRECT_TO_DIR: // (0x800C0015L or -2146697195)\r
+                errorCode = "INET_E_REDIRECT_TO_DIR";\r
+                errorType = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+            case INET_E_CANNOT_LOCK_REQUEST: // (0x800C0016L or -2146697194)\r
+                errorCode = "INET_E_CANNOT_LOCK_REQUEST";\r
+                errorType = wxWEB_NAV_ERR_OTHER;\r
+                break;\r
+            case INET_E_USE_EXTEND_BINDING: // (0x800C0017L or -2146697193)\r
+                errorCode = "INET_E_USE_EXTEND_BINDING";\r
+                errorType = wxWEB_NAV_ERR_OTHER;\r
+                break;\r
+            case INET_E_TERMINATED_BIND: // (0x800C0018L or -2146697192)\r
+                errorCode = "INET_E_TERMINATED_BIND";\r
+                errorType = wxWEB_NAV_ERR_OTHER;\r
+                break;\r
+            case INET_E_INVALID_CERTIFICATE: // (0x800C0019L or -2146697191)\r
+                errorCode = "INET_E_INVALID_CERTIFICATE";\r
+                errorType = wxWEB_NAV_ERR_CERTIFICATE;\r
+                break;\r
+            case INET_E_CODE_DOWNLOAD_DECLINED: // (0x800C0100L or -2146696960)\r
+                errorCode = "INET_E_CODE_DOWNLOAD_DECLINED";\r
+                errorType = wxWEB_NAV_ERR_USER_CANCELLED;\r
+                break;\r
+            case INET_E_RESULT_DISPATCHED: // (0x800C0200L or -2146696704)\r
+                // cancel request cancelled...\r
+                errorCode = "INET_E_RESULT_DISPATCHED";\r
+                errorType = wxWEB_NAV_ERR_OTHER;\r
+                break;\r
+            case INET_E_CANNOT_REPLACE_SFP_FILE: // (0x800C0300L or -2146696448)\r
+                errorCode = "INET_E_CANNOT_REPLACE_SFP_FILE";\r
+                errorType = wxWEB_NAV_ERR_SECURITY;\r
+                break;\r
+            case INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY:\r
+                errorCode = "INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY";\r
+                errorType = wxWEB_NAV_ERR_SECURITY;\r
+                break;\r
+            case INET_E_CODE_INSTALL_SUPPRESSED:\r
+                errorCode = "INET_E_CODE_INSTALL_SUPPRESSED";\r
+                errorType = wxWEB_NAV_ERR_SECURITY;\r
+                break;\r
+            }\r
+\r
+            wxString url = evt[1].GetString();\r
+            wxString target = evt[2].GetString();\r
+            wxWebNavigationEvent event(wxEVT_COMMAND_WEB_VIEW_ERROR, GetId(),\r
+                                       url, target, false);\r
+            event.SetEventObject(this);\r
+            event.SetInt(errorType);\r
+            event.SetString(errorCode);\r
+            HandleWindowEvent(event);\r
+            break;\r
+        }\r
+\r
+        case DISPID_COMMANDSTATECHANGE:\r
+        {\r
+            long commandId = evt[0].GetLong();\r
+            bool enable = evt[1].GetBool();\r
+            if (commandId == CSC_NAVIGATEBACK)\r
+            {\r
+                m_canNavigateBack = enable;\r
+            }\r
+            else if (commandId == CSC_NAVIGATEFORWARD)\r
+            {\r
+                m_canNavigateForward = enable;\r
+            }\r
+        }\r
+\r
+        /*\r
+        case DISPID_NEWWINDOW2:\r
+        //case DISPID_NEWWINDOW3:\r
+        {\r
+            wxLogMessage("DISPID_NEWWINDOW2\n");\r
+            wxActiveXEventNativeMSW* nativeParams = evt.GetNativeParameters();\r
+            // Cancel the attempt to open a new window\r
+            *V_BOOLREF(&nativeParams->pDispParams->rgvarg[0]) = VARIANT_TRUE;\r
+        }*/\r
+    }\r
+\r
+    evt.Skip();\r
+}\r
+\r
+#endif\r
diff --git a/src/osx/webview.mm b/src/osx/webview.mm
new file mode 100644 (file)
index 0000000..83b1336
--- /dev/null
@@ -0,0 +1,1208 @@
+/////////////////////////////////////////////////////////////////////////////\r
+// Name:        src/osx/webkit.mm\r
+// Purpose:     wxOSXWebKitCtrl - embeddable web kit control,\r
+//                             OS X implementation of web view component\r
+// Author:      Jethro Grassie / Kevin Ollivier / Marianne Gagnon\r
+// Modified by:\r
+// Created:     2004-4-16\r
+// RCS-ID:      $Id: webkit.mm 64943 2010-07-13 13:29:58Z VZ $\r
+// Copyright:   (c) Jethro Grassie / Kevin Ollivier / Marianne Gagnon\r
+// Licence:     wxWindows licence\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+// http://developer.apple.com/mac/library/documentation/Cocoa/Reference/WebKit/Classes/WebView_Class/Reference/Reference.html\r
+\r
+#include "wx/osx/webview.h"\r
+\r
+// For compilers that support precompilation, includes "wx.h".\r
+#include "wx/wxprec.h"\r
+\r
+#ifndef WX_PRECOMP\r
+    #include "wx/wx.h"\r
+#endif\r
+\r
+#if wxHAVE_WEB_BACKEND_OSX_WEBKIT\r
+\r
+#ifdef __WXCOCOA__\r
+#include "wx/cocoa/autorelease.h"\r
+#else\r
+#include "wx/osx/private.h"\r
+\r
+#include <WebKit/WebKit.h>\r
+#include <WebKit/HIWebView.h>\r
+#include <WebKit/CarbonUtils.h>\r
+#endif\r
+\r
+#include <Foundation/NSURLError.h>\r
+\r
+// FIXME: find cleaner way to find the wxWidgets ID of a webview than this hack\r
+#include <map>\r
+std::map<WebView*, wxOSXWebKitCtrl*> wx_webviewctrls;\r
+\r
+#define DEBUG_WEBKIT_SIZING 0\r
+\r
+// ----------------------------------------------------------------------------\r
+// macros\r
+// ----------------------------------------------------------------------------\r
+\r
+IMPLEMENT_DYNAMIC_CLASS(wxOSXWebKitCtrl, wxControl)\r
+\r
+BEGIN_EVENT_TABLE(wxOSXWebKitCtrl, wxControl)\r
+#if defined(__WXMAC__) && wxOSX_USE_CARBON\r
+    EVT_SIZE(wxOSXWebKitCtrl::OnSize)\r
+#endif\r
+END_EVENT_TABLE()\r
+\r
+#if defined(__WXOSX__) && wxOSX_USE_CARBON\r
+\r
+// ----------------------------------------------------------------------------\r
+// Carbon Events handlers\r
+// ----------------------------------------------------------------------------\r
+\r
+// prototype for function in src/osx/carbon/nonownedwnd.cpp\r
+void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent );\r
+\r
+static const EventTypeSpec eventList[] =\r
+{\r
+    //{ kEventClassControl, kEventControlTrack } ,\r
+    { kEventClassMouse, kEventMouseUp },\r
+    { kEventClassMouse, kEventMouseDown },\r
+    { kEventClassMouse, kEventMouseMoved },\r
+    { kEventClassMouse, kEventMouseDragged },\r
+\r
+    { kEventClassKeyboard, kEventRawKeyDown } ,\r
+    { kEventClassKeyboard, kEventRawKeyRepeat } ,\r
+    { kEventClassKeyboard, kEventRawKeyUp } ,\r
+    { kEventClassKeyboard, kEventRawKeyModifiersChanged } ,\r
+\r
+    { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,\r
+    { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } ,\r
+\r
+#if DEBUG_WEBKIT_SIZING == 1\r
+    { kEventClassControl, kEventControlBoundsChanged } ,\r
+#endif\r
+};\r
+\r
+// mix this in from window.cpp\r
+pascal OSStatus wxMacUnicodeTextEventHandler(EventHandlerCallRef handler,\r
+                                             EventRef event, void *data) ;\r
+\r
+// NOTE: This is mostly taken from KeyboardEventHandler in toplevel.cpp, but\r
+// that expects the data pointer is a top-level window, so I needed to change\r
+// that in this case. However, once 2.8 is out, we should factor out the common\r
+// logic among the two functions and merge them.\r
+static pascal OSStatus wxWebKitKeyEventHandler(EventHandlerCallRef handler,\r
+                                               EventRef event, void *data)\r
+{\r
+    OSStatus result = eventNotHandledErr ;\r
+    wxMacCarbonEvent cEvent( event ) ;\r
+\r
+    wxOSXWebKitCtrl* thisWindow = (wxOSXWebKitCtrl*) data ;\r
+    wxWindow* focus = thisWindow ;\r
+\r
+    unsigned char charCode ;\r
+    wxChar uniChar[2] ;\r
+    uniChar[0] = 0;\r
+    uniChar[1] = 0;\r
+\r
+    UInt32 keyCode ;\r
+    UInt32 modifiers ;\r
+    Point point ;\r
+    UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;\r
+\r
+#if wxUSE_UNICODE\r
+    ByteCount dataSize = 0 ;\r
+    if ( GetEventParameter(event, kEventParamKeyUnicodes, typeUnicodeText,\r
+                           NULL, 0 , &dataSize, NULL ) == noErr)\r
+    {\r
+        UniChar buf[2] ;\r
+        int numChars = dataSize / sizeof( UniChar) + 1;\r
+\r
+        UniChar* charBuf = buf ;\r
+\r
+        if ( numChars * 2 > 4 )\r
+            charBuf = new UniChar[ numChars ] ;\r
+        GetEventParameter(event, kEventParamKeyUnicodes, typeUnicodeText, NULL,\r
+                          dataSize , NULL , charBuf) ;\r
+        charBuf[ numChars - 1 ] = 0;\r
+\r
+#if SIZEOF_WCHAR_T == 2\r
+        uniChar = charBuf[0] ;\r
+#else\r
+        wxMBConvUTF16 converter ;\r
+        converter.MB2WC( uniChar , (const char*)charBuf , 2 ) ;\r
+#endif\r
+\r
+        if ( numChars * 2 > 4 )\r
+            delete[] charBuf ;\r
+    }\r
+#endif\r
+\r
+    GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL,\r
+                      sizeof(char), NULL, &charCode );\r
+    GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL,\r
+                      sizeof(UInt32), NULL, &keyCode );\r
+    GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL,\r
+                      sizeof(UInt32), NULL, &modifiers );\r
+    GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL,\r
+                      sizeof(Point), NULL, &point );\r
+\r
+    UInt32 message = (keyCode << 8) + charCode;\r
+    switch ( GetEventKind( event ) )\r
+    {\r
+        case kEventRawKeyRepeat :\r
+        case kEventRawKeyDown :\r
+        {\r
+            WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;\r
+            WXEVENTHANDLERCALLREF formerHandler =\r
+                wxTheApp->MacGetCurrentEventHandlerCallRef() ;\r
+\r
+            wxTheApp->MacSetCurrentEvent( event , handler ) ;\r
+            if ( /* focus && */ wxTheApp->MacSendKeyDownEvent(\r
+                focus, message, modifiers, when, point.h, point.v, uniChar[0]))\r
+            {\r
+                result = noErr ;\r
+            }\r
+            wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;\r
+        }\r
+        break ;\r
+\r
+        case kEventRawKeyUp :\r
+            if ( /* focus && */ wxTheApp->MacSendKeyUpEvent(\r
+                focus , message , modifiers , when , point.h , point.v , uniChar[0] ) )\r
+            {\r
+                result = noErr ;\r
+            }\r
+            break ;\r
+\r
+        case kEventRawKeyModifiersChanged :\r
+            {\r
+                wxKeyEvent event(wxEVT_KEY_DOWN);\r
+\r
+                event.m_shiftDown = modifiers & shiftKey;\r
+                event.m_controlDown = modifiers & controlKey;\r
+                event.m_altDown = modifiers & optionKey;\r
+                event.m_metaDown = modifiers & cmdKey;\r
+                event.m_x = point.h;\r
+                event.m_y = point.v;\r
+\r
+#if wxUSE_UNICODE\r
+                event.m_uniChar = uniChar[0] ;\r
+#endif\r
+\r
+                event.SetTimestamp(when);\r
+                event.SetEventObject(focus);\r
+\r
+                if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & controlKey )\r
+                {\r
+                    event.m_keyCode = WXK_CONTROL ;\r
+                    event.SetEventType( ( modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;\r
+                    focus->GetEventHandler()->ProcessEvent( event ) ;\r
+                }\r
+                if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & shiftKey )\r
+                {\r
+                    event.m_keyCode = WXK_SHIFT ;\r
+                    event.SetEventType( ( modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;\r
+                    focus->GetEventHandler()->ProcessEvent( event ) ;\r
+                }\r
+                if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & optionKey )\r
+                {\r
+                    event.m_keyCode = WXK_ALT ;\r
+                    event.SetEventType( ( modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;\r
+                    focus->GetEventHandler()->ProcessEvent( event ) ;\r
+                }\r
+                if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & cmdKey )\r
+                {\r
+                    event.m_keyCode = WXK_COMMAND ;\r
+                    event.SetEventType( ( modifiers & cmdKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;\r
+                    focus->GetEventHandler()->ProcessEvent( event ) ;\r
+                }\r
+\r
+                wxApp::s_lastModifiers = modifiers ;\r
+            }\r
+            break ;\r
+\r
+        default:\r
+            break;\r
+    }\r
+\r
+    return result ;\r
+}\r
+\r
+static pascal OSStatus wxOSXWebKitCtrlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )\r
+{\r
+    OSStatus result = eventNotHandledErr ;\r
+\r
+    wxMacCarbonEvent cEvent( event ) ;\r
+\r
+    ControlRef controlRef ;\r
+    wxOSXWebKitCtrl* thisWindow = (wxOSXWebKitCtrl*) data ;\r
+    wxNonOwnedWindow* tlw = NULL;\r
+    if (thisWindow)\r
+        tlw = thisWindow->MacGetTopLevelWindow();\r
+\r
+    cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;\r
+\r
+    wxWindow* currentMouseWindow = thisWindow ;\r
+\r
+    if ( wxApp::s_captureWindow )\r
+        currentMouseWindow = wxApp::s_captureWindow;\r
+\r
+    switch ( GetEventClass( event ) )\r
+    {\r
+        case kEventClassKeyboard:\r
+        {\r
+            result = wxWebKitKeyEventHandler(handler, event, data);\r
+            break;\r
+        }\r
+\r
+        case kEventClassTextInput:\r
+        {\r
+            result = wxMacUnicodeTextEventHandler(handler, event, data);\r
+            break;\r
+        }\r
+\r
+        case kEventClassMouse:\r
+        {\r
+            switch ( GetEventKind( event ) )\r
+            {\r
+                case kEventMouseDragged :\r
+                case kEventMouseMoved :\r
+                case kEventMouseDown :\r
+                case kEventMouseUp :\r
+                {\r
+                    wxMouseEvent wxevent(wxEVT_LEFT_DOWN);\r
+                    SetupMouseEvent( wxevent , cEvent ) ;\r
+\r
+                    currentMouseWindow->ScreenToClient( &wxevent.m_x , &wxevent.m_y ) ;\r
+                    wxevent.SetEventObject( currentMouseWindow ) ;\r
+                    wxevent.SetId( currentMouseWindow->GetId() ) ;\r
+\r
+                    if ( currentMouseWindow->GetEventHandler()->ProcessEvent(wxevent) )\r
+                    {\r
+                        result = noErr;\r
+                    }\r
+\r
+                    break; // this should enable WebKit to fire mouse dragged and mouse up events...\r
+                }\r
+                default :\r
+                    break ;\r
+            }\r
+        }\r
+        default:\r
+            break;\r
+    }\r
+\r
+    result = CallNextEventHandler(handler, event);\r
+    return result ;\r
+}\r
+\r
+DEFINE_ONE_SHOT_HANDLER_GETTER( wxOSXWebKitCtrlEventHandler )\r
+\r
+#endif\r
+\r
+//---------------------------------------------------------\r
+// helper functions for NSString<->wxString conversion\r
+//---------------------------------------------------------\r
+\r
+inline wxString wxStringWithNSString(NSString *nsstring)\r
+{\r
+#if wxUSE_UNICODE\r
+    return wxString([nsstring UTF8String], wxConvUTF8);\r
+#else\r
+    return wxString([nsstring lossyCString]);\r
+#endif // wxUSE_UNICODE\r
+}\r
+\r
+inline NSString* wxNSStringWithWxString(const wxString &wxstring)\r
+{\r
+#if wxUSE_UNICODE\r
+    return [NSString stringWithUTF8String: wxstring.mb_str(wxConvUTF8)];\r
+#else\r
+    return [NSString stringWithCString: wxstring.c_str() length:wxstring.Len()];\r
+#endif // wxUSE_UNICODE\r
+}\r
+\r
+inline int wxNavTypeFromWebNavType(int type){\r
+    if (type == WebNavigationTypeLinkClicked)\r
+        return wxWEBKIT_NAV_LINK_CLICKED;\r
+\r
+    if (type == WebNavigationTypeFormSubmitted)\r
+        return wxWEBKIT_NAV_FORM_SUBMITTED;\r
+\r
+    if (type == WebNavigationTypeBackForward)\r
+        return wxWEBKIT_NAV_BACK_NEXT;\r
+\r
+    if (type == WebNavigationTypeReload)\r
+        return wxWEBKIT_NAV_RELOAD;\r
+\r
+    if (type == WebNavigationTypeFormResubmitted)\r
+        return wxWEBKIT_NAV_FORM_RESUBMITTED;\r
+\r
+    return wxWEBKIT_NAV_OTHER;\r
+}\r
+\r
+@interface MyFrameLoadMonitor : NSObject\r
+{\r
+    wxOSXWebKitCtrl* webKitWindow;\r
+}\r
+\r
+- initWithWxWindow: (wxOSXWebKitCtrl*)inWindow;\r
+\r
+@end\r
+\r
+@interface MyPolicyDelegate : NSObject\r
+{\r
+    wxOSXWebKitCtrl* webKitWindow;\r
+}\r
+\r
+- initWithWxWindow: (wxOSXWebKitCtrl*)inWindow;\r
+\r
+@end\r
+\r
+// ----------------------------------------------------------------------------\r
+// creation/destruction\r
+// ----------------------------------------------------------------------------\r
+\r
+bool wxOSXWebKitCtrl::Create(wxWindow *parent,\r
+                                 wxWindowID winID,\r
+                                 const wxString& strURL,\r
+                                 const wxPoint& pos,\r
+                                 const wxSize& size, long style,\r
+                                 const wxString& name)\r
+{\r
+    m_busy = false;\r
+    //m_pageTitle = _("Untitled Page");\r
+\r
+ //still needed for wxCocoa??\r
+/*\r
+    int width, height;\r
+    wxSize sizeInstance;\r
+    if (size.x == wxDefaultCoord || size.y == wxDefaultCoord)\r
+    {\r
+        m_parent->GetClientSize(&width, &height);\r
+        sizeInstance.x = width;\r
+        sizeInstance.y = height;\r
+    }\r
+    else\r
+    {\r
+        sizeInstance.x = size.x;\r
+        sizeInstance.y = size.y;\r
+    }\r
+*/\r
+    // now create and attach WebKit view...\r
+#ifdef __WXCOCOA__\r
+    wxControl::Create(parent, m_windowID, pos, sizeInstance, style, name);\r
+    SetSize(pos.x, pos.y, sizeInstance.x, sizeInstance.y);\r
+\r
+    wxTopLevelWindowCocoa *topWin = wxDynamicCast(this, wxTopLevelWindowCocoa);\r
+    NSWindow* nsWin = topWin->GetNSWindow();\r
+    NSRect rect;\r
+    rect.origin.x = pos.x;\r
+    rect.origin.y = pos.y;\r
+    rect.size.width = sizeInstance.x;\r
+    rect.size.height = sizeInstance.y;\r
+    m_webView = (WebView*)[[WebView alloc] initWithFrame:rect\r
+                                               frameName:@"webkitFrame"\r
+                                               groupName:@"webkitGroup"];\r
+    SetNSView(m_webView);\r
+    [m_cocoaNSView release];\r
+\r
+    if(m_parent) m_parent->CocoaAddChild(this);\r
+    SetInitialFrameRect(pos,sizeInstance);\r
+#else\r
+    m_macIsUserPane = false;\r
+    wxControl::Create(parent, winID, pos, size, style, wxDefaultValidator, name);\r
+\r
+#if wxOSX_USE_CARBON\r
+    m_peer = new wxMacControl(this);\r
+    WebInitForCarbon();\r
+    HIWebViewCreate( m_peer->GetControlRefAddr() );\r
+\r
+    m_webView = (WebView*) HIWebViewGetWebView( m_peer->GetControlRef() );\r
+\r
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3\r
+    if ( UMAGetSystemVersion() >= 0x1030 )\r
+        HIViewChangeFeatures( m_peer->GetControlRef() , kHIViewIsOpaque , 0 ) ;\r
+#endif\r
+    InstallControlEventHandler(m_peer->GetControlRef(),\r
+                               GetwxOSXWebKitCtrlEventHandlerUPP(),\r
+                               GetEventTypeCount(eventList), eventList, this,\r
+                              (EventHandlerRef *)&m_webKitCtrlEventHandler);\r
+#else\r
+    NSRect r = wxOSXGetFrameForControl( this, pos , size ) ;\r
+    m_webView = [[WebView alloc] initWithFrame:r\r
+                                     frameName:@"webkitFrame"\r
+                                     groupName:@"webkitGroup"];\r
+    m_peer = new wxWidgetCocoaImpl( this, m_webView );\r
+#endif\r
+\r
+    wx_webviewctrls[m_webView] = this;\r
+\r
+    MacPostControlCreate(pos, size);\r
+\r
+#if wxOSX_USE_CARBON\r
+    HIViewSetVisible( m_peer->GetControlRef(), true );\r
+#endif\r
+    [m_webView setHidden:false];\r
+\r
+#endif\r
+\r
+    // Register event listener interfaces\r
+    MyFrameLoadMonitor* myFrameLoadMonitor =\r
+            [[MyFrameLoadMonitor alloc] initWithWxWindow: this];\r
+\r
+    [m_webView setFrameLoadDelegate:myFrameLoadMonitor];\r
+\r
+    // this is used to veto page loads, etc.\r
+    MyPolicyDelegate* myPolicyDelegate =\r
+            [[MyPolicyDelegate alloc] initWithWxWindow: this];\r
+\r
+    [m_webView setPolicyDelegate:myPolicyDelegate];\r
+\r
+    InternalLoadURL(strURL);\r
+    return true;\r
+}\r
+\r
+wxOSXWebKitCtrl::~wxOSXWebKitCtrl()\r
+{\r
+    MyFrameLoadMonitor* myFrameLoadMonitor = [m_webView frameLoadDelegate];\r
+    MyPolicyDelegate* myPolicyDelegate = [m_webView policyDelegate];\r
+    [m_webView setFrameLoadDelegate: nil];\r
+    [m_webView setPolicyDelegate: nil];\r
+\r
+    if (myFrameLoadMonitor)\r
+        [myFrameLoadMonitor release];\r
+\r
+    if (myPolicyDelegate)\r
+        [myPolicyDelegate release];\r
+}\r
+\r
+// ----------------------------------------------------------------------------\r
+// public methods\r
+// ----------------------------------------------------------------------------\r
+\r
+void wxOSXWebKitCtrl::InternalLoadURL(const wxString &url)\r
+{\r
+    if( !m_webView )\r
+        return;\r
+\r
+    [[m_webView mainFrame] loadRequest:[NSURLRequest requestWithURL:\r
+            [NSURL URLWithString:wxNSStringWithWxString(url)]]];\r
+}\r
+\r
+bool wxOSXWebKitCtrl::CanGoBack()\r
+{\r
+    if ( !m_webView )\r
+        return false;\r
+\r
+    return [m_webView canGoBack];\r
+}\r
+\r
+bool wxOSXWebKitCtrl::CanGoForward()\r
+{\r
+    if ( !m_webView )\r
+        return false;\r
+\r
+    return [m_webView canGoForward];\r
+}\r
+\r
+void wxOSXWebKitCtrl::GoBack()\r
+{\r
+    if ( !m_webView )\r
+        return;\r
+\r
+    bool result = [(WebView*)m_webView goBack];\r
+\r
+    // TODO: return result (if it also exists in other backends...)\r
+    //return result;\r
+}\r
+\r
+void wxOSXWebKitCtrl::GoForward()\r
+{\r
+    if ( !m_webView )\r
+        return;\r
+\r
+    bool result = [(WebView*)m_webView goForward];\r
+\r
+    // TODO: return result (if it also exists in other backends...)\r
+    //return result;\r
+}\r
+\r
+void wxOSXWebKitCtrl::Reload(wxWebViewReloadFlags flags)\r
+{\r
+    if ( !m_webView )\r
+        return;\r
+\r
+    if (flags & wxWEB_VIEW_RELOAD_NO_CACHE)\r
+    {\r
+        // TODO: test this indeed bypasses the cache\r
+        [[m_webView preferences] setUsesPageCache:NO];\r
+        [[m_webView mainFrame] reload];\r
+        [[m_webView preferences] setUsesPageCache:YES];\r
+    }\r
+    else\r
+    {\r
+        [[m_webView mainFrame] reload];\r
+    }\r
+}\r
+\r
+void wxOSXWebKitCtrl::Stop()\r
+{\r
+    if ( !m_webView )\r
+        return;\r
+\r
+    [[m_webView mainFrame] stopLoading];\r
+}\r
+\r
+bool wxOSXWebKitCtrl::CanGetPageSource()\r
+{\r
+    if ( !m_webView )\r
+        return false;\r
+\r
+    WebDataSource* dataSource = [[m_webView mainFrame] dataSource];\r
+    return ( [[dataSource representation] canProvideDocumentSource] );\r
+}\r
+\r
+wxString wxOSXWebKitCtrl::GetPageSource()\r
+{\r
+\r
+    if (CanGetPageSource())\r
+       {\r
+        WebDataSource* dataSource = [[m_webView mainFrame] dataSource];\r
+               wxASSERT (dataSource != nil);\r
+\r
+               id<WebDocumentRepresentation> representation = [dataSource representation];\r
+               wxASSERT (representation != nil);\r
+\r
+               NSString* source = [representation documentSource];\r
+               if (source == nil)\r
+               {\r
+                       return wxEmptyString;\r
+               }\r
+\r
+        return wxStringWithNSString( source );\r
+    }\r
+\r
+    return wxEmptyString;\r
+}\r
+\r
+wxString wxOSXWebKitCtrl::GetSelection()\r
+{\r
+    if ( !m_webView )\r
+        return wxEmptyString;\r
+\r
+    NSString* selectedText = [[m_webView selectedDOMRange] toString];\r
+    return wxStringWithNSString( selectedText );\r
+}\r
+\r
+bool wxOSXWebKitCtrl::CanIncreaseTextSize()\r
+{\r
+    if ( !m_webView )\r
+        return false;\r
+\r
+    if ([m_webView canMakeTextLarger])\r
+        return true;\r
+    else\r
+        return false;\r
+}\r
+\r
+void wxOSXWebKitCtrl::IncreaseTextSize()\r
+{\r
+    if ( !m_webView )\r
+        return;\r
+\r
+    if (CanIncreaseTextSize())\r
+        [m_webView makeTextLarger:(WebView*)m_webView];\r
+}\r
+\r
+bool wxOSXWebKitCtrl::CanDecreaseTextSize()\r
+{\r
+    if ( !m_webView )\r
+        return false;\r
+\r
+    if ([m_webView canMakeTextSmaller])\r
+        return true;\r
+    else\r
+        return false;\r
+}\r
+\r
+void wxOSXWebKitCtrl::DecreaseTextSize()\r
+{\r
+    if ( !m_webView )\r
+        return;\r
+\r
+    if (CanDecreaseTextSize())\r
+        [m_webView makeTextSmaller:(WebView*)m_webView];\r
+}\r
+\r
+void wxOSXWebKitCtrl::Print()\r
+{\r
+\r
+    // TODO: allow specifying the "show prompt" parameter in Print() ?\r
+    bool showPrompt = true;\r
+\r
+    if ( !m_webView )\r
+        return;\r
+\r
+    id view = [[[m_webView mainFrame] frameView] documentView];\r
+    NSPrintOperation *op = [NSPrintOperation printOperationWithView:view\r
+                                 printInfo: [NSPrintInfo sharedPrintInfo]];\r
+    if (showPrompt)\r
+    {\r
+        [op setShowsPrintPanel: showPrompt];\r
+        // in my tests, the progress bar always freezes and it stops the whole\r
+        // print operation. do not turn this to true unless there is a \r
+        // workaround for the bug.\r
+        [op setShowsProgressPanel: false];\r
+    }\r
+    // Print it.\r
+    [op runOperation];\r
+}\r
+\r
+void wxOSXWebKitCtrl::MakeEditable(bool enable)\r
+{\r
+    if ( !m_webView )\r
+        return;\r
+\r
+    [m_webView setEditable:enable ];\r
+}\r
+\r
+bool wxOSXWebKitCtrl::IsEditable()\r
+{\r
+    if ( !m_webView )\r
+        return false;\r
+\r
+    return [m_webView isEditable];\r
+}\r
+\r
+void wxOSXWebKitCtrl::SetZoomType(wxWebViewZoomType zoomType)\r
+{\r
+    // there is only one supported zoom type at the moment so this setter\r
+    // does nothing beyond checking sanity\r
+    wxASSERT(zoomType == wxWEB_VIEW_ZOOM_TYPE_TEXT);\r
+}\r
+\r
+wxWebViewZoomType wxOSXWebKitCtrl::GetZoomType() const\r
+{\r
+    // for now that's the only one that is supported\r
+    // FIXME: does the default zoom type change depending on webkit versions? :S\r
+    //        Then this will be wrong\r
+    return wxWEB_VIEW_ZOOM_TYPE_TEXT;\r
+}\r
+\r
+bool wxOSXWebKitCtrl::CanSetZoomType(wxWebViewZoomType type) const\r
+{\r
+    switch (type)\r
+    {\r
+        // for now that's the only one that is supported\r
+        // TODO: I know recent versions of webkit support layout zoom too,\r
+        //       check if we can support it\r
+        case wxWEB_VIEW_ZOOM_TYPE_TEXT:\r
+            return true;\r
+\r
+        default:\r
+            return false;\r
+    }\r
+}\r
+\r
+int wxOSXWebKitCtrl::GetScrollPos()\r
+{\r
+    id result = [[m_webView windowScriptObject]\r
+                    evaluateWebScript:@"document.body.scrollTop"];\r
+    return [result intValue];\r
+}\r
+\r
+void wxOSXWebKitCtrl::SetScrollPos(int pos)\r
+{\r
+    if ( !m_webView )\r
+        return;\r
+\r
+    wxString javascript;\r
+    javascript.Printf(wxT("document.body.scrollTop = %d;"), pos);\r
+    [[m_webView windowScriptObject] evaluateWebScript:\r
+            (NSString*)wxNSStringWithWxString( javascript )];\r
+}\r
+\r
+wxString wxOSXWebKitCtrl::GetSelectedText()\r
+{\r
+    NSString* selection = [[m_webView selectedDOMRange] markupString];\r
+    if (!selection) return wxEmptyString;\r
+\r
+    return wxStringWithNSString(selection);\r
+}\r
+\r
+wxString wxOSXWebKitCtrl::RunScript(const wxString& javascript)\r
+{\r
+    if ( !m_webView )\r
+        return wxEmptyString;\r
+\r
+    id result = [[m_webView windowScriptObject] evaluateWebScript:\r
+                    (NSString*)wxNSStringWithWxString( javascript )];\r
+\r
+    NSString* resultAsString;\r
+    NSString* className = NSStringFromClass([result class]);\r
+\r
+    if ([className isEqualToString:@"NSCFNumber"])\r
+    {\r
+        resultAsString = [NSString stringWithFormat:@"%@", result];\r
+    }\r
+    else if ([className isEqualToString:@"NSCFString"])\r
+    {\r
+        resultAsString = result;\r
+    }\r
+    else if ([className isEqualToString:@"NSCFBoolean"])\r
+    {\r
+        if ([result boolValue])\r
+            resultAsString = @"true";\r
+        else\r
+            resultAsString = @"false";\r
+    }\r
+    else if ([className isEqualToString:@"WebScriptObject"])\r
+    {\r
+        resultAsString = [result stringRepresentation];\r
+    }\r
+    else\r
+    {\r
+        return wxString();\r
+    }\r
+\r
+    return wxStringWithNSString( resultAsString );\r
+}\r
+\r
+void wxOSXWebKitCtrl::OnSize(wxSizeEvent &event)\r
+{\r
+#if defined(__WXMAC_) && wxOSX_USE_CARBON\r
+    // This is a nasty hack because WebKit seems to lose its position when it is\r
+    // embedded in a control that is not itself the content view for a TLW.\r
+    // I put it in OnSize because these calcs are not perfect, and in fact are\r
+    // basically guesses based on reverse engineering, so it's best to give\r
+    // people the option of overriding OnSize with their own calcs if need be.\r
+    // I also left some test debugging print statements as a convenience if\r
+    // a(nother) problem crops up.\r
+\r
+    wxWindow* tlw = MacGetTopLevelWindow();\r
+\r
+    NSRect frame = [(WebView*)m_webView frame];\r
+    NSRect bounds = [(WebView*)m_webView bounds];\r
+\r
+#if DEBUG_WEBKIT_SIZING\r
+    fprintf(stderr,"Carbon window x=%d, y=%d, width=%d, height=%d\n",\r
+            GetPosition().x, GetPosition().y, GetSize().x, GetSize().y);\r
+    fprintf(stderr, "Cocoa window frame x=%G, y=%G, width=%G, height=%G\n",\r
+            frame.origin.x, frame.origin.y,\r
+            frame.size.width, frame.size.height);\r
+    fprintf(stderr, "Cocoa window bounds x=%G, y=%G, width=%G, height=%G\n",\r
+            bounds.origin.x, bounds.origin.y,\r
+            bounds.size.width, bounds.size.height);\r
+#endif\r
+\r
+    // This must be the case that Apple tested with, because well, in this one case\r
+    // we don't need to do anything! It just works. ;)\r
+    if (GetParent() == tlw) return;\r
+\r
+    // since we no longer use parent coordinates, we always want 0,0.\r
+    int x = 0;\r
+    int y = 0;\r
+\r
+    HIRect rect;\r
+    rect.origin.x = x;\r
+    rect.origin.y = y;\r
+\r
+#if DEBUG_WEBKIT_SIZING\r
+    printf("Before conversion, origin is: x = %d, y = %d\n", x, y);\r
+#endif\r
+\r
+    // NB: In most cases, when calling HIViewConvertRect, what people want is to\r
+    // use GetRootControl(), and this tripped me up at first. But in fact, what\r
+    // we want is the root view, because we need to make the y origin relative\r
+    // to the very top of the window, not its contents, since we later flip\r
+    // the y coordinate for Cocoa.\r
+    HIViewConvertRect (&rect, m_peer->GetControlRef(),\r
+                                HIViewGetRoot(\r
+                                    (WindowRef) MacGetTopLevelWindowRef()\r
+                                 ));\r
+\r
+    x = (int)rect.origin.x;\r
+    y = (int)rect.origin.y;\r
+\r
+#if DEBUG_WEBKIT_SIZING\r
+    printf("Moving Cocoa frame origin to: x = %d, y = %d\n", x, y);\r
+#endif\r
+\r
+    if (tlw){\r
+        //flip the y coordinate to convert to Cocoa coordinates\r
+        y = tlw->GetSize().y - ((GetSize().y) + y);\r
+    }\r
+\r
+#if DEBUG_WEBKIT_SIZING\r
+    printf("y = %d after flipping value\n", y);\r
+#endif\r
+\r
+    frame.origin.x = x;\r
+    frame.origin.y = y;\r
+    [(WebView*)m_webView setFrame:frame];\r
+\r
+    if (IsShown())\r
+        [(WebView*)m_webView display];\r
+    event.Skip();\r
+#endif\r
+}\r
+\r
+void wxOSXWebKitCtrl::MacVisibilityChanged(){\r
+#if defined(__WXMAC__) && wxOSX_USE_CARBON\r
+    bool isHidden = !IsControlVisible( m_peer->GetControlRef());\r
+    if (!isHidden)\r
+        [(WebView*)m_webView display];\r
+\r
+    [m_webView setHidden:isHidden];\r
+#endif\r
+}\r
+\r
+void wxOSXWebKitCtrl::LoadUrl(const wxString& url)\r
+{\r
+    InternalLoadURL(url);\r
+}\r
+\r
+wxString wxOSXWebKitCtrl::GetCurrentURL()\r
+{\r
+    return wxStringWithNSString([m_webView mainFrameURL]);\r
+}\r
+\r
+wxString wxOSXWebKitCtrl::GetCurrentTitle()\r
+{\r
+    return GetPageTitle();\r
+}\r
+\r
+float wxOSXWebKitCtrl::GetWebkitZoom()\r
+{\r
+    return [m_webView textSizeMultiplier];\r
+}\r
+\r
+void wxOSXWebKitCtrl::SetWebkitZoom(float zoom)\r
+{\r
+    [m_webView setTextSizeMultiplier:zoom];\r
+}\r
+\r
+wxWebViewZoom wxOSXWebKitCtrl::GetZoom()\r
+{\r
+    float zoom = GetWebkitZoom();\r
+\r
+    // arbitrary way to map float zoom to our common zoom enum\r
+    if (zoom <= 0.55)\r
+    {\r
+        return wxWEB_VIEW_ZOOM_TINY;\r
+    }\r
+    else if (zoom > 0.55 && zoom <= 0.85)\r
+    {\r
+        return wxWEB_VIEW_ZOOM_SMALL;\r
+    }\r
+    else if (zoom > 0.85 && zoom <= 1.15)\r
+    {\r
+        return wxWEB_VIEW_ZOOM_MEDIUM;\r
+    }\r
+    else if (zoom > 1.15 && zoom <= 1.45)\r
+    {\r
+        return wxWEB_VIEW_ZOOM_LARGE;\r
+    }\r
+    else if (zoom > 1.45)\r
+    {\r
+        return wxWEB_VIEW_ZOOM_LARGEST;\r
+    }\r
+\r
+    // to shut up compilers, this can never be reached logically\r
+    wxASSERT(false);\r
+    return wxWEB_VIEW_ZOOM_MEDIUM;\r
+}\r
+\r
+void wxOSXWebKitCtrl::SetZoom(wxWebViewZoom zoom)\r
+{\r
+    // arbitrary way to map our common zoom enum to float zoom\r
+    switch (zoom)\r
+    {\r
+        case wxWEB_VIEW_ZOOM_TINY:\r
+            SetWebkitZoom(0.4f);\r
+            break;\r
+\r
+        case wxWEB_VIEW_ZOOM_SMALL:\r
+            SetWebkitZoom(0.7f);\r
+            break;\r
+\r
+        case wxWEB_VIEW_ZOOM_MEDIUM:\r
+            SetWebkitZoom(1.0f);\r
+            break;\r
+\r
+        case wxWEB_VIEW_ZOOM_LARGE:\r
+            SetWebkitZoom(1.3);\r
+            break;\r
+\r
+        case wxWEB_VIEW_ZOOM_LARGEST:\r
+            SetWebkitZoom(1.6);\r
+            break;\r
+\r
+        default:\r
+            wxASSERT(false);\r
+    }\r
+\r
+}\r
+\r
+void wxOSXWebKitCtrl::SetPage(const wxString& src, const wxString& baseUrl)\r
+{\r
+   if ( !m_webView )\r
+        return;\r
+\r
+    [[m_webView mainFrame] loadHTMLString:(NSString*)wxNSStringWithWxString(src)\r
+                                  baseURL:[NSURL URLWithString:\r
+                                    wxNSStringWithWxString( baseUrl )]];\r
+}\r
+\r
+//------------------------------------------------------------\r
+// Listener interfaces\r
+//------------------------------------------------------------\r
+\r
+// NB: I'm still tracking this down, but it appears the Cocoa window\r
+// still has these events fired on it while the Carbon control is being\r
+// destroyed. Therefore, we must be careful to check both the existence\r
+// of the Carbon control and the event handler before firing events.\r
+\r
+@implementation MyFrameLoadMonitor\r
+\r
+- initWithWxWindow: (wxOSXWebKitCtrl*)inWindow\r
+{\r
+    [super init];\r
+    webKitWindow = inWindow;    // non retained\r
+    return self;\r
+}\r
+\r
+- (void)webView:(WebView *)sender\r
+    didStartProvisionalLoadForFrame:(WebFrame *)frame\r
+{\r
+       wxASSERT(wx_webviewctrls.find(sender) != wx_webviewctrls.end());\r
+    wx_webviewctrls[sender]->m_busy = true;\r
+}\r
+\r
+- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame\r
+{\r
+       wxASSERT(wx_webviewctrls.find(sender) != wx_webviewctrls.end());\r
+    wx_webviewctrls[sender]->m_busy = true;\r
+\r
+    if (webKitWindow && frame == [sender mainFrame]){\r
+        NSString *url = [[[[frame dataSource] request] URL] absoluteString];\r
+        wxString target = wxStringWithNSString([frame name]);\r
+        wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,\r
+                                       wx_webviewctrls[sender]->GetId(),\r
+                                       wxStringWithNSString( url ),\r
+                                       target, false);\r
+\r
+        if (webKitWindow && webKitWindow->GetEventHandler())\r
+            webKitWindow->GetEventHandler()->ProcessEvent(thisEvent);\r
+    }\r
+}\r
+\r
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame\r
+{\r
+       wxASSERT(wx_webviewctrls.find(sender) != wx_webviewctrls.end());\r
+    wx_webviewctrls[sender]->m_busy = false;\r
+\r
+    if (webKitWindow && frame == [sender mainFrame]){\r
+        NSString *url = [[[[frame dataSource] request] URL] absoluteString];\r
+\r
+        wxString target = wxStringWithNSString([frame name]);\r
+        wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_LOADED,\r
+                                       wx_webviewctrls[sender]->GetId(),\r
+                                       wxStringWithNSString( url ),\r
+                                       target, false);\r
+\r
+        if (webKitWindow && webKitWindow->GetEventHandler())\r
+            webKitWindow->GetEventHandler()->ProcessEvent(thisEvent);\r
+    }\r
+}\r
+\r
+wxString nsErrorToWxHtmlError(NSError* error, wxWebNavigationError* out)\r
+{\r
+    *out = wxWEB_NAV_ERR_OTHER;\r
+\r
+    if ([[error domain] isEqualToString:NSURLErrorDomain])\r
+    {\r
+        switch ([error code])\r
+        {\r
+            case NSURLErrorCannotFindHost:\r
+            case NSURLErrorFileDoesNotExist:\r
+            case NSURLErrorRedirectToNonExistentLocation:\r
+                *out = wxWEB_NAV_ERR_NOT_FOUND;\r
+                break;\r
+\r
+            case NSURLErrorResourceUnavailable:\r
+            case NSURLErrorHTTPTooManyRedirects:\r
+            case NSURLErrorDataLengthExceedsMaximum:\r
+            case NSURLErrorBadURL:\r
+            case NSURLErrorFileIsDirectory:\r
+                *out = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+\r
+            case NSURLErrorTimedOut:\r
+            case NSURLErrorDNSLookupFailed:\r
+            case NSURLErrorNetworkConnectionLost:\r
+            case NSURLErrorCannotConnectToHost:\r
+            case NSURLErrorNotConnectedToInternet:\r
+            //case NSURLErrorInternationalRoamingOff:\r
+            //case NSURLErrorCallIsActive:\r
+            //case NSURLErrorDataNotAllowed:\r
+                *out = wxWEB_NAV_ERR_CONNECTION;\r
+                break;\r
+\r
+            case NSURLErrorCancelled:\r
+            case NSURLErrorUserCancelledAuthentication:\r
+                *out = wxWEB_NAV_ERR_USER_CANCELLED;\r
+                break;\r
+\r
+            case NSURLErrorCannotDecodeRawData:\r
+            case NSURLErrorCannotDecodeContentData:\r
+            case NSURLErrorBadServerResponse:\r
+            case NSURLErrorCannotParseResponse:\r
+                *out = wxWEB_NAV_ERR_REQUEST;\r
+                break;\r
+\r
+            case NSURLErrorUserAuthenticationRequired:\r
+            case NSURLErrorSecureConnectionFailed:\r
+            case NSURLErrorClientCertificateRequired:\r
+                *out = wxWEB_NAV_ERR_AUTH;\r
+                break;\r
+\r
+            case NSURLErrorNoPermissionsToReadFile:\r
+                               *out = wxWEB_NAV_ERR_SECURITY;\r
+                break;\r
+\r
+            case NSURLErrorServerCertificateHasBadDate:\r
+            case NSURLErrorServerCertificateUntrusted:\r
+            case NSURLErrorServerCertificateHasUnknownRoot:\r
+            case NSURLErrorServerCertificateNotYetValid:\r
+            case NSURLErrorClientCertificateRejected:\r
+                *out = wxWEB_NAV_ERR_CERTIFICATE;\r
+                break;\r
+        }\r
+    }\r
+\r
+    wxString message = wxStringWithNSString([error localizedDescription]);\r
+    NSString* detail = [error localizedFailureReason];\r
+    if (detail != NULL)\r
+    {\r
+        message = message + " (" + wxStringWithNSString(detail) + ")";\r
+    }\r
+    return message;\r
+}\r
+\r
+- (void)webView:(WebView *)sender didFailLoadWithError:(NSError*) error\r
+        forFrame:(WebFrame *)frame\r
+{\r
+       wxASSERT(wx_webviewctrls.find(sender) != wx_webviewctrls.end());\r
+    wx_webviewctrls[sender]->m_busy = false;\r
+\r
+    if (webKitWindow && frame == [sender mainFrame]){\r
+        NSString *url = [[[[frame dataSource] request] URL] absoluteString];\r
+\r
+        wxWebNavigationError type;\r
+        wxString description = nsErrorToWxHtmlError(error, &type);\r
+               wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_ERROR,\r
+                                              wx_webviewctrls[sender]->GetId(),\r
+                                       wxStringWithNSString( url ),\r
+                                       wxEmptyString, false);\r
+               thisEvent.SetString(description);\r
+               thisEvent.SetInt(type);\r
+\r
+               if (webKitWindow && webKitWindow->GetEventHandler())\r
+               {\r
+                       webKitWindow->GetEventHandler()->ProcessEvent(thisEvent);\r
+               }\r
+    }\r
+}\r
+\r
+- (void)webView:(WebView *)sender\r
+        didFailProvisionalLoadWithError:(NSError*)error\r
+                               forFrame:(WebFrame *)frame\r
+{\r
+       wxASSERT(wx_webviewctrls.find(sender) != wx_webviewctrls.end());\r
+    wx_webviewctrls[sender]->m_busy = false;\r
+\r
+    if (webKitWindow && frame == [sender mainFrame]){\r
+        NSString *url = [[[[frame provisionalDataSource] request] URL]\r
+                            absoluteString];\r
+\r
+               wxWebNavigationError type;\r
+        wxString description = nsErrorToWxHtmlError(error, &type);\r
+               wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_ERROR,\r
+                                              wx_webviewctrls[sender]->GetId(),\r
+                                       wxStringWithNSString( url ),\r
+                                       wxEmptyString, false);\r
+               thisEvent.SetString(description);\r
+               thisEvent.SetInt(type);\r
+\r
+               if (webKitWindow && webKitWindow->GetEventHandler())\r
+                       webKitWindow->GetEventHandler()->ProcessEvent(thisEvent);\r
+    }\r
+}\r
+\r
+- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title\r
+                                         forFrame:(WebFrame *)frame\r
+{\r
+    if (webKitWindow && frame == [sender mainFrame])\r
+    {\r
+        webKitWindow->SetPageTitle(wxStringWithNSString( title ));\r
+    }\r
+}\r
+@end\r
+\r
+@implementation MyPolicyDelegate\r
+\r
+- initWithWxWindow: (wxOSXWebKitCtrl*)inWindow\r
+{\r
+    [super init];\r
+    webKitWindow = inWindow;    // non retained\r
+    return self;\r
+}\r
+\r
+- (void)webView:(WebView *)sender\r
+        decidePolicyForNavigationAction:(NSDictionary *)actionInformation\r
+                                request:(NSURLRequest *)request\r
+                                  frame:(WebFrame *)frame\r
+                       decisionListener:(id<WebPolicyDecisionListener>)listener\r
+{\r
+    //wxUnusedVar(sender);\r
+    wxUnusedVar(frame);\r
+\r
+    wxASSERT(wx_webviewctrls.find(sender) != wx_webviewctrls.end());\r
+    wx_webviewctrls[sender]->m_busy = true;\r
+    NSString *url = [[request URL] absoluteString];\r
+    wxString target = wxStringWithNSString([frame name]);\r
+    wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_NAVIGATING,\r
+                                   wx_webviewctrls[sender]->GetId(),\r
+                                   wxStringWithNSString( url ), target, true);\r
+\r
+    if (webKitWindow && webKitWindow->GetEventHandler())\r
+        webKitWindow->GetEventHandler()->ProcessEvent(thisEvent);\r
+\r
+    if (thisEvent.IsVetoed())\r
+    {\r
+        wx_webviewctrls[sender]->m_busy = false;\r
+        [listener ignore];\r
+    }\r
+    else\r
+    {\r
+        [listener use];\r
+    }\r
+}\r
+\r
+- (void)webView:(WebView *)sender \r
+      decidePolicyForNewWindowAction:(NSDictionary *)actionInformation\r
+                             request:(NSURLRequest *)request\r
+                        newFrameName:(NSString *)frameName\r
+                    decisionListener:(id < WebPolicyDecisionListener >)listener\r
+{\r
+    wxUnusedVar(sender);\r
+    wxUnusedVar(actionInformation);\r
+\r
+    [listener ignore];\r
+}\r
+@end\r
+\r
+#endif //wxHAVE_WEB_BACKEND_OSX_WEBKIT\r