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.

265 lines
7.8 KiB

18 years ago
11 years ago
18 years ago
18 years ago
18 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2004-2020 KiCad Developers, see change_log.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. /**
  25. * @file collector.h
  26. * @brief COLLECTOR class definition.
  27. */
  28. #ifndef COLLECTOR_H
  29. #define COLLECTOR_H
  30. #include <vector>
  31. #include <eda_item.h> // SEARCH_RESULT
  32. #include <common.h> // GetNewTimeStamp()
  33. #include <eda_rect.h>
  34. class EDA_ITEM;
  35. /**
  36. * COLLECTOR
  37. * is an abstract class that will find and hold all the objects according to
  38. * an inspection done by the Inspect() function which must be implemented by
  39. * any derived class. When Inspect() finds an object that it wants to collect,
  40. * i.e. one that it "likes", then it only has to do an Append( testItem )
  41. * on it to add it to its collection, but in all cases for the scan to continue,
  42. * Inspect() must return SEARCH_CONTINUE.
  43. *
  44. * Later, after collection, the user can iterate through all the objects
  45. * in the remembered collection using GetCount() and the [int] operator.
  46. */
  47. class COLLECTOR
  48. {
  49. protected:
  50. std::vector<EDA_ITEM*> m_list; // Primary list of most likely items
  51. std::vector<EDA_ITEM*> m_backupList; // Secondary list with items removed by heuristics
  52. const KICAD_T* m_scanTypes;
  53. INSPECTOR_FUNC m_inspector;
  54. wxPoint m_refPos; // Reference position used to generate the collection.
  55. EDA_RECT m_refBox; // Selection rectangle used to generate the collection.
  56. public:
  57. int m_Threshold; // Hit-test threshold in internal units.
  58. wxString m_MenuTitle; // The title of selection disambiguation menu (if needed)
  59. bool m_MenuCancelled; // Indicates selection disambiguation menu was cancelled
  60. public:
  61. COLLECTOR() :
  62. m_scanTypes( 0 ),
  63. // Inspect() is virtual so calling it from a class common inspector preserves
  64. // polymorphism.
  65. m_inspector( [=]( EDA_ITEM* aItem, void* aTestData )
  66. {
  67. return this->Inspect( aItem, aTestData );
  68. } ),
  69. m_Threshold( 0 ),
  70. m_MenuCancelled( false )
  71. {
  72. }
  73. virtual ~COLLECTOR() {}
  74. virtual SEARCH_RESULT Inspect( EDA_ITEM* aItem, void* aTestData )
  75. {
  76. return SEARCH_RESULT::QUIT;
  77. };
  78. using ITER = std::vector<EDA_ITEM*>::iterator;
  79. using CITER = std::vector<EDA_ITEM*>::const_iterator;
  80. ITER begin() { return m_list.begin(); }
  81. ITER end() { return m_list.end(); }
  82. CITER begin() const { return m_list.cbegin(); }
  83. CITER end() const { return m_list.cend(); }
  84. /**
  85. * Function GetCount
  86. * returns the number of objects in the list
  87. */
  88. int GetCount() const
  89. {
  90. return (int) m_list.size();
  91. }
  92. /**
  93. * Function Empty
  94. * sets the list to empty
  95. */
  96. void Empty()
  97. {
  98. m_list.clear();
  99. }
  100. /**
  101. * Function Append
  102. * adds an item to the end of the list.
  103. * @param item An EDA_ITEM* to add.
  104. */
  105. void Append( EDA_ITEM* item )
  106. {
  107. m_list.push_back( item );
  108. }
  109. /**
  110. * Function Remove
  111. * removes the item at \a aIndex (first position is 0);
  112. * @param aIndex The index into the list.
  113. */
  114. void Remove( int aIndex )
  115. {
  116. m_list.erase( m_list.begin() + aIndex );
  117. }
  118. /**
  119. * Function Remove
  120. * removes the item aItem (if exists in the collector).
  121. * @param aItem the item to be removed.
  122. */
  123. void Remove( const EDA_ITEM* aItem )
  124. {
  125. m_list.erase( std::remove_if( m_list.begin(), m_list.end(),
  126. [&aItem]( const EDA_ITEM* aCandidate )
  127. {
  128. return aCandidate == aItem;
  129. } ),
  130. m_list.end() );
  131. }
  132. /**
  133. * Test if the collector has heuristic backup items
  134. * @return true if Combine() can run to bring secondary items into the list
  135. */
  136. bool HasAdditionalItems()
  137. {
  138. return !m_backupList.empty();
  139. }
  140. /**
  141. * Re-combines the backup list into the main list of the collector
  142. */
  143. void Combine()
  144. {
  145. std::copy( m_backupList.begin(), m_backupList.end(), std::back_inserter( m_list ) );
  146. m_backupList.clear();
  147. }
  148. /**
  149. * Moves the item at \a aIndex (first position is 0) to the backup list
  150. * @param aIndex The index into the list.
  151. */
  152. void Transfer( int aIndex )
  153. {
  154. m_backupList.push_back( m_list[aIndex] );
  155. m_list.erase( m_list.begin() + aIndex );
  156. }
  157. /**
  158. * Moves the item aItem (if exists in the collector) to the backup list
  159. * @param aItem the item to be moved.
  160. */
  161. void Transfer( EDA_ITEM* aItem )
  162. {
  163. for( size_t i = 0; i < m_list.size(); i++ )
  164. {
  165. if( m_list[i] == aItem )
  166. {
  167. m_list.erase( m_list.begin() + i );
  168. m_backupList.push_back( aItem );
  169. return;
  170. }
  171. }
  172. }
  173. /**
  174. * Function operator[int]
  175. * is used for read only access and returns the object at \a aIndex.
  176. * @param aIndex The index into the list.
  177. * @return EDA_ITEM* - or something derived from it, or NULL.
  178. */
  179. virtual EDA_ITEM* operator[]( int aIndex ) const
  180. {
  181. if( (unsigned)aIndex < (unsigned)GetCount() ) // (unsigned) excludes aIndex<0 also
  182. return m_list[ aIndex ];
  183. return NULL;
  184. }
  185. /**
  186. * Function HasItem
  187. * tests if \a aItem has already been collected.
  188. *
  189. * @param aItem The EDA_ITEM* to be tested.
  190. * @return True if \a aItem is already collected.
  191. */
  192. bool HasItem( const EDA_ITEM* aItem ) const
  193. {
  194. for( size_t i = 0; i < m_list.size(); i++ )
  195. {
  196. if( m_list[i] == aItem )
  197. return true;
  198. }
  199. return false;
  200. }
  201. /**
  202. * Function SetScanTypes
  203. * records the list of KICAD_T types to consider for collection by
  204. * the Inspect() function.
  205. * @param scanTypes An array of KICAD_T, terminated by EOT. No copy is
  206. * is made of this array (so cannot come from caller's stack).
  207. */
  208. void SetScanTypes( const KICAD_T* scanTypes )
  209. {
  210. m_scanTypes = scanTypes;
  211. }
  212. void SetRefPos( const wxPoint& aRefPos ) { m_refPos = aRefPos; }
  213. const EDA_RECT& GetBoundingBox() const { return m_refBox; }
  214. /**
  215. * Function CountType
  216. * counts the number of items matching aType
  217. * @param aType type we are interested in
  218. * @return number of occurences
  219. */
  220. int CountType( KICAD_T aType )
  221. {
  222. int cnt = 0;
  223. for( size_t i = 0; i < m_list.size(); i++ )
  224. {
  225. if( m_list[i]->Type() == aType )
  226. cnt++;
  227. }
  228. return cnt;
  229. }
  230. };
  231. #endif // COLLECTOR_H