Escape "naughty" characters in symbol names.

It's tempting to say that we don't need to exclude filename chars
from symbols, but we might regret that decision down the road.  Better
to just escape them.

Fixes https://gitlab.com/kicad/code/kicad/issues/8694
This commit is contained in:
Jeff Young 2021-06-30 11:53:04 +01:00
parent 17737af130
commit b1b4caee6a
30 changed files with 118 additions and 81 deletions

View File

@ -213,7 +213,7 @@ void LIB_TREE_NODE_LIB_ID::UpdateScore( EDA_COMBINED_MATCHER& aMatcher )
if( !m_Normalized ) if( !m_Normalized )
{ {
m_MatchName = m_MatchName.Lower(); m_MatchName = UnescapeString( m_MatchName ).Lower();
m_SearchText = m_SearchText.Lower(); m_SearchText = m_SearchText.Lower();
m_Normalized = true; m_Normalized = true;
} }

View File

@ -29,6 +29,7 @@
#include <widgets/ui_common.h> #include <widgets/ui_common.h>
#include <wx/tokenzr.h> #include <wx/tokenzr.h>
#include <wx/wupdlock.h> #include <wx/wupdlock.h>
#include <kicad_string.h>
#define PINNED_ITEMS_KEY wxT( "PinnedItems" ) #define PINNED_ITEMS_KEY wxT( "PinnedItems" )
@ -455,7 +456,7 @@ void LIB_TREE_MODEL_ADAPTER::GetValue( wxVariant& aVariant,
{ {
default: // column == -1 is used for default Compare function default: // column == -1 is used for default Compare function
case 0: case 0:
aVariant = node->m_Name; aVariant = UnescapeString( node->m_Name );
break; break;
case 1: case 1:
aVariant = node->m_Desc; aVariant = node->m_Desc;

View File

@ -157,6 +157,14 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
{ {
if( c == '{' ) if( c == '{' )
converted += "{brace}"; converted += "{brace}";
else if( c == '/' )
converted += "{slash}";
else if( c == '\\' )
converted += "{backslash}";
else if( c == '<' )
converted += "{lt}";
else if( c == '>' )
converted += "{gt}";
else if( c == ':' ) else if( c == ':' )
converted += "{colon}"; converted += "{colon}";
else if( c == '\n' || c == '\r' ) else if( c == '\n' || c == '\r' )

View File

@ -606,7 +606,7 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_
if( i == REFERENCE_FIELD ) if( i == REFERENCE_FIELD )
aSymbol->SetRef( aInstance, UTIL::GetRefDesUnannotated( libField->GetText() ) ); aSymbol->SetRef( aInstance, UTIL::GetRefDesUnannotated( libField->GetText() ) );
else if( i == VALUE_FIELD ) else if( i == VALUE_FIELD )
aSymbol->SetValue( aInstance, libField->GetText() ); aSymbol->SetValue( aInstance, UnescapeString( libField->GetText() ) );
else if( i == FOOTPRINT_FIELD ) else if( i == FOOTPRINT_FIELD )
aSymbol->SetFootprint( aInstance, libField->GetText() ); aSymbol->SetFootprint( aInstance, libField->GetText() );
else else

View File

@ -282,6 +282,9 @@ DIALOG_LIB_EDIT_ONE_FIELD::DIALOG_LIB_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent,
{ {
m_fieldId = aField->GetId(); m_fieldId = aField->GetId();
if( m_fieldId == VALUE_FIELD )
m_text = UnescapeString( aField->GetText() );
// When in the library editor, power symbols can be renamed. // When in the library editor, power symbols can be renamed.
m_isPower = false; m_isPower = false;
init(); init();

View File

@ -117,11 +117,16 @@ public:
void UpdateField( LIB_FIELD* aField ) void UpdateField( LIB_FIELD* aField )
{ {
aField->SetText( m_text ); wxString value = m_text;
if( m_fieldId == VALUE_FIELD )
value = EscapeString( value, CTX_LIBID );
aField->SetText( value );
// VALUE === symbol name, so update the parent symbol if it changes. // VALUE === symbol name, so update the parent symbol if it changes.
if( aField->GetId() == VALUE_FIELD && aField->GetParent() ) if( m_fieldId == VALUE_FIELD && aField->GetParent() )
aField->GetParent()->SetName( m_text ); aField->GetParent()->SetName( value );
updateText( aField ); updateText( aField );
} }

View File

@ -30,7 +30,6 @@
#include <confirm.h> #include <confirm.h>
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
#include <sch_draw_panel.h>
#include <sch_symbol.h> #include <sch_symbol.h>
#include <sch_reference_list.h> #include <sch_reference_list.h>
#include <schematic.h> #include <schematic.h>
@ -44,6 +43,8 @@
#include <wx/dcclient.h> #include <wx/dcclient.h>
#include <grid_tricks.h> #include <grid_tricks.h>
#include <widgets/grid_text_button_helpers.h> #include <widgets/grid_text_button_helpers.h>
#include <kicad_string.h>
#define COL_REFS 0 #define COL_REFS 0
#define COL_CURR_LIBID 1 #define COL_CURR_LIBID 1
@ -696,6 +697,11 @@ bool DIALOG_EDIT_SYMBOLS_LIBID::TransferDataFromWindow()
if( !validateLibIds() ) if( !validateLibIds() )
return false; return false;
auto getName = []( const LIB_ID& aLibId )
{
return UnescapeString( aLibId.GetLibItemName().wx_str() );
};
int row_max = m_grid->GetNumberRows() - 1; int row_max = m_grid->GetNumberRows() - 1;
for( int row = 0; row <= row_max; row++ ) for( int row = 0; row <= row_max; row++ )
@ -743,8 +749,8 @@ bool DIALOG_EDIT_SYMBOLS_LIBID::TransferDataFromWindow()
SCH_FIELD* value = candidate.m_Symbol->GetField( VALUE_FIELD ); SCH_FIELD* value = candidate.m_Symbol->GetField( VALUE_FIELD );
// If value is a proxy for the itemName then make sure it gets updated // If value is a proxy for the itemName then make sure it gets updated
if( candidate.m_Symbol->GetLibId().GetLibItemName().wx_str() == value->GetText() ) if( getName( candidate.m_Symbol->GetLibId() ) == value->GetText() )
candidate.m_Symbol->SetValue( id.GetLibItemName().wx_str() ); candidate.m_Symbol->SetValue( getName( id ) );
candidate.m_Symbol->SetLibId( id ); candidate.m_Symbol->SetLibId( id );
candidate.m_Symbol->SetLibSymbol( symbol->Flatten().release() ); candidate.m_Symbol->SetLibSymbol( symbol->Flatten().release() );

View File

@ -31,6 +31,7 @@
#include <sch_symbol.h> #include <sch_symbol.h>
#include <widgets/grid_text_button_helpers.h> #include <widgets/grid_text_button_helpers.h>
#include <widgets/wx_grid.h> #include <widgets/wx_grid.h>
#include <kicad_string.h>
#ifdef KICAD_SPICE #ifdef KICAD_SPICE
#include <dialog_spice_model.h> #include <dialog_spice_model.h>
@ -165,7 +166,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow()
m_grid->ProcessTableMessage( msg ); m_grid->ProcessTableMessage( msg );
adjustGridColumns( m_grid->GetRect().GetWidth() ); adjustGridColumns( m_grid->GetRect().GetWidth() );
m_SymbolNameCtrl->ChangeValue( m_libEntry->GetName() ); m_SymbolNameCtrl->ChangeValue( UnescapeString( m_libEntry->GetName() ) );
m_DescCtrl->ChangeValue( m_libEntry->GetDescription() ); m_DescCtrl->ChangeValue( m_libEntry->GetDescription() );
m_KeywordCtrl->ChangeValue( m_libEntry->GetKeyWords() ); m_KeywordCtrl->ChangeValue( m_libEntry->GetKeyWords() );
@ -200,7 +201,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow()
wxCHECK( rootSymbol, false ); wxCHECK( rootSymbol, false );
wxString parentName = rootSymbol->GetName(); wxString parentName = UnescapeString( rootSymbol->GetName() );
int selection = m_inheritanceSelectCombo->FindString( parentName ); int selection = m_inheritanceSelectCombo->FindString( parentName );
wxCHECK( selection != wxNOT_FOUND, false ); wxCHECK( selection != wxNOT_FOUND, false );
@ -312,7 +313,8 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
wxString msg; wxString msg;
msg.Printf( _( "The name '%s' conflicts with an existing entry in the library '%s'." ), msg.Printf( _( "The name '%s' conflicts with an existing entry in the library '%s'." ),
newName, libName ); UnescapeString( newName ),
libName );
DisplayErrorMessage( this, msg ); DisplayErrorMessage( this, msg );
return false; return false;
} }
@ -339,7 +341,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
// Update the parent for inherited symbols // Update the parent for inherited symbols
if( m_libEntry->IsAlias() ) if( m_libEntry->IsAlias() )
{ {
wxString parentName = m_inheritanceSelectCombo->GetValue(); wxString parentName = EscapeString( m_inheritanceSelectCombo->GetValue(), CTX_LIBID );
// The parentName was verified to be non-empty in the Validator // The parentName was verified to be non-empty in the Validator
wxString libName = m_Parent->GetCurLib(); wxString libName = m_Parent->GetCurLib();
@ -435,7 +437,9 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
} }
} }
else if( event.GetRow() == VALUE_FIELD && event.GetCol() == FDC_VALUE ) else if( event.GetRow() == VALUE_FIELD && event.GetCol() == FDC_VALUE )
{
m_SymbolNameCtrl->ChangeValue( event.GetString() ); m_SymbolNameCtrl->ChangeValue( event.GetString() );
}
editor->DecRef(); editor->DecRef();
} }

View File

@ -781,7 +781,7 @@ void DIALOG_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
if( newName.CmpNoCase( m_fieldsGrid->GetCellValue( i, FDC_NAME ) ) == 0 ) if( newName.CmpNoCase( m_fieldsGrid->GetCellValue( i, FDC_NAME ) ) == 0 )
{ {
DisplayError( this, wxString::Format( _( "The name '%s' is already in use." ), DisplayError( this, wxString::Format( _( "Field name '%s' already in use." ),
newName ) ); newName ) );
event.Veto(); event.Veto();
m_delayedFocusRow = event.GetRow(); m_delayedFocusRow = event.GetRow();

View File

@ -25,6 +25,7 @@
#include <lib_symbol.h> #include <lib_symbol.h>
#include <symbol_edit_frame.h> #include <symbol_edit_frame.h>
#include <template_fieldnames.h> #include <template_fieldnames.h>
#include <kicad_string.h>
bool g_removeExtraLibFields = false; bool g_removeExtraLibFields = false;
@ -44,7 +45,7 @@ DIALOG_UPDATE_SYMBOL_FIELDS::DIALOG_UPDATE_SYMBOL_FIELDS( SYMBOL_EDIT_FRAME* aPa
wxASSERT( aParent ); wxASSERT( aParent );
wxASSERT( aSymbol ); wxASSERT( aSymbol );
m_parentSymbolReadOnly->SetValue( m_symbol->GetParent().lock()->GetName() ); m_parentSymbolReadOnly->SetValue( UnescapeString( m_symbol->GetParent().lock()->GetName() ) );
for( int i = 0; i < MANDATORY_FIELDS; ++i ) for( int i = 0; i < MANDATORY_FIELDS; ++i )
{ {

View File

@ -503,7 +503,7 @@ void PANEL_SYM_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
{ {
wxString filePath = dlg.GetDirectory() + wxFileName::GetPathSeparator() + file; wxString filePath = dlg.GetDirectory() + wxFileName::GetPathSeparator() + file;
wxFileName fn( filePath ); wxFileName fn( filePath );
wxString nickname = LIB_ID::FixIllegalChars( fn.GetName() ); wxString nickname = LIB_ID::FixIllegalChars( fn.GetName(), true );
bool doAdd = true; bool doAdd = true;
if( cur_model()->ContainsNickname( nickname ) ) if( cur_model()->ContainsNickname( nickname ) )

View File

@ -36,6 +36,7 @@
#include <project/project_file.h> #include <project/project_file.h>
#include "eda_doc.h" #include "eda_doc.h"
#include <wx/settings.h> #include <wx/settings.h>
#include <kicad_string.h>
enum enum
@ -381,7 +382,7 @@ wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
return field.GetName( false ); return field.GetName( false );
case FDC_VALUE: case FDC_VALUE:
return field.GetText(); return UnescapeString( field.GetText() );
case FDC_SHOWN: case FDC_SHOWN:
return StringFromBool( field.IsVisible() ); return StringFromBool( field.IsVisible() );
@ -487,6 +488,10 @@ void FIELDS_GRID_TABLE<T>::SetValue( int aRow, int aCol, const wxString &aValue
value = fn.GetFullPath(); value = fn.GetFullPath();
} }
} }
else if( m_parentType == SCH_SYMBOL_T && aRow == VALUE_FIELD )
{
value = EscapeString( value, CTX_LIBID );
}
field.SetText( value ); field.SetText( value );
} }

View File

@ -106,7 +106,7 @@ public:
protected: protected:
void SetHtmlName() void SetHtmlName()
{ {
m_html.Replace( "__NAME__", EscapeHTML( m_symbol->GetName() ) ); m_html.Replace( "__NAME__", EscapeHTML( UnescapeString( m_symbol->GetName() ) ) );
} }
@ -130,7 +130,7 @@ protected:
} }
m_html.Replace( "__ALIASOF__", wxString::Format( AliasOfFormat, m_html.Replace( "__ALIASOF__", wxString::Format( AliasOfFormat,
EscapeHTML( root_name ), EscapeHTML( UnescapeString( root_name ) ),
EscapeHTML( root_desc ) ) ); EscapeHTML( root_desc ) ) );
} }
} }

View File

@ -313,12 +313,10 @@ wxString LIB_SYMBOL::GetUnitReference( int aUnit )
void LIB_SYMBOL::SetName( const wxString& aName ) void LIB_SYMBOL::SetName( const wxString& aName )
{ {
wxString validatedName = LIB_ID::FixIllegalChars( aName ); m_name = aName;
m_libId.SetLibItemName( aName, false );
m_name = validatedName; GetValueField().SetText( aName );
m_libId.SetLibItemName( validatedName, false );
GetValueField().SetText( validatedName );
} }

View File

@ -89,7 +89,7 @@ static void getSymbols( SCHEMATIC* aSchematic, std::vector<SCH_SYMBOL*>& aSymbol
static LIB_SYMBOL* findSymbol( const wxString& aName, SYMBOL_LIBS* aLibs, bool aCached ) static LIB_SYMBOL* findSymbol( const wxString& aName, SYMBOL_LIBS* aLibs, bool aCached )
{ {
LIB_SYMBOL *symbol = NULL; LIB_SYMBOL *symbol = NULL;
wxString new_name = LIB_ID::FixIllegalChars( aName ); wxString new_name = LIB_ID::FixIllegalChars( aName, false );
for( SYMBOL_LIB& each_lib : *aLibs ) for( SYMBOL_LIB& each_lib : *aLibs )
{ {
@ -150,7 +150,7 @@ void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
for( SCH_SYMBOL* eachSymbol : *( aRescuer.GetSymbols() ) ) for( SCH_SYMBOL* eachSymbol : *( aRescuer.GetSymbols() ) )
{ {
symbol_name = eachSymbol->GetLibId().GetLibItemName(); symbol_name = eachSymbol->GetLibId().GetLibItemName();
search_name = LIB_ID::FixIllegalChars( symbol_name ); search_name = LIB_ID::FixIllegalChars( symbol_name, false );
if( last_symbol_name != symbol_name ) if( last_symbol_name != symbol_name )
{ {
@ -255,7 +255,7 @@ void RESCUE_CACHE_CANDIDATE::FindRescues( RESCUER& aRescuer,
for( SCH_SYMBOL* eachSymbol : *( aRescuer.GetSymbols() ) ) for( SCH_SYMBOL* eachSymbol : *( aRescuer.GetSymbols() ) )
{ {
symbol_name = eachSymbol->GetLibId().GetLibItemName(); symbol_name = eachSymbol->GetLibId().GetLibItemName();
search_name = LIB_ID::FixIllegalChars( symbol_name ); search_name = LIB_ID::FixIllegalChars( symbol_name, false );
if( old_symbol_name != symbol_name ) if( old_symbol_name != symbol_name )
{ {
@ -426,7 +426,7 @@ void RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::FindRescues(
} }
// Fix illegal LIB_ID name characters. // Fix illegal LIB_ID name characters.
wxString new_name = LIB_ID::FixIllegalChars( symbol_id.GetLibItemName() ); wxString new_name = LIB_ID::FixIllegalChars( symbol_id.GetLibItemName(), false );
// Differentiate symbol name in the rescue library by appending the symbol library // Differentiate symbol name in the rescue library by appending the symbol library
// table nickname to the symbol name to prevent name clashes in the rescue library. // table nickname to the symbol name to prevent name clashes in the rescue library.

View File

@ -63,6 +63,7 @@
#include <kiface_i.h> #include <kiface_i.h>
#include <default_values.h> #include <default_values.h>
#include <advanced_config.h> #include <advanced_config.h>
#include <kicad_string.h>
#include "sch_painter.h" #include "sch_painter.h"
namespace KIGFX namespace KIGFX
@ -672,7 +673,7 @@ void SCH_PAINTER::draw( const LIB_FIELD *aField, int aLayer )
double orient = aField->GetTextAngleRadians(); double orient = aField->GetTextAngleRadians();
strokeText( aField->GetText(), pos, orient ); strokeText( UnescapeString( aField->GetText() ), pos, orient );
} }
// Draw the umbilical line // Draw the umbilical line

View File

@ -535,7 +535,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSchematicSymbolInstances()
// Name of the net that the symbol instance in CADSTAR refers to: // Name of the net that the symbol instance in CADSTAR refers to:
wxString symbolInstanceNetName = sym.SymbolVariant.Reference; wxString symbolInstanceNetName = sym.SymbolVariant.Reference;
symbolInstanceNetName = LIB_ID::FixIllegalChars( symbolInstanceNetName ); symbolInstanceNetName = EscapeString( symbolInstanceNetName, CTX_LIBID );
// Name of the symbol we will use for saving the part in KiCad // Name of the symbol we will use for saving the part in KiCad
// Note: In CADSTAR all power symbols will start have the reference name be // Note: In CADSTAR all power symbols will start have the reference name be

View File

@ -3006,7 +3006,7 @@ void SCH_EAGLE_PLUGIN::addImplicitConnections( SCH_SYMBOL* aSymbol, SCH_SCREEN*
wxString SCH_EAGLE_PLUGIN::fixSymbolName( const wxString& aName ) wxString SCH_EAGLE_PLUGIN::fixSymbolName( const wxString& aName )
{ {
wxString ret = LIB_ID::FixIllegalChars( aName ); wxString ret = EscapeString( aName, CTX_LIBID );
return ret; return ret;
} }

View File

@ -2734,7 +2734,7 @@ void SCH_LEGACY_PLUGIN_CACHE::loadDocs()
aliasName = wxString::FromUTF8( line ); aliasName = wxString::FromUTF8( line );
aliasName.Trim(); aliasName.Trim();
aliasName = LIB_ID::FixIllegalChars( aliasName ); aliasName = EscapeString( aliasName, CTX_LIBID );
LIB_SYMBOL_MAP::iterator it = m_symbols.find( aliasName ); LIB_SYMBOL_MAP::iterator it = m_symbols.find( aliasName );

View File

@ -36,6 +36,7 @@
#include <trigo.h> #include <trigo.h>
#include <refdes_utils.h> #include <refdes_utils.h>
#include <wx/log.h> #include <wx/log.h>
#include <kicad_string.h>
/** /**
* Convert a wxString to UTF8 and replace any control characters with a ~, * Convert a wxString to UTF8 and replace any control characters with a ~,
@ -791,9 +792,9 @@ void SCH_SYMBOL::UpdateFields( const SCH_SHEET_PATH* aPath, bool aUpdateStyle, b
else if( id == VALUE_FIELD ) else if( id == VALUE_FIELD )
{ {
if( aResetOtherFields ) if( aResetOtherFields )
SetValue( m_lib_id.GetLibItemName() ); // fetch alias-specific value SetValue( UnescapeString( m_lib_id.GetLibItemName() ) ); // alias-specific value
else else
SetValue( libField->GetText() ); SetValue( UnescapeString( libField->GetText() ) );
} }
else if( id == FOOTPRINT_FIELD ) else if( id == FOOTPRINT_FIELD )
{ {
@ -803,7 +804,7 @@ void SCH_SYMBOL::UpdateFields( const SCH_SHEET_PATH* aPath, bool aUpdateStyle, b
else if( id == DATASHEET_FIELD ) else if( id == DATASHEET_FIELD )
{ {
if( aResetOtherFields ) if( aResetOtherFields )
schField->SetText( GetDatasheet() ); // fetch alias-specific value schField->SetText( GetDatasheet() ); // alias-specific value
else if( aUpdateOtherFields ) else if( aUpdateOtherFields )
schField->SetText( libField->GetText() ); schField->SetText( libField->GetText() );
} }
@ -1360,12 +1361,13 @@ void SCH_SYMBOL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aList
aList.push_back( MSG_PANEL_ITEM( msg, GetValue( currentSheet, true ) ) ); aList.push_back( MSG_PANEL_ITEM( msg, GetValue( currentSheet, true ) ) );
#if 0 // Display symbol flags, for debug only #if 0 // Display symbol flags, for debug only
aList.push_back( MSG_PANEL_ITEM( _( "flags" ), wxString::Format( "%X", aList.push_back( MSG_PANEL_ITEM( _( "flags" ),
GetEditFlags() ) ) ); wxString::Format( "%X", GetEditFlags() ) ) );
#endif #endif
// Display symbol reference in library and library // Display symbol reference in library and library
aList.push_back( MSG_PANEL_ITEM( _( "Name" ), GetLibId().GetLibItemName() ) ); aList.push_back( MSG_PANEL_ITEM( _( "Name" ),
UnescapeString( GetLibId().GetLibItemName() ) ) );
if( !m_part->IsRoot() ) if( !m_part->IsRoot() )
{ {
@ -1376,7 +1378,7 @@ void SCH_SYMBOL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aList
if( parent ) if( parent )
msg = parent->GetName(); msg = parent->GetName();
aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), msg ) ); aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), UnescapeString( msg ) ) );
} }
else if( !m_lib_id.GetLibNickname().empty() ) else if( !m_lib_id.GetLibNickname().empty() )
{ {

View File

@ -52,14 +52,7 @@ SCH_FIELD_VALIDATOR::SCH_FIELD_VALIDATOR( bool aIsLibEditor, int aFieldId, wxSt
} }
else if( m_fieldId == SHEETNAME_V ) else if( m_fieldId == SHEETNAME_V )
{ {
// Does it make sense to exclude the colon and back slash characters? The forward slash excludes += wxT( "/" );
// makes sense because it is used as the separator when generating human readable sheet
// paths.
excludes += wxT( ":/\\" );
}
else if( aFieldId == VALUE_FIELD && m_isLibEditor )
{
excludes += wxT( " :/\\" );
} }
long style = GetStyle(); long style = GetStyle();

View File

@ -72,6 +72,7 @@
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>
#include <panel_sym_lib_table.h> #include <panel_sym_lib_table.h>
#include <wx/choicdlg.h> #include <wx/choicdlg.h>
#include <kicad_string.h>
bool SYMBOL_EDIT_FRAME::m_showDeMorgan = false; bool SYMBOL_EDIT_FRAME::m_showDeMorgan = false;
@ -748,10 +749,10 @@ void SYMBOL_EDIT_FRAME::SetCurSymbol( LIB_SYMBOL* aSymbol, bool aUpdateZoom )
wxString link; wxString link;
msg.Printf( _( "Symbol %s is derived from %s. Symbol graphics will not be editable." ), msg.Printf( _( "Symbol %s is derived from %s. Symbol graphics will not be editable." ),
symbolName, UnescapeString( symbolName ),
parentSymbolName ); UnescapeString( parentSymbolName ) );
link.Printf( _( "Open %s" ), parentSymbolName ); link.Printf( _( "Open %s" ), UnescapeString( parentSymbolName ) );
wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, link, wxEmptyString ); wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, link, wxEmptyString );
button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>( button->Bind( wxEVT_COMMAND_HYPERLINK, std::function<void( wxHyperlinkEvent& aEvent )>(

View File

@ -43,7 +43,7 @@
#include <wx/clipbrd.h> #include <wx/clipbrd.h>
#include <wx/filedlg.h> #include <wx/filedlg.h>
#include <wx/log.h> #include <wx/log.h>
#include <kicad_string.h>
/** /**
@ -692,17 +692,15 @@ void SYMBOL_EDIT_FRAME::UpdateAfterSymbolProperties( wxString* aOldName )
{ {
wxCHECK( m_symbol, /* void */ ); wxCHECK( m_symbol, /* void */ );
wxString msg; wxString lib = GetCurLib();
wxString lib = GetCurLib();
if( !lib.IsEmpty() && aOldName && *aOldName != m_symbol->GetName() ) if( !lib.IsEmpty() && aOldName && *aOldName != m_symbol->GetName() )
{ {
// Test the current library for name conflicts // Test the current library for name conflicts
if( m_libMgr->SymbolExists( m_symbol->GetName(), lib ) ) if( m_libMgr->SymbolExists( m_symbol->GetName(), lib ) )
{ {
msg.Printf( _( "The name '%s' conflicts with an existing entry in the library '%s'." ), wxString msg = wxString::Format( _( "Symbol name '%s' already in use." ),
m_symbol->GetName(), UnescapeString( m_symbol->GetName() ) );
lib );
DisplayErrorMessage( this, msg ); DisplayErrorMessage( this, msg );
m_symbol->SetName( *aOldName ); m_symbol->SetName( *aOldName );
@ -1185,14 +1183,14 @@ void SYMBOL_EDIT_FRAME::DisplaySymbolDatasheet()
wxString msg = m_symbol->GetName(); wxString msg = m_symbol->GetName();
AppendMsgPanel( _( "Name" ), msg, 8 ); AppendMsgPanel( _( "Name" ), UnescapeString( msg ), 8 );
if( m_symbol->IsAlias() ) if( m_symbol->IsAlias() )
{ {
LIB_SYMBOL_SPTR parent = m_symbol->GetParent().lock(); LIB_SYMBOL_SPTR parent = m_symbol->GetParent().lock();
msg = parent ? parent->GetName() : _( "Undefined!" ); msg = parent ? parent->GetName() : _( "Undefined!" );
AppendMsgPanel( _( "Parent" ), msg, 8 ); AppendMsgPanel( _( "Parent" ), UnescapeString( msg ), 8 );
} }
static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );

View File

@ -31,6 +31,7 @@
#include <symbol_library_manager.h> #include <symbol_library_manager.h>
#include <wx/filename.h> #include <wx/filename.h>
#include <wx/filedlg.h> #include <wx/filedlg.h>
#include <kicad_string.h>
void SYMBOL_EDIT_FRAME::ImportSymbol() void SYMBOL_EDIT_FRAME::ImportSymbol()
@ -149,7 +150,7 @@ void SYMBOL_EDIT_FRAME::ExportSymbol()
if( old_symbol ) if( old_symbol )
{ {
msg.Printf( _( "Symbol %s already exists in library '%s'." ), msg.Printf( _( "Symbol %s already exists in library '%s'." ),
symbol->GetName(), UnescapeString( symbol->GetName() ),
fn.GetFullName() ); fn.GetFullName() );
KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING ); KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
@ -190,7 +191,9 @@ void SYMBOL_EDIT_FRAME::ExportSymbol()
m_mruPath = fn.GetPath(); m_mruPath = fn.GetPath();
msg.Printf( _( "Symbol %s saved to library '%s'." ), symbol->GetName(), fn.GetFullPath() ); msg.Printf( _( "Symbol %s saved to library '%s'." ),
UnescapeString( symbol->GetName() ),
fn.GetFullPath() );
SetStatusText( msg ); SetStatusText( msg );
// See if the user wants it added to a library table (global or project) // See if the user wants it added to a library table (global or project)

View File

@ -39,6 +39,7 @@
#include <list> #include <list>
#include <locale_io.h> #include <locale_io.h>
#include <wx/log.h> #include <wx/log.h>
#include <kicad_string.h>
#include "lib_logger.h" #include "lib_logger.h"
@ -1091,7 +1092,8 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer(
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxLogError( errorMsg, cachedParent->GetName(), aFileName, ioe.What() ); wxLogError( errorMsg, UnescapeString( cachedParent->GetName() ), aFileName,
ioe.What() );
return false; return false;
} }
@ -1101,7 +1103,8 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer(
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxLogError( errorMsg, newCachedSymbol->GetName(), aFileName, ioe.What() ); wxLogError( errorMsg, UnescapeString( newCachedSymbol->GetName() ), aFileName,
ioe.What() );
return false; return false;
} }
@ -1121,7 +1124,8 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer(
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxLogError( errorMsg, newCachedSymbol->GetName(), aFileName, ioe.What() ); wxLogError( errorMsg, UnescapeString( newCachedSymbol->GetName() ), aFileName,
ioe.What() );
return false; return false;
} }
@ -1146,7 +1150,8 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer(
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxLogError( errorMsg, libSymbol->GetName(), aFileName, ioe.What() ); wxLogError( errorMsg, UnescapeString( libSymbol->GetName() ), aFileName,
ioe.What() );
return false; return false;
} }
@ -1163,7 +1168,8 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer(
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxLogError( errorMsg, libSymbol->GetName(), aFileName, ioe.What() ); wxLogError( errorMsg, UnescapeString( libSymbol->GetName() ), aFileName,
ioe.What() );
return false; return false;
} }
@ -1183,7 +1189,8 @@ bool SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::SaveBuffer(
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxLogError( errorMsg, derivedSymbol->GetName(), aFileName, ioe.What() ); wxLogError( errorMsg, UnescapeString( derivedSymbol->GetName() ), aFileName,
ioe.What() );
return false; return false;
} }
} }
@ -1235,7 +1242,7 @@ void SYMBOL_LIBRARY_MANAGER::LIB_BUFFER::GetRootSymbolNames( wxArrayString& aRoo
if( entry->GetSymbol()->IsAlias() ) if( entry->GetSymbol()->IsAlias() )
continue; continue;
aRootSymbolNames.Add( entry->GetSymbol()->GetName() ); aRootSymbolNames.Add( UnescapeString( entry->GetSymbol()->GetName() ) );
} }
} }

View File

@ -27,6 +27,7 @@
#include <symbol_library_manager.h> #include <symbol_library_manager.h>
#include <symbol_lib_table.h> #include <symbol_lib_table.h>
#include <tools/symbol_editor_control.h> #include <tools/symbol_editor_control.h>
#include <kicad_string.h>
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>
@ -158,10 +159,10 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNo
for( auto nodeIt = aLibNode.m_Children.begin(); nodeIt != aLibNode.m_Children.end(); /**/ ) for( auto nodeIt = aLibNode.m_Children.begin(); nodeIt != aLibNode.m_Children.end(); /**/ )
{ {
auto aliasIt = std::find_if( aliases.begin(), aliases.end(), auto aliasIt = std::find_if( aliases.begin(), aliases.end(),
[&] ( const LIB_SYMBOL* a ) [&] ( const LIB_SYMBOL* a )
{ {
return a->GetName() == (*nodeIt)->m_Name; return a->GetName() == (*nodeIt)->m_LibId.GetLibItemName();
} ); } );
if( aliasIt != aliases.end() ) if( aliasIt != aliases.end() )
{ {
@ -217,9 +218,9 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataVie
node->m_Name = m_frame->GetCurSymbol()->GetLibId().GetLibItemName(); node->m_Name = m_frame->GetCurSymbol()->GetLibId().GetLibItemName();
if( node->m_Pinned ) if( node->m_Pinned )
aVariant = GetPinningSymbol() + node->m_Name; aVariant = GetPinningSymbol() + UnescapeString( node->m_Name );
else else
aVariant = node->m_Name; aVariant = UnescapeString( node->m_Name );
// mark modified items with an asterisk // mark modified items with an asterisk
if( node->m_Type == LIB_TREE_NODE::LIB ) if( node->m_Type == LIB_TREE_NODE::LIB )

View File

@ -55,6 +55,7 @@
#include <wx/listbox.h> #include <wx/listbox.h>
#include <default_values.h> #include <default_values.h>
#include <kicad_string.h>
// Save previous symbol library viewer state. // Save previous symbol library viewer state.
wxString SYMBOL_VIEWER_FRAME::m_libraryName; wxString SYMBOL_VIEWER_FRAME::m_libraryName;
@ -361,8 +362,8 @@ void SYMBOL_VIEWER_FRAME::updatePreviewSymbol()
if( parent ) if( parent )
parentName = parent->GetName(); parentName = parent->GetName();
AppendMsgPanel( _( "Name" ), m_previewItem->GetName() ); AppendMsgPanel( _( "Name" ), UnescapeString( m_previewItem->GetName() ) );
AppendMsgPanel( _( "Parent" ), parentName ); AppendMsgPanel( _( "Parent" ), UnescapeString( parentName ) );
AppendMsgPanel( _( "Description" ), m_previewItem->GetDescription() ); AppendMsgPanel( _( "Description" ), m_previewItem->GetDescription() );
AppendMsgPanel( _( "Keywords" ), m_previewItem->GetKeyWords() ); AppendMsgPanel( _( "Keywords" ), m_previewItem->GetKeyWords() );
} }

View File

@ -529,7 +529,7 @@ void SYMBOL_EDITOR_EDIT_TOOL::editFieldProperties( LIB_FIELD* aField )
if( dlg.ShowQuasiModal() != wxID_OK ) if( dlg.ShowQuasiModal() != wxID_OK )
return; return;
wxString newFieldValue = LIB_ID::FixIllegalChars( dlg.GetText() ); wxString newFieldValue = EscapeString( dlg.GetText(), CTX_LIBID );
wxString oldFieldValue = aField->GetFullText( m_frame->GetUnit() ); wxString oldFieldValue = aField->GetFullText( m_frame->GetUnit() );
bool renamed = aField->GetId() == VALUE_FIELD && newFieldValue != oldFieldValue; bool renamed = aField->GetId() == VALUE_FIELD && newFieldValue != oldFieldValue;
@ -557,9 +557,8 @@ void SYMBOL_EDITOR_EDIT_TOOL::editFieldProperties( LIB_FIELD* aField )
void SYMBOL_EDITOR_EDIT_TOOL::editSymbolProperties() void SYMBOL_EDITOR_EDIT_TOOL::editSymbolProperties()
{ {
LIB_SYMBOL* symbol = m_frame->GetCurSymbol(); LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
bool partLocked = symbol->UnitsLocked(); bool partLocked = symbol->UnitsLocked();
wxString oldName = symbol->GetName();
m_toolMgr->RunAction( ACTIONS::cancelInteractive, true ); m_toolMgr->RunAction( ACTIONS::cancelInteractive, true );
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );

View File

@ -220,7 +220,7 @@ public:
* @param aLib True if we are checking library names, false if we are checking item names * @param aLib True if we are checking library names, false if we are checking item names
* @return the corrected version of \a aLibItemName. * @return the corrected version of \a aLibItemName.
*/ */
static UTF8 FixIllegalChars( const UTF8& aLibItemName, bool aLib = false ); static UTF8 FixIllegalChars( const UTF8& aLibItemName, bool aLib );
/** /**
* Looks for characters that are illegal in library nicknames. * Looks for characters that are illegal in library nicknames.

View File

@ -896,7 +896,7 @@ void PANEL_FP_LIB_TABLE::browseLibrariesHandler( wxCommandEvent& event )
for( const wxString& filePath : files ) for( const wxString& filePath : files )
{ {
wxFileName fn( filePath ); wxFileName fn( filePath );
wxString nickname = LIB_ID::FixIllegalChars( fn.GetName() ); wxString nickname = LIB_ID::FixIllegalChars( fn.GetName(), true );
bool doAdd = true; bool doAdd = true;
if( cur_model()->ContainsNickname( nickname ) ) if( cur_model()->ContainsNickname( nickname ) )