/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2008 Wayne Stambaugh * Copyright (C) 2004-2022 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 #include #include #include #include #include class LIB_SYMBOL; class LIB_ID; class LINE_READER; class OUTPUTFORMATTER; class STRING_UTF8_MAP; class SCH_IO; class SYMBOL_LIB; /* Helpers for creating a list of symbol libraries. */ 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; } SYMBOL_LIBS() {} /** * 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 ); /** * Refreshes the library from the (possibly updated) contents on disk * * @param aFileName is the file name of the symbol library * @return true if successfully updated */ bool ReloadLibrary( const wxString& aFileName ); /** * 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 ); static void GetLibNamesAndPaths( PROJECT* aProject, wxString* aPaths, wxArrayString* aNames = nullptr ); static void SetLibNamesAndPaths( PROJECT* aProject, const wxString& aPaths, const wxArrayString& aNames ); /** * 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& 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& 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* LoadSymbolLibrary( 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_IO > m_plugin; std::unique_ptr 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