KiCad PCB EDA Suite
eeschema/annotate.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) 2004-2020 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <algorithm>
25 
26 #include <fctsys.h>
27 #include <sch_draw_panel.h>
28 #include <confirm.h>
29 #include <reporter.h>
30 #include <sch_edit_frame.h>
31 
32 #include <sch_reference_list.h>
33 #include <class_library.h>
34 
35 
36 void mapExistingAnnotation( std::map<wxString, wxString>& aMap )
37 {
38  SCH_SHEET_LIST sheets( g_RootSheet );
39  SCH_REFERENCE_LIST references;
40 
41  sheets.GetComponents( references );
42 
43  for( size_t i = 0; i < references.GetCount(); i++ )
44  {
45  SCH_COMPONENT* comp = references[ i ].GetComp();
46  SCH_SHEET_PATH* curr_sheetpath = &references[ i ].GetSheetPath();
47  KIID_PATH curr_full_uuid = curr_sheetpath->Path();
48  curr_full_uuid.push_back( comp->m_Uuid );
49 
50  wxString ref = comp->GetRef( curr_sheetpath );
51 
52  if( comp->GetUnitCount() > 1 )
53  ref << LIB_PART::SubReference( comp->GetUnitSelection( curr_sheetpath ) );
54 
55  if( comp->IsAnnotated( curr_sheetpath ) )
56  aMap[ curr_full_uuid.AsString() ] = ref;
57  }
58 }
59 
60 
61 void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly )
62 {
63  if( aCurrentSheetOnly )
64  {
65  SCH_SCREEN* screen = GetScreen();
66  wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) );
68  }
69  else
70  {
71  SCH_SCREENS ScreenList;
72  ScreenList.ClearAnnotation();
73  }
74 
75  // Update the references for the sheet that is currently being displayed.
77 
78  SyncView();
79  GetCanvas()->Refresh();
80  OnModify();
81 }
82 
83 
84 void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
85  ANNOTATE_ORDER_T aSortOption,
86  ANNOTATE_OPTION_T aAlgoOption,
87  int aStartNumber,
88  bool aResetAnnotation,
89  bool aRepairTimestamps,
90  bool aLockUnits,
91  REPORTER& aReporter )
92 {
93  SCH_REFERENCE_LIST references;
94 
95  SCH_SCREENS screens;
96 
97  // Build the sheet list.
98  SCH_SHEET_LIST sheets( g_RootSheet );
99 
100  // Map of locked components
101  SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents;
102 
103  // Map of previous annotation for building info messages
104  std::map<wxString, wxString> previousAnnotation;
105 
106  // Test for and replace duplicate time stamps in components and sheets. Duplicate
107  // time stamps can happen with old schematics, schematic conversions, or manual
108  // editing of files.
109  if( aRepairTimestamps )
110  {
111  int count = screens.ReplaceDuplicateTimeStamps();
112 
113  if( count )
114  {
115  wxString msg;
116  msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count );
117  aReporter.ReportTail( msg, RPT_SEVERITY_WARNING );
118  }
119  }
120 
121  // If units must be locked, collect all the sets that must be annotated together.
122  if( aLockUnits )
123  {
124  if( aAnnotateSchematic )
125  sheets.GetMultiUnitComponents( lockedComponents );
126  else
127  g_CurrentSheet->GetMultiUnitComponents( lockedComponents );
128  }
129 
130  // Store previous annotations for building info messages
131  mapExistingAnnotation( previousAnnotation );
132 
133  // If it is an annotation for all the components, reset previous annotation.
134  if( aResetAnnotation )
135  DeleteAnnotation( !aAnnotateSchematic );
136 
137  // Set sheet number and number of sheets.
139 
140  // Build component list
141  if( aAnnotateSchematic )
142  sheets.GetComponents( references );
143  else
144  g_CurrentSheet->GetComponents( references );
145 
146  // Break full components reference in name (prefix) and number:
147  // example: IC1 become IC, and 1
148  references.SplitReferences();
149 
150  switch( aSortOption )
151  {
152  default:
153  case SORT_BY_X_POSITION: references.SortByXCoordinate(); break;
154  case SORT_BY_Y_POSITION: references.SortByYCoordinate(); break;
155  }
156 
157  bool useSheetNum = false;
158  int idStep = 100;
159 
160  switch( aAlgoOption )
161  {
162  default:
163  case INCREMENTAL_BY_REF:
164  break;
165 
166  case SHEET_NUMBER_X_100:
167  useSheetNum = true;
168  break;
169 
170  case SHEET_NUMBER_X_1000:
171  useSheetNum = true;
172  idStep = 1000;
173  break;
174  }
175 
176  // Recalculate and update reference numbers in schematic
177  references.Annotate( useSheetNum, idStep, aStartNumber, lockedComponents );
178  references.UpdateAnnotation();
179 
180  for( size_t i = 0; i < references.GetCount(); i++ )
181  {
182  SCH_COMPONENT* comp = references[ i ].GetComp();
183  SCH_SHEET_PATH* curr_sheetpath = &references[ i ].GetSheetPath();
184  KIID_PATH curr_full_uuid = curr_sheetpath->Path();
185  curr_full_uuid.push_back( comp->m_Uuid );
186 
187  wxString prevRef = previousAnnotation[ curr_full_uuid.AsString() ];
188 
189  wxString newRef = comp->GetRef( curr_sheetpath );
190 
191  if( comp->GetUnitCount() > 1 )
192  newRef << LIB_PART::SubReference( comp->GetUnitSelection( curr_sheetpath ) );
193 
194  wxString msg;
195 
196  if( prevRef.Length() )
197  {
198  if( newRef == prevRef )
199  continue;
200 
201  if( comp->GetUnitCount() > 1 )
202  msg.Printf( _( "Updated %s (unit %s) from %s to %s" ),
203  comp->GetField( VALUE )->GetShownText(),
204  LIB_PART::SubReference( comp->GetUnit(), false ),
205  prevRef, newRef );
206  else
207  msg.Printf( _( "Updated %s from %s to %s" ),
208  comp->GetField( VALUE )->GetShownText(),
209  prevRef, newRef );
210  }
211  else
212  {
213  if( comp->GetUnitCount() > 1 )
214  msg.Printf( _( "Annotated %s (unit %s) as %s" ),
215  comp->GetField( VALUE )->GetShownText(),
216  LIB_PART::SubReference( comp->GetUnit(), false ),
217  newRef );
218  else
219  msg.Printf( _( "Annotated %s as %s" ),
220  comp->GetField( VALUE )->GetShownText(),
221  newRef );
222  }
223 
224  aReporter.Report( msg, RPT_SEVERITY_ACTION );
225  }
226 
227  // Final control (just in case ... ).
228  if( !CheckAnnotate( aReporter, !aAnnotateSchematic ) )
229  aReporter.ReportTail( _( "Annotation complete." ), RPT_SEVERITY_ACTION );
230 
231  // Update on screen references, that can be modified by previous calculations:
234 
235  SyncView();
236  GetCanvas()->Refresh();
237  OnModify();
238 }
239 
240 
241 int SCH_EDIT_FRAME::CheckAnnotate( REPORTER& aReporter, bool aOneSheetOnly )
242 {
243  // build the screen list
244  SCH_SHEET_LIST sheetList( g_RootSheet );
245  SCH_REFERENCE_LIST componentsList;
246 
247  // Build the list of components
248  if( !aOneSheetOnly )
249  sheetList.GetComponents( componentsList );
250  else
251  g_CurrentSheet->GetComponents( componentsList );
252 
253  // Empty schematic does not need annotation
254  if( componentsList.GetCount() == 0 )
255  return 0;
256 
257  return componentsList.CheckAnnotation( aReporter );
258 }
void GetComponents(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanComponents=false)
Function GetComponents adds a SCH_REFERENCE() object to aReferences for each component in the sheet.
void mapExistingAnnotation(std::map< wxString, wxString > &aMap)
SCH_SHEET_LIST.
void SortByYCoordinate()
Function sortByYCoordinate sorts the list of references by Y position.
This file is part of the common library.
ANNOTATE_ORDER_T
Schematic annotation order options.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
void AnnotateComponents(bool aAnnotateSchematic, ANNOTATE_ORDER_T aSortOption, ANNOTATE_OPTION_T aAlgoOption, int aStartNumber, bool aResetAnnotation, bool aRepairTimestamps, bool aLockUnits, REPORTER &aReporter)
Annotate the components in the schematic that are not currently annotated.
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Function ReportTail Places the report at the end of the list, for objects that support report orderin...
Definition: reporter.h:92
int GetUnitCount() const
Return the number of units per package of the symbol.
Annotate incrementally using the first free reference number.
REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:62
void UpdateAllScreenReferences()
Function UpdateAllScreenReferences updates the reference and the m_Multi parameter (part selection) f...
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
SCH_REFERENCE_LIST is used to create a flattened list of components because in a complex hierarchy,...
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void UpdateAnnotation()
function UpdateAnnotation Updates the reference components for the schematic project (or the current ...
#define VALUE
int GetUnit() const
#define NULL
SCH_SHEET_PATH * g_CurrentSheet
With the new connectivity algorithm, many more places than before want to know what the current sheet...
void SortByXCoordinate()
Function sortByXCoordinate sorts the list of references by X position.
void DeleteAnnotation(bool aCurrentSheetOnly)
Clear the current component annotation.
void SyncView()
Mark all items for refresh.
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
ANNOTATE_OPTION_T
Schematic annotation type options.
void Annotate(bool aUseSheetNum, int aSheetIntervalId, int aStartNumber, SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap)
Function Annotate set the reference designators in the list that have not been annotated.
bool IsAnnotated(const SCH_SHEET_PATH *aSheet)
Checks if the component has a valid annotation (reference) for the given sheet path.
SCH_SHEET_PATH.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false)
Return the reference for the given sheet path.
std::map< wxString, SCH_REFERENCE_LIST > SCH_MULTI_UNIT_REFERENCE_MAP
Type SCH_MULTI_UNIT_REFERENCE_MAP is used to create a map of reference designators for multi-unit par...
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
int CheckAnnotate(REPORTER &aReporter, bool aOneSheetOnly)
Check for annotation errors.
void GetMultiUnitComponents(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols=true)
Function GetMultiUnitComponents adds a SCH_REFERENCE_LIST object to aRefList for each same-reference ...
const KIID m_Uuid
Definition: base_struct.h:169
Annotate by Y position from top to bottom.
Annotate using the first free reference number starting at the sheet number * 100.
void SetSheetNumberAndCount()
Set the m_ScreenNumber and m_NumberOfScreens members for screens.
void ClearAnnotation()
Clear the annotation for all components in the hierarchy.
void SplitReferences()
Function SplitReferences attempts to split all reference designators into a name (U) and number (1).
#define _(s)
Definition: 3d_actions.cpp:33
wxString AsString() const
Definition: common.h:123
Annotate by X position from left to right.
Annotate using the first free reference number starting at the sheet number * 1000.
static wxString SubReference(int aUnit, bool aAddSeparator=true)
SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:99
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear the annotation for the components in aSheetPath on the screen.
Definition: sch_screen.cpp:732
int ReplaceDuplicateTimeStamps()
Test all sheet and component objects in the schematic for duplicate time stamps and replaces them as ...
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
SCH_SHEET * g_RootSheet
void GetMultiUnitComponents(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols=true)
Function GetMultiUnitComponents adds a SCH_REFERENCE_LIST object to aRefList for each same-reference ...
virtual wxString GetShownText() const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:129
Definition for part library class.
void GetComponents(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanComponents=false)
Function GetComponents adds a SCH_REFERENCE() object to aReferences for each component in the list of...
int CheckAnnotation(REPORTER &aReporter)
Function CheckAnnotation check for annotations errors.
unsigned GetCount()
Function GetCount.
int GetUnitSelection(const SCH_SHEET_PATH *aSheet) const
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:491