/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020 Thomas Pointhuber * Copyright (C) 2021-2024 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 */ #ifndef _SCH_IO_ALTIUM_H_ #define _SCH_IO_ALTIUM_H_ #include #include #include #include #include #include #include #include "altium_parser_sch.h" class SCH_SYMBOL; class SCH_SHEET; class TITLE_BLOCK; class ALTIUM_COMPOUND_FILE; /** * SCH_IO_ALTIUM * is a #SCH_IO derivation for loading Altium .SchDoc schematic files. * * As with all SCH_IO there is no UI dependencies i.e. windowing calls allowed. */ static std::vector nullsym; static std::vector nullint; class SCH_IO_ALTIUM : public SCH_IO { public: SCH_IO_ALTIUM(); ~SCH_IO_ALTIUM(); const IO_BASE::IO_FILE_DESC GetSchematicFileDesc() const override { return IO_BASE::IO_FILE_DESC( _HKI( "Altium schematic files" ), { "SchDoc" } ); } const IO_BASE::IO_FILE_DESC GetLibraryDesc() const override { return IO_BASE::IO_FILE_DESC( _HKI( "Altium Schematic Library or Integrated Library" ), { "SchLib", "IntLib" } ); } bool CanReadSchematicFile( const wxString& aFileName ) const override; bool CanReadLibrary( const wxString& aFileName ) const override; int GetModifyHash() const override; SCH_SHEET* LoadSchematicFile( const wxString& aFileName, SCHEMATIC* aSchematic, SCH_SHEET* aAppendToMe = nullptr, const STRING_UTF8_MAP* aProperties = nullptr ) override; // unimplemented functions. Will trigger a not_implemented IO error. //void SaveLibrary( const wxString& aFileName, const PROPERTIES* aProperties = NULL ) override; //void Save( const wxString& aFileName, SCH_SCREEN* aSchematic, KIWAY* aKiway, // const PROPERTIES* aProperties = NULL ) override; void EnumerateSymbolLib( wxArrayString& aSymbolNameList, const wxString& aLibraryPath, const STRING_UTF8_MAP* aProperties = nullptr ) override; void EnumerateSymbolLib( std::vector& aSymbolList, const wxString& aLibraryPath, const STRING_UTF8_MAP* aProperties = nullptr ) override; LIB_SYMBOL* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName, const STRING_UTF8_MAP* aProperties = nullptr ) override; //void SaveSymbol( const wxString& aLibraryPath, const LIB_SYMBOL* aSymbol, // const PROPERTIES* aProperties = NULL ) override; //void DeleteAlias( const wxString& aLibraryPath, const wxString& aAliasName, // const PROPERTIES* aProperties = NULL ) override; //void DeleteSymbol( const wxString& aLibraryPath, const wxString& aAliasName, // const PROPERTIES* aProperties = NULL ) override; bool IsLibraryWritable( const wxString& aLibraryPath ) override { return false; } wxString getLibName(); wxFileName getLibFileName(); void ParseAltiumSch( const wxString& aFileName ); void ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ); void ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ); void ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ); void ParseASCIISchematic( const wxString& aFileName ); void ParseRecord( int index, std::map& properties, const wxString& aSectionName ); private: SCH_SCREEN* getCurrentScreen(); SCH_SHEET* getCurrentSheet(); bool ShouldPutItemOnSheet( int aOwnerindex ); bool IsComponentPartVisible( const ASCH_OWNER_INTERFACE& aElem ) const; const ASCH_STORAGE_FILE* GetFileFromStorage( const wxString& aFilename ) const; void AddTextBox( const ASCH_TEXT_FRAME* aElem ); void AddLibTextBox( const ASCH_TEXT_FRAME* aElem, std::vector& aSymbol = nullsym, std::vector& aFontSize = nullint ); void ParseComponent( int aIndex, const std::map& aProperties ); void ParseTemplate( int aIndex, const std::map& aProperties ); void ParsePin( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseLabel( const std::map& aProperties, std::vector& aSymbol = nullsym, std::vector& aFontSize = nullint ); void ParseTextFrame( const std::map& aProperties, std::vector& aSymbol = nullsym, std::vector& aFontSize = nullint ); void ParseNote( const std::map& aProperties ); void ParseBezier( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParsePolyline( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParsePolygon( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseRoundRectangle( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseArc( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseEllipticalArc( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseEllipse( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseCircle( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseLine( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseSignalHarness( const std::map& aProperties ); void ParseHarnessConnector( int aIndex, const std::map& aProperties ); void ParseHarnessEntry( const std::map& aProperties ); void ParseHarnessType( const std::map& aProperties ); void ParseHarnessPort( const ASCH_PORT& aElem ); void ParseHyperlink( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseRectangle( const std::map& aProperties, std::vector& aSymbol = nullsym); void ParseSheetSymbol( int aIndex, const std::map& aProperties ); void ParseSheetEntry( const std::map& aProperties ); void ParsePowerPort( const std::map& aProperties ); void ParsePort( const ASCH_PORT& aElem ); void ParseNoERC( const std::map& aProperties ); void ParseNetLabel( const std::map& aProperties ); void ParseBus( const std::map& aProperties ); void ParseWire( const std::map& aProperties ); void ParseJunction( const std::map& aProperties ); void ParseImage( const std::map& aProperties ); void ParseSheet( const std::map& aProperties ); void ParseSheetName( const std::map& aProperties ); void ParseFileName( const std::map& aProperties ); void ParseDesignator( const std::map& aProperties ); void ParseLibDesignator( const std::map& aProperties, std::vector& aSymbol = nullsym, std::vector& aFontSize = nullint ); void ParseBusEntry( const std::map& aProperties ); void ParseParameter( const std::map& aProperties ); void ParseLibParameter( const std::map& aProperties, std::vector& aSymbol = nullsym, std::vector& aFontSize = nullint ); void ParseImplementationList( int aIndex, const std::map& aProperties ); void ParseImplementation( const std::map& aProperties, std::vector& aSymbol = nullsym ); void ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile, std::vector& aFontSizes ); std::map ParseLibFile( const ALTIUM_COMPOUND_FILE& aAltiumSchFile ); std::vector ParseLibComponent( const std::map& aProperties ); void doEnumerateSymbolLib( const wxString& aLibraryPath, const STRING_UTF8_MAP* aProperties, std::function aInserter ); private: SCH_SHEET* m_rootSheet; // The root sheet of the schematic being loaded.. SCH_SHEET_PATH m_sheetPath; SCHEMATIC* m_schematic; // Passed to Load(), the schematic object being loaded wxString m_libName; // Library name to save symbols bool m_isIntLib; // Flag to indicate Integrated Library IO_RELEASER m_pi; // Plugin to create KiCad symbol library. std::unique_ptr m_properties; // Library plugin properties. std::unique_ptr m_currentTitleBlock; // Will be assigned at the end of parsing // a sheet VECTOR2I m_sheetOffset; std::unique_ptr m_altiumSheet; std::map m_symbols; std::map m_sheets; std::map m_libSymbols; // every symbol has its unique lib_symbol std::map m_powerSymbols; std::vector m_altiumStorage; std::vector m_altiumAdditional; std::map m_altiumComponents; std::map m_altiumTemplates; std::map m_altiumImplementationList; std::vector m_altiumPortsCurrentSheet; // we require all connections first // parse harness ports after "FileHeader" was parsed, in 2nd run. std::vector m_altiumHarnessPortsCurrentSheet; // Add offset to all harness ownerIndex'es after parsing FileHeader. int m_harnessOwnerIndexOffset; int m_harnessEntryParent; // used to identify harness connector for harness entry element // Symbol caching void ensureLoadedLibrary( const wxString& aLibraryPath, const STRING_UTF8_MAP* aProperties ); long long getLibraryTimestamp( const wxString& aLibraryPath ) const; static bool isBinaryFile( const wxString& aFileName ); static bool isASCIIFile( const wxString& aFileName ); static bool checkFileHeader( const wxString& aFileName ); std::map m_timestamps; std::map> m_libCache; // List of available fonts with font name and font size in pt std::vector> m_fonts; }; #endif // _SCH_IO_ALTIUM_H_