KiCad PCB EDA Suite
sch_altium_plugin.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2020 Thomas Pointhuber <[email protected]>
5 * Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <memory>
26
27#include "altium_parser_sch.h"
28#include "sch_shape.h"
32
33#include <schematic.h>
34
35#include <lib_shape.h>
36#include <lib_id.h>
37#include <lib_item.h>
38#include <lib_pin.h>
39#include <lib_text.h>
40
41#include <sch_bitmap.h>
42#include <sch_bus_entry.h>
43#include <sch_symbol.h>
44#include <sch_junction.h>
45#include <sch_line.h>
46#include <sch_no_connect.h>
47#include <sch_screen.h>
48#include <sch_label.h>
49#include <sch_sheet.h>
50#include <sch_sheet_pin.h>
51#include <sch_textbox.h>
52
53#include <bezier_curves.h>
54#include <compoundfilereader.h>
55#include <string_utils.h>
56#include <sch_edit_frame.h>
57#include <trigo.h>
59#include <wx/mstream.h>
60#include <wx/log.h>
61#include <wx/zstream.h>
62#include <wx/wfstream.h>
63#include <trigo.h>
64
65// Harness port object itself does not contain color information about itself
66// It seems altium is drawing harness ports using these colors
67#define HARNESS_PORT_COLOR_DEFAULT_BACKGROUND COLOR4D( 0.92941176470588238, \
68 0.94901960784313721, \
69 0.98431372549019602, 1.0 )
70
71#define HARNESS_PORT_COLOR_DEFAULT_OUTLINE COLOR4D( 0.56078431372549020, \
72 0.61960784313725492, \
73 0.78823529411764703, 1.0 )
74
75
76static const VECTOR2I GetRelativePosition( const VECTOR2I& aPosition, const SCH_SYMBOL* aSymbol )
77{
79 return t.TransformCoordinate( aPosition - aSymbol->GetPosition() );
80}
81
82
84{
85 int red = color & 0x0000FF;
86 int green = ( color & 0x00FF00 ) >> 8;
87 int blue = ( color & 0xFF0000 ) >> 16;
88
89 return COLOR4D().FromCSSRGBA( red, green, blue, 1.0 );
90}
91
92
94{
95 switch( linestyle )
96 {
101 default: return PLOT_DASH_TYPE::DEFAULT;
102 }
103}
104
105
107{
109 GetColorFromInt( elem.Color ) ) );
110
111 if( !elem.IsSolid )
112 {
114 }
115 else
116 {
118 shape->SetFillColor( GetColorFromInt( elem.AreaColor ) );
119 }
120}
121
122
124{
126
127 if( !elem.IsSolid )
128 {
130 }
131 else if( elem.Color == elem.AreaColor )
132 {
134 }
135 else
136 {
138 }
139}
140
141
143{
144 m_rootSheet = nullptr;
145 m_schematic = nullptr;
148
150}
151
152
154{
155}
156
157
158const wxString SCH_ALTIUM_PLUGIN::GetName() const
159{
160 return "Altium";
161}
162
163
165{
166 return "SchDoc";
167}
168
169
171{
172 return "SchLib";
173}
174
175
177{
178 return 0;
179}
180
181
182bool SCH_ALTIUM_PLUGIN::CheckHeader( const wxString& aFileName )
183{
184 // TODO
185
186 return true;
187}
188
189
191{
192 if( m_libName.IsEmpty() )
193 {
194 // Try to come up with a meaningful name
196
197 if( m_libName.IsEmpty() )
198 {
199 wxFileName fn( m_rootSheet->GetFileName() );
200 m_libName = fn.GetName();
201 }
202
203 if( m_libName.IsEmpty() )
204 m_libName = "noname";
205
206 m_libName += "-altium-import";
208 }
209
210 return m_libName;
211}
212
213
215{
217
218 return fn;
219}
220
221
222SCH_SHEET* SCH_ALTIUM_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchematic,
223 SCH_SHEET* aAppendToMe, const STRING_UTF8_MAP* aProperties )
224{
225 wxCHECK( !aFileName.IsEmpty() && aSchematic, nullptr );
226
227 wxFileName fileName( aFileName );
228 fileName.SetExt( KiCadSchematicFileExtension );
229 m_schematic = aSchematic;
230
231 // Delete on exception, if I own m_rootSheet, according to aAppendToMe
232 std::unique_ptr<SCH_SHEET> deleter( aAppendToMe ? nullptr : m_rootSheet );
233
234 if( aAppendToMe )
235 {
236 wxCHECK_MSG( aSchematic->IsValid(), nullptr, "Can't append to a schematic with no root!" );
237 m_rootSheet = &aSchematic->Root();
238 }
239 else
240 {
241 m_rootSheet = new SCH_SHEET( aSchematic );
242 m_rootSheet->SetFileName( fileName.GetFullPath() );
243
244 aSchematic->SetRoot( m_rootSheet );
245
246 SCH_SHEET_PATH sheetpath;
247 sheetpath.push_back( m_rootSheet );
248
249 // We'll update later if we find a pageNumber record for it.
250 sheetpath.SetPageNumber( "#" );
251 }
252
253 if( !m_rootSheet->GetScreen() )
254 {
255 SCH_SCREEN* screen = new SCH_SCREEN( m_schematic );
256 screen->SetFileName( aFileName );
257 m_rootSheet->SetScreen( screen );
258 const_cast<KIID&>( m_rootSheet->m_Uuid ) = screen->GetUuid();
259 }
260
261 SYMBOL_LIB_TABLE* libTable = m_schematic->Prj().SchSymbolLibTable();
262
263 wxCHECK_MSG( libTable, nullptr, "Could not load symbol lib table." );
264
265 m_pi.set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
266
269 if( !libTable->HasLibrary( getLibName() ) )
270 {
271 // Create a new empty symbol library.
272 m_pi->CreateSymbolLib( getLibFileName().GetFullPath() );
273 wxString libTableUri = "${KIPRJMOD}/" + getLibFileName().GetFullName();
274
275 // Add the new library to the project symbol library table.
276 libTable->InsertRow( new SYMBOL_LIB_TABLE_ROW( getLibName(), libTableUri,
277 wxString( "KiCad" ) ) );
278
279 // Save project symbol library table.
280 wxFileName fn( m_schematic->Prj().GetProjectPath(),
282
283 // So output formatter goes out of scope and closes the file before reloading.
284 {
285 FILE_OUTPUTFORMATTER formatter( fn.GetFullPath() );
286 libTable->Format( &formatter, 0 );
287 }
288
289 // Reload the symbol library table.
291 m_schematic->Prj().SchSymbolLibTable();
292 }
293
295
296 SCH_SCREEN* rootScreen = m_rootSheet->GetScreen();
297 wxCHECK( rootScreen, nullptr );
298
299 SCH_SHEET_INSTANCE sheetInstance;
300
301 sheetInstance.m_Path = m_sheetPath.Path();
302 sheetInstance.m_PageNumber = wxT( "#" );
303
304 rootScreen->m_sheetInstances.emplace_back( sheetInstance );
305
306 ParseAltiumSch( aFileName );
307
308 m_pi->SaveLibrary( getLibFileName().GetFullPath() );
309
310 SCH_SCREENS allSheets( m_rootSheet );
311 allSheets.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
312 allSheets.ClearEditFlags();
313
314 return m_rootSheet;
315}
316
317
319{
320 return m_sheetPath.LastScreen();
321}
322
323
325{
326 return m_sheetPath.Last();
327}
328
329
330void SCH_ALTIUM_PLUGIN::ParseAltiumSch( const wxString& aFileName )
331{
332 ALTIUM_COMPOUND_FILE altiumSchFile( aFileName );
333
334 // Load path may be different from the project path.
335 wxFileName parentFileName = aFileName;
336
337 try
338 {
339 ParseStorage( altiumSchFile ); // we need this before parsing the FileHeader
340 ParseFileHeader( altiumSchFile );
341
342 // Parse "Additional" because sheet is set up during "FileHeader" parsing.
343 ParseAdditional( altiumSchFile );
344 }
345 catch( CFB::CFBException& exception )
346 {
347 THROW_IO_ERROR( exception.what() );
348 }
349
350 SCH_SCREEN* currentScreen = getCurrentScreen();
351 wxCHECK( currentScreen, /* void */ );
352
353 // Descend the sheet hierarchy.
354 for( SCH_ITEM* item : currentScreen->Items().OfType( SCH_SHEET_T ) )
355 {
356 SCH_SCREEN* loadedScreen = nullptr;
357 SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( item );
358
359 wxCHECK2( sheet, continue );
360
361 // The assumption is that all of the Altium schematic files will be in the same
362 // path as the parent sheet path.
363 wxFileName loadAltiumFileName( parentFileName.GetPath(), sheet->GetFileName() );
364
365 m_rootSheet->SearchHierarchy( loadAltiumFileName.GetFullPath(), &loadedScreen );
366
367 if( loadedScreen )
368 {
369 sheet->SetScreen( loadedScreen );
370 // Do not need to load the sub-sheets - this has already been done.
371 }
372 else
373 {
374 sheet->SetScreen( new SCH_SCREEN( m_schematic ) );
375 SCH_SCREEN* screen = sheet->GetScreen();
376 sheet->SetName( loadAltiumFileName.GetName() );
377 wxCHECK2( screen, continue );
378
379 m_sheetPath.push_back( sheet );
380 ParseAltiumSch( loadAltiumFileName.GetFullPath() );
381
382 // Map the loaded Altium file to the project file.
383 wxFileName projectFileName = loadAltiumFileName;
384 projectFileName.SetPath( m_schematic->Prj().GetProjectPath() );
385 projectFileName.SetExt( KiCadSchematicFileExtension );
386 sheet->SetFileName( projectFileName.GetFullName() );
387 screen->SetFileName( projectFileName.GetFullPath() );
388
390 }
391 }
392}
393
394
396{
397 const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "Storage" } );
398
399 if( file == nullptr )
400 return;
401
402 ALTIUM_PARSER reader( aAltiumSchFile, file );
403
404 std::map<wxString, wxString> properties = reader.ReadProperties();
405 wxString header = ALTIUM_PARSER::ReadString( properties, "HEADER", "" );
406 int weight = ALTIUM_PARSER::ReadInt( properties, "WEIGHT", 0 );
407
408 if( weight < 0 )
409 THROW_IO_ERROR( "Storage weight is negative!" );
410
411 for( int i = 0; i < weight; i++ )
412 {
413 m_altiumStorage.emplace_back( reader );
414 }
415
416 if( reader.HasParsingError() )
417 THROW_IO_ERROR( "stream was not parsed correctly!" );
418
419 // TODO pointhi: is it possible to have multiple headers in one Storage file? Otherwise
420 // throw IO Error.
421 if( reader.GetRemainingBytes() != 0 )
422 {
423 m_reporter->Report( wxString::Format( _( "Storage file not fully parsed "
424 "(%d bytes remaining)." ),
425 reader.GetRemainingBytes() ),
427 }
428}
429
430
432{
433 const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "Additional" } );
434
435 if( file == nullptr )
436 return;
437
438 ALTIUM_PARSER reader( aAltiumSchFile, file );
439
440
441 if( reader.GetRemainingBytes() <= 0 )
442 {
443 THROW_IO_ERROR( "Additional section does not contain any data" );
444 }
445 else
446 {
447 std::map<wxString, wxString> properties = reader.ReadProperties();
448
449 int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 );
450 ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
451
452 if( record != ALTIUM_SCH_RECORD::HEADER )
453 THROW_IO_ERROR( "Header expected" );
454 }
455
456 for( int index = 0; reader.GetRemainingBytes() > 0; index++ )
457 {
458 std::map<wxString, wxString> properties = reader.ReadProperties();
459
460 int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 );
461 ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
462
463 // see: https://github.com/vadmium/python-altium/blob/master/format.md
464 switch( record )
465 {
467 ParseHarnessConnector( index, properties );
468 break;
469
471 ParseHarnessEntry( properties );
472 break;
473
475 ParseHarnessType( properties );
476 break;
477
479 ParseSignalHarness( properties );
480 break;
481
482 default:
483 m_reporter->Report( wxString::Format( _( "Unknown or unexpected record ID %d found "
484 "inside \"Additional\" section." ),
485 recordId ),
487 break;
488 }
489 }
490
491 // Handle harness Ports
493 ParseHarnessPort( port );
494
495 if( reader.HasParsingError() )
496 THROW_IO_ERROR( "stream was not parsed correctly!" );
497
498 if( reader.GetRemainingBytes() != 0 )
499 THROW_IO_ERROR( "stream is not fully parsed" );
500}
501
502
504{
505 const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "FileHeader" } );
506
507 if( file == nullptr )
508 THROW_IO_ERROR( "FileHeader not found" );
509
510 ALTIUM_PARSER reader( aAltiumSchFile, file );
511
512 if( reader.GetRemainingBytes() <= 0 )
513 {
514 THROW_IO_ERROR( "FileHeader does not contain any data" );
515 }
516 else
517 {
518 std::map<wxString, wxString> properties = reader.ReadProperties();
519
520 int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 );
521 ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
522
523 if( record != ALTIUM_SCH_RECORD::HEADER )
524 THROW_IO_ERROR( "Header expected" );
525 }
526
527 // Prepare some local variables
528 wxCHECK( m_altiumPortsCurrentSheet.empty(), /* void */ );
529 wxCHECK( !m_currentTitleBlock, /* void */ );
530
531 m_currentTitleBlock = std::make_unique<TITLE_BLOCK>();
532
533 // index is required to resolve OWNERINDEX
534 for( int index = 0; reader.GetRemainingBytes() > 0; index++ )
535 {
536 std::map<wxString, wxString> properties = reader.ReadProperties();
537
538 int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 );
539 ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
540
541 // see: https://github.com/vadmium/python-altium/blob/master/format.md
542 switch( record )
543 {
545 THROW_IO_ERROR( "Header already parsed" );
546
548 ParseComponent( index, properties );
549 break;
550
552 ParsePin( properties );
553 break;
554
556 m_reporter->Report( _( "Record 'IEEE_SYMBOL' not handled." ),
558 break;
559
561 ParseLabel( properties );
562 break;
563
565 ParseBezier( properties );
566 break;
567
569 ParsePolyline( properties );
570 break;
571
573 ParsePolygon( properties );
574 break;
575
577 ParseEllipse( properties );
578 break;
579
581 m_reporter->Report( _( "Record 'PIECHART' not handled." ),
583 break;
584
586 ParseRoundRectangle( properties );
587 break;
588
591 ParseArc( properties );
592 break;
593
595 ParseLine( properties );
596 break;
597
599 ParseRectangle( properties );
600 break;
601
603 ParseSheetSymbol( index, properties );
604 break;
605
607 ParseSheetEntry( properties );
608 break;
609
611 ParsePowerPort( properties );
612 break;
613
615 // Ports are parsed after the sheet was parsed
616 // This is required because we need all electrical connection points before placing.
617 m_altiumPortsCurrentSheet.emplace_back( properties );
618 break;
619
621 ParseNoERC( properties );
622 break;
623
625 ParseNetLabel( properties );
626 break;
627
629 ParseBus( properties );
630 break;
631
633 ParseWire( properties );
634 break;
635
637 ParseTextFrame( properties );
638 break;
639
641 ParseJunction( properties );
642 break;
643
645 ParseImage( properties );
646 break;
647
649 ParseSheet( properties );
650 break;
651
653 ParseSheetName( properties );
654 break;
655
657 ParseFileName( properties );
658 break;
659
661 ParseDesignator( properties );
662 break;
663
665 ParseBusEntry( properties );
666 break;
667
669 break;
670
672 ParseParameter( properties );
673 break;
674
676 break;
677
679 ParseImplementationList( index, properties );
680 break;
681
683 ParseImplementation( properties );
684 break;
685
687 break;
688
690 break;
691
693 break;
694
696 ParseNote( properties );
697 break;
698
700 m_reporter->Report( _( "Compile mask not currently supported." ), RPT_SEVERITY_ERROR );
701 break;
702
704 break;
705
706 default:
707 m_reporter->Report( wxString::Format( _( "Unknown or unexpected record id %d found "
708 "inside \"FileHeader\" section." ),
709 recordId ),
711 break;
712 }
713
715 }
716
717 if( reader.HasParsingError() )
718 THROW_IO_ERROR( "stream was not parsed correctly!" );
719
720 if( reader.GetRemainingBytes() != 0 )
721 THROW_IO_ERROR( "stream is not fully parsed" );
722
723 // assign LIB_SYMBOL -> COMPONENT
724 for( std::pair<const int, SCH_SYMBOL*>& symbol : m_symbols )
725 {
726 auto libSymbolIt = m_libSymbols.find( symbol.first );
727
728 if( libSymbolIt == m_libSymbols.end() )
729 THROW_IO_ERROR( "every symbol should have a symbol attached" );
730
731 m_pi->SaveSymbol( getLibFileName().GetFullPath(),
732 new LIB_SYMBOL( *( libSymbolIt->second ) ), m_properties.get() );
733
734 symbol.second->SetLibSymbol( libSymbolIt->second );
735 }
736
737 SCH_SCREEN* screen = getCurrentScreen();
738 wxCHECK( screen, /* void */ );
739
740 // Handle title blocks
742 m_currentTitleBlock.reset();
743
744 // Handle Ports
745 for( const ASCH_PORT& port : m_altiumPortsCurrentSheet )
746 ParsePort( port );
747
749 m_altiumComponents.clear();
750 m_symbols.clear();
751 m_libSymbols.clear();
752
753 // Otherwise we cannot save the imported sheet?
754 SCH_SHEET* sheet = getCurrentSheet();
755
756 wxCHECK( sheet, /* void */ );
757
758 sheet->SetModified();
759}
760
761
762bool SCH_ALTIUM_PLUGIN::IsComponentPartVisible( int aOwnerindex, int aOwnerpartdisplaymode ) const
763{
764 const auto& component = m_altiumComponents.find( aOwnerindex );
765
766 if( component == m_altiumComponents.end() )
767 return false;
768
769 return component->second.displaymode == aOwnerpartdisplaymode;
770}
771
772
773const ASCH_STORAGE_FILE* SCH_ALTIUM_PLUGIN::GetFileFromStorage( const wxString& aFilename ) const
774{
775 const ASCH_STORAGE_FILE* nonExactMatch = nullptr;
776
777 for( const ASCH_STORAGE_FILE& file : m_altiumStorage )
778 {
779 if( file.filename.IsSameAs( aFilename ) )
780 return &file;
781
782 if( file.filename.EndsWith( aFilename ) )
783 nonExactMatch = &file;
784 }
785
786 return nonExactMatch;
787}
788
789
791 const std::map<wxString, wxString>& aProperties )
792{
793 SCH_SHEET* currentSheet = m_sheetPath.Last();
794 wxCHECK( currentSheet, /* void */ );
795
796 wxString sheetName = currentSheet->GetName();
797
798 if( sheetName.IsEmpty() )
799 sheetName = wxT( "root" );
800
801 ASCH_SYMBOL altiumSymbol( aProperties );
802
803 if( m_altiumComponents.count( aIndex ) )
804 {
805 const ASCH_SYMBOL& currentSymbol = m_altiumComponents.at( aIndex );
806
807 m_reporter->Report( wxString::Format( _( "Symbol \"%s\" in sheet \"%s\" at index %d "
808 "replaced with symbol \"%s\"." ),
809 currentSymbol.libreference,
810 sheetName,
811 aIndex,
812 altiumSymbol.libreference ),
814 }
815
816 auto pair = m_altiumComponents.insert( { aIndex, altiumSymbol } );
817 const ASCH_SYMBOL& elem = pair.first->second;
818
819 // TODO: this is a hack until we correctly apply all transformations to every element
820 wxString name = wxString::Format( "%s_%d%s_%s",
821 sheetName,
822 elem.orientation,
823 elem.isMirrored ? "_mirrored" : "",
824 elem.libreference );
826
827 LIB_SYMBOL* ksymbol = new LIB_SYMBOL( wxEmptyString );
828 ksymbol->SetName( name );
829 ksymbol->SetDescription( elem.componentdescription );
830 ksymbol->SetLibId( libId );
831 m_libSymbols.insert( { aIndex, ksymbol } );
832
833 // each component has its own symbol for now
834 SCH_SYMBOL* symbol = new SCH_SYMBOL();
835
836 symbol->SetPosition( elem.location + m_sheetOffset );
837
838 // TODO: keep it simple for now, and only set position.
839 // component->SetOrientation( elem.orientation );
840 symbol->SetLibId( libId );
841 symbol->SetUnit( std::max( 0, elem.currentpartid ) );
842
843 SCH_SCREEN* screen = getCurrentScreen();
844 wxCHECK( screen, /* void */ );
845
846 screen->Append( symbol );
847
848 m_symbols.insert( { aIndex, symbol } );
849}
850
851
852void SCH_ALTIUM_PLUGIN::ParsePin( const std::map<wxString, wxString>& aProperties )
853{
854 ASCH_PIN elem( aProperties );
855
856 const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex );
857
858 if( libSymbolIt == m_libSymbols.end() )
859 {
860 // TODO: e.g. can depend on Template (RECORD=39
861 m_reporter->Report( wxString::Format( wxT( "Pin's owner (%d) not found." ),
862 elem.ownerindex ),
864 return;
865 }
866
868 return;
869
870 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
871 LIB_PIN* pin = new LIB_PIN( libSymbolIt->second );
872 libSymbolIt->second->AddDrawItem( pin );
873
874 pin->SetUnit( std::max( 0, elem.ownerpartid ) );
875
876 pin->SetName( elem.name );
877 pin->SetNumber( elem.designator );
878 pin->SetLength( elem.pinlength );
879
880 if( !elem.showDesignator )
881 pin->SetNumberTextSize( 0 );
882
883 if( !elem.showPinName )
884 pin->SetNameTextSize( 0 );
885
886 VECTOR2I pinLocation = elem.location; // the location given is not the connection point!
887
888 switch( elem.orientation )
889 {
891 pin->SetOrientation( DrawPinOrient::PIN_LEFT );
892 pinLocation.x += elem.pinlength;
893 break;
894
896 pin->SetOrientation( DrawPinOrient::PIN_DOWN );
897 pinLocation.y -= elem.pinlength;
898 break;
899
901 pin->SetOrientation( DrawPinOrient::PIN_RIGHT );
902 pinLocation.x -= elem.pinlength;
903 break;
904
906 pin->SetOrientation( DrawPinOrient::PIN_UP );
907 pinLocation.y += elem.pinlength;
908 break;
909
910 default:
911 m_reporter->Report( _( "Pin has unexpected orientation." ), RPT_SEVERITY_WARNING );
912 break;
913 }
914
915 // TODO: position can be sometimes off a little bit!
916 pin->SetPosition( GetRelativePosition( pinLocation + m_sheetOffset, symbol ) );
917
918 // TODO: the following fix is even worse for now?
919 // pin->SetPosition( GetRelativePosition( elem.kicadLocation, symbol ) );
920
921 switch( elem.electrical )
922 {
925 break;
926
929 break;
930
933 break;
934
937 break;
938
941 break;
942
945 break;
946
949 break;
950
953 break;
954
956 default:
958 m_reporter->Report( _( "Pin has unexpected electrical type." ), RPT_SEVERITY_WARNING );
959 break;
960 }
961
963 m_reporter->Report( _( "Pin has unexpected outer edge type." ), RPT_SEVERITY_WARNING );
964
966 m_reporter->Report( _( "Pin has unexpected inner edge type." ), RPT_SEVERITY_WARNING );
967
969 {
970 switch( elem.symbolInnerEdge )
971 {
974 break;
975
976 default:
977 pin->SetShape( GRAPHIC_PINSHAPE::INVERTED );
978 break;
979 }
980 }
982 {
983 switch( elem.symbolInnerEdge )
984 {
986 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK_LOW );
987 break;
988
989 default:
990 pin->SetShape( GRAPHIC_PINSHAPE::INPUT_LOW );
991 break;
992 }
993 }
995 {
997 }
998 else
999 {
1000 switch( elem.symbolInnerEdge )
1001 {
1003 pin->SetShape( GRAPHIC_PINSHAPE::CLOCK );
1004 break;
1005
1006 default:
1007 pin->SetShape( GRAPHIC_PINSHAPE::LINE ); // nothing to do
1008 break;
1009 }
1010 }
1011}
1012
1013
1015 ASCH_RECORD_ORIENTATION orientation )
1016{
1017 int vjustify, hjustify;
1019
1020 switch( justification )
1021 {
1022 default:
1027 vjustify = GR_TEXT_V_ALIGN_BOTTOM;
1028 break;
1029
1033 vjustify = GR_TEXT_V_ALIGN_CENTER;
1034 break;
1035
1039 vjustify = GR_TEXT_V_ALIGN_TOP;
1040 break;
1041 }
1042
1043 switch( justification )
1044 {
1045 default:
1050 hjustify = GR_TEXT_H_ALIGN_LEFT;
1051 break;
1052
1056 hjustify = GR_TEXT_H_ALIGN_CENTER;
1057 break;
1058
1062 hjustify = GR_TEXT_H_ALIGN_RIGHT;
1063 break;
1064 }
1065
1066 switch( orientation )
1067 {
1070 break;
1071
1073 vjustify *= -1;
1074 hjustify *= -1;
1076 break;
1077
1080 break;
1081
1083 vjustify *= -1;
1084 hjustify *= -1;
1086 break;
1087 }
1088
1089 text->SetVertJustify( static_cast<GR_TEXT_V_ALIGN_T>( vjustify ) );
1090 text->SetHorizJustify( static_cast<GR_TEXT_H_ALIGN_T>( hjustify ) );
1091 text->SetTextAngle( angle );
1092}
1093
1094
1095void SCH_ALTIUM_PLUGIN::ParseLabel( const std::map<wxString, wxString>& aProperties )
1096{
1097 ASCH_LABEL elem( aProperties );
1098
1100 {
1101 std::map<wxString, wxString> variableMap = {
1102 { "APPLICATION_BUILDNUMBER", "KICAD_VERSION" },
1103 { "SHEETNUMBER", "#" },
1104 { "SHEETTOTAL", "##" },
1105 { "TITLE", "TITLE" }, // 1:1 maps are sort of useless, but it makes it
1106 { "REVISION", "REVISION" }, // easier to see that the list is complete
1107 { "DATE", "ISSUE_DATE" },
1108 { "CURRENTDATE", "CURRENT_DATE" },
1109 { "COMPANYNAME", "COMPANY" },
1110 { "DOCUMENTNAME", "FILENAME" },
1111 { "PROJECTNAME", "PROJECTNAME" },
1112 };
1113
1114 wxString kicadText = AltiumSpecialStringsToKiCadVariables( elem.text, variableMap );
1115 SCH_TEXT* textItem = new SCH_TEXT( elem.location + m_sheetOffset, kicadText );
1116
1117 SetTextPositioning( textItem, elem.justification, elem.orientation );
1118
1119 size_t fontId = static_cast<int>( elem.fontId );
1120
1121 if( m_altiumSheet && fontId > 0 && fontId <= m_altiumSheet->fonts.size() )
1122 {
1123 const ASCH_SHEET_FONT& font = m_altiumSheet->fonts.at( fontId - 1 );
1124 textItem->SetItalic( font.Italic );
1125 textItem->SetBold( font.Bold );
1126 textItem->SetTextSize( { font.Size / 2, font.Size / 2 } );
1127 }
1128
1129 textItem->SetFlags(IS_NEW );
1130
1131 SCH_SCREEN* screen = getCurrentScreen();
1132 wxCHECK( screen, /* void */ );
1133
1134 screen->Append( textItem );
1135 }
1136 else
1137 {
1138 const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex );
1139
1140 if( libSymbolIt == m_libSymbols.end() )
1141 {
1142 // TODO: e.g. can depend on Template (RECORD=39
1143 m_reporter->Report( wxString::Format( wxT( "Label's owner (%d) not found." ),
1144 elem.ownerindex ),
1146 return;
1147 }
1148
1149 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
1150 LIB_TEXT* textItem = new LIB_TEXT( libSymbolIt->second );
1151 libSymbolIt->second->AddDrawItem( textItem );
1152
1153 textItem->SetUnit( std::max( 0, elem.ownerpartid ) );
1154
1155 textItem->SetPosition( GetRelativePosition( elem.location + m_sheetOffset, symbol ) );
1156 textItem->SetText( elem.text );
1157 SetTextPositioning( textItem, elem.justification, elem.orientation );
1158
1159 size_t fontId = static_cast<int>( elem.fontId );
1160
1161 if( m_altiumSheet && fontId > 0 && fontId <= m_altiumSheet->fonts.size() )
1162 {
1163 const ASCH_SHEET_FONT& font = m_altiumSheet->fonts.at( fontId - 1 );
1164 textItem->SetItalic( font.Italic );
1165 textItem->SetBold( font.Bold );
1166 textItem->SetTextSize( { font.Size / 2, font.Size / 2 } );
1167 }
1168 }
1169}
1170
1171
1172void SCH_ALTIUM_PLUGIN::ParseTextFrame( const std::map<wxString, wxString>& aProperties )
1173{
1174 ASCH_TEXT_FRAME elem( aProperties );
1175 AddTextBox( &elem );
1176}
1177
1178
1179void SCH_ALTIUM_PLUGIN::ParseNote( const std::map<wxString, wxString>& aProperties )
1180 {
1181 ASCH_NOTE elem( aProperties );
1182 AddTextBox( static_cast<ASCH_TEXT_FRAME*>( &elem ) );
1183
1184 // TODO: need some sort of property system for storing author....
1185}
1186
1187
1189 {
1190 SCH_TEXTBOX* textBox = new SCH_TEXTBOX();
1191
1192 VECTOR2I sheetTopRight = aElem->TopRight + m_sheetOffset;
1193 VECTOR2I sheetBottomLeft = aElem->BottomLeft + m_sheetOffset;
1194 textBox->SetStart( sheetTopRight );
1195 textBox->SetEnd( sheetBottomLeft );
1196
1197 textBox->SetText( aElem->Text );
1198
1199 textBox->SetFillColor( GetColorFromInt( aElem->AreaColor ) );
1200
1201 if( aElem->IsSolid)
1203 else
1204 textBox->SetFilled( false );
1205
1206 if( aElem->ShowBorder )
1208 GetColorFromInt( aElem->BorderColor ) ) );
1209 else
1211 GetColorFromInt( aElem->BorderColor ) ) );
1212
1213 switch( aElem->Alignment )
1214 {
1215 default:
1218 break;
1221 break;
1224 break;
1225 }
1226
1227 // JEY TODO: word-wrap once KiCad supports wrapped text.
1228
1229 size_t fontId = static_cast<int>( aElem->FontID );
1230
1231 if( m_altiumSheet && fontId > 0 && fontId <= m_altiumSheet->fonts.size() )
1232 {
1233 const ASCH_SHEET_FONT& font = m_altiumSheet->fonts.at( fontId - 1 );
1234 textBox->SetItalic( font.Italic );
1235 textBox->SetBold( font.Bold );
1236 textBox->SetTextSize( { font.Size / 2, font.Size / 2 } );
1237 //textBox->SetFont( //how to set font, we have a font mane here: ( font.fontname );
1238 }
1239
1240 textBox->SetFlags( IS_NEW );
1241
1242 SCH_SCREEN* screen = getCurrentScreen();
1243 wxCHECK( screen, /* void */ );
1244
1245 screen->Append( textBox );
1246}
1247
1248
1249void SCH_ALTIUM_PLUGIN::ParseBezier( const std::map<wxString, wxString>& aProperties )
1250{
1251 ASCH_BEZIER elem( aProperties );
1252
1253 if( elem.points.size() < 2 )
1254 {
1255 m_reporter->Report( wxString::Format( _( "Bezier has %d control points. At least 2 are "
1256 "expected." ),
1257 static_cast<int>( elem.points.size() ) ),
1259 return;
1260 }
1261
1262 SCH_SCREEN* screen = getCurrentScreen();
1263 wxCHECK( screen, /* void */ );
1264
1266 {
1267 for( size_t i = 0; i + 1 < elem.points.size(); i += 3 )
1268 {
1269 if( i + 2 == elem.points.size() )
1270 {
1271 // special case: single line
1272 SCH_LINE* line = new SCH_LINE( elem.points.at( i ) + m_sheetOffset,
1274
1275 line->SetEndPoint( elem.points.at( i + 1 ) + m_sheetOffset );
1277
1278 line->SetFlags( IS_NEW );
1279
1280 screen->Append( line );
1281 }
1282 else
1283 {
1284 // simulate Bezier using line segments
1285 std::vector<VECTOR2I> bezierPoints;
1286 std::vector<VECTOR2I> polyPoints;
1287
1288 for( size_t j = i; j < elem.points.size() && j < i + 4; j++ )
1289 bezierPoints.push_back( elem.points.at( j ) );
1290
1291 BEZIER_POLY converter( bezierPoints );
1292 converter.GetPoly( polyPoints );
1293
1294 for( size_t k = 0; k + 1 < polyPoints.size(); k++ )
1295 {
1296 SCH_LINE* line = new SCH_LINE( polyPoints.at( k ) + m_sheetOffset,
1298
1299 line->SetEndPoint( polyPoints.at( k + 1 ) + m_sheetOffset );
1301
1302 line->SetFlags( IS_NEW );
1303 screen->Append( line );
1304 }
1305 }
1306 }
1307 }
1308 else
1309 {
1310 const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex );
1311
1312 if( libSymbolIt == m_libSymbols.end() )
1313 {
1314 // TODO: e.g. can depend on Template (RECORD=39
1315 m_reporter->Report( wxString::Format( wxT( "Bezier's owner (%d) not found." ),
1316 elem.ownerindex ),
1318 return;
1319 }
1320
1322 return;
1323
1324 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
1325
1326 for( size_t i = 0; i + 1 < elem.points.size(); i += 3 )
1327 {
1328 if( i + 2 == elem.points.size() )
1329 {
1330 // special case: single line
1331 LIB_SHAPE* line = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::POLY );
1332 libSymbolIt->second->AddDrawItem( line );
1333
1334 line->SetUnit( std::max( 0, elem.ownerpartid ) );
1335
1336 for( size_t j = i; j < elem.points.size() && j < i + 2; j++ )
1337 {
1338 line->AddPoint( GetRelativePosition( elem.points.at( j ) + m_sheetOffset,
1339 symbol ) );
1340 }
1341
1343 }
1344 else if( i + 3 == elem.points.size() )
1345 {
1346 // TODO: special case of a single line with an extra point?
1347 // I haven't a clue what this is all about, but the sample document we have in
1348 // https://gitlab.com/kicad/code/kicad/-/issues/8974 responds best by treating it
1349 // as another single line special case.
1350 LIB_SHAPE* line = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::POLY );
1351 libSymbolIt->second->AddDrawItem( line );
1352
1353 line->SetUnit( std::max( 0, elem.ownerpartid ) );
1354
1355 for( size_t j = i; j < elem.points.size() && j < i + 2; j++ )
1356 {
1357 line->AddPoint( GetRelativePosition( elem.points.at( j ) + m_sheetOffset,
1358 symbol ) );
1359 }
1360
1362 }
1363 else
1364 {
1365 // Bezier always has exactly 4 control points
1366 LIB_SHAPE* bezier = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::BEZIER );
1367 libSymbolIt->second->AddDrawItem( bezier );
1368
1369 bezier->SetUnit( std::max( 0, elem.ownerpartid ) );
1370
1371 for( size_t j = i; j < elem.points.size() && j < i + 4; j++ )
1372 {
1373 VECTOR2I pos =
1374 GetRelativePosition( elem.points.at( j ) + m_sheetOffset, symbol );
1375
1376 switch( j - i )
1377 {
1378 case 0: bezier->SetStart( pos ); break;
1379 case 1: bezier->SetBezierC1( pos ); break;
1380 case 2: bezier->SetBezierC2( pos ); break;
1381 case 3: bezier->SetEnd( pos ); break;
1382 default: break; // Can't get here but silence warnings
1383 }
1384 }
1385
1387 }
1388 }
1389 }
1390}
1391
1392
1393void SCH_ALTIUM_PLUGIN::ParsePolyline( const std::map<wxString, wxString>& aProperties )
1394{
1395 ASCH_POLYLINE elem( aProperties );
1396
1397 SCH_SCREEN* screen = getCurrentScreen();
1398 wxCHECK( screen, /* void */ );
1399
1401 {
1402 SCH_SHAPE* poly = new SCH_SHAPE( SHAPE_T::POLY );
1403
1404 for( VECTOR2I& point : elem.Points )
1405 poly->AddPoint( point + m_sheetOffset );
1406
1408 GetColorFromInt( elem.Color ) ) );
1409 poly->SetFlags( IS_NEW );
1410
1411 screen->Append( poly );
1412 }
1413 else
1414 {
1415 const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex );
1416
1417 if( libSymbolIt == m_libSymbols.end() )
1418 {
1419 // TODO: e.g. can depend on Template (RECORD=39
1420 m_reporter->Report( wxString::Format( wxT( "Polyline's owner (%d) not found." ),
1421 elem.OwnerIndex ),
1423 return;
1424 }
1425
1427 return;
1428
1429 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
1430 LIB_SHAPE* line = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::POLY );
1431 libSymbolIt->second->AddDrawItem( line );
1432
1433 line->SetUnit( elem.OwnerPartID );
1434
1435 for( VECTOR2I& point : elem.Points )
1436 line->AddPoint( GetRelativePosition( point + m_sheetOffset, symbol ) );
1437
1439 GetColorFromInt( elem.Color ) ) );
1440 }
1441}
1442
1443
1444void SCH_ALTIUM_PLUGIN::ParsePolygon( const std::map<wxString, wxString>& aProperties )
1445{
1446 ASCH_POLYGON elem( aProperties );
1447
1448 SCH_SCREEN* screen = getCurrentScreen();
1449 wxCHECK( screen, /* void */ );
1450
1452 {
1453 SCH_SHAPE* poly = new SCH_SHAPE( SHAPE_T::POLY );
1454
1455 for( VECTOR2I& point : elem.points )
1456 poly->AddPoint( point + m_sheetOffset );
1457 poly->AddPoint( elem.points.front() + m_sheetOffset );
1458
1459 SetSchShapeFillAndColor( elem, poly );
1460 poly->SetFlags( IS_NEW );
1461
1462 screen->Append( poly );
1463 }
1464 else
1465 {
1466 const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex );
1467
1468 if( libSymbolIt == m_libSymbols.end() )
1469 {
1470 // TODO: e.g. can depend on Template (RECORD=39
1471 m_reporter->Report( wxString::Format( wxT( "Polygon's owner (%d) not found." ),
1472 elem.OwnerIndex ),
1474 return;
1475 }
1476
1478 return;
1479
1480 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
1481 LIB_SHAPE* line = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::POLY );
1482 libSymbolIt->second->AddDrawItem( line );
1483
1484 line->SetUnit( elem.OwnerPartID );
1485
1486 for( VECTOR2I& point : elem.points )
1487 line->AddPoint( GetRelativePosition( point + m_sheetOffset, symbol ) );
1488
1489 line->AddPoint( GetRelativePosition( elem.points.front() + m_sheetOffset, symbol ) );
1490 SetLibShapeFillAndColor( elem, line );
1491 }
1492}
1493
1494
1495void SCH_ALTIUM_PLUGIN::ParseRoundRectangle( const std::map<wxString, wxString>& aProperties )
1496{
1497 ASCH_ROUND_RECTANGLE elem( aProperties );
1498
1499 VECTOR2I sheetTopRight = elem.TopRight + m_sheetOffset;
1500 VECTOR2I sheetBottomLeft = elem.BottomLeft + m_sheetOffset;
1501
1502 SCH_SCREEN* screen = getCurrentScreen();
1503 wxCHECK( screen, /* void */ );
1504
1506 {
1507 // TODO: misses rounded edges
1508 SCH_SHAPE* rect = new SCH_SHAPE( SHAPE_T::RECT );
1509
1510 rect->SetPosition( sheetTopRight );
1511 rect->SetEnd( sheetBottomLeft );
1512 SetSchShapeFillAndColor( elem, rect );
1513 rect->SetFlags( IS_NEW );
1514
1515 screen->Append( rect );
1516 }
1517 else
1518 {
1519 const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex );
1520
1521 if( libSymbolIt == m_libSymbols.end() )
1522 {
1523 // TODO: e.g. can depend on Template (RECORD=39
1524 m_reporter->Report( wxString::Format( wxT( "Rounded rectangle's owner (%d) not "
1525 "found." ),
1526 elem.OwnerIndex ),
1528 return;
1529 }
1530
1532 return;
1533
1534 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
1535 // TODO: misses rounded edges
1536 LIB_SHAPE* rect = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::RECT );
1537 libSymbolIt->second->AddDrawItem( rect );
1538
1539 rect->SetUnit( elem.OwnerPartID );
1540
1541 rect->SetPosition( GetRelativePosition( elem.TopRight + m_sheetOffset, symbol ) );
1542 rect->SetEnd( GetRelativePosition( elem.BottomLeft + m_sheetOffset, symbol ) );
1543 SetLibShapeFillAndColor( elem, rect );
1544 }
1545}
1546
1547
1548void SCH_ALTIUM_PLUGIN::ParseArc( const std::map<wxString, wxString>& aProperties )
1549{
1550 // The Arc can be ALTIUM_SCH_RECORD::ELLIPTICAL_ARC or ALTIUM_SCH_RECORD::ARC
1551 // Elliptical arcs are not handled in kicad. So use an arc instead
1552 // TODO: handle elliptical arc better.
1553
1554 ASCH_ARC elem( aProperties );
1555
1556 SCH_SCREEN* screen = getCurrentScreen();
1557 wxCHECK( screen, /* void */ );
1558
1559 int arc_radius = elem.m_Radius;
1560
1561 // Try to approxiammate this ellipse by an arc. use the biggest of radius and secondary radius
1562 // One can of course use another recipe
1563 if( elem.m_IsElliptical )
1564 arc_radius = std::max( elem.m_Radius, elem.m_SecondaryRadius );
1565
1567 {
1568 if( elem.m_StartAngle == 0 && ( elem.m_EndAngle == 0 || elem.m_EndAngle == 360 ) )
1569 {
1570 SCH_SHAPE* circle = new SCH_SHAPE( SHAPE_T::CIRCLE );
1571
1572 circle->SetPosition( elem.m_Center + m_sheetOffset );
1573 circle->SetEnd( circle->GetPosition() + VECTOR2I( arc_radius, 0 ) );
1575
1576 screen->Append( circle );
1577 }
1578 else
1579 {
1580 SCH_SHAPE* arc = new SCH_SHAPE( SHAPE_T::ARC );
1581 EDA_ANGLE includedAngle( elem.m_EndAngle - elem.m_StartAngle, DEGREES_T );
1582 EDA_ANGLE startAngle( elem.m_EndAngle, DEGREES_T );
1583 VECTOR2I startOffset( KiROUND( arc_radius * startAngle.Cos() ),
1584 -KiROUND( arc_radius * startAngle.Sin() ) );
1585
1586 arc->SetCenter( elem.m_Center + m_sheetOffset );
1587 arc->SetStart( elem.m_Center + startOffset + m_sheetOffset );
1588 arc->SetArcAngleAndEnd( includedAngle.Normalize(), true );
1589
1591
1592 screen->Append( arc );
1593 }
1594 }
1595 else
1596 {
1597 const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex );
1598
1599 if( libSymbolIt == m_libSymbols.end() )
1600 {
1601 // TODO: e.g. can depend on Template (RECORD=39
1602 m_reporter->Report( wxString::Format( wxT( "Arc's owner (%d) not found." ),
1603 elem.ownerindex ),
1605 return;
1606 }
1607
1609 return;
1610
1611 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
1612
1613 if( elem.m_StartAngle == 0 && ( elem.m_EndAngle == 0 || elem.m_EndAngle == 360 ) )
1614 {
1615 LIB_SHAPE* circle = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::CIRCLE );
1616 libSymbolIt->second->AddDrawItem( circle );
1617
1618 circle->SetUnit( std::max( 0, elem.ownerpartid ) );
1619
1620 circle->SetPosition( GetRelativePosition( elem.m_Center + m_sheetOffset, symbol ) );
1621 circle->SetEnd( circle->GetPosition() + VECTOR2I( arc_radius, 0 ) );
1623 }
1624 else
1625 {
1626 LIB_SHAPE* arc = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::ARC );
1627 libSymbolIt->second->AddDrawItem( arc );
1628 arc->SetUnit( std::max( 0, elem.ownerpartid ) );
1629
1630 arc->SetCenter( GetRelativePosition( elem.m_Center + m_sheetOffset, symbol ) );
1631
1632 VECTOR2I arcStart( arc_radius, 0 );
1633 RotatePoint( arcStart, -EDA_ANGLE( elem.m_StartAngle, DEGREES_T ) );
1634 arcStart += arc->GetCenter();
1635 arc->SetStart( arcStart );
1636
1637 VECTOR2I arcEnd( arc_radius, 0 );
1638 RotatePoint( arcEnd, -EDA_ANGLE( elem.m_EndAngle, DEGREES_T ) );
1639 arcEnd += arc->GetCenter();
1640 arc->SetEnd( arcEnd );
1641
1643 }
1644 }
1645}
1646
1647
1648void SCH_ALTIUM_PLUGIN::ParseEllipse( const std::map<wxString, wxString>& aProperties )
1649{
1650 ASCH_ELLIPSE elem( aProperties );
1651
1652 SCH_SCREEN* screen = getCurrentScreen();
1653 wxCHECK( screen, /* void */ );
1654
1655 // To do: Import true ellipses when KiCad supports them
1656 if( elem.Radius != elem.SecondaryRadius )
1657 {
1658 m_reporter->Report( wxString::Format( _( "Unsupported ellipse was not imported at "
1659 "(X = %d; Y = %d)." ),
1660 ( elem.Center + m_sheetOffset ).x,
1661 ( elem.Center + m_sheetOffset ).y ),
1663 return;
1664 }
1665
1667 {
1668 SCH_SHAPE* circle = new SCH_SHAPE( SHAPE_T::CIRCLE );
1669
1670 circle->SetPosition( elem.Center + m_sheetOffset );
1671 circle->SetEnd( circle->GetPosition() + VECTOR2I( elem.Radius, 0 ) );
1673
1674 circle->SetFillColor( GetColorFromInt( elem.AreaColor ) );
1675
1676 if( elem.IsSolid )
1678 else
1679 circle->SetFilled( false );
1680
1681 screen->Append( circle );
1682 }
1683 else
1684 {
1685 const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex );
1686
1687 if( libSymbolIt == m_libSymbols.end() )
1688 {
1689 // TODO: e.g. can depend on Template (RECORD=39
1690 m_reporter->Report( wxString::Format( wxT( "Ellipse's owner (%d) not found." ),
1691 elem.OwnerIndex ),
1693 return;
1694 }
1695
1696 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
1697
1698 LIB_SHAPE* circle = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::CIRCLE );
1699 libSymbolIt->second->AddDrawItem( circle );
1700
1701 circle->SetUnit( elem.OwnerPartID );
1702
1703 circle->SetPosition( GetRelativePosition( elem.Center + m_sheetOffset, symbol ) );
1704 circle->SetEnd( circle->GetPosition() + VECTOR2I( elem.Radius, 0 ) );
1706
1707 circle->SetFillColor( GetColorFromInt( elem.AreaColor ) );
1708
1709 if( elem.IsSolid )
1711 else
1712 circle->SetFilled( false );
1713 }
1714}
1715
1716
1717void SCH_ALTIUM_PLUGIN::ParseLine( const std::map<wxString, wxString>& aProperties )
1718{
1719 ASCH_LINE elem( aProperties );
1720
1721 SCH_SCREEN* screen = getCurrentScreen();
1722 wxCHECK( screen, /* void */ );
1723
1725 {
1726 // close polygon
1728 line->SetEndPoint( elem.point2 + m_sheetOffset );
1729 line->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) ); // TODO?
1730
1731 line->SetFlags( IS_NEW );
1732 screen->Append( line );
1733 }
1734 else
1735 {
1736 const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex );
1737
1738 if( libSymbolIt == m_libSymbols.end() )
1739 {
1740 // TODO: e.g. can depend on Template (RECORD=39
1741 m_reporter->Report( wxString::Format( wxT( "Line's owner (%d) not found." ),
1742 elem.ownerindex ),
1744 return;
1745 }
1746
1748 return;
1749
1750 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
1751 LIB_SHAPE* line = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::POLY );
1752 libSymbolIt->second->AddDrawItem( line );
1753
1754 line->SetUnit( std::max( 0, elem.ownerpartid ) );
1755
1756 line->AddPoint( GetRelativePosition( elem.point1 + m_sheetOffset, symbol ) );
1757 line->AddPoint( GetRelativePosition( elem.point2 + m_sheetOffset, symbol ) );
1758
1760 }
1761}
1762
1763
1764void SCH_ALTIUM_PLUGIN::ParseSignalHarness( const std::map<wxString, wxString>& aProperties )
1765{
1766 ASCH_SIGNAL_HARNESS elem( aProperties );
1767
1768 SCH_SCREEN* screen = getCurrentScreen();
1769 wxCHECK( screen, /* void */ );
1770
1772 {
1773 SCH_SHAPE* poly = new SCH_SHAPE( SHAPE_T::POLY );
1774
1775 for( VECTOR2I& point : elem.Points )
1776 poly->AddPoint( point + m_sheetOffset );
1777
1779 GetColorFromInt( elem.Color ) ) );
1780 poly->SetFlags( IS_NEW );
1781
1782 screen->Append( poly );
1783 }
1784 else
1785 {
1786 // No clue if this situation can ever exist
1787 m_reporter->Report( wxT( "Signal harness, belonging to the part is not currently "
1788 "supported." ), RPT_SEVERITY_DEBUG );
1789 }
1790}
1791
1792
1793void SCH_ALTIUM_PLUGIN::ParseHarnessConnector( int aIndex, const std::map<wxString,
1794 wxString>& aProperties )
1795{
1796 ASCH_HARNESS_CONNECTOR elem( aProperties );
1797
1798 SCH_SCREEN* currentScreen = getCurrentScreen();
1799 wxCHECK( currentScreen, /* void */ );
1800
1802 {
1804 elem.Size );
1805
1807 sheet->SetBorderColor( GetColorFromInt( elem.Color ) );
1808
1809 currentScreen->Append( sheet );
1810
1811 SCH_SHEET_PATH sheetpath = m_sheetPath;
1812 sheetpath.push_back( sheet );
1813
1814 sheetpath.SetPageNumber( "Harness #" );
1815
1817 m_sheets.insert( { m_harnessEntryParent, sheet } );
1818 }
1819 else
1820 {
1821 // I have no clue if this situation can ever exist
1822 m_reporter->Report( wxT( "Harness connector, belonging to the part is not currently "
1823 "supported." ),
1825 }
1826}
1827
1828
1829void SCH_ALTIUM_PLUGIN::ParseHarnessEntry( const std::map<wxString, wxString>& aProperties )
1830{
1831 ASCH_HARNESS_ENTRY elem( aProperties );
1832
1833 const auto& sheetIt = m_sheets.find( m_harnessEntryParent );
1834
1835 if( sheetIt == m_sheets.end() )
1836 {
1837 m_reporter->Report( wxString::Format( wxT( "Harness entry's parent (%d) not found." ),
1840 return;
1841 }
1842
1843 SCH_SHEET_PIN* sheetPin = new SCH_SHEET_PIN( sheetIt->second );
1844 sheetIt->second->AddPin( sheetPin );
1845
1846 sheetPin->SetText( elem.Name );
1848
1849 VECTOR2I pos = sheetIt->second->GetPosition();
1850 wxSize size = sheetIt->second->GetSize();
1851
1852 switch( elem.Side )
1853 {
1854 default:
1856 sheetPin->SetPosition( { pos.x, pos.y + elem.DistanceFromTop } );
1858 sheetPin->SetSide( SHEET_SIDE::LEFT );
1859 break;
1861 sheetPin->SetPosition( { pos.x + size.x, pos.y + elem.DistanceFromTop } );
1863 sheetPin->SetSide( SHEET_SIDE::RIGHT );
1864 break;
1866 sheetPin->SetPosition( { pos.x + elem.DistanceFromTop, pos.y } );
1868 sheetPin->SetSide( SHEET_SIDE::TOP );
1869 break;
1871 sheetPin->SetPosition( { pos.x + elem.DistanceFromTop, pos.y + size.y } );
1873 sheetPin->SetSide( SHEET_SIDE::BOTTOM );
1874 break;
1875 }
1876}
1877
1878
1879void SCH_ALTIUM_PLUGIN::ParseHarnessType( const std::map<wxString, wxString>& aProperties )
1880{
1881 ASCH_HARNESS_TYPE elem( aProperties );
1882
1883 const auto& sheetIt = m_sheets.find( m_harnessEntryParent );
1884
1885 if( sheetIt == m_sheets.end() )
1886 {
1887 m_reporter->Report( wxString::Format( wxT( "Harness type's parent (%d) not found." ),
1890 return;
1891 }
1892
1893 SCH_FIELD& sheetNameField = sheetIt->second->GetFields()[SHEETNAME];
1894
1895 sheetNameField.SetPosition( elem.Location + m_sheetOffset );
1896 sheetNameField.SetText( elem.Text );
1897
1898 // Always set as visible so user is aware about ( !elem.isHidden );
1899 sheetNameField.SetVisible( true );
1902 sheetNameField.SetTextColor( GetColorFromInt( elem.Color ) );
1903
1904 m_reporter->Report( wxString::Format( _( "Altium's harness connector (%s) was imported as a "
1905 "hierarchical sheet. Please review the imported "
1906 "schematic." ),
1907 elem.Text ),
1909}
1910
1911
1912void SCH_ALTIUM_PLUGIN::ParseRectangle( const std::map<wxString, wxString>& aProperties )
1913{
1914 ASCH_RECTANGLE elem( aProperties );
1915
1916 VECTOR2I sheetTopRight = elem.TopRight + m_sheetOffset;
1917 VECTOR2I sheetBottomLeft = elem.BottomLeft + m_sheetOffset;
1918
1919 SCH_SCREEN* screen = getCurrentScreen();
1920 wxCHECK( screen, /* void */ );
1921
1923 {
1924 SCH_SHAPE* rect = new SCH_SHAPE( SHAPE_T::RECT );
1925
1926 rect->SetPosition( sheetTopRight );
1927 rect->SetEnd( sheetBottomLeft );
1928 SetSchShapeFillAndColor( elem, rect );
1929 rect->SetFlags( IS_NEW );
1930
1931 screen->Append( rect );
1932 }
1933 else
1934 {
1935 const auto& libSymbolIt = m_libSymbols.find( elem.OwnerIndex );
1936
1937 if( libSymbolIt == m_libSymbols.end() )
1938 {
1939 // TODO: e.g. can depend on Template (RECORD=39
1940 m_reporter->Report( wxString::Format( wxT( "Rectangle's owner (%d) not found." ),
1941 elem.OwnerIndex ),
1943 return;
1944 }
1945
1947 return;
1948
1949 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
1950 LIB_SHAPE* rect = new LIB_SHAPE( libSymbolIt->second, SHAPE_T::RECT );
1951 libSymbolIt->second->AddDrawItem( rect );
1952
1953 rect->SetUnit( elem.OwnerPartID );
1954
1955 rect->SetPosition( GetRelativePosition( sheetTopRight, symbol ) );
1956 rect->SetEnd( GetRelativePosition( sheetBottomLeft, symbol ) );
1957 SetLibShapeFillAndColor( elem, rect );
1958 }
1959}
1960
1961
1963 const std::map<wxString, wxString>& aProperties )
1964{
1965 ASCH_SHEET_SYMBOL elem( aProperties );
1966
1968 elem.size );
1969
1970 sheet->SetBorderColor( GetColorFromInt( elem.color ) );
1971
1972 if( elem.isSolid )
1974
1975 sheet->SetFlags( IS_NEW );
1976
1977 SCH_SCREEN* currentScreen = getCurrentScreen();
1978 wxCHECK( currentScreen, /* void */ );
1979 currentScreen->Append( sheet );
1980
1981 SCH_SHEET_PATH sheetpath = m_sheetPath;
1982 sheetpath.push_back( sheet );
1983
1984 // We'll update later if we find a pageNumber record for it.
1985 sheetpath.SetPageNumber( "#" );
1986
1987 SCH_SCREEN* rootScreen = m_rootSheet->GetScreen();
1988 wxCHECK( rootScreen, /* void */ );
1989
1990 SCH_SHEET_INSTANCE sheetInstance;
1991
1992 sheetInstance.m_Path = sheetpath.Path();
1993 sheetInstance.m_PageNumber = wxT( "#" );
1994
1995 rootScreen->m_sheetInstances.emplace_back( sheetInstance );
1996 m_sheets.insert( { aIndex, sheet } );
1997}
1998
1999
2000void SCH_ALTIUM_PLUGIN::ParseSheetEntry( const std::map<wxString, wxString>& aProperties )
2001{
2002 ASCH_SHEET_ENTRY elem( aProperties );
2003
2004 const auto& sheetIt = m_sheets.find( elem.ownerindex );
2005
2006 if( sheetIt == m_sheets.end() )
2007 {
2008 m_reporter->Report( wxString::Format( wxT( "Sheet entry's owner (%d) not found." ),
2009 elem.ownerindex ),
2011 return;
2012 }
2013
2014 SCH_SHEET_PIN* sheetPin = new SCH_SHEET_PIN( sheetIt->second );
2015 sheetIt->second->AddPin( sheetPin );
2016
2017 sheetPin->SetText( elem.name );
2019 //sheetPin->SetTextSpinStyle( getSpinStyle( term.OrientAngle, false ) );
2020 //sheetPin->SetPosition( getKiCadPoint( term.Position ) );
2021
2022 VECTOR2I pos = sheetIt->second->GetPosition();
2023 wxSize size = sheetIt->second->GetSize();
2024
2025 switch( elem.side )
2026 {
2027 default:
2029 sheetPin->SetPosition( { pos.x, pos.y + elem.distanceFromTop } );
2031 sheetPin->SetSide( SHEET_SIDE::LEFT );
2032 break;
2033
2035 sheetPin->SetPosition( { pos.x + size.x, pos.y + elem.distanceFromTop } );
2037 sheetPin->SetSide( SHEET_SIDE::RIGHT );
2038 break;
2039
2041 sheetPin->SetPosition( { pos.x + elem.distanceFromTop, pos.y } );
2043 sheetPin->SetSide( SHEET_SIDE::TOP );
2044 break;
2045
2047 sheetPin->SetPosition( { pos.x + elem.distanceFromTop, pos.y + size.y } );
2049 sheetPin->SetSide( SHEET_SIDE::BOTTOM );
2050 break;
2051 }
2052
2053 switch( elem.iotype )
2054 {
2055 default:
2058 break;
2059
2062 break;
2063
2066 break;
2067
2070 break;
2071 }
2072}
2073
2074
2076 REPORTER* aReporter )
2077{
2079 {
2080 LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2081 aKsymbol->AddDrawItem( line1 );
2083 line1->AddPoint( { 0, 0 } );
2084 line1->AddPoint( { 0, schIUScale.MilsToIU( -50 ) } );
2085
2086 if( aStyle == ASCH_POWER_PORT_STYLE::CIRCLE )
2087 {
2088 LIB_SHAPE* circle = new LIB_SHAPE( aKsymbol, SHAPE_T::CIRCLE );
2089 aKsymbol->AddDrawItem( circle );
2091 circle->SetPosition( { schIUScale.MilsToIU( 0 ), schIUScale.MilsToIU( -75 ) } );
2092 circle->SetEnd( circle->GetPosition() + VECTOR2I( schIUScale.MilsToIU( 25 ), 0 ) );
2093 }
2094 else
2095 {
2096 LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2097 aKsymbol->AddDrawItem( line2 );
2099 line2->AddPoint( { schIUScale.MilsToIU( -25 ), schIUScale.MilsToIU( -50 ) } );
2100 line2->AddPoint( { schIUScale.MilsToIU( 25 ), schIUScale.MilsToIU( -50 ) } );
2101 line2->AddPoint( { schIUScale.MilsToIU( 0 ), schIUScale.MilsToIU( -100 ) } );
2102 line2->AddPoint( { schIUScale.MilsToIU( -25 ), schIUScale.MilsToIU( -50 ) } );
2103 }
2104
2105 return { 0, schIUScale.MilsToIU( 150 ) };
2106 }
2107 else if( aStyle == ASCH_POWER_PORT_STYLE::WAVE )
2108 {
2109 LIB_SHAPE* line = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2110 aKsymbol->AddDrawItem( line );
2112 line->AddPoint( { 0, 0 } );
2113 line->AddPoint( { 0, schIUScale.MilsToIU( -72 ) } );
2114
2115 LIB_SHAPE* bezier = new LIB_SHAPE( aKsymbol, SHAPE_T::BEZIER );
2116 aKsymbol->AddDrawItem( bezier );
2118 bezier->AddPoint( { schIUScale.MilsToIU( 30 ), schIUScale.MilsToIU( -50 ) } );
2119 bezier->AddPoint( { schIUScale.MilsToIU( 30 ), schIUScale.MilsToIU( -87 ) } );
2120 bezier->AddPoint( { schIUScale.MilsToIU( -30 ), schIUScale.MilsToIU( -63 ) } );
2121 bezier->AddPoint( { schIUScale.MilsToIU( -30 ), schIUScale.MilsToIU( -100 ) } );
2122
2123 return { 0, schIUScale.MilsToIU( 150 ) };
2124 }
2125 else if( aStyle == ASCH_POWER_PORT_STYLE::POWER_GROUND
2127 || aStyle == ASCH_POWER_PORT_STYLE::EARTH
2129 {
2130 LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2131 aKsymbol->AddDrawItem( line1 );
2133 line1->AddPoint( { 0, 0 } );
2134 line1->AddPoint( { 0, schIUScale.MilsToIU( -100 ) } );
2135
2137 {
2138 LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2139 aKsymbol->AddDrawItem( line2 );
2141 line2->AddPoint( { schIUScale.MilsToIU( -100 ), schIUScale.MilsToIU( -100 ) } );
2142 line2->AddPoint( { schIUScale.MilsToIU( 100 ), schIUScale.MilsToIU( -100 ) } );
2143
2144 LIB_SHAPE* line3 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2145 aKsymbol->AddDrawItem( line3 );
2147 line3->AddPoint( { schIUScale.MilsToIU( -70 ), schIUScale.MilsToIU( -130 ) } );
2148 line3->AddPoint( { schIUScale.MilsToIU( 70 ), schIUScale.MilsToIU( -130 ) } );
2149
2150 LIB_SHAPE* line4 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2151 aKsymbol->AddDrawItem( line4 );
2153 line4->AddPoint( { schIUScale.MilsToIU( -40 ), schIUScale.MilsToIU( -160 ) } );
2154 line4->AddPoint( { schIUScale.MilsToIU( 40 ), schIUScale.MilsToIU( -160 ) } );
2155
2156 LIB_SHAPE* line5 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2157 aKsymbol->AddDrawItem( line5 );
2159 line5->AddPoint( { schIUScale.MilsToIU( -10 ), schIUScale.MilsToIU( -190 ) } );
2160 line5->AddPoint( { schIUScale.MilsToIU( 10 ), schIUScale.MilsToIU( -190 ) } );
2161 }
2162 else if( aStyle == ASCH_POWER_PORT_STYLE::SIGNAL_GROUND )
2163 {
2164 LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2165 aKsymbol->AddDrawItem( line2 );
2167 line2->AddPoint( { schIUScale.MilsToIU( -100 ), schIUScale.MilsToIU( -100 ) } );
2168 line2->AddPoint( { schIUScale.MilsToIU( 100 ), schIUScale.MilsToIU( -100 ) } );
2169 line2->AddPoint( { schIUScale.MilsToIU( 0 ), schIUScale.MilsToIU( -200 ) } );
2170 line2->AddPoint( { schIUScale.MilsToIU( -100 ), schIUScale.MilsToIU( -100 ) } );
2171 }
2172 else if( aStyle == ASCH_POWER_PORT_STYLE::EARTH )
2173 {
2174 LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2175 aKsymbol->AddDrawItem( line2 );
2177 line2->AddPoint( { schIUScale.MilsToIU( -150 ), schIUScale.MilsToIU( -200 ) } );
2178 line2->AddPoint( { schIUScale.MilsToIU( -100 ), schIUScale.MilsToIU( -100 ) } );
2179 line2->AddPoint( { schIUScale.MilsToIU( 100 ), schIUScale.MilsToIU( -100 ) } );
2180 line2->AddPoint( { schIUScale.MilsToIU( 50 ), schIUScale.MilsToIU( -200 ) } );
2181
2182 LIB_SHAPE* line3 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2183 aKsymbol->AddDrawItem( line3 );
2185 line3->AddPoint( { schIUScale.MilsToIU( 0 ), schIUScale.MilsToIU( -100 ) } );
2186 line3->AddPoint( { schIUScale.MilsToIU( -50 ), schIUScale.MilsToIU( -200 ) } );
2187 }
2188 else // ASCH_POWER_PORT_STYLE::GOST_ARROW
2189 {
2190 LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2191 aKsymbol->AddDrawItem( line2 );
2193 line2->AddPoint( { schIUScale.MilsToIU( -25 ), schIUScale.MilsToIU( -50 ) } );
2194 line2->AddPoint( { schIUScale.MilsToIU( 0 ), schIUScale.MilsToIU( -100 ) } );
2195 line2->AddPoint( { schIUScale.MilsToIU( 25 ), schIUScale.MilsToIU( -50 ) } );
2196
2197 return { 0, schIUScale.MilsToIU( 150 ) }; // special case
2198 }
2199
2200 return { 0, schIUScale.MilsToIU( 250 ) };
2201 }
2204 {
2205 LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2206 aKsymbol->AddDrawItem( line1 );
2208 line1->AddPoint( { 0, 0 } );
2209 line1->AddPoint( { 0, schIUScale.MilsToIU( -160 ) } );
2210
2211 LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2212 aKsymbol->AddDrawItem( line2 );
2214 line2->AddPoint( { schIUScale.MilsToIU( -100 ), schIUScale.MilsToIU( -160 ) } );
2215 line2->AddPoint( { schIUScale.MilsToIU( 100 ), schIUScale.MilsToIU( -160 ) } );
2216
2217 LIB_SHAPE* line3 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2218 aKsymbol->AddDrawItem( line3 );
2220 line3->AddPoint( { schIUScale.MilsToIU( -60 ), schIUScale.MilsToIU( -200 ) } );
2221 line3->AddPoint( { schIUScale.MilsToIU( 60 ), schIUScale.MilsToIU( -200 ) } );
2222
2223 LIB_SHAPE* line4 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2224 aKsymbol->AddDrawItem( line4 );
2226 line4->AddPoint( { schIUScale.MilsToIU( -20 ), schIUScale.MilsToIU( -240 ) } );
2227 line4->AddPoint( { schIUScale.MilsToIU( 20 ), schIUScale.MilsToIU( -240 ) } );
2228
2230 return { 0, schIUScale.MilsToIU( 300 ) };
2231
2232 LIB_SHAPE* circle = new LIB_SHAPE( aKsymbol, SHAPE_T::CIRCLE );
2233 aKsymbol->AddDrawItem( circle );
2235 circle->SetPosition( { schIUScale.MilsToIU( 0 ), schIUScale.MilsToIU( -160 ) } );
2236 circle->SetEnd( circle->GetPosition() + VECTOR2I( schIUScale.MilsToIU( 120 ), 0 ) );
2237
2238 return { 0, schIUScale.MilsToIU( 350 ) };
2239 }
2240 else if( aStyle == ASCH_POWER_PORT_STYLE::GOST_BAR )
2241 {
2242 LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2243 aKsymbol->AddDrawItem( line1 );
2245 line1->AddPoint( { 0, 0 } );
2246 line1->AddPoint( { 0, schIUScale.MilsToIU( -200 ) } );
2247
2248 LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2249 aKsymbol->AddDrawItem( line2 );
2251 line2->AddPoint( { schIUScale.MilsToIU( -100 ), schIUScale.MilsToIU( -200 ) } );
2252 line2->AddPoint( { schIUScale.MilsToIU( 100 ), schIUScale.MilsToIU( -200 ) } );
2253
2254 return { 0, schIUScale.MilsToIU( 250 ) };
2255 }
2256 else
2257 {
2258 if( aStyle != ASCH_POWER_PORT_STYLE::BAR )
2259 {
2260 aReporter->Report( _( "Power Port with unknown style imported as 'Bar' type." ),
2262 }
2263
2264 LIB_SHAPE* line1 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2265 aKsymbol->AddDrawItem( line1 );
2267 line1->AddPoint( { 0, 0 } );
2268 line1->AddPoint( { 0, schIUScale.MilsToIU( -100 ) } );
2269
2270 LIB_SHAPE* line2 = new LIB_SHAPE( aKsymbol, SHAPE_T::POLY );
2271 aKsymbol->AddDrawItem( line2 );
2273 line2->AddPoint( { schIUScale.MilsToIU( -50 ), schIUScale.MilsToIU( -100 ) } );
2274 line2->AddPoint( { schIUScale.MilsToIU( 50 ), schIUScale.MilsToIU( -100 ) } );
2275
2276 return { 0, schIUScale.MilsToIU( 150 ) };
2277 }
2278}
2279
2280
2281void SCH_ALTIUM_PLUGIN::ParsePowerPort( const std::map<wxString, wxString>& aProperties )
2282{
2283 ASCH_POWER_PORT elem( aProperties );
2284 LIB_ID libId = AltiumToKiCadLibID( getLibName(), elem.text );
2285 LIB_SYMBOL* libSymbol = nullptr;
2286
2287 const auto& powerSymbolIt = m_powerSymbols.find( elem.text );
2288
2289 if( powerSymbolIt != m_powerSymbols.end() )
2290 {
2291 libSymbol = powerSymbolIt->second; // cache hit
2292 }
2293 else
2294 {
2295 libSymbol = new LIB_SYMBOL( wxEmptyString );
2296 libSymbol->SetPower();
2297 libSymbol->SetName( elem.text );
2298 libSymbol->GetReferenceField().SetText( "#PWR" );
2299 libSymbol->GetValueField().SetText( elem.text );
2300 libSymbol->GetValueField().SetVisible( true );
2301 libSymbol->SetDescription( wxString::Format( _( "Power symbol creates a global "
2302 "label with name '%s'" ), elem.text ) );
2303 libSymbol->SetKeyWords( "power-flag" );
2304 libSymbol->SetLibId( libId );
2305
2306 // generate graphic
2307 LIB_PIN* pin = new LIB_PIN( libSymbol );
2308 libSymbol->AddDrawItem( pin );
2309
2310 pin->SetName( elem.text );
2311 pin->SetPosition( { 0, 0 } );
2312 pin->SetLength( 0 );
2313
2314 // marks the pin as a global label
2316 pin->SetVisible( false );
2317
2318 VECTOR2I valueFieldPos =
2320
2321 libSymbol->GetValueField().SetPosition( valueFieldPos );
2322
2323 // this has to be done after parsing the LIB_SYMBOL!
2324 m_pi->SaveSymbol( getLibFileName().GetFullPath(), libSymbol, m_properties.get() );
2325 m_powerSymbols.insert( { elem.text, libSymbol } );
2326 }
2327
2328 SCH_SCREEN* screen = getCurrentScreen();
2329 wxCHECK( screen, /* void */ );
2330
2331 // each symbol has its own powerSymbolIt for now
2332 SCH_SYMBOL* symbol = new SCH_SYMBOL();
2333 symbol->SetRef( &m_sheetPath, "#PWR?" );
2334 symbol->SetValueFieldText( elem.text );
2335 symbol->SetLibId( libId );
2336 symbol->SetLibSymbol( new LIB_SYMBOL( *libSymbol ) );
2337
2338 SCH_FIELD* valueField = symbol->GetField( VALUE_FIELD );
2339 valueField->SetVisible( elem.showNetName );
2340
2341 // TODO: Why do I need to set this a second time?
2342 valueField->SetPosition( libSymbol->GetValueField().GetPosition() );
2343
2344 symbol->SetPosition( elem.location + m_sheetOffset );
2345
2346 switch( elem.orientation )
2347 {
2350 valueField->SetTextAngle( ANGLE_VERTICAL );
2352 break;
2353
2356 valueField->SetTextAngle( ANGLE_HORIZONTAL );
2358 break;
2359
2362 valueField->SetTextAngle( ANGLE_VERTICAL );
2364 break;
2365
2368 valueField->SetTextAngle( ANGLE_HORIZONTAL );
2370 break;
2371
2372 default:
2373 m_reporter->Report( _( "Pin has unexpected orientation." ), RPT_SEVERITY_WARNING );
2374 break;
2375 }
2376
2377 screen->Append( symbol );
2378}
2379
2380
2382{
2383 SCH_TEXTBOX* textBox = new SCH_TEXTBOX();
2384
2385 textBox->SetText( aElem.Name );
2386 textBox->SetTextColor( GetColorFromInt( aElem.TextColor ) );
2387
2388 int height = aElem.Height;
2389 if( height <= 0 )
2390 height = schIUScale.MilsToIU( 100 ); // chose default 50 grid
2391
2392 textBox->SetStartX( ( aElem.Location + m_sheetOffset ).x );
2393 textBox->SetStartY( ( aElem.Location + m_sheetOffset ).y - ( height / 2 ) );
2394 textBox->SetEndX( ( aElem.Location + m_sheetOffset ).x + ( aElem.Width ) );
2395 textBox->SetEndY( ( aElem.Location + m_sheetOffset ).y + ( height / 2 ) );
2396
2399
2402
2403 switch( aElem.Alignment )
2404 {
2405 default:
2408 break;
2409
2412 break;
2413
2416 break;
2417 }
2418
2419 size_t fontId = static_cast<int>( aElem.FontID );
2420
2421 if( m_altiumSheet && fontId > 0 && fontId <= m_altiumSheet->fonts.size() )
2422 {
2423 const ASCH_SHEET_FONT& font = m_altiumSheet->fonts.at( fontId - 1 );
2424 textBox->SetItalic( font.Italic );
2425 textBox->SetBold( font.Bold );
2426 textBox->SetTextSize( { font.Size / 2, font.Size / 2 } );
2427 //textBox->SetFont( //how to set font, we have a font mane here: ( font.fontname );
2428 }
2429
2430 textBox->SetFlags( IS_NEW );
2431
2432 SCH_SCREEN* screen = getCurrentScreen();
2433 wxCHECK( screen, /* void */ );
2434
2435 screen->Append( textBox );
2436
2437 m_reporter->Report( wxString::Format( _( "Altium's harness port (%s) was imported as "
2438 "a text box. Please review the imported "
2439 "schematic." ),
2440 aElem.Name ),
2442}
2443
2444
2446{
2447 if( !aElem.HarnessType.IsEmpty() )
2448 {
2449 // Parse harness ports after "Additional" compound section is parsed
2450 m_altiumHarnessPortsCurrentSheet.emplace_back( aElem );
2451 return;
2452 }
2453
2454 VECTOR2I start = aElem.Location + m_sheetOffset;
2455 VECTOR2I end = start;
2456
2457 switch( aElem.Style )
2458 {
2459 default:
2464 end.x += aElem.Width;
2465 break;
2466
2471 end.y -= aElem.Width;
2472 break;
2473 }
2474
2475 // Check which connection points exists in the schematic
2476 SCH_SCREEN* screen = getCurrentScreen();
2477 wxCHECK( screen, /* void */ );
2478
2479 bool startIsWireTerminal = screen->IsTerminalPoint( start, LAYER_WIRE );
2480 bool startIsBusTerminal = screen->IsTerminalPoint( start, LAYER_BUS );
2481
2482 bool endIsWireTerminal = screen->IsTerminalPoint( end, LAYER_WIRE );
2483 bool endIsBusTerminal = screen->IsTerminalPoint( end, LAYER_BUS );
2484
2485 // check if any of the points is a terminal point
2486 // TODO: there seems a problem to detect approximated connections towards component pins?
2487 bool connectionFound = startIsWireTerminal
2488 || startIsBusTerminal
2489 || endIsWireTerminal
2490 || endIsBusTerminal;
2491
2492 if( !connectionFound )
2493 {
2494 m_reporter->Report( wxString::Format( _( "Port %s has no connections." ), aElem.Name ),
2496 }
2497
2498 // Select label position. In case both match, we will add a line later.
2499 VECTOR2I position = ( startIsWireTerminal || startIsBusTerminal ) ? start : end;
2500 SCH_LABEL_BASE* label;
2501
2502 // TODO: detect correct label type depending on sheet settings, etc.
2503 #if 1 // Set to 1 to use SCH_HIERLABEL label, 0 to use SCH_GLOBALLABEL
2504 {
2505 label = new SCH_HIERLABEL( position, aElem.Name );
2506 }
2507 #else
2508 label = new SCH_GLOBALLABEL( position, aElem.Name );
2509 #endif
2510
2511 switch( aElem.IOtype )
2512 {
2513 default:
2516 break;
2517
2520 break;
2521
2524 break;
2525
2528 break;
2529 }
2530
2531 switch( aElem.Style )
2532 {
2533 default:
2538 if( ( startIsWireTerminal || startIsBusTerminal ) )
2540 else
2542 break;
2543
2548 if( ( startIsWireTerminal || startIsBusTerminal ) )
2550 else
2552 break;
2553 }
2554
2555 label->AutoplaceFields( screen, false );
2556
2557 // Default "Sheet References" field should be hidden, at least for now
2558 if( label->GetFields().size() > 0 )
2559 label->GetFields()[0].SetVisible( false );
2560
2561 label->SetFlags( IS_NEW );
2562
2563 screen->Append( label );
2564
2565 // This is a hack, for the case both connection points are valid: add a small wire
2566 if( ( startIsWireTerminal && endIsWireTerminal ) )
2567 {
2568 SCH_LINE* wire = new SCH_LINE( start, SCH_LAYER_ID::LAYER_WIRE );
2569 wire->SetEndPoint( end );
2570 wire->SetLineWidth( schIUScale.MilsToIU( 2 ) );
2571 wire->SetFlags( IS_NEW );
2572 screen->Append( wire );
2573 }
2574 else if( startIsBusTerminal && endIsBusTerminal )
2575 {
2576 SCH_LINE* wire = new SCH_LINE( start, SCH_LAYER_ID::LAYER_BUS );
2577 wire->SetEndPoint( end );
2578 wire->SetLineWidth( schIUScale.MilsToIU( 2 ) );
2579 wire->SetFlags( IS_NEW );
2580 screen->Append( wire );
2581 }
2582}
2583
2584
2585void SCH_ALTIUM_PLUGIN::ParseNoERC( const std::map<wxString, wxString>& aProperties )
2586{
2587 ASCH_NO_ERC elem( aProperties );
2588
2589 SCH_SCREEN* screen = getCurrentScreen();
2590 wxCHECK( screen, /* void */ );
2591
2592 if( elem.isActive )
2593 {
2594 SCH_NO_CONNECT* noConnect = new SCH_NO_CONNECT( elem.location + m_sheetOffset );
2595
2596 noConnect->SetFlags( IS_NEW );
2597 screen->Append( noConnect );
2598 }
2599}
2600
2601
2602void SCH_ALTIUM_PLUGIN::ParseNetLabel( const std::map<wxString, wxString>& aProperties )
2603{
2604 ASCH_NET_LABEL elem( aProperties );
2605
2606 SCH_LABEL* label = new SCH_LABEL( elem.location + m_sheetOffset, elem.text );
2607
2608 SCH_SCREEN* screen = getCurrentScreen();
2609 wxCHECK( screen, /* void */ );
2610
2611 switch( elem.orientation )
2612 {
2615 break;
2616
2619 break;
2620
2623 break;
2624
2627 break;
2628
2629 default:
2630 break;
2631 }
2632
2633 label->SetFlags( IS_NEW );
2634 screen->Append( label );
2635}
2636
2637
2638void SCH_ALTIUM_PLUGIN::ParseBus( const std::map<wxString, wxString>& aProperties )
2639{
2640 ASCH_BUS elem( aProperties );
2641
2642 SCH_SCREEN* screen = getCurrentScreen();
2643 wxCHECK( screen, /* void */ );
2644
2645 for( size_t i = 0; i + 1 < elem.points.size(); i++ )
2646 {
2647 SCH_LINE* bus = new SCH_LINE( elem.points.at( i ) + m_sheetOffset,
2649 bus->SetEndPoint( elem.points.at( i + 1 ) + m_sheetOffset );
2650 bus->SetLineWidth( elem.lineWidth );
2651
2652 bus->SetFlags( IS_NEW );
2653 screen->Append( bus );
2654 }
2655}
2656
2657
2658void SCH_ALTIUM_PLUGIN::ParseWire( const std::map<wxString, wxString>& aProperties )
2659{
2660 ASCH_WIRE elem( aProperties );
2661
2662 SCH_SCREEN* screen = getCurrentScreen();
2663 wxCHECK( screen, /* void */ );
2664
2665 for( size_t i = 0; i + 1 < elem.points.size(); i++ )
2666 {
2667 SCH_LINE* wire =
2669 wire->SetEndPoint( elem.points.at( i + 1 ) + m_sheetOffset );
2670 wire->SetLineWidth( elem.lineWidth );
2671
2672 wire->SetFlags( IS_NEW );
2673 screen->Append( wire );
2674 }
2675}
2676
2677
2678void SCH_ALTIUM_PLUGIN::ParseJunction( const std::map<wxString, wxString>& aProperties )
2679{
2680 ASCH_JUNCTION elem( aProperties );
2681
2682 SCH_JUNCTION* junction = new SCH_JUNCTION( elem.location + m_sheetOffset );
2683
2684 SCH_SCREEN* screen = getCurrentScreen();
2685 wxCHECK( screen, /* void */ );
2686
2687 junction->SetFlags( IS_NEW );
2688 screen->Append( junction );
2689}
2690
2691
2692void SCH_ALTIUM_PLUGIN::ParseImage( const std::map<wxString, wxString>& aProperties )
2693{
2694 ASCH_IMAGE elem( aProperties );
2695
2696 VECTOR2I center = ( elem.location + elem.corner ) / 2 + m_sheetOffset;
2697 std::unique_ptr<SCH_BITMAP> bitmap = std::make_unique<SCH_BITMAP>( center );
2698
2699 SCH_SCREEN* screen = getCurrentScreen();
2700 wxCHECK( screen, /* void */ );
2701
2702 if( elem.embedimage )
2703 {
2704 const ASCH_STORAGE_FILE* storageFile = GetFileFromStorage( elem.filename );
2705
2706 if( !storageFile )
2707 {
2708 wxString msg = wxString::Format( _( "Embedded file %s not found in storage." ),
2709 elem.filename );
2711 return;
2712 }
2713
2714 wxString storagePath = wxFileName::CreateTempFileName( "kicad_import_" );
2715
2716 // As wxZlibInputStream is not seekable, we need to write a temporary file
2717 wxMemoryInputStream fileStream( storageFile->data.data(), storageFile->data.size() );
2718 wxZlibInputStream zlibInputStream( fileStream );
2719 wxFFileOutputStream outputStream( storagePath );
2720 outputStream.Write( zlibInputStream );
2721 outputStream.Close();
2722
2723 if( !bitmap->ReadImageFile( storagePath ) )
2724 {
2725 m_reporter->Report( wxString::Format( _( "Error reading image %s." ), storagePath ),
2727 return;
2728 }
2729
2730 // Remove temporary file
2731 wxRemoveFile( storagePath );
2732 }
2733 else
2734 {
2735 if( !wxFileExists( elem.filename ) )
2736 {
2737 m_reporter->Report( wxString::Format( _( "File not found %s." ), elem.filename ),
2739 return;
2740 }
2741
2742 if( !bitmap->ReadImageFile( elem.filename ) )
2743 {
2744 m_reporter->Report( wxString::Format( _( "Error reading image %s." ), elem.filename ),
2746 return;
2747 }
2748 }
2749
2750 // we only support one scale, thus we need to select one in case it does not keep aspect ratio
2751 VECTOR2I currentImageSize = bitmap->GetSize();
2752 VECTOR2I expectedImageSize = elem.location - elem.corner;
2753 double scaleX = std::abs( static_cast<double>( expectedImageSize.x ) / currentImageSize.x );
2754 double scaleY = std::abs( static_cast<double>( expectedImageSize.y ) / currentImageSize.y );
2755 bitmap->SetImageScale( std::min( scaleX, scaleY ) );
2756
2757 bitmap->SetFlags( IS_NEW );
2758 screen->Append( bitmap.release() );
2759}
2760
2761
2762void SCH_ALTIUM_PLUGIN::ParseSheet( const std::map<wxString, wxString>& aProperties )
2763{
2764 m_altiumSheet = std::make_unique<ASCH_SHEET>( aProperties );
2765
2766 SCH_SCREEN* screen = getCurrentScreen();
2767 wxCHECK( screen, /* void */ );
2768
2769 PAGE_INFO pageInfo;
2770
2771 bool isPortrait = m_altiumSheet->sheetOrientation == ASCH_SHEET_WORKSPACEORIENTATION::PORTRAIT;
2772
2773 switch( m_altiumSheet->sheetSize )
2774 {
2775 default:
2776 case ASCH_SHEET_SIZE::A4: pageInfo.SetType( "A4", isPortrait ); break;
2777 case ASCH_SHEET_SIZE::A3: pageInfo.SetType( "A3", isPortrait ); break;
2778 case ASCH_SHEET_SIZE::A2: pageInfo.SetType( "A2", isPortrait ); break;
2779 case ASCH_SHEET_SIZE::A1: pageInfo.SetType( "A1", isPortrait ); break;
2780 case ASCH_SHEET_SIZE::A0: pageInfo.SetType( "A0", isPortrait ); break;
2781 case ASCH_SHEET_SIZE::A: pageInfo.SetType( "A", isPortrait ); break;
2782 case ASCH_SHEET_SIZE::B: pageInfo.SetType( "B", isPortrait ); break;
2783 case ASCH_SHEET_SIZE::C: pageInfo.SetType( "C", isPortrait ); break;
2784 case ASCH_SHEET_SIZE::D: pageInfo.SetType( "D", isPortrait ); break;
2785 case ASCH_SHEET_SIZE::E: pageInfo.SetType( "E", isPortrait ); break;
2786 case ASCH_SHEET_SIZE::LETTER: pageInfo.SetType( "USLetter", isPortrait ); break;
2787 case ASCH_SHEET_SIZE::LEGAL: pageInfo.SetType( "USLegal", isPortrait ); break;
2788 case ASCH_SHEET_SIZE::TABLOID: pageInfo.SetType( "A3", isPortrait ); break;
2789 case ASCH_SHEET_SIZE::ORCAD_A: pageInfo.SetType( "A", isPortrait ); break;
2790 case ASCH_SHEET_SIZE::ORCAD_B: pageInfo.SetType( "B", isPortrait ); break;
2791 case ASCH_SHEET_SIZE::ORCAD_C: pageInfo.SetType( "C", isPortrait ); break;
2792 case ASCH_SHEET_SIZE::ORCAD_D: pageInfo.SetType( "D", isPortrait ); break;
2793 case ASCH_SHEET_SIZE::ORCAD_E: pageInfo.SetType( "E", isPortrait ); break;
2794 }
2795
2796 screen->SetPageSettings( pageInfo );
2797
2798 m_sheetOffset = { 0, pageInfo.GetHeightIU( schIUScale.IU_PER_MILS ) };
2799}
2800
2801
2802void SCH_ALTIUM_PLUGIN::ParseSheetName( const std::map<wxString, wxString>& aProperties )
2803{
2804 ASCH_SHEET_NAME elem( aProperties );
2805
2806 const auto& sheetIt = m_sheets.find( elem.ownerindex );
2807
2808 if( sheetIt == m_sheets.end() )
2809 {
2810 m_reporter->Report( wxString::Format( wxT( "Sheetname's owner (%d) not found." ),
2811 elem.ownerindex ),
2813 return;
2814 }
2815
2816 SCH_FIELD& sheetNameField = sheetIt->second->GetFields()[SHEETNAME];
2817
2818 sheetNameField.SetPosition( elem.location + m_sheetOffset );
2819 sheetNameField.SetText( elem.text );
2820 sheetNameField.SetVisible( !elem.isHidden );
2822}
2823
2824
2825void SCH_ALTIUM_PLUGIN::ParseFileName( const std::map<wxString, wxString>& aProperties )
2826{
2827 ASCH_FILE_NAME elem( aProperties );
2828
2829 const auto& sheetIt = m_sheets.find( elem.ownerindex );
2830
2831 if( sheetIt == m_sheets.end() )
2832 {
2833 m_reporter->Report( wxString::Format( wxT( "Filename's owner (%d) not found." ),
2834 elem.ownerindex ),
2836 return;
2837 }
2838
2839 SCH_FIELD& filenameField = sheetIt->second->GetFields()[SHEETFILENAME];
2840
2841 filenameField.SetPosition( elem.location + m_sheetOffset );
2842
2843 // Keep the filename of the Altium file until after the file is actually loaded.
2844 filenameField.SetText( elem.text );
2845 filenameField.SetVisible( !elem.isHidden );
2847}
2848
2849
2850void SCH_ALTIUM_PLUGIN::ParseDesignator( const std::map<wxString, wxString>& aProperties )
2851{
2852 ASCH_DESIGNATOR elem( aProperties );
2853
2854 const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex );
2855
2856 if( libSymbolIt == m_libSymbols.end() )
2857 {
2858 // TODO: e.g. can depend on Template (RECORD=39
2859 m_reporter->Report( wxString::Format( wxT( "Designator's owner (%d) not found." ),
2860 elem.ownerindex ),
2862 return;
2863 }
2864
2865 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
2866 SCH_SHEET_PATH sheetpath;
2867
2868 SCH_SCREEN* screen = getCurrentScreen();
2869 wxCHECK( screen, /* void */ );
2870
2871 // Graphics symbols have no reference. '#GRAPHIC' allows them to not have footprint associated.
2872 // Note: not all unnamed imported symbols are necessarily graphics.
2873 bool emptyRef = elem.text.IsEmpty();
2874 symbol->SetRef( &m_sheetPath, emptyRef ? "#GRAPHIC" : elem.text );
2875
2876 // I am not sure value and ref should be invisible just because emptyRef is true
2877 // I have examples with this criteria fully incorrect.
2878 bool visible = !emptyRef;
2879
2880 symbol->GetField( VALUE_FIELD )->SetVisible( visible );
2881 symbol->GetField( REFERENCE_FIELD )->SetVisible( visible );
2882
2883 SCH_FIELD* field = symbol->GetField( REFERENCE_FIELD );
2884 field->SetPosition( elem.location + m_sheetOffset );
2885 SetTextPositioning( field, elem.justification, elem.orientation );
2886}
2887
2888
2889void SCH_ALTIUM_PLUGIN::ParseBusEntry( const std::map<wxString, wxString>& aProperties )
2890{
2891 ASCH_BUS_ENTRY elem( aProperties );
2892
2893 SCH_SCREEN* screen = getCurrentScreen();
2894 wxCHECK( screen, /* void */ );
2895
2896 SCH_BUS_WIRE_ENTRY* busWireEntry = new SCH_BUS_WIRE_ENTRY( elem.location + m_sheetOffset );
2897
2898 VECTOR2I vector = elem.corner - elem.location;
2899 busWireEntry->SetSize( { vector.x, vector.y } );
2900
2901 busWireEntry->SetFlags( IS_NEW );
2902 screen->Append( busWireEntry );
2903}
2904
2905
2906void SCH_ALTIUM_PLUGIN::ParseParameter( const std::map<wxString, wxString>& aProperties )
2907{
2908 ASCH_PARAMETER elem( aProperties );
2909
2910 SCH_SCREEN* screen = getCurrentScreen();
2911 wxCHECK( screen, /* void */ );
2912
2913 // TODO: fill in replacements from variant, sheet and project
2914 std::map<wxString, wxString> variableMap = {
2915 { "COMMENT", "VALUE" },
2916 { "VALUE", "ALTIUM_VALUE" },
2917 };
2918
2919 if( elem.ownerindex <= 0 && elem.ownerpartid == ALTIUM_COMPONENT_NONE )
2920 {
2921 // This is some sheet parameter
2922 if( elem.text == "*" )
2923 return; // indicates parameter not set?
2924
2925 wxString paramName = elem.name.Upper();
2926
2927 if( paramName == "SHEETNUMBER" )
2928 {
2930 }
2931 else if( paramName == "TITLE" )
2932 {
2933 m_currentTitleBlock->SetTitle( elem.text );
2934 }
2935 else if( paramName == "REVISION" )
2936 {
2937 m_currentTitleBlock->SetRevision( elem.text );
2938 }
2939 else if( paramName == "DATE" )
2940 {
2941 m_currentTitleBlock->SetDate( elem.text );
2942 }
2943 else if( paramName == "COMPANYNAME" )
2944 {
2945 m_currentTitleBlock->SetCompany( elem.text );
2946 }
2947 else
2948 {
2949 m_schematic->Prj().GetTextVars()[ paramName ] = elem.text;
2950 }
2951 }
2952 else
2953 {
2954 const auto& libSymbolIt = m_libSymbols.find( elem.ownerindex );
2955
2956 if( libSymbolIt == m_libSymbols.end() )
2957 {
2958 // TODO: e.g. can depend on Template (RECORD=39
2959 return;
2960 }
2961
2962 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
2963 SCH_FIELD* field = nullptr;
2964 wxString upperName = elem.name.Upper();
2965
2966 if( upperName == "COMMENT" )
2967 {
2968 field = symbol->GetField( VALUE_FIELD );
2969 }
2970 else
2971 {
2972 int fieldIdx = symbol->GetFieldCount();
2973 wxString fieldName = elem.name.Upper();
2974
2975 if( fieldName.IsEmpty() )
2976 {
2977 int disambiguate = 1;
2978
2979 do
2980 {
2981 fieldName = wxString::Format( "ALTIUM_UNNAMED_%d", disambiguate++ );
2982 } while( !symbol->GetFieldText( fieldName ).IsEmpty() );
2983 }
2984 else if( fieldName == "VALUE" )
2985 {
2986 fieldName = "ALTIUM_VALUE";
2987 }
2988
2989 field = symbol->AddField( SCH_FIELD( VECTOR2I(), fieldIdx, symbol, fieldName ) );
2990 }
2991
2992 wxString kicadText = AltiumSpecialStringsToKiCadVariables( elem.text, variableMap );
2993 field->SetText( kicadText );
2994 field->SetPosition( elem.location + m_sheetOffset );
2995 field->SetVisible( !elem.isHidden );
2996 SetTextPositioning( field, elem.justification, elem.orientation );
2997 }
2998}
2999
3000
3002 const std::map<wxString, wxString>& aProperties )
3003{
3004 ASCH_IMPLEMENTATION_LIST elem( aProperties );
3005
3006 m_altiumImplementationList.emplace( aIndex, elem.ownerindex );
3007}
3008
3009
3010void SCH_ALTIUM_PLUGIN::ParseImplementation( const std::map<wxString, wxString>& aProperties )
3011{
3012 ASCH_IMPLEMENTATION elem( aProperties );
3013
3014 // Only get footprint, currently assigned only
3015 if( ( elem.type == "PCBLIB" ) && ( elem.isCurrent ) )
3016 {
3017 const auto& implementationOwnerIt = m_altiumImplementationList.find( elem.ownerindex );
3018
3019 if( implementationOwnerIt == m_altiumImplementationList.end() )
3020 {
3021 m_reporter->Report( wxString::Format( wxT( "Implementation's owner (%d) not found." ),
3022 elem.ownerindex ),
3024 return;
3025 }
3026
3027 const auto& libSymbolIt = m_libSymbols.find( implementationOwnerIt->second );
3028
3029 if( libSymbolIt == m_libSymbols.end() )
3030 {
3031 m_reporter->Report( wxString::Format( wxT( "Footprint's owner (%d) not found." ),
3032 implementationOwnerIt->second ),
3034 return;
3035 }
3036
3037 LIB_ID fpLibId = AltiumToKiCadLibID( elem.libname, elem.name );
3038 wxArrayString fpFilters;
3039 fpFilters.Add( fpLibId.Format() );
3040
3041 libSymbolIt->second->SetFPFilters( fpFilters ); // TODO: not ideal as we overwrite it
3042
3043 SCH_SYMBOL* symbol = m_symbols.at( libSymbolIt->first );
3044
3045 symbol->SetFootprintFieldText( fpLibId.Format() );
3046 }
3047}
int color
Definition: DXF_plotter.cpp:57
const char * name
Definition: DXF_plotter.cpp:56
ALTIUM_SCH_RECORD
ASCH_RECORD_ORIENTATION
const int ALTIUM_COMPONENT_NONE
ASCH_LABEL_JUSTIFICATION
ASCH_POLYLINE_LINESTYLE
ASCH_POWER_PORT_STYLE
LIB_ID AltiumToKiCadLibID(const wxString &aLibName, const wxString &aLibReference)
wxString AltiumSpecialStringsToKiCadVariables(const wxString &aString, const std::map< wxString, wxString > &aOverrides)
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
const CFB::COMPOUND_FILE_ENTRY * FindStream(const std::vector< std::string > &aStreamPath) const
static int ReadInt(const std::map< wxString, wxString > &aProps, const wxString &aKey, int aDefault)
size_t GetRemainingBytes() const
bool HasParsingError()
std::map< wxString, wxString > ReadProperties()
static wxString ReadString(const std::map< wxString, wxString > &aProps, const wxString &aKey, const wxString &aDefault)
Bezier curves to polygon converter.
Definition: bezier_curves.h:36
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMinSegLen=0, int aMaxSegCount=32)
Convert a Bezier curve to a polygon.
EDA_ANGLE Normalize()
Definition: eda_angle.h:249
double Sin() const
Definition: eda_angle.h:206
double Cos() const
Definition: eda_angle.h:221
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:142
void SetModified()
Definition: eda_item.cpp:64
const KIID m_Uuid
Definition: eda_item.h:494
void SetStartX(int x)
Definition: eda_shape.h:136
void SetBezierC2(const VECTOR2I &aPt)
Definition: eda_shape.h:178
void SetCenter(const VECTOR2I &aCenter)
Definition: eda_shape.cpp:458
void SetEndY(int y)
Definition: eda_shape.h:155
void SetStartY(int y)
Definition: eda_shape.h:130
void SetFilled(bool aFlag)
Definition: eda_shape.h:95
void SetFillColor(const COLOR4D &aColor)
Definition: eda_shape.h:106
void SetEndX(int x)
Definition: eda_shape.h:161
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:124
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:149
void SetBezierC1(const VECTOR2I &aPt)
Definition: eda_shape.h:175
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
Definition: eda_shape.cpp:584
void SetFillMode(FILL_T aFill)
Definition: eda_shape.h:100
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:72
void SetTextColor(const COLOR4D &aColor)
Definition: eda_text.h:197
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:217
void SetBold(bool aBold)
Definition: eda_text.cpp:209
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:347
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:163
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:193
void SetItalic(bool aItalic)
Definition: eda_text.cpp:201
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:240
EE_TYPE OfType(KICAD_T aType) const
Definition: sch_rtree.h:238
Used for text file output.
Definition: richio.h:457
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
COLOR4D & FromCSSRGBA(int aRed, int aGreen, int aBlue, double aAlpha=1.0)
Initialize the color from a RGBA value with 0-255 red/green/blue and 0-1 alpha.
Definition: color4d.cpp:581
Definition: kiid.h:48
VECTOR2I GetPosition() const override
Definition: lib_field.h:161
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
UTF8 Format() const
Definition: lib_id.cpp:117
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Definition: lib_id.cpp:190
void SetPosition(const VECTOR2I &aPosition) override
Definition: lib_item.h:234
void SetUnit(int aUnit)
Definition: lib_item.h:272
void SetStroke(const STROKE_PARAMS &aStroke)
Definition: lib_shape.h:53
void AddPoint(const VECTOR2I &aPosition)
Definition: lib_shape.cpp:501
void SetPosition(const VECTOR2I &aPosition) override
Definition: lib_shape.h:86
VECTOR2I GetCenter() const
Definition: lib_shape.h:88
VECTOR2I GetPosition() const override
Definition: lib_shape.h:85
Define a library symbol object.
Definition: lib_symbol.h:98
LIB_FIELD & GetReferenceField()
Return reference to the reference designator field.
void SetPower()
Definition: lib_symbol.cpp:561
void SetDescription(const wxString &aDescription)
Definition: lib_symbol.h:144
void SetKeyWords(const wxString &aKeyWords)
Definition: lib_symbol.h:157
void AddDrawItem(LIB_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
Definition: lib_symbol.cpp:816
LIB_FIELD & GetValueField()
Return reference to the value field.
void SetLibId(const LIB_ID &aLibId)
Definition: lib_symbol.h:140
virtual void SetName(const wxString &aName)
Definition: lib_symbol.cpp:441
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
Define a symbol library graphical text item.
Definition: lib_text.h:40
Describe the page size and margins of a paper page on which to eventually print or plot.
Definition: page_info.h:54
int GetHeightIU(double aIUScale) const
Gets the page height in IU.
Definition: page_info.h:153
bool SetType(const wxString &aStandardPageDescriptionName, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
Definition: page_info.cpp:120
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:126
virtual const wxString GetProjectName() const
Return the short name of the project.
Definition: project.cpp:132
virtual void SetElem(ELEM_T aIndex, _ELEM *aElem)
Definition: project.cpp:294
virtual std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:82
@ ELEM_SYMBOL_LIB_TABLE
Definition: project.h:210
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:71
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
Holds all the data relating to one schematic.
Definition: schematic.h:61
void SetRoot(SCH_SHEET *aRootSheet)
Initialize the schematic with a new root sheet.
Definition: schematic.cpp:104
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
Definition: schematic.h:107
SCH_SHEET & Root() const
Definition: schematic.h:91
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
Definition: schematic.h:76
std::unique_ptr< ASCH_SHEET > m_altiumSheet
void ParseImplementationList(int aIndex, const std::map< wxString, wxString > &aProperties)
std::vector< ASCH_PORT > m_altiumHarnessPortsCurrentSheet
void ParseStorage(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
std::map< int, int > m_altiumImplementationList
void AddTextBox(const ASCH_TEXT_FRAME *aElem)
void ParseSheetEntry(const std::map< wxString, wxString > &aProperties)
const wxString GetName() const override
Return a brief hard coded name for this SCH_PLUGIN.
int GetModifyHash() const override
Return the modification hash from the library cache.
void ParseComponent(int aIndex, const std::map< wxString, wxString > &aProperties)
void ParsePin(const std::map< wxString, wxString > &aProperties)
std::map< wxString, LIB_SYMBOL * > m_powerSymbols
void ParseImplementation(const std::map< wxString, wxString > &aProperties)
wxFileName getLibFileName()
void ParseImage(const std::map< wxString, wxString > &aProperties)
void ParseNetLabel(const std::map< wxString, wxString > &aProperties)
void ParseBezier(const std::map< wxString, wxString > &aProperties)
void ParseBusEntry(const std::map< wxString, wxString > &aProperties)
void ParseSheetName(const std::map< wxString, wxString > &aProperties)
void ParseBus(const std::map< wxString, wxString > &aProperties)
void ParseAdditional(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
void ParseDesignator(const std::map< wxString, wxString > &aProperties)
void ParseSheetSymbol(int aIndex, const std::map< wxString, wxString > &aProperties)
bool IsComponentPartVisible(int aOwnerindex, int aOwnerpartdisplaymode) const
void ParseAltiumSch(const wxString &aFileName)
void ParsePort(const ASCH_PORT &aElem)
void ParsePowerPort(const std::map< wxString, wxString > &aProperties)
void ParseRoundRectangle(const std::map< wxString, wxString > &aProperties)
std::unique_ptr< STRING_UTF8_MAP > m_properties
void ParseWire(const std::map< wxString, wxString > &aProperties)
SCH_SCREEN * getCurrentScreen()
std::vector< ASCH_STORAGE_FILE > m_altiumStorage
std::map< int, LIB_SYMBOL * > m_libSymbols
void ParseSignalHarness(const std::map< wxString, wxString > &aProperties)
void ParseArc(const std::map< wxString, wxString > &aProperties)
std::unique_ptr< TITLE_BLOCK > m_currentTitleBlock
SCH_SHEET_PATH m_sheetPath
void ParseHarnessType(const std::map< wxString, wxString > &aProperties)
const ASCH_STORAGE_FILE * GetFileFromStorage(const wxString &aFilename) const
const wxString GetFileExtension() const override
Return the file extension for the SCH_PLUGIN.
void ParseRectangle(const std::map< wxString, wxString > &aProperties)
SCH_SHEET * getCurrentSheet()
void ParsePolyline(const std::map< wxString, wxString > &aProperties)
void ParseParameter(const std::map< wxString, wxString > &aProperties)
SCH_PLUGIN::SCH_PLUGIN_RELEASER m_pi
void ParseLabel(const std::map< wxString, wxString > &aProperties)
void ParseHarnessConnector(int aIndex, const std::map< wxString, wxString > &aProperties)
std::vector< ASCH_PORT > m_altiumPortsCurrentSheet
void ParseSheet(const std::map< wxString, wxString > &aProperties)
SCH_SHEET * Load(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const STRING_UTF8_MAP *aProperties=nullptr) override
Load information from some input file format that this SCH_PLUGIN implementation knows about,...
void ParseTextFrame(const std::map< wxString, wxString > &aProperties)
void ParseJunction(const std::map< wxString, wxString > &aProperties)
void ParseFileHeader(const ALTIUM_COMPOUND_FILE &aAltiumSchFile)
void ParseNoERC(const std::map< wxString, wxString > &aProperties)
void ParseLine(const std::map< wxString, wxString > &aProperties)
const wxString GetLibraryFileExtension() const override
Return the library file extension for the SCH_PLUGIN object.
void ParsePolygon(const std::map< wxString, wxString > &aProperties)
std::map< int, ASCH_SYMBOL > m_altiumComponents
void ParseNote(const std::map< wxString, wxString > &aProperties)
bool CheckHeader(const wxString &aFileName) override
Return true if the first line in aFileName begins with the expected header.
std::map< int, SCH_SYMBOL * > m_symbols
void ParseHarnessPort(const ASCH_PORT &aElem)
void ParseFileName(const std::map< wxString, wxString > &aProperties)
void ParseEllipse(const std::map< wxString, wxString > &aProperties)
std::map< int, SCH_SHEET * > m_sheets
void ParseHarnessEntry(const std::map< wxString, wxString > &aProperties)
void SetSize(const wxSize &aSize)
Definition: sch_bus_entry.h:72
Class for a wire to bus entry.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:50
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_field.cpp:1050
void SetTextSpinStyle(TEXT_SPIN_STYLE aSpinStyle) override
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_label.cpp:1536
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
void SetShape(LABEL_FLAG_SHAPE aShape) override
Definition: sch_label.h:74
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_label.cpp:376
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:90
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
void SetLineWidth(const int aSize)
Definition: sch_line.cpp:285
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: sch_line.h:177
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:144
void set(SCH_PLUGIN *aPlugin)
Definition: sch_io_mgr.h:562
virtual void SaveSymbol(const wxString &aLibraryPath, const LIB_SYMBOL *aSymbol, const STRING_UTF8_MAP *aProperties=nullptr)
Write aSymbol to an existing library located at aLibraryPath.
Definition: sch_plugin.cpp:94
virtual void SaveLibrary(const wxString &aFileName, const STRING_UTF8_MAP *aProperties=nullptr)
Definition: sch_plugin.cpp:45
virtual void CreateSymbolLib(const wxString &aLibraryPath, const STRING_UTF8_MAP *aProperties=nullptr)
Create a new empty symbol library at aLibraryPath.
Definition: sch_plugin.cpp:110
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:608
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
void ClearEditFlags()
std::vector< SCH_SHEET_INSTANCE > m_sheetInstances
Definition: sch_screen.h:586
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: sch_screen.h:157
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: sch_screen.h:132
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
Definition: sch_screen.h:109
const KIID & GetUuid() const
Definition: sch_screen.h:499
bool IsTerminalPoint(const VECTOR2I &aPosition, int aLayer) const
Test if aPosition is a connection point on aLayer.
Definition: sch_screen.cpp:778
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:106
void Append(SCH_ITEM *aItem)
Definition: sch_screen.cpp:141
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_shape.h:78
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: sch_shape.cpp:61
void AddPoint(const VECTOR2I &aPosition)
Definition: sch_shape.cpp:460
VECTOR2I GetPosition() const override
Definition: sch_shape.h:77
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:66
void SetPosition(const VECTOR2I &aPosition) override
void SetSide(SHEET_SIDE aEdge)
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:55
void SetBorderColor(KIGFX::COLOR4D aColor)
Definition: sch_sheet.h:113
void SetFileName(const wxString &aFilename)
Definition: sch_sheet.h:306
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition: sch_sheet.h:300
wxString GetName() const
Definition: sch_sheet.h:101
bool SearchHierarchy(const wxString &aFilename, SCH_SCREEN **aScreen)
Search the existing hierarchy for an instance of screen loaded from aFileName.
Definition: sch_sheet.cpp:707
void SetBackgroundColor(KIGFX::COLOR4D aColor)
Definition: sch_sheet.h:116
void SetName(const wxString &aName)
Definition: sch_sheet.h:102
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:104
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:162
Schematic symbol object.
Definition: sch_symbol.h:80
void SetLibId(const LIB_ID &aName)
Definition: sch_symbol.cpp:276
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_symbol.h:698
int GetFieldCount() const
Return the number of fields in this symbol.
Definition: sch_symbol.h:478
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:767
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:788
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
Definition: sch_symbol.cpp:666
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
void SetFootprintFieldText(const wxString &aFootprint)
Definition: sch_symbol.cpp:782
VECTOR2I GetPosition() const override
Definition: sch_symbol.h:697
TRANSFORM & GetTransform()
Definition: sch_symbol.h:277
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
Definition: sch_symbol.cpp:839
void SetUnit(int aUnit)
Change the unit number to aUnit.
Definition: sch_symbol.cpp:380
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
Definition: sch_symbol.cpp:295
wxString GetFieldText(const wxString &aFieldName) const
Search for a field named aFieldName and returns text associated with this field.
Definition: sch_symbol.cpp:812
virtual void SetTextSpinStyle(TEXT_SPIN_STYLE aSpinStyle)
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_text.cpp:188
A name/value tuple with unique names and optional values.
Simple container to manage line stroke parameters.
Definition: stroke_params.h:88
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_PLUGIN obje...
static const wxString & GetSymbolLibTableFileName()
virtual void Format(OUTPUTFORMATTER *aOutput, int aIndentLevel) const override
Generate the table in s-expression format to aOutput with an indentation level of aIndentLevel.
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:47
TRANSFORM InverseTransform() const
Calculate the Inverse mirror/rotation transform.
Definition: transform.cpp:56
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:41
static REPORTER & GetInstance()
Definition: reporter.cpp:177
#define _(s)
static constexpr EDA_ANGLE & ANGLE_HORIZONTAL
Definition: eda_angle.h:408
@ DEGREES_T
Definition: eda_angle.h:31
static constexpr EDA_ANGLE & ANGLE_VERTICAL
Definition: eda_angle.h:409
#define IS_NEW
New item, just created.
@ FILLED_WITH_COLOR
@ FILLED_WITH_BG_BODYCOLOR
@ FILLED_SHAPE
const std::string KiCadSymbolLibFileExtension
const std::string KiCadSchematicFileExtension
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
@ LAYER_WIRE
Definition: layer_ids.h:344
@ LAYER_NOTES
Definition: layer_ids.h:358
@ LAYER_BUS
Definition: layer_ids.h:345
@ PIN_LEFT
Definition: lib_pin.h:46
@ PIN_RIGHT
Definition: lib_pin.h:45
@ PIN_UP
Definition: lib_pin.h:47
@ PIN_DOWN
Definition: lib_pin.h:48
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:401
@ PT_INPUT
usual pin input: must be connected
@ PT_OUTPUT
usual output
@ PT_TRISTATE
tris state bus pin
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_OPENEMITTER
pin type open emitter
@ PT_OPENCOLLECTOR
pin type open collector
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_DEBUG
@ RPT_SEVERITY_INFO
static COLOR4D GetColorFromInt(int color)
#define HARNESS_PORT_COLOR_DEFAULT_OUTLINE
static PLOT_DASH_TYPE GetPlotDashType(const ASCH_POLYLINE_LINESTYLE linestyle)
static void SetLibShapeFillAndColor(const ASCH_SHAPE_INTERFACE &elem, LIB_SHAPE *shape)
VECTOR2I HelperGeneratePowerPortGraphics(LIB_SYMBOL *aKsymbol, ASCH_POWER_PORT_STYLE aStyle, REPORTER *aReporter)
static const VECTOR2I GetRelativePosition(const VECTOR2I &aPosition, const SCH_SYMBOL *aSymbol)
#define HARNESS_PORT_COLOR_DEFAULT_BACKGROUND
static void SetSchShapeFillAndColor(const ASCH_SHAPE_INTERFACE &elem, SCH_SHAPE *shape)
void SetTextPositioning(EDA_TEXT *text, ASCH_LABEL_JUSTIFICATION justification, ASCH_RECORD_ORIENTATION orientation)
@ SYM_ORIENT_270
@ SYM_ORIENT_180
@ SYM_ORIENT_90
@ SYM_ORIENT_0
@ SHEETNAME
Definition: sch_sheet.h:43
@ SHEETFILENAME
Definition: sch_sheet.h:44
@ L_BIDI
Definition: sch_text.h:99
@ L_UNSPECIFIED
Definition: sch_text.h:101
@ L_OUTPUT
Definition: sch_text.h:98
@ L_INPUT
Definition: sch_text.h:97
PLOT_DASH_TYPE
Dashed line types.
Definition: stroke_params.h:48
int ownerpartdisplaymode
double m_StartAngle
VECTOR2I m_Center
double m_EndAngle
std::vector< VECTOR2I > points
VECTOR2I corner
VECTOR2I location
std::vector< VECTOR2I > points
ASCH_LABEL_JUSTIFICATION justification
ASCH_RECORD_ORIENTATION orientation
ASCH_RECORD_ORIENTATION orientation
int DistanceFromTop
ASCH_SHEET_ENTRY_SIDE Side
wxString Name
VECTOR2I location
wxString filename
ASCH_RECORD_ORIENTATION orientation
VECTOR2I location
ASCH_LABEL_JUSTIFICATION justification
VECTOR2I point1
VECTOR2I point2
int ownerpartdisplaymode
ASCH_RECORD_ORIENTATION orientation
ASCH_RECORD_ORIENTATION orientation
ASCH_LABEL_JUSTIFICATION justification
ASCH_PIN_SYMBOL_INNEREDGE symbolInnerEdge
ASCH_PIN_SYMBOL_OUTEREDGE symbolOuterEdge
VECTOR2I location
int ownerpartdisplaymode
wxString name
wxString designator
ASCH_PIN_ELECTRICAL electrical
ASCH_RECORD_ORIENTATION orientation
std::vector< VECTOR2I > points
ASCH_POLYLINE_LINESTYLE LineStyle
std::vector< VECTOR2I > Points
VECTOR2I Location
ASCH_TEXT_FRAME_ALIGNMENT Alignment
ASCH_PORT_IOTYPE IOtype
wxString HarnessType
ASCH_PORT_STYLE Style
ASCH_POWER_PORT_STYLE style
ASCH_RECORD_ORIENTATION orientation
wxString name
int distanceFromTop
ASCH_SHEET_ENTRY_SIDE side
ASCH_PORT_IOTYPE iotype
int ownerindex
ASCH_RECORD_ORIENTATION orientation
std::vector< VECTOR2I > Points
std::vector< char > data
wxString componentdescription
wxString libreference
ASCH_TEXT_FRAME_ALIGNMENT Alignment
std::vector< VECTOR2I > points
const double IU_PER_MILS
Definition: base_units.h:78
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
A simple container for sheet instance information.
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
GR_TEXT_H_ALIGN_T
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
GR_TEXT_V_ALIGN_T
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
@ SCH_SHEET_T
Definition: typeinfo.h:158
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618
Definition of file extensions used in Kicad.