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(
false );
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 )
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() );
506 bool isProjectRoot =
false;
509 aItem =
m_tree->GetSelection();
514 isProjectRoot = (
m_tree->GetRootItem() == aItem.GetID() );
523 ctxMenu.Append(
RENAME,
_(
"Rename" ),
_(
"Change name of this sheet" ) );
529 _(
"Remove this top-level sheet from the project" ) );
533 ctxMenu.AppendSeparator();
537 ctxMenu.Append(
NEW_TOP_LEVEL_SHEET,
_(
"New Top-Level Sheet" ),
_(
"Create a new top-level sheet" ) );
538 ctxMenu.AppendSeparator();
544 int selected = GetPopupMenuSelectionFromUser( ctxMenu );
551 wxTextEntryDialog dlg(
m_frame,
_(
"Enter name for new top-level sheet:" ),
552 _(
"New Top-Level Sheet" ),
555 if( dlg.ShowModal() == wxID_OK )
557 wxString newName = dlg.GetValue();
559 if( !newName.IsEmpty() )
571 wxString filename = newName;
572 filename.Replace(
" ",
"_" );
573 filename = filename.Lower();
575 if( !filename.EndsWith(
".kicad_sch" ) )
576 filename +=
".kicad_sch";
587 pageStr = wxString::Format(
"%d", nextPage++ );
590 m_frame->Schematic().AddTopLevelSheet( newSheet );
596 commit.
Push(
_(
"Add new top-level sheet" ) );
612 wxString msg = wxString::Format(
_(
"Delete top-level sheet '%s'?\n\nThis cannot be undone." ),
615 if( wxMessageBox( msg,
_(
"Delete Top-Level Sheet" ), wxYES_NO | wxICON_QUESTION,
m_frame ) == wxYES )
618 if(
m_frame->Schematic().GetTopLevelSheets().size() <= 1 )
620 wxMessageBox(
_(
"Cannot delete the last top-level sheet." ),
_(
"Delete Top-Level Sheet" ),
621 wxOK | wxICON_ERROR,
m_frame );
628 if(
m_frame->Schematic().RemoveTopLevelSheet( sheet ) )
630 commit.
Push(
_(
"Delete top-level sheet" ) );
646 msg.Printf(
_(
"Enter page number for sheet path %s" ),
647 ( sheetPath.Length() > 20 ) ? wxS(
" \n" ) + sheetPath + wxT(
": " )
648 : sheetPath + wxT(
": " ) );
650 wxTextEntryDialog dlg(
m_frame, msg,
_(
"Edit Sheet Page Number" ), pageNumber );
652 dlg.SetTextValidator( wxFILTER_ALPHANUMERIC );
661 modifyScreen =
m_frame->Schematic().Root().GetScreen();
678 m_frame->GetScreen()->SetPageNumber( dlg.GetValue() );
679 m_frame->OnPageSettingsChange();
683 commit.
Push( wxS(
"Change sheet page number." ) );
698 m_tree->EditLabel( aItem );
715 wxString newName =
event.GetLabel();
719 if( !newName.IsEmpty() )
732 modifyScreen =
m_frame->Schematic().Root().GetScreen();
750 if( !commit.
Empty() )
751 commit.
Push(
_(
"Renaming sheet" ) );
755 m_frame->OnPageSettingsChange();
773 int hotkey = aKeyStroke.GetKeyCode();
775 int mods = aKeyStroke.GetModifiers();
780 if( wxmods & wxMOD_ALTGR )
785 if( mods & wxMOD_CONTROL )
788 if( mods & wxMOD_ALT )
792 if( mods & wxMOD_SHIFT )
796 if( mods & wxMOD_META )
801 if( mods & wxMOD_WIN )
827 if ( !
m_frame->Schematic().IsValid() )
828 return _(
"Schematic" );
831 wxString projectName =
m_frame->Schematic().Project().GetProjectName();
833 if( projectName.IsEmpty() )
834 projectName =
_(
"Schematic" );
842 return aName + wxT(
" " ) + wxString::Format(
_(
"(page %s)" ), aPage );
851 const wxColour markText = netColor.
ToColour();
853 std::set<wxString> sheetsWithNet;
855 if( !aNetName.IsEmpty() &&
m_frame->Schematic().IsValid() )
863 if( sg && sg->GetSheet().Last() )
864 sheetsWithNet.insert( sg->GetSheet().PathAsString() );
869 std::function<void(
const wxTreeItemId& )> recurse = [&](
const wxTreeItemId& id )
871 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
878 m_tree->SetItemTextColour(
id, mark ? markText : wxNullColour );
881 wxTreeItemIdValue cookie;
882 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
884 while( child.IsOk() )
887 child =
m_tree->GetNextChild(
id, cookie );
891 if(
m_tree->GetRootItem().IsOk() )
892 recurse(
m_tree->GetRootItem() );
897 std::function<void(
const wxTreeItemId& )>
recursiveDescent = [&](
const wxTreeItemId& id )
899 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
906 wxFont font =
m_tree->GetItemFont(
id );
907 font.SetUnderlined( highLighted );
908 m_tree->SetItemFont(
id, font );
911 wxTreeItemIdValue cookie;
912 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
914 while( child.IsOk() )
917 child =
m_tree->GetNextChild(
id, cookie );
927 std::function<void(
const wxTreeItemId& )>
recursiveDescent = [&](
const wxTreeItemId& id )
929 wxCHECK_RET(
id.IsOk(), wxT(
"Invalid tree item" ) );
936 wxTreeItemIdValue cookie;
937 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
939 while( child.IsOk() )
942 child =
m_tree->GetNextChild(
id, cookie );
958 modifyScreen =
m_frame->Schematic().Root().GetScreen();
976 m_frame->OnPageSettingsChange();
984 wxTreeItemIdValue cookie;
985 wxTreeItemId child =
m_tree->GetFirstChild(
id, cookie );
987 while( child.IsOk() )
990 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.
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)