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 {
108 SCH_ITEM* sch_item = Schematic()->GetItem( 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->IsType( { SCH_SYMBOL_T, SCH_LABEL_T, SCH_SHEET_T } ) )
117 {
118 return wxString::Format( wxT( "%s|%d|%d|%s|%s|%s|%s|%s" ),
119 m_rcItem->GetSettingsKey(),
120 m_Pos.x,
121 m_Pos.y,
122 parent->m_Uuid.AsString(),
123 text_item->GetText(),
124 sheetSpecificPath,
125 mainItemPath,
126 wxEmptyString );
127 }
128 else
129 {
130 return wxString::Format( wxT( "%s|%d|%d|%s|%s|%s|%s|%s" ),
131 m_rcItem->GetSettingsKey(),
132 m_Pos.x,
133 m_Pos.y,
134 sch_item->m_Uuid.AsString(),
135 wxEmptyString,
136 sheetSpecificPath,
137 mainItemPath,
138 wxEmptyString );
139 }
140 }
141 else
142 {
143 return wxString::Format( wxT( "%s|%d|%d|%s|%s|%s|%s|%s" ),
144 m_rcItem->GetSettingsKey(),
145 m_Pos.x,
146 m_Pos.y,
147 m_rcItem->GetMainItemID().AsString(),
148 m_rcItem->GetAuxItemID().AsString(),
149 sheetSpecificPath,
150 mainItemPath,
151 auxItemPath );
152 }
153}
154
155
157 const wxString& data )
158{
159 wxArrayString props = wxSplit( data, '|' );
160 VECTOR2I markerPos( (int) strtol( props[1].c_str(), nullptr, 10 ),
161 (int) strtol( props[2].c_str(), nullptr, 10 ) );
162
163 std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( props[0] );
164
165 if( !ercItem )
166 return nullptr;
167
168 if( ercItem->GetErrorCode() == ERCE_GENERIC_WARNING
169 || ercItem->GetErrorCode() == ERCE_GENERIC_ERROR )
170 {
171 // SCH_FIELDs and SCH_ITEMs inside LIB_SYMBOLs don't have persistent KIIDs. So the
172 // exclusion will contain the parent's KIID in prop[3], and the text of the original
173 // text item in prop[4].
174
175 if( !props[4].IsEmpty() )
176 {
177 KIID uuid = niluuid;
178 SCH_ITEM* parent = aSheetList.GetItem( KIID( props[3] ) );
179
180 // Check fields and pins for a match
181 parent->RunOnChildren(
182 [&]( SCH_ITEM* child )
183 {
184 if( EDA_TEXT* text_item = dynamic_cast<EDA_TEXT*>( child ) )
185 {
186 if( text_item->GetText() == props[4] )
187 uuid = child->m_Uuid;
188 }
189 } );
190
191 // If it's a symbol, we must also check non-overridden LIB_SYMBOL text children
192 if( uuid == niluuid && parent->Type() == SCH_SYMBOL_T )
193 {
194 static_cast<SCH_SYMBOL*>( parent )->GetLibSymbolRef()->RunOnChildren(
195 [&]( SCH_ITEM* child )
196 {
197 if( child->Type() == SCH_FIELD_T )
198 {
199 // Match only on SCH_SYMBOL fields, not LIB_SYMBOL fields.
200 }
201 else if( EDA_TEXT* text_item = dynamic_cast<EDA_TEXT*>( child ) )
202 {
203 if( text_item->GetText() == props[4] )
204 uuid = child->m_Uuid;
205 }
206 } );
207 }
208
209 if( uuid != niluuid )
210 ercItem->SetItems( uuid );
211 else
212 return nullptr;
213 }
214 else
215 {
216 ercItem->SetItems( KIID( props[3] ) );
217 }
218 }
219 else
220 {
221 ercItem->SetItems( KIID( props[3] ), KIID( props[4] ) );
222 }
223
224 bool isLegacyMarker = true;
225
226 // Deserialize sheet / item specific paths - we are not able to use the file version to determine
227 // if markers are legacy as there could be a file opened with a prior version but which has
228 // new markers - this code is called not just during schematic load, but also to match new
229 // ERC exceptions to exclusions.
230 if( props.size() == 8 )
231 {
232 isLegacyMarker = false;
233
234 if( !props[5].IsEmpty() )
235 {
236 KIID_PATH sheetSpecificKiidPath( props[5] );
237 std::optional<SCH_SHEET_PATH> sheetSpecificPath =
238 aSheetList.GetSheetPathByKIIDPath( sheetSpecificKiidPath, true );
239 if( sheetSpecificPath.has_value() )
240 ercItem->SetSheetSpecificPath( sheetSpecificPath.value() );
241 }
242
243 if( !props[6].IsEmpty() )
244 {
245 KIID_PATH mainItemKiidPath( props[6] );
246 std::optional<SCH_SHEET_PATH> mainItemPath =
247 aSheetList.GetSheetPathByKIIDPath( mainItemKiidPath, true );
248 if( mainItemPath.has_value() )
249 {
250 if( props[7].IsEmpty() )
251 {
252 ercItem->SetItemsSheetPaths( mainItemPath.value() );
253 }
254 else
255 {
256 KIID_PATH auxItemKiidPath( props[7] );
257 std::optional<SCH_SHEET_PATH> auxItemPath =
258 aSheetList.GetSheetPathByKIIDPath( auxItemKiidPath, true );
259
260 if( auxItemPath.has_value() )
261 ercItem->SetItemsSheetPaths( mainItemPath.value(), auxItemPath.value() );
262 }
263 }
264 }
265 }
266
267 SCH_MARKER* marker = new SCH_MARKER( ercItem, markerPos );
268 marker->SetIsLegacyMarker( isLegacyMarker );
269
270 return marker;
271}
272
273
274#if defined(DEBUG)
275
276void SCH_MARKER::Show( int nestLevel, std::ostream& os ) const
277{
278 // for now, make it look like XML:
279 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() << GetPos() << "/>\n";
280}
281
282#endif
283
284
285void SCH_MARKER::ViewGetLayers( int aLayers[], int& aCount ) const
286{
287 wxCHECK_RET( Schematic(), "No SCHEMATIC set for SCH_MARKER!" );
288
289 // Don't display sheet-specific markers when SCH_SHEET_PATHs do not match
290 std::shared_ptr<ERC_ITEM> ercItem = std::static_pointer_cast<ERC_ITEM>( GetRCItem() );
291
292 if( ercItem->IsSheetSpecific()
293 && ( ercItem->GetSpecificSheetPath() != Schematic()->CurrentSheet() ) )
294 {
295 aCount = 0;
296 return;
297 }
298
299 aCount = 2;
300
301 if( IsExcluded() )
302 {
303 aLayers[0] = LAYER_ERC_EXCLUSION;
304 }
305 else
306 {
307 switch( Schematic()->ErcSettings().GetSeverity( m_rcItem->GetErrorCode() ) )
308 {
309 default:
310 case SEVERITY::RPT_SEVERITY_ERROR: aLayers[0] = LAYER_ERC_ERR; break;
311 case SEVERITY::RPT_SEVERITY_WARNING: aLayers[0] = LAYER_ERC_WARN; break;
312 }
313 }
314
315 aLayers[1] = LAYER_SELECTION_SHADOWS;
316}
317
318
320{
321 if( IsExcluded() )
322 return LAYER_ERC_EXCLUSION;
323
324 wxCHECK_MSG( Schematic(), LAYER_ERC_ERR, "No SCHEMATIC set for SCH_MARKER!" );
325
326 switch( Schematic()->ErcSettings().GetSeverity( m_rcItem->GetErrorCode() ) )
327 {
328 default:
329 case SEVERITY::RPT_SEVERITY_ERROR: return LAYER_ERC_ERR;
330 case SEVERITY::RPT_SEVERITY_WARNING: return LAYER_ERC_WARN;
331 }
332}
333
334
336{
338 return colors->GetColor( GetColorLayer() );
339}
340
341
343{
344 if( IsExcluded() )
346
347 ERC_ITEM* item = static_cast<ERC_ITEM*>( m_rcItem.get() );
348
349 return Schematic()->ErcSettings().GetSeverity( item->GetErrorCode() );
350}
351
352
353void SCH_MARKER::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
354 const VECTOR2I& aOffset, bool aForceNoFill, bool aDimmed )
355{
356 PrintMarker( aSettings, aOffset );
357}
358
359
360bool SCH_MARKER::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
361{
362 return SCH_ITEM::Matches( m_rcItem->GetErrorMessage(), aSearchData );
363}
364
365
367{
368 return GetBoundingBoxMarker();
369}
370
371
372void SCH_MARKER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
373{
374 aList.emplace_back( _( "Type" ), _( "Marker" ) );
375 aList.emplace_back( _( "Violation" ), m_rcItem->GetErrorMessage() );
376
377 switch( GetSeverity() )
378 {
380 aList.emplace_back( _( "Severity" ), _( "Ignore" ) );
381 break;
383 aList.emplace_back( _( "Severity" ), _( "Warning" ) );
384 break;
386 aList.emplace_back( _( "Severity" ), _( "Error" ) );
387 break;
388 default:
389 break;
390 }
391
393 {
394 aList.emplace_back( _( "Drawing Sheet" ), wxEmptyString );
395 }
396 else
397 {
398 wxString mainText;
399 wxString auxText;
400 EDA_ITEM* mainItem = nullptr;
401 EDA_ITEM* auxItem = nullptr;
402
403 if( m_rcItem->GetMainItemID() != niluuid )
404 mainItem = aFrame->GetItem( m_rcItem->GetMainItemID() );
405
406 if( m_rcItem->GetAuxItemID() != niluuid )
407 auxItem = aFrame->GetItem( m_rcItem->GetAuxItemID() );
408
409 if( mainItem )
410 mainText = mainItem->GetItemDescription( aFrame, true );
411
412 if( auxItem )
413 auxText = auxItem->GetItemDescription( aFrame, true );
414
415 aList.emplace_back( mainText, auxText );
416 }
417
418 if( IsExcluded() )
419 aList.emplace_back( _( "Excluded" ), m_comment );
420}
421
422
424{
425 return BITMAPS::erc;
426}
427
428
429void SCH_MARKER::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
430{
431 // Marker geometry isn't user-editable
432}
433
434
436{
437 // Marker geometry isn't user-editable
438}
439
440
442{
443 // Marker geometry isn't user-editable
444}
445
446
447bool SCH_MARKER::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
448{
449 return HitTestMarker( aPosition, aAccuracy );
450}
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:294
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:342
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:285
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:360
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:423
static SCH_MARKER * DeserializeFromString(const SCH_SHEET_LIST &aSheetList, const wxString &data)
Definition: sch_marker.cpp:156
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:353
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:319
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_marker.cpp:435
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:447
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:441
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:372
KIGFX::COLOR4D getColor() const override
Definition: sch_marker.cpp:335
BOX2I const GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_marker.cpp:366
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:429
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:105
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_GENERIC_ERROR
Definition: erc_settings.h:101
@ ERCE_GENERIC_WARNING
Definition: erc_settings.h:100
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.