KiCad PCB EDA Suite
Loading...
Searching...
No Matches
rc_item.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24
25#include <wx/wupdlock.h>
26#include <wx/dataview.h>
27#include <wx/settings.h>
28#include <widgets/ui_common.h>
29#include <marker_base.h>
30#include <eda_draw_frame.h>
31#include <rc_item.h>
32#include <rc_json_schema.h>
33#include <eda_item.h>
34#include <base_units.h>
35
36#define WX_DATAVIEW_WINDOW_PADDING 6
37
38
40{
41 if( m_errorMessage.IsEmpty() )
42 return GetErrorText();
43 else
44 return m_errorMessage;
45}
46
47
48static wxString showCoord( UNITS_PROVIDER* aUnitsProvider, const VECTOR2I& aPos )
49{
50 return wxString::Format( wxT( "@(%s, %s)" ),
51 aUnitsProvider->MessageTextFromValue( aPos.x ),
52 aUnitsProvider->MessageTextFromValue( aPos.y ) );
53}
54
55
57{
58 m_ids.push_back( aItem->m_Uuid );
59}
60
61
62void RC_ITEM::SetItems( const EDA_ITEM* aItem, const EDA_ITEM* bItem,
63 const EDA_ITEM* cItem, const EDA_ITEM* dItem )
64{
65 m_ids.clear();
66
67 if( aItem )
68 m_ids.push_back( aItem->m_Uuid );
69
70 if( bItem )
71 m_ids.push_back( bItem->m_Uuid );
72
73 if( cItem )
74 m_ids.push_back( cItem->m_Uuid );
75
76 if( dItem )
77 m_ids.push_back( dItem->m_Uuid );
78}
79
80
82{
83 wxString severity;
84
85 switch( aSeverity )
86 {
87 case RPT_SEVERITY_ERROR: severity = wxS( "error" ); break;
88 case RPT_SEVERITY_WARNING: severity = wxS( "warning" ); break;
89 case RPT_SEVERITY_ACTION: severity = wxS( "action" ); break;
90 case RPT_SEVERITY_INFO: severity = wxS( "info" ); break;
91 case RPT_SEVERITY_EXCLUSION: severity = wxS( "exclusion" ); break;
92 case RPT_SEVERITY_DEBUG: severity = wxS( "debug" ); break;
93 default:;
94 };
95
96 return severity;
97}
98
99
100wxString RC_ITEM::ShowReport( UNITS_PROVIDER* aUnitsProvider, SEVERITY aSeverity,
101 const std::map<KIID, EDA_ITEM*>& aItemMap ) const
102{
103 wxString severity = getSeverityString( aSeverity );
104
105 if( m_parent && m_parent->IsExcluded() )
106 severity += wxT( " (excluded)" );
107
108 EDA_ITEM* mainItem = nullptr;
109 EDA_ITEM* auxItem = nullptr;
110
111 auto ii = aItemMap.find( GetMainItemID() );
112
113 if( ii != aItemMap.end() )
114 mainItem = ii->second;
115
116 ii = aItemMap.find( GetAuxItemID() );
117
118 if( ii != aItemMap.end() )
119 auxItem = ii->second;
120
121 // Note: some customers machine-process these. So:
122 // 1) don't translate
123 // 2) try not to re-order or change syntax
124 // 3) report settings key (which should be more stable) in addition to message
125
126 wxString msg;
127
128 if( mainItem && auxItem )
129 {
130 msg.Printf( wxT( "[%s]: %s\n %s; %s\n %s: %s\n %s: %s\n" ),
134 severity,
135 showCoord( aUnitsProvider, mainItem->GetPosition()),
136 mainItem->GetItemDescription( aUnitsProvider, true ),
137 showCoord( aUnitsProvider, auxItem->GetPosition()),
138 auxItem->GetItemDescription( aUnitsProvider, true ) );
139 }
140 else if( mainItem )
141 {
142 msg.Printf( wxT( "[%s]: %s\n %s; %s\n %s: %s\n" ),
146 severity,
147 showCoord( aUnitsProvider, mainItem->GetPosition()),
148 mainItem->GetItemDescription( aUnitsProvider, true ) );
149 }
150 else
151 {
152 msg.Printf( wxT( "[%s]: %s\n %s; %s\n" ),
156 severity );
157 }
158
159 if( m_parent && m_parent->IsExcluded() && !m_parent->GetComment().IsEmpty() )
160 msg += wxString::Format( wxS( " %s\n" ), m_parent->GetComment() );
161
162 return msg;
163}
164
165
167 SEVERITY aSeverity, const std::map<KIID, EDA_ITEM*>& aItemMap ) const
168{
169 aViolation.severity = getSeverityString( aSeverity );
170 aViolation.description = GetErrorMessage();
171 aViolation.type = GetSettingsKey();
172 aViolation.excluded = ( m_parent && m_parent->IsExcluded() );
173
174 EDA_ITEM* mainItem = nullptr;
175 EDA_ITEM* auxItem = nullptr;
176
177 auto ii = aItemMap.find( GetMainItemID() );
178
179 if( ii != aItemMap.end() )
180 mainItem = ii->second;
181
182 ii = aItemMap.find( GetAuxItemID() );
183
184 if( ii != aItemMap.end() )
185 auxItem = ii->second;
186
187 if( mainItem )
188 {
190 item.description = mainItem->GetItemDescription( aUnitsProvider, true );
191 item.uuid = mainItem->m_Uuid.AsString();
192 item.pos.x = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
193 aUnitsProvider->GetUserUnits(),
194 mainItem->GetPosition().x );
195 item.pos.y = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
196 aUnitsProvider->GetUserUnits(),
197 mainItem->GetPosition().y );
198 aViolation.items.emplace_back( item );
199 }
200
201 if( auxItem )
202 {
204 item.description = auxItem->GetItemDescription( aUnitsProvider, true );
205 item.uuid = auxItem->m_Uuid.AsString();
206 item.pos.x = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
207 aUnitsProvider->GetUserUnits(),
208 auxItem->GetPosition().x );
209 item.pos.y = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
210 aUnitsProvider->GetUserUnits(),
211 auxItem->GetPosition().y );
212 aViolation.items.emplace_back( item );
213 }
214}
215
216
217KIID RC_TREE_MODEL::ToUUID( wxDataViewItem aItem )
218{
219 const RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aItem );
220
221 if( node && node->m_RcItem )
222 {
223 const std::shared_ptr<RC_ITEM> rc_item = node->m_RcItem;
224
225 switch( node->m_Type )
226 {
229 // rc_item->GetParent() can be null, if the parent is not existing
230 // when a RC item has no corresponding ERC/DRC marker
231 if( rc_item->GetParent() )
232 return rc_item->GetParent()->GetUUID();
233
234 break;
235
236 case RC_TREE_NODE::MAIN_ITEM: return rc_item->GetMainItemID();
237 case RC_TREE_NODE::AUX_ITEM: return rc_item->GetAuxItemID();
238 case RC_TREE_NODE::AUX_ITEM2: return rc_item->GetAuxItem2ID();
239 case RC_TREE_NODE::AUX_ITEM3: return rc_item->GetAuxItem3ID();
240 }
241 }
242
243 return niluuid;
244}
245
246
247RC_TREE_MODEL::RC_TREE_MODEL( EDA_DRAW_FRAME* aParentFrame, wxDataViewCtrl* aView ) :
248 m_editFrame( aParentFrame ),
249 m_view( aView ),
250 m_severities( 0 ),
251 m_rcItemsProvider( nullptr )
252{
253}
254
255
257{
258 for( RC_TREE_NODE* topLevelNode : m_tree )
259 delete topLevelNode;
260}
261
262
263void RC_TREE_MODEL::rebuildModel( std::shared_ptr<RC_ITEMS_PROVIDER> aProvider, int aSeverities )
264{
265 wxWindowUpdateLocker updateLock( m_view );
266
267 std::shared_ptr<RC_ITEM> selectedRcItem = nullptr;
268
269 if( m_view )
270 {
271 RC_TREE_NODE* selectedNode = ToNode( m_view->GetSelection() );
272 selectedRcItem = selectedNode ? selectedNode->m_RcItem : nullptr;
273
274 // Even with the updateLock, wxWidgets sometimes ties its knickers in a knot trying
275 // to run a wxdataview_selection_changed_callback() on a row that has been deleted.
276 m_view->UnselectAll();
277 }
278
279 BeforeReset();
280
281 m_rcItemsProvider = std::move( aProvider );
282
283 if( aSeverities != m_severities )
284 m_severities = aSeverities;
285
287 m_rcItemsProvider->SetSeverities( m_severities );
288
289 for( RC_TREE_NODE* topLevelNode : m_tree )
290 delete topLevelNode;
291
292 m_tree.clear();
293
294 // wxDataView::ExpandAll() pukes with large lists
295 int count = 0;
296
298 count = std::min( 1000, m_rcItemsProvider->GetCount() );
299
300 for( int i = 0; i < count; ++i )
301 {
302 std::shared_ptr<RC_ITEM> rcItem = m_rcItemsProvider->GetItem( i );
303
304 m_tree.push_back( new RC_TREE_NODE( nullptr, rcItem, RC_TREE_NODE::MARKER ) );
305 RC_TREE_NODE* n = m_tree.back();
306
307 if( rcItem->GetMainItemID() != niluuid )
308 n->m_Children.push_back( new RC_TREE_NODE( n, rcItem, RC_TREE_NODE::MAIN_ITEM ) );
309
310 if( rcItem->GetAuxItemID() != niluuid )
311 n->m_Children.push_back( new RC_TREE_NODE( n, rcItem, RC_TREE_NODE::AUX_ITEM ) );
312
313 if( rcItem->GetAuxItem2ID() != niluuid )
314 n->m_Children.push_back( new RC_TREE_NODE( n, rcItem, RC_TREE_NODE::AUX_ITEM2 ) );
315
316 if( rcItem->GetAuxItem3ID() != niluuid )
317 n->m_Children.push_back( new RC_TREE_NODE( n, rcItem, RC_TREE_NODE::AUX_ITEM3 ) );
318
319 if( MARKER_BASE* marker = rcItem->GetParent() )
320 {
321 if( marker->IsExcluded() && !marker->GetComment().IsEmpty() )
322 n->m_Children.push_back( new RC_TREE_NODE( n, rcItem, RC_TREE_NODE::COMMENT ) );
323 }
324 }
325
326 // Must be called after a significant change of items to force the
327 // wxDataViewModel to reread all of them, repopulating itself entirely.
328 AfterReset();
329
330#ifdef __WXGTK__
331 // The fastest method to update wxDataViewCtrl is to rebuild from
332 // scratch by calling Cleared(). Linux requires to reassociate model to
333 // display data, but Windows will create multiple associations.
334 // On MacOS, this crashes KiCad. See https://gitlab.com/kicad/code/kicad/-/issues/3666
335 // and https://gitlab.com/kicad/code/kicad/-/issues/3653
336 m_view->AssociateModel( this );
337#endif
338
339 m_view->ClearColumns();
340 m_view->AppendTextColumn( wxEmptyString, 0, wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE );
341
342 ExpandAll();
343
344 // Most annoyingly wxWidgets won't tell us the scroll position (and no, all the usual
345 // routines don't work), so we can only restore the scroll position based on a selection.
346 if( selectedRcItem )
347 {
348 for( RC_TREE_NODE* candidate : m_tree )
349 {
350 if( candidate->m_RcItem == selectedRcItem )
351 {
352 m_view->Select( ToItem( candidate ) );
353 m_view->EnsureVisible( ToItem( candidate ) );
354 break;
355 }
356 }
357 }
358}
359
360
361void RC_TREE_MODEL::Update( std::shared_ptr<RC_ITEMS_PROVIDER> aProvider, int aSeverities )
362{
363 rebuildModel( aProvider, aSeverities );
364}
365
366
368{
369 for( RC_TREE_NODE* topLevelNode : m_tree )
370 m_view->Expand( ToItem( topLevelNode ) );
371}
372
373
374bool RC_TREE_MODEL::IsContainer( wxDataViewItem const& aItem ) const
375{
376 if( ToNode( aItem ) == nullptr ) // must be tree root...
377 return true;
378 else
379 return ToNode( aItem )->m_Type == RC_TREE_NODE::MARKER;
380}
381
382
383wxDataViewItem RC_TREE_MODEL::GetParent( wxDataViewItem const& aItem ) const
384{
385 return ToItem( ToNode( aItem)->m_Parent );
386}
387
388
389unsigned int RC_TREE_MODEL::GetChildren( wxDataViewItem const& aItem,
390 wxDataViewItemArray& aChildren ) const
391{
392 const RC_TREE_NODE* node = ToNode( aItem );
393 const std::vector<RC_TREE_NODE*>& children = node ? node->m_Children : m_tree;
394
395 for( const RC_TREE_NODE* child: children )
396 aChildren.push_back( ToItem( child ) );
397
398 return children.size();
399}
400
401
402void RC_TREE_MODEL::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
403 unsigned int aCol ) const
404{
405 if( !aItem.IsOk() || m_view->IsFrozen() )
406 return;
407
408 const RC_TREE_NODE* node = ToNode( aItem );
409 const std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
410 MARKER_BASE* marker = rcItem->GetParent();
411 EDA_ITEM* item = nullptr;
412 wxString msg;
413
414 switch( node->m_Type )
415 {
417 if( marker )
418 {
419 SEVERITY severity = marker->GetSeverity();
420
421 if( severity == RPT_SEVERITY_EXCLUSION )
422 {
423 if( m_editFrame->GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
424 msg = _( "Excluded warning: " );
425 else
426 msg = _( "Excluded error: " );
427 }
428 else if( severity == RPT_SEVERITY_WARNING )
429 {
430 msg = _( "Warning: " );
431 }
432 else
433 {
434 msg = _( "Error: " );
435 }
436 }
437
438 msg += rcItem->GetErrorMessage();
439 break;
440
442 if( marker && marker->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
443 msg = _( "Drawing Sheet" );
444 else
445 item = m_editFrame->ResolveItem( rcItem->GetMainItemID() );
446
447 break;
448
450 item = m_editFrame->ResolveItem( rcItem->GetAuxItemID() );
451 break;
452
454 item = m_editFrame->ResolveItem( rcItem->GetAuxItem2ID() );
455 break;
456
458 item = m_editFrame->ResolveItem( rcItem->GetAuxItem3ID() );
459 break;
460
462 if( marker )
463 msg = marker->GetComment();
464
465 break;
466 }
467
468 if( item )
469 msg += item->GetItemDescription( m_editFrame, true );
470
471 msg.Replace( wxS( "\n" ), wxS( " " ) );
472 aVariant = msg;
473}
474
475
476bool RC_TREE_MODEL::GetAttr( wxDataViewItem const& aItem,
477 unsigned int aCol,
478 wxDataViewItemAttr& aAttr ) const
479{
480 if( !aItem.IsOk() || m_view->IsFrozen() )
481 return false;
482
483 const RC_TREE_NODE* node = ToNode( aItem );
484
485 bool ret = false;
486 bool heading = node->m_Type == RC_TREE_NODE::MARKER;
487
488 if( heading )
489 {
490 aAttr.SetBold( true );
491 ret = true;
492 }
493
494 if( node->m_RcItem->GetParent()
495 && node->m_RcItem->GetParent()->GetSeverity() == RPT_SEVERITY_EXCLUSION )
496 {
497 wxColour textColour = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXTEXT );
498 double brightness = KIGFX::COLOR4D( textColour ).GetBrightness();
499
500 if( brightness > 0.5 )
501 {
502 int lightness = static_cast<int>( brightness * ( heading ? 50 : 60 ) );
503 aAttr.SetColour( textColour.ChangeLightness( lightness ) );
504 }
505 else
506 {
507 aAttr.SetColour( textColour.ChangeLightness( heading ? 170 : 165 ) );
508 }
509
510 aAttr.SetItalic( true ); // Strikethrough would be better, if wxWidgets supported it
511 ret = true;
512 }
513
514 return ret;
515}
516
517
519{
520 if( aNode->m_Type != RC_TREE_NODE::MARKER )
521 {
522 ValueChanged( aNode->m_Parent );
523 return;
524 }
525
526 wxDataViewItem markerItem = ToItem( aNode );
527
528 wxDataViewModel::ValueChanged( markerItem, 0 );
529
530 for( const RC_TREE_NODE* child : aNode->m_Children )
531 wxDataViewModel::ValueChanged( ToItem( child ), 0 );
532
533 // Comment items can come and go depening on exclusion state and comment content.
534 //
535 const std::shared_ptr<RC_ITEM> rcItem = aNode->m_RcItem;
536 MARKER_BASE* marker = rcItem ? rcItem->GetParent() : nullptr;
537
538 if( marker )
539 {
540 bool needsCommentNode = marker->IsExcluded() && !marker->GetComment().IsEmpty();
541 RC_TREE_NODE* commentNode = aNode->m_Children.back();
542
543 if( commentNode && commentNode->m_Type != RC_TREE_NODE::COMMENT )
544 commentNode = nullptr;
545
546 if( needsCommentNode && !commentNode )
547 {
548 commentNode = new RC_TREE_NODE( aNode, rcItem, RC_TREE_NODE::COMMENT );
549 wxDataViewItemArray newItems;
550 newItems.push_back( ToItem( commentNode ) );
551
552 aNode->m_Children.push_back( commentNode );
553 ItemsAdded( markerItem, newItems );
554 }
555 else if( commentNode && !needsCommentNode )
556 {
557 wxDataViewItemArray deletedItems;
558 deletedItems.push_back( ToItem( commentNode ) );
559
560 aNode->m_Children.erase( aNode->m_Children.end() - 1 );
561 ItemsDeleted( markerItem, deletedItems );
562 }
563 }
564}
565
566
568{
569 DeleteItems( true, true, aDeep );
570}
571
572
573void RC_TREE_MODEL::DeleteItems( bool aCurrentOnly, bool aIncludeExclusions, bool aDeep )
574{
575 RC_TREE_NODE* current_node = m_view ? ToNode( m_view->GetCurrentItem() ) : nullptr;
576 const std::shared_ptr<RC_ITEM> current_item = current_node ? current_node->m_RcItem : nullptr;
577
579 std::vector<RC_TREE_NODE*> to_delete;
580 std::vector<RC_TREE_NODE*> expanded;
581
582 if( aCurrentOnly && !current_item )
583 {
584 wxBell();
585 return;
586 }
587
588 // wxWidgets 3.1.x on MacOS (at least) loses the expanded state of the tree when deleting
589 // items.
590 if( m_view && aCurrentOnly )
591 {
592 for( RC_TREE_NODE* node : m_tree )
593 {
594 if( m_view->IsExpanded( ToItem( node ) ) )
595 expanded.push_back( node );
596 }
597 }
598
599 int lastGood = -1;
600 bool itemDeleted = false;
601
602 if( m_view )
603 {
604 m_view->UnselectAll();
605 wxSafeYield();
606 m_view->Freeze();
607 }
608
609 if( !m_rcItemsProvider )
610 return;
611
612 for( int i = m_rcItemsProvider->GetCount() - 1; i >= 0; --i )
613 {
614 std::shared_ptr<RC_ITEM> rcItem = m_rcItemsProvider->GetItem( i );
615 MARKER_BASE* marker = rcItem->GetParent();
616 bool excluded = false;
617
618 if( marker && marker->GetSeverity() == RPT_SEVERITY_EXCLUSION )
619 excluded = true;
620
621 if( aCurrentOnly && itemDeleted && lastGood >= 0 )
622 break;
623
624 if( aCurrentOnly && rcItem != current_item )
625 {
626 lastGood = i;
627 continue;
628 }
629
630 if( excluded && !aIncludeExclusions )
631 continue;
632
633 if( i < (int) m_tree.size() ) // Careful; tree is truncated for large datasets
634 {
635 wxDataViewItem markerItem = ToItem( m_tree[i] );
636 wxDataViewItemArray childItems;
637 wxDataViewItem parentItem = ToItem( m_tree[i]->m_Parent );
638
639 for( RC_TREE_NODE* child : m_tree[i]->m_Children )
640 {
641 childItems.push_back( ToItem( child ) );
642 to_delete.push_back( child );
643 }
644
645 m_tree[i]->m_Children.clear();
646 ItemsDeleted( markerItem, childItems );
647
648 to_delete.push_back( m_tree[i] );
649 m_tree.erase( m_tree.begin() + i );
650 ItemDeleted( parentItem, markerItem );
651 }
652
653 // Only deep delete the current item here; others will be done by the caller, which
654 // can more efficiently delete all markers on the board.
655 m_rcItemsProvider->DeleteItem( i, aDeep && aCurrentOnly );
656
657 if( lastGood > i )
658 lastGood--;
659
660 itemDeleted = true;
661 }
662
663 if( m_view && aCurrentOnly && lastGood >= 0 )
664 {
665 for( RC_TREE_NODE* node : expanded )
666 {
667 wxDataViewItem item = ToItem( node );
668
669 if( item.IsOk() )
670 m_view->Expand( item );
671 }
672
673 wxDataViewItem selItem = ToItem( m_tree[ lastGood ] );
674 m_view->Select( selItem );
675
676 // wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED doesn't get propogated from the Select()
677 // call on (at least) MSW.
678 wxDataViewEvent selectEvent( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, m_view, selItem );
679 m_view->GetEventHandler()->ProcessEvent( selectEvent );
680 }
681
682 for( RC_TREE_NODE* item : to_delete )
683 delete( item );
684
685 if( m_view )
686 m_view->Thaw();
687}
688
689
691{
692 RC_TREE_NODE* currentNode = ToNode( m_view->GetCurrentItem() );
693 RC_TREE_NODE* prevMarker = nullptr;
694
695 while( currentNode && currentNode->m_Type != RC_TREE_NODE::MARKER )
696 currentNode = currentNode->m_Parent;
697
698 for( RC_TREE_NODE* candidate : m_tree )
699 {
700 if( candidate == currentNode )
701 break;
702 else
703 prevMarker = candidate;
704 }
705
706 if( prevMarker )
707 m_view->Select( ToItem( prevMarker ) );
708}
709
710
712{
713 RC_TREE_NODE* currentNode = ToNode( m_view->GetCurrentItem() );
714
715 while( currentNode && currentNode->m_Type != RC_TREE_NODE::MARKER )
716 currentNode = currentNode->m_Parent;
717
718 RC_TREE_NODE* nextMarker = nullptr;
719 bool trigger = currentNode == nullptr;
720
721 for( RC_TREE_NODE* candidate : m_tree )
722 {
723 if( candidate == currentNode )
724 {
725 trigger = true;
726 }
727 else if( trigger )
728 {
729 nextMarker = candidate;
730 break;
731 }
732 }
733
734 if( nextMarker )
735 m_view->Select( ToItem( nextMarker ) );
736}
737
738
740{
741 wxCHECK( !m_view->IsFrozen(), /* void */ );
742
743 for( RC_TREE_NODE* candidate : m_tree )
744 {
745 if( candidate->m_RcItem->GetParent() == aMarker )
746 {
747 m_view->Select( ToItem( candidate ) );
748 return;
749 }
750 }
751}
752
753
755{
756 wxCHECK( !m_view->IsFrozen(), /* void */ );
757
758 for( RC_TREE_NODE* candidate : m_tree )
759 {
760 if( candidate->m_RcItem->GetParent() == aMarker )
761 {
762 m_view->EnsureVisible( ToItem( candidate ) );
763 return;
764 }
765 }
766}
virtual SEVERITY GetSeverity(int aErrorCode) const
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 VECTOR2I GetPosition() const
Definition: eda_item.h:272
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
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double GetBrightness() const
Returns the brightness value of the color ranged from 0.0 to 1.0.
Definition: color4d.h:333
Definition: kiid.h:49
wxString AsString() const
Definition: kiid.cpp:246
Marker are mainly used to show a DRC or ERC error or warning.
Definition: marker_base.h:49
virtual SEVERITY GetSeverity() const
Definition: marker_base.h:102
bool IsExcluded() const
Definition: marker_base.h:93
@ MARKER_DRAWING_SHEET
Definition: marker_base.h:56
enum MARKER_T GetMarkerType() const
Definition: marker_base.h:91
wxString GetComment() const
Definition: marker_base.h:100
virtual void GetJsonViolation(RC_JSON::VIOLATION &aViolation, UNITS_PROVIDER *aUnitsProvider, SEVERITY aSeverity, const std::map< KIID, EDA_ITEM * > &aItemMap) const
Translate this object into an RC_JSON::VIOLATION object.
Definition: rc_item.cpp:166
static wxString getSeverityString(SEVERITY aSeverity)
Definition: rc_item.cpp:81
void AddItem(EDA_ITEM *aItem)
Definition: rc_item.cpp:56
MARKER_BASE * m_parent
The marker this item belongs to, if any.
Definition: rc_item.h:189
KIIDS m_ids
Definition: rc_item.h:191
virtual KIID GetMainItemID() const
Definition: rc_item.h:121
virtual KIID GetAuxItemID() const
Definition: rc_item.h:122
wxString GetErrorText() const
Definition: rc_item.h:167
virtual wxString ShowReport(UNITS_PROVIDER *aUnitsProvider, SEVERITY aSeverity, const std::map< KIID, EDA_ITEM * > &aItemMap) const
Translate this object into a text string suitable for saving to disk in a report.
Definition: rc_item.cpp:100
virtual wxString GetErrorMessage() const
Definition: rc_item.cpp:39
wxString m_errorMessage
A message describing the details of this specific error.
Definition: rc_item.h:186
wxString GetSettingsKey() const
Definition: rc_item.h:172
virtual wxString GetViolatingRuleDesc() const
Definition: rc_item.h:177
void SetItems(const KIIDS &aIds)
Definition: rc_item.h:103
void ExpandAll()
Definition: rc_item.cpp:367
void PrevMarker()
Definition: rc_item.cpp:690
int m_severities
Definition: rc_item.h:329
void GetValue(wxVariant &aVariant, wxDataViewItem const &aItem, unsigned int aCol) const override
Called by the wxDataView to fetch an item's value.
Definition: rc_item.cpp:402
std::vector< RC_TREE_NODE * > m_tree
Definition: rc_item.h:332
unsigned int GetChildren(wxDataViewItem const &aItem, wxDataViewItemArray &aChildren) const override
Definition: rc_item.cpp:389
EDA_DRAW_FRAME * m_editFrame
Definition: rc_item.h:327
static wxDataViewItem ToItem(RC_TREE_NODE const *aNode)
Definition: rc_item.h:238
void SelectMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:739
RC_TREE_MODEL(EDA_DRAW_FRAME *aParentFrame, wxDataViewCtrl *aView)
Definition: rc_item.cpp:247
static RC_TREE_NODE * ToNode(wxDataViewItem aItem)
Definition: rc_item.h:243
void ValueChanged(RC_TREE_NODE *aNode)
Definition: rc_item.cpp:518
void Update(std::shared_ptr< RC_ITEMS_PROVIDER > aProvider, int aSeverities)
Definition: rc_item.cpp:361
bool GetAttr(wxDataViewItem const &aItem, unsigned int aCol, wxDataViewItemAttr &aAttr) const override
Called by the wxDataView to fetch an item's formatting.
Definition: rc_item.cpp:476
void DeleteItems(bool aCurrentOnly, bool aIncludeExclusions, bool aDeep)
Delete the current item or all items.
Definition: rc_item.cpp:573
void DeleteCurrentItem(bool aDeep)
Definition: rc_item.cpp:567
wxDataViewItem GetParent(wxDataViewItem const &aItem) const override
Definition: rc_item.cpp:383
void CenterMarker(const MARKER_BASE *aMarker)
Definition: rc_item.cpp:754
static KIID ToUUID(wxDataViewItem aItem)
Definition: rc_item.cpp:217
wxDataViewCtrl * m_view
Definition: rc_item.h:328
std::shared_ptr< RC_ITEMS_PROVIDER > m_rcItemsProvider
Definition: rc_item.h:330
void NextMarker()
Definition: rc_item.cpp:711
bool IsContainer(wxDataViewItem const &aItem) const override
Definition: rc_item.cpp:374
void rebuildModel(std::shared_ptr< RC_ITEMS_PROVIDER > aProvider, int aSeverities)
Definition: rc_item.cpp:263
std::shared_ptr< RC_ITEM > m_RcItem
Definition: rc_item.h:228
RC_TREE_NODE * m_Parent
Definition: rc_item.h:230
std::vector< RC_TREE_NODE * > m_Children
Definition: rc_item.h:231
NODE_TYPE m_Type
Definition: rc_item.h:227
const EDA_IU_SCALE & GetIuScale() const
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
EDA_UNITS GetUserUnits() const
#define _(s)
KIID niluuid(0)
KICOMMON_API double ToUserUnit(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnit, double aValue)
Convert aValue in internal units to the appropriate user units defined by aUnit.
Definition: eda_units.cpp:289
static wxString showCoord(UNITS_PROVIDER *aUnitsProvider, const VECTOR2I &aPos)
Definition: rc_item.cpp:48
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_DEBUG
@ RPT_SEVERITY_INFO
@ RPT_SEVERITY_ACTION
std::vector< AFFECTED_ITEM > items
Functions to provide common constants and other functions to assist in making a consistent UI.