From e4a74213e4ae81c79999e280908a77094f26acc2 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sun, 21 Dec 2014 15:13:14 +0100 Subject: [PATCH] Add wizard to fp lib dialog to easily add entries to this table. --- CMakeLists.txt | 26 +- cvpcb/CMakeLists.txt | 11 + pcbnew/CMakeLists.txt | 11 + pcbnew/dialogs/dialog_fp_lib_table.cpp | 81 +- pcbnew/dialogs/dialog_fp_lib_table_base.cpp | 5 + pcbnew/dialogs/dialog_fp_lib_table_base.fbp | 88 + pcbnew/dialogs/dialog_fp_lib_table_base.h | 2 + pcbnew/dialogs/dialog_select_dirlist_base.cpp | 59 + pcbnew/dialogs/dialog_select_dirlist_base.fbp | 391 +++ pcbnew/dialogs/dialog_select_dirlist_base.h | 58 + pcbnew/dialogs/wizard_add_fplib.cpp | 772 +++++ pcbnew/dialogs/wizard_add_fplib.h | 221 ++ pcbnew/dialogs/wizard_add_fplib_base.cpp | 302 ++ pcbnew/dialogs/wizard_add_fplib_base.fbp | 2488 +++++++++++++++++ pcbnew/dialogs/wizard_add_fplib_base.h | 117 + webviewer/CMakeLists.txt | 15 + webviewer/html_link_parser.cpp | 70 + webviewer/html_link_parser.h | 109 + webviewer/webviewer.cpp | 970 +++++++ 19 files changed, 5794 insertions(+), 2 deletions(-) create mode 100644 pcbnew/dialogs/dialog_select_dirlist_base.cpp create mode 100644 pcbnew/dialogs/dialog_select_dirlist_base.fbp create mode 100644 pcbnew/dialogs/dialog_select_dirlist_base.h create mode 100644 pcbnew/dialogs/wizard_add_fplib.cpp create mode 100644 pcbnew/dialogs/wizard_add_fplib.h create mode 100644 pcbnew/dialogs/wizard_add_fplib_base.cpp create mode 100644 pcbnew/dialogs/wizard_add_fplib_base.fbp create mode 100644 pcbnew/dialogs/wizard_add_fplib_base.h create mode 100644 webviewer/CMakeLists.txt create mode 100644 webviewer/html_link_parser.cpp create mode 100644 webviewer/html_link_parser.h create mode 100644 webviewer/webviewer.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d59b96a4dd..11cd04d401 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 ) diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index 4095cac73f..c49051bccf 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -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 diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 494b373369..478f2a5d44 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -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 diff --git a/pcbnew/dialogs/dialog_fp_lib_table.cpp b/pcbnew/dialogs/dialog_fp_lib_table.cpp index 0272385331..a24f6e448c 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table.cpp +++ b/pcbnew/dialogs/dialog_fp_lib_table.cpp @@ -43,6 +43,8 @@ #include #include #include +#include + /// 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,8 +553,11 @@ 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 ); diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.cpp b/pcbnew/dialogs/dialog_fp_lib_table_base.cpp index 12d432b169..d9daaaffb9 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.cpp +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.cpp @@ -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 ); diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.fbp b/pcbnew/dialogs/dialog_fp_lib_table_base.fbp index 24104e6e39..7d3f2fdef8 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.fbp +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.fbp @@ -751,6 +751,94 @@ + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Append with Wizard + + 0 + + + 0 + + 1 + m_buttonWizard + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnClickLibraryWizard + + + + + + + + + + + + + + + + + + + + + + + + + 5 wxALL diff --git a/pcbnew/dialogs/dialog_fp_lib_table_base.h b/pcbnew/dialogs/dialog_fp_lib_table_base.h index ba4fec1a39..50ea6afa55 100644 --- a/pcbnew/dialogs/dialog_fp_lib_table_base.h +++ b/pcbnew/dialogs/dialog_fp_lib_table_base.h @@ -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; diff --git a/pcbnew/dialogs/dialog_select_dirlist_base.cpp b/pcbnew/dialogs/dialog_select_dirlist_base.cpp new file mode 100644 index 0000000000..f982d624b5 --- /dev/null +++ b/pcbnew/dialogs/dialog_select_dirlist_base.cpp @@ -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 ); + +} diff --git a/pcbnew/dialogs/dialog_select_dirlist_base.fbp b/pcbnew/dialogs/dialog_select_dirlist_base.fbp new file mode 100644 index 0000000000..fdddffb7e4 --- /dev/null +++ b/pcbnew/dialogs/dialog_select_dirlist_base.fbp @@ -0,0 +1,391 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + dialog_select_dirlist_base + 1000 + none + 1 + dialog_select_dirlist_base + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + 400,300 + DIALOG_SELECT_DIRLIST_BASE + + 400,300 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + DIALOG_SHIM; dialog_shim.h + Select Footprint Library Folder + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizerMain + wxVERTICAL + none + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,92,-1,70,0 + 0 + 0 + wxID_ANY + The footprint library is a folde. Footprints are files inside this folder. + + 0 + + + 0 + + 1 + m_staticText + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + + Dock + 0 + Left + 1 + + *.pretty|* + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_dirCtrl + 1 + + + protected + 1 + + Resizable + 1 + 0 + + wxDIRCTRL_3D_INTERNAL|wxDIRCTRL_DIR_ONLY|wxDIRCTRL_MULTIPLE|wxDIRCTRL_SHOW_FILTERS + + 0 + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnSelectFolder + + + + + + + + + OnSelectFolder + + + + + + 5 + wxEXPAND | wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline1 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizer + protected + + + + + + + + + + + + + + diff --git a/pcbnew/dialogs/dialog_select_dirlist_base.h b/pcbnew/dialogs/dialog_select_dirlist_base.h new file mode 100644 index 0000000000..6a15a11049 --- /dev/null +++ b/pcbnew/dialogs/dialog_select_dirlist_base.h @@ -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 +#include +#include +class DIALOG_SHIM; + +#include "dialog_shim.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// 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__ diff --git a/pcbnew/dialogs/wizard_add_fplib.cpp b/pcbnew/dialogs/wizard_add_fplib.cpp new file mode 100644 index 0000000000..abea28e053 --- /dev/null +++ b/pcbnew/dialogs/wizard_add_fplib.cpp @@ -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 +#include +#include +#include +#include +#include // For PROJECT_VAR_NAME definition +#include +#include + +// 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() ); +} diff --git a/pcbnew/dialogs/wizard_add_fplib.h b/pcbnew/dialogs/wizard_add_fplib.h new file mode 100644 index 0000000000..0d9223967d --- /dev/null +++ b/pcbnew/dialogs/wizard_add_fplib.h @@ -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 +#include +#include + +// 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; + } +}; + diff --git a/pcbnew/dialogs/wizard_add_fplib_base.cpp b/pcbnew/dialogs/wizard_add_fplib_base.cpp new file mode 100644 index 0000000000..8b4a869310 --- /dev/null +++ b/pcbnew/dialogs/wizard_add_fplib_base.cpp @@ -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 ); + +} diff --git a/pcbnew/dialogs/wizard_add_fplib_base.fbp b/pcbnew/dialogs/wizard_add_fplib_base.fbp new file mode 100644 index 0000000000..f9e7971b88 --- /dev/null +++ b/pcbnew/dialogs/wizard_add_fplib_base.fbp @@ -0,0 +1,2488 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + wizard_add_fplib_base + 1000 + none + 1 + wizard_add_fplib_base + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + + + Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + 450,-1 + WIZARD_FPLIB_TABLE_BASE + + 450,389 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + ; + Footprint Library Wizard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnFinish + + OnPageChanged + OnPageChanging + + + + + 1 + 1 + + + 0 + wxID_ANY + + 500,-1 + m_wizPage1 + public + + + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + bSizerPage1 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "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)" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Library Format: + 1 + + 0 + + + 0 + + 1 + m_rbFpLibFormat + 1 + + + protected + 1 + + Resizable + 0 + 1 + + wxRA_SPECIFY_COLS + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + OnPluginSelection + + + + + + + + + + 5 + wxEXPAND | wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline2 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + Load From Art Provider; wxART_INFORMATION; wxART_OTHER + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_bitmapGithubURL + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Default URL for KiCad libraries on Github: + + 0 + + + 0 + + 1 + m_staticText10 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_textCtrlGithubURL + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + 0 + wxID_ANY + + 450,-1 + m_wizPage2 + public + + + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + -1,-1 + bSizerPage2 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Use path relative to the project" "Use environment variable in path" "Use absolute path" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Path management: + 1 + + 0 + + + 0 + + 1 + m_rbPathManagement + 1 + + + protected + 1 + + Resizable + 2 + 1 + + wxRA_SPECIFY_COLS + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + OnPathManagementSelection + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Environment variables: + + 0 + + + 0 + + 1 + m_staticText1 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + 1 + 1 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTRE + 30 + "Environment Variable" "Path Segment" + wxALIGN_CENTRE + 2 + 125,154 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + 0 + 0 + 1 + 1 + + 1 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 0 + + 0 + + + 0 + + 1 + m_gridEnvironmentVariablesList + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTRE + 40 + + wxALIGN_CENTRE + + 3 + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnSelectEnvVarCell + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + + bSizerButs + wxHORIZONTAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Add Environment Variable + + 0 + + + 0 + + 1 + m_buttonAddEV + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnAddEVariable + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Remove Environment Variable + + 0 + + + 0 + + 1 + m_buttonRemoveEV + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRemoveEVariable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + 0 + wxID_ANY + + 450,-1 + m_wizPage3 + public + + + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + -1,-1 + bSizerPage3 + wxVERTICAL + none + + 5 + wxEXPAND|wxBOTTOM + 0 + + wxID_ANY + Options + + sbSizer1 + wxVERTICAL + none + + + 5 + wxEXPAND + 0 + + 2 + wxBOTH + 1 + + 0 + + fgSizer1 + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Plugin type: + + 0 + + + 0 + + 1 + m_textPluginTitle + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + KiCad + + 0 + + + 0 + + 1 + m_textPluginType + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Option: + + 0 + + + 0 + + 1 + m_textOptionTitle + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxBOTTOM|wxRIGHT|wxLEFT + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + dummy + + 0 + + + 0 + + 1 + m_textOption + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Path: + + 0 + + + 0 + + 1 + m_stPathTitle + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxBOTTOM|wxRIGHT|wxLEFT + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + dummy + + 0 + + + 0 + + 1 + m_textPath + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Library list to add in Fp table: + + 0 + + + 0 + + 1 + m_staticText2 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer6 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + 0 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTRE + 30 + "NickName" "Path" "Plugin" + wxALIGN_CENTRE + 3 + + + 1 + 0 + Dock + 0 + Left + 0 + 1 + 0 + 1 + 1 + 1 + + 1 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 0 + + 0 + + + 0 + + 1 + m_gridFpListLibs + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTRE + 30 + + wxALIGN_CENTRE + + 0 + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + + bSizer5 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Add FP Libraries + + 0 + + + 0 + + 1 + m_buttonAddLib + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnAddFpLibs + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Remove FP Libraries + + 0 + + + 0 + + 1 + m_buttonRemoveLib + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRemoveFpLibs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_SELECT_DIRLIST_BASE + + 346,325 + wxDEFAULT_DIALOG_STYLE + + Select Footprint Library Folder + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizerMain + wxVERTICAL + none + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,92,-1,70,0 + 0 + 0 + wxID_ANY + The footprint library is a folder. Footprints are files inside this folder. + + 0 + + + 0 + + 1 + m_staticTextInfo + 1 + + + protected + 1 + + Resizable + 1 + + wxALIGN_CENTRE + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + + Dock + 0 + Left + 1 + + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_dirCtrl + 1 + + + protected + 1 + + Resizable + 1 + 0 + + wxDIRCTRL_3D_INTERNAL|wxDIRCTRL_DIR_ONLY|wxDIRCTRL_MULTIPLE + + 0 + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND | wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_staticline1 + 1 + + + protected + 1 + + Resizable + 1 + + wxLI_HORIZONTAL + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizer + protected + + OnCancelClick + + + + OnOKClick + + + + + + + + diff --git a/pcbnew/dialogs/wizard_add_fplib_base.h b/pcbnew/dialogs/wizard_add_fplib_base.h new file mode 100644 index 0000000000..25bf783660 --- /dev/null +++ b/pcbnew/dialogs/wizard_add_fplib_base.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +WX_DEFINE_ARRAY_PTR( wxWizardPageSimple*, WizardPages ); +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// 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__ diff --git a/webviewer/CMakeLists.txt b/webviewer/CMakeLists.txt new file mode 100644 index 0000000000..caf653d848 --- /dev/null +++ b/webviewer/CMakeLists.txt @@ -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 ) + diff --git a/webviewer/html_link_parser.cpp b/webviewer/html_link_parser.cpp new file mode 100644 index 0000000000..22e52ebb21 --- /dev/null +++ b/webviewer/html_link_parser.cpp @@ -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 +#include +#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 ); + } +} diff --git a/webviewer/html_link_parser.h b/webviewer/html_link_parser.h new file mode 100644 index 0000000000..d4de3cf30e --- /dev/null +++ b/webviewer/html_link_parser.h @@ -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 +#include + +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: + * " Valves.pretty" + * 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 diff --git a/webviewer/webviewer.cpp b/webviewer/webviewer.cpp new file mode 100644 index 0000000000..3b3e0cf6a9 --- /dev/null +++ b/webviewer/webviewer.cpp @@ -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 +#include +#if wxUSE_STC +#include "wx/stc/stc.h" +#else +#error "wxStyledTextControl is needed by this sample" +#endif + +#include +#include +#include "html_link_parser.h" + +// We map menu items to their history items +WX_DECLARE_HASH_MAP( int, wxSharedPtr, + wxIntegerHash, wxIntegerEqual, wxMenuHistoryMap ); + + +class WEB_NAVIGATOR : public DIALOG_SHIM +{ + wxArrayString* urlListSelection; + +public: + WEB_NAVIGATOR( wxWindow* aParent, + const wxString& aUrlOnStart, + wxArrayString* aUrlListSelection = NULL ); + virtual ~WEB_NAVIGATOR(); + + void InitNavigator( const wxString& aUrlOnStart ); + +private: + void buildToolBar(); + void buildToolMenu(); + void CreateFindToolBar( wxWindow* aParent ); + + void UpdateState(); + + // wxWebViewEvents: + /** Callback invoked when a navigation request was accepted + */ + void OnNavigationComplete( wxWebViewEvent& evt ) + { + UpdateState(); + } + + /** Callback invoked when a page is finished loading + */ + void OnDocumentLoaded( wxWebViewEvent& evt ) + { + UpdateState(); + } + + /** On new window, we veto to stop extra windows appearing + */ + void OnNewWindow( wxWebViewEvent& evt ) + { + UpdateState(); + } + + void OnTitleChanged( wxWebViewEvent& evt ) + { + SetTitle( evt.GetString() ); + } + + // event functions: + void OnIdle( wxIdleEvent& evt ); + void OnUrl( wxCommandEvent& evt ); + void OnBack( wxCommandEvent& evt ); + void OnForward( wxCommandEvent& evt ); + void OnStop( wxCommandEvent& evt ); + void OnReload( wxCommandEvent& evt ); + void OnClearHistory( wxCommandEvent& evt ); + void OnNavigationRequest( wxWebViewEvent& evt ); + void OnViewSourceRequest( wxCommandEvent& evt ); + void OnToolsClicked( wxCommandEvent& evt ); + void OnSetZoom( wxCommandEvent& evt ); + void OnError( wxWebViewEvent& evt ); + + void OnPrint( wxCommandEvent& evt ) + { + m_browser->Print(); + } + + void OnZoomLayout( wxCommandEvent& evt ); + + void OnHistory( wxCommandEvent& evt ) + { + m_browser->LoadHistoryItem( m_histMenuItems[evt.GetId()] ); + } + + void OnFind( wxCommandEvent& evt ); + void OnFindDone( wxCommandEvent& evt ); + void OnFindText( wxCommandEvent& evt ); + void OnFindOptions( wxCommandEvent& evt ); + + // only for fp lib wizard called if there is a non null + // aUrlListSelection from idle event, to see if a valid + // footprint lib was selected by user, from the context menu + // (command copy link) + void TestAndStoreFootprintLibLink(); + // Alternate way to list and select fp libraries: + void OnListPrettyLibURLs( wxCommandEvent& event ); + +private: + wxTextCtrl* m_url; + wxWebView* m_browser; + + wxToolBar* m_toolbar; + wxToolBarToolBase* m_toolbar_back; + wxToolBarToolBase* m_toolbar_forward; + wxToolBarToolBase* m_toolbar_stop; + wxToolBarToolBase* m_toolbar_reload; + wxToolBarToolBase* m_toolbar_tools; + wxToolBarToolBase* m_toolbar_ListLibs; + + wxToolBarToolBase* m_find_toolbar_done; + wxToolBarToolBase* m_find_toolbar_next; + wxToolBarToolBase* m_find_toolbar_previous; + wxToolBarToolBase* m_find_toolbar_options; + + wxMenuItem* m_find_toolbar_wrap; + wxMenuItem* m_find_toolbar_highlight; + wxMenuItem* m_find_toolbar_matchcase; + wxMenuItem* m_find_toolbar_wholeword; + + wxMenu* m_tools_menu; + wxMenuItem* m_tools_viewSource; + wxMenuItem* m_tools_print; + wxMenu* m_tools_history_menu; + wxMenuItem* m_tools_clearhist; + wxMenuItem* m_tools_layout; + wxMenuItem* m_tools_tiny; + wxMenuItem* m_tools_small; + wxMenuItem* m_tools_medium; + wxMenuItem* m_tools_large; + wxMenuItem* m_tools_largest; + wxMenuItem* m_find; + + wxInfoBar* m_info; + wxStaticText* m_info_text; + wxTextCtrl* m_find_ctrl; + wxToolBar* m_find_toolbar; + + wxMenuHistoryMap m_histMenuItems; + wxString m_findText; + int m_findFlags, m_findCount; +}; + +class SourceViewDialog : public wxDialog +{ +public: + SourceViewDialog( wxWindow* parent, wxString source ); +}; + +// Helper function to run the web viewer from an other dialog or frame: +int RunWebViewer( wxWindow* aParent, const wxString& aUrlOnStart, wxArrayString* aUrlListSelection ) +{ + WEB_NAVIGATOR dlg( aParent, aUrlOnStart, aUrlListSelection ); + return dlg.ShowModal(); +} + + +WEB_NAVIGATOR::WEB_NAVIGATOR( wxWindow* aParent, + const wxString& aUrlOnStart, wxArrayString* aUrlListSelection ) : + DIALOG_SHIM( aParent, wxID_ANY, "Web Viewer", wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ) +{ + urlListSelection = aUrlListSelection; + InitNavigator( aUrlOnStart ); + + SetMinSize( wxSize( 700, 500 ) ); + + GetSizer()->Fit( this ); + + 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 > back = m_browser->GetBackwardHistory(); + wxVector > forward = m_browser->GetForwardHistory(); + + wxMenuItem* item; + + unsigned int i; + + for( i = 0; i < back.size(); i++ ) + { + item = m_tools_history_menu->AppendRadioItem( wxID_ANY, back[i]->GetTitle() ); + m_histMenuItems[item->GetId()] = back[i]; + Connect( item->GetId(), wxEVT_MENU, + wxCommandEventHandler( WEB_NAVIGATOR::OnHistory ), NULL, this ); + } + + wxString title = m_browser->GetCurrentTitle(); + + if( title.empty() ) + title = "(untitled)"; + + item = m_tools_history_menu->AppendRadioItem( wxID_ANY, title ); + item->Check(); + + // No need to connect the current item + m_histMenuItems[item->GetId()] = + wxSharedPtr( new wxWebViewHistoryItem( m_browser->GetCurrentURL(), + m_browser->GetCurrentTitle() ) ); + + for( i = 0; i < forward.size(); i++ ) + { + item = m_tools_history_menu->AppendRadioItem( wxID_ANY, forward[i]->GetTitle() ); + m_histMenuItems[item->GetId()] = forward[i]; + Connect( item->GetId(), wxEVT_TOOL, + wxCommandEventHandler( WEB_NAVIGATOR::OnHistory ), NULL, this ); + } + + wxPoint position = ScreenToClient( wxGetMousePosition() ); + PopupMenu( m_tools_menu, position.x, position.y ); +} + + +/** + * Invoked when user selects the zoom size in the menu + */ +void WEB_NAVIGATOR::OnSetZoom( wxCommandEvent& evt ) +{ + if( evt.GetId() == m_tools_tiny->GetId() ) + m_browser->SetZoom( wxWEBVIEW_ZOOM_TINY ); + else if( evt.GetId() == m_tools_small->GetId() ) + m_browser->SetZoom( wxWEBVIEW_ZOOM_SMALL ); + else if( evt.GetId() == m_tools_medium->GetId() ) + m_browser->SetZoom( wxWEBVIEW_ZOOM_MEDIUM ); + else if( evt.GetId() == m_tools_large->GetId() ) + m_browser->SetZoom( wxWEBVIEW_ZOOM_LARGE ); + else if( evt.GetId() == m_tools_largest->GetId() ) + m_browser->SetZoom( wxWEBVIEW_ZOOM_LARGEST ); + else + wxFAIL; +} + + +void WEB_NAVIGATOR::OnZoomLayout( wxCommandEvent& WXUNUSED( evt ) ) +{ + if( m_tools_layout->IsChecked() ) + m_browser->SetZoomType( wxWEBVIEW_ZOOM_TYPE_LAYOUT ); + else + m_browser->SetZoomType( wxWEBVIEW_ZOOM_TYPE_TEXT ); +} + + +/** + * Callback invoked when a loading error occurs + */ +void WEB_NAVIGATOR::OnError( wxWebViewEvent& evt ) +{ +#define WX_ERROR_CASE( type ) case type: \ + category = # type; break; + + wxString category; + + switch( evt.GetInt() ) + { + WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_CONNECTION ); + WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_CERTIFICATE ); + WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_AUTH ); + WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_SECURITY ); + WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_NOT_FOUND ); + WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_REQUEST ); + WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_USER_CANCELLED ); + WX_ERROR_CASE( wxWEBVIEW_NAV_ERR_OTHER ); + } + + // Show the info bar with an error + wxString msg; + msg.Printf( _( "An error occurred loading %s\n'%s'" ), evt.GetURL().GetData(), + category.GetData() ); + m_info->ShowMessage( msg, wxICON_ERROR ); + + UpdateState(); +} + + +SourceViewDialog::SourceViewDialog( wxWindow* parent, wxString source ) : + wxDialog( parent, wxID_ANY, "Source Code", + wxDefaultPosition, wxSize( 700, 500 ), + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ) +{ + wxStyledTextCtrl* text = new wxStyledTextCtrl( this, wxID_ANY ); + + text->SetMarginWidth( 1, 30 ); + text->SetMarginType( 1, wxSTC_MARGIN_NUMBER ); + text->SetText( source ); + + text->StyleClearAll(); + text->SetLexer( wxSTC_LEX_HTML ); + text->StyleSetForeground( wxSTC_H_DOUBLESTRING, wxColour( 255, 0, 0 ) ); + text->StyleSetForeground( wxSTC_H_SINGLESTRING, wxColour( 255, 0, 0 ) ); + text->StyleSetForeground( wxSTC_H_ENTITY, wxColour( 255, 0, 0 ) ); + text->StyleSetForeground( wxSTC_H_TAG, wxColour( 0, 150, 0 ) ); + text->StyleSetForeground( wxSTC_H_TAGUNKNOWN, wxColour( 0, 150, 0 ) ); + text->StyleSetForeground( wxSTC_H_ATTRIBUTE, wxColour( 0, 0, 150 ) ); + text->StyleSetForeground( wxSTC_H_ATTRIBUTEUNKNOWN, wxColour( 0, 0, 150 ) ); + text->StyleSetForeground( wxSTC_H_COMMENT, wxColour( 150, 150, 150 ) ); + + wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL ); + sizer->Add( text, 1, wxEXPAND ); + SetSizer( sizer ); +}