diff --git a/common/widgets/infobar.cpp b/common/widgets/infobar.cpp index 764745e39b..e9317e32cc 100644 --- a/common/widgets/infobar.cpp +++ b/common/widgets/infobar.cpp @@ -26,6 +26,7 @@ #include #include #include +#include wxDEFINE_EVENT( KIEVT_SHOW_INFOBAR, wxCommandEvent ); @@ -199,6 +200,19 @@ void WX_INFOBAR::AddButton( wxButton* aButton ) } +void WX_INFOBAR::AddButton( wxHyperlinkCtrl* aHypertextButton ) +{ + wxSizer* sizer = GetSizer(); + + wxASSERT( aHypertextButton ); + + sizer->Add( aHypertextButton, wxSizerFlags().Centre().Border( wxRIGHT ) ); + + if( IsShown() ) + sizer->Layout(); +} + + void WX_INFOBAR::AddCloseButton( const wxString& aTooltip ) { wxBitmapButton* button = wxBitmapButton::NewCloseButton( this, ID_CLOSE_INFOBAR ); diff --git a/include/widgets/infobar.h b/include/widgets/infobar.h index 1c678c1df5..686b970bb1 100644 --- a/include/widgets/infobar.h +++ b/include/widgets/infobar.h @@ -25,7 +25,9 @@ #include #include + class wxAuiManager; +class wxHyperlinkCtrl; enum @@ -105,6 +107,14 @@ public: */ void AddButton( wxButton* aButton ); + /** + * Add an already created hypertext link to the infobar. + * New buttons are added in the right-most position. + * + * @param aHypertextButton is the button to add + */ + void AddButton( wxHyperlinkCtrl* aHypertextButton ); + /** * Add a button with the provided ID and text. * The new button is created on the right-most positon. diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index 53ea96e471..39649fd8ff 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -210,8 +210,7 @@ void DIALOG_DRC::OnRunDRCClick( wxCommandEvent& aEvent ) // issues (on at least OSX) if we don't. drcTool->DestroyDRCDialog(); - m_brdEditor->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR, - pe.lineNumber, pe.byteIndex ); + m_brdEditor->ShowBoardSetupDialog( _( "Rules" ) ); return; } diff --git a/pcbnew/dialogs/panel_setup_rules.cpp b/pcbnew/dialogs/panel_setup_rules.cpp index 6f4f0e2a0d..3009a738bb 100644 --- a/pcbnew/dialogs/panel_setup_rules.cpp +++ b/pcbnew/dialogs/panel_setup_rules.cpp @@ -386,6 +386,9 @@ bool PANEL_SETUP_RULES::TransferDataToWindow() ConvertSmartQuotesAndDashes( &str ); m_textEditor->AddText( str << '\n' ); } + + wxCommandEvent dummy; + OnCompile( dummy ); } } diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index 88f527ecb5..5201aef37c 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -406,7 +406,7 @@ void DRC_ENGINE::loadRules( const wxFileName& aPath ) } -bool DRC_ENGINE::CompileRules() +void DRC_ENGINE::compileRules() { ReportAux( wxString::Format( "Compiling Rules (%d rules, %d conditions): ", (int) m_rules.size(), @@ -477,8 +477,6 @@ bool DRC_ENGINE::CompileRules() } } } - - return true; } @@ -497,14 +495,17 @@ void DRC_ENGINE::InitEngine( const wxFileName& aRulePath ) m_ruleConditions.clear(); m_rules.clear(); + m_rulesValid = false; loadImplicitRules(); loadRules( aRulePath ); - CompileRules(); + compileRules(); for( int ii = DRCE_FIRST; ii < DRCE_LAST; ++ii ) m_errorLimits[ ii ] = INT_MAX; + + m_rulesValid = true; } diff --git a/pcbnew/drc/drc_engine.h b/pcbnew/drc/drc_engine.h index d15af28b53..3b23eac6da 100644 --- a/pcbnew/drc/drc_engine.h +++ b/pcbnew/drc/drc_engine.h @@ -164,7 +164,7 @@ public: bool GetReportAllTrackErrors() const { return m_reportAllTrackErrors; } bool GetTestFootprints() const { return m_testFootprints; } - bool CompileRules(); + bool RulesValid() { return m_rulesValid; } void ReportViolation( const std::shared_ptr& aItem, wxPoint aPos ); bool ReportProgress( double aProgress ); @@ -193,7 +193,7 @@ private: */ void loadRules( const wxFileName& aPath ); - void freeCompiledRules(); + void compileRules(); struct CONSTRAINT_WITH_CONDITIONS { @@ -215,6 +215,7 @@ protected: std::vector m_ruleConditions; std::vector m_rules; + bool m_rulesValid; std::vector m_testProviders; EDA_UNITS m_userUnits; diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index f41e89b97c..c1eb894b21 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -876,8 +876,7 @@ void PCB_EDIT_FRAME::ActivateGalCanvas() } -void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage, const wxString& aErrorMsg, - int aErrorCtrlId, int aErrorLine, int aErrorCol ) +void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage ) { // Make sure everything's up-to-date GetBoard()->BuildListOfNets(); @@ -887,9 +886,6 @@ void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage, const w if( !aInitialPage.IsEmpty() ) dlg.SetInitialPage( aInitialPage, wxEmptyString ); - if( !aErrorMsg.IsEmpty() ) - dlg.SetError( aErrorMsg, aInitialPage, aErrorCtrlId, aErrorLine, aErrorCol ); - if( dlg.ShowQuasiModal() == wxID_OK ) { Prj().GetProjectFile().NetSettings().ResolveNetClassAssignments( true ); diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index dd9f13cad8..327988812c 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -475,9 +475,7 @@ public: /** * Function ShowBoardSetupDialog */ - void ShowBoardSetupDialog( const wxString& aInitialPage = wxEmptyString, - const wxString& aErrorMsg = wxEmptyString, int aErrorCtrlId = -1, - int aErrorLine = -1, int aErrorCol = -1 ); + void ShowBoardSetupDialog( const wxString& aInitialPage = wxEmptyString ); /* toolbars update UI functions: */ diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 3d281e0e64..44ad9c4bb8 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -19,7 +19,7 @@ * with this program. If not, see . */ -#include +#include #include using namespace std::placeholders; #include @@ -32,6 +32,7 @@ using namespace std::placeholders; #include #include #include +#include #include #include #include @@ -717,15 +718,39 @@ int ROUTER_TOOL::onViaCommand( const TOOL_EVENT& aEvent ) // Cannot place microvias or blind vias if not allowed (obvious) if( ( viaType == VIATYPE::BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) ) { - frame()->ShowInfoBarError( _( "Blind/buried vias have to be enabled in " - "Board Setup > Design Rules > Constraints." ) ); + WX_INFOBAR* infobar = frame()->GetInfoBar(); + wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, + _("Show board setup"), wxEmptyString ); + + button->Bind( wxEVT_COMMAND_HYPERLINK, std::function( + [&]( wxHyperlinkEvent& aEvent ) + { + getEditFrame()->ShowBoardSetupDialog( _( "Constraints" ) ); + } ) ); + + infobar->ShowMessageFor( _( "Blind/buried vias have to be enabled in " + "Board Setup > Design Rules > Constraints." ), + 10000, wxICON_ERROR ); + infobar->AddButton( button ); return false; } if( ( viaType == VIATYPE::MICROVIA ) && ( !bds.m_MicroViasAllowed ) ) { - frame()->ShowInfoBarError( _( "Microvias have to be enabled in " - "Board Setup > Design Rules > Constraints." ) ); + WX_INFOBAR* infobar = frame()->GetInfoBar(); + wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, + _("Show board setup"), wxEmptyString ); + + button->Bind( wxEVT_COMMAND_HYPERLINK, std::function( + [&]( wxHyperlinkEvent& aEvent ) + { + getEditFrame()->ShowBoardSetupDialog( _( "Constraints" ) ); + } ) ); + + infobar->ShowMessageFor( _( "Microvias have to be enabled in " + "Board Setup > Design Rules > Constraints." ), + 10000, wxICON_ERROR ); + infobar->AddButton( button ); return false; } diff --git a/pcbnew/tools/pcb_inspection_tool.cpp b/pcbnew/tools/pcb_inspection_tool.cpp index 40f57441c4..13f861887c 100644 --- a/pcbnew/tools/pcb_inspection_tool.cpp +++ b/pcbnew/tools/pcb_inspection_tool.cpp @@ -197,8 +197,7 @@ void PCB_INSPECTION_TOOL::reportClearance( DRC_CONSTRAINT_TYPE_T aClearanceType, } catch( PARSE_ERROR& pe ) { - m_frame->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR, - pe.lineNumber, pe.byteIndex ); + m_frame->ShowBoardSetupDialog( _( "Rules" ) ); return; } @@ -390,8 +389,7 @@ int PCB_INSPECTION_TOOL::InspectConstraints( const TOOL_EVENT& aEvent ) } catch( PARSE_ERROR& pe ) { - m_frame->ShowBoardSetupDialog( _( "Rules" ), pe.What(), ID_RULES_EDITOR, - pe.lineNumber, pe.byteIndex ); + m_frame->ShowBoardSetupDialog( _( "Rules" ) ); return 1; } diff --git a/pcbnew/tools/zone_filler_tool.cpp b/pcbnew/tools/zone_filler_tool.cpp index 6a03eeae96..f821a7e3dd 100644 --- a/pcbnew/tools/zone_filler_tool.cpp +++ b/pcbnew/tools/zone_filler_tool.cpp @@ -28,7 +28,9 @@ #include #include #include +#include #include +#include #include #include "pcb_actions.h" #include "zone_filler_tool.h" @@ -102,6 +104,23 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller, PROGRESS_REPORTER* aRepo ZONE_FILLER filler( board(), &commit ); + if( !board()->GetDesignSettings().m_DRCEngine->RulesValid() ) + { + WX_INFOBAR* infobar = frame()->GetInfoBar(); + wxHyperlinkCtrl* button = new wxHyperlinkCtrl( infobar, wxID_ANY, _("Show DRC rules"), + wxEmptyString ); + + button->Bind( wxEVT_COMMAND_HYPERLINK, std::function( + [&]( wxHyperlinkEvent& aEvent ) + { + getEditFrame()->ShowBoardSetupDialog( _( "Rules" ) ); + } ) ); + + infobar->ShowMessageFor( _( "Zone fills may be inaccurate. DRC rules contain errors." ), + 10000, wxICON_WARNING ); + infobar->AddButton( button ); + } + if( aReporter ) filler.SetProgressReporter( aReporter ); else