Allow setting mandatory derived symbol field properties.

CHANGED: All mandatory fields in derived symbols can be edited.  This
not only includes the field value but also all text properties.

Kill the dual datasheet variable storage which caused many datasheet
bugs over the years.  The datasheet is now always stored in the data
sheet field.
This commit is contained in:
Wayne Stambaugh 2020-06-01 09:13:32 -04:00
parent dd1a7627f8
commit 52078a4b1b
17 changed files with 76 additions and 216 deletions

View File

@ -133,7 +133,6 @@ LIB_PART::LIB_PART( const LIB_PART& aPart, PART_LIB* aLibrary ) :
m_libId = aPart.m_libId;
m_description = aPart.m_description;
m_keyWords = aPart.m_keyWords;
m_docFileName = aPart.m_docFileName;
ClearSelected();
@ -187,7 +186,6 @@ const LIB_PART& LIB_PART::operator=( const LIB_PART& aPart )
m_libId = aPart.m_libId;
m_description = aPart.m_description;
m_keyWords = aPart.m_keyWords;
m_docFileName = aPart.m_docFileName;
m_drawings.clear();
@ -275,11 +273,6 @@ int LIB_PART::Compare( const LIB_PART& aRhs ) const
retv = m_keyWords.Cmp( aRhs.m_keyWords );
if( retv )
return retv;
retv = m_docFileName.Cmp( aRhs.m_docFileName );
if( retv )
return retv;
@ -339,12 +332,20 @@ std::unique_ptr< LIB_PART > LIB_PART::Flatten() const
// Copy the parent.
retv.reset( new LIB_PART( *parent.get() ) );
// Now add the inherited part (this) information.
// Now add the inherited part mandator field (this) information.
retv->SetName( m_name );
const LIB_FIELD* datasheetField = GetField( DATASHEET );
retv->GetField( DATASHEET )->SetText( datasheetField->GetText() );
retv->SetDocFileName( m_docFileName );
for( int i = 0; i < MANDATORY_FIELDS; i++ )
{
wxString tmp = GetField( i )->GetText();
// If the field isn't defined then inherit the parent field value.
if( tmp.IsEmpty() )
retv->GetField( i )->SetText( parent->GetField( i )->GetText() );
else
*retv->GetField( i ) = *GetField( i );
}
retv->SetKeyWords( m_keyWords );
retv->SetDescription( m_description );
}
@ -887,6 +888,14 @@ LIB_FIELD& LIB_PART::GetFootprintField()
}
LIB_FIELD& LIB_PART::GetDatasheetField()
{
LIB_FIELD* field = GetField( DATASHEET );
wxASSERT( field != NULL );
return *field;
}
void LIB_PART::SetOffset( const wxPoint& aOffset )
{
for( LIB_ITEM& item : m_drawings )

View File

@ -118,7 +118,6 @@ class LIB_PART : public EDA_ITEM, public LIB_TREE_ITEM
wxString m_name; ///< Symbol name.
wxString m_description; ///< documentation for info
wxString m_keyWords; ///< keyword list (used for search for parts by keyword)
wxString m_docFileName; ///< Associate doc file name
static int m_subpartIdSeparator; ///< the separator char between
///< the subpart id and the reference like U1A
@ -178,13 +177,6 @@ public:
wxString GetKeyWords() const { return m_keyWords; }
void SetDocFileName( const wxString& aDocFileName )
{
m_docFileName = aDocFileName;
}
wxString GetDocFileName() const { return m_docFileName; }
wxString GetSearchText() override;
/**
@ -296,6 +288,9 @@ public:
/** Return reference to the footprint field */
LIB_FIELD& GetFootprintField();
/** Return reference to the datasheet field. */
LIB_FIELD& GetDatasheetField();
/**
* Print part.
*

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 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
@ -145,10 +145,6 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::TransferDataToWindow()
// Push a copy of each field into m_updateFields
m_libEntry->GetFields( *m_fields );
// Copy the data sheet field from the old alias document file name if it's not empty.
if( !m_libEntry->GetDocFileName().IsEmpty() )
m_fields->at( DATASHEET ).SetText( m_libEntry->GetDocFileName() );
// The Y axis for components in lib is from bottom to top while the screen axis is top
// to bottom: we must change the y coord sign for editing
for( size_t i = 0; i < m_fields->size(); ++i )
@ -203,7 +199,9 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::TransferDataToWindow()
m_inheritanceSelectCombo->SetSelection( selection );
// Copy the reference field from the root symbol to prevent validation errors.
m_fields->at( REFERENCE ).SetText( rootPart->GetReferenceField().GetText() );
if( m_fields->at( REFERENCE ).GetText().IsEmpty() )
m_fields->at( REFERENCE ).SetText( rootPart->GetReferenceField().GetText() );
m_lastOpenedPage = 0;
}
@ -313,8 +311,6 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::TransferDataFromWindow()
m_fields->at( i ).SetPosition( pos );
}
// Datasheet field is special; copy it to the root alias docfilename
m_libEntry->SetDocFileName( m_fields->at( DATASHEET ).GetText() );
m_libEntry->SetFields( *m_fields );
// We need to keep the name and the value the same at the moment!

View File

@ -2,6 +2,8 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -190,7 +192,7 @@ void DIALOG_UPDATE_FIELDS::updateFields( SCH_COMPONENT* aComponent )
if( fieldName == TEMPLATE_FIELDNAME::GetDefaultFieldName( VALUE ) )
fieldValue = alias->GetName();
else if( fieldName == TEMPLATE_FIELDNAME::GetDefaultFieldName( DATASHEET ) )
fieldValue = alias->GetDocFileName();
fieldValue = alias->GetDatasheetField().GetText();
}
if( fieldValue.IsEmpty() )

View File

@ -247,20 +247,13 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
{
wxGridCellAttr* tmp;
// Only the VALUE and DATASHEET fields can be edited for inherited symbols.
bool rowIsReadOnly = m_part && m_part->IsAlias() && ( aRow == REFERENCE || aRow == FOOTPRINT );
switch( aCol )
{
case FDC_NAME:
if( aRow < m_mandatoryFieldCount || rowIsReadOnly )
if( aRow < m_mandatoryFieldCount )
{
tmp = m_fieldNameAttr->Clone();
tmp->SetReadOnly( true );
if( rowIsReadOnly )
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
@ -272,25 +265,14 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
case FDC_VALUE:
if( m_parentType == SCH_COMPONENT_T && aRow == REFERENCE )
{
if( rowIsReadOnly )
{
tmp = m_referenceAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_referenceAttr->IncRef();
return m_referenceAttr;
}
m_referenceAttr->IncRef();
return m_referenceAttr;
}
else if( m_parentType == SCH_COMPONENT_T && aRow == VALUE )
{
// 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 ) )
|| rowIsReadOnly )
if( ( m_part && m_part->IsPower() && !m_frame->IsType( FRAME_SCH_LIB_EDITOR ) ) )
{
tmp = m_readOnlyAttr->Clone();
tmp->SetReadOnly( true );
@ -305,18 +287,8 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
}
else if( m_parentType == SCH_COMPONENT_T && aRow == FOOTPRINT )
{
if( rowIsReadOnly )
{
tmp = m_footprintAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_footprintAttr->IncRef();
return m_footprintAttr;
}
m_footprintAttr->IncRef();
return m_footprintAttr;
}
else if( m_parentType == SCH_COMPONENT_T && aRow == DATASHEET )
{
@ -340,33 +312,13 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
if( templateFn && templateFn->m_URL )
{
if( rowIsReadOnly )
{
tmp = m_urlAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_urlAttr->IncRef();
return m_urlAttr;
}
m_urlAttr->IncRef();
return m_urlAttr;
}
else
{
if( rowIsReadOnly )
{
tmp = m_nonUrlAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_nonUrlAttr->IncRef();
return m_nonUrlAttr;
}
m_nonUrlAttr->IncRef();
return m_nonUrlAttr;
}
}
@ -375,74 +327,25 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
case FDC_TEXT_SIZE:
case FDC_POSX:
case FDC_POSY:
if( rowIsReadOnly )
{
tmp = m_readOnlyAttr->Clone();
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
return nullptr;
}
return nullptr;
case FDC_H_ALIGN:
if( rowIsReadOnly )
{
tmp = m_hAlignAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_hAlignAttr->IncRef();
return m_hAlignAttr;
}
m_hAlignAttr->IncRef();
return m_hAlignAttr;
case FDC_V_ALIGN:
if( rowIsReadOnly )
{
tmp = m_vAlignAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_vAlignAttr->IncRef();
return m_vAlignAttr;
}
m_vAlignAttr->IncRef();
return m_vAlignAttr;
case FDC_ORIENTATION:
if( rowIsReadOnly )
{
tmp = m_orientationAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_orientationAttr->IncRef();
return m_orientationAttr;
}
m_orientationAttr->IncRef();
return m_orientationAttr;
case FDC_SHOWN:
case FDC_ITALIC:
case FDC_BOLD:
if( rowIsReadOnly )
{
tmp = m_boolAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_boolAttr->IncRef();
return m_boolAttr;
}
m_boolAttr->IncRef();
return m_boolAttr;
default:
wxFAIL;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
* Copyright (C) 2017-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2020 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 as published by the
@ -168,7 +168,7 @@ protected:
switch( aField.GetId() )
{
case DATASHEET:
text = m_symbol->GetDocFileName();
text = m_symbol->GetDatasheetField().GetText();
if( text.IsEmpty() || text == wxT( "~" ) )
{

View File

@ -432,10 +432,7 @@ void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart )
// select the current component in the tree widget
if( m_my_part )
{
m_treePane->GetLibTree()->SelectLibId( m_my_part->GetLibId() );
m_my_part->GetField( DATASHEET )->SetText( aPart->GetDocFileName() );
}
wxString partName = m_my_part ? m_my_part->GetName() : wxString();
m_libMgr->SetCurrentPart( partName );

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2020 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
@ -240,5 +240,5 @@ void LIB_EDIT_FRAME::DisplayCmpDoc()
AppendMsgPanel( _( "Type" ), msg, MAGENTA, 8 );
AppendMsgPanel( _( "Description" ), m_my_part->GetDescription(), CYAN, 8 );
AppendMsgPanel( _( "Key words" ), m_my_part->GetKeyWords(), DARKDARKGRAY );
AppendMsgPanel( _( "Datasheet" ), m_my_part->GetDocFileName(), DARKDARKGRAY );
AppendMsgPanel( _( "Datasheet" ), m_my_part->GetDatasheetField().GetText(), DARKDARKGRAY );
}

View File

@ -418,8 +418,8 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeLibParts()
if( !lcomp->GetDescription().IsEmpty() )
xlibpart->AddChild( node( "description", lcomp->GetDescription() ) );
if( !lcomp->GetDocFileName().IsEmpty() )
xlibpart->AddChild( node( "docs", lcomp->GetDocFileName() ) );
if( !lcomp->GetDatasheetField().GetText().IsEmpty() )
xlibpart->AddChild( node( "docs", lcomp->GetDatasheetField().GetText() ) );
// Write the footprint list
if( lcomp->GetFootprints().GetCount() )

View File

@ -136,9 +136,9 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* sh
// Update the reference -- just the prefix for now.
if( sheet )
SetRef( sheet, aPart.GetReferenceField().GetText() + wxT( "?" ) );
SetRef( sheet, m_part->GetReferenceField().GetText() + wxT( "?" ) );
else
m_prefix = aPart.GetReferenceField().GetText() + wxT( "?" );
m_prefix = m_part->GetReferenceField().GetText() + wxT( "?" );
}
@ -269,9 +269,7 @@ wxString SCH_COMPONENT::GetDescription() const
wxString SCH_COMPONENT::GetDatasheet() const
{
if( m_part )
{
return m_part->GetDocFileName();
}
return m_part->GetDatasheetField().GetText();
return wxEmptyString;
}
@ -660,7 +658,9 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
continue;
if( idx >= 0 && idx < MANDATORY_FIELDS )
{
schField = GetField( idx );
}
else
{
schField = FindField( libField.GetCanonicalName() );
@ -687,12 +687,6 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
else if( idx == DATASHEET )
{
schField->SetText( GetDatasheet() ); // fetch alias-specific value
// Some older libraries may be broken and the alias datasheet information
// in the document file for the root part may have been dropped. This only
// happens for the root part.
if( schField->GetText().IsEmpty() && symbolName == m_part->GetName() )
schField->SetText( m_part->GetField( DATASHEET )->GetText() );
}
else
{

View File

@ -2728,10 +2728,7 @@ void SCH_LEGACY_PLUGIN_CACHE::loadDocs()
case 'F':
if( symbol )
{
symbol->SetDocFileName( text );
symbol->GetField( DATASHEET )->SetText( text );
}
break;
case 0:
@ -4268,7 +4265,7 @@ void SCH_LEGACY_PLUGIN_CACHE::saveDocFile()
{
wxString description = it->second->GetDescription();
wxString keyWords = it->second->GetKeyWords();
wxString docFileName = it->second->GetDocFileName();
wxString docFileName = it->second->GetDatasheetField().GetText();
if( description.IsEmpty() && keyWords.IsEmpty() && docFileName.IsEmpty() )
continue;

View File

@ -765,13 +765,6 @@ void SCH_SEXPR_PARSER::parseProperty( std::unique_ptr<LIB_PART>& aSymbol )
{
existingField = aSymbol->GetField( field->GetId() );
/// @todo Remove this once the legacy file format is deprecated.
if( field->GetId() == DATASHEET )
{
aSymbol->SetDocFileName( value );
field->SetText( wxEmptyString );
}
*existingField = *field;
}
else if( name == "ki_keywords" )

View File

@ -1471,6 +1471,8 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
{
wxCHECK_RET( aSymbol, "Invalid LIB_PART pointer." );
int lastFieldId;
LIB_FIELDS fields;
std::string name = aFormatter.Quotew( aSymbol->GetLibId().Format().wx_str() );
std::string unitName = aSymbol->GetLibId().GetLibItemName();
@ -1520,14 +1522,12 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
aFormatter.Print( 0, "\n" );
LIB_FIELDS fields;
aSymbol->GetFields( fields );
for( auto field : fields )
saveField( &field, aFormatter, aNestLevel + 1 );
int lastFieldId = fields.back().GetId() + 1;
lastFieldId = fields.back().GetId() + 1;
// @todo At some point in the future the lock status (all units interchangeable) should
// be set deterministically. For now a custom lock properter is used to preserve the
@ -1565,18 +1565,14 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
name.c_str(),
aFormatter.Quotew( parent->GetName() ).c_str() );
LIB_FIELD tmp = parent->GetValueField();
tmp.SetText( aSymbol->GetName() );
saveField( &tmp, aFormatter, aNestLevel + 1 );
aSymbol->GetFields( fields );
if( !aSymbol->GetDocFileName().IsEmpty() )
{
tmp = *aSymbol->GetField( DATASHEET );
tmp.SetText( aSymbol->GetDocFileName() );
saveField( &tmp, aFormatter, aNestLevel + 1 );
}
for( auto field : fields )
saveField( &field, aFormatter, aNestLevel + 1 );
saveDcmInfoAsFields( aSymbol, aFormatter, aNestLevel, MANDATORY_FIELDS );
lastFieldId = fields.back().GetId() + 1;
saveDcmInfoAsFields( aSymbol, aFormatter, aNestLevel, lastFieldId );
}
aFormatter.Print( aNestLevel, ")\n" );

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019 CERN
*
* This program is free software: you can redistribute it and/or modify it
@ -151,7 +151,7 @@ void LIB_VIEW_FRAME::SyncToolbars()
LIB_PART* symbol = GetSelectedSymbol();
m_mainToolBar->Toggle( EE_ACTIONS::showDatasheet,
symbol && !symbol->GetDocFileName().IsEmpty() );
symbol && !symbol->GetDatasheetField().GetText().IsEmpty() );
m_mainToolBar->Toggle( EE_ACTIONS::showDeMorganStandard, symbol && symbol->HasConversion(),
m_convert == LIB_FIELD::LIB_CONVERT::BASE );
m_mainToolBar->Toggle( EE_ACTIONS::showDeMorganAlternate, symbol && symbol->HasConversion(),

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2020 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
@ -263,7 +263,7 @@ int EE_INSPECTION_TOOL::ShowDatasheet( const TOOL_EVENT& aEvent )
if( !part )
return 0;
datasheet = part->GetDocFileName();
datasheet = part->GetDatasheetField().GetText();
}
else if( m_frame->IsType( FRAME_SCH_VIEWER ) || m_frame->IsType( FRAME_SCH_VIEWER_MODAL ) )
{
@ -272,7 +272,7 @@ int EE_INSPECTION_TOOL::ShowDatasheet( const TOOL_EVENT& aEvent )
if( !entry )
return 0;
datasheet = entry->GetDocFileName();
datasheet = entry->GetDatasheetField().GetText();
}
else if( m_frame->IsType( FRAME_SCH ) )
{

View File

@ -1226,19 +1226,8 @@ bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, bool checkVisibilityO
case LIB_PART_T: // In libedit we do not want to select the symbol itself.
return false;
case LIB_FIELD_T:
{
if( symbeditFrame )
{
LIB_PART* currentPart = symbeditFrame->GetCurPart();
// Nothing in derived symbols is editable at the moment.
if( currentPart && currentPart->IsAlias() )
return false;
}
case LIB_FIELD_T: // LIB_FIELD object can always be edited.
break;
}
case LIB_ARC_T:
case LIB_CIRCLE_T:

View File

@ -323,17 +323,6 @@ BOOST_AUTO_TEST_CASE( Compare )
m_part_no_data.SetKeyWords( wxEmptyString );
testPart.SetKeyWords( wxEmptyString );
// Documentation file string tests.
m_part_no_data.SetDocFileName( "b" );
testPart.SetDocFileName( "b" );
BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 );
m_part_no_data.SetDocFileName( "a" );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
m_part_no_data.SetDocFileName( "c" );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
m_part_no_data.SetDocFileName( wxEmptyString );
testPart.SetDocFileName( wxEmptyString );
// Pin name offset comparison tests.
testPart.SetPinNameOffset( testPart.GetPinNameOffset() + 1 );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );