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.

360 lines
9.4 KiB

  1. /*************************************************************************/
  2. /* listboxes.cpp: class for displaying footprint list and component list */
  3. /*************************************************************************/
  4. #include "fctsys.h"
  5. #include "wxstruct.h"
  6. #include "common.h"
  7. #include "cvpcb.h"
  8. #include "protos.h"
  9. #include "cvstruct.h"
  10. /***************************************/
  11. /* ListBox handling the footprint list */
  12. /***************************************/
  13. FOOTPRINTS_LISTBOX::FOOTPRINTS_LISTBOX( WinEDA_CvpcbFrame* parent,
  14. wxWindowID id, const wxPoint& loc,
  15. const wxSize& size,
  16. int nbitems, wxString choice[] ) :
  17. ITEMS_LISTBOX_BASE( parent, id, loc, size )
  18. {
  19. m_UseFootprintFullList = true;
  20. m_ActiveFootprintList = NULL;
  21. SetActiveFootprintList( TRUE );
  22. }
  23. FOOTPRINTS_LISTBOX::~FOOTPRINTS_LISTBOX()
  24. {
  25. }
  26. /*
  27. * Return number of items
  28. */
  29. int FOOTPRINTS_LISTBOX::GetCount()
  30. {
  31. return m_ActiveFootprintList->Count();
  32. }
  33. /*
  34. * Change an item text
  35. */
  36. void FOOTPRINTS_LISTBOX::SetString( unsigned linecount, const wxString& text )
  37. {
  38. if( linecount >= m_ActiveFootprintList->Count() )
  39. linecount = m_ActiveFootprintList->Count() - 1;
  40. if( linecount >= 0 )
  41. (*m_ActiveFootprintList)[linecount] = text;
  42. }
  43. wxString FOOTPRINTS_LISTBOX::GetSelectedFootprint()
  44. {
  45. wxString FootprintName;
  46. int ii = GetFirstSelected();
  47. if( ii >= 0 )
  48. {
  49. wxString msg = (*m_ActiveFootprintList)[ii];
  50. msg.Trim( TRUE );
  51. msg.Trim( FALSE );
  52. FootprintName = msg.AfterFirst( wxChar( ' ' ) );
  53. }
  54. return FootprintName;
  55. }
  56. void FOOTPRINTS_LISTBOX::AppendLine( const wxString& text )
  57. {
  58. m_ActiveFootprintList->Add( text );
  59. SetItemCount( m_ActiveFootprintList->Count() );
  60. }
  61. /*
  62. * Overlaid function: MUST be provided in wxLC_VIRTUAL mode
  63. * because real data is not handled by ITEMS_LISTBOX_BASE
  64. */
  65. wxString FOOTPRINTS_LISTBOX::OnGetItemText( long item, long column ) const
  66. {
  67. return m_ActiveFootprintList->Item( item );
  68. }
  69. /*
  70. * Enable or disable an item
  71. */
  72. void FOOTPRINTS_LISTBOX::SetSelection( unsigned index, bool State )
  73. {
  74. if( (int) index >= GetCount() )
  75. index = GetCount() - 1;
  76. if( (index >= 0) && (GetCount() > 0) )
  77. {
  78. #ifndef __WXMAC__
  79. Select( index, State );
  80. #endif
  81. EnsureVisible( index );
  82. #ifdef __WXMAC__
  83. Refresh();
  84. #endif
  85. }
  86. }
  87. void FOOTPRINTS_LISTBOX::SetFootprintFullList( FOOTPRINT_LIST& list )
  88. {
  89. wxString msg;
  90. int OldSelection = GetSelection();
  91. m_FullFootprintList.Clear();
  92. BOOST_FOREACH( FOOTPRINT & footprint, list ) {
  93. msg.Printf( wxT( "%3d %s" ), m_FullFootprintList.GetCount() + 1,
  94. footprint.m_Module.GetData() );
  95. m_FullFootprintList.Add( msg );
  96. }
  97. SetActiveFootprintList( TRUE );
  98. if( ( GetCount() == 0 )
  99. || ( OldSelection < 0 ) || ( OldSelection >= GetCount() ) )
  100. SetSelection( 0, TRUE );
  101. Refresh();
  102. }
  103. void FOOTPRINTS_LISTBOX::SetFootprintFilteredList( COMPONENT* Component,
  104. FOOTPRINT_LIST& list )
  105. {
  106. FOOTPRINT_LIST::iterator i;
  107. wxString msg;
  108. unsigned jj;
  109. int OldSelection = GetSelection();
  110. bool HasItem = FALSE;
  111. m_FilteredFootprintList.Clear();
  112. BOOST_FOREACH( FOOTPRINT & footprint, list ) {
  113. /* Search for matching footprints */
  114. for( jj = 0; jj < Component->m_FootprintFilter.GetCount(); jj++ )
  115. {
  116. if( !footprint.m_Module.Matches( Component->m_FootprintFilter[jj] ) )
  117. continue;
  118. msg.Printf( wxT( "%3d %s" ), m_FilteredFootprintList.GetCount() + 1,
  119. footprint.m_Module.GetData() );
  120. m_FilteredFootprintList.Add( msg );
  121. HasItem = TRUE;
  122. }
  123. }
  124. if( HasItem )
  125. SetActiveFootprintList( FALSE );
  126. else
  127. SetActiveFootprintList( TRUE );
  128. if( ( GetCount() == 0 ) || ( OldSelection >= GetCount() ) )
  129. SetSelection( 0, TRUE );
  130. Refresh();
  131. }
  132. /** Set the footprint list. We can have 2 footprint list:
  133. * The full footprint list
  134. * The filtered footprint list (if the current selected component has a
  135. * filter for footprints)
  136. * @param FullList true = full footprint list, false = filtered footprint list
  137. * @param Redraw = true to redraw the window
  138. */
  139. void FOOTPRINTS_LISTBOX::SetActiveFootprintList( bool FullList, bool Redraw )
  140. {
  141. bool old_selection = m_UseFootprintFullList;
  142. #ifdef __WINDOWS__
  143. /* Workaround for a curious bug in wxWidgets:
  144. * if we switch from a long list of footprints to a short list (a
  145. * filtered footprint list), and if the selected item is near the end
  146. * of the long list, the new list is not displayed from the top of
  147. * the list box
  148. */
  149. if( m_ActiveFootprintList )
  150. {
  151. bool new_selection;
  152. if( FullList )
  153. new_selection = TRUE;
  154. else
  155. new_selection = FALSE;
  156. if( new_selection != old_selection )
  157. SetSelection( 0, TRUE );
  158. }
  159. #endif
  160. if( FullList )
  161. {
  162. m_UseFootprintFullList = TRUE;
  163. m_ActiveFootprintList = &m_FullFootprintList;
  164. SetItemCount( m_FullFootprintList.GetCount() );
  165. }
  166. else
  167. {
  168. m_UseFootprintFullList = FALSE;
  169. m_ActiveFootprintList = &m_FilteredFootprintList;
  170. SetItemCount( m_FilteredFootprintList.GetCount() );
  171. }
  172. if( Redraw )
  173. {
  174. if( !m_UseFootprintFullList
  175. || ( m_UseFootprintFullList != old_selection ) )
  176. {
  177. Refresh();
  178. }
  179. }
  180. if( !m_UseFootprintFullList || ( m_UseFootprintFullList != old_selection ) )
  181. {
  182. GetParent()->SetStatusText( wxEmptyString, 0 );
  183. GetParent()->SetStatusText( wxEmptyString, 1 );
  184. }
  185. wxString msg;
  186. if( FullList )
  187. msg.Printf( _( "Footprints (All): %d" ),
  188. m_ActiveFootprintList->GetCount() );
  189. else
  190. msg.Printf( _( "Footprints (filtered): %d" ),
  191. m_ActiveFootprintList->GetCount() );
  192. GetParent()->SetStatusText( msg, 2 );
  193. }
  194. /**************************************/
  195. /* Event table for the footprint list */
  196. /**************************************/
  197. BEGIN_EVENT_TABLE( FOOTPRINTS_LISTBOX, ITEMS_LISTBOX_BASE )
  198. EVT_SIZE( ITEMS_LISTBOX_BASE::OnSize )
  199. EVT_CHAR( FOOTPRINTS_LISTBOX::OnChar )
  200. END_EVENT_TABLE()
  201. /********************************************************/
  202. void FOOTPRINTS_LISTBOX::OnLeftClick( wxListEvent& event )
  203. /********************************************************/
  204. {
  205. FOOTPRINT* Module;
  206. wxString FootprintName = GetSelectedFootprint();
  207. Module = GetModuleDescrByName( FootprintName, GetParent()->m_footprints );
  208. if( GetParent()->DrawFrame )
  209. {
  210. GetParent()->CreateScreenCmp(); /* refresh general */
  211. }
  212. if( Module )
  213. {
  214. wxString msg;
  215. msg = Module->m_Doc;
  216. GetParent()->SetStatusText( msg, 0 );
  217. msg = wxT( "KeyW: " );
  218. msg += Module->m_KeyWord;
  219. GetParent()->SetStatusText( msg, 1 );
  220. }
  221. }
  222. /******************************************************/
  223. void FOOTPRINTS_LISTBOX::OnLeftDClick( wxListEvent& event )
  224. /******************************************************/
  225. {
  226. wxString FootprintName = GetSelectedFootprint();
  227. GetParent()->SetNewPkg( FootprintName );
  228. }
  229. FOOTPRINT* GetModuleDescrByName( const wxString& FootprintName,
  230. FOOTPRINT_LIST& list )
  231. {
  232. BOOST_FOREACH( FOOTPRINT & footprint, list ) {
  233. if( footprint.m_Module == FootprintName )
  234. return &footprint;
  235. }
  236. return NULL;
  237. }
  238. /** function OnChar
  239. * called on a key pressed
  240. * Call default handler for some special keys,
  241. * and for "ascii" keys, select the first footprint
  242. * that the name starts by the letter.
  243. * This is the defaut behaviour of a listbox, but because we use
  244. * virtual lists, the listbox does not know anything to what is displayed,
  245. * we must handle this behaviour here.
  246. * Furthermore the footprint name is not at the beginning of
  247. * displayed lines (the first word is the line number)
  248. */
  249. void FOOTPRINTS_LISTBOX::OnChar( wxKeyEvent& event )
  250. {
  251. int key = event.GetKeyCode();
  252. switch( key )
  253. {
  254. case WXK_LEFT:
  255. case WXK_NUMPAD_LEFT:
  256. GetParent()->m_ListCmp->SetFocus();
  257. return;
  258. case WXK_HOME:
  259. case WXK_END:
  260. case WXK_UP:
  261. case WXK_DOWN:
  262. case WXK_PAGEUP:
  263. case WXK_PAGEDOWN:
  264. case WXK_RIGHT:
  265. case WXK_NUMPAD_RIGHT:
  266. event.Skip();
  267. return;
  268. default:
  269. break;
  270. }
  271. // Search for an item name starting by the key code:
  272. key = toupper(key);
  273. for( unsigned ii = 0; ii < m_ActiveFootprintList->GetCount(); ii++ )
  274. {
  275. wxString text = m_ActiveFootprintList->Item(ii);
  276. /* search for the start char of the footprint name.
  277. * we must skip the line number
  278. */
  279. text.Trim(false); // Remove leading spaces in line
  280. unsigned jj = 0;
  281. for( ; jj < text.Len(); jj++ )
  282. { // skip line number
  283. if( text[jj] == ' ' )
  284. break;
  285. }
  286. for( ; jj < text.Len(); jj++ )
  287. { // skip blanks
  288. if( text[jj] != ' ' )
  289. break;
  290. }
  291. int start_char = toupper(text[jj]);
  292. if ( key == start_char )
  293. {
  294. Focus( ii );
  295. SetSelection( ii, true ); // Ensure visible
  296. break;
  297. }
  298. }
  299. }