39#include <wx/generic/textdlgg.h>
41#include <wx/wupdlock.h>
77 wxBoxSizer* sizer =
new wxBoxSizer( wxVERTICAL );
81 wxVector<wxBitmapBundle> images;
84 m_tree->SetImages( images );
86 sizer->Add(
m_tree, 1, wxEXPAND, wxBORDER_NONE );
114 if(
m_tree->GetEditControl() )
128 std::vector<SCH_ITEM*> sheetChildren;
131 for(
SCH_ITEM* aItem : sheetChildren )
139 if( sheetNameBase.IsEmpty() )
142 sheetNameBase = fn.GetName();
146 wxTreeItemId child =
m_tree->AppendItem( aParent, sheetName, 0, 1 );
153 m_tree->SortChildren( aParent );
161 if( eventsWereBound )
173 [&](
const wxTreeItemId& id )
175 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
182 wxTreeItemIdValue cookie;
183 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
185 while( child.IsOk() )
188 child =
m_tree->GetNextChild(
id, cookie );
196 wxTreeItemId parent =
m_tree->GetItemParent(
id );
203 if(
m_tree->IsVisible( parent ) && !
m_tree->IsExpanded( parent ) )
207 if( !
m_tree->IsVisible(
id ) )
208 m_tree->EnsureVisible(
id );
210 m_tree->SetItemBold(
id,
true );
211 m_tree->SetFocusedItem(
id );
215 m_tree->SetItemBold(
id,
false );
218 wxTreeItemIdValue cookie;
219 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
221 while( child.IsOk() )
224 child =
m_tree->GetNextChild(
id, cookie );
230 if( eventsWereBound )
245 wxWindowUpdateLocker updateLock(
this );
249 if( !
m_frame->Schematic().HasHierarchy() )
254 if( eventsWereBound )
268 std::function<void(
const wxTreeItemId& )> getCollapsedNodes =
269 [&](
const wxTreeItemId& id )
271 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
276 if( itemData &&
m_tree->ItemHasChildren(
id ) && !
m_tree->IsExpanded(
id )
283 wxTreeItemIdValue cookie;
284 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
286 while( child.IsOk() )
288 getCollapsedNodes( child );
289 child =
m_tree->GetNextChild(
id, cookie );
295 if( !aClear && !
m_tree->IsEmpty() )
297 collapsedNodes.clear();
298 getCollapsedNodes(
m_tree->GetRootItem() );
308 std::vector<SCH_SHEET*> topLevelSheets =
m_frame->Schematic().GetTopLevelSheets();
316 m_list.push_back( sheet );
318 wxString sheetNameBase = sheet->GetShownName(
false );
321 if( sheetNameBase.IsEmpty() && sheet->GetScreen() )
323 wxFileName fn( sheet->GetScreen()->GetFileName() );
324 sheetNameBase = fn.GetName();
329 wxTreeItemId topLevelItem =
m_tree->AppendItem( projectRoot, sheetName, 0, 1 );
341 std::function<void(
const wxTreeItemId& )> collapseNodes =
342 [&](
const wxTreeItemId& id )
344 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
349 if(
id != projectRoot && itemData &&
356 wxTreeItemIdValue cookie;
357 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
359 while( child.IsOk() )
361 collapseNodes( child );
362 child =
m_tree->GetNextChild(
id, cookie );
366 collapseNodes( projectRoot );
372 if( eventsWereBound )
387 wxTreeItemId itemSel =
m_tree->GetSelection();
389 if( !itemSel.IsOk() )
397 SetCursor( wxCURSOR_ARROWWAIT );
399 SetCursor( wxCURSOR_ARROW );
409 std::function<void(
const wxTreeItemId& )> updateLabel =
410 [&](
const wxTreeItemId& id )
422 if(
m_tree->GetItemText(
id ) != sheetName )
423 m_tree->SetItemText(
id, sheetName );
426 wxTreeItemId rootId =
m_tree->GetRootItem();
427 updateLabel( rootId );
430 [&](
const wxTreeItemId& id )
432 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
433 wxTreeItemIdValue cookie;
434 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
436 while( child.IsOk() )
438 updateLabel( child );
440 child =
m_tree->GetNextChild(
id, cookie );
450 std::vector<wxString> collapsed;
455 std::function<void(
const wxTreeItemId& )> collect =
456 [&](
const wxTreeItemId& id )
458 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
462 if(
id !=
m_tree->GetRootItem() &&
m_tree->ItemHasChildren(
id )
463 && !
m_tree->IsExpanded(
id ) )
469 wxTreeItemIdValue cookie;
470 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
472 while( child.IsOk() )
475 child =
m_tree->GetNextChild(
id, cookie );
479 collect(
m_tree->GetRootItem() );
510 bool isProjectRoot =
false;
513 aItem =
m_tree->GetSelection();
518 isProjectRoot = (
m_tree->GetRootItem() == aItem.GetID() );
527 ctxMenu.Append(
RENAME,
_(
"Rename" ),
_(
"Change name of this sheet" ) );
533 _(
"Remove this top-level sheet from the project" ) );
537 ctxMenu.AppendSeparator();
541 ctxMenu.Append(
NEW_TOP_LEVEL_SHEET,
_(
"New Top-Level Sheet" ),
_(
"Create a new top-level sheet" ) );
542 ctxMenu.AppendSeparator();
548 int selected = GetPopupMenuSelectionFromUser( ctxMenu );
555 wxTextEntryDialog dlg(
m_frame,
_(
"Enter name for new top-level sheet:" ),
556 _(
"New Top-Level Sheet" ),
559 if( dlg.ShowModal() == wxID_OK )
561 wxString newName = dlg.GetValue();
563 if( !newName.IsEmpty() )
575 wxString filename = newName;
576 filename.Replace(
" ",
"_" );
577 filename = filename.Lower();
579 if( !filename.EndsWith(
".kicad_sch" ) )
580 filename +=
".kicad_sch";
591 pageStr = wxString::Format(
"%d", nextPage++ );
594 m_frame->Schematic().AddTopLevelSheet( newSheet );
600 commit.
Push(
_(
"Add new top-level sheet" ) );
616 wxString msg = wxString::Format(
_(
"Delete top-level sheet '%s'?\n\nThis cannot be undone." ),
619 if( wxMessageBox( msg,
_(
"Delete Top-Level Sheet" ), wxYES_NO | wxICON_QUESTION,
m_frame ) == wxYES )
622 if(
m_frame->Schematic().GetTopLevelSheets().size() <= 1 )
624 wxMessageBox(
_(
"Cannot delete the last top-level sheet." ),
_(
"Delete Top-Level Sheet" ),
625 wxOK | wxICON_ERROR,
m_frame );
632 if(
m_frame->Schematic().RemoveTopLevelSheet( sheet ) )
634 commit.
Push(
_(
"Delete top-level sheet" ) );
650 msg.Printf(
_(
"Enter page number for sheet path %s" ),
651 ( sheetPath.Length() > 20 ) ? wxS(
" \n" ) + sheetPath + wxT(
": " )
652 : sheetPath + wxT(
": " ) );
654 wxTextEntryDialog dlg(
m_frame, msg,
_(
"Edit Sheet Page Number" ), pageNumber );
656 dlg.SetTextValidator( wxFILTER_ALPHANUMERIC );
665 modifyScreen =
m_frame->Schematic().Root().GetScreen();
682 m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
683 m_frame->OnPageSettingsChange();
687 commit.
Push( wxS(
"Change sheet page number." ) );
702 m_tree->EditLabel( aItem );
719 wxString newName =
event.GetLabel();
723 if( !newName.IsEmpty() )
736 modifyScreen =
m_frame->Schematic().Root().GetScreen();
754 if( !commit.
Empty() )
755 commit.
Push(
_(
"Renaming sheet" ) );
759 m_frame->OnPageSettingsChange();
777 int hotkey = aKeyStroke.GetKeyCode();
779 int mods = aKeyStroke.GetModifiers();
784 if( wxmods & wxMOD_ALTGR )
789 if( mods & wxMOD_CONTROL )
792 if( mods & wxMOD_ALT )
796 if( mods & wxMOD_SHIFT )
800 if( mods & wxMOD_META )
805 if( mods & wxMOD_WIN )
831 if ( !
m_frame->Schematic().IsValid() )
832 return _(
"Schematic" );
835 wxString projectName =
m_frame->Schematic().Project().GetProjectName();
837 if( projectName.IsEmpty() )
838 projectName =
_(
"Schematic" );
846 return aName + wxT(
" " ) + wxString::Format(
_(
"(page %s)" ), aPage );
855 const wxColour markBG = netColor.
ToColour();
856 const wxColour markText = netColor.
GetBrightness() > 0.5 ? *wxBLACK : *wxWHITE;
858 std::set<wxString> sheetsWithNet;
860 if( !aNetName.IsEmpty() &&
m_frame->Schematic().IsValid() )
868 if( sg && sg->GetSheet().Last() )
869 sheetsWithNet.insert( sg->GetSheet().PathAsString() );
874 std::function<void(
const wxTreeItemId& )> recurse = [&](
const wxTreeItemId& id )
876 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
883 m_tree->SetItemBackgroundColour(
id, mark ? markBG : wxNullColour );
884 m_tree->SetItemTextColour(
id, mark ? markText : wxNullColour );
887 wxTreeItemIdValue cookie;
888 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
890 while( child.IsOk() )
893 child =
m_tree->GetNextChild(
id, cookie );
897 if(
m_tree->GetRootItem().IsOk() )
898 recurse(
m_tree->GetRootItem() );
903 std::function<void(
const wxTreeItemId& )>
recursiveDescent = [&](
const wxTreeItemId& id )
905 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
912 wxFont font =
m_tree->GetItemFont(
id );
913 font.SetUnderlined( highLighted );
914 m_tree->SetItemFont(
id, font );
917 wxTreeItemIdValue cookie;
918 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
920 while( child.IsOk() )
923 child =
m_tree->GetNextChild(
id, cookie );
933 std::function<void(
const wxTreeItemId& )>
recursiveDescent = [&](
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.
Calculate the connectivity of a schematic and generates netlists.
const std::vector< CONNECTION_SUBGRAPH * > & GetAllSubgraphs(const wxString &aNetName) const
A subgraph is a set of items that are electrically connected on a single sheet.
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 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.
double GetBrightness() const
Returns the brightness value of the color ranged from 0.0 to 1.0.
wxColour ToColour() 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.
Schematic editor (Eeschema) main window.
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0, const wxString &aVariantName=wxEmptyString) 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.
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)