diff --git a/common/lib_table_base.cpp b/common/lib_table_base.cpp index 6b7edc188c..99e0fc11ed 100644 --- a/common/lib_table_base.cpp +++ b/common/lib_table_base.cpp @@ -259,6 +259,19 @@ bool LIB_TABLE::HasLibrary( const wxString& aNickname ) const } +wxString LIB_TABLE::GetFullURI( const wxString& aNickname, bool aExpandEnvVars ) const +{ + const LIB_TABLE_ROW* row = findRow( aNickname ); + + wxString retv; + + if( row ) + retv = row->GetFullURI( aExpandEnvVars ); + + return retv; +} + + LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName ) const { LIB_TABLE* cur = (LIB_TABLE*) this; diff --git a/common/single_top.cpp b/common/single_top.cpp index a1f41ec25d..657bec85d2 100644 --- a/common/single_top.cpp +++ b/common/single_top.cpp @@ -186,6 +186,40 @@ struct APP_SINGLE_TOP : public wxApp return ret; } + +#if defined( DEBUG ) + /** + * Override main loop exception handling on debug builds. + * + * It can be painfully difficult to debug exceptions that happen in wxUpdateUIEvent + * handlers. The override provides a bit more useful information about the exception + * and a breakpoint can be set to pin point the event where the exception was thrown. + */ + virtual bool OnExceptionInMainLoop() override + { + try + { + throw; + } + catch( const std::exception& e ) + { + wxLogError( "Unhandled exception class: %s what: %s", + FROM_UTF8( typeid(e).name() ), + FROM_UTF8( e.what() ) ); + } + catch( const IO_ERROR& ioe ) + { + wxLogError( ioe.What() ); + } + catch(...) + { + wxLogError( "Unhandled exception of unknown type" ); + } + + return false; // continue on. Return false to abort program + } +#endif + #ifdef __WXMAC__ /** diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp index e1a50e14e8..9436c288a9 100644 --- a/eeschema/annotate.cpp +++ b/eeschema/annotate.cpp @@ -6,7 +6,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -94,11 +94,11 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, { if( aAnnotateSchematic ) { - sheets.GetMultiUnitComponents( Prj().SchLibs(), lockedComponents ); + sheets.GetMultiUnitComponents( lockedComponents ); } else { - m_CurrentSheet->GetMultiUnitComponents( Prj().SchLibs(), lockedComponents ); + m_CurrentSheet->GetMultiUnitComponents( lockedComponents ); } } @@ -112,11 +112,11 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic, // Build component list if( aAnnotateSchematic ) { - sheets.GetComponents( Prj().SchLibs(), references ); + sheets.GetComponents( references ); } else { - m_CurrentSheet->GetComponents( Prj().SchLibs(), references ); + m_CurrentSheet->GetComponents( references ); } // Break full components reference in name (prefix) and number: @@ -192,9 +192,9 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn // Build the list of components if( !aOneSheetOnly ) - sheetList.GetComponents( Prj().SchLibs(), componentsList ); + sheetList.GetComponents( componentsList ); else - m_CurrentSheet->GetComponents( Prj().SchLibs(), componentsList ); + m_CurrentSheet->GetComponents( componentsList ); return componentsList.CheckAnnotation( aMessageList ); } diff --git a/eeschema/backanno.cpp b/eeschema/backanno.cpp index 7a745ba6fe..71a581189b 100644 --- a/eeschema/backanno.cpp +++ b/eeschema/backanno.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2008-2016 Wayne Stambaugh + * Copyright (C) 2008 Wayne Stambaugh * Copyright (C) 2004-2016 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -55,7 +55,7 @@ void SCH_EDIT_FRAME::backAnnotateFootprints( const std::string& aChangedSetOfRef SCH_SHEET_LIST sheets( g_RootSheet ); bool isChanged = false; - sheets.GetComponents( Prj().SchLibs(), refs, false ); + sheets.GetComponents( refs, false ); DSNLEXER lexer( aChangedSetOfReferences, FROM_UTF8( __func__ ) ); PTREE doc; @@ -89,8 +89,6 @@ void SCH_EDIT_FRAME::backAnnotateFootprints( const std::string& aChangedSetOfRef else footprint.Empty(); - // DBG( printf( "%s: ref:%s fpid:%s\n", __func__, TO_UTF8( reference ), TO_UTF8( footprint ) ); ) - // Search the component in the flat list for( unsigned ii = 0; ii < refs.GetCount(); ++ii ) { @@ -108,7 +106,6 @@ void SCH_EDIT_FRAME::backAnnotateFootprints( const std::string& aChangedSetOfRef fpfield->SetVisible( false ); } - // DBG( printf("%s: ref:%s fpid:%s\n", __func__, TO_UTF8( refs[ii].GetRef() ), TO_UTF8( footprint ) );) if( oldfp != footprint ) isChanged = true; @@ -136,7 +133,7 @@ bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( const wxString& aFullFilenam SCH_REFERENCE_LIST referencesList; SCH_SHEET_LIST sheetList( g_RootSheet ); - sheetList.GetComponents( Prj().SchLibs(), referencesList, false ); + sheetList.GetComponents( referencesList, false ); FILE* cmpFile = wxFopen( aFullFilename, wxT( "rt" ) ); diff --git a/eeschema/class_sch_screen.h b/eeschema/class_sch_screen.h index 82c95948ca..5239b1235f 100644 --- a/eeschema/class_sch_screen.h +++ b/eeschema/class_sch_screen.h @@ -527,9 +527,9 @@ public: /** - * Class SCH_SCREENS - * is a container class that holds multiple SCH_SCREENs in a hierarchy. - * Individual SCH_SCREENs are unique, and correspond to .sch files. + * Container class that holds multiple #SCH_SCREEN objects in a hierarchy. + * + * Individual #SCH_SCREEN objects are unique and correspond to .sch files. */ class SCH_SCREENS { @@ -546,37 +546,33 @@ public: SCH_SCREEN* GetScreen( unsigned int aIndex ) const; /** - * Function ClearAnnotation - * clears the annotation for all components in the hierarchy. + * Clear the annotation for all components in the hierarchy. */ void ClearAnnotation(); /** - * Function SchematicCleanUp - * merges and breaks wire segments in the entire schematic hierarchy. + * Merge and break wire segments in the entire schematic hierarchy. */ void SchematicCleanUp(); /** - * Function ReplaceDuplicateTimeStamps - * test all sheet and component objects in the schematic for duplicate time stamps - * an replaces them as necessary. Time stamps must be unique in order for complex - * hierarchies know which components go to which sheets. + * Test all sheet and component objects in the schematic for duplicate time stamps + * and replaces them as necessary. + * Time stamps must be unique in order for complex hierarchies know which components go + * to which sheets. * @return The number of duplicate time stamps replaced. */ int ReplaceDuplicateTimeStamps(); /** - * Function DeleteAllMarkers - * deletes all electronic rules check markers of \a aMarkerType from all the screens in + * Delete all electronic rules check markers of \a aMarkerType from all the screens in * the list. * @param aMarkerType Type of markers to be deleted. */ void DeleteAllMarkers( enum MARKER_BASE::TYPEMARKER aMarkerType ); /** - * Function GetMarkerCount - * returns the number of ERC markers of \a aMarkerType from all of the screens in the list. + * Return the number of ERC markers of \a aMarkerType from all of the screens in the list. * * @param aMarkerType Indicates the type of marker to count. if MARKER_UNSPEC * all markers are counted. @@ -588,8 +584,9 @@ public: enum MARKER_BASE::MARKER_SEVERITY aSeverity ); /** - * initializes or reinitializes the weak reference - * to the LIB_PART for each SCH_COMPONENT found in the full schematic + * Initialize or reinitialize the weak reference to the #LIB_PART for each #SCH_COMPONENT + * found in the full schematic. + * * It must be called from: * - Draw function * - when loading a schematic file @@ -600,15 +597,14 @@ public: void TestDanglingEnds(); /** - * Function HasNoFullyDefinedLibIds - * - * tests all of the schematic symbols to see if all #LIB_ID objects library nickname is not + * Test all of the schematic symbols to see if all #LIB_ID objects library nickname is not * set. * * If none of the #LIB_ID object library nicknames are not set, this indicates that the * project was created before the symbol library implementation. * - * @return true if all of the #LIB_ID object library nick names are empty, otherwise false. + * @return true in there are any symbols and if all of the #LIB_ID object library nicknames + * are empty, otherwise false. */ bool HasNoFullyDefinedLibIds(); diff --git a/eeschema/dialogs/dialog_bom_editor.cpp b/eeschema/dialogs/dialog_bom_editor.cpp index 11eb185498..92fca290cb 100644 --- a/eeschema/dialogs/dialog_bom_editor.cpp +++ b/eeschema/dialogs/dialog_bom_editor.cpp @@ -308,7 +308,7 @@ void DIALOG_BOM_EDITOR::LoadComponents() // Generate a list of schematic sheets SCH_SHEET_LIST sheets( g_RootSheet ); - sheets.GetComponents( m_parent->Prj().SchLibs(), refs, false ); + sheets.GetComponents( refs, false ); // Pass the references through to the model m_bom->SetComponents( refs, m_parent->GetTemplateFieldNames() ); diff --git a/eeschema/dialogs/dialog_choose_component.cpp b/eeschema/dialogs/dialog_choose_component.cpp index 87a93061c6..01886e9c40 100644 --- a/eeschema/dialogs/dialog_choose_component.cpp +++ b/eeschema/dialogs/dialog_choose_component.cpp @@ -253,17 +253,20 @@ void DIALOG_CHOOSE_COMPONENT::PopulateFootprintSelector( LIB_ID const& aLibId ) LIB_ALIAS* alias = nullptr; - try + if( aLibId.IsValid() ) { - alias = Prj().SchSymbolLibTable()->LoadSymbol( aLibId ); - } - catch( const IO_ERROR& ioe ) - { - wxLogError( wxString::Format( _( "Error occurred loading symbol %s from library %s." - "\n\n%s" ), - aLibId.GetLibItemName().wx_str(), - aLibId.GetLibNickname().wx_str(), - ioe.What() ) ); + try + { + alias = Prj().SchSymbolLibTable()->LoadSymbol( aLibId ); + } + catch( const IO_ERROR& ioe ) + { + wxLogError( wxString::Format( _( "Error occurred loading symbol %s from library %s." + "\n\n%s" ), + aLibId.GetLibItemName().wx_str(), + aLibId.GetLibNickname().wx_str(), + ioe.What() ) ); + } } if( alias != nullptr ) diff --git a/eeschema/dialogs/dialog_edit_component_in_lib.cpp b/eeschema/dialogs/dialog_edit_component_in_lib.cpp index 14f54ca5d4..ca3639e8e4 100644 --- a/eeschema/dialogs/dialog_edit_component_in_lib.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_lib.cpp @@ -5,7 +5,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -36,6 +36,7 @@ #include #include #include // for MAX_UNIT_COUNT_PER_PACKAGE definition +#include #include @@ -316,14 +317,14 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::DeleteAllAliasOfPart( wxCommandEvent& eve */ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::AddAliasOfPart( wxCommandEvent& event ) { - wxString aliasname; - LIB_PART* component = m_Parent->GetCurPart(); - PART_LIB* library = m_Parent->GetCurLib(); + wxString aliasname; + LIB_PART* component = m_Parent->GetCurPart(); + wxString library = m_Parent->GetCurLib(); if( component == NULL ) return; - wxTextEntryDialog dlg( this, _( "New alias:" ), _( "Component Alias" ), aliasname ); + wxTextEntryDialog dlg( this, _( "New Alias:" ), _( "Symbol alias:" ), aliasname ); if( dlg.ShowModal() != wxID_OK ) return; // cancelled by user @@ -331,6 +332,7 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::AddAliasOfPart( wxCommandEvent& event ) aliasname = dlg.GetValue( ); aliasname.Replace( wxT( " " ), wxT( "_" ) ); + if( aliasname.IsEmpty() ) return; @@ -343,12 +345,10 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::AddAliasOfPart( wxCommandEvent& event ) return; } - if( library && library->FindAlias( aliasname ) != NULL ) + if( !library.empty() && Prj().SchSymbolLibTable()->LoadSymbol( library, aliasname ) != NULL ) { wxString msg; - msg.Printf( _( "Alias or component name <%s> already exists in library <%s>." ), - GetChars( aliasname ), - GetChars( library->GetName() ) ); + msg.Printf( _( "Symbol name '%s' already exists in library '%s'." ), aliasname, library ); DisplayError( this, msg ); return; } diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp index e9500d8308..a500ec7add 100644 --- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp +++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp @@ -43,11 +43,13 @@ #include #include #include +#include #include #include #include + #ifdef KICAD_SPICE #include #include @@ -59,36 +61,36 @@ /** - * class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC - * is hand coded and implements DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP which - * is maintained by wxFormBuilder. Do not auto-generate this class or file, - * it is hand coded. + * Dialog used to edit #SCH_COMPONENT objects in a schematic. + * + * This is derived from DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP which is maintained by + * wxFormBuilder. Do not auto-generate this class or file, it is hand coded. */ class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC : public DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP { public: - /** Constructor */ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC( wxWindow* aParent ); /** - * Function InitBuffers - * sets up to edit the given component. + * Initialize controls with \a aComponent. + *. * @param aComponent The component to edit. */ void InitBuffers( SCH_COMPONENT* aComponent ); + SCH_EDIT_FRAME* GetParent() { return dynamic_cast< SCH_EDIT_FRAME* >( wxDialog::GetParent() ); } + private: friend class SCH_EDIT_FRAME; - SCH_EDIT_FRAME* m_parent; SCH_COMPONENT* m_cmp; LIB_PART* m_part; bool m_skipCopyFromPanel; static int s_SelectedRow; - /// a copy of the edited component's SCH_FIELDs + /// a copy of the edited symbol's SCH_FIELDs SCH_FIELDS m_FieldsBuf; void setSelectedFieldNdx( int aFieldNdx ); @@ -96,17 +98,13 @@ private: int getSelectedFieldNdx(); /** - * Function copySelectedFieldToPanel - * sets the values displayed on the panel according to - * the currently selected field row + * Sets the values displayed on the panel according to the currently selected field row. */ void copySelectedFieldToPanel(); - /** - * Function copyPanelToSelectedField - * copies the values displayed on the panel fields to the currently - * selected field + * Copy the values displayed on the panel fields to the currently selected field. + * * @return bool - true if all fields are OK, else false if the user has put * bad data into a field, and this value can be used to deny a row change. */ @@ -151,9 +149,9 @@ private: SCH_FIELD* findField( const wxString& aFieldName ); /** - * Function updateDisplay - * update the listbox showing fields, according to the fields texts - * must be called after a text change in fields, if this change is not an edition + * Update the listbox showing fields according to the field's text. + * + * This must be called after a text change in fields if this change is not an edition. */ void updateDisplay() { @@ -203,12 +201,12 @@ void SCH_EDIT_FRAME::EditComponent( SCH_COMPONENT* aComponent ) DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::DIALOG_EDIT_COMPONENT_IN_SCHEMATIC( wxWindow* aParent ) : DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_FBP( aParent ) { + wxASSERT( dynamic_cast< SCH_EDIT_FRAME* >( aParent ) ); + #ifndef KICAD_SPICE spiceFieldsButton->Hide(); #endif /* not KICAD_SPICE */ - m_parent = (SCH_EDIT_FRAME*) aParent; - m_cmp = NULL; m_part = NULL; m_skipCopyFromPanel = false; @@ -251,47 +249,39 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnListItemDeselected( wxListEvent& even void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnTestChipName( wxCommandEvent& event ) { - wxString partname = chipnameTextCtrl->GetValue(); - LIB_PART* entry = Prj().SchLibs()->FindLibPart( partname ); - + LIB_ID id; wxString msg; + wxString partname = chipnameTextCtrl->GetValue(); - if( entry ) + if( id.Parse( partname ) != -1 || !id.IsValid() ) { - msg.Printf( _( "Component '%s' found in library '%s'" ), - GetChars( partname ), GetChars( entry->GetLibraryName() ) ); - wxMessageBox( msg ); + msg.Printf( _( "'%s' is not a valid library symbol indentifier." ), partname ); + DisplayError( this, msg ); return; } - msg.Printf( _( "Component '%s' not found in any library" ), GetChars( partname ) ); + LIB_ALIAS* alias = NULL; - // Try to find components which have a name "near" the current chip name, - // i.e. the same name when the comparison is case insensitive. - // Could be helpful for old designs when lower cases and upper case were - // equivalent. - std::vector candidates; - Prj().SchLibs()->FindLibraryNearEntries( candidates, partname ); - - if( candidates.size() == 0 ) + try { - wxMessageBox( msg ); + alias = Prj().SchSymbolLibTable()->LoadSymbol( id ); + } + catch( ... ) + { + } + + if( !alias ) + { + msg.Printf( _( "Symbol '%s' not found in library '%s'" ), + id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() ); + DisplayError( this, msg ); return; } - // Some candidates are found. Show them: - msg << wxT("\n") << _( "However, some candidates are found:" ); + msg.Printf( _( "Symbol '%s' found in library '%s'" ), + id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() ); - // add candidate names: - for( unsigned ii = 0; ii < candidates.size(); ii++ ) - { - msg << wxT("\n") << - wxString::Format( _( "'%s' found in library '%s'" ), - GetChars( candidates[ii]->GetName() ), - GetChars( candidates[ii]->GetLibraryName() ) ); - } - - wxMessageBox( msg ); + DisplayInfoMessage( this, msg ); } @@ -299,12 +289,14 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnSelectChipName( wxCommandEvent& event { SCH_BASE_FRAME::HISTORY_LIST dummy; - auto sel = m_parent->SelectComponentFromLibrary( NULL, dummy, true, 0, 0 ); + auto sel = GetParent()->SelectComponentFromLibrary( NULL, dummy, true, 0, 0 ); - if( sel.Name.IsEmpty() ) + if( sel.Name.IsEmpty() || sel.LibNickname.IsEmpty() ) return; - chipnameTextCtrl->SetValue( sel.Name ); + LIB_ID id( sel.LibNickname, sel.Name ); + + chipnameTextCtrl->SetValue( id.Format() ); } @@ -322,8 +314,6 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::EditSpiceModel( wxCommandEvent& event ) void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnListItemSelected( wxListEvent& event ) { - DBG( printf( "OnListItemSelected()\n" ); ) - // remember the selected row, statically s_SelectedRow = event.GetIndex(); @@ -352,36 +342,46 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnCancelButtonClick( wxCommandEvent& ev void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyPanelToOptions() { LIB_ID id; + wxString msg; wxString tmp = chipnameTextCtrl->GetValue(); tmp.Replace( wxT( " " ), wxT( "_" ) ); - id.SetLibItemName( tmp, false ); + id.Parse( tmp ); // Save current flags which could be modified by next change settings STATUS_FLAGS flags = m_cmp->GetFlags(); - if( id.empty() ) + if( !id.IsValid() ) { - DisplayError( NULL, _( "No Component Name!" ) ); + msg.Printf( _( "Symbol library identifier '%s' is not valid!" ), tmp ); + DisplayError( this, msg ); } else if( id != m_cmp->GetLibId() ) { - PART_LIBS* libs = Prj().SchLibs(); + LIB_ALIAS* alias = NULL; - if( libs->FindLibraryAlias( id ) == NULL ) + try { - wxString msg = wxString::Format( _( "Component '%s' not found!" ), - GetChars( id.Format() ) ); + alias = Prj().SchSymbolLibTable()->LoadSymbol( id ); + } + catch( ... ) + { + } + + if( !alias ) + { + msg.Printf( _( "Symbol '%s' not found in library '%s'!" ), + id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() ); DisplayError( this, msg ); } - else // Change component from lib! + else // Change symbol from lib! { - m_cmp->SetLibId( id, libs ); + m_cmp->SetLibId( id, Prj().SchSymbolLibTable(), Prj().SchLibs()->GetCacheLibrary() ); } } - // For components with multiple shapes (De Morgan representation) Set the selected shape: + // For symbols with multiple shapes (De Morgan representation) Set the selected shape: if( convertCheckBox->IsEnabled() ) { m_cmp->SetConvert( convertCheckBox->GetValue() ? 2 : 1 ); @@ -392,7 +392,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::copyPanelToOptions() { int unit_selection = unitChoice->GetCurrentSelection() + 1; - m_cmp->SetUnitSelection( &m_parent->GetCurrentSheet(), unit_selection ); + m_cmp->SetUnitSelection( &GetParent()->GetCurrentSheet(), unit_selection ); m_cmp->SetUnit( unit_selection ); } @@ -453,8 +453,8 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event // save old cmp in undo list if not already in edit, or moving ... // or the component to be edited is part of a block if( m_cmp->GetFlags() == 0 - || m_parent->GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK ) - m_parent->SaveCopyInUndoList( m_cmp, UR_CHANGED ); + || GetParent()->GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK ) + GetParent()->SaveCopyInUndoList( m_cmp, UR_CHANGED ); copyPanelToOptions(); @@ -468,8 +468,8 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event // correct the problem before removing the undefined fields. It should also // resolve most of the bug reports and questions regarding missing fields. if( !m_FieldsBuf[i].GetName( false ).IsEmpty() && m_FieldsBuf[i].GetText().IsEmpty() - && !m_parent->GetTemplates().HasFieldName( m_FieldsBuf[i].GetName( false ) ) - && !removeRemainingFields ) + && !GetParent()->GetTemplates().HasFieldName( m_FieldsBuf[i].GetName( false ) ) + && !removeRemainingFields ) { wxString msg = wxString::Format( _( "The field name <%s> does not have a value and is not defined in " @@ -500,7 +500,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event m_FieldsBuf[i].Offset( m_cmp->m_Pos ); } - LIB_PART* entry = Prj().SchLibs()->FindLibPart( m_cmp->GetLibId() ); + LIB_PART* entry = GetParent()->GetLibPart( m_cmp->GetLibId() ); if( entry && entry->IsPower() ) m_FieldsBuf[VALUE].SetText( m_cmp->GetLibId().GetLibItemName() ); @@ -511,10 +511,10 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event // Reference has a specific initialization, depending on the current active sheet // because for a given component, in a complex hierarchy, there are more than one // reference. - m_cmp->SetRef( &m_parent->GetCurrentSheet(), m_FieldsBuf[REFERENCE].GetText() ); + m_cmp->SetRef( &GetParent()->GetCurrentSheet(), m_FieldsBuf[REFERENCE].GetText() ); - m_parent->OnModify(); - m_parent->GetScreen()->TestDanglingEnds(); + GetParent()->OnModify(); + GetParent()->GetScreen()->TestDanglingEnds(); EndQuasiModal( wxID_OK ); } @@ -598,7 +598,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::showButtonHandler( wxCommandEvent& even // pick a footprint using the footprint picker. wxString fpid; - KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true, m_parent ); + KIWAY_PLAYER* frame = Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true, GetParent() ); if( frame->ShowModal( &fpid, this ) ) { @@ -743,7 +743,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::InitBuffers( SCH_COMPONENT* aComponent which came from the component. */ - m_part = Prj().SchLibs()->FindLibPart( m_cmp->GetLibId() ); + m_part = GetParent()->GetLibPart( m_cmp->GetLibId() ); #if 0 && defined(DEBUG) for( int i = 0; iGetFieldCount(); ++i ) @@ -773,7 +773,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::InitBuffers( SCH_COMPONENT* aComponent // Add template fieldnames: // Now copy in the template fields, in the order that they are present in the // template field editor UI. - const TEMPLATE_FIELDNAMES& tfnames = m_parent->GetTemplateFieldNames(); + const TEMPLATE_FIELDNAMES& tfnames = GetParent()->GetTemplateFieldNames(); for( TEMPLATE_FIELDNAMES::const_iterator it = tfnames.begin(); it!=tfnames.end(); ++it ) { @@ -832,7 +832,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::InitBuffers( SCH_COMPONENT* aComponent } #endif - m_FieldsBuf[REFERENCE].SetText( m_cmp->GetRef( &m_parent->GetCurrentSheet() ) ); + m_FieldsBuf[REFERENCE].SetText( m_cmp->GetRef( &GetParent()->GetCurrentSheet() ) ); for( unsigned i = 0; iAppend( LIB_PART::SubReference( ii, false ) ); } - // For components with multiple parts per package, set the unit selection + // For symbols with multiple parts per package, set the unit selection if( m_cmp->GetUnit() <= (int)unitChoice->GetCount() ) unitChoice->SetSelection( m_cmp->GetUnit() - 1 ); @@ -1160,14 +1160,14 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::SetInitCmp( wxCommandEvent& event ) if( !m_cmp ) return; - if( LIB_PART* part = Prj().SchLibs()->FindLibPart( m_cmp->GetLibId() ) ) + if( LIB_PART* part = GetParent()->GetLibPart( m_cmp->GetLibId() ) ) { // save old cmp in undo list if not already in edit, or moving ... if( m_cmp->GetFlags() == 0 ) - m_parent->SaveCopyInUndoList( m_cmp, UR_CHANGED ); + GetParent()->SaveCopyInUndoList( m_cmp, UR_CHANGED ); - INSTALL_UNBUFFERED_DC( dc, m_parent->GetCanvas() ); - m_cmp->Draw( m_parent->GetCanvas(), &dc, wxPoint( 0, 0 ), g_XorMode ); + INSTALL_UNBUFFERED_DC( dc, GetParent()->GetCanvas() ); + m_cmp->Draw( GetParent()->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, @@ -1201,9 +1201,9 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::SetInitCmp( wxCommandEvent& event ) m_cmp->SetOrientation( CMP_NORMAL ); - m_parent->OnModify(); + GetParent()->OnModify(); - m_cmp->Draw( m_parent->GetCanvas(), &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); + m_cmp->Draw( GetParent()->GetCanvas(), &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); EndQuasiModal( wxID_OK ); } diff --git a/eeschema/dialogs/dialog_edit_one_field.cpp b/eeschema/dialogs/dialog_edit_one_field.cpp index d65f997cda..20ba49d7c9 100644 --- a/eeschema/dialogs/dialog_edit_one_field.cpp +++ b/eeschema/dialogs/dialog_edit_one_field.cpp @@ -8,7 +8,7 @@ * * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.com * Copyright (C) 2016 Wayne Stambaugh, stambaughw@gmail.com - * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -277,7 +277,7 @@ DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, wxASSERT_MSG( component != NULL && component->Type() == SCH_COMPONENT_T, wxT( "Invalid schematic field parent item." ) ); - const LIB_PART* part = GetParent()->Prj().SchLibs()->FindLibPart( component->GetLibId() ); + const LIB_PART* part = GetParent()->GetLibPart( component->GetLibId() ); wxASSERT_MSG( part, wxT( "Library part for component <" ) + component->GetLibId().Format() + wxT( "> could not be found." ) ); diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp index bf7770f6ca..cbf972d24a 100644 --- a/eeschema/dialogs/dialog_erc.cpp +++ b/eeschema/dialogs/dialog_erc.cpp @@ -458,7 +458,7 @@ void DIALOG_ERC::TestErc( wxArrayString* aMessagesList ) // Build the whole sheet list in hierarchy (sheet, not screen) SCH_SHEET_LIST sheets( g_RootSheet ); - sheets.AnnotatePowerSymbols( Prj().SchLibs() ); + sheets.AnnotatePowerSymbols(); if( m_parent->CheckAnnotate( aMessagesList, false ) ) { diff --git a/eeschema/dialogs/dialog_symbol_remap.cpp b/eeschema/dialogs/dialog_symbol_remap.cpp index 3c43fcbb09..b3982780d9 100644 --- a/eeschema/dialogs/dialog_symbol_remap.cpp +++ b/eeschema/dialogs/dialog_symbol_remap.cpp @@ -221,7 +221,7 @@ void DIALOG_SYMBOL_REMAP::remapSymbolsToLibTable( REPORTER& aReporter ) if( !remapSymbolToLibTable( symbol ) ) { - msg.Printf( _( "No symbol '%s' founded in symbol library table." ), + msg.Printf( _( "No symbol '%s' found in symbol library table." ), symbol->GetLibId().GetLibItemName().wx_str() ); aReporter.Report( msg, REPORTER::RPT_WARNING ); } @@ -237,6 +237,7 @@ void DIALOG_SYMBOL_REMAP::remapSymbolsToLibTable( REPORTER& aReporter ) } aReporter.Report( _( "Symbol library table mapping complete!" ), REPORTER::RPT_INFO ); + schematic.UpdateSymbolLinks(); } diff --git a/eeschema/edit_component_in_schematic.cpp b/eeschema/edit_component_in_schematic.cpp index 9ea4798164..32f53cd635 100644 --- a/eeschema/edit_component_in_schematic.cpp +++ b/eeschema/edit_component_in_schematic.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2008-2017 Wayne Stambaugh + * Copyright (C) 2008 Wayne Stambaugh * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -52,10 +53,22 @@ void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField ) wxCHECK_RET( component != NULL && component->Type() == SCH_COMPONENT_T, wxT( "Invalid schematic field parent item." ) ); - LIB_PART* part = Prj().SchLibs()->FindLibPart( component->GetLibId() ); + LIB_ID id = component->GetLibId(); + LIB_ALIAS* alias = NULL; - wxCHECK_RET( part, wxT( "Library part for component <" ) + - component->GetLibId().GetLibItemName() + wxT( "> could not be found." ) ); + try + { + alias = Prj().SchSymbolLibTable()->LoadSymbol( id ); + } + catch( ... ) + { + } + + LIB_PART* part = ( alias ) ? alias->GetPart() : NULL; + + wxCHECK_RET( part, wxString::Format( "Symbol '%s' not found in library '%s'", + id.GetLibItemName().wx_str(), + id.GetLibNickname().wx_str() ) ); // Save old component in undo list if not already in edit, or moving. if( aField->GetFlags() == 0 ) diff --git a/eeschema/find.cpp b/eeschema/find.cpp index 6515cdae35..5e7962e447 100644 --- a/eeschema/find.cpp +++ b/eeschema/find.cpp @@ -2,8 +2,8 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2008-2016 Wayne Stambaugh - * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2008 Wayne Stambaugh + * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -285,8 +286,7 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference, bool SCH_EDIT_FRAME::IsSearchCacheObsolete( const SCH_FIND_REPLACE_DATA& aSearchCriteria ) { - PART_LIBS* libs = Prj().SchLibs(); - int mod_hash = libs->GetModifyHash(); + int mod_hash = Prj().SchSymbolLibTable()->GetModifyHash(); // the cache is obsolete whenever any library changes. if( mod_hash != m_foundItems.GetLibHash() ) diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp index 1239b1b8cf..62e49e66fb 100644 --- a/eeschema/getpart.cpp +++ b/eeschema/getpart.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2008-2017 Wayne Stambaugh + * Copyright (C) 2008 Wayne Stambaugh * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -166,8 +166,7 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibrary( if( !aHighlight.IsEmpty() ) adapter->SetPreselectNode( aHighlight, /* aUnit */ 0 ); - dialogTitle.Printf( _( "Choose Component (%d items loaded)" ), - adapter->GetComponentsCount() ); + dialogTitle.Printf( _( "Choose Symbol (%d items loaded)" ), adapter->GetComponentsCount() ); DIALOG_CHOOSE_COMPONENT dlg( this, dialogTitle, adapter, aConvert, aAllowFields ); if( dlg.ShowQuasiModal() == wxID_CANCEL ) @@ -184,6 +183,7 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibrary( sel.Fields = dlg.GetFields(); sel.Name = id.GetLibItemName(); + sel.LibNickname = id.GetLibNickname(); if( dlg.IsExternalBrowserSelected() ) // User requested component browser. sel = SelectComponentFromLibBrowser( aFilter, id, sel.Unit, sel.Convert ); @@ -194,7 +194,8 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibrary( std::remove_if( aHistoryList.begin(), aHistoryList.end(), - [ &sel ]( COMPONENT_SELECTION const& i ) { return i.Name == sel.Name; } ), + [ &sel ]( COMPONENT_SELECTION const& i ){ return i.Name == sel.Name + && i.LibNickname == sel.LibNickname; } ), aHistoryList.end() ); aHistoryList.insert( aHistoryList.begin(), sel ); @@ -204,19 +205,19 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibrary( } -SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( - wxDC* aDC, - const SCHLIB_FILTER* aFilter, - SCH_BASE_FRAME::HISTORY_LIST& aHistoryList, - bool aUseLibBrowser ) +SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( wxDC* aDC, + const SCHLIB_FILTER* aFilter, + SCH_BASE_FRAME::HISTORY_LIST& aHistoryList, + bool aUseLibBrowser ) { + wxString msg; + SetRepeatItem( NULL ); m_canvas->SetIgnoreMouseEvents( true ); - auto sel = SelectComponentFromLibrary( aFilter, aHistoryList, - aUseLibBrowser, 1, 1 ); + auto sel = SelectComponentFromLibrary( aFilter, aHistoryList, aUseLibBrowser, 1, 1 ); - if( sel.Name.IsEmpty() ) + if( sel.Name.IsEmpty() || sel.LibNickname.IsEmpty() ) { m_canvas->SetIgnoreMouseEvents( false ); m_canvas->MoveCursorToCrossHair(); @@ -231,17 +232,15 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( if( aFilter ) libsource = aFilter->GetLibSource(); - LIB_PART* part = Prj().SchLibs()->FindLibPart( LIB_ID( wxEmptyString, sel.Name ), libsource ); + LIB_ID libId; + + libId.SetLibItemName( sel.Name, false ); + libId.SetLibNickname( sel.LibNickname ); + + LIB_PART* part = GetLibPart( libId, true ); if( !part ) - { - wxString msg = wxString::Format( _( - "Failed to find part '%s' in library" ), - GetChars( sel.Name ) - ); - wxMessageBox( msg ); return NULL; - } SCH_COMPONENT* component = new SCH_COMPONENT( *part, m_CurrentSheet, sel.Unit, sel.Convert, GetCrossHairPosition(), true ); @@ -249,13 +248,10 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( // Set the m_ChipName value, from component name in lib, for aliases // Note if part is found, and if name is an alias of a component, // alias exists because its root component was found - LIB_ID libId; - - libId.SetLibItemName( sel.Name, false ); component->SetLibId( libId ); // Be sure the link to the corresponding LIB_PART is OK: - component->Resolve( Prj().SchLibs() ); + component->Resolve( *Prj().SchSymbolLibTable() ); // Set any fields that have been modified for( auto const& i : sel.Fields ) @@ -330,9 +326,6 @@ void SCH_EDIT_FRAME::OrientComponent( COMPONENT_ORIENTATION_T aOrientation ) } -/* - * Handle select part in multi-unit part. - */ void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); @@ -349,68 +342,77 @@ void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent ) int unit = aEvent.GetId() + 1 - ID_POPUP_SCH_SELECT_UNIT1; - if( LIB_PART* part = Prj().SchLibs()->FindLibPart( component->GetLibId() ) ) - { - int unitCount = part->GetUnitCount(); + LIB_PART* part = GetLibPart( component->GetLibId() ); - wxCHECK_RET( (unit >= 1) && (unit <= unitCount), - wxString::Format( wxT( "Cannot select unit %d from component " ), unit ) + - part->GetName() ); + if( !part ) + return; - if( unitCount <= 1 || component->GetUnit() == unit ) - return; + int unitCount = part->GetUnitCount(); - if( unit > unitCount ) - unit = unitCount; + wxCHECK_RET( (unit >= 1) && (unit <= unitCount), + wxString::Format( wxT( "Cannot select unit %d from component " ), unit ) + + part->GetName() ); - STATUS_FLAGS flags = component->GetFlags(); + if( unitCount <= 1 || component->GetUnit() == unit ) + return; - if( !flags ) // No command in progress: save in undo list - SaveCopyInUndoList( component, UR_CHANGED ); + if( unit > unitCount ) + unit = unitCount; - 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 ); + STATUS_FLAGS flags = component->GetFlags(); - /* 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 ) // No command in progress: save in undo list + SaveCopyInUndoList( component, UR_CHANGED ); - if( m_autoplaceFields ) - component->AutoAutoplaceFields( GetScreen() ); + 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( screen->TestDanglingEnds() ) - m_canvas->Refresh(); + /* Update the unit number. */ + component->SetUnitSelection( m_CurrentSheet, unit ); + component->SetUnit( unit ); + component->ClearFlags(); + component->SetFlags( flags ); // Restore m_Flag modified by SetUnit() - OnModify(); - } + if( m_autoplaceFields ) + component->AutoAutoplaceFields( GetScreen() ); + + if( screen->TestDanglingEnds() ) + m_canvas->Refresh(); + + OnModify(); } -void SCH_EDIT_FRAME::ConvertPart( SCH_COMPONENT* DrawComponent, wxDC* DC ) +void SCH_EDIT_FRAME::ConvertPart( SCH_COMPONENT* aComponent, wxDC* DC ) { - if( !DrawComponent ) + if( !aComponent ) return; - if( LIB_PART* part = Prj().SchLibs()->FindLibPart( DrawComponent->GetLibId() ) ) + LIB_ID id = aComponent->GetLibId(); + LIB_PART* part = GetLibPart( id ); + + if( part ) { + wxString msg; + if( !part->HasConversion() ) { - DisplayError( this, wxT( "No convert found" ) ); + msg.Printf( _( "No alternate body style found for symbol '%s' in library '%s'." ), + id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() ); + DisplayError( this, msg ); return; } - STATUS_FLAGS flags = DrawComponent->GetFlags(); + STATUS_FLAGS flags = aComponent->GetFlags(); - if( DrawComponent->GetFlags() ) - DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); + if( aComponent->GetFlags() ) + aComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); else - DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode ); + aComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode ); - DrawComponent->SetConvert( DrawComponent->GetConvert() + 1 ); + aComponent->SetConvert( aComponent->GetConvert() + 1 ); // ensure m_Convert = 0, 1 or 2 // 0 and 1 = shape 1 = not converted @@ -418,20 +420,20 @@ void SCH_EDIT_FRAME::ConvertPart( SCH_COMPONENT* DrawComponent, wxDC* DC ) // > 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 ); + if( aComponent->GetConvert() > 2 ) + aComponent->SetConvert( 1 ); // The alternate symbol may cause a change in the connection status so test the // connections so the connection indicators are drawn correctly. GetScreen()->TestDanglingEnds(); - DrawComponent->ClearFlags(); - DrawComponent->SetFlags( flags ); // Restore m_Flag (modified by SetConvert()) + aComponent->ClearFlags(); + aComponent->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 ); + if( aComponent->IsMoving() ) + aComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), g_XorMode, g_GhostColor ); else - DrawComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); + aComponent->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); OnModify(); } diff --git a/eeschema/lib_export.cpp b/eeschema/lib_export.cpp index 4d4a3a4f88..083c968801 100644 --- a/eeschema/lib_export.cpp +++ b/eeschema/lib_export.cpp @@ -2,8 +2,8 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2008-2016 Wayne Stambaugh - * Copyright (C) 2004-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2008 Wayne Stambaugh + * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -46,9 +46,10 @@ extern int ExportPartId; void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event ) { + wxString msg; m_lastDrawItem = NULL; - wxFileDialog dlg( this, _( "Import Component" ), m_mruPath, + wxFileDialog dlg( this, _( "Import Symbol" ), m_mruPath, wxEmptyString, SchematicLibraryFileWildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST ); @@ -59,44 +60,38 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event ) m_mruPath = fn.GetPath(); - std::unique_ptr lib; + wxArrayString symbols; + SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) ); try { - std::unique_ptr new_lib( PART_LIB::LoadLibrary( fn.GetFullPath() ) ); - lib = std::move( new_lib ); + pi->EnumerateSymbolLib( symbols, fn.GetFullPath() ); } - catch( const IO_ERROR& ) + catch( const IO_ERROR& ioe ) { - wxString msg = wxString::Format( _( - "Unable to import library '%s'. Error:\n" - "%s" ), - GetChars( fn.GetFullPath() ) - ); - - DisplayError( this, msg ); + msg.Printf( _( "Cannot import symbol library '%s'." ), fn.GetFullPath() ); + DisplayErrorMessage( this, msg, ioe.What() ); return; } - wxArrayString aliasNames; - - lib->GetAliasNames( aliasNames ); - - if( aliasNames.IsEmpty() ) + if( symbols.empty() ) { - wxString msg = wxString::Format( _( "Part library file '%s' is empty." ), - GetChars( fn.GetFullPath() ) ); + msg.Printf( _( "Symbol library file '%s' is empty." ), fn.GetFullPath() ); DisplayError( this, msg ); return; } - LIB_ALIAS* entry = lib->FindAlias( aliasNames[0] ); + LIB_ALIAS* entry = pi->LoadSymbol( fn.GetFullPath(), symbols[0] ); - if( LoadOneLibraryPartAux( entry, lib.get() ) ) + if( LoadOneLibraryPartAux( entry, fn.GetFullPath() ) ) { DisplayLibInfos(); GetScreen()->ClearUndoRedoList(); Zoom_Automatique( false ); + + // This effectively adds a new symbol to the library. Set the modified flag so the + // save library toolbar button and menu entry are enabled. + OnModify(); } } @@ -110,15 +105,16 @@ void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event ) if( !part ) { - DisplayError( this, _( "There is no component selected to save." ) ); + DisplayError( this, _( "There is no symbol selected to save." ) ); return; } - wxFileName fn = part->GetName().Lower(); + wxFileName fn; + fn.SetName( part->GetName().Lower() ); fn.SetExt( SchematicLibraryFileExtension ); - title = createLib ? _( "New Library" ) : _( "Export Component" ); + title = createLib ? _( "New Symbol Library" ) : _( "Export Symbol" ); wxFileDialog dlg( this, title, m_mruPath, fn.GetFullName(), SchematicLibraryFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); @@ -127,18 +123,56 @@ void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event ) return; fn = dlg.GetPath(); + fn.MakeAbsolute(); - std::unique_ptr temp_lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, fn.GetFullPath() ) ); + LIB_PART* old_part = NULL; + + SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) ); + + if( fn.FileExists() ) + { + try + { + LIB_ALIAS* alias = pi->LoadSymbol( fn.GetFullPath(), part->GetName() ); + + if( alias ) + old_part = alias->GetPart(); + } + catch( const IO_ERROR& ioe ) + { + msg.Printf( _( "Error occurred attempting to load symbol library file '%s'" ), + fn.GetFullPath() ); + DisplayErrorMessage( this, msg, ioe.What() ); + return; + } + + if( old_part ) + { + msg.Printf( _( "Symbol '%s' already exists. Overwrite it?" ), part->GetName() ); + + if( !IsOK( this, msg ) ) + return; + } + } + + if( fn.Exists() && !fn.IsDirWritable() ) + { + msg.Printf( _( "Write permissions are requured to save library '%s'." ), fn.GetFullPath() ); + DisplayError( this, msg ); + return; + } try { - SaveOnePart( temp_lib.get() ); + if( !fn.FileExists() ) + pi->CreateSymbolLib( fn.GetFullPath() ); + + pi->SaveSymbol( fn.GetFullPath(), new LIB_PART( *part ) ); } - catch( ... /* IO_ERROR ioe */ ) + catch( const IO_ERROR& ioe ) { - fn.MakeAbsolute(); - msg = wxT( "Failed to create symbol library file " ) + fn.GetFullPath(); - DisplayError( this, msg ); + msg = _( "Failed to create symbol library file " ) + fn.GetFullPath(); + DisplayErrorMessage( this, msg, ioe.What() ); msg.Printf( _( "Error creating symbol library '%s'" ), fn.GetFullName() ); SetStatusText( msg ); return; @@ -146,12 +180,13 @@ void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event ) m_mruPath = fn.GetPath(); - 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." ) ); + /// @todo Give the user a choice to add the new library to the symbol library table. + DisplayInfoMessage( this, _( "This library will not be available until it is added to the " + "symbol library table." ) ); - msg.Printf( _( "'%s' - Export OK" ), GetChars( fn.GetFullPath() ) ); + GetScreen()->ClrModify(); + m_drawItem = m_lastDrawItem = NULL; + + msg.Printf( _( "Symbol '%s' saved in library '%s'" ), part->GetName(), fn.GetFullPath() ); SetStatusText( msg ); } diff --git a/eeschema/libarch.cpp b/eeschema/libarch.cpp index 2ceefb2331..f11d0decd2 100644 --- a/eeschema/libarch.cpp +++ b/eeschema/libarch.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2004 Jean-Pierre Charras, jp.charras ar wanadoo.fr - * Copyright (C) 2008-2017 Wayne Stambaugh + * Copyright (C) 2008 Wayne Stambaugh * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -30,14 +30,15 @@ #include #include -#include #include -#include +#include +#include +#include +#include #include #include #include -#include bool SCH_EDIT_FRAME::CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilename ) @@ -65,9 +66,8 @@ bool SCH_EDIT_FRAME::CreateArchiveLibraryCacheFile( bool aUseCurrentSheetFilenam bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName ) { - wxString msg; - SCH_SCREENS screens; - PART_LIBS* libs = Prj().SchLibs(); + wxString msg; + SCH_SCREENS screens; // Create a new empty library to archive components: std::unique_ptr archLib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, aFileName ) ); @@ -89,19 +89,17 @@ bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName ) SCH_COMPONENT* component = (SCH_COMPONENT*) item; - if( !archLib->FindAlias( component->GetLibId().GetLibItemName() ) ) - { - LIB_PART* part = NULL; + if( archLib->FindAlias( component->GetLibId().GetLibItemName() ) ) + continue; + LIB_PART* part = GetLibPart( component->GetLibId() ); + + if( !part ) + { try { - part = libs->FindLibPart( component->GetLibId() ); - - if( part ) - { - // AddPart() does first clone the part before adding. - archLib->AddPart( part ); - } + part = Prj().SchLibs()->GetCacheLibrary()->FindPart( + component->GetLibId().GetLibItemName() ); } catch( ... /* IO_ERROR ioe */ ) { @@ -110,6 +108,12 @@ bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName ) DisplayError( this, msg ); return false; } + + if( part ) + { + // AddPart() does first clone the part before adding. + archLib->AddPart( part ); + } } } } diff --git a/eeschema/libedit.cpp b/eeschema/libedit.cpp index 80e8147801..1a6b712b6e 100644 --- a/eeschema/libedit.cpp +++ b/eeschema/libedit.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2008 Wayne Stambaugh + * Copyright (C) 2008 Wayne Stambaugh * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -55,43 +55,70 @@ void LIB_EDIT_FRAME::DisplayLibInfos() { - PART_LIB* lib = GetCurLib(); - wxString title = wxString::Format( _( "Part Library Editor -- %s %s" ), - lib ? lib->GetFullFileName() : _( "no library selected" ), - lib && lib->IsReadOnly() ? _( "[Read Only]") : wxString( wxEmptyString ) ); + wxString lib = GetCurLib(); + wxString title = _( "Symbol Library Editor - " ); + + if( !lib.empty() && Prj().SchSymbolLibTable()->HasLibrary( lib ) ) + { + wxString fileName = Prj().SchSymbolLibTable()->GetFullURI( lib ); + + title += lib + " (" + fileName + ")"; + + if( !wxFileName::IsFileWritable( fileName ) ) + title += " " + _( "[Read Only]" ); + } + else + title += _( "no library selected" ); SetTitle( title ); } -void LIB_EDIT_FRAME::SelectActiveLibrary( PART_LIB* aLibrary ) +void LIB_EDIT_FRAME::SelectActiveLibrary( const wxString& aLibrary ) { - if( !aLibrary ) - aLibrary = SelectLibraryFromList(); + wxString selectedLib = aLibrary; - if( aLibrary ) - { - SetCurLib( aLibrary ); - } + if( selectedLib.empty() ) + selectedLib = SelectLibraryFromList(); + + if( !selectedLib.empty() ) + SetCurLib( selectedLib ); DisplayLibInfos(); } -bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, PART_LIB* aLibrary ) +bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( const LIB_ID& aLibId ) { if( GetScreen()->IsModify() - && !IsOK( this, _( "The current component is not saved.\n\nDiscard current changes?" ) ) ) + && !IsOK( this, _( "The current symbol is not saved.\n\nDiscard current changes?" ) ) ) return false; - SelectActiveLibrary( aLibrary ); - return LoadComponentFromCurrentLib( aLibEntry ); + SelectActiveLibrary( aLibId.GetLibNickname() ); + return LoadComponentFromCurrentLib( aLibId.GetLibItemName() ); } -bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry, int aUnit, int aConvert ) +bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( const wxString& aAliasName, int aUnit, + int aConvert ) { - if( !LoadOneLibraryPartAux( aLibEntry, GetCurLib() ) ) + LIB_ALIAS* alias = nullptr; + + try + { + alias = Prj().SchSymbolLibTable()->LoadSymbol( GetCurLib(), aAliasName ); + } + catch( const IO_ERROR& ioe ) + { + wxString msg; + + msg.Printf( _( "Error occurred loading symbol '%s' from library '%s'." ), + aAliasName, GetCurLib() ); + DisplayErrorMessage( this, msg, ioe.What() ); + return false; + } + + if( !alias || !LoadOneLibraryPartAux( alias, GetCurLib() ) ) return false; if( aUnit > 0 ) @@ -115,23 +142,22 @@ bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry, int aUni void LIB_EDIT_FRAME::LoadOneLibraryPart( wxCommandEvent& event ) { - LIB_ALIAS* libEntry = NULL; - m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); if( GetScreen()->IsModify() - && !IsOK( this, _( "The current component is not saved.\n\nDiscard current changes?" ) ) ) + && !IsOK( this, _( "The current symbol is not saved.\n\nDiscard current changes?" ) ) ) return; - PART_LIB* lib = GetCurLib(); + wxString lib = GetCurLib(); // No current lib, ask user for the library to use. - if( !lib ) + if( lib.empty() ) { SelectActiveLibrary(); + lib = GetCurLib(); - if( !lib ) + if( lib.empty() ) return; } @@ -141,75 +167,35 @@ void LIB_EDIT_FRAME::LoadOneLibraryPart( wxCommandEvent& event ) SCH_BASE_FRAME::HISTORY_LIST dummyHistoryList; SCHLIB_FILTER filter; - filter.LoadFrom( lib->GetName() ); + filter.LoadFrom( lib ); auto sel = SelectComponentFromLibrary( &filter, dummyHistoryList, - true, 0, 0, part_name, false ); + true, 0, 0, part_name, false ); - if( sel.Name.IsEmpty() ) + if( sel.Name.empty() ) return; GetScreen()->ClrModify(); m_lastDrawItem = m_drawItem = NULL; - // Delete previous library component, if any + // Delete previous library symbol, if any SetCurPart( NULL ); m_aliasName.Empty(); - // Load the new library component - libEntry = lib->FindAlias( sel.Name ); - PART_LIB* searchLib = lib; - - if( !libEntry ) - { - // Not found in the active library: search inside the full list - // (can happen when using Viewlib to load a component) - libEntry = Prj().SchLibs()->FindLibraryAlias( LIB_ID( wxEmptyString, sel.Name ) ); - - if( libEntry ) - { - searchLib = libEntry->GetLib(); - - // The entry to load is not in the active lib - // Ask for a new active lib - wxString msg = _( "The selected component is not in the active library." ); - msg += "\n\n"; - msg += _( "Do you want to change the active library?" ); - - if( IsOK( this, msg ) ) - SelectActiveLibrary( searchLib ); - } - } - - if( !libEntry ) - { - wxString msg = wxString::Format( _( "Part name '%s' not found in library '%s'" ), - GetChars( sel.Name ), - GetChars( searchLib->GetName() ) ); - DisplayError( this, msg ); - return; - } - - PART_LIB* old = SetCurLib( searchLib ); - - LoadComponentFromCurrentLib( libEntry, sel.Unit, sel.Convert ); - - SetCurLib( old ); - - DisplayLibInfos(); + // Load the new library symbol + LoadComponentFromCurrentLib( sel.Name, sel.Unit, sel.Convert ); } -bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, PART_LIB* aLibrary ) +bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, const wxString& aLibrary ) { wxString msg, rootName; - if( !aEntry || !aLibrary ) + if( !aEntry || aLibrary.empty() ) return false; if( aEntry->GetName().IsEmpty() ) { - wxLogWarning( "Entry in library <%s> has empty name field.", - GetChars( aLibrary->GetName() ) ); + wxLogWarning( "Symbol in library '%s' has empty name field.", aLibrary ); return false; } @@ -219,10 +205,6 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, PART_LIB* aLibrar wxASSERT( lib_part ); - wxLogDebug( "\"<%s>\" is alias of \"<%s>\"", - GetChars( cmpName ), - GetChars( lib_part->GetName() ) ); - LIB_PART* part = new LIB_PART( *lib_part ); // clone it and own it. SetCurPart( part ); m_aliasName = aEntry->GetName(); @@ -300,12 +282,7 @@ void LIB_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) void LIB_EDIT_FRAME::OnSaveActiveLibrary( wxCommandEvent& event ) { - bool newFile = false; - - if( event.GetId() == ID_LIBEDIT_SAVE_CURRENT_LIB_AS ) - newFile = true; - - SaveActiveLibrary( newFile ); + SaveActiveLibrary( event.GetId() == ID_LIBEDIT_SAVE_CURRENT_LIB_AS ); } @@ -313,48 +290,23 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) { wxFileName fn; wxString msg; + PROJECT& prj = Prj(); m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() ); - PART_LIB* lib = GetCurLib(); + wxString lib = GetCurLib(); - if( !lib ) + if( !newFile && ( lib.empty() || !prj.SchSymbolLibTable()->HasLibrary( lib ) ) ) { DisplayError( this, _( "No library specified." ) ); return false; } - // Just in case the library hasn't been cached yet. - lib->GetCount(); - - wxString oldFileName = lib->GetFullFileName(); - - if( GetScreen()->IsModify() ) - { - if( IsOK( this, _( "Include last component changes?" ) ) ) - { - lib->EnableBuffering(); - - try - { - SaveOnePart( lib, false ); - } - catch( ... ) - { - lib->EnableBuffering( false ); - msg.Printf( _( "Unexpected error occured saving part to '%s' symbol library." ), - lib->GetName() ); - DisplayError( this, msg ); - return false; - } - - lib->EnableBuffering( false ); - } - } + if( GetScreen()->IsModify() && !IsOK( this, _( "Include current symbol changes?" ) ) ) + return false; if( newFile ) { - PROJECT& prj = Prj(); SEARCH_STACK* search = prj.SchSearchS(); // Get a new name for the library @@ -363,7 +315,7 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) if( !default_path ) default_path = search->LastVisitedPath(); - wxFileDialog dlg( this, _( "Part Library Name:" ), default_path, + wxFileDialog dlg( this, _( "Symbol Library Name" ), default_path, wxEmptyString, SchematicLibraryFileWildcard, wxFD_SAVE | wxFD_OVERWRITE_PROMPT ); @@ -381,9 +333,9 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) } else { - fn = wxFileName( lib->GetFullFileName() ); + fn = prj.SchSymbolLibTable()->GetFullURI( lib ); - msg.Printf( _( "Modify library file '%s' ?" ), GetChars( fn.GetFullPath() ) ); + msg.Printf( _( "Modify symbol library file '%s' ?" ), fn.GetFullPath() ); if( !IsOK( this, msg ) ) return false; @@ -398,7 +350,7 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) wxFileName libFileName = fn; wxFileName backupFileName = fn; - // Rename the old .lib file to .bak. + // Copy .lib file to .bak. if( libFileName.FileExists() ) { backupFileName.SetExt( "bak" ); @@ -406,12 +358,13 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) if( backupFileName.FileExists() ) wxRemoveFile( backupFileName.GetFullPath() ); - if( !wxRenameFile( libFileName.GetFullPath(), backupFileName.GetFullPath() ) ) + if( !wxCopyFile( libFileName.GetFullPath(), backupFileName.GetFullPath() ) ) { libFileName.MakeAbsolute(); - msg = _( "Failed to rename old component library file " ) + + msg = _( "Failed to rename old symbol library to file " ) + backupFileName.GetFullPath(); DisplayError( this, msg ); + return false; } } @@ -419,7 +372,7 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) docFileName.SetExt( DOC_EXT ); - // Rename .doc file to .bck. + // Copy .dcm file to .bck. if( docFileName.FileExists() ) { backupFileName.SetExt( "bck" ); @@ -427,32 +380,61 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) if( backupFileName.FileExists() ) wxRemoveFile( backupFileName.GetFullPath() ); - if( !wxRenameFile( docFileName.GetFullPath(), backupFileName.GetFullPath() ) ) + if( !wxCopyFile( docFileName.GetFullPath(), backupFileName.GetFullPath() ) ) { - msg = _( "Failed to save old library document file " ) + backupFileName.GetFullPath(); + msg = _( "Failed to save old library document to file " ) + + backupFileName.GetFullPath(); DisplayError( this, msg ); + return false; } } - try + // Copy the library and document files to the new destination library files. + if( newFile ) { - lib->SetFileName( fn.GetFullPath() ); - lib->Save(); - } - catch( ... /* IO_ERROR ioe */ ) - { - lib->SetFileName( oldFileName ); - msg.Printf( _( "Failed to create symbol library file '%s'" ), - GetChars( docFileName.GetFullPath() ) ); - DisplayError( this, msg ); - return false; + wxFileName src = prj.SchSymbolLibTable()->GetFullURI( GetCurLib() ); + + if( !wxCopyFile( src.GetFullPath(), libFileName.GetFullPath() ) ) + { + msg.Printf( _( "Failed to copy symbol library file " ) + libFileName.GetFullPath() ); + DisplayError( this, msg ); + return false; + } + + src.SetExt( DOC_EXT ); + + if( !wxCopyFile( src.GetFullPath(), docFileName.GetFullPath() ) ) + { + msg.Printf( _( "Failed to copy symbol library document file " ) + + docFileName.GetFullPath() ); + DisplayError( this, msg ); + return false; + } } - lib->SetFileName( oldFileName ); - msg.Printf( _( "Library file '%s' saved" ), GetChars( fn.GetFullPath() ) ); - fn.SetExt( DOC_EXT ); + // Update symbol changes in library. + if( GetScreen()->IsModify() ) + { + SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) ); + + try + { + pi->SaveSymbol( fn.GetFullPath(), new LIB_PART( *GetCurPart() ) ); + } + catch( const IO_ERROR& ioe ) + { + msg.Printf( _( "Failed to save changes to symbol library file '%s'" ), + libFileName.GetFullPath() ); + DisplayErrorMessage( this, msg, ioe.What() ); + return false; + } + + GetScreen()->ClrModify(); + } + + msg.Printf( _( "Symbol library file '%s' saved" ), libFileName.GetFullPath() ); wxString msg1; - msg1.Printf( _( "Documentation file '%s' saved" ), GetChars( fn.GetFullPath() ) ); + msg1.Printf( _( "Symbol library documentation file '%s' saved" ), docFileName.GetFullPath() ); AppendMsgPanel( msg, msg1, BLUE ); UpdateAliasSelectList(); UpdatePartSelectList(); @@ -465,12 +447,11 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile ) void LIB_EDIT_FRAME::DisplayCmpDoc() { LIB_ALIAS* alias; - PART_LIB* lib = GetCurLib(); LIB_PART* part = GetCurPart(); ClearMsgPanel(); - if( !lib || !part ) + if( !part ) return; wxString msg = part->GetName(); @@ -484,7 +465,7 @@ void LIB_EDIT_FRAME::DisplayCmpDoc() alias = part->GetAlias( m_aliasName ); - wxCHECK_RET( alias != NULL, "Alias not found in component." ); + wxCHECK_RET( alias != NULL, "Alias not found in symbol." ); AppendMsgPanel( _( "Alias" ), msg, RED, 8 ); @@ -524,16 +505,17 @@ void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event ) m_drawItem = NULL; LIB_PART *part = GetCurPart(); - PART_LIB* lib = GetCurLib(); + wxString lib = GetCurLib(); - if( !lib ) + if( lib.empty() ) { SelectActiveLibrary(); lib = GetCurLib(); + if( !lib ) { - DisplayError( this, _( "Please select a component library." ) ); + DisplayError( this, _( "Please select a symbol library." ) ); return; } } @@ -543,10 +525,10 @@ void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event ) wxString name = part ? part->GetName() : wxString( wxEmptyString ); adapter->SetPreselectNode( name, /* aUnit */ 0 ); adapter->ShowUnits( false ); - adapter->AddLibrary( lib->GetName() ); + adapter->AddLibrary( lib ); wxString dialogTitle; - dialogTitle.Printf( _( "Delete Component (%u items loaded)" ), adapter->GetComponentsCount() ); + dialogTitle.Printf( _( "Delete Symbol (%u items loaded)" ), adapter->GetComponentsCount() ); DIALOG_CHOOSE_COMPONENT dlg( this, dialogTitle, adapter, m_convert, false ); @@ -567,7 +549,7 @@ void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event ) if( !alias ) return; - msg.Printf( _( "Delete component '%s' from library '%s' ?" ), + msg.Printf( _( "Delete symbol '%s' from library '%s'?" ), id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() ); if( !IsOK( this, msg ) ) @@ -586,13 +568,23 @@ void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event ) // the current entry, sync the changes in the current entry as well. if( GetScreen()->IsModify() && !IsOK( this, _( - "The component being deleted has been modified." + "The symbol being deleted has been modified." " All changes will be lost. Discard changes?" ) ) ) { return; } - Prj().SchSymbolLibTable()->DeleteAlias( id.GetLibNickname(), id.GetLibItemName() ); + try + { + Prj().SchSymbolLibTable()->DeleteAlias( id.GetLibNickname(), id.GetLibItemName() ); + } + catch( ... /* IO_ERROR ioe */ ) + { + msg.Printf( _( "Error occurred deleting symbol '%s' from library '%s'" ), + id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() ); + DisplayError( this, msg ); + return; + } SetCurPart( NULL ); // delete CurPart m_aliasName.Empty(); @@ -605,8 +597,8 @@ void LIB_EDIT_FRAME::CreateNewLibraryPart( wxCommandEvent& event ) wxString name; if( GetCurPart() && GetScreen()->IsModify() && !IsOK( this, _( - "All changes to the current component will be lost!\n\n" - "Clear the current component from the screen?" ) ) ) + "All changes to the current symbol will be lost!\n\n" + "Clear the current symbol from the screen?" ) ) ) { return; } @@ -624,23 +616,20 @@ void LIB_EDIT_FRAME::CreateNewLibraryPart( wxCommandEvent& event ) if( dlg.GetName().IsEmpty() ) { - wxMessageBox( _( "This new component has no name and cannot be created. Aborted" ) ); + wxMessageBox( _( "This new symbol has no name and cannot be created." ) ); return; } name = dlg.GetName(); name.Replace( " ", "_" ); - PART_LIB* lib = GetCurLib(); + wxString lib = GetCurLib(); // Test if there a component with this name already. - if( lib && lib->FindAlias( name ) ) + if( !lib.empty() && Prj().SchSymbolLibTable()->LoadSymbol( lib, name ) != NULL ) { - wxString msg = wxString::Format( _( - "Part '%s' already exists in library '%s'" ), - GetChars( name ), - GetChars( lib->GetName() ) - ); + wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'" ), + name, lib ); DisplayError( this, msg ); return; } @@ -696,46 +685,3 @@ void LIB_EDIT_FRAME::CreateNewLibraryPart( wxCommandEvent& event ) m_canvas->Refresh(); m_mainToolBar->Refresh(); } - - -bool LIB_EDIT_FRAME::SaveOnePart( PART_LIB* aLib, bool aPromptUser ) -{ - wxString msg; - LIB_PART* part = GetCurPart(); - LIB_PART* old_part = NULL; - - GetScreen()->ClrModify(); - - if( !wxFileName::FileExists( aLib->GetFullFileName() ) ) - { - aLib->Create(); - } - else - { - old_part = aLib->FindPart( part->GetName() ); - - if( old_part && aPromptUser ) - { - msg.Printf( _( "Part '%s' already exists. Change it?" ), - GetChars( part->GetName() ) ); - - if( !IsOK( this, msg ) ) - return false; - } - } - - m_drawItem = m_lastDrawItem = NULL; - - if( old_part ) - aLib->ReplacePart( old_part, part ); - else - aLib->AddPart( part ); - - msg.Printf( _( "Part '%s' saved in library '%s'" ), - GetChars( part->GetName() ), - GetChars( aLib->GetName() ) ); - - SetStatusText( msg ); - - return true; -} diff --git a/eeschema/libeditframe.cpp b/eeschema/libeditframe.cpp index 3355ae8298..d2bea02a2e 100644 --- a/eeschema/libeditframe.cpp +++ b/eeschema/libeditframe.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2008-2017 Wayne Stambaugh + * Copyright (C) 2008 Wayne Stambaugh * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -166,7 +167,7 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME ) EVT_UPDATE_UI( wxID_UNDO, LIB_EDIT_FRAME::OnUpdateUndo ) EVT_UPDATE_UI( wxID_REDO, LIB_EDIT_FRAME::OnUpdateRedo ) EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_LIB, LIB_EDIT_FRAME::OnUpdateSaveCurrentLib ) - EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_LIB_AS, LIB_EDIT_FRAME::OnUpdateSaveCurrentLib ) + EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_LIB_AS, LIB_EDIT_FRAME::OnUpdateSaveCurrentLibAs ) EVT_UPDATE_UI( ID_LIBEDIT_VIEW_DOC, LIB_EDIT_FRAME::OnUpdateViewDoc ) EVT_UPDATE_UI( ID_LIBEDIT_EDIT_PIN_BY_PIN, LIB_EDIT_FRAME::OnUpdatePinByPin ) EVT_UPDATE_UI( ID_LIBEDIT_EDIT_PIN_BY_TABLE, LIB_EDIT_FRAME::OnUpdatePinTable ) @@ -256,7 +257,6 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_aliasName = part->GetName(); } - CreateOptionToolbar(); DisplayLibInfos(); DisplayCmpDoc(); @@ -334,7 +334,7 @@ void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) break; case wxID_YES: - if ( this->SaveActiveLibrary( false ) ) + if( SaveActiveLibrary( false ) ) break; // fall through: cancel the close because of an error @@ -343,28 +343,10 @@ void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) Event.Veto(); return; } + GetScreen()->ClrModify(); } - PART_LIBS* libs = Prj().SchLibs(); - - for( const PART_LIB& lib : *libs ) - { - if( lib.IsModified() ) - { - wxString msg = wxString::Format( _( - "Library '%s' was modified!\nDiscard changes?" ), - GetChars( lib.GetName() ) - ); - - if( !IsOK( this, msg ) ) - { - Event.Veto(); - return; - } - } - } - Destroy(); } @@ -525,10 +507,20 @@ void LIB_EDIT_FRAME::OnUpdateRedo( wxUpdateUIEvent& event ) void LIB_EDIT_FRAME::OnUpdateSaveCurrentLib( wxUpdateUIEvent& event ) { - PART_LIB* lib = GetCurLib(); + wxString lib = GetCurLib(); + SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable(); - event.Enable( lib && !lib->IsReadOnly() - && ( lib->IsModified() || GetScreen()->IsModify() ) ); + event.Enable( !lib.empty() && table->HasLibrary( lib ) && table->IsSymbolLibWritable( lib ) && + GetScreen()->IsModify() ); +} + + +void LIB_EDIT_FRAME::OnUpdateSaveCurrentLibAs( wxUpdateUIEvent& event ) +{ + wxString lib = GetCurLib(); + SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable(); + + event.Enable( !lib.empty() && table->HasLibrary( lib ) ); } @@ -536,14 +528,15 @@ void LIB_EDIT_FRAME::OnUpdateViewDoc( wxUpdateUIEvent& event ) { bool enable = false; - PART_LIB* lib = GetCurLib(); - LIB_PART* part = GetCurPart(); + LIB_PART* part = GetCurPart(); - if( part && lib ) + if( part ) { LIB_ALIAS* alias = part->GetAlias( m_aliasName ); - wxCHECK_RET( alias != NULL, wxT( "Alias <" ) + m_aliasName + wxT( "> not found." ) ); + wxCHECK_RET( alias != NULL, + wxString::Format( "Alias '%s' not found in symbol '%s'.", + m_aliasName, part->GetName() ) ); enable = !alias->GetDocFileName().IsEmpty(); } @@ -694,28 +687,28 @@ void LIB_EDIT_FRAME::OnSaveCurrentPart( wxCommandEvent& aEvent ) return; } - PART_LIB* lib = GetCurLib(); + wxString libNickname = GetCurLib(); - if( !lib ) + if( libNickname.empty() ) SelectActiveLibrary(); - lib = GetCurLib(); + libNickname = GetCurLib(); - if( !lib ) + if( !libNickname ) { - DisplayError( this, _( "No library specified." ) ); + DisplayError( this, _( "No valid library specified." ) ); return; } try { - SaveOnePart( lib ); + Prj().SchSymbolLibTable()->SaveSymbol( libNickname, new LIB_PART( *part ) ); } catch( ... ) { wxString msg; msg.Printf( _( "Unexpected error occured saving symbol '%s' to symbol library '%s'." ), - part->GetName(), lib->GetName() ); + part->GetName(), libNickname ); DisplayError( this, msg ); return; } @@ -976,32 +969,31 @@ void LIB_EDIT_FRAME::OnActivate( wxActivateEvent& event ) } -PART_LIB* LIB_EDIT_FRAME::GetCurLib() +wxString LIB_EDIT_FRAME::GetCurLib() { - wxString name = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_LIB ); + wxString libNickname = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_LIB ); - if( !!name ) + if( !libNickname.empty() ) { - PART_LIB* lib = Prj().SchLibs()->FindLibrary( name ); - - if( !lib ) + if( !Prj().SchSymbolLibTable()->HasLibrary( libNickname ) ) + { Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, wxEmptyString ); - - return lib; + libNickname = wxEmptyString; + } } - return NULL; + return libNickname; } -PART_LIB* LIB_EDIT_FRAME::SetCurLib( PART_LIB* aLib ) +wxString LIB_EDIT_FRAME::SetCurLib( const wxString& aLibNickname ) { - PART_LIB* old = GetCurLib(); + wxString old = GetCurLib(); - if( !aLib || !aLib->GetName() ) + if( aLibNickname.empty() || !Prj().SchSymbolLibTable()->HasLibrary( aLibNickname ) ) Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, wxEmptyString ); else - Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, aLib->GetName() ); + Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, aLibNickname ); return old; } @@ -1009,20 +1001,6 @@ PART_LIB* LIB_EDIT_FRAME::SetCurLib( PART_LIB* aLib ) 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( LIB_ID( wxEmptyString, 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; } @@ -1033,8 +1011,7 @@ void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart ) 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() ); + Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART, aPart ? aPart->GetName() : wxString() ); } diff --git a/eeschema/libeditframe.h b/eeschema/libeditframe.h index 619a72c60b..5242fe3987 100644 --- a/eeschema/libeditframe.h +++ b/eeschema/libeditframe.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2008-2017 Wayne Stambaugh + * Copyright (C) 2008 Wayne Stambaugh * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -39,14 +39,15 @@ class SCH_EDIT_FRAME; -class PART_LIB; class LIB_PART; class LIB_ALIAS; class LIB_FIELD; class DIALOG_LIB_EDIT_TEXT; +class LIB_ID; + /** - * The component library editor main window. + * The symbol library editor main window. */ class LIB_EDIT_FRAME : public SCH_BASE_FRAME { @@ -135,23 +136,21 @@ public: ~LIB_EDIT_FRAME(); - /** The current library being edited, or NULL if none. */ - PART_LIB* GetCurLib(); + /** The nickname of the current library being edited and empty string if none. */ + wxString GetCurLib(); - /** Sets the current library and return the old. */ - PART_LIB* SetCurLib( PART_LIB* aLib ); + /** Sets the current library nickname and returns the old library nickname. */ + wxString SetCurLib( const wxString& aLibNickname ); /** - * Function GetCurPart - * returns the current part being edited, or NULL if none selected. + * Return 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. + * Take ownership of aPart and notes that it is the one currently being edited. */ void SetCurPart( LIB_PART* aPart ); @@ -187,19 +186,11 @@ public: void ReCreateMenuBar() override; - /** - * Function EnsureActiveLibExists - * must be called after the libraries are reloaded - * (for instance after loading a schematic project) - */ - static void EnsureActiveLibExists(); - void InstallConfigFrame( wxCommandEvent& event ); void OnPreferencesOptions( wxCommandEvent& event ); void Process_Config( wxCommandEvent& event ); /** - * Function SycnronizePins * @return True if the edit pins per part or convert is false and the current * component has multiple parts or body styles. Otherwise false is * returned. @@ -207,8 +198,7 @@ public: bool SynchronizePins(); /** - * Function OnPlotCurrentComponent - * plot the current component in SVG or PNG format. + * Plot the current symbol in SVG or PNG format. */ void OnPlotCurrentComponent( wxCommandEvent& event ); void Process_Special_Functions( wxCommandEvent& event ); @@ -237,8 +227,7 @@ public: void OnShowElectricalType( wxCommandEvent& event ); /** - * Function DeleteOnePart - * is the command event handler to delete an entry from the current library. + * Delete a symbol from the current library. * * The deleted entry can be an alias or a component. If the entry is an alias, * it is removed from the component and the list of alias is updated. If the @@ -252,8 +241,7 @@ public: void DeleteOnePart( wxCommandEvent& event ); /** - * Function CreateNewLibraryPart - * is the command event handler to create a new library component. + * Create a new library symbol. * * If an old component is currently in edit, it is deleted. */ @@ -264,8 +252,7 @@ public: void InstallFieldsEditorDialog( wxCommandEvent& event ); /** - * Function LoadOneLibraryPart - * loads a library component from the currently selected library. + * Loads a symbol from the currently selected library. * * If a library is already selected, the user is prompted for the component name * to load. If there is no current selected library, the user is prompted to select @@ -289,6 +276,7 @@ public: void OnUpdateUndo( wxUpdateUIEvent& event ); void OnUpdateRedo( wxUpdateUIEvent& event ); void OnUpdateSaveCurrentLib( wxUpdateUIEvent& event ); + void OnUpdateSaveCurrentLibAs( wxUpdateUIEvent& event ); void OnUpdateViewDoc( wxUpdateUIEvent& event ); void OnUpdatePinByPin( wxUpdateUIEvent& event ); void OnUpdatePinTable( wxUpdateUIEvent& event ); @@ -302,14 +290,12 @@ public: void UpdatePartSelectList(); /** - * Function DisplayLibInfos - * updates the main window title bar with the current library name and read only status + * Updates the main window title bar with the current library name and read only status * of the library. */ void DisplayLibInfos(); /** - * Function RedrawComponent * Redraw the current component loaded in library editor * Display reference like in schematic (a reference U is shown U? or U?A) * accordint to the current selected unit and De Morgan selection @@ -321,7 +307,6 @@ public: void RedrawComponent( wxDC* aDC, wxPoint aOffset ); /** - * Function RedrawActiveWindow * Redraw the current component loaded in library editor, an axes * Display reference like in schematic (a reference U is shown U? or U?A) * update status bar and info shown in the bottom of the window @@ -349,11 +334,10 @@ public: void SaveSettings( wxConfigBase* aCfg ) override; /** - * Function CloseWindow - * triggers the wxCloseEvent, which is handled by the function given - * to EVT_CLOSE() macro: + * Trigger the wxCloseEvent, which is handled by the function given to EVT_CLOSE() macro: *

* EVT_CLOSE( LIB_EDIT_FRAME::OnCloseWindow ) + *

*/ void CloseWindow( wxCommandEvent& event ) { @@ -362,9 +346,8 @@ public: } /** - * Function OnModify - * Must be called after a schematic change - * in order to set the "modify" flag of the current screen + * Must be called after a schematic change in order to set the "modify" flag of the + * current screen. */ void OnModify() { @@ -411,28 +394,25 @@ public: FILL_T GetFillStyle() { return m_drawFillStyle; } /** - * Function TempCopyComponent - * create a temporary copy of the current edited component - * Used to prepare an Undo ant/or abort command before editing the component + * Create a temporary copy of the current edited component. + * + * Used to prepare an undo and/or abort command before editing the symbol. */ void TempCopyComponent(); /** - * Function RestoreComponent * Restore the current edited component from its temporary copy. * Used to abort a command */ void RestoreComponent(); /** - * Function GetTempCopyComponent * @return the temporary copy of the current component. */ LIB_PART* GetTempCopyComponent() { return m_tempCopyComponent; } /** - * Function ClearTempCopyComponent - * delete temporary copy of the current component and clear pointer + * Delete temporary copy of the current component and clear pointer */ void ClearTempCopyComponent(); @@ -441,8 +421,7 @@ public: private: /** - * Function OnActivate - * is called when the frame is activated. Tests if the current library exists. + * 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 library can point a non existent lib. */ @@ -451,31 +430,15 @@ private: // General: /** - * Function SaveOnePart - * saves the current LIB_PART into the provided PART_LIB. + * Set the current active library to \a aLibrary. * - * 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. - * @param aLib - the part library where the part must be saved. - * @param aPromptUser true to ask for confirmation, when the part_lib is already existing - * in memory, false to save silently - * @return true if the part was saved, false if aborted by user + * @param aLibrary the nickname of the library in the symbol library table. If wxEmptyString, + * then display list of available libraries to select from. */ - bool SaveOnePart( PART_LIB* aLib, bool aPromptUser = true ); + void SelectActiveLibrary( const wxString& aLibrary = wxEmptyString ); /** - * Function SelectActiveLibrary - * sets the current active library to \a aLibrary. - * - * @param aLibrary A pointer to the PART_LIB object to select. If NULL, then display - * list of available libraries to select from. - */ - void SelectActiveLibrary( PART_LIB* aLibrary = NULL ); - - /** - * Function OnSaveActiveLibrary - * it the command event handler to save the changes to the current library. + * The command event handler to save the changes to the current library. * * A backup file of the current library is saved with the .bak extension before the * changes made to the library are saved. @@ -483,8 +446,7 @@ private: void OnSaveActiveLibrary( wxCommandEvent& event ); /** - * Function SaveActiveLibrary - * saves the changes to the current library. + * Saves the changes to the current library. * * A backup file of the current library is saved with the .bak extension before the * changes made to the library are saved. @@ -494,47 +456,44 @@ private: bool SaveActiveLibrary( bool newFile ); /** - * Function LoadComponentFromCurrentLib - * loads a component from the current active library, optionally setting the selected - * unit and convert - * @param aLibEntry The component to load from \a aLibrary (can be an alias) + * Loads a symbol from the current active library, optionally setting the selected + * unit and convert. + * + * @param aAliasName The symbol alias name to load from the current library. * @param aUnit Unit to be selected * @param aConvert Convert to be selected - * @return true if \a aLibEntry loaded correctly. + * @return true if the symbol loaded correctly. */ - bool LoadComponentFromCurrentLib( LIB_ALIAS* aLibEntry, int aUnit = 0, int aConvert = 0 ); + bool LoadComponentFromCurrentLib( const wxString& aAliasName, int aUnit = 0, int aConvert = 0 ); /** - * Function LoadOneLibraryPartAux - * loads a copy of \a aLibEntry from \a aLibrary into memory. + * Create a copy of \a aLibEntry into memory. * - * @param aLibEntry A pointer to the LIB_ALIAS object to load. - * @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. + * @param aLibEntry A pointer to the LIB_ALIAS object to an already loaded. + * @param aLibrary the path to the library file that \a aLibEntry was loaded from. This is + * for error messaging purposes only. + * @return True if a copy of \a aLibEntry was successfully copied. */ - bool LoadOneLibraryPartAux( LIB_ALIAS* aLibEntry, PART_LIB* aLibrary ); + bool LoadOneLibraryPartAux( LIB_ALIAS* aLibEntry, const wxString& aLibrary ); /** - * Function DisplayCmpDoc - * displays the documentation of the selected component. + * Display the documentation of the selected component. */ void DisplayCmpDoc(); /** - * Function OnRotateItem - * rotates the current item. + * Rotates the current item. */ void OnRotateItem( wxCommandEvent& aEvent ); /** - * Function OnOrient * Handles the ID_LIBEDIT_MIRROR_X and ID_LIBEDIT_MIRROR_Y events. */ void OnOrient( wxCommandEvent& aEvent ); /** - * Function deleteItem - * deletes the currently selected draw item. + * Deletes the currently selected draw item. + * * @param aDC The device context to draw upon when removing item. */ void deleteItem( wxDC* aDC ); @@ -542,8 +501,8 @@ private: // General editing public: /** - * Function SaveCopyInUndoList. * Create a copy of the current component, and save it in the undo list. + * * Because a component in library editor does not a lot of primitives, * the full data is duplicated. It is not worth to try to optimize this save funtion */ @@ -558,8 +517,7 @@ private: void StartMovePin( wxDC* DC ); /** - * Function CreateImagePins - * adds copies of \a aPin for \a aUnit in components with multiple parts and + * Adds copies of \a aPin for \a aUnit in components with multiple parts and * \a aConvert for components that have multiple body styles. * * @param aPin The pin to copy. @@ -571,8 +529,7 @@ private: void CreateImagePins( LIB_PIN* aPin, int aUnit, int aConvert, bool aDeMorgan ); /** - * Function PlaceAnchor - * places an anchor reference coordinate for the current component. + * Places an anchor reference coordinate for the current component. *

* All object coordinates are offset to the current cursor position. *

@@ -580,26 +537,22 @@ private: void PlaceAnchor(); // Editing graphic items - LIB_ITEM* CreateGraphicItem( LIB_PART* LibEntry, wxDC* DC ); + LIB_ITEM* CreateGraphicItem( LIB_PART* LibEntry, wxDC* DC ); void GraphicItemBeginDraw( wxDC* DC ); void StartMoveDrawSymbol( wxDC* DC ); void StartModifyDrawSymbol( wxDC* DC ); // - * A symbol file *.sym has the same format as a library, and contains only - * one symbol. - *

+ * Read a component symbol file (*.sym ) and add graphic items to the current component. + * + * A symbol file *.sym has the same format as a library, and contains only one symbol. */ void LoadOneSymbol(); /** - * Function SaveOneSymbol - * saves the current component to a symbol file. - *

+ * Saves the current symbol to a symbol file. + * * The symbol file format is similar to the standard component library file format, but * there is only one symbol. Invisible pins are not saved. */ @@ -615,47 +568,41 @@ private: public: /** - * Function LoadComponentAndSelectLib - * selects the current active library. + * Selects the currently active library and loads the symbol from \a aLibId. * - * @param aLibrary The PART_LIB to select - * @param aLibEntry The component to load from aLibrary (can be an alias). - * @return true if \a aLibEntry was loaded from \a aLibrary. + * @param aLibId is the #LIB_ID of the symbol to select. + * @return true if the symbol defined by \a aLibId was loaded. */ - bool LoadComponentAndSelectLib( LIB_ALIAS* aLibEntry, PART_LIB* aLibrary ); + bool LoadComponentAndSelectLib( const LIB_ID& aLibId ); /* Block commands: */ /** - * Function BlockCommand - * returns the block command (BLOCK_MOVE, BLOCK_DUPLICATE...) corresponding to + * Returns the block command (BLOCK_MOVE, BLOCK_DUPLICATE...) corresponding to * the \a aKey (ALT, SHIFT ALT ..) */ virtual int BlockCommand( EDA_KEY aKey ) override; /** - * Function HandleBlockPlace - * handles the block place command. + * Handles the block place command. */ virtual void HandleBlockPlace( wxDC* DC ) override; /** - * Function HandleBlockEnd - * performs a block end command. + * Performs a block end command. + * * @return If command finished (zoom, delete ...) false is returned otherwise true * is returned indicating more processing is required. */ virtual bool HandleBlockEnd( wxDC* DC ) override; /** - * Function PlacePin * Place at cursor location the pin currently moved (i.e. pin pointed by m_drawItem) * (and the linked pins, if any) */ void PlacePin(); /** - * Function GlobalSetPins * @param aMasterPin is the "template" pin * @param aId is a param to select what should be mofified: * - aId = ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM: @@ -674,16 +621,15 @@ public: void RepeatPinItem( wxDC* DC, LIB_PIN* Pin ); /** - * Function CreatePNGorJPEGFile - * creates an image (screenshot) of the current component in PNG or JPEG format. + * Creates an image (screenshot) of the current component in PNG or JPEG format. * @param aFileName = the full filename * @param aFmt_jpeg = true to use JPEG file format, false to use PNG file format */ void CreatePNGorJPEGFile( const wxString& aFileName, bool aFmt_jpeg ); /** - * Virtual function PrintPage - * used to print a page + * Print a page + * * @param aDC = wxDC given by the calling print function * @param aPrintMask = not used here * @param aPrintMirrorMode = not used here (Set when printing in mirror mode) @@ -693,8 +639,8 @@ public: bool aPrintMirrorMode, void* aData = NULL ) override; /** - * Function SVG_PlotComponent * Creates the SVG print file for the current edited component. + * * @param aFullFileName = the full filename */ void SVG_PlotComponent( const wxString& aFullFileName ); diff --git a/eeschema/libfield.cpp b/eeschema/libfield.cpp index d3d4eef42f..eaca9bdf87 100644 --- a/eeschema/libfield.cpp +++ b/eeschema/libfield.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2007-2016 KiCad Developers, see CHANGELOG.TXT for contributors. + * Copyright (C) 2007-2017 KiCad Developers, see CHANGELOG.TXT for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -81,17 +82,16 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField ) if( aField->GetId() == VALUE && newFieldValue != aField->GetText() ) { wxString msg; - - PART_LIB* lib = GetCurLib(); + wxString lib = GetCurLib(); // Test the current library for name conflicts. - if( lib && lib->FindAlias( newFieldValue ) ) + if( !lib.empty() && Prj().SchSymbolLibTable()->LoadSymbol( lib, newFieldValue ) ) { 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 the library with this one?" ), - GetChars( newFieldValue ), - GetChars( lib->GetName() ) + newFieldValue, + lib ); int rsp = wxMessageBox( msg, _( "Confirm" ), @@ -119,12 +119,12 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField ) parent->SetName( newFieldValue ); // Test the library for any conflicts with the any aliases in the current component. - if( parent->GetAliasCount() > 1 && lib ) + if( parent->GetAliasCount() > 1 && !lib.empty() ) { bool conflicts = false; wxArrayString libAliasNames, symbolAliasNames; - lib->GetAliasNames( libAliasNames ); + Prj().SchSymbolLibTable()->EnumerateSymbolLib( lib, libAliasNames ); symbolAliasNames = parent->GetAliasNames(); for( size_t i = 0; i < symbolAliasNames.GetCount(); i++ ) @@ -138,12 +138,11 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField ) if( conflicts ) { - msg.Printf( _( "The new component contains alias names that conflict with " - "entries in the component library '%s'.\n\n" + msg.Printf( _( "The new symbol contains alias names that conflict with " + "entries in the library '%s'.\n\n" "Do you wish to remove all of the conflicting aliases from " - "this component?" ), - GetChars( lib->GetName() ) - ); + "this symbol?" ), + lib ); int rsp = wxMessageBox( msg, _( "Confirm" ), wxYES_NO | wxICON_QUESTION, this ); @@ -157,7 +156,7 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField ) for( size_t i = 0; i < aliases.GetCount(); i++ ) { - if( lib->FindAlias( aliases[ i ] ) != NULL ) + if( Prj().SchSymbolLibTable()->LoadSymbol( lib, aliases[ i ] ) != NULL ) parent->RemoveAlias( aliases[ i ] ); } } diff --git a/eeschema/netform.cpp b/eeschema/netform.cpp index 6b41c02e1e..7883a4402c 100644 --- a/eeschema/netform.cpp +++ b/eeschema/netform.cpp @@ -57,19 +57,19 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList, switch( aFormat ) { case NET_TYPE_PCBNEW: - helper = new NETLIST_EXPORTER_KICAD( aConnectedItemsList, Prj().SchLibs() ); + helper = new NETLIST_EXPORTER_KICAD( aConnectedItemsList, Prj().SchSymbolLibTable() ); break; case NET_TYPE_ORCADPCB2: - helper = new NETLIST_EXPORTER_ORCADPCB2( aConnectedItemsList, Prj().SchLibs() ); + helper = new NETLIST_EXPORTER_ORCADPCB2( aConnectedItemsList ); break; case NET_TYPE_CADSTAR: - helper = new NETLIST_EXPORTER_CADSTAR( aConnectedItemsList, Prj().SchLibs() ); + helper = new NETLIST_EXPORTER_CADSTAR( aConnectedItemsList ); break; case NET_TYPE_SPICE: - helper = new NETLIST_EXPORTER_PSPICE( aConnectedItemsList, Prj().SchLibs() ); + helper = new NETLIST_EXPORTER_PSPICE( aConnectedItemsList ); break; default: @@ -78,7 +78,7 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList, tmpFile.SetExt( GENERIC_INTERMEDIATE_NETLIST_EXT ); fileName = tmpFile.GetFullPath(); - helper = new NETLIST_EXPORTER_GENERIC( aConnectedItemsList, Prj().SchLibs() ); + helper = new NETLIST_EXPORTER_GENERIC( aConnectedItemsList, Prj().SchSymbolLibTable() ); executeCommandLine = true; } break; diff --git a/eeschema/netlist.cpp b/eeschema/netlist.cpp index d118bf28fd..c39fc47cd2 100644 --- a/eeschema/netlist.cpp +++ b/eeschema/netlist.cpp @@ -2,8 +2,8 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2013-2016 Wayne Stambaugh - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2013 Wayne Stambaugh + * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -62,7 +62,7 @@ bool SCH_EDIT_FRAME::prepareForNetlist() // Ensure all power symbols have a valid reference SCH_SHEET_LIST sheets( g_RootSheet ); - sheets.AnnotatePowerSymbols( Prj().SchLibs() ); + sheets.AnnotatePowerSymbols(); // Performs some controls: if( CheckAnnotate( NULL, 0 ) ) @@ -94,7 +94,7 @@ void SCH_EDIT_FRAME::sendNetlist() { NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase(); - NETLIST_EXPORTER_KICAD exporter( net_atoms, Prj().SchLibs() ); + NETLIST_EXPORTER_KICAD exporter( net_atoms, Prj().SchSymbolLibTable() ); STRING_FORMATTER formatter; diff --git a/eeschema/netlist_exporters/netlist_exporter.h b/eeschema/netlist_exporters/netlist_exporter.h index 795cae57c5..389a1dd647 100644 --- a/eeschema/netlist_exporters/netlist_exporter.h +++ b/eeschema/netlist_exporters/netlist_exporter.h @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2013 jp.charras at wanadoo.fr * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2015 KiCad Developers + * Copyright (C) 1992-2017 KiCad Developers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -87,25 +87,20 @@ struct LIB_PART_LESS_THAN class NETLIST_EXPORTER { protected: - NETLIST_OBJECT_LIST* m_masterList; /// yes ownership, connected items flat list - - PART_LIBS* m_libs; /// no ownership + NETLIST_OBJECT_LIST* m_masterList; /// yes ownership, connected items flat list /// Used to temporarily store and filter the list of pins of a schematic component /// when generating schematic component data in netlist (comp section). No ownership /// of members. - NETLIST_OBJECTS m_SortedComponentPinList; + NETLIST_OBJECTS m_SortedComponentPinList; /// Used for "multi parts per package" components, /// avoids processing a lib component more than once. - UNIQUE_STRINGS m_ReferencesAlreadyFound; + UNIQUE_STRINGS m_ReferencesAlreadyFound; /// unique library parts used. LIB_PART items are sorted by names std::set m_LibParts; - // share a code generated std::set to reduce code volume - std::set m_Libraries; ///< unique libraries used - /** * Function sprintPinNetName * formats the net name for \a aPin using \a aNetNameFormat into \a aResult. @@ -164,21 +159,21 @@ protected: * matching reference designator, and for each unit, add all its pins * to the temporary sorted pin list, m_SortedComponentPinList. */ - void findAllUnitsOfComponent( SCH_COMPONENT* aComponent, - LIB_PART* aEntry, - SCH_SHEET_PATH* aSheetPath ); + void findAllUnitsOfComponent( SCH_COMPONENT* aComponent, + LIB_PART* aEntry, + SCH_SHEET_PATH* aSheetPath ); public: /** * Constructor * @param aMasterList we take ownership of this here. - * @param aLibs is the library list of the project. + * @param aLibTable is the symbol library table of the project. */ - NETLIST_EXPORTER( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) : - m_masterList( aMasterList ), - m_libs( aLibs ) + NETLIST_EXPORTER( NETLIST_OBJECT_LIST* aMasterList ) : + m_masterList( aMasterList ) { + wxASSERT( aMasterList ); } virtual ~NETLIST_EXPORTER() diff --git a/eeschema/netlist_exporters/netlist_exporter_cadstar.h b/eeschema/netlist_exporters/netlist_exporter_cadstar.h index 0c8cbf9da9..e40a3c091f 100644 --- a/eeschema/netlist_exporters/netlist_exporter_cadstar.h +++ b/eeschema/netlist_exporters/netlist_exporter_cadstar.h @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2013 jp.charras at wanadoo.fr * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2015 KiCad Developers + * Copyright (C) 1992-2017 KiCad Developers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -28,6 +28,7 @@ #include "netlist_exporter.h" + /** * Class NETLIST_EXPORTER_CADSTAR * generates a netlist compatible with CADSTAR @@ -47,8 +48,8 @@ class NETLIST_EXPORTER_CADSTAR : public NETLIST_EXPORTER bool writeListOfNets( FILE* f ); public: - NETLIST_EXPORTER_CADSTAR( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) : - NETLIST_EXPORTER( aMasterList, aLibs ) + NETLIST_EXPORTER_CADSTAR( NETLIST_OBJECT_LIST* aMasterList ) : + NETLIST_EXPORTER( aMasterList ) { } diff --git a/eeschema/netlist_exporters/netlist_exporter_generic.cpp b/eeschema/netlist_exporters/netlist_exporter_generic.cpp index 1c3a349b8c..c2fadeee49 100644 --- a/eeschema/netlist_exporters/netlist_exporter_generic.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_generic.cpp @@ -28,6 +28,8 @@ #include #include +#include + #include "netlist_exporter_generic.h" static bool sortPinsByNumber( LIB_PIN* aPin1, LIB_PIN* aPin2 ); @@ -214,6 +216,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeComponents() for( EDA_ITEM* schItem = sheetList[i].LastDrawList(); schItem; schItem = schItem->Next() ) { SCH_COMPONENT* comp = findNextComponent( schItem, &sheetList[i] ); + if( !comp ) break; // No component left @@ -237,9 +240,10 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeComponents() // "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_PART* part = m_libs->FindLibPart( comp->GetLibId() ); + PART_SPTR part = comp->GetPartRef().lock(); + if( part ) - xlibsource->AddAttribute( "lib", part->GetLib()->GetLogicalName() ); + xlibsource->AddAttribute( "lib", part->GetLibId().GetLibNickname() ); // We only want the symbol name, not the full LIB_ID. xlibsource->AddAttribute( "part", comp->GetLibId().GetLibItemName() ); @@ -335,14 +339,17 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeLibraries() { XNODE* xlibs = node( "libraries" ); // auto_ptr - for( std::set::iterator it = m_Libraries.begin(); it!=m_Libraries.end(); ++it ) + for( std::set::iterator it = m_libraries.begin(); it!=m_libraries.end(); ++it ) { - PART_LIB* lib = (PART_LIB*) *it; + wxString libNickname = *it; XNODE* xlibrary; - xlibs->AddChild( xlibrary = node( "library" ) ); - xlibrary->AddAttribute( "logical", lib->GetLogicalName() ); - xlibrary->AddChild( node( "uri", lib->GetFullFileName() ) ); + if( m_libTable->HasLibrary( libNickname ) ) + { + xlibs->AddChild( xlibrary = node( "library" ) ); + xlibrary->AddAttribute( "logical", libNickname ); + xlibrary->AddChild( node( "uri", m_libTable->GetFullURI( libNickname ) ) ); + } // @todo: add more fun stuff here } @@ -358,18 +365,20 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeLibParts() LIB_PINS pinList; LIB_FIELDS fieldList; - m_Libraries.clear(); + m_libraries.clear(); for( std::set::iterator it = m_LibParts.begin(); it!=m_LibParts.end(); ++it ) { LIB_PART* lcomp = *it; - PART_LIB* library = lcomp->GetLib(); + wxString libNickname = lcomp->GetLibId().GetLibNickname();; - m_Libraries.insert( library ); // inserts component's library if unique + // The library nickname will be empty if the cache library is used. + if( !libNickname.IsEmpty() ) + m_libraries.insert( libNickname ); // inserts component's library if unique XNODE* xlibpart; xlibparts->AddChild( xlibpart = node( "libpart" ) ); - xlibpart->AddAttribute( "lib", library->GetLogicalName() ); + xlibpart->AddAttribute( "lib", libNickname ); xlibpart->AddAttribute( "part", lcomp->GetName() ); if( lcomp->GetAliasCount() ) diff --git a/eeschema/netlist_exporters/netlist_exporter_generic.h b/eeschema/netlist_exporters/netlist_exporter_generic.h index edcadd9ed4..d9e9dd651d 100644 --- a/eeschema/netlist_exporters/netlist_exporter_generic.h +++ b/eeschema/netlist_exporters/netlist_exporter_generic.h @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2013 jp.charras at wanadoo.fr * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2015 KiCad Developers + * Copyright (C) 1992-2017 KiCad Developers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,6 +30,8 @@ #include // also nests: +class SYMBOL_LIB_TABLE; + #define GENERIC_INTERMEDIATE_NETLIST_EXT wxT( "xml" ) /** @@ -53,10 +55,17 @@ enum GNL_T */ class NETLIST_EXPORTER_GENERIC : public NETLIST_EXPORTER { +private: + std::set< wxString > m_libraries; ///< Set of library nicknames. + + SYMBOL_LIB_TABLE* m_libTable; + public: - NETLIST_EXPORTER_GENERIC( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) : - NETLIST_EXPORTER( aMasterList, aLibs ) + NETLIST_EXPORTER_GENERIC( NETLIST_OBJECT_LIST* aMasterList, SYMBOL_LIB_TABLE* aLibTable ) : + NETLIST_EXPORTER( aMasterList ), + m_libTable( aLibTable ) { + wxASSERT( aLibTable ); } /** diff --git a/eeschema/netlist_exporters/netlist_exporter_kicad.h b/eeschema/netlist_exporters/netlist_exporter_kicad.h index a9912cac2d..dffecea87a 100644 --- a/eeschema/netlist_exporters/netlist_exporter_kicad.h +++ b/eeschema/netlist_exporters/netlist_exporter_kicad.h @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2013 jp.charras at wanadoo.fr * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2015 KiCad Developers + * Copyright (C) 1992-2017 KiCad Developers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -38,8 +38,8 @@ class OUTPUTFORMATTER; class NETLIST_EXPORTER_KICAD : public NETLIST_EXPORTER_GENERIC { public: - NETLIST_EXPORTER_KICAD( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) : - NETLIST_EXPORTER_GENERIC( aMasterList, aLibs ) + NETLIST_EXPORTER_KICAD( NETLIST_OBJECT_LIST* aMasterList, SYMBOL_LIB_TABLE* aLibTable ) : + NETLIST_EXPORTER_GENERIC( aMasterList, aLibTable ) { } diff --git a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp index 70aea4e484..8532a98159 100644 --- a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.cpp @@ -31,11 +31,14 @@ #include #include #include +#include #include #include "netlist_exporter_orcadpcb2.h" -bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions ) + +bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName, + unsigned aNetlistOptions ) { (void)aNetlistOptions; //unused FILE* f = NULL; @@ -79,15 +82,13 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName, uns item = comp; - // Get the Component FootprintFilter and put the component in - // cmpList if filter is present - LIB_PART* part = m_libs->FindLibPart( comp->GetLibId() ); + PART_SPTR part = comp->GetPartRef().lock(); if( part ) { if( part->GetFootPrints().GetCount() != 0 ) // Put in list { - cmpList.push_back( SCH_REFERENCE( comp, part, sheetList[i] ) ); + cmpList.push_back( SCH_REFERENCE( comp, part.get(), sheetList[i] ) ); } } diff --git a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h index 1765d24481..8a44dbccc0 100644 --- a/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h +++ b/eeschema/netlist_exporters/netlist_exporter_orcadpcb2.h @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2013 jp.charras at wanadoo.fr * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2015 KiCad Developers + * Copyright (C) 1992-2017 KiCad Developers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -35,8 +35,8 @@ class NETLIST_EXPORTER_ORCADPCB2 : public NETLIST_EXPORTER { public: - NETLIST_EXPORTER_ORCADPCB2( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs ) : - NETLIST_EXPORTER( aMasterList, aLibs ) + NETLIST_EXPORTER_ORCADPCB2( NETLIST_OBJECT_LIST* aMasterList ) : + NETLIST_EXPORTER( aMasterList ) { } diff --git a/eeschema/netlist_exporters/netlist_exporter_pspice.h b/eeschema/netlist_exporters/netlist_exporter_pspice.h index be7207f23d..5392357319 100644 --- a/eeschema/netlist_exporters/netlist_exporter_pspice.h +++ b/eeschema/netlist_exporters/netlist_exporter_pspice.h @@ -3,7 +3,7 @@ * * Copyright (C) 1992-2013 jp.charras at wanadoo.fr * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2016 KiCad Developers + * Copyright (C) 1992-2017 KiCad Developers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -99,9 +99,9 @@ struct SPICE_ITEM class NETLIST_EXPORTER_PSPICE : public NETLIST_EXPORTER { public: - NETLIST_EXPORTER_PSPICE( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs, - SEARCH_STACK* aPaths = NULL ) : - NETLIST_EXPORTER( aMasterList, aLibs ), m_paths( aPaths ) + NETLIST_EXPORTER_PSPICE( NETLIST_OBJECT_LIST* aMasterList, SEARCH_STACK* aPaths = NULL ) : + NETLIST_EXPORTER( aMasterList ), + m_paths( aPaths ) { } diff --git a/eeschema/onrightclick.cpp b/eeschema/onrightclick.cpp index 719a42dd8e..3c637fd98c 100644 --- a/eeschema/onrightclick.cpp +++ b/eeschema/onrightclick.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2008 Wayne Stambaugh + * Copyright (C) 2008 Wayne Stambaugh * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -59,8 +60,10 @@ 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, PART_LIBS* aLibs ); -static void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs ); +static void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, + SYMBOL_LIB_TABLE* aLibs ); +static void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, + SYMBOL_LIB_TABLE* 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 ); @@ -88,7 +91,8 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) switch( item->Type() ) { case SCH_COMPONENT_T: - AddMenusForEditComponent( PopMenu, (SCH_COMPONENT *) item, Prj().SchLibs() ); + AddMenusForEditComponent( PopMenu, (SCH_COMPONENT *) item, + Prj().SchSymbolLibTable() ); PopMenu->AppendSeparator(); break; @@ -244,7 +248,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) break; case SCH_COMPONENT_T: - AddMenusForComponent( PopMenu, (SCH_COMPONENT*) item, Prj().SchLibs() ); + AddMenusForComponent( PopMenu, (SCH_COMPONENT*) item, Prj().SchSymbolLibTable() ); break; case SCH_BITMAP_T: @@ -348,7 +352,7 @@ void AddMenusForComponentField( wxMenu* PopMenu, SCH_FIELD* Field ) } -void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs ) +void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, SYMBOL_LIB_TABLE* aLibs ) { if( Component->Type() != SCH_COMPONENT_T ) { @@ -377,7 +381,8 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* AddMenuItem( orientmenu, ID_SCH_MIRROR_X, msg, KiBitmap( mirror_v_xpm ) ); msg = AddHotkeyName( _( "Flip Horizontal" ), g_Schematic_Hokeys_Descr, HK_MIRROR_Y ); AddMenuItem( orientmenu, ID_SCH_MIRROR_Y, msg, KiBitmap( mirror_h_xpm ) ); - msg = AddHotkeyName( _( "Reset to Default" ), g_Schematic_Hokeys_Descr, HK_ORIENT_NORMAL_COMPONENT ); + msg = AddHotkeyName( _( "Reset to Default" ), g_Schematic_Hokeys_Descr, + HK_ORIENT_NORMAL_COMPONENT ); AddMenuItem( orientmenu, ID_SCH_ORIENT_NORMAL, msg, KiBitmap( normal_xpm ) ); AddMenuItem( PopMenu, orientmenu, ID_POPUP_SCH_GENERIC_ORIENT_CMP, _( "Orientation" ), KiBitmap( orient_xpm ) ); @@ -397,11 +402,12 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* AddMenuItem( PopMenu, ID_AUTOPLACE_FIELDS, msg, KiBitmap( autoplace_fields_xpm ) ); if( !Component->GetField( DATASHEET )->GetFullyQualifiedText().IsEmpty() ) - AddMenuItem( PopMenu, ID_POPUP_SCH_DISPLAYDOC_CMP, _( "Open Documentation" ), KiBitmap( datasheet_xpm ) ); + AddMenuItem( PopMenu, ID_POPUP_SCH_DISPLAYDOC_CMP, _( "Open Documentation" ), + KiBitmap( datasheet_xpm ) ); } -void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs ) +void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, SYMBOL_LIB_TABLE* aLibs ) { if( Component->Type() != SCH_COMPONENT_T ) { @@ -411,10 +417,18 @@ void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_L wxString msg; LIB_PART* part = NULL; - LIB_ALIAS* libEntry = aLibs->FindLibraryAlias( Component->GetLibId() ); + LIB_ALIAS* alias = NULL; - if( libEntry ) - part = libEntry->GetPart(); + try + { + alias = aLibs->LoadSymbol( Component->GetLibId() ); + } + catch( ... ) + { + } + + if( alias ) + part = alias->GetPart(); wxMenu* editmenu = new wxMenu; msg = AddHotkeyName( _( "Edit Properties" ), g_Schematic_Hokeys_Descr, HK_EDIT ); diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index dc038962ed..5cc8fd33f6 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -25,7 +25,9 @@ #include #include #include +#include +#include #include #include #include @@ -34,8 +36,48 @@ #include "dialogs/dialog_sym_lib_table.h" -// Sttaic members: +LIB_ALIAS* SchGetLibAlias( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, PART_LIB* aCacheLib, + wxWindow* aParent, bool aShowErrorMsg ) +{ + wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." ); + wxCHECK_MSG( aLibTable, NULL, "Invalid symbol library table." ); + + LIB_ALIAS* alias = NULL; + + try + { + alias = aLibTable->LoadSymbol( aLibId ); + + if( !alias && aCacheLib ) + alias = aCacheLib->FindAlias( aLibId.GetLibItemName() ); + } + catch( const IO_ERROR& ioe ) + { + if( aShowErrorMsg ) + { + wxString msg; + + msg.Printf( _( "Could not load symbol '%s' from library '%s'." ), + aLibId.GetLibItemName().wx_str(), aLibId.GetLibNickname().wx_str() ); + DisplayErrorMessage( aParent, msg, ioe.What() ); + } + } + + return alias; +} + + +LIB_PART* SchGetLibPart( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, PART_LIB* aCacheLib, + wxWindow* aParent, bool aShowErrorMsg ) +{ + LIB_ALIAS* alias = SchGetLibAlias( aLibId, aLibTable, aCacheLib, aParent, aShowErrorMsg ); + + return ( alias ) ? alias->GetPart() : NULL; +} + + +// Sttaic members: SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aWindowType, const wxString& aTitle, @@ -81,7 +123,7 @@ COLOR4D SCH_BASE_FRAME::GetDrawBgColor() const } -void SCH_BASE_FRAME::SetDrawBgColor( COLOR4D aColor) +void SCH_BASE_FRAME::SetDrawBgColor( COLOR4D aColor ) { m_drawBgColor= aColor; SetLayerColor( aColor, LAYER_SCHEMATIC_BACKGROUND ); @@ -93,11 +135,13 @@ SCH_SCREEN* SCH_BASE_FRAME::GetScreen() const return (SCH_SCREEN*) EDA_DRAW_FRAME::GetScreen(); } + const wxString SCH_BASE_FRAME::GetZoomLevelIndicator() const { return EDA_DRAW_FRAME::GetZoomLevelIndicator(); } + void SCH_BASE_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings ) { GetScreen()->SetPageSettings( aPageSettings ); @@ -260,3 +304,24 @@ void SCH_BASE_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent ) if( viewer ) viewer->ReCreateListLib(); } + + +LIB_ALIAS* SCH_BASE_FRAME::GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib, + bool aShowErrorMsg ) +{ + wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." ); + + PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL; + + return SchGetLibAlias( aLibId, Prj().SchSymbolLibTable(), cache, this, aShowErrorMsg ); +} + + +LIB_PART* SCH_BASE_FRAME::GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib, bool aShowErrorMsg ) +{ + wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." ); + + PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL; + + return SchGetLibPart( aLibId, Prj().SchSymbolLibTable(), cache, this, aShowErrorMsg ); +} diff --git a/eeschema/sch_base_frame.h b/eeschema/sch_base_frame.h index 1418e88c4e..fe478035c0 100644 --- a/eeschema/sch_base_frame.h +++ b/eeschema/sch_base_frame.h @@ -32,16 +32,41 @@ class TITLE_BLOCK; class LIB_VIEW_FRAME; class LIB_EDIT_FRAME; class LIB_ALIAS; +class LIB_PART; class PART_LIB; class SCHLIB_FILTER; class LIB_ID; +class SYMBOL_LIB_TABLE; + /** - * Class SCH_BASE_FRAME - * is a shim class between EDA_DRAW_FRAME and several derived classes: + * Load symbol from symbol library table. + * + * Check the symbol library table for the part defined by \a aLibId and optionally + * check the optional cache library. + * + * @param aLibId is the symbol library identifier to load. + * @param aLibTable is the #SYMBOL_LIBRARY_TABLE to load the alias from. + * @param aCacheLib is an optional cache library. + * @param aParent is an optiona parent window when displaying an error message. + * @param aShowErrorMessage set to true to show any error messages. + * + * @return The symbol found in the library or NULL if the symbol was not found. + */ +LIB_ALIAS* SchGetLibAlias( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, + PART_LIB* aCacheLib = NULL, wxWindow* aParent = NULL, + bool aShowErrorMsg = false ); + +LIB_PART* SchGetLibPart( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, + PART_LIB* aCacheLib = NULL, wxWindow* aParent = NULL, + bool aShowErrorMsg = false ); + + +/** + * A shim class between EDA_DRAW_FRAME and several derived classes: * LIB_EDIT_FRAME, LIB_VIEW_FRAME, and SCH_EDIT_FRAME, and it brings in a * common way of handling the provided virtual functions for the derived classes. - *

+ * * The motivation here is to switch onto GetScreen() for the underlying data model. * * @author Dick Hollenbeck @@ -179,6 +204,21 @@ public: void OnEditSymbolLibTable( wxCommandEvent& aEvent ); + /** + * Load symbol from symbol library table. + * + * @param aLibId is the symbol library identifier to load. + * @param aUseCacheLib set to true to fall back to cache library if symbol is not found in + * symbol library table. + * @param aShowErrorMessage set to true to show any error messages. + * @return The symbol found in the library or NULL if the symbol was not found. + */ + LIB_ALIAS* GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib = false, + bool aShowErrorMsg = false ); + + LIB_PART* GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib = false, + bool aShowErrorMsg = false ); + protected: /** @@ -199,7 +239,6 @@ protected: int aUnit, int aConvert ); /** - * Function OnOpenLibraryViewer * Open the library viewer only to browse library contents. * If the viewed is already opened from this, raise the viewer * If the viewed is already opened from an other window, close it and reopen @@ -207,11 +246,10 @@ protected: void OnOpenLibraryViewer( wxCommandEvent& event ); /** - * Function DisplayComponentsNamesInLib * Select a component from the list of components in a library * - * @param aLibrary = a reference to the library to explore - * If NULL the user will be prompted tp chose a library + * @param aLibrary a reference to the library nickname to explore + * If empty, the user will be prompted tp chose a library * @param aBuffer = a wxString to put the selected component name * @param aPreviousChoice = the previously selected component name. * it will be added to the selection list. Can be empty. @@ -219,30 +257,31 @@ protected: * @return true if a component is selected * false on cancel */ - bool DisplayListComponentsInLib( PART_LIB* aLibrary, wxString& aBuffer, - wxString& aPreviousChoice ); + bool DisplayListComponentsInLib( wxString& aLibrary, wxString& aBuffer, + wxString& aPreviousChoice ); /** - * Function SelectLibraryFromList - * displays a list of current loaded libraries, and allows the user to select - * a library + * Dispaly a list of loaded libraries in the symbol library and allows the user to select + * a library. + * * This list is sorted, with the library cache always at end of the list - * @return a reference to the selected library, or NULL + * + * @return the library nickname used in the symbol library table. */ - PART_LIB* SelectLibraryFromList(); + wxString SelectLibraryFromList(); /** * Function SelectPartNameToLoad * Select a part name from the list of components (parts) found in a library. * - * @param aLibrary = a reference to the library to explore - * If NULL the user will be prompted tp chose a library - * @param aBufName = a wxString to put the selected component name + * @param aLibrary is the nickname of the library in the symbol library table. + * If empty the user will be prompted tp chose a library + * @param aBufName a wxString to put the selected component name * * @return true if a component is selected * false on cancel */ - bool SelectPartNameToLoad( PART_LIB* aLibrary, wxString& aBufName ); + bool SelectPartNameToLoad( wxString& aLibrary, wxString& aBufName ); }; #endif // SCH_BASE_FRAME_H_ diff --git a/eeschema/sch_legacy_plugin.cpp b/eeschema/sch_legacy_plugin.cpp index 0e67de29c4..4e89700bba 100644 --- a/eeschema/sch_legacy_plugin.cpp +++ b/eeschema/sch_legacy_plugin.cpp @@ -3634,5 +3634,12 @@ bool SCH_LEGACY_PLUGIN::CheckHeader( const wxString& aFileName ) return firstline.StartsWith( "EESchema" ); } + +bool SCH_LEGACY_PLUGIN::IsSymbolLibWritable( const wxString& aLibraryPath ) +{ + return wxFileName::IsFileWritable( aLibraryPath ); +} + + const char* SCH_LEGACY_PLUGIN::PropBuffering = "buffering"; const char* SCH_LEGACY_PLUGIN::PropNoDocFile = "no_doc_file"; diff --git a/eeschema/sch_legacy_plugin.h b/eeschema/sch_legacy_plugin.h index c640f7c235..c2408fcd41 100644 --- a/eeschema/sch_legacy_plugin.h +++ b/eeschema/sch_legacy_plugin.h @@ -123,6 +123,7 @@ public: void SaveLibrary( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL ) override; bool CheckHeader( const wxString& aFileName ) override; + bool IsSymbolLibWritable( const wxString& aLibraryPath ) override; private: void loadHierarchy( SCH_SHEET* aSheet ); diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 37a80038b8..1500a6f8c0 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -1528,6 +1528,7 @@ bool SCH_SCREENS::HasNoFullyDefinedLibIds() SCH_ITEM* item; SCH_ITEM* nextItem; SCH_SCREEN* screen; + unsigned cnt = 0; for( screen = GetFirst(); screen; screen = GetNext() ) { @@ -1538,6 +1539,7 @@ bool SCH_SCREENS::HasNoFullyDefinedLibIds() if( item->Type() != SCH_COMPONENT_T ) continue; + cnt += 1; symbol = dynamic_cast< SCH_COMPONENT* >( item ); if( !symbol->GetLibId().GetLibNickname().empty() ) @@ -1545,6 +1547,9 @@ bool SCH_SCREENS::HasNoFullyDefinedLibIds() } } + if( cnt == 0 ) + return false; + return true; } diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index bc2a0f0fe0..049b78a145 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2011-2017 Wayne Stambaugh + * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -182,8 +182,7 @@ void SCH_SHEET_PATH::UpdateAllScreenReferences() -void SCH_SHEET_PATH::GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, - bool aIncludePowerSymbols ) +void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols ) { for( SCH_ITEM* item = LastDrawList(); item; item = item->Next() ) { @@ -210,8 +209,7 @@ void SCH_SHEET_PATH::GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aRefer } -void SCH_SHEET_PATH::GetMultiUnitComponents( PART_LIBS* aLibs, - SCH_MULTI_UNIT_REFERENCE_MAP& aRefList, +void SCH_SHEET_PATH::GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP& aRefList, bool aIncludePowerSymbols ) { @@ -512,7 +510,7 @@ void SCH_SHEET_LIST::ClearModifyStatus() } -void SCH_SHEET_LIST::AnnotatePowerSymbols( PART_LIBS* aLibs ) +void SCH_SHEET_LIST::AnnotatePowerSymbols() { // List of reference for power symbols SCH_REFERENCE_LIST references; @@ -590,21 +588,19 @@ void SCH_SHEET_LIST::AnnotatePowerSymbols( PART_LIBS* aLibs ) } -void SCH_SHEET_LIST::GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, - bool aIncludePowerSymbols ) +void SCH_SHEET_LIST::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols ) { for( SCH_SHEET_PATHS_ITER it = begin(); it != end(); ++it ) - (*it).GetComponents( aLibs, aReferences, aIncludePowerSymbols ); + (*it).GetComponents( aReferences, aIncludePowerSymbols ); } -void SCH_SHEET_LIST::GetMultiUnitComponents( PART_LIBS* aLibs, - SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, +void SCH_SHEET_LIST::GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols ) { for( SCH_SHEET_PATHS_ITER it = begin(); it != end(); ++it ) { SCH_MULTI_UNIT_REFERENCE_MAP tempMap; - (*it).GetMultiUnitComponents( aLibs, tempMap ); + (*it).GetMultiUnitComponents( tempMap ); for( SCH_MULTI_UNIT_REFERENCE_MAP::value_type& pair : tempMap ) { diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index ec891b97a1..ab1c2f0496 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2011-2016 Wayne Stambaugh + * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -85,7 +85,7 @@ class SCH_SCREEN; class SCH_MARKER; class SCH_ITEM; class SCH_REFERENCE_LIST; -class PART_LIBS; + #define SHEET_NOT_FOUND -1 @@ -204,23 +204,22 @@ public: /** * Function GetComponents * adds a SCH_REFERENCE() object to \a aReferences for each component in the sheet. - * @param aLibs the library list to use + * * @param aReferences List of references to populate. * @param aIncludePowerSymbols : false to only get normal components. */ - void GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, - bool aIncludePowerSymbols = true ); + void GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true ); /** * Function GetMultiUnitComponents * adds a SCH_REFERENCE_LIST object to \a aRefList for each same-reference set of * multi-unit parts in the sheet. The map key for each element will be the * reference designator. - * @param aLibs the library list to use + * * @param aRefList Map of reference designators to reference lists * @param aIncludePowerSymbols : false to only get normal components. */ - void GetMultiUnitComponents( PART_LIBS* aLibs, SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, + void GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols = true ); /** @@ -364,31 +363,29 @@ public: * It is called before creating a netlist, to annotate power symbols, without prompting * the user about not annotated or duplicate for these symbols, if only these symbols * need annotation ( a very frequent case ). - * @param aLib the library list to use */ - void AnnotatePowerSymbols( PART_LIBS* aLib ); + void AnnotatePowerSymbols(); /** * Function GetComponents * adds a SCH_REFERENCE() object to \a aReferences for each component in the list * of sheets. - * @param aLibs the library list to use + * * @param aReferences List of references to populate. * @param aIncludePowerSymbols Set to false to only get normal components. */ - void GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, - bool aIncludePowerSymbols = true ); + void GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols = true ); /** * Function GetMultiUnitComponents * adds a SCH_REFERENCE_LIST object to \a aRefList for each same-reference set of * multi-unit parts in the list of sheets. The map key for each element will be the * reference designator. - * @param aLibs the library list to use + * * @param aRefList Map of reference designators to reference lists * @param aIncludePowerSymbols Set to false to only get normal components. */ - void GetMultiUnitComponents( PART_LIBS* aLibs, SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, + void GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols = true ); /** diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index 3ec3545753..4dfb2c2577 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -853,6 +854,7 @@ void SCH_EDIT_FRAME::OnErc( wxCommandEvent& event ) InvokeDialogERC( this ); } + void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event ) { wxFileName fn = Prj().AbsolutePath( g_RootSheet->GetScreen()->GetFileName() ); @@ -895,7 +897,7 @@ void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event ) return; NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase(); - NETLIST_EXPORTER_KICAD exporter( net_atoms, Prj().SchLibs() ); + NETLIST_EXPORTER_KICAD exporter( net_atoms, Prj().SchSymbolLibTable() ); STRING_FORMATTER formatter; exporter.Format( &formatter, GNL_ALL ); @@ -905,6 +907,7 @@ void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event ) formatter.GetString(), this ); } + void SCH_EDIT_FRAME::OnCreateNetlist( wxCommandEvent& event ) { int result; @@ -924,6 +927,7 @@ void SCH_EDIT_FRAME::OnCreateBillOfMaterials( wxCommandEvent& ) InvokeDialogCreateBOM( this ); } + void SCH_EDIT_FRAME::OnLaunchBomManager( wxCommandEvent& event ) { // First ensure that entire schematic is annotated @@ -933,6 +937,7 @@ void SCH_EDIT_FRAME::OnLaunchBomManager( wxCommandEvent& event ) InvokeDialogCreateBOMEditor( this ); } + void SCH_EDIT_FRAME::OnFindItems( wxCommandEvent& aEvent ) { wxCHECK_RET( m_findReplaceData != NULL, @@ -1214,17 +1219,27 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event ) if( component ) { - if( PART_LIBS* libs = Prj().SchLibs() ) + LIB_ID id = component->GetLibId(); + LIB_ALIAS* entry = nullptr; + + try { - LIB_ALIAS* entry = libs->FindLibraryAlias( component->GetLibId() ); - - if( !entry ) // Should not occur - return; - - PART_LIB* library = entry->GetLib(); - - libeditFrame->LoadComponentAndSelectLib( entry, library ); + entry = Prj().SchSymbolLibTable()->LoadSymbol( id ); } + catch( const IO_ERROR& ioe ) + { + wxString msg; + + msg.Printf( _( "Error occurred loading symbol '%s' from library '%s'." ), + id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() ); + DisplayErrorMessage( this, msg, ioe.What() ); + return; + } + + if( !entry ) // Should not occur + return; + + libeditFrame->LoadComponentAndSelectLib( id ); } GetScreen()->SchematicCleanUp(); diff --git a/eeschema/selpart.cpp b/eeschema/selpart.cpp index 8cd825cf95..daf561472b 100644 --- a/eeschema/selpart.cpp +++ b/eeschema/selpart.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors. + * Copyright (C) 2015-2017 KiCad Developers, see CHANGELOG.TXT for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -31,114 +31,139 @@ #include #include #include +#include #include #include #include -// Used in DisplayListComponentsInLib: this is a callback function for EDA_LIST_DIALOG -// to display keywords and description of a component -static void DisplayCmpDocAndKeywords( wxString& aName, void* aData ) + +static void DisplayCmpDocAndKeywords( wxString& aSelection, void* aData ) { - PART_LIBS* libs = (PART_LIBS*) aData; + SYMBOL_LIB_TABLE* libs = (SYMBOL_LIB_TABLE*) aData; wxASSERT( libs ); - LIB_ID id( wxEmptyString, aName ); - LIB_ALIAS* part = libs->FindLibraryAlias( id ); + LIB_ID id; + + if( id.Parse( aSelection ) != -1 ) + { + aSelection = _( "Invalid symbol library indentifier!" ); + return; + } + + LIB_ALIAS* part = nullptr; + + try + { + part = libs->LoadSymbol( id ); + } + catch( const IO_ERROR& ioe ) + { + aSelection.Printf( _( "Error occurred loading symbol '%s' from library '%s'." ), + id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() ); + return; + } if( !part ) return; - aName = wxT( "Description: " ) + part->GetDescription(); - aName += wxT( "\nKey Words: " ) + part->GetKeyWords(); + aSelection = _( "Description: " ) + part->GetDescription() + "\n"; + aSelection += _( "Key Words: " ) + part->GetKeyWords(); } -PART_LIB* SCH_BASE_FRAME::SelectLibraryFromList() +wxString SCH_BASE_FRAME::SelectLibraryFromList() { - PROJECT& prj = Prj(); + PROJECT& prj = Prj(); - if( PART_LIBS* libs = prj.SchLibs() ) + if( prj.SchSymbolLibTable()->IsEmpty() ) { - if( !libs->GetLibraryCount() ) - { - DisplayError( this, _( "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( this, _( "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; + DisplayError( this, _( "No symbol libraries are loaded." ) ); + return wxEmptyString; } - return NULL; + wxArrayString headers; + + headers.Add( _( "Library" ) ); + + std::vector< wxArrayString > itemsToDisplay; + std::vector< wxString > libNicknames = prj.SchSymbolLibTable()->GetLogicalLibs(); + + // Conversion from wxArrayString to vector of ArrayString + for( auto name : libNicknames ) + { + wxArrayString item; + + item.Add( name ); + itemsToDisplay.push_back( item ); + } + + wxString old_lib_name = prj.GetRString( PROJECT::SCH_LIB_SELECT ); + + EDA_LIST_DIALOG dlg( this, _( "Select Symbol Library" ), headers, itemsToDisplay, + old_lib_name ); + + if( dlg.ShowModal() != wxID_OK ) + return wxEmptyString; + + wxString libname = dlg.GetTextSelection(); + + if( !libname.empty() ) + { + if( prj.SchSymbolLibTable()->HasLibrary( libname ) ) + prj.SetRString( PROJECT::SCH_LIB_SELECT, libname ); + else + libname = wxEmptyString; + } + + return libname; } -bool SCH_BASE_FRAME::DisplayListComponentsInLib( PART_LIB* aLibrary, - wxString& aBuffer, wxString& aPreviousChoice ) +bool SCH_BASE_FRAME::DisplayListComponentsInLib( wxString& aLibrary, wxString& aBuffer, + wxString& aPreviousChoice ) { - wxArrayString nameList; + wxArrayString nameList; - if( aLibrary == NULL ) + if( !aLibrary ) aLibrary = SelectLibraryFromList(); - if( aLibrary == NULL ) + if( !aLibrary ) return false; - aLibrary->GetAliasNames( nameList ); + try + { + Prj().SchSymbolLibTable()->EnumerateSymbolLib( aLibrary, nameList ); + } + catch( const IO_ERROR& ioe ) + { + wxString msg; + + msg.Printf( _( "Error occurred loading symbol library '%s'." ), aLibrary ); + DisplayErrorMessage( this, msg, ioe.What() ); + return false; + } wxArrayString headers; - headers.Add( wxT("Component") ); - headers.Add( wxT("Library") ); + headers.Add( _( "Library:Symbol" ) ); + std::vector itemsToDisplay; // Conversion from wxArrayString to vector of ArrayString for( unsigned i = 0; i < nameList.GetCount(); i++ ) { + LIB_ID id; wxArrayString item; - item.Add( nameList[i] ); - item.Add( aLibrary->GetLogicalName() ); + id.SetLibItemName( nameList[i] ); + id.SetLibNickname( aLibrary ); + item.Add( id.Format() ); itemsToDisplay.push_back( item ); } - EDA_LIST_DIALOG dlg( this, _( "Select Component" ), headers, itemsToDisplay, - aPreviousChoice, DisplayCmpDocAndKeywords, Prj().SchLibs() ); + EDA_LIST_DIALOG dlg( this, _( "Select Symbol" ), headers, itemsToDisplay, aPreviousChoice, + DisplayCmpDocAndKeywords, Prj().SchSymbolLibTable() ); if( dlg.ShowModal() != wxID_OK ) return false; @@ -149,14 +174,11 @@ bool SCH_BASE_FRAME::DisplayListComponentsInLib( PART_LIB* aLibrary, } -bool SCH_BASE_FRAME::SelectPartNameToLoad( PART_LIB* aLibrary, wxString& aBufName ) +bool SCH_BASE_FRAME::SelectPartNameToLoad( wxString& aLibrary, wxString& aBufName ) { - int ii; static wxString previousCmpName; - ii = DisplayListComponentsInLib( aLibrary, aBufName, previousCmpName ); - - if( ii <= 0 || aBufName.IsEmpty() ) + if( !DisplayListComponentsInLib( aLibrary, aBufName, previousCmpName ) || aBufName.empty() ) return false; previousCmpName = aBufName; diff --git a/eeschema/sim/netlist_exporter_pspice_sim.h b/eeschema/sim/netlist_exporter_pspice_sim.h index 78e03fb5c7..f9544a76f7 100644 --- a/eeschema/sim/netlist_exporter_pspice_sim.h +++ b/eeschema/sim/netlist_exporter_pspice_sim.h @@ -2,6 +2,8 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016 CERN + * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. + * * @author Maciej Suminski * * This program is free software; you can redistribute it and/or @@ -34,9 +36,8 @@ class NETLIST_EXPORTER_PSPICE_SIM : public NETLIST_EXPORTER_PSPICE { public: - NETLIST_EXPORTER_PSPICE_SIM( NETLIST_OBJECT_LIST* aMasterList, PART_LIBS* aLibs, - SEARCH_STACK* aPaths = NULL ) : - NETLIST_EXPORTER_PSPICE( aMasterList, aLibs, aPaths ) + NETLIST_EXPORTER_PSPICE_SIM( NETLIST_OBJECT_LIST* aMasterList ) : + NETLIST_EXPORTER_PSPICE( aMasterList ) { } diff --git a/eeschema/sim/sim_plot_frame.cpp b/eeschema/sim/sim_plot_frame.cpp index a2ab19d0e1..de3bebc25a 100644 --- a/eeschema/sim/sim_plot_frame.cpp +++ b/eeschema/sim/sim_plot_frame.cpp @@ -458,8 +458,7 @@ void SIM_PLOT_FRAME::removePlot( const wxString& aPlotName, bool aErase ) void SIM_PLOT_FRAME::updateNetlistExporter() { - m_exporter.reset( new NETLIST_EXPORTER_PSPICE_SIM( m_schematicFrame->BuildNetListBase(), - Prj().SchLibs(), Prj().SchSearchS() ) ); + m_exporter.reset( new NETLIST_EXPORTER_PSPICE_SIM( m_schematicFrame->BuildNetListBase() ) ); } diff --git a/eeschema/symbol_lib_table.cpp b/eeschema/symbol_lib_table.cpp index 986c934244..d9b8f00126 100644 --- a/eeschema/symbol_lib_table.cpp +++ b/eeschema/symbol_lib_table.cpp @@ -245,10 +245,19 @@ int SYMBOL_LIB_TABLE::GetModifyHash() } +size_t SYMBOL_LIB_TABLE::GetSymbolCount( const wxString& aNickname ) +{ + SYMBOL_LIB_TABLE_ROW* row = dynamic_cast< SYMBOL_LIB_TABLE_ROW* >( findRow( aNickname ) ); + wxASSERT( (SCH_PLUGIN*) row->plugin ); + + return row->plugin->GetSymbolLibCount( row->GetFullURI( true ) ); +} + + void SYMBOL_LIB_TABLE::EnumerateSymbolLib( const wxString& aNickname, wxArrayString& aAliasNames, bool aPowerSymbolsOnly ) { - SYMBOL_LIB_TABLE_ROW* row = dynamic_cast< SYMBOL_LIB_TABLE_ROW* >( findRow( aNickname ) ); + SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname ); wxASSERT( (SCH_PLUGIN*) row->plugin ); wxString options = row->GetOptions(); @@ -263,7 +272,7 @@ void SYMBOL_LIB_TABLE::EnumerateSymbolLib( const wxString& aNickname, wxArrayStr } -const SYMBOL_LIB_TABLE_ROW* SYMBOL_LIB_TABLE::FindRow( const wxString& aNickname ) +SYMBOL_LIB_TABLE_ROW* SYMBOL_LIB_TABLE::FindRow( const wxString& aNickname ) { SYMBOL_LIB_TABLE_ROW* row = dynamic_cast< SYMBOL_LIB_TABLE_ROW* >( findRow( aNickname ) ); diff --git a/eeschema/symbol_lib_table.h b/eeschema/symbol_lib_table.h index d52a24c1e4..63cfe6cc55 100644 --- a/eeschema/symbol_lib_table.h +++ b/eeschema/symbol_lib_table.h @@ -134,12 +134,17 @@ public: * * @throw IO_ERROR if \a aNickName cannot be found. */ - const SYMBOL_LIB_TABLE_ROW* FindRow( const wxString& aNickName ); + SYMBOL_LIB_TABLE_ROW* FindRow( const wxString& aNickName ); int GetModifyHash(); //-------------------------------- + /** + * Return the number of symbols in the symbol library mapped to \a aNickname + */ + size_t GetSymbolCount( const wxString& aNickname ); + /** * Return a list of symbol alias names contained within the library given by @a aNickname. * diff --git a/eeschema/tool_viewlib.cpp b/eeschema/tool_viewlib.cpp index 184468082e..2bb39bbf55 100644 --- a/eeschema/tool_viewlib.cpp +++ b/eeschema/tool_viewlib.cpp @@ -2,8 +2,8 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2008-2016 Wayne Stambaugh - * Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2008 Wayne Stambaugh + * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -39,6 +39,7 @@ #include "help_common_strings.h" #include "hotkeys.h" #include "viewlib_frame.h" +#include void LIB_VIEW_FRAME::ReCreateHToolbar() @@ -124,9 +125,9 @@ void LIB_VIEW_FRAME::ReCreateHToolbar() if( m_libraryName.size() && m_entryName.size() ) { - if( PART_LIB* lib = Prj().SchLibs()->FindLibrary( m_libraryName ) ) + if( Prj().SchSymbolLibTable()->HasLibrary( m_libraryName ) ) { - part = lib->FindPart( m_entryName ); + part = GetLibPart( LIB_ID( m_libraryName, m_entryName ) ); } } diff --git a/include/lib_table_base.h b/include/lib_table_base.h index eba6dbc0f0..c8c3e844cd 100644 --- a/include/lib_table_base.h +++ b/include/lib_table_base.h @@ -352,6 +352,11 @@ public: */ std::vector GetLogicalLibs(); + /** + * Return the full URI of the library mapped to \a aLibNickname. + */ + wxString GetFullURI( const wxString& aLibNickname, bool aExpandEnvVars = true ) const; + /** * Adds \a aRow if it does not already exist or if doReplace is true. If doReplace * is not true and the key for aRow already exists, the function fails and returns false.