diff --git a/common/settings/color_settings.cpp b/common/settings/color_settings.cpp index b71e47b5e4..fe2f56052e 100644 --- a/common/settings/color_settings.cpp +++ b/common/settings/color_settings.cpp @@ -88,6 +88,7 @@ COLOR_SETTINGS::COLOR_SETTINGS( std::string aFilename ) : #endif CLR( "schematic.sheet", LAYER_SHEET, COLOR4D( MAGENTA ) ); CLR( "schematic.sheet_filename", LAYER_SHEETFILENAME, COLOR4D( BROWN ) ); + CLR( "schematic.sheet_fields", LAYER_SHEETFIELDS, COLOR4D( MAGENTA ) ); CLR( "schematic.sheet_label", LAYER_SHEETLABEL, COLOR4D( CYAN ) ); CLR( "schematic.sheet_name", LAYER_SHEETNAME, COLOR4D( CYAN ) ); CLR( "schematic.value", LAYER_VALUEPART, COLOR4D( CYAN ) ); diff --git a/eeschema/autoplace_fields.cpp b/eeschema/autoplace_fields.cpp index 0435571fa9..527c358f5a 100644 --- a/eeschema/autoplace_fields.cpp +++ b/eeschema/autoplace_fields.cpp @@ -676,7 +676,8 @@ void SCH_COMPONENT::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) { if( aManual ) wxASSERT_MSG( aScreen, "A SCH_SCREEN pointer must be given for manual autoplacement" ); + AUTOPLACER autoplacer( this, aScreen ); autoplacer.DoAutoplace( aManual ); - m_fieldsAutoplaced = ( aManual? AUTOPLACED_MANUAL : AUTOPLACED_AUTO ); + m_fieldsAutoplaced = ( aManual ? FIELDS_AUTOPLACED_MANUAL : FIELDS_AUTOPLACED_AUTO ); } diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp index e0f60a379c..eb969122a6 100644 --- a/eeschema/lib_field.cpp +++ b/eeschema/lib_field.cpp @@ -145,12 +145,14 @@ bool LIB_FIELD::HitTest( const wxPoint& aPosition, int aAccuracy ) const // Reference designator text has one or 2 additional character (displays U? or U?A) if( m_id == REFERENCE ) { + const LIB_PART* parent = dynamic_cast( m_Parent ); + wxString extended_text = tmp_text.GetText(); extended_text.Append('?'); - const LIB_PART* parent = static_cast( m_Parent ); - if ( parent && ( parent->GetUnitCount() > 1 ) ) + if ( parent && parent->GetUnitCount() > 1 ) extended_text.Append('A'); + tmp_text.SetText( extended_text ); } diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index 1d037ec90f..c857fbe79b 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -117,7 +117,7 @@ SCH_COMPONENT::SCH_COMPONENT( const wxPoint& aPos, SCH_ITEM* aParent ) : SCH_ITEM( aParent, SCH_COMPONENT_T ) { Init( aPos ); - m_fieldsAutoplaced = AUTOPLACED_NO; + m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; } @@ -136,7 +136,7 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* sh part = aPart.Flatten(); part->SetParent(); m_part.reset( part.release() ); - m_fieldsAutoplaced = AUTOPLACED_NO; + m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; // Copy fields from the library component UpdateFields( true, true ); @@ -208,17 +208,14 @@ void SCH_COMPONENT::Init( const wxPoint& pos ) // construct only the mandatory fields, which are the first 4 only. for( int i = 0; i < MANDATORY_FIELDS; ++i ) { - SCH_FIELD field( pos, i, this, TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) ); + m_Fields.emplace_back( pos, i, this, TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) ); if( i == REFERENCE ) - field.SetLayer( LAYER_REFERENCEPART ); + m_Fields.back().SetLayer( LAYER_REFERENCEPART ); else if( i == VALUE ) - field.SetLayer( LAYER_VALUEPART ); - - // else keep LAYER_FIELDS from SCH_FIELD constructor - - // SCH_FIELD's implicitly created copy constructor is called in here - AddField( field ); + m_Fields.back().SetLayer( LAYER_VALUEPART ); + else + m_Fields.back().SetLayer( LAYER_FIELDS ); } m_prefix = wxString( wxT( "U" ) ); @@ -550,16 +547,8 @@ void SCH_COMPONENT::Print( wxDC* aDC, const wxPoint& aOffset ) dummy()->Print( aDC, m_Pos + aOffset, 0, 0, opts ); } - SCH_FIELD* field = GetField( REFERENCE ); - - if( field->IsVisible() ) - field->Print( aDC, aOffset ); - - for( int ii = VALUE; ii < GetFieldCount(); ii++ ) - { - field = GetField( ii ); - field->Print( aDC, aOffset ); - } + for( SCH_FIELD& field : m_Fields ) + field.Print( aDC, aOffset ); } @@ -1392,13 +1381,13 @@ void SCH_COMPONENT::Rotate( wxPoint aPosition ) SetOrientation( CMP_ROTATE_COUNTERCLOCKWISE ); - for( int ii = 0; ii < GetFieldCount(); ii++ ) + for( SCH_FIELD& field : m_Fields ) { // Move the fields to the new position because the component itself has moved. - wxPoint pos = GetField( ii )->GetTextPos(); + wxPoint pos = field.GetTextPos(); pos.x -= prev.x - m_Pos.x; pos.y -= prev.y - m_Pos.y; - GetField( ii )->SetTextPos( pos ); + field.SetTextPos( pos ); } } diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 42acf02fab..5cd5633b6a 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -99,7 +99,6 @@ struct COMPONENT_INSTANCE_REFERENCE class SCH_COMPONENT : public SCH_ITEM { public: - enum AUTOPLACED { AUTOPLACED_NO = 0, AUTOPLACED_AUTO, AUTOPLACED_MANUAL }; private: @@ -125,7 +124,7 @@ private: SCH_PINS m_pins; ///< a SCH_PIN for every LIB_PIN (across all units) SCH_PIN_MAP m_pinMap; ///< the component's pins mapped by LIB_PIN* - AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement + FIELDS_AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement bool m_isInNetlist; ///< True if the component should appear in the netlist @@ -428,12 +427,12 @@ public: /** * Return whether the fields have been automatically placed. */ - AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; } + FIELDS_AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; } /** * Set fields automatically placed flag false. */ - void ClearFieldsAutoplaced() { m_fieldsAutoplaced = AUTOPLACED_NO; } + void ClearFieldsAutoplaced() { m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; } /** * Automatically orient all the fields in the component. @@ -457,7 +456,7 @@ public: void AutoAutoplaceFields( SCH_SCREEN* aScreen ) { if( GetFieldsAutoplaced() ) - AutoplaceFields( aScreen, GetFieldsAutoplaced() == AUTOPLACED_MANUAL ); + AutoplaceFields( aScreen, GetFieldsAutoplaced() == FIELDS_AUTOPLACED_MANUAL ); } diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 7dcfc9a0ae..f0ea15db1e 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -49,7 +49,7 @@ #include -SCH_FIELD::SCH_FIELD( const wxPoint& aPos, int aFieldId, SCH_COMPONENT* aParent, const wxString& aName ) : +SCH_FIELD::SCH_FIELD( const wxPoint& aPos, int aFieldId, SCH_ITEM* aParent, const wxString& aName ) : SCH_ITEM( aParent, SCH_FIELD_T ), EDA_TEXT() { @@ -77,19 +77,24 @@ const wxString SCH_FIELD::GetFullyQualifiedText() const { wxString text = GetText(); - /* For more than one part per package, we must add the part selection - * A, B, ... or 1, 2, .. to the reference. */ - if( m_id == REFERENCE ) - { - SCH_COMPONENT* component = (SCH_COMPONENT*) m_Parent; + // Note that the IDs of FIELDS and SHEETS overlap, so one must check *both* the + // id and the parent's type. - wxCHECK_MSG( component != NULL, text, - wxT( "No component associated with field" ) + text ); + if( m_id == REFERENCE && m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) + { + // For more than one part per package, we must add the part selection + // A, B, ... or 1, 2, .. to the reference. + SCH_COMPONENT* component = static_cast( m_Parent ); if( component->GetUnitCount() > 1 ) text << LIB_PART::SubReference( component->GetUnit() ); } + if( m_id == SHEETFILENAME && m_Parent && m_Parent->Type() == SCH_SHEET_T ) + { + text = _( "File: " ) + text; + } + return text; } @@ -117,7 +122,7 @@ void SCH_FIELD::Print( wxDC* aDC, const wxPoint& aOffset ) int orient; COLOR4D color; wxPoint textpos; - SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent; + SCH_COMPONENT* parentComponent = dynamic_cast( m_Parent ); int lineWidth = GetThickness(); if( lineWidth == 0 ) // Use default values for pen size @@ -137,7 +142,7 @@ void SCH_FIELD::Print( wxDC* aDC, const wxPoint& aOffset ) // Calculate the text orientation according to the component orientation. orient = GetTextAngle(); - if( parentComponent->GetTransform().y1 ) // Rotate component 90 degrees. + if( parentComponent && parentComponent->GetTransform().y1 ) // Rotate component 90 degrees. { if( orient == TEXT_ANGLE_HORIZ ) orient = TEXT_ANGLE_VERT; @@ -161,12 +166,8 @@ void SCH_FIELD::Print( wxDC* aDC, const wxPoint& aOffset ) if( m_forceVisible ) color = COLOR4D( DARKGRAY ); - else if( m_id == REFERENCE ) - color = GetLayerColor( LAYER_REFERENCEPART ); - else if( m_id == VALUE ) - color = GetLayerColor( LAYER_VALUEPART ); else - color = GetLayerColor( LAYER_FIELDS ); + color = GetLayerColor( m_Layer ); GRText( aDC, textpos, color, GetFullyQualifiedText(), orient, GetTextSize(), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, lineWidth, IsItalic(), IsBold() ); @@ -194,7 +195,6 @@ void SCH_FIELD::SwapData( SCH_ITEM* aItem ) const EDA_RECT SCH_FIELD::GetBoundingBox() const { - SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) m_Parent; int linewidth = GetThickness() == 0 ? GetDefaultLineThickness() : GetThickness(); // We must pass the effective text thickness to GetTextBox @@ -202,20 +202,14 @@ const EDA_RECT SCH_FIELD::GetBoundingBox() const linewidth = Clamp_Text_PenSize( linewidth, GetTextSize(), IsBold() ); // Calculate the text bounding box: - EDA_RECT rect; + EDA_RECT rect; + SCH_FIELD text( *this ); // Make a local copy to change text + // because GetBoundingBox() is const + text.SetText( GetFullyQualifiedText() ); + rect = text.GetTextBox( -1, linewidth, false, GetTextMarkupFlags() ); - if( m_id == REFERENCE ) // multi units have one letter or more added to reference - { - SCH_FIELD text( *this ); // Make a local copy to change text - // because GetBoundingBox() is const - text.SetText( GetFullyQualifiedText() ); - rect = text.GetTextBox( -1, linewidth, false, GetTextMarkupFlags() ); - } - else - rect = GetTextBox( -1, linewidth, false, GetTextMarkupFlags() ); - - // Calculate the bounding box position relative to the component: - wxPoint origin = parentComponent->GetPosition(); + // Calculate the bounding box position relative to the parent: + wxPoint origin = GetParentPosition(); wxPoint pos = GetTextPos() - origin; wxPoint begin = rect.GetOrigin() - origin; wxPoint end = rect.GetEnd() - origin; @@ -228,12 +222,16 @@ const EDA_RECT SCH_FIELD::GetBoundingBox() const MIRROR( end.y, pos.y ); // Now, apply the component transform (mirror/rot) - begin = parentComponent->GetTransform().TransformCoordinate( begin ); - end = parentComponent->GetTransform().TransformCoordinate( end ); - rect.SetOrigin( begin); - rect.SetEnd( end); + if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) + { + SCH_COMPONENT* parentComponent = static_cast( m_Parent ); + rect.SetOrigin( parentComponent->GetTransform().TransformCoordinate( begin )); + rect.SetEnd( parentComponent->GetTransform().TransformCoordinate( end )); + } + rect.Move( origin ); rect.Normalize(); + return rect; } @@ -265,20 +263,22 @@ bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData ) { wxString text = GetFullyQualifiedText(); int flags = aSearchData.GetFlags(); + bool isReference = m_Parent && m_Parent->Type() == SCH_COMPONENT_T && m_id == REFERENCE; + bool isValue = m_Parent && m_Parent->Type() == SCH_COMPONENT_T && m_id == VALUE; // User defined fields have an ID of -1. - if( m_id != REFERENCE && m_id != VALUE && !( flags & FR_SEARCH_ALL_FIELDS ) ) + if( !isReference && !isValue && !( flags & FR_SEARCH_ALL_FIELDS ) ) return false; - if( ( flags & FR_SEARCH_REPLACE ) && m_id == REFERENCE && !( flags & FR_REPLACE_REFERENCES ) ) + if( ( flags & FR_SEARCH_REPLACE ) && isReference && !( flags & FR_REPLACE_REFERENCES ) ) return false; - wxLogTrace( - traceFindItem, wxT( " child item " ) + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) ); + wxLogTrace( traceFindItem, wxT( " child item " ) + + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) ); // Take sheet path into account which effects the reference field and the unit for // components with multiple parts. - if( m_id == REFERENCE && aAuxData != NULL ) + if( isReference && aAuxData != NULL ) { SCH_COMPONENT* component = (SCH_COMPONENT*) m_Parent; @@ -309,10 +309,12 @@ bool SCH_FIELD::IsReplaceable() const bool SCH_FIELD::Replace( wxFindReplaceData& aSearchData, void* aAuxData ) { - bool isReplaced; + bool isReplaced = false; wxString text = GetFullyQualifiedText(); + bool isReference = m_Parent && m_Parent->Type() == SCH_COMPONENT_T && m_id == REFERENCE; + bool isFilename = m_Parent && m_Parent->Type() == SCH_SHEET_T && m_id == SHEETFILENAME; - if( m_id == REFERENCE ) + if( isReference ) { wxCHECK_MSG( aAuxData != NULL, false, wxT( "Cannot replace reference designator without valid sheet path." ) ); @@ -334,6 +336,10 @@ bool SCH_FIELD::Replace( wxFindReplaceData& aSearchData, void* aAuxData ) if( isReplaced ) component->SetRef( (SCH_SHEET_PATH*) aAuxData, text ); } + else if( isFilename ) + { + // This is likely too dangerous to allow.... + } else { isReplaced = EDA_TEXT::Replace( aSearchData ); @@ -370,14 +376,16 @@ wxString SCH_FIELD::GetName( bool aUseDefaultName ) const BITMAP_DEF SCH_FIELD::GetMenuImage() const { - if( m_id == REFERENCE ) - return edit_comp_ref_xpm; - - if( m_id == VALUE ) - return edit_comp_value_xpm; - - if( m_id == FOOTPRINT ) - return edit_comp_footprint_xpm; + if( dynamic_cast( m_Parent ) ) + { + switch( m_id ) + { + case REFERENCE: return edit_comp_ref_xpm; + case VALUE: return edit_comp_value_xpm; + case FOOTPRINT: return edit_comp_footprint_xpm; + default: return edit_text_xpm; + } + } return edit_text_xpm; } @@ -489,6 +497,17 @@ wxPoint SCH_FIELD::GetPosition() const } +wxPoint SCH_FIELD::GetParentPosition() const +{ + if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) + return static_cast( m_Parent )->GetPosition(); + else if( m_Parent && m_Parent->Type() == SCH_SHEET_T ) + return static_cast( m_Parent )->GetPosition(); + else + return wxPoint(); +} + + bool SCH_FIELD::operator <( const SCH_ITEM& aItem ) const { if( Type() != aItem.Type() ) diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h index 7d3c87a47f..4044a80f7f 100644 --- a/eeschema/sch_field.h +++ b/eeschema/sch_field.h @@ -37,6 +37,14 @@ class SCH_COMPONENT; class LIB_FIELD; +enum FIELDS_AUTOPLACED +{ + FIELDS_AUTOPLACED_NO = 0, + FIELDS_AUTOPLACED_AUTO, + FIELDS_AUTOPLACED_MANUAL +}; + + /** * SCH_FIELD * instances are attached to a component and provide a place for the component's value, @@ -56,7 +64,7 @@ class SCH_FIELD : public SCH_ITEM, public EDA_TEXT wxString m_name; public: - SCH_FIELD( const wxPoint& aPos, int aFieldId, SCH_COMPONENT* aParent, + SCH_FIELD( const wxPoint& aPos, int aFieldId, SCH_ITEM* aParent, const wxString& aName = wxEmptyString ); // Do not create a copy constructor. The one generated by the compiler is adequate. @@ -192,6 +200,8 @@ public: wxPoint GetPosition() const override; void SetPosition( const wxPoint& aPosition ) override; + wxPoint GetParentPosition() const; + bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override; bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override; diff --git a/eeschema/sch_item.cpp b/eeschema/sch_item.cpp index 1a8ddc5337..3fb65f6711 100644 --- a/eeschema/sch_item.cpp +++ b/eeschema/sch_item.cpp @@ -88,10 +88,7 @@ SCH_ITEM* SCH_ITEM::Duplicate( bool doClone ) const for( SCH_PIN* pin : component->GetSchPins() ) pin->ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); - std::vector fields; - component->GetFields( fields, false ); - - for( SCH_FIELD* field : fields ) + for( SCH_FIELD* field : component->GetFields() ) field->ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); } @@ -99,6 +96,9 @@ SCH_ITEM* SCH_ITEM::Duplicate( bool doClone ) const { SCH_SHEET* sheet = (SCH_SHEET*) newItem; + for( SCH_FIELD& field : sheet->GetFields() ) + field.ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); + for( SCH_SHEET_PIN* pin : sheet->GetPins() ) pin->ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); } diff --git a/eeschema/sch_legacy_plugin.cpp b/eeschema/sch_legacy_plugin.cpp index 40c60406c9..bdd5c6efb5 100644 --- a/eeschema/sch_legacy_plugin.cpp +++ b/eeschema/sch_legacy_plugin.cpp @@ -1066,7 +1066,10 @@ SCH_SHEET* SCH_LEGACY_PLUGIN::loadSheet( LINE_READER& aReader ) } } else if( strCompare( "$EndSheet", line ) ) + { + sheet->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); return sheet.release(); + } line = aReader.ReadLine(); } diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index 3621d780d9..df580a5a7c 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -1341,10 +1341,7 @@ void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer ) draw( &tempPart, aLayer, false, aComp->GetUnit(), aComp->GetConvert() ); // The fields are SCH_COMPONENT-specific so don't need to be copied/oriented/translated - std::vector fields; - aComp->GetFields( fields, false ); - - for( SCH_FIELD* field : fields ) + for( SCH_FIELD* field : aComp->GetFields() ) draw( field, aLayer ); } @@ -1356,12 +1353,7 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer ) if( drawingShadows && !aField->IsSelected() ) return; - switch( aField->GetId() ) - { - case REFERENCE: aLayer = LAYER_REFERENCEPART; break; - case VALUE: aLayer = LAYER_VALUEPART; break; - default: aLayer = LAYER_FIELDS; break; - } + aLayer = aField->GetLayer(); COLOR4D color = getRenderColor( aField, aLayer, drawingShadows ); @@ -1376,20 +1368,22 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer ) if( aField->IsVoid() ) return; - SCH_COMPONENT* parentComponent = (SCH_COMPONENT*) aField->GetParent(); - - if( drawingShadows && parentComponent->IsSelected() && !GetSelectionDrawChildItems() ) + if( drawingShadows && aField->GetParent()->IsSelected() && !GetSelectionDrawChildItems() ) return; - // Calculate the text orientation according to the component orientation. - int orient = (int) aField->GetTextAngle(); + // Calculate the text orientation according to the parent orientation. + int orient = (int) aField->GetTextAngle(); - if( parentComponent->GetTransform().y1 ) // Rotate component 90 degrees. + if( aField->GetParent() && aField->GetParent()->Type() == SCH_COMPONENT_T ) { + if( static_cast( aField->GetParent() )->GetTransform().y1 ) + { + // Rotate component 90 degrees. if( orient == TEXT_ANGLE_HORIZ ) orient = TEXT_ANGLE_VERT; else orient = TEXT_ANGLE_HORIZ; + } } /* Calculate the text justification, according to the component orientation/mirror. @@ -1436,9 +1430,11 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer ) // Draw the umbilical line if( aField->IsMoving() ) { + wxPoint parentPos = aField->GetParentPosition(); + m_gal->SetLineWidth( m_schSettings.m_outlineWidth ); m_gal->SetStrokeColor( COLOR4D( 0.0, 0.0, 1.0, 1.0 ) ); - m_gal->DrawLine( textpos, parentComponent->GetPosition() ); + m_gal->DrawLine( textpos, parentPos ); } } @@ -1584,60 +1580,11 @@ void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer ) m_gal->DrawRectangle( pos, pos + size ); - VECTOR2D pos_sheetname = aSheet->GetSheetNamePosition(); - VECTOR2D pos_filename = aSheet->GetFileNamePosition(); - double nameAngle = 0.0; + if( drawingShadows && !GetSelectionDrawChildItems() ) + return; - if( aSheet->IsVerticalOrientation() ) - nameAngle = M_PI/2; - - if( drawingShadows ) - { - if( !GetSelectionDrawChildItems() ) - return; - - if( aSheet->IsVerticalOrientation() ) - { - pos_sheetname.y += getShadowWidth() / 2; - pos_filename.y += getShadowWidth() / 2; - } - else - { - pos_sheetname.x -= getShadowWidth() / 2; - pos_filename.x -= getShadowWidth() / 2; - } - } - - if( aSheet->GetShowSheetName() ) - { - wxString text = wxT( "Sheet: " ) + aSheet->GetName(); - - m_gal->SetStrokeColor( getRenderColor( aSheet, LAYER_SHEETNAME, drawingShadows ) ); - m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_LEFT ); - m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_BOTTOM ); - - int txtSize = aSheet->GetSheetNameSize(); - m_gal->SetGlyphSize( VECTOR2D( txtSize, txtSize ) ); - m_gal->SetFontBold( false ); - m_gal->SetFontItalic( false ); - - strokeText( text, pos_sheetname, nameAngle ); - } - - if( aSheet->GetShowFileName() ) - { - wxString text = wxT( "File: " ) + aSheet->GetFileName(); - - m_gal->SetStrokeColor( getRenderColor( aSheet, LAYER_SHEETFILENAME, drawingShadows ) ); - m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_TOP ); - - int txtSize = aSheet->GetFileNameSize(); - m_gal->SetGlyphSize( VECTOR2D( txtSize, txtSize ) ); - m_gal->SetFontBold( false ); - m_gal->SetFontItalic( false ); - - strokeText( text, pos_filename, nameAngle ); - } + for( SCH_FIELD& field : aSheet->GetFields() ) + draw( &field, aLayer ); } } diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index eba596ca5d..286a449681 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -37,6 +37,34 @@ #include #include #include +#include + + +const wxString GetDefaultFieldName( int aFieldNdx ) +{ + static void* locale = nullptr; + static wxString sheetnameDefault; + static wxString sheetfilenameDefault; + static wxString fieldDefault; + + // Fetching translations can take a surprising amount of time when loading libraries, + // so only do it when necessary. + if( Pgm().GetLocale() != locale ) + { + sheetnameDefault = _( "Sheet Name" ); + sheetfilenameDefault = _( "Sheet Filename" ); + fieldDefault = _( "Field" ); + locale = Pgm().GetLocale(); + } + + // Fixed values for the mandatory fields + switch( aFieldNdx ) + { + case SHEETNAME: return sheetnameDefault; + case SHEETFILENAME: return sheetfilenameDefault; + default: return wxString::Format( fieldDefault, aFieldNdx ); + } +} SCH_SHEET::SCH_SHEET( const wxPoint& pos ) : @@ -45,13 +73,22 @@ SCH_SHEET::SCH_SHEET( const wxPoint& pos ) : m_Layer = LAYER_SHEET; m_pos = pos; m_size = wxSize( Mils2iu( MIN_SHEET_WIDTH ), Mils2iu( MIN_SHEET_HEIGHT ) ); - m_showSheetName = true; - m_sheetNameSize = GetDefaultTextSize(); - m_showFileName = true; - m_fileNameSize = GetDefaultTextSize(); m_screen = NULL; - m_name.Printf( wxT( "Sheet%s" ), m_Uuid.AsString() ); - m_fileName.Printf( wxT( "file%s.sch" ), m_Uuid.AsString() ); + + for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i ) + { + m_fields.emplace_back( pos, i, this, GetDefaultFieldName( i ) ); + m_fields.back().SetVisible( true ); + + if( i == SHEETNAME ) + m_fields.back().SetLayer( LAYER_SHEETNAME ); + else if( i == SHEETFILENAME ) + m_fields.back().SetLayer( LAYER_SHEETFILENAME ); + else + m_fields.back().SetLayer( LAYER_SHEETFIELDS ); + } + + m_fieldsAutoplaced = FIELDS_AUTOPLACED_AUTO; } @@ -62,13 +99,9 @@ SCH_SHEET::SCH_SHEET( const SCH_SHEET& aSheet ) : m_size = aSheet.m_size; m_Layer = aSheet.m_Layer; const_cast( m_Uuid ) = aSheet.m_Uuid; - m_showSheetName = aSheet.m_showSheetName; - m_sheetNameSize = aSheet.m_sheetNameSize; - m_showFileName = aSheet.m_showFileName; - m_fileNameSize = aSheet.m_fileNameSize; + m_fields = aSheet.m_fields; + m_fieldsAutoplaced = aSheet.m_fieldsAutoplaced; m_screen = aSheet.m_screen; - m_name = aSheet.m_name; - m_fileName = aSheet.m_fileName; for( SCH_SHEET_PIN* pin : aSheet.m_pins ) { @@ -80,7 +113,6 @@ SCH_SHEET::SCH_SHEET( const SCH_SHEET& aSheet ) : m_screen->IncRefCount(); } -// JEY TODO: add read/write of m_showSheetName & m_showFilename to new eeschema file format.... SCH_SHEET::~SCH_SHEET() { @@ -160,11 +192,8 @@ void SCH_SHEET::SwapData( SCH_ITEM* aItem ) std::swap( m_pos, sheet->m_pos ); std::swap( m_size, sheet->m_size ); - std::swap( m_name, sheet->m_name ); - std::swap( m_showSheetName, sheet->m_showSheetName ); - std::swap( m_sheetNameSize, sheet->m_sheetNameSize ); - std::swap( m_showFileName, sheet->m_showFileName ); - std::swap( m_fileNameSize, sheet->m_fileNameSize ); + m_fields.swap( sheet->m_fields ); + std::swap( m_fieldsAutoplaced, sheet->m_fieldsAutoplaced ); m_pins.swap( sheet->m_pins ); // Update parent pointers after swapping. @@ -202,7 +231,7 @@ void SCH_SHEET::RemovePin( SCH_SHEET_PIN* aSheetPin ) } wxLogDebug( wxT( "Fix me: attempt to remove label %s which is not in sheet %s." ), - GetChars( aSheetPin->GetShownText() ), GetChars( m_name ) ); + aSheetPin->GetShownText(), m_fields[ SHEETNAME ].GetText() ); } @@ -397,41 +426,45 @@ int SCH_SHEET::GetPenSize() const } -wxPoint SCH_SHEET::GetSheetNamePosition() +wxPoint SCH_SHEET::getSheetNamePosition() { - wxPoint pos = m_pos; - int margin = KiROUND( GetPenSize() / 2.0 + 4 + m_sheetNameSize * 0.3 ); + wxSize textSize = m_fields[ SHEETNAME ].GetTextSize(); + int margin = KiROUND( GetPenSize() / 2.0 + 4 + std::max( textSize.x, textSize.y ) * 0.3 ); if( IsVerticalOrientation() ) - { - pos.x -= margin; - pos.y += m_size.y; - } + return wxPoint( -margin, m_size.y ); else - { - pos.y -= margin; - } - - return pos; + return wxPoint( 0, -margin ); } -wxPoint SCH_SHEET::GetFileNamePosition() +wxPoint SCH_SHEET::getFileNamePosition() { - wxPoint pos = m_pos; - int margin = KiROUND( GetPenSize() / 2.0 + 4 + m_fileNameSize * 0.4 ); + wxSize textSize = m_fields[ SHEETNAME ].GetTextSize(); + int margin = KiROUND( GetPenSize() / 2.0 + 4 + std::max( textSize.x, textSize.y ) * 0.4 ); if( IsVerticalOrientation() ) - { - pos.x += m_size.x + margin; - pos.y += m_size.y; - } + return wxPoint( m_size.x + margin, m_size.y ); else - { - pos.y += m_size.y + margin; - } + return wxPoint( 0, m_size.y + margin ); +} - return pos; + +void SCH_SHEET::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) +{ + wxASSERT_MSG( !aManual, "manual autoplacement not currently supported for sheets" ); + + m_fields[ SHEETNAME ].SetTextPos( getSheetNamePosition() ); + m_fields[ SHEETNAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); + m_fields[ SHEETNAME ].SetVertJustify(GR_TEXT_VJUSTIFY_BOTTOM ); + m_fields[ SHEETNAME ].SetTextAngle( IsVerticalOrientation() ? 900 : 0 ); + + m_fields[ SHEETFILENAME ].SetTextPos( getFileNamePosition() ); + m_fields[ SHEETFILENAME ].SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); + m_fields[ SHEETFILENAME ].SetVertJustify(GR_TEXT_VJUSTIFY_TOP ); + m_fields[ SHEETFILENAME ].SetTextAngle( IsVerticalOrientation() ? 900 : 0 ); + + m_fieldsAutoplaced = FIELDS_AUTOPLACED_AUTO; } @@ -448,43 +481,14 @@ void SCH_SHEET::ViewGetLayers( int aLayers[], int& aCount ) const void SCH_SHEET::Print( wxDC* aDC, const wxPoint& aOffset ) { wxString Text; - int name_orientation; - wxPoint pos_sheetname,pos_filename; wxPoint pos = m_pos + aOffset; int lineWidth = GetPenSize(); - int textWidth; - wxSize textSize; COLOR4D color = GetLayerColor( m_Layer ); GRRect( nullptr, aDC, pos.x, pos.y, pos.x + m_size.x, pos.y + m_size.y, lineWidth, color ); - pos_sheetname = GetSheetNamePosition() + aOffset; - pos_filename = GetFileNamePosition() + aOffset; - - if( IsVerticalOrientation() ) - name_orientation = TEXT_ANGLE_VERT; - else - name_orientation = TEXT_ANGLE_HORIZ; - - /* Draw text : SheetName */ - if( m_showSheetName ) - { - Text = wxT( "Sheet: " ) + m_name; - textSize = wxSize( m_sheetNameSize, m_sheetNameSize ); - textWidth = Clamp_Text_PenSize( lineWidth, textSize, false ); - GRText( aDC, pos_sheetname, GetLayerColor( LAYER_SHEETNAME ), Text, name_orientation, - textSize, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM, textWidth, false, false ); - } - - /* Draw text : FileName */ - if( m_showFileName ) - { - Text = wxT( "File: " ) + m_fileName; - textSize = wxSize( m_fileNameSize, m_fileNameSize ); - textWidth = Clamp_Text_PenSize( lineWidth, textSize, false ); - GRText( aDC, pos_filename, GetLayerColor( LAYER_SHEETFILENAME ), Text, name_orientation, - textSize, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP, textWidth, false, false ); - } + for( SCH_FIELD& field : m_fields ) + field.Print( aDC, aOffset ); /* Draw text : SheetLabel */ for( SCH_SHEET_PIN* sheetPin : m_pins ) @@ -499,23 +503,6 @@ const EDA_RECT SCH_SHEET::GetBoundingBox() const int lineWidth = GetPenSize(); int textLength = 0; - // Determine length of texts - if( m_showSheetName ) - { - wxString text = wxT( "Sheet: " ) + m_name; - int textlen = GraphicTextWidth( text, wxSize( m_sheetNameSize, m_sheetNameSize ), - false, false ); - textLength = std::max( textLength, textlen ); - } - - if( m_showFileName ) - { - wxString text = wxT( "File: " ) + m_fileName; - int textlen = GraphicTextWidth( text, wxSize( m_fileNameSize, m_fileNameSize ), - false, false ); - textLength = std::max( textLength, textlen ); - } - // Calculate bounding box X size: end.x = std::max( m_size.x, textLength ); @@ -523,13 +510,12 @@ const EDA_RECT SCH_SHEET::GetBoundingBox() const end.y = m_size.y; end += m_pos; - // Move upper and lower limits to include texts: - box.SetY( box.GetY() - ( KiROUND( m_sheetNameSize * 1.3 ) + 8 ) ); - end.y += KiROUND( m_fileNameSize * 1.3 ) + 8; - box.SetEnd( end ); box.Inflate( lineWidth / 2 ); + for( size_t i = 0; i < m_fields.size(); i++ ) + box.Merge( m_fields[i].GetBoundingBox() ); + return box; } @@ -639,16 +625,10 @@ int SCH_SHEET::CountSheets() } -wxString SCH_SHEET::GetFileName( void ) const -{ - return m_fileName; -} - - void SCH_SHEET::GetMsgPanelInfo( EDA_UNITS aUnits, MSG_PANEL_ITEMS& aList ) { - aList.push_back( MSG_PANEL_ITEM( _( "Sheet Name" ), m_name, CYAN ) ); - aList.push_back( MSG_PANEL_ITEM( _( "File Name" ), m_fileName, BROWN ) ); + aList.emplace_back( _( "Sheet Name" ), m_fields[ SHEETNAME ].GetText(), CYAN ); + aList.emplace_back( _( "File Name" ), m_fields[ SHEETFILENAME ].GetText(), BROWN ); #if 1 // Set to 1 to display the sheet UUID and hierarchical path wxString msgU, msgL; @@ -662,6 +642,8 @@ void SCH_SHEET::GetMsgPanelInfo( EDA_UNITS aUnits, MSG_PANEL_ITEMS& aList ) void SCH_SHEET::Rotate(wxPoint aPosition) { + wxPoint prev = m_pos; + RotatePoint( &m_pos, aPosition, 900 ); RotatePoint( &m_size.x, &m_size.y, 900 ); @@ -677,6 +659,15 @@ void SCH_SHEET::Rotate(wxPoint aPosition) m_size.y = -m_size.y; } + for( SCH_FIELD& field : m_fields ) + { + // Move the fields to the new position because the sheet itself has moved. + wxPoint pos = field.GetTextPos(); + pos.x -= prev.x - m_pos.x; + pos.y -= prev.y - m_pos.y; + field.SetTextPos( pos ); + } + for( SCH_SHEET_PIN* sheetPin : m_pins ) sheetPin->Rotate( aPosition ); } @@ -717,7 +708,11 @@ void SCH_SHEET::Resize( const wxSize& aSize ) m_size = aSize; - /* Move the sheet labels according to the new sheet size. */ + // Move the fields if we're in autoplace mode + if( m_fieldsAutoplaced == FIELDS_AUTOPLACED_AUTO ) + AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); + + // Move the sheet labels according to the new sheet size. for( SCH_SHEET_PIN* sheetPin : m_pins ) sheetPin->ConstrainOnEdge( sheetPin->GetPosition() ); } @@ -727,28 +722,11 @@ bool SCH_SHEET::Matches( wxFindReplaceData& aSearchData, void* aAuxData ) { wxLogTrace( traceFindItem, wxT( " item " ) + GetSelectMenuText( EDA_UNITS::MILLIMETRES ) ); - // Ignore the sheet file name if searching to replace. - if( !(aSearchData.GetFlags() & FR_SEARCH_REPLACE) - && SCH_ITEM::Matches( m_fileName, aSearchData ) ) - { - return true; - } - - if( SCH_ITEM::Matches( m_name, aSearchData ) ) - { - return true; - } - + // Sheets are searchable via the child field and pin item text. return false; } -bool SCH_SHEET::Replace( wxFindReplaceData& aSearchData, void* aAuxData ) -{ - return EDA_ITEM::Replace( aSearchData, m_name ); -} - - void SCH_SHEET::renumberPins() { int id = 2; @@ -822,7 +800,7 @@ SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData, const KICA wxString SCH_SHEET::GetSelectMenuText( EDA_UNITS aUnits ) const { - return wxString::Format( _( "Hierarchical Sheet %s" ), m_name ); + return wxString::Format( _( "Hierarchical Sheet %s" ), m_fields[ SHEETNAME ].GetText() ); } @@ -855,8 +833,7 @@ bool SCH_SHEET::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) } -void SCH_SHEET::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, - SCH_SHEET_PATH* aSheetPath ) +void SCH_SHEET::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, SCH_SHEET_PATH* aSheetPath ) { SCH_SHEET_PATH sheetPath = *aSheetPath; sheetPath.push_back( this ); @@ -882,11 +859,7 @@ void SCH_SHEET::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, void SCH_SHEET::Plot( PLOTTER* aPlotter ) { - COLOR4D txtcolor = COLOR4D::UNSPECIFIED; - wxSize size; wxString Text; - int name_orientation; - wxPoint pos_sheetname, pos_filename; wxPoint pos; aPlotter->SetColor( aPlotter->ColorSettings()->GetColor( GetLayer() ) ); @@ -908,52 +881,8 @@ void SCH_SHEET::Plot( PLOTTER* aPlotter ) aPlotter->LineTo( pos ); aPlotter->FinishTo( m_pos ); - if( IsVerticalOrientation() ) - { - pos_sheetname = wxPoint( m_pos.x - 8, m_pos.y + m_size.y ); - pos_filename = wxPoint( m_pos.x + m_size.x + 4, m_pos.y + m_size.y ); - name_orientation = TEXT_ANGLE_VERT; - } - else - { - pos_sheetname = wxPoint( m_pos.x, m_pos.y - 4 ); - pos_filename = wxPoint( m_pos.x, m_pos.y + m_size.y + 4 ); - name_orientation = TEXT_ANGLE_HORIZ; - } - - bool italic = false; - - /* Draw texts: SheetName */ - if( m_showSheetName ) - { - Text = m_name; - size = wxSize( m_sheetNameSize, m_sheetNameSize ); - - //pos = m_pos; pos.y -= 4; - thickness = GetDefaultLineThickness(); - thickness = Clamp_Text_PenSize( thickness, size, false ); - - txtcolor = aPlotter->ColorSettings()->GetColor( LAYER_SHEETNAME ); - - aPlotter->Text( pos_sheetname, txtcolor, wxT( "Sheet: " ) + Text, name_orientation, size, - GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_BOTTOM, - thickness, false, false ); - } - - /*Draw texts : FileName */ - if( m_showFileName ) - { - Text = GetFileName(); - size = wxSize( m_fileNameSize, m_fileNameSize ); - thickness = GetDefaultLineThickness(); - thickness = Clamp_Text_PenSize( thickness, size, false ); - - txtcolor = aPlotter->ColorSettings()->GetColor( LAYER_SHEETFILENAME ); - - aPlotter->Text( pos_filename, txtcolor, wxT( "File: " ) + Text, name_orientation, size, - GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP, - thickness, italic, false ); - } + for( SCH_FIELD field : m_fields ) + field.Plot( aPlotter ); aPlotter->SetColor( aPlotter->ColorSettings()->GetColor( GetLayer() ) ); @@ -979,9 +908,7 @@ SCH_SHEET& SCH_SHEET::operator=( const SCH_ITEM& aItem ) m_pos = sheet->m_pos; m_size = sheet->m_size; - m_name = sheet->m_name; - m_sheetNameSize = sheet->m_sheetNameSize; - m_fileNameSize = sheet->m_fileNameSize; + m_fields = sheet->m_fields; for( SCH_SHEET_PIN* pin : sheet->m_pins ) { @@ -1001,11 +928,11 @@ bool SCH_SHEET::operator <( const SCH_ITEM& aItem ) const auto sheet = static_cast( &aItem ); - if (m_name != sheet->m_name) - return m_name < sheet->m_name; + if (m_fields[ SHEETNAME ].GetText() != sheet->m_fields[ SHEETNAME ].GetText()) + return m_fields[ SHEETNAME ].GetText() < sheet->m_fields[ SHEETNAME ].GetText(); - if (m_fileName != sheet->m_fileName) - return m_fileName < sheet->m_fileName; + if (m_fields[ SHEETFILENAME ].GetText() != sheet->m_fields[ SHEETFILENAME ].GetText()) + return m_fields[ SHEETFILENAME ].GetText() < sheet->m_fields[ SHEETFILENAME ].GetText(); return false; } @@ -1019,7 +946,7 @@ void SCH_SHEET::Show( int nestLevel, std::ostream& os ) const wxString s = GetClass(); NestedSpace( nestLevel, os ) << '<' << s.Lower().mb_str() << ">" << " sheet_name=\"" - << TO_UTF8( m_name ) << '"' << ">\n"; + << TO_UTF8( m_fields[ SHEETNAME ].GetText() ) << '"' << ">\n"; // show all the pins, and check the linked list integrity for( SCH_SHEET_PIN* sheetPin : m_pins ) diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h index d28ec7a138..98fd8c9822 100644 --- a/eeschema/sch_sheet.h +++ b/eeschema/sch_sheet.h @@ -27,7 +27,7 @@ #include #include - +#include class LINE_READER; class SCH_SCREEN; @@ -62,6 +62,15 @@ enum SHEET_SIDE }; +enum SHEET_FIELD_TYPE { + SHEETNAME = 0, + SHEETFILENAME, + + /// The first 2 are mandatory, and must be instantiated in SCH_SHEET + SHEET_MANDATORY_FIELDS +}; + + /** * Define a sheet pin (label) used in sheets to create hierarchical schematics. * @@ -214,20 +223,11 @@ class SCH_SHEET : public SCH_ITEM /// The list of sheet connection points. std::vector m_pins; - /// The file name is also in the #SCH_SCREEN object associated with the sheet. It is - /// also needed here for loading after reading the sheet description from file. - wxString m_fileName; - bool m_showFileName; // Indicates filename should be drawn on schematic. - int m_fileNameSize; // The height of the text used to draw the file name. + std::vector m_fields; + FIELDS_AUTOPLACED m_fieldsAutoplaced; // indicates status of field autoplacement - /// This is equivalent to the reference designator for components and is stored in F0 - /// sheet pin in the schematic file. - wxString m_name; - bool m_showSheetName; // Indicates sheet name should be drawn on schematic. - int m_sheetNameSize; // The height of the text used to draw the sheet name. - - wxPoint m_pos; // The position of the sheet. - wxSize m_size; // The size of the sheet. + wxPoint m_pos; // The position of the sheet. + wxSize m_size; // The size of the sheet. public: SCH_SHEET( const wxPoint& pos = wxPoint( 0, 0 ) ); @@ -261,20 +261,23 @@ public: */ bool IsMovableFromAnchorPoint() override { return false; } - wxString GetName() const { return m_name; } - void SetName( const wxString& aName ) { m_name = aName; } + std::vector& GetFields() { return m_fields; } - bool GetShowSheetName() const { return m_showSheetName; } - void SetShowSheetName( bool show ) { m_showSheetName = show; } + // JEY TODO: retite these once new dialog is implemented... + wxString GetName() const { return m_fields[ SHEETNAME ].GetText(); } + void SetName( const wxString& aName ) { m_fields[ SHEETNAME ].SetText( aName ); } - int GetSheetNameSize() const { return m_sheetNameSize; } - void SetSheetNameSize( int aSize ) { m_sheetNameSize = aSize; } + bool GetShowSheetName() const { return m_fields[ SHEETNAME ].IsVisible(); } + void SetShowSheetName( bool show ) { m_fields[ SHEETNAME ].SetVisible( show ); } - bool GetShowFileName() const { return m_showFileName; } - void SetShowFileName( bool show ) { m_showFileName = show; } + int GetSheetNameSize() const { return m_fields[ SHEETNAME ].GetTextSize().x; } + void SetSheetNameSize( int aSize ) { m_fields[ SHEETNAME ].SetTextSize( wxSize( aSize, aSize ) ); } - int GetFileNameSize() const { return m_fileNameSize; } - void SetFileNameSize( int aSize ) { m_fileNameSize = aSize; } + bool GetShowFileName() const { return m_fields[ SHEETFILENAME ].IsVisible(); } + void SetShowFileName( bool show ) { m_fields[ SHEETFILENAME ].SetVisible( show ); } + + int GetFileNameSize() const { return m_fields[ SHEETFILENAME ].GetTextSize().x; } + void SetFileNameSize( int aSize ) { m_fields[ SHEETFILENAME ].SetTextSize( wxSize( aSize, aSize ) ); } SCH_SCREEN* GetScreen() { return m_screen; } @@ -459,17 +462,18 @@ public: * * @return a wxString containing the filename */ - wxString GetFileName( void ) const; - - // Set a new filename without changing anything else - void SetFileName( const wxString& aFilename ) + wxString GetFileName() const { - m_fileName = aFilename; - // Filenames are stored using unix notation - m_fileName.Replace( wxT("\\"), wxT("/") ); + return m_fields[ SHEETFILENAME ].GetText(); } - bool ChangeFileName( SCH_EDIT_FRAME* aFrame, const wxString& aFileName ); + // Set a new filename without changing anything else + void SetFileName( wxString aFilename ) + { + // Filenames are stored using unix notation + aFilename.Replace( wxT("\\"), wxT("/") ); + m_fields[ SHEETFILENAME ].SetText( aFilename ); + } // Geometric transforms (used in block operations): @@ -487,8 +491,6 @@ public: bool Matches( wxFindReplaceData& aSearchData, void* aAuxData ) override; - bool Replace( wxFindReplaceData& aSearchData, void* aAuxData = NULL ) override; - bool IsReplaceable() const override { return true; } /** @@ -499,14 +501,16 @@ public: void Resize( const wxSize& aSize ); /** - * @return the position of the anchor of sheet name text + * Return whether the fields have been automatically placed. */ - wxPoint GetSheetNamePosition(); + FIELDS_AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; } /** - * @return the position of the anchor of filename text + * Set fields automatically placed flag false. */ - wxPoint GetFileNamePosition(); + void ClearFieldsAutoplaced() { m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; } + + void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ); void GetEndPoints( std::vector & aItemList ) override; @@ -555,6 +559,16 @@ public: protected: + /** + * @return the position of the anchor of sheet name text + */ + wxPoint getSheetNamePosition(); + + /** + * @return the position of the anchor of filename text + */ + wxPoint getFileNamePosition(); + /** * Renumber the sheet pins in the sheet. * diff --git a/eeschema/template_fieldnames.cpp b/eeschema/template_fieldnames.cpp index 26be93d556..a0f1273314 100644 --- a/eeschema/template_fieldnames.cpp +++ b/eeschema/template_fieldnames.cpp @@ -48,34 +48,19 @@ const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx ) valueDefault = _( "Value" ); footprintDefault = _( "Footprint" ); datasheetDefault = _( "Datasheet" ); - fieldDefault = _( "Field" ); + fieldDefault = _( "Field%d" ); locale = Pgm().GetLocale(); } - // Fixed values for the first few default fields used by EESCHEMA - // (mandatory fields) + // Fixed values for the mandatory fields switch( aFieldNdx ) { - case REFERENCE: - return referenceDefault; // The component reference, R1, C1, etc. - - case VALUE: - return valueDefault; // The component value + name - - case FOOTPRINT: - return footprintDefault; // The footprint for use with Pcbnew - - case DATASHEET: - return datasheetDefault; // Link to a datasheet for component - - default: - break; + case REFERENCE: return referenceDefault; // The component reference, R1, C1, etc. + case VALUE: return valueDefault; // The component value + name + case FOOTPRINT: return footprintDefault; // The footprint for use with Pcbnew + case DATASHEET: return datasheetDefault; // Link to a datasheet for component + default: return wxString::Format( fieldDefault, aFieldNdx ); } - - // Other fields are use fields, give a default name: - wxString fieldName = fieldDefault; - fieldName << aFieldNdx; - return fieldName; } void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out, int nestLevel ) const diff --git a/eeschema/tools/ee_point_editor.cpp b/eeschema/tools/ee_point_editor.cpp index 8e091a1cd5..227a0b73ee 100644 --- a/eeschema/tools/ee_point_editor.cpp +++ b/eeschema/tools/ee_point_editor.cpp @@ -575,6 +575,10 @@ void EE_POINT_EDITOR::updateItem() const sheet->SetPosition( (wxPoint) topLeft ); sheet->SetSize( wxSize( botRight.x - topLeft.x, botRight.y - topLeft.y ) ); + // Update the fields if we're in autoplace mode + if( sheet->GetFieldsAutoplaced() == FIELDS_AUTOPLACED_AUTO ) + sheet->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); + // Keep sheet pins attached to edges: for( SCH_SHEET_PIN* pin : sheet->GetPins() ) { diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index ee1b37ef0e..53b6559bb0 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -970,7 +970,7 @@ void EE_SELECTION_TOOL::RebuildSelection() { LIB_PART* start = static_cast( m_frame )->GetCurPart(); - for( auto& item : start->GetDrawItems() ) + for( LIB_ITEM& item : start->GetDrawItems() ) { if( item.IsSelected() ) select( static_cast( &item ) ); @@ -989,16 +989,26 @@ void EE_SELECTION_TOOL::RebuildSelection() { if( item->Type() == SCH_COMPONENT_T ) { - for( auto field : static_cast( item )->GetFields() ) + for( SCH_FIELD* field : static_cast( item )->GetFields() ) + { if( field->IsSelected() ) select( field ); + } } if( item->Type() == SCH_SHEET_T ) { - for( auto pin : static_cast( item )->GetPins() ) + for( SCH_FIELD& field : static_cast( item )->GetFields() ) + { + if( field.IsSelected() ) + select( &field ); + } + + for( SCH_SHEET_PIN* pin : static_cast( item )->GetPins() ) + { if( pin->IsSelected() ) select( pin ); + } } } @@ -1221,10 +1231,7 @@ void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGr pin->SetBrightened(); } - std::vector fields; - static_cast( aItem )->GetFields( fields, false ); - - for( SCH_FIELD* field : fields ) + for( SCH_FIELD* field : static_cast( aItem )->GetFields() ) { if( aMode == SELECTED ) field->SetSelected(); @@ -1234,9 +1241,15 @@ void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGr } else if( itemType == SCH_SHEET_T ) { - std::vector& pins = static_cast( aItem )->GetPins(); + for( SCH_FIELD& field : static_cast( aItem )->GetFields() ) + { + if( aMode == SELECTED ) + field.SetSelected(); + else if( aMode == BRIGHTENED ) + field.SetBrightened(); + } - for( SCH_SHEET_PIN* pin : pins ) + for( SCH_SHEET_PIN* pin : static_cast( aItem )->GetPins() ) { if( aMode == SELECTED ) pin->SetSelected(); @@ -1278,10 +1291,7 @@ void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* a pin->ClearBrightened(); } - std::vector fields; - static_cast( aItem )->GetFields( fields, false ); - - for( SCH_FIELD* field : fields ) + for( SCH_FIELD* field : static_cast( aItem )->GetFields() ) { if( aMode == SELECTED ) field->ClearSelected(); @@ -1291,9 +1301,15 @@ void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* a } else if( itemType == SCH_SHEET_T ) { - std::vector& pins = static_cast( aItem )->GetPins(); + for( SCH_FIELD& field : static_cast( aItem )->GetFields() ) + { + if( aMode == SELECTED ) + field.ClearSelected(); + else if( aMode == BRIGHTENED ) + field.ClearBrightened(); + } - for( SCH_SHEET_PIN* pin : pins ) + for( SCH_SHEET_PIN* pin : static_cast( aItem )->GetPins() ) { if( aMode == SELECTED ) pin->ClearSelected(); diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index d45a4332f1..4ebe96d8e5 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -850,6 +850,8 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent ) if( m_frame->EditSheet( (SCH_SHEET*)sheet, g_CurrentSheet, nullptr ) ) { + sheet->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); + m_frame->AddItemToScreenAndUndoList( sheet ); m_frame->UpdateHierarchyNavigator(); m_selectionTool->AddItemToSel( sheet ); diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 67f9b01878..2e7e30d60c 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -223,6 +223,23 @@ SCH_ITEM* SCH_EDITOR_CONTROL::nextMatch( return pin; } } + + if( item->Type() == SCH_SHEET_T ) + { + auto sheet = static_cast( item ); + + for( SCH_FIELD& field : sheet->GetFields() ) + { + if( field.Matches( *aData, nullptr ) ) + return &field; + } + + for( SCH_SHEET_PIN* pin : sheet->GetPins() ) + { + if( pin->Matches( *aData, nullptr ) ) + return pin; + } + } } } diff --git a/eeschema/widgets/widget_eeschema_color_config.cpp b/eeschema/widgets/widget_eeschema_color_config.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/include/layers_id_colors_and_visibility.h b/include/layers_id_colors_and_visibility.h index b40b521242..26edeb0b83 100644 --- a/include/layers_id_colors_and_visibility.h +++ b/include/layers_id_colors_and_visibility.h @@ -255,6 +255,7 @@ enum SCH_LAYER_ID: int LAYER_SHEET, LAYER_SHEETNAME, LAYER_SHEETFILENAME, + LAYER_SHEETFIELDS, LAYER_SHEETLABEL, LAYER_NOCONNECT, LAYER_ERC_WARN, diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 612a0678ff..5b15602a43 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -692,7 +692,7 @@ private: TEXTE_MODULE* m_Value; // Component value (74LS00, 22K..) LIB_ID m_fpid; // The #LIB_ID of the MODULE. int m_Attributs; // Flag bits ( see Mod_Attribut ) - int m_ModuleStatus; // For autoplace: flags (LOCKED, AUTOPLACED) + int m_ModuleStatus; // For autoplace: flags (LOCKED, FIELDS_AUTOPLACED) EDA_RECT m_BoundaryBox; // Bounding box : coordinates on board, real orientation. ZONE_CONNECTION m_ZoneConnection;