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 #include <view/view.h>
45 
46 
48 {
49  LIB_PART* part = GetCurPart();
50 
51  // Exit if no library entry is selected or a command is in progress.
52  if( !part || ( GetDrawItem() && GetDrawItem()->GetFlags() ) )
53  return;
54 
55  PROJECT& prj = Prj();
56  SEARCH_STACK* search = prj.SchSearchS();
57 
59 
60  wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
61 
62  if( !default_path )
63  default_path = search->LastVisitedPath();
64 
65  wxFileDialog dlg( this, _( "Import Symbol" ), default_path,
66  wxEmptyString, SchematicSymbolFileWildcard(),
67  wxFD_OPEN | wxFD_FILE_MUST_EXIST );
68 
69  if( dlg.ShowModal() == wxID_CANCEL )
70  return;
71 
72  SetCrossHairPosition( wxPoint( 0, 0 ) );
75 
76  wxString filename = dlg.GetPath();
77 
78  prj.SetRString( PROJECT::SCH_LIB_PATH, filename );
79 
80  wxArrayString symbols;
81  SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
82 
83  wxString msg;
84 
85  try
86  {
87  pi->EnumerateSymbolLib( symbols, filename );
88  }
89  catch( const IO_ERROR& ioe )
90  {
91  msg.Printf( _( "Cannot import symbol library \"%s\"." ), filename );
92  DisplayErrorMessage( this, msg, ioe.What() );
93  return;
94  }
95 
96  if( symbols.empty() )
97  {
98  msg.Printf( _( "Symbol library file \"%s\" is empty." ), filename );
99  DisplayError( this, msg );
100  return;
101  }
102 
103  if( symbols.GetCount() > 1 )
104  {
105  msg.Printf( _( "More than one symbol found in symbol file \"%s\"." ), filename );
106  wxMessageBox( msg, _( "Warning" ), wxOK | wxICON_EXCLAMATION, this );
107  }
108 
109  LIB_ALIAS* alias = nullptr;
110 
111  try
112  {
113  alias = pi->LoadSymbol( filename, symbols[0] );
114  }
115  catch( const IO_ERROR& )
116  {
117  return;
118  }
119 
120  wxCHECK_RET( alias && alias->GetPart(), "Invalid symbol." );
121 
122  SaveCopyInUndoList( part );
123 
124  LIB_PART* first = alias->GetPart();
125  LIB_ITEMS_CONTAINER& drawList = first->GetDrawItems();
126 
127  for( LIB_ITEM& item : drawList )
128  {
129  if( item.Type() == LIB_FIELD_T )
130  continue;
131 
132  if( item.GetUnit() )
133  item.SetUnit( m_unit );
134 
135  if( item.GetConvert() )
136  item.SetConvert( m_convert );
137 
138  item.SetFlags( IS_NEW | SELECTED );
139 
140  LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
141 
142  newItem->SetParent( part );
143  part->AddDrawItem( newItem );
144  item.ClearSelected();
145  }
146 
147  part->RemoveDuplicateDrawItems();
148 
149  OnModify();
150 }
151 
152 
154 {
155  // Export the current part as a symbol (.sym file)
156  // this is the current part without its aliases and doc file
157  // because a .sym file is used to import graphics in a part being edited
158  LIB_PART* part = GetCurPart();
159 
160  if( !part || part->GetDrawItems().empty() )
161  return;
162 
163  PROJECT& prj = Prj();
164  SEARCH_STACK* search = prj.SchSearchS();
165 
166  wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
167 
168  if( !default_path )
169  default_path = search->LastVisitedPath();
170 
171  wxFileDialog dlg( this, _( "Export Symbol" ), default_path,
172  part->GetName() + "." + SchematicSymbolFileExtension,
174  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
175 
176  if( dlg.ShowModal() == wxID_CANCEL )
177  return;
178 
179  wxFileName fn = dlg.GetPath();
180 
181  /* The GTK file chooser doesn't return the file extension added to
182  * file name so add it here. */
183  if( fn.GetExt().IsEmpty() )
184  fn.SetExt( SchematicSymbolFileExtension );
185 
186  prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
187 
188  if( fn.FileExists() )
189  wxRemove( fn.GetFullPath() );
190 
191  SetStatusText( wxString::Format( _( "Saving symbol in \"%s\"" ), fn.GetPath() ) );
192 
193  SCH_PLUGIN::SCH_PLUGIN_RELEASER plugin( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
194 
195  try
196  {
197  PROPERTIES nodoc_props; // Doc file is useless for a .sym file
198  nodoc_props[ SCH_LEGACY_PLUGIN::PropNoDocFile ] = "";
199  plugin->CreateSymbolLib( fn.GetFullPath(), &nodoc_props );
200 
201  LIB_PART* saved_part = new LIB_PART( *part );
202  saved_part->RemoveAllAliases(); // useless in a .sym file
203  plugin->SaveSymbol( fn.GetFullPath(), saved_part, &nodoc_props );
204  }
205  catch( const IO_ERROR& ioe )
206  {
207  wxString msg = wxString::Format( _( "An error occurred saving symbol file \"%s\"" ),
208  fn.GetFullPath() );
209  DisplayErrorMessage( this, msg, ioe.What() );
210  }
211 }
212 
213 
215 {
216  if( LIB_PART* part = GetCurPart() )
217  {
218  const wxPoint& cross_hair = GetCrossHairPosition();
219 
220  wxPoint offset( -cross_hair.x, cross_hair.y );
221  part->SetOffset( offset );
222  OnModify();
223 
224  // Refresh the view without changing the viewport
225  auto view = GetGalCanvas()->GetView();
226  auto center = view->GetCenter();
227  center.x += offset.x;
228  center.y -= offset.y;
229  view->SetCenter( center );
230  view->RecacheAllItems();
231  }
232 }
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
const VECTOR2D & GetCenter() const
Function GetCenter() Returns the center point of this VIEW (in world space coordinates) ...
Definition: view.h:339
void SaveOneSymbol()
Saves the current symbol to a symbol file.
Definition: symbedit.cpp:153
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:47
Class SEARCH_STACK looks for files in a number of places.
Definition: search_stack.h:41
KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
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.
Definition of file extensions used in Kicad.
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
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:925
void PlaceAnchor()
Places an anchor reference coordinate for the current component.
Definition: symbedit.cpp:214
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