KiCad PCB EDA Suite
Loading...
Searching...
No Matches
remote_symbol_import_utils.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
21
22#include <common.h>
23#include <eeschema_settings.h>
24#include <lib_symbol.h>
26#include <pgm_base.h>
28#include <sch_edit_frame.h>
29#include <sch_symbol.h>
31#include <tool/tool_manager.h>
32#include <tools/sch_actions.h>
33
34#include <wx/ffile.h>
35#include <wx/filefn.h>
36#include <wx/intl.h>
37
38
39wxString SanitizeRemoteFileComponent( const wxString& aValue, const wxString& aDefault, bool aLower )
40{
41 wxString result = aValue;
42 result.Trim( true ).Trim( false );
43
44 if( result.IsEmpty() )
45 result = aDefault;
46
47 for( size_t i = 0; i < result.length(); ++i )
48 {
49 const wxUniChar ch = result[i];
50
51 if( !( wxIsalnum( ch ) || ch == '_' || ch == '-' || ch == '.' ) )
52 result[i] = '_';
53 }
54
55 return aLower ? result.Lower() : result;
56}
57
58
60{
62 wxString prefix = settings ? settings->m_RemoteSymbol.library_prefix : wxString();
63
64 if( prefix.IsEmpty() )
66
67 return SanitizeRemoteFileComponent( prefix, wxS( "remote" ), true );
68}
69
70
71bool WriteRemoteBinaryFile( const wxFileName& aOutput, const std::vector<uint8_t>& aPayload,
72 wxString& aError )
73{
74 if( aPayload.empty() )
75 {
76 aError = _( "Payload was empty." );
77 return false;
78 }
79
80 wxFileName targetDir = aOutput;
81 targetDir.SetFullName( wxEmptyString );
82
83 if( !targetDir.DirExists() && !targetDir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
84 {
85 aError = wxString::Format( _( "Unable to create '%s'." ), targetDir.GetFullPath() );
86 return false;
87 }
88
89 wxFFile file( aOutput.GetFullPath(), wxS( "wb" ) );
90
91 if( !file.IsOpened() )
92 {
93 aError = wxString::Format( _( "Unable to open '%s' for writing." ), aOutput.GetFullPath() );
94 return false;
95 }
96
97 if( file.Write( aPayload.data(), aPayload.size() ) != aPayload.size() )
98 {
99 aError = wxString::Format( _( "Failed to write '%s'." ), aOutput.GetFullPath() );
100 return false;
101 }
102
103 file.Close();
104 return true;
105}
106
107
108bool EnsureRemoteDestinationRoot( wxFileName& aOutDir, wxString& aError )
109{
111
112 if( !settings )
113 {
114 aError = _( "Unable to load schematic settings." );
115 return false;
116 }
117
118 wxString destination = settings->m_RemoteSymbol.destination_dir;
119
120 if( destination.IsEmpty() )
122
123 destination = ExpandEnvVarSubstitutions( destination, &Pgm().GetSettingsManager().Prj() );
124 destination.Trim( true ).Trim( false );
125
126 if( destination.IsEmpty() )
127 {
128 aError = _( "Destination directory is not configured." );
129 return false;
130 }
131
132 wxFileName dir = wxFileName::DirName( destination );
133 dir.Normalize( FN_NORMALIZE_FLAGS );
134
135 if( !dir.DirExists() && !dir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
136 {
137 aError = wxString::Format( _( "Unable to create directory '%s'." ), dir.GetFullPath() );
138 return false;
139 }
140
141 aOutDir = dir;
142 return true;
143}
144
145
146bool EnsureRemoteLibraryEntry( LIBRARY_TABLE_TYPE aTableType, const wxFileName& aLibraryPath,
147 const wxString& aNickname, bool aGlobalTable, bool aStrict,
148 wxString& aError )
149{
151 std::optional<LIBRARY_TABLE*> tableOpt = manager.Table(
152 aTableType,
154
155 if( !tableOpt )
156 {
157 if( aStrict )
158 aError = _( "Unable to access the library table." );
159
160 return !aStrict;
161 }
162
163 LIBRARY_TABLE* table = *tableOpt;
164 const wxString fullPath = aLibraryPath.GetFullPath();
165
166 if( table->HasRow( aNickname ) )
167 {
168 if( std::optional<LIBRARY_TABLE_ROW*> rowOpt = table->Row( aNickname ); rowOpt )
169 {
170 LIBRARY_TABLE_ROW* row = *rowOpt;
171
172 if( row->URI() != fullPath )
173 {
174 row->SetURI( fullPath );
175
176 if( !table->Save() )
177 {
178 aError = _( "Failed to update the library table." );
179 return false;
180 }
181 }
182 }
183
184 return true;
185 }
186
187 LIBRARY_TABLE_ROW& row = table->InsertRow();
188 row.SetNickname( aNickname );
189 row.SetURI( fullPath );
190 row.SetType( wxS( "KiCad" ) );
191 row.SetOptions( wxString() );
192 row.SetDescription( _( "Remote download" ) );
193 row.SetOk( true );
194
195 if( !table->Save() )
196 {
197 aError = _( "Failed to save the library table." );
198 return false;
199 }
200
201 return true;
202}
203
204
205bool PlaceRemoteDownloadedSymbol( SCH_EDIT_FRAME* aFrame, const wxString& aNickname,
206 const wxString& aLibItemName, wxString& aError )
207{
208 if( !aFrame )
209 {
210 aError = _( "No schematic editor is available for placement." );
211 return false;
212 }
213
214 LIB_ID libId;
215 libId.SetLibNickname( aNickname );
216 libId.SetLibItemName( aLibItemName );
217
218 LIB_SYMBOL* libSymbol = aFrame->GetLibSymbol( libId );
219
220 if( !libSymbol )
221 {
222 aError = _( "Unable to load the downloaded symbol for placement." );
223 return false;
224 }
225
226 SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libId, &aFrame->GetCurrentSheet(), 1 );
227 symbol->SetParent( aFrame->GetScreen() );
228
229 if( EESCHEMA_SETTINGS* cfg = aFrame->eeconfig(); cfg && cfg->m_AutoplaceFields.enable )
230 symbol->AutoplaceFields( nullptr, AUTOPLACE_AUTO );
231
232 TOOL_MANAGER* toolMgr = aFrame->GetToolManager();
233
234 if( !toolMgr )
235 {
236 delete symbol;
237 aError = _( "Unable to access the schematic placement tools." );
238 return false;
239 }
240
241 aFrame->Raise();
243 SCH_ACTIONS::PLACE_SYMBOL_PARAMS{ symbol, true } );
244 return true;
245}
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:93
REMOTE_PROVIDER_SETTINGS m_RemoteSymbol
AUTOPLACE_FIELDS m_AutoplaceFields
std::optional< LIBRARY_TABLE * > Table(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope)
Retrieves a given table; creating a new empty project table if a valid project is loaded and the give...
void SetOptions(const wxString &aOptions)
void SetNickname(const wxString &aNickname)
void SetOk(bool aOk=true)
void SetType(const wxString &aType)
void SetDescription(const wxString &aDescription)
void SetURI(const wxString &aUri)
const wxString & URI() const
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:49
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition lib_id.cpp:111
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:100
Define a library symbol object.
Definition lib_symbol.h:83
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:133
static TOOL_ACTION placeSymbol
Definition sch_actions.h:66
EESCHEMA_SETTINGS * eeconfig() const
LIB_SYMBOL * GetLibSymbol(const LIB_ID &aLibId, bool aUseCacheLib=false, bool aShowErrorMsg=false)
Load symbol from symbol library table.
Schematic editor (Eeschema) main window.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCH_SHEET_PATH & GetCurrentSheet() const
Schematic symbol object.
Definition sch_symbol.h:76
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
Automatically orient all the fields in the symbol.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Master controller class:
bool PostAction(const std::string &aActionName, T aParam)
Run the specified action after the current action (coroutine) ends.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition common.cpp:558
The common library.
#define _(s)
PROJECT & Prj()
Definition kicad.cpp:642
LIBRARY_TABLE_TYPE
SETTINGS_MANAGER * GetSettingsManager()
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
bool PlaceRemoteDownloadedSymbol(SCH_EDIT_FRAME *aFrame, const wxString &aNickname, const wxString &aLibItemName, wxString &aError)
Place a symbol from a remote download into the schematic editor.
bool EnsureRemoteLibraryEntry(LIBRARY_TABLE_TYPE aTableType, const wxFileName &aLibraryPath, const wxString &aNickname, bool aGlobalTable, bool aStrict, wxString &aError)
Add or update a library table entry for a remote download library.
bool WriteRemoteBinaryFile(const wxFileName &aOutput, const std::vector< uint8_t > &aPayload, wxString &aError)
Write binary data to a file, creating parent directories as needed.
bool EnsureRemoteDestinationRoot(wxFileName &aOutDir, wxString &aError)
Resolve and create the configured destination root directory for remote symbol downloads.
wxString RemoteLibraryPrefix()
Return the configured (or default) library prefix for remote downloads, sanitized for use as a filena...
wxString SanitizeRemoteFileComponent(const wxString &aValue, const wxString &aDefault, bool aLower)
Replace non-alphanumeric characters (other than _ - .) with underscores.
@ AUTOPLACE_AUTO
Definition sch_item.h:71
T * GetAppSettings(const char *aFilename)
wxString result
Test unit parsing edge cases and error handling.
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition wx_filename.h:39