45#include <wx/filedlg.h>
47#include <wx/wupdlock.h>
77 m_footprintTestsRun( false ),
78 m_markersTreeModel( nullptr ),
79 m_unconnectedTreeModel( nullptr ),
80 m_fpWarningsTreeModel( nullptr ),
82 m_lastUpdateUi(
std::chrono::steady_clock::now() )
136 listItem.SetText( str );
137 listItem.SetData( code );
149 { wxID_CANCEL,
_(
"Close" ) } } );
187 if( !
Kiface().IsSingle() )
205 SetReturnCode( wxID_CANCEL );
220 int newValue =
KiROUND( cur * 1000.0 );
227 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
228 if( std::chrono::duration_cast<std::chrono::milliseconds>( now -
m_lastUpdateUi ).count()
231 Pgm().
App().SafeYieldFor(
this, wxEVT_CATEGORY_NATIVE_EVENTS );
276 if( zoneFillerTool->IsBusy() )
296 m_messages->
Report(
_(
"DRC incomplete: could not compile custom design rules." )
297 + wxS(
" " )
298 + wxS(
"<a href='$CUSTOM_RULES'>" ) +
_(
"Show design rules." ) + wxT(
"</a>" ) );
317 for( std::reference_wrapper<RC_ITEM>& item : violations )
323 listItem.SetText( wxT(
" • " ) + item.get().GetErrorText() );
324 listItem.SetData( item.get().GetErrorCode() );
347 drcTool->
RunTests(
this, refillZones, reportAllTrackErrors, testFootprints );
400 auto getActiveLayers =
408 for(
int layer : aItem->GetLayerSet().Seq() )
410 if(
pad->FlashLayer( layer ) )
418 return aItem->GetLayerSet();
428 double dist = selectedItemPos.
Distance( unSelectedItemPos );
430 double minimumMarkerSeparationDistance =
433 return dist <= minimumMarkerSeparationDistance;
444 std::shared_ptr<RC_ITEM> rc_item = node->
m_RcItem;
466 LSET violationLayers;
492 if( a || b || c || d )
503 LSET layersList = getActiveLayers( it );
504 violationLayers &= layersList;
507 principalLayer = layersList.
Seq().front();
511 if( violationLayers.count() )
512 principalLayer = violationLayers.
Seq().front();
513 else if( principalLayer >= 0 )
514 violationLayers.
set( principalLayer );
549 if( item == a && item == b )
551 focusPos = ( node->m_Type == RC_TREE_NODE::MAIN_ITEM )
552 ? edge.GetSourcePos()
553 : edge.GetTargetPos();
557 focusPos = ( item == edge.GetSourceNode()->Parent() )
558 ? edge.GetSourcePos()
559 : edge.GetTargetPos();
579 std::vector<BOARD_ITEM*> items;
587 for(
const KIID&
id : rc_item->GetIDs() )
591 if( candidate && candidate->GetNetCode() == net )
592 items.push_back( candidate );
597 items.push_back( item );
600 m_frame->FocusOnItems( items, principalLayer );
606 std::vector<BOARD_ITEM*> items;
608 for(
BOARD_ITEM* boardMarkerItem : board->Markers() )
610 if( item->m_Uuid != boardMarkerItem->m_Uuid && isOverlapping( item, boardMarkerItem ) )
612 items.push_back( boardMarkerItem );
616 items.push_back( item );
617 m_frame->FocusOnItems( items, principalLayer );
621 m_frame->FocusOnItem( item, principalLayer );
631 if( aEvent.GetItem().IsOk() )
653 std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
663 default: listName =
_(
"appropriate" );
break;
668 ID_EDIT_EXCLUSION_COMMENT = 4467,
670 ID_REMOVE_EXCLUSION_ALL,
672 ID_ADD_EXCLUSION_WITH_COMMENT,
673 ID_ADD_EXCLUSION_ALL,
674 ID_INSPECT_VIOLATION,
675 ID_SET_SEVERITY_TO_ERROR,
676 ID_SET_SEVERITY_TO_WARNING,
677 ID_SET_SEVERITY_TO_IGNORE,
681 if( rcItem->GetParent()->IsExcluded() )
683 menu.Append( ID_REMOVE_EXCLUSION,
684 _(
"Remove exclusion for this violation" ),
685 wxString::Format(
_(
"It will be placed back in the %s list" ), listName ) );
687 menu.Append( ID_EDIT_EXCLUSION_COMMENT,
688 _(
"Edit exclusion comment..." ) );
692 menu.Append( ID_REMOVE_EXCLUSION_ALL,
693 wxString::Format(
_(
"Remove all exclusions for violations of rule '%s'" ),
695 wxString::Format(
_(
"They will be placed back in the %s list" ), listName ) );
700 menu.Append( ID_ADD_EXCLUSION,
701 _(
"Exclude this violation" ),
702 wxString::Format(
_(
"It will be excluded from the %s list" ), listName ) );
704 menu.Append( ID_ADD_EXCLUSION_WITH_COMMENT,
705 _(
"Exclude with comment..." ),
706 wxString::Format(
_(
"It will be excluded from the %s list" ), listName ) );
710 menu.Append( ID_ADD_EXCLUSION_ALL,
711 wxString::Format(
_(
"Exclude all violations of rule '%s'..." ),
713 wxString::Format(
_(
"They will be excluded from the %s list" ), listName ) );
719 if( !inspectDRCErrorMenuText.IsEmpty() )
720 menu.Append( ID_INSPECT_VIOLATION, inspectDRCErrorMenuText );
722 menu.AppendSeparator();
726 menu.Append( ID_SET_SEVERITY_TO_ERROR,
727 wxString::Format(
_(
"Change severity to Error for all '%s' violations" ),
728 rcItem->GetErrorText() ),
729 _(
"Violation severities can also be edited in the Board Setup... dialog" ) );
733 menu.Append( ID_SET_SEVERITY_TO_WARNING,
734 wxString::Format(
_(
"Change severity to Warning for all '%s' violations" ),
735 rcItem->GetErrorText() ),
736 _(
"Violation severities can also be edited in the Board Setup... dialog" ) );
739 menu.Append( ID_SET_SEVERITY_TO_IGNORE,
740 wxString::Format(
_(
"Ignore all '%s' violations" ), rcItem->GetErrorText() ),
741 _(
"Violations will not be checked or reported" ) );
743 menu.AppendSeparator();
745 menu.Append( ID_EDIT_SEVERITIES,
746 _(
"Edit violation severities..." ),
747 _(
"Open the Board Setup... dialog" ) );
749 bool modified =
false;
750 int command = GetPopupMenuSelectionFromUser( menu );
754 case ID_EDIT_EXCLUSION_COMMENT:
758 marker->GetComment(),
true );
763 marker->SetExcluded(
true, dlg.
GetValue() );
765 wxString serialized = marker->SerializeToString();
770 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->ValueChanged( node );
776 case ID_REMOVE_EXCLUSION:
779 marker->SetExcluded(
false );
781 wxString serialized = marker->SerializeToString();
796 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->ValueChanged( node );
802 case ID_ADD_EXCLUSION:
803 case ID_ADD_EXCLUSION_WITH_COMMENT:
808 if( command == ID_ADD_EXCLUSION_WITH_COMMENT )
811 wxEmptyString,
true );
819 marker->SetExcluded(
true, comment );
821 wxString serialized = marker->SerializeToString();
837 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->ValueChanged( node );
839 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->DeleteCurrentItem(
false );
846 case ID_REMOVE_EXCLUSION_ALL:
849 DRC_ITEM* candidateDrcItem =
static_cast<DRC_ITEM*
>( marker->GetRCItem().get() );
853 marker->SetExcluded(
false );
855 wxString serialized = marker->SerializeToString();
866 case ID_ADD_EXCLUSION_ALL:
869 DRC_ITEM* candidateDrcItem =
static_cast<DRC_ITEM*
>( marker->GetRCItem().get() );
873 marker->SetExcluded(
true );
875 wxString serialized = marker->SerializeToString();
885 case ID_INSPECT_VIOLATION:
889 case ID_SET_SEVERITY_TO_ERROR:
894 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
903 case ID_SET_SEVERITY_TO_WARNING:
908 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
917 case ID_SET_SEVERITY_TO_IGNORE:
923 listItem.SetText( wxT(
" • " ) + rcItem->GetErrorText() );
924 listItem.SetData( rcItem->GetErrorCode() );
930 std::vector<BOARD_ITEM*> toRemove;
934 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
937 toRemove.emplace_back( marker );
942 board->
Remove( marker, REMOVE_MODE::BULK );
955 case ID_EDIT_SEVERITIES:
971 int errorCode = (int) event.m_item.GetData();
980 int severity = GetPopupMenuSelectionFromUser( menu );
984 if(
bds().m_DRCSeverities[ errorCode ] != severity )
1006 if( aEvent.GetEventObject() ==
m_showAll )
1015 if( aEvent.IsChecked() )
1017 else if( aEvent.GetEventObject() ==
m_showAll )
1031 wxFileDialog dlg(
this,
_(
"Save Report File" ),
Prj().GetProjectPath(), fn.GetFullName(),
1033 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1035 if( dlg.ShowModal() != wxID_OK )
1040 if( fn.GetExt().IsEmpty() )
1043 if( !fn.IsAbsolute() )
1046 fn.MakeAbsolute( prj_path );
1052 bool success =
false;
1061 fn.GetFullPath() ) );
1065 DisplayError(
this, wxString::Format(
_(
"Failed to create file '%s'." ),
1066 fn.GetFullPath() ) );
1076 wxCommandEvent
dummy;
1092 SetReturnCode( wxID_CANCEL );
1240 static bool s_includeExclusions =
false;
1242 int numExcluded = 0;
1253 if( numExcluded > 0 )
1255 wxMessageDialog dlg(
this,
_(
"Delete exclusions too?" ),
_(
"Delete All Markers" ),
1256 wxYES_NO | wxCANCEL | wxCENTER | wxICON_QUESTION );
1257 dlg.SetYesNoLabels(
_(
"Errors and Warnings Only" ),
1258 _(
"Errors, Warnings and Exclusions" ) );
1260 int ret = dlg.ShowModal();
1262 if( ret == wxID_CANCEL )
1264 else if( ret == wxID_NO )
1265 s_includeExclusions =
true;
1284 int numUnconnected = 0;
1285 int numFootprints = 0;
1288 int numWarnings = 0;
1289 int numExcluded = 0;
1317 bool errorsOverflowed =
false;
1318 bool warningsOverflowed =
false;
1319 bool markersOverflowed =
false;
1320 bool unconnectedOverflowed =
false;
1321 bool footprintsOverflowed =
false;
1327 if( drcEngine->IsErrorLimitExceeded( ii ) )
1330 errorsOverflowed =
true;
1332 warningsOverflowed =
true;
1337 unconnectedOverflowed =
true;
1339 unconnectedOverflowed =
true;
1349 footprintsOverflowed =
true;
1351 footprintsOverflowed =
true;
1356 markersOverflowed =
true;
1358 markersOverflowed =
true;
1370 num.Printf( markersOverflowed ? wxT(
"%d+" ) : wxT(
"%d" ), numMarkers );
1376 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1383 num.Printf( unconnectedOverflowed ? wxT(
"%d+" ) : wxT(
"%d" ), numUnconnected );
1389 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1396 num.Printf( footprintsOverflowed ? wxT(
"%d+" ) : wxT(
"%d" ), numFootprints );
1402 msg.Replace( wxT(
"%s" ),
_(
"not run" ) );
1407 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1420 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1430 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
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 RPT_SEVERITY_ALL
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.
static int RPT_SEVERITY_ALL