KiCad PCB EDA Suite
symbol_editor_import_export.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) 2016 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 <confirm.h>
27 #include <symbol_lib_table.h>
28 #include <symbol_edit_frame.h>
29 #include <class_library.h>
31 #include <symbol_library_manager.h>
32 #include <wx/filename.h>
33 
34 
36 {
37  wxString msg;
38  wxString libName = getTargetLib();
39 
40  if( !m_libMgr->LibraryExists( libName ) )
41  {
42  libName = SelectLibraryFromList();
43 
44  if( !m_libMgr->LibraryExists( libName ) )
45  return;
46  }
47 
48  wxString wildcards = KiCadSymbolLibFileWildcard();
49 
50  wildcards += "|" + LegacySymbolLibFileWildcard();
51 
52  wxFileDialog dlg( this, _( "Import Symbol" ), m_mruPath, wxEmptyString,
53  wildcards, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
54 
55  if( dlg.ShowModal() == wxID_CANCEL )
56  return;
57 
58  wxFileName fn = dlg.GetPath();
59 
60  if( fn.GetExt().IsEmpty() )
61  fn.SetExt( (dlg.GetFilterIndex() == 0) ?
63 
64  m_mruPath = fn.GetPath();
65 
66  wxArrayString symbols;
67  SCH_IO_MGR::SCH_FILE_T piType = SCH_IO_MGR::GuessPluginTypeFromLibPath( fn.GetFullPath() );
68  SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( piType ) );
69 
70  // TODO dialog to select the part to be imported if there is more than one
71  try
72  {
73  pi->EnumerateSymbolLib( symbols, fn.GetFullPath() );
74  }
75  catch( const IO_ERROR& ioe )
76  {
77  msg.Printf( _( "Cannot import symbol library \"%s\"." ), fn.GetFullPath() );
78  DisplayErrorMessage( this, msg, ioe.What() );
79  return;
80  }
81 
82  if( symbols.empty() )
83  {
84  msg.Printf( _( "Symbol library file \"%s\" is empty." ), fn.GetFullPath() );
85  DisplayError( this, msg );
86  return;
87  }
88 
89  wxString symbolName = symbols[0];
90  LIB_PART* entry = pi->LoadSymbol( fn.GetFullPath(), symbolName );
91 
92  if( m_libMgr->PartExists( symbols[0], libName ) )
93  {
94  msg.Printf( _( "Symbol \"%s\" already exists in library \"%s\"." ), symbolName, libName );
95  DisplayError( this, msg );
96  return;
97  }
98 
99  m_libMgr->UpdatePart( entry, libName );
100  SyncLibraries( false );
101  LoadPart( symbolName, libName, 1 );
102 }
103 
104 
106 {
107  wxString msg, title;
108  LIB_PART* part = getTargetPart();
109 
110  if( !part )
111  {
112  ShowInfoBarError( _( "There is no symbol selected to save." ) );
113  return;
114  }
115 
116  wxFileName fn;
117 
118  fn.SetName( part->GetName().Lower() );
119  fn.SetExt( KiCadSymbolLibFileExtension );
120 
121  wxFileDialog dlg( this, _( "Export Symbol" ), m_mruPath, fn.GetFullName(),
122  KiCadSymbolLibFileWildcard(), wxFD_SAVE );
123 
124  if( dlg.ShowModal() == wxID_CANCEL )
125  return;
126 
127  fn = dlg.GetPath();
128  fn.MakeAbsolute();
129 
130  LIB_PART* old_part = NULL;
131 
132  SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
133 
134  if( fn.FileExists() )
135  {
136  try
137  {
138  old_part = pi->LoadSymbol( fn.GetFullPath(), part->GetName() );
139  }
140  catch( const IO_ERROR& ioe )
141  {
142  msg.Printf( _( "Error occurred attempting to load symbol library file \"%s\"" ),
143  fn.GetFullPath() );
144  DisplayErrorMessage( this, msg, ioe.What() );
145  return;
146  }
147 
148  if( old_part )
149  {
150  msg.Printf( _( "Symbol \"%s\" already exists in \"%s\"." ),
151  part->GetName(),
152  fn.GetFullName() );
153 
154  KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
155  errorDlg.SetOKLabel( _( "Overwrite" ) );
156  errorDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
157 
158  if( errorDlg.ShowModal() == wxID_CANCEL )
159  return;
160  }
161  }
162 
163  if( fn.Exists() && !fn.IsDirWritable() )
164  {
165  msg.Printf( _( "Write permissions are required to save library \"%s\"." ),
166  fn.GetFullPath() );
167  DisplayError( this, msg );
168  return;
169  }
170 
171  try
172  {
173  if( !fn.FileExists() )
174  pi->CreateSymbolLib( fn.GetFullPath() );
175 
176  // The flattened symbol is most likely what the user would want. As some point in
177  // the future as more of the symbol library inheritance is implemented, this may have
178  // to be changes to save parts of inherited symbols.
179  pi->SaveSymbol( fn.GetFullPath(), part->Flatten().release() );
180  }
181  catch( const IO_ERROR& ioe )
182  {
183  msg.Printf( _( "Failed to create symbol library file \"%s\"" ), fn.GetFullPath() );
184  DisplayErrorMessage( this, msg, ioe.What() );
185  msg.Printf( _( "Error creating symbol library \"%s\"" ), fn.GetFullName() );
186  SetStatusText( msg );
187  return;
188  }
189 
190  m_mruPath = fn.GetPath();
191 
192  msg.Printf( _( "Symbol \"%s\" saved in library \"%s\"" ), part->GetName(), fn.GetFullPath() );
193  SetStatusText( msg );
194 
195  // See if the user wants it added to a library table (global or project)
196  SYMBOL_LIB_TABLE* libTable = selectSymLibTable( true );
197 
198  if( libTable )
199  {
200  if( !m_libMgr->AddLibrary( fn.GetFullPath(), libTable ) )
201  {
202  DisplayError( this, _( "Could not open the library file." ) );
203  return;
204  }
205 
206  bool globalTable = ( libTable == &SYMBOL_LIB_TABLE::GetGlobalLibTable() );
207  saveSymbolLibTables( globalTable, !globalTable );
208  }
209 }
static SCH_FILE_T GuessPluginTypeFromLibPath(const wxString &aLibPath)
Return a plugin type given a symbol library using the file extension of aLibPath.
Definition: sch_io_mgr.cpp:151
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:252
static SYMBOL_LIB_TABLE & GetGlobalLibTable()
void DoNotShowCheckbox(wxString file, int line)
Checks the 'do not show again' setting for the dialog.
Definition: confirm.cpp:55
wxString m_mruPath
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:265
wxString GetName() const override
Definition: lib_symbol.h:129
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:45
This file is part of the common library.
bool AddLibrary(const wxString &aFilePath, SYMBOL_LIB_TABLE *aTable)
Add an existing library.
const std::string LegacySymbolLibFileExtension
bool PartExists(const wxString &aAlias, const wxString &aLibrary) const
Return true if part with a specific alias exists in library (either original one or buffered).
LIB_PART * getTargetPart() const
Return either the library selected in the symbol tree, if context menu is active or the library that ...
bool UpdatePart(LIB_PART *aPart, const wxString &aLibrary)
Update the part buffer with a new version of the part.
SYMBOL_LIB_TABLE * selectSymLibTable(bool aOptional=false)
Display a dialog asking the user to select a symbol library table.
void LoadPart(const wxString &aLibrary, const wxString &aPart, int Unit)
#define NULL
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:29
wxString getTargetLib() const
Define a library symbol object.
Definition: lib_symbol.h:93
Definition of file extensions used in Kicad.
bool saveSymbolLibTables(bool aGlobal, bool aProject)
Save Symbol Library Tables to disk.
wxString SelectLibraryFromList()
Display a list of loaded libraries in the symbol library and allows the user to select a library.
wxString KiCadSymbolLibFileWildcard()
std::unique_ptr< LIB_PART > Flatten() const
Return a flattened symbol inheritance to the caller.
Definition: lib_symbol.cpp:334
wxString LegacySymbolLibFileWildcard()
Helper object to release a SCH_PLUGIN in the context of a potential thrown exception through its dest...
Definition: sch_io_mgr.h:473
bool LibraryExists(const wxString &aLibrary, bool aCheckEnabled=false) const
Return true if library exists.
#define _(s)
Definition: 3d_actions.cpp:33
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
int ShowModal() override
Definition: confirm.cpp:99
SYMBOL_LIBRARY_MANAGER * m_libMgr
Definition for part library class.
void SyncLibraries(bool aShowProgress, const wxString &aForceRefresh=wxEmptyString)
Synchronize the library manager to the symbol library table, and then the symbol tree to the library ...
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
const std::string KiCadSymbolLibFileExtension