971 lines
30 KiB
C++
971 lines
30 KiB
C++
/*
|
|
* 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 <wx/clipbrd.h>
|
|
#include <wx/uri.h>
|
|
#if wxUSE_STC
|
|
#include "wx/stc/stc.h"
|
|
#else
|
|
#error "wxWidgets must be built with wxStyledTextControl enabled. Please rebuild wxWidgets"
|
|
#endif
|
|
|
|
#include <dialog_shim.h>
|
|
#include <bitmaps.h>
|
|
#include "html_link_parser.h"
|
|
|
|
// We map menu items to their history items
|
|
WX_DECLARE_HASH_MAP( int, wxSharedPtr<wxWebViewHistoryItem>,
|
|
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<wxSharedPtr<wxWebViewHistoryItem> > back = m_browser->GetBackwardHistory();
|
|
wxVector<wxSharedPtr<wxWebViewHistoryItem> > 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<wxWebViewHistoryItem>( 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 );
|
|
}
|