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_MARKER* item = static_cast<SCH_MARKER*>( aItem );
74
75 std::swap( m_isLegacyMarker, item->m_isLegacyMarker );
76 std::swap( m_Pos, item->m_Pos );
77
78 std::swap( m_markerType, item->m_markerType );
79 std::swap( m_excluded, item->m_excluded );
80 std::swap( m_rcItem, item->m_rcItem );
81
82 std::swap( m_scalingFactor, item->m_scalingFactor );
83 std::swap( m_shapeBoundingBox, item->m_shapeBoundingBox );
84
85 // TODO: isn't this going to swap all the stuff above a second time?
86 std::swap( *((SCH_MARKER*) this), *((SCH_MARKER*) aItem ) );
87}
88
89
91{
92 std::shared_ptr<ERC_ITEM> erc = std::static_pointer_cast<ERC_ITEM>( m_rcItem );
93 wxString sheetSpecificPath, mainItemPath, auxItemPath;
94
95 if( erc->IsSheetSpecific() )
96 sheetSpecificPath = erc->GetSpecificSheetPath().Path().AsString();
97
98 if( erc->MainItemHasSheetPath() )
99 mainItemPath = erc->GetMainItemSheetPath().Path().AsString();
100
101 if( erc->AuxItemHasSheetPath() )
102 auxItemPath = erc->GetAuxItemSheetPath().Path().AsString();
103
104 if( m_rcItem->GetErrorCode() == ERCE_GENERIC_WARNING
105 || m_rcItem->GetErrorCode() == ERCE_GENERIC_ERROR
106 || m_rcItem->GetErrorCode() == ERCE_UNRESOLVED_VARIABLE )
107 {
108 SCH_ITEM* sch_item = Schematic()->ResolveItem( erc->GetMainItemID() );
109 SCH_ITEM* parent = static_cast<SCH_ITEM*>( sch_item->GetParent() );
110 EDA_TEXT* text_item = dynamic_cast<EDA_TEXT*>( sch_item );
111
112 // SCH_FIELDs and SCH_ITEMs inside LIB_SYMBOLs don't have persistent KIIDs. So the
113 // exclusion must refer to the parent's KIID, and include the text of the original text
114 // item for later look-up.
115
116 if( parent && parent->IsType( { SCH_SYMBOL_T, SCH_LABEL_T, SCH_SHEET_T } ) )
117 {
118 if( text_item ) // should always be true, but Coverity doesn't know that
119 {
120 return wxString::Format( wxT( "%s|%d|%d|%s|%s|%s|%s|%s" ),
121 m_rcItem->GetSettingsKey(),
122 m_Pos.x,
123 m_Pos.y,
124 parent->m_Uuid.AsString(),
125 text_item->GetText(),
126 sheetSpecificPath,
127 mainItemPath,
128 wxEmptyString );
129 }
130 }
131 }
132
133 return wxString::Format( wxT( "%s|%d|%d|%s|%s|%s|%s|%s" ),
134 m_rcItem->GetSettingsKey(),
135 m_Pos.x,
136 m_Pos.y,
137 m_rcItem->GetMainItemID().AsString(),
138 m_rcItem->GetAuxItemID().AsString(),
139 sheetSpecificPath,
140 mainItemPath,
141 auxItemPath );
142}
143
144
146 const wxString& data )
147{
148 wxArrayString props = wxSplit( data, '|' );
149 VECTOR2I markerPos( (int) strtol( props[1].c_str(), nullptr, 10 ),
150 (int) strtol( props[2].c_str(), nullptr, 10 ) );
151
152 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( props[0] );
153
154 if( !ercItem )
155 return nullptr;
156
157 if( ercItem->GetErrorCode() == ERCE_GENERIC_WARNING
158 || ercItem->GetErrorCode() == ERCE_GENERIC_ERROR
159 || ercItem->GetErrorCode() == ERCE_UNRESOLVED_VARIABLE )
160 {
161 // SCH_FIELDs and SCH_ITEMs inside LIB_SYMBOLs don't have persistent KIIDs. So the
162 // exclusion will contain the parent's KIID in prop[3], and the text of the original
163 // text item in prop[4].
164
165 if( !props[4].IsEmpty() )
166 {
167 KIID uuid = niluuid;
168 SCH_ITEM* parent = aSheetList.ResolveItem( KIID( props[3] ) );
169
170 // Check fields and pins for a match
171 parent->RunOnChildren(
172 [&]( SCH_ITEM* child )
173 {
174 if( EDA_TEXT* text_item = dynamic_cast<EDA_TEXT*>( child ) )
175 {
176 if( text_item->GetText() == props[4] )
177 uuid = child->m_Uuid;
178 }
179 },
180 RECURSE_MODE::NO_RECURSE );
181
182 // If it's a symbol, we must also check non-overridden LIB_SYMBOL text children
183 if( uuid == niluuid && parent->Type() == SCH_SYMBOL_T )
184 {
185 static_cast<SCH_SYMBOL*>( parent )->GetLibSymbolRef()->RunOnChildren(
186 [&]( SCH_ITEM* child )
187 {
188 if( child->Type() == SCH_FIELD_T )
189 {
190 // Match only on SCH_SYMBOL fields, not LIB_SYMBOL fields.
191 }
192 else if( EDA_TEXT* text_item = dynamic_cast<EDA_TEXT*>( child ) )
193 {
194 if( text_item->GetText() == props[4] )
195 uuid = child->m_Uuid;
196 }
197 },
198 RECURSE_MODE::NO_RECURSE );
199 }
200
201 if( uuid != niluuid )
202 ercItem->SetItems( uuid );
203 else
204 return nullptr;
205 }
206 else
207 {
208 ercItem->SetItems( KIID( props[3] ) );
209 }
210 }
211 else
212 {
213 ercItem->SetItems( KIID( props[3] ), KIID( props[4] ) );
214 }
215
216 bool isLegacyMarker = true;
217
218 // Deserialize sheet / item specific paths - we are not able to use the file version to
219 // determine if markers are legacy as there could be a file opened with a prior version
220 // but which has new markers - this code is called not just during schematic load, but
221 // also to match new ERC exceptions to exclusions.
222 if( props.size() == 8 )
223 {
224 isLegacyMarker = false;
225
226 if( !props[5].IsEmpty() )
227 {
228 KIID_PATH sheetSpecificKiidPath( props[5] );
229 std::optional<SCH_SHEET_PATH> sheetSpecificPath =
230 aSheetList.GetSheetPathByKIIDPath( sheetSpecificKiidPath, true );
231
232 if( sheetSpecificPath.has_value() )
233 ercItem->SetSheetSpecificPath( sheetSpecificPath.value() );
234 }
235
236 if( !props[6].IsEmpty() )
237 {
238 KIID_PATH mainItemKiidPath( props[6] );
239 std::optional<SCH_SHEET_PATH> mainItemPath =
240 aSheetList.GetSheetPathByKIIDPath( mainItemKiidPath, true );
241
242 if( mainItemPath.has_value() )
243 {
244 if( props[7].IsEmpty() )
245 {
246 ercItem->SetItemsSheetPaths( mainItemPath.value() );
247 }
248 else
249 {
250 KIID_PATH auxItemKiidPath( props[7] );
251 std::optional<SCH_SHEET_PATH> auxItemPath =
252 aSheetList.GetSheetPathByKIIDPath( auxItemKiidPath, true );
253
254 if( auxItemPath.has_value() )
255 ercItem->SetItemsSheetPaths( mainItemPath.value(), auxItemPath.value() );
256 }
257 }
258 }
259 }
260
261 SCH_MARKER* marker = new SCH_MARKER( std::move( ercItem ), markerPos );
262 marker->SetIsLegacyMarker( isLegacyMarker );
263
264 return marker;
265}
266
267
268#if defined(DEBUG)
269
270void SCH_MARKER::Show( int nestLevel, std::ostream& os ) const
271{
272 // for now, make it look like XML:
273 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << GetPos() << "/>\n";
274}
275
276#endif
277
278
279std::vector<int> SCH_MARKER::ViewGetLayers() const
280{
281 wxCHECK2_MSG( Schematic(), return {}, "No SCHEMATIC set for SCH_MARKER!" );
282
283 // Don't display sheet-specific markers when SCH_SHEET_PATHs do not match
284 std::shared_ptr<ERC_ITEM> ercItem = std::static_pointer_cast<ERC_ITEM>( GetRCItem() );
285
286 if( ercItem->IsSheetSpecific()
287 && ( ercItem->GetSpecificSheetPath() != Schematic()->CurrentSheet() ) )
288 {
289 return {};
290 }
291
292 std::vector<int> layers( 2 );
293
294 if( IsExcluded() )
295 {
296 layers[0] = LAYER_ERC_EXCLUSION;
297 }
298 else
299 {
300 switch( Schematic()->ErcSettings().GetSeverity( m_rcItem->GetErrorCode() ) )
301 {
302 default:
303 case SEVERITY::RPT_SEVERITY_ERROR: layers[0] = LAYER_ERC_ERR; break;
304 case SEVERITY::RPT_SEVERITY_WARNING: layers[0] = LAYER_ERC_WARN; break;
305 }
306 }
307
308 layers[1] = LAYER_SELECTION_SHADOWS;
309 return layers;
310}
311
312
314{
315 if( IsExcluded() )
316 return LAYER_ERC_EXCLUSION;
317
318 wxCHECK_MSG( Schematic(), LAYER_ERC_ERR, "No SCHEMATIC set for SCH_MARKER!" );
319
320 switch( Schematic()->ErcSettings().GetSeverity( m_rcItem->GetErrorCode() ) )
321 {
322 default:
323 case SEVERITY::RPT_SEVERITY_ERROR: return LAYER_ERC_ERR;
324 case SEVERITY::RPT_SEVERITY_WARNING: return LAYER_ERC_WARN;
325 }
326}
327
328
330{
331 return ::GetColorSettings( DEFAULT_THEME )->GetColor( GetColorLayer() );
332}
333
334
336{
337 if( IsExcluded() )
339
340 ERC_ITEM* item = static_cast<ERC_ITEM*>( m_rcItem.get() );
341
342 return Schematic()->ErcSettings().GetSeverity( item->GetErrorCode() );
343}
344
345
346bool SCH_MARKER::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
347{
348 return SCH_ITEM::Matches( m_rcItem->GetErrorMessage(), aSearchData );
349}
350
351
353{
354 return GetBoundingBoxMarker();
355}
356
357
358void SCH_MARKER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
359{
360 aList.emplace_back( _( "Type" ), _( "Marker" ) );
361 aList.emplace_back( _( "Violation" ), m_rcItem->GetErrorMessage() );
362
363 switch( GetSeverity() )
364 {
366 aList.emplace_back( _( "Severity" ), _( "Ignore" ) );
367 break;
369 aList.emplace_back( _( "Severity" ), _( "Warning" ) );
370 break;
372 aList.emplace_back( _( "Severity" ), _( "Error" ) );
373 break;
374 default:
375 break;
376 }
377
379 {
380 aList.emplace_back( _( "Drawing Sheet" ), wxEmptyString );
381 }
382 else
383 {
384 wxString mainText;
385 wxString auxText;
386 EDA_ITEM* mainItem = nullptr;
387 EDA_ITEM* auxItem = nullptr;
388
389 if( m_rcItem->GetMainItemID() != niluuid )
390 mainItem = aFrame->ResolveItem( m_rcItem->GetMainItemID() );
391
392 if( m_rcItem->GetAuxItemID() != niluuid )
393 auxItem = aFrame->ResolveItem( m_rcItem->GetAuxItemID() );
394
395 if( mainItem )
396 mainText = mainItem->GetItemDescription( aFrame, true );
397
398 if( auxItem )
399 auxText = auxItem->GetItemDescription( aFrame, true );
400
401 aList.emplace_back( mainText, auxText );
402 }
403
404 if( IsExcluded() )
405 aList.emplace_back( _( "Excluded" ), m_comment );
406}
407
408
410{
411 return BITMAPS::erc;
412}
413
414
415void SCH_MARKER::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
416{
417 // Marker geometry isn't user-editable
418}
419
420
422{
423 // Marker geometry isn't user-editable
424}
425
426
428{
429 // Marker geometry isn't user-editable
430}
431
432
433bool SCH_MARKER::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
434{
435 return HitTestMarker( aPosition, aAccuracy );
436}
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
The base class for create windows for drawing purpose.
virtual EDA_ITEM * ResolveItem(const KIID &aId, bool aAllowNullptrReturn=false) 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:98
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
Definition: eda_item.cpp:144
const KIID m_Uuid
Definition: eda_item.h:516
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:110
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:401
EDA_ITEM * GetParent() const
Definition: eda_item.h:112
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:302
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:88
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:148
wxString m_comment
User supplied comment.
Definition: marker_base.h:145
const VECTOR2I & GetPos() const
Definition: marker_base.h:83
VECTOR2I m_Pos
Position of the marker.
Definition: marker_base.h:140
@ MARKER_DRAWING_SHEET
Definition: marker_base.h:56
MARKER_T m_markerType
The type of marker.
Definition: marker_base.h:143
bool m_excluded
User has excluded this specific error.
Definition: marker_base.h:144
std::shared_ptr< RC_ITEM > m_rcItem
Definition: marker_base.h:146
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:150
BOX2I GetBoundingBoxMarker() const
Return the orthogonal, bounding box of this object for display purposes.
int GetErrorCode() const
Definition: rc_item.h:154
SCH_ITEM * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
Definition: schematic.h:134
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:363
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:168
virtual void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode)
Definition: sch_item.h:602
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:246
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:183
SEVERITY GetSeverity() const override
Definition: sch_marker.cpp:335
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:346
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:409
static SCH_MARKER * DeserializeFromString(const SCH_SHEET_LIST &aSheetList, const wxString &data)
Definition: sch_marker.cpp:145
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:114
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:313
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_marker.cpp:421
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:279
wxString SerializeToString() const
Definition: sch_marker.cpp:90
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:433
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:427
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:358
KIGFX::COLOR4D getColor() const override
Definition: sch_marker.cpp:329
BOX2I const GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_marker.cpp:352
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:415
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 * ResolveItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr, bool aAllowNullptrReturn=false) const
Fetch a SCH_ITEM by ID.
Schematic symbol object.
Definition: sch_symbol.h:75
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode) override
#define _(s)
@ ERCE_UNRESOLVED_VARIABLE
A text variable could not be resolved.
Definition: erc_settings.h:73
@ ERCE_GENERIC_ERROR
Definition: erc_settings.h:99
@ ERCE_GENERIC_WARNING
Definition: erc_settings.h:98
KIID niluuid(0)
SCH_LAYER_ID
Eeschema drawing layers.
Definition: layer_ids.h:439
@ LAYER_ERC_WARN
Definition: layer_ids.h:469
@ LAYER_ERC_EXCLUSION
Definition: layer_ids.h:471
@ LAYER_ERC_ERR
Definition: layer_ids.h:470
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:484
Message panel definition file.
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
#define DEFAULT_THEME
@ SCH_SYMBOL_T
Definition: typeinfo.h:173
@ SCH_FIELD_T
Definition: typeinfo.h:151
@ SCH_LABEL_T
Definition: typeinfo.h:168
@ SCH_SHEET_T
Definition: typeinfo.h:176
@ SCH_MARKER_T
Definition: typeinfo.h:159
Functions to provide common constants and other functions to assist in making a consistent UI.