Keep name & value in sync for library items.

Also fixes library reference highlighting from board footprints.

Fixes: lp:1792243
* https://bugs.launchpad.net/kicad/+bug/1792243

Fixes: lp:1792256
* https://bugs.launchpad.net/kicad/+bug/1792256
This commit is contained in:
Jeff Young 2018-09-13 16:39:14 +01:00
parent 10a032abdb
commit e5e1a315f1
17 changed files with 315 additions and 122 deletions

View File

@ -59,7 +59,8 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY::DIALOG_EDIT_COMPONENT_IN_LIBRARY( LIB_EDIT_FRA
m_currentAlias( wxNOT_FOUND ),
m_pinNameOffset( aParent, m_nameOffsetLabel, m_nameOffsetCtrl, m_nameOffsetUnits, true ),
m_delayedFocusCtrl( nullptr ),
m_delayedFocusGrid( nullptr )
m_delayedFocusGrid( nullptr ),
m_delayedFocusPage( -1 )
{
m_config = Kiface().KifaceSettings();
@ -95,6 +96,8 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY::DIALOG_EDIT_COMPONENT_IN_LIBRARY( LIB_EDIT_FRA
attr->SetEditor( new GRID_CELL_URL_EDITOR( this ) );
m_aliasGrid->SetAttr( DATASHEET, FDC_VALUE, attr );
m_SymbolNameCtrl->SetValidator( SCH_FIELD_VALIDATOR( true, VALUE ) );
// Configure button logos
m_bpAdd->SetBitmap( KiBitmap( small_plus_xpm ) );
m_bpDelete->SetBitmap( KiBitmap( trash_xpm ) );
@ -224,6 +227,7 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::Validate()
m_delayedFocusGrid = m_grid;
m_delayedFocusColumn = FDC_VALUE;
m_delayedFocusRow = REFERENCE;
m_delayedFocusPage = 0;
return false;
}
@ -243,6 +247,7 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::Validate()
m_delayedFocusGrid = m_grid;
m_delayedFocusColumn = FDC_NAME;
m_delayedFocusRow = i;
m_delayedFocusPage = 0;
return false;
}
@ -346,18 +351,36 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnGridCellChanging( wxGridEvent& event )
{
event.Veto();
if( m_NoteBook->GetSelection() != 0 )
m_NoteBook->SetSelection( 0 );
m_delayedFocusGrid = m_grid;
m_delayedFocusRow = event.GetRow();
m_delayedFocusColumn = event.GetCol();
m_delayedFocusPage = 0;
}
else if( event.GetRow() == VALUE && event.GetCol() == FDC_VALUE )
m_SymbolNameCtrl->ChangeValue( event.GetString() );
editor->DecRef();
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnSymbolNameText( wxCommandEvent& event )
{
m_grid->SetCellValue( VALUE, FDC_VALUE, m_SymbolNameCtrl->GetValue() );
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnSymbolNameKillFocus( wxFocusEvent& event )
{
if( !m_delayedFocusCtrl && !m_SymbolNameCtrl->GetValidator()->Validate( m_SymbolNameCtrl ) )
{
m_delayedFocusCtrl = m_SymbolNameCtrl;
m_delayedFocusPage = 0;
}
event.Skip();
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAddField( wxCommandEvent& event )
{
if( !m_grid->CommitPendingChanges() )
@ -481,13 +504,13 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAliasGridCellChanging( wxGridEvent& eve
{
event.Veto();
if( m_NoteBook->GetSelection() != 1 )
m_NoteBook->SetSelection( 1 );
m_delayedFocusGrid = m_aliasGrid;
m_delayedFocusRow = event.GetRow();
m_delayedFocusColumn = event.GetCol();
m_delayedFocusPage = 1;
}
else
updateAliasName( true, newName );
}
}
@ -500,20 +523,11 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAliasNameText( wxCommandEvent& event )
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAliasNameKillFocus( wxFocusEvent& event )
{
static bool inKillFocus = false;
// If we get an error then we're going to throw up a dialog. Since we haven't yet
// finished the KillFocus event, we'll end up getting another one. Side-effects may
// include death.
if( inKillFocus )
return;
inKillFocus = true;
if( !checkAliasName( m_AliasNameCtrl->GetValue() ) )
if( !m_delayedFocusCtrl && !checkAliasName( m_AliasNameCtrl->GetValue() ) )
{
m_delayedFocusCtrl = m_AliasNameCtrl;
inKillFocus = false;
m_delayedFocusPage = 1;
}
event.Skip();
}
@ -744,6 +758,19 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnUpdateUI( wxUpdateUIEvent& event )
m_OptionPartsLocked->Enable( m_SelNumberOfUnits->GetValue() > 1 );
m_pinNameOffset.Enable( m_PinsNameInsideButt->GetValue() );
if( m_grid->IsCellEditControlShown() )
{
int row = m_grid->GetGridCursorRow();
int col = m_grid->GetGridCursorCol();
if( row == VALUE && col == FDC_VALUE )
{
wxGridCellEditor* editor = m_grid->GetCellEditor( row, col );
m_SymbolNameCtrl->ChangeValue( editor->GetValue() );
editor->DecRef();
}
}
// Synthesize a Select event when the selection is cleared
if( m_aliasListBox->GetSelection() == wxNOT_FOUND && m_currentAlias != wxNOT_FOUND )
{
@ -762,7 +789,28 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnUpdateUI( wxUpdateUIEvent& event )
adjustGridColumns( m_grid->GetRect().GetWidth() );
}
// Handle a delayed focus
// Handle a delayed focus. The delay allows us to:
// a) change focus when the error was triggered from within a killFocus handler
// b) show the correct notebook page in the background before the error dialog comes up
// when triggered from an OK or a notebook page change
if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
{
m_NoteBook->SetSelection( (unsigned) m_delayedFocusPage );
m_delayedFocusPage = -1;
}
if( !m_delayedErrorMessage.IsEmpty() )
{
// We will re-enter this routine when the error dialog is displayed, so make
// sure we don't keep putting up more dialogs.
wxString msg = m_delayedErrorMessage;
m_delayedErrorMessage = wxEmptyString;
// Do not use DisplayErrorMessage(); it screws up window order on Mac
DisplayError( nullptr, msg );
}
if( m_delayedFocusCtrl )
{
m_delayedFocusCtrl->SetFocus();
@ -778,21 +826,12 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnUpdateUI( wxUpdateUIEvent& event )
m_delayedFocusGrid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
m_delayedFocusGrid->SetGridCursor( m_delayedFocusRow, m_delayedFocusColumn );
if( !m_delayedErrorMessage.IsEmpty() )
{
// We will re-enter this routine when the error dialog is displayed, so make
// sure we don't keep putting up more dialogs.
wxString msg = m_delayedErrorMessage;
m_delayedErrorMessage = wxEmptyString;
// Do not use DisplayErrorMessage(); it screws up window order on Mac
DisplayError( nullptr, msg );
}
m_delayedFocusGrid->EnableCellEditControl( true );
m_delayedFocusGrid->ShowCellEditControl();
m_delayedFocusGrid = nullptr;
m_delayedFocusRow = -1;
m_delayedFocusColumn = -1;
}
}

View File

@ -57,10 +57,12 @@ public:
UNIT_BINDER m_pinNameOffset;
wxControl* m_delayedFocusCtrl;
wxString m_delayedErrorMessage;
WX_GRID* m_delayedFocusGrid;
int m_delayedFocusRow;
int m_delayedFocusColumn;
int m_delayedFocusPage;
wxString m_delayedErrorMessage;
wxString m_shownColumns;
bool TransferDataToWindow() override;
@ -80,6 +82,8 @@ private:
void OnDeleteField( wxCommandEvent& event ) override;
void OnMoveUp( wxCommandEvent& event ) override;
void OnMoveDown( wxCommandEvent& event ) override;
void OnSymbolNameKillFocus( wxFocusEvent& event ) override;
void OnSymbolNameText( wxCommandEvent& event ) override;
void OnSelectAlias( wxCommandEvent& event ) override;
void OnAddAlias( wxCommandEvent& event ) override;
void OnDeleteAlias( wxCommandEvent& event ) override;

View File

@ -29,7 +29,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
wxStaticBoxSizer* sbSizer4;
sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( m_PanelBasic, wxID_ANY, _("Fields") ), wxVERTICAL );
m_grid = new WX_GRID( sbSizer4->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER );
m_grid = new WX_GRID( sbSizer4->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_grid->CreateGrid( 4, 11 );
@ -126,7 +126,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
fgSizerFPID->Add( staticNameLabel, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_SymbolNameCtrl = new wxTextCtrl( m_PanelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerFPID->Add( m_SymbolNameCtrl, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
fgSizerFPID->Add( m_SymbolNameCtrl, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
wxStaticText* staticDescriptionLabel;
staticDescriptionLabel = new wxStaticText( m_PanelBasic, wxID_ANY, _("Description:"), wxDefaultPosition, wxDefaultSize, 0 );
@ -134,7 +134,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
fgSizerFPID->Add( staticDescriptionLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_DescCtrl = new wxTextCtrl( m_PanelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerFPID->Add( m_DescCtrl, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
fgSizerFPID->Add( m_DescCtrl, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
staticKeywordsLabel = new wxStaticText( m_PanelBasic, wxID_ANY, _("Keywords:"), wxDefaultPosition, wxDefaultSize, 0 );
staticKeywordsLabel->Wrap( -1 );
@ -301,7 +301,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_staticText12->Wrap( -1 );
bRightBoxSizerPanelAlias->Add( m_staticText12, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_aliasGrid = new WX_GRID( m_PanelAlias, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER );
m_aliasGrid = new WX_GRID( m_PanelAlias, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_aliasGrid->CreateGrid( 4, 2 );
@ -452,6 +452,8 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_bpMoveUp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnMoveUp ), NULL, this );
m_bpMoveDown->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnMoveDown ), NULL, this );
m_bpDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnDeleteField ), NULL, this );
m_SymbolNameCtrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSymbolNameKillFocus ), NULL, this );
m_SymbolNameCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSymbolNameText ), NULL, this );
m_aliasListBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSelectAlias ), NULL, this );
m_addAliasButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnAddAlias ), NULL, this );
m_deleteAliasButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnDeleteAlias ), NULL, this );
@ -472,6 +474,8 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::~DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE()
m_bpMoveUp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnMoveUp ), NULL, this );
m_bpMoveDown->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnMoveDown ), NULL, this );
m_bpDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnDeleteField ), NULL, this );
m_SymbolNameCtrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSymbolNameKillFocus ), NULL, this );
m_SymbolNameCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSymbolNameText ), NULL, this );
m_aliasListBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSelectAlias ), NULL, this );
m_addAliasButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnAddAlias ), NULL, this );
m_deleteAliasButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnDeleteAlias ), NULL, this );

View File

@ -365,7 +365,7 @@
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxSIMPLE_BORDER</property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@ -818,20 +818,20 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="0">
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="0">
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerMidBasicPanel</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="proportion">1</property>
<object class="wxFlexGridSizer" expanded="0">
<object class="wxFlexGridSizer" expanded="1">
<property name="cols">2</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">1</property>
@ -928,7 +928,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
@ -993,7 +993,7 @@
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnKillFocus">OnSymbolNameKillFocus</event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
@ -1010,7 +1010,7 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnText">OnSymbolNameText</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
@ -1102,7 +1102,7 @@
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT</property>
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
@ -3082,7 +3082,7 @@
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxSIMPLE_BORDER</property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>

View File

@ -97,6 +97,8 @@ class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE : public DIALOG_SHIM
virtual void OnMoveUp( wxCommandEvent& event ) { event.Skip(); }
virtual void OnMoveDown( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDeleteField( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSymbolNameKillFocus( wxFocusEvent& event ) { event.Skip(); }
virtual void OnSymbolNameText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSelectAlias( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAddAlias( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDeleteAlias( wxCommandEvent& event ) { event.Skip(); }

View File

@ -51,7 +51,8 @@ FIELDS_GRID_TABLE<T>::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* a
m_userUnits( aDialog->GetUserUnits() ),
m_part( aPart ),
m_fieldNameValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_NAME ),
m_referenceValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), REFERENCE )
m_referenceValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), REFERENCE ),
m_valueValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), VALUE )
{
// Build the various grid cell attributes.
@ -68,6 +69,11 @@ FIELDS_GRID_TABLE<T>::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* a
referenceEditor->SetValidator( m_referenceValidator );
m_referenceAttr->SetEditor( referenceEditor );
m_valueAttr = new wxGridCellAttr;
GRID_CELL_TEXT_EDITOR* valueEditor = new GRID_CELL_TEXT_EDITOR();
valueEditor->SetValidator( m_valueValidator );
m_valueAttr->SetEditor( valueEditor );
m_footprintAttr = new wxGridCellAttr;
m_footprintAttr->SetEditor( new GRID_CELL_FOOTPRINT_EDITOR( aDialog ) );
@ -111,6 +117,7 @@ FIELDS_GRID_TABLE<T>::~FIELDS_GRID_TABLE()
m_fieldNameAttr->DecRef();
m_boolAttr->DecRef();
m_referenceAttr->DecRef();
m_valueAttr->DecRef();
m_footprintAttr->DecRef();
m_urlAttr->DecRef();
m_vAlignAttr->DecRef();
@ -199,21 +206,17 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
}
else if( aRow == VALUE )
{
if( m_frame->IsType( FRAME_SCH_LIB_EDITOR ) )
// For power symbols, the value is not editable, because value and pin name must
// be the same and can be edited only in library editor.
if( m_part && m_part->IsPower() && ! m_frame->IsType( FRAME_SCH_LIB_EDITOR ) )
{
// This field is the lib name and the default value when loading this component
// in schematic. The value is now not editable here (in this dialog) because
// changing it is equivalent to create a new component or alias. This is handled
// in libedit, not in this dialog.
m_readOnlyAttr->IncRef();
return m_readOnlyAttr;
}
else if( m_part && m_part->IsPower() )
else
{
// For power symbols, the value is not editable, because value and pin name must
// be the same and can be edited only in library editor.
m_readOnlyAttr->IncRef();
return m_readOnlyAttr;
m_valueAttr->IncRef();
return m_valueAttr;
}
}
else if( aRow == FOOTPRINT )

View File

@ -101,10 +101,12 @@ private:
SCH_FIELD_VALIDATOR m_fieldNameValidator;
SCH_FIELD_VALIDATOR m_referenceValidator;
SCH_FIELD_VALIDATOR m_valueValidator;
wxGridCellAttr* m_readOnlyAttr;
wxGridCellAttr* m_fieldNameAttr;
wxGridCellAttr* m_referenceAttr;
wxGridCellAttr* m_valueAttr;
wxGridCellAttr* m_footprintAttr;
wxGridCellAttr* m_urlAttr;
wxGridCellAttr* m_boolAttr;

View File

@ -72,9 +72,11 @@ DIALOG_FOOTPRINT_FP_EDITOR::DIALOG_FOOTPRINT_FP_EDITOR( FOOTPRINT_EDIT_FRAME* aP
m_texts = new TEXT_MOD_GRID_TABLE( m_units, m_frame );
m_delayedErrorMessage = wxEmptyString;
m_delayedFocusCtrl = nullptr;
m_delayedFocusGrid = nullptr;
m_delayedFocusRow = -1;
m_delayedFocusColumn = -1;
m_delayedFocusPage = -1;
// Give an icon
wxIcon icon;
@ -119,13 +121,15 @@ DIALOG_FOOTPRINT_FP_EDITOR::DIALOG_FOOTPRINT_FP_EDITOR( FOOTPRINT_EDIT_FRAME* aP
m_staticTextInfoValPos->SetFont( infoFont );
m_staticTextInfoCopper->SetFont( infoFont );
m_NoteBook->SetSelection( m_page );
if( m_page >= 0 )
m_NoteBook->SetSelection( (unsigned) m_page );
if( m_page == 0 )
{
m_delayedFocusGrid = m_itemsGrid;
m_delayedFocusRow = 0;
m_delayedFocusColumn = 0;
m_delayedFocusPage = 0;
}
else if ( m_page == 1 )
SetInitialFocus( m_NetClearanceCtrl );
@ -134,6 +138,7 @@ DIALOG_FOOTPRINT_FP_EDITOR::DIALOG_FOOTPRINT_FP_EDITOR( FOOTPRINT_EDIT_FRAME* aP
m_delayedFocusGrid = m_modelsGrid;
m_delayedFocusRow = 0;
m_delayedFocusColumn = 0;
m_delayedFocusPage = 2;
}
m_sdbSizerStdButtonsOK->SetDefault();
@ -145,6 +150,9 @@ DIALOG_FOOTPRINT_FP_EDITOR::DIALOG_FOOTPRINT_FP_EDITOR( FOOTPRINT_EDIT_FRAME* aP
m_button3DShapeBrowse->SetBitmap( KiBitmap( folder_xpm ) );
m_button3DShapeRemove->SetBitmap( KiBitmap( trash_xpm ) );
// wxFormBuilder doesn't include this event...
m_itemsGrid->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_FOOTPRINT_FP_EDITOR::OnGridCellChanging ), NULL, this );
FinishDialogSettings();
}
@ -156,6 +164,8 @@ DIALOG_FOOTPRINT_FP_EDITOR::~DIALOG_FOOTPRINT_FP_EDITOR()
// Prevents crash bug in wxGrid's d'tor
m_itemsGrid->DestroyTable( m_texts );
m_itemsGrid->Disconnect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( DIALOG_FOOTPRINT_FP_EDITOR::OnGridCellChanging ), NULL, this );
// Delete the GRID_TRICKS.
m_itemsGrid->PopEventHandler( true );
m_modelsGrid->PopEventHandler( true );
@ -177,7 +187,7 @@ bool DIALOG_FOOTPRINT_FP_EDITOR::TransferDataToWindow()
LIB_ID fpID = m_footprint->GetFPID();
wxString footprintName = fpID.GetLibItemName();
m_FootprintNameCtrl->SetValue( footprintName );
m_FootprintNameCtrl->ChangeValue( footprintName );
m_DocCtrl->SetValue( m_footprint->GetDescription() );
m_KeywordCtrl->SetValue( m_footprint->GetKeywords() );
@ -330,6 +340,7 @@ void DIALOG_FOOTPRINT_FP_EDITOR::On3DModelCellChanged( wxGridEvent& aEvent )
m_delayedFocusGrid = m_modelsGrid;
m_delayedFocusRow = aEvent.GetRow();
m_delayedFocusColumn = aEvent.GetCol();
m_delayedFocusPage = 2;
aEvent.Veto();
}
@ -459,6 +470,23 @@ void DIALOG_FOOTPRINT_FP_EDITOR::OnAdd3DRow( wxCommandEvent& )
}
bool DIALOG_FOOTPRINT_FP_EDITOR::checkFootprintName( const wxString& aFootprintName )
{
if( aFootprintName.IsEmpty() || !MODULE::IsLibNameValid( aFootprintName ) )
{
if( aFootprintName.IsEmpty() )
m_delayedErrorMessage = _( "Footprint must have a name." );
else
m_delayedErrorMessage.Printf( _( "Footprint name may not contain \"%s\"." ),
MODULE::StringLibNameInvalidChars( true ) );
return false;
}
return true;
}
bool DIALOG_FOOTPRINT_FP_EDITOR::Validate()
{
if( !m_itemsGrid->CommitPendingChanges() )
@ -470,18 +498,13 @@ bool DIALOG_FOOTPRINT_FP_EDITOR::Validate()
// First, test for invalid chars in module name
wxString footprintName = m_FootprintNameCtrl->GetValue();
if( footprintName.IsEmpty() || !MODULE::IsLibNameValid( footprintName ) )
if( !checkFootprintName( footprintName ) )
{
wxString msg;
if( footprintName.IsEmpty() )
msg = _( "Footprint must have a name." );
else
msg.Printf( _( "Footprint name may not contain \"%s\"." ),
MODULE::StringLibNameInvalidChars( true ) );
if( m_NoteBook->GetSelection() != 0 )
m_NoteBook->SetSelection( 0 );
DisplayError( nullptr, msg );
m_FootprintNameCtrl->SetFocus();
m_delayedFocusCtrl = m_FootprintNameCtrl;
m_delayedFocusPage = 0;
return false;
}
@ -607,6 +630,59 @@ bool DIALOG_FOOTPRINT_FP_EDITOR::TransferDataFromWindow()
}
static bool footprintIsFromBoard( MODULE* aFootprint )
{
return aFootprint->GetLink() != 0;
}
void DIALOG_FOOTPRINT_FP_EDITOR::OnGridCellChanging( wxGridEvent& event )
{
if( event.GetRow() == 1 && event.GetCol() == TMC_TEXT )
{
if( !checkFootprintName( event.GetString() ) )
{
event.Veto();
if( m_NoteBook->GetSelection() != 0 )
m_NoteBook->SetSelection( 0 );
m_delayedFocusGrid = m_itemsGrid;
m_delayedFocusRow = event.GetRow();
m_delayedFocusColumn = event.GetCol();
m_delayedFocusPage = 0;
}
else if( !footprintIsFromBoard( m_footprint ) )
{
// Keep Name and Value of footprints in library in sync
m_FootprintNameCtrl->ChangeValue( event.GetString() );
}
}
}
void DIALOG_FOOTPRINT_FP_EDITOR::OnFootprintNameText( wxCommandEvent& event )
{
if( !footprintIsFromBoard( m_footprint ) )
{
// Keep Name and Value of footprints in library in sync
m_itemsGrid->SetCellValue( 1, TMC_TEXT, m_FootprintNameCtrl->GetValue() );
}
}
void DIALOG_FOOTPRINT_FP_EDITOR::OnFootprintNameKillFocus( wxFocusEvent& event )
{
if( !m_delayedFocusCtrl && !checkFootprintName( m_FootprintNameCtrl->GetValue() ) )
{
m_delayedFocusCtrl = m_FootprintNameCtrl;
m_delayedFocusPage = 0;
}
event.Skip();
}
void DIALOG_FOOTPRINT_FP_EDITOR::OnAddField( wxCommandEvent& event )
{
if( !m_itemsGrid->CommitPendingChanges() )
@ -698,12 +774,30 @@ void DIALOG_FOOTPRINT_FP_EDITOR::OnUpdateUI( wxUpdateUIEvent& event )
if( !m_itemsGrid->IsCellEditControlShown() && !m_modelsGrid->IsCellEditControlShown() )
adjustGridColumns( m_itemsGrid->GetRect().GetWidth());
// Handle a grid error. This is delayed to OnUpdateUI so that we can change focus
// even when the original validation was triggered from a killFocus event, and so
// that the corresponding notebook page can be shown in the background when triggered
// from an OK.
if( m_delayedFocusRow >= 0 )
if( m_itemsGrid->IsCellEditControlShown() )
{
int row = m_itemsGrid->GetGridCursorRow();
int col = m_itemsGrid->GetGridCursorCol();
if( row == 1 && col == TMC_TEXT )
{
wxGridCellEditor* editor = m_itemsGrid->GetCellEditor( row, col );
m_FootprintNameCtrl->ChangeValue( editor->GetValue() );
editor->DecRef();
}
}
// Handle a delayed focus. The delay allows us to:
// a) change focus when the error was triggered from within a killFocus handler
// b) show the correct notebook page in the background before the error dialog comes up
// when triggered from an OK or a notebook page change
if( m_delayedFocusPage >= 0 && m_NoteBook->GetSelection() != m_delayedFocusPage )
{
m_NoteBook->SetSelection( (unsigned) m_delayedFocusPage );
m_delayedFocusPage = -1;
}
if( !m_delayedErrorMessage.IsEmpty() )
{
// We will re-enter this routine when the error dialog is displayed, so make
@ -715,6 +809,17 @@ void DIALOG_FOOTPRINT_FP_EDITOR::OnUpdateUI( wxUpdateUIEvent& event )
DisplayError( nullptr, msg );
}
if( m_delayedFocusCtrl )
{
m_delayedFocusCtrl->SetFocus();
if( dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl ) )
dynamic_cast<wxTextEntry*>( m_delayedFocusCtrl )->SelectAll();
m_delayedFocusCtrl = nullptr;
}
else if( m_delayedFocusGrid )
{
m_delayedFocusGrid->SetFocus();
m_delayedFocusGrid->MakeCellVisible( m_delayedFocusRow, m_delayedFocusColumn );
m_delayedFocusGrid->SetGridCursor( m_delayedFocusRow, m_delayedFocusColumn );
@ -722,6 +827,7 @@ void DIALOG_FOOTPRINT_FP_EDITOR::OnUpdateUI( wxUpdateUIEvent& event )
m_delayedFocusGrid->EnableCellEditControl( true );
m_delayedFocusGrid->ShowCellEditControl();
m_delayedFocusGrid = nullptr;
m_delayedFocusRow = -1;
m_delayedFocusColumn = -1;
}

View File

@ -25,14 +25,16 @@
#ifndef DIALOG_EDIT_FOOTPRINT_FOR_MODEDIT_H
#define DIALOG_EDIT_FOOTPRINT_FOR_MODEDIT_H
// Include the wxFormBuider header base:
#include <vector>
#include <dialog_edit_footprint_for_fp_editor_base.h>
#include <text_mod_grid_table.h>
#include <widgets/unit_binder.h>
#include <class_module.h>
#include <dialog_edit_footprint_for_fp_editor_base.h>
class PANEL_PREV_3D;
class MODULE;
class FOOTPRINT_EDIT_FRAME;
class DIALOG_FOOTPRINT_FP_EDITOR : public DIALOG_FOOTPRINT_FP_EDITOR_BASE
{
@ -52,15 +54,17 @@ private:
std::vector<MODULE_3D_SETTINGS> m_shapes3D_list;
PANEL_PREV_3D* m_PreviewPane;
wxString m_delayedErrorMessage;
wxGrid* m_delayedFocusGrid;
wxControl* m_delayedFocusCtrl;
int m_delayedFocusPage;
WX_GRID* m_delayedFocusGrid;
int m_delayedFocusRow;
int m_delayedFocusColumn;
wxString m_delayedErrorMessage;
bool m_inSelect;
public:
// Constructor and destructor
DIALOG_FOOTPRINT_FP_EDITOR( FOOTPRINT_EDIT_FRAME* aParent, MODULE* aModule );
~DIALOG_FOOTPRINT_FP_EDITOR() override;
@ -79,10 +83,15 @@ private:
void OnAdd3DRow( wxCommandEvent& event ) override;
void Cfg3DPath( wxCommandEvent& event ) override;
void OnGridSize( wxSizeEvent& event ) override;
void OnFootprintNameKillFocus( wxFocusEvent& event ) override;
void OnFootprintNameText( wxCommandEvent& event ) override;
void OnGridCellChanging( wxGridEvent& event );
void OnAddField( wxCommandEvent& event ) override;
void OnDeleteField( wxCommandEvent& event ) override;
void OnUpdateUI( wxUpdateUIEvent& event ) override;
bool checkFootprintName( const wxString& aFootprintName );
void select3DModel( int aModelIdx );
void adjustGridColumns( int aWidth );

View File

@ -26,7 +26,7 @@ DIALOG_FOOTPRINT_FP_EDITOR_BASE::DIALOG_FOOTPRINT_FP_EDITOR_BASE( wxWindow* pare
wxStaticBoxSizer* sbSizerTexts;
sbSizerTexts = new wxStaticBoxSizer( new wxStaticBox( m_PanelGeneral, wxID_ANY, wxEmptyString ), wxVERTICAL );
m_itemsGrid = new WX_GRID( sbSizerTexts->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxSIMPLE_BORDER );
m_itemsGrid = new WX_GRID( sbSizerTexts->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), 0 );
// Grid
m_itemsGrid->CreateGrid( 2, 11 );
@ -409,6 +409,8 @@ DIALOG_FOOTPRINT_FP_EDITOR_BASE::DIALOG_FOOTPRINT_FP_EDITOR_BASE( wxWindow* pare
m_itemsGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnGridSize ), NULL, this );
m_bpAdd->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnAddField ), NULL, this );
m_bpDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnDeleteField ), NULL, this );
m_FootprintNameCtrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnFootprintNameKillFocus ), NULL, this );
m_FootprintNameCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnFootprintNameText ), NULL, this );
m_modelsGrid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::On3DModelCellChanged ), NULL, this );
m_modelsGrid->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::On3DModelSelected ), NULL, this );
m_button3DShapeAdd->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnAdd3DRow ), NULL, this );
@ -425,6 +427,8 @@ DIALOG_FOOTPRINT_FP_EDITOR_BASE::~DIALOG_FOOTPRINT_FP_EDITOR_BASE()
m_itemsGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnGridSize ), NULL, this );
m_bpAdd->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnAddField ), NULL, this );
m_bpDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnDeleteField ), NULL, this );
m_FootprintNameCtrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnFootprintNameKillFocus ), NULL, this );
m_FootprintNameCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnFootprintNameText ), NULL, this );
m_modelsGrid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::On3DModelCellChanged ), NULL, this );
m_modelsGrid->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::On3DModelSelected ), NULL, this );
m_button3DShapeAdd->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_FP_EDITOR_BASE::OnAdd3DRow ), NULL, this );

View File

@ -356,7 +356,7 @@
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxSIMPLE_BORDER</property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@ -789,7 +789,7 @@
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnKillFocus">OnFootprintNameKillFocus</event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
@ -806,7 +806,7 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnText">OnFootprintNameText</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>

View File

@ -105,6 +105,8 @@ class DIALOG_FOOTPRINT_FP_EDITOR_BASE : public DIALOG_SHIM
virtual void OnGridSize( wxSizeEvent& event ) { event.Skip(); }
virtual void OnAddField( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDeleteField( wxCommandEvent& event ) { event.Skip(); }
virtual void OnFootprintNameKillFocus( wxFocusEvent& event ) { event.Skip(); }
virtual void OnFootprintNameText( wxCommandEvent& event ) { event.Skip(); }
virtual void On3DModelCellChanged( wxGridEvent& event ) { event.Skip(); }
virtual void On3DModelSelected( wxGridEvent& event ) { event.Skip(); }
virtual void OnAdd3DRow( wxCommandEvent& event ) { event.Skip(); }

View File

@ -410,7 +410,7 @@ public:
* Function DeleteModuleFromLibrary
* deletes the given module from its library.
*/
bool DeleteModuleFromLibrary( MODULE* aModule );
bool DeleteModuleFromLibrary( const LIB_ID& aFPID, bool aConfirm );
/**
* Function IsElementVisible
@ -550,6 +550,11 @@ protected:
private:
/**
* Run the Footprint Properties dialog and handle changes made in it.
*/
void editFootprintProperties( MODULE* aFootprint );
/**
* Function moveExact
* Move the selected item exactly, popping up a dialog to allow the

View File

@ -524,13 +524,9 @@ void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem )
break;
case PCB_MODULE_T:
{
DIALOG_FOOTPRINT_FP_EDITOR dialog( this, static_cast<MODULE*>( aItem ) );
dialog.ShowModal();
GetScreen()->GetCurItem()->ClearFlags();
editFootprintProperties( (MODULE*) aItem );
m_canvas->MoveCursorToCrossHair();
m_canvas->Refresh();
}
break;
case PCB_MODULE_TEXT_T:

View File

@ -276,7 +276,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_MODEDIT_DELETE_PART:
if( DeleteModuleFromLibrary( LoadFootprint( getTargetFPId() ) ) )
if( DeleteModuleFromLibrary( getTargetFPId(), true ) )
{
if( getTargetFPId() == GetCurrentFPId() )
Clear_Pcb( false );
@ -556,11 +556,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
if( GetBoard()->m_Modules )
{
SetCurItem( GetBoard()->m_Modules );
DIALOG_FOOTPRINT_FP_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() );
dialog.ShowModal();
GetScreen()->GetCurItem()->ClearFlags();
editFootprintProperties( (MODULE*) GetScreen()->GetCurItem() );
m_canvas->Refresh();
}
@ -585,13 +581,9 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_EDIT_MODULE_PRMS:
{
DIALOG_FOOTPRINT_FP_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() );
dialog.ShowModal();
GetScreen()->GetCurItem()->ClearFlags();
editFootprintProperties( (MODULE*) GetScreen()->GetCurItem() );
m_canvas->MoveCursorToCrossHair();
m_canvas->Refresh();
}
break;
case ID_POPUP_PCB_MOVE_PAD_REQUEST:
@ -775,6 +767,32 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
}
void FOOTPRINT_EDIT_FRAME::editFootprintProperties( MODULE* aModule )
{
LIB_ID oldFPID = aModule->GetFPID();
DIALOG_FOOTPRINT_FP_EDITOR dialog( this, aModule );
dialog.ShowModal();
if( aModule->GetValue() != oldFPID.GetLibItemName() )
{
if( aModule->GetLink() )
{
SaveFootprintToBoard( false );
}
else
{
DeleteModuleFromLibrary( oldFPID, false );
SaveFootprint( aModule );
SyncLibraryTree( true );
}
}
GetScreen()->GetCurItem()->ClearFlags();
}
void FOOTPRINT_EDIT_FRAME::moveExact()
{
wxPoint translation;

View File

@ -524,18 +524,13 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName )
}
bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromLibrary( MODULE* aModule )
bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromLibrary( const LIB_ID& aFPID, bool aConfirm )
{
if( !aModule )
if( !aFPID.IsValid() )
return false;
LIB_ID fpid = aModule->GetFPID();
if( !fpid.IsValid() )
return false;
wxString nickname = fpid.GetLibNickname();
wxString fpname = fpid.GetLibItemName();
wxString nickname = aFPID.GetLibNickname();
wxString fpname = aFPID.GetLibItemName();
// Legacy libraries are readable, but modifying legacy format is not allowed
// So prompt the user if he try to delete a footprint from a legacy lib
@ -557,7 +552,7 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromLibrary( MODULE* aModule )
// Confirmation
wxString msg = wxString::Format( FMT_OK_DELETE, fpname.GetData(), nickname.GetData() );
if( !IsOK( this, msg ) )
if( aConfirm && !IsOK( this, msg ) )
return false;
try

View File

@ -186,6 +186,10 @@ bool FP_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsign
if( aCol != 0 )
return false;
// don't link to a board footprint, even if the FPIDs match
if( m_frame->IsCurrentFPFromBoard() )
return false;
auto node = ToNode( aItem );
wxCHECK( node, false );