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
39wxString RC_ITEM::GetErrorMessage( bool aTranslate ) const
40{
41 if( m_errorMessage.IsEmpty() )
42 return GetErrorText( aTranslate );
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" ),
132 GetErrorMessage( false ),
133 GetViolatingRuleDesc( false ),
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" ),
144 GetErrorMessage( false ),
145 GetViolatingRuleDesc( false ),
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" ),
154 GetErrorMessage( false ),
155 GetViolatingRuleDesc( false ),
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( false );
171 aViolation.type = GetSettingsKey();
172
173 if( m_parent && m_parent->IsExcluded() )
174 {
175 aViolation.excluded = true;
176 aViolation.comment = m_parent->GetComment();
177 }
178 else
179 {
180 aViolation.excluded = false;
181 }
182
183 EDA_ITEM* mainItem = nullptr;
184 EDA_ITEM* auxItem = nullptr;
185
186 auto ii = aItemMap.find( GetMainItemID() );
187
188 if( ii != aItemMap.end() )
189 mainItem = ii->second;
190
191 ii = aItemMap.find( GetAuxItemID() );
192
193 if( ii != aItemMap.end() )
194 auxItem = ii->second;
195
196 if( mainItem )
197 {
199 item.description = mainItem->GetItemDescription( aUnitsProvider, true );
200 item.uuid = mainItem->m_Uuid.AsString();
201 item.pos.x = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
202 aUnitsProvider->GetUserUnits(),
203 mainItem->GetPosition().x );
204 item.pos.y = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
205 aUnitsProvider->GetUserUnits(),
206 mainItem->GetPosition().y );
207 aViolation.items.emplace_back( item );
208 }
209
210 if( auxItem )
211 {
213 item.description = auxItem->GetItemDescription( aUnitsProvider, true );
214 item.uuid = auxItem->m_Uuid.AsString();
215 item.pos.x = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
216 aUnitsProvider->GetUserUnits(),
217 auxItem->GetPosition().x );
218 item.pos.y = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
219 aUnitsProvider->GetUserUnits(),
220 auxItem->GetPosition().y );
221 aViolation.items.emplace_back( item );
222 }
223}
224
225
226KIID RC_TREE_MODEL::ToUUID( wxDataViewItem aItem )
227{
228 const RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aItem );
229
230 if( node && node->m_RcItem )
231 {
232 const std::shared_ptr<RC_ITEM> rc_item = node->m_RcItem;
233
234 switch( node->m_Type )
235 {
238 // rc_item->GetParent() can be null, if the parent is not existing
239 // when a RC item has no corresponding ERC/DRC marker
240 if( rc_item->GetParent() )
241 return rc_item->GetParent()->GetUUID();
242
243 break;
244
245 case RC_TREE_NODE::MAIN_ITEM: return rc_item->GetMainItemID();
246 case RC_TREE_NODE::AUX_ITEM: return rc_item->GetAuxItemID();
247 case RC_TREE_NODE::AUX_ITEM2: return rc_item->GetAuxItem2ID();
248 case RC_TREE_NODE::AUX_ITEM3: return rc_item->GetAuxItem3ID();
249 }
250 }
251
252 return niluuid;
253}
254
255
256RC_TREE_MODEL::RC_TREE_MODEL( EDA_DRAW_FRAME* aParentFrame, wxDataViewCtrl* aView ) :
257 m_editFrame( aParentFrame ),
258 m_view( aView ),
259 m_severities( 0 ),
260 m_rcItemsProvider( nullptr )
261{
262}
263
264
266 const std::shared_ptr<RC_ITEM>& aRcItem,
268{
269 RC_TREE_NODE* node = new RC_TREE_NODE( aParent, aRcItem, aType );
270
271 m_handles.push_back( std::make_unique<RC_TREE_NODE::HANDLE>() );
272 node->m_Handle = m_handles.back().get();
273 node->m_Handle->m_Node = node;
274
275 return node;
276}
277
278
280{
281 if( !aNode )
282 return;
283
284 if( aNode->m_Handle )
285 aNode->m_Handle->m_Node = nullptr;
286
287 for( RC_TREE_NODE* child : aNode->m_Children )
288 retireNodeTree( child );
289}
290
291
293{
294 if( !aNode )
295 return;
296
297 delete aNode;
298}
299
300
302{
303 for( RC_TREE_NODE* topLevelNode : m_tree )
304 {
305 retireNodeTree( topLevelNode );
306 deleteNodeTree( topLevelNode );
307 }
308}
309
310
311void RC_TREE_MODEL::rebuildModel( std::shared_ptr<RC_ITEMS_PROVIDER> aProvider, int aSeverities )
312{
313 wxWindowUpdateLocker updateLock( m_view );
314
315 std::shared_ptr<RC_ITEM> selectedRcItem = nullptr;
316
317 if( m_view )
318 {
319 RC_TREE_NODE* selectedNode = ToNode( m_view->GetSelection() );
320 selectedRcItem = selectedNode ? selectedNode->m_RcItem : nullptr;
321
322 // Even with the updateLock, wxWidgets sometimes ties its knickers in a knot trying
323 // to run a wxdataview_selection_changed_callback() on a row that has been deleted.
324 m_view->UnselectAll();
325 }
326
327 BeforeReset();
328
329 m_rcItemsProvider = std::move( aProvider );
330
331 if( aSeverities != m_severities )
332 m_severities = aSeverities;
333
335 m_rcItemsProvider->SetSeverities( m_severities );
336
337 for( RC_TREE_NODE* topLevelNode : m_tree )
338 {
339 retireNodeTree( topLevelNode );
340 deleteNodeTree( topLevelNode );
341 }
342
343 m_tree.clear();
344 m_handles.clear();
345
346 // wxDataView::ExpandAll() pukes with large lists
347 int count = 0;
348
350 count = std::min( 1000, m_rcItemsProvider->GetCount() );
351
352 for( int i = 0; i < count; ++i )
353 {
354 std::shared_ptr<RC_ITEM> rcItem = m_rcItemsProvider->GetItem( i );
355
356 m_tree.push_back( createNode( nullptr, rcItem, RC_TREE_NODE::MARKER ) );
357 RC_TREE_NODE* n = m_tree.back();
358
359 if( rcItem->GetMainItemID() != niluuid )
360 n->m_Children.push_back( createNode( n, rcItem, RC_TREE_NODE::MAIN_ITEM ) );
361
362 if( rcItem->GetAuxItemID() != niluuid )
363 n->m_Children.push_back( createNode( n, rcItem, RC_TREE_NODE::AUX_ITEM ) );
364
365 if( rcItem->GetAuxItem2ID() != niluuid )
366 n->m_Children.push_back( createNode( n, rcItem, RC_TREE_NODE::AUX_ITEM2 ) );
367
368 if( rcItem->GetAuxItem3ID() != niluuid )
369 n->m_Children.push_back( createNode( n, rcItem, RC_TREE_NODE::AUX_ITEM3 ) );
370
371 if( MARKER_BASE* marker = rcItem->GetParent() )
372 {
373 if( marker->IsExcluded() && !marker->GetComment().IsEmpty() )
374 n->m_Children.push_back( createNode( n, rcItem, RC_TREE_NODE::COMMENT ) );
375 }
376 }
377
378 // Must be called after a significant change of items to force the
379 // wxDataViewModel to reread all of them, repopulating itself entirely.
380 AfterReset();
381
382#ifdef __WXGTK__
383 // The fastest method to update wxDataViewCtrl is to rebuild from
384 // scratch by calling Cleared(). Linux requires to reassociate model to
385 // display data, but Windows will create multiple associations.
386 // On MacOS, this crashes KiCad. See https://gitlab.com/kicad/code/kicad/-/issues/3666
387 // and https://gitlab.com/kicad/code/kicad/-/issues/3653
388 m_view->AssociateModel( this );
389#endif
390
391 m_view->ClearColumns();
392 m_view->AppendTextColumn( wxEmptyString, 0, wxDATAVIEW_CELL_INERT, wxCOL_WIDTH_AUTOSIZE );
393
394 ExpandAll();
395
396 // Most annoyingly wxWidgets won't tell us the scroll position (and no, all the usual
397 // routines don't work), so we can only restore the scroll position based on a selection.
398 if( selectedRcItem )
399 {
400 for( RC_TREE_NODE* candidate : m_tree )
401 {
402 if( candidate->m_RcItem == selectedRcItem )
403 {
404 m_view->Select( ToItem( candidate ) );
405 m_view->EnsureVisible( ToItem( candidate ) );
406 break;
407 }
408 }
409 }
410}
411
412
413void RC_TREE_MODEL::Update( std::shared_ptr<RC_ITEMS_PROVIDER> aProvider, int aSeverities )
414{
415 rebuildModel( aProvider, aSeverities );
416}
417
418
420{
421 for( RC_TREE_NODE* topLevelNode : m_tree )
422 m_view->Expand( ToItem( topLevelNode ) );
423}
424
425
426bool RC_TREE_MODEL::IsContainer( wxDataViewItem const& aItem ) const
427{
428 const RC_TREE_NODE* node = ToNode( aItem );
429
430 if( !aItem.IsOk() ) // tree root
431 return true;
432
433 if( node == nullptr )
434 return false;
435
436 return node->m_Type == RC_TREE_NODE::MARKER;
437}
438
439
440wxDataViewItem RC_TREE_MODEL::GetParent( wxDataViewItem const& aItem ) const
441{
442 const RC_TREE_NODE* node = ToNode( aItem );
443 return node ? ToItem( node->m_Parent ) : wxDataViewItem();
444}
445
446
447unsigned int RC_TREE_MODEL::GetChildren( wxDataViewItem const& aItem,
448 wxDataViewItemArray& aChildren ) const
449{
450 const RC_TREE_NODE* node = ToNode( aItem );
451 const std::vector<RC_TREE_NODE*>& children = node ? node->m_Children : m_tree;
452
453 if( aItem.IsOk() && !node )
454 return 0;
455
456 for( const RC_TREE_NODE* child : children )
457 aChildren.push_back( ToItem( child ) );
458
459 return children.size();
460}
461
462
463void RC_TREE_MODEL::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
464 unsigned int aCol ) const
465{
466 if( !aItem.IsOk() || m_view->IsFrozen() || m_tree.empty() )
467 return;
468
469 const RC_TREE_NODE* node = ToNode( aItem );
470
471 if( !node || !node->m_RcItem )
472 return;
473
474 const std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
475 MARKER_BASE* marker = rcItem->GetParent();
476 EDA_ITEM* item = nullptr;
477 wxString msg;
478
479 switch( node->m_Type )
480 {
482 if( marker )
483 {
484 SEVERITY severity = marker->GetSeverity();
485
486 if( severity == RPT_SEVERITY_EXCLUSION )
487 {
488 if( m_editFrame->GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
489 msg = _( "Excluded warning: " );
490 else
491 msg = _( "Excluded error: " );
492 }
493 else if( severity == RPT_SEVERITY_WARNING )
494 {
495 msg = _( "Warning: " );
496 }
497 else
498 {
499 msg = _( "Error: " );
500 }
501 }
502
503 msg += rcItem->GetErrorMessage( true );
504 break;
505
507 if( marker && marker->GetMarkerType() == MARKER_BASE::MARKER_DRAWING_SHEET )
508 msg = _( "Drawing Sheet" );
509 else
510 item = m_editFrame->ResolveItem( rcItem->GetMainItemID() );
511
512 break;
513
515 item = m_editFrame->ResolveItem( rcItem->GetAuxItemID() );
516 break;
517
519 item = m_editFrame->ResolveItem( rcItem->GetAuxItem2ID() );
520 break;
521
523 item = m_editFrame->ResolveItem( rcItem->GetAuxItem3ID() );
524 break;
525
527 if( marker )
528 msg = marker->GetComment();
529
530 break;
531 }
532
533 if( item )
534 msg += item->GetItemDescription( m_editFrame, true );
535
536 msg.Replace( wxS( "\n" ), wxS( " " ) );
537 aVariant = msg;
538}
539
540
541bool RC_TREE_MODEL::GetAttr( wxDataViewItem const& aItem,
542 unsigned int aCol,
543 wxDataViewItemAttr& aAttr ) const
544{
545 if( !aItem.IsOk() || m_view->IsFrozen() || m_tree.empty() )
546 return false;
547
548 const RC_TREE_NODE* node = ToNode( aItem );
549
550 if( !node || !node->m_RcItem )
551 return false;
552
553 bool ret = false;
554 bool heading = node->m_Type == RC_TREE_NODE::MARKER;
555
556 if( heading )
557 {
558 aAttr.SetBold( true );
559 ret = true;
560 }
561
562 if( node->m_RcItem->GetParent()
564 {
565 wxColour textColour = wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXTEXT );
566 double brightness = KIGFX::COLOR4D( textColour ).GetBrightness();
567
568 if( brightness > 0.5 )
569 {
570 int lightness = static_cast<int>( brightness * ( heading ? 50 : 60 ) );
571 aAttr.SetColour( textColour.ChangeLightness( lightness ) );
572 }
573 else
574 {
575 aAttr.SetColour( textColour.ChangeLightness( heading ? 170 : 165 ) );
576 }
577
578 aAttr.SetItalic( true ); // Strikethrough would be better, if wxWidgets supported it
579 ret = true;
580 }
581
582 return ret;
583}
584
585
587{
588 if( aNode->m_Type != RC_TREE_NODE::MARKER )
589 {
590 ValueChanged( aNode->m_Parent );
591 return;
592 }
593
594 wxDataViewItem markerItem = ToItem( aNode );
595
596 wxDataViewModel::ValueChanged( markerItem, 0 );
597
598 for( const RC_TREE_NODE* child : aNode->m_Children )
599 wxDataViewModel::ValueChanged( ToItem( child ), 0 );
600
601 // Comment items can come and go depening on exclusion state and comment content.
602 //
603 const std::shared_ptr<RC_ITEM> rcItem = aNode->m_RcItem;
604 MARKER_BASE* marker = rcItem ? rcItem->GetParent() : nullptr;
605
606 if( marker )
607 {
608 bool needsCommentNode = marker->IsExcluded() && !marker->GetComment().IsEmpty();
609 RC_TREE_NODE* commentNode = aNode->m_Children.back();
610
611 if( commentNode && commentNode->m_Type != RC_TREE_NODE::COMMENT )
612 commentNode = nullptr;
613
614 if( needsCommentNode && !commentNode )
615 {
616 commentNode = createNode( aNode, rcItem, RC_TREE_NODE::COMMENT );
617 wxDataViewItemArray newItems;
618 newItems.push_back( ToItem( commentNode ) );
619
620 aNode->m_Children.push_back( commentNode );
621 ItemsAdded( markerItem, newItems );
622 }
623 else if( commentNode && !needsCommentNode )
624 {
625 wxDataViewItemArray deletedItems;
626 deletedItems.push_back( ToItem( commentNode ) );
627
628 aNode->m_Children.erase( aNode->m_Children.end() - 1 );
629 retireNodeTree( commentNode );
630 ItemsDeleted( markerItem, deletedItems );
631 deleteNodeTree( commentNode );
632 }
633 }
634}
635
636
638{
639 DeleteItems( true, true, aDeep );
640}
641
642
643void RC_TREE_MODEL::DeleteItems( bool aCurrentOnly, bool aIncludeExclusions, bool aDeep )
644{
645 RC_TREE_NODE* current_node = m_view ? ToNode( m_view->GetCurrentItem() ) : nullptr;
646 const std::shared_ptr<RC_ITEM> current_item = current_node ? current_node->m_RcItem : nullptr;
647
648 std::vector<wxDataViewItem> expanded;
649
650 if( aCurrentOnly && !current_item )
651 {
652 wxBell();
653 return;
654 }
655
656 // wxWidgets 3.1.x on MacOS (at least) loses the expanded state of the tree when deleting
657 // items.
658 if( m_view && aCurrentOnly )
659 {
660 for( RC_TREE_NODE* node : m_tree )
661 {
662 if( m_view->IsExpanded( ToItem( node ) ) )
663 expanded.push_back( ToItem( node ) );
664 }
665 }
666
667 int lastGood = -1;
668 bool itemDeleted = false;
669
670 if( m_view )
671 {
672 m_view->UnselectAll();
673 m_view->Freeze();
674 }
675
676 if( !m_rcItemsProvider )
677 {
678 if( m_view )
679 m_view->Thaw();
680
681 return;
682 }
683
684 for( int i = m_rcItemsProvider->GetCount() - 1; i >= 0; --i )
685 {
686 std::shared_ptr<RC_ITEM> rcItem = m_rcItemsProvider->GetItem( i );
687 MARKER_BASE* marker = rcItem->GetParent();
688 bool excluded = false;
689
690 if( marker && marker->GetSeverity() == RPT_SEVERITY_EXCLUSION )
691 excluded = true;
692
693 if( aCurrentOnly && itemDeleted && lastGood >= 0 )
694 break;
695
696 if( aCurrentOnly && rcItem != current_item )
697 {
698 lastGood = i;
699 continue;
700 }
701
702 if( excluded && !aIncludeExclusions )
703 continue;
704
705 if( i < (int) m_tree.size() ) // Careful; tree is truncated for large datasets
706 {
707 wxDataViewItem markerItem = ToItem( m_tree[i] );
708 wxDataViewItemArray childItems;
709 wxDataViewItem parentItem = ToItem( m_tree[i]->m_Parent );
710
711 for( RC_TREE_NODE* child : m_tree[i]->m_Children )
712 {
713 childItems.push_back( ToItem( child ) );
714 retireNodeTree( child );
715 }
716
717 ItemsDeleted( markerItem, childItems );
718
720 RC_TREE_NODE* deletedNode = m_tree[i];
721 m_tree.erase( m_tree.begin() + i );
722 ItemDeleted( parentItem, markerItem );
723 deleteNodeTree( deletedNode );
724 }
725
726 // Only deep delete the current item here; others will be done by the caller, which
727 // can more efficiently delete all markers on the board.
728 m_rcItemsProvider->DeleteItem( i, aDeep && aCurrentOnly );
729
730 if( lastGood > i )
731 lastGood--;
732
733 itemDeleted = true;
734 }
735
736 if( m_view && aCurrentOnly && lastGood >= 0 )
737 {
738 for( const wxDataViewItem& item : expanded )
739 {
740 if( item.IsOk() )
741 m_view->Expand( item );
742 }
743
744 wxDataViewItem selItem = ToItem( m_tree[ lastGood ] );
745 m_view->Select( selItem );
746
747 // wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED doesn't get propogated from the Select()
748 // call on (at least) MSW.
749 wxDataViewEvent selectEvent( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, m_view, selItem );
750 m_view->GetEventHandler()->ProcessEvent( selectEvent );
751 }
752
753 if( m_view )
754 m_view->Thaw();
755}
756
757
759{
760 RC_TREE_NODE* currentNode = ToNode( m_view->GetCurrentItem() );
761 RC_TREE_NODE* prevMarker = nullptr;
762
763 while( currentNode && currentNode->m_Type != RC_TREE_NODE::MARKER )
764 currentNode = currentNode->m_Parent;
765
766 for( RC_TREE_NODE* candidate : m_tree )
767 {
768 if( candidate == currentNode )
769 break;
770 else
771 prevMarker = candidate;
772 }
773
774 if( prevMarker )
775 m_view->Select( ToItem( prevMarker ) );
776}
777
778
780{
781 RC_TREE_NODE* currentNode = ToNode( m_view->GetCurrentItem() );
782
783 while( currentNode && currentNode->m_Type != RC_TREE_NODE::MARKER )
784 currentNode = currentNode->m_Parent;
785
786 RC_TREE_NODE* nextMarker = nullptr;
787 bool trigger = currentNode == nullptr;
788
789 for( RC_TREE_NODE* candidate : m_tree )
790 {
791 if( candidate == currentNode )
792 {
793 trigger = true;
794 }
795 else if( trigger )
796 {
797 nextMarker = candidate;
798 break;
799 }
800 }
801
802 if( nextMarker )
803 m_view->Select( ToItem( nextMarker ) );
804}
805
806
808{
809 wxCHECK( !m_view->IsFrozen(), /* void */ );
810
811 for( RC_TREE_NODE* candidate : m_tree )
812 {
813 if( candidate->m_RcItem->GetParent() == aMarker )
814 {
815 m_view->Select( ToItem( candidate ) );
816 return;
817 }
818 }
819}
820
821
823{
824 wxCHECK( !m_view->IsFrozen(), /* void */ );
825
826 for( RC_TREE_NODE* candidate : m_tree )
827 {
828 if( candidate->m_RcItem->GetParent() == aMarker )
829 {
830 m_view->EnsureVisible( ToItem( candidate ) );
831 return;
832 }
833 }
834}
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition eda_item.h:100
virtual VECTOR2I GetPosition() const
Definition eda_item.h:279
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
Definition eda_item.cpp:154
const KIID m_Uuid
Definition eda_item.h:528
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:105
double GetBrightness() const
Returns the brightness value of the color ranged from 0.0 to 1.0.
Definition color4d.h:334
Definition kiid.h:48
wxString AsString() const
Definition kiid.cpp:244
Marker are mainly used to show a DRC or ERC error or warning.
Definition marker_base.h:49
virtual SEVERITY GetSeverity() const
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
wxString GetErrorText(bool aTranslate) const
Definition rc_item.h:174
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
virtual wxString GetViolatingRuleDesc(bool aTranslate) const
Definition rc_item.h:187
MARKER_BASE * GetParent() const
Definition rc_item.h:136
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:199
KIIDS m_ids
Definition rc_item.h:201
virtual KIID GetMainItemID() const
Definition rc_item.h:128
virtual KIID GetAuxItemID() const
Definition rc_item.h:129
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
wxString m_errorMessage
A message describing the details of this specific error.
Definition rc_item.h:196
wxString GetSettingsKey() const
Definition rc_item.h:182
virtual wxString GetErrorMessage(bool aTranslate) const
Definition rc_item.cpp:39
void SetItems(const KIIDS &aIds)
Definition rc_item.h:110
void ExpandAll()
Definition rc_item.cpp:419
void PrevMarker()
Definition rc_item.cpp:758
int m_severities
Definition rc_item.h:350
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:463
std::vector< RC_TREE_NODE * > m_tree
Definition rc_item.h:354
unsigned int GetChildren(wxDataViewItem const &aItem, wxDataViewItemArray &aChildren) const override
Definition rc_item.cpp:447
std::vector< std::unique_ptr< RC_TREE_NODE::HANDLE > > m_handles
Definition rc_item.h:353
EDA_DRAW_FRAME * m_editFrame
Definition rc_item.h:348
void retireNodeTree(RC_TREE_NODE *aNode)
Definition rc_item.cpp:279
static wxDataViewItem ToItem(RC_TREE_NODE const *aNode)
Definition rc_item.h:254
void SelectMarker(const MARKER_BASE *aMarker)
Definition rc_item.cpp:807
RC_TREE_MODEL(EDA_DRAW_FRAME *aParentFrame, wxDataViewCtrl *aView)
Definition rc_item.cpp:256
void deleteNodeTree(RC_TREE_NODE *aNode)
Definition rc_item.cpp:292
static RC_TREE_NODE * ToNode(wxDataViewItem aItem)
Definition rc_item.h:259
void ValueChanged(RC_TREE_NODE *aNode)
Definition rc_item.cpp:586
void Update(std::shared_ptr< RC_ITEMS_PROVIDER > aProvider, int aSeverities)
Definition rc_item.cpp:413
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:541
void DeleteItems(bool aCurrentOnly, bool aIncludeExclusions, bool aDeep)
Delete the current item or all items.
Definition rc_item.cpp:643
RC_TREE_NODE * createNode(RC_TREE_NODE *aParent, const std::shared_ptr< RC_ITEM > &aRcItem, RC_TREE_NODE::NODE_TYPE aType)
Definition rc_item.cpp:265
void DeleteCurrentItem(bool aDeep)
Definition rc_item.cpp:637
wxDataViewItem GetParent(wxDataViewItem const &aItem) const override
Definition rc_item.cpp:440
void CenterMarker(const MARKER_BASE *aMarker)
Definition rc_item.cpp:822
static KIID ToUUID(wxDataViewItem aItem)
Definition rc_item.cpp:226
wxDataViewCtrl * m_view
Definition rc_item.h:349
std::shared_ptr< RC_ITEMS_PROVIDER > m_rcItemsProvider
Definition rc_item.h:351
void NextMarker()
Definition rc_item.cpp:779
bool IsContainer(wxDataViewItem const &aItem) const override
Definition rc_item.cpp:426
void rebuildModel(std::shared_ptr< RC_ITEMS_PROVIDER > aProvider, int aSeverities)
Definition rc_item.cpp:311
std::shared_ptr< RC_ITEM > m_RcItem
Definition rc_item.h:238
RC_TREE_NODE * m_Parent
Definition rc_item.h:246
std::vector< RC_TREE_NODE * > m_Children
Definition rc_item.h:247
HANDLE * m_Handle
Definition rc_item.h:245
NODE_TYPE m_Type
Definition rc_item.h:237
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.
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
RC_TREE_NODE * m_Node
Definition rc_item.h:242
Functions to provide common constants and other functions to assist in making a consistent UI.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687