KiCad PCB EDA Suite
getpart.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) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors.
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 2
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  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 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 
26 #include <algorithm>
27 #include <class_library.h>
28 #include <confirm.h>
29 #include <eeschema_id.h>
30 #include <fctsys.h>
31 #include <general.h>
32 #include <kiway.h>
33 #include <lib_edit_frame.h>
34 #include <lib_view_frame.h>
35 #include <pgm_base.h>
36 #include <sch_component.h>
37 #include <sch_edit_frame.h>
38 #include <symbol_lib_table.h>
39 #include <tool/tool_manager.h>
40 #include <tools/ee_actions.h>
41 
44 
46  const SCHLIB_FILTER* aFilter, const LIB_ID& aPreselectedLibId, int aUnit, int aConvert )
47 {
48  // Close any open non-modal Lib browser, and open a new one, in "modal" mode:
49  LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false );
50 
51  if( viewlibFrame )
52  viewlibFrame->Destroy();
53 
54  viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER_MODAL, true, aParent );
55 
56  if( aFilter )
57  viewlibFrame->SetFilter( aFilter );
58 
59  if( aPreselectedLibId.IsValid() )
60  {
61  viewlibFrame->SetSelectedLibrary( aPreselectedLibId.GetLibNickname() );
62  viewlibFrame->SetSelectedComponent( aPreselectedLibId.GetLibItemName() );
63  }
64 
65  viewlibFrame->SetUnitAndConvert( aUnit, aConvert );
66 
67  viewlibFrame->Refresh();
68 
70  wxString symbol;
71 
72  if( viewlibFrame->ShowModal( &symbol, aParent ) )
73  {
74  LIB_ID id;
75 
76  if( id.Parse( symbol, LIB_ID::ID_SCH ) == -1 )
77  sel.LibId = id;
78 
79  sel.Unit = viewlibFrame->GetUnit();
80  sel.Convert = viewlibFrame->GetConvert();
81  }
82 
83  viewlibFrame->Destroy();
84 
85  return sel;
86 }
87 
88 
90  std::vector<COMPONENT_SELECTION>& aHistoryList, bool aUseLibBrowser, int aUnit,
91  int aConvert, bool aShowFootprints, const LIB_ID* aHighlight, bool aAllowFields )
92 {
93  std::unique_lock<std::mutex> dialogLock( DIALOG_CHOOSE_COMPONENT::g_Mutex, std::defer_lock );
94  wxString dialogTitle;
95  SYMBOL_LIB_TABLE* libs = Prj().SchSymbolLibTable();
96 
97  // One CHOOSE_COMPONENT dialog at a time. User probaby can't handle more anyway.
98  if( !dialogLock.try_lock() )
99  return COMPONENT_SELECTION();
100 
101  auto adapterPtr( SYMBOL_TREE_MODEL_ADAPTER::Create( this, libs ) );
102  auto adapter = static_cast<SYMBOL_TREE_MODEL_ADAPTER*>( adapterPtr.get() );
103  bool loaded = false;
104 
105  if( aFilter )
106  {
107  const wxArrayString& liblist = aFilter->GetAllowedLibList();
108 
109  for( unsigned ii = 0; ii < liblist.GetCount(); ii++ )
110  {
111  if( libs->HasLibrary( liblist[ii], true ) )
112  {
113  loaded = true;
114  adapter->AddLibrary( liblist[ii] );
115  }
116  }
117 
118  adapter->AssignIntrinsicRanks();
119 
120  if( aFilter->GetFilterPowerParts() )
121  adapter->SetFilter( SYMBOL_TREE_MODEL_ADAPTER::CMP_FILTER_POWER );
122  }
123 
124  std::vector< LIB_TREE_ITEM* > history_list;
125 
126  for( auto const& i : aHistoryList )
127  {
128  LIB_PART* symbol = GetLibPart( i.LibId );
129 
130  // This can be null, for example when a symbol has been deleted from a library
131  if( symbol )
132  history_list.push_back( symbol );
133  }
134 
135  adapter->DoAddLibrary( "-- " + _( "Recently Used" ) + " --", wxEmptyString, history_list,
136  true );
137 
138  if( !aHistoryList.empty() )
139  adapter->SetPreselectNode( aHistoryList[0].LibId, aHistoryList[0].Unit );
140 
141  const std::vector< wxString > libNicknames = libs->GetLogicalLibs();
142 
143  if( !loaded )
144  adapter->AddLibraries( libNicknames, this );
145 
146  if( aHighlight && aHighlight->IsValid() )
147  adapter->SetPreselectNode( *aHighlight, /* aUnit */ 0 );
148 
149  if( adapter->GetFilter() == SYMBOL_TREE_MODEL_ADAPTER::CMP_FILTER_POWER )
150  dialogTitle.Printf( _( "Choose Power Symbol (%d items loaded)" ), adapter->GetItemCount() );
151  else
152  dialogTitle.Printf( _( "Choose Symbol (%d items loaded)" ), adapter->GetItemCount() );
153 
154  DIALOG_CHOOSE_COMPONENT dlg( this, dialogTitle, adapterPtr, aConvert,
155  aAllowFields, aShowFootprints, aUseLibBrowser );
156 
157  if( dlg.ShowModal() == wxID_CANCEL )
158  return COMPONENT_SELECTION();
159 
161  LIB_ID id = dlg.GetSelectedLibId( &sel.Unit );
162 
163  if( dlg.IsExternalBrowserSelected() ) // User requested component browser.
164  {
165  sel = SelectComponentFromLibBrowser( this, aFilter, id, sel.Unit, sel.Convert );
166  id = sel.LibId;
167  }
168 
169  if( !id.IsValid() ) // Dialog closed by OK button,
170  // or the selection by lib browser was requested,
171  // but no symbol selected
172  return COMPONENT_SELECTION();
173 
174  if( sel.Unit == 0 )
175  sel.Unit = 1;
176 
177  sel.Fields = dlg.GetFields();
178  sel.LibId = id;
179 
180  if( sel.LibId.IsValid() )
181  {
182  aHistoryList.erase( std::remove_if( aHistoryList.begin(), aHistoryList.end(),
183  [ &sel ]( COMPONENT_SELECTION const& i )
184  {
185  return i.LibId == sel.LibId;
186  } ),
187  aHistoryList.end() );
188 
189  aHistoryList.insert( aHistoryList.begin(), sel );
190  }
191 
192  return sel;
193 }
194 
195 
196 void SCH_EDIT_FRAME::SelectUnit( SCH_COMPONENT* aComponent, int aUnit )
197 {
198  LIB_PART* part = GetLibPart( aComponent->GetLibId() );
199 
200  if( !part )
201  return;
202 
203  int unitCount = part->GetUnitCount();
204 
205  if( unitCount <= 1 || aComponent->GetUnit() == aUnit )
206  return;
207 
208  if( aUnit > unitCount )
209  aUnit = unitCount;
210 
211  STATUS_FLAGS savedFlags = aComponent->GetFlags();
212 
213  if( !aComponent->GetEditFlags() ) // No command in progress: save in undo list
214  SaveCopyInUndoList( GetScreen(), aComponent, UNDO_REDO::CHANGED, false );
215 
216  /* Update the unit number. */
217  aComponent->SetUnitSelection( &GetCurrentSheet(), aUnit );
218  aComponent->SetUnit( aUnit );
219  aComponent->ClearFlags();
220  aComponent->SetFlags( savedFlags ); // Restore m_Flag modified by SetUnit()
221 
222  if( !aComponent->GetEditFlags() ) // No command in progress: update schematic
223  {
225  aComponent->AutoAutoplaceFields( GetScreen() );
226 
228 
229  UpdateItem( aComponent );
230  OnModify();
231  }
232 }
233 
234 
236 {
237  if( !aComponent || !aComponent->GetPartRef() )
238  return;
239 
240  wxString msg;
241 
242  if( !aComponent->GetPartRef()->HasConversion() )
243  {
244  LIB_ID id = aComponent->GetPartRef()->GetLibId();
245 
246  msg.Printf( _( "No alternate body style found for symbol \"%s\" in library \"%s\"." ),
247  id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() );
248  DisplayError( this, msg );
249  return;
250  }
251 
252  STATUS_FLAGS savedFlags = aComponent->GetFlags();
253 
254  aComponent->SetConvert( aComponent->GetConvert() + 1 );
255 
256  // ensure m_Convert = 1 or 2
257  // 1 = shape 1 = not converted
258  // 2 = shape 2 = first converted shape
259  // > 2 is not used but could be used for more shapes
260  // like multiple shapes for a programmable component
261  // When m_Convert = val max, return to the first shape
262  if( aComponent->GetConvert() > LIB_ITEM::LIB_CONVERT::DEMORGAN )
263  aComponent->SetConvert( LIB_ITEM::LIB_CONVERT::BASE );
264 
266  aComponent->ClearFlags();
267  aComponent->SetFlags( savedFlags ); // Restore m_Flags (modified by SetConvert())
268 
269  // If selected make sure all the now-included pins are selected
270  if( aComponent->IsSelected() )
271  m_toolManager->RunAction( EE_ACTIONS::addItemToSel, true, aComponent );
272 
273  UpdateItem( aComponent );
274  OnModify();
275 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
void SetFilter(const SCHLIB_FILTER *aFilter)
Set a filter to display only libraries and/or components which match the filter.
const UTF8 & GetLibItemName() const
Definition: lib_id.h:114
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false)
Mark an item for refresh.
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_holder.h:56
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
void SetUnitAndConvert(int aUnit, int aConvert)
Set unit and convert, and set flag preventing them from automatically resetting to 1.
bool ShowModal(wxString *aSymbol, wxWindow *aParent) override
Function ShowModal.
bool IsSelected() const
Definition: base_struct.h:203
This file is part of the common library.
void AutoAutoplaceFields(SCH_SCREEN *aScreen)
Autoplace fields only if correct to do so automatically.
Definition: sch_item.h:457
int GetUnit() const
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:140
LIB_PART * GetLibPart(const LIB_ID &aLibId, bool aUseCacheLib=false, bool aShowErrorMsg=false)
Load symbol from symbol library table.
bool TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
bool IsValid() const
Definition: lib_id.h:171
void SetSelectedComponent(const wxString &aComponentName)
Set the selected component.
Symbol library viewer main window.
static PTR Create(EDA_BASE_FRAME *aParent, LIB_TABLE *aLibs)
Factory function: create a model adapter in a reference-counting container.
int GetConvert() const
void SetConvert(int aConvert)
EESCHEMA_SETTINGS * eeconfig() const
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
Dialog class to select a component from the libraries.
bool IsExternalBrowserSelected() const
Function IsExternalBrowserSelected.
AUTOPLACE_FIELDS m_AutoplaceFields
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:232
static TOOL_ACTION addItemToSel
Selects an item (specified as the event parameter).
Definition: ee_actions.h:59
int GetUnitCount() const override
For items with units, return the number of units.
VTBL_ENTRY KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=NULL)
Function Player returns the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:343
std::vector< std::pair< int, wxString > > GetFields() const
Get a list of fields edited by the user.
STATUS_FLAGS GetEditFlags() const
Definition: base_struct.h:237
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
Define a library symbol object.
void SaveCopyInUndoList(SCH_SCREEN *aScreen, SCH_ITEM *aItemToCopy, UNDO_REDO aTypeCommand, bool aAppend, const wxPoint &aTransformPoint=wxPoint(0, 0))
Create a copy of the current schematic item, and put it in the undo list.
unsigned STATUS_FLAGS
Definition: base_struct.h:152
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:97
void SetUnit(int aUnit)
Change the unit number to aUnit.
std::unique_ptr< LIB_PART > & GetPartRef()
COMPONENT_SELECTION SelectCompFromLibTree(const SCHLIB_FILTER *aFilter, std::vector< COMPONENT_SELECTION > &aHistoryList, bool aUseLibBrowser, int aUnit, int aConvert, bool aShowFootprints, const LIB_ID *aHighlight=nullptr, bool aAllowFields=true)
Function SelectComponentFromLib Calls the library viewer to select component to import into schematic...
Definition: getpart.cpp:89
bool GetFilterPowerParts() const
COMPONENT_SELECTION SelectComponentFromLibBrowser(wxTopLevelWindow *aParent, const SCHLIB_FILTER *aFilter, const LIB_ID &aPreselectedLibid, int aUnit, int aConvert)
Function SelectComponentFromLibBrowser Calls the library viewer to select component to import into sc...
Definition: getpart.cpp:45
void SelectUnit(SCH_COMPONENT *aComponent, int aUnit)
Definition: getpart.cpp:196
void SetUnitSelection(const SCH_SHEET_PATH *aSheet, int aUnitSelection)
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:50
see class PGM_BASE
#define _(s)
Definition: 3d_actions.cpp:33
Schematic symbol object.
Definition: sch_component.h:80
const wxArrayString & GetAllowedLibList() const
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:233
SCH_SHEET_PATH & GetCurrentSheet() const
std::vector< std::pair< int, wxString > > Fields
Definition: sch_screen.h:86
int GetConvert() const
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
Definition for part library class.
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:234
const LIB_ID & GetLibId() const
void ConvertPart(SCH_COMPONENT *aComponent)
Definition: getpart.cpp:235
LIB_ID GetSelectedLibId(int *aUnit=nullptr) const
To be called after this dialog returns from ShowModal().
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
void SetSelectedLibrary(const wxString &aLibName)
Set the selected library in the library window.