487 lines
16 KiB
C++
487 lines
16 KiB
C++
/*
|
|
* 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 <stambaughw@gmail.com>
|
|
* Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, you may find one here:
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
/**
|
|
* @file symbol_library.h
|
|
* @brief Definition for symbol library class.
|
|
*/
|
|
|
|
#ifndef SYMBOL_LIBRARY_H
|
|
#define SYMBOL_LIBRARY_H
|
|
|
|
#include <map>
|
|
#include <mutex>
|
|
#include <boost/ptr_container/ptr_vector.hpp>
|
|
#include <wx/filename.h>
|
|
|
|
#include <sch_io_mgr.h>
|
|
#include <project.h>
|
|
|
|
class LIB_SYMBOL;
|
|
class LIB_ID;
|
|
class LINE_READER;
|
|
class OUTPUTFORMATTER;
|
|
class SCH_LEGACY_PLUGIN;
|
|
class SCH_PLUGIN;
|
|
|
|
|
|
#define DOC_EXT "dcm"
|
|
|
|
/*
|
|
* Symbol Library version and file header macros.
|
|
*/
|
|
#define LIB_VERSION_MAJOR 2
|
|
#define LIB_VERSION_MINOR 4
|
|
|
|
/* Must be the first line of symbol library (.lib) files. */
|
|
#define LIBFILE_IDENT "EESchema-LIBRARY Version"
|
|
|
|
#define LIB_VERSION( major, minor ) ( major * 100 + minor )
|
|
|
|
#define IS_LIB_CURRENT_VERSION( major, minor ) \
|
|
( \
|
|
LIB_VERSION( major1, minor1 ) == \
|
|
LIB_VERSION( LIB_VERSION_MAJOR, LIB_VERSION_MINOR) \
|
|
)
|
|
|
|
/*
|
|
* Library versions 2.4 and lower use the old separate library (.lib) and
|
|
* document (.dcm) files. Symbol libraries after 2.4 merged the library
|
|
* and document files into a single library file. This macro checks if the
|
|
* library version supports the old format
|
|
*/
|
|
#define USE_OLD_DOC_FILE_FORMAT( major, minor ) \
|
|
( LIB_VERSION( major, minor ) <= LIB_VERSION( 2, 4 ) )
|
|
|
|
enum class SCH_LIB_TYPE
|
|
{
|
|
LT_EESCHEMA,
|
|
LT_SYMBOL
|
|
};
|
|
|
|
// Helper class to filter a list of libraries, and/or a list of SYMBOL_LIB
|
|
// in dialogs
|
|
class SCHLIB_FILTER
|
|
{
|
|
public:
|
|
SCHLIB_FILTER()
|
|
{
|
|
m_filterPowerSymbols = false;
|
|
m_forceLoad = false;
|
|
}
|
|
|
|
/**
|
|
* add a lib name to the allowed libraries
|
|
*/
|
|
void AddLib( const wxString& aLibName )
|
|
{
|
|
m_allowedLibs.Add( aLibName );
|
|
m_forceLoad = false;
|
|
}
|
|
|
|
|
|
/**
|
|
* add a lib name to the allowed libraries
|
|
*/
|
|
void LoadFrom( const wxString& aLibName )
|
|
{
|
|
m_allowedLibs.Clear();
|
|
m_allowedLibs.Add( aLibName );
|
|
m_forceLoad = true;
|
|
}
|
|
|
|
/**
|
|
* Clear the allowed libraries list (allows all libs)
|
|
*/
|
|
void ClearLibList()
|
|
{
|
|
m_allowedLibs.Clear();
|
|
m_forceLoad = false;
|
|
}
|
|
|
|
/**
|
|
* Set the filtering of power symbols
|
|
*/
|
|
void FilterPowerSymbols( bool aFilterEnable )
|
|
{
|
|
m_filterPowerSymbols = aFilterEnable;
|
|
}
|
|
|
|
// Accessors
|
|
|
|
/**
|
|
* @return true if the filtering of power symbols is on
|
|
*/
|
|
bool GetFilterPowerSymbols() const { return m_filterPowerSymbols; }
|
|
|
|
|
|
/**
|
|
* @return am wxArrayString of the names of allowed libs
|
|
*/
|
|
const wxArrayString& GetAllowedLibList() const { return m_allowedLibs; }
|
|
|
|
/**
|
|
* @return the name of the lib to use to load a symbol, or an a empty string
|
|
* Useful to load (in lib editor or lib viewer) a symbol from a given library
|
|
*/
|
|
const wxString& GetLibSource() const
|
|
{
|
|
static wxString dummy;
|
|
|
|
if( m_forceLoad && m_allowedLibs.GetCount() > 0 )
|
|
return m_allowedLibs[0];
|
|
else
|
|
return dummy;
|
|
}
|
|
|
|
private:
|
|
wxArrayString m_allowedLibs; ///< a list of lib names to list some libraries
|
|
///< if empty: no filter
|
|
bool m_filterPowerSymbols; ///< true to filter (show only) power symbols
|
|
bool m_forceLoad; // When true, load a symbol lib from the lib
|
|
// which is given in m_allowedLibs[0]
|
|
};
|
|
|
|
|
|
/* Helpers for creating a list of symbol libraries. */
|
|
class SYMBOL_LIB;
|
|
class wxRegEx;
|
|
|
|
/**
|
|
* LIB_SYMBOL map sorting.
|
|
*/
|
|
struct LibSymbolMapSort
|
|
{
|
|
bool operator() ( const wxString& aItem1, const wxString& aItem2 ) const
|
|
{
|
|
return aItem1 < aItem2;
|
|
}
|
|
};
|
|
|
|
/// Symbol map used by symbol library object.
|
|
|
|
typedef std::map< wxString, LIB_SYMBOL*, LibSymbolMapSort > LIB_SYMBOL_MAP;
|
|
typedef std::vector< LIB_SYMBOL* > LIB_SYMBOLS;
|
|
typedef boost::ptr_vector< SYMBOL_LIB > SYMBOL_LIBS_BASE;
|
|
|
|
|
|
/**
|
|
* A collection of #SYMBOL_LIB objects.
|
|
*
|
|
* It extends from PROJECT::_ELEM so it can be hung in the PROJECT. It does not use any
|
|
* UI calls, but rather simply throws an IO_ERROR when there is a problem.
|
|
*/
|
|
class SYMBOL_LIBS : public SYMBOL_LIBS_BASE, public PROJECT::_ELEM
|
|
{
|
|
public:
|
|
KICAD_T Type() override { return SYMBOL_LIBS_T; }
|
|
|
|
static int s_modify_generation; ///< helper for GetModifyHash()
|
|
static std::mutex s_generationMutex;
|
|
|
|
SYMBOL_LIBS()
|
|
{
|
|
IncrementModifyGeneration();
|
|
}
|
|
|
|
static void IncrementModifyGeneration()
|
|
{
|
|
std::lock_guard<std::mutex> mut( SYMBOL_LIBS::s_generationMutex );
|
|
++SYMBOL_LIBS::s_modify_generation;
|
|
}
|
|
|
|
static int GetModifyGeneration()
|
|
{
|
|
std::lock_guard<std::mutex> mut( SYMBOL_LIBS::s_generationMutex );
|
|
return SYMBOL_LIBS::s_modify_generation;
|
|
}
|
|
|
|
/// Return the modification hash for all libraries. The value returned
|
|
/// changes on every library modification.
|
|
int GetModifyHash();
|
|
|
|
/**
|
|
* Allocate and adds a symbol library to the library list.
|
|
*
|
|
* @param aFileName is the file name object of symbol library.
|
|
* @throw IO_ERROR if there's any problem loading.
|
|
*/
|
|
SYMBOL_LIB* AddLibrary( const wxString& aFileName );
|
|
|
|
/**
|
|
* Insert a symbol library into the library list.
|
|
*
|
|
* @param aFileName is the file name object of symbol library.
|
|
* @param aIterator is an iterator to insert library in front of.
|
|
* @return the new SYMBOL_LIB, which remains owned by this SYMBOL_LIBS container.
|
|
* @throw IO_ERROR if there's any problem loading.
|
|
*/
|
|
SYMBOL_LIB* AddLibrary( const wxString& aFileName, SYMBOL_LIBS::iterator& aIterator );
|
|
|
|
/**
|
|
* Load all of the project's libraries into this container, which should
|
|
* be cleared before calling it.
|
|
*
|
|
* @note This method is only to be used when loading legacy projects. All further symbol
|
|
* library access should be done via the symbol library table.
|
|
*/
|
|
void LoadAllLibraries( PROJECT* aProject, bool aShowProgress=true );
|
|
|
|
/**
|
|
* Save or load the names of the currently configured symbol libraries (without paths).
|
|
*/
|
|
static void LibNamesAndPaths( PROJECT* aProject, bool doSave,
|
|
wxString* aPaths, wxArrayString* aNames = nullptr );
|
|
|
|
/**
|
|
* Return the name of the cache library after potentially fixing it from
|
|
* an older naming scheme. That is, the old file is renamed if needed.
|
|
*
|
|
* @param aFullProjectFilename is the *.pro filename with absolute path.
|
|
*/
|
|
static const wxString CacheName( const wxString& aFullProjectFilename );
|
|
|
|
/**
|
|
* Find a symbol library by \a aName.
|
|
*
|
|
* @param aName is the library file name without path or extension to find.
|
|
* @return the symbol library if found, otherwise NULL.
|
|
*/
|
|
SYMBOL_LIB* FindLibrary( const wxString& aName );
|
|
|
|
SYMBOL_LIB* FindLibraryByFullFileName( const wxString& aFullFileName );
|
|
|
|
SYMBOL_LIB* GetCacheLibrary();
|
|
|
|
/**
|
|
* Return the list of symbol library file names without path and extension.
|
|
*
|
|
* @param aSorted sort the list of name if true. Otherwise use the library load order.
|
|
* @return the list of library names.
|
|
*/
|
|
wxArrayString GetLibraryNames( bool aSorted = true );
|
|
|
|
/**
|
|
* Search all libraries in the list for a symbol.
|
|
*
|
|
* A symbol object will always be returned. If the entry found
|
|
* is an alias. The root symbol will be found and returned.
|
|
*
|
|
* @param aLibId is the #LIB_ID of the symbol to search for.
|
|
* @param aLibraryName is the name of the library to search for symbol.
|
|
* @return the symbol object if found, otherwise NULL.
|
|
*/
|
|
LIB_SYMBOL* FindLibSymbol( const LIB_ID& aLibId, const wxString& aLibraryName = wxEmptyString );
|
|
|
|
/**
|
|
* Search all libraries in the list for a #LIB_SYMBOL using a case insensitive comparison.
|
|
*
|
|
* Helper function used in dialog to find all candidates.
|
|
* During a long time, eeschema was using a case insensitive search.
|
|
* Therefore, for old schematics (<= 2013), or libs, for some symbols,
|
|
* the chip name (name of alias in lib) can be broken.
|
|
* This function can be used to display a list of candidates, in symbol properties dialog.
|
|
*
|
|
* @param aEntryName is the name of entries to search for (case insensitive).
|
|
* @param aLibraryName is the name of the library to search.
|
|
* @param aCandidates is a std::vector to store candidates.
|
|
*/
|
|
void FindLibraryNearEntries( std::vector<LIB_SYMBOL*>& aCandidates, const wxString& aEntryName,
|
|
const wxString& aLibraryName = wxEmptyString );
|
|
|
|
int GetLibraryCount() { return size(); }
|
|
};
|
|
|
|
|
|
/**
|
|
* Object used to load, save, search, and otherwise manipulate symbol library files.
|
|
*
|
|
* @warning This code is obsolete with the exception of the cache library. All other
|
|
* symbol library I/O is managed by the #SCH_IO_MGR object.
|
|
*/
|
|
class SYMBOL_LIB
|
|
{
|
|
public:
|
|
SYMBOL_LIB( SCH_LIB_TYPE aType, const wxString& aFileName,
|
|
SCH_IO_MGR::SCH_FILE_T aPluginType = SCH_IO_MGR::SCH_LEGACY );
|
|
~SYMBOL_LIB();
|
|
|
|
/**
|
|
* @return a magic number that changes if the library has changed
|
|
*/
|
|
int GetModHash() const { return m_mod_hash; }
|
|
|
|
SCH_IO_MGR::SCH_FILE_T GetPluginType() const { return m_pluginType; }
|
|
|
|
void SetPluginType( SCH_IO_MGR::SCH_FILE_T aPluginType );
|
|
|
|
void Create( const wxString& aFileName = wxEmptyString );
|
|
|
|
void SetFileName( const wxString& aFileName ) { fileName = aFileName; }
|
|
|
|
bool IsModified() const
|
|
{
|
|
return isModified;
|
|
}
|
|
|
|
bool IsCache() const;
|
|
|
|
void SetCache();
|
|
|
|
bool IsBuffering() const;
|
|
|
|
void EnableBuffering( bool aEnable = true );
|
|
|
|
void Save( bool aSaveDocFile = true );
|
|
|
|
/**
|
|
* @return true if current user does not have write access to the library file.
|
|
*/
|
|
bool IsReadOnly() const { return !fileName.IsFileWritable(); }
|
|
|
|
/**
|
|
* Load a string array with the names of all the entries in this library.
|
|
*
|
|
* @param aNames is the array to place entry names into.
|
|
*/
|
|
void GetSymbolNames( wxArrayString& aNames ) const;
|
|
|
|
/**
|
|
* Load a vector with all the entries in this library.
|
|
*
|
|
* @param aSymbols is a vector to receive the aliases.
|
|
*/
|
|
void GetSymbols( std::vector<LIB_SYMBOL*>& aSymbols ) const;
|
|
|
|
/**
|
|
* Find #LIB_SYMBOL by \a aName.
|
|
*
|
|
* @param aName is the name of the symbol, case sensitive.
|
|
* @return LIB_SYMBOL pointer symbol if found, else NULL.
|
|
*/
|
|
LIB_SYMBOL* FindSymbol( const wxString& aName ) const;
|
|
|
|
LIB_SYMBOL* FindSymbol( const LIB_ID& aLibId ) const;
|
|
|
|
/**
|
|
* Add \a aSymbol entry to library.
|
|
*
|
|
* @note A #LIB_SYMBOL can have an alias list so these alias will be added in library.
|
|
* and the any existing duplicate aliases will be removed from the library.
|
|
*
|
|
* @param aSymbol is the symbol to add, caller retains ownership, a clone is added.
|
|
*/
|
|
void AddSymbol( LIB_SYMBOL* aSymbol );
|
|
|
|
/**
|
|
* Safely remove \a aEntry from the library and return the next entry.
|
|
*
|
|
* The next entry returned depends on the entry being removed. If the entry being
|
|
* remove also removes the symbol, then the next entry from the list is returned.
|
|
* If the entry being used only removes an alias from a symbol, then the next alias
|
|
* of the symbol is returned.
|
|
*
|
|
* @param aEntry is the entry to remove from library.
|
|
* @return The next entry in the library or NULL if the library is empty.
|
|
*/
|
|
LIB_SYMBOL* RemoveSymbol( LIB_SYMBOL* aEntry );
|
|
|
|
/**
|
|
* Replace an existing symbol entry in the library.
|
|
*
|
|
* @note A symbol can have an alias list so these aliases will be added in library and
|
|
* previously existing alias removed.
|
|
*
|
|
* @param aOldSymbol is the symbol to replace.
|
|
* @param aNewSymbol is the new symbol.
|
|
*/
|
|
LIB_SYMBOL* ReplaceSymbol( LIB_SYMBOL* aOldSymbol, LIB_SYMBOL* aNewSymbol );
|
|
|
|
/**
|
|
* Return the file name without path or extension.
|
|
*
|
|
* @return the name of library file.
|
|
*/
|
|
const wxString GetName() const { return fileName.GetName(); }
|
|
|
|
/**
|
|
* Return the full file library name with path and extension.
|
|
*
|
|
* @return the full library file name with path and extension.
|
|
*/
|
|
wxString GetFullFileName() const { return fileName.GetFullPath(); }
|
|
|
|
/**
|
|
* Return the logical name of the library.
|
|
*
|
|
* @return The logical name of this library.
|
|
*/
|
|
const wxString GetLogicalName() const
|
|
{
|
|
/* for now is the filename without path or extension.
|
|
|
|
Technically the library should not know its logical name!
|
|
This will eventually come out of a pair of lookup tables using a
|
|
reverse lookup using the full name or library pointer as a key.
|
|
Search will be by project lookup table and then user lookup table if
|
|
not found.
|
|
*/
|
|
return fileName.GetName();
|
|
}
|
|
|
|
|
|
/**
|
|
* Allocate and load a symbol library file.
|
|
*
|
|
* @param aFileName is the file name of the symbol library to load.
|
|
* @return SYMBOL_LIB* is the allocated and loaded SYMBOL_LIB, which is owned by the caller.
|
|
* @throw IO_ERROR if there's any problem loading the library.
|
|
*/
|
|
static SYMBOL_LIB* LoadLibrary( const wxString& aFileName );
|
|
|
|
private:
|
|
SCH_LIB_TYPE type; ///< Library type indicator.
|
|
wxFileName fileName; ///< Library file name.
|
|
wxDateTime timeStamp; ///< Library save time and date.
|
|
int versionMajor; ///< Library major version number.
|
|
int versionMinor; ///< Library minor version number.
|
|
wxString header; ///< first line of loaded library.
|
|
bool isModified; ///< Library modification status.
|
|
int m_mod_hash; ///< incremented each time library is changed.
|
|
|
|
SCH_IO_MGR::SCH_FILE_T m_pluginType;
|
|
std::unique_ptr< SCH_PLUGIN > m_plugin;
|
|
std::unique_ptr< PROPERTIES > m_properties; ///< Library properties
|
|
};
|
|
|
|
|
|
/**
|
|
* Case insensitive library name comparison.
|
|
*/
|
|
bool operator==( const SYMBOL_LIB& aLibrary, const wxString& aName );
|
|
bool operator!=( const SYMBOL_LIB& aLibrary, const wxString& aName );
|
|
|
|
#endif // SYMBOL_LIBRARY_H
|