From 7e483f69bd8d6a83a299a35f28475cadb5b53cfd Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Wed, 13 Aug 2014 15:28:54 -0500 Subject: [PATCH] Modular KiCad Blueprint Milestone B), major portions: *) When kicad.exe closes a project, close any open KIFACEs so that they cannot get disassociated from their true PROJECT. *) Allow loading eeschema library editor from kicad.exe *) Allow loading pcbnew library editor from kicad.exe *) Rename LIB_COMPONENT to LIB_PART. *) Add class PART_LIBS, and PART_LIB. *) Make PART_LIBS non-global, i.e. PROJECT specific. *) Implement "data on demand" for PART_LIBS *) Implement "data on demand" for schematic SEARCH_STACK. *) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited. *) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use a weak pointer. *) Remove all chdir() calls so projects don't need to be CWD. *) Romove APPEND support from OpenProjectFiles(). *) Make OpenProjectFiles() robust, even for creating new projects. *) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open, and save them in the .eeschema config file, not in the project file. *) Fix bug with wxDir() while accessing protected dirs in kicad.exe *) Consolidate template copying into PROJECT class, not in kicad.exe source. *) Generally untangle eeschema, making its libraries not global but rather held in the PROJECT. --- TODO.txt | 23 +- common/config_params.cpp | 69 +- common/dialog_shim.cpp | 3 +- common/dialogs/dialog_page_settings.cpp | 18 +- common/displlst.cpp | 13 +- common/draw_frame.cpp | 2 +- common/gestfich.cpp | 94 - common/hotkeys_basic.cpp | 26 +- common/pgm_base.cpp | 6 +- common/project.cpp | 202 +-- common/search_stack.cpp | 72 +- common/single_top.cpp | 32 - cvpcb/autosel.cpp | 4 +- cvpcb/cfg.cpp | 22 +- cvpcb/cvpcb_mainframe.h | 2 +- cvpcb/readwrite_dlgs.cpp | 2 +- eeschema/annotate.cpp | 18 +- eeschema/backanno.cpp | 14 +- eeschema/block_libedit.cpp | 87 +- eeschema/class_libentry.cpp | 299 ++-- eeschema/class_libentry.h | 273 ++- eeschema/class_library.cpp | 720 +++++--- eeschema/class_library.h | 430 ++--- eeschema/component_references_lister.cpp | 44 +- eeschema/component_tree_search_container.cpp | 19 +- eeschema/component_tree_search_container.h | 13 +- eeschema/database.cpp | 22 +- eeschema/dialogs/dialog_bom.cpp | 2 +- eeschema/dialogs/dialog_choose_component.cpp | 4 +- eeschema/dialogs/dialog_choose_component.h | 4 +- .../dialogs/dialog_edit_component_in_lib.cpp | 43 +- .../dialog_edit_component_in_schematic.cpp | 130 +- .../dialog_edit_libentry_fields_in_lib.cpp | 10 +- eeschema/dialogs/dialog_eeschema_config.cpp | 285 ++- .../dialogs/dialog_eeschema_config_fbp.fbp | 1576 ++++++++--------- eeschema/dialogs/dialog_erc.cpp | 21 +- eeschema/dialogs/dialog_lib_edit_pin.cpp | 2 +- eeschema/dialogs/dialog_lib_new_component.h | 2 +- eeschema/dialogs/dialog_netlist.cpp | 2 +- eeschema/edit_component_in_schematic.cpp | 16 +- eeschema/eelibs_read_libraryfiles.cpp | 113 -- eeschema/eeschema.cpp | 76 +- eeschema/eeschema_config.cpp | 235 +-- eeschema/files-io.cpp | 397 ++--- eeschema/getpart.cpp | 188 +- eeschema/invoke_sch_dialog.h | 4 +- eeschema/lib_arc.cpp | 2 +- eeschema/lib_arc.h | 2 +- eeschema/lib_bezier.cpp | 2 +- eeschema/lib_bezier.h | 2 +- eeschema/lib_circle.cpp | 2 +- eeschema/lib_circle.h | 2 +- eeschema/lib_draw_item.cpp | 2 +- eeschema/lib_draw_item.h | 10 +- eeschema/lib_export.cpp | 89 +- eeschema/lib_field.cpp | 10 +- eeschema/lib_field.h | 2 +- eeschema/lib_pin.cpp | 8 +- eeschema/lib_pin.h | 2 +- eeschema/lib_polyline.cpp | 2 +- eeschema/lib_polyline.h | 2 +- eeschema/lib_rectangle.cpp | 2 +- eeschema/lib_rectangle.h | 2 +- eeschema/lib_text.cpp | 2 +- eeschema/lib_text.h | 2 +- eeschema/libarch.cpp | 36 +- eeschema/libedit.cpp | 387 ++-- eeschema/libedit_onleftclick.cpp | 24 +- eeschema/libedit_onrightclick.cpp | 10 +- eeschema/libedit_plot_component.cpp | 50 +- eeschema/libedit_undo_redo.cpp | 54 +- eeschema/libeditframe.cpp | 362 ++-- eeschema/libeditframe.h | 88 +- eeschema/libfield.cpp | 39 +- eeschema/load_one_schematic_file.cpp | 23 +- eeschema/menubar.cpp | 7 +- eeschema/netform.cpp | 64 +- eeschema/netlist.cpp | 125 +- eeschema/netlist.h | 29 +- eeschema/onrightclick.cpp | 141 +- eeschema/pinedit.cpp | 192 +- eeschema/plot_schematic_DXF.cpp | 3 + eeschema/plot_schematic_HPGL.cpp | 3 + eeschema/plot_schematic_PDF.cpp | 6 +- eeschema/plot_schematic_PS.cpp | 3 + eeschema/plot_schematic_SVG.cpp | 5 +- eeschema/protos.h | 8 +- eeschema/sch_collectors.cpp | 20 + eeschema/sch_collectors.h | 33 + eeschema/sch_component.cpp | 572 +++--- eeschema/sch_component.h | 62 +- eeschema/sch_field.cpp | 16 +- eeschema/sch_screen.cpp | 130 +- eeschema/sch_sheet.cpp | 5 +- eeschema/sch_sheet_path.cpp | 86 +- eeschema/sch_sheet_path.h | 9 +- eeschema/schedit.cpp | 52 +- eeschema/schframe.cpp | 318 ++-- eeschema/selpart.cpp | 94 +- eeschema/sheet.cpp | 6 +- eeschema/symbdraw.cpp | 97 +- eeschema/symbedit.cpp | 118 +- eeschema/template_fieldnames.h | 4 +- eeschema/tool_sch.cpp | 8 +- eeschema/tool_viewlib.cpp | 29 +- eeschema/viewlib_frame.cpp | 33 +- eeschema/viewlib_frame.h | 6 +- eeschema/viewlibs.cpp | 203 +-- gerbview/excellon_read_drill_file.cpp | 3 +- include/class_collector.h | 23 +- include/class_sch_screen.h | 33 +- include/core/typeinfo.h | 2 +- include/dialog_helpers.h | 15 +- include/gestfich.h | 18 - include/html_messagebox.h | 2 +- include/id.h | 19 +- include/kiway.h | 13 + include/kiway_player.h | 43 +- include/project.h | 91 +- include/search_stack.h | 33 +- include/wxEeschemaStruct.h | 38 +- include/wxPcbStruct.h | 32 +- include/wxstruct.h | 4 +- kicad/class_treeproject_item.cpp | 64 +- kicad/commandframe.cpp | 10 +- kicad/files-io.cpp | 6 +- kicad/kicad.cpp | 41 +- kicad/kicad.h | 19 +- kicad/mainframe.cpp | 32 +- kicad/menubar.cpp | 13 +- kicad/prjconfig.cpp | 60 +- kicad/tree_project_frame.cpp | 193 +- pcbnew/build_BOM_from_board.cpp | 37 +- pcbnew/class_board.cpp | 3 +- pcbnew/collectors.cpp | 5 +- pcbnew/collectors.h | 6 +- pcbnew/dialogs/dialog_SVG_print.cpp | 11 +- .../dialog_edit_module_for_BoardEditor.cpp | 3 +- .../dialog_edit_module_for_Modedit.cpp | 3 +- pcbnew/dialogs/dialog_gendrill.cpp | 19 +- pcbnew/dialogs/dialog_netlist.cpp | 17 +- pcbnew/dialogs/dialog_plot.cpp | 11 +- pcbnew/dialogs/dialog_select_pretty_lib.cpp | 9 +- .../dialogs/dialog_select_pretty_lib_base.cpp | 4 +- .../dialogs/dialog_select_pretty_lib_base.fbp | 4 +- .../dialogs/dialog_select_pretty_lib_base.h | 7 +- pcbnew/exporters/export_d356.cpp | 12 +- pcbnew/exporters/export_gencad.cpp | 4 +- pcbnew/exporters/gen_modules_placefile.cpp | 9 +- pcbnew/files.cpp | 949 +++++----- pcbnew/kicad_plugin.cpp | 5 +- pcbnew/loadcmp.cpp | 6 +- pcbnew/moduleframe.cpp | 2 + pcbnew/modview_frame.cpp | 1 + pcbnew/netlist_reader.h | 7 +- pcbnew/pcb_parser.cpp | 2 + pcbnew/pcb_parser.h | 6 +- pcbnew/pcbframe.cpp | 27 +- pcbnew/pcbnew.cpp | 27 +- pcbnew/pcbnew_config.cpp | 41 +- pcbnew/specctra.h | 7 +- pcbnew/specctra_export.cpp | 23 +- pcbnew/xchgmod.cpp | 8 +- 163 files changed, 5839 insertions(+), 5589 deletions(-) diff --git a/TODO.txt b/TODO.txt index 7cb4d3325d..0427a5f324 100644 --- a/TODO.txt +++ b/TODO.txt @@ -64,18 +64,13 @@ PCBNew Dick's Final TODO List: ====================== +*) Milestone B of Modular KiCad Blueprint: + * Put SEARCH_STACK::LastVisitedPath() out of its misery. + * Combine CVPCB into PCBNEW. + +*) Milestone C of Modular KiCad Blueprint + * SWIG class KIWAY, PROJECT, and KIWAY_MGR and fill out KIWAY_MGR as needed. + * Implement PROJECT::Substitute(). + * Other stuff in blueprint milestone. + *) Get licensing cleaned up. - -*) DLL-ization of pcbnew & eeschema - http://www.eevblog.com/forum/open-source-kicad-geda/seriously-irritated-with-the-library-editor!/ - https://blueprints.launchpad.net/kicad/+spec/modular-kicad - - Issues as a result of minimal testing: - * If eeschema launched from C++ project manager and does not find all libraries, - then the dialog showing the names of missing libraries is shown twice. - - * Clear all/some? retained strings on project change. - * Clear the FP_LIB_TABLE when the last KIWAY_PLAYER using it is closed. - - -Fix export gencad \ No newline at end of file diff --git a/common/config_params.cpp b/common/config_params.cpp index a5ec23f7c4..4f5c6b84a3 100644 --- a/common/config_params.cpp +++ b/common/config_params.cpp @@ -40,6 +40,40 @@ #include +void wxConfigLoadParams( wxConfigBase* aCfg, + const PARAM_CFG_ARRAY& aList, const wxString& aGroup ) +{ + wxASSERT( aCfg ); + + BOOST_FOREACH( const PARAM_CFG_BASE& param, aList ) + { + if( !!param.m_Group ) + aCfg->SetPath( param.m_Group ); + else + aCfg->SetPath( aGroup ); + + if( param.m_Setup ) + continue; + + param.ReadParam( aCfg ); + } +} + + +void wxConfigLoadSetups( wxConfigBase* aCfg, const PARAM_CFG_ARRAY& aList ) +{ + wxASSERT( aCfg ); + + BOOST_FOREACH( const PARAM_CFG_BASE& param, aList ) + { + if( !param.m_Setup ) + continue; + + param.ReadParam( aCfg ); + } +} + + void wxConfigSaveParams( wxConfigBase* aCfg, const PARAM_CFG_ARRAY& aList, const wxString& aGroup ) { @@ -68,26 +102,6 @@ void wxConfigSaveParams( wxConfigBase* aCfg, } -void wxConfigLoadParams( wxConfigBase* aCfg, - const PARAM_CFG_ARRAY& aList, const wxString& aGroup ) -{ - wxASSERT( aCfg ); - - BOOST_FOREACH( const PARAM_CFG_BASE& param, aList ) - { - if( !!param.m_Group ) - aCfg->SetPath( param.m_Group ); - else - aCfg->SetPath( aGroup ); - - if( param.m_Setup ) - continue; - - param.ReadParam( aCfg ); - } -} - - void wxConfigSaveSetups( wxConfigBase* aCfg, const PARAM_CFG_ARRAY& aList ) { wxASSERT( aCfg ); @@ -110,21 +124,6 @@ void wxConfigSaveSetups( wxConfigBase* aCfg, const PARAM_CFG_ARRAY& aList ) } -void wxConfigLoadSetups( wxConfigBase* aCfg, const PARAM_CFG_ARRAY& aList ) -{ - wxASSERT( aCfg ); - - BOOST_FOREACH( const PARAM_CFG_BASE& param, aList ) - { - if( !param.m_Setup ) - continue; - - param.ReadParam( aCfg ); - } -} - - - void ConfigBaseWriteDouble( wxConfigBase* aConfig, const wxString& aKey, double aValue ) { // Use a single strategy, regardless of wx version. diff --git a/common/dialog_shim.cpp b/common/dialog_shim.cpp index 1d3e9b6054..c699fb4a1e 100644 --- a/common/dialog_shim.cpp +++ b/common/dialog_shim.cpp @@ -62,8 +62,7 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl // pray that aParent is either a KIWAY_PLAYER or DIALOG_SHIM derivation. KIWAY_HOLDER* h = dynamic_cast( aParent ); - wxASSERT_MSG( h, - wxT( "DIALOG_SHIM's parent is NULL or not derived from KIWAY_PLAYER nor DIALOG_SHIM" ) ); + // wxASSERT_MSG( h, wxT( "DIALOG_SHIM's parent is NULL or not derived from KIWAY_PLAYER nor DIALOG_SHIM" ) ); if( h ) SetKiway( this, &h->Kiway() ); diff --git a/common/dialogs/dialog_page_settings.cpp b/common/dialogs/dialog_page_settings.cpp index 34af27ef53..940c41ea38 100644 --- a/common/dialogs/dialog_page_settings.cpp +++ b/common/dialogs/dialog_page_settings.cpp @@ -28,6 +28,7 @@ #include #include // DIM() #include +#include #include #include #include @@ -781,9 +782,11 @@ void DIALOG_PAGES_SETTINGS::GetCustomSizeMilsFromDialog() // Called on .kicad_wks file description selection change void DIALOG_PAGES_SETTINGS::OnWksFileSelection( wxCommandEvent& event ) { + wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + // Display a file picker dialog wxFileDialog fileDialog( this, _( "Select Page Layout Descr File" ), - wxGetCwd(), GetWksFileName(), + pro_dir, GetWksFileName(), PageLayoutDescrFileWildcard, wxFD_DEFAULT_STYLE | wxFD_FILE_MUST_EXIST ); @@ -800,11 +803,14 @@ void DIALOG_PAGES_SETTINGS::OnWksFileSelection( wxCommandEvent& event ) // For Win/Linux/macOS compatibility, a relative path is a good idea if( fn.IsAbsolute() && fileName != GetWksFileName() ) { - fn.MakeRelativeTo( wxGetCwd() ); - wxString msg; - msg.Printf( _( "The page layout descr filename has changed\n" - "Do you want to use the relative path:\n%s"), - fn.GetFullPath().GetData() ); + fn.MakeRelativeTo( pro_dir ); + + wxString msg = wxString::Format( _( + "The page layout descr filename has changed.\n" + "Do you want to use the relative path:\n" + "'%s'" ), + GetChars( fn.GetFullPath() ) + ); if( IsOK( this, msg ) ) shortFileName = fn.GetFullPath(); } diff --git a/common/displlst.cpp b/common/displlst.cpp index e78a72eac8..e41081de63 100644 --- a/common/displlst.cpp +++ b/common/displlst.cpp @@ -37,12 +37,14 @@ EDA_LIST_DIALOG::EDA_LIST_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aTitl const wxArrayString& aItemHeaders, const std::vector& aItemList, const wxString& aSelection, - void( *aCallBackFunction )( wxString& ), + void( *aCallBackFunction )( wxString&, void* ), + void* aCallBackFunctionData, bool aSortList ) : EDA_LIST_DIALOG_BASE( aParent, wxID_ANY, aTitle ) { m_sortList = aSortList; - m_callBackFct = aCallBackFunction; + m_cb_func = aCallBackFunction; + m_cb_data = aCallBackFunctionData; m_itemsListCp = &aItemList; for( unsigned i = 0; i < aItemHeaders.Count(); i++ ) @@ -57,7 +59,7 @@ EDA_LIST_DIALOG::EDA_LIST_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aTitl InsertItems( aItemList, 0 ); - if( m_callBackFct == NULL ) + if( m_cb_func == NULL ) { m_messages->Show( false ); m_staticTextMsg->Show( false ); @@ -231,12 +233,11 @@ void EDA_LIST_DIALOG::onCancelClick( wxCommandEvent& event ) void EDA_LIST_DIALOG::onListItemSelected( wxListEvent& event ) { - - if( m_callBackFct ) + if( m_cb_func ) { m_messages->Clear(); wxString text = GetTextSelection(); - m_callBackFct( text ); + m_cb_func( text, m_cb_data ); m_messages->WriteText( text ); } } diff --git a/common/draw_frame.cpp b/common/draw_frame.cpp index 840f498ad8..01a1296a51 100644 --- a/common/draw_frame.cpp +++ b/common/draw_frame.cpp @@ -659,7 +659,7 @@ void EDA_DRAW_FRAME::AppendMsgPanel( const wxString& textUpper, } -void EDA_DRAW_FRAME::ClearMsgPanel( void ) +void EDA_DRAW_FRAME::ClearMsgPanel() { if( m_messagePanel == NULL ) return; diff --git a/common/gestfich.cpp b/common/gestfich.cpp index 88e992ec7d..c3e0483289 100644 --- a/common/gestfich.cpp +++ b/common/gestfich.cpp @@ -41,100 +41,6 @@ #include #include -/* List of default paths used to locate help files and KiCad library files. - * - * Under windows, KiCad search its files from the binary path file (first - * argument when running "main") So for a standard install, default paths - * are not mandatory, but they exist, just in case. - * KiCad is often installed in c:/Program Files/kicad or c:/kicad (or d: or - * e: ... ) and the directory "share" has no meaning under windows. - * - * Under linux, the problem is more complex. - * In fact there are 3 cases: - * 1 - When released in a distribution: - * binaries are in /usr/bin, KiCad libs in /usr/share/kicad/ and doc in - * /usr/share/doc/kicad/ - * 2 - When compiled by an user: - * binaries also can be in /usr/local/bin, KiCad libs in - * /usr/local/share/kicad/ and doc in /usr/local/share/doc/kicad/ - * 3 - When in an "universal tarball" or build for a server: - * all files are in /usr/local/kicad - * This is mandatory when KiCad is installed on a server (in a school for - * instance) because one can export /usr/local/kicad and obviously the others - * paths cannot be used (cannot be mounted by the client, because they are - * already used). - * - * in cases 1 and 2 KiCad files cannot be found from the binary path. - * in case 3 KiCad files can be found from the binary path only if this is - * a KiCad binary file which is launched. - * But if an user creates a symbolic link to the actual binary file to run - * KiCad, the binary path is not good and the defaults paths must be used - * - * Note: - * KiCad uses first the bin path lo locate KiCad tree. - * if not found KiCad uses the environment variable KICAD to find its files - * and at last KiCad uses the default paths. - * So we can export (linux and windows) the variable KICAD: - * like export KICAD=/my_path/kicad if /my_path/kicad is not a default path - */ - - -wxString MakeReducedFileName( const wxString& fullfilename, - const wxString& default_path, - const wxString& default_ext ) -{ - wxString reduced_filename = fullfilename; - wxString Cwd, ext, path; - - Cwd = default_path; - ext = default_ext; - path = wxPathOnly( reduced_filename ) + UNIX_STRING_DIR_SEP; - reduced_filename.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); - Cwd.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); - - if( Cwd.Last() != '/' ) - Cwd += UNIX_STRING_DIR_SEP; - - path.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); - -#ifdef __WINDOWS__ - - // names are case insensitive under windows - path.MakeLower(); - Cwd.MakeLower(); - ext.MakeLower(); -#endif - - // if the path is "default_path" -> remove it - wxString root_path = path.Left( Cwd.Length() ); - - if( root_path == Cwd ) - { - reduced_filename.Remove( 0, Cwd.Length() ); - } - else // if the path is the current path -> change path to ./ - { - Cwd = wxGetCwd() + UNIX_STRING_DIR_SEP; -#ifdef __WINDOWS__ - Cwd.MakeLower(); -#endif - Cwd.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); - - if( path == Cwd ) - { // the path is the current path -> path = "./" - reduced_filename.Remove( 0, Cwd.Length() ); - wxString tmp = wxT( "./" ) + reduced_filename; - reduced_filename = tmp; - } - } - - // remove extension if == default_ext: - if( !ext.IsEmpty() && reduced_filename.Contains( ext ) ) - reduced_filename.Truncate( reduced_filename.Length() - ext.Length() ); - - return reduced_filename; -} - void AddDelimiterString( wxString& string ) { diff --git a/common/hotkeys_basic.cpp b/common/hotkeys_basic.cpp index 5724fe94cd..273a8240a9 100644 --- a/common/hotkeys_basic.cpp +++ b/common/hotkeys_basic.cpp @@ -676,16 +676,17 @@ void ParseHotkeyConfig( const wxString& data, } -/** - * Function ImportHotkeyConfigFromFile - * Prompt the user for an old hotkey file to read, and read it. - * @param aDescList = current hotkey list descr. to initialize. - */ -void EDA_BASE_FRAME::ImportHotkeyConfigFromFile( struct EDA_HOTKEY_CONFIG* aDescList ) +void EDA_BASE_FRAME::ImportHotkeyConfigFromFile( EDA_HOTKEY_CONFIG* aDescList ) { wxString ext = DEFAULT_HOTKEY_FILENAME_EXT; wxString mask = wxT( "*." ) + ext; + +#if 0 // pass in the project dir as an argument + wxString path = wxPathOnly( Prj().GetProjectFullName() ); +#else wxString path = wxGetCwd(); +#endif + wxString filename = Kiface().Name() + wxT( '.' ) + ext; filename = EDA_FileSelector( _( "Read Hotkey Configuration File:" ), @@ -704,16 +705,17 @@ void EDA_BASE_FRAME::ImportHotkeyConfigFromFile( struct EDA_HOTKEY_CONFIG* aDesc } -/** - * Function ExportHotkeyConfigToFile - * Prompt the user for an old hotkey file to read, and read it. - * @param aDescList = current hotkey list descr. to initialize. - */ -void EDA_BASE_FRAME::ExportHotkeyConfigToFile( struct EDA_HOTKEY_CONFIG* aDescList ) +void EDA_BASE_FRAME::ExportHotkeyConfigToFile( EDA_HOTKEY_CONFIG* aDescList ) { wxString ext = DEFAULT_HOTKEY_FILENAME_EXT; wxString mask = wxT( "*." ) + ext; + +#if 0 + wxString path = wxPathOnly( Prj().GetProjectFullName() ); +#else wxString path = wxGetCwd(); +#endif + wxString filename = Kiface().Name() + wxT( "." ) + ext; filename = EDA_FileSelector( _( "Write Hotkey Configuration File:" ), diff --git a/common/pgm_base.cpp b/common/pgm_base.cpp index d7f923676c..5b7bda64b3 100644 --- a/common/pgm_base.cpp +++ b/common/pgm_base.cpp @@ -364,6 +364,8 @@ bool PGM_BASE::initPgm() { wxFileName pgm_name( App().argv[0] ); + wxConfigBase::DontCreateOnDemand(); + wxInitAllImageHandlers(); m_pgm_checker = new wxSingleInstanceChecker( pgm_name.GetName().Lower() + wxT( "-" ) + wxGetUserId() ); @@ -536,7 +538,9 @@ void PGM_BASE::saveCommonSettings() // process startup: initPgm(), so test before using: if( m_common_settings ) { - m_common_settings->Write( workingDirKey, wxGetCwd() ); + wxString cur_dir = wxGetCwd(); + + m_common_settings->Write( workingDirKey, cur_dir ); } } diff --git a/common/project.cpp b/common/project.cpp index 5ec1245737..0047d085ee 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -45,12 +45,13 @@ PROJECT::PROJECT() void PROJECT::ElemsClear() { + DBG( printf( "%s: clearing all _ELEMS for project %s\n", __func__, TO_UTF8( GetProjectFullName() ) );) + // careful here, this should work, but the virtual destructor may not // be in the same link image as PROJECT. - for( unsigned i = 0; iRead( key, wxEmptyString ); + DBG( printf( "%s: template file '%s' not found using search paths.\n", __func__, TO_UTF8( templateFile ) );) - if( !upath ) - break; + wxFileName templ( wxStandardPaths::Get().GetDocumentsDir(), + wxT( "kicad" ), ProjectFileExtension ); - aDst->AddPaths( upath, aIndex ); + if( !templ.IsFileReadable() ) + { + wxString msg = wxString::Format( _( + "Unable to find '%s' template config file." ), + GetChars( templateFile ) ); + + DisplayError( NULL, msg ); + + return false; + } + + kicad_pro_template = templ.GetFullPath(); } -} + DBG( printf( "%s: using template file '%s' as project file.\n", __func__, TO_UTF8( kicad_pro_template ) );) -// non-member so it can be moved easily, and kept REALLY private. -// Do NOT Clear() in here. -static void add_search_paths( SEARCH_STACK* aDst, const SEARCH_STACK& aSrc, int aIndex ) -{ - for( unsigned i=0; iAddPaths( aSrc[i], aIndex ); -} + wxCopyFile( kicad_pro_template, aDestination ); - -/* -bool PROJECT::MaybeLoadProjectSettings( const std::vector& aFileSet ) -{ - // @todo return true; } -*/ -wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, const wxString& aFileName, - const wxString& aGroupName, bool aForceUseLocalConfig ) +wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, + const wxString& aGroupName, const wxString& aFileName ) { wxConfigBase* cfg = 0; + wxString cur_pro_fn = !aFileName ? GetProjectFullName() : aFileName; - wxFileName fn = aFileName; - fn.SetExt( ProjectFileExtension ); - - wxString cur_pro_fn = fn.GetFullPath(); - - // is there an edge transition, a change in m_project_filename? - if( m_project_name != cur_pro_fn ) - { - m_sch_search.Clear(); - - // to the empty lists, add project dir as first - m_sch_search.AddPaths( fn.GetPath() ); - - // append all paths from aSList - add_search_paths( &m_sch_search, aSList, -1 ); - - // addLibrarySearchPaths( SEARCH_STACK* aSP, wxConfigBase* aCfg ) - // This is undocumented, but somebody wanted to store !schematic! - // library search paths in the .kicad_common file? - add_search_paths( &m_sch_search, Pgm().CommonSettings(), -1 ); - -#if 1 && defined(DEBUG) - m_sch_search.Show( __func__ ); -#endif - } - - // Init local config filename - if( aForceUseLocalConfig || fn.FileExists() ) + if( wxFileName( cur_pro_fn ).IsFileReadable() ) { cfg = new wxFileConfig( wxEmptyString, wxEmptyString, cur_pro_fn, wxEmptyString ); - cfg->DontCreateOnDemand(); - - if( aForceUseLocalConfig ) - { - SetProjectFullName( cur_pro_fn ); - return cfg; - } - /* Check the application version against the version saved in the * project file. * @@ -286,12 +264,11 @@ wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, const wxString& if( version > 0 ) { cfg->SetPath( wxCONFIG_PATH_SEPARATOR ); - SetProjectFullName( cur_pro_fn ); return cfg; } else // Version incorrect { - wxLogDebug( wxT( "Project file version is zero, not using this old project file, going with template." ) ); + DBG( printf( "%s: project file version is zero, not using this old project file, going with template.", __func__ );) delete cfg; cfg = 0; } @@ -299,49 +276,18 @@ wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, const wxString& // No suitable pro file was found, either does not exist, or is too old. // Use the template kicad.pro file. Find it by using caller's SEARCH_STACK. - wxString templateFile = wxT( "kicad." ) + ProjectFileExtension; - wxString kicad_pro_template = aSList.FindValidPath( templateFile ); - - if( !kicad_pro_template ) - { - wxLogDebug( wxT( "Template file <%s> not found using search paths." ), - GetChars( templateFile ) ); - - wxFileName templ( wxStandardPaths::Get().GetDocumentsDir(), - wxT( "kicad" ), ProjectFileExtension ); - - if( !templ.IsFileReadable() ) - { - wxString msg = wxString::Format( _( "Unable to find %s template config file." ), - GetChars( templateFile ) ); - - DisplayError( NULL, msg ); - - return NULL; - } - - kicad_pro_template = templ.GetFullPath(); - } - - // The project config file is not found (happens for new projects, - // or if the schematic editor is run outside an existing project - // In this case the default template (kicad.pro) is used - cur_pro_fn = kicad_pro_template; - wxLogDebug( wxT( "Use template file '%s' as project file." ), GetChars( cur_pro_fn ) ); + copy_pro_file_template( aSList, cur_pro_fn ); cfg = new wxFileConfig( wxEmptyString, wxEmptyString, cur_pro_fn, wxEmptyString ); - cfg->DontCreateOnDemand(); - - SetProjectFullName( cur_pro_fn ); return cfg; } -void PROJECT::ConfigSave( const SEARCH_STACK& aSList, const wxString& aFileName, - const wxString& aGroupName, const PARAM_CFG_ARRAY& aParams ) +void PROJECT::ConfigSave( const SEARCH_STACK& aSList, const wxString& aGroupName, + const PARAM_CFG_ARRAY& aParams, const wxString& aFileName ) { - std::auto_ptr cfg( configCreate( aSList, aFileName, aGroupName, true ) ); + std::auto_ptr cfg( configCreate( aSList, aGroupName, aFileName ) ); if( !cfg.get() ) { @@ -373,11 +319,10 @@ void PROJECT::ConfigSave( const SEARCH_STACK& aSList, const wxString& aFileName } -bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aFileName, - const wxString& aGroupName, const PARAM_CFG_ARRAY& aParams, - bool doLoadOnlyIfNew ) +bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aGroupName, + const PARAM_CFG_ARRAY& aParams, const wxString& aForeignProjectFileName ) { - std::auto_ptr cfg( configCreate( aSList, aFileName, aGroupName, false ) ); + std::auto_ptr cfg( configCreate( aSList, aGroupName, aForeignProjectFileName ) ); if( !cfg.get() ) { @@ -389,11 +334,6 @@ bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aFileName, wxString timestamp = cfg->Read( wxT( "update" ) ); - if( doLoadOnlyIfNew && timestamp.size() && timestamp == m_pro_date_and_time ) - { - return false; - } - m_pro_date_and_time = timestamp; wxConfigLoadParams( cfg.get(), aParams, aGroupName ); @@ -401,3 +341,17 @@ bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aFileName, return true; } + +const wxString PROJECT::AbsolutePath( const wxString& aFileName ) const +{ + wxFileName fn = aFileName; + + if( !fn.IsAbsolute() ) + { + wxString pro_dir = wxPathOnly( GetProjectFullName() ); + + fn.Normalize( wxPATH_NORM_ALL, pro_dir ); + } + + return fn.GetFullPath(); +} diff --git a/common/search_stack.cpp b/common/search_stack.cpp index a4722a574f..e4cc11e572 100644 --- a/common/search_stack.cpp +++ b/common/search_stack.cpp @@ -11,17 +11,39 @@ #endif -wxString SEARCH_STACK::FilenameWithRelativePathInSearchList( const wxString& aFullFilename ) +int SEARCH_STACK::Split( wxArrayString* aResult, const wxString aPathString ) +{ + wxStringTokenizer tokenizer( aPathString, PATH_SEPS, wxTOKEN_STRTOK ); + + while( tokenizer.HasMoreTokens() ) + { + wxString path = tokenizer.GetNextToken(); + + aResult->Add( path ); + } + + return aResult->GetCount(); +} + + +// Convert aRelativePath to an absolute path based on aBaseDir +static wxString base_dir( const wxString& aRelativePath, const wxString& aBaseDir ) +{ + wxFileName fn = aRelativePath; + + if( !fn.IsAbsolute() && !!aBaseDir ) + { + wxASSERT_MSG( wxFileName( aBaseDir ).IsAbsolute(), wxT( "Must pass absolute path in aBaseDir" ) ); + fn.MakeRelativeTo( aBaseDir ); + } + + return fn.GetFullPath(); +} + + +wxString SEARCH_STACK::FilenameWithRelativePathInSearchList( + const wxString& aFullFilename, const wxString& aBaseDir ) { - /* If the library path is already in the library search paths - * list, just add the library name to the list. Otherwise, add - * the library name with the full or relative path. - * the relative path, when possible is preferable, - * because it preserve use of default libraries paths, when the path is a sub path of - * these default paths - * Note we accept only sub paths, - * not relative paths starting by ../ that are not subpaths and are outside kicad libs paths - */ wxFileName fn = aFullFilename; wxString filename = aFullFilename; @@ -33,7 +55,7 @@ wxString SEARCH_STACK::FilenameWithRelativePathInSearchList( const wxString& aFu fn = aFullFilename; // Search for the shortest subpath within 'this': - if( fn.MakeRelativeTo( (*this)[kk] ) ) + if( fn.MakeRelativeTo( base_dir( (*this)[kk], aBaseDir ) ) ) { if( fn.GetPathWithSep().StartsWith( wxT("..") ) ) // Path outside kicad libs paths continue; @@ -52,13 +74,16 @@ wxString SEARCH_STACK::FilenameWithRelativePathInSearchList( const wxString& aFu void SEARCH_STACK::RemovePaths( const wxString& aPaths ) { - wxStringTokenizer tokenizer( aPaths, PATH_SEPS, wxTOKEN_STRTOK ); + bool isCS = wxFileName::IsCaseSensitive(); + wxArrayString paths; - while( tokenizer.HasMoreTokens() ) + Split( &paths, aPaths ); + + for( unsigned i=0; i= GetCount() ) { - while( tokenizer.HasMoreTokens() ) + for( unsigned i=0; iRead( workingDirKey, &dir ) && wxDirExists( dir ) ) - { - wxSetWorkingDirectory( dir ); - } - */ - } frame->Show(); diff --git a/cvpcb/autosel.cpp b/cvpcb/autosel.cpp index bdee3e4d8b..d05c6505c6 100644 --- a/cvpcb/autosel.cpp +++ b/cvpcb/autosel.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -91,7 +92,8 @@ void CVPCB_MAINFRAME::AssocieModule( wxCommandEvent& event ) char Line[1024]; FILE* file; size_t ii; - SEARCH_STACK& search = Prj().SchSearchS(); + + SEARCH_STACK& search = Kiface().KifaceSearch(); if( m_netlist.IsEmpty() ) return; diff --git a/cvpcb/cfg.cpp b/cvpcb/cfg.cpp index b0b1778ed2..4568b67ad9 100644 --- a/cvpcb/cfg.cpp +++ b/cvpcb/cfg.cpp @@ -59,30 +59,25 @@ PARAM_CFG_ARRAY& CVPCB_MAINFRAME::GetProjectFileParameters() } -void CVPCB_MAINFRAME::LoadProjectFile( const wxString& aFileName ) +void CVPCB_MAINFRAME::LoadProjectFile() { - wxFileName fn( aFileName ); - PROJECT& prj = Prj(); + PROJECT& prj = Prj(); m_ModuleLibNames.Clear(); m_AliasLibNames.Clear(); - fn.SetExt( ProjectFileExtension ); - // was: Pgm().ReadProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters(), false ); - prj.ConfigLoad( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP_CVP, GetProjectFileParameters(), false ); + prj.ConfigLoad( Kiface().KifaceSearch(), GROUP_CVP, GetProjectFileParameters() ); if( m_NetlistFileExtension.IsEmpty() ) m_NetlistFileExtension = wxT( "net" ); - - // Force FP_LIB_TABLE to be loaded on demand. - prj.ElemClear( PROJECT::ELEM_FPTBL ); } void CVPCB_MAINFRAME::SaveProjectFile( wxCommandEvent& aEvent ) { - wxFileName fn = m_NetlistFileName; + PROJECT& prj = Prj(); + wxFileName fn = prj.AbsolutePath( m_NetlistFileName.GetFullPath() ); fn.SetExt( ProjectFileExtension ); @@ -103,11 +98,8 @@ void CVPCB_MAINFRAME::SaveProjectFile( wxCommandEvent& aEvent ) if( !IsWritable( fn ) ) return; - // was: - // Pgm().WriteProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters() ); + wxString pro_name = fn.GetFullPath(); - PROJECT& prj = Prj(); - - prj.ConfigSave( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP_CVP, GetProjectFileParameters() ); + prj.ConfigSave( Kiface().KifaceSearch(), GROUP_CVP, GetProjectFileParameters(), pro_name ); } diff --git a/cvpcb/cvpcb_mainframe.h b/cvpcb/cvpcb_mainframe.h index adb67974d6..2d42947ed7 100644 --- a/cvpcb/cvpcb_mainframe.h +++ b/cvpcb/cvpcb_mainframe.h @@ -217,7 +217,7 @@ public: * Function LoadProjectFile * reads the configuration parameter from the project (.pro) file \a aFileName */ - void LoadProjectFile( const wxString& aFileName ); + void LoadProjectFile(); void LoadSettings( wxConfigBase* aCfg ); // override virtual diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp index c48d6dfe89..7733855884 100644 --- a/cvpcb/readwrite_dlgs.cpp +++ b/cvpcb/readwrite_dlgs.cpp @@ -169,7 +169,7 @@ bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles() if( m_compListBox == NULL ) return false; - LoadProjectFile( m_NetlistFileName.GetFullPath() ); + LoadProjectFile(); LoadFootprintFiles(); BuildFOOTPRINTS_LISTBOX(); diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp index 30881e4fa1..f15e49ab5b 100644 --- a/eeschema/annotate.cpp +++ b/eeschema/annotate.cpp @@ -95,18 +95,18 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, // Set sheet number and number of sheets. SetSheetNumberAndCount(); - /* Build component list */ + // Build component list if( aAnnotateSchematic ) { - sheets.GetComponents( references ); + sheets.GetComponents( Prj().SchLibs(), references ); } else { - m_CurrentSheet->GetComponents( references ); + m_CurrentSheet->GetComponents( Prj().SchLibs(), references ); } - /* Break full components reference in name (prefix) and number: - * example: IC1 become IC, and 1 */ + // Break full components reference in name (prefix) and number: + // example: IC1 become IC, and 1 references.SplitReferences(); switch( aSortOption ) @@ -172,15 +172,15 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly ) { - /* build the screen list */ + // build the screen list SCH_SHEET_LIST SheetList; SCH_REFERENCE_LIST ComponentsList; - /* Build the list of components */ + // Build the list of components if( !aOneSheetOnly ) - SheetList.GetComponents( ComponentsList ); + SheetList.GetComponents( Prj().SchLibs(), ComponentsList ); else - m_CurrentSheet->GetComponents( ComponentsList ); + m_CurrentSheet->GetComponents( Prj().SchLibs(), ComponentsList ); return ComponentsList.CheckAnnotation( aMessageList ); } diff --git a/eeschema/backanno.cpp b/eeschema/backanno.cpp index de39e8bcb4..a41c65caee 100644 --- a/eeschema/backanno.cpp +++ b/eeschema/backanno.cpp @@ -54,7 +54,7 @@ void SCH_EDIT_FRAME::backAnnotateFootprints( const std::string& aChangedSetOfRef SCH_SHEET_LIST sheets; bool isChanged = false; - sheets.GetComponents( refs, false ); + sheets.GetComponents( Prj().SchLibs(), refs, false ); DSNLEXER lexer( aChangedSetOfReferences, FROM_UTF8( __func__ ) ); PTREE doc; @@ -98,7 +98,7 @@ void SCH_EDIT_FRAME::backAnnotateFootprints( const std::string& aChangedSetOfRef // We have found a candidate. // Note: it can be not unique (multiple parts per package) // So we *do not* stop the search here - SCH_COMPONENT* component = refs[ii].GetComponent(); + SCH_COMPONENT* component = refs[ii].GetComp(); SCH_FIELD* fpfield = component->GetField( FOOTPRINT ); const wxString& oldfp = fpfield->GetText(); @@ -133,9 +133,9 @@ bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( const wxString& aFullFilenam { // Build a flat list of components in schematic: SCH_REFERENCE_LIST referencesList; - SCH_SHEET_LIST SheetList; + SCH_SHEET_LIST sheetList; - SheetList.GetComponents( referencesList, false ); + sheetList.GetComponents( Prj().SchLibs(), referencesList, false ); FILE* cmpFile = wxFopen( aFullFilename, wxT( "rt" ) ); if( cmpFile == NULL ) @@ -196,9 +196,9 @@ bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( const wxString& aFullFilenam if( Cmp_KEEPCASE( reference, referencesList[ii].GetRef() ) == 0 ) { // We have found a candidate. - // Note: it can be not unique (multiple parts per package) + // Note: it can be not unique (multiple units per part) // So we *do not* stop the search here - SCH_COMPONENT* component = referencesList[ii].GetComponent(); + SCH_COMPONENT* component = referencesList[ii].GetComp(); SCH_FIELD* fpfield = component->GetField( FOOTPRINT ); fpfield->SetText( footprint ); @@ -218,7 +218,7 @@ bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( const wxString& aFullFilenam bool SCH_EDIT_FRAME::LoadCmpToFootprintLinkFile() { - wxString path = wxGetCwd(); + wxString path = wxPathOnly( Prj().GetProjectFullName() ); wxFileDialog dlg( this, _( "Load Component-Footprint Link File" ), path, wxEmptyString, diff --git a/eeschema/block_libedit.cpp b/eeschema/block_libedit.cpp index 139e6cf3ff..64dc21c5f2 100644 --- a/eeschema/block_libedit.cpp +++ b/eeschema/block_libedit.cpp @@ -109,12 +109,12 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC ) DisplayError( this, wxT( "Error in HandleBlockPLace" ) ); break; - case BLOCK_DRAG: + case BLOCK_DRAG: // Drag case BLOCK_DRAG_ITEM: - case BLOCK_MOVE: - case BLOCK_COPY: - if ( m_component ) - ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate, + case BLOCK_MOVE: // Move + case BLOCK_COPY: // Copy + if( GetCurPart() ) + ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate, m_unit, m_convert, m_editPinsPerPartOrConvert ); if( ItemCount ) @@ -139,57 +139,56 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC ) GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE ); break; - case BLOCK_DELETE: /* Delete */ - if ( m_component ) - ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate, + case BLOCK_DELETE: // Delete + if( GetCurPart() ) + ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate, m_unit, m_convert, m_editPinsPerPartOrConvert ); if( ItemCount ) - SaveCopyInUndoList( m_component ); + SaveCopyInUndoList( GetCurPart() ); - if ( m_component ) + if( GetCurPart() ) { - m_component->DeleteSelectedItems(); + GetCurPart()->DeleteSelectedItems(); OnModify(); } break; - case BLOCK_SAVE: /* Save */ + case BLOCK_SAVE: // Save case BLOCK_PASTE: case BLOCK_FLIP: break; - case BLOCK_ROTATE: case BLOCK_MIRROR_X: case BLOCK_MIRROR_Y: - if ( m_component ) - ItemCount = m_component->SelectItems( GetScreen()->m_BlockLocate, + if( GetCurPart() ) + ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate, m_unit, m_convert, m_editPinsPerPartOrConvert ); if( ItemCount ) - SaveCopyInUndoList( m_component ); + SaveCopyInUndoList( GetCurPart() ); pt = GetScreen()->m_BlockLocate.Centre(); pt = GetNearestGridPosition( pt ); NEGATE( pt.y ); - if ( m_component ) + if( GetCurPart() ) { OnModify(); int block_cmd = GetScreen()->m_BlockLocate.GetCommand(); if( block_cmd == BLOCK_MIRROR_Y) - m_component->MirrorSelectedItemsH( pt ); + GetCurPart()->MirrorSelectedItemsH( pt ); else if( block_cmd == BLOCK_MIRROR_X) - m_component->MirrorSelectedItemsV( pt ); + GetCurPart()->MirrorSelectedItemsV( pt ); else if( block_cmd == BLOCK_ROTATE ) - m_component->RotateSelectedItems( pt ); + GetCurPart()->RotateSelectedItems( pt ); } break; - case BLOCK_ZOOM: /* Window Zoom */ + case BLOCK_ZOOM: // Window Zoom Window_Zoom( GetScreen()->m_BlockLocate ); break; @@ -200,10 +199,10 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC ) break; } - if( ! nextCmd ) + if( !nextCmd ) { - if( GetScreen()->m_BlockLocate.GetCommand() != BLOCK_SELECT_ITEMS_ONLY && m_component ) - m_component->ClearSelectedItems(); + if( GetScreen()->m_BlockLocate.GetCommand() != BLOCK_SELECT_ITEMS_ONLY && GetCurPart() ) + GetCurPart()->ClearSelectedItems(); GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK ); GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE ); @@ -233,62 +232,62 @@ void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC ) case BLOCK_IDLE: break; - case BLOCK_DRAG: + case BLOCK_DRAG: // Drag case BLOCK_DRAG_ITEM: - case BLOCK_MOVE: - case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/ + case BLOCK_MOVE: // Move + case BLOCK_PRESELECT_MOVE: // Move with preselection list GetScreen()->m_BlockLocate.ClearItemsList(); - if ( m_component ) - SaveCopyInUndoList( m_component ); + if( GetCurPart() ) + SaveCopyInUndoList( GetCurPart() ); pt = GetScreen()->m_BlockLocate.GetMoveVector(); pt.y *= -1; - if ( m_component ) - m_component->MoveSelectedItems( pt ); + if( GetCurPart() ) + GetCurPart()->MoveSelectedItems( pt ); m_canvas->Refresh( true ); break; - case BLOCK_COPY: /* Copy */ + case BLOCK_COPY: // Copy GetScreen()->m_BlockLocate.ClearItemsList(); - if ( m_component ) - SaveCopyInUndoList( m_component ); + if( GetCurPart() ) + SaveCopyInUndoList( GetCurPart() ); pt = GetScreen()->m_BlockLocate.GetMoveVector(); NEGATE( pt.y ); - if ( m_component ) - m_component->CopySelectedItems( pt ); + if( GetCurPart() ) + GetCurPart()->CopySelectedItems( pt ); break; - case BLOCK_PASTE: /* Paste (recopy the last block saved) */ + case BLOCK_PASTE: // Paste (recopy the last block saved) GetScreen()->m_BlockLocate.ClearItemsList(); break; case BLOCK_ROTATE: // Invert by popup menu, from block move case BLOCK_MIRROR_X: // Invert by popup menu, from block move case BLOCK_MIRROR_Y: // Invert by popup menu, from block move - if ( m_component ) - SaveCopyInUndoList( m_component ); + if( GetCurPart() ) + SaveCopyInUndoList( GetCurPart() ); pt = GetScreen()->m_BlockLocate.Centre(); pt = GetNearestGridPosition( pt ); NEGATE( pt.y ); - if ( m_component ) + if( GetCurPart() ) { int block_cmd = GetScreen()->m_BlockLocate.GetCommand(); if( block_cmd == BLOCK_MIRROR_Y) - m_component->MirrorSelectedItemsH( pt ); + GetCurPart()->MirrorSelectedItemsH( pt ); else if( block_cmd == BLOCK_MIRROR_X) - m_component->MirrorSelectedItemsV( pt ); + GetCurPart()->MirrorSelectedItemsV( pt ); else if( block_cmd == BLOCK_ROTATE ) - m_component->RotateSelectedItems( pt ); + GetCurPart()->RotateSelectedItems( pt ); } break; @@ -326,7 +325,7 @@ void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) aPanel->GetParent(); wxASSERT( parent != NULL ); - LIB_COMPONENT* component = parent->GetComponent(); + LIB_PART* component = parent->GetCurPart(); if( component == NULL ) return; diff --git a/eeschema/class_libentry.cpp b/eeschema/class_libentry.cpp index bd7f81120f..331c65a06b 100644 --- a/eeschema/class_libentry.cpp +++ b/eeschema/class_libentry.cpp @@ -51,36 +51,30 @@ #include -// Set this to 1 to print debugging output in alias and component destructors to verify -// objects get cleaned up properly. -#if defined( TRACE_DESTRUCTOR ) -#undef TRACE_DESTRUCTOR -#endif - -#define TRACE_DESTRUCTOR 0 - // the separator char between the subpart id and the reference // 0 (no separator) or '.' or some other character -int LIB_COMPONENT::m_subpartIdSeparator = 0; +int LIB_PART::m_subpartIdSeparator = 0; + // the ascii char value to calculate the subpart symbol id from the part number: // 'A' or '1' usually. (to print U1.A or U1.1) // if this a a digit, a number is used as id symbol -int LIB_COMPONENT::m_subpartFirstId = 'A'; +int LIB_PART::m_subpartFirstId = 'A'; -LIB_ALIAS::LIB_ALIAS( const wxString& aName, LIB_COMPONENT* aRootComponent ): - EDA_ITEM( LIB_ALIAS_T ) +LIB_ALIAS::LIB_ALIAS( const wxString& aName, LIB_PART* aRootPart ): + EDA_ITEM( LIB_ALIAS_T ), + shared( aRootPart ) { - root = aRootComponent; name = aName; } -LIB_ALIAS::LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_COMPONENT* aRootComponent ) : - EDA_ITEM( aAlias ) +LIB_ALIAS::LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_PART* aRootPart ) : + EDA_ITEM( aAlias ), + shared( aRootPart ) { - name = aAlias.name; - root = aRootComponent; + name = aAlias.name; + description = aAlias.description; keyWords = aAlias.keyWords; docFileName = aAlias.docFileName; @@ -89,17 +83,24 @@ LIB_ALIAS::LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_COMPONENT* aRootComponent ) : LIB_ALIAS::~LIB_ALIAS() { -#if TRACE_DESTRUCTOR - wxLogDebug( wxT( "Destroying alias \"%s\" of component \"%s\" with alias list count %d." ), - GetChars( name ), GetChars( root->GetName() ), root->m_aliases.size() ); + wxASSERT_MSG( shared, wxT( "~LIB_ALIAS() without a LIB_PART" ) ); + +#if defined(DEBUG) && 1 + printf( "%s: destroying alias:'%s' of part:'%s' alias count:%zd.\n", + __func__, TO_UTF8( name ), TO_UTF8( shared->GetName() ), shared->m_aliases.size() ); #endif + + if( shared ) + shared->RemoveAlias( this ); } -wxString LIB_ALIAS::GetLibraryName() +const wxString LIB_ALIAS::GetLibraryName() { - if( GetComponent() ) - return GetComponent()->GetLibraryName(); + wxASSERT_MSG( shared, wxT( "LIB_ALIAS without a LIB_PART" ) ); + + if( shared ) + return shared->GetLibraryName(); return wxString( _( "none" ) ); } @@ -107,12 +108,13 @@ wxString LIB_ALIAS::GetLibraryName() bool LIB_ALIAS::IsRoot() const { - return name.CmpNoCase( root->GetName() ) == 0; + return Cmp_KEEPCASE( name, shared->GetName() ) == 0; } -CMP_LIBRARY* LIB_ALIAS::GetLibrary() + +PART_LIB* LIB_ALIAS::GetLib() { - return root->GetLibrary(); + return shared->GetLib(); } @@ -147,24 +149,34 @@ bool LIB_ALIAS::SaveDoc( OUTPUTFORMATTER& aFormatter ) bool LIB_ALIAS::operator==( const wxChar* aName ) const { - return name.CmpNoCase( aName ) == 0; + return Cmp_KEEPCASE( name, aName ) == 0; } bool operator<( const LIB_ALIAS& aItem1, const LIB_ALIAS& aItem2 ) { - return aItem1.GetName().CmpNoCase( aItem2.GetName() ) < 0; + return Cmp_KEEPCASE( aItem1.GetName(), aItem2.GetName() ) < 0; } int LibraryEntryCompare( const LIB_ALIAS* aItem1, const LIB_ALIAS* aItem2 ) { - return aItem1->GetName().CmpNoCase( aItem2->GetName() ); + return Cmp_KEEPCASE( aItem1->GetName(), aItem2->GetName() ); } -LIB_COMPONENT::LIB_COMPONENT( const wxString& aName, CMP_LIBRARY* aLibrary ) : - EDA_ITEM( LIB_COMPONENT_T ) +/// http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared +struct null_deleter +{ + void operator()(void const *) const + { + } +}; + + +LIB_PART::LIB_PART( const wxString& aName, PART_LIB* aLibrary ) : + EDA_ITEM( LIB_PART_T ), + m_me( this, null_deleter() ) { m_name = aName; m_library = aLibrary; @@ -192,23 +204,24 @@ LIB_COMPONENT::LIB_COMPONENT( const wxString& aName, CMP_LIBRARY* aLibrary ) : } -LIB_COMPONENT::LIB_COMPONENT( LIB_COMPONENT& aComponent, CMP_LIBRARY* aLibrary ) : - EDA_ITEM( aComponent ) +LIB_PART::LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary ) : + EDA_ITEM( aPart ), + m_me( this, null_deleter() ) { LIB_ITEM* newItem; m_library = aLibrary; - m_name = aComponent.m_name; - m_FootprintList = aComponent.m_FootprintList; - m_unitCount = aComponent.m_unitCount; - m_unitsLocked = aComponent.m_unitsLocked; - m_pinNameOffset = aComponent.m_pinNameOffset; - m_showPinNumbers = aComponent.m_showPinNumbers; - m_showPinNames = aComponent.m_showPinNames; - m_dateModified = aComponent.m_dateModified; - m_options = aComponent.m_options; + m_name = aPart.m_name; + m_FootprintList = aPart.m_FootprintList; + m_unitCount = aPart.m_unitCount; + m_unitsLocked = aPart.m_unitsLocked; + m_pinNameOffset = aPart.m_pinNameOffset; + m_showPinNumbers = aPart.m_showPinNumbers; + m_showPinNames = aPart.m_showPinNames; + m_dateModified = aPart.m_dateModified; + m_options = aPart.m_options; - BOOST_FOREACH( LIB_ITEM& oldItem, aComponent.GetDrawItemList() ) + BOOST_FOREACH( LIB_ITEM& oldItem, aPart.GetDrawItemList() ) { if( oldItem.IsNew() ) continue; @@ -218,47 +231,49 @@ LIB_COMPONENT::LIB_COMPONENT( LIB_COMPONENT& aComponent, CMP_LIBRARY* aLibrary ) drawings.push_back( newItem ); } - for( size_t i = 0; i < aComponent.m_aliases.size(); i++ ) + for( size_t i = 0; i < aPart.m_aliases.size(); i++ ) { - LIB_ALIAS* alias = new LIB_ALIAS( *aComponent.m_aliases[i], this ); + LIB_ALIAS* alias = new LIB_ALIAS( *aPart.m_aliases[i], this ); m_aliases.push_back( alias ); } } -LIB_COMPONENT::~LIB_COMPONENT() +LIB_PART::~LIB_PART() { -#if TRACE_DESTRUCTOR - wxLogDebug( wxT( "Destroying component <%s> with alias list count of %d" ), - GetChars( GetName() ), m_aliases.size() ); +#if defined(DEBUG) && 1 + + if( m_aliases.size() ) + { + int breakhere = 1; + (void) breakhere; + } + + printf( "%s: destroying part '%s' with alias list count of %zd\n", + __func__, TO_UTF8( GetName() ), m_aliases.size() ); #endif - // If the component is being delete directly rather than trough the library, free all - // of the memory allocated by the aliases. - if( !m_aliases.empty() ) + // If the part is being deleted directly rather than through the library, + // delete all of the aliases. + while( m_aliases.size() ) { - LIB_ALIAS* alias; - - while( !m_aliases.empty() ) - { - alias = m_aliases.back(); - m_aliases.pop_back(); - delete alias; - } + LIB_ALIAS* alias = m_aliases.back(); + m_aliases.pop_back(); + delete alias; } } -wxString LIB_COMPONENT::GetLibraryName() +const wxString LIB_PART::GetLibraryName() { - if( m_library != NULL ) + if( m_library ) return m_library->GetName(); return wxString( _( "none" ) ); } -wxString LIB_COMPONENT::SubReference( int aUnit, bool aAddSeparator ) +wxString LIB_PART::SubReference( int aUnit, bool aAddSeparator ) { wxString subRef; @@ -274,7 +289,7 @@ wxString LIB_COMPONENT::SubReference( int aUnit, bool aAddSeparator ) } -void LIB_COMPONENT::SetName( const wxString& aName ) +void LIB_PART::SetName( const wxString& aName ) { m_name = aName; GetValueField().SetText( aName ); @@ -282,7 +297,7 @@ void LIB_COMPONENT::SetName( const wxString& aName ) } -void LIB_COMPONENT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDc, const wxPoint& aOffset, int aMulti, +void LIB_PART::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDc, const wxPoint& aOffset, int aMulti, int aConvert, GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor, const TRANSFORM& aTransform, bool aShowPinText, bool aDrawFields, bool aOnlySelected ) { @@ -390,7 +405,7 @@ void LIB_COMPONENT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDc, const wxPoint& aOff } -void LIB_COMPONENT::Plot( PLOTTER* aPlotter, int aUnit, int aConvert, +void LIB_PART::Plot( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint& aOffset, const TRANSFORM& aTransform ) { wxASSERT( aPlotter != NULL ); @@ -415,7 +430,7 @@ void LIB_COMPONENT::Plot( PLOTTER* aPlotter, int aUnit, int aConvert, } } -void LIB_COMPONENT::PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert, +void LIB_PART::PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert, const wxPoint& aOffset, const TRANSFORM& aTransform ) { wxASSERT( aPlotter != NULL ); @@ -449,7 +464,7 @@ void LIB_COMPONENT::PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert, } -void LIB_COMPONENT::RemoveDrawItem( LIB_ITEM* aItem, EDA_DRAW_PANEL* aPanel, wxDC* aDc ) +void LIB_PART::RemoveDrawItem( LIB_ITEM* aItem, EDA_DRAW_PANEL* aPanel, wxDC* aDc ) { wxASSERT( aItem != NULL ); @@ -461,10 +476,10 @@ void LIB_COMPONENT::RemoveDrawItem( LIB_ITEM* aItem, EDA_DRAW_PANEL* aPanel, wxD if( field->GetId() < MANDATORY_FIELDS ) { - wxLogWarning( _( "An attempt was made to remove the %s field \ -from component %s in library %s." ), - GetChars( field->GetName() ), GetChars( GetName() ), - GetChars( GetLibraryName() ) ); + wxLogWarning( _( + "An attempt was made to remove the %s field from component %s in library %s." ), + GetChars( field->GetName() ), GetChars( GetName() ), + GetChars( GetLibraryName() ) ); return; } } @@ -486,7 +501,7 @@ from component %s in library %s." ), } -void LIB_COMPONENT::AddDrawItem( LIB_ITEM* aItem ) +void LIB_PART::AddDrawItem( LIB_ITEM* aItem ) { wxASSERT( aItem != NULL ); @@ -495,7 +510,7 @@ void LIB_COMPONENT::AddDrawItem( LIB_ITEM* aItem ) } -LIB_ITEM* LIB_COMPONENT::GetNextDrawItem( LIB_ITEM* aItem, KICAD_T aType ) +LIB_ITEM* LIB_PART::GetNextDrawItem( LIB_ITEM* aItem, KICAD_T aType ) { /* Return the next draw object pointer. * If item is NULL return the first item of type in the list. @@ -532,7 +547,7 @@ LIB_ITEM* LIB_COMPONENT::GetNextDrawItem( LIB_ITEM* aItem, KICAD_T aType ) } -void LIB_COMPONENT::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) +void LIB_PART::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) { /* Notes: * when aUnit == 0: no unit filtering @@ -558,7 +573,7 @@ void LIB_COMPONENT::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) } -LIB_PIN* LIB_COMPONENT::GetPin( const wxString& aNumber, int aUnit, int aConvert ) +LIB_PIN* LIB_PART::GetPin( const wxString& aNumber, int aUnit, int aConvert ) { wxString pNumber; LIB_PINS pinList; @@ -579,7 +594,7 @@ LIB_PIN* LIB_COMPONENT::GetPin( const wxString& aNumber, int aUnit, int aConvert } -bool LIB_COMPONENT::Save( OUTPUTFORMATTER& aFormatter ) +bool LIB_PART::Save( OUTPUTFORMATTER& aFormatter ) { LIB_FIELD& value = GetValueField(); @@ -714,7 +729,7 @@ bool LIB_COMPONENT::Save( OUTPUTFORMATTER& aFormatter ) } -bool LIB_COMPONENT::Load( LINE_READER& aLineReader, wxString& aErrorMsg ) +bool LIB_PART::Load( LINE_READER& aLineReader, wxString& aErrorMsg ) { int unused; char* p; @@ -866,7 +881,7 @@ ok: } -bool LIB_COMPONENT::LoadDrawEntries( LINE_READER& aLineReader, wxString& aErrorMsg ) +bool LIB_PART::LoadDrawEntries( LINE_READER& aLineReader, wxString& aErrorMsg ) { char* line; LIB_ITEM* newEntry = NULL; @@ -914,8 +929,8 @@ bool LIB_COMPONENT::LoadDrawEntries( LINE_READER& aLineReader, wxString& aErrorM newEntry = ( LIB_ITEM* ) new LIB_BEZIER( this ); break; - case '#': // Comment - continue; + case '#': // Comment + continue; default: aErrorMsg.Printf( wxT( "undefined DRAW command %c" ), line[0] ); @@ -924,7 +939,7 @@ bool LIB_COMPONENT::LoadDrawEntries( LINE_READER& aLineReader, wxString& aErrorM if( !newEntry->Load( aLineReader, aErrorMsg ) ) { - aErrorMsg.Printf( wxT( "error <%s> in DRAW command %c" ), + aErrorMsg.Printf( wxT( "error '%s' in DRAW command %c" ), GetChars( aErrorMsg ), line[0] ); delete newEntry; @@ -951,7 +966,7 @@ bool LIB_COMPONENT::LoadDrawEntries( LINE_READER& aLineReader, wxString& aErrorM } -bool LIB_COMPONENT::LoadAliases( char* aLine, wxString& aErrorMsg ) +bool LIB_PART::LoadAliases( char* aLine, wxString& aErrorMsg ) { char* text = strtok( aLine, " \t\r\n" ); @@ -965,7 +980,7 @@ bool LIB_COMPONENT::LoadAliases( char* aLine, wxString& aErrorMsg ) } -bool LIB_COMPONENT::LoadField( LINE_READER& aLineReader, wxString& aErrorMsg ) +bool LIB_PART::LoadField( LINE_READER& aLineReader, wxString& aErrorMsg ) { LIB_FIELD* field = new LIB_FIELD( this ); @@ -1000,7 +1015,7 @@ bool LIB_COMPONENT::LoadField( LINE_READER& aLineReader, wxString& aErrorMsg ) } -bool LIB_COMPONENT::LoadFootprints( LINE_READER& aLineReader, wxString& aErrorMsg ) +bool LIB_PART::LoadFootprints( LINE_READER& aLineReader, wxString& aErrorMsg ) { char* line; char* p; @@ -1025,7 +1040,7 @@ bool LIB_COMPONENT::LoadFootprints( LINE_READER& aLineReader, wxString& aErrorMs } -EDA_RECT LIB_COMPONENT::GetBoundingBox( int aUnit, int aConvert ) const +EDA_RECT LIB_PART::GetBoundingBox( int aUnit, int aConvert ) const { EDA_RECT bBox( wxPoint( 0, 0 ), wxSize( 0, 0 ) ); @@ -1050,7 +1065,7 @@ EDA_RECT LIB_COMPONENT::GetBoundingBox( int aUnit, int aConvert ) const } -EDA_RECT LIB_COMPONENT::GetBodyBoundingBox( int aUnit, int aConvert ) const +EDA_RECT LIB_PART::GetBodyBoundingBox( int aUnit, int aConvert ) const { EDA_RECT bBox( wxPoint( 0, 0 ), wxSize( 0, 0 ) ); @@ -1075,7 +1090,7 @@ EDA_RECT LIB_COMPONENT::GetBodyBoundingBox( int aUnit, int aConvert ) const } -void LIB_COMPONENT::deleteAllFields() +void LIB_PART::deleteAllFields() { LIB_ITEMS::iterator it; @@ -1093,7 +1108,7 @@ void LIB_COMPONENT::deleteAllFields() } -void LIB_COMPONENT::SetFields( const std::vector & aFields ) +void LIB_PART::SetFields( const std::vector & aFields ) { deleteAllFields(); @@ -1111,7 +1126,7 @@ void LIB_COMPONENT::SetFields( const std::vector & aFields ) } -void LIB_COMPONENT::GetFields( LIB_FIELDS& aList ) +void LIB_PART::GetFields( LIB_FIELDS& aList ) { LIB_FIELD* field; @@ -1146,7 +1161,7 @@ void LIB_COMPONENT::GetFields( LIB_FIELDS& aList ) } -LIB_FIELD* LIB_COMPONENT::GetField( int aId ) +LIB_FIELD* LIB_PART::GetField( int aId ) { BOOST_FOREACH( LIB_ITEM& item, drawings ) { @@ -1163,7 +1178,7 @@ LIB_FIELD* LIB_COMPONENT::GetField( int aId ) } -LIB_FIELD* LIB_COMPONENT::FindField( const wxString& aFieldName ) +LIB_FIELD* LIB_PART::FindField( const wxString& aFieldName ) { BOOST_FOREACH( LIB_ITEM& item, drawings ) { @@ -1180,7 +1195,7 @@ LIB_FIELD* LIB_COMPONENT::FindField( const wxString& aFieldName ) } -LIB_FIELD& LIB_COMPONENT::GetValueField() +LIB_FIELD& LIB_PART::GetValueField() { LIB_FIELD* field = GetField( VALUE ); wxASSERT( field != NULL ); @@ -1188,7 +1203,7 @@ LIB_FIELD& LIB_COMPONENT::GetValueField() } -LIB_FIELD& LIB_COMPONENT::GetReferenceField() +LIB_FIELD& LIB_PART::GetReferenceField() { LIB_FIELD* field = GetField( REFERENCE ); wxASSERT( field != NULL ); @@ -1196,7 +1211,7 @@ LIB_FIELD& LIB_COMPONENT::GetReferenceField() } -bool LIB_COMPONENT::SaveDateAndTime( OUTPUTFORMATTER& aFormatter ) +bool LIB_PART::SaveDateAndTime( OUTPUTFORMATTER& aFormatter ) { int year, mon, day, hour, min, sec; @@ -1216,7 +1231,7 @@ bool LIB_COMPONENT::SaveDateAndTime( OUTPUTFORMATTER& aFormatter ) } -bool LIB_COMPONENT::LoadDateAndTime( char* aLine ) +bool LIB_PART::LoadDateAndTime( char* aLine ) { int year, mon, day, hour, min, sec; @@ -1235,7 +1250,7 @@ bool LIB_COMPONENT::LoadDateAndTime( char* aLine ) } -void LIB_COMPONENT::SetOffset( const wxPoint& aOffset ) +void LIB_PART::SetOffset( const wxPoint& aOffset ) { BOOST_FOREACH( LIB_ITEM& item, drawings ) { @@ -1244,13 +1259,13 @@ void LIB_COMPONENT::SetOffset( const wxPoint& aOffset ) } -void LIB_COMPONENT::RemoveDuplicateDrawItems() +void LIB_PART::RemoveDuplicateDrawItems() { drawings.unique(); } -bool LIB_COMPONENT::HasConversion() const +bool LIB_PART::HasConversion() const { for( unsigned ii = 0; ii < drawings.size(); ii++ ) { @@ -1263,7 +1278,7 @@ bool LIB_COMPONENT::HasConversion() const } -void LIB_COMPONENT::ClearStatus() +void LIB_PART::ClearStatus() { BOOST_FOREACH( LIB_ITEM& item, drawings ) { @@ -1272,7 +1287,7 @@ void LIB_COMPONENT::ClearStatus() } -int LIB_COMPONENT::SelectItems( EDA_RECT& aRect, int aUnit, int aConvert, bool aEditPinByPin ) +int LIB_PART::SelectItems( EDA_RECT& aRect, int aUnit, int aConvert, bool aEditPinByPin ) { int itemCount = 0; @@ -1303,7 +1318,7 @@ int LIB_COMPONENT::SelectItems( EDA_RECT& aRect, int aUnit, int aConvert, bool a } -void LIB_COMPONENT::MoveSelectedItems( const wxPoint& aOffset ) +void LIB_PART::MoveSelectedItems( const wxPoint& aOffset ) { BOOST_FOREACH( LIB_ITEM& item, drawings ) { @@ -1318,7 +1333,7 @@ void LIB_COMPONENT::MoveSelectedItems( const wxPoint& aOffset ) } -void LIB_COMPONENT::ClearSelectedItems() +void LIB_PART::ClearSelectedItems() { BOOST_FOREACH( LIB_ITEM& item, drawings ) { @@ -1327,7 +1342,7 @@ void LIB_COMPONENT::ClearSelectedItems() } -void LIB_COMPONENT::DeleteSelectedItems() +void LIB_PART::DeleteSelectedItems() { LIB_ITEMS::iterator item = drawings.begin(); @@ -1357,7 +1372,7 @@ void LIB_COMPONENT::DeleteSelectedItems() } -void LIB_COMPONENT::CopySelectedItems( const wxPoint& aOffset ) +void LIB_PART::CopySelectedItems( const wxPoint& aOffset ) { /* *do not* use iterators here, because new items * are added to drawings that is a boost::ptr_vector. @@ -1390,7 +1405,7 @@ void LIB_COMPONENT::CopySelectedItems( const wxPoint& aOffset ) -void LIB_COMPONENT::MirrorSelectedItemsH( const wxPoint& aCenter ) +void LIB_PART::MirrorSelectedItemsH( const wxPoint& aCenter ) { BOOST_FOREACH( LIB_ITEM& item, drawings ) { @@ -1404,7 +1419,7 @@ void LIB_COMPONENT::MirrorSelectedItemsH( const wxPoint& aCenter ) drawings.sort(); } -void LIB_COMPONENT::MirrorSelectedItemsV( const wxPoint& aCenter ) +void LIB_PART::MirrorSelectedItemsV( const wxPoint& aCenter ) { BOOST_FOREACH( LIB_ITEM& item, drawings ) { @@ -1418,7 +1433,7 @@ void LIB_COMPONENT::MirrorSelectedItemsV( const wxPoint& aCenter ) drawings.sort(); } -void LIB_COMPONENT::RotateSelectedItems( const wxPoint& aCenter ) +void LIB_PART::RotateSelectedItems( const wxPoint& aCenter ) { BOOST_FOREACH( LIB_ITEM& item, drawings ) { @@ -1434,7 +1449,7 @@ void LIB_COMPONENT::RotateSelectedItems( const wxPoint& aCenter ) -LIB_ITEM* LIB_COMPONENT::LocateDrawItem( int aUnit, int aConvert, +LIB_ITEM* LIB_PART::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType, const wxPoint& aPoint ) { BOOST_FOREACH( LIB_ITEM& item, drawings ) @@ -1452,7 +1467,7 @@ LIB_ITEM* LIB_COMPONENT::LocateDrawItem( int aUnit, int aConvert, } -LIB_ITEM* LIB_COMPONENT::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType, +LIB_ITEM* LIB_PART::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType, const wxPoint& aPoint, const TRANSFORM& aTransform ) { /* we use LocateDrawItem( int aUnit, int convert, KICAD_T type, const @@ -1473,7 +1488,7 @@ LIB_ITEM* LIB_COMPONENT::LocateDrawItem( int aUnit, int aConvert, KICAD_T aType, } -void LIB_COMPONENT::SetPartCount( int aCount ) +void LIB_PART::SetUnitCount( int aCount ) { if( m_unitCount == aCount ) return; @@ -1520,7 +1535,7 @@ void LIB_COMPONENT::SetPartCount( int aCount ) } -void LIB_COMPONENT::SetConversion( bool aSetConvert ) +void LIB_PART::SetConversion( bool aSetConvert ) { if( aSetConvert == HasConversion() ) return; @@ -1559,7 +1574,7 @@ void LIB_COMPONENT::SetConversion( bool aSetConvert ) } -wxArrayString LIB_COMPONENT::GetAliasNames( bool aIncludeRoot ) const +wxArrayString LIB_PART::GetAliasNames( bool aIncludeRoot ) const { wxArrayString names; @@ -1577,14 +1592,14 @@ wxArrayString LIB_COMPONENT::GetAliasNames( bool aIncludeRoot ) const } -bool LIB_COMPONENT::HasAlias( const wxString& aName ) const +bool LIB_PART::HasAlias( const wxString& aName ) const { wxCHECK2_MSG( !aName.IsEmpty(), return false, wxT( "Cannot get alias with an empty name, bad programmer." ) ); for( size_t i = 0; i < m_aliases.size(); i++ ) { - if( aName.CmpNoCase( m_aliases[i]->GetName() ) == 0 ) + if( Cmp_KEEPCASE( aName, m_aliases[i]->GetName() ) == 0 ) return true; } @@ -1592,10 +1607,10 @@ bool LIB_COMPONENT::HasAlias( const wxString& aName ) const } -void LIB_COMPONENT::SetAliases( const wxArrayString& aAliasList ) +void LIB_PART::SetAliases( const wxArrayString& aAliasList ) { - wxCHECK_RET( m_library == NULL, - wxT( "Component aliases cannot be changed when they are owned by a library." ) ); + wxCHECK_RET( !m_library, + wxT( "Part aliases cannot be changed when they are owned by a library." ) ); if( aAliasList == GetAliasNames() ) return; @@ -1624,17 +1639,19 @@ void LIB_COMPONENT::SetAliases( const wxArrayString& aAliasList ) } -void LIB_COMPONENT::RemoveAlias( const wxString& aName ) +#if 0 // this version looked suspect to me, it did not rename a deleted root + +void LIB_PART::RemoveAlias( const wxString& aName ) { wxCHECK_RET( m_library == NULL, - wxT( "Component aliases cannot be changed when they are owned by a library." ) ); + wxT( "Part aliases cannot be changed when they are owned by a library." ) ); wxCHECK_RET( !aName.IsEmpty(), wxT( "Cannot get alias with an empty name." ) ); LIB_ALIASES::iterator it; for( it = m_aliases.begin(); it < m_aliases.end(); it++ ) { - if( aName.CmpNoCase( (*it)->GetName() ) == 0 ) + if( Cmp_KEEPCASE( aName, (*it)->GetName() ) == 0 ) { m_aliases.erase( it ); break; @@ -1642,39 +1659,53 @@ void LIB_COMPONENT::RemoveAlias( const wxString& aName ) } } - -LIB_ALIAS* LIB_COMPONENT::RemoveAlias( LIB_ALIAS* aAlias ) +#else +void LIB_PART::RemoveAlias( const wxString& aName ) { - wxCHECK_MSG( aAlias != NULL, NULL, wxT( "Cannot remove alias by NULL pointer." ) ); + LIB_ALIAS* a = GetAlias( aName ); + + if( a ) + RemoveAlias( a ); +} +#endif + + +LIB_ALIAS* LIB_PART::RemoveAlias( LIB_ALIAS* aAlias ) +{ + wxCHECK_MSG( aAlias, NULL, wxT( "Cannot remove alias by NULL pointer." ) ); LIB_ALIAS* nextAlias = NULL; + LIB_ALIASES::iterator it = find( m_aliases.begin(), m_aliases.end(), aAlias ); if( it != m_aliases.end() ) { bool rename = aAlias->IsRoot(); + DBG( printf( "%s: part:'%s' alias:'%s'\n", __func__, + TO_UTF8( m_name ), + TO_UTF8( aAlias->GetName() ) + );) + it = m_aliases.erase( it ); - delete aAlias; if( !m_aliases.empty() ) { if( it == m_aliases.end() ) it = m_aliases.begin(); - nextAlias = (*it); + nextAlias = *it; if( rename ) SetName( nextAlias->GetName() ); } - } return nextAlias; } -void LIB_COMPONENT::RemoveAllAliases() +void LIB_PART::RemoveAllAliases() { // Remove all of the aliases except the root alias. while( m_aliases.size() > 1 ) @@ -1682,14 +1713,14 @@ void LIB_COMPONENT::RemoveAllAliases() } -LIB_ALIAS* LIB_COMPONENT::GetAlias( const wxString& aName ) +LIB_ALIAS* LIB_PART::GetAlias( const wxString& aName ) { wxCHECK2_MSG( !aName.IsEmpty(), return NULL, wxT( "Cannot get alias with an empty name. Bad programmer!" ) ); for( size_t i = 0; i < m_aliases.size(); i++ ) { - if( aName.CmpNoCase( m_aliases[i]->GetName() ) == 0 ) + if( Cmp_KEEPCASE( aName, m_aliases[i]->GetName() ) == 0 ) return m_aliases[i]; } @@ -1697,7 +1728,7 @@ LIB_ALIAS* LIB_COMPONENT::GetAlias( const wxString& aName ) } -LIB_ALIAS* LIB_COMPONENT::GetAlias( size_t aIndex ) +LIB_ALIAS* LIB_PART::GetAlias( size_t aIndex ) { wxCHECK2_MSG( aIndex < m_aliases.size(), return NULL, wxT( "Illegal alias list index, bad programmer." ) ); @@ -1706,10 +1737,10 @@ LIB_ALIAS* LIB_COMPONENT::GetAlias( size_t aIndex ) } -void LIB_COMPONENT::AddAlias( const wxString& aName ) +void LIB_PART::AddAlias( const wxString& aName ) { wxCHECK_RET( !HasAlias( aName ), - wxT( "Component <" ) + GetName() + wxT( "> already has an alias <" ) + + wxT( "Part <" ) + GetName() + wxT( "> already has an alias <" ) + aName + wxT( ">. Bad programmer." ) ); m_aliases.push_back( new LIB_ALIAS( aName, this ) ); @@ -1725,7 +1756,7 @@ void LIB_COMPONENT::AddAlias( const wxString& aName ) * @param aSep = the separator symbol (0 (no separator) or '.' , '-' and '_') * @param aFirstId = the Id of the first part ('A' or '1') */ -void LIB_COMPONENT::SetSubpartIdNotation( int aSep, int aFirstId ) +void LIB_PART::SetSubpartIdNotation( int aSep, int aFirstId ) { m_subpartFirstId = 'A'; m_subpartIdSeparator = 0; diff --git a/eeschema/class_libentry.h b/eeschema/class_libentry.h index a730d9d19b..bf9abd439a 100644 --- a/eeschema/class_libentry.h +++ b/eeschema/class_libentry.h @@ -33,15 +33,13 @@ #include #include #include - -#include - +#include class LINE_READER; class OUTPUTFORMATTER; -class CMP_LIBRARY; +class PART_LIB; class LIB_ALIAS; -class LIB_COMPONENT; +class LIB_PART; class LIB_FIELD; @@ -58,65 +56,50 @@ inline int Cmp_KEEPCASE( const wxString& aString1, const wxString& aString2 ) } -/** - * LIB_ALIAS map sorting. - */ -struct AliasMapSort -{ - bool operator() ( const wxString& aItem1, const wxString& aItem2 ) const - { - return Cmp_KEEPCASE( aItem1, aItem2 ) < 0; - } -}; +typedef std::vector LIB_ALIASES; +typedef boost::shared_ptr PART_SPTR; ///< shared pointer to LIB_PART +typedef boost::weak_ptr PART_REF; ///< weak pointer to LIB_PART -/** - * Alias map used by component library object. - */ -typedef std::map< wxString, LIB_ALIAS*, AliasMapSort > LIB_ALIAS_MAP; - -typedef std::vector< LIB_ALIAS* > LIB_ALIASES; - /* values for member .m_options */ enum LibrEntryOptions { - ENTRY_NORMAL, // Libentry is a standard component (real or alias) + ENTRY_NORMAL, // Libentry is a standard part (real or alias) ENTRY_POWER // Libentry is a power symbol }; /** - * Component library alias object definition. + * Part library alias object definition. * - * Component aliases are not really components. An alias uses the component definition + * Part aliases are not really parts. An alias uses the part definition * (graphic, pins...) but has its own name, keywords and documentation. Therefore, when - * the component is modified, alias of this component are modified. This is a simple - * method to create components that have the same physical layout with different names + * the part is modified, alias of this part are modified. This is a simple + * method to create parts that have the same physical layout with different names * such as 74LS00, 74HC00 ... and many op amps. */ class LIB_ALIAS : public EDA_ITEM { /** - * The actual component of the alias. + * Actual LIB_PART referenced by [multiple] aliases. * - * @note - Do not delete the root component. The root component is actually shared by - * all of the aliases associated with it. The component pointer will be delete - * in the destructor of the last alias that shares this component is deleted. - * Deleting the root component will likely cause Eeschema to crash. + * @note - Do not delete the shared part. The shared part is shared by + * all of the aliases associated with it. A shared LIB_PART will + * be deleted when all LIB_ALIASes pointing to it are deleted. */ - LIB_COMPONENT* root; + LIB_PART* shared; - friend class LIB_COMPONENT; + friend class LIB_PART; protected: - wxString name; - wxString description; ///< documentation for info - wxString keyWords; ///< keyword list (used for search for components by keyword) - wxString docFileName; ///< Associate doc file name + wxString name; + wxString description; ///< documentation for info + wxString keyWords; ///< keyword list (used for search for parts by keyword) + wxString docFileName; ///< Associate doc file name public: - LIB_ALIAS( const wxString& aName, LIB_COMPONENT* aRootComponent ); - LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_COMPONENT* aRootComponent = NULL ); + LIB_ALIAS( const wxString& aName, LIB_PART* aRootComponent ); + LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_PART* aRootComponent = NULL ); virtual ~LIB_ALIAS(); @@ -126,22 +109,26 @@ public: } /** - * Get the alias root component. + * Function GetPart + * gets the shared LIB_PART. + * + * @return LIB_PART* - the LIB_PART shared by + * this LIB_ALIAS with possibly other LIB_ALIASes. */ - LIB_COMPONENT* GetComponent() const + LIB_PART* GetPart() const { - return root; + return shared; } - virtual wxString GetLibraryName(); + const wxString GetLibraryName(); bool IsRoot() const; - CMP_LIBRARY* GetLibrary(); + PART_LIB* GetLib(); - virtual const wxString& GetName() const { return name; } + const wxString& GetName() const { return name; } - virtual void SetName( const wxString& aName ) { name = aName; } + void SetName( const wxString& aName ) { name = aName; } void SetDescription( const wxString& aDescription ) { @@ -174,7 +161,7 @@ public: bool SaveDoc( OUTPUTFORMATTER& aFormatter ); /** - * Case insensitive comparison of the component entry name. + * KEEPCASE sensitive comparison of the part entry name. */ bool operator==( const wxChar* aName ) const; bool operator!=( const wxChar* aName ) const @@ -195,66 +182,75 @@ extern int LibraryEntryCompare( const LIB_ALIAS* aItem1, const LIB_ALIAS* aItem2 /** - * Class LIB_COMPONENT - * defines a library component object. + * Class LIB_PART + * defines a library part object. * - * A library component object is typically saved and loaded in a component library file (.lib). - * Library components are different from schematic components. + * A library part object is typically saved and loaded in a part library file (.lib). + * Library parts are different from schematic components. */ -class LIB_COMPONENT : public EDA_ITEM +class LIB_PART : public EDA_ITEM { - friend class CMP_LIBRARY; + friend class PART_LIB; friend class LIB_ALIAS; - wxString m_name; - int m_pinNameOffset; ///< The offset in mils to draw the pin name. Set to 0 - ///< to draw the pin name above the pin. - bool m_unitsLocked; ///< True if component has multiple parts and changing - ///< one part does not automatically change another part. - bool m_showPinNames; ///< Determines if component pin names are visible. - bool m_showPinNumbers; ///< Determines if component pin numbers are visible. - long m_dateModified; ///< Date the component was last modified. - LibrEntryOptions m_options; ///< Special component features such as POWER or NORMAL.) - int m_unitCount; ///< Number of units (parts) per package. - LIB_ITEMS drawings; ///< How to draw this part. - wxArrayString m_FootprintList; /**< List of suitable footprint names for the - component (wild card names accepted). */ - LIB_ALIASES m_aliases; ///< List of alias object pointers associated with the - ///< component. - CMP_LIBRARY* m_library; ///< Library the component belongs to if any. + PART_SPTR m_me; ///< http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared + wxString m_name; + int m_pinNameOffset; ///< The offset in mils to draw the pin name. Set to 0 + ///< to draw the pin name above the pin. + bool m_unitsLocked; ///< True if part has multiple units and changing + ///< one unit does not automatically change another unit. + bool m_showPinNames; ///< Determines if part pin names are visible. + bool m_showPinNumbers; ///< Determines if part pin numbers are visible. + long m_dateModified; ///< Date the part was last modified. + LibrEntryOptions m_options; ///< Special part features such as POWER or NORMAL.) + int m_unitCount; ///< Number of units (parts) per package. + LIB_ITEMS drawings; ///< How to draw this part. + wxArrayString m_FootprintList; /**< List of suitable footprint names for the + part (wild card names accepted). */ + LIB_ALIASES m_aliases; ///< List of alias object pointers associated with the + ///< part. + PART_LIB* m_library; ///< Library the part belongs to if any. - static int m_subpartIdSeparator; ///< the separator char between - ///< the subpart id and the reference - ///< like U1A ( m_subpartIdSeparator = 0 ) or U1.A or U1-A - static int m_subpartFirstId; ///< the ascii char value to calculate the subpart symbol id - ///< from the part number: only 'A', 'a' or '1' can be used, - ///< other values have no sense. + static int m_subpartIdSeparator; ///< the separator char between + ///< the subpart id and the reference + ///< like U1A ( m_subpartIdSeparator = 0 ) or U1.A or U1-A + static int m_subpartFirstId; ///< the ascii char value to calculate the subpart symbol id + ///< from the part number: only 'A', 'a' or '1' can be used, + ///< other values have no sense. private: void deleteAllFields(); -public: - LIB_COMPONENT( const wxString& aName, CMP_LIBRARY* aLibrary = NULL ); - LIB_COMPONENT( LIB_COMPONENT& aComponent, CMP_LIBRARY* aLibrary = NULL ); + // LIB_PART() { } // not legal - virtual ~LIB_COMPONENT(); +public: + + LIB_PART( const wxString& aName, PART_LIB* aLibrary = NULL ); + LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary = NULL ); + + virtual ~LIB_PART(); + + PART_SPTR SharedPtr() + { + // clone a shared pointer + return m_me; + } virtual wxString GetClass() const { - return wxT( "LIB_COMPONENT" ); + return wxT( "LIB_PART" ); } - virtual void SetName( const wxString& aName ); - wxString GetName() { return m_name; } + const wxString& GetName() { return m_name; } - wxString GetLibraryName(); + const wxString GetLibraryName(); - CMP_LIBRARY* GetLibrary() { return m_library; } + PART_LIB* GetLib() { return m_library; } wxArrayString GetAliasNames( bool aIncludeRoot = true ) const; - size_t GetAliasCount() const { return m_aliases.size(); } + size_t GetAliasCount() const { return m_aliases.size(); } LIB_ALIAS* GetAlias( size_t aIndex ); @@ -263,7 +259,7 @@ public: /** * Function AddAlias * - * Add an alias \a aName to the component. + * Add an alias \a aName to the part. * * Duplicate alias names are not added to the alias list. Debug builds will raise an * assertion. Release builds will fail silently. @@ -273,7 +269,7 @@ public: void AddAlias( const wxString& aName ); /** - * Test if alias \a aName is in component alias list. + * Test if alias \a aName is in part alias list. * * Alias name comparisons are case insensitive. * @@ -285,7 +281,6 @@ public: void SetAliases( const wxArrayString& aAliasList ); void RemoveAlias( const wxString& aName ); - LIB_ALIAS* RemoveAlias( LIB_ALIAS* aAlias ); void RemoveAllAliases(); @@ -294,7 +289,7 @@ public: /** * Function GetBoundingBox - * @return the component boundary box ( in user coordinates ) + * @return the part bounding box ( in user coordinates ) * @param aUnit = unit selection = 0, or 1..n * @param aConvert = 0, 1 or 2 * If aUnit == 0, unit is not used @@ -305,7 +300,7 @@ public: /** * Function GetBodyBoundingBox - * @return the component boundary box ( in user coordinates ) without fields + * @return the part bounding box ( in user coordinates ) without fields * @param aUnit = unit selection = 0, or 1..n * @param aConvert = 0, 1 or 2 * If aUnit == 0, unit is not used @@ -316,7 +311,7 @@ public: /** * Function SaveDateAndTime - * write the date and time of component to \a aFile in the format: + * write the date and time of part to \a aFile in the format: * "Ti yy/mm/jj hh:mm:ss" * * @param aFormatter A reference to an #OUTPUTFORMATTER object containing the @@ -329,7 +324,7 @@ public: /** * Function Save - * writes the data structures out to \a aFormatter in the component library "*.lib" + * writes the data structures out to \a aFormatter in the part library "*.lib" * format. * * @param aFormatter A reference to an OUTPUTFORMATTER to write to. @@ -338,7 +333,7 @@ public: bool Save( OUTPUTFORMATTER& aFormatter ); /** - * Load component definition from \a aReader. + * Load part definition from \a aReader. * * @param aReader A LINE_READER object to load file from. * @param aErrorMsg - Description of error on load failure. @@ -350,20 +345,20 @@ public: bool LoadAliases( char* aLine, wxString& aErrorMsg ); bool LoadFootprints( LINE_READER& aReader, wxString& aErrorMsg ); - bool IsPower() { return m_options == ENTRY_POWER; } - bool IsNormal() { return m_options == ENTRY_NORMAL; } + bool IsPower() { return m_options == ENTRY_POWER; } + bool IsNormal() { return m_options == ENTRY_NORMAL; } - void SetPower() { m_options = ENTRY_POWER; } - void SetNormal() { m_options = ENTRY_NORMAL; } + void SetPower() { m_options = ENTRY_POWER; } + void SetNormal() { m_options = ENTRY_NORMAL; } void LockUnits( bool aLockUnits ) { m_unitsLocked = aLockUnits; } - bool UnitsLocked() { return m_unitsLocked; } + bool UnitsLocked() { return m_unitsLocked; } /** * Function SetFields - * overwrites all the existing in this component with fields supplied + * overwrites all the existing in this part with fields supplied * in \a aFieldsList. The only known caller of this function is the - * library component field editor, and it establishes needed behavior. + * library part field editor, and it establishes needed behavior. * ` * @param aFieldsList is a set of fields to import, removing all previous fields. */ @@ -371,8 +366,8 @@ public: /** * Function GetFields - * returns a list of fields withing this component. The only known caller of - * this function is the library component field editor, and it establishes + * returns a list of fields withing this part. The only known caller of + * this function is the library part field editor, and it establishes * needed behavior. * * @param aList - List to add fields to @@ -381,7 +376,7 @@ public: /** * Function FindField - * finds a field within this component matching \a aFieldName and returns + * finds a field within this part matching \a aFieldName and returns * it or NULL if not found. */ LIB_FIELD* FindField( const wxString& aFieldName ); @@ -401,21 +396,21 @@ public: LIB_FIELD& GetReferenceField(); /** - * Draw component. + * Draw part. * * @param aPanel - Window to draw on. Can be NULL if not available. * @param aDc - Device context to draw on. - * @param aOffset - Position to component. - * @param aMulti - Component unit if multiple parts per component. + * @param aOffset - Position of part. + * @param aMulti - unit if multiple units per part. * @param aConvert - Component conversion (DeMorgan) if available. * @param aDrawMode - Device context drawing mode, see wxDC. - * @param aColor - Color to draw component. + * @param aColor - Color to draw part. * @param aTransform - Coordinate adjustment settings. * @param aShowPinText - Show pin text if true. * @param aDrawFields - Draw field text if true otherwise just draw * body items (useful to draw a body in schematic, * because fields of schematic components replace - * the lib component fields). + * the lib part fields). * @param aOnlySelected - Draws only the body items that are selected. * Used for block move redraws. */ @@ -427,7 +422,7 @@ public: bool aOnlySelected = false ); /** - * Plot lib component to plotter. + * Plot lib part to plotter. * Lib Fields not are plotted here, because this plot function * is used to plot schematic items, which have they own fields * @@ -441,8 +436,8 @@ public: const TRANSFORM& aTransform ); /** - * Plot Lib Fields only of the component to plotter. - * is used to plot the full lib component, outside the schematic + * Plot Lib Fields only of the part to plotter. + * is used to plot the full lib part, outside the schematic * * @param aPlotter - Plotter object to plot to. * @param aUnit - Component part to plot. @@ -456,7 +451,7 @@ public: /** * Add a new draw \a aItem to the draw object list. * - * @param aItem - New draw object to add to component. + * @param aItem - New draw object to add to part. */ void AddDrawItem( LIB_ITEM* aItem ); @@ -498,15 +493,15 @@ public: /** * Return a list of pin object pointers from the draw item list. * - * Note pin objects are owned by the draw list of the component. + * Note pin objects are owned by the draw list of the part. * Deleting any of the objects will leave list in a unstable state * and will likely segfault when the list is destroyed. * * @param aList - Pin list to place pin object pointers into. * @param aUnit - Unit number of pin to add to list. Set to 0 to - * get pins from any component part. + * get pins from any part unit. * @param aConvert - Convert number of pin to add to list. Set to 0 to - * get pins from any convert of component. + * get pins from any convert of part. */ void GetPins( LIB_PINS& aList, int aUnit = 0, int aConvert = 0 ); @@ -514,7 +509,7 @@ public: * Return pin object with the requested pin \a aNumber. * * @param aNumber - Number of the pin to find. - * @param aUnit - Unit of the component to find. Set to 0 if a specific + * @param aUnit - Unit of the part to find. Set to 0 if a specific * unit number is not required. * @param aConvert - Alternate body style filter (DeMorgan). Set to 0 if * no alternate body style is required. @@ -523,7 +518,7 @@ public: LIB_PIN* GetPin( const wxString& aNumber, int aUnit = 0, int aConvert = 0 ); /** - * Move the component \a aOffset. + * Move the part \a aOffset. * * @param aOffset - Offset displacement. */ @@ -535,19 +530,19 @@ public: void RemoveDuplicateDrawItems(); /** - * Test if component has more than one body conversion type (DeMorgan). + * Test if part has more than one body conversion type (DeMorgan). * - * @return True if component has more than one conversion. + * @return True if part has more than one conversion. */ bool HasConversion() const; /** - * Clears the status flag all draw objects in this component. + * Clears the status flag all draw objects in this part. */ void ClearStatus(); /** - * Checks all draw objects of component to see if they are with block. + * Checks all draw objects of part to see if they are with block. * * Use this method to mark draw objects as selected during block * functions. @@ -571,7 +566,7 @@ public: * Deletes the select draw items marked by a block select. * * The name and reference field will not be deleted. They are the - * minimum drawing items required for any component. Their properties + * minimum drawing items required for any part. Their properties * can be changed but the cannot be removed. */ void DeleteSelectedItems(); @@ -584,7 +579,7 @@ public: /** * Make a copy of the selected draw items marked by a block select. * - * Fields are not copied. Only component body items are copied. + * Fields are not copied. Only part body items are copied. * Copying fields would result in duplicate fields which does not * make sense in this context. */ @@ -643,29 +638,29 @@ public: LIB_ITEMS& GetDrawItemList() { return drawings; } /** - * Set the part per package count. + * Set the units per part count. * * If the count is greater than the current count, then the all of the * current draw items are duplicated for each additional part. If the - * count is less than the current count, all draw objects for parts - * greater that count are removed from the component. + * count is less than the current count, all draw objects for units + * greater that count are removed from the part. * - * @param count - Number of parts per package. + * @param count - Number of units per package. */ - void SetPartCount( int count ); + void SetUnitCount( int count ); - int GetPartCount() const { return m_unitCount; } + int GetUnitCount() const { return m_unitCount; } /** * Function IsMulti - * @return true if the component has multiple parts per package. + * @return true if the part has multiple units per part. * When happens, the reference has a sub reference ti identify part */ bool IsMulti() const { return m_unitCount > 1; } /** * Function SubReference - * @return the sub reference for component having multiple parts per package. + * @return the sub reference for part having multiple units per part. * The sub reference identify the part (or unit) * @param aUnit = the part identifier ( 1 to max count) * @param aAddSeparator = true (default) to prpebd the sub ref @@ -700,15 +695,15 @@ public: static void SetSubpartIdNotation( int aSep, int aFirstId ); /** - * Set or clear the alternate body style (DeMorgan) for the component. + * Set or clear the alternate body style (DeMorgan) for the part. * - * If the component already has an alternate body style set and a + * If the part already has an alternate body style set and a * asConvert if false, all of the existing draw items for the alternate * body style are remove. If the alternate body style is not set and * asConvert is true, than the base draw items are duplicated and - * added to the component. + * added to the part. * - * @param aSetConvert - Set or clear the component alternate body style. + * @param aSetConvert - Set or clear the part alternate body style. */ void SetConversion( bool aSetConvert ); @@ -726,7 +721,7 @@ public: /** * Set or clear the pin name visibility flag. * - * @param aShow - True to make the component pin names visible. + * @param aShow - True to make the part pin names visible. */ void SetShowPinNames( bool aShow ) { m_showPinNames = aShow; } @@ -735,13 +730,13 @@ public: /** * Set or clear the pin number visibility flag. * - * @param aShow - True to make the component pin numbers visible. + * @param aShow - True to make the part pin numbers visible. */ void SetShowPinNumbers( bool aShow ) { m_showPinNumbers = aShow; } bool ShowPinNumbers() { return m_showPinNumbers; } - bool operator==( const LIB_COMPONENT* aComponent ) const { return this == aComponent; } + bool operator==( const LIB_PART* aPart ) const { return this == aPart; } #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override diff --git a/eeschema/class_library.cpp b/eeschema/class_library.cpp index 39443a8e3f..2e93ade48a 100644 --- a/eeschema/class_library.cpp +++ b/eeschema/class_library.cpp @@ -28,6 +28,7 @@ */ #include +#include #include #include #include @@ -35,6 +36,9 @@ #include #include #include +#include +#include +//#include #include #include @@ -44,27 +48,30 @@ #include #include -static const wxString duplicate_name_msg = - _( "Library '%s' has duplicate entry name '%s'.\n" - "This may cause some unexpected behavior when loading components into a schematic." ); +#define duplicate_name_msg \ + _( "Library '%s' has duplicate entry name '%s'.\n" \ + "This may cause some unexpected behavior when loading components into a schematic." ) -bool operator==( const CMP_LIBRARY& aLibrary, const wxString& aName ) +bool operator==( const PART_LIB& aLibrary, const wxString& aName ) { // See our header class_libentry.h for function Cmp_KEEPCASE(). return Cmp_KEEPCASE( aLibrary.GetName(), aName ) == 0; } -bool operator!=( const CMP_LIBRARY& aLibrary, const wxString& aName ) +bool operator!=( const PART_LIB& aLibrary, const wxString& aName ) { return !( aLibrary == aName ); } -bool operator<( const CMP_LIBRARY& aItem1, const CMP_LIBRARY& aItem2 ) +wxArrayString PART_LIBS::s_libraryListSortOrder; + + +bool operator<( const PART_LIB& aItem1, const PART_LIB& aItem2 ) { - /* The cache library always is sorted to the end of the library list. */ + // The cache library always is sorted to the end of the library list. if( aItem2.IsCache() ) return true; @@ -72,11 +79,11 @@ bool operator<( const CMP_LIBRARY& aItem1, const CMP_LIBRARY& aItem2 ) return false; // If the sort order array isn't set, then sort alphabetically except. - if( CMP_LIBRARY::GetSortOrder().IsEmpty() ) + if( PART_LIBS::GetSortOrder().IsEmpty() ) return Cmp_KEEPCASE( aItem1.GetName(), aItem2.GetName() ) < 0; - int i1 = CMP_LIBRARY::GetSortOrder().Index( aItem1.GetName(), false ); - int i2 = CMP_LIBRARY::GetSortOrder().Index( aItem2.GetName(), false ); + int i1 = PART_LIBS::GetSortOrder().Index( aItem1.GetName(), false ); + int i2 = PART_LIBS::GetSortOrder().Index( aItem2.GetName(), false ); if( i1 == wxNOT_FOUND && i2 == wxNOT_FOUND ) return true; @@ -91,7 +98,10 @@ bool operator<( const CMP_LIBRARY& aItem1, const CMP_LIBRARY& aItem2 ) } -CMP_LIBRARY::CMP_LIBRARY( int aType, const wxFileName& aFileName ) +PART_LIB::PART_LIB( int aType, const wxString& aFileName ) : + // start @ != 0 so each additional library added + // is immediately detectable, zero would not be. + m_mod_hash( PART_LIBS::s_modify_generation ) { type = aType; isModified = false; @@ -99,33 +109,21 @@ CMP_LIBRARY::CMP_LIBRARY( int aType, const wxFileName& aFileName ) isCache = false; timeStamp = wxDateTime::Now(); - if( aFileName.IsOk() ) - fileName = aFileName; - else - fileName = wxFileName( wxT( "unnamed.lib" ) ); + fileName = aFileName; + + if( !fileName.IsOk() ) + fileName = wxT( "unnamed.lib" ); } -CMP_LIBRARY::~CMP_LIBRARY() +PART_LIB::~PART_LIB() { - for( LIB_ALIAS_MAP::iterator it=aliases.begin(); it!=aliases.end(); it++ ) - { - LIB_ALIAS* alias = (*it).second; - LIB_COMPONENT* component = alias->GetComponent(); - - alias = component->RemoveAlias( alias ); - - if( alias == NULL ) - delete component; - } } -void CMP_LIBRARY::GetEntryNames( wxArrayString& aNames, bool aSort, bool aMakeUpperCase ) +void PART_LIB::GetEntryNames( wxArrayString& aNames, bool aSort, bool aMakeUpperCase ) { - LIB_ALIAS_MAP::iterator it; - - for( it=aliases.begin(); it!=aliases.end(); it++ ) + for( LIB_ALIAS_MAP::iterator it = m_amap.begin(); it!=m_amap.end(); it++ ) { if( aMakeUpperCase ) { @@ -158,28 +156,28 @@ bool sortFunction( wxArrayString aItem1, wxArrayString aItem2 ) } -void CMP_LIBRARY::SearchEntryNames( std::vector& aNames, +void PART_LIB::SearchEntryNames( std::vector& aNames, const wxString& aNameSearch, const wxString& aKeySearch, bool aSort ) { - LIB_ALIAS_MAP::iterator it; - - for( it = aliases.begin(); it!=aliases.end(); it++ ) + for( LIB_ALIAS_MAP::iterator it = m_amap.begin(); it != m_amap.end(); ++it ) { - if( !aKeySearch.IsEmpty() && KeyWordOk( aKeySearch, (*it).second->GetKeyWords() ) ) + if( !!aKeySearch && KeyWordOk( aKeySearch, it->second->GetKeyWords() ) ) { wxArrayString item; - item.Add( (*it).first ); + + item.Add( it->first ); item.Add( GetLogicalName() ); aNames.push_back( item ); } - if( !aNameSearch.IsEmpty() && WildCompareString( aNameSearch, - (*it).second->GetName(), false ) ) + if( !aNameSearch.IsEmpty() && + WildCompareString( aNameSearch, it->second->GetName(), false ) ) { wxArrayString item; - item.Add( (*it).first ); + + item.Add( it->first ); item.Add( GetLogicalName() ); aNames.push_back( item ); } @@ -190,17 +188,17 @@ void CMP_LIBRARY::SearchEntryNames( std::vector& aNames, } -void CMP_LIBRARY::SearchEntryNames( wxArrayString& aNames, const wxRegEx& aRe, bool aSort ) +void PART_LIB::SearchEntryNames( wxArrayString& aNames, const wxRegEx& aRe, bool aSort ) { if( !aRe.IsValid() ) return; LIB_ALIAS_MAP::iterator it; - for( it = aliases.begin(); it!=aliases.end(); it++ ) + for( it = m_amap.begin(); it!=m_amap.end(); it++ ) { - if( aRe.Matches( (*it).second->GetKeyWords() ) ) - aNames.Add( (*it).first ); + if( aRe.Matches( it->second->GetKeyWords() ) ) + aNames.Add( it->first ); } if( aSort ) @@ -208,16 +206,16 @@ void CMP_LIBRARY::SearchEntryNames( wxArrayString& aNames, const wxRegEx& aRe, b } -bool CMP_LIBRARY::Conflicts( LIB_COMPONENT* aComponent ) +bool PART_LIB::Conflicts( LIB_PART* aPart ) { - wxCHECK_MSG( aComponent != NULL, false, + wxCHECK_MSG( aPart != NULL, false, wxT( "Cannot test NULL component for conflicts in library " ) + GetName() ); - for( size_t i=0; im_aliases.size(); i++ ) + for( size_t i=0; im_aliases.size(); i++ ) { - LIB_ALIAS_MAP::iterator it = aliases.find( aComponent->m_aliases[i]->GetName() ); + LIB_ALIAS_MAP::iterator it = m_amap.find( aPart->m_aliases[i]->GetName() ); - if( it != aliases.end() ) + if( it != m_amap.end() ) return true; } @@ -225,29 +223,28 @@ bool CMP_LIBRARY::Conflicts( LIB_COMPONENT* aComponent ) } -LIB_ALIAS* CMP_LIBRARY::FindEntry( const wxString& aName ) +LIB_ALIAS* PART_LIB::FindEntry( const wxString& aName ) { - LIB_ALIAS_MAP::iterator it = aliases.find( aName ); + LIB_ALIAS_MAP::iterator it = m_amap.find( aName ); - if( it != aliases.end() ) - return (*it).second; + if( it != m_amap.end() ) + return it->second; return NULL; } -LIB_ALIAS* CMP_LIBRARY::GetFirstEntry() +LIB_ALIAS* PART_LIB::GetFirstEntry() { - if( aliases.size() ) - return (*aliases.begin()).second; + if( m_amap.size() ) + return m_amap.begin()->second; else return NULL; } -LIB_COMPONENT* CMP_LIBRARY::FindComponent( const wxString& aName ) +LIB_PART* PART_LIB::FindPart( const wxString& aName ) { - #if 0 && defined(DEBUG) if( !aName.Cmp( wxT( "TI_STELLARIS_BOOSTERPACK" ) ) ) { @@ -256,21 +253,20 @@ LIB_COMPONENT* CMP_LIBRARY::FindComponent( const wxString& aName ) } #endif - LIB_COMPONENT* component = NULL; - LIB_ALIAS* entry = FindEntry( aName ); + if( LIB_ALIAS* alias = FindEntry( aName ) ) + { + return alias->GetPart(); + } - if( entry ) - component = entry->GetComponent(); - - return component; + return NULL; } -bool CMP_LIBRARY::AddAlias( LIB_ALIAS* aAlias ) +bool PART_LIB::AddAlias( LIB_ALIAS* aAlias ) { wxASSERT( aAlias ); -#if 0 && defined(DEBUG) +#if defined(DEBUG) && 0 if( !aAlias->GetName().Cmp( wxT( "TI_STELLARIS_BOOSTERPACK" ) ) ) { int breakhere = 1; @@ -278,173 +274,175 @@ bool CMP_LIBRARY::AddAlias( LIB_ALIAS* aAlias ) } #endif - LIB_ALIAS_MAP::iterator it = aliases.find( aAlias->GetName() ); + LIB_ALIAS_MAP::iterator it = m_amap.find( aAlias->GetName() ); - if( it != aliases.end() ) + if( it != m_amap.end() ) { wxString msg; - msg.Printf( _( "Cannot add duplicate alias <%s> to library <%s>." ), + msg.Printf( _( "Cannot add duplicate alias '%s' to library '%s'." ), GetChars( aAlias->GetName() ), GetChars( fileName.GetName() ) ); return false; } - aliases[ aAlias->GetName() ] = aAlias; + wxString name = aAlias->GetName(); + + m_amap[ name ] = aAlias; isModified = true; + ++m_mod_hash; + return true; } -LIB_COMPONENT* CMP_LIBRARY::AddComponent( LIB_COMPONENT* aComponent ) +bool PART_LIB::AddPart( LIB_PART* aPart ) { - if( !aComponent ) - return NULL; - // Conflict detection: See if already existing aliases exist, // and if yes, ask user for continue or abort // Special case: if the library is the library cache of the project, // old aliases are always removed to avoid conflict, // and user is not prompted ) - if( Conflicts( aComponent ) && !IsCache() ) + if( Conflicts( aPart ) && !IsCache() ) { - wxFAIL_MSG( wxT( "Cannot add component <" ) + aComponent->GetName() + + wxFAIL_MSG( wxT( "Cannot add component <" ) + aPart->GetName() + wxT( "> to library <" ) + GetName() + wxT( "> due to name conflict." ) ); - return NULL; + return false; } - LIB_COMPONENT* newCmp = new LIB_COMPONENT( *aComponent, this ); + // add a clone, not the caller's copy + LIB_PART* my_part = new LIB_PART( *aPart, this ); - for( size_t i = 0; i < newCmp->m_aliases.size(); i++ ) + for( size_t i = 0; i < my_part->m_aliases.size(); i++ ) { - wxString aliasname = newCmp->m_aliases[i]->GetName(); - LIB_ALIAS* alias = FindAlias( aliasname ); + wxString aliasname = my_part->m_aliases[i]->GetName(); - if( alias != NULL ) + if( LIB_ALIAS* alias = FindAlias( aliasname ) ) RemoveEntry( alias ); - aliases[ aliasname ] = newCmp->m_aliases[i]; + m_amap[ aliasname ] = my_part->m_aliases[i]; } isModified = true; + ++m_mod_hash; - return newCmp; + return true; } -LIB_ALIAS* CMP_LIBRARY::RemoveEntry( LIB_ALIAS* aEntry ) +LIB_ALIAS* PART_LIB::RemoveEntry( LIB_ALIAS* aEntry ) { wxCHECK_MSG( aEntry != NULL, NULL, wxT( "NULL pointer cannot be removed from library." ) ); - LIB_ALIAS_MAP::iterator it = aliases.find( aEntry->GetName() ); + LIB_ALIAS_MAP::iterator it = m_amap.find( aEntry->GetName() ); - if( it == aliases.end() ) + if( it == m_amap.end() ) return NULL; // If the entry pointer doesn't match the name it is mapped to in the library, we // have done something terribly wrong. - wxCHECK_MSG( (*it).second == aEntry, NULL, + wxCHECK_MSG( *it->second == aEntry, NULL, wxT( "Pointer mismatch while attempting to remove entry <" ) + aEntry->GetName() + wxT( "> from library <" ) + GetName() + wxT( ">." ) ); - LIB_ALIAS* alias = (LIB_ALIAS*) aEntry; - LIB_COMPONENT* component = alias->GetComponent(); - alias = component->RemoveAlias( alias ); + LIB_ALIAS* alias = aEntry; + LIB_PART* part = alias->GetPart(); - if( alias == NULL ) + alias = part->RemoveAlias( alias ); + + if( !alias ) { - delete component; + delete part; - if( aliases.size() > 1 ) + if( m_amap.size() > 1 ) { LIB_ALIAS_MAP::iterator next = it; next++; - if( next == aliases.end() ) - next = aliases.begin(); + if( next == m_amap.end() ) + next = m_amap.begin(); - alias = (*next).second; + alias = next->second; } } - aliases.erase( it ); + m_amap.erase( it ); isModified = true; - + ++m_mod_hash; return alias; } -LIB_COMPONENT* CMP_LIBRARY::ReplaceComponent( LIB_COMPONENT* aOldComponent, - LIB_COMPONENT* aNewComponent ) +LIB_PART* PART_LIB::ReplacePart( LIB_PART* aOldPart, LIB_PART* aNewPart ) { - wxASSERT( aOldComponent != NULL ); - wxASSERT( aNewComponent != NULL ); + wxASSERT( aOldPart != NULL ); + wxASSERT( aNewPart != NULL ); /* Remove the old root component. The component will automatically be deleted * when all it's aliases are deleted. Do not place any code that accesses - * aOldComponent inside this loop that gets evaluated after the last alias is + * aOldPart inside this loop that gets evaluated after the last alias is * removed in RemoveEntry(). Failure to heed this warning will result in a * segfault. */ - size_t i = aOldComponent->m_aliases.size(); + size_t i = aOldPart->m_aliases.size(); - while( i != 0 ) + while( i > 0 ) { i -= 1; - RemoveEntry( aOldComponent->m_aliases[ i ] ); + RemoveEntry( aOldPart->m_aliases[ i ] ); } - LIB_COMPONENT* newCmp = new LIB_COMPONENT( *aNewComponent, this ); + LIB_PART* my_part = new LIB_PART( *aNewPart, this ); // Add new aliases to library alias map. - for( i = 0; i < newCmp->m_aliases.size(); i++ ) + for( i = 0; i < my_part->m_aliases.size(); i++ ) { - aliases[ newCmp->m_aliases[ i ]->GetName() ] = newCmp->m_aliases[ i ]; + wxString aname = my_part->m_aliases[ i ]->GetName(); + m_amap[ aname ] = my_part->m_aliases[ i ]; } isModified = true; - - return newCmp; + ++m_mod_hash; + return my_part; } -LIB_ALIAS* CMP_LIBRARY::GetNextEntry( const wxString& aName ) +LIB_ALIAS* PART_LIB::GetNextEntry( const wxString& aName ) { - if( aliases.empty() ) + if( m_amap.empty() ) return NULL; - LIB_ALIAS_MAP::iterator it = aliases.find( aName ); + LIB_ALIAS_MAP::iterator it = m_amap.find( aName ); it++; - if( it == aliases.end() ) - it = aliases.begin(); + if( it == m_amap.end() ) + it = m_amap.begin(); - return (*it).second; + return it->second; } -LIB_ALIAS* CMP_LIBRARY::GetPreviousEntry( const wxString& aName ) +LIB_ALIAS* PART_LIB::GetPreviousEntry( const wxString& aName ) { - if( aliases.empty() ) + if( m_amap.empty() ) return NULL; - LIB_ALIAS_MAP::iterator it = aliases.find( aName ); + LIB_ALIAS_MAP::iterator it = m_amap.find( aName ); - if( it == aliases.begin() ) - it = aliases.end(); + if( it == m_amap.begin() ) + it = m_amap.end(); it--; - return (*it).second; + return it->second; } -bool CMP_LIBRARY::Load( wxString& aErrorMsg ) +bool PART_LIB::Load( wxString& aErrorMsg ) { FILE* file; char* line; - LIB_COMPONENT* libEntry; wxString msg; if( fileName.GetFullPath().IsEmpty() ) @@ -469,7 +467,7 @@ bool CMP_LIBRARY::Load( wxString& aErrorMsg ) return false; } - /* There is no header if this is a symbol library. */ + // There is no header if this is a symbol library. if( type == LIBRARY_TYPE_EESCHEMA ) { wxString tmp; @@ -514,14 +512,15 @@ bool CMP_LIBRARY::Load( wxString& aErrorMsg ) || !vers.GetNextToken().ToLong( & minor ) || minor < 0L || minor > 99 ) { -#if 0 // Note for developers: - // Not sure this warning is very useful: old designs *must* be always loadable - wxLogWarning( wxT( "The component library <%s> header version \ -number is invalid.\n\nIn future versions of Eeschema this library may not \ -load correctly. To resolve this problem open the library in the library \ -editor and save it. If this library is the project cache library, save \ -the current schematic." ), - GetChars( GetName() ) ); +#if 0 // Note for developers: + // Not sure this warning is very useful: old designs *must* be always loadable + wxLogWarning( wxT( + "The component library '%s' header version " + "number is invalid.\n\nIn future versions of Eeschema this library may not " + "load correctly. To resolve this problem open the library in the library " + "editor and save it. If this library is the project cache library, save " + "the current schematic." ), + GetChars( GetName() ) ); #endif } else @@ -548,60 +547,63 @@ the current schematic." ), if( strnicmp( line, "DEF", 3 ) == 0 ) { - /* Read one DEF/ENDDEF part entry from library: */ - libEntry = new LIB_COMPONENT( wxEmptyString, this ); + // Read one DEF/ENDDEF part entry from library: + LIB_PART* part = new LIB_PART( wxEmptyString, this ); - if( libEntry->Load( reader, msg ) ) + if( part->Load( reader, msg ) ) { - /* Check for duplicate entry names and warn the user about - * the potential conflict. - */ - if( FindEntry( libEntry->GetName() ) != NULL ) + // Check for duplicate entry names and warn the user about + // the potential conflict. + if( FindEntry( part->GetName() ) != NULL ) { - wxString msg( wxGetTranslation( duplicate_name_msg ) ); + wxString msg = duplicate_name_msg; + wxLogWarning( msg, GetChars( fileName.GetName() ), - GetChars( libEntry->GetName() ) ); + GetChars( part->GetName() ) ); } - LoadAliases( libEntry ); + LoadAliases( part ); } else { - wxLogWarning( _( "Library <%s> component load error %s." ), + wxLogWarning( _( "Library '%s' component load error %s." ), GetChars( fileName.GetName() ), GetChars( msg ) ); msg.Clear(); - delete libEntry; + delete part; } } } + ++m_mod_hash; + return true; } -void CMP_LIBRARY::LoadAliases( LIB_COMPONENT* component ) +void PART_LIB::LoadAliases( LIB_PART* aPart ) { - wxCHECK_RET( component != NULL, - wxT( "Cannot load aliases of NULL component object. Bad programmer!" ) ); + wxCHECK_RET( aPart, wxT( "Cannot load aliases of NULL part. Bad programmer!" ) ); - for( size_t i = 0; i < component->m_aliases.size(); i++ ) + for( size_t i = 0; i < aPart->m_aliases.size(); i++ ) { - if( FindEntry( component->m_aliases[i]->GetName() ) != NULL ) + if( FindEntry( aPart->m_aliases[i]->GetName() ) != NULL ) { - wxString msg( wxGetTranslation( duplicate_name_msg ) ); + wxString msg = duplicate_name_msg; + wxLogError( msg, GetChars( fileName.GetName() ), - GetChars( component->m_aliases[i]->GetName() ) ); + GetChars( aPart->m_aliases[i]->GetName() ) ); } - aliases[ component->m_aliases[i]->GetName() ] = component->m_aliases[i]; + wxString aname = aPart->m_aliases[i]->GetName(); + m_amap[ aname ] = aPart->m_aliases[i]; } } -bool CMP_LIBRARY::LoadHeader( LINE_READER& aLineReader ) +bool PART_LIB::LoadHeader( LINE_READER& aLineReader ) { char* line, * text, * data; @@ -623,7 +625,7 @@ bool CMP_LIBRARY::LoadHeader( LINE_READER& aLineReader ) } -bool CMP_LIBRARY::LoadDocs( wxString& aErrorMsg ) +bool PART_LIB::LoadDocs( wxString& aErrorMsg ) { int lineNumber = 0; char line[8000], * name, * text; @@ -638,14 +640,14 @@ bool CMP_LIBRARY::LoadDocs( wxString& aErrorMsg ) if( file == NULL ) { - aErrorMsg.Printf( _( "Could not open component document library file <%s>." ), + aErrorMsg.Printf( _( "Could not open component document library file '%s'." ), GetChars( fn.GetFullPath() ) ); return false; } if( GetLine( file, line, &lineNumber, sizeof(line) ) == NULL ) { - aErrorMsg.Printf( _( "Component document library file <%s> is empty." ), + aErrorMsg.Printf( _( "Part document library file '%s' is empty." ), GetChars( fn.GetFullPath() ) ); fclose( file ); return false; @@ -653,7 +655,7 @@ bool CMP_LIBRARY::LoadDocs( wxString& aErrorMsg ) if( strnicmp( line, DOCFILE_IDENT, 10 ) != 0 ) { - aErrorMsg.Printf( _( "File <%s> is not a valid component library document file." ), + aErrorMsg.Printf( _( "File '%s' is not a valid component library document file." ), GetChars( fn.GetFullPath() ) ); fclose( file ); return false; @@ -668,7 +670,7 @@ bool CMP_LIBRARY::LoadDocs( wxString& aErrorMsg ) return false; } - /* Read one $CMP/$ENDCMP part entry from library: */ + // Read one $CMP/$ENDCMP part entry from library: name = strtok( line + 5, "\n\r" ); wxString cmpname = FROM_UTF8( name ); @@ -707,7 +709,7 @@ bool CMP_LIBRARY::LoadDocs( wxString& aErrorMsg ) } -bool CMP_LIBRARY::Save( OUTPUTFORMATTER& aFormatter ) +bool PART_LIB::Save( OUTPUTFORMATTER& aFormatter ) { if( isModified ) { @@ -721,12 +723,12 @@ bool CMP_LIBRARY::Save( OUTPUTFORMATTER& aFormatter ) { SaveHeader( aFormatter ); - for( LIB_ALIAS_MAP::iterator it=aliases.begin(); it!=aliases.end(); it++ ) + for( LIB_ALIAS_MAP::iterator it=m_amap.begin(); it!=m_amap.end(); it++ ) { - if( !(*it).second->IsRoot() ) + if( !it->second->IsRoot() ) continue; - (*it).second->GetComponent()->Save( aFormatter ); + it->second->GetPart()->Save( aFormatter ); } aFormatter.Print( 0, "#\n#End Library\n" ); @@ -740,7 +742,7 @@ bool CMP_LIBRARY::Save( OUTPUTFORMATTER& aFormatter ) } -bool CMP_LIBRARY::SaveDocs( OUTPUTFORMATTER& aFormatter ) +bool PART_LIB::SaveDocs( OUTPUTFORMATTER& aFormatter ) { bool success = true; @@ -748,9 +750,9 @@ bool CMP_LIBRARY::SaveDocs( OUTPUTFORMATTER& aFormatter ) { aFormatter.Print( 0, "%s\n", DOCFILE_IDENT ); - for( LIB_ALIAS_MAP::iterator it=aliases.begin(); it!=aliases.end(); it++ ) + for( LIB_ALIAS_MAP::iterator it=m_amap.begin(); it!=m_amap.end(); it++ ) { - if ( !(*it).second->SaveDoc( aFormatter ) ) + if( !it->second->SaveDoc( aFormatter ) ) success = false; } @@ -765,7 +767,7 @@ bool CMP_LIBRARY::SaveDocs( OUTPUTFORMATTER& aFormatter ) } -bool CMP_LIBRARY::SaveHeader( OUTPUTFORMATTER& aFormatter ) +bool PART_LIB::SaveHeader( OUTPUTFORMATTER& aFormatter ) { aFormatter.Print( 0, "%s %d.%d\n", LIBFILE_IDENT, LIB_VERSION_MAJOR, LIB_VERSION_MINOR ); @@ -775,7 +777,7 @@ bool CMP_LIBRARY::SaveHeader( OUTPUTFORMATTER& aFormatter ) #if 0 aFormatter.Print( 0, "$HEADER\n" ); aFormatter.Print( 0, "TimeStamp %8.8lX\n", m_TimeStamp ); - aFormatter.Print( 0, "Parts %d\n", aliases.size() ); + aFormatter.Print( 0, "Parts %d\n", m_amap.size() ); aFormatter.Print( 0, "$ENDHEADER\n" ) != 1 ); #endif @@ -783,136 +785,126 @@ bool CMP_LIBRARY::SaveHeader( OUTPUTFORMATTER& aFormatter ) } -/* - * The static library list and list management methods. - */ -CMP_LIBRARY_LIST CMP_LIBRARY::libraryList; -wxArrayString CMP_LIBRARY::libraryListSortOrder; - - -CMP_LIBRARY* CMP_LIBRARY::LoadLibrary( const wxFileName& aFileName, wxString& aErrorMsg ) +PART_LIB* PART_LIB::LoadLibrary( const wxString& aFileName ) throw( IO_ERROR ) { - CMP_LIBRARY* lib = NULL; - - lib = new CMP_LIBRARY( LIBRARY_TYPE_EESCHEMA, aFileName ); + std::auto_ptr lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, aFileName ) ); wxBusyCursor ShowWait; - if( !lib->Load( aErrorMsg ) ) - { - delete lib; - return NULL; - } + wxString errorMsg; + + if( !lib->Load( errorMsg ) ) + THROW_IO_ERROR( errorMsg ); if( USE_OLD_DOC_FILE_FORMAT( lib->versionMajor, lib->versionMinor ) ) - lib->LoadDocs( aErrorMsg ); + { +#if 1 + // not fatal if error here. + lib->LoadDocs( errorMsg ); +#else + if( !lib->LoadDocs( errorMsg ) ) + THROW_IO_ERROR( errorMsg ); +#endif + } + + PART_LIB* ret = lib.release(); + + return ret; +} + + +PART_LIB* PART_LIBS::AddLibrary( const wxString& aFileName ) throw( IO_ERROR ) +{ + PART_LIB* lib; + +#if 1 + wxFileName fn = aFileName; + // Don't reload the library if it is already loaded. + lib = FindLibrary( fn.GetName() ); + if( lib ) + return lib; +#endif + + lib = PART_LIB::LoadLibrary( aFileName ); + + push_back( lib ); return lib; } -bool CMP_LIBRARY::AddLibrary( const wxFileName& aFileName, wxString& aErrorMsg ) +PART_LIB* PART_LIBS::AddLibrary( const wxString& aFileName, PART_LIBS::iterator& aIterator ) throw( IO_ERROR ) { - CMP_LIBRARY* lib; +#if 1 + // Don't reload the library if it is already loaded. + wxFileName fn( aFileName ); + PART_LIB* lib = FindLibrary( fn.GetName() ); - /* Don't reload the library if it is already loaded. */ - lib = FindLibrary( aFileName.GetName() ); + if( lib ) + return lib; +#endif - if( lib != NULL ) - return true; + lib = PART_LIB::LoadLibrary( aFileName ); - lib = LoadLibrary( aFileName, aErrorMsg ); - - if( lib == NULL ) - return false; - - libraryList.push_back( lib ); - - return true; -} - - -bool CMP_LIBRARY::AddLibrary( const wxFileName& aFileName, wxString& aErrorMsg, - CMP_LIBRARY_LIST::iterator& aIterator ) -{ - CMP_LIBRARY* lib; - - /* Don't reload the library if it is already loaded. */ - lib = FindLibrary( aFileName.GetName() ); - - if( lib != NULL ) - return true; - - lib = LoadLibrary( aFileName, aErrorMsg ); - - if( lib == NULL ) - return false; - - if( aIterator >= libraryList.begin() && aIterator < libraryList.end() ) - libraryList.insert( aIterator, lib ); + if( aIterator >= begin() && aIterator < end() ) + insert( aIterator, lib ); else - libraryList.push_back( lib ); + push_back( lib ); - return true; + return lib; } -void CMP_LIBRARY::RemoveLibrary( const wxString& aName ) +void PART_LIBS::RemoveLibrary( const wxString& aName ) { if( aName.IsEmpty() ) return; - CMP_LIBRARY_LIST::iterator i; - - for( i = libraryList.begin(); i < libraryList.end(); i++ ) + for( PART_LIBS::iterator it = begin(); it < end(); ++it ) { - if( i->GetName().CmpNoCase( aName ) == 0 ) + if( it->GetName().CmpNoCase( aName ) == 0 ) { - CMP_LIBRARY::libraryList.erase( i ); + erase( it ); return; } } } -bool CMP_LIBRARY::LibraryExists( const CMP_LIBRARY* aLibptr ) +PART_LIB* PART_LIBS::FindLibrary( const wxString& aName ) { - BOOST_FOREACH( CMP_LIBRARY& lib, libraryList ) - { - if( &lib == aLibptr ) - return true; - } - - return false; -} - - -CMP_LIBRARY* CMP_LIBRARY::FindLibrary( const wxString& aName ) -{ - BOOST_FOREACH( CMP_LIBRARY& lib, libraryList ) +#if 0 + BOOST_FOREACH( PART_LIB& lib, *this ) { if( lib == aName ) return &lib; } +#else + for( PART_LIBS::iterator it = begin(); it!=end(); ++it ) + { + if( *it == aName ) + return &*it; + } +#endif return NULL; } -wxArrayString CMP_LIBRARY::GetLibraryNames( bool aSorted ) +wxArrayString PART_LIBS::GetLibraryNames( bool aSorted ) { wxArrayString cacheNames; wxArrayString names; - BOOST_FOREACH( CMP_LIBRARY& lib, CMP_LIBRARY::libraryList ) + BOOST_FOREACH( PART_LIB& lib, *this ) { - if( lib.isCache && aSorted ) + if( lib.IsCache() && aSorted ) cacheNames.Add( lib.GetName() ); else names.Add( lib.GetName() ); } - /* Even sorted, the cache library is always at the end of the list. */ + // Even sorted, the cache library is always at the end of the list. if( aSorted ) names.Sort(); @@ -923,38 +915,37 @@ wxArrayString CMP_LIBRARY::GetLibraryNames( bool aSorted ) } -LIB_COMPONENT* CMP_LIBRARY::FindLibraryComponent( const wxString& aName, - const wxString& aLibraryName ) +LIB_PART* PART_LIBS::FindLibPart( const wxString& aName, const wxString& aLibraryName ) { - LIB_COMPONENT* component = NULL; + LIB_PART* part = NULL; - BOOST_FOREACH( CMP_LIBRARY& lib, libraryList ) + BOOST_FOREACH( PART_LIB& lib, *this ) { if( !aLibraryName.IsEmpty() && lib.GetName() != aLibraryName ) continue; - component = lib.FindComponent( aName ); + part = lib.FindPart( aName ); - if( component != NULL ) + if( part ) break; } - return component; + return part; } -LIB_ALIAS* CMP_LIBRARY::FindLibraryEntry( const wxString& aName, const wxString& aLibraryName ) +LIB_ALIAS* PART_LIBS::FindLibraryEntry( const wxString& aName, const wxString& aLibraryName ) { LIB_ALIAS* entry = NULL; - BOOST_FOREACH( CMP_LIBRARY& lib, libraryList ) + BOOST_FOREACH( PART_LIB& lib, *this ) { - if( !aLibraryName.IsEmpty() && lib.GetName() != aLibraryName ) + if( !!aLibraryName && lib.GetName() != aLibraryName ) continue; entry = lib.FindEntry( aName ); - if( entry != NULL ) + if( entry ) break; } @@ -962,13 +953,214 @@ LIB_ALIAS* CMP_LIBRARY::FindLibraryEntry( const wxString& aName, const wxString& } -void CMP_LIBRARY::RemoveCacheLibrary() -{ - CMP_LIBRARY_LIST::iterator i; +int PART_LIBS::s_modify_generation = 1; // starts at 1 and goes up - for( i = libraryList.begin(); i < libraryList.end(); i++ ) + +int PART_LIBS::GetModifyHash() +{ + int hash = 0; + + for( PART_LIBS::const_iterator it = begin(); it != end(); ++it ) { - if( i->isCache ) - libraryList.erase( i-- ); + hash += it->m_mod_hash; + } + + return hash; +} + + +/* +void PART_LIBS::RemoveCacheLibrary() +{ + for( PART_LIBS::iterator it = begin(); it < end(); ++it ) + { + if( it->IsCache() ) + erase( it-- ); } } +*/ + + +void PART_LIBS::LibNamesAndPaths( PROJECT* aProject, bool doSave, + wxString* aPaths, wxArrayString* aNames ) throw( IO_ERROR ) +{ + wxString pro = aProject->GetProjectFullName(); + + PARAM_CFG_ARRAY ca; + + if( aPaths ) + ca.push_back( new PARAM_CFG_FILENAME( wxT( "LibDir" ), aPaths ) ); + + if( aNames ) + ca.push_back( new PARAM_CFG_LIBNAME_LIST( wxT( "LibName" ), aNames, GROUP_SCH_LIBS ) ); + + if( doSave ) + { + aProject->ConfigSave( Kiface().KifaceSearch(), GROUP_SCH, ca ); + + /* + { + wxString msg = wxString::Format( _( + "Unable save project's '%s' file" ), + GetChars( pro ) + ); + THROW_IO_ERROR( msg ); + } + */ + } + else + { + wxString pro = aProject->GetProjectFullName(); + + if( !aProject->ConfigLoad( Kiface().KifaceSearch(), GROUP_SCH, ca ) ) + { + wxString msg = wxString::Format( _( + "Unable to load project's '%s' file" ), + GetChars( pro ) + ); + THROW_IO_ERROR( msg ); + } + } +} + + +const wxString PART_LIBS::CacheName( const wxString& aFullProjectFilename ) +{ + /* until apr 2009 the project cache lib was named: .cache.lib, + * and after: -cache.lib. So if the -cache.lib is not found, + * the old file will be renamed and returned. + */ + wxFileName new_name = aFullProjectFilename; + + new_name.SetName( new_name.GetName() + wxT( "-cache" ) ); + new_name.SetExt( SchematicLibraryFileExtension ); + + if( new_name.FileExists() ) + return new_name.GetFullPath(); + else + { + wxFileName old_name = aFullProjectFilename; + old_name.SetExt( wxT( "cache.lib" ) ); + + if( old_name.FileExists() ) + { + wxRenameFile( old_name.GetFullPath(), new_name.GetFullPath() ); + return new_name.GetFullPath(); + } + } + return wxEmptyString; +} + + +void PART_LIBS::LoadAllLibraries( PROJECT* aProject ) throw( IO_ERROR ) +{ + wxFileName fn; + wxString filename; + wxString libs_not_found; + wxArrayString sortOrder; + SEARCH_STACK* lib_search = aProject->SchSearchS(); + +#if defined(DEBUG) && 1 + lib_search->Show( __func__ ); +#endif + + wxArrayString lib_names; + + LibNamesAndPaths( aProject, false, NULL, &lib_names ); + + // If the list is empty, force loading the standard power symbol library. + if( !lib_names.GetCount() ) + lib_names.Add( wxT( "power" ) ); + + wxASSERT( !size() ); // expect to load into "this" empty container. + + for( unsigned i = 0; i < lib_names.GetCount(); ++i ) + { + fn.Clear(); + fn.SetName( lib_names[i] ); + fn.SetExt( SchematicLibraryFileExtension ); + + // Skip if the file name is not valid.. + if( !fn.IsOk() ) + continue; + + if( !fn.FileExists() ) + { + filename = lib_search->FindValidPath( fn.GetFullPath() ); + + if( !filename ) + { + libs_not_found += fn.GetName(); + libs_not_found += wxT( '\n' ); + continue; + } + } + else + { + filename = fn.GetFullPath(); + } + + try + { + AddLibrary( filename ); + } + catch( const IO_ERROR& ioe ) + { + wxString msg = wxString::Format( _( + "Part library '%s' failed to load. Error:\n" + "%s" ), + GetChars( filename ), + GetChars( ioe.errorText ) + ); + + THROW_IO_ERROR( msg ); + } + } + + // add the special cache library. + wxString cache_name = CacheName( aProject->GetProjectFullName() ); + if( !!cache_name ) + { + try + { + if( PART_LIB* lib = AddLibrary( cache_name ) ) + lib->SetCache(); + } + catch( const IO_ERROR& ioe ) + { + wxString msg = wxString::Format( _( + "Part library '%s' failed to load.\nError: %s" ), + GetChars( cache_name ), + GetChars( ioe.errorText ) + ); + + THROW_IO_ERROR( msg ); + } + } + + // Print the libraries not found + if( !!libs_not_found ) + { + // Use a different exception type so catch()er can route to proper use + // of the HTML_MESSAGE_BOX. + THROW_PARSE_ERROR( wxEmptyString, UTF8( __func__ ), + UTF8( libs_not_found ), 0, 0 ); + } + + // Put the libraries in the correct order. + PART_LIBS::SetSortOrder( sortOrder ); + + sort(); + +#if defined(DEBUG) && 1 + printf( "%s: sort order:\n", __func__ ); + + for( size_t i = 0; i < sortOrder.GetCount(); i++ ) + printf( " %s\n", TO_UTF8( sortOrder[i] ) ); + + printf( "%s: actual order:\n", __func__ ); + + for( PART_LIBS::const_iterator it = begin(); it < end(); ++it ) + printf( " %s\n", TO_UTF8( it->GetName() ) ); +#endif +} diff --git a/eeschema/class_library.h b/eeschema/class_library.h index 4ab56f1986..27ab81e4e6 100644 --- a/eeschema/class_library.h +++ b/eeschema/class_library.h @@ -25,7 +25,7 @@ /** * @file class_library.h - * @brief Definition for component library class. + * @brief Definition for part library class. */ #ifndef CLASS_LIBRARY_H @@ -35,18 +35,19 @@ #include +#include class LINE_READER; class OUTPUTFORMATTER; /* - * Component Library version and file header macros. + * Part Library version and file header macros. */ #define LIB_VERSION_MAJOR 2 #define LIB_VERSION_MINOR 3 -/* Must be the first line of component library (.lib) files. */ +/* Must be the first line of part library (.lib) files. */ #define LIBFILE_IDENT "EESchema-LIBRARY Version" #define LIB_VERSION( major, minor ) ( major * 100 + minor ) @@ -59,59 +60,212 @@ class OUTPUTFORMATTER; /* * Library versions 2.3 and lower use the old separate library (.lib) and - * document (.dcm) files. Component libraries after 2.3 merged the library + * document (.dcm) files. Part libraries after 2.3 merged the library * and document files into a single library file. This macro checks if the * library version supports the old format */ #define USE_OLD_DOC_FILE_FORMAT( major, minor ) \ ( LIB_VERSION( major, minor ) <= LIB_VERSION( 2, 3 ) ) -/* Must be the first line of component library document (.dcm) files. */ +/* Must be the first line of part library document (.dcm) files. */ #define DOCFILE_IDENT "EESchema-DOCLIB Version 2.0" #define DOC_EXT wxT( "dcm" ) -/* Helpers for creating a list of component libraries. */ -class CMP_LIBRARY; +/* Helpers for creating a list of part libraries. */ +class PART_LIB; class wxRegEx; +/** + * LIB_ALIAS map sorting. + */ +struct AliasMapSort +{ + bool operator() ( const wxString& aItem1, const wxString& aItem2 ) const + { + return Cmp_KEEPCASE( aItem1, aItem2 ) < 0; + } +}; -typedef boost::ptr_vector< CMP_LIBRARY > CMP_LIBRARY_LIST; +/// Alias map used by part library object. -extern bool operator<( const CMP_LIBRARY& item1, const CMP_LIBRARY& item2 ); +typedef std::map< wxString, LIB_ALIAS*, AliasMapSort > LIB_ALIAS_MAP; +typedef std::vector< LIB_ALIAS* > LIB_ALIASES; +typedef boost::ptr_vector< PART_LIB > PART_LIBS_BASE; /** - * Class CMP_LIBRARY - * is used to load, save, search, and otherwise manipulate - * component library files. + * Class PART_LIBS + * is a collection of PART_LIBs. It extends from PROJECT::_ELEM so it can be + * hung in the PROJECT. It does not use any UI calls, but rather simply throws + * an IO_ERROR when there is a problem. */ -class CMP_LIBRARY +class PART_LIBS : public PART_LIBS_BASE, public PROJECT::_ELEM { - int type; ///< Library type indicator. - wxFileName fileName; ///< Library file name. - wxDateTime timeStamp; ///< Library save time and date. - int versionMajor; ///< Library major version number. - int versionMinor; ///< Library minor version number. - bool isCache; /**< False for the "standard" libraries, - True for the library cache */ - wxString header; ///< first line of loaded library. - bool isModified; ///< Library modification status. - LIB_ALIAS_MAP aliases; ///< Map of aliases objects associated with the library. - - static CMP_LIBRARY_LIST libraryList; - static wxArrayString libraryListSortOrder; - - friend class LIB_COMPONENT; + static wxArrayString s_libraryListSortOrder; public: - CMP_LIBRARY( int aType, const wxFileName& aFileName ); - CMP_LIBRARY( int aType, const wxString& aFileName ) + + static int s_modify_generation; ///< helper for GetModifyHash() + + PART_LIBS() { - CMP_LIBRARY( aType, wxFileName( aFileName ) ); + ++s_modify_generation; } - ~CMP_LIBRARY(); + + /// Return the modification hash for all libraries. The value returned + /// changes on every library modification. + int GetModifyHash(); + + /** + * Function AddLibrary + * allocates and adds a part library to the library list. + * + * @param aFileName - File name object of part library. + * @param aErrorMsg - Error message if the part library failed to load. + * @return PART_LIB* - the new PART_LIB, which remains owned by this PART_LIBS container. + * @throw IO_ERROR if there's any problem loading. + */ + PART_LIB* AddLibrary( const wxString& aFileName ) throw( IO_ERROR ); + + /** + * Function AddLibrary + * inserts a part library into the library list. + * + * @param aFileName - File name object of part library. + * @param aIterator - Iterator to insert library in front of. + * @return PART_LIB* - the new PART_LIB, which remains owned by this PART_LIBS container. + * @throw IO_ERROR if there's any problem loading. + */ + PART_LIB* AddLibrary( const wxString& aFileName, PART_LIBS::iterator& aIterator ) throw( IO_ERROR ); + + /** + * Function RemoveLibrary + * removes a part library from the library list. + * + * @param aName - Name of part library to remove. + */ + void RemoveLibrary( const wxString& aName ); + + void RemoveAllLibraries() { clear(); } + + /** + * Function LoadAllLibraries + * loads all of the project's libraries into this container, which should + * be cleared before calling it. + */ + void LoadAllLibraries( PROJECT* aProject ) throw( IO_ERROR ); + + /** + * Function LibNamesAndPaths + * either saves or loads the names of the currently configured part libraries + * (without paths). + */ + static void LibNamesAndPaths( PROJECT* aProject, bool doSave, + wxString* aPaths, wxArrayString* aNames=NULL ) throw( IO_ERROR ); + + /** + * Function cacheName + * returns the name of the cache library after potentially fixing it from + * an older naming scheme. That is, the old file is renamed if needed. + * @param aFullProjectFilename - the *.pro filename with absolute path. + */ + static const wxString CacheName( const wxString& aFullProjectFilename ); + + /** + * Function FindLibrary + * finds a part library by \a aName. + * + * @param aName - Library file name without path or extension to find. + * @return Part library if found, otherwise NULL. + */ + PART_LIB* FindLibrary( const wxString& aName ); + + /** + * Function GetLibraryNames + * returns the list of part library file names without path and extension. + * + * @param aSorted - Sort the list of name if true. Otherwise use the + * library load order. + * @return The list of library names. + */ + wxArrayString GetLibraryNames( bool aSorted = true ); + + /** + * Function FindLibPart + * searches all libraries in the list for a part. + * + * A part object will always be returned. If the entry found + * is an alias. The root part will be found and returned. + * + * @param aPartName - Name of part to search for. + * @param aLibraryName - Name of the library to search for part. + * @return LIB_PART* - The part object if found, otherwise NULL. + */ + LIB_PART* FindLibPart( const wxString& aPartName, const wxString& aLibraryName = wxEmptyString ); + + /** + * Function FindLibraryEntry + * searches all libraries in the list for an entry. + * + * The object can be either a part or an alias. + * + * @param aEntryName - Name of entry to search for. + * @param aLibraryName - Name of the library to search. + * @return The entry object if found, otherwise NULL. + */ + LIB_ALIAS* FindLibraryEntry( const wxString& aEntryName, + const wxString& aLibraryName = wxEmptyString ); + + /** + * Function RemoveCacheLibrary + * removes all cache libraries from library list. + */ + //void RemoveCacheLibrary(); + + int GetLibraryCount() { return size(); } + + static void SetSortOrder( const wxArrayString& aSortOrder ) + { + s_libraryListSortOrder = aSortOrder; + } + + static wxArrayString& GetSortOrder() + { + return s_libraryListSortOrder; + } +}; + + +bool operator<( const PART_LIB& item1, const PART_LIB& item2 ); + + +/** + * Class PART_LIB + * is used to load, save, search, and otherwise manipulate + * part library files. + */ +class PART_LIB +{ + int type; ///< Library type indicator. + wxFileName fileName; ///< Library file name. + wxDateTime timeStamp; ///< Library save time and date. + int versionMajor; ///< Library major version number. + int versionMinor; ///< Library minor version number. + bool isCache; /**< False for the "standard" libraries, + True for the library cache */ + wxString header; ///< first line of loaded library. + bool isModified; ///< Library modification status. + LIB_ALIAS_MAP m_amap; ///< Map of alias objects associated with the library. + int m_mod_hash; ///< incremented each time library is changed. + + friend class LIB_PART; + friend class PART_LIBS; + +public: + PART_LIB( int aType, const wxString& aFileName ); + ~PART_LIB(); /** * Function Save @@ -145,7 +299,7 @@ private: bool SaveHeader( OUTPUTFORMATTER& aFormatter ); bool LoadHeader( LINE_READER& aLineReader ); - void LoadAliases( LIB_COMPONENT* aComponent ); + void LoadAliases( LIB_PART* aPart ); public: /** @@ -155,18 +309,18 @@ public: */ bool IsEmpty() const { - return aliases.empty(); + return m_amap.empty(); } /** * Function GetCount * returns the number of entries in the library. * - * @return The number of component and alias entries. + * @return The number of part and alias entries. */ int GetCount() const { - return aliases.size(); + return m_amap.size(); } bool IsModified() const @@ -218,21 +372,21 @@ public: bool aSort = true ); /** - * Find components in library by key word regular expression search. + * Find parts in library by key word regular expression search. * - * @param aNames - String array to place found component names into. - * @param aRe - Regular expression used to search component key words. - * @param aSort - Sort component name list. + * @param aNames - String array to place found part names into. + * @param aRe - Regular expression used to search part key words. + * @param aSort - Sort part name list. */ void SearchEntryNames( wxArrayString& aNames, const wxRegEx& aRe, bool aSort = true ); /** - * Checks \a aComponent for name conflict in the library. + * Checks \a aPart for name conflict in the library. * - * @param aComponent - The component to check. + * @param aPart - The part to check. * @return True if a conflict exists. Otherwise false. */ - bool Conflicts( LIB_COMPONENT* aComponent ); + bool Conflicts( LIB_PART* aPart ); /** * Find entry by name. @@ -243,22 +397,19 @@ public: LIB_ALIAS* FindEntry( const wxString& aName ); /** - * Find component by \a aName. + * Find part by \a aName. * * This is a helper for FindEntry so casting a LIB_ALIAS pointer to - * a LIB_COMPONENT pointer is not required. + * a LIB_PART pointer is not required. * - * @param aName - Name of component, case insensitive. - * @return Component if found. NULL if not found. + * @param aName - Name of part, case insensitive. + * @return LIB_PART* - part if found, else NULL. */ - LIB_COMPONENT* FindComponent( const wxString& aName ); + LIB_PART* FindPart( const wxString& aName ); /** * Find alias by \a nName. * - * This is a helper for FindEntry so casting a LIB_ALIAS pointer to - * a LIB_ALIAS pointer is not required. - * * @param aName - Name of alias, case insensitive. * @return Alias if found. NULL if not found. */ @@ -270,7 +421,7 @@ public: /** * Add a new \a aAlias entry to the library. * - * First check if a component or alias with the same name already exists + * First check if a part or alias with the same name already exists * in the library and add alias if no conflict occurs. Once the alias * is added to the library it is owned by the library. Deleting the * alias pointer will render the library unstable. Use RemoveEntry to @@ -282,23 +433,24 @@ public: bool AddAlias( LIB_ALIAS* aAlias ); /** - * Add \a aComponent entry to library. - * Note a component can have an alias list, + * Add \a aPart entry to library. + * Note a part can have an alias list, * so these alias will be added in library. * Conflicts can happen if aliases are already existing. * User is asked to choose what alias is removed (existing, or new) - * @param aComponent - Component to add. - * @return Added component if successful. + * + * @param aPart - Part to add, caller retains ownership, a clone is added. + * @return bool - true iff successful. */ - LIB_COMPONENT* AddComponent( LIB_COMPONENT* aComponent ); + bool AddPart( LIB_PART* aPart ); /** * Safely remove \a aEntry from the library and return the next entry. * * The next entry returned depends on the entry being removed. If the entry being - * remove also removes the component, then the next entry from the list is returned. - * If the entry being used only removes an alias from a component, then the next alias - * of the component is returned. + * remove also removes the part, then the next entry from the list is returned. + * If the entry being used only removes an alias from a part, then the next alias + * of the part is returned. * * @param aEntry - Entry to remove from library. * @return The next entry in the library or NULL if the library is empty. @@ -306,14 +458,13 @@ public: LIB_ALIAS* RemoveEntry( LIB_ALIAS* aEntry ); /** - * Replace an existing component entry in the library. - * Note a component can have an alias list, + * Replace an existing part entry in the library. + * Note a part can have an alias list, * so these alias will be added in library (and previously existing alias removed) - * @param aOldComponent - The component to replace. - * @param aNewComponent - The new component. + * @param aOldPart - The part to replace. + * @param aNewPart - The new part. */ - LIB_COMPONENT* ReplaceComponent( LIB_COMPONENT* aOldComponent, - LIB_COMPONENT* aNewComponent ); + LIB_PART* ReplacePart( LIB_PART* aOldPart, LIB_PART* aNewPart ); /** * Return the first entry in the library. @@ -333,7 +484,6 @@ public: */ LIB_ALIAS* GetNextEntry( const wxString& aName ); - /** * Find previous library entry by \a aName. * @@ -350,7 +500,7 @@ public: * * @return Name of library file. */ - wxString GetName() const { return fileName.GetName(); } + const wxString GetName() const { return fileName.GetName(); } /** * Function GetFullFileName @@ -358,14 +508,14 @@ public: * * @return wxString - Full library file name with path and extension. */ - wxString GetFullFileName() { return fileName.GetFullPath(); } + wxString GetFullFileName() { return fileName.GetFullPath(); } /** * Function GetLogicalName * returns the logical name of the library. * @return wxString - The logical name of this library. */ - wxString GetLogicalName() + const wxString GetLogicalName() { /* for now is the filename without path or extension. @@ -381,151 +531,33 @@ public: /** * Function SetFileName - * sets the component library file name. + * sets the part library file name. * * @param aFileName - New library file name. */ - void SetFileName( const wxFileName aFileName ) + void SetFileName( const wxString& aFileName ) { - if( aFileName != fileName ) + if( aFileName != fileName.GetFullName() ) fileName = aFileName; } - /* - * The following static methods are for manipulating the list of - * component libraries. This eliminates the need for yet another - * global variable ( formerly g_LibraryList ) and gives some measure - * of safety from abusing the library list. - */ - - /** - * Function LibraryExists - * tests for existence of a library. - * - * @param aLibptr - aLibptr. - * @return bool - true if exists, else false - */ - - static bool LibraryExists( const CMP_LIBRARY* aLibptr ); - /** * Function LoadLibrary - * loads a component library file. + * allocates and loads a part library file. * - * @param aFileName - File name of the component library to load. - * @param aErrorMsg - Error message if the component library failed to load. - * @return Library object if library file loaded successfully, - * otherwise NULL. + * @param aFileName - File name of the part library to load. + * @return PART_LIB* - the allocated and loaded PART_LIB, which is owned by + * the caller. + * @throw IO_ERROR if there's any problem loading the library. */ - static CMP_LIBRARY* LoadLibrary( const wxFileName& aFileName, wxString& aErrorMsg ); - - /** - * Function AddLibrary - * adds a component library to the library list. - * - * @param aFileName - File name object of component library. - * @param aErrorMsg - Error message if the component library failed to load. - * @return True if library loaded properly otherwise false. - */ - static bool AddLibrary( const wxFileName& aFileName, wxString& aErrorMsg ); - - /** - * Function AddLibrary - * inserts a component library into the library list. - * - * @param aFileName - File name object of component library. - * @param aErrorMsg - Error message if the component library failed to load. - * @param aIterator - Iterator to insert library in front of. - * @return True if library loaded properly otherwise false. - */ - static bool AddLibrary( const wxFileName& aFileName, wxString& aErrorMsg, - CMP_LIBRARY_LIST::iterator& aIterator ); - - /** - * Function RemoveLibrary - * removes a component library from the library list. - * - * @param aName - Name of component library to remove. - */ - static void RemoveLibrary( const wxString& aName ); - - static void RemoveAllLibraries() { libraryList.clear(); } - - /** - * Function FindLibrary - * finds a component library by \a aName. - * - * @param aName - Library file name without path or extension to find. - * @return Component library if found, otherwise NULL. - */ - static CMP_LIBRARY* FindLibrary( const wxString& aName ); - - /** - * Function GetLibraryNames - * returns the list of component library file names without path and extension. - * - * @param aSorted - Sort the list of name if true. Otherwise use the - * library load order. - * @return The list of library names. - */ - static wxArrayString GetLibraryNames( bool aSorted = true ); - - /** - * Function FindLibraryComponent - * searches all libraries in the list for a component. - * - * A component object will always be returned. If the entry found - * is an alias. The root component will be found and returned. - * - * @param aComponentName - Name of component to search for. - * @param aLibraryName - Name of the library to search for component. - * @return The component object if found, otherwise NULL. - */ - static LIB_COMPONENT* FindLibraryComponent( const wxString& aComponentName, - const wxString& aLibraryName = wxEmptyString ); - - /** - * Function FindLibraryEntry - * searches all libraries in the list for an entry. - * - * The object can be either a component or an alias. - * - * @param aEntryName - Name of entry to search for. - * @param aLibraryName - Name of the library to search. - * @return The entry object if found, otherwise NULL. - */ - static LIB_ALIAS* FindLibraryEntry( const wxString& aEntryName, - const wxString& aLibraryName = wxEmptyString ); - - /** - * Function RemoveCacheLibrary - * removes all cache libraries from library list. - */ - static void RemoveCacheLibrary(); - - static int GetLibraryCount() { return libraryList.size(); } - - static CMP_LIBRARY_LIST& GetLibraryList() - { - return libraryList; - } - - static void SetSortOrder( const wxArrayString& aSortOrder ) - { - libraryListSortOrder = aSortOrder; - } - - static wxArrayString& GetSortOrder( void ) - { - return libraryListSortOrder; - } + static PART_LIB* LoadLibrary( const wxString& aFileName ) throw( IO_ERROR ); }; /** * Case insensitive library name comparison. */ -extern bool operator==( const CMP_LIBRARY& aLibrary, const wxString& aName ); -extern bool operator!=( const CMP_LIBRARY& aLibrary, const wxString& aName ); +bool operator==( const PART_LIB& aLibrary, const wxString& aName ); +bool operator!=( const PART_LIB& aLibrary, const wxString& aName ); #endif // CLASS_LIBRARY_H diff --git a/eeschema/component_references_lister.cpp b/eeschema/component_references_lister.cpp index d2b553af5a..f83b45c40d 100644 --- a/eeschema/component_references_lister.cpp +++ b/eeschema/component_references_lister.cpp @@ -291,7 +291,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId ) int LastReferenceNumber = 0; int NumberOfUnits, Unit; - /* Components with an invisible reference (power...) always are re-annotated. */ + // Components with an invisible reference (power...) always are re-annotated. ResetHiddenReferences(); /* calculate index of the first component with the same reference prefix @@ -301,7 +301,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId ) */ unsigned first = 0; - /* calculate the last used number for this reference prefix: */ + // calculate the last used number for this reference prefix: #ifdef USE_OLD_ALGO int minRefId = 0; @@ -330,7 +330,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId ) if( ( componentFlatList[first].CompareRef( componentFlatList[ii] ) != 0 ) || ( aUseSheetNum && ( componentFlatList[first].m_SheetNum != componentFlatList[ii].m_SheetNum ) ) ) { - /* New reference found: we need a new ref number for this reference */ + // New reference found: we need a new ref number for this reference first = ii; #ifdef USE_OLD_ALGO minRefId = 0; @@ -352,7 +352,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId ) } // Annotation of one part per package components (trivial case). - if( componentFlatList[ii].GetLibComponent()->GetPartCount() <= 1 ) + if( componentFlatList[ii].GetLibComponent()->GetUnitCount() <= 1 ) { if( componentFlatList[ii].m_IsNew ) { @@ -370,8 +370,8 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId ) continue; } - /* Annotation of multi-part components ( n parts per package ) (complex case) */ - NumberOfUnits = componentFlatList[ii].GetLibComponent()->GetPartCount(); + // Annotation of multi-unit parts ( n units per part ) (complex case) + NumberOfUnits = componentFlatList[ii].GetLibComponent()->GetUnitCount(); if( componentFlatList[ii].m_IsNew ) { @@ -382,7 +382,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId ) #endif componentFlatList[ii].m_NumRef = LastReferenceNumber; - if( !componentFlatList[ii].IsPartsLocked() ) + if( !componentFlatList[ii].IsUnitsLocked() ) componentFlatList[ii].m_Unit = 1; componentFlatList[ii].m_Flag = 1; @@ -400,9 +400,9 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId ) int found = FindUnit( ii, Unit ); if( found >= 0 ) - continue; /* this unit exists for this reference (unit already annotated) */ + continue; // this unit exists for this reference (unit already annotated) - /* Search a component to annotate ( same prefix, same value, not annotated) */ + // Search a component to annotate ( same prefix, same value, not annotated) for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ ) { if( componentFlatList[jj].m_Flag ) // already tested @@ -420,8 +420,8 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId ) if( !componentFlatList[jj].m_IsNew ) continue; - /* Component without reference number found, annotate it if possible */ - if( !componentFlatList[jj].IsPartsLocked() + // Component without reference number found, annotate it if possible + if( !componentFlatList[jj].IsUnitsLocked() || ( componentFlatList[jj].m_Unit == Unit ) ) { componentFlatList[jj].m_NumRef = componentFlatList[ii].m_NumRef; @@ -486,7 +486,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( wxArrayString* aMessageList ) // Error if unit number selected does not exist ( greater than the number of // parts in the component ). This can happen if a component has changed in a // library after a previous annotation. - if( std::max( componentFlatList[ii].GetLibComponent()->GetPartCount(), 1 ) + if( std::max( componentFlatList[ii].GetLibComponent()->GetUnitCount(), 1 ) < componentFlatList[ii].m_Unit ) { if( componentFlatList[ii].m_NumRef >= 0 ) @@ -498,7 +498,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( wxArrayString* aMessageList ) GetChars( componentFlatList[ii].GetRef() ), GetChars( tmp ), componentFlatList[ii].m_Unit, - componentFlatList[ii].GetLibComponent()->GetPartCount() ); + componentFlatList[ii].GetLibComponent()->GetUnitCount() ); if( aMessageList ) aMessageList->Add( msg ); @@ -555,8 +555,8 @@ int SCH_REFERENCE_LIST::CheckAnnotation( wxArrayString* aMessageList ) /* Test error if units are different but number of parts per package * too high (ex U3 ( 1 part) and we find U3B this is an error) */ - if( componentFlatList[ii].GetLibComponent()->GetPartCount() - != componentFlatList[ii + 1].GetLibComponent()->GetPartCount() ) + if( componentFlatList[ii].GetLibComponent()->GetUnitCount() + != componentFlatList[ii + 1].GetLibComponent()->GetUnitCount() ) { if( componentFlatList[ii].m_NumRef >= 0 ) tmp << componentFlatList[ii].m_NumRef; @@ -584,7 +584,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( wxArrayString* aMessageList ) error++; } - /* Error if values are different between units, for the same reference */ + // Error if values are different between units, for the same reference int next = ii + 1; if( componentFlatList[ii].CompareValue( componentFlatList[next] ) != 0 ) @@ -592,12 +592,12 @@ int SCH_REFERENCE_LIST::CheckAnnotation( wxArrayString* aMessageList ) msg.Printf( _( "Different values for %s%d%s (%s) and %s%d%s (%s)" ), GetChars( componentFlatList[ii].GetRef() ), componentFlatList[ii].m_NumRef, - GetChars( LIB_COMPONENT::SubReference( + GetChars( LIB_PART::SubReference( componentFlatList[ii].m_Unit ) ), GetChars( componentFlatList[ii].m_Value->GetText() ), GetChars( componentFlatList[next].GetRef() ), componentFlatList[next].m_NumRef, - GetChars( LIB_COMPONENT::SubReference( + GetChars( LIB_PART::SubReference( componentFlatList[next].m_Unit ) ), GetChars( componentFlatList[next].m_Value->GetText() ) ); @@ -617,7 +617,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( wxArrayString* aMessageList ) || ( componentFlatList[ii].GetSheetPath() != componentFlatList[ii + 1].GetSheetPath() ) ) continue; - /* Same time stamp found. */ + // Same time stamp found. wxString full_path; full_path.Printf( wxT( "%s%8.8X" ), @@ -640,7 +640,7 @@ int SCH_REFERENCE_LIST::CheckAnnotation( wxArrayString* aMessageList ) } -SCH_REFERENCE::SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_COMPONENT* aLibComponent, +SCH_REFERENCE::SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_PART* aLibComponent, SCH_SHEET_PATH& aSheetPath ) { wxASSERT( aComponent != NULL && aLibComponent != NULL ); @@ -694,7 +694,7 @@ void SCH_REFERENCE::Split() { m_IsNew = true; - if( !IsPartsLocked() ) + if( !IsUnitsLocked() ) m_Unit = 0x7FFFFFFF; refText.erase( ll ); // delete last char @@ -705,7 +705,7 @@ void SCH_REFERENCE::Split() { m_IsNew = true; - if( !IsPartsLocked() ) + if( !IsUnitsLocked() ) m_Unit = 0x7FFFFFFF; } else diff --git a/eeschema/component_tree_search_container.cpp b/eeschema/component_tree_search_container.cpp index f1613b6586..2c4114fc3f 100644 --- a/eeschema/component_tree_search_container.cpp +++ b/eeschema/component_tree_search_container.cpp @@ -98,8 +98,11 @@ bool COMPONENT_TREE_SEARCH_CONTAINER::scoreComparator( const TREE_NODE* a1, cons } -COMPONENT_TREE_SEARCH_CONTAINER::COMPONENT_TREE_SEARCH_CONTAINER() - : tree( NULL ), libraries_added( 0 ), preselect_unit_number( -1 ) +COMPONENT_TREE_SEARCH_CONTAINER::COMPONENT_TREE_SEARCH_CONTAINER( PART_LIBS* aLibs ) : + tree( NULL ), + libraries_added( 0 ), + preselect_unit_number( -1 ), + m_libs( aLibs ) { } @@ -127,7 +130,7 @@ void COMPONENT_TREE_SEARCH_CONTAINER::SetTree( wxTreeCtrl* aTree ) } -void COMPONENT_TREE_SEARCH_CONTAINER::AddLibrary( CMP_LIBRARY& aLib ) +void COMPONENT_TREE_SEARCH_CONTAINER::AddLibrary( PART_LIB& aLib ) { wxArrayString all_aliases; @@ -139,7 +142,7 @@ void COMPONENT_TREE_SEARCH_CONTAINER::AddLibrary( CMP_LIBRARY& aLib ) void COMPONENT_TREE_SEARCH_CONTAINER::AddAliasList( const wxString& aNodeName, const wxArrayString& aAliasNameList, - CMP_LIBRARY* aOptionalLib ) + PART_LIB* aOptionalLib ) { TREE_NODE* const lib_node = new TREE_NODE( TREE_NODE::TYPE_LIB, NULL, NULL, aNodeName, wxEmptyString, wxEmptyString ); @@ -152,7 +155,7 @@ void COMPONENT_TREE_SEARCH_CONTAINER::AddAliasList( const wxString& aNodeName, if( aOptionalLib ) a = aOptionalLib->FindAlias( aName ); else - a = CMP_LIBRARY::FindLibraryEntry( aName, wxEmptyString ); + a = m_libs->FindLibraryEntry( aName, wxEmptyString ); if( a == NULL ) continue; @@ -186,12 +189,12 @@ void COMPONENT_TREE_SEARCH_CONTAINER::AddAliasList( const wxString& aNodeName, a, a->GetName(), display_info, search_text ); nodes.push_back( alias_node ); - if( a->GetComponent()->IsMulti() ) // Add all units as sub-nodes. + if( a->GetPart()->IsMulti() ) // Add all units as sub-nodes. { - for( int u = 1; u <= a->GetComponent()->GetPartCount(); ++u ) + for( int u = 1; u <= a->GetPart()->GetUnitCount(); ++u ) { wxString unitName = _("Unit"); - unitName += wxT( " " ) + LIB_COMPONENT::SubReference( u, false ); + unitName += wxT( " " ) + LIB_PART::SubReference( u, false ); TREE_NODE* unit_node = new TREE_NODE( TREE_NODE::TYPE_UNIT, alias_node, a, unitName, diff --git a/eeschema/component_tree_search_container.h b/eeschema/component_tree_search_container.h index 19d2a54df6..3ffd94f410 100644 --- a/eeschema/component_tree_search_container.h +++ b/eeschema/component_tree_search_container.h @@ -28,13 +28,14 @@ #include class LIB_ALIAS; -class CMP_LIBRARY; +class PART_LIB; +class PART_LIBS; class wxTreeCtrl; class wxArrayString; // class COMPONENT_TREE_SEARCH_CONTAINER // A container for components that allows to search them matching their name, keywords -// and descripotions, updating a wxTreeCtrl with the results (toplevel nodes: +// and descriptions, updating a wxTreeCtrl with the results (toplevel nodes: // libraries, leafs: components), scored by relevance. // // The scored result list is adpated on each update on the search-term: this allows @@ -42,7 +43,7 @@ class wxArrayString; class COMPONENT_TREE_SEARCH_CONTAINER { public: - COMPONENT_TREE_SEARCH_CONTAINER(); + COMPONENT_TREE_SEARCH_CONTAINER( PART_LIBS* aLibs ); ~COMPONENT_TREE_SEARCH_CONTAINER(); /** Function AddLibrary @@ -51,7 +52,7 @@ public: * * @param aLib containting all the components to be added. */ - void AddLibrary( CMP_LIBRARY& aLib ); + void AddLibrary( PART_LIB& aLib ); /** Function AddComponentList * Add the given list of components, given by name, to be searched. @@ -62,7 +63,7 @@ public: * @param aOptionalLib Library to look up the component names (if NULL: global lookup) */ void AddAliasList( const wxString& aNodeName, const wxArrayString& aAliasNameList, - CMP_LIBRARY* aOptionalLib ); + PART_LIB* aOptionalLib ); /** Function SetPreselectNode * Set the component name to be selected in absence of any search-result. @@ -111,6 +112,8 @@ private: wxString preselect_node_name; int preselect_unit_number; + + PART_LIBS* m_libs; // no ownership }; #endif /* COMPONENT_TREE_SEARCH_CONTAINER_H */ diff --git a/eeschema/database.cpp b/eeschema/database.cpp index 4cf8089364..7a1f67850c 100644 --- a/eeschema/database.cpp +++ b/eeschema/database.cpp @@ -38,25 +38,27 @@ #include -extern void DisplayCmpDocAndKeywords( wxString& Name ); - // Used in DataBaseGetName: this is a callback function for EDA_LIST_DIALOG // to display keywords and description of a component -void DisplayCmpDocAndKeywords( wxString& Name ) +void DisplayCmpDocAndKeywords( wxString& aName, void* aData ) { - LIB_ALIAS* CmpEntry = NULL; + PART_LIBS* libs = (PART_LIBS*) aData; - CmpEntry = CMP_LIBRARY::FindLibraryEntry( Name ); + wxASSERT( libs ); - if( CmpEntry == NULL ) + LIB_ALIAS* part = libs->FindLibraryEntry( aName ); + + if( !part ) return; - Name = wxT( "Description: " ) + CmpEntry->GetDescription(); - Name += wxT( "\nKey Words: " ) + CmpEntry->GetKeyWords(); + aName = wxT( "Description: " ) + part->GetDescription(); + aName += wxT( "\nKey Words: " ) + part->GetKeyWords(); } +#if 0 // not used, should be wxFrame member for KIWAY and PROJECT access. + /* * Displays a list of filtered components found in libraries for selection, * Keys is a list of keywords to filter components which do not match these keywords @@ -75,7 +77,7 @@ wxString DataBaseGetName( EDA_DRAW_FRAME* frame, wxString& Keys, wxString& BufNa Keys.MakeUpper(); /* Review the list of libraries for counting. */ - BOOST_FOREACH( CMP_LIBRARY& lib, CMP_LIBRARY::GetLibraryList() ) + BOOST_FOREACH( PART_LIB& lib, PART_LIB::GetLibraryList() ) { lib.SearchEntryNames( nameList, BufName, Keys ); } @@ -119,6 +121,7 @@ wxString DataBaseGetName( EDA_DRAW_FRAME* frame, wxString& Keys, wxString& BufNa // Show candidate list: wxString cmpname; + EDA_LIST_DIALOG dlg( frame, _( "Select Component" ), headers, nameList, cmpname, DisplayCmpDocAndKeywords, true ); @@ -128,3 +131,4 @@ wxString DataBaseGetName( EDA_DRAW_FRAME* frame, wxString& Keys, wxString& BufNa cmpname = dlg.GetTextSelection(); return cmpname; } +#endif diff --git a/eeschema/dialogs/dialog_bom.cpp b/eeschema/dialogs/dialog_bom.cpp index ba64849867..df07a13d14 100644 --- a/eeschema/dialogs/dialog_bom.cpp +++ b/eeschema/dialogs/dialog_bom.cpp @@ -302,7 +302,7 @@ void DIALOG_BOM::OnRunPlugin( wxCommandEvent& event ) fn = g_RootSheet->GetScreen()->GetFileName(); if( fn.GetPath().IsEmpty() ) - fn.SetPath( wxGetCwd() ); + fn.SetPath( wxPathOnly( Prj().GetProjectFullName() ) ); fn.ClearExt(); wxString fullfilename = fn.GetFullPath(); diff --git a/eeschema/dialogs/dialog_choose_component.cpp b/eeschema/dialogs/dialog_choose_component.cpp index c442a6e0f5..383f7faee4 100644 --- a/eeschema/dialogs/dialog_choose_component.cpp +++ b/eeschema/dialogs/dialog_choose_component.cpp @@ -251,13 +251,13 @@ void DIALOG_CHOOSE_COMPONENT::OnHandlePreviewRepaint( wxPaintEvent& aRepaintEven int unit = 0; LIB_ALIAS* selection = m_search_container->GetSelectedAlias( &unit ); - renderPreview( selection ? selection->GetComponent() : NULL, unit ); + renderPreview( selection ? selection->GetPart() : NULL, unit ); } // Render the preview in our m_componentView. If this gets more complicated, we should // probably have a derived class from wxPanel; but this keeps things local. -void DIALOG_CHOOSE_COMPONENT::renderPreview( LIB_COMPONENT* aComponent, int aUnit ) +void DIALOG_CHOOSE_COMPONENT::renderPreview( LIB_PART* aComponent, int aUnit ) { wxPaintDC dc( m_componentView ); dc.SetBackground( *wxWHITE_BRUSH ); diff --git a/eeschema/dialogs/dialog_choose_component.h b/eeschema/dialogs/dialog_choose_component.h index b8839ccc63..b61b3a2815 100644 --- a/eeschema/dialogs/dialog_choose_component.h +++ b/eeschema/dialogs/dialog_choose_component.h @@ -28,7 +28,7 @@ class COMPONENT_TREE_SEARCH_CONTAINER; class LIB_ALIAS; -class LIB_COMPONENT; +class LIB_PART; class wxTreeItemId; class DIALOG_CHOOSE_COMPONENT : public DIALOG_CHOOSE_COMPONENT_BASE @@ -79,7 +79,7 @@ protected: private: bool updateSelection(); void selectIfValid( const wxTreeItemId& aTreeId ); - void renderPreview( LIB_COMPONENT* aComponent, int aUnit ); + void renderPreview( LIB_PART* aComponent, int aUnit ); COMPONENT_TREE_SEARCH_CONTAINER* const m_search_container; const int m_deMorganConvert; diff --git a/eeschema/dialogs/dialog_edit_component_in_lib.cpp b/eeschema/dialogs/dialog_edit_component_in_lib.cpp index de0ff02b11..1cc0b73aed 100644 --- a/eeschema/dialogs/dialog_edit_component_in_lib.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_lib.cpp @@ -64,7 +64,7 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::initDlg() { m_AliasLocation = -1; - LIB_COMPONENT* component = m_Parent->GetComponent(); + LIB_PART* component = m_Parent->GetCurPart(); if( component == NULL ) { @@ -125,7 +125,7 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnCancelClick( wxCommandEvent& event ) void DIALOG_EDIT_COMPONENT_IN_LIBRARY::InitPanelDoc() { LIB_ALIAS* alias; - LIB_COMPONENT* component = m_Parent->GetComponent(); + LIB_PART* component = m_Parent->GetCurPart(); if( component == NULL ) return; @@ -151,7 +151,7 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::InitPanelDoc() */ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::InitBasicPanel() { - LIB_COMPONENT* component = m_Parent->GetComponent(); + LIB_PART* component = m_Parent->GetCurPart(); if( m_Parent->GetShowDeMorgan() ) m_AsConvertButt->SetValue( true ); @@ -172,10 +172,10 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::InitBasicPanel() m_ShowPinNumButt->SetValue( component->ShowPinNumbers() ); m_ShowPinNameButt->SetValue( component->ShowPinNames() ); m_PinsNameInsideButt->SetValue( component->GetPinNameOffset() != 0 ); - m_SelNumberOfUnits->SetValue( component->GetPartCount() ); + m_SelNumberOfUnits->SetValue( component->GetUnitCount() ); m_SetSkew->SetValue( component->GetPinNameOffset() ); m_OptionPower->SetValue( component->IsPower() ); - m_OptionPartsLocked->SetValue( component->UnitsLocked() && component->GetPartCount() > 1 ); + m_OptionPartsLocked->SetValue( component->UnitsLocked() && component->GetUnitCount() > 1 ); } @@ -184,7 +184,7 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnOkClick( wxCommandEvent& event ) /* Update the doc, keyword and doc filename strings */ int index; LIB_ALIAS* alias; - LIB_COMPONENT* component = m_Parent->GetComponent(); + LIB_PART* component = m_Parent->GetCurPart(); if( component == NULL ) { @@ -248,7 +248,7 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnOkClick( wxCommandEvent& event ) * Obviously, cannot be true if there is only one part */ component->LockUnits( m_OptionPartsLocked->GetValue() ); - if( component->GetPartCount() <= 1 ) + if( component->GetUnitCount() <= 1 ) component->LockUnits( false ); /* Update the footprint filter list */ @@ -265,7 +265,7 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::CopyDocFromRootToAlias( wxCommandEvent& e return; LIB_ALIAS* parent_alias; - LIB_COMPONENT* component = m_Parent->GetComponent(); + LIB_PART* component = m_Parent->GetCurPart(); if( component == NULL ) return; @@ -309,8 +309,8 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::DeleteAllAliasOfPart( wxCommandEvent& eve void DIALOG_EDIT_COMPONENT_IN_LIBRARY::AddAliasOfPart( wxCommandEvent& event ) { wxString aliasname; - LIB_COMPONENT* component = m_Parent->GetComponent(); - CMP_LIBRARY* library = m_Parent->GetLibrary(); + LIB_PART* component = m_Parent->GetCurPart(); + PART_LIB* library = m_Parent->GetCurLib(); if( component == NULL ) return; @@ -371,7 +371,7 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::DeleteAliasOfPart( wxCommandEvent& event } m_PartAliasListCtrl->Delete( m_PartAliasListCtrl->GetSelection() ); - LIB_COMPONENT* component = m_Parent->GetComponent(); + LIB_PART* component = m_Parent->GetCurPart(); if( component ) component->RemoveAlias( aliasname ); @@ -389,16 +389,16 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::DeleteAliasOfPart( wxCommandEvent& event */ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::ChangeNbUnitsPerPackage( int MaxUnit ) { - LIB_COMPONENT* component = m_Parent->GetComponent(); + LIB_PART* part = m_Parent->GetCurPart(); - if( component == NULL || component->GetPartCount() == MaxUnit || MaxUnit < 1 ) + if( !part || part->GetUnitCount() == MaxUnit || MaxUnit < 1 ) return false; - if( MaxUnit < component->GetPartCount() + if( MaxUnit < part->GetUnitCount() && !IsOK( this, _( "Delete extra parts from component?" ) ) ) return false; - component->SetPartCount( MaxUnit ); + part->SetUnitCount( MaxUnit ); return true; } @@ -408,7 +408,7 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::ChangeNbUnitsPerPackage( int MaxUnit ) */ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::SetUnsetConvert() { - LIB_COMPONENT* component = m_Parent->GetComponent(); + LIB_PART* component = m_Parent->GetCurPart(); if( component == NULL || ( m_Parent->GetShowDeMorgan() == component->HasConversion() ) ) return false; @@ -437,13 +437,13 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::SetUnsetConvert() void DIALOG_EDIT_COMPONENT_IN_LIBRARY::BrowseAndSelectDocFile( wxCommandEvent& event ) { PROJECT& prj = Prj(); - SEARCH_STACK& search = prj.SchSearchS(); + SEARCH_STACK* search = prj.SchSearchS(); wxString mask = wxT( "*" ); wxString docpath = prj.GetRString( PROJECT::DOC_PATH ); if( !docpath ) - docpath = search.LastVisitedPath( wxT( "doc" ) ); + docpath = search->LastVisitedPath( wxT( "doc" ) ); wxString fullFileName = EDA_FileSelector( _( "Doc Files" ), docpath, @@ -468,7 +468,8 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::BrowseAndSelectDocFile( wxCommandEvent& e prj.SetRString( PROJECT::DOC_PATH, fn.GetPath() ); - wxString filename = search.FilenameWithRelativePathInSearchList( fullFileName ); + wxString filename = search->FilenameWithRelativePathInSearchList( + fullFileName, wxPathOnly( Prj().GetProjectFullName() ) ); // Filenames are always stored in unix like mode, ie separator "\" is stored as "/" // to ensure files are identical under unices and windows @@ -496,7 +497,7 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::DeleteAllFootprintFilter( wxCommandEvent& void DIALOG_EDIT_COMPONENT_IN_LIBRARY::AddFootprintFilter( wxCommandEvent& event ) { wxString Line; - LIB_COMPONENT* component = m_Parent->GetComponent(); + LIB_PART* component = m_Parent->GetCurPart(); if( component == NULL ) return; @@ -531,7 +532,7 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::AddFootprintFilter( wxCommandEvent& event void DIALOG_EDIT_COMPONENT_IN_LIBRARY::DeleteOneFootprintFilter( wxCommandEvent& event ) { - LIB_COMPONENT* component = m_Parent->GetComponent(); + LIB_PART* component = m_Parent->GetCurPart(); int ii = m_FootprintFilterListBox->GetSelection(); m_FootprintFilterListBox->Delete( ii ); diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp index 0ea32ac16e..4fc45d14db 100644 --- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp @@ -70,7 +70,7 @@ private: SCH_EDIT_FRAME* m_Parent; SCH_COMPONENT* m_Cmp; - LIB_COMPONENT* m_LibEntry; + LIB_PART* m_part; bool m_skipCopyFromPanel; static int s_SelectedRow; @@ -161,7 +161,7 @@ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::DIALOG_EDIT_COMPONENT_IN_SCHEMATIC( wxWindow { m_Parent = (SCH_EDIT_FRAME*) parent; - m_LibEntry = NULL; + m_part = NULL; m_skipCopyFromPanel = false; wxListItem columnLabel; @@ -225,23 +225,27 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyPanelToOptions() #ifndef KICAD_KEEPCASE newname.MakeUpper(); #endif + newname.Replace( wxT( " " ), wxT( "_" ) ); if( newname.IsEmpty() ) { DisplayError( NULL, _( "No Component Name!" ) ); } - else if( newname.CmpNoCase( m_Cmp->m_ChipName ) ) + else if( Cmp_KEEPCASE( newname, m_Cmp->m_part_name ) ) { - if( CMP_LIBRARY::FindLibraryEntry( newname ) == NULL ) + PART_LIBS* libs = Prj().SchLibs(); + + if( libs->FindLibraryEntry( newname ) == NULL ) { - wxString message; - message.Printf( _( "Component [%s] not found!" ), GetChars( newname ) ); - DisplayError( NULL, message ); + wxString msg = wxString::Format( _( + "Component '%s' not found!" ), + GetChars( newname ) ); + DisplayError( this, msg ); } else // Change component from lib! { - m_Cmp->m_ChipName = newname; + m_Cmp->SetPartName( newname, libs ); } } @@ -256,6 +260,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyPanelToOptions() { int unit_selection = unitChoice->GetCurrentSelection() + 1; STATUS_FLAGS flags = m_Cmp->GetFlags(); + m_Cmp->SetUnitSelection( &m_Parent->GetCurrentSheet(), unit_selection ); m_Cmp->SetUnit( unit_selection ); m_Cmp->ClearFlags(); @@ -362,10 +367,10 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event m_FieldsBuf[i].SetTextPosition( m_FieldsBuf[i].GetTextPosition() + m_Cmp->m_Pos ); } - LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( m_Cmp->m_ChipName ); + LIB_PART* entry = Prj().SchLibs()->FindLibPart( m_Cmp->m_part_name ); - if( entry && entry->IsPower() ) - m_FieldsBuf[VALUE].SetText( m_Cmp->m_ChipName ); + if( entry && entry->IsPower() ) + m_FieldsBuf[VALUE].SetText( m_Cmp->m_part_name ); // copy all the fields back, and change the length of m_Fields. m_Cmp->SetFields( m_FieldsBuf ); @@ -553,7 +558,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::InitBuffers( SCH_COMPONENT* aComponent which came from the component. */ - m_LibEntry = CMP_LIBRARY::FindLibraryComponent( m_Cmp->m_ChipName ); + m_part = Prj().SchLibs()->FindLibPart( m_Cmp->m_part_name ); #if 0 && defined(DEBUG) for( int i = 0; iGetFieldCount(); ++i ) @@ -765,7 +770,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copySelectedFieldToPanel() // For power symbols, the value is NOR editable, because value and pin // name must be same and can be edited only in library editor - if( fieldNdx == VALUE && m_LibEntry && m_LibEntry->IsPower() ) + if( fieldNdx == VALUE && m_part && m_part->IsPower() ) fieldValueTextCtrl->Enable( false ); else fieldValueTextCtrl->Enable( true ); @@ -869,7 +874,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyOptionsToPanel() int choiceCount = unitChoice->GetCount(); // Remove non existing choices (choiceCount must be <= number for parts) - int unitcount = m_LibEntry ? m_LibEntry->GetPartCount() : 1; + int unitcount = m_part ? m_part->GetUnitCount() : 1; if( unitcount < 1 ) unitcount = 1; @@ -899,7 +904,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyOptionsToPanel() else { // Show the "Units are not interchangeable" message option? - if( !m_LibEntry || !m_LibEntry->UnitsLocked() ) + if( !m_part || !m_part->UnitsLocked() ) unitsInterchageableLabel->SetLabel( _("Yes") ); else unitsInterchageableLabel->SetLabel( _("No") ); @@ -937,11 +942,11 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyOptionsToPanel() if( m_Cmp->GetConvert() > 1 ) convertCheckBox->SetValue( true ); - if( m_LibEntry == NULL || !m_LibEntry->HasConversion() ) + if( m_part == NULL || !m_part->HasConversion() ) convertCheckBox->Enable( false ); // Set the component's library name. - chipnameTextCtrl->SetValue( m_Cmp->m_ChipName ); + chipnameTextCtrl->SetValue( m_Cmp->m_part_name ); // Set the component's unique ID time stamp. m_textCtrlTimeStamp->SetValue( wxString::Format( wxT("%8.8lX"), @@ -955,53 +960,54 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyOptionsToPanel() */ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::SetInitCmp( wxCommandEvent& event ) { - LIB_COMPONENT* entry; - - if( m_Cmp == NULL ) + if( !m_Cmp ) return; - entry = CMP_LIBRARY::FindLibraryComponent( m_Cmp->m_ChipName ); - - if( entry == NULL ) - return; - - // save old cmp in undo list if not already in edit, or moving ... - if( m_Cmp->m_Flags == 0 ) - m_Parent->SaveCopyInUndoList( m_Cmp, UR_CHANGED ); - - INSTALL_UNBUFFERED_DC( dc, m_Parent->GetCanvas() ); - m_Cmp->Draw( m_Parent->GetCanvas(), &dc, wxPoint( 0, 0 ), g_XorMode ); - - // Initialize fixed field values to default values found in library - // Note: the field texts are not modified because they are set in schematic, - // the text from libraries is most of time a dummy text - // Only VALUE, REFERENCE , FOOTPRINT and DATASHEET are re-initialized - LIB_FIELD& refField = entry->GetReferenceField(); - m_Cmp->GetField( REFERENCE )->SetTextPosition( refField.GetTextPosition() + m_Cmp->m_Pos ); - m_Cmp->GetField( REFERENCE )->ImportValues( refField ); - - LIB_FIELD& valField = entry->GetValueField(); - m_Cmp->GetField( VALUE )->SetTextPosition( valField.GetTextPosition() + m_Cmp->m_Pos ); - m_Cmp->GetField( VALUE )->ImportValues( valField ); - - LIB_FIELD* field = entry->GetField(FOOTPRINT); - if( field && m_Cmp->GetField( FOOTPRINT ) ) + if( LIB_PART* part = Prj().SchLibs()->FindLibPart( m_Cmp->m_part_name ) ) { - m_Cmp->GetField( FOOTPRINT )->SetTextPosition( field->GetTextPosition() + m_Cmp->m_Pos ); - m_Cmp->GetField( FOOTPRINT )->ImportValues( *field ); + // save old cmp in undo list if not already in edit, or moving ... + if( m_Cmp->m_Flags == 0 ) + m_Parent->SaveCopyInUndoList( m_Cmp, UR_CHANGED ); + + INSTALL_UNBUFFERED_DC( dc, m_Parent->GetCanvas() ); + m_Cmp->Draw( m_Parent->GetCanvas(), &dc, wxPoint( 0, 0 ), g_XorMode ); + + // Initialize fixed field values to default values found in library + // Note: the field texts are not modified because they are set in schematic, + // the text from libraries is most of time a dummy text + // Only VALUE, REFERENCE , FOOTPRINT and DATASHEET are re-initialized + LIB_FIELD& refField = part->GetReferenceField(); + + m_Cmp->GetField( REFERENCE )->SetTextPosition( refField.GetTextPosition() + m_Cmp->m_Pos ); + m_Cmp->GetField( REFERENCE )->ImportValues( refField ); + + LIB_FIELD& valField = part->GetValueField(); + + m_Cmp->GetField( VALUE )->SetTextPosition( valField.GetTextPosition() + m_Cmp->m_Pos ); + m_Cmp->GetField( VALUE )->ImportValues( valField ); + + LIB_FIELD* field = part->GetField(FOOTPRINT); + + if( field && m_Cmp->GetField( FOOTPRINT ) ) + { + m_Cmp->GetField( FOOTPRINT )->SetTextPosition( field->GetTextPosition() + m_Cmp->m_Pos ); + m_Cmp->GetField( FOOTPRINT )->ImportValues( *field ); + } + + field = part->GetField(DATASHEET); + + if( field && m_Cmp->GetField( DATASHEET ) ) + { + m_Cmp->GetField( DATASHEET )->SetTextPosition( field->GetTextPosition() + m_Cmp->m_Pos ); + m_Cmp->GetField( DATASHEET )->ImportValues( *field ); + } + + m_Cmp->SetOrientation( CMP_NORMAL ); + + m_Parent->OnModify(); + + m_Cmp->Draw( m_Parent->GetCanvas(), &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); + + EndQuasiModal( 1 ); } - - field = entry->GetField(DATASHEET); - if( field && m_Cmp->GetField( DATASHEET ) ) - { - m_Cmp->GetField( DATASHEET )->SetTextPosition( field->GetTextPosition() + m_Cmp->m_Pos ); - m_Cmp->GetField( DATASHEET )->ImportValues( *field ); - } - - m_Cmp->SetOrientation( CMP_NORMAL ); - - m_Parent->OnModify(); - - m_Cmp->Draw( m_Parent->GetCanvas(), &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); - EndQuasiModal( 1 ); } diff --git a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp index 67d891b23f..31a5615082 100644 --- a/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp +++ b/eeschema/dialogs/dialog_edit_libentry_fields_in_lib.cpp @@ -54,7 +54,7 @@ static int s_SelectedRow; class DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB : public DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE { public: - DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB( LIB_EDIT_FRAME* aParent, LIB_COMPONENT* aLibEntry ); + DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB( LIB_EDIT_FRAME* aParent, LIB_PART* aLibEntry ); //~DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB() {} private: @@ -125,7 +125,7 @@ private: } LIB_EDIT_FRAME* m_parent; - LIB_COMPONENT* m_libEntry; + LIB_PART* m_libEntry; bool m_skipCopyFromPanel; /// a copy of the edited component's LIB_FIELDs @@ -135,12 +135,12 @@ private: void LIB_EDIT_FRAME::InstallFieldsEditorDialog( wxCommandEvent& event ) { - if( m_component == NULL ) + if( !GetCurLib() ) return; m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); - DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB dlg( this, m_component ); + DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB dlg( this, GetCurPart() ); int abort = dlg.ShowQuasiModal(); @@ -156,7 +156,7 @@ void LIB_EDIT_FRAME::InstallFieldsEditorDialog( wxCommandEvent& event ) DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB( LIB_EDIT_FRAME* aParent, - LIB_COMPONENT* aLibEntry ) : + LIB_PART* aLibEntry ) : DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB_BASE( aParent ) { m_parent = aParent; diff --git a/eeschema/dialogs/dialog_eeschema_config.cpp b/eeschema/dialogs/dialog_eeschema_config.cpp index 1e2a85ed9a..aea90816bf 100644 --- a/eeschema/dialogs/dialog_eeschema_config.cpp +++ b/eeschema/dialogs/dialog_eeschema_config.cpp @@ -39,31 +39,44 @@ #include #include #include - #include - - #include + class SCH_EDIT_FRAME; class EDA_DRAW_FRAME; + class DIALOG_EESCHEMA_CONFIG : public DIALOG_EESCHEMA_CONFIG_FBP { public: - DIALOG_EESCHEMA_CONFIG( SCH_EDIT_FRAME* parent, wxFrame* activeWindow ); + DIALOG_EESCHEMA_CONFIG( wxWindow* aParent, + wxString* aCallersProjectSpecificLibPaths, wxArrayString* aCallersLibNames ); private: - SCH_EDIT_FRAME* m_Parent; - bool m_LibListChanged; - bool m_LibPathChanged; - wxString m_UserLibDirBufferImg; + wxString* m_callers_project_specific_lib_paths; + wxArrayString* m_callers_lib_names; + + bool m_lib_list_changed; + bool m_lib_path_changed; + + //------ event handlers, overiding the fbp handlers -------------- - // event handlers, overiding the fbp handlers - void Init(); void OnCloseWindow( wxCloseEvent& event ); + + /* Remove a library to the library list. + * The real list (m_Parent->m_ComponentLibFiles) is not changed, so the change can be canceled + */ void OnRemoveLibClick( wxCommandEvent& event ); + + /* Insert or add a library to the library list: + * The new library is put in list before (insert button) the selection, + * or added (add button) to end of list + * The real list (m_Parent->m_ComponentLibFiles) is not changed, so the change + * can be canceled + */ void OnAddOrInsertLibClick( wxCommandEvent& event ); + void OnAddOrInsertPath( wxCommandEvent& event ); void OnOkClick( wxCommandEvent& event ); void OnCancelClick( wxCommandEvent& event ); @@ -73,59 +86,53 @@ private: }; -DIALOG_EESCHEMA_CONFIG::DIALOG_EESCHEMA_CONFIG( SCH_EDIT_FRAME* aSchFrame, - wxFrame* aParent ) : - DIALOG_EESCHEMA_CONFIG_FBP( aParent ) +DIALOG_EESCHEMA_CONFIG::DIALOG_EESCHEMA_CONFIG( wxWindow* aParent, + wxString* aCallersProjectSpecificLibPaths, wxArrayString* aCallersLibNames ) : + DIALOG_EESCHEMA_CONFIG_FBP( aParent ), + m_callers_project_specific_lib_paths( aCallersProjectSpecificLibPaths ), + m_callers_lib_names( aCallersLibNames ), + m_lib_list_changed( false ), + m_lib_path_changed( false ) { - m_Parent = aSchFrame; + m_ListLibr->InsertItems( *aCallersLibNames, 0 ); - Init(); + // Load user libs paths: + wxArrayString paths; - wxString msg = wxString::Format( - _( "from '%s'" ), - GetChars( Prj().GetProjectFullName() ) ); + SEARCH_STACK::Split( &paths, *aCallersProjectSpecificLibPaths ); + + for( unsigned i=0; iAppend( path ); + } + + // Display actual library paths which come in part from KIFACE::KifaceSearch() + // along with aCallersProjectSpecificLibPaths at the front. + SEARCH_STACK* libpaths = Prj().SchSearchS(); + + DBG( libpaths->Show( __func__ ); ) + + for( unsigned ii = 0; ii < libpaths->GetCount(); ii++ ) + { + m_DefaultLibraryPathslistBox->Append( (*libpaths)[ii] ); + } + + // select the first path after the current project's path + if( libpaths->GetCount() > 1 ) + m_DefaultLibraryPathslistBox->Select( 1 ); + + wxString msg = wxString::Format( _( + "Project '%s'" ), + GetChars( Prj().GetProjectFullName() ) + ); SetTitle( msg ); if( GetSizer() ) GetSizer()->SetSizeHints( this ); -} - - -void DIALOG_EESCHEMA_CONFIG::Init() -{ - wxString msg; - - SetFocus(); - - m_LibListChanged = false; - m_LibPathChanged = false; - m_UserLibDirBufferImg = m_Parent->GetUserLibraryPath(); - - m_ListLibr->InsertItems( m_Parent->GetComponentLibraries(), 0 ); - - // Load user libs paths: - wxStringTokenizer tokenizer( m_UserLibDirBufferImg, wxT( ";\n\r" ) ); - - while( tokenizer.HasMoreTokens() ) - { - wxString path = tokenizer.GetNextToken(); - - if( wxFileName::DirExists( path ) ) - m_listUserPaths->Append( path ); - } - - // Display actual libraries paths: - SEARCH_STACK& libpaths = Prj().SchSearchS(); - - for( unsigned ii = 0; ii < libpaths.GetCount(); ii++ ) - { - m_DefaultLibraryPathslistBox->Append( libpaths[ii] ); - } - - // select the first path after the current path project - if ( libpaths.GetCount() > 1 ) - m_DefaultLibraryPathslistBox->Select( 1 ); m_sdbSizer1OK->SetDefault(); } @@ -160,7 +167,7 @@ void DIALOG_EESCHEMA_CONFIG::OnButtonUpClick( wxCommandEvent& event ) m_ListLibr->SetSelection(jj-1); } - m_LibListChanged = true; + m_lib_list_changed = true; } @@ -194,49 +201,36 @@ void DIALOG_EESCHEMA_CONFIG::OnButtonDownClick( wxCommandEvent& event ) m_ListLibr->SetSelection(jj+1); } - m_LibListChanged = true; + m_lib_list_changed = true; } void DIALOG_EESCHEMA_CONFIG::OnCancelClick( wxCommandEvent& event ) { - SEARCH_STACK& lib_search = Prj().SchSearchS(); - - // Recreate the user lib path - if( m_LibPathChanged ) - { - for( unsigned ii = 0; ii < m_listUserPaths->GetCount(); ii++ ) - lib_search.RemovePaths( m_listUserPaths->GetString(ii) ); - - lib_search.AddPaths( m_Parent->GetUserLibraryPath(), 1 ); - } - EndModal( wxID_CANCEL ); } void DIALOG_EESCHEMA_CONFIG::OnOkClick( wxCommandEvent& event ) { - // Recreate the user lib path - if( m_LibPathChanged ) + // Give caller the changed paths + if( m_lib_path_changed ) { - wxString path; + wxString paths; for( unsigned ii = 0; ii < m_listUserPaths->GetCount(); ii++ ) { if( ii > 0 ) - path << wxT( ";" ); + paths += wxT( ';' ); - path << m_listUserPaths->GetString( ii ); + paths += m_listUserPaths->GetString( ii ); } - m_Parent->SetUserLibraryPath( path ); + *m_callers_project_specific_lib_paths = paths; } - /* Set new active library list if the lib list of if default path list - * was modified - */ - if( m_LibListChanged || m_LibPathChanged ) + // Update caller's lib_names if changed. + if( m_lib_list_changed ) { wxArrayString list; @@ -244,18 +238,9 @@ void DIALOG_EESCHEMA_CONFIG::OnOkClick( wxCommandEvent& event ) list.Add( m_ListLibr->GetString( ii ) ); // Recreate lib list - m_Parent->SetComponentLibraries( list ); - - // take new list in account - m_Parent->LoadLibraries(); - - // Clear (if needed) the current active library in libedit because it could be - // removed from memory - LIB_EDIT_FRAME::EnsureActiveLibExists(); + *m_callers_lib_names = list; } - m_Parent->SaveProjectSettings( false ); - EndModal( wxID_OK ); } @@ -266,9 +251,6 @@ void DIALOG_EESCHEMA_CONFIG::OnCloseWindow( wxCloseEvent& event ) } -/* Remove a library to the library list. - * The real list (m_Parent->m_ComponentLibFiles) is not changed, so the change can be canceled - */ void DIALOG_EESCHEMA_CONFIG::OnRemoveLibClick( wxCommandEvent& event ) { wxArrayInt selections; @@ -278,7 +260,7 @@ void DIALOG_EESCHEMA_CONFIG::OnRemoveLibClick( wxCommandEvent& event ) for( int ii = selections.GetCount()-1; ii >= 0; ii-- ) { m_ListLibr->Delete( selections[ii] ); - m_LibListChanged = true; + m_lib_list_changed = true; } // Select next item after deleted in m_ListLibr @@ -294,21 +276,13 @@ void DIALOG_EESCHEMA_CONFIG::OnRemoveLibClick( wxCommandEvent& event ) } -/* Insert or add a library to the library list: - * The new library is put in list before (insert button) the selection, - * or added (add button) to end of list - * The real list (m_Parent->m_ComponentLibFiles) is not changed, so the change - * can be canceled - */ void DIALOG_EESCHEMA_CONFIG::OnAddOrInsertLibClick( wxCommandEvent& event ) { int ii; wxString libfilename; - wxFileName fn; wxArrayInt selections; PROJECT& prj = Prj(); - SEARCH_STACK& search = prj.SchSearchS(); m_ListLibr->GetSelections( selections ); @@ -319,13 +293,12 @@ void DIALOG_EESCHEMA_CONFIG::OnAddOrInsertLibClick( wxCommandEvent& event ) else ii = 0; - wxString libpath = m_DefaultLibraryPathslistBox->GetStringSelection(); + wxString selection = m_DefaultLibraryPathslistBox->GetStringSelection(); + wxString libpath = Prj().AbsolutePath( selection ); if( !libpath ) { libpath = prj.GetRString( PROJECT::SCH_LIB_PATH ); - if( !libpath ) - libpath = search.LastVisitedPath(); } wxFileDialog filesDialog( this, _( "Library files:" ), libpath, @@ -335,10 +308,12 @@ void DIALOG_EESCHEMA_CONFIG::OnAddOrInsertLibClick( wxCommandEvent& event ) if( filesDialog.ShowModal() != wxID_OK ) return; - wxArrayString filenames; + wxArrayString filenames; filesDialog.GetPaths( filenames ); + wxFileName fn; + for( unsigned jj = 0; jj < filenames.GetCount(); jj++ ) { fn = filenames[jj]; @@ -346,24 +321,15 @@ void DIALOG_EESCHEMA_CONFIG::OnAddOrInsertLibClick( wxCommandEvent& event ) if( jj == 0 ) prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() ); - /* If the library path is already in the library search paths - * list, just add the library name to the list. Otherwise, add - * the library name with the full or relative path. - * the relative path, when possible is preferable, - * because it preserve use of default libraries paths, when the path - * is a sub path of these default paths - */ - libfilename = search.FilenameWithRelativePathInSearchList( fn.GetFullPath() ); - // Remove extension: - fn = libfilename; fn.SetExt( wxEmptyString ); - libfilename = fn.GetFullPath(); + + libfilename = fn.GetName(); // Add or insert new library name, if not already in list if( m_ListLibr->FindString( libfilename, fn.IsCaseSensitive() ) == wxNOT_FOUND ) { - m_LibListChanged = true; + m_lib_list_changed = true; if( event.GetId() == ID_ADD_LIB ) m_ListLibr->Append( libfilename ); @@ -372,8 +338,10 @@ void DIALOG_EESCHEMA_CONFIG::OnAddOrInsertLibClick( wxCommandEvent& event ) } else { - wxString msg = wxT( "<" ) + libfilename + wxT( "> : " ) + - _( "Library already in use" ); + wxString msg = wxString::Format( _( + "'%s' : library already in use" ), + GetChars( libfilename ) + ); DisplayError( this, msg ); } } @@ -383,24 +351,21 @@ void DIALOG_EESCHEMA_CONFIG::OnAddOrInsertLibClick( wxCommandEvent& event ) void DIALOG_EESCHEMA_CONFIG::OnAddOrInsertPath( wxCommandEvent& event ) { PROJECT& prj = Prj(); - SEARCH_STACK& search = Prj().SchSearchS(); - wxString path = prj.GetRString( PROJECT::SCH_LIB_PATH ); - - if( !path ) - path = search.LastVisitedPath(); + wxString abs_path = prj.GetRString( PROJECT::SCH_LIB_PATH ); + wxString path; bool select = EDA_DirectorySelector( _( "Default Path for Libraries" ), - path, wxDD_DEFAULT_STYLE, + abs_path, wxDD_DEFAULT_STYLE, this, wxDefaultPosition ); if( !select ) return; - if( !wxFileName::DirExists( path ) ) // Should not occurs + if( !wxFileName::DirExists( abs_path ) ) // Should not occur return; // Add or insert path if not already in list - if( m_listUserPaths->FindString( path ) == wxNOT_FOUND ) + if( m_listUserPaths->FindString( abs_path ) == wxNOT_FOUND ) { int ipos = m_listUserPaths->GetCount(); @@ -416,43 +381,53 @@ void DIALOG_EESCHEMA_CONFIG::OnAddOrInsertPath( wxCommandEvent& event ) } // Ask the user if this is a relative path - int diag = wxMessageBox( _( "Use a relative path?" ), _( "Path type" ), + int diag = wxMessageBox( _( "Use a relative path?" ), _( "Path type" ), wxYES_NO | wxICON_QUESTION, this ); if( diag == wxYES ) { // Make it relative - wxFileName fn = path; - fn.MakeRelativeTo( wxT(".") ); + wxFileName fn = abs_path; + fn.MakeRelativeTo( wxPathOnly( Prj().GetProjectFullName() ) ); path = fn.GetPathWithSep() + fn.GetFullName(); } + else + path = abs_path; - m_listUserPaths->Insert(path, ipos); - m_LibPathChanged = true; + m_listUserPaths->Insert( path, ipos ); + m_lib_path_changed = true; - search.AddPaths( path, ipos+1 ); - - // Display actual libraries paths: - m_DefaultLibraryPathslistBox->Clear(); - - for( unsigned ii = 0; ii < search.GetCount(); ii++ ) - { - m_DefaultLibraryPathslistBox->Append( search[ii] ); - } + m_DefaultLibraryPathslistBox->InsertItems( 1, &path, ipos+1 ); } else { DisplayError( this, _("Path already in use") ); } - prj.SetRString( PROJECT::SCH_LIB_PATH, path ); + prj.SetRString( PROJECT::SCH_LIB_PATH, abs_path ); +} + + +static void remove_from_listbox( wxListBox* aListBox, const wxString& aText ) +{ + wxArrayString a; + + for( int i=0, cnt = aListBox->GetCount(); iGetString( i ); + + if( item != aText ) + a.Add( item ); + } + + aListBox->Clear(); + + aListBox->InsertItems( a, 0 ); } void DIALOG_EESCHEMA_CONFIG::OnRemoveUserPath( wxCommandEvent& event ) { - SEARCH_STACK& lib_search = Prj().SchSearchS(); - int ii = m_listUserPaths->GetSelection(); if( ii < 0 ) @@ -460,27 +435,23 @@ void DIALOG_EESCHEMA_CONFIG::OnRemoveUserPath( wxCommandEvent& event ) if( ii >= 0 ) { - lib_search.RemovePaths( m_listUserPaths->GetStringSelection() ); + wxString sel = m_listUserPaths->GetStringSelection(); + + remove_from_listbox( m_DefaultLibraryPathslistBox, sel ); m_listUserPaths->Delete( ii ); - m_LibPathChanged = true; - } - - // Display actual libraries paths: - m_DefaultLibraryPathslistBox->Clear(); - - for( unsigned ii = 0; ii < lib_search.GetCount(); ii++ ) - { - m_DefaultLibraryPathslistBox->Append( lib_search[ii] ); + m_lib_path_changed = true; } } -int InvokeEeschemaConfig( SCH_EDIT_FRAME* aEditFrame, wxFrame* aParent ) +bool InvokeEeschemaConfig( wxWindow* aParent, + wxString* aCallersProjectSpecificLibPaths, wxArrayString* aCallersLibNames ) { - DIALOG_EESCHEMA_CONFIG dlg( aEditFrame, aParent ); + DIALOG_EESCHEMA_CONFIG dlg( aParent, + aCallersProjectSpecificLibPaths, aCallersLibNames ); - dlg.ShowModal(); + int ret = dlg.ShowModal(); - return 1; + return wxID_OK == ret; } diff --git a/eeschema/dialogs/dialog_eeschema_config_fbp.fbp b/eeschema/dialogs/dialog_eeschema_config_fbp.fbp index 2062d5e43c..5fe277f65c 100644 --- a/eeschema/dialogs/dialog_eeschema_config_fbp.fbp +++ b/eeschema/dialogs/dialog_eeschema_config_fbp.fbp @@ -1,8 +1,8 @@ - + - + C++ 1 source_name @@ -16,9 +16,9 @@ none 1 dialog_eeschema_config - + . - + 1 1 1 @@ -29,67 +29,67 @@ 0 wxAUI_MGR_DEFAULT - + wxBOTH - + 1 1 impl_virtual - - - + + + 0 wxID_ANY - - + + DIALOG_EESCHEMA_CONFIG_FBP - + -1,-1 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h - - - - - - - - - - - - - - + + + + + + + + + + + + + + OnCloseWindow - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + bMainSizer wxVERTICAL none @@ -98,7 +98,7 @@ wxEXPAND 2 - + bSizerUpper wxVERTICAL none @@ -111,78 +111,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Component library files - + 0 - - + + 0 - + 1 m_staticTextLibsList 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -190,7 +190,7 @@ wxEXPAND 1 - + bSizerLibsChoice wxHORIZONTAL none @@ -203,83 +203,83 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 - + 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - + + 0 400,250 1 m_ListLibr 1 - - + + protected 1 - + Resizable 1 - + wxLB_EXTENDED|wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE - + 0 List of active library files. Only library files in this list are loaded by Eeschema. The order of this list is important: Eeschema searchs for a given component using this list order priority. - + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - + + + + + + + + + + + + + + OnFilesListClick OnFilesListClick - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -287,7 +287,7 @@ wxALIGN_CENTER_VERTICAL|wxALL 0 - + bRightSizer wxVERTICAL none @@ -300,17 +300,17 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 0 @@ -318,65 +318,65 @@ 0 Left 1 - + 1 - + 0 0 ID_ADD_LIB Add - + 0 - - + + 0 - + 1 m_buttonAddLib 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 Add a new library after the selected library, and load it - + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnAddOrInsertLibClick - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -388,17 +388,17 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 0 @@ -406,65 +406,65 @@ 0 Left 1 - + 1 - + 0 0 wxID_ANY Insert - + 0 - - + + 0 - + 1 m_buttonIns 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 Add a new library before the selected library, and load it - + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnAddOrInsertLibClick - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -476,17 +476,17 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 0 @@ -494,65 +494,65 @@ 0 Left 1 - + 1 - + 0 0 ID_REMOVE_LIB Remove - + 0 - - + + 0 - + 1 m_buttonRemoveLib 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 Unload the selected library - + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnRemoveLibClick - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -564,17 +564,17 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 0 @@ -582,65 +582,65 @@ 0 Left 1 - + 1 - + 0 0 wxID_ANY Up - + 0 - - + + 0 - + 1 m_buttonUp 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnButtonUpClick - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -652,17 +652,17 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 0 @@ -670,65 +670,65 @@ 0 Left 1 - + 1 - + 0 0 wxID_ANY Down - + 0 - - + + 0 - + 1 m_buttonDown 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnButtonDownClick - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -742,7 +742,7 @@ wxEXPAND 1 - + bSizerMiddle wxVERTICAL none @@ -755,78 +755,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY User defined search path - + 0 - - + + 0 - + 1 m_staticTextPaths 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -834,7 +834,7 @@ wxEXPAND 1 - + bSizerPathsChoice wxHORIZONTAL none @@ -847,83 +847,83 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 - + 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - + + 0 400,90 1 m_listUserPaths 1 - - + + protected 1 - + Resizable 1 - + wxLB_HSCROLL|wxLB_NEEDED_SB|wxLB_SINGLE - + 0 Additional paths used in this project. The priority is higher than default KiCad paths. - + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -931,7 +931,7 @@ wxALIGN_CENTER_VERTICAL|wxALL 0 - + bUserPathsButtonsSizer wxVERTICAL none @@ -944,17 +944,17 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 0 @@ -962,65 +962,65 @@ 0 Left 1 - + 1 - + 0 0 ID_LIB_PATH_SEL Add - + 0 - - + + 0 - + 1 m_buttonAddPath 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnAddOrInsertPath - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -1032,17 +1032,17 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 0 @@ -1050,65 +1050,65 @@ 0 Left 1 - + 1 - + 0 0 wxID_INSERT_PATH Insert - + 0 - - + + 0 - + 1 m_buttonInsPath 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnAddOrInsertPath - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -1120,17 +1120,17 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 0 @@ -1138,65 +1138,65 @@ 0 Left 1 - + 1 - + 0 0 wxID_REMOVE_PATH Remove - + 0 - - + + 0 - + 1 m_buttonRemovePath 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - + + wxFILTER_NONE wxDefaultValidator - - - - + + + + OnRemoveUserPath - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -1210,7 +1210,7 @@ wxEXPAND 1 - + bSizerLower wxVERTICAL none @@ -1223,78 +1223,78 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY Current search path list - + 0 - - + + 0 - + 1 m_staticTextPathlist 1 - - + + protected 1 - + Resizable 1 - - - + + + 0 - - - - + + + + -1 - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -1306,83 +1306,83 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 - + 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - + + 0 -1,-1 1 m_DefaultLibraryPathslistBox 1 - - + + protected 1 - + Resizable 1 - + wxLB_NEEDED_SB - + 0 System and user paths used to search and load library files and component doc files. Sorted by decreasing priority order. - + wxFILTER_NONE wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1396,76 +1396,76 @@ 1 1 1 - - - - - - - + + + + + + + 1 0 1 - + 1 0 Dock 0 Left 1 - + 1 - + 0 0 wxID_ANY - + 0 - - + + 0 - + 1 m_staticline3 1 - - + + protected 1 - + Resizable 1 - + wxLI_HORIZONTAL - + 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1481,17 +1481,17 @@ 1 0 0 - + m_sdbSizer1 public - + OnCancelClick - - - + + + OnOkClick - - + + diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp index 9e4bf1aae4..90d03494cf 100644 --- a/eeschema/dialogs/dialog_erc.cpp +++ b/eeschema/dialogs/dialog_erc.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -134,14 +135,12 @@ void DIALOG_ERC::OnCloseErcDialog( wxCloseEvent& event ) } -/* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_RESET_MATRIX */ void DIALOG_ERC::OnResetMatrixClick( wxCommandEvent& event ) { ResetDefaultERCDiag( event ); } -/* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_ERC_CMP */ void DIALOG_ERC::OnErcCmpClick( wxCommandEvent& event ) { wxBusyCursor(); @@ -155,7 +154,6 @@ void DIALOG_ERC::OnErcCmpClick( wxCommandEvent& event ) m_MessagesList->AppendText( messageList[ii] ); } -// Single click on a marker info: void DIALOG_ERC::OnLeftClickMarkersList( wxCommandEvent& event ) { m_lastMarkerFound = NULL; @@ -209,8 +207,7 @@ void DIALOG_ERC::OnLeftClickMarkersList( wxCommandEvent& event ) m_parent->RedrawScreen( marker->m_Pos, false); } -// Double click on a marker info: -// Close the dialog and jump to the selected marker + void DIALOG_ERC::OnLeftDblClickMarkersList( wxCommandEvent& event ) { // Remember: OnLeftClickMarkersList was called just berfore @@ -231,8 +228,6 @@ void DIALOG_ERC::OnLeftDblClickMarkersList( wxCommandEvent& event ) } -/* Build or rebuild the panel showing the ERC conflict matrix - */ void DIALOG_ERC::ReBuildMatrixPanel() { // Try to know the size of bitmap button used in drc matrix @@ -325,10 +320,6 @@ void DIALOG_ERC::ReBuildMatrixPanel() } -/* - * Function DisplayERC_MarkersList - * read the schematic and display the list of ERC markers - */ void DIALOG_ERC::DisplayERC_MarkersList() { SCH_SHEET_LIST sheetList; @@ -358,8 +349,6 @@ void DIALOG_ERC::DisplayERC_MarkersList() } -/* Resets the default values of the ERC matrix. - */ void DIALOG_ERC::ResetDefaultERCDiag( wxCommandEvent& event ) { memcpy( DiagErc, DefaultDiagErc, sizeof(DiagErc) ); @@ -367,8 +356,6 @@ void DIALOG_ERC::ResetDefaultERCDiag( wxCommandEvent& event ) } -/* Change the error level for the pressed button, on the matrix table - */ void DIALOG_ERC::ChangeErrorLevel( wxCommandEvent& event ) { int id, level, ii, x, y; @@ -426,9 +413,9 @@ void DIALOG_ERC::TestErc( wxArrayString* aMessagesList ) m_writeErcFile = m_WriteResultOpt->GetValue(); - /* Build the whole sheet list in hierarchy (sheet, not screen) */ + // Build the whole sheet list in hierarchy (sheet, not screen) SCH_SHEET_LIST sheets; - sheets.AnnotatePowerSymbols(); + sheets.AnnotatePowerSymbols( Prj().SchLibs() ); if( m_parent->CheckAnnotate( aMessagesList, false ) ) { diff --git a/eeschema/dialogs/dialog_lib_edit_pin.cpp b/eeschema/dialogs/dialog_lib_edit_pin.cpp index f23ea1bc3b..ff4ecac8ef 100644 --- a/eeschema/dialogs/dialog_lib_edit_pin.cpp +++ b/eeschema/dialogs/dialog_lib_edit_pin.cpp @@ -48,7 +48,7 @@ void DIALOG_LIB_EDIT_PIN::OnPaintShowPanel( wxPaintEvent& event ) // In fact m_dummyPin should not have a parent, but draw functions need a parent // to know some options, about pin texts LIB_EDIT_FRAME* libframe = (LIB_EDIT_FRAME*) GetParent(); - m_dummyPin->SetParent( libframe->GetComponent() ); + m_dummyPin->SetParent( libframe->GetCurPart() ); // Calculate a suitable scale to fit the available draw area EDA_RECT bBox = m_dummyPin->GetBoundingBox(); diff --git a/eeschema/dialogs/dialog_lib_new_component.h b/eeschema/dialogs/dialog_lib_new_component.h index dfbad6b171..33c87ad2bd 100644 --- a/eeschema/dialogs/dialog_lib_new_component.h +++ b/eeschema/dialogs/dialog_lib_new_component.h @@ -25,7 +25,7 @@ public: wxString GetReference( void ) { return m_textReference->GetValue(); } void SetPartCount( int count ) { m_spinPartCount->SetValue( count ); } - int GetPartCount( void ) { return m_spinPartCount->GetValue(); } + int GetUnitCount( void ) { return m_spinPartCount->GetValue(); } void SetAlternateBodyStyle( bool enable ) { diff --git a/eeschema/dialogs/dialog_netlist.cpp b/eeschema/dialogs/dialog_netlist.cpp index 83bc84dfbe..70e99497e1 100644 --- a/eeschema/dialogs/dialog_netlist.cpp +++ b/eeschema/dialogs/dialog_netlist.cpp @@ -613,7 +613,7 @@ void NETLIST_DIALOG::GenNetlist( wxCommandEvent& event ) fn.SetExt( fileExt ); if( fn.GetPath().IsEmpty() ) - fn.SetPath( wxGetCwd() ); + fn.SetPath( wxPathOnly( Prj().GetProjectFullName() ) ); wxString fullpath = fn.GetFullPath(); diff --git a/eeschema/edit_component_in_schematic.cpp b/eeschema/edit_component_in_schematic.cpp index e9e508eda3..4a2e47ec92 100644 --- a/eeschema/edit_component_in_schematic.cpp +++ b/eeschema/edit_component_in_schematic.cpp @@ -53,18 +53,20 @@ void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField ) wxCHECK_RET( component != NULL && component->Type() == SCH_COMPONENT_T, wxT( "Invalid schematic field parent item." ) ); - LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( component->GetLibName() ); + LIB_PART* part = Prj().SchLibs()->FindLibPart( component->GetPartName() ); - wxCHECK_RET( entry != NULL, wxT( "Library entry for component <" ) + - component->GetLibName() + wxT( "> could not be found." ) ); + wxCHECK_RET( part, wxT( "Library part for component <" ) + + component->GetPartName() + wxT( "> could not be found." ) ); fieldNdx = aField->GetId(); - if( fieldNdx == VALUE && entry->IsPower() ) + if( fieldNdx == VALUE && part->IsPower() ) { - wxString msg; - msg.Printf( _( "%s is a power component and it's value cannot be modified!\n\nYou must \ -create a new power component with the new value." ), GetChars( entry->GetName() ) ); + wxString msg = wxString::Format( _( + "%s is a power component and it's value cannot be modified!\n\n" + "You must create a new power component with the new value." ), + GetChars( part->GetName() ) + ); DisplayInfoMessage( this, msg ); return; } diff --git a/eeschema/eelibs_read_libraryfiles.cpp b/eeschema/eelibs_read_libraryfiles.cpp index 036599a827..72afe1389f 100644 --- a/eeschema/eelibs_read_libraryfiles.cpp +++ b/eeschema/eelibs_read_libraryfiles.cpp @@ -16,116 +16,3 @@ #include - -void SCH_EDIT_FRAME::LoadLibraries() -{ - size_t ii; - wxFileName fn; - wxString msg, tmp, errMsg; - wxString libraries_not_found; - wxArrayString sortOrder; - SEARCH_STACK& lib_search = Prj().SchSearchS(); - -#if defined(DEBUG) && 1 - lib_search.Show( __func__ ); -#endif - - CMP_LIBRARY_LIST::iterator i = CMP_LIBRARY::GetLibraryList().begin(); - - // Free the unwanted libraries but keep the cache library. - while( i < CMP_LIBRARY::GetLibraryList().end() ) - { - if( i->IsCache() ) - { - i++; - continue; - } - - DBG(printf( "ll:%s\n", TO_UTF8( i->GetName() ) );) - - if( m_componentLibFiles.Index( i->GetName(), false ) == wxNOT_FOUND ) - i = CMP_LIBRARY::GetLibraryList().erase( i ); - else - i++; - } - - // Load missing libraries. - for( ii = 0; ii < m_componentLibFiles.GetCount(); ii++ ) - { - fn.Clear(); - fn.SetName( m_componentLibFiles[ii] ); - fn.SetExt( SchematicLibraryFileExtension ); - - // Skip if the file name is not valid.. - if( !fn.IsOk() ) - continue; - - if( !fn.FileExists() ) - { - tmp = lib_search.FindValidPath( fn.GetFullPath() ); - - if( !tmp ) - { - libraries_not_found += fn.GetName() + _( "\n" ); - continue; - } - } - else - { - tmp = fn.GetFullPath(); - } - - // Loaded library statusbar message - fn = tmp; - - if( CMP_LIBRARY::AddLibrary( fn, errMsg ) ) - { - msg.Printf( _( "Library '%s' loaded" ), GetChars( tmp ) ); - sortOrder.Add( fn.GetName() ); - } - else - { - wxString prompt; - - prompt.Printf( _( "Component library '%s' failed to load.\nError: %s" ), - GetChars( fn.GetFullPath() ), - GetChars( errMsg ) ); - DisplayError( this, prompt ); - msg.Printf( _( "Library '%s' error!" ), GetChars( tmp ) ); - } - - PrintMsg( msg ); - } - - // Print the libraries not found - if( !libraries_not_found.IsEmpty() ) - { - // parent of this dialog cannot be NULL since that breaks the Kiway() chain. - HTML_MESSAGE_BOX dialog( this, _("Files not found") ); - - dialog.MessageSet( _( "The following libraries could not be found:" ) ); - dialog.ListSet( libraries_not_found ); - libraries_not_found.empty(); - dialog.ShowModal(); - } - - // Put the libraries in the correct order. - CMP_LIBRARY::SetSortOrder( sortOrder ); - CMP_LIBRARY::GetLibraryList().sort(); - -#if 0 && defined(__WXDEBUG__) - wxLogDebug( wxT( "LoadLibraries() requested component library sort order:" ) ); - - for( size_t i = 0; i < sortOrder.GetCount(); i++ ) - wxLogDebug( wxT( " " ) + sortOrder[i] ); - - wxLogDebug( wxT( "Real component library sort order:" ) ); - - for ( i = CMP_LIBRARY::GetLibraryList().begin(); - i < CMP_LIBRARY::GetLibraryList().end(); i++ ) - wxLogDebug( wxT( " " ) + i->GetName() ); - - wxLogDebug( wxT( "end LoadLibraries ()" ) ); -#endif -} - diff --git a/eeschema/eeschema.cpp b/eeschema/eeschema.cpp index 52da445fd0..eb60af31e5 100644 --- a/eeschema/eeschema.cpp +++ b/eeschema/eeschema.cpp @@ -70,10 +70,7 @@ static struct IFACE : public KIFACE_I bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ); - void OnKifaceEnd( PGM_BASE* aProgram ) - { - end_common(); - } + void OnKifaceEnd( PGM_BASE* aProgram ); wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 ) { @@ -83,11 +80,6 @@ static struct IFACE : public KIFACE_I { SCH_EDIT_FRAME* frame = new SCH_EDIT_FRAME( aKiway, aParent ); - frame->Zoom_Automatique( true ); - - // Read a default config file in case no project given on command line. - frame->LoadProjectFile( wxEmptyString, true ); - if( Kiface().IsSingle() ) { // only run this under single_top, not under a project manager. @@ -162,6 +154,62 @@ PGM_BASE& Pgm() } +static EDA_COLOR_T s_layerColor[NB_SCH_LAYERS]; + +EDA_COLOR_T GetLayerColor( LayerNumber aLayer ) +{ + wxASSERT( unsigned( aLayer ) < DIM( s_layerColor ) ); + return s_layerColor[aLayer]; +} + +void SetLayerColor( EDA_COLOR_T aColor, int aLayer ) +{ + wxASSERT( unsigned( aLayer ) < DIM( s_layerColor ) ); + s_layerColor[aLayer] = aColor; +} + + +static PARAM_CFG_ARRAY& cfg_params() +{ + static PARAM_CFG_ARRAY ca; + + if( !ca.size() ) + { + // These are KIFACE specific, they need to be loaded once when the + // eeschema KIFACE comes in. + +#define CLR(x, y, z) ca.push_back( new PARAM_CFG_SETCOLOR( true, wxT( x ), &s_layerColor[y], z )); + + CLR( "ColorWireEx", LAYER_WIRE, GREEN ) + CLR( "ColorBusEx", LAYER_BUS, BLUE ) + CLR( "ColorConnEx", LAYER_JUNCTION, GREEN ) + CLR( "ColorLLabelEx", LAYER_LOCLABEL, BLACK ) + CLR( "ColorHLabelEx", LAYER_HIERLABEL, BROWN ) + CLR( "ColorGLabelEx", LAYER_GLOBLABEL, RED ) + CLR( "ColorPinNumEx", LAYER_PINNUM, RED ) + CLR( "ColorPinNameEx", LAYER_PINNAM, CYAN ) + CLR( "ColorFieldEx", LAYER_FIELDS, MAGENTA ) + CLR( "ColorReferenceEx", LAYER_REFERENCEPART, CYAN ) + CLR( "ColorValueEx", LAYER_VALUEPART, CYAN ) + CLR( "ColorNoteEx", LAYER_NOTES, LIGHTBLUE ) + CLR( "ColorBodyEx", LAYER_DEVICE, RED ) + CLR( "ColorBodyBgEx", LAYER_DEVICE_BACKGROUND,LIGHTYELLOW ) + CLR( "ColorNetNameEx", LAYER_NETNAM, DARKGRAY ) + CLR( "ColorPinEx", LAYER_PIN, RED ) + CLR( "ColorSheetEx", LAYER_SHEET, MAGENTA ) + CLR( "ColorSheetFileNameEx", LAYER_SHEETFILENAME, BROWN ) + CLR( "ColorSheetNameEx", LAYER_SHEETNAME, CYAN ) + CLR( "ColorSheetLabelEx", LAYER_SHEETLABEL, BROWN ) + CLR( "ColorNoConnectEx", LAYER_NOCONNECT, BLUE ) + CLR( "ColorErcWEx", LAYER_ERC_WARN, GREEN ) + CLR( "ColorErcEEx", LAYER_ERC_ERR, RED ) + CLR( "ColorGridEx", LAYER_GRID, DARKGRAY ) + } + + return ca; +} + + bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) { // This is process level, not project level, initialization of the DSO. @@ -179,6 +227,16 @@ bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) // display the real hotkeys in menus or tool tips ReadHotkeyConfig( wxT("SchematicFrame"), s_Eeschema_Hokeys_Descr ); + wxConfigLoadSetups( KifaceSettings(), cfg_params() ); + return true; } + +void IFACE::OnKifaceEnd( PGM_BASE* aProgram ) +{ + wxConfigSaveSetups( KifaceSettings(), cfg_params() ); + + end_common(); +} + diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index 219fad72c4..a7dc88f874 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -55,8 +56,6 @@ #define FR_HISTORY_LIST_CNT 10 ///< Maximum number of find and replace strings. -static EDA_COLOR_T s_layerColor[NB_SCH_LAYERS]; - /// The width to draw busses that do not have a specific width static int s_defaultBusThickness; @@ -131,18 +130,6 @@ void SetDefaultPinLength( int aLength ) } -EDA_COLOR_T GetLayerColor( LayerNumber aLayer ) -{ - return s_layerColor[aLayer]; -} - - -void SetLayerColor( EDA_COLOR_T aColor, int aLayer ) -{ - s_layerColor[aLayer] = aColor; -} - - // Color to draw selected items EDA_COLOR_T GetItemSelectedColor() { @@ -160,10 +147,31 @@ EDA_COLOR_T GetInvisibleItemColor() void LIB_EDIT_FRAME::InstallConfigFrame( wxCommandEvent& event ) { - SCH_EDIT_FRAME* frame = (SCH_EDIT_FRAME*) Kiway().Player( FRAME_SCH, false ); - wxASSERT( frame ); + // Identical to SCH_EDIT_FRAME::InstallConfigFrame() - InvokeEeschemaConfig( frame, this ); + PROJECT* prj = &Prj(); + wxArrayString lib_names; + wxString lib_paths; + + try + { + PART_LIBS::LibNamesAndPaths( prj, false, &lib_paths, &lib_names ); + } + catch( const IO_ERROR& ioe ) + { + DBG(printf( "%s: %s\n", __func__, TO_UTF8( ioe.errorText ) );) + return; + } + + if( InvokeEeschemaConfig( this, &lib_paths, &lib_names ) ) + { + // save the [changed] settings. + PART_LIBS::LibNamesAndPaths( prj, true, &lib_paths, &lib_names ); + + // Force a reload of the PART_LIBS + prj->SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL ); + prj->SetElem( PROJECT::ELEM_SCH_SEARCH_STACK, NULL ); + } } @@ -191,6 +199,10 @@ void LIB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) case ID_CONFIG_READ: { +#if 0 // This is confusing. From the library parts editor, we trigger the loading + // of configuration information into the schematic editor? Makes no more sense + // than me storing my old newspapers in your garage. + fn = g_RootSheet->GetScreen()->GetFileName(); fn.SetExt( ProjectFileExtension ); @@ -201,11 +213,14 @@ void LIB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) if( dlg.ShowModal() == wxID_CANCEL ) break; - schFrame->LoadProjectFile( dlg.GetPath(), true ); + wxString foreign_pro = dlg.GetPath(); + + Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_SCH, + GetProjectFileParametersList(), foreign_pro ); +#endif } break; - // Hotkey IDs case ID_PREFERENCES_HOTKEY_SHOW_EDITOR: InstallHotkeyFrame( this, s_Eeschema_Hokeys_Descr ); @@ -240,7 +255,41 @@ void SCH_EDIT_FRAME::OnColorConfig( wxCommandEvent& aEvent ) void SCH_EDIT_FRAME::InstallConfigFrame( wxCommandEvent& event ) { - InvokeEeschemaConfig( this, this ); + // Identical to LIB_EDIT_FRAME::InstallConfigFrame() + + PROJECT* prj = &Prj(); + wxArrayString lib_names; + wxString lib_paths; + + try + { + PART_LIBS::LibNamesAndPaths( prj, false, &lib_paths, &lib_names ); + } + catch( const IO_ERROR& ioe ) + { + DBG(printf( "%s: %s\n", __func__, TO_UTF8( ioe.errorText ) );) + return; + } + + if( InvokeEeschemaConfig( this, &lib_paths, &lib_names ) ) + { + // save the [changed] settings. + PART_LIBS::LibNamesAndPaths( prj, true, &lib_paths, &lib_names ); + +#if defined(DEBUG) + printf( "%s: lib_names:\n", __func__ ); + for( unsigned i=0; iSetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL ); + prj->SetElem( PROJECT::ELEM_SCH_SEARCH_STACK, NULL ); + } } @@ -267,7 +316,12 @@ void SCH_EDIT_FRAME::Process_Config( wxCommandEvent& event ) if( dlg.ShowModal() == wxID_CANCEL ) break; - LoadProjectFile( dlg.GetPath(), true ); + wxString chosen = dlg.GetPath(); + + if( chosen == Prj().GetProjectFullName() ) + LoadProjectFile(); + else + Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_SCH, GetProjectFileParametersList() ); } break; @@ -315,8 +369,8 @@ void SCH_EDIT_FRAME::OnSetOptions( wxCommandEvent& event ) dlg.SetRepeatVertical( g_RepeatStep.y ); dlg.SetRepeatLabel( g_RepeatDeltaLabel ); dlg.SetAutoSaveInterval( GetAutoSaveInterval() / 60 ); - dlg.SetRefIdSeparator( LIB_COMPONENT::GetSubpartIdSeparator( ), - LIB_COMPONENT::GetSubpartFirstId() ); + dlg.SetRefIdSeparator( LIB_PART::GetSubpartIdSeparator( ), + LIB_PART::GetSubpartFirstId() ); dlg.SetShowGrid( IsGridVisible() ); dlg.SetShowHiddenPins( m_showAllPins ); @@ -349,11 +403,10 @@ void SCH_EDIT_FRAME::OnSetOptions( wxCommandEvent& event ) int sep, firstId; dlg.GetRefIdSeparator( sep, firstId); - - if( sep != (int)LIB_COMPONENT::GetSubpartIdSeparator() - || firstId != (int)LIB_COMPONENT::GetSubpartFirstId() ) + if( sep != (int)LIB_PART::GetSubpartIdSeparator() || + firstId != (int)LIB_PART::GetSubpartFirstId() ) { - LIB_COMPONENT::SetSubpartIdNotation( sep, firstId ); + LIB_PART::SetSubpartIdNotation( sep, firstId ); SaveProjectSettings( true ); } @@ -408,17 +461,19 @@ PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetProjectFileParametersList() &BASE_SCREEN::m_PageLayoutDescrFileName ) ); m_projectFileParams.push_back( new PARAM_CFG_INT( wxT( "SubpartIdSeparator" ), - LIB_COMPONENT::SubpartIdSeparatorPtr(), + LIB_PART::SubpartIdSeparatorPtr(), 0, 0, 126 ) ); m_projectFileParams.push_back( new PARAM_CFG_INT( wxT( "SubpartFirstId" ), - LIB_COMPONENT::SubpartFirstIdPtr(), + LIB_PART::SubpartFirstIdPtr(), 'A', '1', 'z' ) ); + /* moved to library load/save specific code m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "LibDir" ), &m_userLibraryPath ) ); m_projectFileParams.push_back( new PARAM_CFG_LIBNAME_LIST( wxT( "LibName" ), &m_componentLibFiles, GROUP_SCH_LIBS ) ); + */ m_projectFileParams.push_back( new PARAM_CFG_WXSTRING( wxT( "NetFmtName" ), &m_netListFormat) ); @@ -445,52 +500,23 @@ PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetProjectFileParametersList() } -bool SCH_EDIT_FRAME::LoadProjectFile( const wxString& aFileName, bool aForceReread ) +bool SCH_EDIT_FRAME::LoadProjectFile() { - wxFileName fn; - bool isRead = true; - wxArrayString liblist_tmp = m_componentLibFiles; - PROJECT& prj = Prj(); - - if( aFileName.IsEmpty() ) - fn = g_RootSheet->GetScreen()->GetFileName(); - else - fn = aFileName; - - m_componentLibFiles.Clear(); - - // Change the schematic file extension (.sch) to the project file - // extension (.pro). - fn.SetExt( ProjectFileExtension ); - - if( !prj.ConfigLoad( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP_SCH, - GetProjectFileParametersList(), !aForceReread ) ) - { - m_componentLibFiles = liblist_tmp; - isRead = false; - } + bool isRead = Prj().ConfigLoad( Kiface().KifaceSearch(), + GROUP_SCH, GetProjectFileParametersList() ); // Verify some values, because the config file can be edited by hand, // and have bad values: - LIB_COMPONENT::SetSubpartIdNotation( LIB_COMPONENT::GetSubpartIdSeparator(), - LIB_COMPONENT::GetSubpartFirstId() ); + LIB_PART::SetSubpartIdNotation( + LIB_PART::GetSubpartIdSeparator(), + LIB_PART::GetSubpartFirstId() ); // Load the page layout decr file, from the filename stored in // BASE_SCREEN::m_PageLayoutDescrFileName, read in config project file // If empty, the default descr is loaded WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance(); - pglayout.SetPageLayout(BASE_SCREEN::m_PageLayoutDescrFileName); - // libraries in the *.pro file take precedence over standard library search paths, - // but not over the directory of the project, which is at index 0. - prj.SchSearchS().AddPaths( m_userLibraryPath, 1 ); - - // If the list is empty, force loading the standard power symbol library. - if( m_componentLibFiles.GetCount() == 0 ) - m_componentLibFiles.Add( wxT( "power" ) ); - - LoadLibraries(); - GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); + pglayout.SetPageLayout( BASE_SCREEN::m_PageLayoutDescrFileName ); return isRead; } @@ -518,8 +544,7 @@ void SCH_EDIT_FRAME::SaveProjectSettings( bool aAskForSave ) fn = dlg.GetPath(); } - prj.ConfigSave( Kiface().KifaceSearch(), - fn.GetFullPath(), GROUP_SCH, GetProjectFileParametersList() ); + prj.ConfigSave( Kiface().KifaceSearch(), GROUP_SCH, GetProjectFileParametersList() ); } @@ -549,7 +574,7 @@ static const wxChar FieldNamesEntry[] = wxT( "FieldNames" ); static const wxChar SimulatorCommandEntry[] = wxT( "SimCmdLine" ); -PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetConfigurationSettings( void ) +PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetConfigurationSettings() { if( !m_configSettings.empty() ) return m_configSettings; @@ -562,79 +587,6 @@ PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetConfigurationSettings( void ) &m_drawBgColor, WHITE ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorWireEx" ), - &s_layerColor[LAYER_WIRE], - GREEN ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorBusEx" ), - &s_layerColor[LAYER_BUS], - BLUE ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorConnEx" ), - &s_layerColor[LAYER_JUNCTION], - GREEN ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorLLabelEx" ), - &s_layerColor[LAYER_LOCLABEL], - BLACK ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorHLabelEx" ), - &s_layerColor[LAYER_HIERLABEL], - BROWN ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorGLabelEx" ), - &s_layerColor[LAYER_GLOBLABEL], - RED ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorPinNumEx" ), - &s_layerColor[LAYER_PINNUM], - RED ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorPinNameEx" ), - &s_layerColor[LAYER_PINNAM], - CYAN ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorFieldEx" ), - &s_layerColor[LAYER_FIELDS], - MAGENTA ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorReferenceEx" ), - &s_layerColor[LAYER_REFERENCEPART], - CYAN ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorValueEx" ), - &s_layerColor[LAYER_VALUEPART], - CYAN ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorNoteEx" ), - &s_layerColor[LAYER_NOTES], - LIGHTBLUE ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorBodyEx" ), - &s_layerColor[LAYER_DEVICE], - RED ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorBodyBgEx" ), - &s_layerColor[LAYER_DEVICE_BACKGROUND], - LIGHTYELLOW ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorNetNameEx" ), - &s_layerColor[LAYER_NETNAM], - DARKGRAY ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorPinEx" ), - &s_layerColor[LAYER_PIN], - RED ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorSheetEx" ), - &s_layerColor[LAYER_SHEET], - MAGENTA ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, - wxT( "ColorSheetFileNameEx" ), - &s_layerColor[LAYER_SHEETFILENAME], - BROWN ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorSheetNameEx" ), - &s_layerColor[LAYER_SHEETNAME], - CYAN ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorSheetLabelEx" ), - &s_layerColor[LAYER_SHEETLABEL], - BROWN ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorNoConnectEx" ), - &s_layerColor[LAYER_NOCONNECT], - BLUE ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorErcWEx" ), - &s_layerColor[LAYER_ERC_WARN], - GREEN ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorErcEEx" ), - &s_layerColor[LAYER_ERC_ERR], - RED ) ); - m_configSettings.push_back( new PARAM_CFG_SETCOLOR( true, wxT( "ColorGridEx" ), - &s_layerColor[LAYER_GRID], - DARKGRAY ) ); m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "PrintMonochrome" ), &m_printMonochrome, true ) ); m_configSettings.push_back( new PARAM_CFG_BOOL( true, wxT( "PrintSheetReferenceAndTitleBlock" ), @@ -652,7 +604,6 @@ void SCH_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg ) wxConfigLoadSetups( aCfg, GetConfigurationSettings() ); - // This is required until someone gets rid of the global variable s_layerColor. m_GridColor = GetLayerColor( LAYER_GRID ); SetDefaultBusThickness( aCfg->Read( DefaultBusWidthEntry, 12l ) ); diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index 83950e0a9d..d7a4c3b062 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -48,7 +48,6 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName, bo { wxString msg; wxFileName schematicFileName; - FILE* f; bool success; if( aScreen == NULL ) @@ -59,11 +58,12 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName, bo aSaveUnderNewName = true; // Construct the name of the file to be saved - schematicFileName = aScreen->GetFileName(); + schematicFileName = Prj().AbsolutePath( aScreen->GetFileName() ); if( aSaveUnderNewName ) { - wxFileDialog dlg( this, _( "Schematic Files" ), wxGetCwd(), + wxFileDialog dlg( this, _( "Schematic Files" ), + wxPathOnly( Prj().GetProjectFullName() ), schematicFileName.GetFullName(), SchematicFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); @@ -75,43 +75,38 @@ bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName, bo if( schematicFileName.GetExt() != SchematicFileExtension ) schematicFileName.SetExt( SchematicFileExtension ); } - else - { - // Sheet file names are relative to the root sheet path which is the current - // working directory. The IsWritable function expects the path to be set. - if( schematicFileName.GetPath().IsEmpty() ) - schematicFileName.Assign( wxFileName::GetCwd(), - schematicFileName.GetFullName() ); - } if( !IsWritable( schematicFileName ) ) return false; - /* Create backup if requested */ + // Create backup if requested if( aCreateBackupFile && schematicFileName.FileExists() ) { wxFileName backupFileName = schematicFileName; - /* Rename the old file to a '.bak' one: */ + // Rename the old file to a '.bak' one: backupFileName.SetExt( SchematicBackupFileExtension ); + if( backupFileName.FileExists() ) wxRemoveFile( backupFileName.GetFullPath() ); if( !wxRenameFile( schematicFileName.GetFullPath(), backupFileName.GetFullPath() ) ) { - msg.Printf( _( "Could not save backup of file <%s>" ), + msg.Printf( _( "Could not save backup of file '%s'" ), GetChars( schematicFileName.GetFullPath() ) ); DisplayError( this, msg ); } } - /* Save */ + // Save wxLogTrace( traceAutoSave, wxT( "Saving file <" ) + schematicFileName.GetFullPath() + wxT( ">" ) ); - if( ( f = wxFopen( schematicFileName.GetFullPath(), wxT( "wt" ) ) ) == NULL ) + FILE* f = wxFopen( schematicFileName.GetFullPath(), wxT( "wt" ) ); + + if( !f ) { - msg.Printf( _( "Failed to create file <%s>" ), + msg.Printf( _( "Failed to create file '%s'" ), GetChars( schematicFileName.GetFullPath() ) ); DisplayError( this, msg ); return false; @@ -176,245 +171,170 @@ void SCH_EDIT_FRAME::Save_File( wxCommandEvent& event ) } -bool SCH_EDIT_FRAME::LoadCacheLibrary( const wxString& aFilename ) -{ - wxString msg; - bool LibCacheExist = false; - wxFileName fn = aFilename; - - /* Loading the project library cache - * until apr 2009 the lib is named .cache.lib - * and after (due to code change): -cache.lib - * so if the -cache.lib is not found, the old way will be tried - */ - bool use_oldcachename = false; - wxString cachename = fn.GetName() + wxT( "-cache" ); - - fn.SetName( cachename ); - fn.SetExt( SchematicLibraryFileExtension ); - - if( ! fn.FileExists() ) - { - fn = aFilename; - fn.SetExt( wxT( "cache.lib" ) ); - use_oldcachename = true; - } - - if( fn.FileExists() ) - { - wxString errMsg; - - wxLogDebug( wxT( "Load schematic cache library file <%s>" ), - GetChars( fn.GetFullPath() ) ); - msg = wxT( "Load " ) + fn.GetFullPath(); - - CMP_LIBRARY* LibCache = CMP_LIBRARY::LoadLibrary( fn, errMsg ); - - if( LibCache ) - { - LibCache->SetCache(); - msg += wxT( " OK" ); - - if ( use_oldcachename ) // set the new name - { - fn.SetName( cachename ); - fn.SetExt( SchematicLibraryFileExtension ); - LibCache->SetFileName( fn ); - } - - LibCacheExist = true; - CMP_LIBRARY::GetLibraryList().push_back( LibCache ); - } - else - { - wxString prompt; - - prompt.Printf( _( "Component library <%s> failed to load.\nError: %s" ), - GetChars( fn.GetFullPath() ), - GetChars( errMsg ) ); - DisplayError( this, prompt ); - msg += _( " ->Error" ); - } - - PrintMsg( msg ); - } - - return LibCacheExist; -} - - bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, int aCtl ) { - SCH_SCREEN* screen; - wxString fullFileName( aFileSet[0] ); - wxString msg; + // implement the pseudo code from KIWAY_PLAYER.h: + SCH_SCREENS screenList; - for( screen = screenList.GetFirst(); screen != NULL; screen = screenList.GetNext() ) + // This is for python: + if( aFileSet.size() != 1 ) { - if( screen->IsModify() ) - break; - } - - if( screen ) - { - int response = YesNoCancelDialog( this, - _( "The current schematic has been modified. Do you wish to save the changes?" ), - wxEmptyString, - _( "Save and Load" ), - _( "Load Without Saving" ) - ); - - if( response == wxID_CANCEL ) - { - return false; - } - else if( response == wxID_YES ) - { - wxCommandEvent dummy; - OnSaveProject( dummy ); - } - } - -/* - if( fullFileName.IsEmpty() && !aIsNew ) - { - wxFileDialog dlg( this, _( "Open Schematic" ), wxGetCwd(), - wxEmptyString, SchematicFileWildcard, - wxFD_OPEN | wxFD_FILE_MUST_EXIST ); - - if( dlg.ShowModal() == wxID_CANCEL ) - return false; - - FullFileName = dlg.GetPath(); - } -*/ - - wxFileName fn = fullFileName; - - if( fn.IsRelative() ) - { - fn.MakeAbsolute(); - fullFileName = fn.GetFullPath(); - } - - if( !Pgm().LockFile( fullFileName ) ) - { - DisplayError( this, _( "This file is already open." ) ); + UTF8 msg = StrPrintf( "Eeschema:%s() takes only a single filename", __func__ ); + DisplayError( this, msg ); return false; } - // Clear the screen before open a new file - if( g_RootSheet ) + wxString fullFileName( aFileSet[0] ); + + // We insist on caller sending us an absolute path, if it does not, we say it's a bug. + wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), + wxT( "bug in single_top.cpp or project manager." ) ); + + if( !Pgm().LockFile( fullFileName ) ) + { + wxString msg = wxString::Format( _( + "Schematic file '%s' is already open." ), + GetChars( fullFileName ) + ); + DisplayError( this, msg ); + return false; + } + + // save any currently open and modified project files. + for( SCH_SCREEN* screen = screenList.GetFirst(); screen; screen = screenList.GetNext() ) + { + if( screen->IsModify() ) + { + int response = YesNoCancelDialog( this, _( + "The current schematic has been modified. Do you wish to save the changes?" ), + wxEmptyString, + _( "Save and Load" ), + _( "Load Without Saving" ) + ); + + if( response == wxID_CANCEL ) + { + return false; + } + else if( response == wxID_YES ) + { + wxCommandEvent dummy; + OnSaveProject( dummy ); + } + else + { + // response == wxID_NO, fall thru + } + break; + } + } + + wxFileName pro = fullFileName; + pro.SetExt( ProjectFileExtension ); + + bool is_new = !wxFileName::IsFileReadable( fullFileName ); + + // If its a non-existent schematic and caller thinks it exists + if( is_new && !( aCtl & KICTL_CREATE ) ) + { + // notify user that fullFileName does not exist, ask if user wants to create it. + wxString ask = wxString::Format( _( + "Schematic '%s' does not exist. Do you wish to create it?" ), + GetChars( fullFileName ) + ); + if( !IsOK( this, ask ) ) + return false; + } + + // unload current project file before loading new { delete g_RootSheet; g_RootSheet = NULL; + + CreateScreens(); } - CreateScreens(); - screen = GetScreen(); - - wxLogDebug( wxT( "Loading schematic " ) + fullFileName ); - - // @todo: this is bad: - wxSetWorkingDirectory( fn.GetPath() ); - - screen->SetFileName( fullFileName ); - g_RootSheet->SetFileName( fullFileName ); - SetStatusText( wxEmptyString ); - ClearMsgPanel(); - - screen->ClrModify(); - -#if 0 - if( aIsNew ) +#if defined(DEBUG) && 1 { - /* SCH_SCREEN constructor does this now - screen->SetPageSettings( PAGE_INFO( wxT( "A4" ) ) ); - */ + wxFileName fn = aFileSet[0]; + fn.SetExt( ProjectFileExtension ); - screen->SetZoom( 32 ); - m_LastGridSizeId = screen->SetGrid( ID_POPUP_GRID_LEVEL_50 ); + wxString n1 = fn.GetFullPath(); + wxString n2 = Prj().GetProjectFullName(); - TITLE_BLOCK tb; - wxString title; - - title += NAMELESS_PROJECT; - title += wxT( ".sch" ); - tb.SetTitle( title ); - screen->SetTitleBlock( tb ); - - GetScreen()->SetFileName( title ); - - LoadProjectFile( wxEmptyString, true ); - Zoom_Automatique( false ); - SetSheetNumberAndCount(); - m_canvas->Refresh(); - return true; + wxASSERT( n1 == n2 ); } #endif - // Reloading configuration. - msg.Printf( _( "Ready\nWorking dir: '%s'\n" ), GetChars( wxGetCwd() ) ); - PrintMsg( msg ); + GetScreen()->SetFileName( fullFileName ); + g_RootSheet->SetFileName( fullFileName ); - LoadProjectFile( wxEmptyString, true ); + SetStatusText( wxEmptyString ); + ClearMsgPanel(); - // Clear (if needed) the current active library in libedit because it could be - // removed from memory - LIB_EDIT_FRAME::EnsureActiveLibExists(); + wxString msg = wxString::Format( _( + "Ready\nProject dir: '%s'\n" ), + GetChars( wxPathOnly( Prj().GetProjectFullName() ) ) + ); + SetStatusText( msg ); - // Delete old caches. - CMP_LIBRARY::RemoveCacheLibrary(); + // PROJECT::SetProjectFullName() is an impactful function. It should only be + // called under carefully considered circumstances. - if( !wxFileExists( g_RootSheet->GetScreen()->GetFileName() ) ) + // The calling code should know not to ask me here to change projects unless + // it knows what consequences that will have on other KIFACEs running and using + // this same PROJECT. It can be very harmful if that calling code is stupid. + Prj().SetProjectFullName( pro.GetFullPath() ); + + LoadProjectFile(); + + if( is_new ) { - Zoom_Automatique( false ); + // mark new, unsaved file as modified. + GetScreen()->SetModify(); + } + else + { + g_RootSheet->SetScreen( NULL ); - if( aCtl == 0 ) - { - msg.Printf( _( "File '%s' not found." ), - GetChars( g_RootSheet->GetScreen()->GetFileName() ) ); - DisplayInfoMessage( this, msg ); - } + DBG( printf( "%s: loading schematic %s\n", __func__, TO_UTF8( fullFileName ) );) - return true; // do not close Eeschema if the file if not found: - // we may have to create a new schematic file. + bool diag = g_RootSheet->Load( this ); + (void) diag; + + SetScreen( m_CurrentSheet->LastScreen() ); + + GetScreen()->ClrModify(); + + UpdateFileHistory( fullFileName ); } - // load the project. - bool libCacheExist = LoadCacheLibrary( g_RootSheet->GetScreen()->GetFileName() ); - - g_RootSheet->SetScreen( NULL ); - - bool diag = g_RootSheet->Load( this ); - - SetScreen( m_CurrentSheet->LastScreen() ); - - UpdateFileHistory( g_RootSheet->GetScreen()->GetFileName() ); - - // Redraw base screen (ROOT) if necessary. GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId ); Zoom_Automatique( false ); SetSheetNumberAndCount(); + + /* this is done in ReDraw() + UpdateTitle(); + */ + + // load the libraries here, not in SCH_SCREEN::Draw() which is a context + // that will not tolerate DisplayError() dialog since we're already in an + // event handler in there. + Prj().SchLibs(); + m_canvas->Refresh( true ); - (void) libCacheExist; - (void) diag; - -// return diag; - return true; // do not close Eeschema if the file if not found: - // we may have to create a new schematic file. + return true; } bool SCH_EDIT_FRAME::AppendOneEEProject() { - SCH_SCREEN* screen; wxString fullFileName; wxString msg; - screen = GetScreen(); + SCH_SCREEN* screen = GetScreen(); if( !screen ) { @@ -423,7 +343,9 @@ bool SCH_EDIT_FRAME::AppendOneEEProject() } // open file chooser dialog - wxFileDialog dlg( this, _( "Import Schematic" ), wxGetCwd(), + wxString path = wxPathOnly( Prj().GetProjectFullName() ); + + wxFileDialog dlg( this, _( "Import Schematic" ), path, wxEmptyString, SchematicFileWildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST ); @@ -440,7 +362,14 @@ bool SCH_EDIT_FRAME::AppendOneEEProject() fullFileName = fn.GetFullPath(); } - LoadCacheLibrary( fullFileName ); + wxString cache_name = PART_LIBS::CacheName( fullFileName ); + if( !!cache_name ) + { + PART_LIBS* libs = Prj().SchLibs(); + + if( PART_LIB* lib = libs->AddLibrary( cache_name ) ) + lib->SetCache(); + } wxLogDebug( wxT( "Importing schematic " ) + fullFileName ); @@ -462,6 +391,7 @@ bool SCH_EDIT_FRAME::AppendOneEEProject() { ( (SCH_COMPONENT*) bs )->SetTimeStamp( GetNewTimeStamp() ); ( (SCH_COMPONENT*) bs )->ClearAnnotation( NULL ); + // Clear flags, which are set by these previous modifications: bs->ClearFlags(); } @@ -495,23 +425,25 @@ void SCH_EDIT_FRAME::OnAppendProject( wxCommandEvent& event ) void SCH_EDIT_FRAME::OnSaveProject( wxCommandEvent& aEvent ) { SCH_SCREEN* screen; - wxFileName fn; - wxFileName tmp; - SCH_SCREENS ScreenList; + SCH_SCREENS screenList; - fn = g_RootSheet->GetFileName(); + // I want to see it in the debugger, show me the string! Can't do that with wxFileName. + wxString fileName = Prj().AbsolutePath( g_RootSheet->GetFileName() ); - // Ensure a path exists. if no path, assume the cwd is used - // The IsWritable function expects the path to be set - if( !fn.GetPath().IsEmpty() ) - tmp.AssignDir( fn.GetPath() ); - else - tmp.AssignDir( wxGetCwd() ); + wxFileName fn = fileName; - if( !IsWritable( tmp ) ) + if( !fn.IsDirWritable() ) + { + wxString msg = wxString::Format( _( + "Directory '%s' is not writable" ), + GetChars( fn.GetPath() ) + ); + + DisplayError( this, msg ); return; + } - for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() ) + for( screen = screenList.GetFirst(); screen; screen = screenList.GetNext() ) SaveEEFile( screen ); CreateArchiveLibraryCacheFile(); @@ -522,10 +454,11 @@ void SCH_EDIT_FRAME::OnSaveProject( wxCommandEvent& aEvent ) bool SCH_EDIT_FRAME::doAutoSave() { - wxFileName tmpFileName = g_RootSheet->GetFileName(); - wxFileName fn = tmpFileName; + wxFileName tmpFileName = g_RootSheet->GetFileName(); + wxFileName fn = tmpFileName; wxFileName tmp; SCH_SCREENS screens; + bool autoSaveOk = true; tmp.AssignDir( fn.GetPath() ); @@ -533,7 +466,7 @@ bool SCH_EDIT_FRAME::doAutoSave() if( !IsWritable( tmp ) ) return false; - for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) + for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) { // Only create auto save files for the schematics that have been modified. if( !screen->IsSave() ) diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index cd4c15a90a..2b6df9cb76 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -102,14 +102,15 @@ wxString SCH_BASE_FRAME::SelectComponentFromLibrary( const wxString& aLibname, { int cmpCount = 0; wxString dialogTitle; + PART_LIBS* libs = Prj().SchLibs(); - COMPONENT_TREE_SEARCH_CONTAINER search_container; // Container doing search-as-you-type + COMPONENT_TREE_SEARCH_CONTAINER search_container( libs ); // Container doing search-as-you-type if( !aLibname.IsEmpty() ) { - CMP_LIBRARY* currLibrary = CMP_LIBRARY::FindLibrary( aLibname ); + PART_LIB* currLibrary = libs->FindLibrary( aLibname ); - if( currLibrary != NULL ) + if( currLibrary ) { cmpCount = currLibrary->GetCount(); search_container.AddLibrary( *currLibrary ); @@ -117,7 +118,7 @@ wxString SCH_BASE_FRAME::SelectComponentFromLibrary( const wxString& aLibname, } else { - BOOST_FOREACH( CMP_LIBRARY& lib, CMP_LIBRARY::GetLibraryList() ) + BOOST_FOREACH( PART_LIB& lib, *libs ) { cmpCount += lib.GetCount(); search_container.AddLibrary( lib ); @@ -153,7 +154,7 @@ wxString SCH_BASE_FRAME::SelectComponentFromLibrary( const wxString& aLibname, if( dlg.IsExternalBrowserSelected() ) // User requested big component browser. cmpName = SelectComponentFromLibBrowser( alias, aUnit, aConvert); - if ( !cmpName.empty() ) + if( !cmpName.empty() ) { AddHistoryComponentName( aHistoryList, cmpName ); if ( aUnit ) aHistoryLastUnit = *aUnit; @@ -174,10 +175,10 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( wxDC* aDC, SetRepeatItem( NULL ); m_canvas->SetIgnoreMouseEvents( true ); - wxString Name = SelectComponentFromLibrary( aLibname, aHistoryList, aHistoryLastUnit, + wxString name = SelectComponentFromLibrary( aLibname, aHistoryList, aHistoryLastUnit, aUseLibBrowser, &unit, &convert ); - if( Name.IsEmpty() ) + if( name.IsEmpty() ) { m_canvas->SetIgnoreMouseEvents( false ); m_canvas->MoveCursorToCrossHair(); @@ -185,33 +186,34 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( wxDC* aDC, } #ifndef KICAD_KEEPCASE - Name.MakeUpper(); + name.MakeUpper(); #endif - LIB_COMPONENT* Entry = CMP_LIBRARY::FindLibraryComponent( Name, aLibname ); - m_canvas->SetIgnoreMouseEvents( false ); m_canvas->MoveCursorToCrossHair(); - if( Entry == NULL ) + LIB_PART* part = Prj().SchLibs()->FindLibPart( name, aLibname ); + + if( !part ) { - wxString msg; - msg.Printf( _( "Failed to find part <%s> in library" ), GetChars( Name ) ); + wxString msg = wxString::Format( _( + "Failed to find part '%s' in library" ), + GetChars( name ) + ); wxMessageBox( msg ); return NULL; } - SCH_COMPONENT* component; - component = new SCH_COMPONENT( *Entry, m_CurrentSheet, unit, convert, - GetCrossHairPosition(), true ); + SCH_COMPONENT* component = new SCH_COMPONENT( *part, m_CurrentSheet, unit, convert, + GetCrossHairPosition(), true ); // Set the m_ChipName value, from component name in lib, for aliases - // Note if Entry is found, and if Name is an alias of a component, + // Note if part is found, and if name is an alias of a component, // alias exists because its root component was found - component->SetLibName( Name ); + component->SetPartName( name ); // Set the component value that can differ from component name in lib, for aliases - component->GetField( VALUE )->SetText( Name ); + component->GetField( VALUE )->SetText( name ); MSG_PANEL_ITEMS items; @@ -275,12 +277,12 @@ void SCH_EDIT_FRAME::OrientComponent( COMPONENT_ORIENTATION_T aOrientation ) /* - * Handle select part in multi-part component. + * Handle select part in multi-unit part. */ void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); - SCH_ITEM* item = screen->GetCurItem(); + SCH_ITEM* item = screen->GetCurItem(); wxCHECK_RET( item != NULL && item->Type() == SCH_COMPONENT_T, wxT( "Cannot select unit of invalid schematic item." ) ); @@ -293,98 +295,92 @@ void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent ) int unit = aEvent.GetId() + 1 - ID_POPUP_SCH_SELECT_UNIT1; - LIB_COMPONENT* libEntry = CMP_LIBRARY::FindLibraryComponent( component->GetLibName() ); + if( LIB_PART* part = Prj().SchLibs()->FindLibPart( component->GetPartName() ) ) + { + wxCHECK_RET( (unit >= 1) && (unit <= part->GetUnitCount()), + wxString::Format( wxT( "Cannot select unit %d from component " ), unit ) + + part->GetName() ); - if( libEntry == NULL ) - return; + int unitCount = part->GetUnitCount(); - wxCHECK_RET( (unit >= 1) && (unit <= libEntry->GetPartCount()), - wxString::Format( wxT( "Cannot select unit %d from component "), unit ) + - libEntry->GetName() ); + if( unitCount <= 1 || component->GetUnit() == unit ) + return; - int unitCount = libEntry->GetPartCount(); + if( unit < 1 ) + unit = 1; - if( (unitCount <= 1) || (component->GetUnit() == unit) ) - return; + if( unit > unitCount ) + unit = unitCount; - if( unit < 1 ) - unit = 1; + STATUS_FLAGS flags = component->GetFlags(); - if( unit > unitCount ) - unit = unitCount; + if( !flags ) // No command in progress: save in undo list + SaveCopyInUndoList( component, UR_CHANGED ); - STATUS_FLAGS flags = component->GetFlags(); + if( flags ) + component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); + else + component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode ); - if( !flags ) // No command in progress: save in undo list - SaveCopyInUndoList( component, UR_CHANGED ); + /* Update the unit number. */ + component->SetUnitSelection( m_CurrentSheet, unit ); + component->SetUnit( unit ); + component->ClearFlags(); + component->SetFlags( flags ); // Restore m_Flag modified by SetUnit() - if( flags ) - component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); - else - component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode ); + /* Redraw the component in the new position. */ + if( flags ) + component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); + else + component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); - /* Update the unit number. */ - component->SetUnitSelection( m_CurrentSheet, unit ); - component->SetUnit( unit ); - component->ClearFlags(); - component->SetFlags( flags ); // Restore m_Flag modified by SetUnit() - - /* Redraw the component in the new position. */ - if( flags ) - component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); - else - component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); - - screen->TestDanglingEnds( m_canvas, &dc ); - OnModify(); + screen->TestDanglingEnds( m_canvas, &dc ); + OnModify(); + } } void SCH_EDIT_FRAME::ConvertPart( SCH_COMPONENT* DrawComponent, wxDC* DC ) { - LIB_COMPONENT* LibEntry; - - if( DrawComponent == NULL ) + if( !DrawComponent ) return; - LibEntry = CMP_LIBRARY::FindLibraryComponent( DrawComponent->GetLibName() ); - - if( LibEntry == NULL ) - return; - - if( !LibEntry->HasConversion() ) + if( LIB_PART* part = Prj().SchLibs()->FindLibPart( DrawComponent->GetPartName() ) ) { - DisplayError( this, wxT( "No convert found" ) ); - return; + if( !part->HasConversion() ) + { + DisplayError( this, wxT( "No convert found" ) ); + return; + } + + STATUS_FLAGS flags = DrawComponent->GetFlags(); + + if( DrawComponent->GetFlags() ) + DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); + else + DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode ); + + DrawComponent->SetConvert( DrawComponent->GetConvert() + 1 ); + + // ensure m_Convert = 0, 1 or 2 + // 0 and 1 = shape 1 = not converted + // 2 = shape 2 = first converted shape + // > 2 is not used but could be used for more shapes + // like multiple shapes for a programmable component + // When m_Convert = val max, return to the first shape + if( DrawComponent->GetConvert() > 2 ) + DrawComponent->SetConvert( 1 ); + + DrawComponent->ClearFlags(); + DrawComponent->SetFlags( flags ); // Restore m_Flag (modified by SetConvert()) + + /* Redraw the component in the new position. */ + if( DrawComponent->IsMoving() ) + DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); + else + DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); + + GetScreen()->TestDanglingEnds( m_canvas, DC ); + OnModify(); } - - STATUS_FLAGS flags = DrawComponent->GetFlags(); - - if( DrawComponent->GetFlags() ) - DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); - else - DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode ); - - DrawComponent->SetConvert( DrawComponent->GetConvert() + 1 ); - - // ensure m_Convert = 0, 1 or 2 - // 0 and 1 = shape 1 = not converted - // 2 = shape 2 = first converted shape - // > 2 is not used but could be used for more shapes - // like multiple shapes for a programmable component - // When m_Convert = val max, return to the first shape - if( DrawComponent->GetConvert() > 2 ) - DrawComponent->SetConvert( 1 ); - - DrawComponent->ClearFlags(); - DrawComponent->SetFlags( flags ); // Restore m_Flag (modified by SetConvert()) - - /* Redraw the component in the new position. */ - if( DrawComponent->IsMoving() ) - DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); - else - DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); - - GetScreen()->TestDanglingEnds( m_canvas, DC ); - OnModify( ); } diff --git a/eeschema/invoke_sch_dialog.h b/eeschema/invoke_sch_dialog.h index b2a8fba3f8..a6d95147e0 100644 --- a/eeschema/invoke_sch_dialog.h +++ b/eeschema/invoke_sch_dialog.h @@ -75,6 +75,8 @@ int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller ); #define NET_PLUGIN_CHANGE 1 int InvokeDialogNetList( SCH_EDIT_FRAME* aCaller ); -int InvokeEeschemaConfig( SCH_EDIT_FRAME* aEditFrame, wxFrame* aParent ); +bool InvokeEeschemaConfig( wxWindow* aParent, + wxString* aCallersProjectSpecificLibPaths, wxArrayString* aCallersLibNames ); + #endif // INVOKE_SCH_DIALOG_H_ diff --git a/eeschema/lib_arc.cpp b/eeschema/lib_arc.cpp index fa5e1a42bc..5876194af2 100644 --- a/eeschema/lib_arc.cpp +++ b/eeschema/lib_arc.cpp @@ -84,7 +84,7 @@ static wxPoint calcCenter( const wxPoint& A, const wxPoint& B, const wxPoint& C } -LIB_ARC::LIB_ARC( LIB_COMPONENT* aParent ) : LIB_ITEM( LIB_ARC_T, aParent ) +LIB_ARC::LIB_ARC( LIB_PART* aParent ) : LIB_ITEM( LIB_ARC_T, aParent ) { m_Radius = 0; m_t1 = 0; diff --git a/eeschema/lib_arc.h b/eeschema/lib_arc.h index 74fc633071..dcebbdfb97 100644 --- a/eeschema/lib_arc.h +++ b/eeschema/lib_arc.h @@ -84,7 +84,7 @@ class LIB_ARC : public LIB_ITEM void calcRadiusAngles(); public: - LIB_ARC( LIB_COMPONENT * aParent ); + LIB_ARC( LIB_PART * aParent ); // Do not create a copy constructor. The one generated by the compiler is adequate. diff --git a/eeschema/lib_bezier.cpp b/eeschema/lib_bezier.cpp index 3378bb1603..97c9f1d847 100644 --- a/eeschema/lib_bezier.cpp +++ b/eeschema/lib_bezier.cpp @@ -42,7 +42,7 @@ #include -LIB_BEZIER::LIB_BEZIER( LIB_COMPONENT* aParent ) : +LIB_BEZIER::LIB_BEZIER( LIB_PART* aParent ) : LIB_ITEM( LIB_BEZIER_T, aParent ) { m_Fill = NO_FILL; diff --git a/eeschema/lib_bezier.h b/eeschema/lib_bezier.h index 0a1be188f1..940b054281 100644 --- a/eeschema/lib_bezier.h +++ b/eeschema/lib_bezier.h @@ -47,7 +47,7 @@ class LIB_BEZIER : public LIB_ITEM const TRANSFORM& aTransform ); public: - LIB_BEZIER( LIB_COMPONENT * aParent ); + LIB_BEZIER( LIB_PART * aParent ); // Do not create a copy constructor. The one generated by the compiler is adequate. diff --git a/eeschema/lib_circle.cpp b/eeschema/lib_circle.cpp index 6a249ec740..b6a7719cfd 100644 --- a/eeschema/lib_circle.cpp +++ b/eeschema/lib_circle.cpp @@ -43,7 +43,7 @@ #include -LIB_CIRCLE::LIB_CIRCLE( LIB_COMPONENT* aParent ) : +LIB_CIRCLE::LIB_CIRCLE( LIB_PART* aParent ) : LIB_ITEM( LIB_CIRCLE_T, aParent ) { m_Radius = 0; diff --git a/eeschema/lib_circle.h b/eeschema/lib_circle.h index cbd0b31778..fe6ee3cea8 100644 --- a/eeschema/lib_circle.h +++ b/eeschema/lib_circle.h @@ -45,7 +45,7 @@ class LIB_CIRCLE : public LIB_ITEM void calcEdit( const wxPoint& aPosition ); public: - LIB_CIRCLE( LIB_COMPONENT * aParent ); + LIB_CIRCLE( LIB_PART * aParent ); // Do not create a copy constructor. The one generated by the compiler is adequate. diff --git a/eeschema/lib_draw_item.cpp b/eeschema/lib_draw_item.cpp index 9b830ad027..f78c252ab4 100644 --- a/eeschema/lib_draw_item.cpp +++ b/eeschema/lib_draw_item.cpp @@ -41,7 +41,7 @@ const int fill_tab[3] = { 'N', 'F', 'f' }; LIB_ITEM::LIB_ITEM( KICAD_T aType, - LIB_COMPONENT* aComponent, + LIB_PART* aComponent, int aUnit, int aConvert, FILL_T aFillType ) : diff --git a/eeschema/lib_draw_item.h b/eeschema/lib_draw_item.h index 10e972eb4a..9015c23a07 100644 --- a/eeschema/lib_draw_item.h +++ b/eeschema/lib_draw_item.h @@ -39,7 +39,7 @@ class LINE_READER; class OUTPUTFORMATTER; -class LIB_COMPONENT; +class LIB_PART; class PLOTTER; class LIB_ITEM; class LIB_PIN; @@ -117,7 +117,7 @@ class LIB_ITEM : public EDA_ITEM bool m_eraseLastDrawItem; ///< Used when editing a new draw item to prevent drawing ///< artifacts. - friend class LIB_COMPONENT; + friend class LIB_PART; protected: /** @@ -150,7 +150,7 @@ protected: public: LIB_ITEM( KICAD_T aType, - LIB_COMPONENT* aComponent = NULL, + LIB_PART* aComponent = NULL, int aUnit = 0, int aConvert = 0, FILL_T aFillType = NO_FILL ); @@ -237,9 +237,9 @@ public: virtual bool Load( LINE_READER& aLine, wxString& aErrorMsg ) = 0; - LIB_COMPONENT* GetParent() const + LIB_PART* GetParent() const { - return (LIB_COMPONENT *)m_Parent; + return (LIB_PART *)m_Parent; } virtual bool HitTest( const wxPoint& aPosition ) const diff --git a/eeschema/lib_export.cpp b/eeschema/lib_export.cpp index b32980b330..5b00024a83 100644 --- a/eeschema/lib_export.cpp +++ b/eeschema/lib_export.cpp @@ -46,11 +46,6 @@ extern int ExportPartId; void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event ) { - wxString errMsg; - wxFileName fn; - CMP_LIBRARY* LibTmp; - LIB_ALIAS* LibEntry; - m_lastDrawItem = NULL; wxFileDialog dlg( this, _( "Import Component" ), m_lastLibImportPath, @@ -60,25 +55,40 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event ) if( dlg.ShowModal() == wxID_CANCEL ) return; - fn = dlg.GetPath(); + wxFileName fn = dlg.GetPath(); - LibTmp = CMP_LIBRARY::LoadLibrary( fn, errMsg ); + std::auto_ptr lib; - if( LibTmp == NULL ) - return; - - LibEntry = LibTmp->GetFirstEntry(); - - if( LibEntry == NULL ) + try { - wxString msg; + std::auto_ptr new_lib( PART_LIB::LoadLibrary( fn.GetFullPath() ) ); + lib = new_lib; + } + catch( const IO_ERROR& ioe ) + { + wxString msg = wxString::Format( _( + "Unable to import library '%s'. Error:\n" + "%s" ), + GetChars( fn.GetFullPath() ) + ); - msg.Printf( _( "Component library file <%s> is empty." ), GetChars( fn.GetFullPath() ) ); + DisplayError( this, msg ); + return; + } + + LIB_ALIAS* entry = lib->GetFirstEntry(); + + if( !entry ) + { + wxString msg = wxString::Format( _( + "Part library file '%s' is empty." ), + GetChars( fn.GetFullPath() ) + ); DisplayError( this, msg ); return; } - if( LoadOneLibraryPartAux( LibEntry, LibTmp ) ) + if( LoadOneLibraryPartAux( entry, lib.get() ) ) { fn = dlg.GetPath(); m_lastLibImportPath = fn.GetPath(); @@ -86,42 +96,39 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event ) GetScreen()->ClearUndoRedoList(); m_canvas->Refresh(); } - - delete LibTmp; } void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event ) { - wxFileName fn; - wxString msg, title; - CMP_LIBRARY* CurLibTmp; - bool createLib = ( event.GetId() == ExportPartId ) ? false : true; + wxString msg, title; + bool createLib = ( event.GetId() == ExportPartId ) ? false : true; - if( m_component == NULL ) + LIB_PART* part = GetCurPart(); + + if( !part ) { DisplayError( this, _( "There is no component selected to save." ) ); return; } - fn = m_component->GetName().Lower(); + wxFileName fn = part->GetName().Lower(); + fn.SetExt( SchematicLibraryFileExtension ); title = createLib ? _( "New Library" ) : _( "Export Component" ); - wxFileDialog dlg( this, title, wxGetCwd(), fn.GetFullName(), - SchematicLibraryFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); + wxFileDialog dlg( this, title, m_lastLibExportPath, fn.GetFullName(), + SchematicLibraryFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); if( dlg.ShowModal() == wxID_CANCEL ) return; fn = dlg.GetPath(); - CurLibTmp = m_library; + std::auto_ptr temp_lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, fn.GetFullPath() ) ); - m_library = new CMP_LIBRARY( LIBRARY_TYPE_EESCHEMA, fn ); - - SaveOnePartInMemory(); + SaveOnePart( temp_lib.get() ); bool result = false; @@ -129,7 +136,7 @@ void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event ) { FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() ); - result = m_library->Save( formatter ); + result = GetCurLib()->Save( formatter ); } catch( ... /* IO_ERROR ioe */ ) { @@ -142,26 +149,24 @@ void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event ) if( result ) m_lastLibExportPath = fn.GetPath(); - delete m_library; - m_library = CurLibTmp; - if( result ) { if( createLib ) { - msg.Printf( _( "<%s> - OK" ), GetChars( fn.GetFullPath() ) ); - DisplayInfoMessage( this, _( "This library will not be available \ -until it is loaded by Eeschema.\n\nModify the Eeschema library configuration \ -if you want to include it as part of this project." ) ); + msg.Printf( _( "'%s' - OK" ), GetChars( fn.GetFullPath() ) ); + DisplayInfoMessage( this, _( + "This library will not be available until it is loaded by Eeschema.\n\n" + "Modify the Eeschema library configuration if you want to include it" + " as part of this project." ) ); } else { - msg.Printf( _( "<%s> - Export OK" ), GetChars( fn.GetFullPath() ) ); + msg.Printf( _( "'%s' - Export OK" ), GetChars( fn.GetFullPath() ) ); } - } // Error - else + } + else // Error { - msg.Printf( _( "Error creating <%s>" ), GetChars( fn.GetFullName() ) ); + msg.Printf( _( "Error creating '%s'" ), GetChars( fn.GetFullName() ) ); } SetStatusText( msg ); diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp index 83e89a98cd..b787e8867b 100644 --- a/eeschema/lib_field.cpp +++ b/eeschema/lib_field.cpp @@ -46,7 +46,7 @@ #include -LIB_FIELD::LIB_FIELD(LIB_COMPONENT * aParent, int idfield ) : +LIB_FIELD::LIB_FIELD(LIB_PART * aParent, int idfield ) : LIB_ITEM( LIB_FIELD_T, aParent ) { Init( idfield ); @@ -346,9 +346,9 @@ bool LIB_FIELD::HitTest( const wxPoint &aPosition, int aThreshold, const TRANSFO { wxString extended_text = tmp_text.GetText(); extended_text.Append('?'); - const LIB_COMPONENT* parent = static_cast( m_Parent ); + const LIB_PART* parent = static_cast( m_Parent ); - if ( parent && ( parent->GetPartCount() > 1 ) ) + if ( parent && ( parent->GetUnitCount() > 1 ) ) extended_text.Append('A'); tmp_text.SetText( extended_text ); } @@ -506,7 +506,7 @@ wxString LIB_FIELD::GetFullText( int unit ) text << wxT( "?" ); if( GetParent()->IsMulti() ) - text << LIB_COMPONENT::SubReference( unit ); + text << LIB_PART::SubReference( unit ); return text; } @@ -649,7 +649,7 @@ void LIB_FIELD::SetText( const wxString& aText ) if( m_id == VALUE && m_Parent != NULL ) { - LIB_COMPONENT* parent = GetParent(); + LIB_PART* parent = GetParent(); // Set the parent component and root alias to the new name. if( parent->GetName().CmpNoCase( aText ) != 0 ) diff --git a/eeschema/lib_field.h b/eeschema/lib_field.h index 49e36d8be5..d768b56f7b 100644 --- a/eeschema/lib_field.h +++ b/eeschema/lib_field.h @@ -85,7 +85,7 @@ public: LIB_FIELD( int idfield = 2 ); - LIB_FIELD( LIB_COMPONENT * aParent, int idfield = 2 ); + LIB_FIELD( LIB_PART * aParent, int idfield = 2 ); // Do not create a copy constructor. The one generated by the compiler is adequate. diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp index 1313e5a010..e7bf664a8a 100644 --- a/eeschema/lib_pin.cpp +++ b/eeschema/lib_pin.cpp @@ -199,7 +199,7 @@ static int ExternalPinDecoSize( const LIB_PIN &aPin ) return aPin.GetNumberTextSize() / 2; } -LIB_PIN::LIB_PIN( LIB_COMPONENT* aParent ) : +LIB_PIN::LIB_PIN( LIB_PART* aParent ) : LIB_ITEM( LIB_PIN_T, aParent ) { m_length = GetDefaultPinLength(); // default Pin len @@ -209,7 +209,7 @@ LIB_PIN::LIB_PIN( LIB_COMPONENT* aParent ) : m_attributes = 0; // bit 0 != 0: pin invisible m_number = 0; // pin number (i.e. 4 ASCII chars) m_numTextSize = GetDefaultTextSize(); // Default size for pin name and num - m_nameTextSize = GetDefaultTextSize(); + m_nameTextSize = GetDefaultTextSize(); m_width = 0; m_typeName = _( "Pin" ); } @@ -834,7 +834,7 @@ void LIB_PIN::drawGraphic( EDA_DRAW_PANEL* aPanel, aColor = GetInvisibleItemColor(); } - LIB_COMPONENT* Entry = GetParent(); + LIB_PART* Entry = GetParent(); bool DrawPinText = true; if( ( aData != NULL ) && ( (bool*) aData == false ) ) @@ -1956,7 +1956,7 @@ void LIB_PIN::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList ) const EDA_RECT LIB_PIN::GetBoundingBox() const { - LIB_COMPONENT* entry = (LIB_COMPONENT*) m_Parent; + LIB_PART* entry = (LIB_PART* ) m_Parent; EDA_RECT bbox; wxPoint begin; wxPoint end; diff --git a/eeschema/lib_pin.h b/eeschema/lib_pin.h index 8e15a12738..aecc11e83d 100644 --- a/eeschema/lib_pin.h +++ b/eeschema/lib_pin.h @@ -105,7 +105,7 @@ class LIB_PIN : public LIB_ITEM const TRANSFORM& aTransform ); public: - LIB_PIN( LIB_COMPONENT* aParent ); + LIB_PIN( LIB_PART* aParent ); // Do not create a copy constructor. The one generated by the compiler is adequate. diff --git a/eeschema/lib_polyline.cpp b/eeschema/lib_polyline.cpp index 75eae61c71..018a16818d 100644 --- a/eeschema/lib_polyline.cpp +++ b/eeschema/lib_polyline.cpp @@ -44,7 +44,7 @@ #include -LIB_POLYLINE::LIB_POLYLINE( LIB_COMPONENT* aParent ) : +LIB_POLYLINE::LIB_POLYLINE( LIB_PART* aParent ) : LIB_ITEM( LIB_POLYLINE_T, aParent ) { m_Fill = NO_FILL; diff --git a/eeschema/lib_polyline.h b/eeschema/lib_polyline.h index 78a3891613..88e397f140 100644 --- a/eeschema/lib_polyline.h +++ b/eeschema/lib_polyline.h @@ -46,7 +46,7 @@ class LIB_POLYLINE : public LIB_ITEM void calcEdit( const wxPoint& aPosition ); public: - LIB_POLYLINE( LIB_COMPONENT * aParent ); + LIB_POLYLINE( LIB_PART * aParent ); // Do not create a copy constructor. The one generated by the compiler is adequate. diff --git a/eeschema/lib_rectangle.cpp b/eeschema/lib_rectangle.cpp index 451fb7e158..13678149e3 100644 --- a/eeschema/lib_rectangle.cpp +++ b/eeschema/lib_rectangle.cpp @@ -42,7 +42,7 @@ #include -LIB_RECTANGLE::LIB_RECTANGLE( LIB_COMPONENT* aParent ) : +LIB_RECTANGLE::LIB_RECTANGLE( LIB_PART* aParent ) : LIB_ITEM( LIB_RECTANGLE_T, aParent ) { m_Width = 0; diff --git a/eeschema/lib_rectangle.h b/eeschema/lib_rectangle.h index 63e182691d..6df93c9c50 100644 --- a/eeschema/lib_rectangle.h +++ b/eeschema/lib_rectangle.h @@ -48,7 +48,7 @@ class LIB_RECTANGLE : public LIB_ITEM void calcEdit( const wxPoint& aPosition ); public: - LIB_RECTANGLE( LIB_COMPONENT * aParent ); + LIB_RECTANGLE( LIB_PART * aParent ); // Do not create a copy constructor. The one generated by the compiler is adequate. diff --git a/eeschema/lib_text.cpp b/eeschema/lib_text.cpp index b1e3eb0837..6fb5ace11a 100644 --- a/eeschema/lib_text.cpp +++ b/eeschema/lib_text.cpp @@ -43,7 +43,7 @@ #include -LIB_TEXT::LIB_TEXT( LIB_COMPONENT * aParent ) : +LIB_TEXT::LIB_TEXT( LIB_PART * aParent ) : LIB_ITEM( LIB_TEXT_T, aParent ), EDA_TEXT() { diff --git a/eeschema/lib_text.h b/eeschema/lib_text.h index 8353869226..518678b785 100644 --- a/eeschema/lib_text.h +++ b/eeschema/lib_text.h @@ -55,7 +55,7 @@ class LIB_TEXT : public LIB_ITEM, public EDA_TEXT void calcEdit( const wxPoint& aPosition ); public: - LIB_TEXT( LIB_COMPONENT * aParent ); + LIB_TEXT( LIB_PART * aParent ); // Do not create a copy constructor. The one generated by the compiler is adequate. diff --git a/eeschema/libarch.cpp b/eeschema/libarch.cpp index 12d9573386..7644258d21 100644 --- a/eeschema/libarch.cpp +++ b/eeschema/libarch.cpp @@ -61,19 +61,18 @@ bool SCH_EDIT_FRAME::CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilenam bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName ) { - wxString msg; - LIB_COMPONENT* libComponent; - CMP_LIBRARY* libCache; - SCH_SCREENS screens; + SCH_SCREENS screens; + PART_LIBS* libs = Prj().SchLibs(); + + std::auto_ptr libCache( new PART_LIB( LIBRARY_TYPE_EESCHEMA, aFileName ) ); - libCache = new CMP_LIBRARY( LIBRARY_TYPE_EESCHEMA, aFileName ); libCache->SetCache(); /* examine all screens (not sheets) used and build the list of components * found in lib complex hierarchies are not a problem because we just want * to know used components in libraries */ - for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) + for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) { for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() ) { @@ -81,14 +80,15 @@ bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName ) continue; SCH_COMPONENT* component = (SCH_COMPONENT*) item; + // If not already saved in the new cache, put it: - - if( libCache->FindEntry( component->GetLibName()) == NULL ) + if( !libCache->FindEntry( component->GetPartName() ) ) { - libComponent = CMP_LIBRARY::FindLibraryComponent( component->GetLibName() ); - - if( libComponent ) // if NULL : component not found, cannot be stored - libCache->AddComponent( libComponent ); + if( LIB_PART* part = libs->FindLibPart( component->GetPartName() ) ) + { + // AddPart() does first clone the part before adding. + libCache->AddPart( part ); + } } } } @@ -99,16 +99,20 @@ bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName ) if( !libCache->Save( formatter ) ) { - msg.Printf( _( "An error occurred attempting to save component library <%s>." ), - GetChars( aFileName ) ); + wxString msg = wxString::Format( _( + "An error occurred attempting to save component library '%s'." ), + GetChars( aFileName ) + ); DisplayError( this, msg ); return false; } } catch( ... /* IO_ERROR ioe */ ) { - msg.Printf( _( "Failed to create component library file <%s>" ), - GetChars( aFileName ) ); + wxString msg = wxString::Format( _( + "Failed to create component library file '%s'" ), + GetChars( aFileName ) + ); DisplayError( this, msg ); return false; } diff --git a/eeschema/libedit.cpp b/eeschema/libedit.cpp index 9a27bb8c8a..8b51763de4 100644 --- a/eeschema/libedit.cpp +++ b/eeschema/libedit.cpp @@ -51,15 +51,14 @@ void LIB_EDIT_FRAME::DisplayLibInfos() { - wxString msg = _( "Component Library Editor: " ); + wxString msg = _( "Part Library Editor: " ); + PART_LIB* lib = GetCurLib(); - EnsureActiveLibExists(); - - if( m_library ) + if( lib ) { - msg += m_library->GetFullFileName(); + msg += lib->GetFullFileName(); - if( m_library->IsReadOnly() ) + if( lib->IsReadOnly() ) msg += _( " [Read Only]" ); } else @@ -71,21 +70,21 @@ void LIB_EDIT_FRAME::DisplayLibInfos() } -void LIB_EDIT_FRAME::SelectActiveLibrary( CMP_LIBRARY* aLibrary ) +void LIB_EDIT_FRAME::SelectActiveLibrary( PART_LIB* aLibrary ) { - if( aLibrary == NULL ) + if( !aLibrary ) aLibrary = SelectLibraryFromList( this ); if( aLibrary ) { - m_library = aLibrary; + SetCurLib( aLibrary ); } DisplayLibInfos(); } -bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, CMP_LIBRARY* aLibrary ) +bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, PART_LIB* aLibrary ) { if( GetScreen()->IsModify() && !IsOK( this, _( "The current component is not saved.\n\nDiscard current changes?" ) ) ) @@ -98,14 +97,14 @@ bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, CMP_LIBRAR bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry ) { - if( !LoadOneLibraryPartAux( aLibEntry, m_library ) ) + if( !LoadOneLibraryPartAux( aLibEntry, GetCurLib() ) ) return false; - m_editPinsPerPartOrConvert = m_component->UnitsLocked() ? true : false; + m_editPinsPerPartOrConvert = GetCurPart()->UnitsLocked() ? true : false; GetScreen()->ClearUndoRedoList(); Zoom_Automatique( false ); - SetShowDeMorgan( m_component->HasConversion() ); + SetShowDeMorgan( GetCurPart()->HasConversion() ); return true; } @@ -113,8 +112,7 @@ bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry ) void LIB_EDIT_FRAME::LoadOneLibraryPart( wxCommandEvent& event ) { - wxString msg; - wxString CmpName; + wxString cmp_name; LIB_ALIAS* libEntry = NULL; m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); @@ -123,80 +121,84 @@ void LIB_EDIT_FRAME::LoadOneLibraryPart( wxCommandEvent& event ) && !IsOK( this, _( "The current component is not saved.\n\nDiscard current changes?" ) ) ) return; - // No current lib, ask user for the library to use. - if( m_library == NULL ) + PART_LIB* lib = GetCurLib(); + + // No current lib, ask user for the library to use. + if( !lib ) { SelectActiveLibrary(); + lib = GetCurLib(); - if( m_library == NULL ) + if( !lib ) return; } wxArrayString dummyHistoryList; int dummyLastUnit; - CmpName = SelectComponentFromLibrary( m_library->GetName(), dummyHistoryList, dummyLastUnit, + cmp_name = SelectComponentFromLibrary( lib->GetName(), dummyHistoryList, dummyLastUnit, true, NULL, NULL ); - if( CmpName.IsEmpty() ) + if( cmp_name.IsEmpty() ) return; GetScreen()->ClrModify(); m_lastDrawItem = m_drawItem = NULL; // Delete previous library component, if any - if( m_component ) + SetCurPart( NULL ); + m_aliasName.Empty(); + + // Load the new library component + libEntry = lib->FindEntry( cmp_name ); + PART_LIB* searchLib = lib; + + if( !libEntry ) { - delete m_component; - m_component = NULL; - m_aliasName.Empty(); - } - - /* Load the new library component */ - libEntry = m_library->FindEntry( CmpName ); - CMP_LIBRARY* searchLib = m_library; - - if( libEntry == NULL ) - { // Not found in the active library: search inside the full list + // Not found in the active library: search inside the full list // (can happen when using Viewlib to load a component) - libEntry = CMP_LIBRARY::FindLibraryEntry( CmpName ); + libEntry = Prj().SchLibs()->FindLibraryEntry( cmp_name ); if( libEntry ) { - searchLib = libEntry->GetLibrary(); + searchLib = libEntry->GetLib(); + // The entry to load is not in the active lib // Ask for a new active lib - wxString msg; - msg << _("The selected component is not in the active library"); - msg << wxT("\n\n"); - msg << _("Do you want to change the active library?"); + wxString msg = _( "The selected component is not in the active library." ); + msg += wxT("\n\n"); + msg += _( "Do you want to change the active library?" ); if( IsOK( this, msg ) ) SelectActiveLibrary( searchLib ); } } - if( libEntry == NULL ) + if( !libEntry ) { - msg.Printf( _( "Component name %s not found in library %s" ), - GetChars( CmpName ), - GetChars( searchLib->GetName() ) ); + wxString msg = wxString::Format( _( + "Part name '%s' not found in library '%s'" ), + GetChars( cmp_name ), + GetChars( searchLib->GetName() ) + ); DisplayError( this, msg ); return; } - EXCHG( searchLib, m_library ); + PART_LIB* old = SetCurLib( searchLib ); + LoadComponentFromCurrentLib( libEntry ); - EXCHG( searchLib, m_library ); + + SetCurLib( old ); + DisplayLibInfos(); } -bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, CMP_LIBRARY* aLibrary ) +bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, PART_LIB* aLibrary ) { - wxString msg, cmpName, rootName; - LIB_COMPONENT* component; + wxString msg, rootName; - if( ( aEntry == NULL ) || ( aLibrary == NULL ) ) + if( !aEntry || !aLibrary ) return false; if( aEntry->GetName().IsEmpty() ) @@ -206,41 +208,28 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, CMP_LIBRARY* aLib return false; } - cmpName = m_aliasName = aEntry->GetName(); + wxString cmpName = m_aliasName = aEntry->GetName(); LIB_ALIAS* alias = (LIB_ALIAS*) aEntry; - component = alias->GetComponent(); - wxASSERT( component != NULL ); + LIB_PART* lib_part = alias->GetPart(); + + wxASSERT( lib_part ); wxLogDebug( wxT( "\"<%s>\" is alias of \"<%s>\"" ), GetChars( cmpName ), - GetChars( component->GetName() ) ); - - if( m_component ) - { - delete m_component; - m_aliasName.Empty(); - } - - m_component = new LIB_COMPONENT( *component ); - - if( m_component == NULL ) - { - msg.Printf( _( "Could not create copy of component <%s> in library <%s>." ), - GetChars( aEntry->GetName() ), - GetChars( aLibrary->GetName() ) ); - DisplayError( this, msg ); - return false; - } + GetChars( lib_part->GetName() ) ); + LIB_PART* part = new LIB_PART( *lib_part ); // clone it and own it. + SetCurPart( part ); m_aliasName = aEntry->GetName(); + m_unit = 1; m_convert = 1; m_showDeMorgan = false; - if( m_component->HasConversion() ) + if( part->HasConversion() ) m_showDeMorgan = true; GetScreen()->ClrModify(); @@ -248,8 +237,8 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, CMP_LIBRARY* aLib UpdateAliasSelectList(); UpdatePartSelectList(); - /* Display the document information based on the entry selected just in - * case the entry is an alias. */ + // Display the document information based on the entry selected just in + // case the entry is an alias. DisplayCmpDoc(); return true; @@ -258,16 +247,19 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, CMP_LIBRARY* aLib void LIB_EDIT_FRAME::RedrawComponent( wxDC* aDC, wxPoint aOffset ) { - if( m_component ) + LIB_PART* part = GetCurPart(); + + if( part ) { // display reference like in schematic (a reference U is shown U? or U?A) // although it is stored without ? and part id. // So temporary change the reference by a schematic like reference - LIB_FIELD* field = m_component->GetField( REFERENCE ); - wxString fieldText = field->GetText(); - wxString fieldfullText = field->GetFullText( m_unit ); + LIB_FIELD* field = part->GetField( REFERENCE ); + wxString fieldText = field->GetText(); + wxString fieldfullText = field->GetFullText( m_unit ); + field->EDA_TEXT::SetText( fieldfullText ); // change the field text string only - m_component->Draw( m_canvas, aDC, aOffset, m_unit, m_convert, GR_DEFAULT_DRAWMODE ); + part->Draw( m_canvas, aDC, aOffset, m_unit, m_convert, GR_DEFAULT_DRAWMODE ); field->EDA_TEXT::SetText( fieldText ); // restore the field text string } } @@ -317,7 +309,9 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); - if( !m_library ) + PART_LIB* lib = GetCurLib(); + + if( !lib ) { DisplayError( this, _( "No library specified." ) ); return false; @@ -326,20 +320,21 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) if( GetScreen()->IsModify() ) { if( IsOK( this, _( "Include last component changes?" ) ) ) - SaveOnePartInMemory(); + SaveOnePart( lib ); } if( newFile ) { PROJECT& prj = Prj(); - SEARCH_STACK& search = prj.SchSearchS(); + SEARCH_STACK* search = prj.SchSearchS(); // Get a new name for the library wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH ); - if( !default_path ) - default_path = search.LastVisitedPath(); - wxFileDialog dlg( this, _( "Component Library Name:" ), default_path, + if( !default_path ) + default_path = search->LastVisitedPath(); + + wxFileDialog dlg( this, _( "Part Library Name:" ), default_path, wxEmptyString, SchematicLibraryFileExtension, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); @@ -348,8 +343,8 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) fn = dlg.GetPath(); - /* The GTK file chooser doesn't return the file extension added to - * file name so add it here. */ + // The GTK file chooser doesn't return the file extension added to + // file name so add it here. if( fn.GetExt().IsEmpty() ) fn.SetExt( SchematicLibraryFileExtension ); @@ -357,16 +352,17 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) } else { - fn = wxFileName( m_library->GetFullFileName() ); + fn = wxFileName( lib->GetFullFileName() ); - msg.Printf( _( "Modify library file <%s> ?" ), + msg.Printf( _( "Modify library file '%s' ?" ), GetChars( fn.GetFullPath() ) ); if( !IsOK( this, msg ) ) return false; } - // Verify the user has write privileges before attempting to save the library file. + // Verify the user has write privileges before attempting to + // save the library file. if( !IsWritable( fn ) ) return false; @@ -379,6 +375,7 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) if( libFileName.FileExists() ) { backupFileName.SetExt( wxT( "bak" ) ); + if( backupFileName.FileExists() ) wxRemoveFile( backupFileName.GetFullPath() ); @@ -395,9 +392,9 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) { FILE_OUTPUTFORMATTER libFormatter( libFileName.GetFullPath() ); - if( !m_library->Save( libFormatter ) ) + if( !lib->Save( libFormatter ) ) { - msg.Printf( _( "Error occurred while saving library file <%s>" ), + msg.Printf( _( "Error occurred while saving library file '%s'" ), GetChars( fn.GetFullPath() ) ); AppendMsgPanel( _( "*** ERROR: ***" ), msg, RED ); DisplayError( this, msg ); @@ -407,7 +404,7 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) catch( ... /* IO_ERROR ioe */ ) { libFileName.MakeAbsolute(); - msg.Printf( _( "Failed to create component library file <%s>" ), + msg.Printf( _( "Failed to create component library file '%s'" ), GetChars( libFileName.GetFullPath() ) ); DisplayError( this, msg ); return false; @@ -437,7 +434,7 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) { FILE_OUTPUTFORMATTER docFormatter( docFileName.GetFullPath() ); - if( !m_library->SaveDocs( docFormatter ) ) + if( !lib->SaveDocs( docFormatter ) ) { msg.Printf( _( "Error occurred while saving library documentation file <%s>" ), GetChars( docFileName.GetFullPath() ) ); @@ -455,10 +452,10 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) return false; } - msg.Printf( _( "Library file <%s> OK" ), GetChars( fn.GetFullName() ) ); + msg.Printf( _( "Library file '%s' OK" ), GetChars( fn.GetFullName() ) ); fn.SetExt( DOC_EXT ); wxString msg1; - msg1.Printf( _( "Documentation file <%s> OK" ), GetChars( fn.GetFullPath() ) ); + msg1.Printf( _( "Documentation file '%s' OK" ), GetChars( fn.GetFullPath() ) ); AppendMsgPanel( msg, msg1, BLUE ); return true; @@ -467,24 +464,25 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) void LIB_EDIT_FRAME::DisplayCmpDoc() { - wxString msg; - LIB_ALIAS* alias; + LIB_ALIAS* alias; + PART_LIB* lib = GetCurLib(); + LIB_PART* part = GetCurPart(); ClearMsgPanel(); - if( m_library == NULL || m_component == NULL ) + if( !lib || !part ) return; - msg = m_component->GetName(); + wxString msg = part->GetName(); AppendMsgPanel( _( "Name" ), msg, BLUE, 8 ); - if( m_aliasName == m_component->GetName() ) + if( m_aliasName == part->GetName() ) msg = _( "None" ); else msg = m_aliasName; - alias = m_component->GetAlias( m_aliasName ); + alias = part->GetAlias( m_aliasName ); wxCHECK_RET( alias != NULL, wxT( "Alias not found in component." ) ); @@ -502,10 +500,10 @@ void LIB_EDIT_FRAME::DisplayCmpDoc() AppendMsgPanel( _( "Body" ), msg, GREEN, 8 ); - if( m_component->IsPower() ) + if( part->IsPower() ) msg = _( "Power Symbol" ); else - msg = _( "Component" ); + msg = _( "Part" ); AppendMsgPanel( _( "Type" ), msg, MAGENTA, 8 ); AppendMsgPanel( _( "Description" ), alias->GetDescription(), CYAN, 8 ); @@ -516,9 +514,9 @@ void LIB_EDIT_FRAME::DisplayCmpDoc() void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event ) { - wxString CmpName; - LIB_ALIAS* LibEntry; - wxArrayString ListNames; + wxString cmp_name; + LIB_ALIAS* libEntry; + wxArrayString nameList; wxString msg; m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); @@ -526,79 +524,84 @@ void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event ) m_lastDrawItem = NULL; m_drawItem = NULL; - if( m_library == NULL ) + PART_LIB* lib = GetCurLib(); + + if( !lib ) { SelectActiveLibrary(); - if( m_library == NULL ) + lib = GetCurLib(); + if( !lib ) { DisplayError( this, _( "Please select a component library." ) ); return; } } - m_library->GetEntryNames( ListNames ); + lib->GetEntryNames( nameList ); - if( ListNames.IsEmpty() ) + if( nameList.IsEmpty() ) { - msg.Printf( _( "Component library <%s> is empty." ), GetChars( m_library->GetName() ) ); + msg.Printf( _( "Part library '%s' is empty." ), GetChars( lib->GetName() ) ); wxMessageBox( msg, _( "Delete Entry Error" ), wxID_OK | wxICON_EXCLAMATION, this ); return; } - msg.Printf( _( "Select 1 of %d components to delete\nfrom library <%s>." ), - ListNames.GetCount(), - GetChars( m_library->GetName() ) ); + msg.Printf( _( "Select 1 of %d components to delete\nfrom library '%s'." ), + nameList.GetCount(), + GetChars( lib->GetName() ) ); - wxSingleChoiceDialog dlg( this, msg, _( "Delete Component" ), ListNames ); + wxSingleChoiceDialog dlg( this, msg, _( "Delete Part" ), nameList ); if( dlg.ShowModal() == wxID_CANCEL || dlg.GetStringSelection().IsEmpty() ) return; - LibEntry = m_library->FindEntry( dlg.GetStringSelection() ); + libEntry = lib->FindEntry( dlg.GetStringSelection() ); - if( LibEntry == NULL ) + if( !libEntry ) { - msg.Printf( _( "Entry <%s> not found in library <%s>." ), + msg.Printf( _( "Entry '%s' not found in library '%s'." ), GetChars( dlg.GetStringSelection() ), - GetChars( m_library->GetName() ) ); + GetChars( lib->GetName() ) ); DisplayError( this, msg ); return; } - msg.Printf( _( "Delete component %s from library %s?" ), - GetChars( LibEntry->GetName() ), - GetChars( m_library->GetName() ) ); + msg.Printf( _( "Delete component '%s' from library '%s' ?" ), + GetChars( libEntry->GetName() ), + GetChars( lib->GetName() ) ); if( !IsOK( this, msg ) ) return; - if( m_component == NULL || !m_component->HasAlias( LibEntry->GetName() ) ) + LIB_PART* part = GetCurPart(); + + if( !part || !part->HasAlias( libEntry->GetName() ) ) { - m_library->RemoveEntry( LibEntry ); + lib->RemoveEntry( libEntry ); return; } - /* If deleting the current entry or removing one of the aliases for - * the current entry, sync the changes in the current entry as well. - */ + // If deleting the current entry or removing one of the aliases for + // the current entry, sync the changes in the current entry as well. - if( GetScreen()->IsModify() - && !IsOK( this, _( "The component being deleted has been modified. \ -All changes will be lost. Discard changes?" ) ) ) + if( GetScreen()->IsModify() && !IsOK( this, _( + "The component being deleted has been modified." + " All changes will be lost. Discard changes?" ) ) ) + { return; + } - LIB_ALIAS* nextEntry = m_library->RemoveEntry( LibEntry ); + LIB_ALIAS* nextEntry = lib->RemoveEntry( libEntry ); if( nextEntry != NULL ) { - if( LoadOneLibraryPartAux( nextEntry, m_library ) ) + if( LoadOneLibraryPartAux( nextEntry, lib ) ) Zoom_Automatique( false ); } else { - delete m_component; - m_component = NULL; + SetCurPart( NULL ); // delete CurPart m_aliasName.Empty(); } @@ -611,16 +614,19 @@ void LIB_EDIT_FRAME::CreateNewLibraryPart( wxCommandEvent& event ) { wxString name; - if( m_component && GetScreen()->IsModify() - && !IsOK( this, _( "All changes to the current component will be \ -lost!\n\nClear the current component from the screen?" ) ) ) + if( GetCurPart() && GetScreen()->IsModify() && !IsOK( this, _( + "All changes to the current component will be lost!\n\n" + "Clear the current component from the screen?" ) ) ) + { return; + } m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); m_drawItem = NULL; DIALOG_LIB_NEW_COMPONENT dlg( this ); + dlg.SetMinSize( dlg.GetSize() ); if( dlg.ShowModal() == wxID_CANCEL ) @@ -639,101 +645,86 @@ lost!\n\nClear the current component from the screen?" ) ) ) #endif name.Replace( wxT( " " ), wxT( "_" ) ); - /* Test if there a component with this name already. */ - if( m_library && m_library->FindEntry( name ) ) + PART_LIB* lib = GetCurLib(); + + // Test if there a component with this name already. + if( lib && lib->FindEntry( name ) ) { - wxString msg; - msg.Printf( _( "Component %s already exists in library %s" ), - GetChars( name ), - GetChars( m_library->GetName() ) ); + wxString msg = wxString::Format( _( + "Part '%s' already exists in library '%s'" ), + GetChars( name ), + GetChars( lib->GetName() ) + ); DisplayError( this, msg ); return; } - LIB_COMPONENT* component = new LIB_COMPONENT( name ); - component->GetReferenceField().SetText( dlg.GetReference() ); - component->SetPartCount( dlg.GetPartCount() ); + LIB_PART* new_part = new LIB_PART( name ); - // Initialize component->m_TextInside member: + SetCurPart( new_part ); + m_aliasName = new_part->GetName(); + + new_part->GetReferenceField().SetText( dlg.GetReference() ); + new_part->SetUnitCount( dlg.GetUnitCount() ); + + // Initialize new_part->m_TextInside member: // if 0, pin text is outside the body (on the pin) // if > 0, pin text is inside the body - component->SetConversion( dlg.GetAlternateBodyStyle() ); + new_part->SetConversion( dlg.GetAlternateBodyStyle() ); SetShowDeMorgan( dlg.GetAlternateBodyStyle() ); if( dlg.GetPinNameInside() ) { - component->SetPinNameOffset( dlg.GetPinTextPosition() ); + new_part->SetPinNameOffset( dlg.GetPinTextPosition() ); - if( component->GetPinNameOffset() == 0 ) - component->SetPinNameOffset( 1 ); + if( new_part->GetPinNameOffset() == 0 ) + new_part->SetPinNameOffset( 1 ); } else { - component->SetPinNameOffset( 0 ); + new_part->SetPinNameOffset( 0 ); } - ( dlg.GetPowerSymbol() ) ? component->SetPower() : component->SetNormal(); - component->SetShowPinNumbers( dlg.GetShowPinNumber() ); - component->SetShowPinNames( dlg.GetShowPinName() ); - component->LockUnits( dlg.GetLockItems() ); + ( dlg.GetPowerSymbol() ) ? new_part->SetPower() : new_part->SetNormal(); + new_part->SetShowPinNumbers( dlg.GetShowPinNumber() ); + new_part->SetShowPinNames( dlg.GetShowPinName() ); + new_part->LockUnits( dlg.GetLockItems() ); - if( dlg.GetPartCount() < 2 ) - component->LockUnits( false ); + if( dlg.GetUnitCount() < 2 ) + new_part->LockUnits( false ); - m_aliasName = component->GetName(); - - if( m_component ) - { - delete m_component; - m_aliasName.Empty(); - } - - m_component = component; - m_aliasName = m_component->GetName(); m_unit = 1; m_convert = 1; + DisplayLibInfos(); DisplayCmpDoc(); UpdateAliasSelectList(); UpdatePartSelectList(); - m_editPinsPerPartOrConvert = m_component->UnitsLocked() ? true : false; + + m_editPinsPerPartOrConvert = new_part->UnitsLocked() ? true : false; m_lastDrawItem = NULL; + GetScreen()->ClearUndoRedoList(); OnModify(); + m_canvas->Refresh(); m_mainToolBar->Refresh(); } -void LIB_EDIT_FRAME::SaveOnePartInMemory() +void LIB_EDIT_FRAME::SaveOnePart( PART_LIB* aLib ) { - LIB_COMPONENT* oldComponent; - LIB_COMPONENT* component; - wxString msg; - - if( m_component == NULL ) - { - DisplayError( this, _( "No component to save." ) ); - return; - } - - if( m_library == NULL ) - SelectActiveLibrary(); - - if( m_library == NULL ) - { - DisplayError( this, _( "No library specified." ) ); - return; - } + wxString msg; + LIB_PART* part = GetCurPart(); GetScreen()->ClrModify(); - oldComponent = m_library->FindComponent( m_component->GetName() ); + LIB_PART* old_part = aLib->FindPart( part->GetName() ); - if( oldComponent != NULL ) + if( old_part ) { - msg.Printf( _( "Component %s already exists. Change it?" ), - GetChars( m_component->GetName() ) ); + msg.Printf( _( "Part '%s' already exists. Change it?" ), + GetChars( part->GetName() ) ); if( !IsOK( this, msg ) ) return; @@ -741,16 +732,14 @@ void LIB_EDIT_FRAME::SaveOnePartInMemory() m_drawItem = m_lastDrawItem = NULL; - if( oldComponent != NULL ) - component = m_library->ReplaceComponent( oldComponent, m_component ); + if( old_part ) + aLib->ReplacePart( old_part, part ); else - component = m_library->AddComponent( m_component ); + aLib->AddPart( part ); - if( component == NULL ) - return; + msg.Printf( _( "Part '%s' saved in library '%s'" ), + GetChars( part->GetName() ), + GetChars( aLib->GetName() ) ); - msg.Printf( _( "Component %s saved in library %s" ), - GetChars( component->GetName() ), - GetChars( m_library->GetName() ) ); SetStatusText( msg ); } diff --git a/eeschema/libedit_onleftclick.cpp b/eeschema/libedit_onleftclick.cpp index 6e566a096c..5ee53d9622 100644 --- a/eeschema/libedit_onleftclick.cpp +++ b/eeschema/libedit_onleftclick.cpp @@ -40,11 +40,13 @@ void LIB_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& aPosition ) { - LIB_ITEM* item = m_drawItem; - bool item_in_edit = item && item->InEditMode(); - bool no_item_edited = !item_in_edit; + LIB_ITEM* item = m_drawItem; + bool item_in_edit = item && item->InEditMode(); + bool no_item_edited = !item_in_edit; - if( m_component == NULL ) // No component loaded ! + LIB_PART* part = GetCurPart(); + + if( !part ) // No component loaded ! return; if( ( GetToolId() == ID_NO_TOOL_SELECTED ) && no_item_edited ) @@ -98,7 +100,7 @@ void LIB_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& aPosition ) case ID_LIBEDIT_BODY_RECT_BUTT: case ID_LIBEDIT_BODY_TEXT_BUTT: if( no_item_edited ) - m_drawItem = CreateGraphicItem( m_component, DC ); + m_drawItem = CreateGraphicItem( part, DC ); else if( m_drawItem ) { if( m_drawItem->IsNew() ) @@ -119,7 +121,7 @@ void LIB_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& aPosition ) break; case ID_LIBEDIT_ANCHOR_ITEM_BUTT: - SaveCopyInUndoList( m_component ); + SaveCopyInUndoList( part ); PlaceAnchor(); SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); break; @@ -139,16 +141,19 @@ void LIB_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& aPosition ) */ void LIB_EDIT_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& aPosition ) { - if( m_component == NULL ) + LIB_PART* part = GetCurPart(); + + if( !part ) return; - if( ( m_drawItem == NULL ) || !m_drawItem->InEditMode() ) + if( !m_drawItem || !m_drawItem->InEditMode() ) { // We can locate an item m_drawItem = LocateItemUsingCursor( aPosition ); if( m_drawItem == NULL ) { wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); + cmd.SetId( ID_LIBEDIT_GET_FRAME_EDIT_PART ); GetEventHandler()->ProcessEvent( cmd ); } @@ -160,7 +165,7 @@ void LIB_EDIT_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& aPosition ) return; m_canvas->SetIgnoreMouseEvents( true ); - bool not_edited = ! m_drawItem->InEditMode(); + bool not_edited = !m_drawItem->InEditMode(); switch( m_drawItem->Type() ) { @@ -168,6 +173,7 @@ void LIB_EDIT_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& aPosition ) if( not_edited ) { wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); + cmd.SetId( ID_LIBEDIT_EDIT_PIN ); GetEventHandler()->ProcessEvent( cmd ); } diff --git a/eeschema/libedit_onrightclick.cpp b/eeschema/libedit_onrightclick.cpp index 47eade4997..38f9e98151 100644 --- a/eeschema/libedit_onrightclick.cpp +++ b/eeschema/libedit_onrightclick.cpp @@ -49,17 +49,19 @@ static void AddMenusForPin( wxMenu* PopMenu, LIB_PIN* Pin, LIB_EDIT_FRAME* frame bool LIB_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) { - LIB_ITEM* item = GetDrawItem(); - bool BlockActive = GetScreen()->IsBlockActive(); + LIB_ITEM* item = GetDrawItem(); + bool blockActive = GetScreen()->IsBlockActive(); - if( BlockActive ) + if( blockActive ) { AddMenusForBlock( PopMenu, this ); PopMenu->AppendSeparator(); return true; } - if( m_component == NULL ) + LIB_PART* part = GetCurPart(); + + if( !part ) return true; // If Command in progress, put menu "cancel" diff --git a/eeschema/libedit_plot_component.cpp b/eeschema/libedit_plot_component.cpp index 45cc109de1..5399339f33 100644 --- a/eeschema/libedit_plot_component.cpp +++ b/eeschema/libedit_plot_component.cpp @@ -46,12 +46,13 @@ void LIB_EDIT_FRAME::OnPlotCurrentComponent( wxCommandEvent& event ) { - LIB_COMPONENT* cmp = GetComponent(); - wxString FullFileName; + wxString fullFileName; wxString file_ext; wxString mask; - if( cmp == NULL ) + LIB_PART* part = GetCurPart(); + + if( !part ) { wxMessageBox( _( "No component" ) ); return; @@ -65,20 +66,22 @@ void LIB_EDIT_FRAME::OnPlotCurrentComponent( wxCommandEvent& event ) file_ext = fmt_is_jpeg ? wxT( "jpg" ) : wxT( "png" ); mask = wxT( "*." ) + file_ext; - wxFileName fn( cmp->GetName() ); + wxFileName fn( part->GetName() ); fn.SetExt( file_ext ); - FullFileName = EDA_FileSelector( _( "Filename:" ), wxGetCwd(), + wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + + fullFileName = EDA_FileSelector( _( "Filename:" ), pro_dir, fn.GetFullName(), file_ext, mask, this, wxFD_SAVE, true ); - if( FullFileName.IsEmpty() ) + if( fullFileName.IsEmpty() ) return; // calling wxYield is mandatory under Linux, after closing the file selector dialog // to refresh the screen before creating the PNG or JPEG image from screen wxYield(); - CreatePNGorJPEGFile( FullFileName, fmt_is_jpeg ); + CreatePNGorJPEGFile( fullFileName, fmt_is_jpeg ); } break; @@ -86,26 +89,29 @@ void LIB_EDIT_FRAME::OnPlotCurrentComponent( wxCommandEvent& event ) { file_ext = wxT( "svg" ); mask = wxT( "*." ) + file_ext; - wxFileName fn( cmp->GetName() ); + wxFileName fn( part->GetName() ); fn.SetExt( file_ext ); - FullFileName = EDA_FileSelector( _( "Filename:" ), wxGetCwd(), + + wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + + fullFileName = EDA_FileSelector( _( "Filename:" ), pro_dir, fn.GetFullName(), file_ext, mask, this, wxFD_SAVE, true ); - if( FullFileName.IsEmpty() ) + if( fullFileName.IsEmpty() ) return; PAGE_INFO pageSave = GetScreen()->GetPageSettings(); PAGE_INFO pageTemp = pageSave; - wxSize componentSize = m_component->GetBoundingBox( m_unit, m_convert ).GetSize(); + wxSize componentSize = part->GetBoundingBox( m_unit, m_convert ).GetSize(); // Add a small margin to the plot bounding box pageTemp.SetWidthMils( int( componentSize.x * 1.2 ) ); pageTemp.SetHeightMils( int( componentSize.y * 1.2 ) ); GetScreen()->SetPageSettings( pageTemp ); - SVG_PlotComponent( FullFileName ); + SVG_PlotComponent( fullFileName ); GetScreen()->SetPageSettings( pageSave ); } break; @@ -165,18 +171,20 @@ void LIB_EDIT_FRAME::SVG_PlotComponent( const wxString& aFullFileName ) plotter->StartPlot(); - if( m_component ) + LIB_PART* part = GetCurPart(); + + if( part ) { - TRANSFORM temp; // Uses default transform - wxPoint plotPos; + TRANSFORM temp; // Uses default transform + wxPoint plotPos; + plotPos.x = pageInfo.GetWidthIU() /2; plotPos.y = pageInfo.GetHeightIU()/2; - m_component->Plot( plotter, GetUnit(), GetConvert(), plotPos, temp ); + part->Plot( plotter, GetUnit(), GetConvert(), plotPos, temp ); // Plot lib fields, not plotted by m_component->Plot(): - m_component->PlotLibFields( plotter, GetUnit(), GetConvert(), - plotPos, temp ); + part->PlotLibFields( plotter, GetUnit(), GetConvert(), plotPos, temp ); } plotter->EndPlot(); @@ -185,7 +193,9 @@ void LIB_EDIT_FRAME::SVG_PlotComponent( const wxString& aFullFileName ) void LIB_EDIT_FRAME::PrintPage( wxDC* aDC, LSET aPrintMask, bool aPrintMirrorMode, void* aData) { - if( ! m_component ) + LIB_PART* part = GetCurPart(); + + if( !part ) return; wxSize pagesize = GetScreen()->GetPageSettings().GetSizeIU(); @@ -198,7 +208,7 @@ void LIB_EDIT_FRAME::PrintPage( wxDC* aDC, LSET aPrintMask, bool aPrintMirrorMod plot_offset.x = pagesize.x/2; plot_offset.y = pagesize.y/2; - m_component->Draw( m_canvas, aDC, plot_offset, m_unit, m_convert, GR_DEFAULT_DRAWMODE ); + part->Draw( m_canvas, aDC, plot_offset, m_unit, m_convert, GR_DEFAULT_DRAWMODE ); } diff --git a/eeschema/libedit_undo_redo.cpp b/eeschema/libedit_undo_redo.cpp index bce47576d4..fa59cb5db8 100644 --- a/eeschema/libedit_undo_redo.cpp +++ b/eeschema/libedit_undo_redo.cpp @@ -13,10 +13,10 @@ void LIB_EDIT_FRAME::SaveCopyInUndoList( EDA_ITEM* ItemToCopy, int unused_flag ) { - LIB_COMPONENT* CopyItem; + LIB_PART* CopyItem; PICKED_ITEMS_LIST* lastcmd; - CopyItem = new LIB_COMPONENT( *( (LIB_COMPONENT*) ItemToCopy ) ); + CopyItem = new LIB_PART( * (LIB_PART*) ItemToCopy ); // Clear current flags (which can be temporary set by a current edit command). CopyItem->ClearStatus(); @@ -31,35 +31,38 @@ void LIB_EDIT_FRAME::SaveCopyInUndoList( EDA_ITEM* ItemToCopy, int unused_flag ) } -/* Redo the last edition: - * - Place the current edited library component in undo list - * - Get old version of the current edited library component - */ void LIB_EDIT_FRAME::GetComponentFromRedoList( wxCommandEvent& event ) { - if ( GetScreen()->GetRedoCommandCount() <= 0 ) + if( GetScreen()->GetRedoCommandCount() <= 0 ) return; PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); - ITEM_PICKER wrapper( m_component, UR_LIBEDIT ); + + LIB_PART* part = GetCurPart(); + + ITEM_PICKER wrapper( part, UR_LIBEDIT ); + lastcmd->PushItem( wrapper ); GetScreen()->PushCommandToUndoList( lastcmd ); lastcmd = GetScreen()->PopCommandFromRedoList(); wrapper = lastcmd->PopItem(); - m_component = (LIB_COMPONENT*) wrapper.GetItem(); - if( m_component == NULL ) + part = (LIB_PART*) wrapper.GetItem(); + + SetCurPart( part ); + + if( !part ) return; - if( !m_aliasName.IsEmpty() && !m_component->HasAlias( m_aliasName ) ) - m_aliasName = m_component->GetName(); + if( !m_aliasName.IsEmpty() && !part->HasAlias( m_aliasName ) ) + m_aliasName = part->GetName(); m_drawItem = NULL; UpdateAliasSelectList(); UpdatePartSelectList(); - SetShowDeMorgan( m_component->HasConversion() ); + SetShowDeMorgan( part->HasConversion() ); DisplayLibInfos(); DisplayCmpDoc(); OnModify(); @@ -67,35 +70,38 @@ void LIB_EDIT_FRAME::GetComponentFromRedoList( wxCommandEvent& event ) } -/** Undo the last edition: - * - Place the current edited library component in Redo list - * - Get old version of the current edited library component - */ void LIB_EDIT_FRAME::GetComponentFromUndoList( wxCommandEvent& event ) { - if ( GetScreen()->GetUndoCommandCount() <= 0 ) + if( GetScreen()->GetUndoCommandCount() <= 0 ) return; PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST(); - ITEM_PICKER wrapper( m_component, UR_LIBEDIT ); + + LIB_PART* part = GetCurPart(); + + ITEM_PICKER wrapper( part, UR_LIBEDIT ); + lastcmd->PushItem( wrapper ); GetScreen()->PushCommandToRedoList( lastcmd ); lastcmd = GetScreen()->PopCommandFromUndoList(); wrapper = lastcmd->PopItem(); - m_component = (LIB_COMPONENT*) wrapper.GetItem(); - if( m_component == NULL ) + part = (LIB_PART* ) wrapper.GetItem(); + + SetCurPart( part ); + + if( !part ) return; - if( !m_aliasName.IsEmpty() && !m_component->HasAlias( m_aliasName ) ) - m_aliasName = m_component->GetName(); + if( !m_aliasName.IsEmpty() && !part->HasAlias( m_aliasName ) ) + m_aliasName = part->GetName(); m_drawItem = NULL; UpdateAliasSelectList(); UpdatePartSelectList(); - SetShowDeMorgan( m_component->HasConversion() ); + SetShowDeMorgan( part->HasConversion() ); DisplayLibInfos(); DisplayCmpDoc(); OnModify(); diff --git a/eeschema/libeditframe.cpp b/eeschema/libeditframe.cpp index fd3597d3ac..0cb15e4e7b 100644 --- a/eeschema/libeditframe.cpp +++ b/eeschema/libeditframe.cpp @@ -72,15 +72,6 @@ int ImportPartId = ::wxNewId(); int CreateNewLibAndSavePartId = ::wxNewId(); -/* - * Static component library editor members. These are static so their - * state is saved between editing sessions. This way the last component - * that was being edited will be displayed. These members are protected - * making it necessary to use the class access methods. - */ -LIB_COMPONENT* LIB_EDIT_FRAME::m_component = NULL; -CMP_LIBRARY* LIB_EDIT_FRAME:: m_library = NULL; - wxString LIB_EDIT_FRAME:: m_aliasName; int LIB_EDIT_FRAME:: m_unit = 1; int LIB_EDIT_FRAME:: m_convert = 1; @@ -189,7 +180,9 @@ END_EVENT_TABLE() LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_LIB_EDITOR, _( "Library Editor" ), - wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GetLibEditFrameName() ) + wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GetLibEditFrameName() ), + m_my_part( 0 ), + m_tempCopyComponent( 0 ) { wxASSERT( aParent ); @@ -199,7 +192,6 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : SetShowDeMorgan( false ); m_drawSpecificConvert = true; m_drawSpecificUnit = false; - m_tempCopyComponent = NULL; m_HotkeysZoomAndGridList = s_Libedit_Hokeys_Descr; m_editPinsPerPartOrConvert = false; @@ -214,7 +206,7 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : icon.CopyFromBitmap( KiBitmap( libedit_icon_xpm ) ); SetIcon( icon ); - SetScreen( new SCH_SCREEN() ); + SetScreen( new SCH_SCREEN( aKiway ) ); GetScreen()->m_Center = true; SetCrossHairPosition( wxPoint( 0, 0 ) ); @@ -235,7 +227,6 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : if( m_canvas ) m_canvas->SetEnableBlockCommands( true ); - EnsureActiveLibExists(); ReCreateMenuBar(); ReCreateHToolbar(); ReCreateVToolbar(); @@ -284,10 +275,8 @@ LIB_EDIT_FRAME::~LIB_EDIT_FRAME() { m_drawItem = m_lastDrawItem = NULL; - if ( m_tempCopyComponent ) - delete m_tempCopyComponent; - - m_tempCopyComponent = NULL; + delete m_tempCopyComponent; + delete m_my_part; } const wxChar* LIB_EDIT_FRAME::GetLibEditFrameName() @@ -299,16 +288,6 @@ static const wxChar drawBgColorKey[] = wxT( "LibeditBgColor" ); void LIB_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg ) { -#if 0 // original - - wxConfigBase* cfg; - - EDA_DRAW_FRAME::LoadSettings(); - - wxConfigPathChanger cpc( wxGetApp().GetSettings(), m_configPath ); - cfg = Pgm().GetSettings(); -#else - EDA_DRAW_FRAME::LoadSettings( aCfg ); wxConfigPathChanger cpc( aCfg, m_configPath ); @@ -316,13 +295,13 @@ void LIB_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg ) EDA_COLOR_T itmp = ColorByName( aCfg->Read( drawBgColorKey, wxT("WHITE") ) ); SetDrawBgColor( itmp ); - m_lastLibExportPath = aCfg->Read( lastLibExportPathEntry, ::wxGetCwd() ); - m_lastLibImportPath = aCfg->Read( lastLibImportPathEntry, ::wxGetCwd() ); + wxString pro_dir = Prj().GetProjectFullName(); -#endif + m_lastLibExportPath = aCfg->Read( lastLibExportPathEntry, pro_dir ); + m_lastLibImportPath = aCfg->Read( lastLibImportPathEntry, pro_dir ); - m_lastLibExportPath = aCfg->Read( lastLibExportPathEntry, ::wxGetCwd() ); - m_lastLibImportPath = aCfg->Read( lastLibImportPathEntry, ::wxGetCwd() ); + m_lastLibExportPath = aCfg->Read( lastLibExportPathEntry, pro_dir ); + m_lastLibImportPath = aCfg->Read( lastLibImportPathEntry, pro_dir ); } @@ -332,7 +311,6 @@ void LIB_EDIT_FRAME::SetDrawItem( LIB_ITEM* drawItem ) } - void LIB_EDIT_FRAME::SaveSettings( wxConfigBase* aCfg ) { EDA_DRAW_FRAME::SaveSettings( aCfg ); @@ -369,13 +347,16 @@ void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) GetScreen()->ClrModify(); } - BOOST_FOREACH( const CMP_LIBRARY &lib, CMP_LIBRARY::GetLibraryList() ) + PART_LIBS* libs = Prj().SchLibs(); + + BOOST_FOREACH( const PART_LIB& lib, *libs ) { if( lib.IsModified() ) { - wxString msg; - msg.Printf( _( "Library %s was modified!\nDiscard changes?" ), - GetChars( lib.GetName() ) ); + wxString msg = wxString::Format( _( + "Library '%s' was modified!\nDiscard changes?" ), + GetChars( lib.GetName() ) + ); if( !IsOK( this, msg ) ) { @@ -398,14 +379,15 @@ double LIB_EDIT_FRAME::BestZoom() * and replace by static const int VIEWPORT_EXTENT = 10000; */ int dx, dy; - wxSize size; - EDA_RECT BoundaryBox; - if( m_component ) + LIB_PART* part = GetCurPart(); + + if( part ) { - BoundaryBox = m_component->GetBoundingBox( m_unit, m_convert ); - dx = BoundaryBox.GetWidth(); - dy = BoundaryBox.GetHeight(); + EDA_RECT boundingBox = part->GetBoundingBox( m_unit, m_convert ); + + dx = boundingBox.GetWidth(); + dy = boundingBox.GetHeight(); SetScrollCenterPosition( wxPoint( 0, 0 ) ); } else @@ -418,7 +400,7 @@ double LIB_EDIT_FRAME::BestZoom() SetScrollCenterPosition( wxPoint( 0, 0 ) ); } - size = m_canvas->GetClientSize(); + wxSize size = m_canvas->GetClientSize(); // Reserve a 10% margin around component bounding box. double margin_scale_factor = 0.8; @@ -443,10 +425,12 @@ void LIB_EDIT_FRAME::UpdateAliasSelectList() m_aliasSelectBox->Clear(); - if( m_component == NULL ) + LIB_PART* part = GetCurPart(); + + if( !part ) return; - m_aliasSelectBox->Append( m_component->GetAliasNames() ); + m_aliasSelectBox->Append( part->GetAliasNames() ); m_aliasSelectBox->SetSelection( 0 ); int index = m_aliasSelectBox->FindString( m_aliasName ); @@ -464,17 +448,19 @@ void LIB_EDIT_FRAME::UpdatePartSelectList() if( m_partSelectBox->GetCount() != 0 ) m_partSelectBox->Clear(); - if( m_component == NULL || m_component->GetPartCount() <= 1 ) + LIB_PART* part = GetCurPart(); + + if( !part || part->GetUnitCount() <= 1 ) { m_partSelectBox->Append( wxEmptyString ); } else { - for( int i = 0; i < m_component->GetPartCount(); i++ ) + for( int i = 0; i < part->GetUnitCount(); i++ ) { - wxString sub = LIB_COMPONENT::SubReference( i+1, false ); - wxString part = wxString::Format( _( "Unit %s" ), GetChars( sub ) ); - m_partSelectBox->Append( part ); + wxString sub = LIB_PART::SubReference( i+1, false ); + wxString unit = wxString::Format( _( "Unit %s" ), GetChars( sub ) ); + m_partSelectBox->Append( unit ); } } @@ -484,37 +470,41 @@ void LIB_EDIT_FRAME::UpdatePartSelectList() void LIB_EDIT_FRAME::OnUpdateEditingPart( wxUpdateUIEvent& aEvent ) { - aEvent.Enable( m_component != NULL ); + LIB_PART* part = GetCurPart(); - if( m_component != NULL && aEvent.GetEventObject() == m_drawToolBar ) + aEvent.Enable( part != NULL ); + + if( part && aEvent.GetEventObject() == m_drawToolBar ) aEvent.Check( GetToolId() == aEvent.GetId() ); } void LIB_EDIT_FRAME::OnUpdateNotEditingPart( wxUpdateUIEvent& event ) { - event.Enable( m_component == NULL ); + event.Enable( !GetCurPart() ); } void LIB_EDIT_FRAME::OnUpdateUndo( wxUpdateUIEvent& event ) { - event.Enable( m_component != NULL && GetScreen() != NULL - && GetScreen()->GetUndoCommandCount() != 0 && !IsEditingDrawItem() ); + event.Enable( GetCurPart() && GetScreen() && + GetScreen()->GetUndoCommandCount() != 0 && !IsEditingDrawItem() ); } void LIB_EDIT_FRAME::OnUpdateRedo( wxUpdateUIEvent& event ) { - event.Enable( m_component != NULL && GetScreen() != NULL - && GetScreen()->GetRedoCommandCount() != 0 && !IsEditingDrawItem() ); + event.Enable( GetCurPart() && GetScreen() && + GetScreen()->GetRedoCommandCount() != 0 && !IsEditingDrawItem() ); } void LIB_EDIT_FRAME::OnUpdateSaveCurrentLib( wxUpdateUIEvent& event ) { - event.Enable( m_library != NULL && !m_library->IsReadOnly() - && ( m_library->IsModified() || GetScreen()->IsModify() ) ); + PART_LIB* lib = GetCurLib(); + + event.Enable( lib && !lib->IsReadOnly() + && ( lib->IsModified() || GetScreen()->IsModify() ) ); } @@ -522,9 +512,12 @@ void LIB_EDIT_FRAME::OnUpdateViewDoc( wxUpdateUIEvent& event ) { bool enable = false; - if( m_component != NULL && m_library != NULL ) + PART_LIB* lib = GetCurLib(); + LIB_PART* part = GetCurPart(); + + if( part && lib ) { - LIB_ALIAS* alias = m_component->GetAlias( m_aliasName ); + LIB_ALIAS* alias = part->GetAlias( m_aliasName ); wxCHECK_RET( alias != NULL, wxT( "Alias <" ) + m_aliasName + wxT( "> not found." ) ); @@ -537,8 +530,9 @@ void LIB_EDIT_FRAME::OnUpdateViewDoc( wxUpdateUIEvent& event ) void LIB_EDIT_FRAME::OnUpdatePinByPin( wxUpdateUIEvent& event ) { - event.Enable( ( m_component != NULL ) - && ( ( m_component->GetPartCount() > 1 ) || m_showDeMorgan ) ); + LIB_PART* part = GetCurPart(); + + event.Enable( part && ( part->GetUnitCount() > 1 || m_showDeMorgan ) ); event.Check( m_editPinsPerPartOrConvert ); } @@ -549,10 +543,11 @@ void LIB_EDIT_FRAME::OnUpdatePartNumber( wxUpdateUIEvent& event ) if( m_partSelectBox == NULL ) return; - /* Using the typical event.Enable() call doesn't seem to work with wxGTK - * so use the pointer to alias combobox to directly enable or disable. - */ - m_partSelectBox->Enable( m_component && m_component->GetPartCount() > 1 ); + LIB_PART* part = GetCurPart(); + + // Using the typical event.Enable() call doesn't seem to work with wxGTK + // so use the pointer to alias combobox to directly enable or disable. + m_partSelectBox->Enable( part && part->GetUnitCount() > 1 ); } @@ -561,7 +556,9 @@ void LIB_EDIT_FRAME::OnUpdateDeMorganNormal( wxUpdateUIEvent& event ) if( m_mainToolBar == NULL ) return; - event.Enable( GetShowDeMorgan() || ( m_component && m_component->HasConversion() ) ); + LIB_PART* part = GetCurPart(); + + event.Enable( GetShowDeMorgan() || ( part && part->HasConversion() ) ); event.Check( m_convert <= 1 ); } @@ -571,7 +568,9 @@ void LIB_EDIT_FRAME::OnUpdateDeMorganConvert( wxUpdateUIEvent& event ) if( m_mainToolBar == NULL ) return; - event.Enable( GetShowDeMorgan() || ( m_component && m_component->HasConversion() ) ); + LIB_PART* part = GetCurPart(); + + event.Enable( GetShowDeMorgan() || ( part && part->HasConversion() ) ); event.Check( m_convert > 1 ); } @@ -581,10 +580,11 @@ void LIB_EDIT_FRAME::OnUpdateSelectAlias( wxUpdateUIEvent& event ) if( m_aliasSelectBox == NULL ) return; - /* Using the typical event.Enable() call doesn't seem to work with wxGTK - * so use the pointer to alias combobox to directly enable or disable. - */ - m_aliasSelectBox->Enable( m_component != NULL && m_component->GetAliasCount() > 1 ); + LIB_PART* part = GetCurPart(); + + // Using the typical event.Enable() call doesn't seem to work with wxGTK + // so use the pointer to alias combobox to directly enable or disable. + m_aliasSelectBox->Enable( part && part->GetAliasCount() > 1 ); } @@ -618,11 +618,13 @@ void LIB_EDIT_FRAME::OnSelectPart( wxCommandEvent& event ) void LIB_EDIT_FRAME::OnViewEntryDoc( wxCommandEvent& event ) { - if( m_component == NULL ) + LIB_PART* part = GetCurPart(); + + if( !part ) return; wxString fileName; - LIB_ALIAS* alias = m_component->GetAlias( m_aliasName ); + LIB_ALIAS* alias = part->GetAlias( m_aliasName ); wxCHECK_RET( alias != NULL, wxT( "Alias not found." ) ); @@ -630,7 +632,7 @@ void LIB_EDIT_FRAME::OnViewEntryDoc( wxCommandEvent& event ) if( !fileName.IsEmpty() ) { - SEARCH_STACK* lib_search = &Prj().SchSearchS(); + SEARCH_STACK* lib_search = Prj().SchSearchS(); GetAssociatedDocument( this, fileName, lib_search ); } @@ -710,7 +712,30 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_LIBEDIT_SAVE_CURRENT_PART: - SaveOnePartInMemory(); + { + LIB_PART* part = GetCurPart(); + + if( !part ) + { + DisplayError( this, _( "No part to save." ) ); + break; + } + + PART_LIB* lib = GetCurLib(); + + if( !lib ) + SelectActiveLibrary(); + + lib = GetCurLib(); + + if( !lib ) + { + DisplayError( this, _( "No library specified." ) ); + break; + } + + SaveOnePart( lib ); + } break; case ID_LIBEDIT_EDIT_PIN_BY_PIN: @@ -821,13 +846,18 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM: case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM: case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM: - if( ( m_drawItem == NULL ) || ( m_drawItem->Type() != LIB_PIN_T ) ) - break; + { + if( !m_drawItem || m_drawItem->Type() != LIB_PIN_T ) + break; - SaveCopyInUndoList( m_component ); - GlobalSetPins( (LIB_PIN*) m_drawItem, id ); - m_canvas->MoveCursorToCrossHair(); - m_canvas->Refresh(); + LIB_PART* part = GetCurPart(); + + SaveCopyInUndoList( part ); + + GlobalSetPins( (LIB_PIN*) m_drawItem, id ); + m_canvas->MoveCursorToCrossHair(); + m_canvas->Refresh(); + } break; case ID_POPUP_ZOOM_BLOCK: @@ -899,49 +929,92 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) void LIB_EDIT_FRAME::OnActivate( wxActivateEvent& event ) { EDA_DRAW_FRAME::OnActivate( event ); - - // Verify the existence of the current active library - // (can be removed or changed by the schematic editor) - EnsureActiveLibExists(); } -void LIB_EDIT_FRAME::EnsureActiveLibExists() +PART_LIB* LIB_EDIT_FRAME::GetCurLib() { - if( m_library == NULL ) - return; + wxString name = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_LIB ); - bool exists = CMP_LIBRARY::LibraryExists( m_library ); + if( !!name ) + { + PART_LIB* lib = Prj().SchLibs()->FindLibrary( name ); - if( exists ) - return; + if( !lib ) + Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, wxEmptyString ); + + return lib; + } + + return NULL; +} + + +PART_LIB* LIB_EDIT_FRAME::SetCurLib( PART_LIB* aLib ) +{ + PART_LIB* old = GetCurLib(); + + if( !aLib || !aLib->GetName() ) + Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, wxEmptyString ); else - m_library = NULL; + Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, aLib->GetName() ); + + return old; +} + + +LIB_PART* LIB_EDIT_FRAME::GetCurPart() +{ + if( !m_my_part ) + { + wxString name = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_PART ); + LIB_PART* part; + + if( !!name && ( part = Prj().SchLibs()->FindLibPart( name ) ) ) + { + // clone it from the PART_LIB and own it. + m_my_part = new LIB_PART( *part ); + } + else + Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART, wxEmptyString ); + } + + return m_my_part; +} + + +void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart ) +{ + delete m_my_part; + m_my_part = aPart; // take ownership here + + // retain in case this wxFrame is re-opened later on the same PROJECT + Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART, + aPart ? aPart->GetName() : wxString() ); } void LIB_EDIT_FRAME::TempCopyComponent() { - if( m_tempCopyComponent ) - delete m_tempCopyComponent; + delete m_tempCopyComponent; - m_tempCopyComponent = NULL; - - if( m_component ) - m_tempCopyComponent = new LIB_COMPONENT( *m_component ); + if( LIB_PART* part = GetCurPart() ) + // clone it and own the clone. + m_tempCopyComponent = new LIB_PART( *part ); + else + // clear it, there was no CurPart + m_tempCopyComponent = NULL; } void LIB_EDIT_FRAME::RestoreComponent() { - if( m_tempCopyComponent == NULL ) - return; - - if( m_component ) - delete m_component; - - m_component = m_tempCopyComponent; - m_tempCopyComponent = NULL; + if( m_tempCopyComponent ) + { + // transfer ownership to CurPart + SetCurPart( m_tempCopyComponent ); + m_tempCopyComponent = NULL; + } } @@ -952,7 +1025,6 @@ void LIB_EDIT_FRAME::ClearTempCopyComponent() } - void LIB_EDIT_FRAME::EditSymbolText( wxDC* DC, LIB_ITEM* DrawItem ) { if ( ( DrawItem == NULL ) || ( DrawItem->Type() != LIB_TEXT_T ) ) @@ -977,18 +1049,18 @@ void LIB_EDIT_FRAME::EditSymbolText( wxDC* DC, LIB_ITEM* DrawItem ) void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event ) { - bool partLocked = GetComponent()->UnitsLocked(); + bool partLocked = GetCurPart()->UnitsLocked(); DIALOG_EDIT_COMPONENT_IN_LIBRARY dlg( this ); if( dlg.ShowModal() == wxID_CANCEL ) return; - if( partLocked != GetComponent()->UnitsLocked() ) + if( partLocked != GetCurPart()->UnitsLocked() ) { // m_editPinsPerPartOrConvert is set to the better value, if m_UnitSelectionLocked // has changed - m_editPinsPerPartOrConvert = GetComponent()->UnitsLocked() ? true : false; + m_editPinsPerPartOrConvert = GetCurPart()->UnitsLocked() ? true : false; } UpdateAliasSelectList(); @@ -1009,16 +1081,20 @@ void LIB_EDIT_FRAME::InstallDimensionsDialog( wxCommandEvent& event ) void LIB_EDIT_FRAME::OnCreateNewPartFromExisting( wxCommandEvent& event ) { - wxCHECK_RET( m_component != NULL, - wxT( "Cannot create new part from non-existent current part." ) ); + LIB_PART* part = GetCurPart(); + + wxCHECK_RET( part, wxT( "Cannot create new part from non-existent current part." ) ); INSTALL_UNBUFFERED_DC( dc, m_canvas ); m_canvas->CrossHairOff( &dc ); - EditField( &m_component->GetValueField() ); + + EditField( &part->GetValueField() ); + m_canvas->MoveCursorToCrossHair(); m_canvas->CrossHairOn( &dc ); } + void LIB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) { int id = aEvent.GetId(); @@ -1029,6 +1105,8 @@ void LIB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); + LIB_PART* part = GetCurPart(); + switch( id ) { case ID_NO_TOOL_SELECTED: @@ -1036,14 +1114,16 @@ void LIB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) break; case ID_LIBEDIT_PIN_BUTT: - if( m_component ) + if( part ) { SetToolID( id, wxCURSOR_PENCIL, _( "Add pin" ) ); } else { SetToolID( id, wxCURSOR_ARROW, _( "Set pin options" ) ); + wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); + cmd.SetId( ID_LIBEDIT_EDIT_PIN ); GetEventHandler()->ProcessEvent( cmd ); SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString ); @@ -1087,7 +1167,7 @@ void LIB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent ) break; case ID_LIBEDIT_DELETE_ITEM_BUTT: - if( m_component == NULL ) + if( !part ) { wxBell(); break; @@ -1111,7 +1191,9 @@ void LIB_EDIT_FRAME::OnRotateItem( wxCommandEvent& aEvent ) if( !m_drawItem->InEditMode() ) { - SaveCopyInUndoList( m_component ); + LIB_PART* part = GetCurPart(); + + SaveCopyInUndoList( part ); m_drawItem->SetUnit( m_unit ); } @@ -1131,7 +1213,9 @@ void LIB_EDIT_FRAME::OnRotateItem( wxCommandEvent& aEvent ) LIB_ITEM* LIB_EDIT_FRAME::LocateItemUsingCursor( const wxPoint& aPosition, const KICAD_T aFilterList[] ) { - if( m_component == NULL ) + LIB_PART* part = GetCurPart(); + + if( !part ) return NULL; LIB_ITEM* item = locateItem( aPosition, aFilterList ); @@ -1150,12 +1234,14 @@ LIB_ITEM* LIB_EDIT_FRAME::LocateItemUsingCursor( const wxPoint& aPosition, LIB_ITEM* LIB_EDIT_FRAME::locateItem( const wxPoint& aPosition, const KICAD_T aFilterList[] ) { - if( m_component == NULL ) + LIB_PART* part = GetCurPart(); + + if( !part ) return NULL; LIB_ITEM* item = NULL; - m_collectedItems.Collect( m_component->GetDrawItemList(), aFilterList, aPosition, + m_collectedItems.Collect( part->GetDrawItemList(), aFilterList, aPosition, m_unit, m_convert ); if( m_collectedItems.GetCount() == 0 ) @@ -1181,8 +1267,9 @@ LIB_ITEM* LIB_EDIT_FRAME::locateItem( const wxPoint& aPosition, const KICAD_T aF for( int i = 0; i < m_collectedItems.GetCount() && i < MAX_SELECT_ITEM_IDS; i++ ) { - wxString text = m_collectedItems[i]->GetSelectMenuText(); - BITMAP_DEF xpm = m_collectedItems[i]->GetMenuImage(); + wxString text = m_collectedItems[i]->GetSelectMenuText(); + BITMAP_DEF xpm = m_collectedItems[i]->GetMenuImage(); + AddMenuItem( &selectMenu, ID_SELECT_ITEM_START + i, text, KiBitmap( xpm ) ); } @@ -1215,28 +1302,31 @@ void LIB_EDIT_FRAME::deleteItem( wxDC* aDC ) wxCHECK_RET( m_drawItem != NULL, wxT( "No drawing item selected to delete." ) ); m_canvas->CrossHairOff( aDC ); - SaveCopyInUndoList( m_component ); + + LIB_PART* part = GetCurPart(); + + SaveCopyInUndoList( part ); if( m_drawItem->Type() == LIB_PIN_T ) { - LIB_PIN* pin = (LIB_PIN*) m_drawItem; - wxPoint pos = pin->GetPosition(); + LIB_PIN* pin = (LIB_PIN*) m_drawItem; + wxPoint pos = pin->GetPosition(); - m_component->RemoveDrawItem( (LIB_ITEM*) pin, m_canvas, aDC ); + part->RemoveDrawItem( (LIB_ITEM*) pin, m_canvas, aDC ); if( SynchronizePins() ) { - LIB_PIN* tmp = m_component->GetNextPin(); + LIB_PIN* tmp = part->GetNextPin(); while( tmp != NULL ) { pin = tmp; - tmp = m_component->GetNextPin( pin ); + tmp = part->GetNextPin( pin ); if( pin->GetPosition() != pos ) continue; - m_component->RemoveDrawItem( (LIB_ITEM*) pin ); + part->RemoveDrawItem( (LIB_ITEM*) pin ); } } @@ -1250,7 +1340,7 @@ void LIB_EDIT_FRAME::deleteItem( wxDC* aDC ) } else { - m_component->RemoveDrawItem( m_drawItem, m_canvas, aDC ); + part->RemoveDrawItem( m_drawItem, m_canvas, aDC ); m_canvas->Refresh(); } } @@ -1277,8 +1367,10 @@ void LIB_EDIT_FRAME::OnSelectItem( wxCommandEvent& aEvent ) } -bool LIB_EDIT_FRAME::SynchronizePins() const +bool LIB_EDIT_FRAME::SynchronizePins() { - return !m_editPinsPerPartOrConvert && ( m_component && ( m_component->HasConversion() || - m_component->IsMulti()) ); + LIB_PART* part = GetCurPart(); + + return !m_editPinsPerPartOrConvert && ( part && + ( part->HasConversion() || part->IsMulti() ) ); } diff --git a/eeschema/libeditframe.h b/eeschema/libeditframe.h index b328785980..a423d45487 100644 --- a/eeschema/libeditframe.h +++ b/eeschema/libeditframe.h @@ -39,8 +39,8 @@ class SCH_EDIT_FRAME; -class CMP_LIBRARY; -class LIB_COMPONENT; +class PART_LIB; +class LIB_PART; class LIB_ALIAS; class LIB_FIELD; class DIALOG_LIB_EDIT_TEXT; @@ -50,7 +50,8 @@ class DIALOG_LIB_EDIT_TEXT; */ class LIB_EDIT_FRAME : public SCH_BASE_FRAME { - LIB_COMPONENT* m_tempCopyComponent; ///< Temporary copy of current component during edit. + LIB_PART* m_my_part; ///< a part I own, it is not in any library, but a copy could be. + LIB_PART* m_tempCopyComponent; ///< temp copy of a part during edit, I own it here. LIB_COLLECTOR m_collectedItems; ///< Used for hit testing. wxComboBox* m_partSelectBox; ///< a Box to select a part to edit (if any) wxComboBox* m_aliasSelectBox; ///< a box to select the alias to edit (if any) @@ -85,14 +86,9 @@ class LIB_EDIT_FRAME : public SCH_BASE_FRAME /** Default line width for drawing or editing graphic items. */ static int m_drawLineWidth; - /** The current active library. NULL if no active library is selected. */ - static CMP_LIBRARY* m_library; - /** The current component being edited. NULL if no component is selected. */ - static LIB_COMPONENT* m_component; - - static LIB_ITEM* m_lastDrawItem; - static LIB_ITEM* m_drawItem; - static wxString m_aliasName; + static LIB_ITEM* m_lastDrawItem; + static LIB_ITEM* m_drawItem; + static wxString m_aliasName; // The unit number to edit and show static int m_unit; @@ -133,6 +129,26 @@ public: */ static const wxChar* GetLibEditFrameName(); + /** The current library being edited, or NULL if none. */ + PART_LIB* GetCurLib(); + + /** Sets the current library and return the old. */ + PART_LIB* SetCurLib( PART_LIB* aLib ); + + /** + * Function GetCurPart + * returns the current part being edited, or NULL if none selected. + * This is a LIB_PART that I own, it is at best a copy of one in a library. + */ + LIB_PART* GetCurPart(); + + /** + * Function SetCurPart + * takes ownership over aPart and notes that it is the one currently + * being edited. + */ + void SetCurPart( LIB_PART* aPart ); + void ReCreateMenuBar(); /** @@ -153,7 +169,7 @@ public: * component has multiple parts or body styles. Otherwise false is * returned. */ - bool SynchronizePins() const; + bool SynchronizePins(); /** * Function OnPlotCurrentComponent @@ -296,7 +312,6 @@ public: Close( false ); } - /** * Function OnModify * Must be called after a schematic change @@ -307,14 +322,9 @@ public: GetScreen()->SetModify(); } + const wxString& GetAliasName() { return m_aliasName; } - LIB_COMPONENT* GetComponent( void ) { return m_component; } - - CMP_LIBRARY* GetLibrary( void ) { return m_library; } - - wxString& GetAliasName( void ) { return m_aliasName; } - - int GetUnit( void ) { return m_unit; } + int GetUnit() { return m_unit; } void SetUnit( int unit ) { @@ -322,8 +332,7 @@ public: m_unit = unit; } - - int GetConvert( void ) { return m_convert; } + int GetConvert() { return m_convert; } void SetConvert( int convert ) { @@ -331,24 +340,22 @@ public: m_convert = convert; } - - LIB_ITEM* GetLastDrawItem( void ) { return m_lastDrawItem; } + LIB_ITEM* GetLastDrawItem() { return m_lastDrawItem; } void SetLastDrawItem( LIB_ITEM* drawItem ) { m_lastDrawItem = drawItem; } - - LIB_ITEM* GetDrawItem( void ) { return m_drawItem; } + LIB_ITEM* GetDrawItem() { return m_drawItem; } void SetDrawItem( LIB_ITEM* drawItem ); - bool GetShowDeMorgan( void ) { return m_showDeMorgan; } + bool GetShowDeMorgan() { return m_showDeMorgan; } void SetShowDeMorgan( bool show ) { m_showDeMorgan = show; } - FILL_T GetFillStyle( void ) { return m_drawFillStyle; } + FILL_T GetFillStyle() { return m_drawFillStyle; } /** * Function TempCopyComponent @@ -368,7 +375,7 @@ public: * Function GetTempCopyComponent * @return the temporary copy of the current component. */ - LIB_COMPONENT* GetTempCopyComponent() { return m_tempCopyComponent; } + LIB_PART* GetTempCopyComponent() { return m_tempCopyComponent; } /** * Function ClearTempCopyComponent @@ -384,30 +391,30 @@ private: * Function OnActivate * is called when the frame is activated. Tests if the current library exists. * The library list can be changed by the schematic editor after reloading a new schematic - * and the current m_library can point a non existent lib. + * and the current library can point a non existent lib. */ virtual void OnActivate( wxActivateEvent& event ); // General: /** - * Function SaveOnePartInMemory - * updates the current component being edited in the active library. + * Function SaveOnePart + * saves the current LIB_PART into the provided PART_LIB. * * Any changes are updated in memory only and NOT to a file. The old component is * deleted from the library and/or any aliases before the edited component is updated * in the library. */ - void SaveOnePartInMemory(); + void SaveOnePart( PART_LIB* aLib ); /** * Function SelectActiveLibrary * sets the current active library to \a aLibrary. * - * @param aLibrary A pointer to the CMP_LIBRARY object to select. If NULL, then display + * @param aLibrary A pointer to the PART_LIB object to select. If NULL, then display * list of available libraries to select from. */ - void SelectActiveLibrary( CMP_LIBRARY* aLibrary = NULL ); + void SelectActiveLibrary( PART_LIB* aLibrary = NULL ); /** * Function OnSaveActiveLibrary @@ -442,10 +449,10 @@ private: * loads a copy of \a aLibEntry from \a aLibrary into memory. * * @param aLibEntry A pointer to the LIB_ALIAS object to load. - * @param aLibrary A pointer to the CMP_LIBRARY object to load \a aLibEntry from. + * @param aLibrary A pointer to the PART_LIB object to load \a aLibEntry from. * @return True if a copy of \a aLibEntry was successfully loaded from \a aLibrary. */ - bool LoadOneLibraryPartAux( LIB_ALIAS* aLibEntry, CMP_LIBRARY* aLibrary ); + bool LoadOneLibraryPartAux( LIB_ALIAS* aLibEntry, PART_LIB* aLibrary ); /** * Function DisplayCmpDoc @@ -501,7 +508,7 @@ private: void PlaceAnchor(); // Editing graphic items - LIB_ITEM* CreateGraphicItem( LIB_COMPONENT* LibEntry, wxDC* DC ); + LIB_ITEM* CreateGraphicItem( LIB_PART* LibEntry, wxDC* DC ); void GraphicItemBeginDraw( wxDC* DC ); void StartMoveDrawSymbol( wxDC* DC ); void StartModifyDrawSymbol( wxDC* DC ); //GetParent(); + LIB_PART* parent = aField->GetParent(); // Editing the component value field is equivalent to creating a new component based // on the current component. Set the dialog message to inform the user. @@ -71,17 +71,21 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField ) * the old one. Rename the component and remove any conflicting aliases to prevent name * errors when updating the library. */ - if( (aField->GetId() == VALUE) && ( text != aField->GetText() ) ) + if( aField->GetId() == VALUE && text != aField->GetText() ) { wxString msg; + PART_LIB* lib = GetCurLib(); + // Test the current library for name conflicts. - if( m_library && m_library->FindEntry( text ) != NULL ) + if( lib && lib->FindEntry( text ) ) { - msg.Printf( _( "The name <%s> conflicts with an existing entry in the component \ -library <%s>.\n\nDo you wish to replace the current component in library with this one?" ), - GetChars( text ), - GetChars( m_library->GetName() ) ); + msg.Printf( _( + "The name '%s' conflicts with an existing entry in the component library '%s'.\n\n" + "Do you wish to replace the current component in library with this one?" ), + GetChars( text ), + GetChars( lib->GetName() ) + ); int rsp = wxMessageBox( msg, _( "Confirm" ), wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT, this ); @@ -93,9 +97,11 @@ library <%s>.\n\nDo you wish to replace the current component in library with th // Test the current component for name conflicts. if( parent->HasAlias( text ) ) { - msg.Printf( _( "The current component already has an alias named <%s>.\n\nDo you \ -wish to remove this alias from the component?" ), - GetChars( text ) ); + msg.Printf( _( + "The current component already has an alias named '%s'.\n\n" + "Do you wish to remove this alias from the component?" ), + GetChars( text ) + ); int rsp = wxMessageBox( msg, _( "Confirm" ), wxYES_NO | wxICON_QUESTION, this ); @@ -108,12 +114,13 @@ wish to remove this alias from the component?" ), parent->SetName( text ); // Test the library for any conflicts with the any aliases in the current component. - if( parent->GetAliasCount() > 1 && m_library && m_library->Conflicts( parent ) ) + if( parent->GetAliasCount() > 1 && lib && lib->Conflicts( parent ) ) { - msg.Printf( _( "The new component contains alias names that conflict with entries \ -in the component library <%s>.\n\nDo you wish to remove all of the conflicting aliases from \ -this component?" ), - GetChars( m_library->GetName() ) ); + msg.Printf( _( + "The new component contains alias names that conflict with entries in the component library '%s'.\n\n" + "Do you wish to remove all of the conflicting aliases from this component?" ), + GetChars( lib->GetName() ) + ); int rsp = wxMessageBox( msg, _( "Confirm" ), wxYES_NO | wxICON_QUESTION, this ); @@ -127,7 +134,7 @@ this component?" ), for( size_t i = 0; i < aliases.GetCount(); i++ ) { - if( m_library->FindEntry( aliases[ i ] ) != NULL ) + if( lib->FindEntry( aliases[ i ] ) != NULL ) parent->RemoveAlias( aliases[ i ] ); } } diff --git a/eeschema/load_one_schematic_file.cpp b/eeschema/load_one_schematic_file.cpp index 8aa9243d79..ae159cb315 100644 --- a/eeschema/load_one_schematic_file.cpp +++ b/eeschema/load_one_schematic_file.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -76,17 +77,19 @@ bool SCH_EDIT_FRAME::LoadOneEEFile( SCH_SCREEN* aScreen, const wxString& aFullFi if( !append ) aScreen->SetFileName( aFullFileName ); - FILE* f; - wxString fname = aFullFileName; + wxString fname = Prj().AbsolutePath( aFullFileName ); + #ifdef __WINDOWS__ fname.Replace( wxT("/"), wxT("\\") ); #else fname.Replace( wxT("\\"), wxT("/") ); #endif - if( ( f = wxFopen( fname, wxT( "rt" ) ) ) == NULL ) + FILE* f = wxFopen( fname, wxT( "rt" ) ); + + if( !f ) { - msgDiag.Printf( _( "Failed to open <%s>" ), GetChars( aFullFileName ) ); + msgDiag.Printf( _( "Failed to open '%s'" ), GetChars( aFullFileName ) ); DisplayError( this, msgDiag ); return false; } @@ -94,14 +97,14 @@ bool SCH_EDIT_FRAME::LoadOneEEFile( SCH_SCREEN* aScreen, const wxString& aFullFi // reader now owns the open FILE. FILE_LINE_READER reader( f, aFullFileName ); - msgDiag.Printf( _( "Loading <%s>" ), GetChars( aScreen->GetFileName() ) ); + msgDiag.Printf( _( "Loading '%s'" ), GetChars( aScreen->GetFileName() ) ); PrintMsg( msgDiag ); if( !reader.ReadLine() || strncmp( (char*)reader + 9, SCHEMATIC_HEAD_STRING, sizeof( SCHEMATIC_HEAD_STRING ) - 1 ) != 0 ) { - msgDiag.Printf( _( "<%s> is NOT an Eeschema file!" ), GetChars( aFullFileName ) ); + msgDiag.Printf( _( "'%s' is NOT an Eeschema file!" ), GetChars( aFullFileName ) ); DisplayError( this, msgDiag ); return false; } @@ -119,9 +122,11 @@ bool SCH_EDIT_FRAME::LoadOneEEFile( SCH_SCREEN* aScreen, const wxString& aFullFi if( version > EESCHEMA_VERSION ) { - msgDiag.Printf( _( "<%s> was created by a more recent \ -version of Eeschema and may not load correctly. Please consider updating!" ), - GetChars( aFullFileName ) ); + msgDiag.Printf( _( + "'%s' was created by a more recent version of Eeschema and may not" + " load correctly. Please consider updating!" ), + GetChars( aFullFileName ) + ); DisplayInfoMessage( this, msgDiag ); } diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 6d3e006b56..d8f182cc3b 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -266,7 +266,6 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text, HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) ); // Menu place: - // @todo unify IDs wxMenu* placeMenu = new wxMenu; text = AddHotkeyName( _( "&Component" ), s_Schematic_Hokeys_Descr, @@ -428,7 +427,7 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() wxMenu* toolsMenu = new wxMenu; AddMenuItem( toolsMenu, - ID_TO_LIBRARY, + ID_RUN_LIBRARY, _( "Library &Editor" ), HELP_RUN_LIB_EDITOR, KiBitmap( libedit_xpm ) ); @@ -467,14 +466,14 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() // Run CvPcb AddMenuItem( toolsMenu, - ID_TO_CVPCB, + ID_RUN_CVPCB, _( "A&ssign Component Footprint" ), _( "Run CvPcb" ), KiBitmap( cvpcb_xpm ) ); // Run Pcbnew AddMenuItem( toolsMenu, - ID_TO_PCB, + ID_RUN_PCB, _( "&Layout Printed Circuit Board" ), _( "Run Pcbnew" ), KiBitmap( pcbnew_xpm ) ); diff --git a/eeschema/netform.cpp b/eeschema/netform.cpp index 13cc927694..16f9bde6a8 100644 --- a/eeschema/netform.cpp +++ b/eeschema/netform.cpp @@ -92,7 +92,9 @@ bool UNIQUE_STRINGS::Lookup( const wxString& aString ) */ class NETLIST_EXPORT_TOOL { - NETLIST_OBJECT_LIST * m_masterList; /// The main connected items flat list + NETLIST_OBJECT_LIST* m_masterList; /// The main connected items flat list + + PART_LIBS* m_libs; /// no ownership /// Used to temporary store and filter the list of pins of a schematic component /// when generating schematic component data in netlist (comp section) @@ -167,7 +169,7 @@ class NETLIST_EXPORT_TOOL * to the temporary sorted pin list. */ void findAllInstancesOfComponent( SCH_COMPONENT* aComponent, - LIB_COMPONENT* aEntry, + LIB_PART* aEntry, SCH_SHEET_PATH* aSheetPath ); /** @@ -230,9 +232,10 @@ class NETLIST_EXPORT_TOOL XNODE* makeGenericLibraries(); public: - NETLIST_EXPORT_TOOL( NETLIST_OBJECT_LIST * aMasterList ) + NETLIST_EXPORT_TOOL( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) { m_masterList = aMasterList; + m_libs = aLibs; } /** @@ -375,7 +378,8 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST * aConnectedItemsList { bool ret = true; FILE* f = NULL; - NETLIST_EXPORT_TOOL helper( aConnectedItemsList ); + + NETLIST_EXPORT_TOOL helper( aConnectedItemsList, Prj().SchLibs() ); bool open_file = aFormat < NET_TYPE_CUSTOM1; if( (aFormat == NET_TYPE_PCBNEW) && (aNetlistOptions & NET_PCBNEW_USE_NEW_FORMAT ) ) @@ -524,12 +528,12 @@ SCH_COMPONENT* NETLIST_EXPORT_TOOL::findNextComponent( EDA_ITEM* aItem, SCH_SHEE // (several sheets pointing to 1 screen), this will be erroneously be // toggled. - LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( comp->GetLibName() ); - if( !entry ) + LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() ); + if( !part ) continue; // If component is a "multi parts per package" type - if( entry->GetPartCount() > 1 ) + if( part->GetUnitCount() > 1 ) { // test if this reference has already been processed, and if so skip if( m_ReferencesAlreadyFound.Lookup( ref ) ) @@ -537,7 +541,7 @@ SCH_COMPONENT* NETLIST_EXPORT_TOOL::findNextComponent( EDA_ITEM* aItem, SCH_SHEE } // record the usage of this library component entry. - m_LibParts.insert( entry ); // rejects non-unique pointers + m_LibParts.insert( part ); // rejects non-unique pointers return comp; } @@ -575,13 +579,13 @@ SCH_COMPONENT* NETLIST_EXPORT_TOOL::findNextComponentAndCreatePinList( EDA_ITEM* // (several sheets pointing to 1 screen), this will be erroneously be // toggled. - LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( comp->GetLibName() ); + LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() ); - if( !entry ) + if( !part ) continue; // If component is a "multi parts per package" type - if( entry->GetPartCount() > 1 ) + if( part->GetUnitCount() > 1 ) { // test if this reference has already been processed, and if so skip if( m_ReferencesAlreadyFound.Lookup( ref ) ) @@ -590,14 +594,14 @@ SCH_COMPONENT* NETLIST_EXPORT_TOOL::findNextComponentAndCreatePinList( EDA_ITEM* // Collect all pins for this reference designator by searching // the entire design for other parts with the same reference designator. // This is only done once, it would be too expensive otherwise. - findAllInstancesOfComponent( comp, entry, aSheetPath ); + findAllInstancesOfComponent( comp, part, aSheetPath ); } - else // entry->GetPartCount() <= 1 means one part per package + else // entry->GetUnitCount() <= 1 means one part per package { LIB_PINS pins; // constructed once here - entry->GetPins( pins, comp->GetUnitSelection( aSheetPath ), comp->GetConvert() ); + part->GetPins( pins, comp->GetUnitSelection( aSheetPath ), comp->GetConvert() ); for( size_t i = 0; i < pins.size(); i++ ) { @@ -617,7 +621,7 @@ SCH_COMPONENT* NETLIST_EXPORT_TOOL::findNextComponentAndCreatePinList( EDA_ITEM* eraseDuplicatePins( ); // record the usage of this library component entry. - m_LibParts.insert( entry ); // rejects non-unique pointers + m_LibParts.insert( part ); // rejects non-unique pointers return comp; } @@ -690,7 +694,7 @@ XNODE* NETLIST_EXPORT_TOOL::makeGenericLibraries() for( std::set::iterator it = m_Libraries.begin(); it!=m_Libraries.end(); ++it ) { - CMP_LIBRARY* lib = (CMP_LIBRARY*) *it; + PART_LIB* lib = (PART_LIB*) *it; XNODE* xlibrary; xlibs->AddChild( xlibrary = node( wxT( "library" ) ) ); @@ -732,8 +736,8 @@ XNODE* NETLIST_EXPORT_TOOL::makeGenericLibParts() for( std::set::iterator it = m_LibParts.begin(); it!=m_LibParts.end(); ++it ) { - LIB_COMPONENT* lcomp = (LIB_COMPONENT*) *it; - CMP_LIBRARY* library = lcomp->GetLibrary(); + LIB_PART* lcomp = (LIB_PART* ) *it; + PART_LIB* library = lcomp->GetLib(); m_Libraries.insert( library ); // inserts component's library if unique @@ -1028,12 +1032,14 @@ XNODE* NETLIST_EXPORT_TOOL::makeGenericComponents() // "logical" library name, which is in anticipation of a better search // algorithm for parts based on "logical_lib.part" and where logical_lib // is merely the library name minus path and extension. - LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( comp->GetLibName() ); - if( entry ) - xlibsource->AddAttribute( sLib, entry->GetLibrary()->GetLogicalName() ); - xlibsource->AddAttribute( sPart, comp->GetLibName() ); + LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() ); + if( part ) + xlibsource->AddAttribute( sLib, part->GetLib()->GetLogicalName() ); + + xlibsource->AddAttribute( sPart, comp->GetPartName() ); XNODE* xsheetpath; + xcomp->AddChild( xsheetpath = node( sSheetPath ) ); xsheetpath->AddAttribute( sNames, path->PathHumanReadable() ); xsheetpath->AddAttribute( sTStamps, path->Path() ); @@ -1410,13 +1416,13 @@ bool NETLIST_EXPORT_TOOL::WriteNetListPCBNEW( FILE* f, bool with_pcbnew ) // Get the Component FootprintFilter and put the component in // cmpList if filter is present - LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( comp->GetLibName() ); + LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() ); - if( entry ) + if( part ) { - if( entry->GetFootPrints().GetCount() != 0 ) // Put in list + if( part->GetFootPrints().GetCount() != 0 ) // Put in list { - cmpList.push_back( SCH_REFERENCE( comp, entry, *path ) ); + cmpList.push_back( SCH_REFERENCE( comp, part, *path ) ); } } @@ -1442,7 +1448,7 @@ bool NETLIST_EXPORT_TOOL::WriteNetListPCBNEW( FILE* f, bool with_pcbnew ) if( with_pcbnew ) // Add the lib name for this component { - field = comp->GetLibName(); + field = comp->GetPartName(); field.Replace( wxT( " " ), wxT( "_" ) ); ret |= fprintf( f, " {Lib=%s}", TO_UTF8( field ) ); } @@ -1482,7 +1488,7 @@ bool NETLIST_EXPORT_TOOL::WriteNetListPCBNEW( FILE* f, bool with_pcbnew ) for( unsigned ii = 0; ii < cmpList.size(); ii++ ) { - LIB_COMPONENT* entry = cmpList[ii].GetLibComponent(); + LIB_PART* entry = cmpList[ii].GetLibComponent(); ref = cmpList[ii].GetRef(); @@ -1612,7 +1618,7 @@ void NETLIST_EXPORT_TOOL::eraseDuplicatePins( ) void NETLIST_EXPORT_TOOL::findAllInstancesOfComponent( SCH_COMPONENT* aComponent, - LIB_COMPONENT* aEntry, + LIB_PART* aEntry, SCH_SHEET_PATH* aSheetPath ) { wxString ref = aComponent->GetRef( aSheetPath ); diff --git a/eeschema/netlist.cpp b/eeschema/netlist.cpp index 016ff5387f..d78848c779 100644 --- a/eeschema/netlist.cpp +++ b/eeschema/netlist.cpp @@ -55,7 +55,8 @@ bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName, unsigned aNetlistOptions ) { SCH_SHEET_LIST sheets; - sheets.AnnotatePowerSymbols(); + + sheets.AnnotatePowerSymbols( Prj().SchLibs() ); // Performs some controls: if( CheckAnnotate( NULL, 0 ) ) @@ -81,9 +82,11 @@ bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName, // Cleanup the entire hierarchy SCH_SCREENS screens; + screens.SchematicCleanUp(); - NETLIST_OBJECT_LIST * connectedItemsList = BuildNetListBase(); + NETLIST_OBJECT_LIST* connectedItemsList = BuildNetListBase(); + bool success = WriteNetListFile( connectedItemsList, aFormat, aFullFileName, aNetlistOptions ); @@ -105,10 +108,6 @@ NETLIST_OBJECT_LIST::~NETLIST_OBJECT_LIST() } -/* - * Delete all objects in list and clear list - * (free memory used to store info about NETLIST_OBJECT items) - */ void NETLIST_OBJECT_LIST::FreeList() { std::vector::iterator iter; @@ -122,21 +121,19 @@ void NETLIST_OBJECT_LIST::FreeList() clear(); } + void NETLIST_OBJECT_LIST::SortListbyNetcode() { sort( this->begin(), this->end(), NETLIST_OBJECT_LIST::sortItemsbyNetcode ); } + void NETLIST_OBJECT_LIST::SortListbySheet() { sort( this->begin(), this->end(), NETLIST_OBJECT_LIST::sortItemsBySheet ); } -/* - * Build net list connection table. - * Initializes s_NetObjectslist - */ NETLIST_OBJECT_LIST * SCH_EDIT_FRAME::BuildNetListBase() { wxBusyCursor Busy; @@ -163,10 +160,7 @@ NETLIST_OBJECT_LIST * SCH_EDIT_FRAME::BuildNetListBase() return &s_NetObjectslist; } -/* the master function of NETLIST_OBJECT_LIST class. - * Build the list of connected objects (pins, labels ...) and - * all info needed to generate netlists or run ERC diags - */ + bool NETLIST_OBJECT_LIST::BuildNetListInfo( SCH_SHEET_LIST& aSheets ) { s_NetObjectslist.SetOwner( true ); @@ -237,7 +231,7 @@ bool NETLIST_OBJECT_LIST::BuildNetListInfo( SCH_SHEET_LIST& aSheets ) segmentToPointConnect( net_item, IS_WIRE, istart ); - /* Control of the junction, on BUS. */ + // Control of the junction, on BUS. if( net_item->m_BusNetCode == 0 ) { net_item->m_BusNetCode = m_lastBusNetCode; @@ -265,7 +259,7 @@ bool NETLIST_OBJECT_LIST::BuildNetListInfo( SCH_SHEET_LIST& aSheets ) break; case NET_BUS: - /* Control type connections point to point mode bus */ + // Control type connections point to point mode bus if( net_item->m_BusNetCode == 0 ) { net_item->m_BusNetCode = m_lastBusNetCode; @@ -278,7 +272,7 @@ bool NETLIST_OBJECT_LIST::BuildNetListInfo( SCH_SHEET_LIST& aSheets ) case NET_BUSLABELMEMBER: case NET_HIERBUSLABELMEMBER: case NET_GLOBBUSLABELMEMBER: - /* Control connections similar has on BUS */ + // Control connections similar has on BUS if( net_item->GetNet() == 0 ) { net_item->m_BusNetCode = m_lastBusNetCode; @@ -295,10 +289,10 @@ bool NETLIST_OBJECT_LIST::BuildNetListInfo( SCH_SHEET_LIST& aSheets ) DumpNetTable(); #endif - /* Updating the Bus Labels Netcode connected by Bus */ + // Updating the Bus Labels Netcode connected by Bus connectBusLabels(); - /* Group objects by label. */ + // Group objects by label. for( unsigned ii = 0; ii < size(); ii++ ) { switch( GetItem( ii )->m_Type ) @@ -350,7 +344,7 @@ bool NETLIST_OBJECT_LIST::BuildNetListInfo( SCH_SHEET_LIST& aSheets ) DumpNetTable(); #endif - /* Compress numbers of Netcode having consecutive values. */ + // Compress numbers of Netcode having consecutive values. int NetCode = 0; m_lastNetCode = 0; @@ -392,6 +386,7 @@ static int getPriority( const NETLIST_OBJECT* Objet ) return 0; } + /* function evalLabelsPriority used by findBestNetNameForEachNet() * evalLabelsPriority calculates the priority of alabel1 and aLabel2 * return true if alabel1 has a highter priority than aLabel2 @@ -434,17 +429,6 @@ static bool evalLabelsPriority( const NETLIST_OBJECT* aLabel1, } -/** - * Function findBestNetNameForEachNet - * fill the .m_NetNameCandidate member of each item of aNetItemBuffer - * with a reference to the "best" NETLIST_OBJECT usable to give a name to the net - * If no suitable object found, .m_NetNameCandidate is filled with 0. - * The "best" NETLIST_OBJECT is a NETLIST_OBJECT that have the type label - * and by priority order: - * the label is global or local - * the label is in the first sheet in a hierarchy (the root sheet has the most priority) - * alphabetic order. - */ void NETLIST_OBJECT_LIST::findBestNetNameForEachNet() { int netcode = 0; // current netcode for tested items @@ -582,10 +566,6 @@ void NETLIST_OBJECT_LIST::findBestNetNameForEachNet() } -/* - * Propagate net codes from a parent sheet to an include sheet, - * from a pin sheet connection - */ void NETLIST_OBJECT_LIST::sheetLabelConnect( NETLIST_OBJECT* SheetLabel ) { if( SheetLabel->GetNet() == 0 ) @@ -616,13 +596,6 @@ void NETLIST_OBJECT_LIST::sheetLabelConnect( NETLIST_OBJECT* SheetLabel ) } -/* - * Analyzes the labels type bus member ( - * Propagate net codes between the corresponding labels (ie when - * the is the same) when they are connected - * uqsually by their BusNetCode - * Uses and updates the variable m_lastNetCode - */ void NETLIST_OBJECT_LIST::connectBusLabels() { for( unsigned ii = 0; ii < size(); ii++ ) @@ -663,12 +636,6 @@ void NETLIST_OBJECT_LIST::connectBusLabels() } -/* - * propageNetCode propagates the net code NewNetCode to all elements - * having previously the net code OldNetCode - * If IsBus == false, m_Netcode is used to propagate the new net code - * If IsBus == true, m_BusNetCode is used to propagate the new net code - */ void NETLIST_OBJECT_LIST::propageNetCode( int aOldNetCode, int aNewNetCode, bool aIsBus ) { if( aOldNetCode == aNewNetCode ) @@ -678,44 +645,25 @@ void NETLIST_OBJECT_LIST::propageNetCode( int aOldNetCode, int aNewNetCode, bool { for( unsigned jj = 0; jj < size(); jj++ ) { - NETLIST_OBJECT* objet = GetItem( jj ); + NETLIST_OBJECT* object = GetItem( jj ); - if( objet->GetNet() == aOldNetCode ) - objet->SetNet( aNewNetCode ); + if( object->GetNet() == aOldNetCode ) + object->SetNet( aNewNetCode ); } } else // Propagate BusNetCode { for( unsigned jj = 0; jj < size(); jj++ ) { - NETLIST_OBJECT* objet = GetItem( jj ); + NETLIST_OBJECT* object = GetItem( jj ); - if( objet->m_BusNetCode == aOldNetCode ) - objet->m_BusNetCode = aNewNetCode; + if( object->m_BusNetCode == aOldNetCode ) + object->m_BusNetCode = aNewNetCode; } } } -/* - * Check if Ref element is connected to other elements of the list of objects - * in the schematic, by mode point - * A point (end superimposed) - * - * If IsBus: - * The connection involves elements such as bus - * (Or BUS or BUSLABEL JUNCTION) - * Otherwise - * The connection involves elements such as non-bus - * (Other than BUS or BUSLABEL) - * - * The Ref object must have a valid Netcode. - * - * The list of objects is SUPPOSED class by SheetPath Croissants, - * And research is done from the start element, 1st element - * Leaf schema - * (There can be no physical connection between elements of different sheets) - */ void NETLIST_OBJECT_LIST::pointToPointConnect( NETLIST_OBJECT* aRef, bool aIsBus, int start ) { @@ -765,13 +713,13 @@ void NETLIST_OBJECT_LIST::pointToPointConnect( NETLIST_OBJECT* aRef, bool aIsBus } } } - else /* Object type BUS, BUSLABELS, and junctions. */ + else // Object type BUS, BUSLABELS, and junctions. { netCode = aRef->m_BusNetCode; for( unsigned i = start; i < size(); i++ ) { - NETLIST_OBJECT* item = GetItem( i ); + NETLIST_OBJECT* item = GetItem( i ); if( item->m_SheetPath != aRef->m_SheetPath ) continue; @@ -812,13 +760,6 @@ void NETLIST_OBJECT_LIST::pointToPointConnect( NETLIST_OBJECT* aRef, bool aIsBus } -/* - * Search connections betweena junction and segments - * Propagate the junction net code to objects connected by this junction. - * The junction must have a valid net code - * The list of objects is expected sorted by sheets. - * Search is done from index aIdxStart to the last element of list - */ void NETLIST_OBJECT_LIST::segmentToPointConnect( NETLIST_OBJECT* aJonction, bool aIsBus, int aIdxStart ) { @@ -863,11 +804,6 @@ void NETLIST_OBJECT_LIST::segmentToPointConnect( NETLIST_OBJECT* aJonction, } -/* - * This function merges the net codes of groups of objects already connected - * to labels (wires, bus, pins ... ) when 2 labels are equivalents - * (i.e. group objects connected by labels) - */ void NETLIST_OBJECT_LIST::labelConnect( NETLIST_OBJECT* aLabelRef ) { if( aLabelRef->GetNet() == 0 ) @@ -911,12 +847,6 @@ void NETLIST_OBJECT_LIST::labelConnect( NETLIST_OBJECT* aLabelRef ) } -/* Set the m_ConnectionType member of items in list - * depending on the connection type: - * UNCONNECTED, PAD_CONNECT or NOCONNECT_SYMBOL_PRESENT - * The list is expected sorted by order of net code, - * i.e. items having the same net code are grouped - */ void NETLIST_OBJECT_LIST::setUnconnectedFlag() { NETLIST_OBJECT* NetItemRef; @@ -931,13 +861,13 @@ void NETLIST_OBJECT_LIST::setUnconnectedFlag() if( NetItemRef->m_Type == NET_NOCONNECT && StateFlag != PAD_CONNECT ) StateFlag = NOCONNECT_SYMBOL_PRESENT; - /* Analysis of current net. */ + // Analysis of current net. unsigned idxtoTest = ii + 1; if( ( idxtoTest >= size() ) || ( NetItemRef->GetNet() != GetItem( idxtoTest )->GetNet() ) ) { - /* Net analysis to update m_ConnectionType */ + // Net analysis to update m_ConnectionType NetEnd = idxtoTest; /* set m_ConnectionType member to StateFlag for all items of @@ -948,7 +878,7 @@ void NETLIST_OBJECT_LIST::setUnconnectedFlag() if( idxtoTest >= size() ) return; - /* Start Analysis next Net */ + // Start Analysis next Net StateFlag = UNCONNECTED; NetStart = idxtoTest; continue; @@ -962,7 +892,7 @@ void NETLIST_OBJECT_LIST::setUnconnectedFlag() * StateFlag is already set to PAD_CONNECT this state is kept (the * no connect symbol was surely an error and an ERC will report this) */ - for( ; ; idxtoTest++ ) + for( ; ; idxtoTest++ ) { if( ( idxtoTest >= size() ) || ( NetItemRef->GetNet() != GetItem( idxtoTest )->GetNet() ) ) @@ -1003,4 +933,3 @@ void NETLIST_OBJECT_LIST::setUnconnectedFlag() } } } - diff --git a/eeschema/netlist.h b/eeschema/netlist.h index d315739a36..c4ca369304 100644 --- a/eeschema/netlist.h +++ b/eeschema/netlist.h @@ -84,11 +84,10 @@ class SCH_REFERENC_LIST; */ class SCH_REFERENCE { -private: /// Component reference prefix, without number (for IC1, this is IC) ) - std::string m_Ref; // it's private, use the accessors please + UTF8 m_Ref; // it's private, use the accessors please SCH_COMPONENT* m_RootCmp; ///< The component associated the reference object. - LIB_COMPONENT* m_Entry; ///< The source component from a library. + LIB_PART* m_Entry; ///< The source component from a library. wxPoint m_CmpPos; ///< The physical position of the component in schematic ///< used to annotate by X or Y position int m_Unit; ///< The unit number for components with multiple parts @@ -104,9 +103,11 @@ private: friend class SCH_REFERENCE_LIST; + public: - SCH_REFERENCE() + SCH_REFERENCE() : + m_SheetPath() { m_RootCmp = NULL; m_Entry = NULL; @@ -119,16 +120,16 @@ public: m_SheetNum = 0; } - SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_COMPONENT* aLibComponent, + SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_PART* aLibComponent, SCH_SHEET_PATH& aSheetPath ); - SCH_COMPONENT* GetComponent() const { return m_RootCmp; } + SCH_COMPONENT* GetComp() const { return m_RootCmp; } - LIB_COMPONENT* GetLibComponent() const { return m_Entry; } + LIB_PART* GetLibComponent() const { return m_Entry; } - SCH_SHEET_PATH GetSheetPath() const { return m_SheetPath; } + SCH_SHEET_PATH GetSheetPath() const { return m_SheetPath; } - int GetUnit() const { return m_Unit; } + int GetUnit() const { return m_Unit; } void SetSheetNumber( int aSheetNumber ) { m_SheetNum = aSheetNumber; } @@ -153,12 +154,12 @@ public: void SetRef( const wxString& aReference ) { - m_Ref = TO_UTF8( aReference ); + m_Ref = aReference; } wxString GetRef() const { - return FROM_UTF8( m_Ref.c_str() ); + return m_Ref; } void SetRefStr( const std::string& aReference ) { @@ -171,7 +172,7 @@ public: int CompareValue( const SCH_REFERENCE& item ) const { - return m_Value->GetText().CmpNoCase( item.m_Value->GetText() ); + return Cmp_KEEPCASE( m_Value->GetText(), item.m_Value->GetText() ); } int CompareRef( const SCH_REFERENCE& item ) const @@ -181,10 +182,10 @@ public: int CompareLibName( const SCH_REFERENCE& item ) const { - return m_RootCmp->GetLibName().CmpNoCase( item.m_RootCmp->GetLibName() ); + return Cmp_KEEPCASE( m_RootCmp->GetPartName(), item.m_RootCmp->GetPartName() ); } - bool IsPartsLocked() + bool IsUnitsLocked() { return m_Entry->UnitsLocked(); } diff --git a/eeschema/onrightclick.cpp b/eeschema/onrightclick.cpp index 9e10448382..00abc35ecd 100644 --- a/eeschema/onrightclick.cpp +++ b/eeschema/onrightclick.cpp @@ -59,29 +59,24 @@ static void AddMenusForText( wxMenu* PopMenu, SCH_TEXT* Text ); static void AddMenusForLabel( wxMenu* PopMenu, SCH_LABEL* Label ); static void AddMenusForGLabel( wxMenu* PopMenu, SCH_GLOBALLABEL* GLabel ); static void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* GLabel ); -static void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ); -static void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ); +static void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs ); +static void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs ); static void AddMenusForComponentField( wxMenu* PopMenu, SCH_FIELD* Field ); static void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_FRAME* aFrame ); static void AddMenusForBitmap( wxMenu* aPopMenu, SCH_BITMAP * aBitmap ); static void AddMenusForBusEntry( wxMenu* aPopMenu, SCH_BUS_ENTRY_BASE * aBusEntry ); - -/* Prepare context menu when a click on the right mouse button occurs. - * - * This menu is then added to the list of zoom commands. - */ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) { - SCH_ITEM* item = GetScreen()->GetCurItem(); - bool BlockActive = GetScreen()->IsBlockActive(); - wxString msg; + SCH_ITEM* item = GetScreen()->GetCurItem(); + bool blockActive = GetScreen()->IsBlockActive(); + wxString msg; // Do not start a block command on context menu. m_canvas->SetCanStartBlock( -1 ); - if( BlockActive ) + if( blockActive ) { AddMenusForBlock( PopMenu, this ); PopMenu->AppendSeparator(); @@ -92,45 +87,45 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) { switch( item->Type() ) { - case SCH_COMPONENT_T: - AddMenusForEditComponent( PopMenu, (SCH_COMPONENT *) item ); - PopMenu->AppendSeparator(); - break; + case SCH_COMPONENT_T: + AddMenusForEditComponent( PopMenu, (SCH_COMPONENT *) item, Prj().SchLibs() ); + PopMenu->AppendSeparator(); + break; - case SCH_TEXT_T: - msg = AddHotkeyName( _( "Edit Text" ), s_Schematic_Hokeys_Descr, HK_EDIT ); - AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); - PopMenu->AppendSeparator(); - break; + case SCH_TEXT_T: + msg = AddHotkeyName( _( "Edit Text" ), s_Schematic_Hokeys_Descr, HK_EDIT ); + AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); + PopMenu->AppendSeparator(); + break; - case SCH_LABEL_T: - msg = AddHotkeyName( _( "Edit Label" ), s_Schematic_Hokeys_Descr, HK_EDIT ); - AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); - PopMenu->AppendSeparator(); - break; + case SCH_LABEL_T: + msg = AddHotkeyName( _( "Edit Label" ), s_Schematic_Hokeys_Descr, HK_EDIT ); + AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); + PopMenu->AppendSeparator(); + break; - case SCH_GLOBAL_LABEL_T: - msg = AddHotkeyName( _( "Edit Global Label" ), s_Schematic_Hokeys_Descr, - HK_EDIT ); - AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); - PopMenu->AppendSeparator(); - break; + case SCH_GLOBAL_LABEL_T: + msg = AddHotkeyName( _( "Edit Global Label" ), s_Schematic_Hokeys_Descr, + HK_EDIT ); + AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); + PopMenu->AppendSeparator(); + break; - case SCH_HIERARCHICAL_LABEL_T: - msg = AddHotkeyName( _( "Edit Hierarchical Label" ), s_Schematic_Hokeys_Descr, - HK_EDIT ); - AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); - PopMenu->AppendSeparator(); - break; + case SCH_HIERARCHICAL_LABEL_T: + msg = AddHotkeyName( _( "Edit Hierarchical Label" ), s_Schematic_Hokeys_Descr, + HK_EDIT ); + AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_text_xpm ) ); + PopMenu->AppendSeparator(); + break; - case SCH_BITMAP_T: - msg = AddHotkeyName( _( "Edit Image" ), s_Schematic_Hokeys_Descr, HK_EDIT ); - AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( image_xpm ) ); - PopMenu->AppendSeparator(); - break; + case SCH_BITMAP_T: + msg = AddHotkeyName( _( "Edit Image" ), s_Schematic_Hokeys_Descr, HK_EDIT ); + AddMenuItem( PopMenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( image_xpm ) ); + PopMenu->AppendSeparator(); + break; - default: - break; + default: + break; } } return true; @@ -168,20 +163,20 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) switch( GetToolId() ) { - case ID_WIRE_BUTT: - AddMenusForWire( PopMenu, NULL, this ); - if( item == NULL ) - PopMenu->AppendSeparator(); - break; + case ID_WIRE_BUTT: + AddMenusForWire( PopMenu, NULL, this ); + if( item == NULL ) + PopMenu->AppendSeparator(); + break; - case ID_BUS_BUTT: - AddMenusForBus( PopMenu, NULL, this ); - if( item == NULL ) - PopMenu->AppendSeparator(); - break; + case ID_BUS_BUTT: + AddMenusForBus( PopMenu, NULL, this ); + if( item == NULL ) + PopMenu->AppendSeparator(); + break; - default: - break; + default: + break; } } else @@ -210,7 +205,6 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) switch( item->Type() ) { case SCH_NO_CONNECT_T: - AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE, _( "Delete No Connect" ), KiBitmap( delete_xpm ) ); break; @@ -249,7 +243,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) break; case SCH_COMPONENT_T: - AddMenusForComponent( PopMenu, (SCH_COMPONENT*) item ); + AddMenusForComponent( PopMenu, (SCH_COMPONENT*) item, Prj().SchLibs() ); break; case SCH_BITMAP_T: @@ -353,7 +347,7 @@ void AddMenusForComponentField( wxMenu* PopMenu, SCH_FIELD* Field ) } -void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) +void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs ) { if( Component->Type() != SCH_COMPONENT_T ) { @@ -362,9 +356,7 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) } wxString msg; - LIB_ALIAS* libEntry; - - libEntry = CMP_LIBRARY::FindLibraryEntry( Component->GetLibName() ); + LIB_ALIAS* libEntry = aLibs->FindLibraryEntry( Component->GetPartName() ); if( !Component->GetFlags() ) { @@ -391,7 +383,7 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) AddMenuItem( PopMenu, orientmenu, ID_POPUP_SCH_GENERIC_ORIENT_CMP, _( "Orient Component" ), KiBitmap( orient_xpm ) ); - AddMenusForEditComponent( PopMenu, Component ); + AddMenusForEditComponent( PopMenu, Component, aLibs ); if( !Component->GetFlags() ) { @@ -407,7 +399,7 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) } -void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) +void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs ) { if( Component->Type() != SCH_COMPONENT_T ) { @@ -415,20 +407,18 @@ void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) return; } - wxString msg; - LIB_ALIAS* libEntry; - LIB_COMPONENT* libComponent = NULL; - - libEntry = CMP_LIBRARY::FindLibraryEntry( Component->GetLibName() ); + wxString msg; + LIB_PART* part = NULL; + LIB_ALIAS* libEntry = aLibs->FindLibraryEntry( Component->GetPartName() ); if( libEntry ) - libComponent = libEntry->GetComponent(); + part = libEntry->GetPart(); wxMenu* editmenu = new wxMenu; msg = AddHotkeyName( _( "Edit" ), s_Schematic_Hokeys_Descr, HK_EDIT ); AddMenuItem( editmenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_component_xpm ) ); - if( libComponent && libComponent->IsNormal() ) + if( part && part->IsNormal() ) { msg = AddHotkeyName( _( "Value" ), s_Schematic_Hokeys_Descr, HK_EDIT_COMPONENT_VALUE ); @@ -446,15 +436,15 @@ void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) KiBitmap( edit_comp_footprint_xpm ) ); } - if( libComponent && libComponent->HasConversion() ) + if( part && part->HasConversion() ) AddMenuItem( editmenu, ID_POPUP_SCH_EDIT_CONVERT_CMP, _( "Convert" ), KiBitmap( component_select_alternate_shape_xpm ) ); - if( libComponent && ( libComponent->GetPartCount() >= 2 ) ) + if( part && part->GetUnitCount() >= 2 ) { wxMenu* sel_unit_menu = new wxMenu; int ii; - for( ii = 0; ii < libComponent->GetPartCount(); ii++ ) + for( ii = 0; ii < part->GetUnitCount(); ii++ ) { wxString num_unit; int unit = Component->GetUnit(); @@ -480,7 +470,6 @@ void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component ) AddMenuItem( PopMenu, editmenu, ID_SCH_EDIT_ITEM, _( "Edit Component" ), KiBitmap( edit_component_xpm ) ); - } @@ -863,6 +852,7 @@ void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_FRAME* KiBitmap( info_xpm ) ); } + void AddMenusForBitmap( wxMenu* aPopMenu, SCH_BITMAP * aBitmap ) { wxString msg; @@ -892,6 +882,7 @@ void AddMenusForBitmap( wxMenu* aPopMenu, SCH_BITMAP * aBitmap ) } } + void AddMenusForBusEntry( wxMenu* aPopMenu, SCH_BUS_ENTRY_BASE* aBusEntry ) { wxString msg; diff --git a/eeschema/pinedit.cpp b/eeschema/pinedit.cpp index ad92bd77de..7b75ac8a0d 100644 --- a/eeschema/pinedit.cpp +++ b/eeschema/pinedit.cpp @@ -222,14 +222,13 @@ static void AbortPinMove( EDA_DRAW_PANEL* Panel, wxDC* DC ) */ void LIB_EDIT_FRAME::PlacePin() { - LIB_PIN* Pin; - LIB_PIN* CurrentPin = (LIB_PIN*) m_drawItem; + LIB_PIN* cur_pin = (LIB_PIN*) m_drawItem; bool ask_for_pin = true; wxPoint newpos; bool status; // Some tests - if( (CurrentPin == NULL) || (CurrentPin->Type() != LIB_PIN_T) ) + if( !cur_pin || cur_pin->Type() != LIB_PIN_T ) { wxMessageBox( wxT( "LIB_EDIT_FRAME::PlacePin() error" ) ); return; @@ -237,18 +236,20 @@ void LIB_EDIT_FRAME::PlacePin() newpos = GetCrossHairPosition( true ); + LIB_PART* part = GetCurPart(); + // Test for an other pin in same new position: - for( Pin = m_component->GetNextPin(); Pin != NULL; Pin = m_component->GetNextPin( Pin ) ) + for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) ) { - if( Pin == CurrentPin || newpos != Pin->GetPosition() || Pin->GetFlags() ) + if( pin == cur_pin || newpos != pin->GetPosition() || pin->GetFlags() ) continue; if( ask_for_pin && SynchronizePins() ) { m_canvas->SetIgnoreMouseEvents( true ); - status = - IsOK( this, _( "This position is already occupied by \ -another pin. Continue?" ) ); + + status = IsOK( this, _( "This position is already occupied by another pin. Continue?" ) ); + m_canvas->MoveCursorToCrossHair(); m_canvas->SetIgnoreMouseEvents( false ); @@ -264,33 +265,33 @@ another pin. Continue?" ) ); if( GetTempCopyComponent() ) SaveCopyInUndoList( GetTempCopyComponent() ); else - SaveCopyInUndoList( m_component ); + SaveCopyInUndoList( part ); m_canvas->SetMouseCapture( NULL, NULL ); OnModify(); - CurrentPin->Move( newpos ); + cur_pin->Move( newpos ); - if( CurrentPin->IsNew() ) + if( cur_pin->IsNew() ) { - LastPinOrient = CurrentPin->GetOrientation(); - LastPinType = CurrentPin->GetType(); - LastPinShape = CurrentPin->GetShape(); + LastPinOrient = cur_pin->GetOrientation(); + LastPinType = cur_pin->GetType(); + LastPinShape = cur_pin->GetShape(); if( SynchronizePins() ) - CreateImagePins( CurrentPin, m_unit, m_convert, m_showDeMorgan ); + CreateImagePins( cur_pin, m_unit, m_convert, m_showDeMorgan ); - m_lastDrawItem = CurrentPin; - m_component->AddDrawItem( m_drawItem ); + m_lastDrawItem = cur_pin; + part->AddDrawItem( m_drawItem ); } // Put linked pins in new position, and clear flags - for( Pin = m_component->GetNextPin(); Pin != NULL; Pin = m_component->GetNextPin( Pin ) ) + for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) ) { - if( Pin->GetFlags() == 0 ) + if( pin->GetFlags() == 0 ) continue; - Pin->Move( CurrentPin->GetPosition() ); - Pin->ClearFlags(); + pin->Move( cur_pin->GetPosition() ); + pin->ClearFlags(); } m_drawItem = NULL; @@ -307,37 +308,41 @@ another pin. Continue?" ) ); */ void LIB_EDIT_FRAME::StartMovePin( wxDC* DC ) { - LIB_PIN* currentPin = (LIB_PIN*) m_drawItem; + LIB_PIN* cur_pin = (LIB_PIN*) m_drawItem; wxPoint startPos; TempCopyComponent(); - // Mark pins for moving. - LIB_PIN* pin = m_component->GetNextPin(); + LIB_PART* part = GetCurPart(); - for( ; pin != NULL; pin = m_component->GetNextPin( pin ) ) + // Mark pins for moving. + for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) ) { pin->ClearFlags(); - if( pin == currentPin ) + if( pin == cur_pin ) continue; - if( ( pin->GetPosition() == currentPin->GetPosition() ) - && ( pin->GetOrientation() == currentPin->GetOrientation() ) - && SynchronizePins() ) + if( pin->GetPosition() == cur_pin->GetPosition() && + pin->GetOrientation() == cur_pin->GetOrientation() && SynchronizePins() ) + { pin->SetFlags( IS_LINKED | IS_MOVED ); + } } - currentPin->SetFlags( IS_LINKED | IS_MOVED ); - PinPreviousPos = OldPos = currentPin->GetPosition(); + cur_pin->SetFlags( IS_LINKED | IS_MOVED ); + + PinPreviousPos = OldPos = cur_pin->GetPosition(); startPos.x = OldPos.x; startPos.y = -OldPos.y; + // m_canvas->CrossHairOff( DC ); SetCrossHairPosition( startPos ); m_canvas->MoveCursorToCrossHair(); MSG_PANEL_ITEMS items; - currentPin->GetMsgPanelInfo( items ); + + cur_pin->GetMsgPanelInfo( items ); SetMsgPanel( items ); m_canvas->SetMouseCapture( DrawMovePin, AbortPinMove ); // m_canvas->CrossHairOn( DC ); @@ -358,33 +363,33 @@ static void DrawMovePin( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosi if( parent == NULL ) return; - LIB_PIN* CurrentPin = (LIB_PIN*) parent->GetDrawItem(); + LIB_PIN* cur_pin = (LIB_PIN*) parent->GetDrawItem(); - if( CurrentPin == NULL || CurrentPin->Type() != LIB_PIN_T ) + if( cur_pin == NULL || cur_pin->Type() != LIB_PIN_T ) return; - wxPoint pinpos = CurrentPin->GetPosition(); + wxPoint pinpos = cur_pin->GetPosition(); bool showPinText = true; // Erase pin in old position if( aErase ) { - CurrentPin->Move( PinPreviousPos ); - CurrentPin->Draw( aPanel, aDC, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, + cur_pin->Move( PinPreviousPos ); + cur_pin->Draw( aPanel, aDC, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, &showPinText, DefaultTransform ); } // Redraw pin in new position - CurrentPin->Move( aPanel->GetParent()->GetCrossHairPosition( true ) ); - CurrentPin->Draw( aPanel, aDC, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, + cur_pin->Move( aPanel->GetParent()->GetCrossHairPosition( true ) ); + cur_pin->Draw( aPanel, aDC, wxPoint( 0, 0 ), UNSPECIFIED_COLOR, g_XorMode, &showPinText, DefaultTransform ); - PinPreviousPos = CurrentPin->GetPosition(); + PinPreviousPos = cur_pin->GetPosition(); /* Keep the original position for existing pin (for Undo command) * and the current position for a new pin */ - if( !CurrentPin->IsNew() ) - CurrentPin->Move( pinpos ); + if( !cur_pin->IsNew() ) + cur_pin->Move( pinpos ); } @@ -393,15 +398,16 @@ static void DrawMovePin( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosi */ void LIB_EDIT_FRAME::CreatePin( wxDC* DC ) { - LIB_PIN* pin; bool showPinText = true; - if( m_component == NULL ) + LIB_PART* part = GetCurPart(); + + if( !part ) return; - m_component->ClearStatus(); + part->ClearStatus(); - pin = new LIB_PIN( m_component ); + LIB_PIN* pin = new LIB_PIN( part ); m_drawItem = pin; @@ -469,7 +475,7 @@ void LIB_EDIT_FRAME::CreateImagePins( LIB_PIN* aPin, int aUnit, int aConvert, bo aPin->GetParent()->AddDrawItem( NewPin ); } - for( ii = 1; ii <= aPin->GetParent()->GetPartCount(); ii++ ) + for( ii = 1; ii <= aPin->GetParent()->GetUnitCount(); ii++ ) { if( ii == aUnit || aPin->GetUnit() == 0 ) continue; // Pin common to all units. @@ -513,7 +519,9 @@ void LIB_EDIT_FRAME::GlobalSetPins( LIB_PIN* aMasterPin, int aId ) { bool selected = aMasterPin->IsSelected(); - if( ( m_component == NULL ) || ( aMasterPin == NULL ) ) + LIB_PART* part = GetCurPart(); + + if( !part || !aMasterPin ) return; if( aMasterPin->Type() != LIB_PIN_T ) @@ -521,11 +529,9 @@ void LIB_EDIT_FRAME::GlobalSetPins( LIB_PIN* aMasterPin, int aId ) OnModify( ); - LIB_PIN* pin = m_component->GetNextPin(); - - for( ; pin != NULL; pin = m_component->GetNextPin( pin ) ) + for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) ) { - if( ( pin->GetConvert() ) && ( pin->GetConvert() != m_convert ) ) + if( pin->GetConvert() && pin->GetConvert() != m_convert ) continue; // Is it the "selected mode" ? @@ -557,45 +563,47 @@ void LIB_EDIT_FRAME::GlobalSetPins( LIB_PIN* aMasterPin, int aId ) // Create a new pin based on the previous pin with an incremented pin number. void LIB_EDIT_FRAME::RepeatPinItem( wxDC* DC, LIB_PIN* SourcePin ) { - LIB_PIN* Pin; wxString msg; - if( m_component == NULL || SourcePin == NULL || SourcePin->Type() != LIB_PIN_T ) + LIB_PART* part = GetCurPart(); + + if( !part || !SourcePin || SourcePin->Type() != LIB_PIN_T ) return; - Pin = (LIB_PIN*) SourcePin->Clone(); - Pin->ClearFlags(); - Pin->SetFlags( IS_NEW ); - Pin->Move( Pin->GetPosition() + wxPoint( g_RepeatStep.x, -g_RepeatStep.y ) ); - wxString nextName = Pin->GetName(); + LIB_PIN* pin = (LIB_PIN*) SourcePin->Clone(); + + pin->ClearFlags(); + pin->SetFlags( IS_NEW ); + pin->Move( pin->GetPosition() + wxPoint( g_RepeatStep.x, -g_RepeatStep.y ) ); + wxString nextName = pin->GetName(); IncrementLabelMember( nextName ); - Pin->SetName( nextName ); + pin->SetName( nextName ); - Pin->PinStringNum( msg ); + pin->PinStringNum( msg ); IncrementLabelMember( msg ); - Pin->SetPinNumFromString( msg ); + pin->SetPinNumFromString( msg ); - m_drawItem = Pin; + m_drawItem = pin; if( SynchronizePins() ) - Pin->SetFlags( IS_LINKED ); + pin->SetFlags( IS_LINKED ); wxPoint savepos = GetCrossHairPosition(); m_canvas->CrossHairOff( DC ); - SetCrossHairPosition( wxPoint( Pin->GetPosition().x, -Pin->GetPosition().y ) ); + SetCrossHairPosition( wxPoint( pin->GetPosition().x, -pin->GetPosition().y ) ); // Add this new pin in list, and creates pins for others parts if needed - m_drawItem = Pin; + m_drawItem = pin; ClearTempCopyComponent(); PlacePin(); - m_lastDrawItem = Pin; + m_lastDrawItem = pin; SetCrossHairPosition( savepos ); m_canvas->CrossHairOn( DC ); MSG_PANEL_ITEMS items; - Pin->GetMsgPanelInfo( items ); + pin->GetMsgPanelInfo( items ); SetMsgPanel( items ); OnModify( ); } @@ -620,20 +628,18 @@ bool sort_by_pin_number( const LIB_PIN* ref, const LIB_PIN* tst ) } -/* Test for duplicate pins and off grid pins: - * Pins are considered off grid when they are not on the 25 mils grid - * A grid smaller than 25 mils must be used only to build graphic shapes. - */ void LIB_EDIT_FRAME::OnCheckComponent( wxCommandEvent& event ) { - if( m_component == NULL ) + LIB_PART* part = GetCurPart(); + + if( !part ) return; const int MIN_GRID_SIZE = 25; LIB_PINS pinList; - m_component->GetPins( pinList ); + part->GetPins( pinList ); if( pinList.size() == 0 ) { @@ -672,18 +678,20 @@ void LIB_EDIT_FRAME::OnCheckComponent( wxCommandEvent& event ) this thing! Lorenzo */ curr_pin->PinStringNum( stringCurrPinNum ); - wxString msg = wxString::Format( _( "Duplicate pin %s \"%s\" at location (%.3f, \ -%.3f) conflicts with pin %s \"%s\" at location (%.3f, %.3f)" ), - GetChars( stringCurrPinNum ), - GetChars( curr_pin->GetName() ), - curr_pin->GetPosition().x / 1000.0, - -curr_pin->GetPosition().y / 1000.0, - GetChars( stringPinNum ), - GetChars( pin->GetName() ), - pin->GetPosition().x / 1000.0, - -pin->GetPosition().y / 1000.0 ); + wxString msg = wxString::Format( _( + "Duplicate pin %s \"%s\" at location (%.3f, %.3f)" + " conflicts with pin %s \"%s\" at location (%.3f, %.3f)" ), + GetChars( stringCurrPinNum ), + GetChars( curr_pin->GetName() ), + curr_pin->GetPosition().x / 1000.0, + -curr_pin->GetPosition().y / 1000.0, + GetChars( stringPinNum ), + GetChars( pin->GetName() ), + pin->GetPosition().x / 1000.0, + -pin->GetPosition().y / 1000.0 + ); - if( m_component->GetPartCount() > 1 ) + if( part->GetUnitCount() > 1 ) { msg += wxString::Format( _( " in part %c" ), 'A' + curr_pin->GetUnit() - 1 ); } @@ -717,13 +725,15 @@ void LIB_EDIT_FRAME::OnCheckComponent( wxCommandEvent& event ) wxString stringPinNum; pin->PinStringNum( stringPinNum ); - wxString msg = wxString::Format( _( "Off grid pin %s \"%s\" at location (%.3f, %.3f)" ), - GetChars( stringPinNum ), - GetChars( pin->GetName() ), - pin->GetPosition().x / 1000.0, - -pin->GetPosition().y / 1000.0 ); + wxString msg = wxString::Format( _( + "Off grid pin %s \"%s\" at location (%.3f, %.3f)" ), + GetChars( stringPinNum ), + GetChars( pin->GetName() ), + pin->GetPosition().x / 1000.0, + -pin->GetPosition().y / 1000.0 + ); - if( m_component->GetPartCount() > 1 ) + if( part->GetUnitCount() > 1 ) { msg += wxString::Format( _( " in part %c" ), 'A' + pin->GetUnit() - 1 ); } diff --git a/eeschema/plot_schematic_DXF.cpp b/eeschema/plot_schematic_DXF.cpp index 9c86362398..c42b54fcb3 100644 --- a/eeschema/plot_schematic_DXF.cpp +++ b/eeschema/plot_schematic_DXF.cpp @@ -31,6 +31,7 @@ #include #include #include +#include void DIALOG_PLOT_SCHEMATIC::CreateDXFFile( bool aPlotAll, bool aPlotFrameRef ) @@ -80,6 +81,8 @@ void DIALOG_PLOT_SCHEMATIC::CreateDXFFile( bool aPlotAll, bool aPlotFrameRef ) plotFileName = schframe->GetUniqueFilenameForCurrentSheet() + wxT(".") + DXF_PLOTTER::GetDefaultFileExtension(); + plotFileName = Prj().AbsolutePath( plotFileName ); + wxString msg; if( PlotOneSheetDXF( plotFileName, screen, plot_offset, 1.0, aPlotFrameRef ) ) diff --git a/eeschema/plot_schematic_HPGL.cpp b/eeschema/plot_schematic_HPGL.cpp index f1a4dff409..6c40eb6759 100644 --- a/eeschema/plot_schematic_HPGL.cpp +++ b/eeschema/plot_schematic_HPGL.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -176,6 +177,8 @@ void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef ) plotFileName = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( "." ) + HPGL_PLOTTER::GetDefaultFileExtension(); + plotFileName = Prj().AbsolutePath( plotFileName ); + LOCALE_IO toggle; wxString msg; diff --git a/eeschema/plot_schematic_PDF.cpp b/eeschema/plot_schematic_PDF.cpp index 9a751db0de..ecab45a1c7 100644 --- a/eeschema/plot_schematic_PDF.cpp +++ b/eeschema/plot_schematic_PDF.cpp @@ -32,6 +32,8 @@ #include #include #include +#include + void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef ) { @@ -87,7 +89,9 @@ void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef ) plotFileName = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( "." ) + PDF_PLOTTER::GetDefaultFileExtension(); - if( ! plotter->OpenFile( plotFileName ) ) + plotFileName = Prj().AbsolutePath( plotFileName ); + + if( !plotter->OpenFile( plotFileName ) ) { msg.Printf( _( "Unable to create <%s>\n" ), GetChars( plotFileName ) ); m_MessagesBox->AppendText( msg ); diff --git a/eeschema/plot_schematic_PS.cpp b/eeschema/plot_schematic_PS.cpp index 86b2982ca6..3ded1578a0 100644 --- a/eeschema/plot_schematic_PS.cpp +++ b/eeschema/plot_schematic_PS.cpp @@ -31,6 +31,7 @@ #include #include #include +#include void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef ) @@ -104,6 +105,8 @@ void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef ) plotFileName = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( "." ) + PS_PLOTTER::GetDefaultFileExtension(); + plotFileName = Prj().AbsolutePath( plotFileName ); + wxString msg; if( plotOneSheetPS( plotFileName, screen, plotPage, plot_offset, diff --git a/eeschema/plot_schematic_SVG.cpp b/eeschema/plot_schematic_SVG.cpp index 050bad1105..2badb2c968 100644 --- a/eeschema/plot_schematic_SVG.cpp +++ b/eeschema/plot_schematic_SVG.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -72,7 +73,9 @@ void DIALOG_PLOT_SCHEMATIC::createSVGFile( bool aPrintAll, bool aPrintFrameRef ) sheetpath = SheetList.GetNext(); - fn = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( ".svg" ); + wxString fileName = m_parent->GetUniqueFilenameForCurrentSheet() + wxT( ".svg" ); + + fn = Prj().AbsolutePath( fileName ); bool success = plotOneSheetSVG( m_parent, fn.GetFullPath(), screen, getModeColor() ? false : true, diff --git a/eeschema/protos.h b/eeschema/protos.h index 5ffd9fe183..cacea7adec 100644 --- a/eeschema/protos.h +++ b/eeschema/protos.h @@ -7,7 +7,7 @@ class EDA_DRAW_PANEL; class EDA_DRAW_FRAME; class PICKED_ITEMS_LIST; -class CMP_LIBRARY; +class PART_LIB; class SCH_ITEM; //void DisplayCmpDoc( wxString& Name ); @@ -51,7 +51,7 @@ void DrawDanglingSymbol( EDA_DRAW_PANEL* panel, wxDC* DC, * 0 if canceled order */ int DisplayComponentsNamesInLib( EDA_DRAW_FRAME* frame, - CMP_LIBRARY* Library, + PART_LIB* Library, wxString& Buffer, wxString& OldName ); @@ -61,7 +61,7 @@ int DisplayComponentsNamesInLib( EDA_DRAW_FRAME* frame, * a library * This list is sorted, with the library cache always at end of the list */ -CMP_LIBRARY* SelectLibraryFromList( EDA_DRAW_FRAME* frame ); +PART_LIB* SelectLibraryFromList( EDA_DRAW_FRAME* frame ); /** * Get the name component from a library to load. @@ -72,6 +72,6 @@ CMP_LIBRARY* SelectLibraryFromList( EDA_DRAW_FRAME* frame ); * 0 if canceled order * Place the name of the selected component list in BufName */ -int GetNameOfPartToLoad( EDA_DRAW_FRAME* frame, CMP_LIBRARY* Lib, wxString& BufName ); +int GetNameOfPartToLoad( EDA_DRAW_FRAME* frame, PART_LIB* Lib, wxString& BufName ); #endif /* __PROTOS_H__ */ diff --git a/eeschema/sch_collectors.cpp b/eeschema/sch_collectors.cpp index 6f8562091e..5cb9c3f814 100644 --- a/eeschema/sch_collectors.cpp +++ b/eeschema/sch_collectors.cpp @@ -542,3 +542,23 @@ void SCH_FIND_COLLECTOR::Collect( SCH_FIND_REPLACE_DATA& aFindReplaceData, m_data.clear(); } } + + +SEARCH_RESULT SCH_TYPE_COLLECTOR::Inspect( EDA_ITEM* aItem, const void* aTestData ) +{ + // The Vist() function only visits the testItem if its type was in the + // the scanList, so therefore we can collect anything given to us here. + Append( aItem ); + + return SEARCH_CONTINUE; +} + + +void SCH_TYPE_COLLECTOR::Collect( SCH_ITEM* aItem, const KICAD_T aFilterList[] ) +{ + Empty(); // empty the collection + + SetScanTypes( aFilterList ); + + EDA_ITEM::IterateForward( aItem, this, NULL, m_ScanTypes ); +} diff --git a/eeschema/sch_collectors.h b/eeschema/sch_collectors.h index 4813253919..d94020c7f7 100644 --- a/eeschema/sch_collectors.h +++ b/eeschema/sch_collectors.h @@ -352,4 +352,37 @@ public: }; +/** + * Class TYPE_COLLECTOR + * merely gathers up all SCH_ITEMs of a given set of KICAD_T type(s). It does + * no hit-testing. + * + * @see class COLLECTOR + */ +class SCH_TYPE_COLLECTOR : public SCH_COLLECTOR +{ +public: + /** + * Function Inspect + * is the examining function within the INSPECTOR which is passed to the + * Iterate function. + * + * @param testItem An EDA_ITEM to examine. + * @param testData is not used in this class. + * @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan, + * else SCAN_CONTINUE; + */ + SEARCH_RESULT Inspect( EDA_ITEM* testItem, const void* testData ); + + /** + * Function Collect + * scans a BOARD_ITEM using this class's Inspector method, which does + * the collection. + * @param aBoard The BOARD_ITEM to scan. + * @param aScanList The KICAD_Ts to gather up. + */ + void Collect( SCH_ITEM* aBoard, const KICAD_T aScanList[] ); +}; + + #endif // _SCH_COLLECTORS_H_ diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index 0ee3715fd2..0a12ef6ad4 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -46,6 +46,7 @@ #include #include #include +//#include #include #include @@ -54,9 +55,6 @@ #define NULL_STRING "_NONAME_" -static LIB_COMPONENT* DummyCmp; - - /** * Function toUTFTildaText * convert a wxString to UTF8 and replace any control characters with a ~, @@ -75,34 +73,42 @@ static std::string toUTFTildaText( const wxString& txt ) } -/* Descr component used when a component is not found in library, - * to draw a dummy shape - * This component is a 400 mils square with the text ?? - * DEF DUMMY U 0 40 Y Y 1 0 N - * F0 "U" 0 -350 60 H V - * F1 "DUMMY" 0 350 60 H V - * DRAW - * T 0 0 0 150 0 0 0 ?? - * S -200 200 200 -200 0 1 0 - * ENDDRAW - * ENDDEF +/** + * Used when a LIB_PART is not found in library + * to draw a dummy shape + * This component is a 400 mils square with the text ?? + * DEF DUMMY U 0 40 Y Y 1 0 N + * F0 "U" 0 -350 60 H V + * F1 "DUMMY" 0 350 60 H V + * DRAW + * T 0 0 0 150 0 0 0 ?? + * S -200 200 200 -200 0 1 0 + * ENDDRAW + * ENDDEF */ -void CreateDummyCmp() +static LIB_PART* dummy() { - DummyCmp = new LIB_COMPONENT( wxEmptyString ); + static LIB_PART* part; - LIB_RECTANGLE* Square = new LIB_RECTANGLE( DummyCmp ); + if( !part ) + { + part = new LIB_PART( wxEmptyString ); - Square->Move( wxPoint( -200, 200 ) ); - Square->SetEndPosition( wxPoint( 200, -200 ) ); + LIB_RECTANGLE* square = new LIB_RECTANGLE( part ); - LIB_TEXT* Text = new LIB_TEXT( DummyCmp ); + square->Move( wxPoint( -200, 200 ) ); + square->SetEndPosition( wxPoint( 200, -200 ) ); - Text->SetSize( wxSize( 150, 150 ) ); - Text->SetText( wxString( wxT( "??" ) ) ); + LIB_TEXT* text = new LIB_TEXT( part ); - DummyCmp->AddDrawItem( Square ); - DummyCmp->AddDrawItem( Text ); + text->SetSize( wxSize( 150, 150 ) ); + text->SetText( wxString( wxT( "??" ) ) ); + + part->AddDrawItem( square ); + part->AddDrawItem( text ); + } + + return part; } @@ -113,7 +119,7 @@ SCH_COMPONENT::SCH_COMPONENT( const wxPoint& aPos, SCH_ITEM* aParent ) : } -SCH_COMPONENT::SCH_COMPONENT( LIB_COMPONENT& libComponent, SCH_SHEET_PATH* sheet, int unit, +SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, SCH_SHEET_PATH* sheet, int unit, int convert, const wxPoint& pos, bool setNewItemFlag ) : SCH_ITEM( NULL, SCH_COMPONENT_T ) { @@ -121,7 +127,9 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_COMPONENT& libComponent, SCH_SHEET_PATH* sheet m_unit = unit; m_convert = convert; - m_ChipName = libComponent.GetName(); + m_part_name = aPart.GetName(); + m_part = aPart.SharedPtr(); + SetTimeStamp( GetNewTimeStamp() ); if( setNewItemFlag ) @@ -130,7 +138,7 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_COMPONENT& libComponent, SCH_SHEET_PATH* sheet // Import user defined fields from the library component: LIB_FIELDS libFields; - libComponent.GetFields( libFields ); + aPart.GetFields( libFields ); for( LIB_FIELDS::iterator it = libFields.begin(); it!=libFields.end(); ++it ) { @@ -155,7 +163,7 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_COMPONENT& libComponent, SCH_SHEET_PATH* sheet schField->SetText( it->GetText() ); } - wxString msg = libComponent.GetReferenceField().GetText(); + wxString msg = aPart.GetReferenceField().GetText(); if( msg.IsEmpty() ) msg = wxT( "U" ); @@ -166,22 +174,24 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_COMPONENT& libComponent, SCH_SHEET_PATH* sheet msg += wxT( "?" ); SetRef( sheet, msg ); - /* Use the schematic component name instead of the library value field - * name. - */ - GetField( VALUE )->SetText( m_ChipName ); + // Use the schematic component name instead of the library value field + // name. + GetField( VALUE )->SetText( GetPartName() ); } SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) : SCH_ITEM( aComponent ) { - m_Parent = aComponent.m_Parent; - m_Pos = aComponent.m_Pos; - m_unit = aComponent.m_unit; - m_convert = aComponent.m_convert; - m_ChipName = aComponent.m_ChipName; + m_Parent = aComponent.m_Parent; + m_Pos = aComponent.m_Pos; + m_unit = aComponent.m_unit; + m_convert = aComponent.m_convert; + m_part_name = aComponent.m_part_name; + m_part = aComponent.m_part; + SetTimeStamp( aComponent.m_TimeStamp ); + m_transform = aComponent.m_transform; m_prefix = aComponent.m_prefix; m_PathsAndReferences = aComponent.m_PathsAndReferences; @@ -230,12 +240,44 @@ EDA_ITEM* SCH_COMPONENT::Clone() const } -void SCH_COMPONENT::SetLibName( const wxString& aName ) +void SCH_COMPONENT::SetPartName( const wxString& aName, PART_LIBS* aLibs ) { - if( m_ChipName != aName ) + if( m_part_name != aName ) { - m_ChipName = aName; + m_part_name = aName; SetModified(); + + if( aLibs ) + Resolve( aLibs ); + else + m_part.reset(); + } +} + + +bool SCH_COMPONENT::Resolve( PART_LIBS* aLibs ) +{ + // I've never been happy that the actual individual PART_LIB is left up to + // flimsy search path ordering. None-the-less find a part based on that design: + if( LIB_PART* part = aLibs->FindLibPart( m_part_name ) ) + { + m_part = part->SharedPtr(); + return true; + } + + return false; +} + + +void SCH_COMPONENT::ResolveAll( + const SCH_COLLECTOR& aComponents, PART_LIBS* aLibs ) +{ + for( int i = 0; i < aComponents.GetCount(); ++i ) + { + SCH_COMPONENT* c = dynamic_cast( aComponents[i] ); + wxASSERT( c ); + + c->Resolve( aLibs ); } } @@ -275,38 +317,28 @@ void SCH_COMPONENT::SetTransform( const TRANSFORM& aTransform ) } -int SCH_COMPONENT::GetPartCount() const +int SCH_COMPONENT::GetUnitCount() const { - LIB_COMPONENT* Entry = CMP_LIBRARY::FindLibraryComponent( m_ChipName ); + if( PART_SPTR part = m_part.lock() ) + { + return part->GetUnitCount(); + } - if( Entry == NULL ) - return 0; - - return Entry->GetPartCount(); + return 0; } - void SCH_COMPONENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset, GR_DRAWMODE DrawMode, EDA_COLOR_T Color, bool DrawPinText ) { - bool dummy = false; - - LIB_COMPONENT* Entry = CMP_LIBRARY::FindLibraryComponent( m_ChipName ); - - if( Entry == NULL ) + if( PART_SPTR part = m_part.lock() ) { - /* Create a dummy component if the actual component can not be found. */ - dummy = true; - - if( DummyCmp == NULL ) - CreateDummyCmp(); - - Entry = DummyCmp; + part->Draw( panel, DC, m_Pos + offset, m_unit, m_convert, DrawMode, Color, m_transform, DrawPinText, false ); + } + else // Use dummy() part if the actual cannot be found. + { + dummy()->Draw( panel, DC, m_Pos + offset, 0, 0, DrawMode, Color, m_transform, DrawPinText, false ); } - - Entry->Draw( panel, DC, m_Pos + offset, dummy ? 0 : m_unit, dummy ? 0 : m_convert, - DrawMode, Color, m_transform, DrawPinText, false ); SCH_FIELD* field = GetField( REFERENCE ); @@ -325,24 +357,23 @@ void SCH_COMPONENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset field->Draw( panel, DC, offset, DrawMode ); } - #if 0 - /* Draw the component boundary box */ + // Draw the component bounding box { - EDA_RECT BoundaryBox; - BoundaryBox = GetBoundingBox(); - GRRect( panel->GetClipBox(), DC, BoundaryBox, 0, BROWN ); + EDA_RECT boundingBox = GetBoundingBox(); + + GRRect( panel->GetClipBox(), DC, boundingBox, 0, BROWN ); #if 1 if( GetField( REFERENCE )->IsVisible() ) { - BoundaryBox = GetField( REFERENCE )->GetBoundingBox(); - GRRect( panel->GetClipBox(), DC, BoundaryBox, 0, BROWN ); + boundingBox = GetField( REFERENCE )->GetBoundingBox(); + GRRect( panel->GetClipBox(), DC, boundingBox, 0, BROWN ); } if( GetField( VALUE )->IsVisible() ) { - BoundaryBox = GetField( VALUE )->GetBoundingBox(); - GRRect( panel->GetClipBox(), DC, BoundaryBox, 0, BROWN ); + boundingBox = GetField( VALUE )->GetBoundingBox(); + GRRect( panel->GetClipBox(), DC, boundingBox, 0, BROWN ); } #endif } @@ -631,12 +662,11 @@ SCH_FIELD* SCH_COMPONENT::FindField( const wxString& aFieldName ) LIB_PIN* SCH_COMPONENT::GetPin( const wxString& number ) { - LIB_COMPONENT* Entry = CMP_LIBRARY::FindLibraryComponent( m_ChipName ); - - if( Entry == NULL ) - return NULL; - - return Entry->GetPin( number, m_unit, m_convert ); + if( PART_SPTR part = m_part.lock() ) + { + return part->GetPin( number, m_unit, m_convert ); + } + return NULL; } @@ -647,12 +677,14 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem ) SCH_COMPONENT* component = (SCH_COMPONENT*) aItem; - EXCHG( m_ChipName, component->m_ChipName ); + EXCHG( m_part_name, component->m_part_name ); + EXCHG( m_part, component->m_part ); EXCHG( m_Pos, component->m_Pos ); EXCHG( m_unit, component->m_unit ); EXCHG( m_convert, component->m_convert ); TRANSFORM tmp = m_transform; + m_transform = component->m_transform; component->m_transform = tmp; @@ -677,13 +709,13 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem ) void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) { bool keepMulti = false; - LIB_COMPONENT* Entry; - static const wxString separators( wxT( " " ) ); wxArrayString reference_fields; - Entry = CMP_LIBRARY::FindLibraryComponent( m_ChipName ); + static const wxChar separators[] = wxT( " " ); - if( Entry && Entry->UnitsLocked() ) + PART_SPTR part = m_part.lock(); + + if( part && part->UnitsLocked() ) keepMulti = true; // Build a reference with no annotation, @@ -930,7 +962,7 @@ void SCH_COMPONENT::Show( int nestLevel, std::ostream& os ) const NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << " ref=\"" << TO_UTF8( GetField( 0 )->GetName() ) << '"' << " chipName=\"" - << TO_UTF8( m_ChipName ) << '"' << m_Pos + << TO_UTF8( GetPartName() ) << '"' << m_Pos << " layer=\"" << m_Layer << '"' << ">\n"; @@ -978,9 +1010,11 @@ bool SCH_COMPONENT::Save( FILE* f ) const name1 = toUTFTildaText( GetField( REFERENCE )->GetText() ); } - if( !m_ChipName.IsEmpty() ) + wxString part_name = GetPartName(); + + if( part_name.size() ) { - name2 = toUTFTildaText( m_ChipName ); + name2 = toUTFTildaText( part_name ); } else { @@ -993,11 +1027,11 @@ bool SCH_COMPONENT::Save( FILE* f ) const if( fprintf( f, "L %s %s\n", name2.c_str(), name1.c_str() ) == EOF ) return false; - /* Generate unit number, convert and time stamp*/ + // Generate unit number, convert and time stamp if( fprintf( f, "U %d %d %8.8lX\n", m_unit, m_convert, m_TimeStamp ) == EOF ) return false; - /* Save the position */ + // Save the position if( fprintf( f, "P %d %d\n", m_Pos.x, m_Pos.y ) == EOF ) return false; @@ -1058,7 +1092,7 @@ bool SCH_COMPONENT::Save( FILE* f ) const return false; } - /* Unit number, position, box ( old standard ) */ + // Unit number, position, box ( old standard ) if( fprintf( f, "\t%-4d %-4d %-4d\n", m_unit, m_Pos.x, m_Pos.y ) == EOF ) return false; @@ -1109,14 +1143,14 @@ bool SCH_COMPONENT::Load( LINE_READER& aLine, wxString& aErrorMsg ) name1[ii] = ' '; } - m_ChipName = FROM_UTF8( name1 ); + SetPartName( FROM_UTF8( name1 ) ); if( !newfmt ) GetField( VALUE )->SetText( FROM_UTF8( name1 ) ); } else { - m_ChipName.Empty(); + m_part_name.Empty(); GetField( VALUE )->Empty(); GetField( VALUE )->SetOrientation( TEXT_ORIENT_HORIZ ); GetField( VALUE )->SetVisible( false ); @@ -1385,29 +1419,27 @@ bool SCH_COMPONENT::Load( LINE_READER& aLine, wxString& aErrorMsg ) EDA_RECT SCH_COMPONENT::GetBodyBoundingBox() const { - LIB_COMPONENT* Entry = CMP_LIBRARY::FindLibraryComponent( m_ChipName ); - EDA_RECT bBox; - int x0, xm, y0, ym; + EDA_RECT bBox; - if( Entry == NULL ) + if( PART_SPTR part = m_part.lock() ) { - if( DummyCmp == NULL ) - CreateDummyCmp(); - Entry = DummyCmp; + bBox = part->GetBodyBoundingBox( m_unit, m_convert ); + } + else + { + bBox = dummy()->GetBodyBoundingBox( m_unit, m_convert ); } - /* Get the basic Boundary box */ - bBox = Entry->GetBodyBoundingBox( m_unit, m_convert ); - x0 = bBox.GetX(); - xm = bBox.GetRight(); + int x0 = bBox.GetX(); + int xm = bBox.GetRight(); // We must reverse Y values, because matrix orientation // suppose Y axis normal for the library items coordinates, // m_transform reverse Y values, but bBox is already reversed! - y0 = -bBox.GetY(); - ym = -bBox.GetBottom(); + int y0 = -bBox.GetY(); + int ym = -bBox.GetBottom(); - /* Compute the real Boundary box (rotated, mirrored ...)*/ + // Compute the real Boundary box (rotated, mirrored ...) int x1 = m_transform.x1 * x0 + m_transform.y1 * y0; int y1 = m_transform.x2 * x0 + m_transform.y2 * y0; int x2 = m_transform.x1 * xm + m_transform.y1 * ym; @@ -1433,6 +1465,7 @@ EDA_RECT SCH_COMPONENT::GetBodyBoundingBox() const const EDA_RECT SCH_COMPONENT::GetBoundingBox() const { EDA_RECT bbox = GetBodyBoundingBox(); + for( size_t i = 0; i < m_Fields.size(); i++ ) { bbox.Merge( m_Fields[i].GetBoundingBox() ); @@ -1444,47 +1477,43 @@ const EDA_RECT SCH_COMPONENT::GetBoundingBox() const void SCH_COMPONENT::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList ) { - // search for the component in lib - // Entry and root_component can differ if Entry is an alias - LIB_ALIAS* alias = CMP_LIBRARY::FindLibraryEntry( m_ChipName ); - LIB_COMPONENT* root_component = CMP_LIBRARY::FindLibraryComponent( m_ChipName ); + // part and alias can differ if alias is not the root + if( PART_SPTR part = m_part.lock() ) + { + LIB_ALIAS* alias = part->GetAlias( GetPartName() ); - if( (alias == NULL) || (root_component == NULL) ) - return; + if( !alias ) + return; - wxString msg; + if( m_currentSheetPath ) + aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), + GetRef( m_currentSheetPath ), + DARKCYAN ) ); - if( m_currentSheetPath ) - aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), - GetRef( m_currentSheetPath ), - DARKCYAN ) ); + wxString msg = part->IsPower() ? _( "Power symbol" ) : _( "Value" ); - if( root_component->IsPower() ) - msg = _( "Power symbol" ); - else - msg = _( "Value" ); + aList.push_back( MSG_PANEL_ITEM( msg, GetField( VALUE )->GetText(), DARKCYAN ) ); - aList.push_back( MSG_PANEL_ITEM( msg, GetField( VALUE )->GetText(), DARKCYAN ) ); + // Display component reference in library and library + aList.push_back( MSG_PANEL_ITEM( _( "Component" ), GetPartName(), BROWN ) ); - // Display component reference in library and library - aList.push_back( MSG_PANEL_ITEM( _( "Component" ), m_ChipName, BROWN ) ); + if( alias->GetName() != part->GetName() ) + aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), part->GetName(), BROWN ) ); - if( alias->GetName() != root_component->GetName() ) - aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), root_component->GetName(), BROWN ) ); + aList.push_back( MSG_PANEL_ITEM( _( "Library" ), alias->GetLibraryName(), BROWN ) ); - aList.push_back( MSG_PANEL_ITEM( _( "Library" ), alias->GetLibraryName(), BROWN ) ); + // Display the current associated footprint, if exists. + if( !GetField( FOOTPRINT )->IsVoid() ) + msg = GetField( FOOTPRINT )->GetText(); + else + msg = _( "" ); - // Display the current associated footprin, if exists. - if( ! GetField( FOOTPRINT )->IsVoid() ) - msg = GetField( FOOTPRINT )->GetText(); - else - msg = _( "" ); + aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKRED ) ); - aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKRED ) ); - - // Display description of the component, and keywords found in lib - aList.push_back( MSG_PANEL_ITEM( _( "Description" ), alias->GetDescription(), DARKCYAN ) ); - aList.push_back( MSG_PANEL_ITEM( _( "Key words" ), alias->GetKeyWords(), DARKCYAN ) ); + // Display description of the component, and keywords found in lib + aList.push_back( MSG_PANEL_ITEM( _( "Description" ), alias->GetDescription(), DARKCYAN ) ); + aList.push_back( MSG_PANEL_ITEM( _( "Key words" ), alias->GetKeyWords(), DARKCYAN ) ); + } } @@ -1559,23 +1588,21 @@ bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData, void SCH_COMPONENT::GetEndPoints( std::vector & aItemList ) { - LIB_COMPONENT* Entry = CMP_LIBRARY::FindLibraryComponent( m_ChipName ); - - if( Entry == NULL ) - return; - - for( LIB_PIN* Pin = Entry->GetNextPin(); Pin != NULL; Pin = Entry->GetNextPin( Pin ) ) + if( PART_SPTR part = m_part.lock() ) { - wxASSERT( Pin->Type() == LIB_PIN_T ); + for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) ) + { + wxASSERT( pin->Type() == LIB_PIN_T ); - if( Pin->GetUnit() && m_unit && ( m_unit != Pin->GetUnit() ) ) - continue; + if( pin->GetUnit() && m_unit && ( m_unit != pin->GetUnit() ) ) + continue; - if( Pin->GetConvert() && m_convert && ( m_convert != Pin->GetConvert() ) ) - continue; + if( pin->GetConvert() && m_convert && ( m_convert != pin->GetConvert() ) ) + continue; - DANGLING_END_ITEM item( PIN_END, Pin, GetPinPhysicalPosition( Pin ) ); - aItemList.push_back( item ); + DANGLING_END_ITEM item( PIN_END, pin, GetPinPhysicalPosition( pin ) ); + aItemList.push_back( item ); + } } } @@ -1606,42 +1633,44 @@ bool SCH_COMPONENT::IsSelectStateChanged( const wxRect& aRect ) void SCH_COMPONENT::GetConnectionPoints( std::vector< wxPoint >& aPoints ) const { - LIB_PIN* pin; - LIB_COMPONENT* component = CMP_LIBRARY::FindLibraryComponent( m_ChipName ); - - wxCHECK_RET( component != NULL, - wxT( "Cannot add connection points to list. Cannot find component <" ) + - m_ChipName + wxT( "> in any of the loaded libraries." ) ); - - for( pin = component->GetNextPin(); pin != NULL; pin = component->GetNextPin( pin ) ) + if( PART_SPTR part = m_part.lock() ) { - wxCHECK_RET( pin->Type() == LIB_PIN_T, - wxT( "GetNextPin() did not return a pin object. Bad programmer!" ) ); + for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) ) + { + wxCHECK_RET( pin->Type() == LIB_PIN_T, + wxT( "GetNextPin() did not return a pin object. Bad programmer!" ) ); - // Skip items not used for this part. - if( m_unit && pin->GetUnit() && ( pin->GetUnit() != m_unit ) ) - continue; + // Skip items not used for this part. + if( m_unit && pin->GetUnit() && ( pin->GetUnit() != m_unit ) ) + continue; - if( m_convert && pin->GetConvert() && ( pin->GetConvert() != m_convert ) ) - continue; + if( m_convert && pin->GetConvert() && ( pin->GetConvert() != m_convert ) ) + continue; - // Calculate the pin position relative to the component position and orientation. - aPoints.push_back( m_transform.TransformCoordinate( pin->GetPosition() ) + m_Pos ); + // Calculate the pin position relative to the component position and orientation. + aPoints.push_back( m_transform.TransformCoordinate( pin->GetPosition() ) + m_Pos ); + } + } + else + { + wxCHECK_RET( 0, + wxT( "Cannot add connection points to list. Cannot find component <" ) + + GetPartName() + wxT( "> in any of the loaded libraries." ) ); } } LIB_ITEM* SCH_COMPONENT::GetDrawItem( const wxPoint& aPosition, KICAD_T aType ) { - LIB_COMPONENT* component = CMP_LIBRARY::FindLibraryComponent( m_ChipName ); + if( PART_SPTR part = m_part.lock() ) + { + // Calculate the position relative to the component. + wxPoint libPosition = aPosition - m_Pos; - if( component == NULL ) - return NULL; + return part->LocateDrawItem( m_unit, m_convert, aType, libPosition, m_transform ); + } - // Calculate the position relative to the component. - wxPoint libPosition = aPosition - m_Pos; - - return component->LocateDrawItem( m_unit, m_convert, aType, libPosition, m_transform ); + return NULL; } @@ -1649,7 +1678,7 @@ wxString SCH_COMPONENT::GetSelectMenuText() const { wxString tmp; tmp.Printf( _( "Component %s, %s" ), - GetChars( m_ChipName ), + GetChars( GetPartName() ), GetChars( GetField( REFERENCE )->GetText() ) ); return tmp; } @@ -1658,8 +1687,7 @@ wxString SCH_COMPONENT::GetSelectMenuText() const SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR* aInspector, const void* aTestData, const KICAD_T aFilterTypes[] ) { - KICAD_T stype; - LIB_COMPONENT* component; + KICAD_T stype; for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p ) { @@ -1669,50 +1697,51 @@ SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR* aInspector, const void* aTestData if( SEARCH_QUIT == aInspector->Inspect( this, aTestData ) ) return SEARCH_QUIT; } + switch( stype ) { - case SCH_FIELD_T: - // Test the bounding boxes of fields if they are visible and not empty. - for( int ii = 0; ii < GetFieldCount(); ii++ ) + case SCH_FIELD_T: + // Test the bounding boxes of fields if they are visible and not empty. + for( int ii = 0; ii < GetFieldCount(); ii++ ) + { + if( SEARCH_QUIT == aInspector->Inspect( GetField( ii ), (void*) this ) ) + return SEARCH_QUIT; + } + break; + + case SCH_FIELD_LOCATE_REFERENCE_T: + if( SEARCH_QUIT == aInspector->Inspect( GetField( REFERENCE ), (void*) this ) ) + return SEARCH_QUIT; + break; + + case SCH_FIELD_LOCATE_VALUE_T: + if( SEARCH_QUIT == aInspector->Inspect( GetField( VALUE ), (void*) this ) ) + return SEARCH_QUIT; + break; + + case SCH_FIELD_LOCATE_FOOTPRINT_T: + if( SEARCH_QUIT == aInspector->Inspect( GetField( FOOTPRINT ), (void*) this ) ) + return SEARCH_QUIT; + break; + + + case LIB_PIN_T: + if( PART_SPTR part = m_part.lock() ) + { + LIB_PINS pins; + + part->GetPins( pins, m_unit, m_convert ); + + for( size_t i = 0; i < pins.size(); i++ ) { - if( SEARCH_QUIT == aInspector->Inspect( GetField( ii ), (void*) this ) ) + if( SEARCH_QUIT == aInspector->Inspect( pins[ i ], (void*) this ) ) return SEARCH_QUIT; } - break; + } + break; - case SCH_FIELD_LOCATE_REFERENCE_T: - if( SEARCH_QUIT == aInspector->Inspect( GetField( REFERENCE ), (void*) this ) ) - return SEARCH_QUIT; - break; - - case SCH_FIELD_LOCATE_VALUE_T: - if( SEARCH_QUIT == aInspector->Inspect( GetField( VALUE ), (void*) this ) ) - return SEARCH_QUIT; - break; - - case SCH_FIELD_LOCATE_FOOTPRINT_T: - if( SEARCH_QUIT == aInspector->Inspect( GetField( FOOTPRINT ), (void*) this ) ) - return SEARCH_QUIT; - break; - - - case LIB_PIN_T: - component = CMP_LIBRARY::FindLibraryComponent( m_ChipName ); - - if( component != NULL ) - { - LIB_PINS pins; - component->GetPins( pins, m_unit, m_convert ); - for( size_t i = 0; i < pins.size(); i++ ) - { - if( SEARCH_QUIT == aInspector->Inspect( pins[ i ], (void*) this ) ) - return SEARCH_QUIT; - } - } - break; - - default: - break; + default: + break; } } @@ -1723,49 +1752,47 @@ SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR* aInspector, const void* aTestData void SCH_COMPONENT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, SCH_SHEET_PATH* aSheetPath ) { - LIB_COMPONENT* component = CMP_LIBRARY::FindLibraryComponent( GetLibName() ); - - if( component == NULL ) - return; - - for( LIB_PIN* pin = component->GetNextPin(); pin; pin = component->GetNextPin( pin ) ) + if( PART_SPTR part = m_part.lock() ) { - wxASSERT( pin->Type() == LIB_PIN_T ); - - if( pin->GetUnit() && ( pin->GetUnit() != GetUnitSelection( aSheetPath ) ) ) - continue; - - if( pin->GetConvert() && ( pin->GetConvert() != GetConvert() ) ) - continue; - - wxPoint pos = GetTransform().TransformCoordinate( pin->GetPosition() ) + m_Pos; - - NETLIST_OBJECT* item = new NETLIST_OBJECT(); - item->m_SheetPathInclude = *aSheetPath; - item->m_Comp = (SCH_ITEM*) pin; - item->m_SheetPath = *aSheetPath; - item->m_Type = NET_PIN; - item->m_Link = (SCH_ITEM*) this; - item->m_ElectricalType = pin->GetType(); - item->m_PinNum = pin->GetNumber(); - item->m_Label = pin->GetName(); - item->m_Start = item->m_End = pos; - - aNetListItems.push_back( item ); - - if( ( (int) pin->GetType() == (int) PIN_POWER_IN ) && !pin->IsVisible() ) + for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) ) { - /* There is an associated PIN_LABEL. */ - item = new NETLIST_OBJECT(); + wxASSERT( pin->Type() == LIB_PIN_T ); + + if( pin->GetUnit() && ( pin->GetUnit() != GetUnitSelection( aSheetPath ) ) ) + continue; + + if( pin->GetConvert() && ( pin->GetConvert() != GetConvert() ) ) + continue; + + wxPoint pos = GetTransform().TransformCoordinate( pin->GetPosition() ) + m_Pos; + + NETLIST_OBJECT* item = new NETLIST_OBJECT(); item->m_SheetPathInclude = *aSheetPath; - item->m_Comp = NULL; + item->m_Comp = (SCH_ITEM*) pin; item->m_SheetPath = *aSheetPath; - item->m_Type = NET_PINLABEL; + item->m_Type = NET_PIN; + item->m_Link = (SCH_ITEM*) this; + item->m_ElectricalType = pin->GetType(); + item->m_PinNum = pin->GetNumber(); item->m_Label = pin->GetName(); - item->m_Start = pos; - item->m_End = item->m_Start; + item->m_Start = item->m_End = pos; aNetListItems.push_back( item ); + + if( ( (int) pin->GetType() == (int) PIN_POWER_IN ) && !pin->IsVisible() ) + { + // There is an associated PIN_LABEL. + item = new NETLIST_OBJECT(); + item->m_SheetPathInclude = *aSheetPath; + item->m_Comp = NULL; + item->m_SheetPath = *aSheetPath; + item->m_Type = NET_PINLABEL; + item->m_Label = pin->GetName(); + item->m_Start = pos; + item->m_End = item->m_Start; + + aNetListItems.push_back( item ); + } } } } @@ -1824,15 +1851,18 @@ SCH_ITEM& SCH_COMPONENT::operator=( const SCH_ITEM& aItem ) { SCH_ITEM::operator=( aItem ); - SCH_COMPONENT* component = (SCH_COMPONENT*) &aItem; - m_ChipName = component->m_ChipName; - m_Pos = component->m_Pos; - m_unit = component->m_unit; - m_convert = component->m_convert; - m_transform = component->m_transform; - m_PathsAndReferences = component->m_PathsAndReferences; + SCH_COMPONENT* c = (SCH_COMPONENT*) &aItem; - m_Fields = component->m_Fields; // std::vector's assignment operator. + m_part_name = c->m_part_name; + m_part = c->m_part; + m_Pos = c->m_Pos; + m_unit = c->m_unit; + m_convert = c->m_convert; + m_transform = c->m_transform; + + m_PathsAndReferences = c->m_PathsAndReferences; + + m_Fields = c->m_Fields; // std::vector's assignment operator. // Reparent fields after assignment to new component. for( int ii = 0; ii < GetFieldCount(); ++ii ) @@ -1888,10 +1918,7 @@ bool SCH_COMPONENT::doIsConnected( const wxPoint& aPosition ) const return false; } -/* return true if the component is in netlist - * which means this is not a power component, or something - * like a component reference starting by # - */ + bool SCH_COMPONENT::IsInNetlist() const { SCH_FIELD* rf = GetField( REFERENCE ); @@ -1901,20 +1928,17 @@ bool SCH_COMPONENT::IsInNetlist() const void SCH_COMPONENT::Plot( PLOTTER* aPlotter ) { - LIB_COMPONENT* Entry; - TRANSFORM temp = TRANSFORM(); + TRANSFORM temp; - Entry = CMP_LIBRARY::FindLibraryComponent( GetLibName() ); - - if( Entry == NULL ) - return; - - temp = GetTransform(); - - Entry->Plot( aPlotter, GetUnit(), GetConvert(), m_Pos, temp ); - - for( size_t i = 0; i < m_Fields.size(); i++ ) + if( PART_SPTR part = m_part.lock() ) { - m_Fields[i].Plot( aPlotter ); + temp = GetTransform(); + + part->Plot( aPlotter, GetUnit(), GetConvert(), m_Pos, temp ); + + for( size_t i = 0; i < m_Fields.size(); i++ ) + { + m_Fields[i].Plot( aPlotter ); + } } } diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index aac7dac913..0f243736d2 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -34,16 +34,23 @@ #include #include #include +#include class SCH_SHEET_PATH; class LIB_ITEM; class LIB_PIN; -class LIB_COMPONENT; +class LIB_PART; class NETLIST_OBJECT_LIST; +class LIB_PART; +class PART_LIBS; +class SCH_COLLECTOR; + /// A container for several SCH_FIELD items -typedef std::vector SCH_FIELDS; +typedef std::vector SCH_FIELDS; + +typedef boost::weak_ptr PART_REF; /** @@ -54,18 +61,21 @@ class SCH_COMPONENT : public SCH_ITEM { friend class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC; - wxPoint m_Pos; - wxString m_ChipName; ///< Name to look for in the library, i.e. "74LS00". - int m_unit; ///< The unit for multiple part per package components. - int m_convert; ///< The alternate body style for components that have more than - ///< one body style defined. Primarily used for components that - ///< have a De Morgan conversion. - wxString m_prefix; ///< C, R, U, Q etc - the first character which typically indicates - ///< what the component is. Determined, upon placement, from the - ///< library component. Created upon file load, by the first - ///< non-digits in the reference fields. - TRANSFORM m_transform; ///< The rotation/mirror transformation matrix. - SCH_FIELDS m_Fields; ///< Variable length list of fields. + wxPoint m_Pos; + wxString m_part_name; ///< Name to look for in the library, i.e. "74LS00". + + int m_unit; ///< The unit for multiple part per package components. + int m_convert; ///< The alternate body style for components that have more than + ///< one body style defined. Primarily used for components that + ///< have a De Morgan conversion. + wxString m_prefix; ///< C, R, U, Q etc - the first character which typically indicates + ///< what the component is. Determined, upon placement, from the + ///< library component. Created upon file load, by the first + ///< non-digits in the reference fields. + TRANSFORM m_transform; ///< The rotation/mirror transformation matrix. + SCH_FIELDS m_Fields; ///< Variable length list of fields. + + PART_REF m_part; ///< points into the PROJECT's libraries to the LIB_PART for this component /** * A temporary sheet path is required to generate the correct reference designator string @@ -93,9 +103,8 @@ public: /** * Create schematic component from library component object. * - * @param libComponent - Component library object to create schematic - * component from. - * @param sheet - Schematic sheet the component is place into. + * @param aPart - library part to create schematic component from. + * @param aSheet - Schematic sheet the component is place into. * @param unit - Part for components that have multiple parts per * package. * @param convert - Use the alternate body style for the schematic @@ -103,7 +112,7 @@ public: * @param pos - Position to place new component. * @param setNewItemFlag - Set the component IS_NEW and IS_MOVED flags. */ - SCH_COMPONENT( LIB_COMPONENT& libComponent, SCH_SHEET_PATH* sheet, + SCH_COMPONENT( LIB_PART& aPart, SCH_SHEET_PATH* aSheet, int unit = 0, int convert = 0, const wxPoint& pos = wxPoint( 0, 0 ), bool setNewItemFlag = false ); @@ -124,9 +133,18 @@ public: return wxT( "SCH_COMPONENT" ); } - wxString GetLibName() const { return m_ChipName; } + void SetPartName( const wxString& aName, PART_LIBS* aLibs=NULL ); + const wxString& GetPartName() const { return m_part_name; } - void SetLibName( const wxString& aName ); + /** + * Function Resolve + * [re-]assigns the current LIB_PART from aLibs which this component + * is based on. + * @param aLibs is the current set of LIB_PARTs to choose from. + */ + bool Resolve( PART_LIBS* aLibs ); + + static void ResolveAll( const SCH_COLLECTOR& aComponents, PART_LIBS* aLibs ); int GetUnit() const { return m_unit; } @@ -158,12 +176,12 @@ public: void SetTransform( const TRANSFORM& aTransform ); /** - * Function GetPartCount + * Function GetUnitCount * returns the number of parts per package of the component. * * @return The number of parts per package or zero if the library entry cannot be found. */ - int GetPartCount() const; + int GetUnitCount() const; bool Save( FILE* aFile ) const; diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 3eb8462e9f..7dde463b2f 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -90,8 +90,8 @@ const wxString SCH_FIELD::GetFullyQualifiedText() const wxCHECK_MSG( component != NULL, text, wxT( "No component associated with field" ) + text ); - if( component->GetPartCount() > 1 ) - text << LIB_COMPONENT::SubReference( component->GetUnit() ); + if( component->GetUnitCount() > 1 ) + text << LIB_PART::SubReference( component->GetUnit() ); } return text; @@ -393,8 +393,8 @@ bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint text = component->GetRef( (SCH_SHEET_PATH*) aAuxData ); - if( component->GetPartCount() > 1 ) - text << LIB_COMPONENT::SubReference( component->GetUnit() ); + if( component->GetUnitCount() > 1 ) + text << LIB_PART::SubReference( component->GetUnit() ); } match = SCH_ITEM::Matches( text, aSearchData ); @@ -431,8 +431,8 @@ bool SCH_FIELD::Replace( wxFindReplaceData& aSearchData, void* aAuxData ) text = component->GetRef( (SCH_SHEET_PATH*) aAuxData ); - // if( component->GetPartCount() > 1 ) - // text << LIB_COMPONENT::SubReference( component->GetUnit() ); + // if( component->GetUnitCount() > 1 ) + // text << LIB_PART::SubReference( component->GetUnit() ); isReplaced = EDA_ITEM::Replace( aSearchData, text ); @@ -565,7 +565,7 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter ) int thickness = GetPenSize(); - if( (parent->GetPartCount() <= 1) || (m_id != REFERENCE) ) + if( (parent->GetUnitCount() <= 1) || (m_id != REFERENCE) ) { aPlotter->Text( textpos, color, m_Text, orient, m_Size, hjustify, vjustify, thickness, m_Italic, m_Bold ); @@ -573,7 +573,7 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter ) else /* We plot the reference, for a multiple parts per package */ { /* Adding A, B ... to the reference */ - wxString Text = m_Text + LIB_COMPONENT::SubReference( parent->GetUnit() ); + wxString Text = m_Text + LIB_PART::SubReference( parent->GetUnit() ); aPlotter->Text( textpos, color, Text, orient, m_Size, hjustify, vjustify, thickness, m_Italic, m_Bold ); diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index fff8788f30..684ece90c7 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -74,7 +74,6 @@ static double SchematicZoomList[] = 12.0, 16.0, 23.0, 32.0, 48.0, 64.0, 80.0, 128.0 }; -#define SCHEMATIC_ZOOM_LIST_CNT ( sizeof( SchematicZoomList ) / sizeof( SchematicZoomList[0] ) ) #define MM_TO_SCH_UNITS 1000.0 / 25.4 //schematic internal unites are mils @@ -97,20 +96,18 @@ static GRID_TYPE SchematicGridList[] = { { ID_POPUP_GRID_LEVEL_1, wxRealPoint( 1, 1 ) }, }; -#define SCHEMATIC_GRID_LIST_CNT ( sizeof( SchematicGridList ) / sizeof( GRID_TYPE ) ) - -SCH_SCREEN::SCH_SCREEN() : BASE_SCREEN( SCH_SCREEN_T ), +SCH_SCREEN::SCH_SCREEN( KIWAY* aKiway ) : + BASE_SCREEN( SCH_SCREEN_T ), + KIWAY_HOLDER( aKiway ), m_paper( wxT( "A4" ) ) { - size_t i; - SetZoom( 32 ); - for( i = 0; i < SCHEMATIC_ZOOM_LIST_CNT; i++ ) + for( unsigned i = 0; i < DIM( SchematicZoomList ); i++ ) m_ZoomList.push_back( SchematicZoomList[i] ); - for( i = 0; i < SCHEMATIC_GRID_LIST_CNT; i++ ) + for( unsigned i = 0; i < DIM( SchematicGridList ); i++ ) AddGrid( SchematicGridList[i] ); SetGrid( wxRealPoint( 50, 50 ) ); // Default grid size. @@ -169,7 +166,7 @@ void SCH_SCREEN::Remove( SCH_ITEM* aItem ) void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem ) { - wxCHECK_RET( aItem != NULL, wxT( "Cannot delete invalid item from screen." ) ); + wxCHECK_RET( aItem, wxT( "Cannot delete invalid item from screen." ) ); SetModify(); @@ -178,7 +175,7 @@ void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem ) // This structure is attached to a sheet, get the parent sheet object. SCH_SHEET_PIN* sheetPin = (SCH_SHEET_PIN*) aItem; SCH_SHEET* sheet = sheetPin->GetParent(); - wxCHECK_RET( sheet != NULL, + wxCHECK_RET( sheet, wxT( "Sheet label parent not properly set, bad programmer!" ) ); sheet->RemovePin( sheetPin ); return; @@ -208,7 +205,7 @@ bool SCH_SCREEN::CheckIfOnDrawList( SCH_ITEM* aItem ) SCH_ITEM* SCH_SCREEN::GetItem( const wxPoint& aPosition, int aAccuracy, KICAD_T aType ) const { - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->HitTest( aPosition, aAccuracy ) && (aType == NOT_USED) ) return item; @@ -249,7 +246,7 @@ void SCH_SCREEN::ExtractWires( DLIST< SCH_ITEM >& aList, bool aCreateCopy ) SCH_ITEM* item; SCH_ITEM* next_item; - for( item = m_drawList.begin(); item != NULL; item = next_item ) + for( item = m_drawList.begin(); item; item = next_item ) { next_item = item->Next(); @@ -277,7 +274,7 @@ void SCH_SCREEN::ReplaceWires( DLIST< SCH_ITEM >& aWireList ) SCH_ITEM* item; SCH_ITEM* next_item; - for( item = m_drawList.begin(); item != NULL; item = next_item ) + for( item = m_drawList.begin(); item; item = next_item ) { next_item = item->Next(); @@ -300,10 +297,10 @@ void SCH_SCREEN::ReplaceWires( DLIST< SCH_ITEM >& aWireList ) void SCH_SCREEN::MarkConnections( SCH_LINE* aSegment ) { - wxCHECK_RET( (aSegment != NULL) && (aSegment->Type() == SCH_LINE_T), + wxCHECK_RET( (aSegment) && (aSegment->Type() == SCH_LINE_T), wxT( "Invalid object pointer." ) ); - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->GetFlags() & CANDIDATE ) continue; @@ -436,7 +433,7 @@ bool SCH_SCREEN::SchematicCleanUp( EDA_DRAW_PANEL* aCanvas, wxDC* aDC ) item = m_drawList.begin(); - for( ; item != NULL; item = item->Next() ) + for( ; item; item = item->Next() ) { if( ( item->Type() != SCH_LINE_T ) && ( item->Type() != SCH_JUNCTION_T ) ) continue; @@ -500,7 +497,7 @@ bool SCH_SCREEN::Save( FILE* aFile ) const SCHEMATIC_HEAD_STRING, EESCHEMA_VERSION ) < 0 ) return false; - BOOST_FOREACH( const CMP_LIBRARY& lib, CMP_LIBRARY::GetLibraryList() ) + BOOST_FOREACH( const PART_LIB& lib, *Prj().SchLibs() ) { if( fprintf( aFile, "LIBS:%s\n", TO_UTF8( lib.GetName() ) ) < 0 ) return false; @@ -549,13 +546,33 @@ bool SCH_SCREEN::Save( FILE* aFile ) const return true; } -/* note: SCH_SCREEN::Draw is useful only for schematic. - * library editor and library viewer do not use a draw list, and therefore - * SCH_SCREEN::Draw draws nothing - */ + void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, GR_DRAWMODE aDrawMode, EDA_COLOR_T aColor ) { - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + /* note: SCH_SCREEN::Draw is useful only for schematic. + * library editor and library viewer do not use m_drawList, and therefore + * their SCH_SCREEN::Draw() draws nothing + */ + + if( m_drawList.GetCount() ) + { + PART_LIBS* libs = Prj().SchLibs(); + int mod_hash = libs->GetModifyHash(); + + // Must we resolve? + if( m_modification_sync != mod_hash ) + { + SCH_TYPE_COLLECTOR c; + + c.Collect( GetDrawItems(), SCH_COLLECTOR::ComponentsOnly ); + + SCH_COMPONENT::ResolveAll( c, libs ); + + m_modification_sync = mod_hash; // note the last mod_hash + } + } + + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->IsMoving() || item->IsResized() ) continue; @@ -609,7 +626,7 @@ void SCH_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER& aList, int aItemCount void SCH_SCREEN::ClearDrawingState() { - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) item->ClearFlags(); } @@ -617,11 +634,11 @@ void SCH_SCREEN::ClearDrawingState() LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponent, bool aEndPointOnly ) const { - SCH_ITEM* item; - SCH_COMPONENT* component = NULL; - LIB_PIN* pin = NULL; + SCH_ITEM* item; + SCH_COMPONENT* component = NULL; + LIB_PIN* pin = NULL; - for( item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() != SCH_COMPONENT_T ) continue; @@ -631,12 +648,13 @@ LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponen if( aEndPointOnly ) { pin = NULL; - LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( component->GetLibName() ); - if( entry == NULL ) + LIB_PART* part = Prj().SchLibs()->FindLibPart( component->GetPartName() ); + + if( !part ) continue; - for( pin = entry->GetNextPin(); pin != NULL; pin = entry->GetNextPin( pin ) ) + for( pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) ) { // Skip items not used for this part. if( component->GetUnit() && pin->GetUnit() && @@ -671,7 +689,7 @@ LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponen SCH_SHEET* SCH_SCREEN::GetSheet( const wxString& aName ) { - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() != SCH_SHEET_T ) continue; @@ -690,7 +708,7 @@ SCH_SHEET_PIN* SCH_SCREEN::GetSheetLabel( const wxPoint& aPosition ) { SCH_SHEET_PIN* sheetPin = NULL; - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() != SCH_SHEET_T ) continue; @@ -711,7 +729,7 @@ int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) SCH_ITEM* item; int count = 0; - for( item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() == SCH_JUNCTION_T && !aTestJunctions ) continue; @@ -726,7 +744,7 @@ int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) { - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() == SCH_COMPONENT_T ) { @@ -826,7 +844,7 @@ void SCH_SCREEN::addConnectedItemsToBlock( const wxPoint& position ) ITEM_PICKER picker; bool addinlist = true; - for( item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item; item = item->Next() ) { picker.SetItem( item ); @@ -874,7 +892,7 @@ int SCH_SCREEN::UpdatePickList() area.SetSize( m_BlockLocate.GetSize() ); area.Normalize(); - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { // An item is picked if its bounding box intersects the reference area. if( item->HitTest( area ) ) @@ -906,12 +924,12 @@ bool SCH_SCREEN::TestDanglingEnds( EDA_DRAW_PANEL* aCanvas, wxDC* aDC ) std::vector< DANGLING_END_ITEM > endPoints; bool hasDanglingEnds = false; - for( item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item; item = item->Next() ) item->GetEndPoints( endPoints ); for( item = m_drawList.begin(); item; item = item->Next() ) { - if( item->IsDanglingStateChanged( endPoints ) && ( aCanvas != NULL ) && ( aDC != NULL ) ) + if( item->IsDanglingStateChanged( endPoints ) && ( aCanvas ) && ( aDC ) ) { item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), g_XorMode ); item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); @@ -931,7 +949,7 @@ bool SCH_SCREEN::BreakSegment( const wxPoint& aPoint ) SCH_LINE* newSegment; bool brokenSegments = false; - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( (item->Type() != SCH_LINE_T) || (item->GetLayer() == LAYER_NOTES) ) continue; @@ -958,7 +976,7 @@ bool SCH_SCREEN::BreakSegmentsOnJunctions() { bool brokenSegments = false; - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() == SCH_JUNCTION_T ) { @@ -985,7 +1003,7 @@ bool SCH_SCREEN::BreakSegmentsOnJunctions() int SCH_SCREEN::GetNode( const wxPoint& aPosition, EDA_ITEMS& aList ) { - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() == SCH_LINE_T && item->HitTest( aPosition ) && (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) ) @@ -1004,7 +1022,7 @@ int SCH_SCREEN::GetNode( const wxPoint& aPosition, EDA_ITEMS& aList ) SCH_LINE* SCH_SCREEN::GetWireOrBus( const wxPoint& aPosition ) { - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( (item->Type() == SCH_LINE_T) && item->HitTest( aPosition ) && (item->GetLayer() == LAYER_BUS || item->GetLayer() == LAYER_WIRE) ) @@ -1020,7 +1038,7 @@ SCH_LINE* SCH_SCREEN::GetWireOrBus( const wxPoint& aPosition ) SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLayer, SCH_LINE_TEST_T aSearchType ) { - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() != SCH_LINE_T ) continue; @@ -1053,7 +1071,7 @@ SCH_LINE* SCH_SCREEN::GetLine( const wxPoint& aPosition, int aAccuracy, int aLay SCH_TEXT* SCH_SCREEN::GetLabel( const wxPoint& aPosition, int aAccuracy ) { - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { switch( item->Type() ) { @@ -1078,7 +1096,7 @@ bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxStri SCH_COMPONENT* component; bool found = false; - for( SCH_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { if( item->Type() != SCH_COMPONENT_T ) continue; @@ -1147,7 +1165,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis { SCH_LINE* segment; - for( item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item; item = item->Next() ) { if( !(item->GetFlags() & SELECTEDNODE) ) continue; @@ -1159,7 +1177,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis } // Search all attached wires (i.e wire with one new dangling end ) - for( item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item; item = item->Next() ) { bool noconnect = false; @@ -1178,7 +1196,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis /* If the wire start point is connected to a wire that was already found * and now is not connected, add the wire to the list. */ - for( tmp = m_drawList.begin(); tmp != NULL; tmp = tmp->Next() ) + for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() ) { // Ensure tmp is a previously deleted segment: if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 ) @@ -1202,7 +1220,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis /* If the wire end point is connected to a wire that has already been found * and now is not connected, add the wire to the list. */ - for( tmp = m_drawList.begin(); tmp != NULL; tmp = tmp->Next() ) + for( tmp = m_drawList.begin(); tmp; tmp = tmp->Next() ) { // Ensure tmp is a previously deleted segment: if( ( tmp->GetFlags() & STRUCT_DELETED ) == 0 ) @@ -1239,7 +1257,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis // Get redundant junctions (junctions which connect < 3 end wires // and no pin) - for( item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item; item = item->Next() ) { if( item->GetFlags() & STRUCT_DELETED ) continue; @@ -1261,7 +1279,7 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis } } - for( item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( item = m_drawList.begin(); item; item = item->Next() ) { if( item->GetFlags() & STRUCT_DELETED ) continue; @@ -1462,9 +1480,9 @@ void SCH_SCREENS::DeleteAllMarkers( int aMarkerType ) SCH_MARKER* marker; SCH_SCREEN* screen; - for( screen = GetFirst(); screen != NULL; screen = GetNext() ) + for( screen = GetFirst(); screen; screen = GetNext() ) { - for( item = screen->GetDrawItems(); item != NULL; item = nextItem ) + for( item = screen->GetDrawItems(); item; item = nextItem ) { nextItem = item->Next(); @@ -1490,9 +1508,9 @@ int SCH_SCREENS::GetMarkerCount( int aMarkerType ) SCH_SCREEN* screen; int count = 0; - for( screen = GetFirst(); screen != NULL; screen = GetNext() ) + for( screen = GetFirst(); screen; screen = GetNext() ) { - for( item = screen->GetDrawItems(); item != NULL; item = nextItem ) + for( item = screen->GetDrawItems(); item; item = nextItem ) { nextItem = item->Next(); @@ -1517,7 +1535,7 @@ void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const // for now, make it look like XML, expand on this later. NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << ">\n"; - for( EDA_ITEM* item = m_drawList.begin(); item != NULL; item = item->Next() ) + for( EDA_ITEM* item = m_drawList.begin(); item; item = item->Next() ) { item->Show( nestLevel+1, os ); } diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index 4d51daa852..67782fad23 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -768,7 +768,8 @@ bool SCH_SHEET::Load( SCH_EDIT_FRAME* aFrame ) } else { - SetScreen( new SCH_SCREEN() ); + SetScreen( new SCH_SCREEN( &aFrame->Kiway() ) ); + success = aFrame->LoadOneEEFile( m_screen, m_fileName ); if( success ) @@ -777,7 +778,7 @@ bool SCH_SHEET::Load( SCH_EDIT_FRAME* aFrame ) while( bs ) { - if( bs->Type() == SCH_SHEET_T ) + if( bs->Type() == SCH_SHEET_T ) { SCH_SHEET* sheetstruct = (SCH_SHEET*) bs; diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index 230ea77fe3..6f8f41ad2b 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -156,7 +156,7 @@ SCH_ITEM* SCH_SHEET_PATH::FirstDrawList() const */ SCH_ITEM* lastItem = NULL; - while( item != NULL ) + while( item ) { lastItem = item; item = item->Next(); @@ -242,22 +242,22 @@ void SCH_SHEET_PATH::UpdateAllScreenReferences() } -void SCH_SHEET_PATH::AnnotatePowerSymbols( int* aReference ) +void SCH_SHEET_PATH::AnnotatePowerSymbols( PART_LIBS* aLibs, int* aReference ) { int ref = 1; - if( aReference != NULL ) + if( aReference ) ref = *aReference; - for( EDA_ITEM* item = LastDrawList(); item != NULL; item = item->Next() ) + for( EDA_ITEM* item = LastDrawList(); item; item = item->Next() ) { if( item->Type() != SCH_COMPONENT_T ) continue; - SCH_COMPONENT* component = (SCH_COMPONENT*) item; - LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( component->GetLibName() ); + SCH_COMPONENT* component = (SCH_COMPONENT*) item; + LIB_PART* part = aLibs->FindLibPart( component->GetPartName() ); - if( ( entry == NULL ) || !entry->IsPower() ) + if( !part || !part->IsPower() ) continue; wxString refstr = component->GetPrefix(); @@ -274,25 +274,25 @@ void SCH_SHEET_PATH::AnnotatePowerSymbols( int* aReference ) ref++; } - if( aReference != NULL ) + if( aReference ) *aReference = ref; } -void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols ) +void SCH_SHEET_PATH::GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols ) { // Search to sheet path number: int sheetnumber = 1; // 1 = root + SCH_SHEET_LIST sheetList; - for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path != NULL; - path = sheetList.GetNext(), sheetnumber++ ) + for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext(), sheetnumber++ ) { - if( Cmp(*path) == 0 ) + if( Cmp( *path ) == 0 ) break; } - for( SCH_ITEM* item = LastDrawList(); item != NULL; item = item->Next() ) + for( SCH_ITEM* item = LastDrawList(); item; item = item->Next() ) { if( item->Type() == SCH_COMPONENT_T ) { @@ -303,14 +303,12 @@ void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aInclu if( !aIncludePowerSymbols && component->GetRef( this )[0] == wxT( '#' ) ) continue; - LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( component->GetLibName() ); - - if( entry == NULL ) - continue; - - SCH_REFERENCE reference = SCH_REFERENCE( component, entry, *this ); - reference.SetSheetNumber( sheetnumber ); - aReferences.AddItem( reference ); + if( LIB_PART* part = aLibs->FindLibPart( component->GetPartName() ) ) + { + SCH_REFERENCE reference = SCH_REFERENCE( component, part, *this ); + reference.SetSheetNumber( sheetnumber ); + aReferences.AddItem( reference ); + } } } } @@ -322,11 +320,11 @@ SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool bool firstItemFound = false; SCH_ITEM* drawItem = LastDrawList(); - while( drawItem != NULL ) + while( drawItem ) { if( drawItem->Type() == aType ) { - if( aLastItem == NULL || firstItemFound ) + if( !aLastItem || firstItemFound ) { return drawItem; } @@ -338,7 +336,7 @@ SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool drawItem = drawItem->Next(); - if( drawItem == NULL && aLastItem && aWrap && !hasWrapped ) + if( !drawItem && aLastItem && aWrap && !hasWrapped ) { hasWrapped = true; drawItem = LastDrawList(); @@ -355,7 +353,7 @@ SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, bool firstItemFound = false; SCH_ITEM* drawItem = FirstDrawList(); - while( drawItem != NULL ) + while( drawItem ) { if( drawItem->Type() == aType ) { @@ -503,7 +501,7 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheet( const wxString aPath, bool aHumanReada SCH_SHEET_PATH* sheet = GetFirst(); wxString sheetPath; - while( sheet != NULL ) + while( sheet ) { sheetPath = ( aHumanReadable ) ? sheet->PathHumanReadable() : sheet->Path(); @@ -525,6 +523,7 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet ) if( m_List == NULL ) { int count = aSheet->CountSheets(); + m_count = count; m_index = 0; m_List = new SCH_SHEET_PATH[ count ]; @@ -535,7 +534,7 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet ) m_List[m_index] = m_currList; m_index++; - if( aSheet->GetScreen() != NULL ) + if( aSheet->GetScreen() ) { EDA_ITEM* strct = m_currList.LastDrawList(); @@ -557,7 +556,7 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet ) bool SCH_SHEET_LIST::IsModified() { - for( SCH_SHEET_PATH* sheet = GetFirst(); sheet != NULL; sheet = GetNext() ) + for( SCH_SHEET_PATH* sheet = GetFirst(); sheet; sheet = GetNext() ) { if( sheet->LastScreen() && sheet->LastScreen()->IsModify() ) return true; @@ -569,7 +568,7 @@ bool SCH_SHEET_LIST::IsModified() bool SCH_SHEET_LIST::IsAutoSaveRequired() { - for( SCH_SHEET_PATH* sheet = GetFirst(); sheet != NULL; sheet = GetNext() ) + for( SCH_SHEET_PATH* sheet = GetFirst(); sheet; sheet = GetNext() ) { if( sheet->LastScreen() && sheet->LastScreen()->IsSave() ) return true; @@ -581,7 +580,7 @@ bool SCH_SHEET_LIST::IsAutoSaveRequired() void SCH_SHEET_LIST::ClearModifyStatus() { - for( SCH_SHEET_PATH* sheet = GetFirst(); sheet != NULL; sheet = GetNext() ) + for( SCH_SHEET_PATH* sheet = GetFirst(); sheet; sheet = GetNext() ) { if( sheet->LastScreen() ) sheet->LastScreen()->ClrModify(); @@ -589,20 +588,20 @@ void SCH_SHEET_LIST::ClearModifyStatus() } -void SCH_SHEET_LIST::AnnotatePowerSymbols() +void SCH_SHEET_LIST::AnnotatePowerSymbols( PART_LIBS* aLibs ) { int ref = 1; - for( SCH_SHEET_PATH* path = GetFirst(); path != NULL; path = GetNext() ) - path->AnnotatePowerSymbols( &ref ); + for( SCH_SHEET_PATH* path = GetFirst(); path; path = GetNext() ) + path->AnnotatePowerSymbols( aLibs, &ref ); } -void SCH_SHEET_LIST::GetComponents( SCH_REFERENCE_LIST& aReferences, - bool aIncludePowerSymbols ) +void SCH_SHEET_LIST::GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, + bool aIncludePowerSymbols ) { - for( SCH_SHEET_PATH* path = GetFirst(); path != NULL; path = GetNext() ) - path->GetComponents( aReferences, aIncludePowerSymbols ); + for( SCH_SHEET_PATH* path = GetFirst(); path; path = GetNext() ) + path->GetComponents( aLibs, aReferences, aIncludePowerSymbols ); } @@ -611,14 +610,15 @@ SCH_ITEM* SCH_SHEET_LIST::FindNextItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFo { bool hasWrapped = false; bool firstItemFound = false; - SCH_ITEM* drawItem = NULL; + + SCH_ITEM* drawItem = NULL; SCH_SHEET_PATH* sheet = GetFirst(); - while( sheet != NULL ) + while( sheet ) { drawItem = sheet->LastDrawList(); - while( drawItem != NULL ) + while( drawItem ) { if( drawItem->Type() == aType ) { @@ -659,11 +659,11 @@ SCH_ITEM* SCH_SHEET_LIST::FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aShe SCH_ITEM* drawItem = NULL; SCH_SHEET_PATH* sheet = GetLast(); - while( sheet != NULL ) + while( sheet ) { drawItem = sheet->FirstDrawList(); - while( drawItem != NULL ) + while( drawItem ) { if( drawItem->Type() == aType ) { @@ -701,7 +701,7 @@ bool SCH_SHEET_LIST::SetComponentFootprint( const wxString& aReference, { bool found = false; - for( SCH_SHEET_PATH* path = GetFirst(); path != NULL; path = GetNext() ) + for( SCH_SHEET_PATH* path = GetFirst(); path; path = GetNext() ) found = path->SetComponentFootprint( aReference, aFootPrint, aSetVisible ); return found; diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index f6a32fbeb9..88a73a3875 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -83,6 +83,7 @@ class SCH_MARKER; class SCH_SHEET; class SCH_ITEM; class SCH_REFERENCE_LIST; +class PART_LIBS; /** @@ -215,7 +216,7 @@ public: * the annotation starts at 1. The number is incremented for * each power symbol annotated. */ - void AnnotatePowerSymbols( int* aReference ); + void AnnotatePowerSymbols( PART_LIBS* aLibs, int* aReference ); /** * Function GetComponents @@ -223,7 +224,7 @@ public: * @param aReferences List of references to populate. * @param aIncludePowerSymbols Set to false to only get normal components. */ - void GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true ); + void GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true ); /** * Function SetFootprintField @@ -391,7 +392,7 @@ public: * Function AnnotatePowerSymbols * clear and annotates the entire hierarchy of the sheet path list. */ - void AnnotatePowerSymbols(); + void AnnotatePowerSymbols( PART_LIBS* aLib ); /** * Function GetComponents @@ -400,7 +401,7 @@ public: * @param aReferences List of references to populate. * @param aIncludePowerSymbols Set to false to only get normal components. */ - void GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true ); + void GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true ); /** * Function FindNextItem diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp index a4dec01a55..b48ea7e87a 100644 --- a/eeschema/schedit.cpp +++ b/eeschema/schedit.cpp @@ -192,32 +192,32 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_POPUP_SCH_BREAK_WIRE: - { - DLIST< SCH_ITEM > oldWires; - - oldWires.SetOwnership( false ); // Prevent DLIST for deleting items in destructor. - m_canvas->MoveCursorToCrossHair(); - screen->ExtractWires( oldWires, true ); - screen->BreakSegment( GetCrossHairPosition() ); - - if( oldWires.GetCount() != 0 ) { - PICKED_ITEMS_LIST oldItems; + DLIST< SCH_ITEM > oldWires; - oldItems.m_Status = UR_WIRE_IMAGE; + oldWires.SetOwnership( false ); // Prevent DLIST for deleting items in destructor. + m_canvas->MoveCursorToCrossHair(); + screen->ExtractWires( oldWires, true ); + screen->BreakSegment( GetCrossHairPosition() ); - while( oldWires.GetCount() != 0 ) + if( oldWires.GetCount() != 0 ) { - ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE ); - oldItems.PushItem( picker ); + PICKED_ITEMS_LIST oldItems; + + oldItems.m_Status = UR_WIRE_IMAGE; + + while( oldWires.GetCount() != 0 ) + { + ITEM_PICKER picker = ITEM_PICKER( oldWires.PopFront(), UR_WIRE_IMAGE ); + oldItems.PushItem( picker ); + } + + SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE ); } - SaveCopyInUndoList( oldItems, UR_WIRE_IMAGE ); + screen->TestDanglingEnds( m_canvas, &dc ); } - - screen->TestDanglingEnds( m_canvas, &dc ); - } - break; + break; case ID_POPUP_SCH_DELETE_CMP: case ID_POPUP_SCH_DELETE: @@ -290,14 +290,16 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) // Ensure the struct is a component (could be a piece of a component, like Field, text..) if( item && item->Type() == SCH_COMPONENT_T ) { - LIB_ALIAS* LibEntry; - LibEntry = CMP_LIBRARY::FindLibraryEntry( ( (SCH_COMPONENT*) item )->GetLibName() ); - - if( LibEntry && LibEntry->GetDocFileName() != wxEmptyString ) + if( PART_LIBS* libs = Prj().SchLibs() ) { - SEARCH_STACK* lib_search = &Prj().SchSearchS(); + LIB_ALIAS* entry = libs->FindLibraryEntry( ( (SCH_COMPONENT*) item )->GetPartName() ); - GetAssociatedDocument( this, LibEntry->GetDocFileName(), lib_search ); + if( entry && !!entry->GetDocFileName() ) + { + SEARCH_STACK* lib_search = Prj().SchSearchS(); + + GetAssociatedDocument( this, entry->GetDocFileName(), lib_search ); + } } } break; diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index 8ad74ebe33..554ec27c13 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -60,6 +61,132 @@ #include +// non-member so it can be moved easily, and kept REALLY private. +// Do NOT Clear() in here. +static void add_search_paths( SEARCH_STACK* aDst, const SEARCH_STACK& aSrc, int aIndex ) +{ + for( unsigned i=0; iAddPaths( aSrc[i], aIndex ); +} + + +// non-member so it can be moved easily, and kept REALLY private. +// Do NOT Clear() in here. +static void add_search_paths( SEARCH_STACK* aDst, wxConfigBase* aCfg, int aIndex ) +{ + for( int i=1; true; ++i ) + { + wxString key = wxString::Format( wxT( "LibraryPath%d" ), i ); + wxString upath = aCfg->Read( key, wxEmptyString ); + + if( !upath ) + break; + + aDst->AddPaths( upath, aIndex ); + } +} + +//------------------------------------------------ + +SEARCH_STACK* PROJECT::SchSearchS() +{ + SEARCH_STACK* ss = (SEARCH_STACK*) GetElem( PROJECT::ELEM_SCH_SEARCH_STACK ); + + wxASSERT( !ss || dynamic_cast( GetElem( PROJECT::ELEM_SCH_SEARCH_STACK ) ) ); + + if( !ss ) + { + ss = new SEARCH_STACK(); + + // Make PROJECT the new SEARCH_STACK owner. + SetElem( PROJECT::ELEM_SCH_SEARCH_STACK, ss ); + + // to the empty SEARCH_STACK for SchSearchS(), add project dir as first + ss->AddPaths( m_project_name.GetPath() ); + + // next add the paths found in *.pro, variable "LibDir" + wxString libDir; + + try + { + PART_LIBS::LibNamesAndPaths( this, false, &libDir ); + } + catch( const IO_ERROR& ioe ) + { + DBG(printf( "%s: %s\n", __func__, TO_UTF8( ioe.errorText ) );) + } + + if( !!libDir ) + { + wxArrayString paths; + + SEARCH_STACK::Split( &paths, libDir ); + + for( unsigned i =0; iAddPaths( path ); // at the end + } + } + + // append all paths from aSList + add_search_paths( ss, Kiface().KifaceSearch(), -1 ); + + // addLibrarySearchPaths( SEARCH_STACK* aSP, wxConfigBase* aCfg ) + // This is undocumented, but somebody wanted to store !schematic! + // library search paths in the .kicad_common file? + add_search_paths( ss, Pgm().CommonSettings(), -1 ); + } + + return ss; +} + + +PART_LIBS* PROJECT::SchLibs() +{ + PART_LIBS* libs = (PART_LIBS*) GetElem( PROJECT::ELEM_SCH_PART_LIBS ); + + wxASSERT( !libs || dynamic_cast( libs ) ); + + if( !libs ) + { + libs = new PART_LIBS(); + + // Make PROJECT the new PART_LIBS owner. + SetElem( PROJECT::ELEM_SCH_PART_LIBS, libs ); + + try + { + libs->LoadAllLibraries( this ); + } + catch( const PARSE_ERROR& pe ) + { + wxString lib_list = UTF8( pe.inputLine ); + wxWindow* parent = 0; // Pgm().App().GetTopWindow(); + + // parent of this dialog cannot be NULL since that breaks the Kiway() chain. + HTML_MESSAGE_BOX dlg( parent, _( "Not Found" ) ); + + dlg.MessageSet( _( "The following libraries were not found:" ) ); + + dlg.ListSet( lib_list ); + + dlg.Layout(); + + dlg.ShowModal(); + } + catch( const IO_ERROR& ioe ) + { + DisplayError( NULL, ioe.errorText ); + } + } + + return libs; +} + +//----------------------------------------------- + BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_SOCKET( ID_EDA_SOCKET_EVENT_SERV, EDA_DRAW_FRAME::OnSockRequestServer ) @@ -96,14 +223,14 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_MENU( ID_COLORS_SETUP, SCH_EDIT_FRAME::OnColorConfig ) EVT_TOOL( wxID_PREFERENCES, SCH_EDIT_FRAME::OnSetOptions ) - EVT_TOOL( ID_TO_LIBRARY, SCH_EDIT_FRAME::OnOpenLibraryEditor ) + EVT_TOOL( ID_RUN_LIBRARY, SCH_EDIT_FRAME::OnOpenLibraryEditor ) EVT_TOOL( ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP, SCH_EDIT_FRAME::OnOpenLibraryEditor ) EVT_TOOL( ID_TO_LIBVIEW, SCH_EDIT_FRAME::OnOpenLibraryViewer ) - EVT_TOOL( ID_TO_PCB, SCH_EDIT_FRAME::OnOpenPcbnew ) - EVT_TOOL( ID_TO_PCB_MODULE_EDITOR, SCH_EDIT_FRAME::OnOpenPcbModuleEditor ) + EVT_TOOL( ID_RUN_PCB, SCH_EDIT_FRAME::OnOpenPcbnew ) + EVT_TOOL( ID_RUN_PCB_MODULE_EDITOR, SCH_EDIT_FRAME::OnOpenPcbModuleEditor ) - EVT_TOOL( ID_TO_CVPCB, SCH_EDIT_FRAME::OnOpenCvpcb ) + EVT_TOOL( ID_RUN_CVPCB, SCH_EDIT_FRAME::OnOpenCvpcb ) EVT_TOOL( ID_SHEET_SET, EDA_DRAW_FRAME::Process_PageSettings ) EVT_TOOL( ID_HIERARCHY, SCH_EDIT_FRAME::Process_Special_Functions ) @@ -183,7 +310,7 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ): m_FrameName = SCH_EDIT_FRAME_NAME; m_showAxis = false; // true to show axis m_showBorderAndTitleBlock = true; // true to show sheet references - m_CurrentSheet = new SCH_SHEET_PATH(); + m_CurrentSheet = new SCH_SHEET_PATH; m_DefaultSchematicFileName = NAMELESS_PROJECT; m_DefaultSchematicFileName += wxT( ".sch" ); m_showAllPins = false; @@ -270,6 +397,8 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ): // Now Drawpanel is sized, we can use BestZoom to show the component (if any) GetScreen()->SetZoom( BestZoom() ); + + Zoom_Automatique( true ); } @@ -278,18 +407,18 @@ SCH_EDIT_FRAME::~SCH_EDIT_FRAME() delete m_item_to_repeat; // we own the cloned object, see this->SetRepeatItem() SetScreen( NULL ); + delete m_CurrentSheet; // a SCH_SHEET_PATH, on the heap. delete m_undoItem; delete g_RootSheet; delete m_findReplaceData; + m_CurrentSheet = NULL; m_undoItem = NULL; g_RootSheet = NULL; m_findReplaceData = NULL; - CMP_LIBRARY::RemoveAllLibraries(); } - void SCH_EDIT_FRAME::SetRepeatItem( SCH_ITEM* aItem ) { // we cannot store a pointer to an item in the display list here since @@ -326,13 +455,13 @@ void SCH_EDIT_FRAME::SetSheetNumberAndCount() int sheet_count = g_RootSheet->CountSheets(); int SheetNumber = 1; wxString current_sheetpath = m_CurrentSheet->Path(); - SCH_SHEET_LIST SheetList; + SCH_SHEET_LIST sheetList; // Examine all sheets path to find the current sheets path, // and count them from root to the current sheet path: SCH_SHEET_PATH* sheet; - for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) + for( sheet = sheetList.GetFirst(); sheet != NULL; sheet = sheetList.GetNext() ) { wxString sheetpath = sheet->Path(); @@ -376,7 +505,7 @@ void SCH_EDIT_FRAME::CreateScreens() if( g_RootSheet->GetScreen() == NULL ) { - g_RootSheet->SetScreen( new SCH_SCREEN() ); + g_RootSheet->SetScreen( new SCH_SCREEN( &Kiway() ) ); SetScreen( g_RootSheet->GetScreen() ); } @@ -386,7 +515,7 @@ void SCH_EDIT_FRAME::CreateScreens() m_CurrentSheet->Push( g_RootSheet ); if( GetScreen() == NULL ) - SetScreen( new SCH_SCREEN() ); + SetScreen( new SCH_SCREEN( &Kiway() ) ); GetScreen()->SetZoom( 32.0 ); GetScreen()->m_UndoRedoCountMax = 10; @@ -458,13 +587,15 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) return; } - SCH_SHEET_LIST SheetList; + SCH_SHEET_LIST sheetList; - if( SheetList.IsModified() ) + if( sheetList.IsModified() ) { - wxString msg; - msg.Printf( _("Save the changes in\n<%s>\nbefore closing?"), - GetChars( g_RootSheet->GetScreen()->GetFileName() ) ); + wxString fileName = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); + wxString msg = wxString::Format( _( + "Save the changes in\n'%s'\nbefore closing?"), + GetChars( fileName ) + ); int ii = DisplayExitDialog( this, msg ); @@ -500,7 +631,7 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) { - fn = screen->GetFileName(); + fn = Prj().AbsolutePath( screen->GetFileName() ); // Auto save file name is the normal file name prepended with $. fn.SetName( wxT( "$" ) + fn.GetName() ); @@ -509,11 +640,15 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent ) wxRemoveFile( fn.GetFullPath() ); } - SheetList.ClearModifyStatus(); + sheetList.ClearModifyStatus(); - if( !g_RootSheet->GetScreen()->GetFileName().IsEmpty() - && (g_RootSheet->GetScreen()->GetDrawItems() != NULL) ) - UpdateFileHistory( g_RootSheet->GetScreen()->GetFileName() ); + wxString fileName = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); + + if( !g_RootSheet->GetScreen()->GetFileName().IsEmpty() && + g_RootSheet->GetScreen()->GetDrawItems() != NULL ) + { + UpdateFileHistory( fileName ); + } g_RootSheet->GetScreen()->Clear(); @@ -552,9 +687,8 @@ wxString SCH_EDIT_FRAME::GetUniqueFilenameForCurrentSheet() { wxFileName fn = GetScreen()->GetFileName(); - /* Name is - and has no extension. - * However if filename is too long name is - - */ + // Name is - and has no extension. + // However if filename is too long name is - #define FN_LEN_MAX 80 // A reasonable value for the short filename len @@ -738,22 +872,43 @@ void SCH_EDIT_FRAME::OnLoadCmpToFootprintLinkFile( wxCommandEvent& event ) void SCH_EDIT_FRAME::OnNewProject( wxCommandEvent& event ) { - wxFileDialog dlg( this, _( "New Schematic" ), wxGetCwd(), +// wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + wxString pro_dir = wxGetCwd(); + + wxFileDialog dlg( this, _( "New Schematic" ), pro_dir, wxEmptyString, SchematicFileWildcard, wxFD_SAVE ); if( dlg.ShowModal() != wxID_CANCEL ) { - OpenProjectFiles( std::vector( 1, dlg.GetPath() ), 1 ); + // Enforce the extension, wxFileDialog is inept. + wxFileName create_me = dlg.GetPath(); + create_me.SetExt( SchematicFileExtension ); + + if( create_me.FileExists() ) + { + wxString msg = wxString::Format( _( + "Schematic file '%s' already exists, use Open instead" ), + GetChars( create_me.GetFullName() ) + ); + DisplayError( this, msg ); + return ; + } + + // OpenProjectFiles() requires absolute + wxASSERT_MSG( create_me.IsAbsolute(), wxT( "wxFileDialog returned non-absolute" ) ); + + OpenProjectFiles( std::vector( 1, create_me.GetFullPath() ), KICTL_CREATE ); } } void SCH_EDIT_FRAME::OnLoadProject( wxCommandEvent& event ) { - // LoadOneEEProject( wxEmptyString, false ); +// wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + wxString pro_dir = wxGetCwd(); - wxFileDialog dlg( this, _( "Open Schematic" ), wxGetCwd(), + wxFileDialog dlg( this, _( "Open Schematic" ), pro_dir, wxEmptyString, SchematicFileWildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST ); @@ -766,7 +921,7 @@ void SCH_EDIT_FRAME::OnLoadProject( wxCommandEvent& event ) void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event ) { - wxFileName fn = g_RootSheet->GetScreen()->GetFileName(); + wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); if( fn.IsOk() ) { @@ -801,7 +956,7 @@ void SCH_EDIT_FRAME::OnOpenPcbModuleEditor( wxCommandEvent& event ) { if( !Kiface().IsSingle() ) { - wxFileName fn = g_RootSheet->GetScreen()->GetFileName(); + wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); if( fn.IsOk() ) { @@ -815,32 +970,25 @@ void SCH_EDIT_FRAME::OnOpenPcbModuleEditor( wxCommandEvent& event ) void SCH_EDIT_FRAME::OnOpenCvpcb( wxCommandEvent& event ) { - wxFileName fn = g_RootSheet->GetScreen()->GetFileName(); + wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); fn.SetExt( NetlistFileExtension ); - if( fn.IsOk() && fn.FileExists() ) + if( Kiface().IsSingle() ) { - if( Kiface().IsSingle() ) - { - ExecuteFile( this, CVPCB_EXE, QuoteFullPath( fn ) ); - } - else - { - KIWAY_PLAYER* player = Kiway().Player( FRAME_CVPCB, false ); // test open already. - - if( !player ) - { - player = Kiway().Player( FRAME_CVPCB, true ); - player->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); - player->Show( true ); - } - player->Raise(); - } + ExecuteFile( this, CVPCB_EXE, QuoteFullPath( fn ) ); } else { - ExecuteFile( this, CVPCB_EXE ); + KIWAY_PLAYER* player = Kiway().Player( FRAME_CVPCB, false ); // test open already. + + if( !player ) + { + player = Kiway().Player( FRAME_CVPCB, true ); + player->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + player->Show( true ); + } + player->Raise(); } } @@ -863,46 +1011,28 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) } LIB_EDIT_FRAME* libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false ); + if( !libeditFrame ) { libeditFrame = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, true ); libeditFrame->Show( true ); } - else - { - // if( libeditFrame->IsIconized() ) - // libeditFrame->Iconize( false ); - } libeditFrame->Raise(); -#if 0 - if( libeditFrame ) - { - if( libeditFrame->IsIconized() ) - libeditFrame->Iconize( false ); - - libeditFrame->Raise(); - } - else - { - KIFACE_I& kf = Kiface(); - - wxWindow* w = kf.CreateWindow( this, FRAME_SCH_LIB_EDITOR, &Kiway(), kf.StartFlags() ); - libeditFrame = dynamic_cast( w ); - } -#endif - - if( component ) { - LIB_ALIAS* entry = CMP_LIBRARY::FindLibraryEntry( component->GetLibName() ); + if( PART_LIBS* libs = Prj().SchLibs() ) + { + LIB_ALIAS* entry = libs->FindLibraryEntry( component->GetPartName() ); - if( entry == NULL ) // Should not occur - return; + if( !entry ) // Should not occur + return; - CMP_LIBRARY* library = entry->GetLibrary(); - libeditFrame->LoadComponentAndSelectLib( entry, library ); + PART_LIB* library = entry->GetLib(); + + libeditFrame->LoadComponentAndSelectLib( entry, library ); + } } } @@ -915,21 +1045,14 @@ void SCH_EDIT_FRAME::OnExit( wxCommandEvent& event ) void SCH_EDIT_FRAME::OnPrint( wxCommandEvent& event ) { - wxFileName fn; - InvokeDialogPrintUsingPrinter( this ); - fn = g_RootSheet->GetScreen()->GetFileName(); + wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); - wxString default_name = NAMELESS_PROJECT wxT( ".sch" ); - - if( fn.GetFullName() != default_name ) + if( fn.GetName() != NAMELESS_PROJECT ) { - fn.SetExt( ProjectFileExtension ); - // was: wxGetApp().WriteProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParametersList() ); - Prj().ConfigSave( Kiface().KifaceSearch(), - fn.GetFullPath(), GROUP_SCH, GetProjectFileParametersList() ); + Prj().ConfigSave( Kiface().KifaceSearch(), GROUP_SCH, GetProjectFileParametersList() ); } } @@ -937,9 +1060,10 @@ void SCH_EDIT_FRAME::OnPrint( wxCommandEvent& event ) void SCH_EDIT_FRAME::PrintPage( wxDC* aDC, LSET aPrintMask, bool aPrintMirrorMode, void* aData ) { + wxString fileName = Prj().AbsolutePath( GetScreen()->GetFileName() ); + GetScreen()->Draw( m_canvas, aDC, GR_DEFAULT_DRAWMODE ); - DrawWorkSheet( aDC, GetScreen(), GetDefaultLineThickness(), IU_PER_MILS, - GetScreen()->GetFileName() ); + DrawWorkSheet( aDC, GetScreen(), GetDefaultLineThickness(), IU_PER_MILS, fileName ); } @@ -960,9 +1084,9 @@ void SCH_EDIT_FRAME::OnSelectItem( wxCommandEvent& aEvent ) bool SCH_EDIT_FRAME::isAutoSaveRequired() const { - SCH_SHEET_LIST SheetList; + SCH_SHEET_LIST sheetList; - return SheetList.IsAutoSaveRequired(); + return sheetList.IsAutoSaveRequired(); } @@ -1078,12 +1202,9 @@ void SCH_EDIT_FRAME::UpdateTitle() } else { - wxFileName fn( GetScreen()->GetFileName() ); + wxString fileName = Prj().AbsolutePath( GetScreen()->GetFileName() ); + wxFileName fn = fileName; - // Often the /path/to/filedir is blank because of the FullFileName argument - // passed to LoadOneEEFile() which omits the path on non-root schematics. - // Making the path absolute solves this problem. - fn.MakeAbsolute(); title.Printf( wxT( "[ %s %s] (%s)" ), GetChars( fn.GetName() ), GetChars( m_CurrentSheet->PathHumanReadable() ), @@ -1092,11 +1213,10 @@ void SCH_EDIT_FRAME::UpdateTitle() if( fn.FileExists() ) { if( !fn.IsFileWritable() ) - title << _( " [Read Only]" ); + title += _( " [Read Only]" ); } else - title << _( " [no file]" ); - + title += _( " [no file]" ); } SetTitle( title ); diff --git a/eeschema/selpart.cpp b/eeschema/selpart.cpp index 22fa518c9b..c2b266eb23 100644 --- a/eeschema/selpart.cpp +++ b/eeschema/selpart.cpp @@ -13,54 +13,65 @@ #include -CMP_LIBRARY* SelectLibraryFromList( EDA_DRAW_FRAME* frame ) +PART_LIB* SelectLibraryFromList( EDA_DRAW_FRAME* aFrame ) { - static wxString OldLibName; - wxArrayString libNamesList; - CMP_LIBRARY* Lib = NULL; + PROJECT& prj = aFrame->Prj(); - int count = CMP_LIBRARY::GetLibraryCount(); - if( count == 0 ) + if( PART_LIBS* libs = prj.SchLibs() ) { - DisplayError( frame, _( "No component libraries are loaded." ) ); - return NULL; + if( !libs->GetLibraryCount() ) + { + DisplayError( aFrame, _( "No component libraries are loaded." ) ); + return NULL; + } + + wxArrayString headers; + + headers.Add( wxT( "Library" ) ); + + wxArrayString libNamesList = libs->GetLibraryNames(); + + std::vector itemsToDisplay; + + // Conversion from wxArrayString to vector of ArrayString + for( unsigned i = 0; i < libNamesList.GetCount(); i++ ) + { + wxArrayString item; + + item.Add( libNamesList[i] ); + + itemsToDisplay.push_back( item ); + } + + wxString old_lib_name = prj.GetRString( PROJECT::SCH_LIB_SELECT ); + + EDA_LIST_DIALOG dlg( aFrame, _( "Select Library" ), headers, itemsToDisplay, old_lib_name ); + + if( dlg.ShowModal() != wxID_OK ) + return NULL; + + wxString libname = dlg.GetTextSelection(); + + if( !libname ) + return NULL; + + PART_LIB* lib = libs->FindLibrary( libname ); + + if( lib ) + prj.SetRString( PROJECT::SCH_LIB_SELECT, libname ); + + return lib; } - wxArrayString headers; - headers.Add( wxT("Library") ); - - libNamesList = CMP_LIBRARY::GetLibraryNames(); - std::vector itemsToDisplay; - - // Conversion from wxArrayString to vector of ArrayString - for( unsigned i = 0; i < libNamesList.GetCount(); i++ ) - { - wxArrayString item; - item.Add( libNamesList[i] ); - itemsToDisplay.push_back( item ); - } - EDA_LIST_DIALOG dlg( frame, _( "Select Library" ), headers, itemsToDisplay, OldLibName ); - - if( dlg.ShowModal() != wxID_OK ) - return NULL; - - wxString libname = dlg.GetTextSelection(); - - if( libname.IsEmpty() ) - return NULL; - - Lib = CMP_LIBRARY::FindLibrary( libname ); - - if( Lib != NULL ) - OldLibName = libname; - - return Lib; + return NULL; } -extern void DisplayCmpDocAndKeywords( wxString& Name ); + +void DisplayCmpDocAndKeywords( wxString& aName, void* aData ); + int DisplayComponentsNamesInLib( EDA_DRAW_FRAME* frame, - CMP_LIBRARY* Library, + PART_LIB* Library, wxString& Buffer, wxString& OldName ) { wxArrayString nameList; @@ -86,8 +97,9 @@ int DisplayComponentsNamesInLib( EDA_DRAW_FRAME* frame, item.Add( Library->GetLogicalName() ); itemsToDisplay.push_back( item ); } + EDA_LIST_DIALOG dlg( frame, _( "Select Component" ), headers, itemsToDisplay, - OldName, DisplayCmpDocAndKeywords ); + OldName, DisplayCmpDocAndKeywords, frame->Prj().SchLibs() ); if( dlg.ShowModal() != wxID_OK ) return 0; @@ -98,7 +110,7 @@ int DisplayComponentsNamesInLib( EDA_DRAW_FRAME* frame, } -int GetNameOfPartToLoad( EDA_DRAW_FRAME* frame, CMP_LIBRARY* Library, wxString& BufName ) +int GetNameOfPartToLoad( EDA_DRAW_FRAME* frame, PART_LIB* Library, wxString& BufName ) { int ii; static wxString OldCmpName; diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index 23e9ae5100..bbaa213e88 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -109,12 +109,12 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, wxDC* aDC ) { if( useScreen != NULL ) { - msg.Printf( _( "A file named <%s> already exists in the current schematic hierarchy." ), + msg.Printf( _( "A file named '%s' already exists in the current schematic hierarchy." ), GetChars( newFullFilename ) ); } else { - msg.Printf( _( "A file named <%s> already exists." ), + msg.Printf( _( "A file named '%s' already exists." ), GetChars( newFullFilename ) ); } @@ -125,7 +125,7 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, wxDC* aDC ) } else // New file. { - aSheet->SetScreen( new SCH_SCREEN() ); + aSheet->SetScreen( new SCH_SCREEN( &Kiway() ) ); aSheet->GetScreen()->SetFileName( newFullFilename ); } } diff --git a/eeschema/symbdraw.cpp b/eeschema/symbdraw.cpp index 79d80f3491..e2cdee0b26 100644 --- a/eeschema/symbdraw.cpp +++ b/eeschema/symbdraw.cpp @@ -55,15 +55,12 @@ static void RedrawWhileMovingCursor( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wx bool aErase ); -/* - * Show the dialog box for editing a graphical item properties - */ void LIB_EDIT_FRAME::EditGraphicSymbol( wxDC* DC, LIB_ITEM* DrawItem ) { if( DrawItem == NULL ) return; - LIB_COMPONENT* component = DrawItem->GetParent(); + LIB_PART* component = DrawItem->GetParent(); DIALOG_LIB_EDIT_DRAW_ITEM dialog( this, DrawItem->GetTypeName() ); @@ -72,7 +69,7 @@ void LIB_EDIT_FRAME::EditGraphicSymbol( wxDC* DC, LIB_ITEM* DrawItem ) wxString val = StringFromValue( g_UserUnit, DrawItem->GetWidth() ); dialog.SetWidth( val ); dialog.SetApplyToAllUnits( DrawItem->GetUnit() == 0 ); - dialog.EnableApplyToAllUnits( component && component->GetPartCount() > 1 ); + dialog.EnableApplyToAllUnits( component && component->GetUnitCount() > 1 ); dialog.SetApplyToAllConversions( DrawItem->GetConvert() == 0 ); dialog.EnableApplyToAllConversions( component && component->HasConversion() ); dialog.SetFillStyle( DrawItem->GetFillMode() ); @@ -150,7 +147,7 @@ static void AbortSymbolTraceOn( EDA_DRAW_PANEL* Panel, wxDC* DC ) } -LIB_ITEM* LIB_EDIT_FRAME::CreateGraphicItem( LIB_COMPONENT* LibEntry, wxDC* DC ) +LIB_ITEM* LIB_EDIT_FRAME::CreateGraphicItem( LIB_PART* LibEntry, wxDC* DC ) { m_canvas->SetMouseCapture( SymbolDisplayDraw, AbortSymbolTraceOn ); wxPoint drawPos = GetCrossHairPosition( true ); @@ -178,28 +175,29 @@ LIB_ITEM* LIB_EDIT_FRAME::CreateGraphicItem( LIB_COMPONENT* LibEntry, wxDC* DC ) break; case ID_LIBEDIT_BODY_TEXT_BUTT: - { - LIB_TEXT* Text = new LIB_TEXT( LibEntry ); - Text->SetSize( wxSize( m_textSize, m_textSize ) ); - Text->SetOrientation( m_textOrientation ); - - // Enter the graphic text info - m_canvas->SetIgnoreMouseEvents( true ); - EditSymbolText( NULL, Text ); - m_canvas->SetIgnoreMouseEvents( false ); - m_canvas->MoveCursorToCrossHair(); - - if( Text->GetText().IsEmpty() ) { - delete Text; - m_drawItem = NULL; - } - else - { - m_drawItem = Text; + LIB_TEXT* Text = new LIB_TEXT( LibEntry ); + Text->SetSize( wxSize( m_textSize, m_textSize ) ); + Text->SetOrientation( m_textOrientation ); + + // Enter the graphic text info + m_canvas->SetIgnoreMouseEvents( true ); + EditSymbolText( NULL, Text ); + m_canvas->SetIgnoreMouseEvents( false ); + m_canvas->MoveCursorToCrossHair(); + + if( Text->GetText().IsEmpty() ) + { + delete Text; + m_drawItem = NULL; + } + else + { + m_drawItem = Text; + } } break; - } + default: DisplayError( this, wxT( "LIB_EDIT_FRAME::CreateGraphicItem() error" ) ); return NULL; @@ -232,8 +230,6 @@ LIB_ITEM* LIB_EDIT_FRAME::CreateGraphicItem( LIB_COMPONENT* LibEntry, wxDC* DC ) } -/* Create new library component graphic object. - */ void LIB_EDIT_FRAME::GraphicItemBeginDraw( wxDC* DC ) { if( m_drawItem == NULL ) @@ -304,7 +300,6 @@ void LIB_EDIT_FRAME::StartMoveDrawSymbol( wxDC* DC ) } -// @brief Modify a graphic symbol (drag edges etc.) void LIB_EDIT_FRAME::StartModifyDrawSymbol( wxDC* DC ) { if( m_drawItem == NULL ) @@ -332,35 +327,37 @@ static void SymbolDisplayDraw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& } -/* - * Place the new graphic object in the list of component drawing objects, - * or terminate a draw item edition - */ void LIB_EDIT_FRAME::EndDrawGraphicItem( wxDC* DC ) { - if( m_component == NULL || m_drawItem == NULL ) - return; + if( LIB_PART* part = GetCurPart() ) + { + if( !m_drawItem ) + return; - if( GetToolId() != ID_NO_TOOL_SELECTED ) - SetCursor( wxCURSOR_PENCIL ); - else - SetCursor( (wxStockCursor) m_canvas->GetDefaultCursor() ); + if( GetToolId() != ID_NO_TOOL_SELECTED ) + SetCursor( wxCURSOR_PENCIL ); + else + SetCursor( (wxStockCursor) m_canvas->GetDefaultCursor() ); - if( GetTempCopyComponent() ) // used when editing an existing item - SaveCopyInUndoList( GetTempCopyComponent() ); - else // When creating a new item, there is still no change for the current component - // So save it. - SaveCopyInUndoList( m_component ); + if( GetTempCopyComponent() ) // used when editing an existing item + SaveCopyInUndoList( GetTempCopyComponent() ); + else + { + // When creating a new item, there is still no change for the + // current component. So save it. + SaveCopyInUndoList( part ); + } - if( m_drawItem->IsNew() ) - m_component->AddDrawItem( m_drawItem ); + if( m_drawItem->IsNew() ) + part->AddDrawItem( m_drawItem ); - m_drawItem->EndEdit( GetCrossHairPosition( true ) ); + m_drawItem->EndEdit( GetCrossHairPosition( true ) ); - m_drawItem = NULL; + m_drawItem = NULL; - OnModify(); + OnModify(); - m_canvas->SetMouseCapture( NULL, NULL ); - m_canvas->Refresh(); + m_canvas->SetMouseCapture( NULL, NULL ); + m_canvas->Refresh(); + } } diff --git a/eeschema/symbedit.cpp b/eeschema/symbedit.cpp index 8d6a744cdf..10536b33e0 100644 --- a/eeschema/symbedit.cpp +++ b/eeschema/symbedit.cpp @@ -47,22 +47,20 @@ void LIB_EDIT_FRAME::LoadOneSymbol() { - LIB_COMPONENT* Component; - wxString msg, err; - CMP_LIBRARY* Lib; + LIB_PART* part = GetCurPart(); - /* Exit if no library entry is selected or a command is in progress. */ - if( m_component == NULL || ( m_drawItem && m_drawItem->GetFlags() ) ) + // Exit if no library entry is selected or a command is in progress. + if( !part || ( m_drawItem && m_drawItem->GetFlags() ) ) return; PROJECT& prj = Prj(); - SEARCH_STACK& search = prj.SchSearchS(); + SEARCH_STACK* search = prj.SchSearchS(); m_canvas->SetIgnoreMouseEvents( true ); wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH ); if( !default_path ) - default_path = search.LastVisitedPath(); + default_path = search->LastVisitedPath(); wxFileDialog dlg( this, _( "Import Symbol Drawings" ), default_path, wxEmptyString, SchematicSymbolFileWildcard, @@ -75,38 +73,46 @@ void LIB_EDIT_FRAME::LoadOneSymbol() m_canvas->MoveCursorToCrossHair(); m_canvas->SetIgnoreMouseEvents( false ); - wxFileName fn = dlg.GetPath(); + wxString filename = dlg.GetPath(); - prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() ); + prj.SetRString( PROJECT::SCH_LIB_PATH, filename ); - Lib = new CMP_LIBRARY( LIBRARY_TYPE_SYMBOL, fn ); + std::auto_ptr lib( new PART_LIB( LIBRARY_TYPE_SYMBOL, filename ) ); - if( !Lib->Load( err ) ) + wxString err; + + if( !lib->Load( err ) ) { - msg.Printf( _( "Error '%s' occurred loading symbol library '%s'." ), - GetChars( err ), GetChars( fn.GetName() ) ); + wxString msg = wxString::Format( _( + "Error '%s' occurred loading part file '%s'." ), + GetChars( err ), + GetChars( filename ) + ); DisplayError( this, msg ); - delete Lib; return; } - if( Lib->IsEmpty() ) + if( lib->IsEmpty() ) { - msg.Printf( _( "No components found in symbol library '%s'." ), - GetChars( fn.GetName() ) ); - delete Lib; + wxString msg = wxString::Format( _( + "No parts found in part file '%s'." ), + GetChars( filename ) + ); + DisplayError( this, msg ); return; } - if( Lib->GetCount() > 1 ) + if( lib->GetCount() > 1 ) { - msg.Printf( _( "More than one part in symbol file '%s'." ), - GetChars( fn.GetName() ) ); + wxString msg = wxString::Format( _( + "More than one part in part file '%s'." ), + GetChars( filename ) + ); wxMessageBox( msg, _( "Warning" ), wxOK | wxICON_EXCLAMATION, this ); } - Component = Lib->GetFirstEntry()->GetComponent(); - LIB_ITEMS& drawList = Component->GetDrawItemList(); + LIB_PART* first = lib->GetFirstEntry()->GetPart(); + LIB_ITEMS& drawList = first->GetDrawItemList(); BOOST_FOREACH( LIB_ITEM& item, drawList ) { @@ -122,17 +128,16 @@ void LIB_EDIT_FRAME::LoadOneSymbol() item.SetFlags( IS_NEW | SELECTED ); LIB_ITEM* newItem = (LIB_ITEM*) item.Clone(); - newItem->SetParent( m_component ); - m_component->AddDrawItem( newItem ); + + newItem->SetParent( part ); + part->AddDrawItem( newItem ); } - m_component->RemoveDuplicateDrawItems(); - m_component->ClearSelectedItems(); + part->RemoveDuplicateDrawItems(); + part->ClearSelectedItems(); OnModify(); m_canvas->Refresh(); - - delete Lib; } @@ -140,17 +145,18 @@ void LIB_EDIT_FRAME::SaveOneSymbol() { wxString msg; PROJECT& prj = Prj(); - SEARCH_STACK& search = prj.SchSearchS(); + SEARCH_STACK* search = prj.SchSearchS(); + LIB_PART* part = GetCurPart(); - if( m_component->GetDrawItemList().empty() ) + if( !part || part->GetDrawItemList().empty() ) return; wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH ); if( !default_path ) - default_path = search.LastVisitedPath(); + default_path = search->LastVisitedPath(); wxFileDialog dlg( this, _( "Export Symbol Drawings" ), default_path, - m_component->GetName(), SchematicSymbolFileWildcard, + part->GetName(), SchematicSymbolFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); if( dlg.ShowModal() == wxID_CANCEL ) @@ -170,28 +176,28 @@ void LIB_EDIT_FRAME::SaveOneSymbol() wxString line; - /* File header */ + // File header line << wxT( LIBFILE_IDENT ) << wxT( " " ) << LIB_VERSION_MAJOR << wxT( "." ) << LIB_VERSION_MINOR << wxT( " SYMBOL " ) << wxT( "Date: " ) << DateAndTime() << wxT( "\n" ); - /* Component name comment and definition. */ - line << wxT( "# SYMBOL " ) << m_component->GetName() << wxT( "\n#\nDEF " ) - << m_component->GetName() << wxT( " " ); + // Component name comment and definition. + line << wxT( "# SYMBOL " ) << part->GetName() << wxT( "\n#\nDEF " ) + << part->GetName() << wxT( " " ); - if( !m_component->GetReferenceField().GetText().IsEmpty() ) - line << m_component->GetReferenceField().GetText() << wxT( " " ); + if( !part->GetReferenceField().GetText().IsEmpty() ) + line << part->GetReferenceField().GetText() << wxT( " " ); else line << wxT( "~ " ); - line << 0 << wxT( " " ) << m_component->GetPinNameOffset() << wxT( " " ); + line << 0 << wxT( " " ) << part->GetPinNameOffset() << wxT( " " ); - if( m_component->ShowPinNumbers() ) + if( part->ShowPinNumbers() ) line << wxT( "Y " ); else line << wxT( "N " ); - if( m_component->ShowPinNames() ) + if( part->ShowPinNames() ) line << wxT( "Y " ); else line << wxT( "N " ); @@ -205,18 +211,18 @@ void LIB_EDIT_FRAME::SaveOneSymbol() try { formatter.Print( 0, "%s", TO_UTF8( line ) ); - m_component->GetReferenceField().Save( formatter ); - m_component->GetValueField().Save( formatter ); + part->GetReferenceField().Save( formatter ); + part->GetValueField().Save( formatter ); formatter.Print( 0, "DRAW\n" ); - LIB_ITEMS& drawList = m_component->GetDrawItemList(); + LIB_ITEMS& drawList = part->GetDrawItemList(); BOOST_FOREACH( LIB_ITEM& item, drawList ) { if( item.Type() == LIB_FIELD_T ) continue; - /* Don't save unused parts or alternate body styles. */ + // Don't save unused parts or alternate body styles. if( m_unit && item.GetUnit() && ( item.GetUnit() != m_unit ) ) continue; @@ -246,18 +252,18 @@ void LIB_EDIT_FRAME::SaveOneSymbol() void LIB_EDIT_FRAME::PlaceAnchor() { - if( m_component == NULL ) - return; + if( LIB_PART* part = GetCurPart() ) + { + const wxPoint& cross_hair = GetCrossHairPosition(); - const wxPoint& cross_hair = GetCrossHairPosition(); + wxPoint offset( -cross_hair.x, cross_hair.y ); - wxPoint offset( -cross_hair.x, cross_hair.y ); + OnModify( ); - OnModify( ); + part->SetOffset( offset ); - m_component->SetOffset( offset ); - - /* Redraw the symbol */ - RedrawScreen( wxPoint( 0 , 0 ), true ); - m_canvas->Refresh(); + // Redraw the symbol + RedrawScreen( wxPoint( 0 , 0 ), true ); + m_canvas->Refresh(); + } } diff --git a/eeschema/template_fieldnames.h b/eeschema/template_fieldnames.h index 4b74c1ba35..369f3bb30e 100644 --- a/eeschema/template_fieldnames.h +++ b/eeschema/template_fieldnames.h @@ -13,7 +13,7 @@ class TEMPLATE_FIELDNAMES_LEXER; /** * Enum NumFieldType * is the set of all field indices assuming an array like sequence that a - * SCH_COMPONENT or LIB_COMPONENT can hold. + * SCH_COMPONENT or LIB_PART can hold. * The first fields are called fixed fields and the quantity of them is * given by MANDATORY_FIELDS. After that come an unlimited number of * user defined fields, only some of which have indices defined here. @@ -25,7 +25,7 @@ enum NumFieldType { DATASHEET, ///< name of datasheet /// The first 4 are mandatory, and must be instantiated in SCH_COMPONENT - /// and LIB_COMPONENT constructors + /// and LIB_PART constructors MANDATORY_FIELDS, FIELD1 = MANDATORY_FIELDS, diff --git a/eeschema/tool_sch.cpp b/eeschema/tool_sch.cpp index 962ef3847f..b11cd5b786 100644 --- a/eeschema/tool_sch.cpp +++ b/eeschema/tool_sch.cpp @@ -134,7 +134,7 @@ void SCH_EDIT_FRAME::ReCreateHToolbar() m_mainToolBar->AddSeparator(); - m_mainToolBar->AddTool( ID_TO_LIBRARY, wxEmptyString, KiBitmap( libedit_xpm ), + m_mainToolBar->AddTool( ID_RUN_LIBRARY, wxEmptyString, KiBitmap( libedit_xpm ), HELP_RUN_LIB_EDITOR ); m_mainToolBar->AddTool( ID_TO_LIBVIEW, wxEmptyString, KiBitmap( library_browse_xpm ), @@ -161,14 +161,14 @@ void SCH_EDIT_FRAME::ReCreateHToolbar() // the CVPCB. if( !Kiface().IsSingle() ) // if pcbnew is not a separate process { - m_mainToolBar->AddTool( ID_TO_PCB_MODULE_EDITOR, wxEmptyString, KiBitmap( module_editor_xpm ), + m_mainToolBar->AddTool( ID_RUN_PCB_MODULE_EDITOR, wxEmptyString, KiBitmap( module_editor_xpm ), _( "Footprint Editor" ) ); } - m_mainToolBar->AddTool( ID_TO_CVPCB, wxEmptyString, KiBitmap( cvpcb_xpm ), + m_mainToolBar->AddTool( ID_RUN_CVPCB, wxEmptyString, KiBitmap( cvpcb_xpm ), _( "Run CvPcb to associate components and footprints" ) ); - m_mainToolBar->AddTool( ID_TO_PCB, wxEmptyString, KiBitmap( pcbnew_xpm ), + m_mainToolBar->AddTool( ID_RUN_PCB, wxEmptyString, KiBitmap( pcbnew_xpm ), _( "Run Pcbnew to layout printed circuit board" ) ); m_mainToolBar->AddTool( ID_BACKANNO_ITEMS, wxEmptyString, diff --git a/eeschema/tool_viewlib.cpp b/eeschema/tool_viewlib.cpp index e1982ca1ca..7d53802184 100644 --- a/eeschema/tool_viewlib.cpp +++ b/eeschema/tool_viewlib.cpp @@ -41,12 +41,10 @@ void LIB_VIEW_FRAME::ReCreateHToolbar() { - int ii; - wxString msg; - CMP_LIBRARY* lib; - LIB_COMPONENT* component = NULL; - LIB_ALIAS* entry = NULL; - bool asdeMorgan = false; + wxString msg; + LIB_ALIAS* entry = NULL; + bool asdeMorgan = false; + LIB_PART* part = NULL; if( m_mainToolBar == NULL ) { @@ -131,13 +129,11 @@ void LIB_VIEW_FRAME::ReCreateHToolbar() if( m_libraryName.size() && m_entryName.size() ) { - lib = CMP_LIBRARY::FindLibrary( m_libraryName ); - - if( lib ) + if( PART_LIB* lib = Prj().SchLibs()->FindLibrary( m_libraryName ) ) { - component = lib->FindComponent( m_entryName ); + part = lib->FindPart( m_entryName ); - if( component && component->HasConversion() ) + if( part && part->HasConversion() ) asdeMorgan = true; entry = lib->FindEntry( m_entryName ); @@ -162,22 +158,21 @@ void LIB_VIEW_FRAME::ReCreateHToolbar() int parts_count = 1; - if( component ) - parts_count = std::max( component->GetPartCount(), 1 ); + if( part ) + parts_count = std::max( part->GetUnitCount(), 1 ); m_selpartBox->Clear(); - for( ii = 0; ii < parts_count; ii++ ) + for( int ii = 0; ii < parts_count; ii++ ) { wxString msg = wxString::Format( _( "Unit %c" ), 'A' + ii ); m_selpartBox->Append( msg ); } - m_selpartBox->SetSelection( (m_unit > 0 ) ? m_unit - 1 : 0 ); + m_selpartBox->SetSelection( m_unit > 0 ? m_unit - 1 : 0 ); m_selpartBox->Enable( parts_count > 1 ); - m_mainToolBar->EnableTool( ID_LIBVIEW_VIEWDOC, - entry && ( entry->GetDocFileName() != wxEmptyString ) ); + m_mainToolBar->EnableTool( ID_LIBVIEW_VIEWDOC, entry && !!entry->GetDocFileName() ); m_mainToolBar->Refresh(); } diff --git a/eeschema/viewlib_frame.cpp b/eeschema/viewlib_frame.cpp index 0cfbc55a17..0596d192f1 100644 --- a/eeschema/viewlib_frame.cpp +++ b/eeschema/viewlib_frame.cpp @@ -93,7 +93,7 @@ static wxAcceleratorEntry accels[] = #define LIB_VIEW_FRAME_NAME wxT( "ViewlibFrame" ) LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, - CMP_LIBRARY* aLibrary ) : + PART_LIB* aLibrary ) : SCH_BASE_FRAME( aKiway, aParent, aFrameType, _( "Library Browser" ), wxDefaultPosition, wxDefaultSize, aFrameType==FRAME_SCH_VIEWER ? @@ -121,7 +121,7 @@ LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame m_cmpList = NULL; m_libList = NULL; - SetScreen( new SCH_SCREEN() ); + SetScreen( new SCH_SCREEN( aKiway ) ); GetScreen()->m_Center = true; // Axis origin centered on screen. LoadSettings( config() ); @@ -284,14 +284,14 @@ double LIB_VIEW_FRAME::BestZoom() * and replace by static const int VIEWPORT_EXTENT = 10000; */ - LIB_COMPONENT* component = NULL; - double bestzoom = 16.0; // default value for bestzoom - CMP_LIBRARY* lib = CMP_LIBRARY::FindLibrary( m_libraryName ); + LIB_PART* part = NULL; + double bestzoom = 16.0; // default value for bestzoom + PART_LIB* lib = Prj().SchLibs()->FindLibrary( m_libraryName ); if( lib ) - component = lib->FindComponent( m_entryName ); + part = lib->FindPart( m_entryName ); - if( component == NULL ) + if( !part ) { SetScrollCenterPosition( wxPoint( 0, 0 ) ); return bestzoom; @@ -299,13 +299,13 @@ double LIB_VIEW_FRAME::BestZoom() wxSize size = m_canvas->GetClientSize(); - EDA_RECT BoundaryBox = component->GetBoundingBox( m_unit, m_convert ); + EDA_RECT boundingBox = part->GetBoundingBox( m_unit, m_convert ); // Reserve a 10% margin around component bounding box. double margin_scale_factor = 0.8; - double zx =(double) BoundaryBox.GetWidth() / + double zx =(double) boundingBox.GetWidth() / ( margin_scale_factor * (double)size.x ); - double zy = (double) BoundaryBox.GetHeight() / + double zy = (double) boundingBox.GetHeight() / ( margin_scale_factor * (double)size.y); // Calculates the best zoom @@ -316,7 +316,7 @@ double LIB_VIEW_FRAME::BestZoom() if( bestzoom < GetScreen()->m_ZoomList[0] ) bestzoom = GetScreen()->m_ZoomList[0]; - SetScrollCenterPosition( BoundaryBox.Centre() ); + SetScrollCenterPosition( boundingBox.Centre() ); return bestzoom; } @@ -324,11 +324,11 @@ double LIB_VIEW_FRAME::BestZoom() void LIB_VIEW_FRAME::ReCreateListLib() { - if( m_libList == NULL ) + if( !m_libList ) return; m_libList->Clear(); - m_libList->Append( CMP_LIBRARY::GetLibraryNames() ); + m_libList->Append( Prj().SchLibs()->GetLibraryNames() ); // Search for a previous selection: int index = m_libList->FindString( m_libraryName ); @@ -361,9 +361,9 @@ void LIB_VIEW_FRAME::ReCreateListCmp() m_cmpList->Clear(); - CMP_LIBRARY* Library = CMP_LIBRARY::FindLibrary( m_libraryName ); + PART_LIB* lib = Prj().SchLibs()->FindLibrary( m_libraryName ); - if( Library == NULL ) + if( !lib ) { m_libraryName = wxEmptyString; m_entryName = wxEmptyString; @@ -373,7 +373,8 @@ void LIB_VIEW_FRAME::ReCreateListCmp() } wxArrayString nameList; - Library->GetEntryNames( nameList ); + + lib->GetEntryNames( nameList ); m_cmpList->Append( nameList ); int index = m_cmpList->FindString( m_entryName ); diff --git a/eeschema/viewlib_frame.h b/eeschema/viewlib_frame.h index e87952a64e..29cbecce2d 100644 --- a/eeschema/viewlib_frame.h +++ b/eeschema/viewlib_frame.h @@ -37,7 +37,7 @@ #include class wxListBox; -class CMP_LIBRARY; +class PART_LIB; /** @@ -53,7 +53,7 @@ public: * FRAME_SCH_LIB_VIEWER_MODAL */ LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, - FRAME_T aFrameType, CMP_LIBRARY* aLibrary = NULL ); + FRAME_T aFrameType, PART_LIB* aLibrary = NULL ); ~LIB_VIEW_FRAME(); @@ -128,7 +128,7 @@ private: * exports the current component to schematic and close the library browser. */ void ExportToSchematicLibraryPart( wxCommandEvent& event ); - void ViewOneLibraryContent( CMP_LIBRARY* Lib, int Flag ); + void ViewOneLibraryContent( PART_LIB* Lib, int Flag ); bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ); void DClickOnCmpList( wxCommandEvent& event ); diff --git a/eeschema/viewlibs.cpp b/eeschema/viewlibs.cpp index 15e76c8941..63774d1d59 100644 --- a/eeschema/viewlibs.cpp +++ b/eeschema/viewlibs.cpp @@ -27,7 +27,7 @@ void LIB_VIEW_FRAME::Process_Special_Functions( wxCommandEvent& event ) { wxString msg; - LIB_ALIAS* LibEntry; + LIB_ALIAS* entry; int ii, id = event.GetId(); switch( id ) @@ -49,13 +49,13 @@ void LIB_VIEW_FRAME::Process_Special_Functions( wxCommandEvent& event ) break; case ID_LIBVIEW_VIEWDOC: - LibEntry = CMP_LIBRARY::FindLibraryEntry( m_entryName, m_libraryName ); + entry = Prj().SchLibs()->FindLibraryEntry( m_entryName, m_libraryName ); - if( LibEntry && ( !LibEntry->GetDocFileName().IsEmpty() ) ) + if( entry && !entry->GetDocFileName().IsEmpty() ) { - SEARCH_STACK& lib_search = Prj().SchSearchS(); + SEARCH_STACK* lib_search = Prj().SchSearchS(); - GetAssociatedDocument( this, LibEntry->GetDocFileName(), &lib_search ); + GetAssociatedDocument( this, entry->GetDocFileName(), lib_search ); } break; @@ -100,33 +100,33 @@ bool LIB_VIEW_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ) } -/* Displays the name of the current opened library in the caption */ void LIB_VIEW_FRAME::DisplayLibInfos() { - wxString msg; - CMP_LIBRARY* Lib; + PART_LIBS* libs = Prj().SchLibs(); - Lib = CMP_LIBRARY::FindLibrary( m_libraryName ); - msg = _( "Library Browser" ); + if( libs ) + { + PART_LIB* lib = libs->FindLibrary( m_libraryName ); - msg << wxT( " [" ); + wxString msg = _( "Library Browser" ); - if( Lib ) - msg << Lib->GetFullFileName(); - else - msg += _( "no library selected" ); + msg += wxT( " [" ); - msg << wxT( "]" ); - SetTitle( msg ); + if( lib ) + msg += lib->GetFullFileName(); + else + msg += _( "no library selected" ); + + msg += wxT( "]" ); + + SetTitle( msg ); + } } -/*****************************************/ -/* Function to Select Current library */ -/*****************************************/ void LIB_VIEW_FRAME::SelectCurrentLibrary() { - CMP_LIBRARY* Lib; + PART_LIB* Lib; Lib = SelectLibraryFromList( this ); @@ -151,49 +151,40 @@ void LIB_VIEW_FRAME::SelectCurrentLibrary() } -/* - * Routine to select and view library Part (NEW, NEXT or PREVIOUS) - */ void LIB_VIEW_FRAME::SelectAndViewLibraryPart( int option ) { - CMP_LIBRARY* Lib; - if( m_libraryName.IsEmpty() ) SelectCurrentLibrary(); if( m_libraryName.IsEmpty() ) return; - Lib = CMP_LIBRARY::FindLibrary( m_libraryName ); - - if( Lib == NULL ) - return; - - if( ( m_entryName.IsEmpty() ) || ( option == NEW_PART ) ) + if( PART_LIBS* libs = Prj().SchLibs() ) { - ViewOneLibraryContent( Lib, NEW_PART ); - return; + if( PART_LIB* lib = libs->FindLibrary( m_libraryName ) ) + { + if( m_entryName.IsEmpty() || option == NEW_PART ) + { + ViewOneLibraryContent( lib, NEW_PART ); + return; + } + + if( lib->FindEntry( m_entryName ) ) + { + if( option == NEXT_PART ) + ViewOneLibraryContent( lib, NEXT_PART ); + + if( option == PREVIOUS_PART ) + ViewOneLibraryContent( lib, PREVIOUS_PART ); + } + } } - - LIB_ALIAS* LibEntry = Lib->FindEntry( m_entryName ); - - if( LibEntry == NULL ) - return; - - if( option == NEXT_PART ) - ViewOneLibraryContent( Lib, NEXT_PART ); - - if( option == PREVIOUS_PART ) - ViewOneLibraryContent( Lib, PREVIOUS_PART ); } -/*************************************************/ -/* Routine to view one selected library content. */ -/*************************************************/ -void LIB_VIEW_FRAME::ViewOneLibraryContent( CMP_LIBRARY* Lib, int Flag ) +void LIB_VIEW_FRAME::ViewOneLibraryContent( PART_LIB* Lib, int Flag ) { int NumOfParts = 0; - LIB_ALIAS* LibEntry; + LIB_ALIAS* entry; wxString CmpName; if( Lib ) @@ -215,24 +206,24 @@ void LIB_VIEW_FRAME::ViewOneLibraryContent( CMP_LIBRARY* Lib, int Flag ) if( Flag == NEXT_PART ) { - LibEntry = Lib->GetNextEntry( m_entryName ); + entry = Lib->GetNextEntry( m_entryName ); - if( LibEntry ) - CmpName = LibEntry->GetName(); + if( entry ) + CmpName = entry->GetName(); } if( Flag == PREVIOUS_PART ) { - LibEntry = Lib->GetPreviousEntry( m_entryName ); + entry = Lib->GetPreviousEntry( m_entryName ); - if( LibEntry ) - CmpName = LibEntry->GetName(); + if( entry ) + CmpName = entry->GetName(); } m_unit = 1; m_convert = 1; - LibEntry = Lib->FindEntry( CmpName ); + entry = Lib->FindEntry( CmpName ); m_entryName = CmpName; DisplayLibInfos(); Zoom_Automatique( false ); @@ -248,65 +239,55 @@ void LIB_VIEW_FRAME::ViewOneLibraryContent( CMP_LIBRARY* Lib, int Flag ) } -/** - * Function RedrawActiveWindow - * Display the current selected component. - * If the component is an alias, the ROOT component is displayed -*/ void LIB_VIEW_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) { - LIB_COMPONENT* component; - LIB_ALIAS* entry; - CMP_LIBRARY* lib; - wxString msg; - wxString tmp; - - lib = CMP_LIBRARY::FindLibrary( m_libraryName ); - - if( lib == NULL ) - return; - - entry = lib->FindEntry( m_entryName ); - - if( entry == NULL ) - return; - - component = entry->GetComponent(); - - m_canvas->DrawBackGround( DC ); - - if( !entry->IsRoot() ) + if( PART_LIBS* libs = Prj().SchLibs() ) { - if( component == NULL ) // Should not occur - return; + if( PART_LIB* lib = libs->FindLibrary( m_libraryName ) ) + { + if( LIB_ALIAS* entry = lib->FindEntry( m_entryName ) ) + { + if( LIB_PART* part = entry->GetPart() ) + { + wxString msg; + wxString tmp; - // Temporarily change the name field text to reflect the alias name. - msg = entry->GetName(); - tmp = component->GetName(); - component->SetName( msg ); + m_canvas->DrawBackGround( DC ); - if( m_unit < 1 ) - m_unit = 1; + if( !entry->IsRoot() ) + { + // Temporarily change the name field text to reflect the alias name. + msg = entry->GetName(); + tmp = part->GetName(); - if( m_convert < 1 ) - m_convert = 1; + part->SetName( msg ); + + if( m_unit < 1 ) + m_unit = 1; + + if( m_convert < 1 ) + m_convert = 1; + } + else + { + msg = _( "None" ); + } + + part->Draw( m_canvas, DC, wxPoint( 0, 0 ), m_unit, m_convert, GR_DEFAULT_DRAWMODE ); + + // Redraw the cursor + m_canvas->DrawCrossHair( DC ); + + if( !tmp.IsEmpty() ) + part->SetName( tmp ); + + ClearMsgPanel(); + AppendMsgPanel( _( "Part" ), part->GetName(), BLUE, 6 ); + AppendMsgPanel( _( "Alias" ), msg, RED, 6 ); + AppendMsgPanel( _( "Description" ), entry->GetDescription(), CYAN, 6 ); + AppendMsgPanel( _( "Key words" ), entry->GetKeyWords(), DARKDARKGRAY ); + } + } + } } - else - { - msg = _( "None" ); - } - - component->Draw( m_canvas, DC, wxPoint( 0, 0 ), m_unit, m_convert, GR_DEFAULT_DRAWMODE ); - - /* Redraw the cursor */ - m_canvas->DrawCrossHair( DC ); - - if( !tmp.IsEmpty() ) - component->SetName( tmp ); - - ClearMsgPanel(); - AppendMsgPanel( _( "Part" ), component->GetName(), BLUE, 6 ); - AppendMsgPanel( _( "Alias" ), msg, RED, 6 ); - AppendMsgPanel( _( "Description" ), entry->GetDescription(), CYAN, 6 ); - AppendMsgPanel( _( "Key words" ), entry->GetKeyWords(), DARKDARKGRAY ); } diff --git a/gerbview/excellon_read_drill_file.cpp b/gerbview/excellon_read_drill_file.cpp index 7c9726d2b0..540be36983 100644 --- a/gerbview/excellon_read_drill_file.cpp +++ b/gerbview/excellon_read_drill_file.cpp @@ -188,6 +188,7 @@ bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName ) } wxString path = wxPathOnly( aFullFileName ); + if( path != wxEmptyString ) wxSetWorkingDirectory( path ); @@ -196,7 +197,7 @@ bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName ) // Display errors list if( m_Messages.size() > 0 ) { - HTML_MESSAGE_BOX dlg( this, _("Files not found") ); + HTML_MESSAGE_BOX dlg( this, _( "Files not found" ) ); dlg.ListSet( m_Messages ); dlg.ShowModal(); } diff --git a/include/class_collector.h b/include/class_collector.h index e51b32fe96..294fa0b3d9 100644 --- a/include/class_collector.h +++ b/include/class_collector.h @@ -70,19 +70,13 @@ protected: /// The time at which the collection was made. time_t m_TimeAtCollection; - public: - COLLECTOR() { m_ScanTypes = 0; } - - virtual ~COLLECTOR() - { - } - + virtual ~COLLECTOR() {} /** * Function IsValidIndex @@ -97,7 +91,6 @@ public: return ( (unsigned) aIndex < m_List.size() ); } - /** * Function GetCount * returns the number of objects in the list @@ -107,7 +100,6 @@ public: return (int) m_List.size(); } - /** * Function Empty * sets the list to empty @@ -117,7 +109,6 @@ public: m_List.clear(); } - /** * Function Append * adds an item to the end of the list. @@ -128,7 +119,6 @@ public: m_List.push_back( item ); } - /** * Function Remove * removes the item at \a aIndex (first position is 0); @@ -139,7 +129,6 @@ public: m_List.erase( m_List.begin() + aIndex ); } - /** * Function operator[int] * is used for read only access and returns the object at \a aIndex. @@ -154,7 +143,6 @@ public: return NULL; } - /** * Function BasePtr * returns the address of the first element in the array. Only call this @@ -166,7 +154,6 @@ public: return &m_List[0]; } - /** * Function HasItem * tests if \a aItem has already been collected. @@ -185,7 +172,6 @@ public: return false; } - /** * Function SetScanTypes * records the list of KICAD_T types to consider for collection by @@ -198,13 +184,11 @@ public: m_ScanTypes = scanTypes; } - void SetTimeNow() { m_TimeAtCollection = GetNewTimeStamp(); } - time_t GetTime() { return m_TimeAtCollection; @@ -216,7 +200,6 @@ public: void SetBoundingBox( const EDA_RECT& aRefBox ) { m_RefBox = aRefBox; } const EDA_RECT& GetBoundingBox() const { return m_RefBox; } - /** * Function IsSimilarPointAndTime * returns true if the given reference point is "similar" (defined here) @@ -241,7 +224,6 @@ public: return false; } - /** * Function Collect * scans an EDA_ITEM using this class's Inspector method, which does @@ -251,7 +233,7 @@ public: * * example implementation, in derived class: * - virtual void Collect( EDA_ITEM* container, const wxPoint& aRefPos ) + void Collect( EDA_ITEM* container, const wxPoint& aRefPos ) { example implementation: @@ -266,7 +248,6 @@ public: SetTimeNow(); // when it was taken } */ - }; #endif // COLLECTOR_H diff --git a/include/class_sch_screen.h b/include/class_sch_screen.h index acf8f20819..1a19657483 100644 --- a/include/class_sch_screen.h +++ b/include/class_sch_screen.h @@ -35,6 +35,7 @@ #include #include #include +#include #include <../eeschema/general.h> @@ -60,9 +61,10 @@ enum SCH_LINE_TEST_T #define NB_MAX_SHEET 500 -class SCH_SCREEN : public BASE_SCREEN +class SCH_SCREEN : public BASE_SCREEN, public KIWAY_HOLDER { private: + wxString m_fileName; ///< File used to load the screen. int m_refCount; ///< Number of sheets referencing this screen. @@ -76,8 +78,10 @@ private: /// Origin of the auxilliary axis, which is used in exports mostly, but not yet in EESCHEMA wxPoint m_aux_origin; - DLIST< SCH_ITEM > m_drawList; ///< Object list for the screen. - /// @todo use DLIST or superior container + DLIST< SCH_ITEM > m_drawList; ///< Object list for the screen. + + int m_modification_sync; ///< inequality with PART_LIBS::GetModificationHash() + ///< will trigger ResolveAll(). /** * Function addConnectedItemsToBlock @@ -96,7 +100,7 @@ public: /** * Constructor */ - SCH_SCREEN(); + SCH_SCREEN( KIWAY* aKiway ); ~SCH_SCREEN(); @@ -123,15 +127,19 @@ public: void IncRefCount(); - int GetRefCount() const { return m_refCount; } + int GetRefCount() const { return m_refCount; } /** * Function GetDrawItems(). * @return - A pointer to the first item in the linked list of draw items. */ - SCH_ITEM* GetDrawItems() const { return m_drawList.begin(); } + SCH_ITEM* GetDrawItems() const { return m_drawList.begin(); } - void Append( SCH_ITEM* aItem ) { m_drawList.Append( aItem ); } + void Append( SCH_ITEM* aItem ) + { + m_drawList.Append( aItem ); + --m_modification_sync; + } /** * Function Append @@ -139,7 +147,11 @@ public: * * @param aList A reference to a #DLIST containing the #SCH_ITEM to add to the sheet. */ - void Append( DLIST< SCH_ITEM >& aList ) { m_drawList.Append( aList ); } + void Append( DLIST< SCH_ITEM >& aList ) + { + m_drawList.Append( aList ); + --m_modification_sync; + } /** * Function GetCurItem @@ -507,10 +519,9 @@ public: /** * Class SCH_SCREENS - * is a class to handle the list of *screens* in a hierarchy. + * is a container class that holds multiple SCH_SCREENs in a hierarchy. + * Individual SCH_SCREENs are unique, and correspond to .sch files. */ - -// screens are unique, and correspond to .sch files. class SCH_SCREENS { private: diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h index dbb066f4a8..8c89e4c75b 100644 --- a/include/core/typeinfo.h +++ b/include/core/typeinfo.h @@ -98,7 +98,7 @@ enum KICAD_T * If you add a new draw item, type, please make sure you add it so the * sort order is logical. */ - LIB_COMPONENT_T, + LIB_PART_T, LIB_ALIAS_T, LIB_ARC_T, LIB_CIRCLE_T, diff --git a/include/dialog_helpers.h b/include/dialog_helpers.h index 9b33e23d37..a6c1cf9777 100644 --- a/include/dialog_helpers.h +++ b/include/dialog_helpers.h @@ -52,12 +52,8 @@ class EDA_DRAW_FRAME; */ class EDA_LIST_DIALOG : public EDA_LIST_DIALOG_BASE { -private: - bool m_sortList; - void (*m_callBackFct)( wxString& Text ); - const std::vector* m_itemsListCp; - public: + /** * Constructor: * @param aParent Pointer to the parent window. @@ -66,13 +62,15 @@ public: * @param aItemList = A wxArrayString of the list of elements. * @param aRefText = An item name if an item must be preselected. * @param aCallBackFunction = callback function to display comments + * @param aCallBackFunctionData = a pointer to pass to @a aCallBackFunction * @param aSortList = true to sort list items by alphabetic order. */ EDA_LIST_DIALOG( EDA_DRAW_FRAME* aParent, const wxString& aTitle, const wxArrayString& aItemHeaders, const std::vector& aItemList, const wxString& aRefText, - void(*aCallBackFunction)(wxString& Text) = NULL, + void (* aCallBackFunction)( wxString& text, void* data ) = NULL, + void* aCallBackFunctionData = NULL, bool aSortList = false ); // ~EDA_LIST_DIALOG() {} @@ -97,6 +95,11 @@ private: void onListItemActivated( wxListEvent& event ); void textChangeInFilterBox(wxCommandEvent& event); void sortList(); + + bool m_sortList; + void (* m_cb_func)( wxString& text, void* data ); + void* m_cb_data; + const std::vector* m_itemsListCp; }; diff --git a/include/gestfich.h b/include/gestfich.h index 6a972ea059..5158a3372c 100644 --- a/include/gestfich.h +++ b/include/gestfich.h @@ -54,24 +54,6 @@ wxString EDA_FileSelector( const wxString& Title, const wxPoint& Pos = wxPoint( -1, -1 ) ); -/** - * Function MakeReducedFileName - * calculate the "reduced" filename from \a fullfilename. - * - * @param fullfilename = full filename - * @param default_path = default path - * @param default_ext = default extension - * @return the "reduced" filename, i.e.: - * without path if it is default_path - * with ./ if the path is the current path - * without extension if extension is default_ext - * - * the new filename is in unix like notation ('/' as path separator) - */ -wxString MakeReducedFileName( const wxString& fullfilename, - const wxString& default_path, - const wxString& default_ext ); - EDA_LIST_DIALOG* GetFileNames( char* Directory, char* Mask ); diff --git a/include/html_messagebox.h b/include/html_messagebox.h index 72c79dad3f..c177086788 100644 --- a/include/html_messagebox.h +++ b/include/html_messagebox.h @@ -25,7 +25,7 @@ public: */ HTML_MESSAGE_BOX( wxWindow* parent, const wxString& aTitle, wxPoint aPos = wxDefaultPosition, - wxSize aSize = wxSize( 450,250 ) ); + wxSize aSize = wxSize( 450, 250 ) ); /** * Function ListSet diff --git a/include/id.h b/include/id.h index a243491c30..5bcfcbd18a 100644 --- a/include/id.h +++ b/include/id.h @@ -28,8 +28,8 @@ */ -#ifndef ID_H -#define ID_H +#ifndef ID_H_ +#define ID_H_ #define MAX_ITEMS_IN_PICKER 15 ///< max no. items in the popup menu for item selection @@ -44,9 +44,11 @@ enum main_id { - ID_TO_PCB = wxID_HIGHEST, - ID_TO_PCB_MODULE_EDITOR, - ID_TO_CVPCB, + ID_RUN_PCB = wxID_HIGHEST, + ID_RUN_PCB_MODULE_EDITOR, + ID_RUN_CVPCB, + ID_RUN_LIBRARY, // pcbnew & eeschema each use this internally to load their respective lib editors + ID_LOAD_PROJECT, ID_APPEND_PROJECT, ID_NEW_PROJECT, @@ -207,7 +209,6 @@ enum main_id ID_POPUP_GRID_USER, ID_SHEET_SET, - ID_TO_LIBRARY, ID_COMPONENT_BUTT, ID_ZOOM_IN, @@ -215,7 +216,7 @@ enum main_id ID_ZOOM_PAGE, ID_ZOOM_REDRAW, - /* Panning command event IDs. */ + // Panning command event IDs. ID_PAN_UP, ID_PAN_DOWN, ID_PAN_LEFT, @@ -228,7 +229,7 @@ enum main_id ID_EDA_SOCKET_EVENT_SERV, ID_EDA_SOCKET_EVENT, - /* Command IDs common to Pcbnew and CvPcb. */ + // Command IDs common to Pcbnew and CvPcb. ID_PCB_DISPLAY_FOOTPRINT_DOC, // Common to all @@ -252,4 +253,4 @@ enum main_id ID_END_LIST }; -#endif /* define ID_H */ +#endif // ID_H_ diff --git a/include/kiway.h b/include/kiway.h index 469a0fde27..380f300352 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -393,6 +393,19 @@ private: }; +/* +/// Given aProject, return its KIWAY* +inline KIWAY* PrjToKiway( PROJECT* aProject ) +{ + // It's ugly, but isolated. The compiler should simply do what's + // it's told to do here and shut up. + KIWAY* p = 0; + ptrdiff_t offset = (char*) &p->m_project - (char*) p; + + return (KIWAY*) ((char*)aProject - offset); +} +*/ + extern KIWAY Kiway; // provided by single_top.cpp and kicad.cpp diff --git a/include/kiway_player.h b/include/kiway_player.h index 0bdc2e8045..94be92dcb1 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -126,8 +126,8 @@ public: //--------------------------------------------------------- // For the aCtl argument of OpenProjectFiles() -#define KICTL_OPEN_APPEND (1<<0) ///< append the data file, rather than replace -#define KICTL_EAGLE_BRD (1<<1) ///< chosen *.brd file is Eagle according to user. +#define KICTL_EAGLE_BRD (1<<0) ///< chosen *.brd file is Eagle according to user. +#define KICTL_CREATE (1<<1) ///< caller thinks requested project files may not exist /** * Function OpenProjectFiles @@ -139,12 +139,15 @@ public: * KIWAY_PLAYER is precluded. *

* Each derived class should handle this in a way specific to its needs. - * No prompting is done inside here for any file or project. There should be - * no need to call this with aFileList which is empty. However, calling it with + * No filename prompting is done inside here for any file or project. There should + * be no need to call this with aFileList which is empty. However, calling it with * a single filename which does not exist should indicate to the implementor * that a new session is being started and that the given name is the desired * name for the data file at time of save. *

+ * This function does not support "appending". Use a different function for that. + * Any prior project data tree should be cleared before loading the new stuff. + *

* Therefore, one of the first things an implementation should do is test for * existence of the first file in the list, and if it does not exist, treat * it as a new session, possibly with a UI notification to that effect. @@ -255,19 +258,33 @@ bool OpenProjectFiles( const std::vector& aFileList, int aCtl = 0 ) assert( aFileList[0] is absolute ) // bug in single_top.cpp or project manager. - if (window does not support appending) || !(aCtl & KICTL_OPEN_APPEND) + if( !Pgm().LockFile( fullFileName ) ) { - close any currently open project files. + DisplayError( this, _( "This file is already open." ) ); + return false; } + if current open project files have been modified + { + ask if user wants to save them and if yes save. + } + + unload any currently open project files. + + Prj().SetProjectFullName( ) + if( aFileList[0] does not exist ) { - notify user file does not exist. + notify user file does not exist and ask if he wants to create it + if( yes ) + { + create empty project file(s) + mark file as modified. - create an empty project file - mark file as modified. - - use the default project config file. + use the default project config file. + } + else + return false } else { @@ -276,7 +293,11 @@ bool OpenProjectFiles( const std::vector& aFileList, int aCtl = 0 ) use the project config file for project given by aFileList[0]s full path. } + UpdateFileHistory( g_RootSheet->GetScreen()->GetFileName() ); + + /* done in ReDraw typically: UpdateTitle(); + */ show contents. } diff --git a/include/project.h b/include/project.h index b8828798bf..9683518849 100644 --- a/include/project.h +++ b/include/project.h @@ -26,7 +26,6 @@ #include #include #include -#include /// A variable name whose value holds the current project directory. /// Currently an environment variable, eventually a project variable. @@ -36,6 +35,8 @@ class wxConfigBase; class PARAM_CFG_ARRAY; class FP_LIB_TABLE; +class PART_LIBS; +class SEARCH_STACK; #define VTBL_ENTRY virtual @@ -98,14 +99,15 @@ public: * Then the wxConfigBase derivative is written to the *.pro file for the project. * * @param aSearchS a SEARCH_STACK - * @param aFileName is where to save the *.pro file. * @param aGroupName * @param aParams is a ptr vector of PARAM_CFG_BASE derivatives. * Saved parameters are the subset in this array having the .m_Setup member * set to false. + * @param aFileName is where to save the *.pro file and if NULL means use this PROJECT's + * @a m_project_name. */ - VTBL_ENTRY void ConfigSave( const SEARCH_STACK& aSearchS, const wxString& aFileName, - const wxString& aGroupName, const PARAM_CFG_ARRAY& aParams ); + VTBL_ENTRY void ConfigSave( const SEARCH_STACK& aSList, const wxString& aGroupName, + const PARAM_CFG_ARRAY& aParams, const wxString& aFileName = wxEmptyString ); /** * Function ConfigLoad @@ -116,31 +118,30 @@ public: *

* set: * m_pro_date_and_time - * m_pro_name * * @param aSearchS a SEARCH_STACK where a kicad.pro template file may be found. - * @param aLocalConfigFileName * @param aGroupName * @param aParams is ptr vector of PARAM_CFG_BASE derivatives. - * @param doLoadOnlyIfNew if true, then this file is read only if it differs from - * the current config on date (different dates), else the *.pro file is read and - * extracted from unconditionally. + * @param aForeignConfigFileName when NULL means load the *.pro filename given + * in this PROJECT's @a m_project_name field, otherwise load the provided filename. * * @return bool - true if loaded OK. */ - VTBL_ENTRY bool ConfigLoad( const SEARCH_STACK& aSearchS, const wxString& aLocalConfigFileName, - const wxString& aGroupName, const PARAM_CFG_ARRAY& aParams, bool doLoadOnlyIfNew ); - - /// Accessor for Eeschema search stack. - VTBL_ENTRY SEARCH_STACK& SchSearchS() { return m_sch_search; } + VTBL_ENTRY bool ConfigLoad( const SEARCH_STACK& aSearchS, const wxString& aGroupName, + const PARAM_CFG_ARRAY& aParams, const wxString& aForeignConfigFileName = wxEmptyString ); /// Retain a number of project specific wxStrings, enumerated here: enum RSTRING_T { DOC_PATH, SCH_LIB_PATH, - PCB_LIB_NICKNAME, + SCH_LIB_SELECT, // eeschema/selpart.cpp + SCH_LIBEDIT_CUR_LIB, + SCH_LIBEDIT_CUR_PART, // eeschema/libeditframe.cpp + VIEWER_3D_PATH, + + PCB_LIB_NICKNAME, PCB_FOOTPRINT, PCB_FOOTPRINT_VIEWER_FPNAME, PCB_FOOTPRINT_VIEWER_NICKNAME, @@ -172,6 +173,9 @@ public: { ELEM_FPTBL, + ELEM_SCH_PART_LIBS, + ELEM_SCH_SEARCH_STACK, + ELEM_COUNT }; @@ -187,20 +191,33 @@ public: VTBL_ENTRY _ELEM* GetElem( ELEM_T aIndex ); VTBL_ENTRY void SetElem( ELEM_T aIndex, _ELEM* aElem ); - /// Inline, clear the _ELEM at position aIndex - void ElemClear( ELEM_T aIndex ) - { - _ELEM* existing = GetElem( aIndex ); - delete existing; // virtual - SetElem( aIndex, NULL ); - } - /** * Function ElemsClear * deletes all the _ELEMs and set their pointers to NULL. */ VTBL_ENTRY void ElemsClear(); + /** + * Function Clear + * clears the _ELEMs and RSTRINGs. + */ + void Clear() // inline not virtual + { + ElemsClear(); + + for( unsigned i = 0; i--------------------------------------------------- //----------------------------------------------------- @@ -209,7 +226,7 @@ public: // data on demand, and do so typicallly into m_elems[] at a particular index using // SetElem() & GetElem(). That is, they wrap SetElem() and GetElem(). // To get the data to reload on demand, first SetProjectFullName(), - // then call ElemClear() from client code. + // then call SetElem( ELEM_T, NULL ) from client code. // non-virtuals resident in PCBNEW link image(s). By being non-virtual, these // functions can get linked into the KIFACE that needs them, and only there. @@ -222,6 +239,10 @@ public: #if defined(EESCHEMA) // These are all prefaced with "Sch" + PART_LIBS* SchLibs(); + + /// Accessor for Eeschema search stack. + SEARCH_STACK* SchSearchS(); #endif //---------------------------------------------------- @@ -230,24 +251,14 @@ private: /** * Function configCreate - * creates or recreates the KiCad project file and wxConfigBase: + * loads a *.pro file and returns a wxConfigBase. * - * .pro - * - * @param aFilename is a local configuration file path and basename. - * - * Initializes ? - * G_Prj_Config - * G_Prj_Config_LocalFilename - * G_Prj_Default_Config_FullFilename - * : + * @param aSList is the KIFACE or PGM's SEARCH_STACK + * @param aGroupName is the default config file subset to use. + * @param aProjectFileName is the *.pro file to open. */ - wxConfigBase* configCreate( const SEARCH_STACK& aSearchS, - const wxString& aFilename, const wxString& aGroupName, - bool aForceUseLocalConfig ); - - SEARCH_STACK m_sch_search; ///< Eeschema's search paths - SEARCH_STACK m_pcb_search; ///< Pcbnew's obsolete footprint search paths, see comment above. + wxConfigBase* configCreate( const SEARCH_STACK& aSList, + const wxString& aGroupName, const wxString& aFileName = wxEmptyString ); wxFileName m_project_name; ///< /.pro wxString m_pro_date_and_time; diff --git a/include/search_stack.h b/include/search_stack.h index 8c36c90849..e16b2b67bd 100644 --- a/include/search_stack.h +++ b/include/search_stack.h @@ -3,6 +3,7 @@ #include #include +#include /** @@ -12,7 +13,7 @@ * that anything you put in here means searching work at some point in time. * (An alternative is to simply know where something is.) */ -class SEARCH_STACK : public wxPathList +class SEARCH_STACK : public wxPathList, public PROJECT::_ELEM { public: @@ -22,11 +23,25 @@ public: /** * Function FilenameWithRelativePathInSearchList + * returns the shortest possible path which can be use later to find + * a full path from this SEARCH_STACK. + *

+ * If the library path is already in the library search paths list, + * just add the library name to the list. Otherwise, add the library + * name with the full or relative path. The relative path is preferable + * because it preserves use of default libraries paths, when the path + * is a sub path of these default paths. Note we accept only sub paths + * not relative paths starting by ../ that are not subpaths and are + * outside kicad libs paths + * + * @param aFullFilename The filename with path and extension. + * @param aBaseDir The absolute path on which relative paths in this + * SEARCH_STACK are based. * @return a short filename (with extension) with only a relative path if * this filename can be found in library paths - * @param aFullFilename The filename with path and extension. */ - wxString FilenameWithRelativePathInSearchList( const wxString& aFullFilename ); + wxString FilenameWithRelativePathInSearchList( + const wxString& aFullFilename, const wxString& aBaseDir ); wxString FindValidPath( const wxString& aFileName ) const { @@ -58,6 +73,16 @@ public: */ void RemovePaths( const wxString& aPaths ); + /** + * Function Split + * separates aPathString into individual paths. + * @param aResult is where to put the paths, it should be empty upon entry. + * @param aPathString is concatonated string with interposing ';' or ':' separators. + * @return int - the count of paths found in aPathString + */ + static int Split( wxArrayString* aResult, const wxString aPathString ); + +#if 1 // this function is so poorly designed it deserves not to exist. /** * Function LastVisitedPath * is a quirky function inherited from old code that seems to serve particular @@ -70,6 +95,8 @@ public: * @param aSubPathToSearch is the preferred sub path to search in path list */ const wxString LastVisitedPath( const wxString& aSubPathToSearch = wxEmptyString ); +#endif + }; #endif // SEARCH_STACK_H_ diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index 247b79a35a..7d56fdf830 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -115,7 +115,6 @@ enum SCH_SEARCH_T { class SCH_EDIT_FRAME : public SCH_BASE_FRAME { private: - SCH_SHEET_PATH* m_CurrentSheet; ///< which sheet we are presently working on. wxString m_DefaultSchematicFileName; PARAM_CFG_ARRAY m_projectFileParams; @@ -161,13 +160,14 @@ private: /// Use netcodes (net number) as net names when generating spice net lists. bool m_spiceNetlistUseNetcodeAsNetname; - wxString m_userLibraryPath; + /* these are PROJECT specific, not schematic editor specific + wxString m_userLibraryPath; + wxArrayString m_componentLibFiles; + */ - wxArrayString m_componentLibFiles; - - static int m_lastSheetPinType; ///< Last sheet pin type. - static wxSize m_lastSheetPinTextSize; ///< Last sheet pin text size. - static wxPoint m_lastSheetPinPosition; ///< Last sheet pin position. + static int m_lastSheetPinType; ///< Last sheet pin type. + static wxSize m_lastSheetPinTextSize; ///< Last sheet pin text size. + static wxPoint m_lastSheetPinPosition; ///< Last sheet pin position. protected: TEMPLATES m_TemplateFieldNames; @@ -231,13 +231,12 @@ public: void SetSpiceUseNetcodeAsNetname( bool aEnable ) { m_spiceNetlistUseNetcodeAsNetname = aEnable; } + /* These are PROJECT specific, not schematic editor specific wxString GetUserLibraryPath() const { return m_userLibraryPath; } - void SetUserLibraryPath( const wxString& aPath ) { m_userLibraryPath = aPath; } - const wxArrayString& GetComponentLibraries() const { return m_componentLibFiles; } - void SetComponentLibraries( const wxArrayString& aList ) { m_componentLibFiles = aList; } + */ void Process_Special_Functions( wxCommandEvent& event ); void OnColorConfig( wxCommandEvent& aEvent ); @@ -250,15 +249,12 @@ public: * Function GetProjectFileParametersList * returns the project file parameter list for Eeschema. * - * * Populate the project file parameter array specific to Eeschema if it hasn't * already been populated and return a reference to the array to the caller. - * Creating the parameter list at run time has the advantage of being able to - * define local variables. The old method of statically building the array at - * compile time required global variable definitions. *

*/ - PARAM_CFG_ARRAY& GetProjectFileParametersList( void ); + PARAM_CFG_ARRAY& GetProjectFileParametersList(); /** * Function SaveProjectSettings @@ -275,7 +271,7 @@ public: * @param aForceReread Force the project file to be reread if true. * @return True if the project file was loaded correctly. */ - bool LoadProjectFile( const wxString& aFileName, bool aForceReread ); + bool LoadProjectFile(); /** * Function GetDefaultFieldName @@ -342,7 +338,7 @@ public: * setting that need to be loaded at run time, this is the place to define it. *

*/ - PARAM_CFG_ARRAY& GetConfigurationSettings( void ); + PARAM_CFG_ARRAY& GetConfigurationSettings(); void LoadSettings( wxConfigBase* aCfg ); void SaveSettings( wxConfigBase* aCfg ); @@ -736,6 +732,7 @@ public: // General search: private: + /** * Function OnMoveItem * handles the #ID_SCH_MOVE_ITEM event used to move schematic itams. @@ -1231,13 +1228,6 @@ public: */ void SaveUndoItemInUndoList( SCH_ITEM* aItem ); - /** - * Function LoadLibraries - * - * Clear all libraries currently loaded and load all of the project libraries. - */ - void LoadLibraries( void ); - /** * Function CreateArchiveLibraryCacheFile * creates a library file with the name of the root document plus the '-cache' suffix, diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index cc2650fcde..fbcd92aedd 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -336,13 +336,12 @@ public: void SaveProjectSettings( bool aAskForSave ); /** - * Load the project file configuration settings. + * Load the current project's file configuration settings which are pertinent + * to this PCB_EDIT_FRAME instance. * - * @param aProjectFileName = The project filename. - * if not found use kicad.pro and initialize default values * @return always returns true. */ - bool LoadProjectSettings( const wxString& aProjectFileName ); + bool LoadProjectSettings(); /** * Function GetConfigurationSettings @@ -826,14 +825,10 @@ public: bool OpenProjectFiles( const std::vector& aFileSet, int aCtl = 0 ); /** - * Function ReadPcbFile - * reads a board file <file>.brd - * @param aReader The line reader object to read from. - * @param Append if 0: a previously loaded board is deleted before loading - * the file else all items of the board file are added to the - * existing board + * Function AppendBoardFile + * appends a board file onto the current one, creating God knows what. */ - int ReadPcbFile( LINE_READER* aReader, bool Append ); + bool AppendBoardFile( const wxString& aFullFileName, int aCtl ); /** * Function SavePcbFile @@ -1649,19 +1644,4 @@ public: DECLARE_EVENT_TABLE() }; - -/** - * Function AskBoardFileName - * puts up a wxFileDialog asking for a BOARD filename to open. - * - * @param aParent is a wxFrame passed to wxFileDialog. - * @param aCtl is where to put the OpenProjectFiles() control bits. - * - * @param aFileName on entry is a probable choice, on return is the chosen filename. - * - * @return bool - true if chosen, else false if user aborted. - */ -bool AskBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName ); - - #endif // WXPCB_STRUCT_H_ diff --git a/include/wxstruct.h b/include/wxstruct.h index 5b6215838a..416ddb625f 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -295,14 +295,14 @@ public: * Prompt the user for an old hotkey file to read, and read it. * @param aDescList = current hotkey list descr. to initialize. */ - void ImportHotkeyConfigFromFile( struct EDA_HOTKEY_CONFIG* aDescList ); + void ImportHotkeyConfigFromFile( EDA_HOTKEY_CONFIG* aDescList ); /** * Function ExportHotkeyConfigToFile * Prompt the user for an old hotkey file to read, and read it. * @param aDescList = current hotkey list descr. to initialize. */ - void ExportHotkeyConfigToFile( struct EDA_HOTKEY_CONFIG* aDescList ); + void ExportHotkeyConfigToFile( EDA_HOTKEY_CONFIG* aDescList ); /** * Function GetFileFromHistory diff --git a/kicad/class_treeproject_item.cpp b/kicad/class_treeproject_item.cpp index 30ce219716..a602abff00 100644 --- a/kicad/class_treeproject_item.cpp +++ b/kicad/class_treeproject_item.cpp @@ -107,12 +107,10 @@ bool TREEPROJECT_ITEM::Rename( const wxString& name, bool check ) if( check && !ext.IsEmpty() && !reg.Matches( newFile ) ) { - wxMessageDialog dialog( m_parent, - _( - "Changing file extension will change file \ -type.\n Do you want to continue ?" ), - _( "Rename File" ), - wxYES_NO | wxICON_QUESTION ); + wxMessageDialog dialog( m_parent, _( + "Changing file extension will change file type.\n Do you want to continue ?" ), + _( "Rename File" ), + wxYES_NO | wxICON_QUESTION ); if( wxID_YES != dialog.ShowModal() ) return false; @@ -184,7 +182,7 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* prjframe ) wxString fullFileName = GetFileName(); wxTreeItemId id = GetId(); - KICAD_MANAGER_FRAME* mainFrame = (KICAD_MANAGER_FRAME*) Pgm().App().GetTopWindow(); + KICAD_MANAGER_FRAME* frame = (KICAD_MANAGER_FRAME*) Pgm().App().GetTopWindow(); switch( GetType() ) { @@ -196,46 +194,34 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* prjframe ) break; case TREE_SCHEMA: + if( fullFileName == frame->SchFileName() ) { - wxFileName ffn( fullFileName ); - wxFileName pro( mainFrame->GetProjectFileName() ); - - // compare all but the extension: - if( pro.GetPath()==ffn.GetPath() && pro.GetName()==ffn.GetName() ) - { - // the project's schematic is opened using the *.kiface as part of this process. - mainFrame->RunEeschema( fullFileName ); - } - else - { - // schematics not part of the project are opened in a separate process. - mainFrame->Execute( m_parent, EESCHEMA_EXE, fullFileName ); - } + // the project's schematic is opened using the *.kiface as part of this process. + frame->RunEeschema( fullFileName ); + } + else + { + // schematics not part of the project are opened in a separate process. + frame->Execute( m_parent, EESCHEMA_EXE, fullFileName ); } break; case TREE_LEGACY_PCB: case TREE_SEXP_PCB: + if( fullFileName == frame->PcbFileName() || fullFileName == frame->PcbLegacyFileName() ) { - wxFileName ffn( fullFileName ); - wxFileName pro( mainFrame->GetProjectFileName() ); - - // compare all but the extension: - if( pro.GetPath()==ffn.GetPath() && pro.GetName()==ffn.GetName() ) - { - // the project's BOARD is opened using the *.kiface as part of this process. - mainFrame->RunPcbNew( fullFileName ); - } - else - { - // boards not part of the project are opened in a separate process. - mainFrame->Execute( m_parent, PCBNEW_EXE, fullFileName ); - } + // the project's BOARD is opened using the *.kiface as part of this process. + frame->RunPcbNew( fullFileName ); + } + else + { + // boards not part of the project are opened in a separate process. + frame->Execute( m_parent, PCBNEW_EXE, fullFileName ); } break; case TREE_GERBER: - mainFrame->Execute( m_parent, GERBVIEW_EXE, fullFileName ); + frame->Execute( m_parent, GERBVIEW_EXE, fullFileName ); break; case TREE_PDF: @@ -244,7 +230,7 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* prjframe ) break; case TREE_NET: - mainFrame->Execute( m_parent, CVPCB_EXE, fullFileName ); + frame->Execute( m_parent, CVPCB_EXE, fullFileName ); break; case TREE_TXT: @@ -252,12 +238,12 @@ void TREEPROJECT_ITEM::Activate( TREE_PROJECT_FRAME* prjframe ) wxString editorname = Pgm().GetEditorName(); if( !editorname.IsEmpty() ) - mainFrame->Execute( m_parent, editorname, fullFileName ); + frame->Execute( m_parent, editorname, fullFileName ); } break; case TREE_PAGE_LAYOUT_DESCR: - mainFrame->Execute( m_parent, PL_EDITOR_EXE, fullFileName ); + frame->Execute( m_parent, PL_EDITOR_EXE, fullFileName ); break; default: diff --git a/kicad/commandframe.cpp b/kicad/commandframe.cpp index 1dc1b03d6b..70d6d776bb 100644 --- a/kicad/commandframe.cpp +++ b/kicad/commandframe.cpp @@ -63,15 +63,23 @@ void LAUNCHER_PANEL::CreateCommandToolbar() { wxBitmapButton* btn; - btn = AddBitmapButton( ID_TO_EESCHEMA, KiBitmap( icon_eeschema_xpm ) ); + btn = AddBitmapButton( ID_TO_SCH, KiBitmap( icon_eeschema_xpm ) ); btn->SetToolTip( _( "Eeschema - Electronic schematic editor" ) ); + btn = AddBitmapButton( ID_TO_SCH_LIB_EDITOR, KiBitmap( libedit_icon_xpm ) ); + btn->SetToolTip( _( "Schematic library editor" ) ); + +#if 0 btn = AddBitmapButton( ID_TO_CVPCB, KiBitmap( icon_cvpcb_xpm ) ); btn->SetToolTip( _( "CvPcb - Associate footprint to components" ) ); +#endif btn = AddBitmapButton( ID_TO_PCB, KiBitmap( icon_pcbnew_xpm ) ); btn->SetToolTip( _( "Pcbnew - Printed circuit board editor" ) ); + btn = AddBitmapButton( ID_TO_PCB_FP_EDITOR, KiBitmap( icon_modedit_xpm ) ); + btn->SetToolTip( _( "PCB footprint editor" ) ); + btn = AddBitmapButton( ID_TO_GERBVIEW, KiBitmap( icon_gerbview_xpm ) ); btn->SetToolTip( _( "GerbView - Gerber viewer" ) ); diff --git a/kicad/files-io.cpp b/kicad/files-io.cpp index 6e1ca00db8..727ce63cf4 100644 --- a/kicad/files-io.cpp +++ b/kicad/files-io.cpp @@ -82,7 +82,6 @@ void KICAD_MANAGER_FRAME::OnUnarchiveFiles( wxCommandEvent& event ) if( dirDlg.ShowModal() == wxID_CANCEL ) return; - wxSetWorkingDirectory( dirDlg.GetPath() ); msg.Printf( _( "Unzipping project in '%s'\n" ), GetChars( dirDlg.GetPath() ) ); PrintMsg( msg ); @@ -105,7 +104,7 @@ void KICAD_MANAGER_FRAME::OnUnarchiveFiles( wxCommandEvent& event ) wxString unzipfilename = localfilename.AfterLast( ':' ); - msg.Printf( _( "Extract file <%s>" ), GetChars( unzipfilename ) ); + msg.Printf( _( "Extract file '%s'" ), GetChars( unzipfilename ) ); PrintMsg( msg ); wxInputStream* stream = zipfile->GetStream(); @@ -122,12 +121,11 @@ void KICAD_MANAGER_FRAME::OnUnarchiveFiles( wxCommandEvent& event ) delete ofile; delete zipfile; + localfilename = zipfilesys.FindNext(); } PrintMsg( wxT( "** end **\n" ) ); - - wxSetWorkingDirectory( fn.GetPath() ); } diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp index 23d0d5c1c1..76675381f1 100644 --- a/kicad/kicad.cpp +++ b/kicad/kicad.cpp @@ -137,18 +137,6 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) //DBG( m_bm.m_search.Show( (std::string( __func__ ) + " SysSearch()").c_str() );) } - // Read current setup and reopen last directory if no filename to open on - // command line. - if( App().argc == 1 ) - { - wxString dir; - - if( PgmSettings()->Read( workingDirKey, &dir ) && wxDirExists( dir ) ) - { - wxSetWorkingDirectory( dir ); - } - } - KICAD_MANAGER_FRAME* frame = new KICAD_MANAGER_FRAME( NULL, wxT( "KiCad" ), wxDefaultPosition, wxDefaultSize ); App().SetTopWindow( frame ); @@ -162,14 +150,23 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) else if( GetFileHistory().GetCount() ) { - // Try to open the last opened project, - // if a project name is not given when starting Kicad - frame->SetProjectFileName( GetFileHistory().GetHistoryFile( 0 ) ); + wxString last_pro = GetFileHistory().GetHistoryFile( 0 ); - if( !wxFileExists( frame->GetProjectFileName() ) ) + if( !wxFileExists( last_pro ) ) + { GetFileHistory().RemoveFileFromHistory( 0 ); + + wxFileName namelessProject( wxGetCwd(), NAMELESS_PROJECT, + ProjectFileExtension ); + + frame->SetProjectFileName( namelessProject.GetFullPath() ); + } else { + // Try to open the last opened project, + // if a project name is not given when starting Kicad + frame->SetProjectFileName( last_pro ); + wxCommandEvent cmd( 0, wxID_FILE1 ); frame->OnFileHistory( cmd ); @@ -177,14 +174,6 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp ) } } - if( !wxFileExists( frame->GetProjectFileName() ) ) - { - wxFileName namelessProject( wxGetCwd(), NAMELESS_PROJECT, - ProjectFileExtension ); - - frame->SetProjectFileName( namelessProject.GetFullPath() ); - } - if( !prjloaded ) { wxCommandEvent cmd( 0, wxID_ANY ); @@ -220,9 +209,7 @@ void PGM_KICAD::MacOpenFile( const wxString& aFileName ) frame->SetProjectFileName( aFileName ); - wxCommandEvent loadEvent; - - loadEvent.SetId( wxID_ANY ); + wxCommandEvent loadEvent( 0, wxID_ANY ); frame->OnLoadProject( loadEvent ); #endif diff --git a/kicad/kicad.h b/kicad/kicad.h index 3b7e45c036..bd4ef2fbaf 100644 --- a/kicad/kicad.h +++ b/kicad/kicad.h @@ -39,12 +39,11 @@ #include #include -//#include // With a recent wxWidget, we can use the wxFileSystemWatcherEvent // to monitor files add/remove/rename in tree project #if wxCHECK_VERSION( 2, 9, 4 ) -#define KICAD_USE_FILES_WATCHER + #define KICAD_USE_FILES_WATCHER #endif class LAUNCHER_PANEL; @@ -97,12 +96,17 @@ enum id_kicad_frm { ID_PROJECT_RENAME, ID_PROJECT_OPEN_FILE_WITH_TEXT_EDITOR, - ID_TO_EDITOR, - ID_TO_EESCHEMA, + ID_TO_SCH, + ID_TO_SCH_LIB_EDITOR, + ID_TO_CVPCB, + ID_TO_PCB, + ID_TO_PCB_FP_EDITOR, ID_TO_GERBVIEW, ID_TO_BITMAP_CONVERTER, ID_TO_PCB_CALCULATOR, ID_TO_PL_EDITOR, + + ID_TO_TEXT_EDITOR, ID_BROWSE_AN_SELECT_FILE, ID_SELECT_PREFERED_EDITOR, ID_SELECT_PREFERED_PDF_BROWSER_NAME, @@ -144,9 +148,12 @@ public: void OnArchiveFiles( wxCommandEvent& event ); void OnUnarchiveFiles( wxCommandEvent& event ); - void OnRunPcbNew( wxCommandEvent& event ); - void OnRunCvpcb( wxCommandEvent& event ); + void OnRunEeschema( wxCommandEvent& event ); + void OnRunSchLibEditor( wxCommandEvent& event ); + void OnRunPcbNew( wxCommandEvent& event ); + void OnRunPcbFpEditor( wxCommandEvent& event ); + void OnRunCvpcb( wxCommandEvent& event ); void OnRunGerbview( wxCommandEvent& event ); void OnRunBitmapConverter( wxCommandEvent& event ); void OnRunPcbCalculator( wxCommandEvent& event ); diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp index cf6690cd1a..e096443538 100644 --- a/kicad/mainframe.cpp +++ b/kicad/mainframe.cpp @@ -149,7 +149,7 @@ const wxString KICAD_MANAGER_FRAME::SchFileName() fn.SetExt( SchematicFileExtension ); - return fn.GetFullName(); + return fn.GetFullPath(); } @@ -159,7 +159,7 @@ const wxString KICAD_MANAGER_FRAME::PcbFileName() fn.SetExt( PcbFileExtension ); - return fn.GetFullName(); + return fn.GetFullPath(); } @@ -169,7 +169,7 @@ const wxString KICAD_MANAGER_FRAME::PcbLegacyFileName() fn.SetExt( LegacyPcbFileExtension ); - return fn.GetFullName(); + return fn.GetFullPath(); } @@ -298,6 +298,19 @@ void KICAD_MANAGER_FRAME::OnRunEeschema( wxCommandEvent& event ) } +void KICAD_MANAGER_FRAME::OnRunSchLibEditor( wxCommandEvent& event ) +{ + KIWAY_PLAYER* frame = Kiway.Player( FRAME_SCH_LIB_EDITOR, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_SCH_LIB_EDITOR, true ); + // frame->OpenProjectFiles( std::vector( 1, aProjectSchematicFileName ) ); + frame->Show( true ); + } + frame->Raise(); +} + + void KICAD_MANAGER_FRAME::RunPcbNew( const wxString& aProjectBoardFileName ) { KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB, false ); @@ -323,6 +336,19 @@ void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event ) } +void KICAD_MANAGER_FRAME::OnRunPcbFpEditor( wxCommandEvent& event ) +{ + KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB_MODULE_EDITOR, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_PCB_MODULE_EDITOR, true ); +// frame->OpenProjectFiles( std::vector( 1, aProjectBoardFileName ) ); + frame->Show( true ); + } + frame->Raise(); +} + + void KICAD_MANAGER_FRAME::OnRunBitmapConverter( wxCommandEvent& event ) { Execute( this, BITMAPCONVERTER_EXE ); diff --git a/kicad/menubar.cpp b/kicad/menubar.cpp index e792987a3c..ffbc6938d8 100644 --- a/kicad/menubar.cpp +++ b/kicad/menubar.cpp @@ -49,7 +49,7 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME ) // Menu events EVT_MENU( ID_SAVE_PROJECT, KICAD_MANAGER_FRAME::OnSaveProject ) EVT_MENU( wxID_EXIT, KICAD_MANAGER_FRAME::OnExit ) - EVT_MENU( ID_TO_EDITOR, KICAD_MANAGER_FRAME::OnOpenTextEditor ) + EVT_MENU( ID_TO_TEXT_EDITOR, KICAD_MANAGER_FRAME::OnOpenTextEditor ) EVT_MENU( ID_BROWSE_AN_SELECT_FILE, KICAD_MANAGER_FRAME::OnOpenFileInTextEditor ) EVT_MENU( ID_SELECT_PREFERED_EDITOR, EDA_BASE_FRAME::OnSelectPreferredEditor ) EVT_MENU( ID_SELECT_DEFAULT_PDF_BROWSER, KICAD_MANAGER_FRAME::OnSelectDefaultPdfBrowser ) @@ -74,9 +74,14 @@ BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME ) #endif // Button events - EVT_BUTTON( ID_TO_PCB, KICAD_MANAGER_FRAME::OnRunPcbNew ) + EVT_BUTTON( ID_TO_SCH, KICAD_MANAGER_FRAME::OnRunEeschema ) + EVT_BUTTON( ID_TO_SCH_LIB_EDITOR, KICAD_MANAGER_FRAME::OnRunSchLibEditor ) + EVT_BUTTON( ID_TO_CVPCB, KICAD_MANAGER_FRAME::OnRunCvpcb ) - EVT_BUTTON( ID_TO_EESCHEMA, KICAD_MANAGER_FRAME::OnRunEeschema ) + + EVT_BUTTON( ID_TO_PCB, KICAD_MANAGER_FRAME::OnRunPcbNew ) + EVT_BUTTON( ID_TO_PCB_FP_EDITOR, KICAD_MANAGER_FRAME::OnRunPcbFpEditor ) + EVT_BUTTON( ID_TO_GERBVIEW, KICAD_MANAGER_FRAME::OnRunGerbview ) EVT_BUTTON( ID_TO_BITMAP_CONVERTER, KICAD_MANAGER_FRAME::OnRunBitmapConverter ) EVT_BUTTON( ID_TO_PCB_CALCULATOR, KICAD_MANAGER_FRAME::OnRunPcbCalculator ) @@ -193,7 +198,7 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar() // Text editor AddMenuItem( browseMenu, - ID_TO_EDITOR, + ID_TO_TEXT_EDITOR, _( "Open Text E&ditor" ), _( "Launch preferred text editor" ), KiBitmap( editor_xpm ) ); diff --git a/kicad/prjconfig.cpp b/kicad/prjconfig.cpp index ee391c6bdf..72792fe194 100644 --- a/kicad/prjconfig.cpp +++ b/kicad/prjconfig.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -60,15 +61,11 @@ PARAM_CFG_ARRAY s_KicadManagerParams; void KICAD_MANAGER_FRAME::CreateNewProject( const wxString& aPrjFullFileName, bool aTemplateSelector = false ) { - wxString filename; wxFileName newProjectName = aPrjFullFileName; wxChar sep[2] = { SEP(), 0 }; // nul terminated separator wxChar string. ClearMsg(); - // default config filename - filename = Pgm().SysSearch().FindValidPath( wxT( "kicad.pro" ) ); - // If we are creating a project from a template, make sure the template directory is sane if( aTemplateSelector ) { @@ -155,40 +152,38 @@ void KICAD_MANAGER_FRAME::CreateNewProject( const wxString& aPrjFullFileName, } } } - else - { - // Check if file kicad.pro exist in template directory - if( wxFileName::FileExists( filename ) ) - { - wxCopyFile( filename, aPrjFullFileName ); - } - else - { - DisplayInfoMessage( NULL, _( "Project template file not found. " ) ); - return; - } - } // Init project filename SetProjectFileName( newProjectName.GetFullPath() ); // Write settings to project file // was: wxGetApp().WriteProjectConfig( aPrjFullFileName, GeneralGroupName, s_KicadManagerParams ); - Prj().ConfigSave( Pgm().SysSearch(), aPrjFullFileName, GeneralGroupName, s_KicadManagerParams ); + Prj().ConfigSave( Pgm().SysSearch(), GeneralGroupName, s_KicadManagerParams ); } void KICAD_MANAGER_FRAME::OnLoadProject( wxCommandEvent& event ) { + // Any open KIFACE's must be closed if they are not part of the new project. + // (We never want a KIWAY_PLAYER open on a KIWAY that isn't in the same project.) + // User is prompted here to close those KIWAY_PLAYERs: + if( !Kiway.PlayersClose( false ) ) + return; + + // evt_id can be one of: + // ID_NEW_PROJECT, ID_NEW_PROJECT_FROM_TEMPLATE, ID_LOAD_PROJECT, and + // wxID_ANY from 3 different places. + int evt_id = event.GetId(); + wxString title; ClearMsg(); - if( event.GetId() != wxID_ANY ) + if( evt_id != wxID_ANY ) { int style; - bool newProject = ( event.GetId() == ID_NEW_PROJECT ) || - ( event.GetId() == ID_NEW_PROJECT_FROM_TEMPLATE ); + bool newProject = ( evt_id == ID_NEW_PROJECT ) || + ( evt_id == ID_NEW_PROJECT_FROM_TEMPLATE ); if( newProject ) { @@ -208,15 +203,14 @@ void KICAD_MANAGER_FRAME::OnLoadProject( wxCommandEvent& event ) if( dlg.ShowModal() == wxID_CANCEL ) return; - DBG( printf( "%s: wxFileDialog::GetPath=%s\n", __func__, TO_UTF8( dlg.GetPath() ) );) + //DBG( printf( "%s: wxFileDialog::GetPath=%s\n", __func__, TO_UTF8( dlg.GetPath() ) );) wxFileName pro( dlg.GetPath() ); + pro.SetExt( ProjectFileExtension ); // enforce extension if( !pro.IsAbsolute() ) pro.MakeAbsolute(); - pro.SetExt( ProjectFileExtension ); - if( newProject ) { // Check if the project directory is empty @@ -240,11 +234,11 @@ void KICAD_MANAGER_FRAME::OnLoadProject( wxCommandEvent& event ) } } - if( event.GetId() == ID_NEW_PROJECT ) + if( evt_id == ID_NEW_PROJECT ) { CreateNewProject( pro.GetFullPath() ); } - else if( event.GetId() == ID_NEW_PROJECT_FROM_TEMPLATE ) + else if( evt_id == ID_NEW_PROJECT_FROM_TEMPLATE ) { // Launch the template selector dialog CreateNewProject( pro.GetFullPath(), true ); @@ -261,20 +255,15 @@ void KICAD_MANAGER_FRAME::OnLoadProject( wxCommandEvent& event ) // Check if project file exists and if it is not noname.pro if( !wxFileExists( prj_filename ) && !prj_filename.IsSameAs( nameless_prj ) ) { - wxString msg = wxString::Format( - _( "KiCad project file '%s' not found" ), + wxString msg = wxString::Format( _( + "KiCad project file '%s' not found" ), GetChars( prj_filename ) ); DisplayError( this, msg ); return; } - wxSetWorkingDirectory( wxFileName( prj_filename ).GetPath() ); - - // was wxGetApp().ReadProjectConfig( m_ProjectFileName.GetFullPath(), - // GeneralGroupName, s_KicadManagerParams, false ); - Prj().ConfigLoad( Pgm().SysSearch(), prj_filename, - GeneralGroupName, s_KicadManagerParams, false ); + Prj().ConfigLoad( Pgm().SysSearch(), GeneralGroupName, s_KicadManagerParams ); title = wxT( "KiCad " ) + GetBuildVersion() + wxT( ' ' ) + prj_filename; @@ -308,6 +297,5 @@ void KICAD_MANAGER_FRAME::OnSaveProject( wxCommandEvent& event ) // was: wxGetApp().WriteProjectConfig( m_ProjectFileName.GetFullPath(), // GeneralGroupName, s_KicadManagerParams ); - Prj().ConfigSave( Pgm().SysSearch(), GetProjectFileName(), - GeneralGroupName, s_KicadManagerParams ); + Prj().ConfigSave( Pgm().SysSearch(), GeneralGroupName, s_KicadManagerParams ); } diff --git a/kicad/tree_project_frame.cpp b/kicad/tree_project_frame.cpp index eec1659008..3dc0dfa7c8 100644 --- a/kicad/tree_project_frame.cpp +++ b/kicad/tree_project_frame.cpp @@ -107,7 +107,7 @@ const wxChar TextFileWildcard[] = wxT( "Text files (*.txt)|*.txt" ); * only useful files are shown. */ -/*****************************************************************************/ + BEGIN_EVENT_TABLE( TREE_PROJECT_FRAME, wxSashLayoutWindow ) EVT_TREE_ITEM_ACTIVATED( ID_PROJECT_TREE, TREE_PROJECT_FRAME::OnSelect ) EVT_TREE_ITEM_EXPANDED( ID_PROJECT_TREE, TREE_PROJECT_FRAME::OnExpand ) @@ -116,19 +116,15 @@ EVT_MENU( ID_PROJECT_TXTEDIT, TREE_PROJECT_FRAME::OnOpenSelectedFileWithTextEdit EVT_MENU( ID_PROJECT_NEWDIR, TREE_PROJECT_FRAME::OnCreateNewDirectory ) EVT_MENU( ID_PROJECT_DELETE, TREE_PROJECT_FRAME::OnDeleteFile ) EVT_MENU( ID_PROJECT_RENAME, TREE_PROJECT_FRAME::OnRenameFile ) - END_EVENT_TABLE() -/*****************************************************************************/ -/******************************************************************/ TREE_PROJECT_FRAME::TREE_PROJECT_FRAME( KICAD_MANAGER_FRAME* parent ) : wxSashLayoutWindow( parent, ID_LEFT_FRAME, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxSW_3D ) -/******************************************************************/ { m_Parent = parent; m_TreeProject = NULL; @@ -213,8 +209,8 @@ void TREE_PROJECT_FRAME::OnCreateNewDirectory( wxCommandEvent& event ) curr_dir = fn.GetPath() + wxFileName::GetPathSeparator(); } - wxString msg; - msg.Printf( wxT( "Current working directory:\n%s" ), GetChars( wxGetCwd() ) ); + wxString msg = wxString::Format( _( "Current working directory:\n%s" ), GetChars( wxGetCwd() ) ); + wxString subdir = wxGetTextFromUser( msg, _( "Create New Directory" ), curr_dir ); if( subdir.IsEmpty() ) @@ -291,7 +287,7 @@ wxString TREE_PROJECT_FRAME::GetFileExt( TreeFileType type ) ext = PageLayoutDescrFileExtension; break; - default: /* Eliminates unnecessary GCC warning. */ + default: // Eliminates unnecessary GCC warning. break; } @@ -361,7 +357,7 @@ wxString TREE_PROJECT_FRAME::GetFileWildcard( TreeFileType type ) ext = PageLayoutDescrFileWildcard; break; - default: /* Eliminates unnecessary GCC warning. */ + default: // Eliminates unnecessary GCC warning. break; } @@ -515,7 +511,7 @@ bool TREE_PROJECT_FRAME::AddItemToTreeProject( const wxString& aName, m_TreeProject->SetItemData( cellule, data ); data->SetState( 0 ); - /* Mark root files (files which have the same aName as the project) */ + // Mark root files (files which have the same aName as the project) wxFileName project( m_Parent->GetProjectFileName() ); wxFileName currfile( file ); @@ -528,21 +524,25 @@ bool TREE_PROJECT_FRAME::AddItemToTreeProject( const wxString& aName, // in this case AddFile is recursive, but for the first level only. if( TREE_DIRECTORY == type && aRecurse ) { - const wxString sep = wxFileName().GetPathSeparator(); - wxDir dir( aName ); - wxString dir_filename; + wxDir dir( aName ); - data->SetPopulated( true ); - - if( dir.GetFirst( &dir_filename ) ) + if( dir.IsOpened() ) // protected dirs will not open properly. { - do // Add name in tree, but do not recurse + wxString dir_filename; + + data->SetPopulated( true ); + + if( dir.GetFirst( &dir_filename ) ) { - AddItemToTreeProject( aName + sep + dir_filename, cellule, false ); - } while( dir.GetNext( &dir_filename ) ); + do // Add name in tree, but do not recurse + { + wxString path = aName + wxCONFIG_PATH_SEPARATOR + dir_filename; + AddItemToTreeProject( path, cellule, false ); + } while( dir.GetNext( &dir_filename ) ); + } } - /* Sort filenames by alphabetic order */ + // Sort filenames by alphabetic order m_TreeProject->SortChildren( cellule ); } @@ -554,13 +554,17 @@ void TREE_PROJECT_FRAME::ReCreateTreePrj() { wxTreeItemId rootcellule; bool prjOpened = false; + wxString pro_dir = m_Parent->GetProjectFileName(); if( !m_TreeProject ) m_TreeProject = new TREEPROJECTFILES( this ); else m_TreeProject->DeleteAllItems(); - wxFileName fn = m_Parent->GetProjectFileName(); + if( !pro_dir ) // This is empty from TREE_PROJECT_FRAME constructor + return; + + wxFileName fn = pro_dir; if( !fn.IsOk() ) { @@ -587,17 +591,24 @@ void TREE_PROJECT_FRAME::ReCreateTreePrj() // Now adding all current files if available if( prjOpened ) { - wxString filename; - wxDir dir( wxGetCwd() ); - bool cont = dir.GetFirst( &filename ); + wxString pro_dir = wxPathOnly( m_Parent->GetProjectFileName() ); + wxDir dir( pro_dir ); - while( cont ) + if( dir.IsOpened() ) // protected dirs will not open, see "man opendir()" { - if( filename != fn.GetFullName() ) - AddItemToTreeProject( dir.GetName() + wxFileName::GetPathSeparator() + - filename, m_root ); + wxString filename; + bool cont = dir.GetFirst( &filename ); - cont = dir.GetNext( &filename ); + while( cont ) + { + if( filename != fn.GetFullName() ) + { + wxString n = dir.GetName() + wxCONFIG_PATH_SEPARATOR + filename; + AddItemToTreeProject( n, m_root ); + } + + cont = dir.GetNext( &filename ); + } } } else @@ -609,8 +620,6 @@ void TREE_PROJECT_FRAME::ReCreateTreePrj() // Sort filenames by alphabetic order m_TreeProject->SortChildren( m_root ); - - m_Parent->SetProjectFileName( fn.GetFullPath() ); } @@ -714,7 +723,7 @@ void TREE_PROJECT_FRAME::OnRenameFile( wxCommandEvent& ) wxString buffer = m_TreeProject->GetItemText( curr_item ); wxString msg = wxString::Format( - _( "Change filename: <%s>" ), + _( "Change filename: '%s'" ), GetChars( tree_data->GetFileName() ) ); wxTextEntryDialog dlg( this, msg, _( "Change filename" ), buffer ); @@ -771,21 +780,25 @@ void TREE_PROJECT_FRAME::OnExpand( wxTreeEvent& Event ) if( itemData->IsPopulated() ) continue; - wxString fileName = itemData->GetFileName(); - const wxString sep = wxFileName().GetPathSeparator(); - wxDir dir( fileName ); - wxString dir_filename; + wxString fileName = itemData->GetFileName(); + wxDir dir( fileName ); - if( dir.GetFirst( &dir_filename ) ) + if( dir.IsOpened() ) { - do // Add name to tree item, but do not recurse in subdirs: - { - AddItemToTreeProject( fileName + sep + dir_filename, kid, false ); - } while( dir.GetNext( &dir_filename ) ); - } + wxString dir_filename; - itemData->SetPopulated( true ); // set state to populated - subdir_populated = true; + if( dir.GetFirst( &dir_filename ) ) + { + do // Add name to tree item, but do not recurse in subdirs: + { + wxString n = fileName + wxCONFIG_PATH_SEPARATOR + dir_filename; + AddItemToTreeProject( n, kid, false ); + } while( dir.GetNext( &dir_filename ) ); + } + + itemData->SetPopulated( true ); // set state to populated + subdir_populated = true; + } // Sort filenames by alphabetic order m_TreeProject->SortChildren( kid ); @@ -902,11 +915,29 @@ void TREE_PROJECT_FRAME::OnFileSystemEvent( wxFileSystemWatcherEvent& event ) switch( event.GetChangeType() ) { - case wxFSW_EVENT_CREATE: - AddItemToTreeProject( pathModified.GetFullPath(), root_id, false ); - break; + case wxFSW_EVENT_CREATE: + AddItemToTreeProject( pathModified.GetFullPath(), root_id, false ); + break; + + case wxFSW_EVENT_DELETE: + while( kid.IsOk() ) + { + TREEPROJECT_ITEM* itemData = GetItemIdData( kid ); + + if( itemData && itemData->GetFileName() == fn ) + { + m_TreeProject->Delete( kid ); + return; + } + kid = m_TreeProject->GetNextChild( root_id, cookie ); + } + break; + + case wxFSW_EVENT_RENAME : + { + wxFileName newpath = event.GetNewPath(); + wxString newfn = newpath.GetFullPath(); - case wxFSW_EVENT_DELETE: while( kid.IsOk() ) { TREEPROJECT_ITEM* itemData = GetItemIdData( kid ); @@ -914,33 +945,15 @@ void TREE_PROJECT_FRAME::OnFileSystemEvent( wxFileSystemWatcherEvent& event ) if( itemData && itemData->GetFileName() == fn ) { m_TreeProject->Delete( kid ); - return; + break; } + kid = m_TreeProject->GetNextChild( root_id, cookie ); } - break; - case wxFSW_EVENT_RENAME : - { - wxFileName newpath = event.GetNewPath(); - wxString newfn = newpath.GetFullPath(); - - while( kid.IsOk() ) - { - TREEPROJECT_ITEM* itemData = GetItemIdData( kid ); - - if( itemData && itemData->GetFileName() == fn ) - { - m_TreeProject->Delete( kid ); - break; - } - - kid = m_TreeProject->GetNextChild( root_id, cookie ); - } - - AddItemToTreeProject( newfn, root_id, false ); - } - break; + AddItemToTreeProject( newfn, root_id, false ); + } + break; } // Sort filenames by alphabetic order @@ -961,21 +974,25 @@ void TREE_PROJECT_FRAME::FileWatcherReset() // see http://docs.wxwidgets.org/trunk/classwx_file_system_watcher.htm // under unix, the file watcher needs more work to be efficient // moreover, under wxWidgets 2.9.4, AddTree does not work properly. - wxFileName watched_path = wxFileName::DirName( wxGetCwd() ); + + // We can see wxString under a debugger, not a wxFileName + wxString pro_dir = wxPathOnly( m_Parent->GetProjectFileName() ); + #ifdef __WINDOWS__ - m_watcher->AddTree( watched_path ); + m_watcher->AddTree( pro_dir ); #else - m_watcher->Add( watched_path ); + m_watcher->Add( pro_dir ); // Add subdirs wxTreeItemIdValue cookie; wxTreeItemId root_id = m_root; + std::stack < wxTreeItemId > subdirs_id; wxTreeItemId kid = m_TreeProject->GetFirstChild( root_id, cookie ); while( 1 ) { - if( ! kid.IsOk() ) + if( !kid.IsOk() ) { if( subdirs_id.empty() ) // all items were explored break; @@ -984,32 +1001,40 @@ void TREE_PROJECT_FRAME::FileWatcherReset() root_id = subdirs_id.top(); subdirs_id.pop(); kid = m_TreeProject->GetFirstChild( root_id, cookie ); - if( ! kid.IsOk() ) + if( !kid.IsOk() ) continue; } } TREEPROJECT_ITEM* itemData = GetItemIdData( kid ); - if( itemData && ( itemData->GetType() == TREE_DIRECTORY ) ) + if( itemData && itemData->GetType() == TREE_DIRECTORY ) { - watched_path = wxFileName::DirName( itemData->GetFileName() ); - m_watcher->Add( watched_path ); + // we can see wxString under a debugger, not a wxFileName + wxString path = itemData->GetFileName(); - // if kid is a subdir, push in list to explore it later - if( itemData->IsPopulated() && m_TreeProject->GetChildrenCount( kid ) ) - subdirs_id.push( kid ); + DBG(printf( "%s: add '%s'\n", __func__, TO_UTF8( path ) );) + + if( wxFileName::IsDirReadable( path ) ) // linux whines about watching protected dir + { + m_watcher->Add( path ); + + // if kid is a subdir, push in list to explore it later + if( itemData->IsPopulated() && m_TreeProject->GetChildrenCount( kid ) ) + subdirs_id.push( kid ); + } } kid = m_TreeProject->GetNextChild( root_id, cookie ); } #endif -#if 0 // For test only! +#if defined(DEBUG) && 1 wxArrayString paths; m_watcher->GetWatchedPaths( &paths ); + printf( "%s: watched paths:\n", __func__ ); for( unsigned ii = 0; ii < paths.GetCount(); ii++ ) - wxLogMessage( paths[ii] ); + printf( " %s\n", TO_UTF8( paths[ii] ) ); #endif } diff --git a/pcbnew/build_BOM_from_board.cpp b/pcbnew/build_BOM_from_board.cpp index 65f1e57d2c..233aaed6c7 100644 --- a/pcbnew/build_BOM_from_board.cpp +++ b/pcbnew/build_BOM_from_board.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -52,12 +53,11 @@ WX_DEFINE_LIST( CmpList ) void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) { wxFileName fn; - FILE* FichBom; - MODULE* Module = GetBoard()->m_Modules; + FILE* fp_bom; + MODULE* module = GetBoard()->m_Modules; wxString msg; - - if( Module == NULL ) + if( module == NULL ) { DisplayError( this, _( "No Modules!" ) ); return; @@ -67,7 +67,9 @@ void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) fn = GetBoard()->GetFileName(); fn.SetExt( CsvFileExtension ); - wxFileDialog dlg( this, _( "Save Bill of Materials" ), wxGetCwd(), + wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + + wxFileDialog dlg( this, _( "Save Bill of Materials" ), pro_dir, fn.GetFullName(), CsvFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); @@ -76,9 +78,9 @@ void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) fn = dlg.GetPath(); - FichBom = wxFopen( fn.GetFullPath(), wxT( "wt" ) ); + fp_bom = wxFopen( fn.GetFullPath(), wxT( "wt" ) ); - if( FichBom == NULL ) + if( fp_bom == NULL ) { msg.Printf( _( "Unable to create file <%s>" ), GetChars( fn.GetFullPath() ) ); DisplayError( this, msg ); @@ -93,7 +95,7 @@ void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) msg << _( "Quantity" ) << wxT( "\";\"" ); msg << _( "Designation" ) << wxT( "\";\"" ); msg << _( "Supplier and ref" ) << wxT( "\";\n" ); - fprintf( FichBom, "%s", TO_UTF8( msg ) ); + fprintf( fp_bom, "%s", TO_UTF8( msg ) ); // Build list CmpList list; @@ -101,7 +103,7 @@ void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) CmpList::iterator iter; int i = 1; - while( Module != NULL ) + while( module != NULL ) { bool valExist = false; @@ -110,10 +112,10 @@ void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) { cmp* current = *iter; - if( (current->m_Val == Module->GetValue()) && (current->m_fpid == Module->GetFPID()) ) + if( (current->m_Val == module->GetValue()) && (current->m_fpid == module->GetFPID()) ) { current->m_Ref.Append( wxT( ", " ), 1 ); - current->m_Ref.Append( Module->GetReference() ); + current->m_Ref.Append( module->GetReference() ); current->m_CmpCount++; valExist = true; @@ -126,15 +128,15 @@ void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) { comp = new cmp(); comp->m_Id = i++; - comp->m_Val = Module->GetValue(); - comp->m_Ref = Module->GetReference(); - comp->m_fpid = Module->GetFPID(); + comp->m_Val = module->GetValue(); + comp->m_Ref = module->GetReference(); + comp->m_fpid = module->GetFPID(); comp->m_CmpCount = 1; list.Append( comp ); } // increment module - Module = Module->Next(); + module = module->Next(); } // Print list @@ -149,12 +151,11 @@ void PCB_EDIT_FRAME::RecreateBOMFileFromBoard( wxCommandEvent& aEvent ) msg << FROM_UTF8( current->m_fpid.Format().c_str() ) << wxT( "\";" ); msg << current->m_CmpCount << wxT( ";\"" ); msg << current->m_Val << wxT( "\";;;\n" ); - fprintf( FichBom, "%s", TO_UTF8( msg ) ); + fprintf( fp_bom, "%s", TO_UTF8( msg ) ); list.DeleteObject( current ); delete (current); } - - fclose( FichBom ); + fclose( fp_bom ); } diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index b51657ff0a..d8b75825ca 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -2532,6 +2532,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets, } } + /* Extracts the board outlines and build a closed polygon * from lines, arcs and circle items on edge cut layer * Any closed outline inside the main outline is a hole @@ -2544,7 +2545,7 @@ bool BOARD::GetBoardPolygonOutlines( CPOLYGONS_LIST& aOutlines, wxString* aErrorText ) { // the SPECCTRA_DB function to extract board outlines: - SPECCTRA_DB dummy; + DSN::SPECCTRA_DB dummy; return dummy.GetBoardPolygonOutlines( this, aOutlines, aHoles, aErrorText ); } diff --git a/pcbnew/collectors.cpp b/pcbnew/collectors.cpp index cb99353899..dc047834aa 100644 --- a/pcbnew/collectors.cpp +++ b/pcbnew/collectors.cpp @@ -447,7 +447,7 @@ void GENERAL_COLLECTOR::Collect( BOARD_ITEM* aItem, const KICAD_T aScanList[], // see collectors.h -SEARCH_RESULT TYPE_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testData ) +SEARCH_RESULT PCB_TYPE_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testData ) { // The Vist() function only visits the testItem if its type was in the // the scanList, so therefore we can collect anything given to us here. @@ -456,7 +456,8 @@ SEARCH_RESULT TYPE_COLLECTOR::Inspect( EDA_ITEM* testItem, const void* testData return SEARCH_CONTINUE; // always when collecting } -void TYPE_COLLECTOR::Collect( BOARD_ITEM* aBoard, const KICAD_T aScanList[] ) + +void PCB_TYPE_COLLECTOR::Collect( BOARD_ITEM* aBoard, const KICAD_T aScanList[] ) { Empty(); // empty any existing collection diff --git a/pcbnew/collectors.h b/pcbnew/collectors.h index 4d2520c06d..7ebac91b8a 100644 --- a/pcbnew/collectors.h +++ b/pcbnew/collectors.h @@ -587,11 +587,11 @@ public: /** - * Class TYPE_COLLECTOR + * Class PCB_TYPE_COLLECTOR * merely gathers up all BOARD_ITEMs of a given set of KICAD_T type(s). * @see class COLLECTOR */ -class TYPE_COLLECTOR : public COLLECTOR +class PCB_TYPE_COLLECTOR : public COLLECTOR { public: @@ -634,6 +634,4 @@ public: void Collect( BOARD_ITEM* aBoard, const KICAD_T aScanList[] ); }; - - #endif // COLLECTORS_H diff --git a/pcbnew/dialogs/dialog_SVG_print.cpp b/pcbnew/dialogs/dialog_SVG_print.cpp index 6acf7c7299..f7573e04f2 100644 --- a/pcbnew/dialogs/dialog_SVG_print.cpp +++ b/pcbnew/dialogs/dialog_SVG_print.cpp @@ -209,12 +209,7 @@ void DIALOG_SVG_PRINT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) // Build the absolute path of current output plot directory // to preselect it when opening the dialog. wxFileName fn( m_outputDirectoryName->GetValue() ); - wxString path; - - if( fn.IsRelative() ) - path = wxGetCwd() + fn.GetPathSeparator() + m_outputDirectoryName->GetValue(); - else - path = m_outputDirectoryName->GetValue(); + wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() ); wxDirDialog dirDialog( this, _( "Select Output Directory" ), path ); @@ -229,7 +224,9 @@ void DIALOG_SVG_PRINT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) if( dialog.ShowModal() == wxID_YES ) { - wxString boardFilePath = ( (wxFileName) m_board->GetFileName() ).GetPath(); + wxString boardFilePath = Prj().AbsolutePath( m_board->GetFileName() ); + + boardFilePath = wxPathOnly( boardFilePath ); if( !dirName.MakeRelativeTo( boardFilePath ) ) wxMessageBox( _( "Cannot make path relative (target volume different from board file volume)!" ), diff --git a/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp index fb636c2095..4148673db4 100644 --- a/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp +++ b/pcbnew/dialogs/dialog_edit_module_for_BoardEditor.cpp @@ -481,7 +481,8 @@ void DIALOG_MODULE_BOARD_EDITOR::Browse3DLib( wxCommandEvent& event ) * because it preserve use of default libraries paths, when the path is a * sub path of these default paths */ - shortfilename = search.FilenameWithRelativePathInSearchList( fullfilename ); + shortfilename = search.FilenameWithRelativePathInSearchList( + fullfilename, wxPathOnly( Prj().GetProjectFullName() ) ); wxFileName aux = shortfilename; if( aux.IsAbsolute() ) diff --git a/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp b/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp index 3a2d03949c..3debc1be0f 100644 --- a/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp +++ b/pcbnew/dialogs/dialog_edit_module_for_Modedit.cpp @@ -341,7 +341,8 @@ void DIALOG_MODULE_MODULE_EDITOR::BrowseAndAdd3DLib( wxCommandEvent& event ) * the relative path, when possible is preferable, * because it preserve use of default libraries paths, when the path is a sub path of these default paths */ - shortfilename = search.FilenameWithRelativePathInSearchList( fullfilename ); + shortfilename = search.FilenameWithRelativePathInSearchList( + fullfilename, wxPathOnly( Prj().GetProjectFullName() ) ); wxFileName aux = shortfilename; diff --git a/pcbnew/dialogs/dialog_gendrill.cpp b/pcbnew/dialogs/dialog_gendrill.cpp index 34ef9d48dc..570d2acf17 100644 --- a/pcbnew/dialogs/dialog_gendrill.cpp +++ b/pcbnew/dialogs/dialog_gendrill.cpp @@ -288,12 +288,7 @@ void DIALOG_GENDRILL::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) // Build the absolute path of current output plot directory // to preselect it when opening the dialog. wxFileName fn( m_outputDirectoryName->GetValue() ); - wxString path; - - if( fn.IsRelative() ) - path = wxGetCwd() + fn.GetPathSeparator() + m_outputDirectoryName->GetValue(); - else - path = m_outputDirectoryName->GetValue(); + wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() ); wxDirDialog dirDialog( this, _( "Select Output Directory" ), path ); @@ -308,7 +303,9 @@ void DIALOG_GENDRILL::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) if( dialog.ShowModal() == wxID_YES ) { - wxString boardFilePath = ( (wxFileName) m_parent->GetBoard()->GetFileName() ).GetPath(); + wxString boardFilePath = Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() ); + + boardFilePath = wxPathOnly( boardFilePath ); if( !dirName.MakeRelativeTo( boardFilePath ) ) wxMessageBox( _( "Cannot make path relative. The target volume is different from board file volume!" ), @@ -368,8 +365,6 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap) bool gen_through_holes = true; bool gen_NPTH_holes = false; - wxString currentWD = ::wxGetCwd(); - UpdateConfig(); // set params and Save drill options m_parent->ClearMsgPanel(); @@ -414,10 +409,8 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap) } fn.SetName( fn.GetName() + layername_extend ); - wxString defaultPath = m_plotOpts.GetOutputDirectory(); - if( defaultPath.IsEmpty() ) - defaultPath = ::wxGetCwd(); + wxString defaultPath = Prj().AbsolutePath( m_plotOpts.GetOutputDirectory() ); fn.SetPath( defaultPath ); @@ -492,8 +485,6 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles(bool aGenDrill, bool aGenMap) gen_through_holes = false; } } - - ::wxSetWorkingDirectory( currentWD ); } diff --git a/pcbnew/dialogs/dialog_netlist.cpp b/pcbnew/dialogs/dialog_netlist.cpp index ccbb6341af..e888eeb38d 100644 --- a/pcbnew/dialogs/dialog_netlist.cpp +++ b/pcbnew/dialogs/dialog_netlist.cpp @@ -85,12 +85,13 @@ void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC ) && !GetBoard()->GetFileName().IsEmpty() && IsOK( NULL, _( "The project configuration has changed. Do you want to save it?" ) ) ) { - wxFileName fn = GetBoard()->GetFileName(); + wxFileName fn = Prj().AbsolutePath( GetBoard()->GetFileName() ); fn.SetExt( ProjectFileExtension ); - // was: wxGetApp().WriteProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters() ); - Prj().ConfigSave( Kiface().KifaceSearch(), fn.GetFullPath(), - GROUP_PCB, GetProjectFileParameters() ); + wxString pro_name = fn.GetFullPath(); + + Prj().ConfigSave( Kiface().KifaceSearch(), GROUP_PCB, + GetProjectFileParameters(), pro_name ); } } @@ -122,9 +123,11 @@ DIALOG_NETLIST::~DIALOG_NETLIST() (long) m_rbSingleNets->GetSelection() ); } + void DIALOG_NETLIST::OnOpenNetlistClick( wxCommandEvent& event ) { - wxString lastPath = wxFileName::GetCwd(); + wxString lastPath = wxFileName( Prj().GetProjectFullName() ).GetPath(); + wxString lastNetlistRead = m_parent->GetLastNetListRead(); if( !lastNetlistRead.IsEmpty() && !wxFileName::FileExists( lastNetlistRead ) ) @@ -138,7 +141,7 @@ void DIALOG_NETLIST::OnOpenNetlistClick( wxCommandEvent& event ) lastNetlistRead = fn.GetFullName(); } - wxLogDebug( wxT( "Last net list read path <%s>, file name <%s>." ), + wxLogDebug( wxT( "Last net list read path '%s', file name '%s'." ), GetChars( lastPath ), GetChars( lastNetlistRead ) ); wxFileDialog FilesDialog( this, _( "Select Netlist" ), lastPath, lastNetlistRead, @@ -354,7 +357,7 @@ void DIALOG_NETLIST::OnSaveMessagesToFile( wxCommandEvent& aEvent ) } else { - fn.SetPath( wxFileName::GetCwd() ); + fn = wxPathOnly( Prj().GetProjectFullName() ); } wxFileDialog dlg( this, _( "Save contents of message window" ), fn.GetPath(), fn.GetName(), diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index 9d5c689c1d..68a26bd4ad 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -306,12 +306,7 @@ void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) // Build the absolute path of current output plot directory // to preselect it when opening the dialog. wxFileName fn( m_outputDirectoryName->GetValue() ); - wxString path; - - if( fn.IsRelative() ) - path = wxGetCwd() + fn.GetPathSeparator() + m_outputDirectoryName->GetValue(); - else - path = m_outputDirectoryName->GetValue(); + wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() ); wxDirDialog dirDialog( this, _( "Select Output Directory" ), path ); @@ -326,7 +321,9 @@ void DIALOG_PLOT::OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) if( dialog.ShowModal() == wxID_YES ) { - wxString boardFilePath = ( (wxFileName) m_parent->GetBoard()->GetFileName() ).GetPath(); + wxString boardFilePath = Prj().AbsolutePath( m_parent->GetBoard()->GetFileName() ); + + boardFilePath = wxPathOnly( boardFilePath ); if( !dirName.MakeRelativeTo( boardFilePath ) ) wxMessageBox( _( "Cannot make path relative (target volume different from board file volume)!" ), diff --git a/pcbnew/dialogs/dialog_select_pretty_lib.cpp b/pcbnew/dialogs/dialog_select_pretty_lib.cpp index c080855c27..6b7ccd1908 100644 --- a/pcbnew/dialogs/dialog_select_pretty_lib.cpp +++ b/pcbnew/dialogs/dialog_select_pretty_lib.cpp @@ -31,12 +31,15 @@ */ #include +#include -DIALOG_SELECT_PRETTY_LIB::DIALOG_SELECT_PRETTY_LIB( wxWindow* parent ) - :DIALOG_SELECT_PRETTY_LIB_BASE( parent ) +DIALOG_SELECT_PRETTY_LIB::DIALOG_SELECT_PRETTY_LIB( wxWindow* parent ) : + DIALOG_SELECT_PRETTY_LIB_BASE( parent ) { - m_dirCtrl->SetPath( wxGetCwd() ); + wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + + m_dirCtrl->SetPath( pro_dir ); } diff --git a/pcbnew/dialogs/dialog_select_pretty_lib_base.cpp b/pcbnew/dialogs/dialog_select_pretty_lib_base.cpp index 58dd0f65b6..65d8909584 100644 --- a/pcbnew/dialogs/dialog_select_pretty_lib_base.cpp +++ b/pcbnew/dialogs/dialog_select_pretty_lib_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Nov 6 2013) +// C++ code generated with wxFormBuilder (version Jun 6 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -9,7 +9,7 @@ /////////////////////////////////////////////////////////////////////////// -DIALOG_SELECT_PRETTY_LIB_BASE::DIALOG_SELECT_PRETTY_LIB_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +DIALOG_SELECT_PRETTY_LIB_BASE::DIALOG_SELECT_PRETTY_LIB_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 ); diff --git a/pcbnew/dialogs/dialog_select_pretty_lib_base.fbp b/pcbnew/dialogs/dialog_select_pretty_lib_base.fbp index bac0e1981b..fc5de26cd9 100644 --- a/pcbnew/dialogs/dialog_select_pretty_lib_base.fbp +++ b/pcbnew/dialogs/dialog_select_pretty_lib_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -46,7 +46,7 @@ 400,300 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER - + DIALOG_SHIM; dialog_shim.h Select Footprint Library Folder diff --git a/pcbnew/dialogs/dialog_select_pretty_lib_base.h b/pcbnew/dialogs/dialog_select_pretty_lib_base.h index b1d7eb2aaf..307f826c6d 100644 --- a/pcbnew/dialogs/dialog_select_pretty_lib_base.h +++ b/pcbnew/dialogs/dialog_select_pretty_lib_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Nov 6 2013) +// C++ code generated with wxFormBuilder (version Jun 6 2014) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -11,6 +11,9 @@ #include #include #include +class DIALOG_SHIM; + +#include "dialog_shim.h" #include #include #include @@ -30,7 +33,7 @@ /////////////////////////////////////////////////////////////////////////////// /// Class DIALOG_SELECT_PRETTY_LIB_BASE /////////////////////////////////////////////////////////////////////////////// -class DIALOG_SELECT_PRETTY_LIB_BASE : public wxDialog +class DIALOG_SELECT_PRETTY_LIB_BASE : public DIALOG_SHIM { private: diff --git a/pcbnew/exporters/export_d356.cpp b/pcbnew/exporters/export_d356.cpp index 2c3d433873..67609fc5bd 100644 --- a/pcbnew/exporters/export_d356.cpp +++ b/pcbnew/exporters/export_d356.cpp @@ -348,18 +348,20 @@ static void write_D356_records( std::vector &aRecords, } } -/* Driver function: processing starts here */ + void PCB_EDIT_FRAME::GenD356File( wxCommandEvent& aEvent ) { - wxFileName fn = GetBoard()->GetFileName(); - wxString msg, ext, wildcard; - FILE *file; + wxFileName fn = GetBoard()->GetFileName(); + wxString msg, ext, wildcard; + FILE* file; ext = wxT( "d356" ); wildcard = _( "IPC-D-356 Test Files (.d356)|*.d356" ); fn.SetExt( ext ); - wxFileDialog dlg( this, _( "Export D-356 Test File" ), wxGetCwd(), + wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + + wxFileDialog dlg( this, _( "Export D-356 Test File" ), pro_dir, fn.GetFullName(), wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); diff --git a/pcbnew/exporters/export_gencad.cpp b/pcbnew/exporters/export_gencad.cpp index 648aebc60d..571e8db4cf 100644 --- a/pcbnew/exporters/export_gencad.cpp +++ b/pcbnew/exporters/export_gencad.cpp @@ -251,7 +251,9 @@ void PCB_EDIT_FRAME::ExportToGenCAD( wxCommandEvent& aEvent ) fn.SetExt( ext ); - wxFileDialog dlg( this, _( "Save GenCAD Board File" ), wxGetCwd(), + wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + + wxFileDialog dlg( this, _( "Save GenCAD Board File" ), pro_dir, fn.GetFullName(), wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); diff --git a/pcbnew/exporters/gen_modules_placefile.cpp b/pcbnew/exporters/gen_modules_placefile.cpp index fd9cdebab3..6682cf8c74 100644 --- a/pcbnew/exporters/gen_modules_placefile.cpp +++ b/pcbnew/exporters/gen_modules_placefile.cpp @@ -140,13 +140,8 @@ void DIALOG_GEN_MODULE_POSITION::OnOutputDirectoryBrowseClicked( wxCommandEvent& { // Build the absolute path of current output plot directory // to preselect it when opening the dialog. - wxFileName fn( m_outputDirectoryName->GetValue() ); - wxString path; - - if( fn.IsRelative() ) - path = wxGetCwd() + fn.GetPathSeparator() + m_outputDirectoryName->GetValue(); - else - path = m_outputDirectoryName->GetValue(); + wxFileName fn( m_outputDirectoryName->GetValue() ); + wxString path = Prj().AbsolutePath( m_outputDirectoryName->GetValue() ); wxDirDialog dirDialog( this, _( "Select Output Directory" ), path ); diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 0a31eb956c..7b53172267 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -58,159 +58,26 @@ #define USE_INSTRUMENTATION false -static const wxChar backupSuffix[] = wxT( "-bak" ); -static const wxChar autosavePrefix[]= wxT( "_autosave-" ); +static const wxChar backupSuffix[] = wxT( "-bak" ); +static const wxChar autosavePrefix[] = wxT( "_autosave-" ); -void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event ) -{ - wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) ); - - if( !!fn ) - { - int open_ctl = 0; - - m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); - ::wxSetWorkingDirectory( ::wxPathOnly( fn ) ); - - // LoadOnePcbFile( fn, bool aAppend = false, bool aForceFileDialog = false ); - if( !wxFileName::IsFileReadable( fn ) ) - { - if( !AskBoardFileName( this, &open_ctl, &fn ) ) - return; - } - - OpenProjectFiles( std::vector( 1, fn ), open_ctl ); - } -} - - -void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event ) -{ - int id = event.GetId(); - wxString msg; - - // If an edition is in progress, stop it. - // For something else than save, get rid of current tool. - if( id == ID_SAVE_BOARD ) - m_canvas->EndMouseCapture( -1, m_canvas->GetDefaultCursor() ); - else - m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); - - switch( id ) - { - case ID_LOAD_FILE: - { - // LoadOnePcbFile( GetBoard()->GetFileName(), append=false, aForceFileDialog=true ); - - int open_ctl; - wxString fileName = GetBoard()->GetFileName(); - - if( !AskBoardFileName( this, &open_ctl, &fileName ) ) - return; - - OpenProjectFiles( std::vector( 1, fileName ), open_ctl ); - } - break; - - case ID_MENU_READ_BOARD_BACKUP_FILE: - case ID_MENU_RECOVER_BOARD_AUTOSAVE: - { - wxFileName currfn = GetBoard()->GetFileName(); - wxFileName fn = currfn; - - if( id == ID_MENU_RECOVER_BOARD_AUTOSAVE ) - { - wxString rec_name = wxString( autosavePrefix ) + fn.GetName(); - fn.SetName( rec_name ); - } - else - { - wxString backup_ext = fn.GetExt()+ backupSuffix; - fn.SetExt( backup_ext ); - } - - if( !fn.FileExists() ) - { - msg.Printf( _( "Recovery file '%s' not found." ), - GetChars( fn.GetFullPath() ) ); - DisplayInfoMessage( this, msg ); - break; - } - - msg.Printf( _( "OK to load recovery or backup file '%s'" ), - GetChars(fn.GetFullPath() ) ); - - if( !IsOK( this, msg ) ) - break; - - GetScreen()->ClrModify(); // do not prompt the user for changes - - // LoadOnePcbFile( fn.GetFullPath(), aAppend=false, aForceFileDialog=false ); - OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); - - // Re-set the name since name or extension was changed - GetBoard()->SetFileName( currfn.GetFullPath() ); - UpdateTitle(); - } - break; - - case ID_APPEND_FILE: - { - // LoadOnePcbFile( wxEmptyString, aAppend = true, aForceFileDialog=false ); - int open_ctl; - wxString fileName; - - if( !AskBoardFileName( this, &open_ctl, &fileName ) ) - break; - - OpenProjectFiles( std::vector( 1, fileName ), open_ctl | KICTL_OPEN_APPEND ); - } - break; - - case ID_NEW_BOARD: - { - if( ! Clear_Pcb( true ) ) - break; - - // Clear footprint library table for the new board. - Prj().PcbFootprintLibs()->Clear(); - - wxFileName fn; - - fn.AssignCwd(); - fn.SetName( wxT( "noname" ) ); - - Prj().SetProjectFullName( fn.GetFullPath() ); - - fn.SetExt( PcbFileExtension ); - - GetBoard()->SetFileName( fn.GetFullPath() ); - UpdateTitle(); - ReCreateLayerBox(); - } - break; - - case ID_SAVE_BOARD: - SavePcbFile( GetBoard()->GetFileName() ); - break; - - case ID_SAVE_BOARD_AS: - SavePcbFile( wxEmptyString ); - break; - - default: - DisplayError( this, wxT( "File_io Internal Error" ) ); break; - } -} - - -bool AskBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName ) +/** + * Function AskLoadBoardFileName + * puts up a wxFileDialog asking for a BOARD filename to open. + * + * @param aParent is a wxFrame passed to wxFileDialog. + * @param aCtl is where to put the OpenProjectFiles() control bits. + * + * @param aFileName on entry is a probable choice, on return is the chosen filename. + * + * @return bool - true if chosen, else false if user aborted. + */ +bool AskLoadBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName ) { // This is a subset of all PLUGINs which are trusted to be able to - // load a BOARD. Order is subject to change as KICAD plugin matures. - // User may occasionally use the wrong plugin to load a *.brd file, - // (since both legacy and eagle use *.brd extension), + // load a BOARD. User may occasionally use the wrong plugin to load a + // *.brd file (since both legacy and eagle use *.brd extension), // but eventually *.kicad_pcb will be more common than legacy *.brd files. static const struct { @@ -269,24 +136,280 @@ bool AskBoardFileName( wxWindow* aParent, int* aCtl, wxString* aFileName ) } +/** + * Function AskSaveBoardFileName + * puts up a wxFileDialog asking for a BOARD filename to save. + * + * @param aParent is a wxFrame passed to wxFileDialog. + * @param aFullFileName on entry is a probable choice, on return is the + * chosen full filename (includes path). + * + * @return bool - true if chosen, else false if user aborted. + */ +bool AskSaveBoardFileName( wxWindow* aParent, wxString* aFileName ) +{ + wxString wildcard = wxGetTranslation( PcbFileWildcard ); + wxFileName fn = *aFileName; + + fn.SetExt( KiCadPcbFileExtension ); + + wxFileDialog dlg( aParent, + _( "Save Board File As" ), + fn.GetPath(), + fn.GetFullName(), + wildcard, + wxFD_SAVE + /* wxFileDialog is not equipped to handle multiple wildcards and + wxFD_OVERWRITE_PROMPT both together. + | wxFD_OVERWRITE_PROMPT + */ + ); + + if( dlg.ShowModal() != wxID_OK ) + return false; + + fn = dlg.GetPath(); + + // always enforce filename extension, user may not have entered it. + fn.SetExt( KiCadPcbFileExtension ); + + // Since the file overwrite test was removed from wxFileDialog because it doesn't work + // when multiple wildcards are defined, we have to check it ourselves to prevent an + // existing board file from silently being over written. + if( fn.FileExists() ) + { + wxString ask = wxString::Format( _( + "The file '%s' already exists.\n\n" + "Do you want to overwrite it?" ), + GetChars( fn.GetFullPath() ) + ); + + if( !IsOK( aParent, ask ) ) + { + return false; + } + } + + *aFileName = fn.GetFullPath(); + + return true; +} + + +void PCB_EDIT_FRAME::OnFileHistory( wxCommandEvent& event ) +{ + wxString fn = GetFileFromHistory( event.GetId(), _( "Printed circuit board" ) ); + + if( !!fn ) + { + int open_ctl = 0; + + m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); + + if( !wxFileName::IsFileReadable( fn ) ) + { + if( !AskLoadBoardFileName( this, &open_ctl, &fn ) ) + return; + } + + OpenProjectFiles( std::vector( 1, fn ), open_ctl ); + } +} + + +void PCB_EDIT_FRAME::Files_io( wxCommandEvent& event ) +{ + int id = event.GetId(); + wxString msg; + + // If an edition is in progress, stop it. + // For something else than save, get rid of current tool. + if( id == ID_SAVE_BOARD ) + m_canvas->EndMouseCapture( -1, m_canvas->GetDefaultCursor() ); + else + m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); + + switch( id ) + { + case ID_LOAD_FILE: + { + // LoadOnePcbFile( GetBoard()->GetFileName(), append=false, aForceFileDialog=true ); + + int open_ctl; + wxString fileName = Prj().AbsolutePath( GetBoard()->GetFileName() ); + + if( !AskLoadBoardFileName( this, &open_ctl, &fileName ) ) + return; + + OpenProjectFiles( std::vector( 1, fileName ), open_ctl ); + } + break; + + case ID_MENU_READ_BOARD_BACKUP_FILE: + case ID_MENU_RECOVER_BOARD_AUTOSAVE: + { + wxFileName currfn = Prj().AbsolutePath( GetBoard()->GetFileName() ); + wxFileName fn = currfn; + + if( id == ID_MENU_RECOVER_BOARD_AUTOSAVE ) + { + wxString rec_name = wxString( autosavePrefix ) + fn.GetName(); + fn.SetName( rec_name ); + } + else + { + wxString backup_ext = fn.GetExt()+ backupSuffix; + fn.SetExt( backup_ext ); + } + + if( !fn.FileExists() ) + { + msg.Printf( _( "Recovery file '%s' not found." ), + GetChars( fn.GetFullPath() ) ); + DisplayInfoMessage( this, msg ); + break; + } + + msg.Printf( _( "OK to load recovery or backup file '%s'" ), + GetChars(fn.GetFullPath() ) ); + + if( !IsOK( this, msg ) ) + break; + + GetScreen()->ClrModify(); // do not prompt the user for changes + + // LoadOnePcbFile( fn.GetFullPath(), aAppend=false, aForceFileDialog=false ); + OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + + // Re-set the name since name or extension was changed + GetBoard()->SetFileName( currfn.GetFullPath() ); + UpdateTitle(); + } + break; + + case ID_APPEND_FILE: + { + int open_ctl; + wxString fileName; + + if( !AskLoadBoardFileName( this, &open_ctl, &fileName ) ) + break; + + AppendBoardFile( fileName, open_ctl ); + } + break; + + case ID_NEW_BOARD: + { + if( !Clear_Pcb( true ) ) + break; + + wxFileName fn( wxGetCwd(), wxT( "noname" ), ProjectFileExtension ); + + Prj().SetProjectFullName( fn.GetFullPath() ); + + fn.SetExt( PcbFileExtension ); + + GetBoard()->SetFileName( fn.GetFullPath() ); + UpdateTitle(); + ReCreateLayerBox(); + } + break; + + case ID_SAVE_BOARD: + SavePcbFile( Prj().AbsolutePath( GetBoard()->GetFileName() ) ); + break; + + case ID_SAVE_BOARD_AS: + { + wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + wxFileName fn( pro_dir, _( "noname" ), KiCadPcbFileExtension ); + wxString filename = fn.GetFullPath(); + + if( AskSaveBoardFileName( this, &filename ) ) + SavePcbFile( filename, true ); + } + break; + + default: + DisplayError( this, wxT( "File_io Internal Error" ) ); + break; + } +} + + +// The KIWAY_PLAYER::OpenProjectFiles() API knows nothing about plugins, so +// determine how to load the BOARD here, with minor assistance from KICTL_EAGLE_BRD +// bit flag. +static IO_MGR::PCB_FILE_T plugin_type( const wxString& aFileName, int aCtl ) +{ + IO_MGR::PCB_FILE_T pluginType; + + wxFileName fn = aFileName; + + if( fn.GetExt() == IO_MGR::GetFileExtension( IO_MGR::LEGACY ) ) + { + // both legacy and eagle share a common file extension. + pluginType = ( aCtl & KICTL_EAGLE_BRD ) ? IO_MGR::EAGLE : IO_MGR::LEGACY; + } + else if( fn.GetExt() == IO_MGR::GetFileExtension( IO_MGR::LEGACY ) + backupSuffix ) + { + pluginType = IO_MGR::LEGACY; + } + else if( fn.GetExt() == IO_MGR::GetFileExtension( IO_MGR::IO_MGR::PCAD ) ) + { + pluginType = IO_MGR::PCAD; + } + else + pluginType = IO_MGR::KICAD; + + return pluginType; +} + + +bool PCB_EDIT_FRAME::AppendBoardFile( const wxString& aFullFileName, int aCtl ) +{ + return false; + + // I'll never use it, and it was mucking up OpenProjectFiles() with + // complicated cruft. If you must, put it here separate from that important + // function. + + // Actually I think this serves too many masters. Just do panelization in + // a good gerber file manager. +} + + bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, int aCtl ) { - wxASSERT( aFileSet.size() == 1 ); + // This is for python: + if( aFileSet.size() != 1 ) + { + UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ ); + DisplayError( this, msg ); + return false; + } - bool doAppend = aCtl & KICTL_OPEN_APPEND; - wxFileName fileName( aFileSet[0] ); + wxString fullFileName( aFileSet[0] ); - // Make filename absolute, to avoid issues when the filename is relative, - // for instance when stored in history list without path, and when building - // the config filename ( which should have a path ) - if( fileName.IsRelative() ) - fileName.MakeAbsolute(); + // We insist on caller sending us an absolute path, if it does not, we say it's a bug. + wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), + wxT( "bug in single_top.cpp or project manager." ) ); - if( GetScreen()->IsModify() && !doAppend ) + if( !Pgm().LockFile( fullFileName ) ) + { + wxString msg = wxString::Format( _( + "PCB file '%s' is already open." ), + GetChars( fullFileName ) + ); + DisplayError( this, msg ); + return false; + } + + if( GetScreen()->IsModify() ) { int response = YesNoCancelDialog( this, _( - "The current board has been modified. Do " - "you wish to save the changes?" ), + "The current board has been modified. Do you wish to save the changes?" ), wxEmptyString, _( "Save and Load" ), _( "Load Without Saving" ) @@ -296,124 +419,97 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in return false; else if( response == wxID_YES ) SavePcbFile( GetBoard()->GetFileName(), true ); + else + { + // response == wxID_NO, fall thru + } } - if( doAppend ) + wxFileName pro = fullFileName; + pro.SetExt( ProjectFileExtension ); + + bool is_new = !wxFileName::IsFileReadable( fullFileName ); + + // If its a non-existent schematic and caller thinks it exists + if( is_new && !( aCtl & KICTL_CREATE ) ) + { + // notify user that fullFileName does not exist, ask if user wants to create it. + wxString ask = wxString::Format( _( + "Board '%s' does not exist. Do you wish to create it?" ), + GetChars( fullFileName ) + ); + if( !IsOK( this, ask ) ) + return false; + } + + Clear_Pcb( false ); // pass false since we prompted above for a modified board + + IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl ); + + bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD; + + if( !converted ) + { + // PROJECT::SetProjectFullName() is an impactful function. It should only be + // called under carefully considered circumstances. + + // The calling code should know not to ask me here to change projects unless + // it knows what consequences that will have on other KIFACEs running and using + // this same PROJECT. It can be very harmful if that calling code is stupid. + Prj().SetProjectFullName( pro.GetFullPath() ); + + // load project settings before BOARD + LoadProjectSettings(); + } + + if( is_new ) { - GetBoard()->SetFileName( wxEmptyString ); OnModify(); - GetBoard()->m_Status_Pcb = 0; - } - - // The KIWAY_PLAYER::OpenProjectFiles() API knows nothing about plugins, so - // determine how to load the BOARD here, with minor assistance from KICTL_EAGLE_BRD - // bit flag. - - IO_MGR::PCB_FILE_T pluginType; - - if( fileName.GetExt() == IO_MGR::GetFileExtension( IO_MGR::LEGACY ) ) - { - // both legacy and eagle share a common file extension. - pluginType = ( aCtl & KICTL_EAGLE_BRD ) ? IO_MGR::EAGLE : IO_MGR::LEGACY; - } - else if( fileName.GetExt() == IO_MGR::GetFileExtension( IO_MGR::LEGACY ) + backupSuffix ) - { - pluginType = IO_MGR::LEGACY; - } - else if( fileName.GetExt() == IO_MGR::GetFileExtension( IO_MGR::IO_MGR::PCAD ) ) - { - pluginType = IO_MGR::PCAD; } else - pluginType = IO_MGR::KICAD; - - PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); - - if( !doAppend ) { - if( !Pgm().LockFile( fileName.GetFullPath() ) ) + BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK + + PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); + + try { - DisplayError( this, _( "This file is already open." ) ); + PROPERTIES props; + char xbuf[30]; + char ybuf[30]; + + // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. + sprintf( xbuf, "%d", GetPageSizeIU().x ); + sprintf( ybuf, "%d", GetPageSizeIU().y ); + + props["page_width"] = xbuf; + props["page_height"] = ybuf; + +#if USE_INSTRUMENTATION + // measure the time to load a BOARD. + unsigned startTime = GetRunningMicroSecs(); +#endif + + loadedBoard = pi->Load( fullFileName, NULL, &props ); + +#if USE_INSTRUMENTATION + unsigned stopTime = GetRunningMicroSecs(); + printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime ); +#endif + } + catch( const IO_ERROR& ioe ) + { + wxString msg = wxString::Format( _( + "Error loading board.\n%s" ), + GetChars( ioe.errorText ) + ); + DisplayError( this, msg ); + return false; } - Clear_Pcb( false ); // pass false since we prompted above for a modified board - } - CheckForAutoSaveFile( fileName, fileName.GetExt() ); + SetBoard( loadedBoard ); - GetBoard()->SetFileName( fileName.GetFullPath() ); - - if( !doAppend ) - { - // Update the option toolbar - m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill; - m_DisplayModText = DisplayOpt.DisplayModText; - m_DisplayModEdge = DisplayOpt.DisplayModEdge; - m_DisplayPadFill = DisplayOpt.DisplayPadFill; - m_DisplayViaFill = DisplayOpt.DisplayViaFill; - - // load project settings before BOARD, in case BOARD file has overrides. - LoadProjectSettings( GetBoard()->GetFileName() ); - } - else - { - GetDesignSettings().m_NetClasses.Clear(); - } - - BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK - - try - { - PROPERTIES props; - char xbuf[30]; - char ybuf[30]; - - // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. - sprintf( xbuf, "%d", GetPageSizeIU().x ); - sprintf( ybuf, "%d", GetPageSizeIU().y ); - - props["page_width"] = xbuf; - props["page_height"] = ybuf; - -#if USE_INSTRUMENTATION - // measure the time to load a BOARD. - unsigned startTime = GetRunningMicroSecs(); -#endif - - // load or append either: - loadedBoard = pi->Load( GetBoard()->GetFileName(), doAppend ? GetBoard() : NULL, &props ); - -#if USE_INSTRUMENTATION - unsigned stopTime = GetRunningMicroSecs(); - printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime ); -#endif - - // the Load plugin method makes a 'fresh' board, so we need to - // set its own name - GetBoard()->SetFileName( fileName.GetFullPath() ); - - if( !doAppend ) - { - if( pluginType == IO_MGR::LEGACY && - loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION ) - { - DisplayInfoMessage( this, - _( "This file was created by an older version of Pcbnew.\n" - "It will be stored in the new file format when you save this file again." ) ); - } - - SetBoard( loadedBoard ); - } - } - catch( const IO_ERROR& ioe ) - { - wxString msg = wxString::Format( _( "Error loading board.\n%s" ), - ioe.errorText.GetData() ); - wxMessageBox( msg, _( "Open Board File" ), wxOK | wxICON_ERROR ); - } - - if( loadedBoard ) - { // we should not ask PLUGINs to do these items: loadedBoard->BuildListOfNets(); loadedBoard->SynchronizeNetsAndNetClasses(); @@ -423,42 +519,43 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in // update the layer names in the listbox ReCreateLayerBox( false ); + + GetScreen()->ClrModify(); + + { + wxFileName fn = fullFileName; + CheckForAutoSaveFile( fullFileName, fn.GetExt() ); + } + + if( pluginType == IO_MGR::LEGACY && + loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION ) + { + DisplayInfoMessage( this, + _( "This file was created by an older version of Pcbnew.\n" + "It will be stored in the new file format when you save this file again." ) ); + } } - GetScreen()->ClrModify(); + // Update the option toolbar + m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill; + m_DisplayModText = DisplayOpt.DisplayModText; + m_DisplayModEdge = DisplayOpt.DisplayModEdge; + m_DisplayPadFill = DisplayOpt.DisplayPadFill; + m_DisplayViaFill = DisplayOpt.DisplayViaFill; - if( doAppend ) { - // change the initial board name to -append.brd - wxString new_filename = GetBoard()->GetFileName().BeforeLast( '.' ); + wxFileName fn = fullFileName; - if( !new_filename.EndsWith( wxT( "-append" ) ) ) - new_filename += wxT( "-append" ); + if( converted ) + fn.SetExt( PcbFileExtension ); - new_filename += wxT( "." ) + PcbFileExtension; + wxString fname = fn.GetFullPath(); - OnModify(); - GetBoard()->SetFileName( new_filename ); + fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); + + GetBoard()->SetFileName( fname ); } - // Fix the directory separator on Windows and - // force the new file format for not Kicad boards, - // to ensure the right format when saving the board - bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD; - wxString fn; - - if( converted ) - fn = GetBoard()->GetFileName().BeforeLast( '.' ); - else - fn = GetBoard()->GetFileName(); - - fn.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); - - if( converted ) - fn += wxT( "." ) + PcbFileExtension; - - GetBoard()->SetFileName( fn ); - UpdateTitle(); if( !converted ) @@ -467,24 +564,6 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in // Rebuild the new pad list (for drc and ratsnet control ...) GetBoard()->m_Status_Pcb = 0; - // Dick 5-Feb-2012: I do not agree with this. The layer widget will show what - // is visible or not, and it would be nice for the board to look like it - // did when I saved it, immediately after loading. -#if 0 - /* Reset the items visibility flag when loading a new config - * Because it could creates SERIOUS mistakes for the user, - * if board items are not visible after loading a board... - * Grid and ratsnest can be left to their previous state - */ - bool showGrid = IsElementVisible( GRID_VISIBLE ); - bool showRats = IsElementVisible( RATSNEST_VISIBLE ); - - SetVisibleAlls(); - - SetElementVisibility( GRID_VISIBLE, showGrid ); - SetElementVisibility( RATSNEST_VISIBLE, showRats ); -#endif - // Update info shown by the horizontal toolbars GetDesignSettings().SetCurrentNetClass( NETCLASS::Default ); ReFillLayerWidget(); @@ -541,145 +620,65 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in } -bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupFile ) +static wxString create_backup_file( const wxString& aFileName ) { - wxFileName backupFileName; - wxFileName pcbFileName; - wxString upperTxt; - wxString lowerTxt; - wxString msg; - bool saveok = true; - bool isSaveAs = false; + wxFileName fn = aFileName; + wxFileName backupFileName = aFileName; - IO_MGR::PCB_FILE_T pluginType; + backupFileName.SetExt( fn.GetExt() + backupSuffix ); - if( aFileName == wxEmptyString ) + // If an old backup file exists, delete it. If an old board file exists, + // rename it to the backup file name. + if( fn.FileExists() ) { - wxString wildcard; - wildcard << wxGetTranslation( PcbFileWildcard ) - // << wxChar( '|' ) << wxGetTranslation( LegacyPcbFileWildcard ) - ; + // Remove the old file xxx.000 if it exists. + if( backupFileName.FileExists() ) + wxRemoveFile( backupFileName.GetFullPath() ); - isSaveAs = true; - pcbFileName = GetBoard()->GetFileName(); - - if( pcbFileName.GetName() == wxEmptyString ) + // Rename the current file from .kicad_pcb to .kicad_pcb-bak + if( !wxRenameFile( fn.GetFullPath(), backupFileName.GetFullPath() ) ) { - pcbFileName.SetName( _( "Unnamed file" ) ); + wxString msg = wxString::Format( _( + "Warning: unable to create backup file '%s'" ), + GetChars( backupFileName.GetFullPath() ) + ); + DisplayError( NULL, msg ); } - - // Match the default wildcard filter choice, with the inital file extension shown. - // That'll be the extension unless user changes filter dropdown listbox. - pcbFileName.SetExt( KiCadPcbFileExtension ); - - wxFileDialog dlg( this, _( "Save Board File As" ), pcbFileName.GetPath(), - pcbFileName.GetFullName(), - wildcard, wxFD_SAVE - /* wxFileDialog is not equipped to handle multiple wildcards and - wxFD_OVERWRITE_PROMPT both together. - | wxFD_OVERWRITE_PROMPT - */ - ); - - if( dlg.ShowModal() != wxID_OK ) - return false; - -#if 0 // no more LEGACY_PLUGIN::Save() - int filterNdx = dlg.GetFilterIndex(); - - pluginType = ( filterNdx == 1 ) ? IO_MGR::LEGACY : IO_MGR::KICAD; -#else - pluginType = IO_MGR::KICAD; -#endif - - // Note: on Linux wxFileDialog is not reliable for noticing a changed filename. - // We probably need to file a bug report or implement our own derivation. - pcbFileName = dlg.GetPath(); - - // enforce file extension, must match plugin's policy. - pcbFileName.SetExt( IO_MGR::GetFileExtension( pluginType ) ); - - // Since the file overwrite test was removed from wxFileDialog because it doesn't work - // when multiple wildcards are defined, we have to check it ourselves to prevent an - // existing board file from silently being over written. - if( pcbFileName.FileExists() - && !IsOK( this, wxString::Format( _( "The file '%s' already exists.\n\nDo you want " - "to overwrite it?" ), - GetChars( pcbFileName.GetFullPath() ) )) ) - return false; - -#if 0 // RHH 6-Jul-14: I see no plausible reason to do this. We did not auto generate the - // footprint table. And the dialog which does suppport editing does the saving. - - // Save the project specific footprint library table. - if( !Prj().PcbFootprintLibs()->IsEmpty( false ) ) - { - wxString fp_lib_tbl = Prj().FootprintLibTblName(); - - if( wxFileName::FileExists( fp_lib_tbl ) - && IsOK( this, _( "A footprint library table already exists in this path.\n\nDo " - "you want to overwrite it?" ) ) ) - { - try - { - Prj().PcbFootprintLibs()->Save( fp_lib_tbl ); - } - catch( const IO_ERROR& ioe ) - { - wxString msg = wxString::Format( _( - "An error occurred attempting to save the " - "footprint library table '%s'\n\n%s" ), - GetChars( fp_lib_tbl ), - GetChars( ioe.errorText ) - ); - DisplayError( this, msg ); - } - } - } -#endif - } else { - pcbFileName = aFileName; - - if( pcbFileName.GetExt() == LegacyPcbFileExtension ) - pluginType = IO_MGR::LEGACY; - { - pluginType = IO_MGR::KICAD; - pcbFileName.SetExt( KiCadPcbFileExtension ); - } + backupFileName.Clear(); } + return backupFileName.GetFullPath(); +} + + +bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupFile ) +{ + // please, keep it simple. prompting goes elsewhere. + + wxFileName pcbFileName = aFileName; + + if( pcbFileName.GetExt() == LegacyPcbFileExtension ) + pcbFileName.SetExt( KiCadPcbFileExtension ); + if( !IsWritable( pcbFileName ) ) + { + wxString msg = wxString::Format( _( + "No access rights to write to file '%s'" ), + GetChars( pcbFileName.GetFullPath() ) + ); + + DisplayError( this, msg ); return false; + } + + wxString backupFileName; if( aCreateBackupFile ) { - // Get the backup file name - backupFileName = pcbFileName; - backupFileName.SetExt( pcbFileName.GetExt() + backupSuffix ); - - // If an old backup file exists, delete it. If an old board file exists, rename - // it to the backup file name. - if( pcbFileName.FileExists() ) - { - // Remove the old file xxx.000 if it exists. - if( backupFileName.FileExists() ) - wxRemoveFile( backupFileName.GetFullPath() ); - - // Rename the "old" file" from xxx.kicad_pcb to xxx.000 - if( !wxRenameFile( pcbFileName.GetFullPath(), backupFileName.GetFullPath() ) ) - { - msg = _( "Warning: unable to create backup file " ) + backupFileName.GetFullPath(); - DisplayError( this, msg ); - saveok = false; - } - } - else - { - backupFileName.Clear(); - } + backupFileName = create_backup_file( aFileName ); } GetBoard()->m_Status_Pcb &= ~CONNEXION_OK; @@ -690,79 +689,69 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF // Useful to save default values in headers GetDesignSettings().SetCurrentNetClass( NETCLASS::Default ); + ClearMsgPanel(); + + wxString upperTxt; + wxString lowerTxt; + try { - PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); + PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD ) ); - /* - if( (PLUGIN*)pi == NULL ) - THROW_IO_ERROR( wxString::Format( _( "cannot find file plug in for file format '%s'" ), - GetChars( pcbFileName.GetExt() ) ) ); - */ + wxASSERT( pcbFileName.IsAbsolute() ); pi->Save( pcbFileName.GetFullPath(), GetBoard(), NULL ); } catch( const IO_ERROR& ioe ) { - wxString msg = wxString::Format( _( "Error saving board.\n%s" ), - ioe.errorText.GetData() ); - wxMessageBox( msg, _( "Save Board File" ), wxICON_ERROR | wxOK ); - saveok = false; + wxString msg = wxString::Format( _( + "Error saving board file '%s'.\n%s" ), + GetChars( pcbFileName.GetFullPath() ), + GetChars( ioe.errorText ) + ); + DisplayError( this, msg ); + + lowerTxt = _( "Failed to create " ) + pcbFileName.GetFullPath(); + + AppendMsgPanel( upperTxt, lowerTxt, CYAN ); + + return false; } - if( saveok ) - { - GetBoard()->SetFileName( pcbFileName.GetFullPath() ); - UpdateTitle(); + GetBoard()->SetFileName( pcbFileName.GetFullPath() ); + UpdateTitle(); - // Put the saved file in File History, unless aCreateBackupFile - // is false. - // aCreateBackupFile == false is mainly used to write autosave files - // and not need to have an autosave file in file history - if( aCreateBackupFile ) - UpdateFileHistory( GetBoard()->GetFileName() ); + // Put the saved file in File History, unless aCreateBackupFile + // is false. + // aCreateBackupFile == false is mainly used to write autosave files + // and not need to have an autosave file in file history + if( aCreateBackupFile ) + UpdateFileHistory( GetBoard()->GetFileName() ); - // It's possible that the save as wrote over an existing board file that was part of a - // project so attempt reload the projects settings. - if( isSaveAs ) - LoadProjectSettings( pcbFileName.GetFullPath() ); - } + // Delete auto save file on successful save. + wxFileName autoSaveFileName = pcbFileName; - // Display the file names: - m_messagePanel->EraseMsgBox(); + autoSaveFileName.SetName( wxString( autosavePrefix ) + pcbFileName.GetName() ); - if( saveok ) - { - // Delete auto save file on successful save. - wxFileName autoSaveFileName = pcbFileName; + if( autoSaveFileName.FileExists() ) + wxRemoveFile( autoSaveFileName.GetFullPath() ); - autoSaveFileName.SetName( wxString( autosavePrefix ) + pcbFileName.GetName() ); + if( !!backupFileName ) + upperTxt = _( "Backup file: " ) + backupFileName; - if( autoSaveFileName.FileExists() ) - wxRemoveFile( autoSaveFileName.GetFullPath() ); + lowerTxt = _( "Wrote board file: " ) + pcbFileName.GetFullPath(); - upperTxt = _( "Backup file: " ) + backupFileName.GetFullPath(); - } - - if( saveok ) - lowerTxt = _( "Wrote board file: " ); - else - lowerTxt = _( "Failed to create " ); - - lowerTxt += pcbFileName.GetFullPath(); - - ClearMsgPanel(); AppendMsgPanel( upperTxt, lowerTxt, CYAN ); - GetScreen()->ClrSave(); GetScreen()->ClrModify(); + GetScreen()->ClrSave(); return true; } bool PCB_EDIT_FRAME::doAutoSave() { - wxFileName tmpFileName = GetBoard()->GetFileName(); + wxFileName tmpFileName = Prj().AbsolutePath( GetBoard()->GetFileName() ); wxFileName fn = tmpFileName; // Auto save file name is the normal file name prepended with diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 8c04a1e192..935c11d711 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -52,6 +52,8 @@ #include #include +using namespace PCB_KEYS_T; + #define FMTIU BOARD_ITEM::FormatInternalUnits /** @@ -70,7 +72,7 @@ void filterNetClass( const BOARD& aBoard, NETCLASS& aNetClass ) if( netinfo && netinfo->GetNodesCount() <= 0 ) // hopefully there are no nets with negative aNetClass.Remove( it++ ); // node count, but you never know.. else - ++it; + ++it; } } @@ -307,7 +309,6 @@ void FP_CACHE::Load() void FP_CACHE::Remove( const wxString& aFootprintName ) { - std::string footprintName = TO_UTF8( aFootprintName ); MODULE_CITER it = m_modules.find( footprintName ); diff --git a/pcbnew/loadcmp.cpp b/pcbnew/loadcmp.cpp index 6ef9ba91ec..e9a8e8c2c7 100644 --- a/pcbnew/loadcmp.cpp +++ b/pcbnew/loadcmp.cpp @@ -59,7 +59,7 @@ #include -static void DisplayCmpDoc( wxString& Name ); +static void DisplayCmpDoc( wxString& aName, void* aData ); static FOOTPRINT_LIST MList; @@ -450,7 +450,7 @@ wxString PCB_BASE_FRAME::SelectFootprint( EDA_DRAW_FRAME* aWindow, } -static void DisplayCmpDoc( wxString& aName ) +static void DisplayCmpDoc( wxString& aName, void* aData ) { FOOTPRINT_INFO* module_info = MList.GetModuleInfo( aName ); @@ -494,7 +494,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::SelectFootprint( BOARD* aPcb ) itemsToDisplay.push_back( item ); } - EDA_LIST_DIALOG dlg( this, msg, headers, itemsToDisplay, wxEmptyString, NULL, SORT_LIST ); + EDA_LIST_DIALOG dlg( this, msg, headers, itemsToDisplay, wxEmptyString, NULL, NULL, SORT_LIST ); if( dlg.ShowModal() == wxID_OK ) fpname = dlg.GetTextSelection(); diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp index 88212e408a..8e9c83b67a 100644 --- a/pcbnew/moduleframe.cpp +++ b/pcbnew/moduleframe.cpp @@ -298,6 +298,8 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_Layers->ReFillRender(); m_auimgr.Update(); + + Zoom_Automatique( true ); } diff --git a/pcbnew/modview_frame.cpp b/pcbnew/modview_frame.cpp index 68f1bb5853..c9d3d00f5b 100644 --- a/pcbnew/modview_frame.cpp +++ b/pcbnew/modview_frame.cpp @@ -272,6 +272,7 @@ FOOTPRINT_VIEWER_FRAME::FOOTPRINT_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent #else Zoom_Automatique( false ); #endif + Zoom_Automatique( true ); Show( true ); diff --git a/pcbnew/netlist_reader.h b/pcbnew/netlist_reader.h index 9774d9462f..4d6994142b 100644 --- a/pcbnew/netlist_reader.h +++ b/pcbnew/netlist_reader.h @@ -39,9 +39,6 @@ #include // netlist_lexer is common to Eeschema and Pcbnew -using namespace NL_T; - - class NETLIST; class COMPONENT; @@ -291,7 +288,7 @@ public: class KICAD_NETLIST_PARSER : public NETLIST_LEXER { private: - T token; + NL_T::T token; LINE_READER* m_lineReader; ///< The line reader used to parse the netlist. Not owned. NETLIST* m_netlist; ///< The netlist to parse into. Not owned. @@ -365,7 +362,7 @@ public: void Parse() throw( IO_ERROR, PARSE_ERROR ); // Useful for debug only: - const char* getTokenName( T aTok ) + const char* getTokenName( NL_T::T aTok ) { return NETLIST_LEXER::TokenName( aTok ); } diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 33783ea548..60e40795dc 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -53,6 +53,8 @@ #include +using namespace PCB_KEYS_T; + void PCB_PARSER::init() { diff --git a/pcbnew/pcb_parser.h b/pcbnew/pcb_parser.h index 3d8d6918b2..0e2514bc57 100644 --- a/pcbnew/pcb_parser.h +++ b/pcbnew/pcb_parser.h @@ -34,8 +34,6 @@ #include // LAYER_ID #include // KiROUND -using namespace PCB_KEYS_T; - class BOARD; class BOARD_ITEM; @@ -196,7 +194,7 @@ class PCB_PARSER : public PCB_LEXER return parseDouble(); } - inline double parseDouble( T aToken ) throw( IO_ERROR ) + inline double parseDouble( PCB_KEYS_T::T aToken ) throw( IO_ERROR ) { return parseDouble( GetTokenText( aToken ) ); } @@ -220,7 +218,7 @@ class PCB_PARSER : public PCB_LEXER return KiROUND( parseDouble( aExpected ) * IU_PER_MM ); } - inline int parseBoardUnits( T aToken ) throw( PARSE_ERROR ) + inline int parseBoardUnits( PCB_KEYS_T::T aToken ) throw( PARSE_ERROR ) { return parseBoardUnits( GetTokenText( aToken ) ); } diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 5ae97cd170..c2e20cfb0f 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -193,7 +193,7 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) EVT_MENU( ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, PCB_EDIT_FRAME::ShowDesignRulesEditor ) // Horizontal toolbar - EVT_TOOL( ID_TO_LIBRARY, PCB_EDIT_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_RUN_LIBRARY, PCB_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_SHEET_SET, EDA_DRAW_FRAME::Process_PageSettings ) EVT_TOOL( wxID_CUT, PCB_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( wxID_COPY, PCB_EDIT_FRAME::Process_Special_Functions ) @@ -310,8 +310,6 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) END_EVENT_TABLE() -///////****************************///////////: - #define PCB_EDIT_FRAME_NAME wxT( "PcbFrame" ) PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : @@ -476,6 +474,8 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_auimgr.Update(); setupTools(); + + Zoom_Automatique( true ); } @@ -588,11 +588,14 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) { m_canvas->SetAbortRequest( true ); - if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) + if( GetScreen()->IsModify() ) { - wxString msg; - msg.Printf( _("Save the changes in\n<%s>\nbefore closing?"), - GetChars( GetBoard()->GetFileName() ) ); + wxString msg = wxString::Format( _( + "Save the changes in\n" + "'%s'\n" + "before closing?" ), + GetChars( GetBoard()->GetFileName() ) + ); int ii = DisplayExitDialog( this, msg ); switch( ii ) @@ -621,10 +624,10 @@ void PCB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) // Remove the auto save file on a normal close of Pcbnew. if( fn.FileExists() && !wxRemoveFile( fn.GetFullPath() ) ) { - wxString msg; - - msg.Printf( _( "The auto save file <%s> could not be removed!" ), - GetChars( fn.GetFullPath() ) ); + wxString msg = wxString::Format( _( + "The auto save file '%s' could not be removed!" ), + GetChars( fn.GetFullPath() ) + ); wxMessageBox( msg, Pgm().App().GetAppName(), wxOK | wxICON_ERROR, this ); } @@ -979,6 +982,7 @@ void PCB_EDIT_FRAME::UpdateTitle() SetTitle( title ); } + #if defined(KICAD_SCRIPTING_WXPYTHON) void PCB_EDIT_FRAME::ScriptingConsoleEnableDisable( wxCommandEvent& aEvent ) { @@ -1018,6 +1022,7 @@ void PCB_EDIT_FRAME::ScriptingConsoleEnableDisable( wxCommandEvent& aEvent ) } #endif + void PCB_EDIT_FRAME::OnSelectAutoPlaceMode( wxCommandEvent& aEvent ) { // Automatic placement of modules and tracks is a mutually exclusive operation so diff --git a/pcbnew/pcbnew.cpp b/pcbnew/pcbnew.cpp index 86db046e2c..384a3ca405 100644 --- a/pcbnew/pcbnew.cpp +++ b/pcbnew/pcbnew.cpp @@ -90,7 +90,6 @@ wxPoint g_Offset_Module; /* Distance to offset module trace when moving. */ wxString g_DocModulesFileName = wxT( "footprints_doc/footprints.pdf" ); -// wxWindow* DoPythonStuff(wxWindow* parent); // declaration namespace PCB { @@ -114,8 +113,6 @@ static struct IFACE : public KIFACE_I { PCB_EDIT_FRAME* frame = new PCB_EDIT_FRAME( aKiway, aParent ); - frame->Zoom_Automatique( true ); - #if defined(KICAD_SCRIPTING) // give the scripting helpers access to our frame ScriptingSetPcbEditFrame( frame ); @@ -133,12 +130,6 @@ static struct IFACE : public KIFACE_I case FRAME_PCB_MODULE_EDITOR: { FOOTPRINT_EDIT_FRAME* frame = new FOOTPRINT_EDIT_FRAME( aKiway, aParent ); - - frame->Zoom_Automatique( true ); - - /* Read a default config file in case no project given on command line. - frame->LoadProjectFile( wxEmptyString, true ); - */ return frame; } break; @@ -149,11 +140,6 @@ static struct IFACE : public KIFACE_I FOOTPRINT_VIEWER_FRAME* frame = new FOOTPRINT_VIEWER_FRAME( aKiway, aParent, FRAME_T( aClassId ) ); - frame->Zoom_Automatique( true ); - - /* Read a default config file in case no project given on command line. - frame->LoadProjectFile( wxEmptyString, true ); - */ return frame; } break; @@ -161,7 +147,7 @@ static struct IFACE : public KIFACE_I case FRAME_PCB_FOOTPRINT_WIZARD_MODAL: { FOOTPRINT_WIZARD_FRAME* frame = new FOOTPRINT_WIZARD_FRAME( - aKiway, aParent, FRAME_T( aClassId ) ); + aKiway, aParent, FRAME_T( aClassId ) ); return frame; } @@ -319,7 +305,7 @@ static bool set3DShapesPath( const wxString& aKiSys3Dmod ) } -#ifdef KICAD_SCRIPTING +#if defined(KICAD_SCRIPTING) static bool scriptingSetup() { wxString path_frag; @@ -429,13 +415,6 @@ bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) // Set 3D shape path from environment variable KISYS3DMOD set3DShapesPath( wxT(KISYS3DMOD) ); - /* Now that there are no *.mod files in the standard library, this function - has no utility. User should simply set the variable manually. - Looking for *.mod files which do not exist is fruitless. - - SetFootprintLibTablePath(); - */ - try { // The global table is not related to a specific project. All projects @@ -467,7 +446,7 @@ bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) return false; } -#ifdef KICAD_SCRIPTING +#if defined(KICAD_SCRIPTING) scriptingSetup(); #endif diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index 9fac25ff36..f9f9c41153 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -211,13 +211,17 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) if( !wxFileExists( dlg.GetPath() ) ) { - wxString msg; - msg.Printf( _( "File %s not found" ), GetChars( dlg.GetPath() ) ); + wxString msg = wxString::Format( _( + "File %s not found" ), + GetChars( dlg.GetPath() ) + ); DisplayError( this, msg ); break; } - LoadProjectSettings( dlg.GetPath() ); + wxString pro_file = dlg.GetPath(); + + Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_PCB, GetProjectFileParameters(), pro_file ); } break; @@ -254,19 +258,12 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) } -bool PCB_EDIT_FRAME::LoadProjectSettings( const wxString& aProjectFileName ) +bool PCB_EDIT_FRAME::LoadProjectSettings() { - wxLogDebug( wxT( "Loading project '%s' settings." ), GetChars( aProjectFileName ) ); + wxLogDebug( wxT( "Loading project '%s' settings." ), + GetChars( Prj().GetProjectFullName() ) ); - wxFileName fn = aProjectFileName; - - if( fn.GetExt() != ProjectFileExtension ) - fn.SetExt( ProjectFileExtension ); - - // was: wxGetApp().ReadProjectConfig( fn.GetFullPath(), GROUP, GetProjectFileParameters(), false ); - Prj().ConfigLoad( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP_PCB, GetProjectFileParameters(), false ); - - Prj().ElemClear( PROJECT::ELEM_FPTBL ); // Force it to be reloaded on demand. + bool rc = Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_PCB, GetProjectFileParameters() ); // Load the page layout decr file, from the filename stored in // BASE_SCREEN::m_PageLayoutDescrFileName, read in config project file @@ -274,16 +271,13 @@ bool PCB_EDIT_FRAME::LoadProjectSettings( const wxString& aProjectFileName ) WORKSHEET_LAYOUT& pglayout = WORKSHEET_LAYOUT::GetTheInstance(); pglayout.SetPageLayout( BASE_SCREEN::m_PageLayoutDescrFileName ); - return true; + return rc; } void PCB_EDIT_FRAME::SaveProjectSettings( bool aAskForSave ) { - wxFileName fn; - - fn = GetBoard()->GetFileName(); - fn.SetExt( ProjectFileExtension ); + wxFileName fn = Prj().GetProjectFullName(); if( aAskForSave ) { @@ -297,13 +291,18 @@ void PCB_EDIT_FRAME::SaveProjectSettings( bool aAskForSave ) fn = dlg.GetPath(); } - Prj().ConfigSave( Kiface().KifaceSearch(), fn.GetFullPath(), GROUP_PCB, GetProjectFileParameters() ); + wxString pro_name = fn.GetFullPath(); + + Prj().ConfigSave( Kiface().KifaceSearch(), GROUP_PCB, GetProjectFileParameters(), pro_name ); } PARAM_CFG_ARRAY PCB_EDIT_FRAME::GetProjectFileParameters() { - PARAM_CFG_ARRAY pca; + PARAM_CFG_ARRAY pca; + + // This one cannot be cached because some settings are going to/from the BOARD, + // so pointers into that cannot be saved for long. pca.push_back( new PARAM_CFG_FILENAME( wxT( "PageLayoutDescrFile" ), &BASE_SCREEN::m_PageLayoutDescrFileName ) ); diff --git a/pcbnew/specctra.h b/pcbnew/specctra.h index 94b3154515..84f77ce2d2 100644 --- a/pcbnew/specctra.h +++ b/pcbnew/specctra.h @@ -37,16 +37,15 @@ #include #include - -class TYPE_COLLECTOR; // outside the DSN namespace +// all outside the DSN namespace: +namespace PCB { class TYPE_COLLECTOR; } class BOARD; class TRACK; class VIA; class NETCLASS; class MODULE; -typedef DSN::T DSN_T; -using namespace DSN; +typedef DSN::T DSN_T; /** diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index beda815643..45bc5af051 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -55,7 +55,6 @@ #include - using namespace DSN; @@ -135,6 +134,7 @@ void PCB_EDIT_FRAME::ExportToSpecctra( wxCommandEvent& event ) ExportSpecctraFile( fullFileName ); } + bool PCB_EDIT_FRAME::ExportSpecctraFile( const wxString& aFullFilename ) { SPECCTRA_DB db; @@ -195,6 +195,7 @@ bool PCB_EDIT_FRAME::ExportSpecctraFile( const wxString& aFullFilename ) namespace DSN { + const KICAD_T SPECCTRA_DB::scanPADs[] = { PCB_PAD_T, EOT }; // "specctra reported units" are what we tell the external router that our @@ -259,7 +260,7 @@ static POINT mapPt( const wxPoint& pt ) * @return DRAWSEGMENT* - The first DRAWSEGMENT that has a start or end point matching * aPoint, otherwise NULL if none. */ -static DRAWSEGMENT* findPoint( const wxPoint& aPoint, TYPE_COLLECTOR* items, unsigned aLimit ) +static DRAWSEGMENT* findPoint( const wxPoint& aPoint, ::PCB_TYPE_COLLECTOR* items, unsigned aLimit ) { unsigned min_d = INT_MAX; int ndx_min = 0; @@ -625,9 +626,10 @@ typedef std::map PINMAP; IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, MODULE* aModule ) { - PINMAP pinmap; - TYPE_COLLECTOR moduleItems; - wxString padName; + PINMAP pinmap; + wxString padName; + + PCB_TYPE_COLLECTOR moduleItems; // get all the MODULE's pads. moduleItems.Collect( aModule, scanPADs ); @@ -887,8 +889,9 @@ static void makeCircle( PATH* aPath, DRAWSEGMENT* aGraphic ) void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) throw( IO_ERROR ) { - TYPE_COLLECTOR items; - unsigned prox; // a proximity BIU metric, not an accurate distance + PCB_TYPE_COLLECTOR items; + + unsigned prox; // a proximity BIU metric, not an accurate distance const int STEPS = 36; // for a segmentation of an arc of 360 degrees // Get all the DRAWSEGMENTS and module graphics into 'items', @@ -1365,7 +1368,7 @@ typedef std::pair STRINGSET_PAIR; void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) { - TYPE_COLLECTOR items; + PCB_TYPE_COLLECTOR items; static const KICAD_T scanMODULEs[] = { PCB_MODULE_T, EOT }; @@ -1373,7 +1376,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) // Unless they are unique, we cannot import the session file which comes // back to us later from the router. { - TYPE_COLLECTOR padItems; + PCB_TYPE_COLLECTOR padItems; items.Collect( aBoard, scanMODULEs ); @@ -2168,4 +2171,6 @@ void SPECCTRA_DB::RevertMODULEs( BOARD* aBoard ) modulesAreFlipped = false; } + } // namespace DSN + diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp index 9f4ba54c72..c61ba0d5bd 100644 --- a/pcbnew/xchgmod.cpp +++ b/pcbnew/xchgmod.cpp @@ -515,11 +515,11 @@ void DIALOG_EXCHANGE_MODULE::BrowseAndSelectFootprint( wxCommandEvent& event ) void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent ) { wxFileName fn; - MODULE* Module = GetBoard()->m_Modules; + MODULE* module = GetBoard()->m_Modules; wxString msg; wxString wildcard; - if( Module == NULL ) + if( module == NULL ) { DisplayError( this, _( "No Modules!" ) ); return; @@ -530,7 +530,9 @@ void PCB_EDIT_FRAME::RecreateCmpFileFromBoard( wxCommandEvent& aEvent ) fn.SetExt( ComponentFileExtension ); wildcard = wxGetTranslation( ComponentFileWildcard ); - wxFileDialog dlg( this, _( "Save Component Files" ), wxGetCwd(), + wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() ); + + wxFileDialog dlg( this, _( "Save Component Files" ), pro_dir, fn.GetFullName(), wildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT );