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  * Copyright (C)-2019 KiCad Developers, see AUTHORS.txt for contributors.
6  * @author Maciej Suminski <maciej.suminski@cern.ch>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * https://www.gnu.org/licenses/gpl-3.0.html
21  * or you may search the http://www.gnu.org website for the version 3 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
27 #include <footprint_edit_frame.h>
28 #include <fp_lib_table.h>
29 #include <footprint_info_impl.h>
30 #include <class_board.h>
31 #include <class_module.h>
32 #include <tool/tool_manager.h>
34 
35 
37  FP_LIB_TABLE* aLibs )
38 {
39  return PTR( new FP_TREE_SYNCHRONIZING_ADAPTER( aFrame, aLibs ) );
40 }
41 
42 
44  FP_LIB_TABLE* aLibs ) :
45  FP_TREE_MODEL_ADAPTER( aLibs ),
46  m_frame( aFrame )
47 {
48 }
49 
50 
52 {
54 }
55 
56 
57 bool FP_TREE_SYNCHRONIZING_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
58 {
59  const LIB_TREE_NODE* node = ToNode( aItem );
60  return node ? node->Type == LIB_TREE_NODE::LIB : true;
61 }
62 
63 
64 #define PROGRESS_INTERVAL_MILLIS 66
65 
67 {
68  // Process already stored libraries
69  for( auto it = m_tree.Children.begin(); it != m_tree.Children.end(); )
70  {
71  const wxString& name = it->get()->Name;
72 
73  if( !m_libs->HasLibrary( name, true ) )
74  {
75  it = deleteLibrary( it );
76  continue;
77  }
78 
79  updateLibrary( *(LIB_TREE_NODE_LIB*) it->get() );
80  ++it;
81  }
82 
83  // Look for new libraries
84  size_t count = m_libMap.size();
85 
86  for( const auto& libName : m_libs->GetLogicalLibs() )
87  {
88  if( m_libMap.count( libName ) == 0 )
89  {
90  const FP_LIB_TABLE_ROW* library = m_libs->FindRow( libName );
91 
92  DoAddLibrary( libName, library->GetDescr(), getFootprints( libName ), true );
93  m_libMap.insert( libName );
94  }
95  }
96 
97  if( m_libMap.size() > count )
99 }
100 
101 
103 {
104  return GFootprintTable.GetCount();
105 }
106 
107 
109 {
110  std::vector<LIB_TREE_ITEM*> footprints = getFootprints( aLibNode.Name );
111 
112  // remove the common part from the footprints list
113  for( auto nodeIt = aLibNode.Children.begin(); nodeIt != aLibNode.Children.end(); )
114  {
115  // Since the list is sorted we can use a binary search to speed up searches within
116  // libraries with lots of footprints.
117  FOOTPRINT_INFO_IMPL dummy( wxEmptyString, (*nodeIt)->Name );
118  auto footprintIt = std::lower_bound( footprints.begin(), footprints.end(), &dummy,
119  []( LIB_TREE_ITEM* a, LIB_TREE_ITEM* b )
120  {
121  return StrNumCmp( a->GetName(), b->GetName(), false ) < 0;
122  } );
123 
124  if( footprintIt != footprints.end() && dummy.GetName() == (*footprintIt)->GetName() )
125  {
126  // footprint exists both in the lib tree and the footprint info list; just
127  // update the node data
128  static_cast<LIB_TREE_NODE_LIB_ID*>( nodeIt->get() )->Update( *footprintIt );
129  footprints.erase( footprintIt );
130  ++nodeIt;
131  }
132  else
133  {
134  // node does not exist in the library manager, remove the corresponding node
135  nodeIt = aLibNode.Children.erase( nodeIt );
136  }
137  }
138 
139  // now the footprint list contains only new aliases that need to be added to the tree
140  for( auto footprint : footprints )
141  aLibNode.AddItem( footprint );
142 
143  aLibNode.AssignIntrinsicRanks();
144  m_libMap.insert( aLibNode.Name );
145 }
146 
147 
148 LIB_TREE_NODE::PTR_VECTOR::iterator FP_TREE_SYNCHRONIZING_ADAPTER::deleteLibrary(
149  LIB_TREE_NODE::PTR_VECTOR::iterator& aLibNodeIt )
150 {
151  LIB_TREE_NODE* node = aLibNodeIt->get();
152  m_libMap.erase( node->Name );
153  auto it = m_tree.Children.erase( aLibNodeIt );
154  return it;
155 }
156 
157 
158 void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
159  unsigned int aCol ) const
160 {
161  if( IsFrozen() )
162  {
163  aVariant = wxEmptyString;
164  return;
165  }
166 
167  auto node = ToNode( aItem );
168 
169  switch( aCol )
170  {
171  case 0:
172  if( node->LibId == m_frame->GetLoadedFPID() && !m_frame->IsCurrentFPFromBoard() )
173  {
174  auto mod = m_frame->GetBoard()->GetFirstModule();
175 
176  wxASSERT( mod );
177 
178  wxString currentFPName = mod->GetFPID().GetLibItemName();
179 
180  // mark modified part with an asterisk
181  if( m_frame->GetScreen()->IsModify() )
182  aVariant = currentFPName + " *";
183  else
184  aVariant = currentFPName;
185  }
186  else
187  aVariant = node->Name;
188  break;
189 
190  case 1:
191  aVariant = node->Desc;
192  break;
193 
194  default: // column == -1 is used for default Compare function
195  aVariant = node->Name;
196  break;
197  }
198 }
199 
200 
201 bool FP_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsigned int aCol,
202  wxDataViewItemAttr& aAttr ) const
203 {
204  if( IsFrozen() )
205  return false;
206 
207  // change attributes only for the name field
208  if( aCol != 0 )
209  return false;
210 
211  // don't link to a board footprint, even if the FPIDs match
213  return false;
214 
215  auto node = ToNode( aItem );
216  wxCHECK( node, false );
217 
218  switch( node->Type )
219  {
220  case LIB_TREE_NODE::LIB:
221  if( node->Name == m_frame->GetLoadedFPID().GetLibNickname() )
222  {
223 #ifdef __WXGTK__
224  // The native wxGTK+ impl ignores background colour, so set the text colour
225  // instead. Works reasonably well in dark themes, less well in light ones....
226  aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
227 #else
228  aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
229  aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
230 #endif
231 
232  // mark modified libs with bold font
234  aAttr.SetBold( true );
235  }
236  break;
237 
239  if( node->LibId == m_frame->GetLoadedFPID() )
240  {
241 #ifdef __WXGTK__
242  // The native wxGTK+ impl ignores background colour, so set the text colour
243  // instead. Works reasonably well in dark themes, less well in light ones....
244  aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
245 #else
246  aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
247  aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
248 #endif
249 
250  // mark modified part with bold font
252  aAttr.SetBold( true );
253  }
254  break;
255 
256  default:
257  return false;
258  }
259 
260  return true;
261 }
262 
263 
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
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
Definition: string.cpp:354
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
A mix-in to provide polymorphism between items stored in libraries (symbols, aliases and footprints).
Definition: lib_tree_item.h:39
unsigned GetCount() const
Get the number of rows contained in the table.
int GetLibrariesCount() const override
Return the number of libraries loaded in the tree.
TOOL_INTERACTIVE * GetContextMenuTool() override
FP_LIB_TABLE GFootprintTable
The global footprint library table.
Definition: pcbnew.cpp:303
const wxString & GetDescr() const
Return the description of the library referenced by this row.
std::vector< LIB_TREE_ITEM * > getFootprints(const wxString &aLibName)
LIB_TREE_NODE::PTR_VECTOR::iterator deleteLibrary(LIB_TREE_NODE::PTR_VECTOR::iterator &aLibNodeIt)
LIB_TREE_NODE_LIB_ID & AddItem(LIB_TREE_ITEM *aItem)
Construct a new alias node, add it to this library, and return it.
Node type: library.
MODULE * GetFirstModule() const
Gets the first module in the list (used in footprint viewer/editor) or NULL if none.
Definition: class_board.h:285
static LIB_TREE_NODE const * ToNode(wxDataViewItem aItem)
Convert wxDataViewItem -> CMP_TREE_NODE.
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:97
bool IsModify() const
Definition: base_screen.h:228
Model class in the component selector Model-View-Adapter (mediated MVC) architecture.
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 to draw a dummy shape when a LIB_PART is not found in library.
LIB_ID GetLoadedFPID() const
Return the LIB_ID of the part being edited.
const wxString & GetName() const
Class MODULE_EDITOR_TOOLS.
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
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)
BOARD * GetBoard() const
#define mod(a, n)
Definition: greymap.cpp:24
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.