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.

340 lines
8.7 KiB

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