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 (C) 1992-2023 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->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 determine
215 // if markers are legacy as there could be a file opened with a prior version but which has
216 // new markers - this code is called not just during schematic load, but also to match new
217 // 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 if( sheetSpecificPath.has_value() )
228 ercItem->SetSheetSpecificPath( sheetSpecificPath.value() );
229 }
230
231 if( !props[6].IsEmpty() )
232 {
233 KIID_PATH mainItemKiidPath( props[6] );
234 std::optional<SCH_SHEET_PATH> mainItemPath =
235 aSheetList.GetSheetPathByKIIDPath( mainItemKiidPath, true );
236 if( mainItemPath.has_value() )
237 {
238 if( props[7].IsEmpty() )
239 {
240 ercItem->SetItemsSheetPaths( mainItemPath.value() );
241 }
242 else
243 {
244 KIID_PATH auxItemKiidPath( props[7] );
245 std::optional<SCH_SHEET_PATH> auxItemPath =
246 aSheetList.GetSheetPathByKIIDPath( auxItemKiidPath, true );
247
248 if( auxItemPath.has_value() )
249 ercItem->SetItemsSheetPaths( mainItemPath.value(), auxItemPath.value() );
250 }
251 }
252 }
253 }
254
255 SCH_MARKER* marker = new SCH_MARKER( ercItem, markerPos );
256 marker->SetIsLegacyMarker( isLegacyMarker );
257
258 return marker;
259}
260
261
262#if defined(DEBUG)
263
264void SCH_MARKER::Show( int nestLevel, std::ostream& os ) const
265{
266 // for now, make it look like XML:
267 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << GetPos() << "/>\n";
268}
269
270#endif
271
272
273void SCH_MARKER::ViewGetLayers( int aLayers[], int& aCount ) const
274{
275 wxCHECK_RET( Schematic(), "No SCHEMATIC set for SCH_MARKER!" );
276
277 // Don't display sheet-specific markers when SCH_SHEET_PATHs do not match
278 std::shared_ptr<ERC_ITEM> ercItem = std::static_pointer_cast<ERC_ITEM>( GetRCItem() );
279
280 if( ercItem->IsSheetSpecific()
281 && ( ercItem->GetSpecificSheetPath() != Schematic()->CurrentSheet() ) )
282 {
283 aCount = 0;
284 return;
285 }
286
287 aCount = 2;
288
289 if( IsExcluded() )
290 {
291 aLayers[0] = LAYER_ERC_EXCLUSION;
292 }
293 else
294 {
295 switch( Schematic()->ErcSettings().GetSeverity( m_rcItem->GetErrorCode() ) )
296 {
297 default:
298 case SEVERITY::RPT_SEVERITY_ERROR: aLayers[0] = LAYER_ERC_ERR; break;
299 case SEVERITY::RPT_SEVERITY_WARNING: aLayers[0] = LAYER_ERC_WARN; break;
300 }
301 }
302
303 aLayers[1] = LAYER_SELECTION_SHADOWS;
304}
305
306
308{
309 if( IsExcluded() )
310 return LAYER_ERC_EXCLUSION;
311
312 wxCHECK_MSG( Schematic(), LAYER_ERC_ERR, "No SCHEMATIC set for SCH_MARKER!" );
313
314 switch( Schematic()->ErcSettings().GetSeverity( m_rcItem->GetErrorCode() ) )
315 {
316 default:
317 case SEVERITY::RPT_SEVERITY_ERROR: return LAYER_ERC_ERR;
318 case SEVERITY::RPT_SEVERITY_WARNING: return LAYER_ERC_WARN;
319 }
320}
321
322
324{
326 return colors->GetColor( GetColorLayer() );
327}
328
329
331{
332 if( IsExcluded() )
334
335 ERC_ITEM* item = static_cast<ERC_ITEM*>( m_rcItem.get() );
336
337 return Schematic()->ErcSettings().GetSeverity( item->GetErrorCode() );
338}
339
340
341void SCH_MARKER::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
342 const VECTOR2I& aOffset, bool aForceNoFill, bool aDimmed )
343{
344 PrintMarker( aSettings, aOffset );
345}
346
347
348bool SCH_MARKER::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
349{
350 return SCH_ITEM::Matches( m_rcItem->GetErrorMessage(), aSearchData );
351}
352
353
355{
356 return GetBoundingBoxMarker();
357}
358
359
360void SCH_MARKER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
361{
362 aList.emplace_back( _( "Type" ), _( "Marker" ) );
363 aList.emplace_back( _( "Violation" ), m_rcItem->GetErrorMessage() );
364
365 switch( GetSeverity() )
366 {
368 aList.emplace_back( _( "Severity" ), _( "Ignore" ) );
369 break;
371 aList.emplace_back( _( "Severity" ), _( "Warning" ) );
372 break;
374 aList.emplace_back( _( "Severity" ), _( "Error" ) );
375 break;
376 default:
377 break;
378 }
379
381 {
382 aList.emplace_back( _( "Drawing Sheet" ), wxEmptyString );
383 }
384 else
385 {
386 wxString mainText;
387 wxString auxText;
388 EDA_ITEM* mainItem = nullptr;
389 EDA_ITEM* auxItem = nullptr;
390
391 if( m_rcItem->GetMainItemID() != niluuid )
392 mainItem = aFrame->GetItem( m_rcItem->GetMainItemID() );
393
394 if( m_rcItem->GetAuxItemID() != niluuid )
395 auxItem = aFrame->GetItem( m_rcItem->GetAuxItemID() );
396
397 if( mainItem )
398 mainText = mainItem->GetItemDescription( aFrame, true );
399
400 if( auxItem )
401 auxText = auxItem->GetItemDescription( aFrame, true );
402
403 aList.emplace_back( mainText, auxText );
404 }
405
406 if( IsExcluded() )
407 aList.emplace_back( _( "Excluded" ), m_comment );
408}
409
410
412{
413 return BITMAPS::erc;
414}
415
416
417void SCH_MARKER::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
418{
419 // Marker geometry isn't user-editable
420}
421
422
424{
425 // Marker geometry isn't user-editable
426}
427
428
430{
431 // Marker geometry isn't user-editable
432}
433
434
435bool SCH_MARKER::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
436{
437 return HitTestMarker( aPosition, aAccuracy );
438}
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:108
const KIID m_Uuid
Definition: eda_item.h:489
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:377
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:79
static std::shared_ptr< ERC_ITEM > Create(int aErrorCode)
Constructs an ERC_ITEM for the given error code.
Definition: erc_item.cpp:303
SEVERITY GetSeverity(int aErrorCode) const
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Definition: kiid.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:90
std::shared_ptr< RC_ITEM > GetRCItem() const
Definition: marker_base.h:112
int m_scalingFactor
Definition: marker_base.h:143
wxString m_comment
Definition: marker_base.h:140
const VECTOR2I & GetPos() const
Definition: marker_base.h:88
VECTOR2I m_Pos
position of the marker
Definition: marker_base.h:135
@ MARKER_DRAWING_SHEET
Definition: marker_base.h:56
MARKER_T m_markerType
Definition: marker_base.h:138
bool m_excluded
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:96
BOX2I m_shapeBoundingBox
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:142
int GetErrorCode() const
Definition: rc_item.h:153
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Definition: schematic.h:108
ERC_SETTINGS & ErcSettings() const
Definition: schematic.cpp:304
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:166
SCHEMATIC * Schematic() const
Searches 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:568
void SwapFlags(SCH_ITEM *aItem)
Swap the non-temp and non-edit flags.
Definition: sch_item.cpp:354
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:181
SEVERITY GetSeverity() const override
Definition: sch_marker.cpp:330
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_marker.cpp:273
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:348
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:411
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:341
bool m_isLegacyMarker
Definition: sch_marker.h:142
void SetIsLegacyMarker(bool isLegacyMarker=true)
Sets this marker as a legacy artifact.
Definition: sch_marker.h:117
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:307
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_marker.cpp:423
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:435
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:429
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:360
KIGFX::COLOR4D getColor() const override
Definition: sch_marker.cpp:323
BOX2I const GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_marker.cpp:354
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:417
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:106
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction) override
COLOR_SETTINGS * GetColorSettings(const wxString &aName="user")
Retrieves 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:75
@ ERCE_GENERIC_ERROR
Definition: erc_settings.h:103
@ ERCE_GENERIC_WARNING
Definition: erc_settings.h:102
KIID niluuid(0)
SCH_LAYER_ID
Eeschema drawing layers.
Definition: layer_ids.h:354
@ LAYER_ERC_WARN
Definition: layer_ids.h:384
@ LAYER_ERC_EXCLUSION
Definition: layer_ids.h:386
@ LAYER_ERC_ERR
Definition: layer_ids.h:385
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:397
Message panel definition file.
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1059
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.