KiCad PCB EDA Suite
annotate.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, you may find one here:
23  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24  * or you may search the http://www.gnu.org website for the version 2 license,
25  * or you may write to the Free Software Foundation, Inc.,
26  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27  */
28 
29 #include <algorithm>
30 
31 #include <fctsys.h>
32 #include <class_drawpanel.h>
33 #include <confirm.h>
34 #include <reporter.h>
35 #include <sch_edit_frame.h>
36 
37 #include <sch_reference_list.h>
38 #include <class_library.h>
39 
40 
41 void mapExistingAnnotation( std::map<timestamp_t, wxString>& aMap )
42 {
43  SCH_SHEET_LIST sheets( g_RootSheet );
44  SCH_REFERENCE_LIST references;
45 
46  sheets.GetComponents( references );
47 
48  for( size_t i = 0; i < references.GetCount(); i++ )
49  {
50  SCH_COMPONENT* comp = references[ i ].GetComp();
51  wxString ref = comp->GetField( REFERENCE )->GetFullyQualifiedText();
52 
53  if( !ref.Contains( wxT( "?" ) ) )
54  aMap[ comp->GetTimeStamp() ] = ref;
55  }
56 }
57 
58 
59 void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly )
60 {
61  if( aCurrentSheetOnly )
62  {
63  SCH_SCREEN* screen = GetScreen();
64  wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) );
66  }
67  else
68  {
69  SCH_SCREENS ScreenList;
70  ScreenList.ClearAnnotation();
71  }
72 
73  // Update the references for the sheet that is currently being displayed.
75  GetCanvas()->Refresh();
76  OnModify();
77 }
78 
79 
80 void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
81  ANNOTATE_ORDER_T aSortOption,
82  ANNOTATE_OPTION_T aAlgoOption,
83  int aStartNumber,
84  bool aResetAnnotation,
85  bool aRepairTimestamps,
86  bool aLockUnits,
87  REPORTER& aReporter )
88 {
89  SCH_REFERENCE_LIST references;
90 
91  SCH_SCREENS screens;
92 
93  // Build the sheet list.
94  SCH_SHEET_LIST sheets( g_RootSheet );
95 
96  // Map of locked components
97  SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents;
98 
99  // Map of previous annotation for building info messages
100  std::map<timestamp_t, wxString> previousAnnotation;
101 
102  // Test for and replace duplicate time stamps in components and sheets. Duplicate
103  // time stamps can happen with old schematics, schematic conversions, or manual
104  // editing of files.
105  if( aRepairTimestamps )
106  {
107  int count = screens.ReplaceDuplicateTimeStamps();
108 
109  if( count )
110  {
111  wxString msg;
112  msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count );
113  aReporter.ReportTail( msg, REPORTER::RPT_WARNING );
114  }
115  }
116 
117  // If units must be locked, collect all the sets that must be annotated together.
118  if( aLockUnits )
119  {
120  if( aAnnotateSchematic )
121  {
122  sheets.GetMultiUnitComponents( lockedComponents );
123  }
124  else
125  {
126  m_CurrentSheet->GetMultiUnitComponents( lockedComponents );
127  }
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  {
143  sheets.GetComponents( references );
144  }
145  else
146  {
147  m_CurrentSheet->GetComponents( references );
148  }
149 
150  // Break full components reference in name (prefix) and number:
151  // example: IC1 become IC, and 1
152  references.SplitReferences();
153 
154  switch( aSortOption )
155  {
156  default:
157  case SORT_BY_X_POSITION:
158  references.SortByXCoordinate();
159  break;
160 
161  case SORT_BY_Y_POSITION:
162  references.SortByYCoordinate();
163  break;
164  }
165 
166  bool useSheetNum = false;
167  int idStep = 100;
168 
169  switch( aAlgoOption )
170  {
171  default:
172  case INCREMENTAL_BY_REF:
173  break;
174 
175  case SHEET_NUMBER_X_100:
176  useSheetNum = true;
177  break;
178 
179  case SHEET_NUMBER_X_1000:
180  useSheetNum = true;
181  idStep = 1000;
182  break;
183  }
184 
185  // Recalculate and update reference numbers in schematic
186  references.Annotate( useSheetNum, idStep, aStartNumber, lockedComponents );
187  references.UpdateAnnotation();
188 
189  for( size_t i = 0; i < references.GetCount(); i++ )
190  {
191  SCH_COMPONENT* comp = references[ i ].GetComp();
192  wxString prevRef = previousAnnotation[ comp->GetTimeStamp() ];
193  wxString newRef = comp->GetField( REFERENCE )->GetFullyQualifiedText();
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  GetChars( comp->GetField( VALUE )->GetShownText() ),
204  LIB_PART::SubReference( comp->GetUnit(), false ),
205  GetChars( prevRef ),
206  GetChars( newRef ) );
207  else
208  msg.Printf( _( "Updated %s from %s to %s" ),
209  GetChars( comp->GetField( VALUE )->GetShownText() ),
210  GetChars( prevRef ),
211  GetChars( newRef ) );
212  }
213  else
214  {
215  if( comp->GetUnitCount() > 1 )
216  msg.Printf( _( "Annotated %s (unit %s) as %s" ),
217  GetChars( comp->GetField( VALUE )->GetShownText() ),
218  LIB_PART::SubReference( comp->GetUnit(), false ),
219  GetChars( newRef ) );
220  else
221  msg.Printf( _( "Annotated %s as %s" ),
222  GetChars( comp->GetField( VALUE )->GetShownText() ),
223  GetChars( newRef ) );
224  }
225 
226  aReporter.Report( msg, REPORTER::RPT_ACTION );
227  }
228 
229  // Final control (just in case ... ).
230  if( !CheckAnnotate( aReporter, !aAnnotateSchematic ) )
231  aReporter.ReportTail( _( "Annotation complete." ), REPORTER::RPT_ACTION );
232 
233  OnModify();
234 
235  // Update on screen references, that can be modified by previous calculations:
238 
239  m_canvas->Refresh( true );
240 }
241 
242 
243 int SCH_EDIT_FRAME::CheckAnnotate( REPORTER& aReporter, bool aOneSheetOnly )
244 {
245  // build the screen list
246  SCH_SHEET_LIST sheetList( g_RootSheet );
247  SCH_REFERENCE_LIST componentsList;
248 
249  // Build the list of components
250  if( !aOneSheetOnly )
251  sheetList.GetComponents( componentsList );
252  else
253  m_CurrentSheet->GetComponents( componentsList );
254 
255  return componentsList.CheckAnnotation( aReporter );
256 }
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...
Class SCH_SHEET_LIST.
void SortByYCoordinate()
Function sortByYCoordinate sorts the list of references by Y position.
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
Definition: draw_panel.cpp:321
This file is part of the common library.
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:377
ANNOTATE_ORDER_T
Schematic annotation order options.
void OnModify()
Must be called after a schematic change in order to set the "modify" flag of the current screen* and ...
const wxString GetFullyQualifiedText() const
Function GetFullyQualifiedText returns the fully qualified field text by allowing for the part suffix...
Definition: sch_field.cpp:80
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.
Definition: annotate.cpp:80
Annotate incrementally using the first free reference number.
int GetUnitCount() const
Return the number of units per package of the symbol.
Class REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:61
void UpdateAllScreenReferences()
Function UpdateAllScreenReferences updates the reference and the m_Multi parameter (part selection) f...
Field Reference of part, i.e. "IC21".
Class SCH_REFERENCE_LIST is used to create a flattened list of components because in a complex hierar...
virtual wxString GetShownText() const
Returns the string actually shown after processing of the base text.
Definition: eda_text.h:133
SCH_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
SCH_SHEET_PATH * m_CurrentSheet
which sheet we are presently working on.
void UpdateAnnotation()
function UpdateAnnotation Updates the reference components for the schematic project (or the current ...
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:56
SCH_FIELD * GetField(int aFieldNdx) const
Returns a field in this symbol.
void SortByXCoordinate()
Function sortByXCoordinate sorts the list of references by X position.
void DeleteAnnotation(bool aCurrentSheetOnly)
Clear the current component annotation.
Definition: annotate.cpp:59
virtual REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)
Function ReportTail Places the report at the end of the list, for objects that support report orderin...
Definition: reporter.h:109
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.
int GetUnit() const
void mapExistingAnnotation(std::map< timestamp_t, wxString > &aMap)
Definition: annotate.cpp:41
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...
int CheckAnnotate(REPORTER &aReporter, bool aOneSheetOnly)
Check for annotation errors.
Definition: annotate.cpp:243
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 ...
Annotate by Y position from top to bottom.
Annotate using the first free reference number starting at the sheet number * 100.
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:107
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
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)...
size_t i
Definition: json11.cpp:597
Annotate by X position from left to right.
static wxString SubReference(int aUnit, bool aAddSeparator=true)
Annotate using the first free reference number starting at the sheet number * 1000.
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
void ClearAnnotation(SCH_SHEET_PATH *aSheetPath)
Clear the annotation for the components in aSheetPath on the screen.
Definition: sch_screen.cpp:700
int ReplaceDuplicateTimeStamps()
Test all sheet and component objects in the schematic for duplicate time stamps and replaces them as ...
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 ...
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.
#define VALUE
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:503
timestamp_t GetTimeStamp() const
Definition: base_struct.h:204