/* * This code comes from wxWebView sample webview.cpp and is modified to be used in Kicad * the wxWidgets sample code webview.cpp is under wxWindows licence (author Marianne Gagnon) * * Webviewer runs in a dialog to allows an user to select a list of URLs which are .pretty library * folder accessible from http or https using the Github plugin. * * The Web viewer just return a list of URLs selected from the context menu (command copy link) * when mouse cursor in on a http link. * URLs strings are filtered * Only URLs starting by "http" and ending by ".pretty" can be currently selected and stored in fp lib list */ /* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /* * wxWidgets gives very few info about wxwebkit. For more info and more comments: * see https://forums.wxwidgets.org/viewtopic.php?f=1&t=1119# */ #include "wx/wx.h" #if !wxUSE_WEBVIEW_WEBKIT && !wxUSE_WEBVIEW_IE #error "wxWidgets must be built with wxWebView support enabled. Please rebuild wxWidgets" #endif #include "wx/artprov.h" #include "wx/cmdline.h" #include "wx/notifmsg.h" #include "wx/settings.h" #include "wx/webview.h" #include "wx/webviewarchivehandler.h" #include "wx/webviewfshandler.h" #include "wx/infobar.h" #include "wx/filesys.h" #include "wx/fs_arc.h" #include #include #if wxUSE_STC #include "wx/stc/stc.h" #else #error "wxWidgets must be built with wxStyledTextControl enabled. Please rebuild wxWidgets" #endif #include #include #include "html_link_parser.h" // We map menu items to their history items WX_DECLARE_HASH_MAP( int, wxSharedPtr, wxIntegerHash, wxIntegerEqual, wxMenuHistoryMap ); class WEB_NAVIGATOR : public DIALOG_SHIM { wxArrayString* urlListSelection; public: WEB_NAVIGATOR( wxWindow* aParent, const wxString& aUrlOnStart, wxArrayString* aUrlListSelection = NULL ); virtual ~WEB_NAVIGATOR(); void InitNavigator( const wxString& aUrlOnStart ); private: void buildToolBar(); void buildToolMenu(); void CreateFindToolBar( wxWindow* aParent ); void UpdateState(); // wxWebViewEvents: /** Callback invoked when a navigation request was accepted */ void OnNavigationComplete( wxWebViewEvent& evt ) { UpdateState(); } /** Callback invoked when a page is finished loading */ void OnDocumentLoaded( wxWebViewEvent& evt ) { UpdateState(); } /** On new window, we veto to stop extra windows appearing */ void OnNewWindow( wxWebViewEvent& evt ) { UpdateState(); } void OnTitleChanged( wxWebViewEvent& evt ) { SetTitle( evt.GetString() ); } // event functions: void OnIdle( wxIdleEvent& evt ); void OnUrl( wxCommandEvent& evt ); void OnBack( wxCommandEvent& evt ); void OnForward( wxCommandEvent& evt ); void OnStop( wxCommandEvent& evt ); void OnReload( wxCommandEvent& evt ); void OnClearHistory( wxCommandEvent& evt ); void OnNavigationRequest( wxWebViewEvent& evt ); void OnViewSourceRequest( wxCommandEvent& evt ); void OnToolsClicked( wxCommandEvent& evt ); void OnSetZoom( wxCommandEvent& evt ); void OnError( wxWebViewEvent& evt ); void OnPrint( wxCommandEvent& evt ) { m_browser->Print(); } void OnZoomLayout( wxCommandEvent& evt ); void OnHistory( wxCommandEvent& evt ) { m_browser->LoadHistoryItem( m_histMenuItems[evt.GetId()] ); } void OnFind( wxCommandEvent& evt ); void OnFindDone( wxCommandEvent& evt ); void OnFindText( wxCommandEvent& evt ); void OnFindOptions( wxCommandEvent& evt ); // only for fp lib wizard called if there is a non null // aUrlListSelection from idle event, to see if a valid // footprint lib was selected by user, from the context menu // (command copy link) void TestAndStoreFootprintLibLink(); // Alternate way to list and select fp libraries: void OnListPrettyLibURLs( wxCommandEvent& event ); private: wxTextCtrl* m_url; wxWebView* m_browser; wxToolBar* m_toolbar; wxToolBarToolBase* m_toolbar_back; wxToolBarToolBase* m_toolbar_forward; wxToolBarToolBase* m_toolbar_stop; wxToolBarToolBase* m_toolbar_reload; wxToolBarToolBase* m_toolbar_tools; wxToolBarToolBase* m_toolbar_ListLibs; wxToolBarToolBase* m_find_toolbar_done; wxToolBarToolBase* m_find_toolbar_next; wxToolBarToolBase* m_find_toolbar_previous; wxToolBarToolBase* m_find_toolbar_options; wxMenuItem* m_find_toolbar_wrap; wxMenuItem* m_find_toolbar_highlight; wxMenuItem* m_find_toolbar_matchcase; wxMenuItem* m_find_toolbar_wholeword; wxMenu* m_tools_menu; wxMenuItem* m_tools_viewSource; wxMenuItem* m_tools_print; wxMenu* m_tools_history_menu; wxMenuItem* m_tools_clearhist; wxMenuItem* m_tools_layout; wxMenuItem* m_tools_tiny; wxMenuItem* m_tools_small; wxMenuItem* m_tools_medium; wxMenuItem* m_tools_large; wxMenuItem* m_tools_largest; wxMenuItem* m_find; wxInfoBar* m_info; wxStaticText* m_info_text; wxTextCtrl* m_find_ctrl; wxToolBar* m_find_toolbar; wxMenuHistoryMap m_histMenuItems; wxString m_findText; int m_findFlags, m_findCount; }; class SourceViewDialog : public wxDialog { public: SourceViewDialog( wxWindow* parent, wxString source ); }; // Helper function to run the web viewer from an other dialog or frame: int RunWebViewer( wxWindow* aParent, const wxString& aUrlOnStart, wxArrayString* aUrlListSelection ) { WEB_NAVIGATOR dlg( aParent, aUrlOnStart, aUrlListSelection ); return dlg.ShowModal(); } WEB_NAVIGATOR::WEB_NAVIGATOR( wxWindow* aParent, const wxString& aUrlOnStart, wxArrayString* aUrlListSelection ) : DIALOG_SHIM( aParent, wxID_ANY, "Web Viewer", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ) { urlListSelection = aUrlListSelection; InitNavigator( aUrlOnStart ); SetMinSize( wxSize( 700, 500 ) ); GetSizer()->Fit( this ); Centre(); } void WEB_NAVIGATOR::InitNavigator( const wxString& aUrlOnStart ) { // To collect URLs, the Web Viewer can use the clipboard. // Clear it before running the viewer // For an unknown reason, wxTheClipboard->Clear() does not work, // so use a trick if( wxTheClipboard->Open() ) { wxTheClipboard->SetData( new wxTextDataObject( "" ) ); wxTheClipboard->Close(); } wxBoxSizer* topsizer = new wxBoxSizer( wxVERTICAL ); // Create the main toolbar m_toolbar = new wxToolBar( this, wxID_ANY ); buildToolBar(); topsizer->Add( m_toolbar ); // Shows the tool to choose and select fp libs only if a selected URL list // exists if( urlListSelection == NULL ) m_toolbar_ListLibs->Enable( false ); // Set find parameters and create the find toolbar. m_findFlags = wxWEBVIEW_FIND_DEFAULT; m_findCount = 0; CreateFindToolBar( this ); topsizer->Add( m_find_toolbar, wxSizerFlags().Expand() ); m_find_toolbar->Hide(); // Create the info panel m_info = new wxInfoBar( this ); topsizer->Add( m_info, wxSizerFlags().Expand() ); // Create the webview engine if( aUrlOnStart.IsEmpty() ) // Start on a blank page: m_browser = wxWebView::New( this, wxID_ANY, wxT( "about:blank") ); else m_browser = wxWebView::New( this, wxID_ANY, aUrlOnStart, wxDefaultPosition, wxSize( 900, 600 ) ); m_browser->EnableHistory( true ); topsizer->Add( m_browser, wxSizerFlags().Expand().Proportion( 1 ) ); SetSizer( topsizer ); // Create the Tools menu buildToolMenu(); if( !m_browser->CanSetZoomType( wxWEBVIEW_ZOOM_TYPE_LAYOUT ) ) m_tools_layout->Enable( false ); // Connect the toolbar events Connect( m_toolbar_back->GetId(), wxEVT_TOOL, wxCommandEventHandler( WEB_NAVIGATOR::OnBack ), NULL, this ); Connect( m_toolbar_forward->GetId(), wxEVT_TOOL, wxCommandEventHandler( WEB_NAVIGATOR::OnForward ), NULL, this ); Connect( m_toolbar_stop->GetId(), wxEVT_TOOL, wxCommandEventHandler( WEB_NAVIGATOR::OnStop ), NULL, this ); Connect( m_toolbar_reload->GetId(), wxEVT_TOOL, wxCommandEventHandler( WEB_NAVIGATOR::OnReload ), NULL, this ); Connect( m_toolbar_tools->GetId(), wxEVT_TOOL, wxCommandEventHandler( WEB_NAVIGATOR::OnToolsClicked ), NULL, this ); Connect( m_toolbar_ListLibs->GetId(), wxEVT_TOOL, wxCommandEventHandler( WEB_NAVIGATOR::OnListPrettyLibURLs ), NULL, this ); Connect( m_url->GetId(), wxEVT_TEXT_ENTER, wxCommandEventHandler( WEB_NAVIGATOR::OnUrl ), NULL, this ); // Connect find toolbar events. Connect( m_find_toolbar_done->GetId(), wxEVT_TOOL, wxCommandEventHandler( WEB_NAVIGATOR::OnFindDone ), NULL, this ); Connect( m_find_toolbar_next->GetId(), wxEVT_TOOL, wxCommandEventHandler( WEB_NAVIGATOR::OnFindText ), NULL, this ); Connect( m_find_toolbar_previous->GetId(), wxEVT_TOOL, wxCommandEventHandler( WEB_NAVIGATOR::OnFindText ), NULL, this ); // Connect find control events. Connect( m_find_ctrl->GetId(), wxEVT_TEXT, wxCommandEventHandler( WEB_NAVIGATOR::OnFindText ), NULL, this ); Connect( m_find_ctrl->GetId(), wxEVT_TEXT_ENTER, wxCommandEventHandler( WEB_NAVIGATOR::OnFindText ), NULL, this ); // Connect the webview events Connect( m_browser->GetId(), wxEVT_WEBVIEW_NAVIGATING, wxWebViewEventHandler( WEB_NAVIGATOR::OnNavigationRequest ), NULL, this ); Connect( m_browser->GetId(), wxEVT_WEBVIEW_NAVIGATED, wxWebViewEventHandler( WEB_NAVIGATOR::OnNavigationComplete ), NULL, this ); Connect( m_browser->GetId(), wxEVT_WEBVIEW_LOADED, wxWebViewEventHandler( WEB_NAVIGATOR::OnDocumentLoaded ), NULL, this ); Connect( m_browser->GetId(), wxEVT_WEBVIEW_ERROR, wxWebViewEventHandler( WEB_NAVIGATOR::OnError ), NULL, this ); Connect( m_browser->GetId(), wxEVT_WEBVIEW_NEWWINDOW, wxWebViewEventHandler( WEB_NAVIGATOR::OnNewWindow ), NULL, this ); Connect( m_browser->GetId(), wxEVT_WEBVIEW_TITLE_CHANGED, wxWebViewEventHandler( WEB_NAVIGATOR::OnTitleChanged ), NULL, this ); // Connect the menu events Connect( m_tools_viewSource->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnViewSourceRequest ), NULL, this ); Connect( m_tools_print->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnPrint ), NULL, this ); Connect( m_tools_layout->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnZoomLayout ), NULL, this ); Connect( m_tools_tiny->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnSetZoom ), NULL, this ); Connect( m_tools_small->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnSetZoom ), NULL, this ); Connect( m_tools_medium->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnSetZoom ), NULL, this ); Connect( m_tools_large->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnSetZoom ), NULL, this ); Connect( m_tools_largest->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnSetZoom ), NULL, this ); Connect( m_tools_clearhist->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnClearHistory ), NULL, this ); Connect( m_find->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnFind ), NULL, this ); // Connect the idle events Connect( wxID_ANY, wxEVT_IDLE, wxIdleEventHandler( WEB_NAVIGATOR::OnIdle ), NULL, this ); } WEB_NAVIGATOR::~WEB_NAVIGATOR() { delete m_tools_menu; } void WEB_NAVIGATOR::buildToolMenu() { m_tools_menu = new wxMenu(); m_tools_print = m_tools_menu->Append( wxID_ANY, _( "Print" ) ); m_tools_viewSource = m_tools_menu->Append( wxID_ANY, _( "View Source" ) ); m_tools_menu->AppendSeparator(); m_tools_layout = m_tools_menu->AppendCheckItem( wxID_ANY, _( "Use Layout Zoom" ) ); m_tools_tiny = m_tools_menu->AppendCheckItem( wxID_ANY, _( "Tiny" ) ); m_tools_small = m_tools_menu->AppendCheckItem( wxID_ANY, _( "Small" ) ); m_tools_medium = m_tools_menu->AppendCheckItem( wxID_ANY, _( "Medium" ) ); m_tools_large = m_tools_menu->AppendCheckItem( wxID_ANY, _( "Large" ) ); m_tools_largest = m_tools_menu->AppendCheckItem( wxID_ANY, _( "Largest" ) ); m_tools_menu->AppendSeparator(); // Find m_find = m_tools_menu->Append( wxID_ANY, _( "Find" ) ); m_tools_menu->AppendSeparator(); // History menu m_tools_history_menu = new wxMenu(); m_tools_clearhist = m_tools_history_menu->Append( wxID_ANY, _( "Clear History" ) ); m_tools_history_menu->AppendSeparator(); m_tools_menu->AppendSubMenu( m_tools_history_menu, "History" ); } void WEB_NAVIGATOR::buildToolBar() { // Populate the toolbar m_toolbar->SetToolBitmapSize( wxSize( 26, 26 ) ); m_toolbar->SetMargins( 3, 3 ); // The tool menu (one cannot have a menubar in a dialog, so uise a tool to display a menu m_toolbar_tools = m_toolbar->AddTool( wxID_ANY, _( "Menu" ), KiBitmap( tools_xpm ), _("Access to some options") ); m_toolbar->AddSeparator(); // The navigation tools m_toolbar_back = m_toolbar->AddTool( wxID_ANY, _( "Back" ), KiBitmap( left_xpm ) ); m_toolbar_forward = m_toolbar->AddTool( wxID_ANY, _( "Forward" ), KiBitmap( right_xpm ) ); m_toolbar_stop = m_toolbar->AddTool( wxID_ANY, _( "Stop" ), KiBitmap( red_xpm ) ); m_toolbar_reload = m_toolbar->AddTool( wxID_ANY, _( "Reload" ), KiBitmap( reload2_xpm ) ); m_toolbar->AddSeparator(); m_url = new wxTextCtrl( m_toolbar, wxID_ANY, wxT( "" ), wxDefaultPosition, wxSize( 400, -1 ), wxTE_PROCESS_ENTER ); m_toolbar->AddControl( m_url, _( "URL" ) ); m_toolbar->AddSeparator(); // The Kicad footprint libraries extractor/selector tool: m_toolbar_ListLibs = m_toolbar->AddTool( wxID_ANY, _( "KicadLibs" ), KiBitmap( library_browse_xpm ), _("List .pretty kicad footprint libraries and add selected libraries\n" "to the footprint library table") ); m_toolbar->Realize(); } void WEB_NAVIGATOR::CreateFindToolBar( wxWindow* aParent ) { m_find_toolbar = new wxToolBar( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_HORIZONTAL | wxTB_TEXT | wxTB_HORZ_LAYOUT ); // Create find control. m_find_ctrl = new wxTextCtrl( m_find_toolbar, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 140, -1 ), wxTE_PROCESS_ENTER ); // Find options menu wxMenu* findmenu = new wxMenu; m_find_toolbar_wrap = findmenu->AppendCheckItem( wxID_ANY, "Wrap" ); m_find_toolbar_matchcase = findmenu->AppendCheckItem( wxID_ANY, "Match Case" ); m_find_toolbar_wholeword = findmenu->AppendCheckItem( wxID_ANY, "Entire Word" ); m_find_toolbar_highlight = findmenu->AppendCheckItem( wxID_ANY, "Highlight" ); m_find_toolbar_highlight->Check( true ); // Add find toolbar tools. m_find_toolbar->SetToolSeparation( 7 ); m_find_toolbar_done = m_find_toolbar->AddTool( wxID_ANY, "Close", wxArtProvider::GetBitmap( wxART_CROSS_MARK ) ); m_find_toolbar->AddSeparator(); m_find_toolbar->AddControl( m_find_ctrl, "Find" ); m_find_toolbar->AddSeparator(); m_find_toolbar_next = m_find_toolbar->AddTool( wxID_ANY, "Next", wxArtProvider::GetBitmap( wxART_GO_DOWN, wxART_TOOLBAR, wxSize( 16, 16 ) ) ); m_find_toolbar_previous = m_find_toolbar->AddTool( wxID_ANY, "Previous", wxArtProvider::GetBitmap( wxART_GO_UP, wxART_TOOLBAR, wxSize( 16, 16 ) ) ); m_find_toolbar->AddSeparator(); m_find_toolbar_options = m_find_toolbar->AddTool( wxID_ANY, "Options", wxArtProvider::GetBitmap( wxART_PLUS, wxART_TOOLBAR, wxSize( 16, 16 ) ), "", wxITEM_DROPDOWN ); m_find_toolbar_options->SetDropdownMenu( findmenu ); m_find_toolbar->Realize(); } // A helper function to try to validate urls names // read in github repos. // a valid .pretty github library name ( on github ) // is expected ending with .pretty, and to be a path // relative github url static bool urlFilter( const wxString& aText ) { if( aText.Length() < 8 ) // unlikely a valid .pretty name return false; if( !aText.EndsWith( wxT( ".pretty" ) ) ) return false; wxURI uri( aText ); if( !uri.GetQuery().IsEmpty() ) // the link is a request, not good return false; return true; } void WEB_NAVIGATOR::OnListPrettyLibURLs( wxCommandEvent& event ) { if( m_browser->IsBusy() ) // a page loading is currently in progress return; wxString source = m_browser->GetPageSource(); wxArrayString urls; HTML_LINK_PARSER parser( source, urls ); parser.ParseLinks( urlFilter ); // Create library list. // From github, the links can be relative to the github server URL // In this case, make url absolute wxString reposUrl( m_browser->GetCurrentURL() ); wxURI reposUri( reposUrl ); wxString reposName( reposUri.GetScheme() + wxT( "://" ) + reposUri.GetServer() ); for( unsigned ii = 0; ii < urls.GetCount(); ii++ ) { wxString url = urls[ii]; wxURI currUri( url ); if( !currUri.HasServer() ) { if( url.StartsWith( wxT( "/" ) ) ) // path relative to the server name url.Prepend( reposName ); else // path relative to the server currently open path url.Prepend( reposUrl ); urls[ii] = url; } } // Remove duplicates: // A very basic test, not optimized, but usually we have only few urls for( unsigned ii = 0; ii < urls.GetCount(); ii++ ) { for( unsigned jj = urls.GetCount() - 1; jj > ii; jj-- ) { if( urls[ii] == urls[jj] ) // Duplicate found urls.RemoveAt( jj ); } } wxArrayInt choices; wxString msg( _( "Urls detected as footprint .pretty libraries.\n" "Selected urls will be added to the current footprint library list,\n" "when closing the web viewer") ); if( wxGetSelectedChoices( choices, msg, _( "Footprint libraries" ), urls, this ) <= 0 ) return; // Add selected fp list in list for( unsigned ii = 0; ii < choices.GetCount(); ii++ ) { wxString& url = urls[choices[ii]]; urlListSelection->Add( url ); } } /** * Method that retrieves the current state from the web control and updates the GUI * the reflect this current state. */ void WEB_NAVIGATOR::UpdateState() { m_toolbar->EnableTool( m_toolbar_back->GetId(), m_browser->CanGoBack() ); m_toolbar->EnableTool( m_toolbar_forward->GetId(), m_browser->CanGoForward() ); if( m_browser->IsBusy() ) { m_toolbar->EnableTool( m_toolbar_stop->GetId(), true ); } else { m_toolbar->EnableTool( m_toolbar_stop->GetId(), false ); } SetTitle( m_browser->GetCurrentTitle() ); m_url->SetValue( m_browser->GetCurrentURL() ); } void WEB_NAVIGATOR::OnIdle( wxIdleEvent& WXUNUSED( evt ) ) { if( m_browser->IsBusy() ) { wxSetCursor( wxCURSOR_ARROWWAIT ); m_toolbar->EnableTool( m_toolbar_stop->GetId(), true ); } else { wxSetCursor( wxNullCursor ); m_toolbar->EnableTool( m_toolbar_stop->GetId(), false ); if( urlListSelection ) TestAndStoreFootprintLibLink(); } } // only for fp lib wizard called if there is a non null // aUrlListSelection from idle event, to see if a valid // footprint lib was selected by user, from the context menu // (command copy link) void WEB_NAVIGATOR::TestAndStoreFootprintLibLink() { if( !urlListSelection ) return; if( wxTheClipboard->Open() ) { if( wxTheClipboard->IsSupported( wxDF_TEXT ) ) { wxTextDataObject data; if( wxTheClipboard->GetData( data ) ) { // A valid text data is found const wxString& text = data.GetText(); // Be sure it is a valid data for us, i.e. a valid // kicad url if( urlFilter( text ) && ( text.StartsWith( "http" ) ) ) { urlListSelection->Add( text ); wxTheClipboard->SetData( new wxTextDataObject( wxEmptyString ) ); } } wxTheClipboard->Close(); } } } /** * Callback invoked when user entered an URL and pressed enter */ void WEB_NAVIGATOR::OnUrl( wxCommandEvent& WXUNUSED( evt ) ) { m_browser->LoadURL( m_url->GetValue() ); m_browser->SetFocus(); UpdateState(); } /** * Callback invoked when user pressed the "back" button */ void WEB_NAVIGATOR::OnBack( wxCommandEvent& WXUNUSED( evt ) ) { m_browser->GoBack(); UpdateState(); } /** * Callback invoked when user pressed the "forward" button */ void WEB_NAVIGATOR::OnForward( wxCommandEvent& WXUNUSED( evt ) ) { m_browser->GoForward(); UpdateState(); } /** * Callback invoked when user pressed the "stop" button */ void WEB_NAVIGATOR::OnStop( wxCommandEvent& WXUNUSED( evt ) ) { m_browser->Stop(); UpdateState(); } /** * Callback invoked when user pressed the "reload" button */ void WEB_NAVIGATOR::OnReload( wxCommandEvent& WXUNUSED( evt ) ) { m_browser->Reload(); UpdateState(); } void WEB_NAVIGATOR::OnClearHistory( wxCommandEvent& WXUNUSED( evt ) ) { m_browser->ClearHistory(); UpdateState(); } void WEB_NAVIGATOR::OnFind( wxCommandEvent& WXUNUSED( evt ) ) { wxString value = m_browser->GetSelectedText(); if( value.Len() > 150 ) { value.Truncate( 150 ); } m_find_ctrl->SetValue( value ); if( !m_find_toolbar->IsShown() ) { m_find_toolbar->Show( true ); SendSizeEvent(); } m_find_ctrl->SelectAll(); } void WEB_NAVIGATOR::OnFindDone( wxCommandEvent& WXUNUSED( evt ) ) { m_browser->Find( "" ); m_find_toolbar->Show( false ); SendSizeEvent(); } void WEB_NAVIGATOR::OnFindText( wxCommandEvent& evt ) { int flags = 0; if( m_find_toolbar_wrap->IsChecked() ) flags |= wxWEBVIEW_FIND_WRAP; if( m_find_toolbar_wholeword->IsChecked() ) flags |= wxWEBVIEW_FIND_ENTIRE_WORD; if( m_find_toolbar_matchcase->IsChecked() ) flags |= wxWEBVIEW_FIND_MATCH_CASE; if( m_find_toolbar_highlight->IsChecked() ) flags |= wxWEBVIEW_FIND_HIGHLIGHT_RESULT; if( m_find_toolbar_previous->GetId() == evt.GetId() ) flags |= wxWEBVIEW_FIND_BACKWARDS; wxString find_text = m_find_ctrl->GetValue(); long count = wxNOT_FOUND; // On windows, for an unknwon reason (bug ?) some texts in some // html pages hang the search. // Waiting for 2 chars before starting a search reduces the risk // (but the risk still exists) #ifdef __WINDOWS__ #define MIN_CHAR_CNT 2 if( find_text.Length() >= MIN_CHAR_CNT ) count = m_browser->Find( find_text, flags ); else // Reset search m_browser->Find( wxEmptyString, flags ); #else #define MIN_CHAR_CNT 1 count = m_browser->Find( find_text, flags ); #endif if( m_findText != find_text ) { m_findCount = count; m_findText = find_text; } if( count != wxNOT_FOUND || find_text.Length() < MIN_CHAR_CNT ) m_find_ctrl->SetBackgroundColour( *wxWHITE ); else m_find_ctrl->SetBackgroundColour( wxColour( 255, 101, 101 ) ); m_find_ctrl->Refresh(); } /** * Callback invoked when there is a request to load a new page (for instance * when the user clicks a link) */ void WEB_NAVIGATOR::OnNavigationRequest( wxWebViewEvent& evt ) { if( m_info->IsShown() ) m_info->Dismiss(); wxASSERT( m_browser->IsBusy() ); UpdateState(); } /** * Invoked when user selects the "View Source" menu item */ void WEB_NAVIGATOR::OnViewSourceRequest( wxCommandEvent& WXUNUSED( evt ) ) { SourceViewDialog dlg( this, m_browser->GetPageSource() ); dlg.ShowModal(); } /** * Invoked when user selects the "Menu" item */ void WEB_NAVIGATOR::OnToolsClicked( wxCommandEvent& WXUNUSED( evt ) ) { if( m_browser->GetCurrentURL() == "" ) return; m_tools_tiny->Check( false ); m_tools_small->Check( false ); m_tools_medium->Check( false ); m_tools_large->Check( false ); m_tools_largest->Check( false ); wxWebViewZoom zoom = m_browser->GetZoom(); switch( zoom ) { case wxWEBVIEW_ZOOM_TINY: m_tools_tiny->Check(); break; case wxWEBVIEW_ZOOM_SMALL: m_tools_small->Check(); break; case wxWEBVIEW_ZOOM_MEDIUM: m_tools_medium->Check(); break; case wxWEBVIEW_ZOOM_LARGE: m_tools_large->Check(); break; case wxWEBVIEW_ZOOM_LARGEST: m_tools_largest->Check(); break; } // Firstly we clear the existing menu items, then we add the current ones wxMenuHistoryMap::const_iterator it; for( it = m_histMenuItems.begin(); it != m_histMenuItems.end(); ++it ) { m_tools_history_menu->Destroy( it->first ); } m_histMenuItems.clear(); wxVector > back = m_browser->GetBackwardHistory(); wxVector > forward = m_browser->GetForwardHistory(); wxMenuItem* item; unsigned int i; for( i = 0; i < back.size(); i++ ) { item = m_tools_history_menu->AppendRadioItem( wxID_ANY, back[i]->GetTitle() ); m_histMenuItems[item->GetId()] = back[i]; Connect( item->GetId(), wxEVT_MENU, wxCommandEventHandler( WEB_NAVIGATOR::OnHistory ), NULL, this ); } wxString title = m_browser->GetCurrentTitle(); if( title.empty() ) title = "(untitled)"; item = m_tools_history_menu->AppendRadioItem( wxID_ANY, title ); item->Check(); // No need to connect the current item m_histMenuItems[item->GetId()] = wxSharedPtr( new wxWebViewHistoryItem( m_browser->GetCurrentURL(), m_browser->GetCurrentTitle() ) ); for( i = 0; i < forward.size(); i++ ) { item = m_tools_history_menu->AppendRadioItem( wxID_ANY, forward[i]->GetTitle() ); m_histMenuItems[item->GetId()] = forward[i]; Connect( item->GetId(), wxEVT_TOOL, wxCommandEventHandler( WEB_NAVIGATOR::OnHistory ), NULL, this ); } wxPoint position = ScreenToClient( wxGetMousePosition() ); PopupMenu( m_tools_menu, position.x, position.y ); } /** * Invoked when user selects the zoom size in the menu */ void WEB_NAVIGATOR::OnSetZoom( wxCommandEvent& evt ) { if( evt.GetId() == m_tools_tiny->GetId() ) m_browser->SetZoom( wxWEBVIEW_ZOOM_TINY ); else if( evt.GetId() == m_tools_small->GetId() ) m_browser->SetZoom( wxWEBVIEW_ZOOM_SMALL ); else if( evt.GetId() == m_tools_medium->GetId() ) m_browser->SetZoom( wxWEBVIEW_ZOOM_MEDIUM ); else if( evt.GetId() == m_tools_large->GetId() ) m_browser->SetZoom( wxWEBVIEW_ZOOM_LARGE ); else if( evt.GetId() == m_tools_largest->GetId() ) m_browser->SetZoom( wxWEBVIEW_ZOOM_LARGEST ); else wxFAIL; } void WEB_NAVIGATOR::OnZoomLayout( wxCommandEvent& WXUNUSED( evt ) ) { if( m_tools_layout->IsChecked() ) m_browser->SetZoomType( wxWEBVIEW_ZOOM_TYPE_LAYOUT ); else m_browser->SetZoomType( wxWEBVIEW_ZOOM_TYPE_TEXT ); } /** * Callback invoked when a loading error occurs */ void WEB_NAVIGATOR::OnError( wxWebViewEvent& evt ) { #define WX_ERROR_CASE( type ) case type: \ category = # type; break; wxString category; switch( evt.GetInt() ) { WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_CONNECTION ); WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_CERTIFICATE ); WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_AUTH ); WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_SECURITY ); WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_NOT_FOUND ); WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_REQUEST ); WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_USER_CANCELLED ); WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_OTHER ); } // Show the info bar with an error wxString msg; msg.Printf( _( "An error occurred loading %s\n'%s'" ), evt.GetURL().GetData(), category.GetData() ); m_info->ShowMessage( msg, wxICON_ERROR ); UpdateState(); } SourceViewDialog::SourceViewDialog( wxWindow* parent, wxString source ) : wxDialog( parent, wxID_ANY, "Source Code", wxDefaultPosition, wxSize( 700, 500 ), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ) { wxStyledTextCtrl* text = new wxStyledTextCtrl( this, wxID_ANY ); text->SetMarginWidth( 1, 30 ); text->SetMarginType( 1, wxSTC_MARGIN_NUMBER ); text->SetText( source ); text->StyleClearAll(); text->SetLexer( wxSTC_LEX_HTML ); text->StyleSetForeground( wxSTC_H_DOUBLESTRING, wxColour( 255, 0, 0 ) ); text->StyleSetForeground( wxSTC_H_SINGLESTRING, wxColour( 255, 0, 0 ) ); text->StyleSetForeground( wxSTC_H_ENTITY, wxColour( 255, 0, 0 ) ); text->StyleSetForeground( wxSTC_H_TAG, wxColour( 0, 150, 0 ) ); text->StyleSetForeground( wxSTC_H_TAGUNKNOWN, wxColour( 0, 150, 0 ) ); text->StyleSetForeground( wxSTC_H_ATTRIBUTE, wxColour( 0, 0, 150 ) ); text->StyleSetForeground( wxSTC_H_ATTRIBUTEUNKNOWN, wxColour( 0, 0, 150 ) ); text->StyleSetForeground( wxSTC_H_COMMENT, wxColour( 150, 150, 150 ) ); wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); sizer->Add( text, 1, wxEXPAND ); SetSizer( sizer ); }