Add wizard to fp lib dialog to easily add entries to this table.

This commit is contained in:
jean-pierre charras 2014-12-21 15:13:14 +01:00
parent 1393bcafc0
commit e4a74213e4
19 changed files with 5794 additions and 2 deletions

View File

@ -36,6 +36,21 @@ option( KICAD_KEEPCASE
ON
)
# The footprint library wizard uses wxWEBVIEW, which needs a system webkit to be built
# The default build option in wxWidgets is to build wxWEBVIEW, but it colud be not built
# if web kit devel tools are missing
# So this option disable use of wxWEBVIEW, if building wxWEBVIEW creates issues
# see:
# http://docs.wxwidgets.org/3.0/classwx_web_view.html
# No issues on Windows, needs webkitgtk-devel package installed on Linux.
# (I don't know the OSX status)
# However the default option is on
# This option could be removed soon, if no serious issue happens on Linux or OSX
option( KICAD_USE_WEBKIT
"Use system web kit to build a web viewer in footprint library wizard to easily select github libraries (default ON)."
ON
)
option( USE_WX_GRAPHICS_CONTEXT
"Use wxGraphicsContext for rendering (default OFF). Warning, this is experimental" )
@ -403,7 +418,13 @@ add_definitions( -DWX_COMPATIBILITY )
# See line 41 of CMakeModules/FindwxWidgets.cmake
set( wxWidgets_CONFIG_OPTIONS --static=no )
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml REQUIRED )
if( KICAD_USE_WEBKIT )
set( webkitlib "webview" )
else()
set( webkitlib "" )
endif()
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml ${webkitlib} stc REQUIRED )
# Include wxWidgets macros.
include( ${wxWidgets_USE_FILE} )
@ -684,6 +705,9 @@ add_subdirectory( cvpcb )
add_subdirectory( eeschema )
add_subdirectory( gerbview )
add_subdirectory( lib_dxf )
if( KICAD_USE_WEBKIT )
add_subdirectory( webviewer )
endif()
add_subdirectory( pcbnew )
add_subdirectory( polygon )
add_subdirectory( pagelayout_editor )

View File

@ -8,6 +8,12 @@ endif()
add_definitions( -DCVPCB )
if( KICAD_USE_WEBKIT )
set( WEBVIEWERTOOL "webviewer" )
add_definitions( -DKICAD_USE_WEBKIT )
endif()
include_directories( BEFORE ${INC_BEFORE} )
include_directories(
./dialogs
@ -29,6 +35,8 @@ set( CVPCB_DIALOGS
../pcbnew/dialogs/dialog_fp_lib_table_base.cpp
../pcbnew/dialogs/dialog_fp_plugin_options.cpp
../pcbnew/dialogs/dialog_fp_plugin_options_base.cpp
../pcbnew/dialogs/wizard_add_fplib_base.cpp
../pcbnew/dialogs/wizard_add_fplib.cpp
)
set( CVPCB_SRCS
@ -75,9 +83,11 @@ add_executable( cvpcb WIN32 MACOSX_BUNDLE
../common/pgm_base.cpp
${CVPCB_RESOURCES}
)
set_source_files_properties( ../common/single_top.cpp PROPERTIES
COMPILE_DEFINITIONS "TOP_FRAME=FRAME_CVPCB;PGM_DATA_FILE_EXT=\"net\";BUILD_KIWAY_DLL"
)
target_link_libraries( cvpcb
#singletop # replaces common, giving us restrictive control and link warnings.
# There's way too much crap coming in from common yet.
@ -107,6 +117,7 @@ target_link_libraries( cvpcb_kiface
pcbcommon
pcad2kicadpcb
common
${WEBVIEWERTOOL} # before bitmaps, because it uses some bitmaps defined in bitmaps
bitmaps
polygon
gal

View File

@ -129,6 +129,8 @@ set( PCBNEW_DIALOGS
footprint_wizard_frame.cpp
dialogs/dialog_footprint_wizard_list_base.cpp
dialogs/dialog_footprint_wizard_list.cpp
dialogs/wizard_add_fplib_base.cpp
dialogs/wizard_add_fplib.cpp
)
set( PCBNEW_IMPORT_DXF
@ -368,6 +370,11 @@ if( UNIX AND NOT APPLE )
list( APPEND PCBNEW_EXTRA_LIBS rt )
endif()
if( KICAD_USE_WEBKIT )
set( WEBVIEWERTOOL "webviewer" )
add_definitions( -DKICAD_USE_WEBKIT )
endif()
if( KICAD_SCRIPTING_MODULES )
@ -375,6 +382,7 @@ if( KICAD_SCRIPTING_MODULES )
set( CMAKE_SWIG_FLAGS ${SWIG_FLAGS} )
set_source_files_properties( scripting/pcbnew.i PROPERTIES CPLUSPLUS ON )
swig_add_module( pcbnew
python
scripting/pcbnew.i
@ -383,6 +391,7 @@ if( KICAD_SCRIPTING_MODULES )
${PCBNEW_SRCS}
${PCBNEW_COMMON_SRCS}
)
swig_link_libraries( pcbnew
3d-viewer
pcbcommon
@ -393,6 +402,7 @@ if( KICAD_SCRIPTING_MODULES )
idf3
${GITHUB_PLUGIN_LIBRARIES}
polygon
${WEBVIEWERTOOL}
bitmaps
gal
${GLEW_LIBRARIES}
@ -559,6 +569,7 @@ target_link_libraries( pcbnew_kiface
common
pcad2kicadpcb
polygon
${WEBVIEWERTOOL} # before bitmaps, because it uses some bitmaps defined in bitmap
bitmaps
gal
lib_dxf

View File

@ -43,6 +43,8 @@
#include <invoke_pcb_dialog.h>
#include <grid_tricks.h>
#include <confirm.h>
#include <wizard_add_fplib.h>
/// grid column order is established by this sequence
enum COL_ORDER
@ -356,6 +358,11 @@ public:
wxAuiNotebookEvent uneventful;
pageChangedHandler( uneventful );
// Gives a selection for each grid, mainly for delete lib button.
// Without that, we do not see what lib will be deleted
m_global_grid->SelectRow(0);
m_project_grid->SelectRow(0);
// for ALT+A handling, we want the initial focus to be on the first selected grid.
m_cur_grid->SetFocus();
}
@ -512,11 +519,32 @@ private:
// wx documentation is wrong, SetGridCursor does not make visible.
m_cur_grid->MakeCellVisible( last_row, 0 );
m_cur_grid->SetGridCursor( last_row, 0 );
m_cur_grid->SelectRow( m_cur_grid->GetGridCursorRow() );
}
}
void deleteRowHandler( wxMouseEvent& event )
{
#if 1
int currRow = getCursorRow();
wxArrayInt selectedRows = m_cur_grid->GetSelectedRows();
if( selectedRows.size() == 0 && getCursorRow() >= 0 )
selectedRows.Add( getCursorRow() );
std::sort( selectedRows.begin(), selectedRows.end() );
for( int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
{
int row = selectedRows[ii];
m_cur_grid->DeleteRows( row, 1 );
}
if( currRow >= m_cur_grid->GetNumberRows() )
m_cur_grid->SetGridCursor(m_cur_grid->GetNumberRows()-1, getCursorCol() );
m_cur_grid->SelectRow( m_cur_grid->GetGridCursorRow() );
#else
int rowCount = m_cur_grid->GetNumberRows();
int curRow = getCursorRow();
@ -525,9 +553,12 @@ private:
m_cur_grid->DeleteRows( curRow );
if( curRow && curRow == rowCount - 1 )
{
m_cur_grid->SetGridCursor( curRow-1, getCursorCol() );
}
}
#endif
}
void moveUpHandler( wxMouseEvent& event )
{
@ -557,6 +588,7 @@ private:
m_cur_grid->MakeCellVisible( curRow, curCol );
m_cur_grid->SetGridCursor( curRow, curCol );
m_cur_grid->SelectRow( getCursorRow() );
}
}
@ -588,6 +620,7 @@ private:
m_cur_grid->MakeCellVisible( curRow, curCol );
m_cur_grid->SetGridCursor( curRow, curCol );
m_cur_grid->SelectRow( getCursorRow() );
}
}
@ -623,6 +656,8 @@ private:
}
}
void OnClickLibraryWizard( wxCommandEvent& event );
void onCancelButtonClick( wxCommandEvent& event )
{
EndModal( 0 );
@ -719,7 +754,7 @@ private:
// the current project.
unique.insert( PROJECT_VAR_NAME );
unique.insert( FP_LIB_TABLE::GlobalPathEnvVariableName() );
// This special environment variable is used to locad 3d shapes
// This special environment variable is used to locate 3d shapes
unique.insert( KISYS3DMOD );
unique.insert( FP_LIB_TABLE::GlobalPathEnvVariableName() );
@ -757,6 +792,50 @@ private:
int DIALOG_FP_LIB_TABLE::m_pageNdx = 0;
void DIALOG_FP_LIB_TABLE::OnClickLibraryWizard( wxCommandEvent& event )
{
wxArrayString envVariableList;
// Build the environment variables in use:
for( int ii = 0; ii < m_path_subs_grid->GetTable()->GetRowsCount(); ii ++ )
envVariableList.Add( m_path_subs_grid->GetCellValue( wxGridCellCoords( ii, 0 ) ) );
WIZARD_FPLIB_TABLE dlg( this, envVariableList );
if( ! dlg.RunWizard( dlg.GetFirstPage() ) )
return; // Aborted by user
wxGrid* libgrid = m_cur_grid;
FP_TBL_MODEL* tbl = (FP_TBL_MODEL*) libgrid->GetTable();
// Import fp library list
int idx = 0;
wxArrayString libDescr; // Will contain nickname, URI, plugin
while( dlg.GetLibDescr( idx++, libDescr ) )
{
if( ! libDescr[0].IsEmpty() && m_cur_grid->AppendRows( 1 ) )
{
int last_row = libgrid->GetNumberRows() - 1;
// Add the nickname: currently make it from filename
tbl->SetValue( last_row, COL_NICKNAME, libDescr[0] );
// Add the full path:
tbl->SetValue( last_row, COL_URI, libDescr[1] );
// Add the plugin name:
tbl->SetValue( last_row, COL_TYPE, libDescr[2] );
libgrid->MakeCellVisible( last_row, 0 );
libgrid->SetGridCursor( last_row, 0 );
}
libDescr.Clear();
}
libgrid->SelectRow( libgrid->GetGridCursorRow() );
}
int InvokePcbLibTableEditor( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject )
{
DIALOG_FP_LIB_TABLE dlg( aParent, aGlobal, aProject );

View File

@ -103,6 +103,9 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID
bSizer51->Add( m_append_button, 0, wxALL, 5 );
m_buttonWizard = new wxButton( this, wxID_ANY, _("Append with Wizard"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer51->Add( m_buttonWizard, 0, wxALL, 5 );
m_delete_button = new wxButton( this, wxID_ANY, _("Remove Library"), wxDefaultPosition, wxDefaultSize, 0 );
m_delete_button->SetToolTip( _("Remove a PCB library from this library table") );
@ -194,6 +197,7 @@ DIALOG_FP_LIB_TABLE_BASE::DIALOG_FP_LIB_TABLE_BASE( wxWindow* parent, wxWindowID
this->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FP_LIB_TABLE_BASE::onKeyDown ) );
m_auinotebook->Connect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( DIALOG_FP_LIB_TABLE_BASE::pageChangedHandler ), NULL, this );
m_append_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::appendRowHandler ), NULL, this );
m_buttonWizard->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::OnClickLibraryWizard ), NULL, this );
m_delete_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::deleteRowHandler ), NULL, this );
m_move_up_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveUpHandler ), NULL, this );
m_move_down_button->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveDownHandler ), NULL, this );
@ -209,6 +213,7 @@ DIALOG_FP_LIB_TABLE_BASE::~DIALOG_FP_LIB_TABLE_BASE()
this->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( DIALOG_FP_LIB_TABLE_BASE::onKeyDown ) );
m_auinotebook->Disconnect( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEventHandler( DIALOG_FP_LIB_TABLE_BASE::pageChangedHandler ), NULL, this );
m_append_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::appendRowHandler ), NULL, this );
m_buttonWizard->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FP_LIB_TABLE_BASE::OnClickLibraryWizard ), NULL, this );
m_delete_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::deleteRowHandler ), NULL, this );
m_move_up_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveUpHandler ), NULL, this );
m_move_down_button->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler( DIALOG_FP_LIB_TABLE_BASE::moveDownHandler ), NULL, this );

View File

@ -751,6 +751,94 @@
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Append with Wizard</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_buttonWizard</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnClickLibraryWizard</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>

View File

@ -47,6 +47,7 @@ class DIALOG_FP_LIB_TABLE_BASE : public DIALOG_SHIM
wxPanel* m_project_panel;
wxGrid* m_project_grid;
wxButton* m_append_button;
wxButton* m_buttonWizard;
wxButton* m_delete_button;
wxButton* m_move_up_button;
wxButton* m_move_down_button;
@ -61,6 +62,7 @@ class DIALOG_FP_LIB_TABLE_BASE : public DIALOG_SHIM
virtual void onKeyDown( wxKeyEvent& event ) = 0;
virtual void pageChangedHandler( wxAuiNotebookEvent& event ) = 0;
virtual void appendRowHandler( wxMouseEvent& event ) = 0;
virtual void OnClickLibraryWizard( wxCommandEvent& event ) = 0;
virtual void deleteRowHandler( wxMouseEvent& event ) = 0;
virtual void moveUpHandler( wxMouseEvent& event ) = 0;
virtual void moveDownHandler( wxMouseEvent& event ) = 0;

View File

@ -0,0 +1,59 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 5 2014)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_select_dirlist_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_SELECT_DIRLIST_BASE::DIALOG_SELECT_DIRLIST_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( 400,300 ), wxDefaultSize );
wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL );
m_staticText = new wxStaticText( this, wxID_ANY, _("The footprint library is a folde.\nFootprints are files inside this folder."), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText->Wrap( -1 );
m_staticText->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
bSizerMain->Add( m_staticText, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_dirCtrl = new wxGenericDirCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDIRCTRL_3D_INTERNAL|wxDIRCTRL_DIR_ONLY|wxDIRCTRL_MULTIPLE|wxDIRCTRL_SHOW_FILTERS|wxSUNKEN_BORDER, _("*.pretty|*"), 0 );
m_dirCtrl->ShowHidden( false );
bSizerMain->Add( m_dirCtrl, 1, wxEXPAND | wxALL, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerMain->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bSizerMain->Add( m_sdbSizer, 0, wxALIGN_RIGHT, 5 );
this->SetSizer( bSizerMain );
this->Layout();
this->Centre( wxBOTH );
// Connect Events
m_dirCtrl->Connect( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEventHandler( DIALOG_SELECT_DIRLIST_BASE::OnSelectFolder ), NULL, this );
m_dirCtrl->Connect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( DIALOG_SELECT_DIRLIST_BASE::OnSelectFolder ), NULL, this );
}
DIALOG_SELECT_DIRLIST_BASE::~DIALOG_SELECT_DIRLIST_BASE()
{
// Disconnect Events
m_dirCtrl->Disconnect( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEventHandler( DIALOG_SELECT_DIRLIST_BASE::OnSelectFolder ), NULL, this );
m_dirCtrl->Disconnect( wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEventHandler( DIALOG_SELECT_DIRLIST_BASE::OnSelectFolder ), NULL, this );
}

View File

@ -0,0 +1,391 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="13" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">dialog_select_dirlist_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="internationalize">1</property>
<property name="name">dialog_select_dirlist_base</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="center">wxBOTH</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">400,300</property>
<property name="name">DIALOG_SELECT_DIRLIST_BASE</property>
<property name="pos"></property>
<property name="size">400,300</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title">Select Footprint Library Folder</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnActivate"></event>
<event name="OnActivateApp"></event>
<event name="OnAuiFindManager"></event>
<event name="OnAuiPaneButton"></event>
<event name="OnAuiPaneClose"></event>
<event name="OnAuiPaneMaximize"></event>
<event name="OnAuiPaneRestore"></event>
<event name="OnAuiRender"></event>
<event name="OnChar"></event>
<event name="OnClose"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnHibernate"></event>
<event name="OnIconize"></event>
<event name="OnIdle"></event>
<event name="OnInitDialog"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerMain</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font">,90,92,-1,70,0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">The footprint library is a folde.&#x0A;Footprints are files inside this folder.</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property>
<property name="proportion">1</property>
<object class="wxGenericDirCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="defaultfilter">0</property>
<property name="defaultfolder"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="filter">*.pretty|*</property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_dirCtrl</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="show_hidden">0</property>
<property name="size"></property>
<property name="style">wxDIRCTRL_3D_INTERNAL|wxDIRCTRL_DIR_ONLY|wxDIRCTRL_MULTIPLE|wxDIRCTRL_SHOW_FILTERS</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxSUNKEN_BORDER</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnTreeBeginDrag"></event>
<event name="OnTreeBeginLabelEdit"></event>
<event name="OnTreeBeginRDrag"></event>
<event name="OnTreeDeleteItem"></event>
<event name="OnTreeEndDrag"></event>
<event name="OnTreeEndLabelEdit"></event>
<event name="OnTreeItemActivated">OnSelectFolder</event>
<event name="OnTreeItemCollapsed"></event>
<event name="OnTreeItemCollapsing"></event>
<event name="OnTreeItemExpanded"></event>
<event name="OnTreeItemExpanding"></event>
<event name="OnTreeItemMenu"></event>
<event name="OnTreeItemMiddleClick"></event>
<event name="OnTreeItemRightClick"></event>
<event name="OnTreeKeyDown"></event>
<event name="OnTreeSelChanged">OnSelectFolder</event>
<event name="OnTreeSelChanging"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticLine" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticline1</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxLI_HORIZONTAL</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_RIGHT</property>
<property name="proportion">0</property>
<object class="wxStdDialogButtonSizer" expanded="1">
<property name="Apply">0</property>
<property name="Cancel">1</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
<property name="No">0</property>
<property name="OK">1</property>
<property name="Save">0</property>
<property name="Yes">0</property>
<property name="minimum_size"></property>
<property name="name">m_sdbSizer</property>
<property name="permission">protected</property>
<event name="OnApplyButtonClick"></event>
<event name="OnCancelButtonClick"></event>
<event name="OnContextHelpButtonClick"></event>
<event name="OnHelpButtonClick"></event>
<event name="OnNoButtonClick"></event>
<event name="OnOKButtonClick"></event>
<event name="OnSaveButtonClick"></event>
<event name="OnYesButtonClick"></event>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>

