KiCad PCB EDA Suite
eeschema/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 AUTHORS.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  g_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  g_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  g_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.
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 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.
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:61
void UpdateAllScreenReferences()
Function UpdateAllScreenReferences updates the reference and the m_Multi parameter (part selection) f...
void mapExistingAnnotation(std::map< timestamp_t, wxString > &aMap)
Field Reference of part, i.e. "IC21".
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.
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
Return a pointer to GAL-based canvas of given EDA draw frame.
timestamp_t GetTimeStamp() const
Definition: base_struct.h:213
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.
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 ...
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:101
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:31
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.
const wxString GetFullyQualifiedText() const
Function GetFullyQualifiedText returns the fully qualified field text by allowing for the part suffix...
Definition: sch_field.cpp:75
SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:89
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:742
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.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:498