Revise symbol rescuer to support symbol library table.
Refactor rescue objects so that they can support derivation. Factor out legacy rescuer code to perform legacy project rescues. Create new symbol library table rescuer for rescuing symbol library table based projects. Perform the correct rescue type on project load. Add symbol library table remapping support to the tools menu for run on demand as applicable. Add flag to SCH_SCREENS::UpdateSymbolLinks() to allow forcing the symbol link updates when the library modification hash has not changed.
This commit is contained in:
parent
36f6d4a1f4
commit
c1f7c1778a
|
@ -444,9 +444,6 @@ LIB_ALIAS* PART_LIBS::FindLibraryAlias( const LIB_ID& aLibId, const wxString& aL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* searches all libraries in the list for an entry, using a case insensitive comparison.
|
|
||||||
* Used to find an entry, when the normal (case sensitive) search fails.
|
|
||||||
*/
|
|
||||||
void PART_LIBS::FindLibraryNearEntries( std::vector<LIB_ALIAS*>& aCandidates,
|
void PART_LIBS::FindLibraryNearEntries( std::vector<LIB_ALIAS*>& aCandidates,
|
||||||
const wxString& aEntryName,
|
const wxString& aEntryName,
|
||||||
const wxString& aLibraryName )
|
const wxString& aLibraryName )
|
||||||
|
|
|
@ -196,15 +196,18 @@ public:
|
||||||
void Place( SCH_EDIT_FRAME* frame, wxDC* DC ) { };
|
void Place( SCH_EDIT_FRAME* frame, wxDC* DC ) { };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CheckComponentsToPartsLink
|
* Initialize or reinitialize the weak reference to the #LIB_PART for each #SCH_COMPONENT
|
||||||
* initializes or reinitializes the weak reference
|
* found in m_drawList.
|
||||||
* to the LIB_PART for each SCH_COMPONENT found in m_drawList.
|
*
|
||||||
* It must be called from:
|
* It must be called from:
|
||||||
* - Draw function
|
* - Draw function
|
||||||
* - when loading a schematic file
|
* - when loading a schematic file
|
||||||
* - before creating a netlist (in case a library is modified)
|
* - before creating a netlist (in case a library is modified)
|
||||||
|
* - whenever a symbol library is modified
|
||||||
|
*
|
||||||
|
* @param aForce true forces a refresh even if the library modification has hasn't changed.
|
||||||
*/
|
*/
|
||||||
void CheckComponentsToPartsLinks();
|
void UpdateSymbolLinks( bool aForce = false );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Draw
|
* Function Draw
|
||||||
|
@ -588,11 +591,12 @@ public:
|
||||||
* found in the full schematic.
|
* found in the full schematic.
|
||||||
*
|
*
|
||||||
* It must be called from:
|
* It must be called from:
|
||||||
* - Draw function
|
* - draw functions
|
||||||
* - when loading a schematic file
|
* - when loading a schematic file
|
||||||
* - before creating a netlist (in case a library is modified)
|
* - before creating a netlist (in case a library is modified)
|
||||||
|
* - whenever any of the libraries are modified.
|
||||||
*/
|
*/
|
||||||
void UpdateSymbolLinks();
|
void UpdateSymbolLinks( bool aForce = false );
|
||||||
|
|
||||||
void TestDanglingEnds();
|
void TestDanglingEnds();
|
||||||
|
|
||||||
|
|
|
@ -1215,7 +1215,7 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::UpdateFields( wxCommandEvent& event )
|
||||||
SCH_COMPONENT copy( *m_cmp );
|
SCH_COMPONENT copy( *m_cmp );
|
||||||
std::list<SCH_COMPONENT*> components;
|
std::list<SCH_COMPONENT*> components;
|
||||||
components.push_back( © );
|
components.push_back( © );
|
||||||
InvokeDialogUpdateFields( m_parent, components, false );
|
InvokeDialogUpdateFields( GetParent(), components, false );
|
||||||
|
|
||||||
// Copy fields from the modified component copy to the dialog buffer
|
// Copy fields from the modified component copy to the dialog buffer
|
||||||
m_FieldsBuf.clear();
|
m_FieldsBuf.clear();
|
||||||
|
|
|
@ -38,9 +38,10 @@ class DIALOG_RESCUE_EACH: public DIALOG_RESCUE_EACH_BASE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
|
||||||
* This dialog asks the user which rescuable, cached parts he wants to rescue.
|
* This dialog asks the user which rescuable, cached parts he wants to rescue.
|
||||||
|
*
|
||||||
* Any rejects will be pruned from aCandidates.
|
* Any rejects will be pruned from aCandidates.
|
||||||
|
*
|
||||||
* @param aParent - the SCH_EDIT_FRAME calling this
|
* @param aParent - the SCH_EDIT_FRAME calling this
|
||||||
* @param aRescuer - the active RESCUER instance
|
* @param aRescuer - the active RESCUER instance
|
||||||
* @param aAskShowAgain - if true, a "Never Show Again" button will be included
|
* @param aAskShowAgain - if true, a "Never Show Again" button will be included
|
||||||
|
@ -81,7 +82,7 @@ DIALOG_RESCUE_EACH::DIALOG_RESCUE_EACH( SCH_EDIT_FRAME* aParent, RESCUER& aRescu
|
||||||
|
|
||||||
// Set the info message, customized to include the proper suffix.
|
// Set the info message, customized to include the proper suffix.
|
||||||
wxString info_message =
|
wxString info_message =
|
||||||
_( "It looks like this project was made using older schematic component libraries.\n"
|
_( "It looks like this project was made using older schematic symbol libraries.\n"
|
||||||
"Some parts may need to be relinked to a different symbol name, and some symbols\n"
|
"Some parts may need to be relinked to a different symbol name, and some symbols\n"
|
||||||
"may need to be \"rescued\" (cloned and renamed) into a new library.\n"
|
"may need to be \"rescued\" (cloned and renamed) into a new library.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -157,6 +158,7 @@ void DIALOG_RESCUE_EACH::PopulateInstanceList()
|
||||||
|
|
||||||
wxVector<wxVariant> data;
|
wxVector<wxVariant> data;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for( SCH_COMPONENT* each_component : *m_Rescuer->GetComponents() )
|
for( SCH_COMPONENT* each_component : *m_Rescuer->GetComponents() )
|
||||||
{
|
{
|
||||||
if( each_component->GetLibId().Format() != UTF8( selected_part.GetRequestedName() ) )
|
if( each_component->GetLibId().Format() != UTF8( selected_part.GetRequestedName() ) )
|
||||||
|
@ -290,9 +292,9 @@ void DIALOG_RESCUE_EACH::OnNeverShowClick( wxCommandEvent& aEvent )
|
||||||
wxMessageDialog dlg( m_Parent,
|
wxMessageDialog dlg( m_Parent,
|
||||||
_( "Stop showing this tool?\n"
|
_( "Stop showing this tool?\n"
|
||||||
"No changes will be made.\n\n"
|
"No changes will be made.\n\n"
|
||||||
"This setting can be changed from the \"Component Libraries\" dialog,\n"
|
"This setting can be changed from the \"Symbol Libraries\" dialog,\n"
|
||||||
"and the tool can be activated manually from the \"Tools\" menu." ),
|
"and the tool can be activated manually from the \"Tools\" menu." ),
|
||||||
_( "Rescue Components" ), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
|
_( "Rescue Symbolss" ), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
|
||||||
int resp = dlg.ShowModal ();
|
int resp = dlg.ShowModal ();
|
||||||
|
|
||||||
if( resp == wxID_YES )
|
if( resp == wxID_YES )
|
||||||
|
|
|
@ -237,7 +237,7 @@ void DIALOG_SYMBOL_REMAP::remapSymbolsToLibTable( REPORTER& aReporter )
|
||||||
}
|
}
|
||||||
|
|
||||||
aReporter.Report( _( "Symbol library table mapping complete!" ), REPORTER::RPT_INFO );
|
aReporter.Report( _( "Symbol library table mapping complete!" ), REPORTER::RPT_INFO );
|
||||||
schematic.UpdateSymbolLinks();
|
schematic.UpdateSymbolLinks( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||||
* Copyright (C) 2008-2017 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2008-2017 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -65,6 +65,7 @@ enum id_eeschema_frm
|
||||||
/* Schematic editor main menubar IDs. */
|
/* Schematic editor main menubar IDs. */
|
||||||
ID_RESCUE_CACHED,
|
ID_RESCUE_CACHED,
|
||||||
ID_EDIT_SYM_LIB_TABLE,
|
ID_EDIT_SYM_LIB_TABLE,
|
||||||
|
ID_REMAP_SYMBOLS,
|
||||||
|
|
||||||
/* Schematic editor horizontal toolbar IDs */
|
/* Schematic editor horizontal toolbar IDs */
|
||||||
ID_HIERARCHY,
|
ID_HIERARCHY,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* 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) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2013-2017 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
|
||||||
* Copyright (C) 2013 CERN (www.cern.ch)
|
* Copyright (C) 2013 CERN (www.cern.ch)
|
||||||
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
|
@ -329,22 +329,16 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
|
|
||||||
UpdateFileHistory( fullFileName );
|
UpdateFileHistory( fullFileName );
|
||||||
|
|
||||||
// Check to see whether some old library parts need to be rescued
|
|
||||||
// Only do this if RescueNeverShow was not set.
|
|
||||||
wxConfigBase *config = Kiface().KifaceSettings();
|
|
||||||
bool rescueNeverShow = false;
|
|
||||||
config->Read( RescueNeverShowEntry, &rescueNeverShow, false );
|
|
||||||
|
|
||||||
if( !rescueNeverShow )
|
|
||||||
{
|
|
||||||
RescueProject( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
SCH_SCREENS schematic;
|
SCH_SCREENS schematic;
|
||||||
|
|
||||||
// Convert old projects over to use symbol library table.
|
// Convert old projects over to use symbol library table.
|
||||||
if( schematic.HasNoFullyDefinedLibIds() )
|
if( schematic.HasNoFullyDefinedLibIds() )
|
||||||
{
|
{
|
||||||
|
// Ignore the never show rescue setting for one last rescue of legacy symbol
|
||||||
|
// libraries before remapping to the symbol library table. This ensures the
|
||||||
|
// best remapping results.
|
||||||
|
RescueLegacyProject( false );
|
||||||
|
|
||||||
// Make backups of current schematics just in case something goes wrong.
|
// Make backups of current schematics just in case something goes wrong.
|
||||||
for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
|
for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
|
||||||
SaveEEFile( screen, false, CREATE_BACKUP_FILE );
|
SaveEEFile( screen, false, CREATE_BACKUP_FILE );
|
||||||
|
@ -353,6 +347,17 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
|
|
||||||
dlgRemap.ShowQuasiModal();
|
dlgRemap.ShowQuasiModal();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Check to see whether some old library parts need to be rescued
|
||||||
|
// Only do this if RescueNeverShow was not set.
|
||||||
|
wxConfigBase *config = Kiface().KifaceSettings();
|
||||||
|
bool rescueNeverShow = false;
|
||||||
|
config->Read( RescueNeverShowEntry, &rescueNeverShow, false );
|
||||||
|
|
||||||
|
if( !rescueNeverShow )
|
||||||
|
RescueSymbolLibTableProject( false );
|
||||||
|
}
|
||||||
|
|
||||||
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
|
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
|
||||||
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
|
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
|
||||||
|
|
|
@ -108,6 +108,7 @@ bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName )
|
||||||
DisplayError( this, msg );
|
DisplayError( this, msg );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( part )
|
if( part )
|
||||||
{
|
{
|
||||||
|
@ -116,7 +117,6 @@ bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -274,7 +274,7 @@ again." );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Build links between each components and its part lib LIB_PART
|
// Build links between each components and its part lib LIB_PART
|
||||||
aScreen->CheckComponentsToPartsLinks();
|
aScreen->UpdateSymbolLinks();
|
||||||
|
|
||||||
aScreen->TestDanglingEnds();
|
aScreen->TestDanglingEnds();
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* 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) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2009-2016 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@gmail.com>
|
||||||
* Copyright (C) 1992-2017 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
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -489,8 +489,14 @@ void prepareToolsMenu( wxMenu* aParentMenu )
|
||||||
|
|
||||||
AddMenuItem( aParentMenu,
|
AddMenuItem( aParentMenu,
|
||||||
ID_RESCUE_CACHED,
|
ID_RESCUE_CACHED,
|
||||||
_( "&Rescue Old Component" ),
|
_( "&Rescue Symbols" ),
|
||||||
_( "Find old components in project and rename/rescue them" ),
|
_( "Find old symbols in project and rename/rescue them" ),
|
||||||
|
KiBitmap( rescue_xpm ) );
|
||||||
|
|
||||||
|
AddMenuItem( aParentMenu,
|
||||||
|
ID_REMAP_SYMBOLS,
|
||||||
|
_( "Remap Symbols" ),
|
||||||
|
_( "Remap legacy library symbols to symbol library table" ),
|
||||||
KiBitmap( rescue_xpm ) );
|
KiBitmap( rescue_xpm ) );
|
||||||
|
|
||||||
aParentMenu->AppendSeparator();
|
aParentMenu->AppendSeparator();
|
||||||
|
|
|
@ -122,7 +122,7 @@ bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName,
|
||||||
SCH_SCREENS schematic;
|
SCH_SCREENS schematic;
|
||||||
schematic.UpdateSymbolLinks();
|
schematic.UpdateSymbolLinks();
|
||||||
SCH_SHEET_LIST sheets( g_RootSheet );
|
SCH_SHEET_LIST sheets( g_RootSheet );
|
||||||
sheets.AnnotatePowerSymbols( Prj().SchLibs() );
|
sheets.AnnotatePowerSymbols();
|
||||||
schematic.SchematicCleanUp();
|
schematic.SchematicCleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,13 @@
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <invoke_sch_dialog.h>
|
#include <invoke_sch_dialog.h>
|
||||||
#include <kicad_device_context.h>
|
#include <kicad_device_context.h>
|
||||||
|
#include <kiway.h>
|
||||||
#include <project_rescue.h>
|
#include <project_rescue.h>
|
||||||
#include <sch_component.h>
|
#include <sch_component.h>
|
||||||
#include <sch_sheet.h>
|
#include <sch_sheet.h>
|
||||||
#include <schframe.h>
|
#include <schframe.h>
|
||||||
|
#include <symbol_lib_table.h>
|
||||||
|
#include <viewlib_frame.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
@ -40,117 +43,16 @@
|
||||||
typedef std::pair<SCH_COMPONENT*, wxString> COMPONENT_NAME_PAIR;
|
typedef std::pair<SCH_COMPONENT*, wxString> COMPONENT_NAME_PAIR;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function save_library
|
|
||||||
* writes the library out to disk. Returns true on success.
|
|
||||||
*
|
|
||||||
* @param aLibrary - Library to write
|
|
||||||
* @param aEditFrame - the calling SCH_EDIT_FRAME
|
|
||||||
*/
|
|
||||||
static bool save_library( PART_LIB* aLibrary, SCH_EDIT_FRAME* aEditFrame )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
aLibrary->Save( false );
|
|
||||||
}
|
|
||||||
catch( ... /* IO_ERROR ioe */ )
|
|
||||||
{
|
|
||||||
wxString msg = wxString::Format( _( "Failed to create component library file '%s'" ),
|
|
||||||
GetChars( aLibrary->GetFullFileName() )
|
|
||||||
);
|
|
||||||
DisplayError( aEditFrame, msg );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function insert_library
|
|
||||||
* inserts a library into the project and refreshes libraries.
|
|
||||||
*
|
|
||||||
* @param aProject - project that will be modified
|
|
||||||
* @param aLibrary - PART_LIB to add
|
|
||||||
* @param aIndex - index in the list at which the library is to be inserted
|
|
||||||
*
|
|
||||||
* @return true on success, false on failure
|
|
||||||
*/
|
|
||||||
static bool insert_library( PROJECT *aProject, PART_LIB *aLibrary, size_t aIndex )
|
|
||||||
{
|
|
||||||
wxArrayString libNames;
|
|
||||||
wxString libPaths;
|
|
||||||
|
|
||||||
wxString libName = aLibrary->GetName();
|
|
||||||
PART_LIBS *libs = dynamic_cast<PART_LIBS*>( aProject->GetElem( PROJECT::ELEM_SCH_PART_LIBS ) );
|
|
||||||
if( !libs )
|
|
||||||
{
|
|
||||||
libs = new PART_LIBS();
|
|
||||||
aProject->SetElem( PROJECT::ELEM_SCH_PART_LIBS, libs );
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
PART_LIBS::LibNamesAndPaths( aProject, false, &libPaths, &libNames );
|
|
||||||
|
|
||||||
// Make sure the library is not already in the list
|
|
||||||
while( libNames.Index( libName ) != wxNOT_FOUND )
|
|
||||||
libNames.Remove( libName );
|
|
||||||
|
|
||||||
// Add the library to the list and save
|
|
||||||
libNames.Insert( libName, aIndex );
|
|
||||||
PART_LIBS::LibNamesAndPaths( aProject, true, &libPaths, &libNames );
|
|
||||||
}
|
|
||||||
catch( const IO_ERROR& )
|
|
||||||
{
|
|
||||||
// Could not get or save the current libraries.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the old libraries in case there is a problem after clear(). We'll
|
|
||||||
// put them back in.
|
|
||||||
boost::ptr_vector<PART_LIB> libsSave;
|
|
||||||
libsSave.transfer( libsSave.end(), libs->begin(), libs->end(), *libs );
|
|
||||||
|
|
||||||
aProject->SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
|
|
||||||
|
|
||||||
libs = new PART_LIBS();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
libs->LoadAllLibraries( aProject );
|
|
||||||
}
|
|
||||||
catch( const PARSE_ERROR& )
|
|
||||||
{
|
|
||||||
// Some libraries were not found. There's no point in showing the error,
|
|
||||||
// because it was already shown. Just don't do anything.
|
|
||||||
}
|
|
||||||
catch( const IO_ERROR& )
|
|
||||||
{
|
|
||||||
// Restore the old list
|
|
||||||
libs->clear();
|
|
||||||
libs->transfer( libs->end(), libsSave.begin(), libsSave.end(), libsSave );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
aProject->SetElem( PROJECT::ELEM_SCH_PART_LIBS, libs );
|
|
||||||
|
|
||||||
// Update the schematic symbol library links since the library list has changed.
|
|
||||||
SCH_SCREENS schematic;
|
|
||||||
|
|
||||||
schematic.UpdateSymbolLinks();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Helper sort function, used in get_components, to sort a component list by lib_id
|
// Helper sort function, used in get_components, to sort a component list by lib_id
|
||||||
static bool sort_by_libid( const SCH_COMPONENT* ref, SCH_COMPONENT* cmp )
|
static bool sort_by_libid( const SCH_COMPONENT* ref, SCH_COMPONENT* cmp )
|
||||||
{
|
{
|
||||||
return ref->GetLibId() < cmp->GetLibId();
|
return ref->GetLibId() < cmp->GetLibId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function get_components
|
* Fill a vector with all of the project's components, to ease iterating over them.
|
||||||
* Fills a vector with all of the project's components, to ease iterating over them.
|
*
|
||||||
* The list is sorted by lib id, therefore components using the same library
|
* The list is sorted by lib id, therefore components using the same library
|
||||||
* symbol are grouped, allowing later faster calculations (one library search by group
|
* symbol are grouped, allowing later faster calculations (one library search by group
|
||||||
* of symbols)
|
* of symbols)
|
||||||
|
@ -168,18 +70,21 @@ static void get_components( std::vector<SCH_COMPONENT*>& aComponents )
|
||||||
{
|
{
|
||||||
if( item->Type() != SCH_COMPONENT_T )
|
if( item->Type() != SCH_COMPONENT_T )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( item );
|
SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( item );
|
||||||
aComponents.push_back( component );
|
aComponents.push_back( component );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( aComponents.empty() )
|
||||||
|
return;
|
||||||
|
|
||||||
// sort aComponents by lib part. Components will be grouped by same lib part.
|
// sort aComponents by lib part. Components will be grouped by same lib part.
|
||||||
std::sort( aComponents.begin(), aComponents.end(), sort_by_libid );
|
std::sort( aComponents.begin(), aComponents.end(), sort_by_libid );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function find_component
|
|
||||||
* Search the libraries for the first component with a given name.
|
* Search the libraries for the first component with a given name.
|
||||||
*
|
*
|
||||||
* @param aName - name to search for
|
* @param aName - name to search for
|
||||||
|
@ -199,6 +104,7 @@ static LIB_PART* find_component( wxString aName, PART_LIBS* aLibs, bool aCached
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
part = each_lib.FindPart( aName );
|
part = each_lib.FindPart( aName );
|
||||||
|
|
||||||
if( part )
|
if( part )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -207,50 +113,27 @@ static LIB_PART* find_component( wxString aName, PART_LIBS* aLibs, bool aCached
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RESCUER::RemoveDuplicates()
|
static wxFileName GetRescueLibraryFileName()
|
||||||
{
|
{
|
||||||
std::vector<wxString> names_seen;
|
wxFileName fn( g_RootSheet->GetScreen()->GetFileName() );
|
||||||
|
fn.SetName( fn.GetName() + wxT( "-rescue" ) );
|
||||||
for( boost::ptr_vector<RESCUE_CANDIDATE>::iterator it = m_all_candidates.begin();
|
fn.SetExt( SchematicLibraryFileExtension );
|
||||||
it != m_all_candidates.end(); )
|
return fn;
|
||||||
{
|
|
||||||
bool seen_already = false;
|
|
||||||
for( wxString& name_seen : names_seen )
|
|
||||||
{
|
|
||||||
if( name_seen == it->GetRequestedName() )
|
|
||||||
{
|
|
||||||
seen_already = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( seen_already )
|
|
||||||
{
|
|
||||||
it = m_all_candidates.erase( it );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
names_seen.push_back( it->GetRequestedName() );
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class RESCUE_CASE_CANDIDATE: public RESCUE_CANDIDATE
|
RESCUE_CASE_CANDIDATE::RESCUE_CASE_CANDIDATE( const wxString& aRequestedName,
|
||||||
|
const wxString& aNewName,
|
||||||
|
LIB_PART* aLibCandidate )
|
||||||
{
|
{
|
||||||
wxString m_requested_name;
|
m_requested_name = aRequestedName;
|
||||||
wxString m_new_name;
|
m_new_name = aNewName;
|
||||||
LIB_PART* m_lib_candidate;
|
m_lib_candidate = aLibCandidate;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
|
||||||
* Function FindRescues
|
boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates )
|
||||||
* Grab all possible RESCUE_CASE_CANDIDATES into a vector.
|
|
||||||
* @param aRescuer - the working RESCUER instance.
|
|
||||||
* @param aCandidates - the vector the will hold the candidates.
|
|
||||||
*/
|
|
||||||
static void FindRescues( RESCUER& aRescuer, boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates )
|
|
||||||
{
|
{
|
||||||
typedef std::map<wxString, RESCUE_CASE_CANDIDATE> candidate_map_t;
|
typedef std::map<wxString, RESCUE_CASE_CANDIDATE> candidate_map_t;
|
||||||
candidate_map_t candidate_map;
|
candidate_map_t candidate_map;
|
||||||
|
@ -275,18 +158,18 @@ public:
|
||||||
|
|
||||||
LIB_ID id( wxEmptyString, part_name );
|
LIB_ID id( wxEmptyString, part_name );
|
||||||
|
|
||||||
case_sensitive_match = aRescuer.GetLibs()->FindLibraryAlias( id );
|
case_sensitive_match = aRescuer.GetPrj()->SchLibs()->FindLibraryAlias( id );
|
||||||
|
|
||||||
if( !case_sensitive_match )
|
if( !case_sensitive_match )
|
||||||
// the case sensitive match failed. Try a case insensitive match
|
// the case sensitive match failed. Try a case insensitive match
|
||||||
aRescuer.GetLibs()->FindLibraryNearEntries( case_insensitive_matches, part_name );
|
aRescuer.GetPrj()->SchLibs()->FindLibraryNearEntries( case_insensitive_matches,
|
||||||
|
part_name );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( case_sensitive_match || !( case_insensitive_matches.size() ) )
|
if( case_sensitive_match || !( case_insensitive_matches.size() ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RESCUE_CASE_CANDIDATE candidate(
|
RESCUE_CASE_CANDIDATE candidate( part_name, case_insensitive_matches[0]->GetName(),
|
||||||
part_name, case_insensitive_matches[0]->GetName(),
|
|
||||||
case_insensitive_matches[0]->GetPart() );
|
case_insensitive_matches[0]->GetPart() );
|
||||||
|
|
||||||
candidate_map[part_name] = candidate;
|
candidate_map[part_name] = candidate;
|
||||||
|
@ -299,31 +182,16 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor RESCUE_CANDIDATE
|
|
||||||
* @param aRequestedName - the name the schematic asks for
|
|
||||||
* @param aNewName - the name we want to change it to
|
|
||||||
* @param aLibCandidate - the part that will give us
|
|
||||||
*/
|
|
||||||
RESCUE_CASE_CANDIDATE( const wxString& aRequestedName, const wxString& aNewName,
|
|
||||||
LIB_PART* aLibCandidate )
|
|
||||||
: m_requested_name( aRequestedName ),
|
|
||||||
m_new_name( aNewName ),
|
|
||||||
m_lib_candidate( aLibCandidate ) { }
|
|
||||||
|
|
||||||
RESCUE_CASE_CANDIDATE() { m_lib_candidate = NULL; }
|
wxString RESCUE_CASE_CANDIDATE::GetActionDescription() const
|
||||||
|
|
||||||
virtual wxString GetRequestedName() const override { return m_requested_name; }
|
|
||||||
virtual wxString GetNewName() const override { return m_new_name; }
|
|
||||||
virtual LIB_PART* GetLibCandidate() const override { return m_lib_candidate; }
|
|
||||||
virtual wxString GetActionDescription() const override
|
|
||||||
{
|
{
|
||||||
wxString action;
|
wxString action;
|
||||||
action.Printf( _( "Rename to %s" ), m_new_name );
|
action.Printf( _( "Rename to %s" ), m_new_name );
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool PerformAction( RESCUER* aRescuer ) override
|
|
||||||
|
bool RESCUE_CASE_CANDIDATE::PerformAction( RESCUER* aRescuer )
|
||||||
{
|
{
|
||||||
for( SCH_COMPONENT* each_component : *aRescuer->GetComponents() )
|
for( SCH_COMPONENT* each_component : *aRescuer->GetComponents() )
|
||||||
{
|
{
|
||||||
|
@ -337,28 +205,32 @@ public:
|
||||||
each_component->ClearFlags();
|
each_component->ClearFlags();
|
||||||
aRescuer->LogRescue( each_component, m_requested_name, m_new_name );
|
aRescuer->LogRescue( each_component, m_requested_name, m_new_name );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class RESCUE_CACHE_CANDIDATE: public RESCUE_CANDIDATE
|
RESCUE_CACHE_CANDIDATE::RESCUE_CACHE_CANDIDATE( const wxString& aRequestedName,
|
||||||
|
const wxString& aNewName,
|
||||||
|
LIB_PART* aCacheCandidate,
|
||||||
|
LIB_PART* aLibCandidate )
|
||||||
{
|
{
|
||||||
wxString m_requested_name;
|
m_requested_name = aRequestedName;
|
||||||
wxString m_new_name;
|
m_new_name = aNewName;
|
||||||
LIB_PART* m_cache_candidate;
|
m_cache_candidate = aCacheCandidate;
|
||||||
LIB_PART* m_lib_candidate;
|
m_lib_candidate = aLibCandidate;
|
||||||
|
}
|
||||||
|
|
||||||
static std::unique_ptr<PART_LIB> m_rescue_lib;
|
|
||||||
|
|
||||||
public:
|
RESCUE_CACHE_CANDIDATE::RESCUE_CACHE_CANDIDATE()
|
||||||
/**
|
{
|
||||||
* Function FindRescues
|
m_cache_candidate = NULL;
|
||||||
* Grab all possible RESCUE_CACHE_CANDIDATEs into a vector.
|
m_lib_candidate = NULL;
|
||||||
* @param aRescuer - the working RESCUER instance.
|
}
|
||||||
* @param aCandidates - the vector the will hold the candidates.
|
|
||||||
*/
|
|
||||||
static void FindRescues( RESCUER& aRescuer, boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates )
|
void RESCUE_CACHE_CANDIDATE::FindRescues( RESCUER& aRescuer,
|
||||||
|
boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates )
|
||||||
{
|
{
|
||||||
typedef std::map<wxString, RESCUE_CACHE_CANDIDATE> candidate_map_t;
|
typedef std::map<wxString, RESCUE_CACHE_CANDIDATE> candidate_map_t;
|
||||||
candidate_map_t candidate_map;
|
candidate_map_t candidate_map;
|
||||||
|
@ -380,22 +252,24 @@ public:
|
||||||
// A new part name is found (a new group starts here).
|
// A new part name is found (a new group starts here).
|
||||||
// Search the symbol names candidates only once for this group:
|
// Search the symbol names candidates only once for this group:
|
||||||
old_part_name = part_name;
|
old_part_name = part_name;
|
||||||
cache_match = find_component( part_name, aRescuer.GetLibs(), /* aCached */ true );
|
cache_match = find_component( part_name, aRescuer.GetPrj()->SchLibs(), true );
|
||||||
LIB_ID id( wxEmptyString, part_name );
|
LIB_ID id( wxEmptyString, part_name );
|
||||||
lib_match = aRescuer.GetLibs()->FindLibPart( id );
|
lib_match = aRescuer.GetPrj()->SchLibs()->FindLibPart( id );
|
||||||
|
|
||||||
// Test whether there is a conflict
|
// Test whether there is a conflict
|
||||||
if( !cache_match || !lib_match )
|
if( !cache_match || !lib_match )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( !cache_match->PinsConflictWith( *lib_match, /* aTestNums */ true,
|
if( !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) )
|
||||||
/* aTestNames */ true, /* aTestType */ true, /* aTestOrientation */ true,
|
|
||||||
/* aTestLength */ false ))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RESCUE_CACHE_CANDIDATE candidate(
|
// May have been rescued already.
|
||||||
part_name, part_name + part_name_suffix,
|
wxString new_name = part_name;
|
||||||
cache_match, lib_match );
|
|
||||||
|
if( new_name.Find( part_name_suffix ) == wxNOT_FOUND )
|
||||||
|
new_name += part_name_suffix;
|
||||||
|
|
||||||
|
RESCUE_CACHE_CANDIDATE candidate( part_name, new_name, cache_match, lib_match );
|
||||||
|
|
||||||
candidate_map[part_name] = candidate;
|
candidate_map[part_name] = candidate;
|
||||||
}
|
}
|
||||||
|
@ -408,57 +282,21 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor RESCUE_CACHE_CANDIDATE
|
|
||||||
* @param aRequestedName - the name the schematic asks for
|
|
||||||
* @param aNewName - the name we want to change it to
|
|
||||||
* @param aCacheCandidate - the part from the cache
|
|
||||||
* @param aLibCandidate - the part that would be loaded from the library
|
|
||||||
*/
|
|
||||||
RESCUE_CACHE_CANDIDATE( const wxString& aRequestedName, const wxString& aNewName,
|
|
||||||
LIB_PART* aCacheCandidate, LIB_PART* aLibCandidate )
|
|
||||||
: m_requested_name( aRequestedName ),
|
|
||||||
m_new_name( aNewName ),
|
|
||||||
m_cache_candidate( aCacheCandidate ),
|
|
||||||
m_lib_candidate( aLibCandidate ) { }
|
|
||||||
|
|
||||||
RESCUE_CACHE_CANDIDATE()
|
wxString RESCUE_CACHE_CANDIDATE::GetActionDescription() const
|
||||||
: m_cache_candidate( NULL ), m_lib_candidate( NULL ) {}
|
|
||||||
|
|
||||||
virtual wxString GetRequestedName() const override { return m_requested_name; }
|
|
||||||
virtual wxString GetNewName() const override { return m_new_name; }
|
|
||||||
virtual LIB_PART* GetCacheCandidate() const override { return m_cache_candidate; }
|
|
||||||
virtual LIB_PART* GetLibCandidate() const override { return m_lib_candidate; }
|
|
||||||
virtual wxString GetActionDescription() const override
|
|
||||||
{
|
{
|
||||||
wxString action;
|
wxString action;
|
||||||
action.Printf( _( "Rescue %s as %s" ), m_requested_name, m_new_name );
|
action.Printf( _( "Rescue %s as %s" ), m_requested_name, m_new_name );
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Function OpenRescueLibrary
|
bool RESCUE_CACHE_CANDIDATE::PerformAction( RESCUER* aRescuer )
|
||||||
* Creates the new rescue library. Must be called before calling any PerformAction()s.
|
|
||||||
*/
|
|
||||||
static void OpenRescueLibrary()
|
|
||||||
{
|
{
|
||||||
wxFileName fn( g_RootSheet->GetScreen()->GetFileName() );
|
LIB_PART new_part( *m_cache_candidate );
|
||||||
fn.SetName( fn.GetName() + wxT( "-rescue" ) );
|
|
||||||
fn.SetExt( SchematicLibraryFileExtension );
|
|
||||||
|
|
||||||
std::unique_ptr<PART_LIB> rescue_lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA,
|
|
||||||
fn.GetFullPath() ) );
|
|
||||||
|
|
||||||
m_rescue_lib = std::move( rescue_lib );
|
|
||||||
m_rescue_lib->EnableBuffering();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool PerformAction( RESCUER* aRescuer ) override
|
|
||||||
{
|
|
||||||
LIB_PART new_part( *m_cache_candidate, m_rescue_lib.get() );
|
|
||||||
new_part.SetName( m_new_name );
|
new_part.SetName( m_new_name );
|
||||||
new_part.RemoveAllAliases();
|
new_part.RemoveAllAliases();
|
||||||
RESCUE_CACHE_CANDIDATE::m_rescue_lib.get()->AddPart( &new_part );
|
aRescuer->AddPart( &new_part );
|
||||||
|
|
||||||
for( SCH_COMPONENT* each_component : *aRescuer->GetComponents() )
|
for( SCH_COMPONENT* each_component : *aRescuer->GetComponents() )
|
||||||
{
|
{
|
||||||
|
@ -472,49 +310,129 @@ public:
|
||||||
each_component->ClearFlags();
|
each_component->ClearFlags();
|
||||||
aRescuer->LogRescue( each_component, m_requested_name, m_new_name );
|
aRescuer->LogRescue( each_component, m_requested_name, m_new_name );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Function WriteRescueLibrary
|
RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::RESCUE_SYMBOL_LIB_TABLE_CANDIDATE(
|
||||||
* Writes out the rescue library. Called after successful PerformAction()s. If this fails,
|
const LIB_ID& aRequestedId,
|
||||||
* undo the actions.
|
const LIB_ID& aNewId,
|
||||||
* @return True on success.
|
LIB_PART* aCacheCandidate,
|
||||||
*/
|
LIB_PART* aLibCandidate ) : RESCUE_CANDIDATE()
|
||||||
static bool WriteRescueLibrary( SCH_EDIT_FRAME *aEditFrame, PROJECT* aProject )
|
|
||||||
{
|
{
|
||||||
if( !save_library( m_rescue_lib.get(), aEditFrame ) )
|
m_requested_id = aRequestedId;
|
||||||
return false;
|
m_requested_name = aRequestedId.GetLibItemName();
|
||||||
return insert_library( aProject, m_rescue_lib.get(), 0 );
|
m_new_id = aNewId;
|
||||||
|
m_lib_candidate = aLibCandidate;
|
||||||
|
m_cache_candidate = aCacheCandidate;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<PART_LIB> RESCUE_CACHE_CANDIDATE::m_rescue_lib;
|
RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::RESCUE_SYMBOL_LIB_TABLE_CANDIDATE()
|
||||||
|
{
|
||||||
|
m_cache_candidate = NULL;
|
||||||
|
m_lib_candidate = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(
|
||||||
|
RESCUER& aRescuer,
|
||||||
|
boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates )
|
||||||
|
{
|
||||||
|
typedef std::map<LIB_ID, RESCUE_SYMBOL_LIB_TABLE_CANDIDATE> candidate_map_t;
|
||||||
|
|
||||||
|
candidate_map_t candidate_map;
|
||||||
|
|
||||||
|
// Remember the list of components is sorted by LIB_ID.
|
||||||
|
// So a search in libraries is made only once by group
|
||||||
|
LIB_PART* cache_match = nullptr;
|
||||||
|
LIB_PART* lib_match = nullptr;
|
||||||
|
LIB_ID old_part_id;
|
||||||
|
|
||||||
|
wxString part_name_suffix = aRescuer.GetPartNameSuffix();
|
||||||
|
|
||||||
|
for( SCH_COMPONENT* each_component : *( aRescuer.GetComponents() ) )
|
||||||
|
{
|
||||||
|
LIB_ID part_id = each_component->GetLibId();
|
||||||
|
|
||||||
|
if( old_part_id != part_id )
|
||||||
|
{
|
||||||
|
// A new part name is found (a new group starts here).
|
||||||
|
// Search the symbol names candidates only once for this group:
|
||||||
|
old_part_id = part_id;
|
||||||
|
cache_match = find_component( part_id.GetLibItemName(), aRescuer.GetPrj()->SchLibs(),
|
||||||
|
true );
|
||||||
|
|
||||||
|
lib_match = aRescuer.GetFrame()->GetLibPart( part_id );
|
||||||
|
|
||||||
|
// Test whether there is a conflict
|
||||||
|
if( !cache_match || !lib_match )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( !cache_match->PinsConflictWith( *lib_match, true, true, true, true, false ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// May have been rescued already.
|
||||||
|
wxString new_name = part_id.GetLibItemName();
|
||||||
|
|
||||||
|
if( new_name.Find( part_name_suffix ) == wxNOT_FOUND )
|
||||||
|
new_name += part_name_suffix;
|
||||||
|
|
||||||
|
LIB_ID new_id( GetRescueLibraryFileName().GetName(), new_name );
|
||||||
|
|
||||||
|
RESCUE_SYMBOL_LIB_TABLE_CANDIDATE candidate( part_id, new_id, cache_match, lib_match );
|
||||||
|
|
||||||
|
candidate_map[part_id] = candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, dump the map into aCandidates
|
||||||
|
for( const candidate_map_t::value_type& each_pair : candidate_map )
|
||||||
|
{
|
||||||
|
aCandidates.push_back( new RESCUE_SYMBOL_LIB_TABLE_CANDIDATE( each_pair.second ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::GetActionDescription() const
|
||||||
|
{
|
||||||
|
wxString action;
|
||||||
|
action.Printf( _( "Rescue to %s" ), m_new_id.Format().wx_str() );
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::PerformAction( RESCUER* aRescuer )
|
||||||
|
{
|
||||||
|
LIB_PART new_part( *m_cache_candidate );
|
||||||
|
new_part.SetLibId( m_new_id );
|
||||||
|
new_part.SetName( m_new_id.GetLibItemName() );
|
||||||
|
new_part.RemoveAllAliases();
|
||||||
|
aRescuer->AddPart( &new_part );
|
||||||
|
|
||||||
|
for( SCH_COMPONENT* each_component : *aRescuer->GetComponents() )
|
||||||
|
{
|
||||||
|
if( each_component->GetLibId() != m_requested_id )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
each_component->SetLibId( m_new_id );
|
||||||
|
each_component->ClearFlags();
|
||||||
|
aRescuer->LogRescue( each_component, m_requested_id.Format(), m_new_id.Format() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
RESCUER::RESCUER( SCH_EDIT_FRAME& aEditFrame, PROJECT& aProject )
|
RESCUER::RESCUER( SCH_EDIT_FRAME& aEditFrame, PROJECT& aProject )
|
||||||
{
|
{
|
||||||
get_components( m_components );
|
get_components( m_components );
|
||||||
m_prj = &aProject;
|
m_prj = &aProject;
|
||||||
m_libs = m_prj->SchLibs();
|
|
||||||
m_edit_frame = &aEditFrame;
|
m_edit_frame = &aEditFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RESCUER::FindCandidates()
|
|
||||||
{
|
|
||||||
RESCUE_CASE_CANDIDATE::FindRescues( *this, m_all_candidates );
|
|
||||||
RESCUE_CACHE_CANDIDATE::FindRescues( *this, m_all_candidates );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void RESCUER::InvokeDialog( bool aAskShowAgain )
|
|
||||||
{
|
|
||||||
InvokeDialogRescueEach( m_edit_frame, *this, aAskShowAgain );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void RESCUER::LogRescue( SCH_COMPONENT *aComponent, const wxString &aOldName,
|
void RESCUER::LogRescue( SCH_COMPONENT *aComponent, const wxString &aOldName,
|
||||||
const wxString &aNewName )
|
const wxString &aNewName )
|
||||||
{
|
{
|
||||||
|
@ -533,6 +451,7 @@ bool RESCUER::DoRescues()
|
||||||
if( ! each_candidate->PerformAction( this ) )
|
if( ! each_candidate->PerformAction( this ) )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,6 +473,7 @@ wxString RESCUER::GetPartNameSuffix()
|
||||||
{
|
{
|
||||||
wxString suffix = wxT( "-RESCUE-" );
|
wxString suffix = wxT( "-RESCUE-" );
|
||||||
wxString pname = GetPrj()->GetProjectName();
|
wxString pname = GetPrj()->GetProjectName();
|
||||||
|
|
||||||
for( size_t i = 0; i < pname.Len(); ++i )
|
for( size_t i = 0; i < pname.Len(); ++i )
|
||||||
{
|
{
|
||||||
if( isspace( pname[i].GetValue() ) )
|
if( isspace( pname[i].GetValue() ) )
|
||||||
|
@ -566,13 +486,27 @@ wxString RESCUER::GetPartNameSuffix()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDIT_FRAME::RescueProject( bool aRunningOnDemand )
|
bool SCH_EDIT_FRAME::RescueLegacyProject( bool aRunningOnDemand )
|
||||||
{
|
{
|
||||||
RESCUER rescuer( *this, Prj() );
|
LEGACY_RESCUER rescuer( *this, Prj() );
|
||||||
|
|
||||||
rescuer.FindCandidates();
|
return rescueProject( rescuer, aRunningOnDemand );
|
||||||
|
}
|
||||||
|
|
||||||
if( ! rescuer.GetCandidateCount() )
|
|
||||||
|
bool SCH_EDIT_FRAME::RescueSymbolLibTableProject( bool aRunningOnDemand )
|
||||||
|
{
|
||||||
|
SYMBOL_LIB_TABLE_RESCUER rescuer( *this, Prj() );
|
||||||
|
|
||||||
|
return rescueProject( rescuer, aRunningOnDemand );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SCH_EDIT_FRAME::rescueProject( RESCUER& aRescuer, bool aRunningOnDemand )
|
||||||
|
{
|
||||||
|
aRescuer.FindCandidates();
|
||||||
|
|
||||||
|
if( ! aRescuer.GetCandidateCount() )
|
||||||
{
|
{
|
||||||
if( aRunningOnDemand )
|
if( aRunningOnDemand )
|
||||||
{
|
{
|
||||||
|
@ -580,16 +514,17 @@ bool SCH_EDIT_FRAME::RescueProject( bool aRunningOnDemand )
|
||||||
_( "Project Rescue Helper" ) );
|
_( "Project Rescue Helper" ) );
|
||||||
dlg.ShowModal();
|
dlg.ShowModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
rescuer.RemoveDuplicates();
|
aRescuer.RemoveDuplicates();
|
||||||
|
|
||||||
rescuer.InvokeDialog( !aRunningOnDemand );
|
aRescuer.InvokeDialog( !aRunningOnDemand );
|
||||||
|
|
||||||
// If no components were rescued, let the user know what's going on. He might
|
// If no symbols were rescued, let the user know what's going on. He might
|
||||||
// have clicked cancel by mistake, and should have some indication of that.
|
// have clicked cancel by mistake, and should have some indication of that.
|
||||||
if( !rescuer.GetChosenCandidateCount() )
|
if( !aRescuer.GetChosenCandidateCount() )
|
||||||
{
|
{
|
||||||
wxMessageDialog dlg( this, _( "No symbols were rescued." ),
|
wxMessageDialog dlg( this, _( "No symbols were rescued." ),
|
||||||
_( "Project Rescue Helper" ) );
|
_( "Project Rescue Helper" ) );
|
||||||
|
@ -601,17 +536,20 @@ bool SCH_EDIT_FRAME::RescueProject( bool aRunningOnDemand )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RESCUE_CACHE_CANDIDATE::OpenRescueLibrary();
|
aRescuer.OpenRescueLibrary();
|
||||||
|
|
||||||
if( !rescuer.DoRescues() )
|
if( !aRescuer.DoRescues() )
|
||||||
{
|
{
|
||||||
rescuer.UndoRescues();
|
aRescuer.UndoRescues();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RESCUE_CACHE_CANDIDATE::WriteRescueLibrary( this, &Prj() );
|
aRescuer.WriteRescueLibrary( this );
|
||||||
|
|
||||||
Prj().SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
|
LIB_VIEW_FRAME* viewer = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false );
|
||||||
|
|
||||||
|
if( viewer )
|
||||||
|
viewer->ReCreateListLib();
|
||||||
|
|
||||||
// Clean up wire ends
|
// Clean up wire ends
|
||||||
GetScreen()->SchematicCleanUp();
|
GetScreen()->SchematicCleanUp();
|
||||||
|
@ -620,3 +558,251 @@ bool SCH_EDIT_FRAME::RescueProject( bool aRunningOnDemand )
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RESCUER::RemoveDuplicates()
|
||||||
|
{
|
||||||
|
std::vector<wxString> names_seen;
|
||||||
|
|
||||||
|
for( boost::ptr_vector<RESCUE_CANDIDATE>::iterator it = m_all_candidates.begin();
|
||||||
|
it != m_all_candidates.end(); )
|
||||||
|
{
|
||||||
|
bool seen_already = false;
|
||||||
|
|
||||||
|
for( wxString& name_seen : names_seen )
|
||||||
|
{
|
||||||
|
if( name_seen == it->GetRequestedName() )
|
||||||
|
{
|
||||||
|
seen_already = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( seen_already )
|
||||||
|
{
|
||||||
|
it = m_all_candidates.erase( it );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
names_seen.push_back( it->GetRequestedName() );
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LEGACY_RESCUER::FindCandidates()
|
||||||
|
{
|
||||||
|
RESCUE_CASE_CANDIDATE::FindRescues( *this, m_all_candidates );
|
||||||
|
RESCUE_CACHE_CANDIDATE::FindRescues( *this, m_all_candidates );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LEGACY_RESCUER::InvokeDialog( bool aAskShowAgain )
|
||||||
|
{
|
||||||
|
InvokeDialogRescueEach( m_edit_frame, static_cast< RESCUER& >( *this ), aAskShowAgain );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LEGACY_RESCUER::OpenRescueLibrary()
|
||||||
|
{
|
||||||
|
wxFileName fn = GetRescueLibraryFileName();
|
||||||
|
|
||||||
|
std::unique_ptr<PART_LIB> rescue_lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, fn.GetFullPath() ) );
|
||||||
|
|
||||||
|
m_rescue_lib = std::move( rescue_lib );
|
||||||
|
m_rescue_lib->EnableBuffering();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LEGACY_RESCUER::WriteRescueLibrary( SCH_EDIT_FRAME *aEditFrame )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_rescue_lib->Save( false );
|
||||||
|
}
|
||||||
|
catch( ... /* IO_ERROR ioe */ )
|
||||||
|
{
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
|
msg.Printf( _( "Failed to create symbol library file '%s'" ),
|
||||||
|
m_rescue_lib->GetFullFileName() );
|
||||||
|
DisplayError( aEditFrame, msg );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxArrayString libNames;
|
||||||
|
wxString libPaths;
|
||||||
|
|
||||||
|
wxString libName = m_rescue_lib->GetName();
|
||||||
|
PART_LIBS *libs = dynamic_cast<PART_LIBS*>( m_prj->GetElem( PROJECT::ELEM_SCH_PART_LIBS ) );
|
||||||
|
|
||||||
|
if( !libs )
|
||||||
|
{
|
||||||
|
libs = new PART_LIBS();
|
||||||
|
m_prj->SetElem( PROJECT::ELEM_SCH_PART_LIBS, libs );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PART_LIBS::LibNamesAndPaths( m_prj, false, &libPaths, &libNames );
|
||||||
|
|
||||||
|
// Make sure the library is not already in the list
|
||||||
|
while( libNames.Index( libName ) != wxNOT_FOUND )
|
||||||
|
libNames.Remove( libName );
|
||||||
|
|
||||||
|
// Add the library to the top of the list and save.
|
||||||
|
libNames.Insert( libName, 0 );
|
||||||
|
PART_LIBS::LibNamesAndPaths( m_prj, true, &libPaths, &libNames );
|
||||||
|
}
|
||||||
|
catch( const IO_ERROR& )
|
||||||
|
{
|
||||||
|
// Could not get or save the current libraries.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the old libraries in case there is a problem after clear(). We'll
|
||||||
|
// put them back in.
|
||||||
|
boost::ptr_vector<PART_LIB> libsSave;
|
||||||
|
libsSave.transfer( libsSave.end(), libs->begin(), libs->end(), *libs );
|
||||||
|
|
||||||
|
m_prj->SetElem( PROJECT::ELEM_SCH_PART_LIBS, NULL );
|
||||||
|
|
||||||
|
libs = new PART_LIBS();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
libs->LoadAllLibraries( m_prj );
|
||||||
|
}
|
||||||
|
catch( const PARSE_ERROR& )
|
||||||
|
{
|
||||||
|
// Some libraries were not found. There's no point in showing the error,
|
||||||
|
// because it was already shown. Just don't do anything.
|
||||||
|
}
|
||||||
|
catch( const IO_ERROR& )
|
||||||
|
{
|
||||||
|
// Restore the old list
|
||||||
|
libs->clear();
|
||||||
|
libs->transfer( libs->end(), libsSave.begin(), libsSave.end(), libsSave );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_prj->SetElem( PROJECT::ELEM_SCH_PART_LIBS, libs );
|
||||||
|
|
||||||
|
// Update the schematic symbol library links since the library list has changed.
|
||||||
|
SCH_SCREENS schematic;
|
||||||
|
|
||||||
|
schematic.UpdateSymbolLinks();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LEGACY_RESCUER::AddPart( LIB_PART* aNewPart )
|
||||||
|
{
|
||||||
|
wxCHECK_RET( aNewPart, "Invalid LIB_PART pointer." );
|
||||||
|
|
||||||
|
aNewPart->SetLib( m_rescue_lib.get() );
|
||||||
|
m_rescue_lib->AddPart( aNewPart );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SYMBOL_LIB_TABLE_RESCUER::SYMBOL_LIB_TABLE_RESCUER( SCH_EDIT_FRAME& aEditFrame,
|
||||||
|
PROJECT& aProject ) :
|
||||||
|
RESCUER( aEditFrame, aProject )
|
||||||
|
{
|
||||||
|
m_properties = std::make_unique<PROPERTIES>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SYMBOL_LIB_TABLE_RESCUER::FindCandidates()
|
||||||
|
{
|
||||||
|
RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues( *this, m_all_candidates );
|
||||||
|
RESCUE_CACHE_CANDIDATE::FindRescues( *this, m_all_candidates );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SYMBOL_LIB_TABLE_RESCUER::InvokeDialog( bool aAskShowAgain )
|
||||||
|
{
|
||||||
|
InvokeDialogRescueEach( m_edit_frame, static_cast< RESCUER& >( *this ), aAskShowAgain );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SYMBOL_LIB_TABLE_RESCUER::OpenRescueLibrary()
|
||||||
|
{
|
||||||
|
m_pi.set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
||||||
|
(*m_properties)[ SCH_LEGACY_PLUGIN::PropBuffering ] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SYMBOL_LIB_TABLE_RESCUER::WriteRescueLibrary( SCH_EDIT_FRAME *aEditFrame )
|
||||||
|
{
|
||||||
|
wxString msg;
|
||||||
|
wxFileName fn = GetRescueLibraryFileName();
|
||||||
|
|
||||||
|
// If the rescue library already exists in the symbol library table no need save it to add
|
||||||
|
// it to the table.
|
||||||
|
if( !m_prj->SchSymbolLibTable()->HasLibrary( fn.GetName() ) )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_pi->SaveLibrary( fn.GetFullPath() );
|
||||||
|
}
|
||||||
|
catch( const IO_ERROR& ioe )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "Failed to save rescue library %s." ), fn.GetFullPath() );
|
||||||
|
DisplayErrorMessage( aEditFrame, msg, ioe.What() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString uri = "${KIPRJMOD}/" + fn.GetFullName();
|
||||||
|
SYMBOL_LIB_TABLE_ROW* row = new SYMBOL_LIB_TABLE_ROW( fn.GetName(), uri,
|
||||||
|
wxString( "Legacy" ) );
|
||||||
|
m_prj->SchSymbolLibTable()->InsertRow( row );
|
||||||
|
|
||||||
|
fn = wxFileName( m_prj->GetProjectPath(), SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_prj->SchSymbolLibTable()->Save( fn.GetFullPath() );
|
||||||
|
}
|
||||||
|
catch( const IO_ERROR& ioe )
|
||||||
|
{
|
||||||
|
msg.Printf( _( "Error occurred saving project specific symbol library table." ) );
|
||||||
|
DisplayErrorMessage( aEditFrame, msg, ioe.What() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Relaod the symbol library table.
|
||||||
|
m_prj->SetElem( PROJECT::ELEM_SYMBOL_LIB_TABLE, NULL );
|
||||||
|
|
||||||
|
// This can only happen if the symbol library table file was currupted on write.
|
||||||
|
if( !m_prj->SchSymbolLibTable() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Update the schematic symbol library links since the library list has changed.
|
||||||
|
SCH_SCREENS schematic;
|
||||||
|
|
||||||
|
schematic.UpdateSymbolLinks( true );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SYMBOL_LIB_TABLE_RESCUER::AddPart( LIB_PART* aNewPart )
|
||||||
|
{
|
||||||
|
wxCHECK_RET( aNewPart, "Invalid LIB_PART pointer." );
|
||||||
|
|
||||||
|
wxFileName fn = GetRescueLibraryFileName();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if( !m_prj->SchSymbolLibTable()->HasLibrary( fn.GetName() ) )
|
||||||
|
m_pi->SaveSymbol( fn.GetFullPath(), new LIB_PART( *aNewPart ), m_properties.get() );
|
||||||
|
else
|
||||||
|
m_prj->SchSymbolLibTable()->SaveSymbol( fn.GetName(), new LIB_PART( *aNewPart ) );
|
||||||
|
}
|
||||||
|
catch( ... /* IO_ERROR */ )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Chris Pavlina <pavlina.chris@gmail.com>
|
* Copyright (C) 2015 Chris Pavlina <pavlina.chris@gmail.com>
|
||||||
* Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2015-2017 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -37,15 +37,22 @@
|
||||||
* (if aSilentIfNone is true, the notification is silenced).
|
* (if aSilentIfNone is true, the notification is silenced).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <schframe.h>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include <boost/ptr_container/ptr_vector.hpp>
|
#include <boost/ptr_container/ptr_vector.hpp>
|
||||||
|
|
||||||
|
#include <properties.h>
|
||||||
|
|
||||||
|
#include <class_libentry.h>
|
||||||
|
#include <sch_legacy_plugin.h>
|
||||||
|
|
||||||
|
|
||||||
class LIB_PART;
|
class LIB_PART;
|
||||||
class SCH_COMPONENT;
|
class SCH_COMPONENT;
|
||||||
class RESCUER;
|
class RESCUER;
|
||||||
|
class SCH_EDIT_FRAME;
|
||||||
|
class SCH_LEGACY_PLUGIN;
|
||||||
|
|
||||||
|
|
||||||
enum RESCUE_TYPE
|
enum RESCUE_TYPE
|
||||||
{
|
{
|
||||||
|
@ -53,45 +60,45 @@ enum RESCUE_TYPE
|
||||||
RESCUE_CASE,
|
RESCUE_CASE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class RESCUE_CANDIDATE
|
class RESCUE_CANDIDATE
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
wxString m_requested_name;
|
||||||
|
wxString m_new_name;
|
||||||
|
LIB_PART* m_lib_candidate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~RESCUE_CANDIDATE() {}
|
virtual ~RESCUE_CANDIDATE() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetRequestedName
|
|
||||||
* Get the name that was originally requested in the schematic
|
* Get the name that was originally requested in the schematic
|
||||||
*/
|
*/
|
||||||
virtual wxString GetRequestedName() const = 0;
|
virtual wxString GetRequestedName() const { return m_requested_name; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetNewName
|
|
||||||
* Get the name we're proposing changing it to
|
* Get the name we're proposing changing it to
|
||||||
*/
|
*/
|
||||||
virtual wxString GetNewName() const = 0;
|
virtual wxString GetNewName() const { return m_new_name; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetCacheCandidate
|
|
||||||
* Get the part that can be loaded from the project cache, if possible, or
|
* Get the part that can be loaded from the project cache, if possible, or
|
||||||
* else NULL.
|
* else NULL.
|
||||||
*/
|
*/
|
||||||
virtual LIB_PART* GetCacheCandidate() const { return NULL; }
|
virtual LIB_PART* GetCacheCandidate() const { return NULL; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetLibCandidate
|
|
||||||
* Get the part the would be loaded from the libraries, if possible, or else
|
* Get the part the would be loaded from the libraries, if possible, or else
|
||||||
* NULL.
|
* NULL.
|
||||||
*/
|
*/
|
||||||
virtual LIB_PART* GetLibCandidate() const { return NULL; }
|
virtual LIB_PART* GetLibCandidate() const { return m_lib_candidate; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetActionDescription
|
|
||||||
* Get a description of the action proposed, for displaying in the UI.
|
* Get a description of the action proposed, for displaying in the UI.
|
||||||
*/
|
*/
|
||||||
virtual wxString GetActionDescription() const = 0;
|
virtual wxString GetActionDescription() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function PerformAction
|
|
||||||
* Perform the actual rescue action. If successful, this must log the rescue using
|
* Perform the actual rescue action. If successful, this must log the rescue using
|
||||||
* RESCUER::LogRescue to allow it to be reversed.
|
* RESCUER::LogRescue to allow it to be reversed.
|
||||||
* @return True on success.
|
* @return True on success.
|
||||||
|
@ -99,6 +106,103 @@ public:
|
||||||
virtual bool PerformAction( RESCUER* aRescuer ) = 0;
|
virtual bool PerformAction( RESCUER* aRescuer ) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RESCUE_CASE_CANDIDATE : public RESCUE_CANDIDATE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Grab all possible RESCUE_CASE_CANDIDATE objects into a vector.
|
||||||
|
*
|
||||||
|
* @param aRescuer - the working RESCUER instance.
|
||||||
|
* @param aCandidates - the vector the will hold the candidates.
|
||||||
|
*/
|
||||||
|
static void FindRescues( RESCUER& aRescuer, boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor RESCUE_CANDIDATE
|
||||||
|
* @param aRequestedName - the name the schematic asks for
|
||||||
|
* @param aNewName - the name we want to change it to
|
||||||
|
* @param aLibCandidate - the part that will give us
|
||||||
|
*/
|
||||||
|
RESCUE_CASE_CANDIDATE( const wxString& aRequestedName, const wxString& aNewName,
|
||||||
|
LIB_PART* aLibCandidate );
|
||||||
|
|
||||||
|
RESCUE_CASE_CANDIDATE() { m_lib_candidate = NULL; }
|
||||||
|
|
||||||
|
virtual wxString GetActionDescription() const override;
|
||||||
|
|
||||||
|
virtual bool PerformAction( RESCUER* aRescuer ) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RESCUE_CACHE_CANDIDATE: public RESCUE_CANDIDATE
|
||||||
|
{
|
||||||
|
LIB_PART* m_cache_candidate;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Grab all possible #RESCUE_CACHE_CANDIDATE objectss into a vector.
|
||||||
|
*
|
||||||
|
* @param aRescuer - the working RESCUER instance.
|
||||||
|
* @param aCandidates - the vector the will hold the candidates.
|
||||||
|
*/
|
||||||
|
static void FindRescues( RESCUER& aRescuer, boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor RESCUE_CACHE_CANDIDATE
|
||||||
|
* @param aRequestedName - the name the schematic asks for
|
||||||
|
* @param aNewName - the name we want to change it to
|
||||||
|
* @param aCacheCandidate - the part from the cache
|
||||||
|
* @param aLibCandidate - the part that would be loaded from the library
|
||||||
|
*/
|
||||||
|
RESCUE_CACHE_CANDIDATE( const wxString& aRequestedName, const wxString& aNewName,
|
||||||
|
LIB_PART* aCacheCandidate, LIB_PART* aLibCandidate );
|
||||||
|
|
||||||
|
RESCUE_CACHE_CANDIDATE();
|
||||||
|
|
||||||
|
virtual LIB_PART* GetCacheCandidate() const override { return m_cache_candidate; }
|
||||||
|
|
||||||
|
virtual wxString GetActionDescription() const override;
|
||||||
|
|
||||||
|
virtual bool PerformAction( RESCUER* aRescuer ) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RESCUE_SYMBOL_LIB_TABLE_CANDIDATE : public RESCUE_CANDIDATE
|
||||||
|
{
|
||||||
|
LIB_ID m_requested_id;
|
||||||
|
LIB_ID m_new_id;
|
||||||
|
LIB_PART* m_cache_candidate;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Grab all possible RESCUE_SYMBOL_LIB_TABLE_CANDIDATE objects into a vector.
|
||||||
|
*
|
||||||
|
* @param aRescuer - the working RESCUER instance.
|
||||||
|
* @param aCandidates - the vector the will hold the candidates.
|
||||||
|
*/
|
||||||
|
static void FindRescues( RESCUER& aRescuer, boost::ptr_vector<RESCUE_CANDIDATE>& aCandidates );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor RESCUE_CANDIDATE
|
||||||
|
* @param aRequestedName - the name the schematic asks for
|
||||||
|
* @param aNewName - the name we want to change it to
|
||||||
|
* @param aCacheCandidate - the part from the cache
|
||||||
|
* @param aLibCandidate - the part that would be loaded from the library
|
||||||
|
*/
|
||||||
|
RESCUE_SYMBOL_LIB_TABLE_CANDIDATE( const LIB_ID& aRequestedId, const LIB_ID& aNewId,
|
||||||
|
LIB_PART* aCacheCandidate, LIB_PART* aLibCandidate);
|
||||||
|
|
||||||
|
RESCUE_SYMBOL_LIB_TABLE_CANDIDATE();
|
||||||
|
|
||||||
|
virtual LIB_PART* GetCacheCandidate() const override { return m_cache_candidate; }
|
||||||
|
|
||||||
|
virtual wxString GetActionDescription() const override;
|
||||||
|
|
||||||
|
virtual bool PerformAction( RESCUER* aRescuer ) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class RESCUE_LOG
|
class RESCUE_LOG
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -107,12 +211,13 @@ public:
|
||||||
wxString new_name;
|
wxString new_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class RESCUER
|
class RESCUER
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
friend class DIALOG_RESCUE_EACH;
|
friend class DIALOG_RESCUE_EACH;
|
||||||
|
|
||||||
std::vector<SCH_COMPONENT*> m_components;
|
std::vector<SCH_COMPONENT*> m_components;
|
||||||
PART_LIBS* m_libs;
|
|
||||||
PROJECT* m_prj;
|
PROJECT* m_prj;
|
||||||
SCH_EDIT_FRAME* m_edit_frame;
|
SCH_EDIT_FRAME* m_edit_frame;
|
||||||
|
|
||||||
|
@ -125,74 +230,124 @@ public:
|
||||||
RESCUER( SCH_EDIT_FRAME& aEditFrame, PROJECT& aProject );
|
RESCUER( SCH_EDIT_FRAME& aEditFrame, PROJECT& aProject );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function FindCandidates
|
* Writes out the rescue library. Called after successful PerformAction()s. If this fails,
|
||||||
* Populate the RESCUER with all possible candidates.
|
* undo the actions.
|
||||||
|
*
|
||||||
|
* @return True on success.
|
||||||
*/
|
*/
|
||||||
void FindCandidates();
|
virtual bool WriteRescueLibrary( SCH_EDIT_FRAME *aEditFrame ) = 0;
|
||||||
|
|
||||||
|
virtual void OpenRescueLibrary() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the RESCUER with all possible candidates.
|
||||||
|
*/
|
||||||
|
virtual void FindCandidates() = 0;
|
||||||
|
|
||||||
|
virtual void AddPart( LIB_PART* aNewPart ) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a dialog to allow the user to select rescues.
|
||||||
|
*
|
||||||
|
* @param aAskShowAgain - whether the "Never Show Again" button should be visible
|
||||||
|
*/
|
||||||
|
virtual void InvokeDialog( bool aAskShowAgain ) = 0;
|
||||||
|
|
||||||
|
SCH_EDIT_FRAME* GetFrame() { return m_edit_frame; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function RemoveDuplicates
|
|
||||||
* Filter out duplicately named rescue candidates.
|
* Filter out duplicately named rescue candidates.
|
||||||
*/
|
*/
|
||||||
void RemoveDuplicates();
|
void RemoveDuplicates();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetCandidateCount
|
* Returen the number of rescue candidates found.
|
||||||
*/
|
*/
|
||||||
size_t GetCandidateCount() { return m_all_candidates.size(); }
|
size_t GetCandidateCount() { return m_all_candidates.size(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetChosenCandidateCount
|
* Get the number of resuce candidates chosen by the user.
|
||||||
*/
|
*/
|
||||||
size_t GetChosenCandidateCount() { return m_chosen_candidates.size(); }
|
size_t GetChosenCandidateCount() { return m_chosen_candidates.size(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetComponents
|
* Get the list of symbols that need rescued.
|
||||||
*/
|
*/
|
||||||
std::vector<SCH_COMPONENT*>* GetComponents() { return &m_components; }
|
std::vector<SCH_COMPONENT*>* GetComponents() { return &m_components; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetLibs
|
* Return the #SCH_PROJECT object for access to the symbol libraries.
|
||||||
*/
|
|
||||||
PART_LIBS* GetLibs() { return m_libs; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function GetPrj
|
|
||||||
*/
|
*/
|
||||||
PROJECT* GetPrj() { return m_prj; }
|
PROJECT* GetPrj() { return m_prj; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetPartNameSuffix
|
|
||||||
* Return the suffix to add to rescued parts.
|
* Return the suffix to add to rescued parts.
|
||||||
*/
|
*/
|
||||||
wxString GetPartNameSuffix();
|
wxString GetPartNameSuffix();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function InvokeDialog
|
* Used by individual #RESCUE_CANDIDATE objects to log a rescue for undoing.
|
||||||
* Display a dialog to allow the user to select rescues.
|
|
||||||
* @param aAskShowAgain - whether the "Never Show Again" button should be visible
|
|
||||||
*/
|
|
||||||
void InvokeDialog( bool aAskShowAgain );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function LogRescue
|
|
||||||
* Used by individual RESCUE_CANDIDATEs to log a rescue for undoing.
|
|
||||||
*/
|
*/
|
||||||
void LogRescue( SCH_COMPONENT *aComponent, const wxString& aOldName,
|
void LogRescue( SCH_COMPONENT *aComponent, const wxString& aOldName,
|
||||||
const wxString& aNewName );
|
const wxString& aNewName );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function DoRescues
|
|
||||||
* Perform all chosen rescue actions, logging them to be undone if necessary.
|
* Perform all chosen rescue actions, logging them to be undone if necessary.
|
||||||
|
*
|
||||||
* @return True on success
|
* @return True on success
|
||||||
*/
|
*/
|
||||||
bool DoRescues();
|
bool DoRescues();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function UndoRescues
|
|
||||||
* Reverse the effects of all rescues on the project.
|
* Reverse the effects of all rescues on the project.
|
||||||
*/
|
*/
|
||||||
void UndoRescues();
|
void UndoRescues();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LEGACY_RESCUER : public RESCUER
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::unique_ptr<PART_LIB> m_rescue_lib;
|
||||||
|
PART_LIBS* m_libs;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LEGACY_RESCUER( SCH_EDIT_FRAME& aEditFrame, PROJECT& aProject ) :
|
||||||
|
RESCUER( aEditFrame, aProject )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void FindCandidates() override;
|
||||||
|
|
||||||
|
virtual void InvokeDialog( bool aAskShowAgain ) override;
|
||||||
|
|
||||||
|
virtual void OpenRescueLibrary() override;
|
||||||
|
|
||||||
|
virtual bool WriteRescueLibrary( SCH_EDIT_FRAME *aEditFrame ) override;
|
||||||
|
|
||||||
|
virtual void AddPart( LIB_PART* aNewPart ) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SYMBOL_LIB_TABLE_RESCUER : public RESCUER
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi;
|
||||||
|
|
||||||
|
std::unique_ptr< PROPERTIES > m_properties; ///< Library plugin properties
|
||||||
|
|
||||||
|
public:
|
||||||
|
SYMBOL_LIB_TABLE_RESCUER( SCH_EDIT_FRAME& aEditFrame, PROJECT& aProject );
|
||||||
|
|
||||||
|
virtual void FindCandidates() override;
|
||||||
|
|
||||||
|
virtual void InvokeDialog( bool aAskShowAgain ) override;
|
||||||
|
|
||||||
|
virtual void OpenRescueLibrary() override;
|
||||||
|
|
||||||
|
virtual bool WriteRescueLibrary( SCH_EDIT_FRAME *aEditFrame ) override;
|
||||||
|
|
||||||
|
virtual void AddPart( LIB_PART* aNewPart ) override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // _LIB_CACHE_RESCUE_H_
|
#endif // _LIB_CACHE_RESCUE_H_
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
LIB_ALIAS* SchGetLibAlias( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, PART_LIB* aCacheLib,
|
LIB_ALIAS* SchGetLibAlias( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, PART_LIB* aCacheLib,
|
||||||
wxWindow* aParent, bool aShowErrorMsg )
|
wxWindow* aParent, bool aShowErrorMsg )
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." );
|
// wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." );
|
||||||
wxCHECK_MSG( aLibTable, NULL, "Invalid symbol library table." );
|
wxCHECK_MSG( aLibTable, NULL, "Invalid symbol library table." );
|
||||||
|
|
||||||
LIB_ALIAS* alias = NULL;
|
LIB_ALIAS* alias = NULL;
|
||||||
|
@ -309,7 +309,7 @@ void SCH_BASE_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent )
|
||||||
LIB_ALIAS* SCH_BASE_FRAME::GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib,
|
LIB_ALIAS* SCH_BASE_FRAME::GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib,
|
||||||
bool aShowErrorMsg )
|
bool aShowErrorMsg )
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." );
|
// wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." );
|
||||||
|
|
||||||
PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL;
|
PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL;
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ LIB_ALIAS* SCH_BASE_FRAME::GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib,
|
||||||
|
|
||||||
LIB_PART* SCH_BASE_FRAME::GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib, bool 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." );
|
// wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." );
|
||||||
|
|
||||||
PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL;
|
PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL;
|
||||||
|
|
||||||
|
|
|
@ -1744,6 +1744,8 @@ const EDA_RECT SCH_COMPONENT::GetBoundingBox() const
|
||||||
|
|
||||||
void SCH_COMPONENT::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
|
void SCH_COMPONENT::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
|
||||||
{
|
{
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
// part and alias can differ if alias is not the root
|
// part and alias can differ if alias is not the root
|
||||||
if( PART_SPTR part = m_part.lock() )
|
if( PART_SPTR part = m_part.lock() )
|
||||||
{
|
{
|
||||||
|
@ -1759,7 +1761,7 @@ void SCH_COMPONENT::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
|
||||||
GetRef( m_currentSheetPath ),
|
GetRef( m_currentSheetPath ),
|
||||||
DARKCYAN ) );
|
DARKCYAN ) );
|
||||||
|
|
||||||
wxString msg = part->IsPower() ? _( "Power symbol" ) : _( "Value" );
|
msg = part->IsPower() ? _( "Power symbol" ) : _( "Value" );
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( msg, GetField( VALUE )->GetShownText(), DARKCYAN ) );
|
aList.push_back( MSG_PANEL_ITEM( msg, GetField( VALUE )->GetShownText(), DARKCYAN ) );
|
||||||
|
|
||||||
|
@ -1800,8 +1802,20 @@ void SCH_COMPONENT::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetField( VALUE )->GetShownText(),
|
aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetField( VALUE )->GetShownText(),
|
||||||
DARKCYAN ) );
|
DARKCYAN ) );
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Component" ), GetLibId().GetLibItemName(), BROWN ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "Symbol" ), GetLibId().GetLibItemName(), BROWN ) );
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), _( "Error: symbol not found!!!" ), RED ) );
|
|
||||||
|
wxString libNickname = GetLibId().GetLibNickname();
|
||||||
|
|
||||||
|
if( libNickname.empty() )
|
||||||
|
{
|
||||||
|
aList.push_back( MSG_PANEL_ITEM( _( "Library" ),
|
||||||
|
_( "No library defined!!!" ), RED ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg.Printf( _( "Symbol not found in %s!!!" ), libNickname );
|
||||||
|
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), msg , RED ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -479,12 +479,13 @@ static void parseQuotedString( wxString& aString, FILE_LINE_READER& aReader,
|
||||||
*/
|
*/
|
||||||
class SCH_LEGACY_PLUGIN_CACHE
|
class SCH_LEGACY_PLUGIN_CACHE
|
||||||
{
|
{
|
||||||
|
static int m_modHash; // Keep track of the modification status of the library.
|
||||||
|
|
||||||
wxFileName m_libFileName; // Absolute path and file name is required here.
|
wxFileName m_libFileName; // Absolute path and file name is required here.
|
||||||
wxDateTime m_fileModTime;
|
wxDateTime m_fileModTime;
|
||||||
LIB_ALIAS_MAP m_aliases; // Map of names of LIB_ALIAS pointers.
|
LIB_ALIAS_MAP m_aliases; // Map of names of LIB_ALIAS pointers.
|
||||||
bool m_isWritable;
|
bool m_isWritable;
|
||||||
bool m_isModified;
|
bool m_isModified;
|
||||||
int m_modHash; // Keep track of the modification status of the library.
|
|
||||||
int m_versionMajor;
|
int m_versionMajor;
|
||||||
int m_versionMinor;
|
int m_versionMinor;
|
||||||
int m_libType; // Is this cache a component or symbol library.
|
int m_libType; // Is this cache a component or symbol library.
|
||||||
|
@ -2031,11 +2032,13 @@ void SCH_LEGACY_PLUGIN::saveText( SCH_TEXT* aText )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int SCH_LEGACY_PLUGIN_CACHE::m_modHash = 1; // starts at 1 and goes up
|
||||||
|
|
||||||
|
|
||||||
SCH_LEGACY_PLUGIN_CACHE::SCH_LEGACY_PLUGIN_CACHE( const wxString& aFullPathAndFileName ) :
|
SCH_LEGACY_PLUGIN_CACHE::SCH_LEGACY_PLUGIN_CACHE( const wxString& aFullPathAndFileName ) :
|
||||||
m_libFileName( aFullPathAndFileName ),
|
m_libFileName( aFullPathAndFileName ),
|
||||||
m_isWritable( true ),
|
m_isWritable( true ),
|
||||||
m_isModified( false ),
|
m_isModified( false )
|
||||||
m_modHash( 1 )
|
|
||||||
{
|
{
|
||||||
m_versionMajor = -1;
|
m_versionMajor = -1;
|
||||||
m_versionMinor = -1;
|
m_versionMinor = -1;
|
||||||
|
|
|
@ -527,7 +527,7 @@ bool SCH_SCREEN::Save( FILE* aFile ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_SCREEN::CheckComponentsToPartsLinks()
|
void SCH_SCREEN::UpdateSymbolLinks( bool aForce )
|
||||||
{
|
{
|
||||||
// Initialize or reinitialize the pointer to the LIB_PART for each component
|
// Initialize or reinitialize the pointer to the LIB_PART for each component
|
||||||
// found in m_drawList, but only if needed (change in lib or schematic)
|
// found in m_drawList, but only if needed (change in lib or schematic)
|
||||||
|
@ -539,7 +539,7 @@ void SCH_SCREEN::CheckComponentsToPartsLinks()
|
||||||
int mod_hash = libs->GetModifyHash();
|
int mod_hash = libs->GetModifyHash();
|
||||||
|
|
||||||
// Must we resolve?
|
// Must we resolve?
|
||||||
if( m_modification_sync != mod_hash )
|
if( (m_modification_sync != mod_hash) || aForce )
|
||||||
{
|
{
|
||||||
SCH_TYPE_COLLECTOR c;
|
SCH_TYPE_COLLECTOR c;
|
||||||
|
|
||||||
|
@ -561,7 +561,7 @@ void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, GR_DRAWMODE aDrawMode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Ensure links are up to date, even if a library was reloaded for some reason:
|
// Ensure links are up to date, even if a library was reloaded for some reason:
|
||||||
CheckComponentsToPartsLinks();
|
UpdateSymbolLinks();
|
||||||
|
|
||||||
for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
|
for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
|
||||||
{
|
{
|
||||||
|
@ -582,7 +582,7 @@ void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, GR_DRAWMODE aDrawMode
|
||||||
void SCH_SCREEN::Plot( PLOTTER* aPlotter )
|
void SCH_SCREEN::Plot( PLOTTER* aPlotter )
|
||||||
{
|
{
|
||||||
// Ensure links are up to date, even if a library was reloaded for some reason:
|
// Ensure links are up to date, even if a library was reloaded for some reason:
|
||||||
CheckComponentsToPartsLinks();
|
UpdateSymbolLinks();
|
||||||
|
|
||||||
for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
|
for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
|
||||||
{
|
{
|
||||||
|
@ -1508,10 +1508,10 @@ int SCH_SCREENS::GetMarkerCount( enum MARKER_BASE::TYPEMARKER aMarkerType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_SCREENS::UpdateSymbolLinks()
|
void SCH_SCREENS::UpdateSymbolLinks( bool aForce )
|
||||||
{
|
{
|
||||||
for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
|
for( SCH_SCREEN* screen = GetFirst(); screen; screen = GetNext() )
|
||||||
screen->CheckComponentsToPartsLinks();
|
screen->UpdateSymbolLinks( aForce );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
|
|
||||||
#include <invoke_sch_dialog.h>
|
#include <invoke_sch_dialog.h>
|
||||||
#include <dialogs/dialog_schematic_find.h>
|
#include <dialogs/dialog_schematic_find.h>
|
||||||
|
#include <dialog_symbol_remap.h>
|
||||||
|
|
||||||
#include <wx/display.h>
|
#include <wx/display.h>
|
||||||
#include <build_version.h>
|
#include <build_version.h>
|
||||||
|
@ -251,6 +252,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
|
||||||
EVT_TOOL( ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP, SCH_EDIT_FRAME::OnOpenLibraryEditor )
|
EVT_TOOL( ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP, SCH_EDIT_FRAME::OnOpenLibraryEditor )
|
||||||
EVT_TOOL( ID_TO_LIBVIEW, SCH_EDIT_FRAME::OnOpenLibraryViewer )
|
EVT_TOOL( ID_TO_LIBVIEW, SCH_EDIT_FRAME::OnOpenLibraryViewer )
|
||||||
EVT_TOOL( ID_RESCUE_CACHED, SCH_EDIT_FRAME::OnRescueProject )
|
EVT_TOOL( ID_RESCUE_CACHED, SCH_EDIT_FRAME::OnRescueProject )
|
||||||
|
EVT_MENU( ID_REMAP_SYMBOLS, SCH_EDIT_FRAME::OnRemapSymbols )
|
||||||
|
|
||||||
EVT_TOOL( ID_RUN_PCB, SCH_EDIT_FRAME::OnOpenPcbnew )
|
EVT_TOOL( ID_RUN_PCB, SCH_EDIT_FRAME::OnOpenPcbnew )
|
||||||
EVT_TOOL( ID_RUN_PCB_MODULE_EDITOR, SCH_EDIT_FRAME::OnOpenPcbModuleEditor )
|
EVT_TOOL( ID_RUN_PCB_MODULE_EDITOR, SCH_EDIT_FRAME::OnOpenPcbModuleEditor )
|
||||||
|
@ -333,6 +335,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
|
||||||
EVT_UPDATE_UI( ID_SAVE_PROJECT, SCH_EDIT_FRAME::OnUpdateSave )
|
EVT_UPDATE_UI( ID_SAVE_PROJECT, SCH_EDIT_FRAME::OnUpdateSave )
|
||||||
EVT_UPDATE_UI( ID_UPDATE_ONE_SHEET, SCH_EDIT_FRAME::OnUpdateSaveSheet )
|
EVT_UPDATE_UI( ID_UPDATE_ONE_SHEET, SCH_EDIT_FRAME::OnUpdateSaveSheet )
|
||||||
EVT_UPDATE_UI( ID_POPUP_SCH_LEAVE_SHEET, SCH_EDIT_FRAME::OnUpdateHierarchySheet )
|
EVT_UPDATE_UI( ID_POPUP_SCH_LEAVE_SHEET, SCH_EDIT_FRAME::OnUpdateHierarchySheet )
|
||||||
|
EVT_UPDATE_UI( ID_REMAP_SYMBOLS, SCH_EDIT_FRAME::OnUpdateRemapSymbols )
|
||||||
|
|
||||||
/* Search dialog events. */
|
/* Search dialog events. */
|
||||||
EVT_FIND_CLOSE( wxID_ANY, SCH_EDIT_FRAME::OnFindDialogClose )
|
EVT_FIND_CLOSE( wxID_ANY, SCH_EDIT_FRAME::OnFindDialogClose )
|
||||||
|
@ -823,6 +826,15 @@ void SCH_EDIT_FRAME::OnUpdateSave( wxUpdateUIEvent& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_EDIT_FRAME::OnUpdateRemapSymbols( wxUpdateUIEvent& aEvent )
|
||||||
|
{
|
||||||
|
SCH_SCREENS schematic;
|
||||||
|
|
||||||
|
// The remapping can only be performed on legacy projects.
|
||||||
|
aEvent.Enable( schematic.HasNoFullyDefinedLibIds() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::OnUpdateSaveSheet( wxUpdateUIEvent& aEvent )
|
void SCH_EDIT_FRAME::OnUpdateSaveSheet( wxUpdateUIEvent& aEvent )
|
||||||
{
|
{
|
||||||
aEvent.Enable( GetScreen()->IsModify() );
|
aEvent.Enable( GetScreen()->IsModify() );
|
||||||
|
@ -1249,7 +1261,20 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event )
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::OnRescueProject( wxCommandEvent& event )
|
void SCH_EDIT_FRAME::OnRescueProject( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
RescueProject( true );
|
SCH_SCREENS schematic;
|
||||||
|
|
||||||
|
if( schematic.HasNoFullyDefinedLibIds() )
|
||||||
|
RescueLegacyProject( true );
|
||||||
|
else
|
||||||
|
RescueSymbolLibTableProject( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_EDIT_FRAME::OnRemapSymbols( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
DIALOG_SYMBOL_REMAP dlgRemap( this );
|
||||||
|
|
||||||
|
dlgRemap.ShowQuasiModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras wanadoo.fr
|
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras wanadoo.fr
|
||||||
* Copyright (C) 2008-2017 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||||
* Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -64,6 +64,7 @@ class DIALOG_SCH_FIND;
|
||||||
class wxFindDialogEvent;
|
class wxFindDialogEvent;
|
||||||
class wxFindReplaceData;
|
class wxFindReplaceData;
|
||||||
class SCHLIB_FILTER;
|
class SCHLIB_FILTER;
|
||||||
|
class RESCUER;
|
||||||
|
|
||||||
|
|
||||||
/// enum used in RotationMiroir()
|
/// enum used in RotationMiroir()
|
||||||
|
@ -890,6 +891,7 @@ private:
|
||||||
void OnOpenCvpcb( wxCommandEvent& event );
|
void OnOpenCvpcb( wxCommandEvent& event );
|
||||||
void OnOpenLibraryEditor( wxCommandEvent& event );
|
void OnOpenLibraryEditor( wxCommandEvent& event );
|
||||||
void OnRescueProject( wxCommandEvent& event );
|
void OnRescueProject( wxCommandEvent& event );
|
||||||
|
void OnRemapSymbols( wxCommandEvent& aEvent );
|
||||||
void OnPreferencesOptions( wxCommandEvent& event );
|
void OnPreferencesOptions( wxCommandEvent& event );
|
||||||
void OnCancelCurrentCommand( wxCommandEvent& aEvent );
|
void OnCancelCurrentCommand( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
@ -910,6 +912,7 @@ private:
|
||||||
void OnUpdateSave( wxUpdateUIEvent& aEvent );
|
void OnUpdateSave( wxUpdateUIEvent& aEvent );
|
||||||
void OnUpdateSaveSheet( wxUpdateUIEvent& aEvent );
|
void OnUpdateSaveSheet( wxUpdateUIEvent& aEvent );
|
||||||
void OnUpdateHierarchySheet( wxUpdateUIEvent& aEvent );
|
void OnUpdateHierarchySheet( wxUpdateUIEvent& aEvent );
|
||||||
|
void OnUpdateRemapSymbols( wxUpdateUIEvent& aEvent );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function UpdateTitle
|
* Function UpdateTitle
|
||||||
|
@ -1378,7 +1381,9 @@ public:
|
||||||
* if there are no components to rescue, and a "Never Show Again" button is
|
* if there are no components to rescue, and a "Never Show Again" button is
|
||||||
* displayed.
|
* displayed.
|
||||||
*/
|
*/
|
||||||
bool RescueProject( bool aRunningOnDemand );
|
bool rescueProject( RESCUER& aRescuer, bool aRunningOnDemand );
|
||||||
|
bool RescueLegacyProject( bool aRunningOnDemand );
|
||||||
|
bool RescueSymbolLibTableProject( bool aRunningOnDemand );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function PrintPage
|
* Function PrintPage
|
||||||
|
|
Loading…
Reference in New Issue