From 3656297f99f6449a5517d01a38ebd62e76c08aa7 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sat, 16 May 2020 23:30:30 +0100 Subject: [PATCH] Add a simple editor for DRC rules. --- pcbnew/CMakeLists.txt | 2 + pcbnew/dialogs/dialog_board_setup.cpp | 4 +- pcbnew/dialogs/dialog_board_setup.h | 2 + pcbnew/dialogs/panel_setup_rules.cpp | 126 +++++++++++++ pcbnew/dialogs/panel_setup_rules.h | 52 ++++++ pcbnew/dialogs/panel_setup_rules_base.cpp | 71 ++++++++ pcbnew/dialogs/panel_setup_rules_base.fbp | 209 ++++++++++++++++++++++ pcbnew/dialogs/panel_setup_rules_base.h | 44 +++++ pcbnew/drc/drc.cpp | 6 +- 9 files changed, 512 insertions(+), 4 deletions(-) create mode 100644 pcbnew/dialogs/panel_setup_rules.cpp create mode 100644 pcbnew/dialogs/panel_setup_rules.h create mode 100644 pcbnew/dialogs/panel_setup_rules_base.cpp create mode 100644 pcbnew/dialogs/panel_setup_rules_base.fbp create mode 100644 pcbnew/dialogs/panel_setup_rules_base.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index de428a5ce3..2706adb934 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -165,6 +165,8 @@ set( PCBNEW_DIALOGS dialogs/panel_setup_layers_base.cpp dialogs/panel_setup_netclasses.cpp dialogs/panel_setup_netclasses_base.cpp + dialogs/panel_setup_rules.cpp + dialogs/panel_setup_rules_base.cpp dialogs/panel_setup_text_and_graphics.cpp dialogs/panel_setup_text_and_graphics_base.cpp dialogs/panel_setup_tracks_and_vias.cpp diff --git a/pcbnew/dialogs/dialog_board_setup.cpp b/pcbnew/dialogs/dialog_board_setup.cpp index ba90f3f65b..9d9376fc09 100644 --- a/pcbnew/dialogs/dialog_board_setup.cpp +++ b/pcbnew/dialogs/dialog_board_setup.cpp @@ -32,7 +32,7 @@ #include #include "dialog_board_setup.h" - +#include "panel_setup_rules.h" DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) : PAGED_DIALOG( aFrame, _( "Board Setup" ), _( "Import Settings from Another Project..." ) ), @@ -42,6 +42,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) : m_textAndGraphics = new PANEL_SETUP_TEXT_AND_GRAPHICS( this, aFrame ); m_constraints = new PANEL_SETUP_FEATURE_CONSTRAINTS( this, aFrame ); m_netclasses = new PANEL_SETUP_NETCLASSES( this, aFrame, m_constraints ); + m_rules = new PANEL_SETUP_RULES( this, aFrame ); m_tracksAndVias = new PANEL_SETUP_TRACKS_AND_VIAS( this, aFrame, m_constraints ); m_maskAndPaste = new PANEL_SETUP_MASK_AND_PASTE( this, aFrame ); m_physicalStackup = new PANEL_SETUP_BOARD_STACKUP( this, aFrame, m_layers ); @@ -71,6 +72,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) : m_treebook->AddPage( new wxPanel( this ), _( "Design Rules" ) ); m_treebook->AddSubPage( m_constraints, _( "Constraints" ) ); m_treebook->AddSubPage( m_netclasses, _( "Net Classes" ) ); + m_treebook->AddSubPage( m_rules, _( "Rules" ) ); m_treebook->AddSubPage( m_severities, _( "Violation Severity" ) ); m_treebook->AddPage( new wxPanel( this ), _( "Project" ) ); diff --git a/pcbnew/dialogs/dialog_board_setup.h b/pcbnew/dialogs/dialog_board_setup.h index fa4a7d1f94..cede727998 100644 --- a/pcbnew/dialogs/dialog_board_setup.h +++ b/pcbnew/dialogs/dialog_board_setup.h @@ -28,6 +28,7 @@ class PANEL_SETUP_FEATURE_CONSTRAINTS; class PANEL_SETUP_LAYERS; class PANEL_SETUP_TEXT_AND_GRAPHICS; class PANEL_SETUP_NETCLASSES; +class PANEL_SETUP_RULES; class PANEL_SETUP_TRACKS_AND_VIAS; class PANEL_SETUP_MASK_AND_PASTE; class PANEL_SETUP_BOARD_STACKUP; @@ -50,6 +51,7 @@ protected: PANEL_SETUP_LAYERS* m_layers; PANEL_SETUP_TEXT_AND_GRAPHICS* m_textAndGraphics; PANEL_SETUP_NETCLASSES* m_netclasses; + PANEL_SETUP_RULES* m_rules; PANEL_SETUP_TRACKS_AND_VIAS* m_tracksAndVias; PANEL_SETUP_MASK_AND_PASTE* m_maskAndPaste; PANEL_SETUP_BOARD_STACKUP* m_physicalStackup; diff --git a/pcbnew/dialogs/panel_setup_rules.cpp b/pcbnew/dialogs/panel_setup_rules.cpp new file mode 100644 index 0000000000..b5775a26b7 --- /dev/null +++ b/pcbnew/dialogs/panel_setup_rules.cpp @@ -0,0 +1,126 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include + + +PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame ) : + PANEL_SETUP_RULES_BASE( aParent->GetTreebook() ), + m_frame( aFrame ), + m_lastCaretPos( -1 ) +{ + m_textEditor->SetIndentationGuides( wxSTC_IV_LOOKBOTH ); + + wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ); + wxColour highlightText = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ); + + if( KIGFX::COLOR4D( highlightText ).GetBrightness() > 0.5 ) + highlight = highlight.ChangeLightness( 75 ); + else + highlight = highlight.ChangeLightness( 125 ); + + m_textEditor->StyleSetForeground( wxSTC_STYLE_BRACELIGHT, highlightText ); + m_textEditor->StyleSetBackground( wxSTC_STYLE_BRACELIGHT, highlight ); + m_textEditor->StyleSetForeground( wxSTC_STYLE_BRACEBAD, *wxRED ); + + m_textEditor->Bind( wxEVT_STC_UPDATEUI, &PANEL_SETUP_RULES::onScintillaUpdateUI, this ); +} + + +void PANEL_SETUP_RULES::onScintillaUpdateUI( wxStyledTextEvent& aEvent ) +{ + auto isBrace = []( int c ) -> bool + { + return c == '(' || c == ')'; + }; + + // Has the caret changed position? + int caretPos = m_textEditor->GetCurrentPos(); + + if( m_lastCaretPos != caretPos ) + { + m_lastCaretPos = caretPos; + int bracePos1 = -1; + int bracePos2 = -1; + + // Is there a brace to the left or right? + if( caretPos > 0 && isBrace( m_textEditor->GetCharAt( caretPos-1 ) ) ) + bracePos1 = ( caretPos - 1 ); + else if( isBrace( m_textEditor->GetCharAt( caretPos ) ) ) + bracePos1 = caretPos; + + if( bracePos1 >= 0 ) + { + // Find the matching brace + bracePos2 = m_textEditor->BraceMatch( bracePos1 ); + + if( bracePos2 == -1 ) + { + m_textEditor->BraceBadLight( bracePos1 ); + m_textEditor->SetHighlightGuide( 0 ); + } + else + { + m_textEditor->BraceHighlight( bracePos1, bracePos2 ); + m_textEditor->SetHighlightGuide( m_textEditor->GetColumn( bracePos1 ) ); + } + } + else + { + // Turn off brace matching + m_textEditor->BraceHighlight( -1, -1 ); + m_textEditor->SetHighlightGuide( 0 ); + } + } +} + + +bool PANEL_SETUP_RULES::TransferDataToWindow() +{ + wxString rulesFilepath = m_frame->Prj().AbsolutePath( "drc-rules" ); + wxFileName rulesFile( rulesFilepath ); + + if( rulesFile.FileExists() ) + m_textEditor->LoadFile( rulesFile.GetFullPath() ); + + return true; +} + + +bool PANEL_SETUP_RULES::TransferDataFromWindow() +{ + if( m_textEditor->SaveFile( m_frame->Prj().AbsolutePath( "drc-rules" ) ) ) + { + m_frame->GetToolManager()->GetTool()->Reset( TOOL_BASE::MODEL_RELOAD ); + return true; + } + + return false; +} + + diff --git a/pcbnew/dialogs/panel_setup_rules.h b/pcbnew/dialogs/panel_setup_rules.h new file mode 100644 index 0000000000..8e49862be8 --- /dev/null +++ b/pcbnew/dialogs/panel_setup_rules.h @@ -0,0 +1,52 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#ifndef PANEL_SETUP_RULES_H +#define PANEL_SETUP_RULES_H + +#include + +class DRC; +class PAGED_DIALOG; +class PCB_EDIT_FRAME; + + +class PANEL_SETUP_RULES : public PANEL_SETUP_RULES_BASE +{ +private: + PCB_EDIT_FRAME* m_frame; + int m_lastCaretPos; + +public: + PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame ); + ~PANEL_SETUP_RULES( ) override { }; + +private: + void onScintillaUpdateUI( wxStyledTextEvent& aEvent ); + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; +}; + +#endif //PANEL_SETUP_RULES_H diff --git a/pcbnew/dialogs/panel_setup_rules_base.cpp b/pcbnew/dialogs/panel_setup_rules_base.cpp new file mode 100644 index 0000000000..e1dc7b8cc4 --- /dev/null +++ b/pcbnew/dialogs/panel_setup_rules_base.cpp @@ -0,0 +1,71 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Oct 26 2018) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "panel_setup_rules_base.h" + +/////////////////////////////////////////////////////////////////////////// + +PANEL_SETUP_RULES_BASE::PANEL_SETUP_RULES_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name ) +{ + wxBoxSizer* bPanelSizer; + bPanelSizer = new wxBoxSizer( wxHORIZONTAL ); + + m_leftMargin = new wxBoxSizer( wxHORIZONTAL ); + + m_topMargin = new wxBoxSizer( wxVERTICAL ); + + m_title = new wxStaticText( this, wxID_ANY, _("DRC rules:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_title->Wrap( -1 ); + m_topMargin->Add( m_title, 0, wxTOP|wxBOTTOM, 5 ); + + m_textEditor = new wxStyledTextCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString ); + m_textEditor->SetUseTabs( true ); + m_textEditor->SetTabWidth( 4 ); + m_textEditor->SetIndent( 4 ); + m_textEditor->SetTabIndents( true ); + m_textEditor->SetBackSpaceUnIndents( true ); + m_textEditor->SetViewEOL( false ); + m_textEditor->SetViewWhiteSpace( false ); + m_textEditor->SetMarginWidth( 2, 0 ); + m_textEditor->SetIndentationGuides( true ); + m_textEditor->SetMarginWidth( 1, 0 ); + m_textEditor->SetMarginType( 0, wxSTC_MARGIN_NUMBER ); + m_textEditor->SetMarginWidth( 0, m_textEditor->TextWidth( wxSTC_STYLE_LINENUMBER, wxT("_99999") ) ); + m_textEditor->MarkerDefine( wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS ); + m_textEditor->MarkerSetBackground( wxSTC_MARKNUM_FOLDER, wxColour( wxT("BLACK") ) ); + m_textEditor->MarkerSetForeground( wxSTC_MARKNUM_FOLDER, wxColour( wxT("WHITE") ) ); + m_textEditor->MarkerDefine( wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS ); + m_textEditor->MarkerSetBackground( wxSTC_MARKNUM_FOLDEROPEN, wxColour( wxT("BLACK") ) ); + m_textEditor->MarkerSetForeground( wxSTC_MARKNUM_FOLDEROPEN, wxColour( wxT("WHITE") ) ); + m_textEditor->MarkerDefine( wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_EMPTY ); + m_textEditor->MarkerDefine( wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUS ); + m_textEditor->MarkerSetBackground( wxSTC_MARKNUM_FOLDEREND, wxColour( wxT("BLACK") ) ); + m_textEditor->MarkerSetForeground( wxSTC_MARKNUM_FOLDEREND, wxColour( wxT("WHITE") ) ); + m_textEditor->MarkerDefine( wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUS ); + m_textEditor->MarkerSetBackground( wxSTC_MARKNUM_FOLDEROPENMID, wxColour( wxT("BLACK") ) ); + m_textEditor->MarkerSetForeground( wxSTC_MARKNUM_FOLDEROPENMID, wxColour( wxT("WHITE") ) ); + m_textEditor->MarkerDefine( wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_EMPTY ); + m_textEditor->MarkerDefine( wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_EMPTY ); + m_textEditor->SetSelBackground( true, wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) ); + m_textEditor->SetSelForeground( true, wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) ); + m_topMargin->Add( m_textEditor, 1, wxEXPAND | wxALL, 5 ); + + + m_leftMargin->Add( m_topMargin, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 ); + + + bPanelSizer->Add( m_leftMargin, 1, wxEXPAND, 5 ); + + + this->SetSizer( bPanelSizer ); + this->Layout(); + bPanelSizer->Fit( this ); +} + +PANEL_SETUP_RULES_BASE::~PANEL_SETUP_RULES_BASE() +{ +} diff --git a/pcbnew/dialogs/panel_setup_rules_base.fbp b/pcbnew/dialogs/panel_setup_rules_base.fbp new file mode 100644 index 0000000000..7d94295e99 --- /dev/null +++ b/pcbnew/dialogs/panel_setup_rules_base.fbp @@ -0,0 +1,209 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + panel_setup_rules_base + 1000 + none + + 1 + PanelSetupRules + + . + + 1 + 1 + 1 + 1 + UI + 1 + 0 + + 0 + wxAUI_MGR_DEFAULT + + + 1 + 1 + impl_virtual + + + 0 + wxID_ANY + + + PANEL_SETUP_RULES_BASE + + -1,-1 + ; forward_declare + + + + wxTAB_TRAVERSAL + + + bPanelSizer + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + + m_leftMargin + wxHORIZONTAL + protected + + 10 + wxEXPAND|wxRIGHT|wxLEFT + 1 + + + m_topMargin + wxVERTICAL + protected + + 5 + wxTOP|wxBOTTOM + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + DRC rules: + 0 + + 0 + + + 0 + + 1 + m_title + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + 1 + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + 0 + + 0 + 0 + wxID_ANY + 1 + 1 + + 0 + + + 0 + + 1 + m_textEditor + 1 + + + protected + 1 + + Resizable + 1 + + ; ; forward_declare + 1 + 4 + 0 + + 1 + 0 + 0 + + + + + + + + + + + + + diff --git a/pcbnew/dialogs/panel_setup_rules_base.h b/pcbnew/dialogs/panel_setup_rules_base.h new file mode 100644 index 0000000000..882b26d439 --- /dev/null +++ b/pcbnew/dialogs/panel_setup_rules_base.h @@ -0,0 +1,44 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Oct 26 2018) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +/// Class PANEL_SETUP_RULES_BASE +/////////////////////////////////////////////////////////////////////////////// +class PANEL_SETUP_RULES_BASE : public wxPanel +{ + private: + + protected: + wxBoxSizer* m_leftMargin; + wxBoxSizer* m_topMargin; + wxStaticText* m_title; + wxStyledTextCtrl* m_textEditor; + + public: + + PANEL_SETUP_RULES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString ); + ~PANEL_SETUP_RULES_BASE(); + +}; + diff --git a/pcbnew/drc/drc.cpp b/pcbnew/drc/drc.cpp index 3748e02ea4..b130c96e0a 100644 --- a/pcbnew/drc/drc.cpp +++ b/pcbnew/drc/drc.cpp @@ -92,15 +92,15 @@ void DRC::Reset( RESET_REASON aReason ) { m_pcbEditorFrame = getEditFrame(); - if( aReason == MODEL_RELOAD ) + if( m_pcb != m_pcbEditorFrame->GetBoard() ) { if( m_drcDialog ) DestroyDRCDialog( wxID_OK ); m_pcb = m_pcbEditorFrame->GetBoard(); - - loadRules(); } + + loadRules(); }