35#include <wx/generic/textdlgg.h>
37#include <wx/wupdlock.h>
73 wxBoxSizer* sizer =
new wxBoxSizer( wxVERTICAL );
77 wxVector<wxBitmapBundle> images;
80 m_tree->SetImages( images );
82 sizer->Add(
m_tree, 1, wxEXPAND, wxBORDER_NONE );
110 if(
m_tree->GetEditControl() )
124 std::vector<SCH_ITEM*> sheetChildren;
127 for(
SCH_ITEM* aItem : sheetChildren )
135 if( sheetNameBase.IsEmpty() )
138 sheetNameBase = fn.GetName();
142 wxTreeItemId child =
m_tree->AppendItem( aParent, sheetName, 0, 1 );
149 m_tree->SortChildren( aParent );
157 if( eventsWereBound )
169 [&](
const wxTreeItemId& id )
171 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
178 wxTreeItemIdValue cookie;
179 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
181 while( child.IsOk() )
184 child =
m_tree->GetNextChild(
id, cookie );
192 wxTreeItemId parent =
m_tree->GetItemParent(
id );
199 if(
m_tree->IsVisible( parent ) && !
m_tree->IsExpanded( parent ) )
203 if( !
m_tree->IsVisible(
id ) )
204 m_tree->EnsureVisible(
id );
206 m_tree->SetItemBold(
id,
true );
207 m_tree->SetFocusedItem(
id );
211 m_tree->SetItemBold(
id,
false );
214 wxTreeItemIdValue cookie;
215 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
217 while( child.IsOk() )
220 child =
m_tree->GetNextChild(
id, cookie );
226 if( eventsWereBound )
241 wxWindowUpdateLocker updateLock(
this );
245 if( !
m_frame->Schematic().HasHierarchy() )
250 if( eventsWereBound )
264 std::function<void(
const wxTreeItemId& )> getCollapsedNodes =
265 [&](
const wxTreeItemId& id )
267 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
272 if( itemData &&
m_tree->ItemHasChildren(
id ) && !
m_tree->IsExpanded(
id )
279 wxTreeItemIdValue cookie;
280 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
282 while( child.IsOk() )
284 getCollapsedNodes( child );
285 child =
m_tree->GetNextChild(
id, cookie );
291 if( !aClear && !
m_tree->IsEmpty() )
293 collapsedNodes.clear();
294 getCollapsedNodes(
m_tree->GetRootItem() );
304 std::vector<SCH_SHEET*> topLevelSheets =
m_frame->Schematic().GetTopLevelSheets();
312 m_list.push_back( sheet );
314 wxString sheetNameBase = sheet->GetShownName(
FOR_GUI );
317 if( sheetNameBase.IsEmpty() && sheet->GetScreen() )
319 wxFileName fn( sheet->GetScreen()->GetFileName() );
320 sheetNameBase = fn.GetName();
325 wxTreeItemId topLevelItem =
m_tree->AppendItem( projectRoot, sheetName, 0, 1 );
337 std::function<void(
const wxTreeItemId& )> collapseNodes =
338 [&](
const wxTreeItemId& id )
340 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
345 if(
id != projectRoot && itemData &&
352 wxTreeItemIdValue cookie;
353 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
355 while( child.IsOk() )
357 collapseNodes( child );
358 child =
m_tree->GetNextChild(
id, cookie );
362 collapseNodes( projectRoot );
368 if( eventsWereBound )
383 wxTreeItemId itemSel =
m_tree->GetSelection();
385 if( !itemSel.IsOk() )
393 SetCursor( wxCURSOR_ARROWWAIT );
395 SetCursor( wxCURSOR_ARROW );
405 std::function<void(
const wxTreeItemId& )> updateLabel =
406 [&](
const wxTreeItemId& id )
417 if(
m_tree->GetItemText(
id ) != sheetName )
418 m_tree->SetItemText(
id, sheetName );
421 wxTreeItemId rootId =
m_tree->GetRootItem();
422 updateLabel( rootId );
425 [&](
const wxTreeItemId& id )
427 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
428 wxTreeItemIdValue cookie;
429 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
431 while( child.IsOk() )
433 updateLabel( child );
435 child =
m_tree->GetNextChild(
id, cookie );
445 std::vector<wxString> collapsed;
450 std::function<void(
const wxTreeItemId& )> collect =
451 [&](
const wxTreeItemId& id )
453 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
457 if(
id !=
m_tree->GetRootItem() &&
m_tree->ItemHasChildren(
id )
458 && !
m_tree->IsExpanded(
id ) )
464 wxTreeItemIdValue cookie;
465 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
467 while( child.IsOk() )
470 child =
m_tree->GetNextChild(
id, cookie );
474 collect(
m_tree->GetRootItem() );
508 m_frame->UpdateHierarchyNavigator();
512 if(
m_frame->GetCurrentSheet() != aPreviousSheet )
513 m_frame->DisplayCurrentSheet();
523 bool isProjectRoot =
false;
526 aItem =
m_tree->GetSelection();
531 isProjectRoot = (
m_tree->GetRootItem() == aItem.GetID() );
540 ctxMenu.Append(
RENAME,
_(
"Rename" ),
_(
"Change name of this sheet" ) );
546 _(
"Remove this top-level sheet from the project" ) );
550 ctxMenu.AppendSeparator();
554 ctxMenu.Append(
NEW_TOP_LEVEL_SHEET,
_(
"New Top-Level Sheet" ),
_(
"Create a new top-level sheet" ) );
555 ctxMenu.AppendSeparator();
561 int selected = GetPopupMenuSelectionFromUser( ctxMenu );
568 wxTextEntryDialog dlg(
m_frame,
_(
"Enter name for new top-level sheet:" ),
569 _(
"New Top-Level Sheet" ),
572 if( dlg.ShowModal() == wxID_OK )
574 wxString newName = dlg.GetValue();
576 if( !newName.IsEmpty() )
588 wxString filename = newName;
589 filename.Replace(
" ",
"_" );
590 filename = filename.Lower();
592 if( !filename.EndsWith(
".kicad_sch" ) )
593 filename +=
".kicad_sch";
605 pageStr = wxString::Format(
"%d", nextPage++ );
608 m_frame->Schematic().AddTopLevelSheet( newSheet );
627 wxString msg = wxString::Format(
_(
"Delete top-level sheet '%s'?\n\nThis cannot be undone." ),
630 if( wxMessageBox( msg,
_(
"Delete Top-Level Sheet" ), wxYES_NO | wxICON_QUESTION,
m_frame ) == wxYES )
633 if(
m_frame->Schematic().GetTopLevelSheets().size() <= 1 )
635 wxMessageBox(
_(
"Cannot delete the last top-level sheet." ),
_(
"Delete Top-Level Sheet" ),
636 wxOK | wxICON_ERROR,
m_frame );
643 if(
m_frame->Schematic().RemoveTopLevelSheet( sheet ) )
656 msg.Printf(
_(
"Enter page number for sheet path %s" ),
657 ( sheetPath.Length() > 20 ) ? wxS(
" \n" ) + sheetPath + wxT(
": " )
658 : sheetPath + wxT(
": " ) );
660 wxTextEntryDialog dlg(
m_frame, msg,
_(
"Edit Sheet Page Number" ), pageNumber );
662 dlg.SetTextValidator( wxFILTER_ALPHANUMERIC );
671 modifyScreen =
m_frame->Schematic().Root().GetScreen();
688 m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
689 m_frame->OnPageSettingsChange();
693 commit.
Push( wxS(
"Change sheet page number." ) );
708 m_tree->EditLabel( aItem );
725 wxString newName =
event.GetLabel();
729 if( !newName.IsEmpty() )
742 modifyScreen =
m_frame->Schematic().Root().GetScreen();
760 if( !commit.
Empty() )
761 commit.
Push(
_(
"Renaming sheet" ) );
765 m_frame->OnPageSettingsChange();
783 int hotkey = aKeyStroke.GetKeyCode();
785 int mods = aKeyStroke.GetModifiers();
790 if( wxmods & wxMOD_ALTGR )
795 if( mods & wxMOD_CONTROL )
798 if( mods & wxMOD_ALT )
802 if( mods & wxMOD_SHIFT )
806 if( mods & wxMOD_META )
811 if( mods & wxMOD_WIN )
837 if ( !
m_frame->Schematic().IsValid() )
838 return _(
"Schematic" );
841 wxString projectName =
m_frame->Schematic().Project().GetProjectName();
843 if( projectName.IsEmpty() )
844 projectName =
_(
"Schematic" );
852 return aName + wxT(
" " ) + wxString::Format(
_(
"(page %s)" ), aPage );
861 const wxColour markText = netColor.
ToColour();
863 std::set<wxString> sheetsWithNet;
865 if( !aNetName.IsEmpty() &&
m_frame->Schematic().IsValid() )
868 sheetsWithNet.insert(
path.AsString() );
871 std::function<void(
const wxTreeItemId& )> recurse =
872 [&](
const wxTreeItemId& id )
874 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
881 m_tree->SetItemTextColour(
id, mark ? markText : wxNullColour );
884 wxTreeItemIdValue cookie;
885 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
887 while( child.IsOk() )
890 child =
m_tree->GetNextChild(
id, cookie );
894 if(
m_tree->GetRootItem().IsOk() )
895 recurse(
m_tree->GetRootItem() );
901 [&](
const wxTreeItemId& id )
903 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
910 wxFont font =
m_tree->GetItemFont(
id );
911 font.SetUnderlined( highLighted );
912 m_tree->SetItemFont(
id, font );
915 wxTreeItemIdValue cookie;
916 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
918 while( child.IsOk() )
921 child =
m_tree->GetNextChild(
id, cookie );
932 [&](
const wxTreeItemId& id )
934 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
941 wxTreeItemIdValue cookie;
942 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
944 while( child.IsOk() )
947 child =
m_tree->GetNextChild(
id, cookie );
963 modifyScreen =
m_frame->Schematic().Root().GetScreen();
981 m_frame->OnPageSettingsChange();
989 wxTreeItemIdValue cookie;
990 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
992 while( child.IsOk() )
995 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
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Net membership for one UI operation.
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