Validate new symbol / save as symbol info before exiting dialog.

This commit is contained in:
Jeff Young 2023-09-05 22:07:51 +01:00
parent 0dddb27408
commit 634524dde5
8 changed files with 307 additions and 228 deletions

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -41,12 +41,11 @@ EDA_LIST_DIALOG::EDA_LIST_DIALOG( wxWindow* aParent, const wxString& aTitle,
const std::vector<wxArrayString>& aItemList,
const wxString& aPreselectText, bool aSortList ) :
EDA_LIST_DIALOG_BASE( aParent, wxID_ANY, aTitle ),
m_itemsList( aItemList ),
m_sortList( aSortList )
{
m_filterBox->SetHint( _( "Filter" ) );
initDialog( aItemHeaders, aPreselectText );
initDialog( aItemHeaders, aItemList, aPreselectText );
// DIALOG_SHIM needs a unique hash_key because classname is not sufficient
// because so many dialogs share this same class, with different numbers of
@ -62,6 +61,14 @@ EDA_LIST_DIALOG::EDA_LIST_DIALOG( wxWindow* aParent, const wxString& aTitle,
}
EDA_LIST_DIALOG::EDA_LIST_DIALOG( wxWindow* aParent, const wxString& aTitle, bool aSortList ) :
EDA_LIST_DIALOG_BASE( aParent, wxID_ANY, aTitle ),
m_sortList( aSortList )
{
m_filterBox->SetHint( _( "Filter" ) );
}
bool EDA_LIST_DIALOG::Show( bool show )
{
bool retVal = DIALOG_SHIM::Show( show );
@ -76,7 +83,9 @@ bool EDA_LIST_DIALOG::Show( bool show )
}
void EDA_LIST_DIALOG::initDialog( const wxArrayString& aItemHeaders, const wxString& aSelection )
void EDA_LIST_DIALOG::initDialog( const wxArrayString& aItemHeaders,
const std::vector<wxArrayString>& aItemList,
const wxString& aPreselectText )
{
if( aItemHeaders.Count() == 1 )
{
@ -98,11 +107,12 @@ void EDA_LIST_DIALOG::initDialog( const wxArrayString& aItemHeaders, const wxStr
SetMinClientSize( wxSize( DEFAULT_COL_WIDTHS[0] * 2, 220 ) );
}
m_itemsList = aItemList;
InsertItems( m_itemsList, 0 );
if( !aSelection.IsEmpty() )
if( !aPreselectText.IsEmpty() )
{
long sel = m_listBox->FindItem( -1, aSelection );
long sel = m_listBox->FindItem( -1, aPreselectText );
if( sel != wxNOT_FOUND )
{

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -28,13 +28,14 @@
#include <sch_validators.h>
#include <template_fieldnames.h>
DIALOG_LIB_NEW_SYMBOL::DIALOG_LIB_NEW_SYMBOL( EDA_DRAW_FRAME* aParent,
const wxString& message,
DIALOG_LIB_NEW_SYMBOL::DIALOG_LIB_NEW_SYMBOL( EDA_DRAW_FRAME* aParent, const wxString& aMessage,
const wxArrayString* aRootSymbolNames,
const wxString& inheritFromSymbolName ) :
DIALOG_LIB_NEW_SYMBOL_BASE( dynamic_cast<wxWindow*>( aParent ) ),
m_pinTextPosition( aParent, m_staticPinTextPositionLabel, m_textPinTextPosition,
m_staticPinTextPositionUnits, true )
const wxString& aInheritFromSymbolName,
std::function<bool( wxString newName )> aValidator ) :
DIALOG_LIB_NEW_SYMBOL_BASE( dynamic_cast<wxWindow*>( aParent ) ),
m_pinTextPosition( aParent, m_staticPinTextPositionLabel, m_textPinTextPosition,
m_staticPinTextPositionUnits, true ),
m_validator( std::move( aValidator ) )
{
if( aRootSymbolNames && aRootSymbolNames->GetCount() )
{
@ -45,17 +46,17 @@ DIALOG_LIB_NEW_SYMBOL::DIALOG_LIB_NEW_SYMBOL( EDA_DRAW_FRAME* aParent,
m_comboInheritanceSelect->Append( escapedNames );
if( !inheritFromSymbolName.IsEmpty() )
if( !aInheritFromSymbolName.IsEmpty() )
{
m_comboInheritanceSelect->SetStringSelection( inheritFromSymbolName );
m_comboInheritanceSelect->SetStringSelection( aInheritFromSymbolName );
syncControls( !m_comboInheritanceSelect->GetValue().IsEmpty() );
}
}
if( !message.IsEmpty() )
if( !aMessage.IsEmpty() )
{
m_infoBar->RemoveAllButtons();
m_infoBar->ShowMessage( message );
m_infoBar->ShowMessage( aMessage );
}
m_textName->SetValidator( FIELD_VALIDATOR( VALUE_FIELD ) );
@ -73,6 +74,12 @@ DIALOG_LIB_NEW_SYMBOL::DIALOG_LIB_NEW_SYMBOL( EDA_DRAW_FRAME* aParent,
}
bool DIALOG_LIB_NEW_SYMBOL::TransferDataFromWindow()
{
return m_validator( GetName() );
}
void DIALOG_LIB_NEW_SYMBOL::OnParentSymbolSelect( wxCommandEvent& aEvent )
{
syncControls( !m_comboInheritanceSelect->GetValue().IsEmpty() );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -35,19 +35,24 @@ class wxArrayString;
class DIALOG_LIB_NEW_SYMBOL : public DIALOG_LIB_NEW_SYMBOL_BASE
{
public:
DIALOG_LIB_NEW_SYMBOL( EDA_DRAW_FRAME* parent,
const wxString& message,
const wxArrayString* aRootSymbolNames = nullptr,
const wxString& inheritFromSymbolName = wxEmptyString );
DIALOG_LIB_NEW_SYMBOL( EDA_DRAW_FRAME* aParent, const wxString& aMessage,
const wxArrayString* aRootSymbolNames,
const wxString& aInheritFromSymbolName,
std::function<bool( wxString newName )> aValidator );
void SetName( const wxString& name ) override
{
m_textName->SetValue( UnescapeString( name ) );
}
wxString GetName( void ) const override
wxString GetName() const override
{
return EscapeString( m_textName->GetValue(), CTX_LIBID );
wxString name = EscapeString( m_textName->GetValue(), CTX_LIBID );
// Currently, symbol names cannot include a space, that breaks libraries:
name.Replace( " ", "_" );
return name;
}
wxString GetParentSymbolName() const
@ -56,19 +61,19 @@ public:
}
void SetReference( const wxString& reference ) { m_textReference->SetValue( reference ); }
wxString GetReference( void ) { return m_textReference->GetValue(); }
wxString GetReference() { return m_textReference->GetValue(); }
void SetPartCount( int count ) { m_spinPartCount->SetValue( count ); }
int GetUnitCount( void ) { return m_spinPartCount->GetValue(); }
int GetUnitCount() { return m_spinPartCount->GetValue(); }
void SetAlternateBodyStyle( bool enable ) { m_checkHasConversion->SetValue( enable ); }
bool GetAlternateBodyStyle( void ) { return m_checkHasConversion->GetValue(); }
bool GetAlternateBodyStyle() { return m_checkHasConversion->GetValue(); }
void SetPowerSymbol( bool enable ) { m_checkIsPowerSymbol->SetValue( enable ); }
bool GetPowerSymbol( void ) { return m_checkIsPowerSymbol->GetValue(); }
bool GetPowerSymbol() { return m_checkIsPowerSymbol->GetValue(); }
void SetUnitsInterchangeable( bool enable ) { m_checkUnitsInterchangeable->SetValue( enable ); }
bool GetUnitsInterchangeable( void ) { return m_checkUnitsInterchangeable->GetValue(); }
bool GetUnitsInterchangeable() { return m_checkUnitsInterchangeable->GetValue(); }
void SetIncludeInBom( bool aInclude ) { m_excludeFromBomCheckBox->SetValue( !aInclude ); }
bool GetIncludeInBom() const { return !m_excludeFromBomCheckBox->GetValue(); }
@ -77,25 +82,29 @@ public:
bool GetIncludeOnBoard() const { return !m_excludeFromBoardCheckBox->GetValue(); }
void SetPinTextPosition( int position ) { m_pinTextPosition.SetValue( position ); }
int GetPinTextPosition( void ) { return m_pinTextPosition.GetValue(); }
int GetPinTextPosition() { return m_pinTextPosition.GetValue(); }
void SetShowPinNumber( bool show ) { m_checkShowPinNumber->SetValue( show ); }
bool GetShowPinNumber( void ) { return m_checkShowPinNumber->GetValue(); }
bool GetShowPinNumber() { return m_checkShowPinNumber->GetValue(); }
void SetShowPinName( bool show ) { m_checkShowPinName->SetValue( show ); }
bool GetShowPinName( void ) { return m_checkShowPinName->GetValue(); }
bool GetShowPinName() { return m_checkShowPinName->GetValue(); }
void SetPinNameInside( bool show ) { m_checkShowPinNameInside->SetValue( show ); }
bool GetPinNameInside( void ) { return m_checkShowPinNameInside->GetValue(); }
bool GetPinNameInside() { return m_checkShowPinNameInside->GetValue(); }
protected:
bool TransferDataFromWindow() override;
virtual void OnParentSymbolSelect( wxCommandEvent& aEvent ) override;
virtual void onPowerCheckBox( wxCommandEvent& aEvent ) override;
private:
void syncControls( bool aIsDerivedPart );
UNIT_BINDER m_pinTextPosition;
private:
UNIT_BINDER m_pinTextPosition;
std::function<bool( wxString newName )> m_validator;
};
#endif // __dialog_lib_new_symbol__

View File

@ -134,10 +134,10 @@ public:
/**
* Create a new symbol in the selected library.
*
* @param aInheritFrom is the name of the symbol to derive the new symbol from or empty
* @param newName is the name of the symbol to derive the new symbol from or empty
* to create a new root symbol.
*/
void CreateNewSymbol( const wxString& aInheritFrom = wxEmptyString );
void CreateNewSymbol( const wxString& newName = wxEmptyString );
void ImportSymbol();
void ExportSymbol();

View File

@ -350,6 +350,7 @@ void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& aInheritFrom )
wxString _inheritSymbolName;
wxString _infoMessage;
wxString msg;
// if the symbol being inherited from isn't a root symbol, find its root symbol
// and use that symbol instead
@ -369,38 +370,38 @@ void SYMBOL_EDIT_FRAME::CreateNewSymbol( const wxString& aInheritFrom )
}
}
DIALOG_LIB_NEW_SYMBOL dlg( this, _infoMessage, &symbolNames, _inheritSymbolName );
DIALOG_LIB_NEW_SYMBOL dlg( this, _infoMessage, &symbolNames, _inheritSymbolName,
[&]( wxString newName )
{
if( newName.IsEmpty() )
{
wxMessageBox( _( "Symbol must have a newName." ) );
return false;
}
if( !lib.empty() && m_libMgr->SymbolExists( newName, lib ) )
{
msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
newName,
lib );
KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
wxOK | wxCANCEL | wxICON_WARNING );
errorDlg.SetOKLabel( _( "Overwrite" ) );
return errorDlg.ShowModal() == wxID_OK;
}
return true;
} );
dlg.SetMinSize( dlg.GetSize() );
if( dlg.ShowModal() == wxID_CANCEL )
return;
if( dlg.GetName().IsEmpty() )
{
wxMessageBox( _( "This new symbol has no name and cannot be created." ) );
return;
}
wxString name = dlg.GetName();
// Currently, symbol names cannot include a space, that breaks libraries:
name.Replace( " ", "_" );
// Test if there is a symbol with this name already.
if( !lib.empty() && m_libMgr->SymbolExists( name, lib ) )
{
wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
name,
lib );
KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
errorDlg.SetOKLabel( _( "Overwrite" ) );
errorDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
if( errorDlg.ShowModal() == wxID_CANCEL )
return;
}
LIB_SYMBOL new_symbol( name ); // do not create symbol on the heap, it will be buffered soon
wxString parentSymbolName = dlg.GetParentSymbolName();
@ -546,172 +547,193 @@ void SYMBOL_EDIT_FRAME::SaveSymbolAs()
}
static int ID_SAVE_AS_NAME = 4172;
static int ID_MAKE_NEW_LIBRARY = 4173;
EDA_LIST_DIALOG* SYMBOL_EDIT_FRAME::buildSaveAsDialog( const wxString& aSymbolName,
const wxString& aLibraryPreselect )
class SAVE_AS_DIALOG : public EDA_LIST_DIALOG
{
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = Kiway().Prj().GetProjectFile();
SYMBOL_LIB_TABLE* tbl = Prj().SchSymbolLibTable();
std::vector<wxString> libNicknames = tbl->GetLogicalLibs();
wxArrayString headers;
std::vector<wxArrayString> itemsToDisplay;
headers.Add( _( "Nickname" ) );
headers.Add( _( "Description" ) );
for( const wxString& nickname : libNicknames )
public:
SAVE_AS_DIALOG( SYMBOL_EDIT_FRAME* aParent, const wxString& aSymbolName,
const wxString& aLibraryPreselect,
std::function<bool( wxString libName, wxString symbolName )> aValidator ) :
EDA_LIST_DIALOG( aParent, _( "Save Symbol As" ), false ),
m_validator( std::move( aValidator ) )
{
if( alg::contains( project.m_PinnedSymbolLibs, nickname )
|| alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = aParent->Prj().GetProjectFile();
SYMBOL_LIB_TABLE* tbl = aParent->Prj().SchSymbolLibTable();
std::vector<wxString> libNicknames = tbl->GetLogicalLibs();
wxArrayString headers;
std::vector<wxArrayString> itemsToDisplay;
headers.Add( _( "Nickname" ) );
headers.Add( _( "Description" ) );
for( const wxString& nickname : libNicknames )
{
wxArrayString item;
item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
item.Add( tbl->GetDescription( nickname ) );
itemsToDisplay.push_back( item );
}
}
for( const wxString& nickname : libNicknames )
{
if( !alg::contains( project.m_PinnedSymbolLibs, nickname )
&& !alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
{
wxArrayString item;
item.Add( nickname );
item.Add( tbl->GetDescription( nickname ) );
itemsToDisplay.push_back( item );
}
}
EDA_LIST_DIALOG* dlg = new EDA_LIST_DIALOG( this, _( "Save Symbol As" ), headers,
itemsToDisplay, aLibraryPreselect, false );
dlg->SetListLabel( _( "Save in library:" ) );
dlg->SetOKLabel( _( "Save" ) );
wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
wxStaticText* label = new wxStaticText( dlg, wxID_ANY, _( "Name:" ) );
bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
wxTextCtrl* nameTextCtrl = new wxTextCtrl( dlg, ID_SAVE_AS_NAME, aSymbolName );
bNameSizer->Add( nameTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
wxButton* newLibraryButton = new wxButton( dlg, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
dlg->m_ButtonsSizer->Prepend( 80, 20 );
dlg->m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
dlg->GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
dlg->Bind( wxEVT_BUTTON,
[dlg]( wxCommandEvent& )
if( alg::contains( project.m_PinnedSymbolLibs, nickname )
|| alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
{
dlg->EndModal( ID_MAKE_NEW_LIBRARY );
}, ID_MAKE_NEW_LIBRARY );
wxArrayString item;
item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + nickname );
item.Add( tbl->GetDescription( nickname ) );
itemsToDisplay.push_back( item );
}
}
// Move nameTextCtrl to the head of the tab-order
if( dlg->GetChildren().DeleteObject( nameTextCtrl ) )
dlg->GetChildren().Insert( nameTextCtrl );
for( const wxString& nickname : libNicknames )
{
if( !alg::contains( project.m_PinnedSymbolLibs, nickname )
&& !alg::contains( cfg->m_Session.pinned_symbol_libs, nickname ) )
{
wxArrayString item;
item.Add( nickname );
item.Add( tbl->GetDescription( nickname ) );
itemsToDisplay.push_back( item );
}
}
dlg->SetInitialFocus( nameTextCtrl );
initDialog( headers, itemsToDisplay, aLibraryPreselect );
dlg->Layout();
dlg->GetSizer()->Fit( dlg );
SetListLabel( _( "Save in library:" ) );
SetOKLabel( _( "Save" ) );
return dlg;
}
wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );
wxStaticText* label = new wxStaticText( this, wxID_ANY, _( "Name:" ) );
bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );
m_symbolNameCtrl = new wxTextCtrl( this, wxID_ANY, aSymbolName );
bNameSizer->Add( m_symbolNameCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
wxButton* newLibraryButton = new wxButton( this, ID_MAKE_NEW_LIBRARY, _( "New Library..." ) );
m_ButtonsSizer->Prepend( 80, 20 );
m_ButtonsSizer->Prepend( newLibraryButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
GetSizer()->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );
Bind( wxEVT_BUTTON,
[this]( wxCommandEvent& )
{
EndModal( ID_MAKE_NEW_LIBRARY );
}, ID_MAKE_NEW_LIBRARY );
// Move nameTextCtrl to the head of the tab-order
if( GetChildren().DeleteObject( m_symbolNameCtrl ) )
GetChildren().Insert( m_symbolNameCtrl );
SetInitialFocus( m_symbolNameCtrl );
SetupStandardButtons();
Layout();
GetSizer()->Fit( this );
Centre();
}
wxString GetSymbolName()
{
wxString symbolName = m_symbolNameCtrl->GetValue();
symbolName.Trim( true );
symbolName.Trim( false );
symbolName.Replace( " ", "_" );
return symbolName;
}
protected:
bool TransferDataFromWindow() override
{
return m_validator( GetTextSelection(), GetSymbolName() );
}
private:
wxTextCtrl* m_symbolNameCtrl;
std::function<bool( wxString libName, wxString symbolName )> m_validator;
};
void SYMBOL_EDIT_FRAME::saveSymbolAs()
{
LIB_SYMBOL* symbol = getTargetSymbol();
if( symbol )
if( !symbol )
return;
LIB_ID old_lib_id = symbol->GetLibId();
wxString symbolName = old_lib_id.GetLibItemName();
wxString libraryName = old_lib_id.GetLibNickname();
wxString msg;
bool done = false;
while( !done )
{
LIB_ID old_lib_id = symbol->GetLibId();
wxString symbolName = old_lib_id.GetLibItemName();
wxString libraryName = old_lib_id.GetLibNickname();
bool done = false;
SAVE_AS_DIALOG dlg( this, symbolName, libraryName,
[&]( const wxString& newLib, const wxString& newName )
{
if( newLib.IsEmpty() )
{
wxMessageBox( _( "A library must be specified." ) );
return false;
}
std::unique_ptr<EDA_LIST_DIALOG> dlg;
if( newName.IsEmpty() )
{
wxMessageBox( _( "Symbol must have a name." ) );
return false;
}
while( !done )
if( m_libMgr->SymbolExists( newName, newLib ) )
{
msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
newName, newLib );
KIDIALOG errorDlg( this, msg, _( "Confirmation" ),
wxOK | wxCANCEL | wxICON_WARNING );
errorDlg.SetOKLabel( _( "Overwrite" ) );
return errorDlg.ShowModal() == wxID_OK;
}
// @todo Either check the selecteced library to see if the parent symbol name
// is in the new library and/or copy the parent symbol as well. This is
// the lazy solution to ensure derived symbols do not get orphaned.
if( symbol->IsAlias() && newLib != old_lib_id.GetLibNickname() )
{
DisplayError( this, _( "Derived symbols must be saved in the same library "
"as their parent symbol." ) );
return false;
}
return true;
} );
int ret = dlg.ShowModal();
if( ret == wxID_CANCEL )
{
dlg.reset( buildSaveAsDialog( symbolName, libraryName ) );
int ret = dlg->ShowModal();
if( ret == wxID_CANCEL )
{
return;
}
else if( ret == wxID_OK )
{
done = true;
}
else if( ret == ID_MAKE_NEW_LIBRARY )
{
wxFileName newLibrary( AddLibraryFile( true ) );
libraryName = newLibrary.GetName();
}
}
libraryName = dlg->GetTextSelection();
if( libraryName.IsEmpty() )
{
DisplayError( this, _( "No library specified. Symbol could not be saved." ) );
return;
}
// @todo Either check the selecteced library to see if the parent symbol name is in
// the new library and/or copy the parent symbol as well. This is the lazy
// solution to ensure derived symbols do not get orphaned.
if( symbol->IsAlias() && libraryName != old_lib_id.GetLibNickname() )
else if( ret == wxID_OK )
{
DisplayError( this, _( "Derived symbols must be saved in the same library as their "
"parent symbol." ) );
return;
symbolName = dlg.GetSymbolName();
libraryName = dlg.GetTextSelection();
done = true;
}
symbolName = static_cast<wxTextCtrl*>( dlg->FindWindow( ID_SAVE_AS_NAME ) )->GetValue();
symbolName.Trim( true );
symbolName.Trim( false );
symbolName.Replace( " ", "_" );
if( symbolName.IsEmpty() )
else if( ret == ID_MAKE_NEW_LIBRARY )
{
// This is effectively a cancel. No need to nag the user about it.
return;
wxFileName newLibrary( AddLibraryFile( true ) );
libraryName = newLibrary.GetName();
}
// Test if there is a symbol with this name already.
if( m_libMgr->SymbolExists( symbolName, libraryName ) )
{
wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'" ),
symbolName,
libraryName );
KIDIALOG errorDlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
errorDlg.SetOKLabel( _( "Overwrite" ) );
errorDlg.DoNotShowCheckbox( __FILE__, __LINE__ );
if( errorDlg.ShowModal() == wxID_CANCEL )
return;
}
LIB_SYMBOL new_symbol( *symbol );
new_symbol.SetName( symbolName );
m_libMgr->UpdateSymbol( &new_symbol, libraryName );
SyncLibraries( false );
m_treePane->GetLibTree()->SelectLibId( LIB_ID( libraryName, new_symbol.GetName() ) );
LoadSymbol( symbolName, libraryName, m_unit );
}
LIB_SYMBOL new_symbol( *symbol );
new_symbol.SetName( symbolName );
m_libMgr->UpdateSymbol( &new_symbol, libraryName );
SyncLibraries( false );
m_treePane->GetLibTree()->SelectLibId( LIB_ID( libraryName, new_symbol.GetName() ) );
LoadSymbol( symbolName, libraryName, m_unit );
}

