mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Fix issue when using a page layout file in project folder: eeschema and Pcbnew did not use it, unless using an absolute path. Now, if the file path is nor absolute, it is seen as relative to the project (which is the expected behavior) fp lib wizard: when pcbnew id compiled with USE_GITHUB_PLUGIN=OFF, the github plugin option is no more accessible (and the web viewer no more used).
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 );
|
|
}
|