Add html2 (WebView) classes

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@73036 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2012-11-27 01:23:10 +00:00
parent 1e0bcc84c8
commit 422814f88b
7 changed files with 465 additions and 0 deletions

67
etg/_html2.py Normal file
View File

@@ -0,0 +1,67 @@
#---------------------------------------------------------------------------
# Name: etg/_html2.py
# Author: Robin Dunn
#
# Created: 20-Nov-2012
# Copyright: (c) 2012 by Total Control Software
# License: wxWindows License
#---------------------------------------------------------------------------
import etgtools
import etgtools.tweaker_tools as tools
from etgtools import PyFunctionDef, PyCodeDef, PyPropertyDef
PACKAGE = "wx"
MODULE = "_html2"
NAME = "_html2" # Base name of the file to generate to for this script
DOCSTRING = ""
# The classes and/or the basename of the Doxygen XML files to be processed by
# this script.
ITEMS = [ ]
# The list of other ETG scripts and back-end generator modules that are
# included as part of this module. These should all be items that are put in
# the wxWidgets "webview" library in a multi-lib build.
INCLUDES = [ 'webview',
]
# Separate the list into those that are generated from ETG scripts and the
# rest. These lists can be used from the build scripts to get a list of
# sources and/or additional dependencies when building this extension module.
ETGFILES = ['etg/%s.py' % NAME] + tools.getEtgFiles(INCLUDES)
DEPENDS = tools.getNonEtgFiles(INCLUDES)
OTHERDEPS = [ ]
#---------------------------------------------------------------------------
def run():
# Parse the XML file(s) building a collection of Extractor objects
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
etgtools.parseDoxyXML(module, ITEMS)
module.check4unittest = False
#-----------------------------------------------------------------
# Tweak the parsed meta objects in the module object as needed for
# customizing the generated code and docstrings.
module.addHeaderCode('#include <wxpy_api.h>')
module.addImport('_core')
module.addPyCode('import wx', order=10)
module.addInclude(INCLUDES)
#-----------------------------------------------------------------
#-----------------------------------------------------------------
tools.doCommonTweaks(module)
tools.runGenerators(module)
#---------------------------------------------------------------------------
if __name__ == '__main__':
run()

124
etg/webview.py Normal file
View File

@@ -0,0 +1,124 @@
#---------------------------------------------------------------------------
# Name: etg/webview.py
# Author: Robin Dunn
#
# Created: 20-Nov-2012
# Copyright: (c) 2012 by Total Control Software
# License: wxWindows License
#---------------------------------------------------------------------------
import etgtools
import etgtools.tweaker_tools as tools
PACKAGE = "wx"
MODULE = "_html2"
NAME = "webview" # Base name of the file to generate to for this script
DOCSTRING = ""
# The classes and/or the basename of the Doxygen XML files to be processed by
# this script.
ITEMS = [ 'wxWebViewHistoryItem',
'wxWebViewHandler',
'wxWebViewArchiveHandler',
'wxWebViewFSHandler',
'wxWebView',
'wxWebViewEvent',
]
#---------------------------------------------------------------------------
def run():
# Parse the XML file(s) building a collection of Extractor objects
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
etgtools.parseDoxyXML(module, ITEMS)
#-----------------------------------------------------------------
# Tweak the parsed meta objects in the module object as needed for
# customizing the generated code and docstrings.
module.addHeaderCode('#include <wx/webview.h>')
c = module.find('wxWebView')
assert isinstance(c, etgtools.ClassDef)
tools.fixWindowClass(c)
c.abstract = True
module.addGlobalStr('wxWebViewNameStr', c)
module.addGlobalStr('wxWebViewDefaultURLStr', c)
for m in c.find('New').all():
m.factory = True
c.find('New.id').default = 'wxID_ANY'
c.find('New.parent').transferThis = True
c.find('RegisterHandler.handler').type = 'wxWebViewHandler*'
c.find('RegisterHandler.handler').transfer = True
c.find('RegisterHandler').setCppCode_sip(
"sipCpp->RegisterHandler(wxSharedPtr<wxWebViewHandler>(handler));")
# Custom code to deal with the
# wxVector<wxSharedPtr<wxWebViewHistoryItem>> return type of these two
# methods. We'll just convert them to a Python list of history items.
code = """\
wxPyThreadBlocker blocker;
PyObject* result = PyList_New(0);
wxVector<wxSharedPtr<wxWebViewHistoryItem> > vector = self->{method}();
for (size_t idx=0; idx < vector.size(); idx++) {{
PyObject* obj;
wxWebViewHistoryItem* item = new wxWebViewHistoryItem(*vector[idx].get());
obj = wxPyConstructObject((void*)item, "wxWebViewHistoryItem", true);
PyList_Append(result, obj);
Py_DECREF(obj);
}}
return result;
"""
c.find('GetBackwardHistory').type = 'PyObject*'
c.find('GetBackwardHistory').setCppCode(code.format(method='GetBackwardHistory'))
c.find('GetForwardHistory').type = 'PyObject*'
c.find('GetForwardHistory').setCppCode(code.format(method='GetForwardHistory'))
# Since LoadHistoryItem expects to get an actual item in the history
# list, and since we make copies of the items in the cppCode above, then
# this won't be possible to do from the Python wrappers. However, it's
# just as easy to use LoadURL to reload a history item so it's not a
# great loss.
c.find('LoadHistoryItem').ignore()
##c.find('LoadHistoryItem.item').type = 'wxWebViewHistoryItem*'
##c.find('LoadHistoryItem.item').transfer = True
##c.find('LoadHistoryItem').setCppCode_sip(
## "sipCpp->LoadHistoryItem(wxSharedPtr<wxWebViewHistoryItem>(item));")
c = module.find('wxWebViewEvent')
tools.fixEventClass(c)
module.addPyCode("""\
EVT_WEB_VIEW_NAVIGATING = wx.PyEventBinder( wxEVT_COMMAND_WEB_VIEW_NAVIGATING, 1 )
EVT_WEB_VIEW_NAVIGATED = wx.PyEventBinder( wxEVT_COMMAND_WEB_VIEW_NAVIGATED, 1 )
EVT_WEB_VIEW_LOADED = wx.PyEventBinder( wxEVT_COMMAND_WEB_VIEW_LOADED, 1 )
EVT_WEB_VIEW_ERROR = wx.PyEventBinder( wxEVT_COMMAND_WEB_VIEW_ERROR, 1 )
EVT_WEB_VIEW_NEWWINDOW = wx.PyEventBinder( wxEVT_COMMAND_WEB_VIEW_NEWWINDOW, 1 )
EVT_WEB_VIEW_TITLE_CHANGED = wx.PyEventBinder( wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED, 1 )
""")
c = module.find('wxWebViewHistoryItem')
tools.addAutoProperties(c)
#-----------------------------------------------------------------
tools.doCommonTweaks(module)
tools.runGenerators(module)
#---------------------------------------------------------------------------
if __name__ == '__main__':
run()

View File

@@ -0,0 +1,161 @@
import sys
import wx
import wx.html2 as webview
#----------------------------------------------------------------------
class TestPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.current = "http://wxPython.org"
self.frame = self.GetTopLevelParent()
self.titleBase = self.frame.GetTitle()
sizer = wx.BoxSizer(wx.VERTICAL)
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
self.wv = webview.WebView.New(self)
self.Bind(webview.EVT_WEB_VIEW_NAVIGATING, self.OnWebViewNavigating, self.wv)
self.Bind(webview.EVT_WEB_VIEW_NAVIGATED, self.OnWebViewNavigated, self.wv)
self.Bind(webview.EVT_WEB_VIEW_LOADED, self.OnWebViewLoaded, self.wv)
self.Bind(webview.EVT_WEB_VIEW_TITLE_CHANGED, self.OnWebViewTitleChanged, self.wv)
btn = wx.Button(self, -1, "Open", style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnOpenButton, btn)
btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
btn = wx.Button(self, -1, "<--", style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnPrevPageButton, btn)
btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
self.Bind(wx.EVT_UPDATE_UI, self.OnCheckCanGoBack, btn)
btn = wx.Button(self, -1, "-->", style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnNextPageButton, btn)
btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
self.Bind(wx.EVT_UPDATE_UI, self.OnCheckCanGoForward, btn)
btn = wx.Button(self, -1, "Stop", style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnStopButton, btn)
btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
btn = wx.Button(self, -1, "Refresh", style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnRefreshPageButton, btn)
btnSizer.Add(btn, 0, wx.EXPAND|wx.ALL, 2)
txt = wx.StaticText(self, -1, "Location:")
btnSizer.Add(txt, 0, wx.CENTER|wx.ALL, 2)
self.location = wx.ComboBox(
self, -1, "", style=wx.CB_DROPDOWN|wx.TE_PROCESS_ENTER)
self.location.AppendItems(['http://wxPython.org',
'http://wxwidgets.org',
'http://google.com'])
#for url in ['http://wxPython.org',
# 'http://wxwidgets.org',
# 'http://google.com']:
# item = webview.WebViewHistoryItem(url, url)
# self.wv.LoadHistoryItem(item)
self.Bind(wx.EVT_COMBOBOX, self.OnLocationSelect, self.location)
self.location.Bind(wx.EVT_TEXT_ENTER, self.OnLocationEnter)
btnSizer.Add(self.location, 1, wx.EXPAND|wx.ALL, 2)
sizer.Add(btnSizer, 0, wx.EXPAND)
sizer.Add(self.wv, 1, wx.EXPAND)
self.SetSizer(sizer)
self.wv.LoadURL(self.current)
# WebView events
def OnWebViewNavigating(self, evt):
# this event happens prior to trying to get a resource
if evt.GetURL() == 'http://www.microsoft.com/':
if wx.MessageBox("Are you sure you want to visit Microsoft?",
style=wx.YES_NO|wx.ICON_QUESTION) == wx.NO:
# This is how you can cancel loading a page.
evt.Veto()
def OnWebViewNavigated(self, evt):
self.frame.SetStatusText("Loading %s..." % evt.GetURL())
def OnWebViewLoaded(self, evt):
# The full document has loaded
self.current = evt.GetURL()
self.location.SetValue(self.current)
self.frame.SetStatusText("Loaded")
def OnWebViewTitleChanged(self, evt):
# Set the frame's title to include the document's title
self.frame.SetTitle("%s -- %s" % (self.titleBase, evt.GetString()))
# Control bar events
def OnLocationSelect(self, evt):
url = self.location.GetStringSelection()
print('OnLocationSelect: %s\n' % url)
self.wv.LoadURL(url)
def OnLocationEnter(self, evt):
url = self.location.GetValue()
self.location.Append(url)
self.wv.LoadURL(url)
def OnOpenButton(self, event):
dlg = wx.TextEntryDialog(self, "Open Location",
"Enter a full URL or local path",
self.current, wx.OK|wx.CANCEL)
dlg.CentreOnParent()
if dlg.ShowModal() == wx.ID_OK:
self.current = dlg.GetValue()
self.wv.LoadURL(self.current)
dlg.Destroy()
def OnPrevPageButton(self, event):
for i in self.wv.GetBackwardHistory():
print i.Url, i.Title
self.wv.GoBack()
def OnNextPageButton(self, event):
for i in self.wv.GetForwardHistory():
print i.URL, i.Title
self.wv.GoForward()
def OnCheckCanGoBack(self, event):
event.Enable(self.wv.CanGoBack())
def OnCheckCanGoForward(self, event):
event.Enable(self.wv.CanGoForward())
def OnStopButton(self, evt):
self.wv.Stop()
def OnRefreshPageButton(self, evt):
self.wv.Reload()
#----------------------------------------------------------------------
def main():
app = wx.App()
frm = wx.Frame(None, title="html2.WebView sample", size=(700,500))
frm.CreateStatusBar()
pnl = TestPanel(frm)
frm.Show()
app.MainLoop()
#----------------------------------------------------------------------
if __name__ == '__main__':
main()

View File

@@ -229,6 +229,22 @@ extensions.append(ext)
cfg.CLEANUP.append(opj(cfg.PKGDIR, 'glcanvas.py'))
etg = loadETG('etg/_html2.py')
tgDepends = etg.DEPENDS + etg.OTHERDEPS
ext = Extension('_html2', getEtgSipCppFiles(etg),
depends = getEtgSipHeaders(etg),
include_dirs = cfg.includes,
define_macros = cfg.defines,
library_dirs = cfg.libdirs,
libraries = cfg.libs + cfg.makeLibName('webview', True),
extra_compile_args = cfg.cflags,
extra_link_args = cfg.lflags,
)
extensions.append(ext)
cfg.CLEANUP.append(opj(cfg.PKGDIR, 'html2.py'))
#----------------------------------------------------------------------
if __name__ == '__main__':

View File

@@ -43,6 +43,9 @@ class PIImportTest(unittest.TestCase):
def test_html_pi(self):
self.runPI('html.pi')
def test_html2_pi(self):
self.runPI('html2.pi')
def test_dataview_pi(self):
self.runPI('dataview.pi')

78
unittests/test_webview.py Normal file
View File

@@ -0,0 +1,78 @@
import imp_unittest, unittest
import wtc
import wx
import wx.html2 as webview
#---------------------------------------------------------------------------
class webview_Tests(wtc.WidgetTestCase):
def test_webview1(self):
wv = webview.WebView.New()
wv.Create(self.frame)
def test_webview2(self):
wv = webview.WebView.New(self.frame)
def test_webview3(self):
wv = webview.WebView.New(self.frame)
self.frame.SendSizeEvent()
wv.LoadURL('file://' + __file__)
while wv.IsBusy():
self.myYield()
h = wv.GetBackwardHistory()
self.assertTrue(isinstance(h, list))
if len(h):
self.assertTrue(isinstance(h[0], webview.WebViewHistoryItem))
def test_webview5(self):
webview.WEB_VIEW_ZOOM_TINY
webview.WEB_VIEW_ZOOM_SMALL
webview.WEB_VIEW_ZOOM_MEDIUM
webview.WEB_VIEW_ZOOM_LARGE
webview.WEB_VIEW_ZOOM_LARGEST
webview.WEB_VIEW_ZOOM_TYPE_LAYOUT
webview.WEB_VIEW_ZOOM_TYPE_TEXT
webview.WEB_NAV_ERR_CONNECTION
webview.WEB_NAV_ERR_CERTIFICATE
webview.WEB_NAV_ERR_AUTH
webview.WEB_NAV_ERR_SECURITY
webview.WEB_NAV_ERR_NOT_FOUND
webview.WEB_NAV_ERR_REQUEST
webview.WEB_NAV_ERR_USER_CANCELLED
webview.WEB_NAV_ERR_OTHER
webview.WEB_VIEW_RELOAD_DEFAULT
webview.WEB_VIEW_RELOAD_NO_CACHE
webview.WEB_VIEW_FIND_WRAP
webview.WEB_VIEW_FIND_ENTIRE_WORD
webview.WEB_VIEW_FIND_MATCH_CASE
webview.WEB_VIEW_FIND_HIGHLIGHT_RESULT
webview.WEB_VIEW_FIND_BACKWARDS
webview.WEB_VIEW_FIND_DEFAULT
webview.WEB_VIEW_BACKEND_DEFAULT
webview.WEB_VIEW_BACKEND_WEBKIT
webview.WEB_VIEW_BACKEND_IE
def test_webview6(self):
webview.wxEVT_COMMAND_WEB_VIEW_NAVIGATING
webview.wxEVT_COMMAND_WEB_VIEW_NAVIGATED
webview.wxEVT_COMMAND_WEB_VIEW_LOADED
webview.wxEVT_COMMAND_WEB_VIEW_ERROR
webview.wxEVT_COMMAND_WEB_VIEW_NEWWINDOW
webview.wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED
webview.EVT_WEB_VIEW_NAVIGATING
webview.EVT_WEB_VIEW_NAVIGATED
webview.EVT_WEB_VIEW_LOADED
webview.EVT_WEB_VIEW_ERROR
webview.EVT_WEB_VIEW_NEWWINDOW
webview.EVT_WEB_VIEW_TITLE_CHANGED
#---------------------------------------------------------------------------
if __name__ == '__main__':
unittest.main()

16
wscript
View File

@@ -90,6 +90,8 @@ def configure(conf):
_copyEnvGroup(conf.env, '_WX', '_WXGL')
conf.env.LIB_WXGL += cfg.makeLibName('gl')
_copyEnvGroup(conf.env, '_WX', '_WXWEBVIEW')
conf.env.LIB_WXWEBVIEW += cfg.makeLibName('webview')
@@ -142,6 +144,10 @@ def configure(conf):
args='--cxxflags --libs gl,core,net',
uselib_store='WXGL', mandatory=True)
conf.check_cfg(path=conf.options.wx_config, package='',
args='--cxxflags --libs webview,core,net',
uselib_store='WXWEBVIEW', mandatory=True)
# NOTE: This assumes that if the platform is not win32 (from
# the test above) and not darwin then we must be using the
@@ -314,6 +320,16 @@ def build(bld):
makeExtCopyRule(bld, '_glcanvas')
etg = loadETG('etg/_html2.py')
adv = bld(
features = 'c cxx cxxshlib pyext',
target = makeTargetName(bld, '_html2'),
source = getEtgSipCppFiles(etg) + rc,
uselib = 'WXWEBVIEW WXPY',
)
makeExtCopyRule(bld, '_html2')
#-----------------------------------------------------------------------------
# helpers