KiCad PCB EDA Suite
fp_tree_synchronizing_adapter.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2017 CERN
5  * @author Maciej Suminski <maciej.suminski@cern.ch>
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 3
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  * https://www.gnu.org/licenses/gpl-3.0.html
20  * or you may search the http://www.gnu.org website for the version 3 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 
26 #include <footprint_edit_frame.h>
27 #include <fp_lib_table.h>
28 #include <footprint_info_impl.h>
29 #include <class_board.h>
30 #include <class_module.h>
31 
32 
34  FP_LIB_TABLE* aLibs )
35 {
36  return PTR( new FP_TREE_SYNCHRONIZING_ADAPTER( aFrame, aLibs ) );
37 }
38 
39 
41  FP_LIB_TABLE* aLibs ) :
42  FP_TREE_MODEL_ADAPTER( aLibs ),
43  m_frame( aFrame )
44 {
45 }
46 
47 
48 bool FP_TREE_SYNCHRONIZING_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
49 {
50  const LIB_TREE_NODE* node = ToNode( aItem );
51  return node ? node->Type == LIB_TREE_NODE::LIB : true;
52 }
53 
54 
55 #define PROGRESS_INTERVAL_MILLIS 66
56 
58 {
59  // Process already stored libraries
60  for( auto it = m_tree.Children.begin(); it != m_tree.Children.end(); )
61  {
62  const wxString& name = it->get()->Name;
63 
64  if( !m_libs->HasLibrary( name, true ) )
65  {
66  it = deleteLibrary( it );
67  continue;
68  }
69 
70  updateLibrary( *(LIB_TREE_NODE_LIB*) it->get() );
71  ++it;
72  }
73 
74  // Look for new libraries
75  size_t count = m_libMap.size();
76 
77  for( const auto& libName : m_libs->GetLogicalLibs() )
78  {
79  if( m_libMap.count( libName ) == 0 )
80  {
81  const FP_LIB_TABLE_ROW* library = m_libs->FindRow( libName );
82 
83  DoAddLibrary( libName, library->GetDescr(), getFootprints( libName ), true );
84  m_libMap.insert( libName );
85  }
86  }
87 
88  if( m_libMap.size() > count )
90 }
91 
92 
94 {
95  return GFootprintTable.GetCount();
96 }
97 
98 
100 {
101  std::vector<LIB_TREE_ITEM*> footprints = getFootprints( aLibNode.Name );
102 
103  // remove the common part from the footprints list
104  for( auto nodeIt = aLibNode.Children.begin(); nodeIt != aLibNode.Children.end(); )
105  {
106  // Since the list is sorted we can use a binary search to speed up searches within
107  // libraries with lots of footprints.
108  FOOTPRINT_INFO_IMPL dummy( wxEmptyString, (*nodeIt)->Name );
109  auto footprintIt = std::lower_bound( footprints.begin(), footprints.end(), &dummy,
110  []( LIB_TREE_ITEM* a, LIB_TREE_ITEM* b )
111  {
112  return StrNumCmp( a->GetName(), b->GetName(), INT_MAX, true ) < 0;
113  } );
114 
115  if( footprintIt != footprints.end() && dummy.GetName() == (*footprintIt)->GetName() )
116  {
117  // footprint exists both in the lib tree and the footprint info list; just
118  // update the node data
119  static_cast<LIB_TREE_NODE_LIB_ID*>( nodeIt->get() )->Update( *footprintIt );
120  footprints.erase( footprintIt );
121  ++nodeIt;
122  }
123  else
124  {
125  // node does not exist in the library manager, remove the corresponding node
126  nodeIt = aLibNode.Children.erase( nodeIt );
127  }
128  }
129 
130  // now the footprint list contains only new aliases that need to be added to the tree
131  for( auto footprint : footprints )
132  aLibNode.AddItem( footprint );
133 
134  aLibNode.AssignIntrinsicRanks();
135  m_libMap.insert( aLibNode.Name );
136 }
137 
138 
139 LIB_TREE_NODE::PTR_VECTOR::iterator FP_TREE_SYNCHRONIZING_ADAPTER::deleteLibrary(
140  LIB_TREE_NODE::PTR_VECTOR::iterator& aLibNodeIt )
141 {
142  LIB_TREE_NODE* node = aLibNodeIt->get();
143  m_libMap.erase( node->Name );
144  auto it = m_tree.Children.erase( aLibNodeIt );
145  return it;
146 }
147 
148 
149 void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
150  unsigned int aCol ) const
151 {
152  if( IsFrozen() )
153  {
154  aVariant = wxEmptyString;
155  return;
156  }
157 
158  auto node = ToNode( aItem );
159 
160  switch( aCol )
161  {
162  case 0:
163  if( node->LibId == m_frame->GetLoadedFPID() && !m_frame->IsCurrentFPFromBoard() )
164  {
165  wxString currentFPName = m_frame->GetBoard()->m_Modules->GetFPID().GetLibItemName();
166 
167  // mark modified part with an asterix
168  if( m_frame->GetScreen()->IsModify() )
169  aVariant = currentFPName + " *";
170  else
171  aVariant = currentFPName;
172  }
173  else
174  aVariant = node->Name;
175  break;
176 
177  case 1:
178  aVariant = node->Desc;
179  break;
180 
181  default: // column == -1 is used for default Compare function
182  aVariant = node->Name;
183  break;
184  }
185 }
186 
187 
188 bool FP_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsigned int aCol,
189  wxDataViewItemAttr& aAttr ) const
190 {
191  if( IsFrozen() )
192  return false;
193 
194  // change attributes only for the name field
195  if( aCol != 0 )
196  return false;
197 
198  // don't link to a board footprint, even if the FPIDs match
200  return false;
201 
202  auto node = ToNode( aItem );
203  wxCHECK( node, false );
204 
205  switch( node->Type )
206  {
207  case LIB_TREE_NODE::LIB:
208  if( node->Name == m_frame->GetLoadedFPID().GetLibNickname() )
209  {
210 #ifdef __WXGTK__
211  // The native wxGTK+ impl ignores background colour, so set the text colour
212  // instead. Works reasonably well in dark themes, less well in light ones....
213  aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
214 #else
215  aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
216 #endif
217 
218  // mark modified libs with bold font
220  aAttr.SetBold( true );
221  }
222  break;
223 
225  if( node->LibId == m_frame->GetLoadedFPID() )
226  {
227 #ifdef __WXGTK__
228  // The native wxGTK+ impl ignores background colour, so set the text colour
229  // instead. Works reasonably well in dark themes, less well in light ones....
230  aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
231 #else
232  aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
233 #endif
234 
235  // mark modified part with bold font
237  aAttr.SetBold( true );
238  }
239  break;
240 
241  default:
242  return false;
243  }
244 
245  return true;
246 }
247 
248 
int GetCount()
void DoAddLibrary(wxString const &aNodeName, wxString const &aDesc, std::vector< LIB_TREE_ITEM * > const &aItemList, bool presorted)
Add the given list of components by alias.
void GetValue(wxVariant &aVariant, wxDataViewItem const &aItem, unsigned int aCol) const override
Get the value of an item.
const wxString & GetName() const override
PTR_VECTOR Children
List of child nodes.
enum TYPE Type
Node type.
Class FP_LIB_TABLE_ROW.
Definition: fp_lib_table.h:42
bool IsContainer(const wxDataViewItem &aItem) const override
Check whether an item can have children.
A mix-in to provide polymorphism between items stored in libraries (symbols, aliases and footprints)...
Definition: lib_tree_item.h:39
Class BOARD to handle a board.
Node type: LIB_ID.
BOARD * GetBoard() const
bool IsModify() const
Definition: base_screen.h:328
Definition of class FOOTPRINT_EDIT_FRAME.
int GetLibrariesCount() const override
Return the number of libraries loaded in the tree.
FP_LIB_TABLE GFootprintTable
The global footprint library table.
Definition: pcbnew.cpp:333
const LIB_ID & GetFPID() const
Definition: class_module.h:193
std::vector< LIB_TREE_ITEM * > getFootprints(const wxString &aLibName)
LIB_TREE_NODE::PTR_VECTOR::iterator deleteLibrary(LIB_TREE_NODE::PTR_VECTOR::iterator &aLibNodeIt)
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
LIB_TREE_NODE_LIB_ID & AddItem(LIB_TREE_ITEM *aItem)
Construct a new alias node, add it to this library, and return it.
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
Node type: library.
LIB_ID GetLoadedFPID() const
Return the LIB_ID of the part being edited.
static LIB_TREE_NODE const * ToNode(wxDataViewItem aItem)
Convert wxDataViewItem -> CMP_TREE_NODE.
Model class in the component selector Model-View-Adapter (mediated MVC) architecture.
const wxString & GetDescr() const
Return the description of the library referenced by this row.
FP_TREE_SYNCHRONIZING_ADAPTER(FOOTPRINT_EDIT_FRAME *aFrame, FP_LIB_TABLE *aLibs)
void updateLibrary(LIB_TREE_NODE_LIB &aLibNode)
const FP_LIB_TABLE_ROW * FindRow(const wxString &aNickName)
Function FindRow.
wxString Name
Actual name of the part.
void AssignIntrinsicRanks(bool presorted=false)
Store intrinsic ranks on all children of this node.
const char * name
Definition: DXF_plotter.cpp:61
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
DLIST< MODULE > m_Modules
Definition: class_board.h:248
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
bool GetAttr(wxDataViewItem const &aItem, unsigned int aCol, wxDataViewItemAttr &aAttr) const override
Get any formatting for an item.
static PTR Create(FOOTPRINT_EDIT_FRAME *aFrame, FP_LIB_TABLE *aLibs)
wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > PTR
Reference-counting container for a pointer to CMP_TREE_MODEL_ADAPTER_BASE.
Module description (excepted pads)
int StrNumCmp(const wxString &aString1, const wxString &aString2, int aLength, bool aIgnoreCase)
Function StrNumCmp is a routine compatible with qsort() to sort by alphabetical order.
Definition: string.cpp:315
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:97
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE...