KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_marker.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2009 Jean-Pierre Charras, [email protected]
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <sch_draw_panel.h>
26#include <trigo.h>
27#include <widgets/msgpanel.h>
28#include <bitmaps.h>
29#include <base_units.h>
30#include <eda_draw_frame.h>
31#include <erc/erc_settings.h>
32#include <sch_marker.h>
33#include <schematic.h>
34#include <widgets/ui_common.h>
35#include <pgm_base.h>
38#include <erc/erc_item.h>
39#include <sch_screen.h>
40
42#define SCALING_FACTOR schIUScale.mmToIU( 0.15 )
43
44
45SCH_MARKER::SCH_MARKER( std::shared_ptr<ERC_ITEM> aItem, const VECTOR2I& aPos ) :
46 SCH_ITEM( nullptr, SCH_MARKER_T ),
47 MARKER_BASE( SCALING_FACTOR, aItem, MARKER_BASE::MARKER_ERC )
48{
49 if( m_rcItem )
50 m_rcItem->SetParent( this );
51
52 m_Pos = aPos;
53
54 m_isLegacyMarker = false;
55}
56
57
59{
60 if( m_rcItem )
61 m_rcItem->SetParent( nullptr );
62}
63
64
66{
67 return new SCH_MARKER( *this );
68}
69
70
72{
73 SCH_ITEM::SwapFlags( aItem );
74
75 SCH_MARKER* item = static_cast<SCH_MARKER*>( aItem );
76
77 std::swap( m_isLegacyMarker, item->m_isLegacyMarker );
78 std::swap( m_Pos, item->m_Pos );
79
80 std::swap( m_markerType, item->m_markerType );
81 std::swap( m_excluded, item->m_excluded );
82 std::swap( m_rcItem, item->m_rcItem );
83
84 std::swap( m_scalingFactor, item->m_scalingFactor );
85 std::swap( m_shapeBoundingBox, item->m_shapeBoundingBox );
86
87 std::swap( *((SCH_MARKER*) this), *((SCH_MARKER*) aItem ) );
88}
89
90
92{
93 std::shared_ptr<ERC_ITEM> erc = std::static_pointer_cast<ERC_ITEM>( m_rcItem );
94 wxString sheetSpecificPath, mainItemPath, auxItemPath;
95
96 if( erc->IsSheetSpecific() )
97 sheetSpecificPath = erc->GetSpecificSheetPath().Path().AsString();
98
99 if( erc->MainItemHasSheetPath() )
100 mainItemPath = erc->GetMainItemSheetPath().Path().AsString();
101
102 if( erc->AuxItemHasSheetPath() )
103 auxItemPath = erc->GetAuxItemSheetPath().Path().AsString();
104
105 if( m_rcItem->GetErrorCode() == ERCE_GENERIC_WARNING
106 || m_rcItem->GetErrorCode() == ERCE_GENERIC_ERROR
107 || m_rcItem->GetErrorCode() == ERCE_UNRESOLVED_VARIABLE )
108 {
109 SCH_ITEM* sch_item = Schematic()->GetItem( erc->GetMainItemID() );
110 SCH_ITEM* parent = static_cast<SCH_ITEM*>( sch_item->GetParent() );
111 EDA_TEXT* text_item = dynamic_cast<EDA_TEXT*>( sch_item );
112
113 // SCH_FIELDs and SCH_ITEMs inside LIB_SYMBOLs don't have persistent KIIDs. So the
114 // exclusion must refer to the parent's KIID, and include the text of the original text
115 // item for later look-up.
116
117 if( parent && parent->IsType( { SCH_SYMBOL_T, SCH_LABEL_T, SCH_SHEET_T } ) )
118 {
119 return wxString::Format( wxT( "%s|%d|%d|%s|%s|%s|%s|%s" ),
120 m_rcItem->GetSettingsKey(),
121 m_Pos.x,
122 m_Pos.y,
123 parent->m_Uuid.AsString(),
124 text_item->GetText(),
125 sheetSpecificPath,
126 mainItemPath,
127 wxEmptyString );
128 }
129 }
130
131 return wxString::Format( wxT( "%s|%d|%d|%s|%s|%s|%s|%s" ),
132 m_rcItem->GetSettingsKey(),
133 m_Pos.x,
134 m_Pos.y,
135 m_rcItem->GetMainItemID().AsString(),
136 m_rcItem->GetAuxItemID().AsString(),
137 sheetSpecificPath,
138 mainItemPath,
139 auxItemPath );
140}
141
142
144 const wxString& data )
145{
146 wxArrayString props = wxSplit( data, '|' );
147 VECTOR2I markerPos( (int) strtol( props[1].c_str(), nullptr, 10 ),
148 (int) strtol( props[2].c_str(), nullptr, 10 ) );
149
150 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( props[0] );
151
152 if( !ercItem )
153 return nullptr;
154
155 if( ercItem->GetErrorCode() == ERCE_GENERIC_WARNING
156 || ercItem->GetErrorCode() == ERCE_GENERIC_ERROR
157 || ercItem->GetErrorCode() == ERCE_UNRESOLVED_VARIABLE )
158 {
159 // SCH_FIELDs and SCH_ITEMs inside LIB_SYMBOLs don't have persistent KIIDs. So the
160 // exclusion will contain the parent's KIID in prop[3], and the text of the original
161 // text item in prop[4].
162
163 if( !props[4].IsEmpty() )
164 {
165 KIID uuid = niluuid;
166 SCH_ITEM* parent = aSheetList.GetItem( KIID( props[3] ) );
167
168 // Check fields and pins for a match
169 parent->RunOnChildren(
170 [&]( SCH_ITEM* child )
171 {
172 if( EDA_TEXT* text_item = dynamic_cast<EDA_TEXT*>( child ) )
173 {
174 if( text_item->GetText() == props[4] )
175 uuid = child->m_Uuid;
176 }
177 } );
178
179 // If it's a symbol, we must also check non-overridden LIB_SYMBOL text children
180 if( uuid == niluuid && parent->Type() == SCH_SYMBOL_T )
181 {
182 static_cast<SCH_SYMBOL*>( parent )->GetLibSymbolRef()->RunOnChildren(
183 [&]( SCH_ITEM* child )
184 {
185 if( child->Type() == SCH_FIELD_T )
186 {
187 // Match only on SCH_SYMBOL fields, not LIB_SYMBOL fields.
188 }
189 else if( EDA_TEXT* text_item = dynamic_cast<EDA_TEXT*>( child ) )
190 {
191 if( text_item->GetText() == props[4] )
192 uuid = child->m_Uuid;
193 }
194 } );
195 }
196
197 if( uuid != niluuid )
198 ercItem->SetItems( uuid );
199 else
200 return nullptr;
201 }
202 else
203 {
204 ercItem->SetItems( KIID( props[3] ) );
205 }
206 }
207 else
208 {
209 ercItem->SetItems( KIID( props[3] ), KIID( props[4] ) );
210 }
211
212 bool isLegacyMarker = true;
213
214 // Deserialize sheet / item specific paths - we are not able to use the file version to
215 // determine if markers are legacy as there could be a file opened with a prior version
216 // but which has new markers - this code is called not just during schematic load, but
217 // also to match new ERC exceptions to exclusions.
218 if( props.size() == 8 )
219 {
220 isLegacyMarker = false;
221
222 if( !props[5].IsEmpty() )
223 {
224 KIID_PATH sheetSpecificKiidPath( props[5] );
225 std::optional<SCH_SHEET_PATH> sheetSpecificPath =
226 aSheetList.GetSheetPathByKIIDPath( sheetSpecificKiidPath, true );
227
228 if( sheetSpecificPath.has_value() )
229 ercItem->SetSheetSpecificPath( sheetSpecificPath.value() );
230 }
231
232 if( !props[6].IsEmpty() )
233 {
234 KIID_PATH mainItemKiidPath( props[6] );
235 std::optional<SCH_SHEET_PATH> mainItemPath =
236 aSheetList.GetSheetPathByKIIDPath( mainItemKiidPath, true );
237
238 if( mainItemPath.has_value() )
239 {
240 if( props[7].IsEmpty() )
241 {
242 ercItem->SetItemsSheetPaths( mainItemPath.value() );
243 }
244 else
245 {
246 KIID_PATH auxItemKiidPath( props[7] );
247 std::optional<SCH_SHEET_PATH> auxItemPath =
248 aSheetList.GetSheetPathByKIIDPath( auxItemKiidPath, true );
249
250 if( auxItemPath.has_value() )
251 ercItem->SetItemsSheetPaths( mainItemPath.value(), auxItemPath.value() );
252 }
253 }
254 }
255 }
256
257 SCH_MARKER* marker = new SCH_MARKER( ercItem, markerPos );
258 marker->SetIsLegacyMarker( isLegacyMarker );
259
260 return marker;
261}
262
263
264#if defined(DEBUG)
265
266void SCH_MARKER::Show( int nestLevel, std::ostream& os ) const
267{
268 // for now, make it look like XML:
269 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << GetPos() << "/>\n";
270}
271
272#endif
273
274
275std::vector<int> SCH_MARKER::ViewGetLayers() const
276{
277 wxCHECK2_MSG( Schematic(), return {}, "No SCHEMATIC set for SCH_MARKER!" );
278
279 // Don't display sheet-specific markers when SCH_SHEET_PATHs do not match
280 std::shared_ptr<ERC_ITEM> ercItem = std::static_pointer_cast<ERC_ITEM>( GetRCItem() );
281
282 if( ercItem->IsSheetSpecific()
283 && ( ercItem->GetSpecificSheetPath() != Schematic()->CurrentSheet() ) )
284 {
285 return {};
286 }
287
288 std::vector<int> layers( 2 );
289
290 if( IsExcluded() )
291 {
292 layers[0] = LAYER_ERC_EXCLUSION;
293 }
294 else
295 {
296 switch( Schematic()->ErcSettings().GetSeverity( m_rcItem->GetErrorCode() ) )
297 {
298 default:
299 case SEVERITY::RPT_SEVERITY_ERROR: layers[0] = LAYER_ERC_ERR; break;
300 case SEVERITY::RPT_SEVERITY_WARNING: layers[0] = LAYER_ERC_WARN; break;
301 }
302 }
303
304 layers[1] = LAYER_SELECTION_SHADOWS;
305 return layers;
306}
307
308
310{
311 if( IsExcluded() )
312 return LAYER_ERC_EXCLUSION;
313
314 wxCHECK_MSG( Schematic(), LAYER_ERC_ERR, "No SCHEMATIC set for SCH_MARKER!" );
315
316 switch( Schematic()->ErcSettings().GetSeverity( m_rcItem->GetErrorCode() ) )
317 {
318 default:
319 case SEVERITY::RPT_SEVERITY_ERROR: return LAYER_ERC_ERR;
320 case SEVERITY::RPT_SEVERITY_WARNING: return LAYER_ERC_WARN;
321 }
322}
323
324
326{
328 return colors->GetColor( GetColorLayer() );
329}
330
331
333{
334 if( IsExcluded() )
336
337 ERC_ITEM* item = static_cast<ERC_ITEM*>( m_rcItem.get() );
338
339 return Schematic()->ErcSettings().GetSeverity( item->GetErrorCode() );
340}
341
342
343bool SCH_MARKER::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
344{
345 return SCH_ITEM::Matches( m_rcItem->GetErrorMessage(), aSearchData );
346}
347
348
350{
351 return GetBoundingBoxMarker();
352}
353
354
355void SCH_MARKER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
356{
357 aList.emplace_back( _( "Type" ), _( "Marker" ) );
358 aList.emplace_back( _( "Violation" ), m_rcItem->GetErrorMessage() );
359
360 switch( GetSeverity() )
361 {
363 aList.emplace_back( _( "Severity" ), _( "Ignore" ) );
364 break;
366 aList.emplace_back( _( "Severity" ), _( "Warning" ) );
367 break;
369 aList.emplace_back( _( "Severity" ), _( "Error" ) );
370 break;
371 default:
372 break;
373 }
374
376 {
377 aList.emplace_back( _( "Drawing Sheet" ), wxEmptyString );
378 }
379 else
380 {
381 wxString mainText;
382 wxString auxText;
383 EDA_ITEM* mainItem = nullptr;
384 EDA_ITEM* auxItem = nullptr;
385
386 if( m_rcItem->GetMainItemID() != niluuid )
387 mainItem = aFrame->GetItem( m_rcItem->GetMainItemID() );
388
389 if( m_rcItem->GetAuxItemID() != niluuid )
390 auxItem = aFrame->GetItem( m_rcItem->GetAuxItemID() );
391
392 if( mainItem )
393 mainText = mainItem->GetItemDescription( aFrame, true );
394
395 if( auxItem )
396 auxText = auxItem->GetItemDescription( aFrame, true );
397
398 aList.emplace_back( mainText, auxText );
399 }
400
401 if( IsExcluded() )
402 aList.emplace_back( _( "Excluded" ), m_comment );
403}
404
405
407{
408 return BITMAPS::erc;
409}
410
411
412void SCH_MARKER::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
413{
414 // Marker geometry isn't user-editable
415}
416
417
419{
420 // Marker geometry isn't user-editable
421}
422
423
425{
426 // Marker geometry isn't user-editable
427}
428
429
430bool SCH_MARKER::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
431{
432 return HitTestMarker( aPosition, aAccuracy );
433}
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
Color settings are a bit different than most of the settings objects in that there can be more than o...
COLOR4D GetColor(int aLayer) const
The base class for create windows for drawing purpose.
virtual EDA_ITEM * GetItem(const KIID &aId) const
Fetch an item by KIID.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
Definition: eda_item.cpp:112
const KIID m_Uuid
Definition: eda_item.h:488
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:376
EDA_ITEM * GetParent() const
Definition: eda_item.h:103
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:80
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:296
SEVERITY GetSeverity(int aErrorCode) const
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Definition: kiid.h:49
Marker are mainly used to show a DRC or ERC error or warning.
Definition: marker_base.h:49
bool IsExcluded() const
Definition: marker_base.h:93
bool HitTestMarker(const VECTOR2I &aHitPosition, int aAccuracy) const
Test if the given VECTOR2I is within the bounds of this object.
Definition: marker_base.cpp:87
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:107
int m_scalingFactor
Scaling factor to convert corners coordinates to internal units coordinates.
Definition: marker_base.h:143
wxString m_comment
User supplied comment.
Definition: marker_base.h:140
const VECTOR2I & GetPos() const
Definition: marker_base.h:83
VECTOR2I m_Pos
Position of the marker.
Definition: marker_base.h:135
@ MARKER_DRAWING_SHEET
Definition: marker_base.h:56
MARKER_T m_markerType
The type of marker.
Definition: marker_base.h:138
bool m_excluded
User has excluded this specific error.
Definition: marker_base.h:139
std::shared_ptr< RC_ITEM > m_rcItem
Definition: marker_base.h:141
enum MARKER_T GetMarkerType() const
Definition: marker_base.h:91
BOX2I m_shapeBoundingBox
Bounding box of the graphic symbol relative to the position of the shape in marker shape units.
Definition: marker_base.h:145
BOX2I GetBoundingBoxMarker() const
Return the orthogonal, bounding box of this object for display purposes.
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:125
int GetErrorCode() const
Definition: rc_item.h:154
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Definition: schematic.h:112
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:313
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:167
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:150
virtual void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction)
Definition: sch_item.h:563
void SwapFlags(SCH_ITEM *aItem)
Swap the non-temp and non-edit flags.
Definition: sch_item.cpp:352
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:182
SEVERITY GetSeverity() const override
Definition: sch_marker.cpp:332
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxDat) const override
Compare DRC marker main and auxiliary text against search string.
Definition: sch_marker.cpp:343
wxString GetClass() const override
Return the class name.
Definition: sch_marker.h:47
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_marker.cpp:406
static SCH_MARKER * DeserializeFromString(const SCH_SHEET_LIST &aSheetList, const wxString &data)
Definition: sch_marker.cpp:143
bool m_isLegacyMarker
True if marker was deserialized from a file version < 20230121.
Definition: sch_marker.h:142
void SetIsLegacyMarker(bool isLegacyMarker=true)
Set this marker as a legacy artifact.
Definition: sch_marker.h:116
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_marker.cpp:65
SCH_LAYER_ID GetColorLayer() const
Definition: sch_marker.cpp:309
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_marker.cpp:418
std::vector< int > ViewGetLayers() const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_marker.cpp:275
wxString SerializeToString() const
Definition: sch_marker.cpp:91
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: sch_marker.cpp:430
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_marker.cpp:71
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_marker.cpp:424
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: sch_marker.cpp:355
KIGFX::COLOR4D getColor() const override
Definition: sch_marker.cpp:325
BOX2I const GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_marker.cpp:349
SCH_MARKER(std::shared_ptr< ERC_ITEM > aItem, const VECTOR2I &aPos)
Definition: sch_marker.cpp:45
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_marker.cpp:412
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Fetch a SCH_ITEM by ID.
Schematic symbol object.
Definition: sch_symbol.h:75
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction) override
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieve a color settings object that applications can read colors from.
#define _(s)
@ ERCE_UNRESOLVED_VARIABLE
A text variable could not be resolved.
Definition: erc_settings.h:73
@ ERCE_GENERIC_ERROR
Definition: erc_settings.h:102
@ ERCE_GENERIC_WARNING
Definition: erc_settings.h:101
KIID niluuid(0)
SCH_LAYER_ID
Eeschema drawing layers.
Definition: layer_ids.h:438
@ LAYER_ERC_WARN
Definition: layer_ids.h:468
@ LAYER_ERC_EXCLUSION
Definition: layer_ids.h:470
@ LAYER_ERC_ERR
Definition: layer_ids.h:469
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:483
Message panel definition file.
PGM_BASE & Pgm()
The global program "get" accessor.
Definition: pgm_base.cpp:1073
see class PGM_BASE
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE
#define SCALING_FACTOR
Factor to convert the maker unit shape to internal units:
Definition: sch_marker.cpp:42
@ SCH_SYMBOL_T
Definition: typeinfo.h:172
@ SCH_FIELD_T
Definition: typeinfo.h:150
@ SCH_LABEL_T
Definition: typeinfo.h:167
@ SCH_SHEET_T
Definition: typeinfo.h:174
@ SCH_MARKER_T
Definition: typeinfo.h:158
Functions to provide common constants and other functions to assist in making a consistent UI.