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
343void SCH_MARKER::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
344 const VECTOR2I& aOffset, bool aForceNoFill, bool aDimmed )
345{
346 PrintMarker( aSettings, aOffset );
347}
348
349
350bool SCH_MARKER::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
351{
352 return SCH_ITEM::Matches( m_rcItem->GetErrorMessage(), aSearchData );
353}
354
355
357{
358 return GetBoundingBoxMarker();
359}
360
361
362void SCH_MARKER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
363{
364 aList.emplace_back( _( "Type" ), _( "Marker" ) );
365 aList.emplace_back( _( "Violation" ), m_rcItem->GetErrorMessage() );
366
367 switch( GetSeverity() )
368 {
370 aList.emplace_back( _( "Severity" ), _( "Ignore" ) );
371 break;
373 aList.emplace_back( _( "Severity" ), _( "Warning" ) );
374 break;
376 aList.emplace_back( _( "Severity" ), _( "Error" ) );
377 break;
378 default:
379 break;
380 }
381
383 {
384 aList.emplace_back( _( "Drawing Sheet" ), wxEmptyString );
385 }
386 else
387 {
388 wxString mainText;
389 wxString auxText;
390 EDA_ITEM* mainItem = nullptr;
391 EDA_ITEM* auxItem = nullptr;
392
393 if( m_rcItem->GetMainItemID() != niluuid )
394 mainItem = aFrame->GetItem( m_rcItem->GetMainItemID() );
395
396 if( m_rcItem->GetAuxItemID() != niluuid )
397 auxItem = aFrame->GetItem( m_rcItem->GetAuxItemID() );
398
399 if( mainItem )
400 mainText = mainItem->GetItemDescription( aFrame, true );
401
402 if( auxItem )
403 auxText = auxItem->GetItemDescription( aFrame, true );
404
405 aList.emplace_back( mainText, auxText );
406 }
407
408 if( IsExcluded() )
409 aList.emplace_back( _( "Excluded" ), m_comment );
410}
411
412
414{
415 return BITMAPS::erc;
416}
417
418
419void SCH_MARKER::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
420{
421 // Marker geometry isn't user-editable
422}
423
424
426{
427 // Marker geometry isn't user-editable
428}
429
430
432{
433 // Marker geometry isn't user-editable
434}
435
436
437bool SCH_MARKER::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
438{
439 return HitTestMarker( aPosition, aAccuracy );
440}
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:111
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
void PrintMarker(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset)
Print the shape is the polygon defined in m_Corners (array of VECTOR2Is).
bool IsExcluded() const
Definition: marker_base.h:98
bool HitTestMarker(const VECTOR2I &aHitPosition, int aAccuracy) const
Test if the given VECTOR2I is within the bounds of this object.
Definition: marker_base.cpp:93
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:112
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:88
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:96
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.
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:126
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:329
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:350
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:413
static SCH_MARKER * DeserializeFromString(const SCH_SHEET_LIST &aSheetList, const wxString &data)
Definition: sch_marker.cpp:143
void Print(const SCH_RENDER_SETTINGS *aSettings, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aForceNoFill, bool aDimmed) override
Print an item.
Definition: sch_marker.cpp:343
bool m_isLegacyMarker
True if marker was deserialized from a file version < 20230121.
Definition: sch_marker.h:145
void SetIsLegacyMarker(bool isLegacyMarker=true)
Set this marker as a legacy artifact.
Definition: sch_marker.h:119
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:425
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:437
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:431
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:362
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:356
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:419
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:77
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.