44#include <wx/filedlg.h>
46#include <wx/wupdlock.h>
76 m_footprintTestsRun( false ),
77 m_markersTreeModel( nullptr ),
78 m_unconnectedTreeModel( nullptr ),
79 m_fpWarningsTreeModel( nullptr ),
80 m_lastUpdateUi(
std::chrono::steady_clock::now() )
120 listItem.SetText( str );
121 listItem.SetData( code );
133 { wxID_CANCEL,
_(
"Close" ) } } );
159 g_lastIgnored.push_back( { m_ignoredList->GetItemText( ii ), m_ignoredList->GetItemData( ii ) } );
180 SetReturnCode( wxID_CANCEL );
195 int newValue =
KiROUND( cur * 1000.0 );
202 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
203 if( std::chrono::duration_cast<std::chrono::milliseconds>( now -
m_lastUpdateUi ).count()
206 Pgm().
App().SafeYieldFor(
this, wxEVT_CATEGORY_NATIVE_EVENTS );
255 if( zoneFillerTool->IsBusy() )
275 m_messages->
Report(
_(
"DRC incomplete: could not compile custom design rules." )
276 + wxS(
" " )
277 + wxS(
"<a href='$CUSTOM_RULES'>" ) +
_(
"Show design rules." ) + wxT(
"</a>" ) );
296 for( std::reference_wrapper<RC_ITEM>& item : violations )
302 listItem.SetText( wxT(
" • " ) + item.get().GetErrorText() );
303 listItem.SetData( item.get().GetErrorCode() );
326 drcTool->
RunTests(
this, refillZones, reportAllTrackErrors, testFootprints );
381 auto getActiveLayers =
389 for(
int layer : aItem->GetLayerSet() )
391 if(
pad->FlashLayer( layer ) )
399 return aItem->GetLayerSet();
409 double dist = selectedItemPos.
Distance( unSelectedItemPos );
411 double minimumMarkerSeparationDistance =
414 return dist <= minimumMarkerSeparationDistance;
425 std::shared_ptr<RC_ITEM> rc_item = node->
m_RcItem;
447 LSET violationLayers;
473 if( a || b || c || d )
484 LSET layersList = getActiveLayers( it );
485 violationLayers &= layersList;
488 principalLayer = layersList.
Seq().front();
492 if( violationLayers.count() )
493 principalLayer = violationLayers.
Seq().front();
494 else if( principalLayer >= 0 )
495 violationLayers.
set( principalLayer );
530 if( item == a && item == b )
532 focusPos = ( node->m_Type == RC_TREE_NODE::MAIN_ITEM ) ? edge.GetSourcePos()
533 : edge.GetTargetPos();
537 focusPos = ( item == edge.GetSourceNode()->Parent() ) ? edge.GetSourcePos()
538 : edge.GetTargetPos();
558 std::vector<BOARD_ITEM*> items;
566 for(
const KIID&
id : rc_item->GetIDs() )
570 if( candidate && candidate->GetNetCode() == net )
571 items.push_back( candidate );
576 items.push_back( item );
579 m_frame->FocusOnItems( items, principalLayer );
585 std::vector<BOARD_ITEM*> items;
587 for(
BOARD_ITEM* boardMarkerItem : board->Markers() )
589 if( item->m_Uuid != boardMarkerItem->m_Uuid && isOverlapping( item, boardMarkerItem ) )
590 items.push_back( boardMarkerItem );
593 items.push_back( item );
594 m_frame->FocusOnItems( items, principalLayer );
598 m_frame->FocusOnItem( item, principalLayer );
608 if( aEvent.GetItem().IsOk() )
629 std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
639 default: listName =
_(
"appropriate" );
break;
644 ID_EDIT_EXCLUSION_COMMENT = 4467,
646 ID_REMOVE_EXCLUSION_ALL,
648 ID_ADD_EXCLUSION_WITH_COMMENT,
649 ID_ADD_EXCLUSION_ALL,
650 ID_INSPECT_VIOLATION,
651 ID_SET_SEVERITY_TO_ERROR,
652 ID_SET_SEVERITY_TO_WARNING,
653 ID_SET_SEVERITY_TO_IGNORE,
657 if( rcItem->GetParent()->IsExcluded() )
659 menu.Append( ID_REMOVE_EXCLUSION,
660 _(
"Remove exclusion for this violation" ),
661 wxString::Format(
_(
"It will be placed back in the %s list" ), listName ) );
663 menu.Append( ID_EDIT_EXCLUSION_COMMENT,
664 _(
"Edit exclusion comment..." ) );
668 menu.Append( ID_REMOVE_EXCLUSION_ALL,
669 wxString::Format(
_(
"Remove all exclusions for violations of rule '%s'" ),
671 wxString::Format(
_(
"They will be placed back in the %s list" ), listName ) );
676 menu.Append( ID_ADD_EXCLUSION,
677 _(
"Exclude this violation" ),
678 wxString::Format(
_(
"It will be excluded from the %s list" ), listName ) );
680 menu.Append( ID_ADD_EXCLUSION_WITH_COMMENT,
681 _(
"Exclude with comment..." ),
682 wxString::Format(
_(
"It will be excluded from the %s list" ), listName ) );
686 menu.Append( ID_ADD_EXCLUSION_ALL,
687 wxString::Format(
_(
"Exclude all violations of rule '%s'..." ),
689 wxString::Format(
_(
"They will be excluded from the %s list" ), listName ) );
695 if( !inspectDRCErrorMenuText.IsEmpty() )
696 menu.Append( ID_INSPECT_VIOLATION, inspectDRCErrorMenuText );
698 menu.AppendSeparator();
702 menu.Append( ID_SET_SEVERITY_TO_ERROR,
703 wxString::Format(
_(
"Change severity to Error for all '%s' violations" ),
704 rcItem->GetErrorText() ),
705 _(
"Violation severities can also be edited in the Board Setup... dialog" ) );
709 menu.Append( ID_SET_SEVERITY_TO_WARNING,
710 wxString::Format(
_(
"Change severity to Warning for all '%s' violations" ),
711 rcItem->GetErrorText() ),
712 _(
"Violation severities can also be edited in the Board Setup... dialog" ) );
715 menu.Append( ID_SET_SEVERITY_TO_IGNORE,
716 wxString::Format(
_(
"Ignore all '%s' violations" ), rcItem->GetErrorText() ),
717 _(
"Violations will not be checked or reported" ) );
719 menu.AppendSeparator();
721 menu.Append( ID_EDIT_SEVERITIES,
722 _(
"Edit violation severities..." ),
723 _(
"Open the Board Setup... dialog" ) );
725 bool modified =
false;
726 int command = GetPopupMenuSelectionFromUser( menu );
730 case ID_EDIT_EXCLUSION_COMMENT:
733 WX_TEXT_ENTRY_DIALOG dlg(
this, wxEmptyString,
_(
"Exclusion Comment" ), marker->GetComment(),
true );
738 marker->SetExcluded(
true, dlg.
GetValue() );
740 wxString serialized = marker->SerializeToString();
745 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->ValueChanged( node );
751 case ID_REMOVE_EXCLUSION:
754 marker->SetExcluded(
false );
756 wxString serialized = marker->SerializeToString();
771 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->ValueChanged( node );
777 case ID_ADD_EXCLUSION:
778 case ID_ADD_EXCLUSION_WITH_COMMENT:
783 if( command == ID_ADD_EXCLUSION_WITH_COMMENT )
793 marker->SetExcluded(
true, comment );
795 wxString serialized = marker->SerializeToString();
811 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->ValueChanged( node );
813 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->DeleteCurrentItem(
false );
820 case ID_REMOVE_EXCLUSION_ALL:
823 DRC_ITEM* candidateDrcItem =
static_cast<DRC_ITEM*
>( marker->GetRCItem().get() );
827 marker->SetExcluded(
false );
829 wxString serialized = marker->SerializeToString();
840 case ID_ADD_EXCLUSION_ALL:
843 DRC_ITEM* candidateDrcItem =
static_cast<DRC_ITEM*
>( marker->GetRCItem().get() );
847 marker->SetExcluded(
true );
849 wxString serialized = marker->SerializeToString();
859 case ID_INSPECT_VIOLATION:
863 case ID_SET_SEVERITY_TO_ERROR:
868 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
877 case ID_SET_SEVERITY_TO_WARNING:
882 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
891 case ID_SET_SEVERITY_TO_IGNORE:
897 listItem.SetText( wxT(
" • " ) + rcItem->GetErrorText() );
898 listItem.SetData( rcItem->GetErrorCode() );
904 std::vector<BOARD_ITEM*> toRemove;
908 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
911 toRemove.emplace_back( marker );
916 board->
Remove( marker, REMOVE_MODE::BULK );
929 case ID_EDIT_SEVERITIES:
945 int errorCode = (int) event.m_item.GetData();
954 int severity = GetPopupMenuSelectionFromUser( menu );
958 if(
bds().m_DRCSeverities[ errorCode ] != severity )
978 if( aEvent.GetEventObject() ==
m_showAll )
993 wxFileDialog dlg(
this,
_(
"Save Report File" ),
Prj().GetProjectPath(), fn.GetFullName(),
995 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
997 if( dlg.ShowModal() != wxID_OK )
1002 if( fn.GetExt().IsEmpty() )
1005 if( !fn.IsAbsolute() )
1008 fn.MakeAbsolute( prj_path );
1014 bool success =
false;
1021 m_messages->
Report( wxString::Format(
_(
"Report file '%s' created<br>" ), fn.GetFullPath() ) );
1023 DisplayError(
this, wxString::Format(
_(
"Failed to create file '%s'." ), fn.GetFullPath() ) );
1032 wxCommandEvent
dummy;
1047 SetReturnCode( wxID_CANCEL );
1195 static bool s_includeExclusions =
false;
1197 int numExcluded = 0;
1208 if( numExcluded > 0 )
1210 wxMessageDialog dlg(
this,
_(
"Delete exclusions too?" ),
_(
"Delete All Markers" ),
1211 wxYES_NO | wxCANCEL | wxCENTER | wxICON_QUESTION );
1212 dlg.SetYesNoLabels(
_(
"Errors and Warnings Only" ),
1213 _(
"Errors, Warnings and Exclusions" ) );
1215 int ret = dlg.ShowModal();
1217 if( ret == wxID_CANCEL )
1219 else if( ret == wxID_NO )
1220 s_includeExclusions =
true;
1239 int numUnconnected = 0;
1240 int numFootprints = 0;
1243 int numWarnings = 0;
1244 int numExcluded = 0;
1270 bool errorsOverflowed =
false;
1271 bool warningsOverflowed =
false;
1272 bool markersOverflowed =
false;
1273 bool unconnectedOverflowed =
false;
1274 bool footprintsOverflowed =
false;
1280 if( drcEngine->IsErrorLimitExceeded( ii ) )
1283 errorsOverflowed =
true;
1285 warningsOverflowed =
true;
1290 unconnectedOverflowed =
true;
1292 unconnectedOverflowed =
true;
1302 footprintsOverflowed =
true;
1304 footprintsOverflowed =
true;
1309 markersOverflowed =
true;
1311 markersOverflowed =
true;
1323 num.Printf( markersOverflowed ? wxT(
"%d+" ) : wxT(
"%d" ), numMarkers );
1329 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1336 num.Printf( unconnectedOverflowed ? wxT(
"%d+" ) : wxT(
"%d" ), numUnconnected );
1342 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1349 num.Printf( footprintsOverflowed ? wxT(
"%d+" ) : wxT(
"%d" ), numFootprints );
1355 msg.Replace( wxT(
"%s" ),
_(
"not run" ) );
1360 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1373 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1383 if( !
m_drcRun && numWarnings == 0 )
constexpr double PCB_IU_PER_MM
Pcbnew IU is 1 nanometer.
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static TOOL_ACTION selectionClear
Clear the current selection.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void SetLayerVisible(int aLayer, bool isVisible)
BASE_SET & set(size_t pos)
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
std::map< wxString, wxString > m_DrcExclusionComments
std::map< int, SEVERITY > m_DRCSeverities
std::set< wxString > m_DrcExclusions
SEVERITY GetSeverity(int aDRCErrorCode)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Information pertinent to a Pcbnew printed circuit board.
const LSET & GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
void RecordDRCExclusions()
Scan existing markers and record data from any that are Excluded.
const MARKERS & Markers() const
void FinalizeBulkRemove(std::vector< BOARD_ITEM * > &aRemovedItems)
Must be used if Remove() is used using a BULK_x REMOVE_MODE to generate a change event for listeners.
void UpdateRatsnestExclusions()
Update the visibility flags on the current unconnected ratsnest lines.
void DeleteMARKERs()
Delete all MARKERS from the board.
void Remove(BOARD_ITEM *aBoardItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
CN_EDGE represents a point-to-point connection, whether realized or unrealized (ie: tracks etc.
std::shared_ptr< const CN_ANCHOR > GetSourceNode() const
std::shared_ptr< const CN_ANCHOR > GetTargetNode() const
wxCheckBox * m_cbRefillZones
wxButton * m_DeleteAllMarkersButton
wxCheckBox * m_showExclusions
wxCheckBox * m_showErrors
wxDataViewCtrl * m_unconnectedDataView
wxDataViewCtrl * m_footprintsDataView
NUMBER_BADGE * m_warningsBadge
wxCheckBox * m_cbReportAllTrackErrors
NUMBER_BADGE * m_exclusionsBadge
wxSimplebook * m_runningResultsBook
wxButton * m_DeleteCurrentMarkerButton
wxButton * m_sdbSizerCancel
wxCheckBox * m_cbTestFootprints
wxCheckBox * m_showWarnings
wxListCtrl * m_ignoredList
NUMBER_BADGE * m_errorsBadge
WX_HTML_REPORT_BOX * m_messages
wxDataViewCtrl * m_markerDataView
void OnDRCItemSelected(wxDataViewEvent &aEvent) override
wxString m_footprintsTitleTemplate
void UpdateData()
Rebuild the contents of the violation tabs based on the current markers and severties.
std::shared_ptr< RC_ITEMS_PROVIDER > m_ratsnestProvider
wxString m_markersTitleTemplate
DIALOG_DRC(PCB_EDIT_FRAME *aEditorFrame, wxWindow *aParent)
Constructors.
void OnEditViolationSeverities(wxHyperlinkEvent &aEvent) override
void OnDeleteOneClick(wxCommandEvent &aEvent) override
RC_TREE_MODEL * m_fpWarningsTreeModel
void OnDeleteAllClick(wxCommandEvent &aEvent) override
bool TransferDataToWindow() override
void OnErrorLinkClicked(wxHtmlLinkEvent &event) override
BOARD_DESIGN_SETTINGS & bds()
void SelectMarker(const PCB_MARKER *aMarker)
std::chrono::steady_clock::time_point m_lastUpdateUi
Used to slow down the rate of yields in updateUi()
void OnClose(wxCloseEvent &event) override
void OnDRCItemRClick(wxDataViewEvent &aEvent) override
void OnRunDRCClick(wxCommandEvent &aEvent) override
wxString m_ignoredTitleTemplate
void OnDRCItemDClick(wxDataViewEvent &aEvent) override
void deleteAllMarkers(bool aIncludeExclusions)
void updateDisplayedCounts()
RC_TREE_MODEL * m_unconnectedTreeModel
wxString m_unconnectedTitleTemplate
std::shared_ptr< RC_ITEMS_PROVIDER > m_fpWarningsProvider
std::shared_ptr< RC_ITEMS_PROVIDER > m_markersProvider
void OnSeverity(wxCommandEvent &aEvent) override
void OnIgnoredItemRClick(wxListEvent &event) override
void OnCancelClick(wxCommandEvent &aEvent) override
void OnActivateDlg(wxActivateEvent &aEvent) override
void OnChangingNotebookPage(wxNotebookEvent &aEvent) override
void OnSaveReport(wxCommandEvent &aEvent) override
RC_TREE_MODEL * m_markersTreeModel
bool Show(bool show) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
EDA_UNITS GetUserUnits() const
Design Rule Checker object that performs all the DRC tests.
DRC_RULE * GetViolatingRule() const
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities(bool aIncludeDeprecated=false)
bool WriteJsonReport(const wxString &aFullFileName)
bool WriteTextReport(const wxString &aFullFileName)
void RefreshCanvas() override
void FocusOnLocation(const VECTOR2I &aPos)
Useful to focus on a particular location, in find functions.
virtual void ClearFocus()
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
virtual VECTOR2I GetPosition() const
KICAD_T Type() const
Returns the type of object.
EDA_ITEM_FLAGS GetFlags() const
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
LSET is a set of PCB_LAYER_IDs.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static const LSET & AllLayersMask()
void SetExcluded(bool aExcluded, const wxString &aComment=wxEmptyString)
enum MARKER_T GetMarkerType() const
void SetMaximumNumber(int aMax)
Set the maximum number to be shown on the badge.
void UpdateNumber(int aNumber, SEVERITY aSeverity)
Update the number displayed on the badge.
DISPLAY_OPTIONS m_Display
static TOOL_ACTION showRatsnest
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
APPEARANCE_CONTROLS * GetAppearancePanel()
void FocusOnItem(EDA_ITEM *aItem) override
Focus on a particular canvas item.
PCBNEW_SETTINGS * GetPcbNewSettings() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.
The main frame for Pcbnew.
void ShowBoardSetupDialog(const wxString &aInitialPage=wxEmptyString)
void SetActiveLayer(PCB_LAYER_ID aLayer) override
Change the currently active layer to aLayer and also update the APPEARANCE_CONTROLS.
void OnModify() override
Must be called after a board change to set the modified flag.
SEVERITY GetSeverity() const override
wxString SerializeToString() const
virtual wxApp & App()
Return a bare naked wxApp which may come from wxPython, SINGLE_TOP, or kicad.exe.
This implements all the tricky bits for thread safety, but the GUI is left to derived classes.
virtual void AdvancePhase() override
Use the next available virtual zone of the dialog progress bar.
virtual void SetCurrentProgress(double aProgress) override
Set the progress value to aProgress (0..1).
std::atomic_bool m_cancelled
std::atomic_int m_progress
std::atomic_int m_maxProgress
virtual void AdvancePhase()=0
Use the next available virtual zone of the dialog progress bar.
virtual const wxString GetProjectPath() const
Return the full path of the project.
void SelectMarker(const MARKER_BASE *aMarker)
static RC_TREE_NODE * ToNode(wxDataViewItem aItem)
void ValueChanged(RC_TREE_NODE *aNode)
void Update(std::shared_ptr< RC_ITEMS_PROVIDER > aProvider, int aSeverities)
void DeleteItems(bool aCurrentOnly, bool aIncludeExclusions, bool aDeep)
Delete the current item or all items.
void DeleteCurrentItem(bool aDeep)
void CenterMarker(const MARKER_BASE *aMarker)
static KIID ToUUID(wxDataViewItem aItem)
std::shared_ptr< RC_ITEM > m_RcItem
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
void Clear() override
Delete the stored messages.
void SetImmediateMode()
In immediate mode, messages are flushed as they are added.
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
void Flush()
Build the HTML messages page.
A KICAD version of wxTextEntryDialog which supports the various improvements/work-arounds from DIALOG...
wxString GetValue() const
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
This file is part of the common library.
static int DEFAULT_SINGLE_COL_WIDTH
static BOARD * g_lastDRCBoard
static bool g_lastFootprintTestsRun
static std::vector< std::pair< wxString, int > > g_lastIgnored
#define DIALOG_DRC_WINDOW_NAME
@ DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG
@ DRCE_MALFORMED_COURTYARD
@ DRCE_UNRESOLVED_VARIABLE
@ DRCE_DUPLICATE_FOOTPRINT
#define MALFORMED_F_COURTYARD
#define MALFORMED_B_COURTYARD
static int DEFAULT_SINGLE_COL_WIDTH
double m_MinimumMarkerSeparationDistance
When finding overlapped marker a minium distance (in mm) between two DRC markers required to mark it ...
static const std::string ReportFileExtension
static const std::string JsonFileExtension
static wxString JsonFileWildcard()
static wxString ReportFileWildcard()
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
PGM_BASE & Pgm()
The global program "get" accessor.
std::vector< FAB_LAYER_COLOR > dummy
A filename or source description, a problem input line, a line number, a byte offset,...
bool m_ShowGlobalRatsnest
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
@ PCB_PAD_T
class PAD, a pad in a footprint
Functions to provide common constants and other functions to assist in making a consistent UI.
Definition of file extensions used in Kicad.