36#include <wx/generic/textdlgg.h>
38#include <wx/wupdlock.h>
74 wxBoxSizer* sizer =
new wxBoxSizer( wxVERTICAL );
78 wxVector<wxBitmapBundle> images;
81 m_tree->SetImages( images );
83 sizer->Add(
m_tree, 1, wxEXPAND, wxBORDER_NONE );
111 if(
m_tree->GetEditControl() )
125 std::vector<SCH_ITEM*> sheetChildren;
128 for(
SCH_ITEM* aItem : sheetChildren )
136 if( sheetNameBase.IsEmpty() )
139 sheetNameBase = fn.GetName();
143 wxTreeItemId child =
m_tree->AppendItem( aParent, sheetName, 0, 1 );
150 m_tree->SortChildren( aParent );
158 if( eventsWereBound )
170 [&](
const wxTreeItemId& id )
172 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
179 wxTreeItemIdValue cookie;
180 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
182 while( child.IsOk() )
185 child =
m_tree->GetNextChild(
id, cookie );
193 wxTreeItemId parent =
m_tree->GetItemParent(
id );
200 if(
m_tree->IsVisible( parent ) && !
m_tree->IsExpanded( parent ) )
204 if( !
m_tree->IsVisible(
id ) )
205 m_tree->EnsureVisible(
id );
207 m_tree->SetItemBold(
id,
true );
208 m_tree->SetFocusedItem(
id );
212 m_tree->SetItemBold(
id,
false );
215 wxTreeItemIdValue cookie;
216 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
218 while( child.IsOk() )
221 child =
m_tree->GetNextChild(
id, cookie );
227 if( eventsWereBound )
242 wxWindowUpdateLocker updateLock(
this );
246 if( !
m_frame->Schematic().HasHierarchy() )
251 if( eventsWereBound )
265 std::function<void(
const wxTreeItemId& )> getCollapsedNodes =
266 [&](
const wxTreeItemId& id )
268 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
273 if( itemData &&
m_tree->ItemHasChildren(
id ) && !
m_tree->IsExpanded(
id )
280 wxTreeItemIdValue cookie;
281 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
283 while( child.IsOk() )
285 getCollapsedNodes( child );
286 child =
m_tree->GetNextChild(
id, cookie );
292 if( !aClear && !
m_tree->IsEmpty() )
294 collapsedNodes.clear();
295 getCollapsedNodes(
m_tree->GetRootItem() );
305 std::vector<SCH_SHEET*> topLevelSheets =
m_frame->Schematic().GetTopLevelSheets();
313 m_list.push_back( sheet );
315 wxString sheetNameBase = sheet->GetShownName(
FOR_GUI );
318 if( sheetNameBase.IsEmpty() && sheet->GetScreen() )
320 wxFileName fn( sheet->GetScreen()->GetFileName() );
321 sheetNameBase = fn.GetName();
326 wxTreeItemId topLevelItem =
m_tree->AppendItem( projectRoot, sheetName, 0, 1 );
338 std::function<void(
const wxTreeItemId& )> collapseNodes =
339 [&](
const wxTreeItemId& id )
341 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
346 if(
id != projectRoot && itemData &&
353 wxTreeItemIdValue cookie;
354 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
356 while( child.IsOk() )
358 collapseNodes( child );
359 child =
m_tree->GetNextChild(
id, cookie );
363 collapseNodes( projectRoot );
369 if( eventsWereBound )
384 wxTreeItemId itemSel =
m_tree->GetSelection();
386 if( !itemSel.IsOk() )
394 SetCursor( wxCURSOR_ARROWWAIT );
396 SetCursor( wxCURSOR_ARROW );
406 std::function<void(
const wxTreeItemId& )> updateLabel =
407 [&](
const wxTreeItemId& id )
418 if(
m_tree->GetItemText(
id ) != sheetName )
419 m_tree->SetItemText(
id, sheetName );
422 wxTreeItemId rootId =
m_tree->GetRootItem();
423 updateLabel( rootId );
426 [&](
const wxTreeItemId& id )
428 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
429 wxTreeItemIdValue cookie;
430 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
432 while( child.IsOk() )
434 updateLabel( child );
436 child =
m_tree->GetNextChild(
id, cookie );
446 std::vector<wxString> collapsed;
451 std::function<void(
const wxTreeItemId& )> collect =
452 [&](
const wxTreeItemId& id )
454 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
458 if(
id !=
m_tree->GetRootItem() &&
m_tree->ItemHasChildren(
id )
459 && !
m_tree->IsExpanded(
id ) )
465 wxTreeItemIdValue cookie;
466 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
468 while( child.IsOk() )
471 child =
m_tree->GetNextChild(
id, cookie );
475 collect(
m_tree->GetRootItem() );
509 m_frame->UpdateHierarchyNavigator();
513 if(
m_frame->GetCurrentSheet() != aPreviousSheet )
514 m_frame->DisplayCurrentSheet();
524 bool isProjectRoot =
false;
527 aItem =
m_tree->GetSelection();
532 isProjectRoot = (
m_tree->GetRootItem() == aItem.GetID() );
541 ctxMenu.Append(
RENAME,
_(
"Rename" ),
_(
"Change name of this sheet" ) );
547 _(
"Remove this top-level sheet from the project" ) );
551 ctxMenu.AppendSeparator();
555 ctxMenu.Append(
NEW_TOP_LEVEL_SHEET,
_(
"New Top-Level Sheet" ),
_(
"Create a new top-level sheet" ) );
556 ctxMenu.AppendSeparator();
562 int selected = GetPopupMenuSelectionFromUser( ctxMenu );
569 wxTextEntryDialog dlg(
m_frame,
_(
"Enter name for new top-level sheet:" ),
570 _(
"New Top-Level Sheet" ),
573 if( dlg.ShowModal() == wxID_OK )
575 wxString newName = dlg.GetValue();
577 if( !newName.IsEmpty() )
589 wxString filename = newName;
590 filename.Replace(
" ",
"_" );
591 filename = filename.Lower();
593 if( !filename.EndsWith(
".kicad_sch" ) )
594 filename +=
".kicad_sch";
606 pageStr = wxString::Format(
"%d", nextPage++ );
609 m_frame->Schematic().AddTopLevelSheet( newSheet );
628 wxString msg = wxString::Format(
_(
"Delete top-level sheet '%s'?\n\nThis cannot be undone." ),
631 if( wxMessageBox( msg,
_(
"Delete Top-Level Sheet" ), wxYES_NO | wxICON_QUESTION,
m_frame ) == wxYES )
634 if(
m_frame->Schematic().GetTopLevelSheets().size() <= 1 )
636 wxMessageBox(
_(
"Cannot delete the last top-level sheet." ),
_(
"Delete Top-Level Sheet" ),
637 wxOK | wxICON_ERROR,
m_frame );
644 if(
m_frame->Schematic().RemoveTopLevelSheet( sheet ) )
657 msg.Printf(
_(
"Enter page number for sheet path %s" ),
658 ( sheetPath.Length() > 20 ) ? wxS(
" \n" ) + sheetPath + wxT(
": " )
659 : sheetPath + wxT(
": " ) );
661 wxTextEntryDialog dlg(
m_frame, msg,
_(
"Edit Sheet Page Number" ), pageNumber );
663 dlg.SetTextValidator( wxFILTER_ALPHANUMERIC );
672 modifyScreen =
m_frame->Schematic().Root().GetScreen();
689 m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
690 m_frame->OnPageSettingsChange();
694 commit.
Push(
_(
"Change Page Number" ) );
709 m_tree->EditLabel( aItem );
726 wxString newName =
event.GetLabel();
730 if( !newName.IsEmpty() )
743 modifyScreen =
m_frame->Schematic().Root().GetScreen();
761 if( !commit.
Empty() )
762 commit.
Push(
_(
"Rename Sheet" ) );
766 m_frame->OnPageSettingsChange();
784 int hotkey = aKeyStroke.GetKeyCode();
786 int mods = aKeyStroke.GetModifiers();
791 if( wxmods & wxMOD_ALTGR )
796 if( mods & wxMOD_CONTROL )
799 if( mods & wxMOD_ALT )
803 if( mods & wxMOD_SHIFT )
807 if( mods & wxMOD_META )
812 if( mods & wxMOD_WIN )
838 if ( !
m_frame->Schematic().IsValid() )
839 return _(
"Schematic" );
842 wxString projectName =
m_frame->Schematic().Project().GetProjectName();
844 if( projectName.IsEmpty() )
845 projectName =
_(
"Schematic" );
853 return aName + wxT(
" " ) + wxString::Format(
_(
"(page %s)" ), aPage );
862 const wxColour markText = netColor.
ToColour();
864 std::set<wxString> sheetsWithNet;
866 if( !aNetName.IsEmpty() &&
m_frame->Schematic().IsValid() )
869 sheetsWithNet.insert(
path.AsString() );
872 std::function<void(
const wxTreeItemId& )> recurse =
873 [&](
const wxTreeItemId& id )
875 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
882 m_tree->SetItemTextColour(
id, mark ? markText : wxNullColour );
885 wxTreeItemIdValue cookie;
886 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
888 while( child.IsOk() )
891 child =
m_tree->GetNextChild(
id, cookie );
895 if(
m_tree->GetRootItem().IsOk() )
896 recurse(
m_tree->GetRootItem() );
902 [&](
const wxTreeItemId& id )
904 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
911 wxFont font =
m_tree->GetItemFont(
id );
912 font.SetUnderlined( highLighted );
913 m_tree->SetItemFont(
id, font );
916 wxTreeItemIdValue cookie;
917 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
919 while( child.IsOk() )
922 child =
m_tree->GetNextChild(
id, cookie );
933 [&](
const wxTreeItemId& id )
935 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
942 wxTreeItemIdValue cookie;
943 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
945 while( child.IsOk() )
948 child =
m_tree->GetNextChild(
id, cookie );
964 modifyScreen =
m_frame->Schematic().Root().GetScreen();
982 m_frame->OnPageSettingsChange();
990 wxTreeItemIdValue cookie;
991 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
993 while( child.IsOk() )
996 child =
m_tree->GetNextChild(
id, cookie );
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
static TOOL_ACTION expandAll
static TOOL_ACTION collapseAll
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
void onRightClick(wxTreeItemId aItem)
void UpdateHierarchyTree(bool aClear=false)
Update the hierarchical tree of the schematic.
void onSelectSheetPath(wxTreeEvent &aEvent)
Open the selected sheet and display the corresponding screen when a tree item is selected.
void UpdateLabelsHierarchyTree()
Update the labels of the hierarchical tree of the schematic.
wxString formatPageString(const wxString &aName, const wxString &aPage)
void UpdateHierarchySelection()
Updates the tree's selection to match current page.
wxString m_highlightedNet
HIERARCHY_PANE(SCH_EDIT_FRAME *aParent)
std::set< wxString > m_collapsedPaths
void onCharHook(wxKeyEvent &aKeyStroke)
void renameIdenticalSheets(const SCH_SHEET_PATH &renamedSheet, const wxString newName, SCH_COMMIT *commit)
Rename all sheets in a hierarchial desing which has the same source renamed sheet.
void buildHierarchyTree(SCH_SHEET_PATH *aList, const wxTreeItemId &aParent)
Create the hierarchical tree of the schematic.
void resyncAfterTopLevelSheetChange(const SCH_SHEET_PATH &aPreviousSheet)
Bring the editor back in sync after a top-level sheet was added or removed.
void onContextMenu(wxContextMenuEvent &aEvent)
void onTreeItemRightClick(wxTreeEvent &aEvent)
std::vector< wxString > GetCollapsedPaths() const
Returns a list of sheet paths for nodes that are currently collapsed.
void onTreeEditFinished(wxTreeEvent &event)
void UpdateNetHighlight(const wxString &aNetName)
void setIdenticalSheetsHighlighted(const SCH_SHEET_PATH &path, bool highLighted=true)
When renaming the sheets in tree it is helpful to highlight the identical sheets which got renamed by...
Navigation hierarchy tree control.
int OnCompareItems(const wxTreeItemId &item1, const wxTreeItemId &item2) override
A color representation with 4 components: red, green, blue, alpha.
wxColour ToColour() const
wxString AsString() const
The project local settings are things that are attached to a particular project, but also might be pa...
std::vector< wxString > m_SchHierarchyCollapsed
Collapsed nodes in the schematic hierarchy navigator.
static TOOL_ACTION changeSheet
Commit for the schematic and symbol editors.
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
One UI operation's hierarchy index.
std::set< KIID_PATH > NetSheets(const wxString &aName) const
Schematic editor (Eeschema) main window.
wxString GetShownText(const SCH_SHEET_PATH *aPath, RESOLUTION_CONTEXT aContext, const wxString &aVariantName=wxEmptyString, int aDepth=0) const
void SetText(const wxString &aText) override
Base class for any item which can be embedded within the SCHEMATIC container class,...
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
void GetSheets(std::vector< SCH_ITEM * > *aItems) const
Similar to Items().OfType( SCH_SHEET_T ), but return the sheets in a deterministic order (L-R,...
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
bool PageNumberExists(const wxString &aPageNumber) const
bool HasPath(const KIID_PATH &aPath) const
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
const SCH_SHEET * GetSheet(unsigned aIndex) const
int ComparePageNum(const SCH_SHEET_PATH &aSheetPathToTest) const
Compare sheets by their page number.
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
SCH_SCREEN * LastScreen()
int Cmp(const SCH_SHEET_PATH &aSheetPathToTest) const
Compare if this is the same sheet path as aSheetPathToTest.
wxString GetPageNumber() const
wxString PathHumanReadable(bool aUseShortRootName=true, bool aStripTrailingSeparator=false, bool aEscapeSheetNames=false) const
Return the sheet path in a human readable form made from the sheet names.
wxString PathAsString() const
Return the path of time stamps which do not changes even when editing sheet parameters.
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
size_t size() const
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
wxString GetFileName() const
Return the filename corresponding to this sheet.
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this sheet.
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Store an SCH_SHEET_PATH of each sheet in hierarchy.
SCH_SHEET_PATH m_SheetPath
TREE_ITEM_DATA(SCH_SHEET_PATH &sheet)
WX_PANEL(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
static void recursiveDescent(wxSizer *aSizer, std::map< int, wxString > &aLabels)
wxIMPLEMENT_ABSTRACT_CLASS(HIERARCHY_TREE, wxTreeCtrl)
std::vector< FAB_LAYER_COLOR > dummy