diff --git a/common/eda_text.cpp b/common/eda_text.cpp index 3d011621c9..7fc6ac5045 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -168,8 +168,8 @@ wxString EDA_TEXT::ShortenedShownText() const tmp.Replace( wxT( "\r" ), wxT( " " ) ); tmp.Replace( wxT( "\t" ), wxT( " " ) ); - if( tmp.Length() > 15 ) - tmp = tmp.Left( 12 ) + wxT( "..." ); + if( tmp.Length() > 36 ) + tmp = tmp.Left( 34 ) + wxT( "..." ); return tmp; } diff --git a/eeschema/dialogs/dialog_edit_label.cpp b/eeschema/dialogs/dialog_edit_label.cpp index e0c38648a8..9035ba11c0 100644 --- a/eeschema/dialogs/dialog_edit_label.cpp +++ b/eeschema/dialogs/dialog_edit_label.cpp @@ -322,12 +322,12 @@ bool DIALOG_LABEL_EDITOR::TransferDataFromWindow() return false; } - m_CurrentText->SetLabelSpinStyle( m_TextOrient->GetSelection() ); + m_CurrentText->SetLabelSpinStyle( (LABEL_SPIN_STYLE::SPIN) m_TextOrient->GetSelection() ); m_CurrentText->SetTextSize( wxSize( m_textSize.GetValue(), m_textSize.GetValue() ) ); if( m_TextShape ) - m_CurrentText->SetShape( static_cast( m_TextShape->GetSelection() ) ); + m_CurrentText->SetShape( (PINSHEETLABEL_SHAPE) m_TextShape->GetSelection() ); int style = m_TextStyle->GetSelection(); diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp index 1e6e9e1304..0d17d4ef14 100644 --- a/eeschema/dialogs/dialog_erc.cpp +++ b/eeschema/dialogs/dialog_erc.cpp @@ -316,6 +316,9 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) objectsConnectedList->TestforSimilarLabels(); } + if( g_ErcSettings->IsTestEnabled( ERCE_UNRESOLVED_VARIABLE ) ) + TestTextVars(); + // Display diags: m_markerTreeModel->SetProvider( m_markerProvider ); diff --git a/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp b/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp index 1aec48a4b3..2d4d653e65 100644 --- a/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp +++ b/eeschema/dialogs/dialog_global_edit_text_and_graphics.cpp @@ -246,7 +246,7 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::processItem( const SCH_SHEET_PATH& aS { if( m_orientation->GetStringSelection() != INDETERMINATE ) { - sch_text->SetLabelSpinStyle( m_orientation->GetSelection() ); + sch_text->SetLabelSpinStyle( (LABEL_SPIN_STYLE::SPIN) m_orientation->GetSelection() ); m_hasChange = true; } } diff --git a/eeschema/dialogs/panel_eeschema_color_settings.cpp b/eeschema/dialogs/panel_eeschema_color_settings.cpp index ccb189c5c3..40142c0be4 100644 --- a/eeschema/dialogs/panel_eeschema_color_settings.cpp +++ b/eeschema/dialogs/panel_eeschema_color_settings.cpp @@ -353,27 +353,27 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems() addItem( e2 ); auto t1 = new SCH_TEXT( wxPoint( Mils2iu( 2850 ), Mils2iu( 2250 ) ), wxT( "PLAIN TEXT" ) ); - t1->SetLabelSpinStyle( 0 ); + t1->SetLabelSpinStyle( LABEL_SPIN_STYLE::SPIN::LEFT ); addItem( t1 ); auto t2 = new SCH_LABEL( wxPoint( Mils2iu( 1975 ), Mils2iu( 1500 ) ), wxT( "GLOBAL0" ) ); - t2->SetLabelSpinStyle( 2 ); + t2->SetLabelSpinStyle( LABEL_SPIN_STYLE::SPIN::RIGHT ); t2->SetIsDangling( false ); addItem( t2 ); auto t3 = new SCH_LABEL( wxPoint( Mils2iu( 1975 ), Mils2iu( 2600 ) ), wxT( "GLOBAL1" ) ); - t3->SetLabelSpinStyle( 2 ); + t3->SetLabelSpinStyle( LABEL_SPIN_STYLE::SPIN::RIGHT ); t3->SetIsDangling( false ); addItem( t3 ); auto t4 = new SCH_GLOBALLABEL( wxPoint( Mils2iu( 1750 ), Mils2iu( 1400 ) ), wxT( "GLOBAL[3..0]" ) ); - t4->SetLabelSpinStyle( 0 ); + t4->SetLabelSpinStyle( LABEL_SPIN_STYLE::SPIN::LEFT ); t4->SetIsDangling( false ); addItem( t4 ); auto t5 = new SCH_HIERLABEL( wxPoint( Mils2iu( 3250 ), Mils2iu( 1600 ) ), wxT( "HIER_LABEL" ) ); - t5->SetLabelSpinStyle( 2 ); + t5->SetLabelSpinStyle( LABEL_SPIN_STYLE::SPIN::RIGHT ); t5->SetIsDangling( false ); addItem( t5 ); diff --git a/eeschema/erc.cpp b/eeschema/erc.cpp index 404a4b25bf..437d3ca550 100644 --- a/eeschema/erc.cpp +++ b/eeschema/erc.cpp @@ -198,6 +198,73 @@ int TestDuplicateSheetNames( bool aCreateMarker ) } +void TestTextVars() +{ + SCH_SCREENS screens; + + for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) + { + for( SCH_ITEM* item : screen->Items().OfType( SCH_LOCATE_ANY_T ) ) + { + if( item->Type() == SCH_COMPONENT_T ) + { + SCH_COMPONENT* component = static_cast( item ); + + for( SCH_FIELD& field : component->GetFields() ) + { + if( field.GetShownText().Matches( wxT( "*${*}*" ) ) ) + { + wxPoint delta = field.GetPosition() - component->GetPosition(); + delta = component->GetTransform().TransformCoordinate( delta ); + + SCH_MARKER* marker = new SCH_MARKER( MARKER_BASE::MARKER_ERC ); + marker->SetData( EDA_UNITS::UNSCALED, ERCE_UNRESOLVED_VARIABLE, + component->GetPosition() + delta, &field ); + screen->Append( marker ); + } + } + } + else if( item->Type() == SCH_SHEET_T ) + { + SCH_SHEET* sheet = static_cast( item ); + + for( SCH_FIELD& field : sheet->GetFields() ) + { + if( field.GetShownText().Matches( wxT( "*${*}*" ) ) ) + { + SCH_MARKER* marker = new SCH_MARKER( MARKER_BASE::MARKER_ERC ); + marker->SetData( EDA_UNITS::UNSCALED, ERCE_UNRESOLVED_VARIABLE, + field.GetPosition(), &field ); + screen->Append( marker ); + } + } + + for( SCH_SHEET_PIN* pin : static_cast( item )->GetPins() ) + { + if( pin->GetShownText().Matches( wxT( "*${*}*" ) ) ) + { + SCH_MARKER* marker = new SCH_MARKER( MARKER_BASE::MARKER_ERC ); + marker->SetData( EDA_UNITS::UNSCALED, ERCE_UNRESOLVED_VARIABLE, + pin->GetPosition(), pin ); + screen->Append( marker ); + } + } + } + else if( SCH_TEXT* text = dynamic_cast( item ) ) + { + if( text->GetShownText().Matches( wxT( "*${*}*" ) ) ) + { + SCH_MARKER* marker = new SCH_MARKER( MARKER_BASE::MARKER_ERC ); + marker->SetData( EDA_UNITS::UNSCALED, ERCE_UNRESOLVED_VARIABLE, + text->GetPosition(), text ); + screen->Append( marker ); + } + } + } + } +} + + int TestConflictingBusAliases() { wxString msg; @@ -205,7 +272,7 @@ int TestConflictingBusAliases() SCH_SCREENS screens; std::vector< std::shared_ptr > aliases; - for( auto screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) + for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) { std::unordered_set< std::shared_ptr > screen_aliases = screen->GetBusAliases(); diff --git a/eeschema/erc.h b/eeschema/erc.h index e2c95a284b..714673aaa7 100644 --- a/eeschema/erc.h +++ b/eeschema/erc.h @@ -72,7 +72,8 @@ enum ERCE_T ERCE_BUS_TO_BUS_CONFLICT, // a connection between bus objects doesn't share at least one net ERCE_BUS_TO_NET_CONFLICT, // a bus wire is graphically connected to a net port/pin (or vice versa) ERCE_GLOBLABEL, // a global label is unique - ERCE_LAST = ERCE_GLOBLABEL + ERCE_UNRESOLVED_VARIABLE, + ERCE_LAST = ERCE_UNRESOLVED_VARIABLE }; /* Minimal connection table */ @@ -113,6 +114,12 @@ void TestOthersItems( NETLIST_OBJECT_LIST* aList, unsigned aNetItemRef, unsigned */ int TestDuplicateSheetNames( bool aCreateMarker ); +/** + * Function TestTextVars() + * Checks for any unresolved text variable references. + */ +void TestTextVars(); + /** * Checks that there are not conflicting bus alias definitions in the schematic * diff --git a/eeschema/erc_item.cpp b/eeschema/erc_item.cpp index ddac641a04..d3b770d80b 100644 --- a/eeschema/erc_item.cpp +++ b/eeschema/erc_item.cpp @@ -74,6 +74,8 @@ wxString ERC_ITEM::GetErrorText() const return wxString( _( "Invalid connection between bus and net items" ) ); case ERCE_GLOBLABEL: return wxString( _( "Global label not connected anywhere else in the schematic" ) ); + case ERCE_UNRESOLVED_VARIABLE: + return wxString( _( "Unresolved text variable" ) ); default: wxFAIL_MSG( "Missing ERC error description" ); return wxString( wxT("Unknown.") ); diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp index d39b6cd02c..bd62847429 100644 --- a/eeschema/lib_field.cpp +++ b/eeschema/lib_field.cpp @@ -429,7 +429,7 @@ void LIB_FIELD::SetName( const wxString& aName ) wxString LIB_FIELD::GetSelectMenuText( EDA_UNITS aUnits ) const { - return wxString::Format( _( "Field %s \"%s\"" ), + return wxString::Format( _( "Field %s (%s)" ), GetName(), ShortenedShownText() ); } diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index 2ed550031f..a2242d42a2 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -343,7 +343,11 @@ void SCH_BASE_FRAME::FocusOnItem( SCH_ITEM* aItem ) if( aItem->GetParent() && aItem->GetParent()->Type() == SCH_COMPONENT_T ) { SCH_COMPONENT* comp = static_cast( aItem->GetParent() ); - position += comp->GetPosition(); + + wxPoint delta; + position -= comp->GetPosition(); + delta = comp->GetTransform().TransformCoordinate( position ); + position = delta + comp->GetPosition(); } FocusOnLocation( position ); diff --git a/eeschema/sch_eagle_plugin.cpp b/eeschema/sch_eagle_plugin.cpp index 3a8df37bf9..978424aa3d 100644 --- a/eeschema/sch_eagle_plugin.cpp +++ b/eeschema/sch_eagle_plugin.cpp @@ -1017,7 +1017,7 @@ SCH_TEXT* SCH_EAGLE_PLUGIN::loadLabel( wxXmlNode* aLabelNode, const wxString& aN if( elabel.rot ) { - label->SetLabelSpinStyle( KiROUND( elabel.rot->degrees / 90 ) % 4 ); + label->SetLabelSpinStyle( (LABEL_SPIN_STYLE::SPIN) ( KiROUND( elabel.rot->degrees / 90 ) % 4 ) ); if( elabel.rot->mirror ) { diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 546f611b42..8ce36cf732 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -1059,6 +1059,12 @@ void SCH_EDIT_FRAME::UpdateTitle() } +int SCH_EDIT_FRAME::GetSeverity( int aErrorCode ) const +{ + return ::GetSeverity( aErrorCode ); +} + + void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags ) { SCH_SHEET_LIST list( g_RootSheet ); diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 53cfdd6c05..f431128181 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -549,6 +549,9 @@ public: */ int ModalAnnotate( const wxString& aMessage ); + ///> @copydoc EDA_BASE_FRAME::GetSeverity() + int GetSeverity( int aErrorCode ) const override; + // Functions used for hierarchy handling SCH_SHEET_PATH& GetCurrentSheet(); diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 337ad054c3..cd871756fa 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -501,7 +501,9 @@ void SCH_FIELD::Rotate( wxPoint aPosition ) wxString SCH_FIELD::GetSelectMenuText( EDA_UNITS aUnits ) const { - return wxString::Format( _( "Field %s" ), GetName() ); + return wxString::Format( _( "Field %s (%s)" ), + GetName(), + ShortenedShownText() ); } diff --git a/eeschema/sch_legacy_plugin.cpp b/eeschema/sch_legacy_plugin.cpp index dc855e4261..f033623c56 100644 --- a/eeschema/sch_legacy_plugin.cpp +++ b/eeschema/sch_legacy_plugin.cpp @@ -1406,7 +1406,7 @@ SCH_TEXT* SCH_LEGACY_PLUGIN::loadText( LINE_READER& aReader ) spinStyle = 0; } - text->SetLabelSpinStyle( spinStyle ); + text->SetLabelSpinStyle( (LABEL_SPIN_STYLE::SPIN) spinStyle ); int size = Mils2Iu( parseInt( aReader, line, &line ) ); diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp index aad0bbc613..7b2593f190 100644 --- a/eeschema/sch_text.cpp +++ b/eeschema/sch_text.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2015 Wayne Stambaugh - * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -40,7 +40,7 @@ #include #include #include // for KiROUND - +#include #include #include #include @@ -446,6 +446,69 @@ const EDA_RECT SCH_TEXT::GetBoundingBox() const } +wxString getElectricalTypeLabel( PINSHEETLABEL_SHAPE aType ) +{ + switch( aType ) + { + case PINSHEETLABEL_SHAPE::PS_INPUT: return _( "Input" ); + case PINSHEETLABEL_SHAPE::PS_OUTPUT: return _( "Output" ); + case PINSHEETLABEL_SHAPE::PS_BIDI: return _( "Bidirectional" ); + case PINSHEETLABEL_SHAPE::PS_TRISTATE: return _( "Tri-State" ); + case PINSHEETLABEL_SHAPE::PS_UNSPECIFIED: return _( "Passive" ); + default: return wxT( "???" ); + } +} + + +wxString SCH_TEXT::GetShownText() const +{ + auto textResolver = [this]( wxString* token ) -> bool + { + if( ( Type() == SCH_GLOBAL_LABEL_T + || Type() == SCH_HIER_LABEL_T + || Type() == SCH_SHEET_PIN_T ) + && token->IsSameAs( wxT( "CONNECTION_TYPE" ) ) ) + { + *token = getElectricalTypeLabel( GetShape() ); + return true; + } + + if( Type() == SCH_SHEET_PIN_T && m_Parent ) + { + SCH_SHEET* sheet = static_cast( m_Parent ); + std::vector& fields = sheet->GetFields(); + + for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i ) + { + if( token->IsSameAs( fields[i].GetCanonicalName().Upper() ) ) + { + *token = fields[i].GetShownText(); + return true; + } + } + + for( int i = SHEET_MANDATORY_FIELDS; i < fields.size(); ++i ) + { + if( token->IsSameAs( fields[i].GetName() ) ) + { + *token = fields[i].GetShownText(); + return true; + } + } + } + + return false; + }; + + PROJECT* project = nullptr; + + if( g_RootSheet && g_RootSheet->GetScreen() ) + project = &g_RootSheet->GetScreen()->Kiway().Prj(); + + return ExpandTextVars( GetText(), textResolver, project ); +} + + wxString SCH_TEXT::GetSelectMenuText( EDA_UNITS aUnits ) const { return wxString::Format( _( "Graphic Text \"%s\"" ), GetChars( ShortenedShownText() ) ); @@ -465,7 +528,7 @@ void SCH_TEXT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, return; NETLIST_OBJECT* item = new NETLIST_OBJECT(); - item->m_SheetPath = *aSheetPath; + item->m_SheetPath = *aSheetPath; item->m_SheetPathInclude = *aSheetPath; item->m_Comp = (SCH_ITEM*) this; item->m_Type = NETLIST_ITEM::LABEL; @@ -597,16 +660,7 @@ void SCH_TEXT::GetMsgPanelInfo( EDA_UNITS aUnits, MSG_PANEL_ITEMS& aList ) // Display electrical type if it is relevant if( Type() == SCH_GLOBAL_LABEL_T || Type() == SCH_HIER_LABEL_T || Type() == SCH_SHEET_PIN_T ) { - switch( GetShape() ) - { - case PINSHEETLABEL_SHAPE::PS_INPUT: msg = _( "Input" ); break; - case PINSHEETLABEL_SHAPE::PS_OUTPUT: msg = _( "Output" ); break; - case PINSHEETLABEL_SHAPE::PS_BIDI: msg = _( "Bidirectional" ); break; - case PINSHEETLABEL_SHAPE::PS_TRISTATE: msg = _( "Tri-State" ); break; - case PINSHEETLABEL_SHAPE::PS_UNSPECIFIED: msg = _( "Passive" ); break; - default: msg = wxT( "???" ); break; - } - + msg = getElectricalTypeLabel( GetShape() ); aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, BLUE ) ); } diff --git a/eeschema/sch_text.h b/eeschema/sch_text.h index e5229d66dc..9bbb4fcdf1 100644 --- a/eeschema/sch_text.h +++ b/eeschema/sch_text.h @@ -55,31 +55,21 @@ public: { } - - LABEL_SPIN_STYLE( int aSpin ) - { - m_spin = static_cast( aSpin ); - } - - constexpr bool operator==( SPIN a ) const { return m_spin == a; } - constexpr bool operator!=( SPIN a ) const { return m_spin != a; } - operator int() const { return static_cast( m_spin ); } - LABEL_SPIN_STYLE RotateCW() { SPIN newSpin = m_spin; @@ -96,7 +86,6 @@ public: return LABEL_SPIN_STYLE( newSpin ); } - LABEL_SPIN_STYLE RotateCCW() { SPIN newSpin = m_spin; @@ -113,7 +102,6 @@ public: return LABEL_SPIN_STYLE( newSpin ); } - /* * Mirrors the label spin style across the X axis or simply swaps up and bottom */ @@ -133,7 +121,6 @@ public: return LABEL_SPIN_STYLE( newSpin ); } - /* * Mirrors the label spin style across the Y axis or simply swaps left and right */ @@ -220,6 +207,8 @@ public: return wxT( "SCH_TEXT" ); } + wxString GetShownText() const override; + /** * Increment the label text, if it ends with a number. * diff --git a/eeschema/sch_validators.cpp b/eeschema/sch_validators.cpp index dd636c5d9e..e7cf317e3b 100644 --- a/eeschema/sch_validators.cpp +++ b/eeschema/sch_validators.cpp @@ -235,9 +235,6 @@ wxString SCH_NETNAME_VALIDATOR::IsValid( const wxString& str ) const if( SCH_CONNECTION::IsBusGroupLabel( str ) ) return wxString(); - if( str.Contains( '{' ) || str.Contains( '}' ) ) - return _( "Signal name contains '{' or '}' but is not a valid group bus name" ); - if( ( str.Contains( '[' ) || str.Contains( ']' ) ) && !SCH_CONNECTION::IsBusVectorLabel( str ) ) return _( "Signal name contains '[' or ']' but is not a valid vector bus name" ); diff --git a/pcbnew/drc/drc.cpp b/pcbnew/drc/drc.cpp index 63b0c00eb0..03bc0c322d 100644 --- a/pcbnew/drc/drc.cpp +++ b/pcbnew/drc/drc.cpp @@ -484,6 +484,9 @@ void DRC::RunTests( wxTextCtrl* aMessages ) aMessages->Refresh(); } + if( !m_pcb->GetDesignSettings().Ignore( DRCE_UNRESOLVED_VARIABLE ) ) + testTextVars(); + m_drcRun = true; // update the m_drcDialog listboxes @@ -1160,31 +1163,73 @@ void DRC::testDisabledLayers() // Perform the test only for copper layers disabledLayers &= LSET::AllCuMask(); - auto createMarker = [&]( BOARD_ITEM* aItem ) { - addMarkerToPcb( new MARKER_PCB( userUnits(), DRCE_DISABLED_LAYER_ITEM, - aItem->GetPosition(), aItem ) ); - }; - - for( auto track : board->Tracks() ) + for( TRACK* track : board->Tracks() ) { if( disabledLayers.test( track->GetLayer() ) ) - createMarker( track ); + { + addMarkerToPcb( new MARKER_PCB( userUnits(), DRCE_DISABLED_LAYER_ITEM, + track->GetPosition(), track ) ); + } } - for( auto module : board->Modules() ) + for( MODULE* module : board->Modules() ) { module->RunOnChildren( - [&]( BOARD_ITEM* aItem ) + [&]( BOARD_ITEM* child ) + { + if( disabledLayers.test( child->GetLayer() ) ) + { + addMarkerToPcb( new MARKER_PCB( userUnits(), DRCE_DISABLED_LAYER_ITEM, + child->GetPosition(), child ) ); + } + } ); + } + + for( ZONE_CONTAINER* zone : board->Zones() ) + { + if( disabledLayers.test( zone->GetLayer() ) ) + { + addMarkerToPcb( new MARKER_PCB( userUnits(), DRCE_DISABLED_LAYER_ITEM, + zone->GetPosition(), zone ) ); + } + } +} + + +void DRC::testTextVars() +{ + BOARD* board = m_pcbEditorFrame->GetBoard(); + + for( MODULE* module : board->Modules() ) + { + module->RunOnChildren( + [&]( BOARD_ITEM* child ) { - if( disabledLayers.test( aItem->GetLayer() ) ) - createMarker( aItem ); + if( child->Type() == PCB_MODULE_TEXT_T ) + { + TEXTE_MODULE* text = static_cast( child ); + + if( text->GetShownText().Matches( wxT( "*${*}*" ) ) ) + { + addMarkerToPcb( new MARKER_PCB( userUnits(), DRCE_UNRESOLVED_VARIABLE, + text->GetPosition(), text ) ); + } + } } ); } - for( auto zone : board->Zones() ) + for( BOARD_ITEM* drawing : board->Drawings() ) { - if( disabledLayers.test( zone->GetLayer() ) ) - createMarker( zone ); + if( drawing->Type() == PCB_TEXT_T ) + { + TEXTE_PCB* text = static_cast( drawing ); + + if( text->GetShownText().Matches( wxT( "*${*}*" ) ) ) + { + addMarkerToPcb( new MARKER_PCB( userUnits(), DRCE_UNRESOLVED_VARIABLE, + text->GetPosition(), text ) ); + } + } } } diff --git a/pcbnew/drc/drc.h b/pcbnew/drc/drc.h index 074228c975..22b21ede2e 100644 --- a/pcbnew/drc/drc.h +++ b/pcbnew/drc/drc.h @@ -100,7 +100,9 @@ enum PCB_DRC_CODE { DRCE_ZERO_LENGTH_TRACK, DRCE_TRACK_IN_PAD, - DRCE_LAST = DRCE_TRACK_IN_PAD + DRCE_UNRESOLVED_VARIABLE, + + DRCE_LAST = DRCE_UNRESOLVED_VARIABLE }; @@ -246,9 +248,12 @@ private: void testCopperTextAndGraphics(); - ///> Tests for items placed on disabled layers (causing false connections). + // Tests for items placed on disabled layers (causing false connections). void testDisabledLayers(); + // Test for any unresolved text variable references + void testTextVars(); + /** * Test that the board outline is contiguous and composed of valid elements */ diff --git a/pcbnew/drc/drc_item.cpp b/pcbnew/drc/drc_item.cpp index 4f29fc7c69..53e305d623 100644 --- a/pcbnew/drc/drc_item.cpp +++ b/pcbnew/drc/drc_item.cpp @@ -158,6 +158,9 @@ wxString DRC_ITEM::GetErrorText() const case DRCE_TRACK_IN_PAD: return wxString( _( "Remove track inside pad" ) ); + case DRCE_UNRESOLVED_VARIABLE: + return wxString( _( "Unresolved text variable" ) ); + default: return wxEmptyString; }