KiCad PCB EDA Suite
symbedit.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) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2004-2017 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 
31 #include <fctsys.h>
32 #include <kiway.h>
33 #include <pgm_base.h>
34 #include <sch_draw_panel.h>
35 #include <confirm.h>
36 #include <kicad_string.h>
37 #include <gestfich.h>
38 
39 #include <lib_edit_frame.h>
40 #include <class_libentry.h>
42 #include <sch_legacy_plugin.h>
43 #include <properties.h>
44 
45 
47 {
48  LIB_PART* part = GetCurPart();
49 
50  // Exit if no library entry is selected or a command is in progress.
51  if( !part || ( GetDrawItem() && GetDrawItem()->GetFlags() ) )
52  return;
53 
54  PROJECT& prj = Prj();
55  SEARCH_STACK* search = prj.SchSearchS();
56 
58 
59  wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
60 
61  if( !default_path )
62  default_path = search->LastVisitedPath();
63 
64  wxFileDialog dlg( this, _( "Import Symbol" ), default_path,
65  wxEmptyString, SchematicSymbolFileWildcard(),
66  wxFD_OPEN | wxFD_FILE_MUST_EXIST );
67 
68  if( dlg.ShowModal() == wxID_CANCEL )
69  return;
70 
71  SetCrossHairPosition( wxPoint( 0, 0 ) );
74 
75  wxString filename = dlg.GetPath();
76 
77  prj.SetRString( PROJECT::SCH_LIB_PATH, filename );
78 
79  wxArrayString symbols;
80  SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
81 
82  wxString msg;
83 
84  try
85  {
86  pi->EnumerateSymbolLib( symbols, filename );
87  }
88  catch( const IO_ERROR& ioe )
89  {
90  msg.Printf( _( "Cannot import symbol library \"%s\"." ), filename );
91  DisplayErrorMessage( this, msg, ioe.What() );
92  return;
93  }
94 
95  if( symbols.empty() )
96  {
97  msg.Printf( _( "Symbol library file \"%s\" is empty." ), filename );
98  DisplayError( this, msg );
99  return;
100  }
101 
102  if( symbols.GetCount() > 1 )
103  {
104  msg.Printf( _( "More than one symbol found in symbol file \"%s\"." ), filename );
105  wxMessageBox( msg, _( "Warning" ), wxOK | wxICON_EXCLAMATION, this );
106  }
107 
108  LIB_ALIAS* alias = nullptr;
109 
110  try
111  {
112  alias = pi->LoadSymbol( filename, symbols[0] );
113  }
114  catch( const IO_ERROR& )
115  {
116  return;
117  }
118 
119  wxCHECK_RET( alias && alias->GetPart(), "Invalid symbol." );
120 
121  SaveCopyInUndoList( part );
122 
123  LIB_PART* first = alias->GetPart();
124  LIB_ITEMS_CONTAINER& drawList = first->GetDrawItems();
125 
126  for( LIB_ITEM& item : drawList )
127  {
128  if( item.Type() == LIB_FIELD_T )
129  continue;
130 
131  if( item.GetUnit() )
132  item.SetUnit( m_unit );
133 
134  if( item.GetConvert() )
135  item.SetConvert( m_convert );
136 
137  item.SetFlags( IS_NEW | SELECTED );
138 
139  LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
140 
141  newItem->SetParent( part );
142  part->AddDrawItem( newItem );
143  item.ClearSelected();
144  }
145 
146  part->RemoveDuplicateDrawItems();
147 
148  OnModify();
149 }
150 
151 
153 {
154  // Export the current part as a symbol (.sym file)
155  // this is the current part without its aliases and doc file
156  // because a .sym file is used to import graphics in a part being edited
157  LIB_PART* part = GetCurPart();
158 
159  if( !part || part->GetDrawItems().empty() )
160  return;
161 
162  PROJECT& prj = Prj();
163  SEARCH_STACK* search = prj.SchSearchS();
164 
165  wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
166 
167  if( !default_path )
168  default_path = search->LastVisitedPath();
169 
170  wxFileDialog dlg( this, _( "Export Symbol" ), default_path,
171  part->GetName() + "." + SchematicSymbolFileExtension,
173  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
174 
175  if( dlg.ShowModal() == wxID_CANCEL )
176  return;
177 
178  wxFileName fn = dlg.GetPath();
179 
180  /* The GTK file chooser doesn't return the file extension added to
181  * file name so add it here. */
182  if( fn.GetExt().IsEmpty() )
183  fn.SetExt( SchematicSymbolFileExtension );
184 
185  prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
186 
187  if( fn.FileExists() )
188  wxRemove( fn.GetFullPath() );
189 
190  SetStatusText( wxString::Format( _( "Saving symbol in \"%s\"" ), fn.GetPath() ) );
191 
192  SCH_PLUGIN::SCH_PLUGIN_RELEASER plugin( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
193 
194  try
195  {
196  PROPERTIES nodoc_props; // Doc file is useless for a .sym file
197  nodoc_props[ SCH_LEGACY_PLUGIN::PropNoDocFile ] = "";
198  plugin->CreateSymbolLib( fn.GetFullPath(), &nodoc_props );
199 
200  LIB_PART* saved_part = new LIB_PART( *part );
201  saved_part->RemoveAllAliases(); // useless in a .sym file
202  plugin->SaveSymbol( fn.GetFullPath(), saved_part, &nodoc_props );
203  }
204  catch( const IO_ERROR& ioe )
205  {
206  wxString msg = wxString::Format( _( "An error occurred saving symbol file \"%s\"" ),
207  fn.GetFullPath() );
208  DisplayErrorMessage( this, msg, ioe.What() );
209  }
210 }
211 
212 
214 {
215  if( LIB_PART* part = GetCurPart() )
216  {
217  const wxPoint& cross_hair = GetCrossHairPosition();
218 
219  wxPoint offset( -cross_hair.x, cross_hair.y );
220  part->SetOffset( offset );
221  OnModify();
222  }
223 }
wxString SchematicSymbolFileWildcard()
virtual void CreateSymbolLib(const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
Create a new empty symbol library at aLibraryPath.
Definition: sch_plugin.cpp:126
void SaveOneSymbol()
Saves the current symbol to a symbol file.
Definition: symbedit.cpp:152
Part library alias object definition.
virtual LIB_ALIAS * LoadSymbol(const wxString &aLibraryPath, const wxString &aAliasName, const PROPERTIES *aProperties=NULL)
Load a LIB_ALIAS object having aAliasName from the aLibraryPath containing a library format that this...
Definition: sch_plugin.cpp:93
Class PROJECT holds project specific data.
Definition: project.h:57
static int m_convert
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Function DisplayErrorMessage displays an error message with aMessage.
Definition: confirm.cpp:259
This file is part of the common library TODO brief description.
This file is part of the common library.
virtual EDA_ITEM * Clone() const
Function Clone creates a duplicate of this item with linked list members set to NULL.
bool empty(int aType=UNDEFINED_TYPE)
Definition: multivector.h:224
virtual void EnumerateSymbolLib(wxArrayString &aAliasNameList, const wxString &aLibraryPath, const PROPERTIES *aProperties=NULL)
Populate a list of LIB_PART alias names contained within the library aLibraryPath.
Definition: sch_plugin.cpp:75
const std::string SchematicSymbolFileExtension
void OnModify()
Must be called after a schematic change in order to set the "modify" flag of the current screen...
void LoadOneSymbol()
Read a component symbol file (*.sym ) and add graphic items to the current component.
Definition: symbedit.cpp:46
Class SEARCH_STACK looks for files in a number of places.
Definition: search_stack.h:41
virtual void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Class PROPERTIES is a name/value tuple with unique names and optional values.
Definition: properties.h:34
The base class for drawable items used by schematic library components.
Definition: lib_draw_item.h:67
void AddDrawItem(LIB_ITEM *aItem)
Add a new draw aItem to the draw object list.
#define IS_NEW
New item, just created.
Definition: base_struct.h:114
PROJECT & Prj() const
Function Prj returns a reference to the PROJECT "associated with" this KIWAY.
#define SELECTED
Definition: base_struct.h:121
LIB_PART * GetCurPart() const
Return the current part being edited or NULL if none selected.
void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:216
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Class LIB_ITEM definition.
Define a library symbol object.
The common library.
static const char * PropNoDocFile
const char* PropBuffering
void RemoveDuplicateDrawItems()
Remove duplicate draw items from list.
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:171
LIB_PART * GetPart() const
Get the shared LIB_PART.
Helper object to release a SCH_PLUGIN in the context of a potential thrown exception through its dest...
Definition: sch_io_mgr.h:523
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:123
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:186
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:33
see class PGM_BASE
void RemoveAllAliases()
static int m_unit
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
const wxString LastVisitedPath(const wxString &aSubPathToSearch=wxEmptyString)
Function LastVisitedPath is a quirky function inherited from old code that seems to serve particular ...
void SaveCopyInUndoList(EDA_ITEM *ItemToCopy, UNDO_REDO_T undoType=UR_LIBEDIT)
Create a copy of the current component, and save it in the undo list.
LIB_ITEM * GetDrawItem() const
void SetIgnoreMouseEvents(bool aIgnore)
const wxString & GetName() const
Definition of class LIB_EDIT_FRAME.
virtual void SaveSymbol(const wxString &aLibraryPath, const LIB_PART *aSymbol, const PROPERTIES *aProperties=NULL)
Write aSymbol to an existing library located at aLibraryPath.
Definition: sch_plugin.cpp:102
void PlaceAnchor()
Places an anchor reference coordinate for the current component.
Definition: symbedit.cpp:213
void SetCrossHairPosition(const wxPoint &aPosition, bool aSnapToGrid=true)
Set the screen cross hair position to aPosition in logical (drawing) units.
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Return the current cross hair position in logical (drawing) coordinates.
Struct IO_ERROR is a class used to hold an error message and may be used when throwing exceptions con...
Definition: ki_exception.h:76