You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
7.9 KiB

18 years ago
18 years ago
  1. /**
  2. * @file annotate.cpp
  3. * @brief Component annotation.
  4. */
  5. /*
  6. * This program source code file is part of KiCad, a free EDA CAD application.
  7. *
  8. * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License
  12. * as published by the Free Software Foundation; either version 2
  13. * of the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, you may find one here:
  22. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  23. * or you may search the http://www.gnu.org website for the version 2 license,
  24. * or you may write to the Free Software Foundation, Inc.,
  25. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  26. */
  27. #include <algorithm>
  28. #include <fctsys.h>
  29. #include <sch_draw_panel.h>
  30. #include <confirm.h>
  31. #include <reporter.h>
  32. #include <sch_edit_frame.h>
  33. #include <sch_reference_list.h>
  34. #include <class_library.h>
  35. void mapExistingAnnotation( std::map<timestamp_t, wxString>& aMap )
  36. {
  37. SCH_SHEET_LIST sheets( g_RootSheet );
  38. SCH_REFERENCE_LIST references;
  39. sheets.GetComponents( references );
  40. for( size_t i = 0; i < references.GetCount(); i++ )
  41. {
  42. SCH_COMPONENT* comp = references[ i ].GetComp();
  43. wxString ref = comp->GetField( REFERENCE )->GetFullyQualifiedText();
  44. if( !ref.Contains( wxT( "?" ) ) )
  45. aMap[ comp->GetTimeStamp() ] = ref;
  46. }
  47. }
  48. void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly )
  49. {
  50. if( aCurrentSheetOnly )
  51. {
  52. SCH_SCREEN* screen = GetScreen();
  53. wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) );
  54. screen->ClearAnnotation( m_CurrentSheet );
  55. }
  56. else
  57. {
  58. SCH_SCREENS ScreenList;
  59. ScreenList.ClearAnnotation();
  60. }
  61. // Update the references for the sheet that is currently being displayed.
  62. m_CurrentSheet->UpdateAllScreenReferences();
  63. SyncView();
  64. GetCanvas()->Refresh();
  65. OnModify();
  66. }
  67. void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
  68. ANNOTATE_ORDER_T aSortOption,
  69. ANNOTATE_OPTION_T aAlgoOption,
  70. int aStartNumber,
  71. bool aResetAnnotation,
  72. bool aRepairTimestamps,
  73. bool aLockUnits,
  74. REPORTER& aReporter )
  75. {
  76. SCH_REFERENCE_LIST references;
  77. SCH_SCREENS screens;
  78. // Build the sheet list.
  79. SCH_SHEET_LIST sheets( g_RootSheet );
  80. // Map of locked components
  81. SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents;
  82. // Map of previous annotation for building info messages
  83. std::map<timestamp_t, wxString> previousAnnotation;
  84. // Test for and replace duplicate time stamps in components and sheets. Duplicate
  85. // time stamps can happen with old schematics, schematic conversions, or manual
  86. // editing of files.
  87. if( aRepairTimestamps )
  88. {
  89. int count = screens.ReplaceDuplicateTimeStamps();
  90. if( count )
  91. {
  92. wxString msg;
  93. msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count );
  94. aReporter.ReportTail( msg, REPORTER::RPT_WARNING );
  95. }
  96. }
  97. // If units must be locked, collect all the sets that must be annotated together.
  98. if( aLockUnits )
  99. {
  100. if( aAnnotateSchematic )
  101. {
  102. sheets.GetMultiUnitComponents( lockedComponents );
  103. }
  104. else
  105. {
  106. m_CurrentSheet->GetMultiUnitComponents( lockedComponents );
  107. }
  108. }
  109. // Store previous annotations for building info messages
  110. mapExistingAnnotation( previousAnnotation );
  111. // If it is an annotation for all the components, reset previous annotation.
  112. if( aResetAnnotation )
  113. DeleteAnnotation( !aAnnotateSchematic );
  114. // Set sheet number and number of sheets.
  115. SetSheetNumberAndCount();
  116. // Build component list
  117. if( aAnnotateSchematic )
  118. {
  119. sheets.GetComponents( references );
  120. }
  121. else
  122. {
  123. m_CurrentSheet->GetComponents( references );
  124. }
  125. // Break full components reference in name (prefix) and number:
  126. // example: IC1 become IC, and 1
  127. references.SplitReferences();
  128. switch( aSortOption )
  129. {
  130. default:
  131. case SORT_BY_X_POSITION:
  132. references.SortByXCoordinate();
  133. break;
  134. case SORT_BY_Y_POSITION:
  135. references.SortByYCoordinate();
  136. break;
  137. }
  138. bool useSheetNum = false;
  139. int idStep = 100;
  140. switch( aAlgoOption )
  141. {
  142. default:
  143. case INCREMENTAL_BY_REF:
  144. break;
  145. case SHEET_NUMBER_X_100:
  146. useSheetNum = true;
  147. break;
  148. case SHEET_NUMBER_X_1000:
  149. useSheetNum = true;
  150. idStep = 1000;
  151. break;
  152. }
  153. // Recalculate and update reference numbers in schematic
  154. references.Annotate( useSheetNum, idStep, aStartNumber, lockedComponents );
  155. references.UpdateAnnotation();
  156. for( size_t i = 0; i < references.GetCount(); i++ )
  157. {
  158. SCH_COMPONENT* comp = references[ i ].GetComp();
  159. wxString prevRef = previousAnnotation[ comp->GetTimeStamp() ];
  160. wxString newRef = comp->GetField( REFERENCE )->GetFullyQualifiedText();
  161. wxString msg;
  162. if( prevRef.Length() )
  163. {
  164. if( newRef == prevRef )
  165. continue;
  166. if( comp->GetUnitCount() > 1 )
  167. msg.Printf( _( "Updated %s (unit %s) from %s to %s" ),
  168. GetChars( comp->GetField( VALUE )->GetShownText() ),
  169. LIB_PART::SubReference( comp->GetUnit(), false ),
  170. GetChars( prevRef ),
  171. GetChars( newRef ) );
  172. else
  173. msg.Printf( _( "Updated %s from %s to %s" ),
  174. GetChars( comp->GetField( VALUE )->GetShownText() ),
  175. GetChars( prevRef ),
  176. GetChars( newRef ) );
  177. }
  178. else
  179. {
  180. if( comp->GetUnitCount() > 1 )
  181. msg.Printf( _( "Annotated %s (unit %s) as %s" ),
  182. GetChars( comp->GetField( VALUE )->GetShownText() ),
  183. LIB_PART::SubReference( comp->GetUnit(), false ),
  184. GetChars( newRef ) );
  185. else
  186. msg.Printf( _( "Annotated %s as %s" ),
  187. GetChars( comp->GetField( VALUE )->GetShownText() ),
  188. GetChars( newRef ) );
  189. }
  190. aReporter.Report( msg, REPORTER::RPT_ACTION );
  191. }
  192. // Final control (just in case ... ).
  193. if( !CheckAnnotate( aReporter, !aAnnotateSchematic ) )
  194. aReporter.ReportTail( _( "Annotation complete." ), REPORTER::RPT_ACTION );
  195. // Update on screen references, that can be modified by previous calculations:
  196. m_CurrentSheet->UpdateAllScreenReferences();
  197. SetSheetNumberAndCount();
  198. SyncView();
  199. GetCanvas()->Refresh();
  200. OnModify();
  201. }
  202. int SCH_EDIT_FRAME::CheckAnnotate( REPORTER& aReporter, bool aOneSheetOnly )
  203. {
  204. // build the screen list
  205. SCH_SHEET_LIST sheetList( g_RootSheet );
  206. SCH_REFERENCE_LIST componentsList;
  207. // Build the list of components
  208. if( !aOneSheetOnly )
  209. sheetList.GetComponents( componentsList );
  210. else
  211. m_CurrentSheet->GetComponents( componentsList );
  212. return componentsList.CheckAnnotation( aReporter );
  213. }