View File

@ -0,0 +1,58 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 5 2014)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_SELECT_DIRLIST_BASE_H__
#define __DIALOG_SELECT_DIRLIST_BASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class DIALOG_SHIM;
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/dirctrl.h>
#include <wx/statline.h>
#include <wx/sizer.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_SELECT_DIRLIST_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_SELECT_DIRLIST_BASE : public DIALOG_SHIM
{
private:
protected:
wxStaticText* m_staticText;
wxGenericDirCtrl* m_dirCtrl;
wxStaticLine* m_staticline1;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnSelectFolder( wxTreeEvent& event ) { event.Skip(); }
public:
DIALOG_SELECT_DIRLIST_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select Footprint Library Folder"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 400,300 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_SELECT_DIRLIST_BASE();
};
#endif //__DIALOG_SELECT_DIRLIST_BASE_H__

View File

@ -0,0 +1,772 @@
/**
* @file wizard_add_fplib.cpp
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* 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
*/
/** @brief this code creates a wizard to add entries in the footprint library table.
* The wizard contains 3 pages:
* The first is the selection of the type of libraries (plugin type):
* * Kicad .pretty library (actually a folder containing .kicad_mod footprint files)
* * Gihtub .pretty on line library, accessible via a internet connection
* * Legacy library (old .mod format file containing footprints desc)
* * Eagle xml V6 library (.lbr files)
* * Geda-PCB library (actually a folder containing .fp footprint files
* The second is the selection of path management:
* use environment variable or absolute path.
* When using an environment variable, selec it
* The third is the library list selection
* It allows entering entries by running a tool to select a set of libraries
* The tool depend on the type of lib (files/folder/urls):
* * multi files selector
* * multi folder selector
* * multi URL selector (via a web viewer)
* The path and the plugin type comes from the selection, and a library nickname
* is built from the path.
*/
#include <wx/wx.h>
#include <wx/url.h>
#include <pgm_base.h>
#include <kiface_i.h>
#include <dialog_helpers.h>
#include <project.h> // For PROJECT_VAR_NAME definition
#include <io_mgr.h>
#include <wizard_add_fplib.h>
// a key to store the default Kicad Github libs URL
#define KICAD_FPLIBS_URL_KEY wxT( "kicad_fplib_url" )
// key to store last options of th wizard
#define WIZARD_LAST_PLUGIN_KEY wxT( "wizard_plugin" )
#define WIZARD_LAST_PATHOPTION_KEY wxT( "wizard_path_option" )
// static members to store last choices during a session
int WIZARD_FPLIB_TABLE::m_last_plugin_choice = 0;
int WIZARD_FPLIB_TABLE::m_last_defaultpath_choice = 2;
WIZARD_FPLIB_TABLE::WIZARD_FPLIB_TABLE( wxWindow* aParent, wxArrayString& aEnvVariableList )
: WIZARD_FPLIB_TABLE_BASE( aParent )
{
initDlg( aEnvVariableList );
// Currently, I (JPC) do not know the best way to add/store
// what is currently called env variables
// So do not show tools to change them,
// but do not remove the code, just in case
m_buttonAddEV->Show( false );
m_buttonRemoveEV->Show( false );
// Gives a minimal size to the dialog, which allows displaying any page
wxSize minsize;
for( unsigned ii = 0; ii < m_pages.size(); ii++ )
{
wxSize size = m_pages[ii]->GetSizer()->CalcMin();
minsize.x = std::max( minsize.x, size.x );
minsize.y = std::max( minsize.y, size.y );
}
SetMinSize( minsize );
SetPageSize( minsize );
GetSizer()->SetSizeHints( this );
Center();
}
WIZARD_FPLIB_TABLE::~WIZARD_FPLIB_TABLE()
{
// Use this if you want to store kicad lib URL in pcbnew/cvpcb section config:
// wxConfigBase* cfg = Kiface().KifaceSettings();
// Use this if you want to store kicad lib URL in common section config:
wxConfigBase* cfg = Pgm().CommonSettings();
cfg->Write( KICAD_FPLIBS_URL_KEY, m_textCtrlGithubURL->GetValue() );
m_last_plugin_choice = m_rbFpLibFormat->GetSelection();
m_last_defaultpath_choice = m_rbPathManagement->GetSelection();
cfg->Write( WIZARD_LAST_PLUGIN_KEY, m_last_plugin_choice );
cfg->Write( WIZARD_LAST_PATHOPTION_KEY, m_last_defaultpath_choice );
}
void WIZARD_FPLIB_TABLE::initDlg( wxArrayString& aEnvVariableList )
{
m_currLibDescr = NULL;
SetBitmap( KiBitmap( wizard_add_fplib_icon_xpm ) );
wxString msg;
wxConfigBase* cfg = Pgm().CommonSettings();
cfg->Read( KICAD_FPLIBS_URL_KEY, &msg );
cfg->Read( WIZARD_LAST_PLUGIN_KEY, &m_last_plugin_choice );
cfg->Read( WIZARD_LAST_PATHOPTION_KEY, &m_last_defaultpath_choice );
if( msg.IsEmpty() )
m_textCtrlGithubURL->SetValue( wxT( "http://github.com/KiCad/" ) );
else
m_textCtrlGithubURL->SetValue( msg );
// KIGITHUB is frequently used (examples in docs, and other place)
// So add it if it not yet in list, but if it is defined as env var
// (note this env var is not hardcoded or existing in kicad sources)
if( aEnvVariableList.Index( wxT("KIGITHUB"), false ) == wxNOT_FOUND )
{
// Not yet in use in lib table, see in env. vars
wxString evValue;
wxGetEnv( wxT("KIGITHUB"), &evValue );
// Not yet in use in lib table, but it is defined in environment,
// so add it, just in case
if( ! evValue.IsEmpty() )
aEnvVariableList.Add( wxT("KIGITHUB") );
}
m_rowPrjEnvVarPosition = 0;
m_predefinedEnvVarCnt = aEnvVariableList.GetCount();
for( int row = 0; row < m_predefinedEnvVarCnt; row++ )
{
if( GetEnvVarCount() <= row )
m_gridEnvironmentVariablesList->AppendRows(1);
m_gridEnvironmentVariablesList->SetCellValue( row, 0, aEnvVariableList[row] );
if( aEnvVariableList[row] == PROJECT_VAR_NAME )
m_rowPrjEnvVarPosition = row;
wxString evValue;
if( wxGetEnv( aEnvVariableList[row], &evValue ) )
m_gridEnvironmentVariablesList->SetCellValue( row, 1, evValue );
// All these env var are defined outside the wizard,
// and cannot be modified in this dialog
m_gridEnvironmentVariablesList->SetReadOnly( row, 0, true );
m_gridEnvironmentVariablesList->SetReadOnly( row, 1, true );
}
m_gridEnvironmentVariablesList->Fit();
m_buttonRemoveEV->Enable( GetEnvVarCount() > m_predefinedEnvVarCnt );
m_gridEnvironmentVariablesList->AutoSizeColumns();
m_rbFpLibFormat->SetSelection( m_last_plugin_choice );
m_rbPathManagement->SetSelection( m_last_defaultpath_choice );
wxCommandEvent event;
updateFromPlugingChoice();
OnPathManagementSelection( event );
}
int WIZARD_FPLIB_TABLE::HasGithubEnvVarCompatible()
{
// Return true if at least one env var defines a url relative to github
for( int row = 0; row < GetEnvVarCount(); row++ )
{
if( m_gridEnvironmentVariablesList->GetCellValue(
wxGridCellCoords( row, 1 ) ).Lower().StartsWith( "http" ) )
return row;
}
return -1;
}
bool WIZARD_FPLIB_TABLE::ValidateOptions()
{
// Some choices can be conficting or do not work.
// Warn the user when this is the case
wxString msg;
if( GetSelectedEnvVarValue().IsEmpty() )
{
// PROJECT_PATH option cannot be used with empty local path
if( m_rbPathManagement->GetSelection() == PROJECT_PATH )
{
msg = _("The project path is empty and this option is not valid.\n"
"Looks like you are running the wizard outside a project.");
wxMessageBox( msg );
return false;
}
else if( m_rbPathManagement->GetSelection() != ABSOLUTE_PATH )
{
wxMessageBox( wxString::Format(
_("The default path defined by env var \"%s\" is empty.\nCannot use it"),
GetChars( GetSelectedEnvVar() ) ) );
return false;
}
}
else
{
if( IsGithubPlugin() )
{
// Github plugin cannot be used with local path; Need absolute path or valid URL
if( !GetSelectedEnvVarValue().Lower().StartsWith( "http" ) )
{
msg = _("Github Plugin uses a valid Internet URL starting by http.\n"
"Cannot be used as URL");
wxMessageBox( msg );
return false;
}
}
else
{
if( GetSelectedEnvVarValue().Lower().StartsWith( "http" ) )
{
msg = _("This default path looks strange.\n"
"Cannot be used for a file path");
wxMessageBox( msg );
return false;
}
}
}
// Other conficts: TODO
return true;
}
void WIZARD_FPLIB_TABLE::OnPluginSelection( wxCommandEvent& event )
{
updateFromPlugingChoice();
}
void WIZARD_FPLIB_TABLE::updateFromPlugingChoice()
{
// update dialog options and widgets depending on a plugin choice
// Project path has no sense for GITHUB_PLUGIN
bool enablePrjPathOpt = not IsGithubPlugin();
// Project path cannot be used if unknown
if( m_gridEnvironmentVariablesList->GetCellValue(
wxGridCellCoords( m_rowPrjEnvVarPosition, 1 ) ).IsEmpty() )
enablePrjPathOpt = false;
m_rbPathManagement->Enable( PROJECT_PATH, enablePrjPathOpt );
// Sometimes only the choice "absolute path" is allowed;
// Force this choice, at least make it the default choice
bool force_absolute_path = false;
// For github plugin, the project path is not allowed
if( ( m_rbPathManagement->GetSelection() == PROJECT_PATH ) && !enablePrjPathOpt )
force_absolute_path = true;
// For github plugin, at least one github compatible path must exist
// If no github path, force absolute path
int first_github_envvar = HasGithubEnvVarCompatible();
if( IsGithubPlugin() )
{
if( first_github_envvar < 0 )
force_absolute_path = true;
else if( !GetSelectedEnvVarValue().StartsWith( "http" ) )
m_gridEnvironmentVariablesList->SelectRow( first_github_envvar );
}
if( force_absolute_path )
m_rbPathManagement->SetSelection( ABSOLUTE_PATH );
}
void WIZARD_FPLIB_TABLE::OnPathManagementSelection( wxCommandEvent& event )
{
// Disable irrevant options, and enable others.
int row_count = GetEnvVarCount();
switch( m_rbPathManagement->GetSelection() )
{
case PROJECT_PATH: // Choice = path relative to the project
m_gridEnvironmentVariablesList->Enable( true );
m_buttonAddEV->Enable( false );
m_gridEnvironmentVariablesList->ShowRow( PROJECT_PATH );
for( int row = 0; row < row_count; row++ )
{
if( row == PROJECT_PATH )
continue;
m_gridEnvironmentVariablesList->HideRow( row );
}
break;
case ENV_VAR_PATH: // Choice = path relative to env var
m_gridEnvironmentVariablesList->Enable( true );
m_buttonAddEV->Enable( true );
for( int row = 0; row < row_count; row++ )
m_gridEnvironmentVariablesList->ShowRow( row );
break;
case ABSOLUTE_PATH: // Choice = path relative to the project
m_gridEnvironmentVariablesList->Enable( false );
m_buttonAddEV->Enable( false );
break;
}
}
void WIZARD_FPLIB_TABLE::OnAddEVariable( wxCommandEvent& event )
{
m_gridEnvironmentVariablesList->AppendRows( 1 );
m_gridEnvironmentVariablesList->AutoSizeColumns();
m_buttonRemoveEV->Enable( GetEnvVarCount() > m_predefinedEnvVarCnt );
m_gridEnvironmentVariablesList->SetGridCursor( GetEnvVarCount()-1, 0 );
}
void WIZARD_FPLIB_TABLE::OnRemoveEVariable( wxCommandEvent& event )
{
wxArrayInt selectedRows = m_gridEnvironmentVariablesList->GetSelectedRows();
int row_cursor = m_gridEnvironmentVariablesList->GetGridCursorRow();
if( selectedRows.size() == 0 && row_cursor >= 0 )
selectedRows.Add( row_cursor );
std::sort( selectedRows.begin(), selectedRows.end() );
for( int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
{
int row = selectedRows[ii];
// don't remove them env var. which are already existing in lib table
if( row > m_predefinedEnvVarCnt-1 )
m_gridEnvironmentVariablesList->DeleteRows( row, 1 );
}
m_gridEnvironmentVariablesList->SelectRow( m_gridEnvironmentVariablesList->GetGridCursorRow() );
m_buttonRemoveEV->Enable( GetEnvVarCount() > m_predefinedEnvVarCnt );
}
void WIZARD_FPLIB_TABLE::OnSelectEnvVarCell( wxGridEvent& event )
{
// Ensure the selected row is also the row which have the focus.
// useful when the user want to delete a row, and select it by the mouse
m_gridEnvironmentVariablesList->SelectRow( event.GetRow() );
}
wxString WIZARD_FPLIB_TABLE::GetSelectedEnvVar()
{
wxString envVar;
wxArrayInt selectedRows = m_gridEnvironmentVariablesList->GetSelectedRows();
int row = selectedRows.GetCount() ? selectedRows[0] :
m_gridEnvironmentVariablesList->GetGridCursorRow();
switch( m_rbPathManagement->GetSelection() )
{
case ENV_VAR_PATH: // Choice = path relative to env var
envVar = m_gridEnvironmentVariablesList->GetCellValue(
wxGridCellCoords( row, 0 ) );
break;
case PROJECT_PATH: // Choice = path relative to the project
envVar = PROJECT_VAR_NAME;
break;
case ABSOLUTE_PATH: // Choice = absolute path
default:
break;
}
return envVar;
}
wxString WIZARD_FPLIB_TABLE::GetSelectedEnvVarValue()
{
wxString envVarValue;
wxArrayInt selectedRows = m_gridEnvironmentVariablesList->GetSelectedRows();
int row = selectedRows.GetCount() ? selectedRows[0] :
m_gridEnvironmentVariablesList->GetGridCursorRow();
switch( m_rbPathManagement->GetSelection() )
{
case ENV_VAR_PATH: // Choice = path relative tp env var
envVarValue = m_gridEnvironmentVariablesList->GetCellValue(
wxGridCellCoords( row, 1 ) );
break;
case PROJECT_PATH: // Choice = path relative to the project
envVarValue = m_gridEnvironmentVariablesList->GetCellValue(
wxGridCellCoords( m_rowPrjEnvVarPosition, 1 ) );
break;
case ABSOLUTE_PATH: // Choice = absolute path
default:
break;
}
return envVarValue;
}
void WIZARD_FPLIB_TABLE::OnPageChanged( wxWizardEvent& event )
{
if( GetCurrentPage() == m_pages[2] )
setLastPage();
else if( GetCurrentPage() == m_pages[1] )
setSecondPage();
}
void WIZARD_FPLIB_TABLE::OnPageChanging( wxWizardEvent& event )
{
if( !( GetCurrentPage() == m_pages[1] && event.GetDirection() ) )
return;
if( ! ValidateOptions() )
{
event.Veto();
return;
}
if( ( m_rbPathManagement->GetSelection() != ABSOLUTE_PATH ) &&
( IsGithubPlugin() ) )
{
wxURI uri( GetSelectedEnvVarValue() );
// We cannot use wxURL to test the validity of the url, because
// wxURL does not know https protocol we are using, and aways returns
// error for url starting by https
bool badurl = !uri.HasPath();
if( badurl )
{
wxMessageBox( wxString::Format(
_("The URL defined by env var \"%s\" is an incorrect URL.\nCannot use it"),
GetChars( GetSelectedEnvVar() ) ) );
event.Veto();
}
}
}
bool WIZARD_FPLIB_TABLE::setSecondPage()
{
// Init parameters for the second wizard page: this is only
// the current library description.
updateFromPlugingChoice();
delete m_currLibDescr;
m_currLibDescr = NULL;
switch( m_rbFpLibFormat->GetSelection() )
{
case 0: // Kicad lib type
m_currLibDescr = new LIB_DESCR_KICAD;
break;
case 1: // Github lib type
m_currLibDescr = new LIB_DESCR_GITHUB;
break;
case 2: // Legacy lib type
m_currLibDescr = new LIB_DESCR_LEGACY;
break;
case 3: // Eagle V6 lib type
m_currLibDescr = new LIB_DESCR_EAGLE;
break;
case 4: // Geda lib type
m_currLibDescr = new LIB_DESCR_GEDA;
break;
}
return m_currLibDescr!= NULL;
}
bool WIZARD_FPLIB_TABLE::setLastPage() // Init prms for the last wizard page
{
// Update texts in last wizard page
m_textPluginType->SetLabel( m_rbFpLibFormat->GetStringSelection() );
switch( m_rbPathManagement->GetSelection() )
{
case ENV_VAR_PATH: // Choice = path relative env var
case PROJECT_PATH: // Choice = path relative to the project
m_currLibDescr->m_EnvVarName = GetSelectedEnvVar();
m_currLibDescr->m_DefaultPath = GetSelectedEnvVarValue();
m_currLibDescr->m_IsAbsolutePath = false;
m_textOption->SetLabel( wxString::Format( wxT("%s (%s)"),
m_rbPathManagement->GetStringSelection().GetData(),
GetSelectedEnvVar().GetData() ) );
m_textPath->SetLabel( GetSelectedEnvVarValue() );
break;
case ABSOLUTE_PATH: // Choice = absolute path
m_currLibDescr->m_IsAbsolutePath = true;
m_textOption->SetLabel( m_rbPathManagement->GetStringSelection() );
if( IsGithubPlugin() )
m_textPath->SetLabel( _("Full URL") );
else
m_textPath->SetLabel( _("Full filename") );
break;
}
return true;
}
void WIZARD_FPLIB_TABLE::OnAddFpLibs( wxCommandEvent& event )
{
if( m_currLibDescr->m_IsFile )
selectLibsFiles();
else if( m_currLibDescr->m_IsGitHub )
selectLibsGithub();
else
selectLibsFolders();
m_gridFpListLibs->SetGridCursor( GetLibsCount()-1, 0 );
m_gridFpListLibs->SelectRow( GetLibsCount()-1 );
}
void WIZARD_FPLIB_TABLE::selectLibsFiles() // select a set of library files
{
wxString msk = wxT("*.") + m_currLibDescr->m_Ext;
wxFileDialog dlg( this, _("Select Library Files"), m_currLibDescr->m_DefaultPath,
wxEmptyString, msk,
wxFD_DEFAULT_STYLE|wxFD_FILE_MUST_EXIST|wxFD_MULTIPLE );
dlg.ShowModal();
wxArrayString filepaths;
dlg.GetPaths( filepaths );
// Create the nickname: currently make it from the filename
wxArrayString nicknames;
wxFileName fn;
for( unsigned ii = 0; ii < filepaths.GetCount(); ii++ )
{
fn = filepaths[ii];
nicknames.Add( fn.GetName() );
if( m_currLibDescr->m_IsAbsolutePath || m_currLibDescr->m_DefaultPath.IsEmpty() )
{
filepaths[ii] = fn.GetPathWithSep();
}
else
{
if( ! fn.MakeRelativeTo( m_currLibDescr->m_DefaultPath ) )
filepaths[ii] = fn.GetFullPath();
else
filepaths[ii].Printf( wxT("${%s}%c%s"),
GetChars( m_currLibDescr->m_EnvVarName ),
fn.GetPathSeparator(),
GetChars( fn.GetFullPath() ) );
}
#ifdef __WINDOWS__
// We store paths using Unix notation, which also works fine on Windows
filepaths[ii].Replace( wxT("\\"), wxT("/") );
#endif
}
populateLibList( nicknames, filepaths, m_currLibDescr->m_PluginName );
m_gridFpListLibs->AutoSizeColumns();
}
void WIZARD_FPLIB_TABLE::populateLibList( const wxArrayString& aNickNames,
const wxArrayString& aPaths,
const wxString& aPluginName )
{
if( aPaths.GetCount() <= 0 )
return;
// Ensure there is room for selected libs
int first_row = m_gridFpListLibs->GetTable()->GetRowsCount();
m_gridFpListLibs->AppendRows( aPaths.GetCount() );
// Populates the library list
for( unsigned ii = 0; ii < aPaths.GetCount(); ii++ )
{
int jj = first_row + ii;
// Add the nickname: currently make it from filename
m_gridFpListLibs->SetCellValue( jj, 0, aNickNames[ii] );
// Add the full path:
m_gridFpListLibs->SetCellValue( jj, 1, aPaths[ii] );
// Add the plugin name:
m_gridFpListLibs->SetCellValue( jj, 2, aPluginName );
m_gridFpListLibs->SetReadOnly( jj, 2, true );
}
m_gridFpListLibs->Fit();
}
// A helper dialog to show and select a set of directories
class DIALOG_SELECT_DIRLIST : public DIALOG_SELECT_DIRLIST_BASE
{
public:
DIALOG_SELECT_DIRLIST( wxWindow* parent,
const wxString& aDefaultPath ):
DIALOG_SELECT_DIRLIST_BASE( parent, wxID_ANY )
{
if( !aDefaultPath.IsEmpty() )
m_dirCtrl->SetPath( aDefaultPath );
}
~DIALOG_SELECT_DIRLIST() {};
void GetPaths( wxArrayString& aPaths ) { m_dirCtrl->GetPaths( aPaths ); }
};
void WIZARD_FPLIB_TABLE::selectLibsFolders() // select a set of library folders
{
DIALOG_SELECT_DIRLIST dlg( this, m_currLibDescr->m_DefaultPath );
if( dlg.ShowModal() != wxID_OK )
return;
wxArrayString filepaths;
dlg.GetPaths( filepaths );
// Create the nickname: currently make it from the filename
wxArrayString nicknames;
wxFileName fn;
for( unsigned ii = 0; ii < filepaths.GetCount(); ii++ )
{
fn = filepaths[ii];
nicknames.Add( fn.GetName() );
fn.AssignDir( filepaths[ii] );
if( m_currLibDescr->m_IsAbsolutePath || m_currLibDescr->m_DefaultPath.IsEmpty() )
{
filepaths[ii] = fn.GetFullPath();
}
else
{
if( ! fn.MakeRelativeTo( m_currLibDescr->m_DefaultPath ) )
filepaths[ii] = fn.GetFullPath();
else
filepaths[ii].Printf( wxT("${%s}%c%s"),
GetChars( m_currLibDescr->m_EnvVarName ),
fn.GetPathSeparator(),
GetChars( fn.GetFullPath() ) );
}
#ifdef __WINDOWS__
// We store paths using Unix notation, which also works fine on Windows
filepaths[ii].Replace( wxT("\\"), wxT("/") );
#endif
// Remove trailing path separator, if any.
if( filepaths[ii].EndsWith( wxT("/") ) )
filepaths[ii].RemoveLast();
}
populateLibList( nicknames, filepaths, m_currLibDescr->m_PluginName );
}
#ifdef KICAD_USE_WEBKIT
// A helper function to run the wen viewer (see webviewer.cpp)
extern int RunWebViewer( wxWindow * aParent, const wxString& aUrlOnStart,
wxArrayString* aUrlListSelection = NULL );
#endif
void WIZARD_FPLIB_TABLE::selectLibsGithub() // select a set of library on Github
{
// A string array to store the URLs selected from the web viewer:
wxArrayString urls;
// Run the web viewer and open the default URL: the default path
// or our github library depos
wxString defaultURL = m_currLibDescr->m_DefaultPath;
if( defaultURL.IsEmpty() )
defaultURL = wxT( "https://github.com/KiCad" );
#ifdef KICAD_USE_WEBKIT
RunWebViewer( this, defaultURL, &urls );
#else
urls.Add( defaultURL + wxT("newlibname.pretty") );
#endif
// Create the nickname: currently make it from the url
wxArrayString filepaths;
wxArrayString nicknames;
for( unsigned ii = 0; ii < urls.GetCount(); ii++ )
{
wxString urlstring( urls[ii] );
wxURI uri( urlstring );
// We cannot use wxURL to test the validity of the url, because
// wxURL does not know https protocol we are using, and aways returns
// error for URLs starting by https. Hope this test is enough
if( uri.HasPath() )
nicknames.Add( uri.GetPath().AfterLast( '/').BeforeLast( '.' ) );
else
continue; // Should not happen: bad URL
if( m_currLibDescr->m_IsAbsolutePath ||
m_currLibDescr->m_DefaultPath.IsEmpty() )
{
filepaths.Add( urls[ii] ); // use the full URL
}
else
{
wxString shortURI;
if( urls[ii].Lower().StartsWith(
m_currLibDescr->m_DefaultPath.Lower(), &shortURI ) )
{
shortURI.Prepend( wxT("${") + m_currLibDescr->m_EnvVarName + wxT("}") );
filepaths.Add( shortURI );
}
else // keep the full URL
filepaths.Add( urls[ii] ); // use the full URL
}
}
populateLibList( nicknames, filepaths, m_currLibDescr->m_PluginName );
}
void WIZARD_FPLIB_TABLE::OnRemoveFpLibs( wxCommandEvent& event )
{
wxArrayInt selectedRows = m_gridFpListLibs->GetSelectedRows();
int row_cursor = m_gridFpListLibs->GetGridCursorRow();
if( selectedRows.size() == 0 && row_cursor >= 0 )
selectedRows.Add( row_cursor );
std::sort( selectedRows.begin(), selectedRows.end() );
for( int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
{
int row = selectedRows[ii];
m_gridFpListLibs->DeleteRows( row, 1 );
}
m_gridFpListLibs->SelectRow( m_gridFpListLibs->GetGridCursorRow() );
}

View File

@ -0,0 +1,221 @@
/**
* @file wizard_add_fplib.h
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* 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
*/
#include <wx/wx.h>
#include <dialog_helpers.h>
#include <wizard_add_fplib_base.h>
// A helper class to handle the different types of lib depending
// on the plugin: ext, type of lib: files/folders ... and info
// needed to populate the main fp lib table
class LIB_DESCR
{
public:
wxString m_PluginName; // The "official" name of the plugin (see fp lib table dialog)
wxString m_Ext; // standard extension (.mod, .pretty ...)
wxString m_EnvVarName; // the environment var if selected, or empty
wxString m_DefaultPath;
bool m_IsAbsolutePath; // true if absolue path is selected
bool m_IsFile; // true for libs which are single files,
// false for libs which are directories containing footprints
bool m_IsGitHub; // true only for GitHub plugin
LIB_DESCR()
{
m_IsAbsolutePath = true;
m_IsFile = true;
m_IsGitHub = false;
}
};
class WIZARD_FPLIB_TABLE : public WIZARD_FPLIB_TABLE_BASE
{
int m_rowPrjEnvVarPosition; // the row of the PROJECT_VAR_NAME
int m_predefinedEnvVarCnt; // number of predefined env var when calling the wizard
// at least 3 are always defined
LIB_DESCR * m_currLibDescr;
// static members to store options during a session
static int m_last_plugin_choice;
static int m_last_defaultpath_choice;
// This enum must have the same order than m_rbPathManagement
enum OPT_PATH {
PROJECT_PATH,
ENV_VAR_PATH,
ABSOLUTE_PATH
};
// This enum must have the same order than m_rbFpLibFormat
enum OPT_PLUGIN {
KICAD_PLUGIN,
GITHUB_PLUGIN,
LEGACY_PLUGIN,
EAGLE_PLUGIN,
GEDA_PCB_PLUGIN
};
public:
WIZARD_FPLIB_TABLE( wxWindow* aParent, wxArrayString& aEnvVariableList );
wxWizardPage* GetFirstPage() { return m_pages[0]; }
~WIZARD_FPLIB_TABLE();
/**
* Return info on lib at line aIdx in aLibDescr
* @param aLibDescr = a wxArrayString to return the nickname, the lib URI and the lin type
* @return true if aIdx lin exists
*/
bool GetLibDescr( int aIdx, wxArrayString& aLibDescr )
{
int count = m_gridFpListLibs->GetTable()->GetRowsCount();
if( aIdx >= count )
return false;
// Return info
// Add the nickname:
aLibDescr.Add( m_gridFpListLibs->GetCellValue( aIdx, 0 ) );
// Add the full path:
aLibDescr.Add( m_gridFpListLibs->GetCellValue( aIdx, 1 ) );
// Add the plugin name:
aLibDescr.Add( m_gridFpListLibs->GetCellValue( aIdx, 2 ) );
return true;
}
private:
void initDlg( wxArrayString& aEnvVariableList );
wxString GetSelectedEnvVar(); // return the selected env variable
wxString GetSelectedEnvVarValue(); // return the selected env variable value
bool setSecondPage(); // Init prms for the second wizard page
bool setLastPage(); // Init prms for the last wizard page
void selectLibsFiles(); // select a set of library files
void selectLibsFolders(); // select a set of library folders
void selectLibsGithub(); // select a set of library on Github
void updateFromPlugingChoice(); // update dialog options and widgets
// depending on the plugin choice
int GetEnvVarCount() // Get the number of rows in env var table
{
return m_gridEnvironmentVariablesList->GetTable()->GetRowsCount();
}
int GetLibsCount() // Get the number of rows in libs table
{
return m_gridFpListLibs->GetTable()->GetRowsCount();
}
bool IsGithubPlugin() // Helper funct, return true if
{ // the Github plugin is the choice
return m_rbFpLibFormat->GetSelection() == GITHUB_PLUGIN;
}
int HasGithubEnvVarCompatible(); // Return the first index to one env var
// which defines a url compatible github
// or -1 if not found
// Populate the library list with the currently selected libs
void populateLibList( const wxArrayString& aNickNames,
const wxArrayString& aPaths,
const wxString& aPluginName );
// Virtual event functions, from WIZARD_FPLIB_TABLE_BASE
void OnFinish( wxWizardEvent& event ) { event.Skip(); }
void OnPageChanged( wxWizardEvent& event );
void OnPageChanging( wxWizardEvent& event );
void OnAddEVariable( wxCommandEvent& event );
void OnRemoveEVariable( wxCommandEvent& event );
void OnAddFpLibs( wxCommandEvent& event );
void OnRemoveFpLibs( wxCommandEvent& event );
void OnPathManagementSelection( wxCommandEvent& event );
void OnSelectEnvVarCell( wxGridEvent& event );
void OnPluginSelection( wxCommandEvent& event );
bool ValidateOptions();
};
// Specialized helper classes to handle the different plugin types:
class LIB_DESCR_KICAD: public LIB_DESCR
{
public:
LIB_DESCR_KICAD(): LIB_DESCR()
{
m_PluginName = IO_MGR::ShowType( IO_MGR::KICAD );
m_Ext = wxT("pretty");
m_IsFile = false;
}
};
class LIB_DESCR_GITHUB: public LIB_DESCR
{
public:
LIB_DESCR_GITHUB(): LIB_DESCR()
{
m_PluginName = IO_MGR::ShowType( IO_MGR::GITHUB );
m_Ext = wxT("pretty");
m_IsFile = false;
m_IsGitHub = true;
}
};
class LIB_DESCR_LEGACY: public LIB_DESCR
{
public:
LIB_DESCR_LEGACY(): LIB_DESCR()
{
m_PluginName = IO_MGR::ShowType( IO_MGR::LEGACY );
m_Ext = wxT("mod");
}
};
class LIB_DESCR_EAGLE: public LIB_DESCR
{
public:
LIB_DESCR_EAGLE(): LIB_DESCR()
{
m_PluginName = IO_MGR::ShowType( IO_MGR::EAGLE );
m_Ext = wxT("lbr");
m_IsFile = true;
}
};
class LIB_DESCR_GEDA: public LIB_DESCR
{
public:
// No specific extension known for folders
LIB_DESCR_GEDA(): LIB_DESCR()
{
m_PluginName = IO_MGR::ShowType( IO_MGR::GEDA_PCB );
m_IsFile = false;
}
};

View File

@ -0,0 +1,302 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 5 2014)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "wizard_add_fplib_base.h"
///////////////////////////////////////////////////////////////////////////
WIZARD_FPLIB_TABLE_BASE::WIZARD_FPLIB_TABLE_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxBitmap& bitmap, const wxPoint& pos, long style )
{
this->Create( parent, id, title, bitmap, pos, style );
this->SetSizeHints( wxSize( 450,-1 ), wxDefaultSize );
wxWizardPageSimple* m_wizPage1 = new wxWizardPageSimple( this );
m_pages.Add( m_wizPage1 );
m_wizPage1->SetMinSize( wxSize( 500,-1 ) );
wxBoxSizer* bSizerPage1;
bSizerPage1 = new wxBoxSizer( wxVERTICAL );
wxString m_rbFpLibFormatChoices[] = { _("KiCad (*.Pretty folder containing .kicad_mod files)"), _("GitHub (.Pretty lib stored on GitHub depos)"), _("Legacy ( old *.mod lib file)"), _("Eagle V6 xml library file"), _("Geda footprint folder (folder containing *.fp files)") };
int m_rbFpLibFormatNChoices = sizeof( m_rbFpLibFormatChoices ) / sizeof( wxString );
m_rbFpLibFormat = new wxRadioBox( m_wizPage1, wxID_ANY, _("Library Format:"), wxDefaultPosition, wxDefaultSize, m_rbFpLibFormatNChoices, m_rbFpLibFormatChoices, 1, wxRA_SPECIFY_COLS );
m_rbFpLibFormat->SetSelection( 0 );
bSizerPage1->Add( m_rbFpLibFormat, 0, wxALL|wxEXPAND, 5 );
m_staticline2 = new wxStaticLine( m_wizPage1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerPage1->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
m_bitmapGithubURL = new wxStaticBitmap( m_wizPage1, wxID_ANY, wxArtProvider::GetBitmap( wxART_INFORMATION, wxART_OTHER ), wxDefaultPosition, wxDefaultSize, 0 );
bSizerPage1->Add( m_bitmapGithubURL, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText10 = new wxStaticText( m_wizPage1, wxID_ANY, _("Default URL for KiCad libraries on Github:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText10->Wrap( -1 );
bSizerPage1->Add( m_staticText10, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_textCtrlGithubURL = new wxTextCtrl( m_wizPage1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
bSizerPage1->Add( m_textCtrlGithubURL, 0, wxALL|wxEXPAND, 5 );
m_wizPage1->SetSizer( bSizerPage1 );
m_wizPage1->Layout();
bSizerPage1->Fit( m_wizPage1 );
wxWizardPageSimple* m_wizPage2 = new wxWizardPageSimple( this );
m_pages.Add( m_wizPage2 );
m_wizPage2->SetMinSize( wxSize( 450,-1 ) );
wxBoxSizer* bSizerPage2;
bSizerPage2 = new wxBoxSizer( wxVERTICAL );
wxString m_rbPathManagementChoices[] = { _("Use path relative to the project"), _("Use environment variable in path"), _("Use absolute path") };
int m_rbPathManagementNChoices = sizeof( m_rbPathManagementChoices ) / sizeof( wxString );
m_rbPathManagement = new wxRadioBox( m_wizPage2, wxID_ANY, _("Path management:"), wxDefaultPosition, wxDefaultSize, m_rbPathManagementNChoices, m_rbPathManagementChoices, 1, wxRA_SPECIFY_COLS );
m_rbPathManagement->SetSelection( 2 );
bSizerPage2->Add( m_rbPathManagement, 0, wxALL|wxEXPAND, 5 );
m_staticText1 = new wxStaticText( m_wizPage2, wxID_ANY, _("Environment variables:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText1->Wrap( -1 );
bSizerPage2->Add( m_staticText1, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_gridEnvironmentVariablesList = new wxGrid( m_wizPage2, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_gridEnvironmentVariablesList->CreateGrid( 3, 2 );
m_gridEnvironmentVariablesList->EnableEditing( true );
m_gridEnvironmentVariablesList->EnableGridLines( true );
m_gridEnvironmentVariablesList->EnableDragGridSize( false );
m_gridEnvironmentVariablesList->SetMargins( 0, 0 );
// Columns
m_gridEnvironmentVariablesList->SetColSize( 0, 125 );
m_gridEnvironmentVariablesList->SetColSize( 1, 154 );
m_gridEnvironmentVariablesList->AutoSizeColumns();
m_gridEnvironmentVariablesList->EnableDragColMove( false );
m_gridEnvironmentVariablesList->EnableDragColSize( true );
m_gridEnvironmentVariablesList->SetColLabelSize( 30 );
m_gridEnvironmentVariablesList->SetColLabelValue( 0, _("Environment Variable") );
m_gridEnvironmentVariablesList->SetColLabelValue( 1, _("Path Segment") );
m_gridEnvironmentVariablesList->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
m_gridEnvironmentVariablesList->AutoSizeRows();
m_gridEnvironmentVariablesList->EnableDragRowSize( false );
m_gridEnvironmentVariablesList->SetRowLabelSize( 40 );
m_gridEnvironmentVariablesList->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Label Appearance
// Cell Defaults
m_gridEnvironmentVariablesList->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
bSizerPage2->Add( m_gridEnvironmentVariablesList, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizerButs;
bSizerButs = new wxBoxSizer( wxHORIZONTAL );
m_buttonAddEV = new wxButton( m_wizPage2, wxID_ANY, _("Add Environment Variable"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerButs->Add( m_buttonAddEV, 0, wxALL, 5 );
m_buttonRemoveEV = new wxButton( m_wizPage2, wxID_ANY, _("Remove Environment Variable"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerButs->Add( m_buttonRemoveEV, 0, wxALL, 5 );
bSizerPage2->Add( bSizerButs, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
m_wizPage2->SetSizer( bSizerPage2 );
m_wizPage2->Layout();
bSizerPage2->Fit( m_wizPage2 );
wxWizardPageSimple* m_wizPage3 = new wxWizardPageSimple( this );
m_pages.Add( m_wizPage3 );
m_wizPage3->SetMinSize( wxSize( 450,-1 ) );
wxBoxSizer* bSizerPage3;
bSizerPage3 = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* sbSizer1;
sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( m_wizPage3, wxID_ANY, _("Options") ), wxVERTICAL );
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer1->AddGrowableCol( 1 );
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_textPluginTitle = new wxStaticText( m_wizPage3, wxID_ANY, _("Plugin type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_textPluginTitle->Wrap( -1 );
fgSizer1->Add( m_textPluginTitle, 0, wxALL, 5 );
m_textPluginType = new wxStaticText( m_wizPage3, wxID_ANY, _("KiCad"), wxDefaultPosition, wxDefaultSize, 0 );
m_textPluginType->Wrap( -1 );
fgSizer1->Add( m_textPluginType, 1, wxALL, 5 );
m_textOptionTitle = new wxStaticText( m_wizPage3, wxID_ANY, _("Option:"), wxDefaultPosition, wxDefaultSize, 0 );
m_textOptionTitle->Wrap( -1 );
fgSizer1->Add( m_textOptionTitle, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_textOption = new wxStaticText( m_wizPage3, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 );
m_textOption->Wrap( -1 );
fgSizer1->Add( m_textOption, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_stPathTitle = new wxStaticText( m_wizPage3, wxID_ANY, _("Path:"), wxDefaultPosition, wxDefaultSize, 0 );
m_stPathTitle->Wrap( -1 );
fgSizer1->Add( m_stPathTitle, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_textPath = new wxStaticText( m_wizPage3, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 );
m_textPath->Wrap( -1 );
fgSizer1->Add( m_textPath, 1, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
sbSizer1->Add( fgSizer1, 0, wxEXPAND, 5 );
bSizerPage3->Add( sbSizer1, 0, wxEXPAND|wxBOTTOM, 5 );
m_staticText2 = new wxStaticText( m_wizPage3, wxID_ANY, _("Library list to add in Fp table:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText2->Wrap( -1 );
bSizerPage3->Add( m_staticText2, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizer6;
bSizer6 = new wxBoxSizer( wxVERTICAL );
m_gridFpListLibs = new wxGrid( m_wizPage3, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_gridFpListLibs->CreateGrid( 0, 3 );
m_gridFpListLibs->EnableEditing( true );
m_gridFpListLibs->EnableGridLines( true );
m_gridFpListLibs->EnableDragGridSize( false );
m_gridFpListLibs->SetMargins( 0, 0 );
// Columns
m_gridFpListLibs->EnableDragColMove( false );
m_gridFpListLibs->EnableDragColSize( true );
m_gridFpListLibs->SetColLabelSize( 30 );
m_gridFpListLibs->SetColLabelValue( 0, _("NickName") );
m_gridFpListLibs->SetColLabelValue( 1, _("Path") );
m_gridFpListLibs->SetColLabelValue( 2, _("Plugin") );
m_gridFpListLibs->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
m_gridFpListLibs->EnableDragRowSize( true );
m_gridFpListLibs->SetRowLabelSize( 30 );
m_gridFpListLibs->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Label Appearance
// Cell Defaults
m_gridFpListLibs->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
bSizer6->Add( m_gridFpListLibs, 1, wxALL|wxEXPAND, 5 );
bSizerPage3->Add( bSizer6, 1, wxEXPAND, 5 );
wxBoxSizer* bSizer5;
bSizer5 = new wxBoxSizer( wxHORIZONTAL );
m_buttonAddLib = new wxButton( m_wizPage3, wxID_ANY, _("Add FP Libraries"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer5->Add( m_buttonAddLib, 0, wxALL, 5 );
m_buttonRemoveLib = new wxButton( m_wizPage3, wxID_ANY, _("Remove FP Libraries"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer5->Add( m_buttonRemoveLib, 0, wxALL, 5 );
bSizerPage3->Add( bSizer5, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
m_wizPage3->SetSizer( bSizerPage3 );
m_wizPage3->Layout();
bSizerPage3->Fit( m_wizPage3 );
this->Centre( wxBOTH );
for ( unsigned int i = 1; i < m_pages.GetCount(); i++ )
{
m_pages.Item( i )->SetPrev( m_pages.Item( i - 1 ) );
m_pages.Item( i - 1 )->SetNext( m_pages.Item( i ) );
}
// Connect Events
this->Connect( wxID_ANY, wxEVT_WIZARD_FINISHED, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnFinish ) );
this->Connect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPageChanged ) );
this->Connect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPageChanging ) );
m_rbFpLibFormat->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPluginSelection ), NULL, this );
m_rbPathManagement->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPathManagementSelection ), NULL, this );
m_gridEnvironmentVariablesList->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( WIZARD_FPLIB_TABLE_BASE::OnSelectEnvVarCell ), NULL, this );
m_buttonAddEV->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnAddEVariable ), NULL, this );
m_buttonRemoveEV->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnRemoveEVariable ), NULL, this );
m_buttonAddLib->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnAddFpLibs ), NULL, this );
m_buttonRemoveLib->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnRemoveFpLibs ), NULL, this );
}
WIZARD_FPLIB_TABLE_BASE::~WIZARD_FPLIB_TABLE_BASE()
{
// Disconnect Events
this->Disconnect( wxID_ANY, wxEVT_WIZARD_FINISHED, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnFinish ) );
this->Disconnect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPageChanged ) );
this->Disconnect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPageChanging ) );
m_rbFpLibFormat->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPluginSelection ), NULL, this );
m_rbPathManagement->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnPathManagementSelection ), NULL, this );
m_gridEnvironmentVariablesList->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( WIZARD_FPLIB_TABLE_BASE::OnSelectEnvVarCell ), NULL, this );
m_buttonAddEV->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnAddEVariable ), NULL, this );
m_buttonRemoveEV->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnRemoveEVariable ), NULL, this );
m_buttonAddLib->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnAddFpLibs ), NULL, this );
m_buttonRemoveLib->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_FPLIB_TABLE_BASE::OnRemoveFpLibs ), NULL, this );
m_pages.Clear();
}
DIALOG_SELECT_DIRLIST_BASE::DIALOG_SELECT_DIRLIST_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL );
m_staticTextInfo = new wxStaticText( this, wxID_ANY, _("The footprint library is a folder.\nFootprints are files inside this folder."), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
m_staticTextInfo->Wrap( -1 );
m_staticTextInfo->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
bSizerMain->Add( m_staticTextInfo, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_dirCtrl = new wxGenericDirCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDIRCTRL_3D_INTERNAL|wxDIRCTRL_DIR_ONLY|wxDIRCTRL_MULTIPLE|wxSUNKEN_BORDER, wxEmptyString, 0 );
m_dirCtrl->ShowHidden( false );
bSizerMain->Add( m_dirCtrl, 1, wxEXPAND | wxALL, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerMain->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bSizerMain->Add( m_sdbSizer, 0, wxEXPAND, 5 );
this->SetSizer( bSizerMain );
this->Layout();
this->Centre( wxBOTH );
// Connect Events
m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_DIRLIST_BASE::OnCancelClick ), NULL, this );
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_DIRLIST_BASE::OnOKClick ), NULL, this );
}
DIALOG_SELECT_DIRLIST_BASE::~DIALOG_SELECT_DIRLIST_BASE()
{
// Disconnect Events
m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_DIRLIST_BASE::OnCancelClick ), NULL, this );
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_DIRLIST_BASE::OnOKClick ), NULL, this );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,117 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 5 2014)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __WIZARD_ADD_FPLIB_BASE_H__
#define __WIZARD_ADD_FPLIB_BASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/radiobox.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/statline.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/statbmp.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/grid.h>
#include <wx/button.h>
#include <wx/statbox.h>
#include <wx/wizard.h>
#include <wx/dynarray.h>
WX_DEFINE_ARRAY_PTR( wxWizardPageSimple*, WizardPages );
#include <wx/dirctrl.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class WIZARD_FPLIB_TABLE_BASE
///////////////////////////////////////////////////////////////////////////////
class WIZARD_FPLIB_TABLE_BASE : public wxWizard
{
private:
protected:
wxRadioBox* m_rbFpLibFormat;
wxStaticLine* m_staticline2;
wxStaticBitmap* m_bitmapGithubURL;
wxStaticText* m_staticText10;
wxTextCtrl* m_textCtrlGithubURL;
wxRadioBox* m_rbPathManagement;
wxStaticText* m_staticText1;
wxGrid* m_gridEnvironmentVariablesList;
wxButton* m_buttonAddEV;
wxButton* m_buttonRemoveEV;
wxStaticText* m_textPluginTitle;
wxStaticText* m_textPluginType;
wxStaticText* m_textOptionTitle;
wxStaticText* m_textOption;
wxStaticText* m_stPathTitle;
wxStaticText* m_textPath;
wxStaticText* m_staticText2;
wxGrid* m_gridFpListLibs;
wxButton* m_buttonAddLib;
wxButton* m_buttonRemoveLib;
// Virtual event handlers, overide them in your derived class
virtual void OnFinish( wxWizardEvent& event ) { event.Skip(); }
virtual void OnPageChanged( wxWizardEvent& event ) { event.Skip(); }
virtual void OnPageChanging( wxWizardEvent& event ) { event.Skip(); }
virtual void OnPluginSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPathManagementSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSelectEnvVarCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnAddEVariable( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveEVariable( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAddFpLibs( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveFpLibs( wxCommandEvent& event ) { event.Skip(); }
public:
WIZARD_FPLIB_TABLE_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Footprint Library Wizard"), const wxBitmap& bitmap = wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ), const wxPoint& pos = wxDefaultPosition, long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
WizardPages m_pages;
~WIZARD_FPLIB_TABLE_BASE();
};
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_SELECT_DIRLIST_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_SELECT_DIRLIST_BASE : public wxDialog
{
private:
protected:
wxStaticText* m_staticTextInfo;
wxGenericDirCtrl* m_dirCtrl;
wxStaticLine* m_staticline1;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOKClick( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_SELECT_DIRLIST_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select Footprint Library Folder"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 346,325 ), long style = wxDEFAULT_DIALOG_STYLE );
~DIALOG_SELECT_DIRLIST_BASE();
};
#endif //__WIZARD_ADD_FPLIB_BASE_H__

15
webviewer/CMakeLists.txt Normal file
View File

@ -0,0 +1,15 @@
include_directories(BEFORE ${INC_BEFORE})
include_directories(
${INC_AFTER}
)
set( WEBVIEW_SRCS
html_link_parser.cpp
webviewer.cpp
)
add_library( webviewer STATIC ${WEBVIEW_SRCS})
add_dependencies( webviewer lib-dependencies )

View File

@ -0,0 +1,70 @@
/**
* @file html_link_parse.cpp
*/
/*
* 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>
#include <wx/html/htmlpars.h>
#include "html_link_parser.h"
bool LINK_TAGHANDLER::HandleTag(const wxHtmlTag& tag)
{
if( tag.HasParam( wxT("HREF") ) )
{
wxString href( tag.GetParam( wxT("HREF") ) );
// Add the first parameter (the link)
m_Parser->AddString( href );
// Parse other params, but do nothing, becuse the AddText() callback
// do nothing
ParseInner(tag);
return true;
}
else
return false;
}
HTML_LINK_PARSER::HTML_LINK_PARSER( const wxString& aSrc, wxArrayString& aUrls )
: m_src( aSrc ), stringUrls( aUrls )
{
AddTagHandler( new LINK_TAGHANDLER(this) );
}
void HTML_LINK_PARSER::AddString( const wxString& aText )
{
wxString text = aText;
text.Trim( true );
text.Trim( false );
if( ! m_filter || m_filter( text ) )
{
stringUrls.Add( text );
}
}

View File

@ -0,0 +1,109 @@
/**
* @file html_link_parse.h
*/
/*
* 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#
*/
#ifndef HTML_LINK_PARSE_H
#define HTML_LINK_PARSE_H
#include <wx/wx.h>
#include <wx/html/htmlpars.h>
class HTML_LINK_PARSER ;
/**
* a Tag parser, to extract tagged data in html text.
* this tag handler extract a url link, givent by tag "A"
* like:
* "<a href="/KiCad/Valves.pretty" itemprop="name codeRepository"> Valves.pretty</a>"
* the tag is "a"
* and the link is the parameter given by "href"
*/
class LINK_TAGHANDLER : public wxHtmlTagHandler
{
HTML_LINK_PARSER* m_Parser;
public:
LINK_TAGHANDLER() : m_Parser( NULL )
{
}
LINK_TAGHANDLER( HTML_LINK_PARSER* aParser ) : m_Parser( aParser )
{
}
wxString GetSupportedTags()
{
return "A";
}
bool HandleTag(const wxHtmlTag& tag);
};
/**
* The engine to parse a html text and extract useful data
* Here, the useful data are url links
*/
class HTML_LINK_PARSER : public wxHtmlParser
{
const wxString& m_src; // the html text to parse
wxArrayString& stringUrls; // the strings extracted from html text
bool (*m_filter)( const wxString& aData ); // a callback function to filter strings
public:
HTML_LINK_PARSER( const wxString& aSrc, wxArrayString& aUrls );
/**
* Parse the html text and store links in stringUrls
* Stored links can be filtered if aFilter is non NULL
* @param aFilter a filtering function ( bool aFilter( const wxString& aData ) )
* which return true if the tex(t aData must be stored.
*/
void ParseLinks( bool (*aFilter)( const wxString& aData ) )
{
m_filter = aFilter;
Parse(m_src);
}
// virtual pure from wxHtmlParser, do nothing here, but needed.
void AddText( const wxString& aText ){}
// Our "AddText" used to store selected text (the url link)
void AddString( const wxString& aText );
wxObject* GetProduct()
{
return NULL;
}
};
#endif // ifndef HTML_LINK_PARSE_H

970
webviewer/webviewer.cpp Normal file
View File

@ -0,0 +1,970 @@
/*
* 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 "A wxWebView backend is required by this sample"
#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 "wxStyledTextControl is needed by this sample"
#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 );
SetSize( wxSize( 800, 600 ) );
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
if( aUrlOnStart.IsEmpty() )
m_browser = wxWebView::New( this, wxID_ANY );
else
m_browser = wxWebView::New( this, wxID_ANY, aUrlOnStart );
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 hang 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
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 );
}