54 auto it = std::find_if( aNodes.begin(), aNodes.end(),
57 return node.m_nodeId == aTargetId;
60 if( it != aNodes.end() )
87 if(
Prj().IsReadOnly() )
89 m_infoBar->ShowMessage(
_(
"Project is missing or read-only. Settings will not be "
100 new wxDataViewCtrl(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxDV_ROW_LINES | wxDV_SINGLE );
121 SetMinSize( wxSize( 400, 300 ) );
126 SetSize( wxSize( 980, 680 ) );
145 std::vector<RULE_TREE_NODE>
result;
148 int electricalItemId;
149 int manufacturabilityItemId;
150 int highSpeedDesignId;
169 result.insert(
result.end(), subItemNodes.begin(), subItemNodes.end() );
172 result.insert(
result.end(), subItemNodes.begin(), subItemNodes.end() );
175 result.insert(
result.end(), subItemNodes.begin(), subItemNodes.end() );
178 result.insert(
result.end(), subItemNodes.begin(), subItemNodes.end() );
191 wxFileName rulesFile(
m_frame->GetDesignRulesPath() );
193 if( !rulesFile.FileExists() )
197 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries = loader.
LoadFile( rulesFile.GetFullPath() );
199 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
200 wxS(
"[LoadExistingRules] Loaded %zu entries from %s" ),
201 entries.size(), rulesFile.GetFullPath() );
204 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
205 wxS(
"[LoadExistingRules] Available constraint nodes in m_ruleTreeNodeDatas:" ) );
211 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
212 wxS(
"[LoadExistingRules] Node '%s': nodeId=%d, m_nodeTypeMap=%d" ),
213 wxString( node.m_nodeName ), node.m_nodeId,
214 node.m_nodeTypeMap ?
static_cast<int>( *node.m_nodeTypeMap ) : -1 );
219 std::function<wxTreeItemId( wxTreeItemId,
int )> findItem =
220 [&]( wxTreeItemId aItem,
int aTargetId ) -> wxTreeItemId
225 if( data && data->
GetNodeId() == aTargetId )
228 wxTreeItemIdValue cookie;
229 wxTreeItemId child =
m_ruleTreeCtrl->GetFirstChild( aItem, cookie );
231 while( child.IsOk() )
233 wxTreeItemId
res = findItem( child, aTargetId );
241 return wxTreeItemId();
248 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
249 wxS(
"[LoadExistingRules] Processing entry: rule='%s', panelType=%d" ),
250 entry.ruleName,
static_cast<int>( type ) );
257 if( node.m_nodeType ==
CONSTRAINT && node.m_nodeTypeMap && *node.m_nodeTypeMap == type )
259 parentId = node.m_nodeId;
266 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
267 wxS(
"[LoadExistingRules] No parent found for panelType=%d, skipping" ),
268 static_cast<int>( type ) );
272 wxTreeItemId parentItem = findItem(
m_ruleTreeCtrl->GetRootItem(), parentId );
274 if( !parentItem.IsOk() )
276 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
277 wxS(
"[LoadExistingRules] Tree item not found for parentId=%d, skipping" ),
282 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
283 wxS(
"[LoadExistingRules] Found parent node: parentId=%d" ), parentId );
289 auto ruleData = std::dynamic_pointer_cast<DRC_RE_BASE_CONSTRAINT_DATA>( entry.constraintData );
294 ruleData->SetParentId( parentId );
295 ruleData->SetOriginalRuleText( entry.originalRuleText );
296 ruleData->SetWasEdited( entry.wasEdited );
303 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
304 wxS(
"[LoadExistingRules] Appended rule '%s' to tree under parentId=%d" ),
305 entry.ruleName, parentId );
312 wxTreeItemId treeItemId;
333 auto sourceDataPtr = dynamic_pointer_cast<RULE_EDITOR_DATA_BASE>( sourceTreeNode->
m_nodeData );
351 std::vector<RULE_TREE_NODE*> ruleNodes;
354 std::vector<DRC_RULE_ROW> rows;
355 rows.reserve( ruleNodes.size() );
360 wxString type = parentNode ? parentNode->
m_nodeName : wxString{};
361 rows.push_back( { type, ruleNode->m_nodeData->GetRuleName(), ruleNode->m_nodeData->GetComment() } );
373 wxString constraintName = paretNodeDetail->
m_nodeName;
378 &constraintName, dynamic_pointer_cast<DRC_RE_BASE_CONSTRAINT_DATA>( nodeDetail->
m_nodeData ) );
385 [
this](
int aNodeId )
391 [
this](
int aNodeId )
397 [
this](
int aNodeId )
403 [
this](
int aNodeId, wxString aRuleName )
409 [
this](
int aNodeId ) ->
int
431 bool isNew = data && data->IsNew();
455 auto constraintData =
456 std::dynamic_pointer_cast<DRC_RE_BASE_CONSTRAINT_DATA>( nodeDetail->
m_nodeData );
459 constraintData->SetWasEdited(
true );
481 default:
return true;
494 if(
OKOrCancelDialog(
this,
_(
"Confirmation" ),
"",
_(
"Are you sure you want to delete?" ),
_(
"Delete" ) )
515 std::vector<RULE_TREE_NODE>
result;
567 std::vector<RULE_TREE_NODE>
result;
634 std::vector<RULE_TREE_NODE>
result;
665 std::vector<RULE_TREE_NODE>
result;
723bool nodeExists(
const std::vector<RULE_TREE_NODE>& aRuleTreeNodes,
const wxString& aTargetName )
725 for(
const auto& node : aRuleTreeNodes )
740 using ConstraintDataFactory =
744 static const std::unordered_map<DRC_RULE_EDITOR_CONSTRAINT_NAME, ConstraintDataFactory> s_constraintFactories = {
748 return std::make_shared<DRC_RE_VIA_STYLE_CONSTRAINT_DATA>( data );
753 return std::make_shared<DRC_RE_MINIMUM_TEXT_HEIGHT_THICKNESS_CONSTRAINT_DATA>( data );
758 return std::make_shared<DRC_RE_ROUTING_DIFF_PAIR_CONSTRAINT_DATA>( data );
763 return std::make_shared<DRC_RE_ROUTING_WIDTH_CONSTRAINT_DATA>( data );
768 return std::make_shared<DRC_RE_PERMITTED_LAYERS_CONSTRAINT_DATA>( data );
773 return std::make_shared<DRC_RE_ALLOWED_ORIENTATION_CONSTRAINT_DATA>( data );
778 return std::make_shared<DRC_RE_CUSTOM_RULE_CONSTRAINT_DATA>( data );
787 treeItemData = aRuleTreeItemData;
798 wxString nodeName = nodeDetail->
m_nodeName +
" 1";
809 nodeName = nodeDetail->
m_nodeName + wxString::Format(
" %d", loop );
823 if( s_constraintFactories.find( nodeType ) != s_constraintFactories.end() )
825 newRuleNode.
m_nodeData = s_constraintFactories.at( nodeType )( clearanceData );
829 newRuleNode.
m_nodeData = std::make_shared<DRC_RE_NUMERIC_INPUT_CONSTRAINT_DATA>( clearanceData );
833 newRuleNode.
m_nodeData = std::make_shared<DRC_RE_BOOL_INPUT_CONSTRAINT_DATA>( clearanceData );
837 wxLogWarning(
"No factory found for constraint type: %d", nodeType );
838 newRuleNode.
m_nodeData = std::make_shared<DRC_RE_BASE_CONSTRAINT_DATA>( clearanceData );
841 std::static_pointer_cast<DRC_RE_BASE_CONSTRAINT_DATA>( newRuleNode.
m_nodeData )
856 return node.m_nodeId == aNodeId;
910 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
911 wxS(
"[ShowMatches] nodeId=%d, condition='%s'" ), aNodeId, condition );
914 if( condition.IsEmpty() )
924 if( !testCondition.
Compile(
nullptr ) )
926 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] compile failed" ) );
932 std::vector<BOARD_ITEM*> allMatches =
936 std::vector<BOARD_ITEM*> matches;
940 switch( item->Type() )
948 matches.push_back( item );
953 int matchCount =
static_cast<int>( matches.size() );
955 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] matched_count=%d (filtered from %zu)" ),
956 matchCount, allMatches.size() );
961 if( matches.size() > 0 )
963 std::vector<EDA_ITEM*> selectItems;
966 selectItems.push_back( item );
973 m_frame->FocusOnItems( matches );
985 return node.m_nodeName == aRuleName && node.m_nodeId != aNodeId
986 && node.m_nodeType == RULE;
1005 return node.m_nodeId == aNodeId;
1018 std::vector<RULE_TREE_NODE> children;
1021 for(
const auto& child : children )
1026 aResult.push_back( childNode );
1035 const std::optional<DRC_RULE_EDITOR_CONSTRAINT_NAME>& aConstraintType,
1036 const std::vector<RULE_TREE_NODE>& aChildNodes,
const std::optional<int>&
id )
1055 baseData.
SetId( newId );
1063 .m_nodeName = aName,
1064 .m_nodeType = aNodeType,
1066 .m_nodeTypeMap = aConstraintType,
1067 .m_childNodes = aChildNodes,
1068 .m_nodeData = std::make_shared<RULE_EDITOR_DATA_BASE>( baseData ) };
1073 const std::optional<int>& aParentId )
1079 auto baseData = std::dynamic_pointer_cast<DRC_RE_BASE_CONSTRAINT_DATA>( node.
m_nodeData );
1106 std::vector<DRC_RE_LOADED_PANEL_ENTRY> entries;
1110 if( node.m_nodeType !=
RULE )
1113 auto data = std::dynamic_pointer_cast<DRC_RE_BASE_CONSTRAINT_DATA>( node.m_nodeData );
1120 if( node.m_nodeTypeMap )
1126 entry.
ruleName = data->GetRuleName();
1127 entry.
condition = data->GetRuleCondition();
1131 entries.push_back( entry );
static TOOL_ACTION zoomFitSelection
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
std::vector< RULE_TREE_NODE > m_ruleTreeNodeDatas
PANEL_DRC_GROUP_HEADER * m_groupHeaderPanel
~DIALOG_DRC_RULE_EDITOR()
std::vector< RULE_TREE_NODE > buildElectricalRuleTreeNodes(int &aParentId)
std::vector< RULE_TREE_NODE > buildHighspeedDesignRuleTreeNodes(int &aParentId)
void UpdateRuleTypeTreeItemData(RULE_TREE_ITEM_DATA *aCurrentRuleTreeItemData) override
Updates the rule tree item data by transferring data from the rule editor panel and updating the item...
void collectChildRuleNodes(int aParentId, std::vector< RULE_TREE_NODE * > &aResult)
Collects all child rule nodes for a given parent node ID.
int highlightMatchingItems(int aNodeId)
Highlights board items matching the current rule condition.
RC_TREE_MODEL * m_markersTreeModel
void saveRule(int aNodeId)
Saves the rule after validating the rule editor panel.
void AddNewRule(RULE_TREE_ITEM_DATA *aRuleTreeItemData) override
Adds a new rule to the rule tree, either as a child or under the parent, based on the node type (CONS...
void RuleTreeItemSelectionChanged(RULE_TREE_ITEM_DATA *aCurrentRuleTreeItemData) override
Handles rule tree item selection changes, updating the content panel with appropriate editor or heade...
RULE_TREE_NODE buildRuleTreeNodeData(const std::string &aName, const DRC_RULE_EDITOR_ITEM_TYPE &aNodeType, const std::optional< int > &aParentId=std::nullopt, const std::optional< DRC_RULE_EDITOR_CONSTRAINT_NAME > &aConstraintType=std::nullopt, const std::vector< RULE_TREE_NODE > &aChildNodes={}, const std::optional< int > &aId=std::nullopt)
Creates a new rule tree node with the specified parameters, generating a new ID if not provided.
RULE_TREE_NODE buildRuleNodeFromKicadDrc(const wxString &aName, const wxString &aCode, const std::optional< int > &aParentId=std::nullopt)
Build a rule tree node from a constraint keyword loaded from a .kicad_drc file.
std::vector< RULE_TREE_NODE > GetDefaultRuleTreeItems() override
Pure virtual method to get the default rule tree items.
bool TransferDataFromWindow() override
std::shared_ptr< RC_ITEMS_PROVIDER > m_markersProvider
std::vector< RULE_TREE_NODE > buildManufacturabilityRuleTreeNodes(int &aParentId)
wxDataViewCtrl * m_markerDataView
void RemoveRule(int aNodeId) override
Removes a rule from the rule tree after confirmation, deleting the item and associated data.
void OnCancel(wxCommandEvent &aEvent) override
bool TransferDataToWindow() override
std::vector< RULE_TREE_NODE > buildFootprintsRuleTreeNodes(int &aParentId)
RULE_TREE_NODE * getRuleTreeNodeInfo(const int &aNodeId)
Retrieves the rule tree node for a given ID.
PANEL_DRC_RULE_EDITOR * m_ruleEditorPanel
RULE_TREE_NODE buildRuleTreeNode(RULE_TREE_ITEM_DATA *aRuleTreeItemData)
Creates a new rule tree node with a unique name and assigns the appropriate constraint data.
bool deleteTreeNodeData(const int &aNodeId)
Deletes a rule tree node by its ID.
bool isEnabled(RULE_TREE_ITEM_DATA *aRuleTreeItemData, RULE_EDITOR_TREE_CONTEXT_OPT aOption) override
Verifies if a context menu option should be enabled based on the rule tree item type.
void closeRuleEntryView(int aNodeId)
Closes the rule entry view and re-enables controls.
void OnSave(wxCommandEvent &aEvent) override
void DuplicateRule(RULE_TREE_ITEM_DATA *aRuleTreeItemData) override
Duplicates a rule from the source tree node and appends it as a new item under the same parent.
bool validateRuleName(int aNodeId, wxString aRuleName)
Validates if the rule name is unique for the given node ID.
bool Compile(REPORTER *aReporter, int aSourceLine=0, int aSourceOffset=0)
static bool IsNumericInputType(const DRC_RULE_EDITOR_CONSTRAINT_NAME &aConstraintType)
static wxString ConstraintToKicadDrc(DRC_RULE_EDITOR_CONSTRAINT_NAME aType)
Convert a constraint type into the keyword used in a .kicad_drc file.
static bool ConstraintFromKicadDrc(const wxString &aCode, DRC_RE_BASE_CONSTRAINT_DATA *aData)
Populate a constraint data object using a keyword from a .kicad_drc file.
static std::optional< DRC_RULE_EDITOR_CONSTRAINT_NAME > GetConstraintTypeFromCode(const wxString &aCode)
Resolve a constraint keyword from a rules file into the corresponding rule tree enumeration value.
static bool IsBoolInputType(const DRC_RULE_EDITOR_CONSTRAINT_NAME &aConstraintType)
Loads DRC rules from .kicad_dru files and converts them to panel entries.
std::vector< DRC_RE_LOADED_PANEL_ENTRY > LoadFile(const wxString &aPath)
Load all rules from a .kicad_dru file.
Saves DRC panel entries back to .kicad_dru files.
bool SaveFile(const wxString &aPath, const std::vector< DRC_RE_LOADED_PANEL_ENTRY > &aEntries, const BOARD *aBoard=nullptr)
Save all panel entries to a file.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
The main frame for Pcbnew.
virtual void AdvancePhase() override
Use the next available virtual zone of the dialog progress bar.
PROGRESS_REPORTER_BASE(int aNumPhases)
virtual void SetCurrentProgress(double aProgress) override
Set the progress value to aProgress (0..1).
std::atomic_bool m_cancelled
virtual void AdvancePhase()=0
Use the next available virtual zone of the dialog progress bar.
Concrete class representing the base data structure for a rule editor.
bool IsNew()
Check if the rule is marked as new.
int GetId()
Get the unique ID of the rule.
void SetIsNew(bool aIsNew)
Mark the rule as new or not.
void SetId(int aId)
Set the unique ID of the rule.
void SetParentId(int aParentId)
Set the parent ID of the rule.
void CopyFrom(const ICopyable &aSource) override
Implementation of the polymorphic CopyFrom method.
wxString GetRuleName()
Get the name of the rule.
void DeleteRuleTreeItem(wxTreeItemId aItemId, const int &aNodeId)
Deletes a tree item and removes its corresponding node from history.
void UpdateRuleTreeItemText(wxTreeItemId aItemId, wxString aItemText)
Updates the text of a specified rule tree item.
void AppendNewRuleTreeItem(const RULE_TREE_NODE &aRuleTreeNode, wxTreeItemId aParentTreeItemId)
Adds a new rule tree item under the specified parent and updates the tree history.
void InitRuleTreeItems(const std::vector< RULE_TREE_NODE > &aRuleTreeNodes)
Initializes the rule tree by adding nodes, setting up the structure, and saving its state.
void SetContentPanel(wxPanel *aContentPanel)
Replaces the current content panel with a new one based on the selected constraint type.
wxTreeCtrl * m_ruleTreeCtrl
bool TransferDataToWindow() override
RULE_EDITOR_DIALOG_BASE(wxWindow *aParent, const wxString &aTitle, const wxSize &aInitialSize=wxDefaultSize)
friend class DIALOG_DRC_RULE_EDITOR
bool TransferDataFromWindow() override
void getRuleTreeChildNodes(const std::vector< RULE_TREE_NODE > &aNodes, int aParentId, std::vector< RULE_TREE_NODE > &aResult)
Retrieves child nodes of a given parent node.
wxSplitterWindow * m_splitter
RULE_TREE_ITEM_DATA * GetCurrentlySelectedRuleTreeItemData()
Retrieves the currently selected rule tree item data.
void SetControlsEnabled(bool aEnable)
Enables or disables controls within the rule editor dialog.
A class representing additional data associated with a wxTree item.
wxTreeItemId GetTreeItemId() const
wxTreeItemId GetParentTreeItemId() const
int OKOrCancelDialog(wxWindow *aParent, const wxString &aWarning, const wxString &aMessage, const wxString &aDetailedMessage, const wxString &aOKLabel, const wxString &aCancelLabel, bool *aApplyToAll)
Display a warning dialog with aMessage and returns the user response.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
bool nodeExists(const RULE_TREE_NODE &aRuleTreeNode, const wxString &aTargetName)
Checks if a node with the given name exists in the rule tree or its child nodes.
const RULE_TREE_NODE * FindNodeById(const std::vector< RULE_TREE_NODE > &aNodes, int aTargetId)
SIM_MODEL::PARAM::CATEGORY CATEGORY
DRC_RULE_EDITOR_CONSTRAINT_NAME
@ MINIMUM_SOLDERMASK_SILVER
@ SILK_TO_SOLDERMASK_CLEARANCE
@ BOARD_OUTLINE_CLEARANCE
@ MINIMUM_CONNECTION_WIDTH
@ MINIMUM_THERMAL_RELIEF_SPOKE_COUNT
@ MINIMUM_TEXT_HEIGHT_AND_THICKNESS
@ COPPER_TO_HOLE_CLEARANCE
@ MAXIMUM_ALLOWED_DEVIATION
@ MATCHED_LENGTH_DIFF_PAIR
@ COPPER_TO_EDGE_CLEARANCE
DRC_RULE_EDITOR_ITEM_TYPE
RULE_EDITOR_TREE_CONTEXT_OPT
Enumeration representing the available context menu options for the rule editor tree.
Represents a rule loaded from a .kicad_dru file and mapped to a panel.
wxString originalRuleText
std::shared_ptr< DRC_RE_BASE_CONSTRAINT_DATA > constraintData
DRC_RULE_EDITOR_CONSTRAINT_NAME panelType
Structure representing a node in a rule tree, collection of this used for building the rule tree.
std::shared_ptr< RULE_EDITOR_DATA_BASE > m_nodeData
std::optional< int > m_nodeTypeMap
std::vector< RULE_TREE_NODE > m_childNodes
wxString result
Test unit parsing edge cases and error handling.
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net