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.

287 lines
8.1 KiB

18 years ago
18 years ago
18 years ago
18 years ago
11 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 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-2007 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 class_collector.h
  26. * @brief COLLECTOR class definition.
  27. */
  28. #ifndef COLLECTOR_H
  29. #define COLLECTOR_H
  30. #include <vector>
  31. #include <fctsys.h>
  32. #include <base_struct.h> // SEARCH_RESULT
  33. #include <common.h> // GetNewTimeStamp()
  34. class EDA_ITEM;
  35. /**
  36. * Class 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 : public INSPECTOR
  48. {
  49. protected:
  50. /// Which object types to scan
  51. const KICAD_T* m_ScanTypes;
  52. /// A place to hold collected objects without taking ownership of their memory.
  53. std::vector<EDA_ITEM*> m_List;
  54. /// A point to test against, and that was used to make the collection.
  55. wxPoint m_RefPos;
  56. /// A bounding box to test against, and that was used to make the collection.
  57. EDA_RECT m_RefBox;
  58. /// The time at which the collection was made.
  59. time_t m_TimeAtCollection;
  60. public:
  61. COLLECTOR()
  62. {
  63. m_ScanTypes = 0;
  64. m_TimeAtCollection = 0;
  65. }
  66. virtual ~COLLECTOR() {}
  67. /**
  68. * Function IsValidIndex
  69. * tests if \a aIndex is with the limits of the list of collected items.
  70. *
  71. * @param aIndex The index to test.
  72. * @return True if \a aIndex is with the limits of the list of collected items,
  73. * otherwise false.
  74. */
  75. bool IsValidIndex( int aIndex )
  76. {
  77. return ( (unsigned) aIndex < m_List.size() );
  78. }
  79. /**
  80. * Function GetCount
  81. * returns the number of objects in the list
  82. */
  83. int GetCount() const
  84. {
  85. return (int) m_List.size();
  86. }
  87. /**
  88. * Function Empty
  89. * sets the list to empty
  90. */
  91. void Empty()
  92. {
  93. m_List.clear();
  94. }
  95. /**
  96. * Function Append
  97. * adds an item to the end of the list.
  98. * @param item An EDA_ITEM* to add.
  99. */
  100. void Append( EDA_ITEM* item )
  101. {
  102. m_List.push_back( item );
  103. }
  104. /**
  105. * Function Remove
  106. * removes the item at \a aIndex (first position is 0);
  107. * @param aIndex The index into the list.
  108. */
  109. void Remove( int aIndex )
  110. {
  111. m_List.erase( m_List.begin() + aIndex );
  112. }
  113. /**
  114. * Function Remove
  115. * removes the item aItem (if exists in the collector).
  116. * @param aItem the item to be removed.
  117. */
  118. void Remove( const EDA_ITEM* aItem )
  119. {
  120. for( size_t i = 0; i < m_List.size(); i++ )
  121. {
  122. if( m_List[i] == aItem )
  123. {
  124. m_List.erase( m_List.begin() + i);
  125. return;
  126. }
  127. }
  128. }
  129. /**
  130. * Function operator[int]
  131. * is used for read only access and returns the object at \a aIndex.
  132. * @param aIndex The index into the list.
  133. * @return EDA_ITEM* - or something derived from it, or NULL.
  134. */
  135. EDA_ITEM* operator[]( int aIndex ) const
  136. {
  137. if( (unsigned)aIndex < (unsigned)GetCount() ) // (unsigned) excludes aIndex<0 also
  138. return m_List[ aIndex ];
  139. return NULL;
  140. }
  141. /**
  142. * Function BasePtr
  143. * returns the address of the first element in the array. Only call this
  144. * if there is at least one element in the vector m_List, otherwise a
  145. * C++ exception should get thrown.
  146. */
  147. EDA_ITEM* const* BasePtr() const
  148. {
  149. return &m_List[0];
  150. }
  151. /**
  152. * Function HasItem
  153. * tests if \a aItem has already been collected.
  154. *
  155. * @param aItem The EDA_ITEM* to be tested.
  156. * @return True if \a aItem is already collected.
  157. */
  158. bool HasItem( const EDA_ITEM* aItem ) const
  159. {
  160. for( size_t i = 0; i < m_List.size(); i++ )
  161. {
  162. if( m_List[i] == aItem )
  163. return true;
  164. }
  165. return false;
  166. }
  167. /**
  168. * Function SetScanTypes
  169. * records the list of KICAD_T types to consider for collection by
  170. * the Inspect() function.
  171. * @param scanTypes An array of KICAD_T, terminated by EOT. No copy is
  172. * is made of this array (so cannot come from caller's stack).
  173. */
  174. void SetScanTypes( const KICAD_T* scanTypes )
  175. {
  176. m_ScanTypes = scanTypes;
  177. }
  178. void SetTimeNow()
  179. {
  180. m_TimeAtCollection = GetNewTimeStamp();
  181. }
  182. time_t GetTime()
  183. {
  184. return m_TimeAtCollection;
  185. }
  186. void SetRefPos( const wxPoint& aRefPos ) { m_RefPos = aRefPos; }
  187. const wxPoint& GetRefPos() const { return m_RefPos; }
  188. void SetBoundingBox( const EDA_RECT& aRefBox ) { m_RefBox = aRefBox; }
  189. const EDA_RECT& GetBoundingBox() const { return m_RefBox; }
  190. /**
  191. * Function IsSimilarPointAndTime
  192. * returns true if the given reference point is "similar" (defined here)
  193. * to the internal reference point and the current time is within a few
  194. * seconds of the internal m_TimeAtCollection.
  195. *
  196. * @param aRefPos A wxPoint to compare to.
  197. * @return bool - true if the point and time are similar, else false.
  198. */
  199. bool IsSimilarPointAndTime( const wxPoint& aRefPos )
  200. {
  201. const int distMax = 2; // adjust these here
  202. const time_t timeMax = 3; // seconds
  203. int dx = abs( aRefPos.x - m_RefPos.x );
  204. int dy = abs( aRefPos.y - m_RefPos.y );
  205. if( dx <= distMax && dy <= distMax &&
  206. (int)GetNewTimeStamp() - m_TimeAtCollection <= timeMax )
  207. return true;
  208. else
  209. return false;
  210. }
  211. /**
  212. * Function CountType
  213. * counts the number of items matching aType
  214. * @param aType type we are interested in
  215. * @return number of occurences
  216. */
  217. int CountType( KICAD_T aType )
  218. {
  219. int cnt = 0;
  220. for( size_t i = 0; i < m_List.size(); i++ )
  221. {
  222. if( m_List[i]->Type() == aType )
  223. cnt++;
  224. }
  225. return cnt;
  226. }
  227. /**
  228. * Function Collect
  229. * scans an EDA_ITEM using this class's Inspector method, which does
  230. * the collection.
  231. * @param container An EDA_ITEM to scan, including those items it contains.
  232. * @param aRefPos A wxPoint to use in hit-testing.
  233. *
  234. * example implementation, in derived class:
  235. *
  236. void Collect( EDA_ITEM* container, const wxPoint& aRefPos )
  237. {
  238. example implementation:
  239. SetRefPos( aRefPos ); // remember where the snapshot was taken from
  240. Empty(); // empty the collection
  241. // visit the board with the INSPECTOR (me).
  242. container->Visit( this, // INSPECTOR* inspector
  243. NULL, // const void* testData,
  244. m_ScanTypes);
  245. SetTimeNow(); // when it was taken
  246. }
  247. */
  248. };
  249. #endif // COLLECTOR_H