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() )
128 listItem.SetText( str );
129 listItem.SetData( code );
141 { wxID_CANCEL,
_(
"Close" ) } } );
186 catch(
const std::runtime_error& e )
188 wxFAIL_MSG( e.what() );
196 if( !
Kiface().IsSingle() )
214 SetReturnCode( wxID_CANCEL );
229 int newValue =
KiROUND( cur * 1000.0 );
236 std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
237 if( std::chrono::duration_cast<std::chrono::milliseconds>( now -
m_lastUpdateUi ).count()
240 Pgm().
App().SafeYieldFor(
this, wxEVT_CATEGORY_NATIVE_EVENTS );
285 if( zoneFillerTool->IsBusy() )
305 m_messages->
Report(
_(
"DRC incomplete: could not compile custom design rules." )
306 + wxS(
" " )
307 + wxS(
"<a href='$CUSTOM_RULES'>" ) +
_(
"Show design rules." ) + wxT(
"</a>" ) );
326 for( std::reference_wrapper<RC_ITEM>& item : violations )
332 listItem.SetText( wxT(
" • " ) + item.get().GetErrorText() );
333 listItem.SetData( item.get().GetErrorCode() );
356 drcTool->
RunTests(
this, refillZones, reportAllTrackErrors, testFootprints );
409 auto getActiveLayers =
417 for(
int layer : aItem->GetLayerSet().Seq() )
419 if(
pad->FlashLayer( layer ) )
427 return aItem->GetLayerSet();
437 double dist = selectedItemPos.
Distance( unSelectedItemPos );
439 double minimumMarkerSeparationDistance =
442 return dist <= minimumMarkerSeparationDistance;
453 std::shared_ptr<RC_ITEM> rc_item = node->
m_RcItem;
476 LSET violationLayers;
502 if( a || b || c || d )
513 LSET layersList = getActiveLayers( it );
514 violationLayers &= layersList;
517 principalLayer = layersList.
Seq().front();
521 if( violationLayers.count() )
522 principalLayer = violationLayers.
Seq().front();
524 violationLayers.
set( principalLayer );
559 if( item == a && item == b )
561 focusPos = ( node->m_Type == RC_TREE_NODE::MAIN_ITEM )
562 ? edge.GetSourcePos()
563 : edge.GetTargetPos();
567 focusPos = ( item == edge.GetSourceNode()->Parent() )
568 ? edge.GetSourcePos()
569 : edge.GetTargetPos();
589 std::vector<BOARD_ITEM*> items;
597 for(
const KIID&
id : rc_item->GetIDs() )
601 if( candidate && candidate->GetNetCode() == net )
602 items.push_back( candidate );
607 items.push_back( item );
610 m_frame->FocusOnItems( items, principalLayer );
616 std::vector<BOARD_ITEM*> items;
618 for(
BOARD_ITEM* boardMarkerItem : board->Markers() )
620 if( item->m_Uuid != boardMarkerItem->m_Uuid && isOverlapping( item, boardMarkerItem ) )
622 items.push_back( boardMarkerItem );
626 items.push_back( item );
627 m_frame->FocusOnItems( items, principalLayer );
631 m_frame->FocusOnItem( item, principalLayer );
641 if( aEvent.GetItem().IsOk() )
663 std::shared_ptr<RC_ITEM> rcItem = node->m_RcItem;
673 default: listName =
_(
"appropriate" );
break;
678 ID_EDIT_EXCLUSION_COMMENT = 4467,
680 ID_REMOVE_EXCLUSION_ALL,
682 ID_ADD_EXCLUSION_WITH_COMMENT,
683 ID_ADD_EXCLUSION_ALL,
684 ID_INSPECT_VIOLATION,
685 ID_SET_SEVERITY_TO_ERROR,
686 ID_SET_SEVERITY_TO_WARNING,
687 ID_SET_SEVERITY_TO_IGNORE,
691 if( rcItem->GetParent()->IsExcluded() )
693 menu.Append( ID_REMOVE_EXCLUSION,
694 _(
"Remove exclusion for this violation" ),
695 wxString::Format(
_(
"It will be placed back in the %s list" ), listName ) );
697 menu.Append( ID_EDIT_EXCLUSION_COMMENT,
698 _(
"Edit exclusion comment..." ) );
702 menu.Append( ID_REMOVE_EXCLUSION_ALL,
703 wxString::Format(
_(
"Remove all exclusions for violations of rule '%s'" ),
705 wxString::Format(
_(
"They will be placed back in the %s list" ), listName ) );
710 menu.Append( ID_ADD_EXCLUSION,
711 _(
"Exclude this violation" ),
712 wxString::Format(
_(
"It will be excluded from the %s list" ), listName ) );
714 menu.Append( ID_ADD_EXCLUSION_WITH_COMMENT,
715 _(
"Exclude with comment..." ),
716 wxString::Format(
_(
"It will be excluded from the %s list" ), listName ) );
720 menu.Append( ID_ADD_EXCLUSION_ALL,
721 wxString::Format(
_(
"Exclude all violations of rule '%s'..." ),
723 wxString::Format(
_(
"They will be excluded from the %s list" ), listName ) );
729 if( !inspectDRCErrorMenuText.IsEmpty() )
730 menu.Append( ID_INSPECT_VIOLATION, inspectDRCErrorMenuText );
732 menu.AppendSeparator();
736 menu.Append( ID_SET_SEVERITY_TO_ERROR,
737 wxString::Format(
_(
"Change severity to Error for all '%s' violations" ),
738 rcItem->GetErrorText() ),
739 _(
"Violation severities can also be edited in the Board Setup... dialog" ) );
743 menu.Append( ID_SET_SEVERITY_TO_WARNING,
744 wxString::Format(
_(
"Change severity to Warning for all '%s' violations" ),
745 rcItem->GetErrorText() ),
746 _(
"Violation severities can also be edited in the Board Setup... dialog" ) );
749 menu.Append( ID_SET_SEVERITY_TO_IGNORE,
750 wxString::Format(
_(
"Ignore all '%s' violations" ), rcItem->GetErrorText() ),
751 _(
"Violations will not be checked or reported" ) );
753 menu.AppendSeparator();
755 menu.Append( ID_EDIT_SEVERITIES,
756 _(
"Edit violation severities..." ),
757 _(
"Open the Board Setup... dialog" ) );
759 bool modified =
false;
760 int command = GetPopupMenuSelectionFromUser( menu );
764 case ID_EDIT_EXCLUSION_COMMENT:
768 marker->GetComment(),
true );
773 marker->SetExcluded(
true, dlg.
GetValue() );
775 wxString serialized = marker->SerializeToString();
780 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->ValueChanged( node );
786 case ID_REMOVE_EXCLUSION:
789 marker->SetExcluded(
false );
791 wxString serialized = marker->SerializeToString();
806 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->ValueChanged( node );
812 case ID_ADD_EXCLUSION:
813 case ID_ADD_EXCLUSION_WITH_COMMENT:
818 if( command == ID_ADD_EXCLUSION_WITH_COMMENT )
821 wxEmptyString,
true );
829 marker->SetExcluded(
true, comment );
831 wxString serialized = marker->SerializeToString();
847 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->ValueChanged( node );
849 static_cast<RC_TREE_MODEL*
>( aEvent.GetModel() )->DeleteCurrentItem(
false );
856 case ID_REMOVE_EXCLUSION_ALL:
859 DRC_ITEM* candidateDrcItem =
static_cast<DRC_ITEM*
>( marker->GetRCItem().get() );
863 marker->SetExcluded(
false );
865 wxString serialized = marker->SerializeToString();
876 case ID_ADD_EXCLUSION_ALL:
879 DRC_ITEM* candidateDrcItem =
static_cast<DRC_ITEM*
>( marker->GetRCItem().get() );
883 marker->SetExcluded(
true );
885 wxString serialized = marker->SerializeToString();
895 case ID_INSPECT_VIOLATION:
899 case ID_SET_SEVERITY_TO_ERROR:
904 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
913 case ID_SET_SEVERITY_TO_WARNING:
918 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
927 case ID_SET_SEVERITY_TO_IGNORE:
933 listItem.SetText( wxT(
" • " ) + rcItem->GetErrorText() );
934 listItem.SetData( rcItem->GetErrorCode() );
940 std::vector<BOARD_ITEM*> toRemove;
944 if( marker->GetRCItem()->GetErrorCode() == rcItem->GetErrorCode() )
947 toRemove.emplace_back( marker );
952 board->
Remove( marker, REMOVE_MODE::BULK );
965 case ID_EDIT_SEVERITIES:
981 int errorCode = (int) event.m_item.GetData();
990 int severity = GetPopupMenuSelectionFromUser( menu );
994 if(
bds().m_DRCSeverities[ errorCode ] != severity )
1016 if( aEvent.GetEventObject() ==
m_showAll )
1025 if( aEvent.IsChecked() )
1027 else if( aEvent.GetEventObject() ==
m_showAll )
1041 wxFileDialog dlg(
this,
_(
"Save Report File" ),
Prj().GetProjectPath(), fn.GetFullName(),
1043 wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
1045 if( dlg.ShowModal() != wxID_OK )
1050 if( fn.GetExt().IsEmpty() )
1053 if( !fn.IsAbsolute() )
1056 fn.MakeAbsolute( prj_path );
1062 bool success =
false;
1071 fn.GetFullPath() ) );
1075 DisplayError(
this, wxString::Format(
_(
"Failed to create file '%s'." ),
1076 fn.GetFullPath() ) );
1086 wxCommandEvent
dummy;
1102 SetReturnCode( wxID_CANCEL );
1250 static bool s_includeExclusions =
false;
1252 int numExcluded = 0;
1263 if( numExcluded > 0 )
1265 wxMessageDialog dlg(
this,
_(
"Delete exclusions too?" ),
_(
"Delete All Markers" ),
1266 wxYES_NO | wxCANCEL | wxCENTER | wxICON_QUESTION );
1267 dlg.SetYesNoLabels(
_(
"Errors and Warnings Only" ),
1268 _(
"Errors, Warnings and Exclusions" ) );
1270 int ret = dlg.ShowModal();
1272 if( ret == wxID_CANCEL )
1274 else if( ret == wxID_NO )
1275 s_includeExclusions =
true;
1293 int numUnconnected = 0;
1294 int numFootprints = 0;
1297 int numWarnings = 0;
1298 int numExcluded = 0;
1326 bool errorsOverflowed =
false;
1327 bool warningsOverflowed =
false;
1328 bool markersOverflowed =
false;
1329 bool unconnectedOverflowed =
false;
1330 bool footprintsOverflowed =
false;
1336 if( drcEngine->IsErrorLimitExceeded( ii ) )
1339 errorsOverflowed =
true;
1341 warningsOverflowed =
true;
1346 unconnectedOverflowed =
true;
1348 unconnectedOverflowed =
true;
1358 footprintsOverflowed =
true;
1360 footprintsOverflowed =
true;
1365 markersOverflowed =
true;
1367 markersOverflowed =
true;
1379 num.Printf( markersOverflowed ? wxT(
"%d+" ) : wxT(
"%d" ), numMarkers );
1385 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1392 num.Printf( unconnectedOverflowed ? wxT(
"%d+" ) : wxT(
"%d" ), numUnconnected );
1398 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1405 num.Printf( footprintsOverflowed ? wxT(
"%d+" ) : wxT(
"%d" ), numFootprints );
1411 msg.Replace( wxT(
"%s" ),
_(
"not run" ) );
1416 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1429 msg.Replace( wxT(
"(%s)" ), wxEmptyString );
1439 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 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.
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
BOARD_ITEM * GetItem(const KIID &aID) const
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.
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
static DELETED_BOARD_ITEM * GetInstance()
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 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
bool IsSingle() const
Is this KIFACE running under single_top?
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.
static LSET AllLayersMask()
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
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
static TOOL_ACTION selectionClear
Clear the current selection.
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
APPEARANCE_CONTROLS * GetAppearancePanel()
PCBNEW_SETTINGS * GetPcbNewSettings() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void FocusOnItem(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer=UNDEFINED_LAYER)
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()
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, int aDisplayTime)
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 test_all_track_errors
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