View File

@ -319,6 +319,33 @@ int SYMBOL_EDITOR_CONTROL::DuplicateSymbol( const TOOL_EVENT& aEvent )
}
class RENAME_DIALOG : public wxTextEntryDialog
{
public:
RENAME_DIALOG( wxWindow* aParent, const wxString& aName,
std::function<bool( wxString newName )> aValidator ) :
wxTextEntryDialog( aParent, _( "New name:" ), _( "Change Symbol Name" ), aName ),
m_validator( std::move( aValidator ) )
{ }
wxString GetSymbolName()
{
wxString name = EscapeString( m_textctrl->GetValue(), CTX_LIBID );
name.Trim( true ).Trim( false );
return name;
}
protected:
bool TransferDataFromWindow() override
{
return m_validator( GetSymbolName() );
}
private:
std::function<bool( wxString newName )> m_validator;
};
int SYMBOL_EDITOR_CONTROL::RenameSymbol( const TOOL_EVENT& aEvent )
{
if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
@ -329,40 +356,39 @@ int SYMBOL_EDITOR_CONTROL::RenameSymbol( const TOOL_EVENT& aEvent )
LIB_ID libId = editFrame->GetTreeLIBID();
wxString libName = libId.GetLibNickname();
wxString symbolName = libId.GetLibItemName();
wxString newName = symbolName;
bool done = false;
wxString msg;
if( !libMgr.LibraryExists( libName ) )
return 0;
while( !done )
{
wxTextEntryDialog dlg( m_frame, _( "New name:" ), _( "Change Symbol Name" ), newName );
RENAME_DIALOG dlg( m_frame, symbolName,
[&]( wxString newName )
{
if( newName.IsEmpty() )
{
wxMessageBox( _( "Symbol must have a name." ) );
return false;
}
if( dlg.ShowModal() != wxID_OK )
return 0; // canceled by user
if( libMgr.SymbolExists( newName, libName ) )
{
msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'." ),
newName, libName );
newName = EscapeString( dlg.GetValue(), CTX_LIBID );
newName.Trim( true ).Trim( false );
KIDIALOG errorDlg( m_frame, msg, _( "Confirmation" ),
wxOK | wxCANCEL | wxICON_WARNING );
errorDlg.SetOKLabel( _( "Overwrite" ) );
if( newName.IsEmpty() )
{
DisplayErrorMessage( editFrame, _( "Symbol name cannot be empty." ) );
}
else if( libMgr.SymbolExists( newName, libName ) )
{
DisplayErrorMessage( editFrame, wxString::Format( _( "Symbol name '%s' already "
"in use in library '%s'." ),
UnescapeString( newName ),
libName ) );
newName = symbolName;
}
else
{
done = true;
}
}
return errorDlg.ShowModal() == wxID_OK;
}
return true;
} );
if( dlg.ShowModal() != wxID_OK )
return 0; // canceled by user
wxString newName = dlg.GetSymbolName();
wxString oldName = symbolName;
LIB_SYMBOL* libSymbol = nullptr;

View File

@ -55,7 +55,7 @@ public:
int CutCopyDelete( const TOOL_EVENT& aEvent );
int DuplicateSymbol( const TOOL_EVENT& aEvent );
int RenameSymbol( const TOOL_EVENT& aEvent );
int RenameSymbol( const TOOL_EVENT& newName );
int ExportSymbol( const TOOL_EVENT& aEvent );
int ExportView( const TOOL_EVENT& aEvent );
int ExportSymbolAsSVG( const TOOL_EVENT& aEvent );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -54,6 +54,8 @@ public:
const wxString& aPreselectText = wxEmptyString,
bool aSortList = true );
EDA_LIST_DIALOG( wxWindow* aParent, const wxString& aTitle, bool aSortList = true );
void SetListLabel( const wxString& aLabel );
void SetOKLabel( const wxString& aLabel );
void HideFilter();
@ -73,12 +75,15 @@ public:
bool Show( bool show ) override;
protected:
void initDialog( const wxArrayString& aItemHeaders, const std::vector<wxArrayString>& aItemList,
const wxString& aPreselectText);
private:
virtual void onSize( wxSizeEvent& event ) override;
void onListItemActivated( wxListEvent& event ) override;
void textChangeInFilterBox(wxCommandEvent& event) override;
void initDialog( const wxArrayString& aItemHeaders, const wxString& aSelection);
void sortList();
private: