#############################################################################
## Name: lib/Wx/DemoModules/wxWebview.pm
## Purpose: wxPerl demo helper for Wx::WebView
## Author: Mark Dootson
## Created: 17/03/2012
## RCS-ID: $Id: wxWebView.pm 3223 2012-03-18 03:05:39Z mdootson $
## Copyright: (c) 2012 Mattia Barbon
## Licence: This program is free software; you can redistribute it and/or
## modify it under the same terms as Perl itself
#############################################################################
package Wx::DemoModules::wxWebView;
use strict;
use Wx;
use Wx::WebView;
use base qw( Wx::Panel );
use Wx qw( :webview :misc :id :window :panel :sizer wxYES_NO wxNO :dialog :font);
use Wx::Event (Wx::wxVERSION >= 3.000000)
? qw(
EVT_WEBVIEW_NAVIGATING EVT_WEBVIEW_NAVIGATED
EVT_WEBVIEW_LOADED EVT_WEBVIEW_ERROR
EVT_WEBVIEW_NEWWINDOW EVT_WEBVIEW_TITLE_CHANGED
EVT_BUTTON
)
: qw(
EVT_WEB_VIEW_NAVIGATING EVT_WEB_VIEW_NAVIGATED
EVT_WEB_VIEW_LOADED EVT_WEB_VIEW_ERROR
EVT_WEB_VIEW_NEWWINDOW EVT_WEB_VIEW_TITLE_CHANGED
EVT_BUTTON
);
our $VERSION = '0.01';
sub new {
my( $class, $parent ) = @_;
my $self = $class->SUPER::new( $parent );
$self->{defaulturl} = 'http://wxperl.sourceforge.net';
#controls
$self->{webview} = Wx::WebView::New($self, wxID_ANY, $self->{defaulturl} );
my $btnurl = Wx::Button->new($self, wxID_ANY, 'Load URL');
my $btnback = Wx::Button->new($self, wxID_ANY, 'Back');
my $btnforw = Wx::Button->new($self, wxID_ANY, 'Forward');
my $btnhist = Wx::Button->new($self, wxID_ANY, 'History');
my $btnscpt = Wx::Button->new($self, wxID_ANY, 'Run Script');
my $btnhtml = Wx::Button->new($self, wxID_ANY, 'Load Html');
my $btnsrc = Wx::Button->new($self, wxID_ANY, 'View Source');
$self->{btnback} = $btnback;
$self->{btnback}->Enable(0);
$self->{btnforw} = $btnforw;
$self->{btnforw}->Enable(0);
# Events
if(Wx::wxVERSION >= 3.000000) {
EVT_WEBVIEW_NAVIGATING( $self, $self->{webview}, sub { shift->OnWVNavigating( @_ ); });
EVT_WEBVIEW_NAVIGATED( $self, $self->{webview}, sub { shift->OnWVNavigated( @_ ); });
EVT_WEBVIEW_LOADED( $self, $self->{webview}, sub { shift->OnWVLoaded( @_ ); });
EVT_WEBVIEW_ERROR( $self, $self->{webview}, sub { shift->OnWVError( @_ ); });
EVT_WEBVIEW_NEWWINDOW( $self, $self->{webview}, sub { shift->OnWVNewWindow( @_ ); });
EVT_WEBVIEW_TITLE_CHANGED( $self, $self->{webview}, sub { shift->OnWVTitleChanged( @_ ); });
} else {
EVT_WEB_VIEW_NAVIGATING( $self, $self->{webview}, sub { shift->OnWVNavigating( @_ ); });
EVT_WEB_VIEW_NAVIGATED( $self, $self->{webview}, sub { shift->OnWVNavigated( @_ ); });
EVT_WEB_VIEW_LOADED( $self, $self->{webview}, sub { shift->OnWVLoaded( @_ ); });
EVT_WEB_VIEW_ERROR( $self, $self->{webview}, sub { shift->OnWVError( @_ ); });
EVT_WEB_VIEW_NEWWINDOW( $self, $self->{webview}, sub { shift->OnWVNewWindow( @_ ); });
EVT_WEB_VIEW_TITLE_CHANGED( $self, $self->{webview}, sub { shift->OnWVTitleChanged( @_ ); });
}
EVT_BUTTON($self, $btnurl, sub { shift->OnBtnURL( @_ ); });
EVT_BUTTON($self, $btnback, sub { shift->OnBtnBack( @_ ); });
EVT_BUTTON($self, $btnforw, sub { shift->OnBtnForward( @_ ); });
EVT_BUTTON($self, $btnhist, sub { shift->OnBtnHistory( @_ ); });
EVT_BUTTON($self, $btnscpt, sub { shift->OnBtnRunScript( @_ ); });
EVT_BUTTON($self, $btnhtml, sub { shift->OnBtnLoadHtml( @_ ); });
EVT_BUTTON($self, $btnsrc, sub { shift->OnBtnSource( @_ ); });
# layout
my $buttonsizer = Wx::BoxSizer->new(wxHORIZONTAL);
$buttonsizer->Add($btnurl, 0, wxLEFT|wxRIGHT, 0);
$buttonsizer->Add($btnback, 0, wxLEFT|wxRIGHT, 0);
$buttonsizer->Add($btnforw, 0, wxLEFT|wxRIGHT, 0);
$buttonsizer->Add($btnhist, 0, wxLEFT|wxRIGHT, 0);
$buttonsizer->Add($btnscpt, 0, wxLEFT|wxRIGHT, 0);
$buttonsizer->Add($btnhtml, 0, wxLEFT|wxRIGHT, 0);
$buttonsizer->Add($btnsrc, 0, wxLEFT|wxRIGHT, 0);
my $msizer = Wx::BoxSizer->new( wxVERTICAL );
$msizer->Add($buttonsizer, 0, wxEXPAND|wxALL, 0);
$msizer->Add($self->{webview}, 1, wxEXPAND|wxALL, 0);
$self->SetSizer( $msizer );
$self->Layout;
$self->Refresh;
return $self;
}
sub OnWVNavigating {
my ($self, $event) = @_;
my $url = $event->GetURL;
my $target = $event->GetTarget;
Wx::LogMessage('WebView requested new page "%s" : in target "%s"', $url, $target);
}
sub OnWVNavigated {
my ($self, $event) = @_;
}
sub OnWVLoaded {
my ($self, $event) = @_;
# loading a resource is complete so set our back and forward button states
$self->{btnback}->Enable( $self->{webview}->CanGoBack );
$self->{btnforw}->Enable( $self->{webview}->CanGoForward );
}
sub OnWVError {
my ($self, $event) = @_;
my $errorstring = $event->GetString;
my $url = $event->GetURL;
my $errormap = (Wx::wxVERSION >= 3.000000)
? {
wxWEBVIEW_NAV_ERR_CONNECTION() => 'wxWEB_NAV_ERR_CONNECTION',
wxWEBVIEW_NAV_ERR_CERTIFICATE() => 'wxWEB_NAV_ERR_CERTIFICATE',
wxWEBVIEW_NAV_ERR_AUTH() => 'wxWEB_NAV_ERR_AUTH',
wxWEBVIEW_NAV_ERR_SECURITY() => 'wxWEB_NAV_ERR_SECURITY',
wxWEBVIEW_NAV_ERR_NOT_FOUND() => 'wxWEB_NAV_ERR_NOT_FOUND',
wxWEBVIEW_NAV_ERR_REQUEST() => 'wxWEB_NAV_ERR_REQUEST',
wxWEBVIEW_NAV_ERR_USER_CANCELLED() => 'wxWEB_NAV_ERR_USER_CANCELLED',
wxWEBVIEW_NAV_ERR_OTHER() => 'wxWEB_NAV_ERR_OTHER',
}
: {
wxWEB_NAV_ERR_CONNECTION() => 'wxWEB_NAV_ERR_CONNECTION',
wxWEB_NAV_ERR_CERTIFICATE() => 'wxWEB_NAV_ERR_CERTIFICATE',
wxWEB_NAV_ERR_AUTH() => 'wxWEB_NAV_ERR_AUTH',
wxWEB_NAV_ERR_SECURITY() => 'wxWEB_NAV_ERR_SECURITY',
wxWEB_NAV_ERR_NOT_FOUND() => 'wxWEB_NAV_ERR_NOT_FOUND',
wxWEB_NAV_ERR_REQUEST() => 'wxWEB_NAV_ERR_REQUEST',
wxWEB_NAV_ERR_USER_CANCELLED() => 'wxWEB_NAV_ERR_USER_CANCELLED',
wxWEB_NAV_ERR_OTHER() => 'wxWEB_NAV_ERR_OTHER',
};
my $errorid = $event->GetInt;
my $errname = exists( $errormap->{$errorid} ) ? $errormap->{$errorid} : '<UNKNOWN ID>';
Wx::LogMessage('Getting %s Webview reports the following error code and string : %s : %s', $url, $errname, $errorstring);
}
sub OnWVNewWindow {
my ($self, $event) = @_;
my $target = $event->GetTarget;
my $url = $event->GetURL;
# If we do nothing, nothing will happen
my $message = qq(The WebView has requested that we load $url in a new page or frame.\n\nShould we allow it to be loaded to this page instead?);
my $res = Wx::MessageBox($message, 'WebView Demo', wxYES_NO, $self);
return if $res == wxNO;
$self->{webview}->LoadURL($url);
}
sub OnWVTitleChanged {
my ($self, $event) = @_;
}
sub OnBtnURL {
my ($self, $event) = @_;
my $dialog = Wx::TextEntryDialog->new
( $self, "Enter a URL to load", "Wx::WebView Demo",
$self->{defaulturl} );
my $res = $dialog->ShowModal;
my $rvalue = $dialog->GetValue;
$dialog->Destroy;
return if $res == wxID_CANCEL;
$self->{defaulturl} = $rvalue;
$self->{webview}->LoadURL( $rvalue );
}
sub OnBtnBack {
my ($self, $event) = @_;
$self->{webview}->GoBack if $self->{webview}->CanGoBack;
}
sub OnBtnForward {
my ($self, $event) = @_;
$self->{webview}->GoForward if $self->{webview}->CanGoForward;
}
sub OnBtnHistory {
my ($self, $event) = @_;
my @past = $self->{webview}->GetBackwardHistory;
my @future = $self->{webview}->GetForwardHistory;
my $ptext = '<h3>Backward History</h3><br>';
$ptext .= $_->GetTitle . ' : ' . $_->GetUrl . '<br>' for ( @past );
$ptext .= '<h3>Forward History</h3><br>';
$ptext .= $_->GetTitle . ' : ' . $_->GetUrl . '<br>' for ( @future );
$ptext .= '</font>';
$self->{webview}->SelectAll;
$self->{webview}->DeleteSelection;
$self->{webview}->SetPage($ptext, 'http://localhost:54321/');
}
sub OnBtnRunScript {
my ($self, $event) = @_;
my $javascript ='
// You can write any javascript here and run it in the
// document.
document.write("<p>" + Date() + "</p>");
';
my $style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER;
my $dlg = Wx::DemoModules::wxWebView::HtmlDialog->new(
$self, -1, 'Wx::WebView Run JavaScript',
wxDefaultPosition, [600,400], $style );
$dlg->set_text( $javascript );
my $result = $dlg->ShowModal;
$javascript = $dlg->get_text;
$dlg->Destroy;
return if $result == wxID_CANCEL;
$self->{webview}->RunScript( $javascript);
}
sub OnBtnLoadHtml {
my ($self, $event) = @_;
my $html = q(
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<!-- You can edit or paste any html in this dialog to load it -->
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
);
my $style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER;
my $dlg = Wx::DemoModules::wxWebView::HtmlDialog->new(
$self, -1, 'Wx::WebView Load HTML',
wxDefaultPosition, [600,400], $style );
$dlg->set_text( $html );
my $result = $dlg->ShowModal;
my $htmlout = $dlg->get_text;
$dlg->Destroy;
return if $result == wxID_CANCEL;
# we can add to page content using a string or a file handle
# we will cear content first as on some platforms SetPage
# appends
$self->{webview}->SelectAll;
$self->{webview}->DeleteSelection;
$self->{webview}->SetPage($htmlout, 'http://localhost:54321/');
# we could also have passed any open file handle using SetPageFH
# open my $fh, '<', \$htmlout;
# $self->{webview}->SetPageFH($fh, 'http://localhost:54321/');
# close( $fh );
}
sub OnBtnSource {
my ($self, $event) = @_;
my $html = $self->{webview}->GetPageSource;
my $style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER;
my $dlg = Wx::DemoModules::wxWebView::HtmlDialog->new(
$self, -1, 'Wx::WebView Page Source',
wxDefaultPosition, [600,400], $style );
$dlg->set_text( $html );
$dlg->ShowModal;
$dlg->Destroy;
}
sub add_to_tags { qw(new controls) }
sub title { 'wxWebView' }
package Wx::DemoModules::wxWebView::HtmlDialog;
use Wx::STC;
use Wx qw( :id :stc :sizer :font );
use base qw( Wx::Dialog );
use Wx::Event qw( EVT_BUTTON );
sub new {
my $class = shift;
my $self = $class->SUPER::new( @_ );
my $text = Wx::StyledTextCtrl->new($self, wxID_ANY);
my $ok = Wx::Button->new($self, wxID_OK, 'OK');
my $cancel = Wx::Button->new($self, wxID_CANCEL, 'Cancel');
$ok->SetDefault;
my $sizer = Wx::BoxSizer->new(wxVERTICAL);
$sizer->Add($text, 1, wxEXPAND);
my $bsizer = Wx::BoxSizer->new(wxHORIZONTAL);
$bsizer->AddStretchSpacer(1);
$bsizer->Add($ok, 0, wxALL, 0);
$bsizer->Add($cancel, 0, wxALL, 0);
$sizer->Add($bsizer, 0, wxEXPAND|wxALL, 0);
$self->SetSizer($sizer);
$self->{stc} = $text;
$self->set_style_html;
return $self;
}
sub set_style_html {
my $self = shift;
my $text = $self->{stc};
my $font = Wx::wxMAC()
? Wx::Font->new( 12, wxMODERN, wxNORMAL, wxNORMAL, 0, 'Monaco' )
: Wx::Font->new( 10, wxTELETYPE, wxNORMAL, wxNORMAL);
$text->SetFont( $font );
$text->StyleSetFont( wxSTC_STYLE_DEFAULT, $font );
$text->SetMarginWidth(1, 30);
$text->SetMarginType(1, wxSTC_MARGIN_NUMBER);
$text->StyleClearAll();
$text->SetLexer(wxSTC_LEX_HTML);
$text->StyleSetForeground(wxSTC_H_DOUBLESTRING, Wx::Colour->new(255,0,0));
$text->StyleSetForeground(wxSTC_H_SINGLESTRING, Wx::Colour->new(255,0,0));
$text->StyleSetForeground(wxSTC_H_ENTITY, Wx::Colour->new(255,0,0));
$text->StyleSetForeground(wxSTC_H_TAG, Wx::Colour->new(0,150,0));
$text->StyleSetForeground(wxSTC_H_TAGUNKNOWN, Wx::Colour->new(0,150,0));
$text->StyleSetForeground(wxSTC_H_ATTRIBUTE, Wx::Colour->new(0,0,150));
$text->StyleSetForeground(wxSTC_H_ATTRIBUTEUNKNOWN, Wx::Colour->new(0,0,150));
$text->StyleSetForeground(wxSTC_H_COMMENT, Wx::Colour->new(150,150,150));
}
sub ShowModal {
my $self = shift;
$self->CentreOnParent;
$self->SUPER::ShowModal( @_ );
}
sub set_text { $_[0]->{stc}->SetText($_[1]); }
sub get_text { $_[0]->{stc}->GetText(); }
#Skip loading if no wxWebView
# return 1 or 0
eval { return Wx::_wx_optmod_webview(); };