KiCad PCB EDA Suite
dialog_edit_component_in_lib.cpp
Go to the documentation of this file.
1 
5 /*
6  * This program source code file is part of KiCad, a free EDA CAD application.
7  *
8  * Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, you may find one here:
22  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23  * or you may search the http://www.gnu.org website for the version 2 license,
24  * or you may write to the Free Software Foundation, Inc.,
25  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27 
28 #include <fctsys.h>
29 #include <kiway.h>
30 #include <common.h>
31 #include <confirm.h>
32 #include <gestfich.h>
33 #include <pgm_base.h>
34 
35 #include <general.h>
36 #include <libeditframe.h>
37 #include <class_library.h>
38 #include <eeschema_id.h> // for MAX_UNIT_COUNT_PER_PACKAGE definition
39 
41 
43 
46 {
47  m_Parent = aParent;
48  m_RecreateToolbar = false;
49 
50  initDlg();
51 
52  // Now all widgets have the size fixed, call FinishDialogSettings
54 }
55 
56 
58 {
59  m_lastOpenedPage = m_NoteBook->GetSelection( );
60 }
61 
62 /* Initialize state of check boxes and texts
63 */
65 {
66  m_AliasLocation = -1;
67 
68  LIB_PART* component = m_Parent->GetCurPart();
69 
70  if( component == NULL )
71  {
72  SetTitle( _( "Library Component Properties" ) );
73  return;
74  }
75 
76  wxString title;
77  bool isRoot = m_Parent->GetAliasName().CmpNoCase( component->GetName() ) == 0;
78 
79  if( !isRoot )
80  {
81  title.Printf( _( "Properties for %s (alias of %s)" ),
83  GetChars( component->GetName() ) );
84  }
85  else
86  title.Printf( _( "Properties for %s" ), GetChars( component->GetName() ) );
87 
88  SetTitle( title );
89  InitPanelDoc();
91 
92  if( isRoot && component->GetAliasCount() == 1 )
93  m_ButtonDeleteAllAlias->Enable( false );
94 
95  /* Place list of alias names in listbox */
96  m_PartAliasListCtrl->Append( component->GetAliasNames( false ) );
97 
98  if( component->GetAliasCount() <= 1 )
99  {
100  m_ButtonDeleteAllAlias->Enable( false );
101  m_ButtonDeleteOneAlias->Enable( false );
102  }
103 
104  /* Read the Footprint Filter list */
105  m_FootprintFilterListBox->Append( component->GetFootPrints() );
106 
107  if( component->GetFootPrints().GetCount() == 0 )
108  {
109  m_ButtonDeleteAllFootprintFilter->Enable( false );
110  m_ButtonDeleteOneFootprintFilter->Enable( false );
111  m_buttonEditOneFootprintFilter->Enable( false );
112  }
113 
114  m_NoteBook->SetSelection( m_lastOpenedPage );
115 
116  m_stdSizerButtonOK->SetDefault();
117 }
118 
119 
121 {
122  EndModal( wxID_CANCEL );
123 }
124 
125 
126 
128 {
129  LIB_ALIAS* alias;
130  LIB_PART* component = m_Parent->GetCurPart();
131 
132  if( component == NULL )
133  return;
134 
135  wxString aliasname = m_Parent->GetAliasName();
136 
137  if( aliasname.IsEmpty() )
138  return;
139 
140  alias = component->GetAlias( aliasname );
141 
142  if( alias != NULL )
143  {
144  m_DocCtrl->SetValue( alias->GetDescription() );
145  m_KeywordsCtrl->SetValue( alias->GetKeyWords() );
146  m_DocfileCtrl->SetValue( alias->GetDocFileName() );
147  }
148 }
149 
150 
151 /*
152  * create the basic panel for component properties editing
153  */
155 {
156  LIB_PART* component = m_Parent->GetCurPart();
157 
158  if( m_Parent->GetShowDeMorgan() )
159  m_AsConvertButt->SetValue( true );
160 
161  int maxUnits = MAX_UNIT_COUNT_PER_PACKAGE;
162  m_SelNumberOfUnits->SetRange (1, maxUnits );
163 
165  _( "Number of Units (max allowed %d)" ), maxUnits ) );
166 
167 
168  /* Default values for a new component. */
169  if( component == NULL )
170  {
171  m_ShowPinNumButt->SetValue( true );
172  m_ShowPinNameButt->SetValue( true );
173  m_PinsNameInsideButt->SetValue( true );
174  m_SelNumberOfUnits->SetValue( 1 );
175  m_SetSkew->SetValue( 40 );
176  m_OptionPower->SetValue( false );
177  m_OptionPartsLocked->SetValue( false );
178  return;
179  }
180 
181  m_ShowPinNumButt->SetValue( component->ShowPinNumbers() );
182  m_ShowPinNameButt->SetValue( component->ShowPinNames() );
183  m_PinsNameInsideButt->SetValue( component->GetPinNameOffset() != 0 );
184  m_SelNumberOfUnits->SetValue( component->GetUnitCount() );
185  m_SetSkew->SetValue( component->GetPinNameOffset() );
186  m_OptionPower->SetValue( component->IsPower() );
187  m_OptionPartsLocked->SetValue( component->UnitsLocked() && component->GetUnitCount() > 1 );
188 }
189 
190 
191 void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnOkClick( wxCommandEvent& event )
192 {
193  /* Update the doc, keyword and doc filename strings */
194  LIB_ALIAS* alias;
195  LIB_PART* component = m_Parent->GetCurPart();
196 
197  if( component == NULL )
198  {
199  EndModal( wxID_CANCEL );
200  return;
201  }
202 
203  m_Parent->SaveCopyInUndoList( component );
204 
205  alias = component->GetAlias( m_Parent->GetAliasName() );
206 
207  wxCHECK_RET( alias != NULL,
208  wxT( "Alias \"" ) + m_Parent->GetAliasName() + wxT( "\" of component \"" ) +
209  component->GetName() + wxT( "\" does not exist." ) );
210 
211  alias->SetDescription( m_DocCtrl->GetValue() );
212  alias->SetKeyWords( m_KeywordsCtrl->GetValue() );
213  alias->SetDocFileName( m_DocfileCtrl->GetValue() );
214 
215  component->SetAliases( m_PartAliasListCtrl->GetStrings() );
216 
217  int unitCount = m_SelNumberOfUnits->GetValue();
218  ChangeNbUnitsPerPackage( unitCount );
219 
220  if( m_AsConvertButt->GetValue() )
221  {
222  if( !m_Parent->GetShowDeMorgan() )
223  {
224  m_Parent->SetShowDeMorgan( true );
225  SetUnsetConvert();
226  }
227  }
228  else
229  {
230  if( m_Parent->GetShowDeMorgan() )
231  {
232  m_Parent->SetShowDeMorgan( false );
233  SetUnsetConvert();
234  }
235  }
236 
237  component->SetShowPinNumbers( m_ShowPinNumButt->GetValue() );
238  component->SetShowPinNames( m_ShowPinNameButt->GetValue() );
239 
240  if( m_PinsNameInsideButt->GetValue() == false )
241  component->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
242  else
243  {
244  component->SetPinNameOffset( m_SetSkew->GetValue() );
245  // Ensure component->m_TextInside != 0, because the meaning is "text outside".
246  if( component->GetPinNameOffset() == 0 )
247  component->SetPinNameOffset( 20 ); // give a reasonnable value
248  }
249 
250  if( m_OptionPower->GetValue() == true )
251  component->SetPower();
252  else
253  component->SetNormal();
254 
255  /* Set the option "Units locked".
256  * Obviously, cannot be true if there is only one part */
257  component->LockUnits( m_OptionPartsLocked->GetValue() );
258 
259  if( component->GetUnitCount() <= 1 )
260  component->LockUnits( false );
261 
262  /* Update the footprint filter list */
263  component->GetFootPrints().Clear();
264  component->GetFootPrints() = m_FootprintFilterListBox->GetStrings();
265 
266  EndModal( wxID_OK );
267 }
268 
269 
271 {
272  if( m_Parent == NULL )
273  return;
274 
275  LIB_ALIAS* parent_alias;
276  LIB_PART* component = m_Parent->GetCurPart();
277 
278  if( component == NULL )
279  return;
280 
281  // search for the main alias: this is the first alias in alias list
282  // something like the main component
283  parent_alias = component->GetAlias( 0 );
284 
285  if( parent_alias == NULL ) // Should never occur (bug)
286  return;
287 
288  m_DocCtrl->SetValue( parent_alias->GetDescription() );
289  m_DocfileCtrl->SetValue( parent_alias->GetDocFileName() );
290  m_KeywordsCtrl->SetValue( parent_alias->GetKeyWords() );
291 }
292 
293 
295 {
296  if( m_PartAliasListCtrl->FindString( m_Parent->GetAliasName() ) != wxNOT_FOUND )
297  {
298  wxString msg;
299  msg.Printf( _( "Alias <%s> cannot be removed while it is being edited!" ),
301  DisplayError( this, msg );
302  return;
303  }
304 
305  if( IsOK( this, _( "Remove all aliases from list?" ) ) )
306  {
307  m_PartAliasListCtrl->Clear();
308  m_ButtonDeleteAllAlias->Enable( false );
309  m_ButtonDeleteOneAlias->Enable( false );
310  }
311 }
312 
313 
314 /* Add a new name to the alias list box
315  * New name cannot be the root name, and must not exists
316  */
318 {
319  wxString aliasname;
320  LIB_PART* component = m_Parent->GetCurPart();
321  PART_LIB* library = m_Parent->GetCurLib();
322 
323  if( component == NULL )
324  return;
325 
326  wxTextEntryDialog dlg( this, _( "New alias:" ), _( "Component Alias" ), aliasname );
327 
328  if( dlg.ShowModal() != wxID_OK )
329  return; // cancelled by user
330 
331  aliasname = dlg.GetValue( );
332 
333  aliasname.Replace( wxT( " " ), wxT( "_" ) );
334  if( aliasname.IsEmpty() )
335  return;
336 
337  if( m_PartAliasListCtrl->FindString( aliasname ) != wxNOT_FOUND )
338  {
339  wxString msg;
340  msg.Printf( _( "Alias or component name <%s> already in use." ),
341  GetChars( aliasname ) );
342  DisplayError( this, msg );
343  return;
344  }
345 
346  if( library && library->FindAlias( aliasname ) != NULL )
347  {
348  wxString msg;
349  msg.Printf( _( "Alias or component name <%s> already exists in library <%s>." ),
350  GetChars( aliasname ),
351  GetChars( library->GetName() ) );
352  DisplayError( this, msg );
353  return;
354  }
355 
356  m_PartAliasListCtrl->Append( aliasname );
357 
358  if( m_Parent->GetAliasName().CmpNoCase( component->GetName() ) == 0 )
359  m_ButtonDeleteAllAlias->Enable( true );
360 
361  m_ButtonDeleteOneAlias->Enable( true );
362 }
363 
364 
366 {
367  wxString aliasname = m_PartAliasListCtrl->GetStringSelection();
368 
369  if( aliasname.IsEmpty() )
370  return;
371 
372  if( aliasname.CmpNoCase( m_Parent->GetAliasName() ) == 0 )
373  {
374  wxString msg;
375  msg.Printf( _( "Alias <%s> cannot be removed while it is being edited!" ),
376  GetChars( aliasname ) );
377  DisplayError( this, msg );
378  return;
379  }
380 
381  m_PartAliasListCtrl->Delete( m_PartAliasListCtrl->GetSelection() );
382  LIB_PART* component = m_Parent->GetCurPart();
383 
384  if( component )
385  component->RemoveAlias( aliasname );
386 
387  if( m_PartAliasListCtrl->IsEmpty() )
388  {
389  m_ButtonDeleteAllAlias->Enable( false );
390  m_ButtonDeleteOneAlias->Enable( false );
391  }
392 }
393 
394 
395 /*
396  * Change the number of parts per package.
397  */
399 {
400  LIB_PART* part = m_Parent->GetCurPart();
401 
402  if( !part || part->GetUnitCount() == MaxUnit || MaxUnit < 1 )
403  return false;
404 
405  if( MaxUnit < part->GetUnitCount()
406  && !IsOK( this, _( "Delete extra parts from component?" ) ) )
407  return false;
408 
409  part->SetUnitCount( MaxUnit );
410  return true;
411 }
412 
413 
414 /*
415  * Set or clear the component alternate body style ( DeMorgan ).
416  */
418 {
419  LIB_PART* component = m_Parent->GetCurPart();
420 
421  if( component == NULL || ( m_Parent->GetShowDeMorgan() == component->HasConversion() ) )
422  return false;
423 
424  if( m_Parent->GetShowDeMorgan() )
425  {
426  if( !IsOK( this, _( "Add new pins for alternate body style ( DeMorgan ) to component?" ) ) )
427  return false;
428  }
429  else if( component->HasConversion() )
430  {
431  if( !IsOK( this, _( "Delete alternate body style (DeMorgan) draw items from component?" ) ) )
432  {
433  m_Parent->SetShowDeMorgan( true );
434  return false;
435  }
436  }
437 
438  component->SetConversion( m_Parent->GetShowDeMorgan() );
439  m_Parent->OnModify();
440 
441  return true;
442 }
443 
444 
446 {
447  PROJECT& prj = Prj();
448  SEARCH_STACK* search = prj.SchSearchS();
449 
450  wxString mask = wxT( "*" );
451  wxString docpath = prj.GetRString( PROJECT::DOC_PATH );
452 
453  if( !docpath )
454  docpath = search->LastVisitedPath( wxT( "doc" ) );
455 
456  wxString fullFileName = EDA_FILE_SELECTOR( _( "Doc Files" ),
457  docpath,
458  wxEmptyString,
459  wxEmptyString,
460  mask,
461  this,
462  wxFD_OPEN,
463  true );
464  if( fullFileName.IsEmpty() )
465  return;
466 
467  /* If the path is already in the library search paths
468  * list, just add the library name to the list. Otherwise, add
469  * the library name with the full or relative path.
470  * the relative path, when possible is preferable,
471  * because it preserve use of default libraries paths, when the path is a sub path of
472  * these default paths
473  */
474  wxFileName fn = fullFileName;
475 
476  prj.SetRString( PROJECT::DOC_PATH, fn.GetPath() );
477 
478  wxString filename = search->FilenameWithRelativePathInSearchList(
479  fullFileName, wxPathOnly( Prj().GetProjectFullName() ) );
480 
481  // Filenames are always stored in unix like mode, ie separator "\" is stored as "/"
482  // to ensure files are identical under unices and windows
483 #ifdef __WINDOWS__
484  filename.Replace( wxT( "\\" ), wxT( "/" ) );
485 #endif
486  m_DocfileCtrl->SetValue( filename );
487 }
488 
489 
491 {
492  if( IsOK( this, _( "OK to delete the footprint filter list ?" ) ) )
493  {
494  m_FootprintFilterListBox->Clear();
495  m_ButtonDeleteAllFootprintFilter->Enable( false );
496  m_ButtonDeleteOneFootprintFilter->Enable( false );
497  m_buttonEditOneFootprintFilter->Enable( false );
498  }
499 }
500 
501 
502 /* Add a new name to the footprint filter list box
503  * Obvioulsy, cannot be void
504  */
506 {
507  wxString Line;
508  LIB_PART* component = m_Parent->GetCurPart();
509 
510  if( component == NULL )
511  return;
512 
513  wxTextEntryDialog dlg( this, _( "Add Footprint Filter" ), _( "Footprint Filter" ), Line );
514  if( dlg.ShowModal() != wxID_OK )
515  return; // cancelled by user
516 
517  Line = dlg.GetValue();
518  Line.Replace( wxT( " " ), wxT( "_" ) );
519 
520  if( Line.IsEmpty() )
521  return;
522 
523  /* test for an existing name: */
524  int index = m_FootprintFilterListBox->FindString( Line );
525 
526  if( index != wxNOT_FOUND )
527  {
528  wxString msg;
529 
530  msg.Printf( _( "Foot print filter <%s> is already defined." ), GetChars( Line ) );
531  DisplayError( this, msg );
532  return;
533  }
534 
535  m_FootprintFilterListBox->Append( Line );
536  m_ButtonDeleteAllFootprintFilter->Enable( true );
537  m_ButtonDeleteOneFootprintFilter->Enable( true );
538  m_buttonEditOneFootprintFilter->Enable( true );
539 }
540 
541 
543 {
544  LIB_PART* component = m_Parent->GetCurPart();
545  int ii = m_FootprintFilterListBox->GetSelection();
546 
547  m_FootprintFilterListBox->Delete( ii );
548 
549  if( !component || ( m_FootprintFilterListBox->GetCount() == 0 ) )
550  {
551  m_ButtonDeleteAllFootprintFilter->Enable( false );
552  m_ButtonDeleteOneFootprintFilter->Enable( false );
553  m_buttonEditOneFootprintFilter->Enable( false );
554  }
555 }
556 
558 {
559  int idx = m_FootprintFilterListBox->GetSelection();
560 
561  if( idx < 0 )
562  return;
563 
564  wxString filter = m_FootprintFilterListBox->GetStringSelection();
565 
566  wxTextEntryDialog dlg( this, wxEmptyString, _( "Edit footprint filter" ), filter );
567 
568  if( dlg.ShowModal() != wxID_OK )
569  return; // Aborted by user
570 
571  filter = dlg.GetValue();
572 
573  if( filter.IsEmpty() )
574  return; // do not accept blank filter.
575 
576  m_FootprintFilterListBox->SetString( idx, filter );
577 }
578 
579 
581 {
582  if( m_SelNumberOfUnits->GetValue() <= 1 )
583  m_OptionPartsLocked->Enable( false );
584  else
585  m_OptionPartsLocked->Enable( true );
586 }
bool UnitsLocked() const
Part library alias object definition.
void SetConversion(bool aSetConvert)
Set or clear the alternate body style (DeMorgan) for the part.
void SetPower()
DIALOG_EDIT_COMPONENT_IN_LIBRARY(LIB_EDIT_FRAME *parent)
Constructors.
Class PROJECT holds project specific data.
Definition: project.h:56
PART_LIB * GetCurLib()
The current library being edited, or NULL if none.
int GetPinNameOffset()
bool HasConversion() const
Test if part has more than one body conversion type (DeMorgan).
This file is part of the common library TODO brief description.
bool IsPower() const
LIB_ALIAS * GetAlias(size_t aIndex)
This file is part of the common library.
void CopyDocFromRootToAlias(wxCommandEvent &event) override
void AddFootprintFilter(wxCommandEvent &event) override
void AddAliasOfPart(wxCommandEvent &event) override
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void OnUpdateInterchangeableUnits(wxUpdateUIEvent &event) override
void OnModify()
Function OnModify Must be called after a schematic change in order to set the "modify" flag of the cu...
Definition: libeditframe.h:369
#define MAX_UNIT_COUNT_PER_PACKAGE
The maximum number of units per package.
Definition: eeschema_id.h:48
Class SEARCH_STACK looks for files in a number of places.
Definition: search_stack.h:41
void DeleteAliasOfPart(wxCommandEvent &event) override
size_t GetAliasCount() const
void SetDocFileName(const wxString &aDocFileName)
void SetShowDeMorgan(bool show)
Definition: libeditframe.h:405
void OnCancelClick(wxCommandEvent &event) override
void OnOkClick(wxCommandEvent &event) override
bool ShowPinNames()
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
bool ShowPinNumbers()
void SetUnitCount(int count)
Set the units per part count.
const wxString & GetName() const
wxString GetDescription() const
wxString EDA_FILE_SELECTOR(const wxString &aTitle, const wxString &aPath, const wxString &aFileName, const wxString &aExtension, const wxString &aWildcard, wxWindow *aParent, int aStyle, const bool aKeepWorkingDirectory, const wxPoint &aPosition, wxString *aMruPath)
Function EDA_FILE_SELECTOR.
Definition: gestfich.cpp:82
const wxString GetName() const
Return the file name without path or extension.
Class LIB_PART defines a library part object.
void EditOneFootprintFilter(wxCommandEvent &event) override
void DeleteAllFootprintFilter(wxCommandEvent &event) override
void SetDescription(const wxString &aDescription)
void DeleteOneFootprintFilter(wxCommandEvent &event) override
VTBL_ENTRY void SetRString(RSTRING_T aStringId, const wxString &aString)
Function SetRString stores a "retained string", which is any session and project specific string iden...
Definition: project.cpp:162
int GetUnitCount() const
wxString GetDocFileName() const
void SetAliases(const wxArrayString &aAliasList)
const wxString & GetAliasName()
Definition: libeditframe.h:374
VTBL_ENTRY const wxString & GetRString(RSTRING_T aStringId)
Function GetRString returns a "retained string", which is any session and project specific string ide...
Definition: project.cpp:177
The component library editor main window.
Definition: libeditframe.h:51
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
see class PGM_BASE
void RemoveAlias(const wxString &aName)
bool GetShowDeMorgan()
Definition: libeditframe.h:403
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
void SetKeyWords(const wxString &aKeyWords)
const wxString LastVisitedPath(const wxString &aSubPathToSearch=wxEmptyString)
Function LastVisitedPath is a quirky function inherited from old code that seems to serve particular ...
wxArrayString GetAliasNames(bool aIncludeRoot=true) const
LIB_PART * GetCurPart()
Function GetCurPart returns the current part being edited, or NULL if none selected.
wxArrayString & GetFootPrints()
void DeleteAllAliasOfPart(wxCommandEvent &event) override
void BrowseAndSelectDocFile(wxCommandEvent &event) override
The common library.
Class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE.
Definition for part library class.
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
Class PART_LIB is used to load, save, search, and otherwise manipulate part library files...
wxString GetKeyWords() const
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:71
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Function IsOK displays a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:129
LIB_ALIAS * FindAlias(const wxString &aName)
Find LIB_ALIAS by aName.
Definition of class LIB_EDIT_FRAME.
wxString FilenameWithRelativePathInSearchList(const wxString &aFullFilename, const wxString &aBaseDir)
Function FilenameWithRelativePathInSearchList returns the shortest possible path which can be use lat...
void LockUnits(bool aLockUnits)
void SetNormal()
void SaveCopyInUndoList(EDA_ITEM *ItemToCopy)
Function SaveCopyInUndoList.