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 <sch_draw_panel.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 
76  SyncView();
77  GetCanvas()->Refresh();
78  OnModify();
79 }
80 
81 
82 void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
83  ANNOTATE_ORDER_T aSortOption,
84  ANNOTATE_OPTION_T aAlgoOption,
85  int aStartNumber,
86  bool aResetAnnotation,
87  bool aRepairTimestamps,
88  bool aLockUnits,
89  REPORTER& aReporter )
90 {
91  SCH_REFERENCE_LIST references;
92 
93  SCH_SCREENS screens;
94 
95  // Build the sheet list.
96  SCH_SHEET_LIST sheets( g_RootSheet );
97 
98  // Map of locked components
99  SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents;
100 
101  // Map of previous annotation for building info messages
102  std::map<timestamp_t, wxString> previousAnnotation;
103 
104  // Test for and replace duplicate time stamps in components and sheets. Duplicate
105  // time stamps can happen with old schematics, schematic conversions, or manual
106  // editing of files.
107  if( aRepairTimestamps )
108  {
109  int count = screens.ReplaceDuplicateTimeStamps();
110 
111  if( count )
112  {
113  wxString msg;
114  msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count );
115  aReporter.ReportTail( msg, REPORTER::RPT_WARNING );
116  }
117  }
118 
119  // If units must be locked, collect all the sets that must be annotated together.
120  if( aLockUnits )
121  {
122  if( aAnnotateSchematic )
123  {
124  sheets.GetMultiUnitComponents( lockedComponents );
125  }
126  else
127  {
128  m_CurrentSheet->GetMultiUnitComponents( lockedComponents );
129  }
130  }
131 
132  // Store previous annotations for building info messages
133  mapExistingAnnotation( previousAnnotation );
134 
135  // If it is an annotation for all the components, reset previous annotation.
136  if( aResetAnnotation )
137  DeleteAnnotation( !aAnnotateSchematic );
138 
139  // Set sheet number and number of sheets.
141 
142  // Build component list
143  if( aAnnotateSchematic )
144  {
145  sheets.GetComponents( references );
146  }
147  else
148  {
149  m_CurrentSheet->GetComponents( references );
150  }
151 
152  // Break full components reference in name (prefix) and number:
153  // example: IC1 become IC, and 1
154  references.SplitReferences();
155 
156  switch( aSortOption )
157  {
158  default:
159  case SORT_BY_X_POSITION:
160  references.SortByXCoordinate();
161  break;
162 
163  case SORT_BY_Y_POSITION:
164  references.SortByYCoordinate();
165  break;
166  }
167 
168  bool useSheetNum = false;
169  int idStep = 100;
170 
171  switch( aAlgoOption )
172  {
173  default:
174  case INCREMENTAL_BY_REF:
175  break;
176 
177  case SHEET_NUMBER_X_100:
178  useSheetNum = true;
179  break;
180 
181  case SHEET_NUMBER_X_1000:
182  useSheetNum = true;
183  idStep = 1000;
184  break;
185  }
186 
187  // Recalculate and update reference numbers in schematic
188  references.Annotate( useSheetNum, idStep, aStartNumber, lockedComponents );
189  references.UpdateAnnotation();
190 
191  for( size_t i = 0; i < references.GetCount(); i++ )
192  {
193  SCH_COMPONENT* comp = references[ i ].GetComp();
194  wxString prevRef = previousAnnotation[ comp->GetTimeStamp() ];
195  wxString newRef = comp->GetField( REFERENCE )->GetFullyQualifiedText();
196  wxString msg;
197 
198  if( prevRef.Length() )
199  {
200  if( newRef == prevRef )
201  continue;
202 
203  if( comp->GetUnitCount() > 1 )
204  msg.Printf( _( "Updated %s (unit %s) from %s to %s" ),
205  GetChars( comp->GetField( VALUE )->GetShownText() ),
206  LIB_PART::SubReference( comp->GetUnit(), false ),
207  GetChars( prevRef ),
208  GetChars( newRef ) );
209  else
210  msg.Printf( _( "Updated %s from %s to %s" ),
211  GetChars( comp->GetField( VALUE )->GetShownText() ),
212  GetChars( prevRef ),
213  GetChars( newRef ) );
214  }
215  else
216  {
217  if( comp->GetUnitCount() > 1 )
218  msg.Printf( _( "Annotated %s (unit %s) as %s" ),
219  GetChars( comp->GetField( VALUE )->GetShownText() ),
220  LIB_PART::SubReference( comp->GetUnit(), false ),
221  GetChars( newRef ) );
222  else
223  msg.Printf( _( "Annotated %s as %s" ),
224  GetChars( comp->GetField( VALUE )->GetShownText() ),
225  GetChars( newRef ) );
226  }
227 
228  aReporter.Report( msg, REPORTER::RPT_ACTION );
229  }
230 
231  // Final control (just in case ... ).
232  if( !CheckAnnotate( aReporter, !aAnnotateSchematic ) )
233  aReporter.ReportTail( _( "Annotation complete." ), REPORTER::RPT_ACTION );
234 
235  // Update on screen references, that can be modified by previous calculations:
238 
239  SyncView();
240  GetCanvas()->Refresh();
241  OnModify();
242 }
243 
244 
245 int SCH_EDIT_FRAME::CheckAnnotate( REPORTER& aReporter, bool aOneSheetOnly )
246 {
247  // build the screen list
248  SCH_SHEET_LIST sheetList( g_RootSheet );
249  SCH_REFERENCE_LIST componentsList;
250 
251  // Build the list of components
252  if( !aOneSheetOnly )
253  sheetList.GetComponents( componentsList );
254  else
255  m_CurrentSheet->GetComponents( componentsList );
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...
Class 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.
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:82
Annotate incrementally using the first free reference number.
int GetUnitCount() const
Return the number of units per package of the symbol.
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...
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:148
SCH_SCREEN * GetScreen() const override
Return 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 ...
#define VALUE
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:111
void SyncView()
Mark all items for refresh.
SCH_DRAW_PANEL * GetCanvas() const override
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:245
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.
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:679
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.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:523
timestamp_t GetTimeStamp() const
Definition: base_struct.h:207