diff --git a/common/hash_eda.cpp b/common/hash_eda.cpp index 3992dcf2b8..819fdcf11e 100644 --- a/common/hash_eda.cpp +++ b/common/hash_eda.cpp @@ -31,6 +31,7 @@ #include #include +#include #include using namespace std; @@ -102,16 +103,17 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags ) break; case PCB_FIELD_T: + if( !( aFlags & HASH_REF ) && static_cast( aItem )->IsReference() ) + break; + + if( !( aFlags & HASH_VALUE ) && static_cast( aItem )->IsValue() ) + break; + + KI_FALLTHROUGH; case PCB_TEXT_T: { const PCB_TEXT* text = static_cast( aItem ); - if( !( aFlags & HASH_REF ) && text->GetType() == PCB_TEXT::TEXT_is_REFERENCE ) - break; - - if( !( aFlags & HASH_VALUE ) && text->GetType() == PCB_TEXT::TEXT_is_VALUE ) - break; - ret = hash_board_item( text, aFlags ); hash_combine( ret, text->GetText().ToStdString() ); hash_combine( ret, text->IsItalic() ); diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h index 4a1149a667..d6def1640b 100644 --- a/include/core/typeinfo.h +++ b/include/core/typeinfo.h @@ -106,6 +106,14 @@ enum KICAD_T PCB_NETINFO_T, ///< class NETINFO_ITEM, a description of a net PCB_GROUP_T, ///< class PCB_GROUP, a set of BOARD_ITEMs + // Be prudent with these types: + // they should be used only to locate a specific field type among PCB_FIELD_Ts + // N.B. If you add a type here, be sure to add it below to the BaseType() + PCB_FIELD_LOCATE_REFERENCE_T, + PCB_FIELD_LOCATE_VALUE_T, + PCB_FIELD_LOCATE_FOOTPRINT_T, + PCB_FIELD_LOCATE_DATASHEET_T, + // Be prudent with these types: // they should be used only to locate specific item sub-types // N.B. If you add a type here, be sure to add it below to the BaseType() @@ -264,6 +272,12 @@ constexpr KICAD_T BaseType( const KICAD_T aType ) case SCH_SYMBOL_LOCATE_POWER_T: return SCH_SYMBOL_T; + case PCB_FIELD_LOCATE_REFERENCE_T: + case PCB_FIELD_LOCATE_VALUE_T: + case PCB_FIELD_LOCATE_FOOTPRINT_T: + case PCB_FIELD_LOCATE_DATASHEET_T: + return PCB_FIELD_T; + case PCB_LOCATE_HOLE_T: case PCB_LOCATE_PTH_T: case PCB_LOCATE_NPTH_T: diff --git a/pcbnew/board_commit.cpp b/pcbnew/board_commit.cpp index c070ed7fa1..e154b777d3 100644 --- a/pcbnew/board_commit.cpp +++ b/pcbnew/board_commit.cpp @@ -432,12 +432,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags ) switch( boardItem->Type() ) { case PCB_TEXT_T: - // don't allow deletion of Reference or Value - if( static_cast( boardItem )->GetType() != PCB_TEXT::TEXT_is_DIVERS ) - break; - - KI_FALLTHROUGH; - case PCB_PAD_T: case PCB_SHAPE_T: // a shape (normally not on copper layers) case PCB_BITMAP_T: // a bitmap on a user layer diff --git a/pcbnew/collectors.cpp b/pcbnew/collectors.cpp index 5f3b0a63f4..d695061b36 100644 --- a/pcbnew/collectors.cpp +++ b/pcbnew/collectors.cpp @@ -268,6 +268,17 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData ) break; case PCB_FIELD_T: + { + PCB_FIELD* field = static_cast( item ); + + if( field->IsReference() && m_Guide->IgnoreFPReferences() ) + return INSPECT_RESULT::CONTINUE; + + if( field->IsValue() && m_Guide->IgnoreFPValues() ) + return INSPECT_RESULT::CONTINUE; + } + + KI_FALLTHROUGH; case PCB_TEXT_T: if( item->GetParentFootprint() ) { @@ -290,27 +301,11 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData ) * The three text types have different criteria: reference and value have their own * ignore flags; user text instead follows their layer visibility. Checking this here * is simpler than later (when layer visibility is checked for other entities) + * + * Note: we fallthrough from PCB_FIELD_T above, hence the type check. */ - switch( text->GetType() ) - { - case PCB_TEXT::TEXT_is_REFERENCE: - if( m_Guide->IgnoreFPReferences() ) - return INSPECT_RESULT::CONTINUE; - - break; - - case PCB_TEXT::TEXT_is_VALUE: - if( m_Guide->IgnoreFPValues() ) - return INSPECT_RESULT::CONTINUE; - - break; - - case PCB_TEXT::TEXT_is_DIVERS: - if( !m_Guide->IsLayerVisible( layer ) ) - return INSPECT_RESULT::CONTINUE; - - break; - } + if( text->Type() == PCB_TEXT_T && !m_Guide->IsLayerVisible( layer ) ) + return INSPECT_RESULT::CONTINUE; } break; diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 9a54313eb1..6db0ef7872 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -279,17 +279,16 @@ std::string FormatProbeItem( BOARD_ITEM* aItem ) } case PCB_FIELD_T: - case PCB_TEXT_T: { - PCB_TEXT* text = static_cast( aItem ); - FOOTPRINT* footprint = text->GetParentFootprint(); + PCB_FIELD* field = static_cast( aItem ); + FOOTPRINT* footprint = field->GetParentFootprint(); const char* text_key; /* This can't be a switch since the break need to pull out * from the outer switch! */ - if( text->GetType() == PCB_TEXT::TEXT_is_REFERENCE ) + if( field->IsReference() ) text_key = "$REF:"; - else if( text->GetType() == PCB_TEXT::TEXT_is_VALUE ) + else if( field->IsValue() ) text_key = "$VAL:"; else break; @@ -297,7 +296,7 @@ std::string FormatProbeItem( BOARD_ITEM* aItem ) return StrPrintf( "$PART: \"%s\" %s \"%s\"", TO_UTF8( footprint->GetReference() ), text_key, - TO_UTF8( text->GetText() ) ); + TO_UTF8( field->GetText() ) ); } default: diff --git a/pcbnew/dialogs/dialog_text_properties.cpp b/pcbnew/dialogs/dialog_text_properties.cpp index e3e100d331..fa7567c2f4 100644 --- a/pcbnew/dialogs/dialog_text_properties.cpp +++ b/pcbnew/dialogs/dialog_text_properties.cpp @@ -79,18 +79,30 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, PC if( m_item->GetParentFootprint() ) { - switch( m_item->GetType() ) + if( m_item->Type() == PCB_FIELD_T ) { - case PCB_TEXT::TEXT_is_REFERENCE: title = _( "Footprint Reference Properties" ); break; - case PCB_TEXT::TEXT_is_VALUE: title = _( "Footprint Value Properties" ); break; - case PCB_TEXT::TEXT_is_DIVERS: title = _( "Footprint Text Properties" ); break; - } + PCB_FIELD* field = static_cast( m_item ); - switch( m_item->GetType() ) + if( field->IsReference() ) + { + title = _( "Footprint Reference Properties" ); + m_TextLabel->SetLabel( _( "Reference:" ) ); + } + else if( field->IsValue() ) + { + title = _( "Footprint Value Properties" ); + m_TextLabel->SetLabel( _( "Value:" ) ); + } + else + { + title = _( "Footprint Field Properties" ); + m_TextLabel->SetLabel( _( "Text:" ) ); + } + } + else { - case PCB_TEXT::TEXT_is_REFERENCE: m_TextLabel->SetLabel( _( "Reference:" ) ); break; - case PCB_TEXT::TEXT_is_VALUE: m_TextLabel->SetLabel( _( "Value:" ) ); break; - case PCB_TEXT::TEXT_is_DIVERS: m_TextLabel->SetLabel( _( "Text:" ) ); break; + title = _( "Footprint Text Properties" ); + m_TextLabel->SetLabel( _( "Text:" ) ); } SetInitialFocus( m_SingleLineText ); @@ -227,19 +239,19 @@ void PCB_BASE_EDIT_FRAME::ShowTextPropertiesDialog( PCB_TEXT* aText ) void DIALOG_TEXT_PROPERTIES::OnSetFocusText( wxFocusEvent& event ) { + if( m_item->Type() == PCB_FIELD_T && static_cast( m_item )->IsReference() ) + { #ifdef __WXGTK__ - // Force an update of the text control before setting the text selection - // This is needed because GTK seems to ignore the selection on first update - // - // Note that we can't do this on OSX as it tends to provoke Apple's - // "[NSAlert runModal] may not be invoked inside of transaction begin/commit pair" - // bug. See: https://bugs.launchpad.net/kicad/+bug/1837225 - if( m_item->GetType() == PCB_TEXT::TEXT_is_REFERENCE ) + // Force an update of the text control before setting the text selection + // This is needed because GTK seems to ignore the selection on first update + // + // Note that we can't do this on OSX as it tends to provoke Apple's + // "[NSAlert runModal] may not be invoked inside of transaction begin/commit pair" + // bug. See: https://bugs.launchpad.net/kicad/+bug/1837225 m_SingleLineText->Update(); #endif - - if( m_item->GetType() == PCB_TEXT::TEXT_is_REFERENCE ) KIUI::SelectReferenceNumber( static_cast( m_SingleLineText ) ); + } else m_SingleLineText->SetSelection( -1, -1 ); @@ -256,7 +268,7 @@ bool DIALOG_TEXT_PROPERTIES::TransferDataToWindow() { m_SingleLineText->SetValue( m_item->GetText() ); - if( m_item->GetType() == PCB_TEXT::TEXT_is_REFERENCE ) + if( m_item->Type() == PCB_FIELD_T && static_cast( m_item )->IsReference() ) KIUI::SelectReferenceNumber( static_cast( m_SingleLineText ) ); else m_SingleLineText->SetSelection( -1, -1 ); diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index fa88987483..3998382e8b 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -274,10 +274,10 @@ const PCB_FIELD* FOOTPRINT::GetField( MANDATORY_FIELD_T aFieldType ) const PCB_FIELD* FOOTPRINT::GetFieldById( int aFieldId ) { - for( size_t ii = 0; ii < m_fields.size(); ++ii ) + for( PCB_FIELD* field : m_fields ) { - if( m_fields[ii]->GetId() == aFieldId ) - return m_fields[ii]; + if( field->GetId() == aFieldId ) + return field; } return nullptr; @@ -285,9 +285,9 @@ PCB_FIELD* FOOTPRINT::GetFieldById( int aFieldId ) bool FOOTPRINT::HasFieldByName( const wxString& aFieldName ) const { - for( size_t ii = 0; ii < m_fields.size(); ++ii ) + for( PCB_FIELD* field : m_fields ) { - if( m_fields[ii]->GetCanonicalName() == aFieldName ) + if( field->GetCanonicalName() == aFieldName ) return true; } @@ -296,10 +296,10 @@ bool FOOTPRINT::HasFieldByName( const wxString& aFieldName ) const PCB_FIELD* FOOTPRINT::GetFieldByName( const wxString& aFieldName ) { - for( size_t ii = 0; ii < m_fields.size(); ++ii ) + for( PCB_FIELD* field : m_fields ) { - if( m_fields[ii]->GetName() == aFieldName ) - return m_fields[ii]; + if( field->GetName() == aFieldName ) + return field; } return nullptr; @@ -696,25 +696,14 @@ void FOOTPRINT::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectiv switch( aBoardItem->Type() ) { case PCB_FIELD_T: - case PCB_TEXT_T: - - if( dynamic_cast( aBoardItem ) != nullptr ) - { - if( aMode == ADD_MODE::APPEND ) - m_fields.push_back( static_cast( aBoardItem ) ); - else - m_fields.push_front( static_cast( aBoardItem ) ); - - break; - } + if( aMode == ADD_MODE::APPEND ) + m_fields.push_back( static_cast( aBoardItem ) ); else - { - // Only user text can be added this way. - wxASSERT( static_cast( aBoardItem )->GetType() == PCB_TEXT::TEXT_is_DIVERS ); - } + m_fields.push_front( static_cast( aBoardItem ) ); - KI_FALLTHROUGH; + break; + case PCB_TEXT_T: case PCB_DIM_ALIGNED_T: case PCB_DIM_LEADER_T: case PCB_DIM_CENTER_T: @@ -770,9 +759,12 @@ void FOOTPRINT::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aMode ) { switch( aBoardItem->Type() ) { - case PCB_TEXT_T: + case PCB_FIELD_T: + { + PCB_FIELD* field = static_cast( aBoardItem ); + // Only user text can be removed this way. - wxCHECK_RET( static_cast( aBoardItem )->GetType() == PCB_TEXT::TEXT_is_DIVERS, + wxCHECK_RET( field->IsMandatoryField(), wxT( "Please report this bug: Invalid remove operation on required text" ) ); for( auto it = m_fields.begin(); it != m_fields.end(); ++it ) { @@ -782,8 +774,10 @@ void FOOTPRINT::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aMode ) break; } } - KI_FALLTHROUGH; + } + break; + case PCB_TEXT_T: case PCB_DIM_ALIGNED_T: case PCB_DIM_CENTER_T: case PCB_DIM_ORTHOGONAL_T: @@ -1963,15 +1957,18 @@ BOARD_ITEM* FOOTPRINT::DuplicateItem( const BOARD_ITEM* aItem, bool aAddToFootpr PCB_TEXT* new_text = new PCB_TEXT( *static_cast( aItem ) ); const_cast( new_text->m_Uuid ) = KIID(); - if( new_text->GetType() == PCB_TEXT::TEXT_is_REFERENCE ) + if( aItem->Type() == PCB_FIELD_T ) { - new_text->SetText( wxT( "${REFERENCE}" ) ); - new_text->SetType( PCB_TEXT::TEXT_is_DIVERS ); - } - else if( new_text->GetType() == PCB_TEXT::TEXT_is_VALUE ) - { - new_text->SetText( wxT( "${VALUE}" ) ); - new_text->SetType( PCB_TEXT::TEXT_is_DIVERS ); + switch( static_cast( aItem )->GetId() ) + { + case REFERENCE_FIELD: new_text->SetText( wxT( "${REFERENCE}" ) ); break; + + case VALUE_FIELD: new_text->SetText( wxT( "${VALUE}" ) ); break; + + case DATASHEET_FIELD: new_text->SetText( wxT( "${DATASHEET}" ) ); break; + + case FOOTPRINT_FIELD: new_text->SetText( wxT( "${FOOTPRINT}" ) ); break; + } } if( aAddToFootprint ) diff --git a/pcbnew/footprint_editor_utils.cpp b/pcbnew/footprint_editor_utils.cpp index ef1209b07a..a546a90a05 100644 --- a/pcbnew/footprint_editor_utils.cpp +++ b/pcbnew/footprint_editor_utils.cpp @@ -70,23 +70,13 @@ void FOOTPRINT_EDIT_FRAME::LoadFootprintFromLibrary( LIB_ID aFPID ) footprint->ClearFlags(); - // if either m_Reference or m_Value are gone, reinstall them - + // if either reference or value are missing, reinstall them - // otherwise you cannot see what you are doing on board - PCB_TEXT* ref = &footprint->Reference(); - PCB_TEXT* val = &footprint->Value(); + if( footprint->Reference().GetText().IsEmpty() ) + footprint->SetReference( wxT( "Ref**" ) ); - if( val && ref ) - { - ref->SetType( PCB_TEXT::TEXT_is_REFERENCE ); // just in case ... - - if( ref->GetText().IsEmpty() ) - ref->SetText( wxT( "Ref**" ) ); - - val->SetType( PCB_TEXT::TEXT_is_VALUE ); // just in case ... - - if( val->GetText().IsEmpty() ) - val->SetText( wxT( "Val**" ) ); - } + if( footprint->Value().GetText().IsEmpty() ) + footprint->SetValue( wxT( "Val**" ) ); Zoom_Automatique( false ); diff --git a/pcbnew/footprint_libraries_utils.cpp b/pcbnew/footprint_libraries_utils.cpp index 667bb8104f..6ce44fe712 100644 --- a/pcbnew/footprint_libraries_utils.cpp +++ b/pcbnew/footprint_libraries_utils.cpp @@ -1314,7 +1314,7 @@ FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( const wxString& aFootprintName, b for( size_t i = 2; i < settings.m_DefaultFPTextItems.size(); ++i ) { - PCB_TEXT* textItem = new PCB_TEXT( footprint, PCB_TEXT::TEXT_is_DIVERS ); + PCB_TEXT* textItem = new PCB_TEXT( footprint ); textItem->SetText( settings.m_DefaultFPTextItems[i].m_Text ); textItem->SetVisible( settings.m_DefaultFPTextItems[i].m_Visible ); txt_layer = (PCB_LAYER_ID) settings.m_DefaultFPTextItems[i].m_Layer; diff --git a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp index 1f3326b9b0..319f823cfb 100644 --- a/pcbnew/import_gfx/graphics_importer_pcbnew.cpp +++ b/pcbnew/import_gfx/graphics_importer_pcbnew.cpp @@ -226,5 +226,5 @@ std::unique_ptr GRAPHICS_IMPORTER_FOOTPRINT::createDrawing() std::unique_ptr GRAPHICS_IMPORTER_FOOTPRINT::createText() { - return std::make_unique( m_footprint, PCB_TEXT::TEXT_is_DIVERS ); + return std::make_unique( m_footprint ); } diff --git a/pcbnew/kicad_clipboard.cpp b/pcbnew/kicad_clipboard.cpp index 7712a91cac..a1bb1890ca 100644 --- a/pcbnew/kicad_clipboard.cpp +++ b/pcbnew/kicad_clipboard.cpp @@ -112,9 +112,9 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri const PCB_GROUP* group = dynamic_cast( item ); BOARD_ITEM* clone; - if( const PCB_TEXT* text = dyn_cast( item ) ) + if( const PCB_FIELD* field = dyn_cast( item ) ) { - if( text->GetType() != PCB_TEXT::TEXT_is_DIVERS ) + if( field->IsMandatoryField() ) continue; } @@ -144,13 +144,13 @@ void CLIPBOARD_IO::SaveSelection( const PCB_SELECTION& aSelected, bool isFootpri static_cast( clone )->RunOnDescendants( [&]( BOARD_ITEM* descendant ) { - // One cannot add a text reference or value to a given footprint: - // only one is allowed. So add only PCB_TEXT::TEXT_is_DIVERS + // One cannot add an additional mandatory field to a given footprint: + // only one is allowed. So add only non-mandatory fields. bool can_add = true; - if( const PCB_TEXT* text = dyn_cast( descendant ) ) + if( const PCB_FIELD* field = dyn_cast( item ) ) { - if( text->GetType() != PCB_TEXT::TEXT_is_DIVERS ) + if( field->IsMandatoryField() ) can_add = false; } diff --git a/pcbnew/pcb_field.cpp b/pcbnew/pcb_field.cpp index f4df231d9c..e55ec72f57 100644 --- a/pcbnew/pcb_field.cpp +++ b/pcbnew/pcb_field.cpp @@ -27,18 +27,14 @@ #include PCB_FIELD::PCB_FIELD( FOOTPRINT* aParent, int aFieldId, const wxString& aName ) : - PCB_TEXT( aParent, TEXT_TYPE( aFieldId ) ) + PCB_TEXT( aParent, PCB_FIELD_T ), m_id( aFieldId ), m_name( aName ) { - m_name = aName; - SetId( aFieldId ); } PCB_FIELD::PCB_FIELD( const PCB_TEXT& aText, int aFieldId, const wxString& aName ) : - PCB_TEXT( aText ) + PCB_TEXT( aText ), m_id( aFieldId ), m_name( aName ) { - m_name = aName; - SetId( aFieldId ); } @@ -97,22 +93,61 @@ wxString PCB_FIELD::GetCanonicalName() const } -void PCB_FIELD::SetId( int aId ) +wxString PCB_FIELD::GetTextTypeDescription() const { - m_id = aId; + switch( m_id ) + { + case REFERENCE_FIELD: return _( "Reference" ); + case VALUE_FIELD: return _( "Value" ); + case FOOTPRINT_FIELD: return _( "Footprint" ); + case DATASHEET_FIELD: return _( "Datasheet" ); + default: return _( "User Field" ); + } +} - switch(m_id) + +wxString PCB_FIELD::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const +{ + switch( m_id ) { - case REFERENCE_FIELD: - SetType(TEXT_is_REFERENCE); - break; - case VALUE_FIELD: - SetType(TEXT_is_VALUE); - break; - default: - SetType(TEXT_is_DIVERS); - break; + case REFERENCE_FIELD: + return wxString::Format( _( "Reference '%s'" ), + GetParentFootprint()->GetReference() ); + + case VALUE_FIELD: + return wxString::Format( _( "Value '%s' of %s" ), + KIUI::EllipsizeMenuText( GetText() ), + GetParentFootprint()->GetReference() ); + + case FOOTPRINT_FIELD: + return wxString::Format( _( "Footprint '%s' of %s" ), + KIUI::EllipsizeMenuText( GetText() ), + GetParentFootprint()->GetReference() ); + case DATASHEET_FIELD: + return wxString::Format( _( "Datasheet '%s' of %s" ), + KIUI::EllipsizeMenuText( GetText() ), + GetParentFootprint()->GetReference() ); } + + // Can't get here, but gcc doesn't seem to know that.... + return wxEmptyString; +} + +double PCB_FIELD::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const +{ + constexpr double HIDE = std::numeric_limits::max(); + + if( !aView ) + return 0.0; + + // Handle Render tab switches + if( IsValue() && !aView->IsLayerVisible( LAYER_MOD_VALUES ) ) + return HIDE; + + if( IsReference() && !aView->IsLayerVisible( LAYER_MOD_REFERENCES ) ) + return HIDE; + + return PCB_TEXT::ViewGetLOD( aLayer, aView ); } diff --git a/pcbnew/pcb_field.h b/pcbnew/pcb_field.h index 0934b7e00f..7874c15ab5 100644 --- a/pcbnew/pcb_field.h +++ b/pcbnew/pcb_field.h @@ -37,6 +37,46 @@ public: PCB_FIELD( const PCB_TEXT& aText, int aFieldId, const wxString& aName = wxEmptyString ); + static inline bool ClassOf( const EDA_ITEM* aItem ) + { + return aItem && PCB_FIELD_T == aItem->Type(); + } + + wxString GetClass() const override { return wxT( "PCB_FIELD" ); } + + bool IsType( const std::vector& aScanTypes ) const override + { + if( BOARD_ITEM::IsType( aScanTypes ) ) + return true; + + for( KICAD_T scanType : aScanTypes ) + { + if( scanType == PCB_FIELD_LOCATE_REFERENCE_T && m_id == REFERENCE_FIELD ) + return true; + else if( scanType == PCB_FIELD_LOCATE_VALUE_T && m_id == VALUE_FIELD ) + return true; + else if( scanType == PCB_FIELD_LOCATE_FOOTPRINT_T && m_id == FOOTPRINT_FIELD ) + return true; + else if( scanType == PCB_FIELD_LOCATE_DATASHEET_T && m_id == DATASHEET_FIELD ) + return true; + } + + return false; + } + + bool IsReference() const { return m_id == REFERENCE_FIELD; } + bool IsValue() const { return m_id == VALUE_FIELD; } + bool IsFootprint() const { return m_id == FOOTPRINT_FIELD; } + bool IsDatasheet() const { return m_id == DATASHEET_FIELD; } + + bool IsMandatoryField() const { return m_id < MANDATORY_FIELDS; } + + wxString GetTextTypeDescription() const override; + + wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override; + + double ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const override; + EDA_ITEM* Clone() const override; /** @@ -73,8 +113,6 @@ public: int GetId() const { return m_id; } - void SetId( int aId ); - private: int m_id; ///< Field index, @see enum MANDATORY_FIELD_T diff --git a/pcbnew/pcb_text.cpp b/pcbnew/pcb_text.cpp index 08ff12172f..5ce3825c18 100644 --- a/pcbnew/pcb_text.cpp +++ b/pcbnew/pcb_text.cpp @@ -41,17 +41,15 @@ PCB_TEXT::PCB_TEXT( BOARD_ITEM* parent, KICAD_T idtype ) : BOARD_ITEM( parent, idtype ), - EDA_TEXT( pcbIUScale ), - m_type( TEXT_is_DIVERS ) + EDA_TEXT( pcbIUScale ) { SetMultilineAllowed( true ); } -PCB_TEXT::PCB_TEXT( FOOTPRINT* aParent, TEXT_TYPE text_type ) : +PCB_TEXT::PCB_TEXT( FOOTPRINT* aParent ) : BOARD_ITEM( aParent, PCB_TEXT_T ), - EDA_TEXT( pcbIUScale ), - m_type( text_type ) + EDA_TEXT( pcbIUScale ) { SetKeepUpright( true ); @@ -185,13 +183,13 @@ double PCB_TEXT::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const if( FOOTPRINT* parentFP = GetParentFootprint() ) { // Handle Render tab switches - if( m_type == TEXT_is_VALUE || GetText() == wxT( "${VALUE}" ) ) + if( GetText() == wxT( "${VALUE}" ) ) { if( !aView->IsLayerVisible( LAYER_MOD_VALUES ) ) return HIDE; } - if( m_type == TEXT_is_REFERENCE || GetText() == wxT( "${REFERENCE}" ) ) + if( GetText() == wxT( "${REFERENCE}" ) ) { if( !aView->IsLayerVisible( LAYER_MOD_REFERENCES ) ) return HIDE; @@ -225,14 +223,7 @@ void PCB_TEXT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vectorGetName() == PCB_EDIT_FRAME_NAME && IsLocked() ) aList.emplace_back( _( "Status" ), _( "Locked" ) ); @@ -369,26 +360,18 @@ void PCB_TEXT::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) } +wxString PCB_TEXT::GetTextTypeDescription() const +{ + return _( "Text" ); +} + + wxString PCB_TEXT::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const { if( FOOTPRINT* parentFP = GetParentFootprint() ) { - switch( m_type ) - { - case TEXT_is_REFERENCE: - return wxString::Format( _( "Reference '%s'" ), - parentFP->GetReference() ); - - case TEXT_is_VALUE: - return wxString::Format( _( "Value '%s' of %s" ), - KIUI::EllipsizeMenuText( GetText() ), - parentFP->GetReference() ); - - case TEXT_is_DIVERS: - return wxString::Format( _( "Footprint Text '%s' of %s" ), - KIUI::EllipsizeMenuText( GetText() ), - parentFP->GetReference() ); - } + return wxString::Format( _( "Footprint Text '%s' of %s" ), + KIUI::EllipsizeMenuText( GetText() ), parentFP->GetReference() ); } else { diff --git a/pcbnew/pcb_text.h b/pcbnew/pcb_text.h index c4d319fc19..b23bc931d4 100644 --- a/pcbnew/pcb_text.h +++ b/pcbnew/pcb_text.h @@ -39,20 +39,7 @@ class PCB_TEXT : public BOARD_ITEM, public EDA_TEXT public: PCB_TEXT( BOARD_ITEM* parent, KICAD_T idtype = PCB_TEXT_T ); - /** - * Footprint text type: there must be only one (and only one) for each of the reference - * value texts in one footprint; others could be added for the user (DIVERS is French for - * 'others'). Reference and value always live on silkscreen (on the footprint side); other - * texts are planned to go on whatever layer the user wants. - */ - enum TEXT_TYPE - { - TEXT_is_REFERENCE = 0, - TEXT_is_VALUE = 1, - TEXT_is_DIVERS = 2 - }; - - PCB_TEXT( FOOTPRINT* aParent, TEXT_TYPE text_type ); + PCB_TEXT( FOOTPRINT* aParent ); // Do not create a copy constructor & operator=. // The ones generated by the compiler are adequate. @@ -85,9 +72,6 @@ public: wxString GetShownText( bool aAllowExtraText, int aDepth = 0 ) const override; - void SetType( TEXT_TYPE aType ) { m_type = aType; } - TEXT_TYPE GetType() const { return m_type; } - bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override; virtual VECTOR2I GetPosition() const override @@ -151,6 +135,8 @@ public: GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER, FLASHING aFlash = FLASHING::DEFAULT ) const override; + virtual wxString GetTextTypeDescription() const; + wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override; BITMAPS GetMenuImage() const override; @@ -188,9 +174,6 @@ protected: virtual void swapData( BOARD_ITEM* aImage ) override; int getKnockoutMargin() const; - -private: - TEXT_TYPE m_type; }; #endif // #define PCB_TEXT_H diff --git a/pcbnew/plugins/altium/altium_pcb.cpp b/pcbnew/plugins/altium/altium_pcb.cpp index 44e8dbde65..dfb9a159b0 100644 --- a/pcbnew/plugins/altium/altium_pcb.cpp +++ b/pcbnew/plugins/altium/altium_pcb.cpp @@ -3101,7 +3101,7 @@ void ALTIUM_PCB::ConvertTexts6ToFootprintItemOnLayer( FOOTPRINT* aFootprint, con } else { - fpText = new PCB_TEXT( aFootprint, PCB_TEXT::TEXT_is_DIVERS ); + fpText = new PCB_TEXT( aFootprint ); aFootprint->Add( fpText, ADD_MODE::APPEND ); } diff --git a/pcbnew/plugins/eagle/eagle_plugin.cpp b/pcbnew/plugins/eagle/eagle_plugin.cpp index 9767bffab0..cf3831d5cb 100644 --- a/pcbnew/plugins/eagle/eagle_plugin.cpp +++ b/pcbnew/plugins/eagle/eagle_plugin.cpp @@ -1972,7 +1972,7 @@ void EAGLE_PLUGIN::packageText( FOOTPRINT* aFootprint, wxXmlNode* aTree ) const } else { - textItem = new PCB_TEXT( aFootprint, PCB_TEXT::TEXT_is_DIVERS ); + textItem = new PCB_TEXT( aFootprint ); aFootprint->Add( textItem ); textItem->SetText( interpretText( t.text ) ); diff --git a/pcbnew/plugins/fabmaster/import_fabmaster.cpp b/pcbnew/plugins/fabmaster/import_fabmaster.cpp index d879eedd28..ca67ccc558 100644 --- a/pcbnew/plugins/fabmaster/import_fabmaster.cpp +++ b/pcbnew/plugins/fabmaster/import_fabmaster.cpp @@ -2033,7 +2033,7 @@ bool FABMASTER::loadFootprints( BOARD* aBoard ) if( layer == F_SilkS || layer == B_SilkS ) txt = &( fp->Reference() ); else - txt = new PCB_TEXT( fp, PCB_TEXT::TEXT_is_DIVERS ); + txt = new PCB_TEXT( fp ); if( src->mirror ) { diff --git a/pcbnew/plugins/kicad/pcb_parser.cpp b/pcbnew/plugins/kicad/pcb_parser.cpp index c9387fa8f0..f884b88005 100644 --- a/pcbnew/plugins/kicad/pcb_parser.cpp +++ b/pcbnew/plugins/kicad/pcb_parser.cpp @@ -3008,17 +3008,11 @@ PCB_TEXT* PCB_PARSER::parsePCB_TEXT( BOARD_ITEM* aParent ) { switch( token ) { - case T_reference: - text = std::make_unique( parentFP, PCB_TEXT::TEXT_is_REFERENCE ); - break; + case T_reference: text = std::make_unique( parentFP, REFERENCE_FIELD ); break; - case T_value: - text = std::make_unique( parentFP, PCB_TEXT::TEXT_is_VALUE ); - break; + case T_value: text = std::make_unique( parentFP, VALUE_FIELD ); break; - case T_user: - text = std::make_unique( parentFP, PCB_TEXT::TEXT_is_DIVERS ); - break; + case T_user: text = std::make_unique( parentFP ); break; default: THROW_IO_ERROR( wxString::Format( _( "Cannot handle footprint text type %s" ), @@ -3971,23 +3965,27 @@ FOOTPRINT* PCB_PARSER::parseFOOTPRINT_unchecked( wxArrayString* aInitialComments PCB_TEXT* text = parsePCB_TEXT( footprint.get() ); text->SetTextAngle( text->GetTextAngle() - footprint->GetOrientation()); - switch( text->GetType() ) + if( PCB_FIELD* field = dynamic_cast( text ) ) { - case PCB_TEXT::TEXT_is_REFERENCE: - footprint->Reference() = PCB_FIELD( *text, REFERENCE_FIELD ); - const_cast( footprint->Reference().m_Uuid ) = text->m_Uuid; - delete text; - break; + // Fields other than reference and value weren't historically + // stored in fp_texts so we don't need to handle them here + switch( field->GetId() ) + { + case REFERENCE_FIELD: + footprint->Reference() = PCB_FIELD( *text, REFERENCE_FIELD ); + const_cast( footprint->Reference().m_Uuid ) = text->m_Uuid; + delete text; + break; - case PCB_TEXT::TEXT_is_VALUE: - footprint->Value() = PCB_FIELD( *text, VALUE_FIELD ); - const_cast( footprint->Value().m_Uuid ) = text->m_Uuid; - delete text; - break; - - default: - footprint->Add( text, ADD_MODE::APPEND, true ); + case VALUE_FIELD: + footprint->Value() = PCB_FIELD( *text, VALUE_FIELD ); + const_cast( footprint->Value().m_Uuid ) = text->m_Uuid; + delete text; + break; + } } + else + footprint->Add( text, ADD_MODE::APPEND, true ); break; } diff --git a/pcbnew/plugins/kicad/pcb_plugin.cpp b/pcbnew/plugins/kicad/pcb_plugin.cpp index c6aa5dc634..89621d8276 100644 --- a/pcbnew/plugins/kicad/pcb_plugin.cpp +++ b/pcbnew/plugins/kicad/pcb_plugin.cpp @@ -1752,13 +1752,7 @@ void PCB_PLUGIN::format( const PCB_TEXT* aText, int aNestLevel ) const if( parentFP ) { prefix = "fp"; - - switch( aText->GetType() ) - { - case PCB_TEXT::TEXT_is_REFERENCE: type = " reference"; break; - case PCB_TEXT::TEXT_is_VALUE: type = " value"; break; - case PCB_TEXT::TEXT_is_DIVERS: type = " user"; break; - } + type = " user"; pos -= parentFP->GetPosition(); RotatePoint( pos, -parentFP->GetOrientation() ); diff --git a/pcbnew/plugins/legacy/legacy_plugin.cpp b/pcbnew/plugins/legacy/legacy_plugin.cpp index 1a80d2249f..38b30e9277 100644 --- a/pcbnew/plugins/legacy/legacy_plugin.cpp +++ b/pcbnew/plugins/legacy/legacy_plugin.cpp @@ -180,6 +180,9 @@ typedef unsigned LAYER_MSK; #define NO_LAYERS 0x00000000 +#define PCB_LEGACY_TEXT_is_REFERENCE 0 +#define PCB_LEGACY_TEXT_is_VALUE 1 +#define PCB_LEGACY_TEXT_is_DIVERS 2 // French for "other" // Old internal units definition (UI = decimil) #define PCB_LEGACY_INTERNAL_UNIT 10000 @@ -1152,17 +1155,17 @@ void LEGACY_PLUGIN::loadFOOTPRINT( FOOTPRINT* aFootprint ) switch( tnum ) { - case PCB_TEXT::TEXT_is_REFERENCE: + case PCB_LEGACY_TEXT_is_REFERENCE: text = &aFootprint->Reference(); break; - case PCB_TEXT::TEXT_is_VALUE: + case PCB_LEGACY_TEXT_is_VALUE: text = &aFootprint->Value(); break; // All other fields greater than 1. default: - text = new PCB_TEXT( aFootprint, PCB_TEXT::TEXT_is_DIVERS ); + text = new PCB_TEXT( aFootprint ); aFootprint->Add( text ); } @@ -1690,10 +1693,8 @@ void LEGACY_PLUGIN::loadMODULE_TEXT( PCB_TEXT* aText ) char* hjust = strtok_r( (char*) txt_end, delims, (char**) &data ); char* vjust = strtok_r( nullptr, delims, (char**) &data ); - if( type != PCB_TEXT::TEXT_is_REFERENCE && type != PCB_TEXT::TEXT_is_VALUE ) - type = PCB_TEXT::TEXT_is_DIVERS; - - aText->SetType( static_cast( type ) ); + if( type != PCB_LEGACY_TEXT_is_REFERENCE && type != PCB_LEGACY_TEXT_is_VALUE ) + type = PCB_LEGACY_TEXT_is_DIVERS; aText->SetFPRelativePosition( VECTOR2I( pos0_x, pos0_y ) ); aText->SetTextSize( VECTOR2I( size0_x, size0_y ) ); diff --git a/pcbnew/plugins/pcad/pcad_footprint.cpp b/pcbnew/plugins/pcad/pcad_footprint.cpp index 8ce67f7669..5c53fa660e 100644 --- a/pcbnew/plugins/pcad/pcad_footprint.cpp +++ b/pcbnew/plugins/pcad/pcad_footprint.cpp @@ -503,10 +503,9 @@ void PCAD_FOOTPRINT::AddToBoard( FOOTPRINT* aFootprint ) footprint->SetFPID( fpID ); // reference text - PCB_TEXT* ref_text = &footprint->Reference(); + PCB_FIELD* ref_text = &footprint->Reference(); ref_text->SetText( ValidateReference( m_Name.text ) ); - ref_text->SetType( PCB_TEXT::TEXT_is_REFERENCE ); ref_text->SetFPRelativePosition( VECTOR2I( m_Name.correctedPositionX, m_Name.correctedPositionY ) ); @@ -529,10 +528,9 @@ void PCAD_FOOTPRINT::AddToBoard( FOOTPRINT* aFootprint ) ref_text->SetLayer( m_Mirror ? FlipLayer( m_KiCadLayer ) : m_KiCadLayer ); // value text - PCB_TEXT* val_text = &footprint->Value(); + PCB_FIELD* val_text = &footprint->Value(); val_text->SetText( m_Value.text ); - val_text->SetType( PCB_TEXT::TEXT_is_VALUE ); val_text->SetFPRelativePosition( VECTOR2I( m_Value.correctedPositionX, m_Value.correctedPositionY ) ); diff --git a/pcbnew/tools/drawing_tool.cpp b/pcbnew/tools/drawing_tool.cpp index f3ce71f2d8..68d44d02a2 100644 --- a/pcbnew/tools/drawing_tool.cpp +++ b/pcbnew/tools/drawing_tool.cpp @@ -894,8 +894,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent ) // Init the new item attributes if( m_isFootprintEditor ) { - text = new PCB_TEXT( static_cast( m_frame->GetModel() ), - PCB_TEXT::TEXT_is_DIVERS ); + text = new PCB_TEXT( static_cast( m_frame->GetModel() ) ); } else { diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index b9ee7f1b38..cbbdebfc94 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -1792,37 +1792,13 @@ void EDIT_TOOL::DeleteItems( const PCB_SELECTION& aItems, bool aIsCut ) switch( item->Type() ) { case PCB_FIELD_T: - case PCB_TEXT_T: - switch( static_cast( board_item )->GetType() ) - { - case PCB_TEXT::TEXT_is_VALUE: - case PCB_TEXT::TEXT_is_REFERENCE: - wxASSERT( parentFP ); - m_commit->Modify( parentFP ); - static_cast( board_item )->SetVisible( false ); - getView()->Update( board_item ); - break; - - case PCB_TEXT::TEXT_is_DIVERS: - if( parentFP ) - { - m_commit->Modify( parentFP ); - getView()->Remove( board_item ); - parentFP->Remove( board_item ); - } - else - { - m_commit->Remove( board_item ); - } - break; - - default: - wxFAIL; // Shouldn't get here - break; - } - + wxASSERT( parentFP ); + m_commit->Modify( parentFP ); + static_cast( board_item )->SetVisible( false ); + getView()->Update( board_item ); break; + case PCB_TEXT_T: case PCB_SHAPE_T: case PCB_TEXTBOX_T: case PCB_BITMAP_T: diff --git a/pcbnew/tools/pcb_control.cpp b/pcbnew/tools/pcb_control.cpp index 25e79b8a93..331da40a52 100644 --- a/pcbnew/tools/pcb_control.cpp +++ b/pcbnew/tools/pcb_control.cpp @@ -713,9 +713,6 @@ static void pasteFootprintItemsToFootprintEditor( FOOTPRINT* aClipFootprint, BOA { PCB_TEXT* text = static_cast( item ); - if( text->GetType() != PCB_TEXT::TEXT_is_DIVERS ) - continue; - text->SetTextAngle( text->GetTextAngle() - aClipFootprint->GetOrientation() ); text->SetTextAngle( text->GetTextAngle() + editorFootprint->GetOrientation() ); } diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp index 9440179437..579157f12b 100644 --- a/pcbnew/tools/pcb_selection_tool.cpp +++ b/pcbnew/tools/pcb_selection_tool.cpp @@ -28,6 +28,7 @@ #include #include using namespace std::placeholders; +#include #include #include #include @@ -2430,6 +2431,7 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili const PCB_VIA* via = nullptr; const PAD* pad = nullptr; const PCB_TEXT* text = nullptr; + const PCB_FIELD* field = nullptr; switch( aItem->Type() ) { @@ -2490,6 +2492,16 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili break; case PCB_FIELD_T: + field = static_cast( aItem ); + + if( field->IsReference() && !view()->IsLayerVisible( LAYER_MOD_REFERENCES ) ) + return false; + + if( field->IsValue() && !view()->IsLayerVisible( LAYER_MOD_VALUES ) ) + return false; + + // Handle all other fields with normal text visibility controls + KI_FALLTHROUGH; case PCB_TEXT_T: text = static_cast( aItem ); @@ -2509,31 +2521,12 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili if( !board()->IsLayerVisible( text->GetLayer() ) ) return false; - int controlLayer = UNDEFINED_LAYER; + int controlLayer = LAYER_MOD_TEXT; - switch( text->GetType() ) - { - case PCB_TEXT::TEXT_is_REFERENCE: + if( text->GetText() == wxT( "${REFERENCE}" ) ) controlLayer = LAYER_MOD_REFERENCES; - break; - - case PCB_TEXT::TEXT_is_VALUE: + else if( text->GetText() == wxT( "${VALUE}" ) ) controlLayer = LAYER_MOD_VALUES; - break; - - case PCB_TEXT::TEXT_is_DIVERS: - if( text->GetText() == wxT( "${REFERENCE}" ) ) - controlLayer = LAYER_MOD_REFERENCES; - else if( text->GetText() == wxT( "${VALUE}" ) ) - controlLayer = LAYER_MOD_VALUES; - else - controlLayer = LAYER_MOD_TEXT; - - break; - } - - if( controlLayer == UNDEFINED_LAYER ) - return false; if( !view()->IsLayerVisible( controlLayer ) ) return false;