From 8c5c902fa35818a4eb617a13528bd164f8b4366c Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Tue, 17 Nov 2020 16:02:47 +0000 Subject: [PATCH] Re-write IntersheetRefs on top of SCH_FIELDs and textVars. 1) Generalize SCH_ITEM owners (SCH_COMPONENT, SCH_SHEET, and now SCH_GLOBALLABEL) 2) Generalize hypertext items 3) Use SCH_FIELD autoplace infrastructure for placing intersheet references 4) Use textVar infrastructure for buildin intersheet references. As an important side-effect this also fixes the undo issues with intersheet refs. --- eeschema/CMakeLists.txt | 1 - eeschema/default_values.h | 3 + eeschema/dialogs/dialog_edit_label.cpp | 11 +- eeschema/dialogs/panel_setup_formatting.cpp | 28 +-- eeschema/ee_collectors.cpp | 15 +- eeschema/ee_collectors.h | 2 +- eeschema/sch_base_frame.cpp | 8 +- eeschema/sch_component.cpp | 10 + eeschema/sch_component.h | 2 + eeschema/sch_edit_frame.cpp | 153 +++----------- eeschema/sch_edit_frame.h | 6 +- eeschema/sch_field.cpp | 76 ++++++- eeschema/sch_field.h | 8 +- eeschema/sch_iref.cpp | 146 ------------- eeschema/sch_iref.h | 88 -------- eeschema/sch_item.cpp | 26 +-- eeschema/sch_item.h | 12 +- eeschema/sch_painter.cpp | 30 +-- .../sch_plugins/kicad/sch_sexpr_parser.cpp | 32 +-- .../sch_plugins/kicad/sch_sexpr_plugin.cpp | 23 +- eeschema/sch_screen.cpp | 4 +- eeschema/sch_sheet.cpp | 10 + eeschema/sch_sheet.h | 2 + eeschema/sch_sheet_path.cpp | 87 ++------ eeschema/sch_text.cpp | 199 ++++++++++++++++-- eeschema/sch_text.h | 33 ++- eeschema/schematic.h | 8 + eeschema/schematic_settings.cpp | 18 +- eeschema/schematic_settings.h | 8 +- eeschema/tools/ee_selection_tool.cpp | 151 ++++--------- eeschema/tools/sch_drawing_tools.cpp | 9 +- eeschema/tools/sch_edit_tool.cpp | 77 +++---- eeschema/tools/sch_editor_control.cpp | 33 +-- eeschema/tools/sch_move_tool.cpp | 33 --- eeschema/tools/sch_navigate_tool.cpp | 3 +- eeschema/tools/sch_navigate_tool.h | 2 - include/core/typeinfo.h | 1 - 37 files changed, 557 insertions(+), 801 deletions(-) delete mode 100644 eeschema/sch_iref.cpp delete mode 100644 eeschema/sch_iref.h diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index e91e7077de..ecd333e347 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -235,7 +235,6 @@ set( EESCHEMA_SRCS toolbars_lib_view.cpp toolbars_sch_editor.cpp transform.cpp - sch_iref.cpp netlist_exporters/netlist_exporter_base.cpp netlist_exporters/netlist_exporter_cadstar.cpp diff --git a/eeschema/default_values.h b/eeschema/default_values.h index 563f6f6919..b273850b71 100644 --- a/eeschema/default_values.h +++ b/eeschema/default_values.h @@ -63,6 +63,9 @@ ///< The default text size in mils. (can be changed in preference menu) #define DEFAULT_TEXT_SIZE 50 +///< Ratio of the font height to the baseline of the text above the wire. +#define DEFAULT_TEXT_OFFSET_RATIO 0.08 + ///< The offset of the pin name string from the end of the pin in mils. #define DEFAULT_PIN_NAME_OFFSET 20 diff --git a/eeschema/dialogs/dialog_edit_label.cpp b/eeschema/dialogs/dialog_edit_label.cpp index 50673e9fe9..e41895be55 100644 --- a/eeschema/dialogs/dialog_edit_label.cpp +++ b/eeschema/dialogs/dialog_edit_label.cpp @@ -33,13 +33,11 @@ #include #include #include -#include #include #include #include #include #include -#include class SCH_EDIT_FRAME; class SCH_TEXT; @@ -348,14 +346,7 @@ bool DIALOG_LABEL_EDITOR::TransferDataFromWindow() if( m_CurrentText->Type() == SCH_GLOBAL_LABEL_T ) { SCH_GLOBALLABEL* label = static_cast( m_CurrentText ); - SCH_IREF* iref = label->GetIref(); - - if( iref ) - { - if( iref->GetBoundingBox().Intersects( label->GetBoundingBox() ) ) - iref->PlaceAtDefaultPosition(); - iref->CopyParentStyle(); - } + label->UpdateIntersheetRefProps(); } return true; diff --git a/eeschema/dialogs/panel_setup_formatting.cpp b/eeschema/dialogs/panel_setup_formatting.cpp index 4c2fa82fbe..a7c0c5a10d 100644 --- a/eeschema/dialogs/panel_setup_formatting.cpp +++ b/eeschema/dialogs/panel_setup_formatting.cpp @@ -70,11 +70,11 @@ bool PANEL_SETUP_FORMATTING::TransferDataToWindow() m_pinSymbolSize.SetValue( settings.m_PinSymbolSize ); m_choiceJunctionDotSize->SetSelection( settings.m_JunctionSizeChoice ); - m_showIntersheetsReferences->SetValue( settings.m_IntersheetsRefShow ); - m_radioFormatStandard->SetValue( !settings.m_IntersheetsRefFormatShort ); - m_radioFormatAbbreviated->SetValue( settings.m_IntersheetsRefFormatShort ); - m_prefixCtrl->ChangeValue( settings.m_IntersheetsRefPrefix ); - m_suffixCtrl->ChangeValue( settings.m_IntersheetsRefSuffix ); + m_showIntersheetsReferences->SetValue( settings.m_IntersheetRefsShow ); + m_radioFormatStandard->SetValue( !settings.m_IntersheetRefsFormatShort ); + m_radioFormatAbbreviated->SetValue( settings.m_IntersheetRefsFormatShort ); + m_prefixCtrl->ChangeValue( settings.m_IntersheetRefsPrefix ); + m_suffixCtrl->ChangeValue( settings.m_IntersheetRefsSuffix ); wxString offsetRatio = wxString::Format( "%f", settings.m_TextOffsetRatio * 100.0 ); m_textOffsetRatioCtrl->SetValue( offsetRatio ); @@ -142,10 +142,10 @@ bool PANEL_SETUP_FORMATTING::TransferDataFromWindow() settings.m_JunctionSize = currJunctionDotSize; - settings.m_IntersheetsRefShow = m_showIntersheetsReferences->GetValue(); - settings.m_IntersheetsRefFormatShort = !m_radioFormatStandard->GetValue(); - settings.m_IntersheetsRefPrefix = m_prefixCtrl->GetValue(); - settings.m_IntersheetsRefSuffix = m_suffixCtrl->GetValue(); + settings.m_IntersheetRefsShow = m_showIntersheetsReferences->GetValue(); + settings.m_IntersheetRefsFormatShort = !m_radioFormatStandard->GetValue(); + settings.m_IntersheetRefsPrefix = m_prefixCtrl->GetValue(); + settings.m_IntersheetRefsSuffix = m_suffixCtrl->GetValue(); double dtmp = 0.0; wxString msg = m_textOffsetRatioCtrl->GetValue(); @@ -171,11 +171,11 @@ void PANEL_SETUP_FORMATTING::ImportSettingsFrom( SCHEMATIC_SETTINGS& aSettings ) m_lineWidth.SetValue( aSettings.m_DefaultLineWidth ); m_pinSymbolSize.SetValue( aSettings.m_PinSymbolSize ); - m_showIntersheetsReferences->SetValue( aSettings.m_IntersheetsRefShow ); - m_radioFormatStandard->SetValue( aSettings.m_IntersheetsRefFormatShort ); - m_radioFormatAbbreviated->SetValue( !aSettings.m_IntersheetsRefFormatShort ); - m_prefixCtrl->ChangeValue( aSettings.m_IntersheetsRefPrefix ); - m_suffixCtrl->ChangeValue( aSettings.m_IntersheetsRefSuffix ); + m_showIntersheetsReferences->SetValue( aSettings.m_IntersheetRefsShow ); + m_radioFormatStandard->SetValue( aSettings.m_IntersheetRefsFormatShort ); + m_radioFormatAbbreviated->SetValue( !aSettings.m_IntersheetRefsFormatShort ); + m_prefixCtrl->ChangeValue( aSettings.m_IntersheetRefsPrefix ); + m_suffixCtrl->ChangeValue( aSettings.m_IntersheetRefsSuffix ); wxString offsetRatio = wxString::Format( "%f", aSettings.m_TextOffsetRatio * 100.0 ); m_textOffsetRatioCtrl->SetValue( offsetRatio ); diff --git a/eeschema/ee_collectors.cpp b/eeschema/ee_collectors.cpp index a844002436..a2f681901b 100644 --- a/eeschema/ee_collectors.cpp +++ b/eeschema/ee_collectors.cpp @@ -71,9 +71,10 @@ const KICAD_T EE_COLLECTOR::SheetsOnly[] = { }; -const KICAD_T EE_COLLECTOR::ComponentsOrSheets[] = { +const KICAD_T EE_COLLECTOR::FieldOwners[] = { SCH_COMPONENT_T, SCH_SHEET_T, + SCH_GLOBAL_LABEL_T, EOT }; @@ -122,6 +123,7 @@ void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], co // they're not in the filter list bool componentsVisited = false; bool sheetsVisited = false; + bool globalLabelsVisited = false; for( const KICAD_T* filter = aFilterList; *filter != EOT; ++filter ) { @@ -133,6 +135,9 @@ void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], co if( *filter == SCH_SHEET_T || *filter == SCH_LOCATE_ANY_T ) sheetsVisited = true; + if( *filter == SCH_GLOBAL_LABEL_T || *filter == SCH_LOCATE_ANY_T ) + globalLabelsVisited = true; + item->Visit( m_inspector, nullptr, m_scanTypes ); } } @@ -148,6 +153,12 @@ void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], co for( SCH_ITEM* item : aScreen->Items().OfType( SCH_SHEET_T ) ) item->Visit( m_inspector, nullptr, m_scanTypes ); } + + if( !globalLabelsVisited ) + { + for( SCH_ITEM* item : aScreen->Items().OfType( SCH_GLOBAL_LABEL_T ) ) + item->Visit( m_inspector, nullptr, m_scanTypes ); + } } } @@ -164,7 +175,7 @@ void EE_COLLECTOR::Collect( LIB_ITEMS_CONTAINER& aItems, const KICAD_T aFilterLi // remember where the snapshot was taken from and pass refPos to the Inspect() function. SetRefPos( aPos ); - for( auto& item : aItems ) + for( LIB_ITEM& item : aItems ) { if( item.Visit( m_inspector, nullptr, m_scanTypes ) == SEARCH_RESULT::QUIT ) break; diff --git a/eeschema/ee_collectors.h b/eeschema/ee_collectors.h index d085e50f03..743ed6471e 100644 --- a/eeschema/ee_collectors.h +++ b/eeschema/ee_collectors.h @@ -46,7 +46,7 @@ public: static const KICAD_T EditableItems[]; static const KICAD_T ComponentsOnly[]; static const KICAD_T SheetsOnly[]; - static const KICAD_T ComponentsOrSheets[]; + static const KICAD_T FieldOwners[]; EE_COLLECTOR( const KICAD_T* aScanTypes = EE_COLLECTOR::AllItems ) : m_Unit( 0 ), diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index 1ff2e5bc9b..40e0c9be44 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -301,10 +301,10 @@ void SCH_BASE_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete ) if( !isAddOrDelete ) GetCanvas()->GetView()->Update( aItem ); - // Component children are drawn from their parents. Mark them for re-paint. - if( parent && parent->Type() == SCH_COMPONENT_T ) - GetCanvas()->GetView()->Update( parent, KIGFX::REPAINT ); - else if( parent && parent->Type() == SCH_SHEET_T ) + // Some children are drawn from their parents. Mark them for re-paint. + static KICAD_T parentTypes[] = { SCH_COMPONENT_T, SCH_SHEET_T, SCH_GLOBAL_LABEL_T, EOT }; + + if( parent && parent->IsType( parentTypes ) ) GetCanvas()->GetView()->Update( parent, KIGFX::REPAINT ); } diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index e45b340e29..33f8d9554b 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -793,6 +793,16 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef ) } +void SCH_COMPONENT::RunOnChildren( const std::function& aFunction ) +{ + for( const std::unique_ptr& pin : m_pins ) + aFunction( pin.get() ); + + for( SCH_FIELD& field : m_fields ) + aFunction( &field ); +} + + SCH_PIN* SCH_COMPONENT::GetPin( const wxString& aNumber ) { for( const std::unique_ptr& pin : m_pins ) diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index b60612a928..11ba3a7895 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -454,6 +454,8 @@ public: */ void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override; + void RunOnChildren( const std::function& aFunction ) override; + //--------------------------------------------------------------- diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 8110d28802..cc10fca134 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -45,9 +45,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -1234,182 +1232,99 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags ) timer.Stop(); wxLogTrace( "CONN_PROFILE", "SchematicCleanUp() %0.4f ms", timer.msecs() ); - if( settings.m_IntersheetsRefShow == true ) + if( settings.m_IntersheetRefsShow == true ) RecomputeIntersheetsRefs(); Schematic().ConnectionGraph()->Recalculate( list, true ); } + int SCH_EDIT_FRAME::RecomputeIntersheetsRefs() { - SCHEMATIC_SETTINGS& settings = Schematic().Settings(); - std::vector pagesNumbers; - SCH_GLOBALLABEL* gLabel; - SCH_IREF* iref; + std::map>& pageRefsMap = Schematic().GetPageRefsMap(); - m_labelTable.clear(); + pageRefsMap.clear(); - SCH_SCREENS screens( Schematic().Root() ); + SCH_SCREENS screens( Schematic().Root() ); + std::vector pageNumbers; /* Iterate over screens */ for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) { - pagesNumbers.clear(); + pageNumbers.clear(); /* Find in which sheets this screen is used */ for( const SCH_SHEET_PATH& sheet : Schematic().GetSheets() ) { if( sheet.LastScreen() == screen ) - pagesNumbers.push_back( sheet.GetPageNumber() ); + pageNumbers.push_back( sheet.GetPageNumber() ); } for( SCH_ITEM* item : screen->Items() ) { if( item->Type() == SCH_GLOBAL_LABEL_T ) { - gLabel = static_cast( item ); - m_labelTable.push_back( gLabel ); + SCH_GLOBALLABEL* globalLabel = static_cast( item ); + std::set& pageList = pageRefsMap[ globalLabel->GetText() ]; - if( gLabel->GetIref() == nullptr ) - { - iref = new SCH_IREF(); - gLabel->SetIref( iref ); - - iref->SetParentLabel( gLabel ); - iref->SetFlags( IS_NEW ); - iref->SetScreen( screen ); - - if( gLabel->GetIrefSavedPosition() != wxDefaultPosition ) - iref->SetPosition( gLabel->GetIrefSavedPosition() ); - else - iref->PlaceAtDefaultPosition(); - - iref->CopyParentStyle(); - } - else - { - iref = gLabel->GetIref(); - - wxCHECK2( iref, continue ); - } - - iref->GetRefTable().clear(); - iref->GetRefTable().insert( iref->GetRefTable().end(), - pagesNumbers.begin(), - pagesNumbers.end() ); + for( const wxString& pageNo : pageNumbers ) + pageList.insert( pageNo ); } } } - /* Fill intersheets references for each global label */ - for( SCH_GLOBALLABEL* item : m_labelTable ) - { - for( SCH_GLOBALLABEL* iter : m_labelTable ) - { - if( iter->GetText().IsSameAs( item->GetText() ) && ( iter != item ) ) - { - iter->GetIref()->GetRefTable().insert( iter->GetIref()->GetRefTable().end(), - item->GetIref()->GetRefTable().begin(), - item->GetIref()->GetRefTable().end() ); - } - } - } + bool show = Schematic().Settings().m_IntersheetRefsShow; /* Refresh all global labels */ - for( SCH_GLOBALLABEL* item : m_labelTable ) + for( EDA_ITEM* item : GetScreen()->Items() ) { - wxString text, tmp; - - iref = item->GetIref(); - - wxCHECK2( iref, continue ); - - std::sort( iref->GetRefTable().begin(), iref->GetRefTable().end() ); - iref->GetRefTable().erase( std::unique( iref->GetRefTable().begin(), - iref->GetRefTable().end() ), - iref->GetRefTable().end() ); - - text.Printf( "%s", settings.m_IntersheetsRefPrefix ); - - if( ( settings.m_IntersheetsRefFormatShort ) && ( iref->GetRefTable().size() > 2 ) ) + if( item->Type() == SCH_GLOBAL_LABEL_T ) { - tmp.Printf( "%s..%s", iref->GetRefTable().front(), iref->GetRefTable().back() ); - text.Append( tmp ); + SCH_GLOBALLABEL* global = static_cast( item ); + + global->GetIntersheetRefs()->SetVisible( show ); + + if( show ) + GetCanvas()->GetView()->Update( global ); } - else - { - for( wxString ref : iref->GetRefTable() ) - { - tmp.Printf( "%s,", ref ); - text.Append( tmp ); - } - - if( text.Last() == ',' ) - text.RemoveLast(); - } - - text.Append( settings.m_IntersheetsRefSuffix ); - - iref->SetText( text ); - - SCH_SCREEN* screen = iref->GetScreen(); - - if( !screen->CheckIfOnDrawList( iref ) ) - AddToScreen( iref, screen ); - - iref->ClearFlags( IS_NEW ); - - screen->SetModify(); - Refresh( iref ); - - iref->ClearEditFlags(); - GetCanvas()->Refresh(); } + GetCanvas()->Refresh(); return 0; } -void SCH_EDIT_FRAME::RemoveAllIntersheetsRefs() -{ - SCH_SHEET_LIST sheets = Schematic().GetSheets(); - std::vector irefList; - SCH_GLOBALLABEL* gLabel; +void SCH_EDIT_FRAME::ShowAllIntersheetRefs( bool aShow ) +{ SCH_SCREENS screens( Schematic().Root() ); for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) { - for( SCH_ITEM* item : screen->Items() ) { if( item->Type() == SCH_GLOBAL_LABEL_T ) { - gLabel = (SCH_GLOBALLABEL*)( item ); - SCH_IREF* iref = gLabel->GetIref(); + SCH_GLOBALLABEL* gLabel = (SCH_GLOBALLABEL*)( item ); + SCH_FIELD* intersheetRef = gLabel->GetIntersheetRefs(); - if( iref ) - { - gLabel->SetIref( nullptr ); - gLabel->SetIrefSavedPosition( wxDefaultPosition ); - irefList.push_back( iref ); - } + intersheetRef->SetVisible( aShow ); + + if( aShow ) + AddToScreen( intersheetRef, screen ); + else + RemoveFromScreen( intersheetRef, screen ); } } } - - for( SCH_IREF* iref : irefList ) - RemoveFromScreen( iref, iref->GetScreen() ); } + void SCH_EDIT_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged ) { SCHEMATIC_SETTINGS& settings = Schematic().Settings(); SCH_BASE_FRAME::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged ); - if( settings.m_IntersheetsRefShow == false ) - RemoveAllIntersheetsRefs(); - else - RecomputeIntersheetsRefs(); + ShowAllIntersheetRefs( settings.m_IntersheetRefsShow ); GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL ); GetCanvas()->Refresh(); diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index f218febd92..030cd5dc3a 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -133,10 +133,6 @@ private: DIALOG_SCH_FIND* m_findReplaceDialog; - static PINSHEETLABEL_SHAPE m_lastSheetPinType; ///< Last sheet pin type. - - std::vector m_labelTable; - protected: /** * Save the schematic files that have been modified and not yet saved. @@ -923,7 +919,7 @@ public: int RecomputeIntersheetsRefs(); - void RemoveAllIntersheetsRefs(); + void ShowAllIntersheetRefs( bool aShow ); DECLARE_EVENT_TABLE() }; diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 76228fdcb5..360bdcd312 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -22,7 +22,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -/* Fields are texts attached to a component, having a special meaning +/* + * Fields are texts attached to a component, having a special meaning * Fields 0 and 1 are very important: reference and value * Field 2 is used as default footprint name. * Field 3 is reserved (not currently used @@ -30,6 +31,7 @@ * They can be renamed and can appear in reports */ +#include #include #include #include @@ -45,7 +47,9 @@ #include #include #include - +#include +#include +#include SCH_FIELD::SCH_FIELD( const wxPoint& aPos, int aFieldId, SCH_ITEM* aParent, const wxString& aName ) : @@ -93,7 +97,6 @@ void SCH_FIELD::SetId( int aId ) default: SetLayer( LAYER_FIELDS ); break; } } - } @@ -131,6 +134,13 @@ wxString SCH_FIELD::GetShownText( int aDepth ) const return sheet->ResolveTextVar( token, aDepth + 1 ); }; + std::function globalLabelResolver = + [&]( wxString* token ) -> bool + { + SCH_GLOBALLABEL* globalLabel = static_cast( m_parent ); + return globalLabel->ResolveTextVar( token, aDepth + 1 ); + }; + PROJECT* project = nullptr; bool processTextVars = false; wxString text = EDA_TEXT::GetShownText( &processTextVars ); @@ -146,6 +156,8 @@ wxString SCH_FIELD::GetShownText( int aDepth ) const text = ExpandTextVars( text, &symbolResolver, project ); else if( m_parent && m_parent->Type() == SCH_SHEET_T ) text = ExpandTextVars( text, &sheetResolver, project ); + else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T ) + text = ExpandTextVars( text, &globalLabelResolver, project ); else text = ExpandTextVars( text, nullptr, project ); } @@ -371,6 +383,10 @@ bool SCH_FIELD::IsReplaceable() const if( m_id == SHEETFILENAME ) return false; } + else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T ) + { + return false; + } return true; } @@ -436,6 +452,54 @@ wxString SCH_FIELD::GetSelectMenuText( EDA_UNITS aUnits ) const } +void SCH_FIELD::DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) +{ + static wxString back = "HYPERTEXT_BACK"; + wxMenu menu; + SCH_TEXT* label = dynamic_cast( m_parent ); + + if( label && Schematic() ) + { + auto it = Schematic()->GetPageRefsMap().find( label->GetText() ); + + if( it != Schematic()->GetPageRefsMap().end() ) + { + std::map sheetNames; + std::vector pageListCopy; + + pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() ); + std::sort( pageListCopy.begin(), pageListCopy.end() ); + + for( const SCH_SHEET_PATH& sheet : Schematic()->GetSheets() ) + sheetNames[ sheet.GetPageNumber() ] = sheet.Last()->GetName(); + + for( const wxString& pageNo : pageListCopy ) + { + wxString pageName = pageNo == "/" ? _( "Root" ) : sheetNames[ pageNo ]; + + menu.Append( -1, wxString::Format( _( "Go to Page %s (%s)" ), + pageNo, + pageName ) ); + } + + menu.AppendSeparator(); + menu.Append( -1, _( "Back" ) ); + + int sel = aFrame->GetPopupMenuSelectionFromUser( menu ); + void* param = nullptr; + + if( sel >= 1 && sel <= (int) pageListCopy.size() ) + param = (void*) &pageListCopy[ sel - 1 ]; + else if( sel == (int) pageListCopy.size() ) + param = (void*) &back; + + if( param ) + aFrame->GetToolManager()->RunAction( EE_ACTIONS::hypertextCommand, true, param ); + } + } +} + + wxString SCH_FIELD::GetName( bool aUseDefaultName ) const { if( !m_name.IsEmpty() ) @@ -446,6 +510,8 @@ wxString SCH_FIELD::GetName( bool aUseDefaultName ) const return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id ); else if( m_parent && m_parent->Type() == SCH_SHEET_T ) return SCH_SHEET::GetDefaultFieldName( m_id ); + else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T ) + return _( "Intersheet References" ); } return wxEmptyString; @@ -472,6 +538,10 @@ wxString SCH_FIELD::GetCanonicalName() const case SHEETFILENAME: return wxT( "Sheetfile" ); } } + else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T ) + { + return wxT( "Intersheet References" ); + } return m_name; } diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h index d82437e925..4cf16953f4 100644 --- a/eeschema/sch_field.h +++ b/eeschema/sch_field.h @@ -31,7 +31,6 @@ #include #include - class SCH_EDIT_FRAME; class SCH_COMPONENT; class LIB_FIELD; @@ -93,6 +92,13 @@ public: return false; } + bool IsHypertext() const override + { + return m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T; + } + + void DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) override; + /** * Function GetName * returns the field name. diff --git a/eeschema/sch_iref.cpp b/eeschema/sch_iref.cpp deleted file mode 100644 index 3b389de25e..0000000000 --- a/eeschema/sch_iref.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * Copyright (C) 2019-2020 Franck Jullien, franck.jullien at gmail.com - * 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 - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include -#include -#include -#include -#include - -SCH_IREF::SCH_IREF( const wxPoint& pos, const wxString& text, SCH_GLOBALLABEL* aParent ) : - SCH_TEXT( pos, text, SCH_IREF_T ) -{ - m_layer = LAYER_GLOBLABEL; - m_parentLabel = aParent; - SetMultilineAllowed( false ); - m_screen = nullptr; -} - - -void SCH_IREF::PlaceAtDefaultPosition() -{ - wxPoint offset; - - int labelLen = m_parentLabel->GetBoundingBox().GetSizeMax(); - - switch( m_parentLabel->GetLabelSpinStyle() ) - { - default: - case LABEL_SPIN_STYLE::LEFT: offset.x -= labelLen; break; - case LABEL_SPIN_STYLE::UP: offset.y -= labelLen; break; - case LABEL_SPIN_STYLE::RIGHT: offset.x += labelLen; break; - case LABEL_SPIN_STYLE::BOTTOM: offset.y += labelLen; break; - } - - SetTextPos( m_parentLabel->GetPosition() + offset ); -} - - -wxPoint SCH_IREF::GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const -{ - return m_parentLabel->GetSchematicTextOffset( aSettings ); -} - - -EDA_ITEM* SCH_IREF::Clone() const -{ - return new SCH_IREF( *this ); -} - - -void SCH_IREF::SetIrefOrientation( LABEL_SPIN_STYLE aSpinStyle ) -{ - wxPoint pt = GetTextPos() - m_parentLabel->GetPosition(); - int offset = std::max( abs( pt.x ), abs( pt.y ) ); - - switch( aSpinStyle ) - { - case LABEL_SPIN_STYLE::RIGHT: - SetTextAngle( TEXT_ANGLE_HORIZ ); - SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); - SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); - pt.y = 0; - pt.x = offset; - break; - - case LABEL_SPIN_STYLE::UP: - SetTextAngle( TEXT_ANGLE_VERT ); - SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); - SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); - pt.y = -offset; - pt.x = 0; - break; - - case LABEL_SPIN_STYLE::LEFT: - SetTextAngle( TEXT_ANGLE_HORIZ ); - SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); - SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); - pt.y = 0; - pt.x = -offset; - break; - - case LABEL_SPIN_STYLE::BOTTOM: - SetTextAngle( TEXT_ANGLE_VERT ); - SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); - SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); - pt.y = offset; - pt.x = 0; - break; - } - - SetPosition( m_parentLabel->GetPosition() + pt ); -} - - -void SCH_IREF::CopyParentStyle() -{ - SetTextSize( m_parentLabel->GetTextSize() ); - SetItalic( m_parentLabel->IsItalic() ); - SetBold( m_parentLabel->IsBold() ); - SetTextThickness( m_parentLabel->GetTextThickness() ); - SetIrefOrientation( m_parentLabel->GetLabelSpinStyle() ); -} - - -void SCH_IREF::BuildHypertextMenu( wxMenu* aMenu ) -{ - std::map sheetNames; - - for( const SCH_SHEET_PATH& sheet : Schematic()->GetSheets() ) - sheetNames[ sheet.GetPageNumber() ] = sheet.Last()->GetName(); - - int id = ID_HYPERTEXT_BACK; - - for( wxString& i : m_refTable ) - { - aMenu->Append( id, wxString::Format( _( "Go to Page %s (%s)" ), - i, - i == "/" ? _( "Root" ) : sheetNames[ i ] ) ); - id++; - } - - aMenu->AppendSeparator(); - aMenu->Append( ID_HYPERTEXT_BACK, _( "Back" ) ); -} diff --git a/eeschema/sch_iref.h b/eeschema/sch_iref.h deleted file mode 100644 index c2add6162a..0000000000 --- a/eeschema/sch_iref.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * This program source code file is part of KiCad, a free EDA CAD application. - * - * 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 - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you may find one here: - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * or you may search the http://www.gnu.org website for the version 2 license, - * or you may write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/** - * @file sch_iref.h - * @brief Definitions of the SCH_IREF class and derivatives for Eeschema. - */ - -#ifndef CLASS_IREF_H -#define CLASS_IREF_H - - -#include - -class SCH_GLOBALLABEL; - -class SCH_IREF : public SCH_TEXT -{ -public: - SCH_IREF( const wxPoint& pos = wxPoint( 0, 0 ), const wxString& text = wxEmptyString, - SCH_GLOBALLABEL* aParent = nullptr ); - - ~SCH_IREF() { } - - static inline bool ClassOf( const EDA_ITEM* aItem ) - { - return aItem && SCH_IREF_T == aItem->Type(); - } - - wxString GetClass() const override - { - return wxT( "SCH_IREF" ); - } - - EDA_ITEM* Clone() const override; - - std::vector& GetRefTable() { return m_refTable; } - - bool IsDangling() const override { return false; } - - void CopyParentStyle(); - void PlaceAtDefaultPosition(); - - wxPoint GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const override; - - SCH_GLOBALLABEL* GetParentLabel() { return m_parentLabel; } - - void SetParentLabel( SCH_GLOBALLABEL* parent ) { m_parentLabel = parent; } - - SCH_SCREEN* GetScreen() { return m_screen; } - - void SetScreen( SCH_SCREEN* screen ) { m_screen = screen; } - - void BuildHypertextMenu( wxMenu* aMenu ); - -private: - void SetIrefOrientation( LABEL_SPIN_STYLE aSpinStyle ); - - // We create a different set parent function for this class, so we hide - // the inherited one. - using EDA_ITEM::SetParent; - - std::vector m_refTable; - SCH_GLOBALLABEL* m_parentLabel; - SCH_SCREEN* m_screen; -}; - -#endif diff --git a/eeschema/sch_item.cpp b/eeschema/sch_item.cpp index 43f46cf215..dac7d4a6e5 100644 --- a/eeschema/sch_item.cpp +++ b/eeschema/sch_item.cpp @@ -84,27 +84,11 @@ SCH_ITEM* SCH_ITEM::Duplicate( bool doClone ) const newItem->ClearFlags( SELECTED | BRIGHTENED ); - if( newItem->Type() == SCH_COMPONENT_T ) - { - SCH_COMPONENT* symbol = (SCH_COMPONENT*) newItem; - - for( SCH_PIN* pin : symbol->GetPins() ) - pin->ClearFlags( SELECTED | BRIGHTENED ); - - for( SCH_FIELD& field : symbol->GetFields() ) - field.ClearFlags( SELECTED | BRIGHTENED ); - } - - if( newItem->Type() == SCH_SHEET_T ) - { - SCH_SHEET* sheet = (SCH_SHEET*) newItem; - - for( SCH_FIELD& field : sheet->GetFields() ) - field.ClearFlags( SELECTED | BRIGHTENED ); - - for( SCH_SHEET_PIN* pin : sheet->GetPins() ) - pin->ClearFlags( SELECTED | BRIGHTENED ); - } + newItem->RunOnChildren( + []( SCH_ITEM* aChild ) + { + aChild->ClearFlags( SELECTED | BRIGHTENED ); + } ); return newItem; } diff --git a/eeschema/sch_item.h b/eeschema/sch_item.h index fcb36bc82b..7280e263d4 100644 --- a/eeschema/sch_item.h +++ b/eeschema/sch_item.h @@ -208,8 +208,7 @@ protected: /// Stores connectivity information, per sheet std::unordered_map m_connection_map; - /// True if connectivity info might be out of date - bool m_connectivity_dirty; + bool m_connectivity_dirty; public: SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType ); @@ -273,6 +272,13 @@ public: */ virtual void SetLocked( bool aLocked ) {} + /** + * Allows items to support hypertext actions when hovered/clicked. + */ + virtual bool IsHypertext() const { return false; } + + virtual void DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) { } + /** * Return the layer this item is on. */ @@ -466,6 +472,8 @@ public: virtual void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) { } + virtual void RunOnChildren( const std::function& aFunction ) { } + /** * Check if this schematic item has line stoke properties. * diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index 1d665709e8..80d6f25749 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -221,7 +220,6 @@ bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer ) HANDLE_ITEM( SCH_BUS_BUS_ENTRY_T, SCH_BUS_ENTRY_BASE ); HANDLE_ITEM( SCH_BITMAP_T, SCH_BITMAP ); HANDLE_ITEM( SCH_MARKER_T, SCH_MARKER ); - HANDLE_ITEM( SCH_IREF_T, SCH_TEXT ); default: return false; } @@ -1160,7 +1158,7 @@ void SCH_PAINTER::draw( LIB_BEZIER *aCurve, int aLayer ) std::deque pts_xformed; poly.GetPoly( pts ); - for( const auto &p : pts ) + for( const wxPoint &p : pts ) pts_xformed.push_back( mapCoords( p ) ); m_gal->DrawPolygon( pts_xformed ); @@ -1273,12 +1271,16 @@ void SCH_PAINTER::draw( SCH_LINE *aLine, int aLayer ) } if( aLine->IsStartDangling() ) + { drawDanglingSymbol( aLine->GetStartPoint(), getLineWidth( aLine, drawingShadows ), drawingShadows ); + } if( aLine->IsEndDangling() ) + { drawDanglingSymbol( aLine->GetEndPoint(), getLineWidth( aLine, drawingShadows ), drawingShadows ); + } } @@ -1294,19 +1296,11 @@ void SCH_PAINTER::draw( SCH_TEXT *aText, int aLayer ) case SCH_SHEET_PIN_T: aLayer = LAYER_SHEETLABEL; break; case SCH_HIER_LABEL_T: aLayer = LAYER_HIERLABEL; break; case SCH_GLOBAL_LABEL_T: aLayer = LAYER_GLOBLABEL; break; - case SCH_IREF_T: aLayer = LAYER_GLOBLABEL; break; case SCH_LABEL_T: aLayer = LAYER_LOCLABEL; break; default: aLayer = LAYER_NOTES; break; } COLOR4D color = getRenderColor( aText, aLayer, drawingShadows ); - bool underline = false; - - if( aText->Type() == SCH_IREF_T && ( aText->GetFlags() & IS_ROLLOVER ) > 0 ) - { - color = BLUE; - underline = true; - } if( m_schematic ) { @@ -1329,7 +1323,7 @@ void SCH_PAINTER::draw( SCH_TEXT *aText, int aLayer ) m_gal->SetLineWidth( getTextThickness( aText, drawingShadows ) ); m_gal->SetStrokeColor( color ); m_gal->SetTextAttributes( aText ); - m_gal->SetFontUnderlined( underline ); + m_gal->SetFontUnderlined( false ); VECTOR2D text_offset = aText->GetTextPos() + aText->GetSchematicTextOffset( &m_schSettings ); wxString shownText( aText->GetShownText() ); @@ -1500,6 +1494,14 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer ) return; } + bool underline = false; + + if( aField->IsHypertext() && ( aField->GetFlags() & IS_ROLLOVER ) > 0 ) + { + color = PUREBLUE; + underline = true; + } + // Calculate the text orientation according to the parent orientation. int orient = (int) aField->GetTextAngle(); @@ -1549,7 +1551,7 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer ) m_gal->SetGlyphSize( VECTOR2D( aField->GetTextSize() ) ); m_gal->SetFontBold( aField->IsBold() ); m_gal->SetFontItalic( aField->IsItalic() ); - m_gal->SetFontUnderlined( false ); + m_gal->SetFontUnderlined( underline ); m_gal->SetTextMirrored( aField->IsMirrored() ); m_gal->SetLineWidth( getTextThickness( aField, drawingShadows ) ); @@ -1601,6 +1603,8 @@ void SCH_PAINTER::draw( SCH_GLOBALLABEL *aLabel, int aLayer ) m_gal->DrawPolyline( pts2 ); draw( static_cast( aLabel ), aLayer ); + + draw( aLabel->GetIntersheetRefs(), aLayer ); } diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp index c1ecef09ca..35b39714ff 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp @@ -2231,7 +2231,6 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol() break; case T_property: - { // The field parent symbol must be set and it's orientation must be set before // the field positions are set. field = parseSchField( symbol.get() ); @@ -2282,7 +2281,6 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol() delete field; break; - } case T_pin: { @@ -2703,8 +2701,7 @@ SCH_TEXT* SCH_SEXPR_PARSER::parseSchText() case T_global_label: text = std::make_unique(); break; case T_hierarchical_label: text = std::make_unique(); break; default: - wxCHECK_MSG( false, nullptr, - wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as text." ) ); + wxCHECK_MSG( false, nullptr, "Cannot parse " + GetTokenString( CurTok() ) + " as text." ); } NeedSYMBOL(); @@ -2721,7 +2718,6 @@ SCH_TEXT* SCH_SEXPR_PARSER::parseSchText() switch( token ) { case T_at: - { text->SetPosition( parseXY() ); switch( static_cast( parseDouble( "text angle" ) ) ) @@ -2738,10 +2734,8 @@ SCH_TEXT* SCH_SEXPR_PARSER::parseSchText() NeedRIGHT(); break; - } case T_shape: - { if( text->Type() == SCH_TEXT_T || text->Type() == SCH_LABEL_T ) Unexpected( T_shape ); @@ -2760,22 +2754,36 @@ SCH_TEXT* SCH_SEXPR_PARSER::parseSchText() NeedRIGHT(); break; - } case T_effects: parseEDA_TEXT( static_cast( text.get() ) ); break; - case T_iref: - { + case T_iref: // legacy format; current is a T_property (aka SCH_FIELD) if( text->Type() == SCH_GLOBAL_LABEL_T ) { SCH_GLOBALLABEL* label = static_cast( text.get() ); - label->SetIrefSavedPosition( parseXY() ); + SCH_FIELD* field = label->GetIntersheetRefs(); + + field->SetTextPos( parseXY() ); NeedRIGHT(); + + field->SetVisible( true ); + } + break; + + case T_property: + if( text->Type() == SCH_GLOBAL_LABEL_T ) + { + SCH_GLOBALLABEL* label = static_cast( text.get() ); + SCH_FIELD* field = parseSchField( label ); + + field->SetLayer( LAYER_GLOBLABEL ); + label->SetIntersheetRefs( *field ); + + delete field; } break; - } default: Expecting( "at, shape, iref or effects" ); diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp index cddfdba5b3..0cf95e6227 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -1233,18 +1232,6 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel ) if( ( aText->Type() == SCH_GLOBAL_LABEL_T ) || ( aText->Type() == SCH_HIER_LABEL_T ) ) m_out->Print( 0, " (shape %s)", getSheetPinShapeToken( aText->GetShape() ) ); - if( ( aText->Type() == SCH_GLOBAL_LABEL_T ) ) - { - SCH_GLOBALLABEL* label = static_cast( aText ); - - if( label->GetIref() != nullptr ) - { - SCH_IREF* iref = label->GetIref(); - m_out->Print( 0, " (iref %s %s)", FormatInternalUnits( iref->GetPosition().x ).c_str(), - FormatInternalUnits( iref->GetPosition().y ).c_str() ); - } - } - if( aText->GetText().Length() < 50 ) { m_out->Print( 0, " (at %s %s %s)", @@ -1261,6 +1248,12 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel ) FormatAngle( aText->GetTextAngle() ).c_str() ); } + if( ( aText->Type() == SCH_GLOBAL_LABEL_T ) ) + { + SCH_GLOBALLABEL* label = static_cast( aText ); + saveField( label->GetIntersheetRefs(), aNestLevel + 1 ); + } + m_out->Print( 0, "\n" ); aText->Format( m_out, aNestLevel, 0 ); m_out->Print( aNestLevel, ")\n" ); // Closes text token. @@ -1584,7 +1577,7 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo aSymbol->GetFields( fields ); - for( auto field : fields ) + for( LIB_FIELD& field : fields ) saveField( &field, aFormatter, aNestLevel + 1 ); lastFieldId = fields.back().GetId() + 1; @@ -1630,7 +1623,7 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo aSymbol->GetFields( fields ); - for( auto field : fields ) + for( LIB_FIELD& field : fields ) saveField( &field, aFormatter, aNestLevel + 1 ); lastFieldId = fields.back().GetId() + 1; diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index f8fbfcc70d..1c46d8d07b 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -949,9 +949,11 @@ void SCH_SCREEN::EnsureAlternateReferencesExist() void SCH_SCREEN::GetHierarchicalItems( std::vector* aItems ) { + static KICAD_T hierarchicalTypes[] = { SCH_COMPONENT_T, SCH_SHEET_T, SCH_GLOBAL_LABEL_T, EOT }; + for( SCH_ITEM* item : Items() ) { - if( ( item->Type() == SCH_SHEET_T ) || ( item->Type() == SCH_COMPONENT_T ) ) + if( item->IsType( hierarchicalTypes ) ) aItems->push_back( item ); } } diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index 18d3020024..497c0d1a86 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -900,6 +900,16 @@ SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData, const KICA } +void SCH_SHEET::RunOnChildren( const std::function& aFunction ) +{ + for( SCH_FIELD& field : m_fields ) + aFunction( &field ); + + for( SCH_SHEET_PIN* pin : m_pins ) + aFunction( pin ); +} + + wxString SCH_SHEET::GetSelectMenuText( EDA_UNITS aUnits ) const { return wxString::Format( _( "Hierarchical Sheet %s" ), diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h index b3bc09a3c3..635962c1cc 100644 --- a/eeschema/sch_sheet.h +++ b/eeschema/sch_sheet.h @@ -556,6 +556,8 @@ public: SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override; + void RunOnChildren( const std::function& aFunction ) override; + wxString GetSelectMenuText( EDA_UNITS aUnits ) const override; BITMAP_DEF GetMenuImage() const override; diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index d091505ccd..50631b6372 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -526,56 +526,22 @@ SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut ) return aItem; } - else if( aItem->Type() == SCH_COMPONENT_T ) + + SCH_ITEM* childMatch = nullptr; + + aItem->RunOnChildren( + [&]( SCH_ITEM* aChild ) + { + if( aChild->m_Uuid == aID ) + childMatch = aChild; + } ); + + if( childMatch ) { - SCH_COMPONENT* comp = static_cast( aItem ); + if( aPathOut ) + *aPathOut = sheet; - for( SCH_FIELD& field : comp->GetFields() ) - { - if( field.m_Uuid == aID ) - { - if( aPathOut ) - *aPathOut = sheet; - - return &field; - } - } - - for( SCH_PIN* pin : comp->GetPins() ) - { - if( pin->m_Uuid == aID ) - { - if( aPathOut ) - *aPathOut = sheet; - - return pin; - } - } - } - else if( aItem->Type() == SCH_SHEET_T ) - { - SCH_SHEET* sch_sheet = static_cast( aItem ); - - for( SCH_FIELD& field : sch_sheet->GetFields() ) - { - if( field.m_Uuid == aID ) - { - if( aPathOut ) - *aPathOut = sheet; - return &field; - } - } - - for( SCH_SHEET_PIN* pin : sch_sheet->GetPins() ) - { - if( pin->m_Uuid == aID ) - { - if( aPathOut ) - *aPathOut = sheet; - - return pin; - } - } + return childMatch; } } } @@ -595,26 +561,11 @@ void SCH_SHEET_LIST::FillItemMap( std::map& aMap ) { aMap[ aItem->m_Uuid ] = aItem; - if( aItem->Type() == SCH_COMPONENT_T ) - { - SCH_COMPONENT* comp = static_cast( aItem ); - - for( SCH_FIELD& field : comp->GetFields() ) - aMap[ field.m_Uuid ] = &field; - - for( SCH_PIN* pin : comp->GetPins() ) - aMap[ pin->m_Uuid ] = pin; - } - else if( aItem->Type() == SCH_SHEET_T ) - { - SCH_SHEET* sch_sheet = static_cast( aItem ); - - for( SCH_FIELD& field : sch_sheet->GetFields() ) - aMap[ field.m_Uuid ] = &field; - - for( SCH_SHEET_PIN* pin : sch_sheet->GetPins() ) - aMap[ pin->m_Uuid ] = pin; - } + aItem->RunOnChildren( + [&]( SCH_ITEM* aChild ) + { + aMap[ aChild->m_Uuid ] = aChild; + } ); } } } diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp index 1754e5c36e..8b1e88554c 100644 --- a/eeschema/sch_text.cpp +++ b/eeschema/sch_text.cpp @@ -44,7 +44,6 @@ #include #include #include -#include #include #include @@ -307,10 +306,16 @@ bool SCH_TEXT::operator<( const SCH_ITEM& aItem ) const int SCH_TEXT::GetTextOffset( RENDER_SETTINGS* aSettings ) const { - SCH_RENDER_SETTINGS* renderSettings = static_cast( aSettings ); + double ratio; - if( renderSettings ) - return KiROUND( renderSettings->m_TextOffsetRatio * GetTextSize().y ); + if( aSettings ) + ratio = static_cast( aSettings )->m_TextOffsetRatio; + else if( Schematic() ) + ratio = Schematic()->Settings().m_TextOffsetRatio; + else + ratio = DEFAULT_TEXT_OFFSET_RATIO; // For previews (such as in Preferences), etc. + + return KiROUND( ratio * GetTextSize().y ); return 0; } @@ -767,10 +772,7 @@ bool SCH_LABEL::IsType( const KICAD_T aScanTypes[] ) const const EDA_RECT SCH_LABEL::GetBoundingBox() const { EDA_RECT rect = GetTextBox(); - - // In practice this is controlled by the current TextOffsetRatio, but the default is - // close enough for hit-testing, etc. - int margin = Mils2iu( TXT_MARGIN ); + int margin = GetTextOffset(); rect.Inflate( margin ); @@ -805,15 +807,31 @@ BITMAP_DEF SCH_LABEL::GetMenuImage() const } -SCH_GLOBALLABEL::SCH_GLOBALLABEL( const wxPoint& pos, const wxString& text ) - : SCH_TEXT( pos, text, SCH_GLOBAL_LABEL_T ) +SCH_GLOBALLABEL::SCH_GLOBALLABEL( const wxPoint& pos, const wxString& text ) : + SCH_TEXT( pos, text, SCH_GLOBAL_LABEL_T ), + m_intersheetRefsField( { 0, 0 }, 0, this ) { m_layer = LAYER_GLOBLABEL; m_shape = PINSHEETLABEL_SHAPE::PS_BIDI; m_isDangling = true; - m_iref = nullptr; SetMultilineAllowed( false ); - m_savedIrefPos = wxDefaultPosition; + + m_intersheetRefsField.SetText( wxT( "${INTERSHEET_REFS}" ) ); + m_intersheetRefsField.SetLayer( LAYER_GLOBLABEL ); + m_fieldsAutoplaced = FIELDS_AUTOPLACED_AUTO; +} + + +SCH_GLOBALLABEL::SCH_GLOBALLABEL( const SCH_GLOBALLABEL& aGlobalLabel ) : + SCH_TEXT( aGlobalLabel ), + m_intersheetRefsField( { 0, 0 }, 0, this ) +{ + m_intersheetRefsField = aGlobalLabel.m_intersheetRefsField; + + // Re-parent the fields, which before this had aGlobalLabel as parent + m_intersheetRefsField.SetParent( this ); + + m_fieldsAutoplaced = aGlobalLabel.m_fieldsAutoplaced; } @@ -823,6 +841,52 @@ EDA_ITEM* SCH_GLOBALLABEL::Clone() const } +void SCH_GLOBALLABEL::SwapData( SCH_ITEM* aItem ) +{ + SCH_TEXT::SwapData( aItem ); + + SCH_GLOBALLABEL* globalLabel = static_cast( aItem ); + + // Swap field data wholesale... + std::swap( m_intersheetRefsField, globalLabel->m_intersheetRefsField ); + + // ...and then reset parent pointers. + globalLabel->m_intersheetRefsField.SetParent( globalLabel ); + m_intersheetRefsField.SetParent( this ); +} + + +SEARCH_RESULT SCH_GLOBALLABEL::Visit( INSPECTOR aInspector, void* testData, + const KICAD_T aFilterTypes[] ) +{ + KICAD_T stype; + + for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p ) + { + // If caller wants to inspect my type + if( stype == SCH_LOCATE_ANY_T || stype == Type() ) + { + if( SEARCH_RESULT::QUIT == aInspector( this, NULL ) ) + return SEARCH_RESULT::QUIT; + } + + if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_T ) + { + if( SEARCH_RESULT::QUIT == aInspector( GetIntersheetRefs(), this ) ) + return SEARCH_RESULT::QUIT; + } + } + + return SEARCH_RESULT::CONTINUE; +} + + +void SCH_GLOBALLABEL::RunOnChildren( const std::function& aFunction ) +{ + aFunction( &m_intersheetRefsField ); +} + + wxPoint SCH_GLOBALLABEL::GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const { wxPoint text_offset; @@ -894,6 +958,106 @@ void SCH_GLOBALLABEL::SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle ) } +void SCH_GLOBALLABEL::UpdateIntersheetRefProps() +{ + m_intersheetRefsField.SetTextSize( GetTextSize() ); + m_intersheetRefsField.SetItalic( IsItalic() ); + m_intersheetRefsField.SetBold( IsBold() ); + m_intersheetRefsField.SetTextThickness( GetTextThickness() ); + + if( m_fieldsAutoplaced == FIELDS_AUTOPLACED_AUTO ) + AutoplaceFields( nullptr, false ); +} + + +void SCH_GLOBALLABEL::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) +{ + int margin = GetTextOffset(); + int labelLen = GetBoundingBox().GetSizeMax(); + int penOffset = GetPenWidth() / 2; + + // Set both axes to penOffset; we're going to overwrite the text axis below + wxPoint offset( -penOffset, -penOffset ); + + switch( GetLabelSpinStyle() ) + { + default: + case LABEL_SPIN_STYLE::LEFT: + m_intersheetRefsField.SetTextAngle( TEXT_ANGLE_HORIZ ); + m_intersheetRefsField.SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); + m_intersheetRefsField.SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); + offset.x = - ( labelLen + margin / 2 ); + break; + + case LABEL_SPIN_STYLE::UP: + m_intersheetRefsField.SetTextAngle( TEXT_ANGLE_VERT ); + m_intersheetRefsField.SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); + m_intersheetRefsField.SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); + offset.y = - ( labelLen + margin / 2 ); + break; + + case LABEL_SPIN_STYLE::RIGHT: + m_intersheetRefsField.SetTextAngle( TEXT_ANGLE_HORIZ ); + m_intersheetRefsField.SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); + m_intersheetRefsField.SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); + offset.x = labelLen + margin /2 ; + break; + + case LABEL_SPIN_STYLE::BOTTOM: + m_intersheetRefsField.SetTextAngle( TEXT_ANGLE_VERT ); + m_intersheetRefsField.SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); + m_intersheetRefsField.SetVertJustify( GR_TEXT_VJUSTIFY_CENTER ); + offset.y = labelLen + margin / 2; + break; + } + + m_intersheetRefsField.SetTextPos( GetPosition() + offset ); + + m_fieldsAutoplaced = FIELDS_AUTOPLACED_AUTO; +} + + +bool SCH_GLOBALLABEL::ResolveTextVar( wxString* token, int aDepth ) const +{ + if( token->IsSameAs( wxT( "INTERSHEET_REFS" ) ) && Schematic() ) + { + auto it = Schematic()->GetPageRefsMap().find( GetText() ); + + if( it != Schematic()->GetPageRefsMap().end() ) + { + SCHEMATIC_SETTINGS& settings = Schematic()->Settings(); + std::vector pageListCopy; + + pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() ); + std::sort( pageListCopy.begin(), pageListCopy.end() ); + + token->Printf( "%s", settings.m_IntersheetRefsPrefix ); + + if( ( settings.m_IntersheetRefsFormatShort ) && ( pageListCopy.size() > 2 ) ) + { + token->Append( wxString::Format( wxT( "%s..%s" ), + pageListCopy.front(), + pageListCopy.back() ) ); + } + else + { + for( const wxString& pageNo : pageListCopy ) + token->Append( wxString::Format( wxT( "%s," ), pageNo ) ); + + if( token->Last() == ',' ) + token->RemoveLast(); + } + + token->Append( settings.m_IntersheetRefsSuffix ); + } + + return true; + } + + return false; +} + + void SCH_GLOBALLABEL::Print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset ) { static std::vector Poly; @@ -987,11 +1151,7 @@ const EDA_RECT SCH_GLOBALLABEL::GetBoundingBox() const int x = GetTextPos().x; int y = GetTextPos().y; int penWidth = GetEffectiveTextPenWidth(); - - // In practice this is controlled by the current TextOffsetRatio, but the default is - // close enough for hit-testing, etc. - int margin = Mils2iu( TXT_MARGIN ); - + int margin = GetTextOffset(); int height = ( (GetTextHeight() * 15) / 10 ) + penWidth + 2 * margin; int length = LenSize( GetShownText(), penWidth ) + height // add height for triangular shapes @@ -1153,10 +1313,7 @@ void SCH_HIERLABEL::CreateGraphicShape( RENDER_SETTINGS* aRenderSettings, const EDA_RECT SCH_HIERLABEL::GetBoundingBox() const { int penWidth = GetEffectiveTextPenWidth(); - - // In practice this is controlled by the current TextOffsetRatio, but the default is - // close enough for hit-testing, etc. - int margin = Mils2iu( TXT_MARGIN ); + int margin = GetTextOffset(); int x = GetTextPos().x; int y = GetTextPos().y; diff --git a/eeschema/sch_text.h b/eeschema/sch_text.h index 45a76a8c33..5a618fad32 100644 --- a/eeschema/sch_text.h +++ b/eeschema/sch_text.h @@ -28,12 +28,12 @@ #include #include +#include #include // for CONNECTION_TYPE class NETLIST_OBJECT_LIST; class HTML_MESSAGE_BOX; -class SCH_IREF; /* * Spin style for text items of all kinds on schematics @@ -265,7 +265,7 @@ public: bool operator<( const SCH_ITEM& aItem ) const override; - int GetTextOffset( RENDER_SETTINGS* aSettings ) const; + int GetTextOffset( RENDER_SETTINGS* aSettings = nullptr ) const; int GetPenWidth() const override; @@ -377,7 +377,7 @@ class SCH_GLOBALLABEL : public SCH_TEXT public: SCH_GLOBALLABEL( const wxPoint& aPos = wxPoint( 0, 0 ), const wxString& aText = wxEmptyString ); - // Do not create a copy constructor. The one generated by the compiler is adequate. + SCH_GLOBALLABEL( const SCH_GLOBALLABEL& aGlobalLabel ); ~SCH_GLOBALLABEL() { } @@ -393,6 +393,12 @@ public: EDA_ITEM* Clone() const override; + void SwapData( SCH_ITEM* aItem ) override; + + SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override; + + void RunOnChildren( const std::function& aFunction ) override; + void SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle ) override; wxPoint GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const override; @@ -402,6 +408,11 @@ public: void CreateGraphicShape( RENDER_SETTINGS* aRenderSettings, std::vector& aPoints, const wxPoint& aPos ) override; + void UpdateIntersheetRefProps(); + void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override; + + bool ResolveTextVar( wxString* token, int aDepth ) const; + bool IsConnectable() const override { return true; } bool CanConnect( const SCH_ITEM* aItem ) const override @@ -416,25 +427,27 @@ public: void Print( RENDER_SETTINGS* aSettings, const wxPoint& offset ) override; - SCH_IREF* GetIref() { return m_iref; } - void SetIref( SCH_IREF* iref ) { m_iref = iref; } - - wxPoint GetIrefSavedPosition() { return m_savedIrefPos; } - void SetIrefSavedPosition( wxPoint pos ) { m_savedIrefPos = pos; } + SCH_FIELD* GetIntersheetRefs() { return &m_intersheetRefsField; } + void SetIntersheetRefs( const SCH_FIELD& aField ) { m_intersheetRefsField = aField; } bool IsPointClickableAnchor( const wxPoint& aPos ) const override { return m_isDangling && GetPosition() == aPos; } + void Move( const wxPoint& aMoveVector ) override + { + SCH_TEXT::Move( aMoveVector ); + m_intersheetRefsField.Move( aMoveVector ); + } + private: bool doIsConnected( const wxPoint& aPosition ) const override { return EDA_TEXT::GetTextPos() == aPosition; } - SCH_IREF* m_iref; - wxPoint m_savedIrefPos; + SCH_FIELD m_intersheetRefsField; }; diff --git a/eeschema/schematic.h b/eeschema/schematic.h index 5dd1137d4f..5528c4d784 100644 --- a/eeschema/schematic.h +++ b/eeschema/schematic.h @@ -62,6 +62,12 @@ private: /// Holds and calculates connectivity information of this schematic CONNECTION_GRAPH* m_connectionGraph; + /** + * Holds a map of labels to the page numbers that they appear on. Used to update global + * label intersheet references. + */ + std::map> m_labelToPageRefsMap; + public: SCHEMATIC( PROJECT* aPrj ); @@ -157,6 +163,8 @@ public: */ bool ResolveCrossReference( wxString* token, int aDepth ) const; + std::map>& GetPageRefsMap() { return m_labelToPageRefsMap; } + wxString ConvertRefsToKIIDs( const wxString& aSource ) const; wxString ConvertKIIDsToRefs( const wxString& aSource ) const; diff --git a/eeschema/schematic_settings.cpp b/eeschema/schematic_settings.cpp index 3f55cfddf6..a2ddc4bc75 100644 --- a/eeschema/schematic_settings.cpp +++ b/eeschema/schematic_settings.cpp @@ -38,14 +38,14 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin m_DefaultWireThickness( DEFAULT_WIRE_THICKNESS * IU_PER_MILS ), m_DefaultBusThickness( DEFAULT_BUS_THICKNESS * IU_PER_MILS ), m_DefaultTextSize( DEFAULT_TEXT_SIZE * IU_PER_MILS ), - m_TextOffsetRatio( 0.08 ), + m_TextOffsetRatio( DEFAULT_TEXT_OFFSET_RATIO ), m_PinSymbolSize( DEFAULT_TEXT_SIZE * IU_PER_MILS / 2 ), m_JunctionSize( DEFAULT_JUNCTION_DIAM * IU_PER_MILS ), m_JunctionSizeChoice( 3 ), - m_IntersheetsRefShow( false ), - m_IntersheetsRefFormatShort( false ), - m_IntersheetsRefPrefix( DEFAULT_IREF_PREFIX ), - m_IntersheetsRefSuffix( DEFAULT_IREF_SUFFIX ), + m_IntersheetRefsShow( false ), + m_IntersheetRefsFormatShort( false ), + m_IntersheetRefsPrefix( DEFAULT_IREF_PREFIX ), + m_IntersheetRefsSuffix( DEFAULT_IREF_SUFFIX ), m_SpiceAdjustPassiveValues( false ) { EESCHEMA_SETTINGS* appSettings = dynamic_cast( Kiface().KifaceSettings() ); @@ -74,16 +74,16 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin appSettings ? appSettings->m_Drawing.intersheets_ref_suffix : DEFAULT_IREF_SUFFIX; m_params.emplace_back( new PARAM( "drawing.intersheets_ref_show", - &m_IntersheetsRefShow, defaultIntersheetsRefShow ) ); + &m_IntersheetRefsShow, defaultIntersheetsRefShow ) ); m_params.emplace_back( new PARAM( "drawing.intersheets_ref_short", - &m_IntersheetsRefFormatShort, defaultIntersheetsRefFormatShort ) ); + &m_IntersheetRefsFormatShort, defaultIntersheetsRefFormatShort ) ); m_params.emplace_back( new PARAM( "drawing.intersheets_ref_prefix", - &m_IntersheetsRefPrefix, defaultIntersheetsRefPrefix ) ); + &m_IntersheetRefsPrefix, defaultIntersheetsRefPrefix ) ); m_params.emplace_back( new PARAM( "drawing.intersheets_ref_suffix", - &m_IntersheetsRefSuffix, defaultIntersheetsRefSuffix ) ); + &m_IntersheetRefsSuffix, defaultIntersheetsRefSuffix ) ); m_params.emplace_back( new PARAM_SCALED( "drawing.default_line_thickness", &m_DefaultLineWidth, Mils2iu( defaultLineThickness ), diff --git a/eeschema/schematic_settings.h b/eeschema/schematic_settings.h index 9c76865cda..36a864b475 100644 --- a/eeschema/schematic_settings.h +++ b/eeschema/schematic_settings.h @@ -52,10 +52,10 @@ public: // User choice for junction dot size ( e.g. none = 0, smallest = 1, small = 2, etc ) int m_JunctionSizeChoice; - bool m_IntersheetsRefShow; - bool m_IntersheetsRefFormatShort; - wxString m_IntersheetsRefPrefix; - wxString m_IntersheetsRefSuffix; + bool m_IntersheetRefsShow; + bool m_IntersheetRefsFormatShort; + wxString m_IntersheetRefsPrefix; + wxString m_IntersheetRefsSuffix; wxString m_PageLayoutDescrFile; diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index fd56c09da9..612b89ca61 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -39,11 +39,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -360,14 +358,9 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) m_toolMgr->ProcessEvent( *newEvt ); continueSelect = false; } - else if( collector[0]->Type() == SCH_IREF_T ) + else if( collector[0]->IsHypertext() ) { - wxMenu menu; - - static_cast( collector[0] )->BuildHypertextMenu( &menu ); - - intptr_t sel = m_frame->GetPopupMenuSelectionFromUser( menu ); - m_toolMgr->RunAction( EE_ACTIONS::hypertextCommand, true, (void*) sel ); + collector[0]->DoHypertextMenu( m_frame ); continueSelect = false; } } @@ -518,8 +511,8 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) { displayWireCursor = true; } - else if( collector[0]->Type() == SCH_IREF_T && !m_additive && !m_subtractive - && !m_exclusive_or ) + else if( collector[0]->IsHypertext() + && ( !m_additive && !m_subtractive && !m_exclusive_or ) ) { rolloverItem = collector[0]->m_Uuid; } @@ -538,7 +531,11 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) { item->ClearFlags( IS_ROLLOVER ); lastRolloverItem = niluuid; - m_frame->GetCanvas()->GetView()->Update( item ); + + if( item->Type() == SCH_FIELD_T ) + m_frame->GetCanvas()->GetView()->Update( item->GetParent() ); + else + m_frame->GetCanvas()->GetView()->Update( item ); } item = m_frame->GetItem( rolloverItem ); @@ -547,7 +544,11 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) { item->SetFlags( IS_ROLLOVER ); lastRolloverItem = rolloverItem; - m_frame->GetCanvas()->GetView()->Update( item ); + + if( item->Type() == SCH_FIELD_T ) + m_frame->GetCanvas()->GetView()->Update( item->GetParent() ); + else + m_frame->GetCanvas()->GetView()->Update( item ); } } @@ -659,12 +660,12 @@ bool EE_SELECTION_TOOL::selectPoint( EE_COLLECTOR& aCollector, EDA_ITEM** aItem, { m_selection.ClearReferencePoint(); - // Unmodified clicking of SCH_IREFs results in hypertext links rather than selection. + // Unmodified clicking of hypertext items results in hypertext actions rather than selection. if( !aAdd && !aSubtract && !aExclusiveOr ) { for( int i = aCollector.GetCount() - 1; i >= 0; --i ) { - if( aCollector[i]->Type() == SCH_IREF_T ) + if( aCollector[i]->IsHypertext() ) aCollector.Remove( i ); } } @@ -1302,7 +1303,7 @@ void EE_SELECTION_TOOL::RebuildSelection() } else { - for( auto item : m_frame->GetScreen()->Items() ) + for( SCH_ITEM* item : m_frame->GetScreen()->Items() ) { // If the field and component are selected, only use the component if( item->IsSelected() ) @@ -1311,30 +1312,12 @@ void EE_SELECTION_TOOL::RebuildSelection() } else { - if( item->Type() == SCH_COMPONENT_T ) - { - for( SCH_FIELD& field : static_cast( item )->GetFields() ) - { - if( field.IsSelected() ) - select( &field ); - } - } - - if( item->Type() == SCH_SHEET_T ) - { - 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 ); - } - } - + item->RunOnChildren( + [&]( SCH_ITEM* aChild ) + { + if( aChild->IsSelected() ) + select( aChild ); + } ); } } } @@ -1595,42 +1578,14 @@ void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGr // Highlight pins and fields. (All the other component children are currently only // represented in the LIB_PART and will inherit the settings of the parent component.) - if( itemType == SCH_COMPONENT_T ) - { - for( SCH_PIN* pin : static_cast( aItem )->GetPins() ) - { - if( aMode == SELECTED ) - pin->SetSelected(); - else if( aMode == BRIGHTENED ) - pin->SetBrightened(); - } - - for( SCH_FIELD& field : static_cast( aItem )->GetFields() ) - { - if( aMode == SELECTED ) - field.SetSelected(); - else if( aMode == BRIGHTENED ) - field.SetBrightened(); - } - } - else if( itemType == SCH_SHEET_T ) - { - for( SCH_FIELD& field : static_cast( aItem )->GetFields() ) - { - if( aMode == SELECTED ) - field.SetSelected(); - else if( aMode == BRIGHTENED ) - field.SetBrightened(); - } - - for( SCH_SHEET_PIN* pin : static_cast( aItem )->GetPins() ) - { - if( aMode == SELECTED ) - pin->SetSelected(); - else if( aMode == BRIGHTENED ) - pin->SetBrightened(); - } - } + static_cast( aItem )->RunOnChildren( + [&]( SCH_ITEM* aChild ) + { + if( aMode == SELECTED ) + aChild->SetSelected(); + else if( aMode == BRIGHTENED ) + aChild->SetSelected(); + } ); if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T ) getView()->Update( aItem->GetParent() ); @@ -1653,42 +1608,14 @@ void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* a // Unhighlight pins and fields. (All the other component children are currently only // represented in the LIB_PART.) - if( itemType == SCH_COMPONENT_T ) - { - for( SCH_PIN* pin : static_cast( aItem )->GetPins() ) - { - if( aMode == SELECTED ) - pin->ClearSelected(); - else if( aMode == BRIGHTENED ) - pin->ClearBrightened(); - } - - for( SCH_FIELD& field : static_cast( aItem )->GetFields() ) - { - if( aMode == SELECTED ) - field.ClearSelected(); - else if( aMode == BRIGHTENED ) - field.ClearBrightened(); - } - } - else if( itemType == SCH_SHEET_T ) - { - for( SCH_FIELD& field : static_cast( aItem )->GetFields() ) - { - if( aMode == SELECTED ) - field.ClearSelected(); - else if( aMode == BRIGHTENED ) - field.ClearBrightened(); - } - - for( SCH_SHEET_PIN* pin : static_cast( aItem )->GetPins() ) - { - if( aMode == SELECTED ) - pin->ClearSelected(); - else if( aMode == BRIGHTENED ) - pin->ClearBrightened(); - } - } + static_cast( aItem )->RunOnChildren( + [&]( SCH_ITEM* aChild ) + { + if( aMode == SELECTED ) + aChild->ClearSelected(); + else if( aMode == BRIGHTENED ) + aChild->ClearBrightened(); + } ); if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T ) getView()->Update( aItem->GetParent() ); diff --git a/eeschema/tools/sch_drawing_tools.cpp b/eeschema/tools/sch_drawing_tools.cpp index f516d2b5f8..cc6430c8bb 100644 --- a/eeschema/tools/sch_drawing_tools.cpp +++ b/eeschema/tools/sch_drawing_tools.cpp @@ -779,7 +779,7 @@ SCH_SHEET_PIN* SCH_DRAWING_TOOLS::createSheetPin( SCH_SHEET* aSheet, SCH_HIERLAB int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) { - EDA_ITEM* item = nullptr; + SCH_ITEM* item = nullptr; bool isImportMode = aEvent.IsAction( &EE_ACTIONS::importSheetPin ); bool isText = aEvent.IsAction( &EE_ACTIONS::placeSchematicText ); bool isGlobalLabel = aEvent.IsAction( &EE_ACTIONS::placeGlobalLabel ); @@ -885,11 +885,12 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) break; case SCH_SHEET_PIN_T: { + EDA_ITEM* i; SCH_HIERLABEL* label = nullptr; SCH_SHEET* sheet = nullptr; - if( m_selectionTool->SelectPoint( cursorPos, EE_COLLECTOR::SheetsOnly, &item ) ) - sheet = dynamic_cast( item ); + if( m_selectionTool->SelectPoint( cursorPos, EE_COLLECTOR::SheetsOnly, &i ) ) + sheet = dynamic_cast( i ); item = nullptr; @@ -944,6 +945,8 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent ) else { item->ClearFlags( IS_MOVED ); + item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false ); + m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), (SCH_ITEM*) item, false ); item = nullptr; diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index e89859aee2..401c2d7e52 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -276,8 +275,12 @@ bool SCH_EDIT_TOOL::Init() static KICAD_T entryTypes[] = { SCH_BUS_WIRE_ENTRY_T, SCH_BUS_BUS_ENTRY_T, EOT }; auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( entryTypes ); - auto singleComponentCondition = E_C::Count( 1 ) && E_C::OnlyType( SCH_COMPONENT_T ); - auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T ); + static KICAD_T fieldParentTypes[] = { SCH_COMPONENT_T, SCH_SHEET_T, SCH_GLOBAL_LABEL_T, EOT }; + auto singleFieldParentCondition = E_C::Count( 1 ) && E_C::OnlyTypes( fieldParentTypes ); + + auto singleSymbolCondition = E_C::Count( 1 ) && E_C::OnlyType( SCH_COMPONENT_T ); + + auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T ); // // Add edit actions to the move tool menu // @@ -293,9 +296,9 @@ bool SCH_EDIT_TOOL::Init() moveMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty ); moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition ); - moveMenu.AddItem( EE_ACTIONS::editReference, singleComponentCondition ); - moveMenu.AddItem( EE_ACTIONS::editValue, singleComponentCondition ); - moveMenu.AddItem( EE_ACTIONS::editFootprint, singleComponentCondition ); + moveMenu.AddItem( EE_ACTIONS::editReference, singleSymbolCondition ); + moveMenu.AddItem( EE_ACTIONS::editValue, singleSymbolCondition ); + moveMenu.AddItem( EE_ACTIONS::editFootprint, singleSymbolCondition ); moveMenu.AddItem( EE_ACTIONS::toggleDeMorgan, E_C::SingleDeMorganSymbol ); std::shared_ptr symUnitMenu = std::make_shared(); @@ -323,10 +326,10 @@ bool SCH_EDIT_TOOL::Init() drawMenu.AddItem( EE_ACTIONS::mirrorY, orientCondition, 200 ); drawMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 ); - drawMenu.AddItem( EE_ACTIONS::editReference, singleComponentCondition, 200 ); - drawMenu.AddItem( EE_ACTIONS::editValue, singleComponentCondition, 200 ); - drawMenu.AddItem( EE_ACTIONS::editFootprint, singleComponentCondition, 200 ); - drawMenu.AddItem( EE_ACTIONS::autoplaceFields, singleComponentCondition, 200 ); + drawMenu.AddItem( EE_ACTIONS::editReference, singleSymbolCondition, 200 ); + drawMenu.AddItem( EE_ACTIONS::editValue, singleSymbolCondition, 200 ); + drawMenu.AddItem( EE_ACTIONS::editFootprint, singleSymbolCondition, 200 ); + drawMenu.AddItem( EE_ACTIONS::autoplaceFields, singleFieldParentCondition, 200 ); drawMenu.AddItem( EE_ACTIONS::toggleDeMorgan, E_C::SingleDeMorganSymbol, 200 ); std::shared_ptr symUnitMenu2 = std::make_shared(); @@ -334,7 +337,7 @@ bool SCH_EDIT_TOOL::Init() drawingTools->GetToolMenu().AddSubMenu( symUnitMenu2 ); drawMenu.AddMenu( symUnitMenu2.get(), E_C::SingleMultiUnitSymbol, 1 ); - drawMenu.AddItem( EE_ACTIONS::editWithLibEdit, singleComponentCondition && E_C::Idle, 200 ); + drawMenu.AddItem( EE_ACTIONS::editWithLibEdit, singleSymbolCondition && E_C::Idle, 200 ); drawMenu.AddItem( EE_ACTIONS::toLabel, anyTextTool && E_C::Idle, 200 ); drawMenu.AddItem( EE_ACTIONS::toHLabel, anyTextTool && E_C::Idle, 200 ); @@ -357,8 +360,7 @@ bool SCH_EDIT_TOOL::Init() selToolMenu.AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol, 200 ); selToolMenu.AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 ); selToolMenu.AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol, 200 ); - selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, singleComponentCondition - || singleSheetCondition, 200 ); + selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, singleFieldParentCondition, 200 ); selToolMenu.AddItem( EE_ACTIONS::toggleDeMorgan, E_C::SingleSymbol, 200 ); std::shared_ptr symUnitMenu3 = std::make_shared(); @@ -366,7 +368,7 @@ bool SCH_EDIT_TOOL::Init() m_selectionTool->GetToolMenu().AddSubMenu( symUnitMenu3 ); selToolMenu.AddMenu( symUnitMenu3.get(), E_C::SingleMultiUnitSymbol, 1 ); - selToolMenu.AddItem( EE_ACTIONS::editWithLibEdit, singleComponentCondition && E_C::Idle, 200 ); + selToolMenu.AddItem( EE_ACTIONS::editWithLibEdit, singleSymbolCondition && E_C::Idle, 200 ); selToolMenu.AddItem( EE_ACTIONS::changeSymbol, E_C::SingleSymbol, 200 ); selToolMenu.AddItem( EE_ACTIONS::updateSymbol, E_C::SingleSymbol, 200 ); @@ -460,10 +462,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent ) if( item->Type() == SCH_GLOBAL_LABEL_T ) { SCH_GLOBALLABEL* label = static_cast( item ); - SCH_IREF* iref = label->GetIref(); - - if( iref ) - iref->CopyParentStyle(); + label->UpdateIntersheetRefProps(); } break; @@ -653,10 +652,7 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent ) if( item->Type() == SCH_GLOBAL_LABEL_T ) { SCH_GLOBALLABEL* label = static_cast( item ); - SCH_IREF* iref = label->GetIref(); - - if( iref ) - iref->CopyParentStyle(); + label->UpdateIntersheetRefProps(); } break; @@ -846,14 +842,6 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) case SCH_NO_CONNECT_T: newItem->SetParent( m_frame->GetScreen() ); m_frame->AddToScreen( newItem, m_frame->GetScreen() ); - - if( newItem->Type() == SCH_GLOBAL_LABEL_T ) - { - SCH_GLOBALLABEL* label = static_cast( newItem ); - label->SetIref( nullptr ); - label->SetIrefSavedPosition( wxDefaultPosition ); - } - break; case SCH_SHEET_T: @@ -1062,16 +1050,6 @@ int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent ) sheet->RemovePin( pin ); } - else if( sch_item->Type() == SCH_GLOBAL_LABEL_T ) - { - SCH_GLOBALLABEL* label = (SCH_GLOBALLABEL*) sch_item; - SCH_IREF* iref = label->GetIref(); - - m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() ); - - if( iref ) - m_frame->RemoveFromScreen( iref, m_frame->GetScreen() ); - } else { m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() ); @@ -1259,7 +1237,7 @@ int SCH_EDIT_TOOL::EditField( const TOOL_EVENT& aEvent ) int SCH_EDIT_TOOL::AutoplaceFields( const TOOL_EVENT& aEvent ) { - EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::ComponentsOrSheets ); + EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::FieldOwners ); if( selection.Empty() ) return 0; @@ -1269,16 +1247,7 @@ int SCH_EDIT_TOOL::AutoplaceFields( const TOOL_EVENT& aEvent ) if( !item->IsNew() ) saveCopyInUndoList( item, UNDO_REDO::CHANGED ); - if( item->Type() == SCH_COMPONENT_T ) - { - SCH_COMPONENT* component = static_cast( item ); - component->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true ); - } - else if( item->Type() == SCH_SHEET_T ) - { - SCH_SHEET* sheet = static_cast( item ); - sheet->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true ); - } + item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true ); updateItem( item, true ); m_frame->OnModify(); @@ -1302,7 +1271,9 @@ int SCH_EDIT_TOOL::ChangeSymbols( const TOOL_EVENT& aEvent ) if( aEvent.IsAction( &EE_ACTIONS::changeSymbol ) || aEvent.IsAction( &EE_ACTIONS::changeSymbols ) ) + { mode = DIALOG_CHANGE_SYMBOLS::MODE::CHANGE; + } DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode ); @@ -1323,11 +1294,15 @@ int SCH_EDIT_TOOL::ConvertDeMorgan( const TOOL_EVENT& aEvent ) if( aEvent.IsAction( &EE_ACTIONS::showDeMorganStandard ) && component->GetConvert() == LIB_ITEM::LIB_CONVERT::BASE ) + { return 0; + } if( aEvent.IsAction( &EE_ACTIONS::showDeMorganAlternate ) && component->GetConvert() != LIB_ITEM::LIB_CONVERT::DEMORGAN ) + { return 0; + } if( !component->IsNew() ) saveCopyInUndoList( component, UNDO_REDO::CHANGED ); diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index f8aa4069e6..5363608a0d 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -268,27 +268,11 @@ int SCH_EDITOR_CONTROL::UpdateFind( const TOOL_EVENT& aEvent ) { visit( item, &m_frame->GetCurrentSheet() ); - if( item->Type() == SCH_COMPONENT_T ) - { - SCH_COMPONENT* cmp = static_cast( item ); - - for( SCH_FIELD& field : cmp->GetFields() ) - visit( &field, &m_frame->GetCurrentSheet() ); - - for( SCH_PIN* pin : cmp->GetPins() ) - visit( pin, &m_frame->GetCurrentSheet() ); - } - else if( item->Type() == SCH_SHEET_T ) - { - SCH_SHEET* sheet = static_cast( item ); - - for( SCH_FIELD& field : sheet->GetFields() ) - visit( &field, &m_frame->GetCurrentSheet() ); - - for( SCH_SHEET_PIN* pin : sheet->GetPins() ) - visit( pin, &m_frame->GetCurrentSheet() ); - } - + item->RunOnChildren( + [&]( SCH_ITEM* aChild ) + { + visit( aChild, &m_frame->GetCurrentSheet() ); + } ); } } else if( aEvent.Matches( EVENTS::SelectedItemsModified ) ) @@ -1542,13 +1526,6 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent ) updatePastedInstances( pastePath, clipPath, sheet, forceKeepAnnotations ); } - if( item->Type() == SCH_GLOBAL_LABEL_T ) - { - SCH_GLOBALLABEL* label = static_cast( item ); - label->SetIref( nullptr ); - label->SetIrefSavedPosition( wxDefaultPosition ); - } - item->SetFlags( IS_NEW | IS_PASTED | IS_MOVED ); m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), (SCH_ITEM*) item, i > 0 ); diff --git a/eeschema/tools/sch_move_tool.cpp b/eeschema/tools/sch_move_tool.cpp index fca9f54996..ebcb0a24bd 100644 --- a/eeschema/tools/sch_move_tool.cpp +++ b/eeschema/tools/sch_move_tool.cpp @@ -29,11 +29,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -98,7 +96,6 @@ static const KICAD_T movableItems[] = SCH_COMPONENT_T, SCH_SHEET_PIN_T, SCH_SHEET_T, - SCH_IREF_T, EOT }; @@ -710,36 +707,6 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta ) break; } - case SCH_GLOBAL_LABEL_T: - { - SCH_GLOBALLABEL* label = static_cast( aItem ); - EDA_ITEM* iref = (EDA_ITEM*) ( label->GetIref() ); - static_cast( aItem )->Move( (wxPoint) aDelta ); - - if( iref ) - static_cast( iref )->Move( (wxPoint) aDelta ); - - break; - } - case SCH_IREF_T: - { - SCH_IREF* iref = static_cast( aItem ); - wxPoint pt = (wxPoint) aDelta; - - int style = iref->GetParentLabel()->GetLabelSpinStyle(); - - if( iref->GetParentLabel()->IsSelected() ) - break; - - if( ( style == LABEL_SPIN_STYLE::RIGHT ) || ( style == LABEL_SPIN_STYLE::LEFT ) ) - pt.y = 0; - - if( ( style == LABEL_SPIN_STYLE::UP ) || ( style == LABEL_SPIN_STYLE::BOTTOM ) ) - pt.x = 0; - - iref->Move( pt ); - break; - } default: static_cast( aItem )->Move( (wxPoint) aDelta ); break; diff --git a/eeschema/tools/sch_navigate_tool.cpp b/eeschema/tools/sch_navigate_tool.cpp index f538845a95..026e9fc98f 100644 --- a/eeschema/tools/sch_navigate_tool.cpp +++ b/eeschema/tools/sch_navigate_tool.cpp @@ -23,6 +23,7 @@ */ #include +#include #include #include @@ -58,7 +59,7 @@ int SCH_NAVIGATE_TOOL::HypertextCommand( const TOOL_EVENT& aEvent ) } }; - if( aEvent.GetCommandId() == ID_HYPERTEXT_BACK ) + if( *page == "HYPERTEXT_BACK" ) { if( m_hypertextStack.size() > 0 ) { diff --git a/eeschema/tools/sch_navigate_tool.h b/eeschema/tools/sch_navigate_tool.h index 35e81f7339..1f6e5db66d 100644 --- a/eeschema/tools/sch_navigate_tool.h +++ b/eeschema/tools/sch_navigate_tool.h @@ -32,8 +32,6 @@ class SCH_EDIT_FRAME; -#define ID_HYPERTEXT_BACK 999 - /** * SCH_NAVIGATE_TOOL * diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h index 5fdc184048..eb3908dc66 100644 --- a/include/core/typeinfo.h +++ b/include/core/typeinfo.h @@ -137,7 +137,6 @@ enum KICAD_T SCH_SHEET_PIN_T, SCH_SHEET_T, SCH_PIN_T, - SCH_IREF_T, // Be prudent with these types: // they should be used only to locate a specific field type among SCH_FIELD_Ts