29#include <wx/treectrl.h>
30#include <wx/listctrl.h>
31#include <wx/stc/stc.h>
36#include <wx/dcclient.h>
37#include <wx/dcbuffer.h>
51 wxSearchCtrl* search_widget =
new wxSearchCtrl( aParent, wxID_ANY );
53 search_widget->ShowSearchButton(
false );
54 search_widget->ShowCancelButton(
true );
56 search_widget->SetDescriptiveText( aDescriptiveText );
61 search_widget->SetMinSize( wxSize( -1, aParent->GetTextExtent( wxT(
"qb" ) ).y + 10 ) );
69 const wxSize& aInitialSize ) :
70 DIALOG_SHIM( aParent, wxID_ANY, aTitle, wxDefaultPosition, aInitialSize,
71 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ),
86 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
87 SetSizer( mainSizer );
89 wxBoxSizer* infoBarSizer =
new wxBoxSizer( wxHORIZONTAL );
92 infoBarSizer->Add(
m_infoBar, 0, wxEXPAND, 0 );
95 m_splitter =
new wxSplitterWindow(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
96 wxBORDER_NONE | wxSP_LIVE_UPDATE | wxSP_3DSASH );
101 wxBORDER_NONE | wxTAB_TRAVERSAL );
102 treeCtrlPanel->
SetBorders(
false,
false,
false,
true );
103 wxBoxSizer* treeCtrlSizer =
new wxBoxSizer( wxVERTICAL );
104 treeCtrlPanel->SetSizer( treeCtrlSizer );
111 m_ruleTreeCtrl =
new wxTreeCtrl( treeCtrlPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize,
112 wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT | wxTR_HAS_BUTTONS | wxBORDER_NONE );
119 wxBoxSizer* actionButtonsSizer =
new wxBoxSizer( wxHORIZONTAL );
123 wxDefaultSize, wxBU_AUTODRAW );
125 wxDefaultSize, wxBU_AUTODRAW );
127 wxDefaultSize, wxBU_AUTODRAW );
129 wxDefaultSize, wxBU_AUTODRAW );
131 wxDefaultSize, wxBU_AUTODRAW );
139 actionButtonsSizer->AddSpacer( 20 );
145 treeCtrlSizer->Add( actionButtonsSizer, 0, wxBOTTOM | wxEXPAND, 5 );
147 treeCtrlPanel->Layout();
157 wxVSCROLL | wxBORDER_NONE );
159 m_scrolledContentWin->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK ) );
164 treeCtrlPanel->Layout();
165 int minTreeWidth = treeCtrlPanel->GetBestSize().GetWidth();
168 if( minTreeWidth < 240 )
178 wxBoxSizer* m_sizerButtons =
new wxBoxSizer( wxHORIZONTAL );
180 wxStdDialogButtonSizer* m_sdbSizer =
new wxStdDialogButtonSizer();
187 m_sdbSizer->Realize();
189 m_sizerButtons->Add( m_sdbSizer, 1, wxEXPAND, 5 );
193 mainSizer->Add( infoBarSizer, 0, wxEXPAND, 0 );
194 mainSizer->Add(
m_splitter, 1, wxEXPAND | wxBOTTOM, 5 );
195 mainSizer->Add( m_sizerButtons, 0, wxALL | wxEXPAND, 5 );
197 if( aInitialSize != wxDefaultSize )
198 SetSize( aInitialSize );
227 [
this]( wxSizeEvent& evt )
243 SetMinSize( wxSize( 400, 500 ) );
246 wxLogTrace(
"debug_dlg_size",
"finishInitialization: size=%dx%d minSize=%dx%d bestSize=%dx%d",
247 GetSize().x, GetSize().y, GetMinSize().x, GetMinSize().y, GetBestSize().x,
263 if(
minSize.GetHeight() > 500 )
264 SetMinSize( wxSize(
minSize.GetWidth(), 500 ) );
266 wxLogTrace(
"debug_dlg_size",
"Show: size=%dx%d minSize=%dx%d",
267 GetSize().x, GetSize().y, GetMinSize().x, GetMinSize().y );
306 if( !DIALOG_SHIM::TransferDataToWindow() )
319 if( !DIALOG_SHIM::TransferDataFromWindow() )
328 if( aEvt.GetKeyCode() ==
'S' && aEvt.ControlDown() && !aEvt.ShiftDown() && !aEvt.AltDown() )
344 return currentDialog;
346 aParent = aParent->GetParent();
363 wxTreeItemId rootId =
m_ruleTreeCtrl->AddRoot( aNodes[0].m_nodeName );
368 std::vector<RULE_TREE_NODE> childNodes;
371 for(
const auto& child : childNodes )
424 int width = clientSize.GetWidth();
425 int height = std::max( clientSize.GetHeight(), bestSize.GetHeight() );
434 wxTreeItemId aParent )
442 std::vector<int>& existingChildren = std::get<1>( it->second );
443 existingChildren.push_back( aNode.
m_nodeId );
501 if( !currentText.EndsWith( wxS(
" *" ) ) )
537 std::vector<RULE_TREE_NODE> childNodes;
540 for(
const auto& child : childNodes )
551 wxTreeItemId item = aEvent.GetItem();
560 if( !ruleTreeItemData )
582 menu.Bind( wxEVT_COMMAND_MENU_SELECTED,
583 [&]( wxCommandEvent& aCmd )
585 switch( aCmd.GetId() )
596 default: aCmd.Skip();
609 wxTreeItemId selectedItem = aEvent.GetItem();
614 if( !selectedItemData )
679 if( !selectedItem.IsOk() )
682 wxTreeItemId parent =
m_ruleTreeCtrl->GetItemParent( selectedItem );
687 wxTreeItemIdValue cookie;
688 wxTreeItemId current =
m_ruleTreeCtrl->GetFirstChild( parent, cookie );
689 wxTreeItemId previous;
690 wxTreeItemId beforePrevious;
692 while( current.IsOk() && current != selectedItem )
694 beforePrevious = previous;
699 if( !previous.IsOk() )
704 wxTreeItemId insertPosition = beforePrevious.IsOk() ? beforePrevious : wxTreeItemId();
706 wxTreeItemId newItem =
m_ruleTreeCtrl->InsertItem( parent, insertPosition,
711 wxTreeItemData* itemData =
m_ruleTreeCtrl->GetItemData( selectedItem );
741 if( !selectedItem.IsOk() )
744 wxTreeItemId parent =
m_ruleTreeCtrl->GetItemParent( selectedItem );
745 wxTreeItemIdValue cookie;
746 wxTreeItemId current =
m_ruleTreeCtrl->GetFirstChild( parent, cookie );
748 while( current.IsOk() && current != selectedItem )
761 wxTreeItemData* itemData =
m_ruleTreeCtrl->GetItemData( selectedItem );
789 wxPoint pt = aEvent.GetPosition();
794 if( flags & wxTREE_HITTEST_ONITEMBUTTON )
826 wxTreeItemId hitItem =
m_ruleTreeCtrl->HitTest( aEvent.GetPosition(), flags );
830 wxTreeItemId hitParent =
m_ruleTreeCtrl->GetItemParent( hitItem );
833 if( hitParent == dragParent )
836 wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
857 wxPoint pos = aEvent.GetPosition();
861 if( !targetItem.IsOk() )
865 wxTreeItemId targetParent =
m_ruleTreeCtrl->GetItemParent( targetItem );
867 if( draggedParent != targetParent )
870 if( draggedParent == targetParent )
872 wxTreeItemId newItem;
873 wxTreeItemIdValue cookie;
875 if( flags & wxTREE_HITTEST_ONITEMLABEL
876 && targetItem ==
m_ruleTreeCtrl->GetFirstChild( targetParent, cookie ) )
884 wxTreeItemId current =
m_ruleTreeCtrl->GetFirstChild( targetParent, cookie );
885 wxTreeItemId previous;
888 while( current.IsOk() && current != targetItem )
894 if( !previous.IsOk() )
902 wxTreeItemId nextSibling =
m_ruleTreeCtrl->GetNextChild( targetParent, cookie );
904 if( nextSibling.IsOk() )
952 const auto searchStr = aEvent.GetString().Lower();
975 bool matches =
m_ruleTreeCtrl->GetItemText( aItem ).Lower().Contains( aFilter );
977 wxTreeItemIdValue cookie;
978 wxTreeItemId child =
m_ruleTreeCtrl->GetFirstChild( aItem, cookie );
979 bool hasVisibleChildren =
false;
981 std::vector<wxTreeItemId> itemsToDelete;
983 while( child.IsOk() )
987 hasVisibleChildren =
true;
991 itemsToDelete.push_back( child );
997 for(
const auto&
id : itemsToDelete )
1002 return matches || hasVisibleChildren;
1009 std::vector<int> children;
1011 wxTreeItemIdValue cookie;
1012 wxTreeItemId child =
m_ruleTreeCtrl->GetFirstChild( aItem, cookie );
1014 while( child.IsOk() )
1018 int childId = childItemData->
GetNodeId();
1020 children.push_back( childId );
1038 const auto& [itemText, children, itemId] = it->second;
1040 wxTreeItemId newItem;
1049 wxTreeItemId& treeItemId = std::get<2>( it->second );
1050 treeItemId = newItem;
1056 for(
const auto& childId : children )
1072 displayName += wxS(
" *" );
1074 wxTreeItemId currentTreeItemId =
m_ruleTreeCtrl->AppendItem( aParent, displayName );
1081 return currentTreeItemId;
1087 std::vector<RULE_TREE_NODE>& aResult )
1089 std::vector<RULE_TREE_NODE> filteredNodes;
1091 std::copy_if( aNodes.begin(), aNodes.end(), std::back_inserter( filteredNodes ),
1094 return node.m_nodeData->GetParentId() == aParentId;
1097 if( filteredNodes.size() > 0 )
1099 aResult.insert( aResult.end(), filteredNodes.begin(), filteredNodes.end() );
1104 wxTreeItemId aDest )
1106 wxTreeItemIdValue cookie;
1107 wxTreeItemId child =
m_ruleTreeCtrl->GetFirstChild( aSrc, cookie );
1109 while( child.IsOk() )
1135 if( !selectedItem.IsOk() )
1151 wxTreeItemId parent =
m_ruleTreeCtrl->GetItemParent( selectedItem );
1152 wxTreeItemIdValue cookie;
1153 wxTreeItemId firstChild =
m_ruleTreeCtrl->GetFirstChild( parent, cookie );
1154 wxTreeItemId lastChild = firstChild;
1156 while( lastChild.IsOk() )
1219 wxPostEvent(
this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL ) );
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
bool Show(bool show) override
void resetUndoRedoForNewContent(wxWindowList &aChildren)
Reset undo/redo tracking after dynamically replacing child panels.
void unregisterUnitBinders(wxWindow *aWindow)
Remove UNIT_BINDER registrations for a window and all its descendants.
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
DIALOG_SHIM(wxWindow *aParent, wxWindowID id, const wxString &title, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER, const wxString &name=wxDialogNameStr)
virtual void OnCharHook(wxKeyEvent &aEvt)
bool IsNew()
Check if the rule is marked as new.
int GetParentId()
Get the parent ID of the rule.
void populateRuleTreeCtrl(const std::vector< RULE_TREE_NODE > &aRuleTreeNodes, const RULE_TREE_NODE &aRuleTreeNode, wxTreeItemId aParentTreeItemId)
Populates the rule tree with nodes and their children.
void onRuleTreeItemSelectionChanged(wxTreeEvent &aEvent)
Updates action buttons based on the selected tree item.
STD_BITMAP_BUTTON * m_moveTreeItemUpButton
void moveRuleTreeItemChildrensTooOnDrag(wxTreeItemId aSrcTreeItemId, wxTreeItemId aDestTreeItemId)
Recursively moves all child nodes of a source item to a destination during drag.
void DeleteRuleTreeItem(wxTreeItemId aItemId, const int &aNodeId)
Deletes a tree item and removes its corresponding node from history.
void onRuleTreeItemMouseMotion(wxMouseEvent &aEvent)
Handles drag motion to move the item along with the cursor.
wxTreeItemId m_draggedItem
void UpdateRuleTreeItemText(wxTreeItemId aItemId, wxString aItemText)
Updates the text of a specified rule tree item.
STD_BITMAP_BUTTON * m_deleteRuleButton
void onNewRuleOptionClick(wxCommandEvent &aEvent)
Creates a new rule when the "New Rule" option is clicked.
void onRuleTreeItemLeftDown(wxMouseEvent &aEvent)
Initiates drag operation for a tree item on mouse down.
void onMoveUpRuleOptionClick(wxCommandEvent &aEvent)
Moves a rule item up in the tree when "Move Up" is clicked.
virtual void RuleTreeItemSelectionChanged(RULE_TREE_ITEM_DATA *aCurrentRuleTreeItemData)=0
Pure virtual method to handle tree item selection changes.
void onClose(wxCloseEvent &aEvt)
bool Show(bool show) override
void SetModified()
Marks the dialog as modified, indicating unsaved changes.
void RefreshContentScrollArea()
Recalculates the scrolled content area's virtual size based on the current content panel's best size,...
void onMoveDownRuleOptionClick(wxCommandEvent &aEvent)
Moves a rule item down in the tree when "Move Down" is clicked.
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 saveRuleTreeState(const wxTreeItemId &aItem, const int &aNodeId=0)
Saves the state of a tree item to history.
static RULE_EDITOR_DIALOG_BASE * GetDialog(wxWindow *aWindow)
Static method to retrieve the rule editor dialog instance associated with a given window.
wxTreeItemId m_previousId
void onRuleTreeItemLeftUp(wxMouseEvent &aEvent)
Completes the drag operation on mouse release.
void onRuleTreeItemActivated(wxTreeEvent &aEvent)
Handles double-click activation of a tree item.
void SetContentPanel(wxPanel *aContentPanel)
Replaces the current content panel with a new one based on the selected constraint type.
virtual void OnSave(wxCommandEvent &aEvent)=0
wxTreeCtrl * m_ruleTreeCtrl
wxButton * m_cancelRuleButton
void OnCharHook(wxKeyEvent &aEvt) override
std::vector< RULE_TREE_NODE > m_defaultTreeItems
wxTreeItemId m_dropTargetItem
virtual void AddNewRule(RULE_TREE_ITEM_DATA *aRuleTreeItemData)=0
Pure virtual method to add a new rule to the tree.
STD_BITMAP_BUTTON * m_moveTreeItemDownButton
wxButton * m_saveRuleButton
void onDuplicateRuleOptionClick(wxCommandEvent &aEvent)
Duplicates the selected rule when "Duplicate Rule" is clicked.
wxScrolledWindow * m_scrolledContentWin
void ClearModified()
Clears the modified flag, typically after saving.
bool m_enableDuplicateRule
RULE_TREE_ITEM_DATA * m_selectedData
void restoreRuleTree(const wxTreeItemId &aParent, const int &aNodeId)
Restores a tree item from history and appends it under a parent.
bool TransferDataToWindow() override
RULE_EDITOR_DIALOG_BASE(wxWindow *aParent, const wxString &aTitle, const wxSize &aInitialSize=wxDefaultSize)
virtual void RemoveRule(int aNodeId)=0
Pure virtual method to remove a rule from the tree.
wxTreeItemId appendRuleTreeItem(const RULE_TREE_NODE &aRuleTreeNode, wxTreeItemId aParentTreeItemId)
Appends a new rule item to the tree.
bool m_suppressSelectionEvents
std::unordered_map< int, std::tuple< wxString, std::vector< int >, wxTreeItemId > > m_treeHistoryData
void onResize(wxSizeEvent &event)
STD_BITMAP_BUTTON * m_addRuleButton
STD_BITMAP_BUTTON * m_copyRuleButton
void onDeleteRuleOptionClick(wxCommandEvent &aEvent)
Deletes the selected rule when "Delete Rule" is clicked.
wxSearchCtrl * m_filterSearch
int m_defaultSashPosition
virtual void DuplicateRule(RULE_TREE_ITEM_DATA *aRuleTreeItemData)=0
Pure virtual method to duplicate an existing rule in the tree.
bool TransferDataFromWindow() override
~RULE_EDITOR_DIALOG_BASE() override
void onRuleTreeItemRightClick(wxTreeEvent &aEvent)
Handles right-click on a rule tree item to create a context menu.
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.
void onFilterSearch(wxCommandEvent &aEvent)
Applies filter to the rule tree based on the search string.
wxSplitterWindow * m_splitter
virtual bool isEnabled(RULE_TREE_ITEM_DATA *aRuleTreeItemData, RULE_EDITOR_TREE_CONTEXT_OPT aOption)=0
Pure virtual method to verify if a context menu option for a rule tree item should be enabled.
void updateRuleTreeItemMoveOptionState()
Updates the state of move options (up/down) for the selected item.
virtual void OnCancel(wxCommandEvent &aEvent)=0
void updateRuleTreeActionButtonsState(RULE_TREE_ITEM_DATA *aRuleTreeItemData)
Updates the action buttons based on the current selection.
void finishInitialization()
void SetControlsEnabled(bool aEnable)
Enables or disables controls within the rule editor dialog.
bool filterRuleTree(const wxTreeItemId &aItem, const wxString &aFilter)
Recursively filters tree items to show only those matching the filter.
A class representing additional data associated with a wxTree item.
void SetTreeItemId(wxTreeItemId aTreeItemId)
void SetParentTreeItemId(wxTreeItemId aParentTreeItemId)
A modified version of the wxInfoBar class that allows us to:
void SetBorders(bool aLeft, bool aRight, bool aTop, bool aBottom)
This file is part of the common library.
const int minSize
Push and Shove router track width and via size dialog.
KICOMMON_API wxFont GetControlFont(wxWindow *aWindow)
KICOMMON_API wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmapBundle &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
static wxSearchCtrl * CreateTextFilterBox(wxWindow *aParent, const wxString &aDescriptiveText)
Helper function to add a filter box to a panel, with some sensible defaults for that purpose.
static wxSearchCtrl * CreateTextFilterBox(wxWindow *aParent, const wxString &aDescriptiveText)
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
Functions to provide common constants and other functions to assist in making a consistent UI.