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.
wxString GetName() const override
enum TYPE Type
Node type.
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
FP_LIB_TABLE GFootprintTable
!!!!!!!!!!!!!! This code is obsolete because of the merge into pcbnew, don't bother with it.
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
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:275
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:60
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.
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
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.