KiCad PCB EDA Suite
hierarch.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
30 #include <fctsys.h>
31 #include <class_drawpanel.h>
32 #include <confirm.h>
33 #include <id.h>
34 #include <bitmaps.h>
35 #include <dialog_shim.h>
36 
37 #include <sch_edit_frame.h>
38 #include <general.h>
39 #include <sch_sheet.h>
40 #include <sch_sheet_path.h>
41 
42 #include <wx/imaglist.h>
43 #include <wx/treectrl.h>
44 
45 #include <netlist_object.h>
46 #include <sch_sheet_path.h>
47 
48 
50 
51 
55 class TreeItemData : public wxTreeItemData
56 {
57 public:
59 
60  TreeItemData( SCH_SHEET_PATH& sheet ) : wxTreeItemData()
61  {
62  m_SheetPath = sheet;
63  }
64 };
65 
66 
70 class HIERARCHY_TREE : public wxTreeCtrl
71 {
72 private:
74  wxImageList* imageList;
75 
76 public:
78 
79  // Closes the dialog on escape key
80  void onChar( wxKeyEvent& event );
81 };
82 
83 
85  wxTreeCtrl( (wxWindow*) parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
86  wxTR_HAS_BUTTONS, wxDefaultValidator, wxT( "HierachyTreeCtrl" ) )
87 {
88  m_parent = parent;
89 
90  // Make an image list containing small icons
91  // All icons are expected having the same size.
92  wxBitmap tree_nosel_bm( KiBitmap( tree_nosel_xpm ) );
93  imageList = new wxImageList( tree_nosel_bm.GetWidth(),
94  tree_nosel_bm.GetHeight(), true, 2 );
95 
96  imageList->Add( tree_nosel_bm );
97  imageList->Add( KiBitmap( tree_sel_xpm ) );
98 
99  AssignImageList( imageList );
100 }
101 
102 
104 {
105 public:
109 
110 private:
111  SCH_SHEET_PATH m_currSheet; // The currently opened scheet in hierarchy
112 
113 public:
114  HIERARCHY_NAVIG_DLG( SCH_EDIT_FRAME* aParent, const wxPoint& aPos );
115 
117 
118  // Select the sheet currently selected in the tree, and close the dialog
119  void SelectNewSheetAndQuit();
120 
121 private:
129  void buildHierarchyTree( SCH_SHEET_PATH* aList, wxTreeItemId* aPreviousmenu );
130 
135  void onSelectSheetPath( wxTreeEvent& event );
136 };
137 
138 
140 {
141  HIERARCHY_NAVIG_DLG* treeframe = new HIERARCHY_NAVIG_DLG( this, pos );
142 
143  treeframe->ShowQuasiModal();
144  treeframe->Destroy();
145 }
146 
147 
149  DIALOG_SHIM( aParent, wxID_ANY, _( "Navigator" ), wxDefaultPosition, wxDefaultSize,
150  wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
151 {
152  wxASSERT( dynamic_cast< SCH_EDIT_FRAME* >( aParent ) );
153 
154  m_SchFrameEditor = aParent;
155  m_currSheet = aParent->GetCurrentSheet();
156  m_Tree = new HIERARCHY_TREE( this );
157  m_nbsheets = 1;
158 
159  // root is the link to the main sheet.
160  wxTreeItemId root;
161  root = m_Tree->AddRoot( _( "Root" ), 0, 1 );
162  m_Tree->SetItemBold( root, true );
163 
164  SCH_SHEET_PATH list;
165  list.push_back( g_RootSheet );
166  m_Tree->SetItemData( root, new TreeItemData( list ) );
167 
169  m_Tree->SelectItem( root );
170 
171  buildHierarchyTree( &list, &root );
172 
173  m_Tree->ExpandAll();
174 
175  // This bloc gives a good size to the dialog, better than the default "best" size,
176  // the first time the dialog is opened, during a session
177  wxRect itemrect;
178  wxSize tree_size;
179 
180  m_Tree->GetBoundingRect( root, itemrect );
181 
182  // Set dialog window size to be large enough
183  tree_size.x = itemrect.GetWidth() + 20;
184  tree_size.x = std::max( tree_size.x, 250 );
185 
186  // Readjust the size of the frame to an optimal value.
187  tree_size.y = m_nbsheets * itemrect.GetHeight();
188 
189  if( m_nbsheets < 2 )
190  tree_size.y += 10; // gives a better look for small trees
191 
192  SetClientSize( tree_size );
193 
194  // manage the ESC key to close the dialog, because thre is no Cancel button
195  // in dialog
196  m_Tree->Connect( wxEVT_CHAR, wxKeyEventHandler( HIERARCHY_TREE::onChar ) );
197 
198  // Manage double click on a selection, or the enter key:
199  Bind( wxEVT_TREE_ITEM_ACTIVATED, &HIERARCHY_NAVIG_DLG::onSelectSheetPath, this );
200  // Manage a simple click on a selection, if the selection changes
201  Bind( wxEVT_TREE_SEL_CHANGED, &HIERARCHY_NAVIG_DLG::onSelectSheetPath, this );
202 }
203 
204 
206 {
207  Unbind( wxEVT_TREE_ITEM_ACTIVATED, &HIERARCHY_NAVIG_DLG::onSelectSheetPath, this );
208  Unbind( wxEVT_TREE_SEL_CHANGED, &HIERARCHY_NAVIG_DLG::onSelectSheetPath, this );
209  m_Tree->Disconnect( wxEVT_CHAR, wxKeyEventHandler( HIERARCHY_TREE::onChar ) );
210 }
211 
212 
213 void HIERARCHY_TREE::onChar( wxKeyEvent& event )
214 {
215  if( event.GetKeyCode() == WXK_ESCAPE )
216  m_parent->Close( true );
217  else
218  event.Skip();
219 }
220 
221 
222 void HIERARCHY_NAVIG_DLG::buildHierarchyTree( SCH_SHEET_PATH* aList, wxTreeItemId* aPreviousmenu )
223 {
224  wxCHECK_RET( m_nbsheets < NB_MAX_SHEET, "Maximum number of sheets exceeded." );
225 
226  SCH_ITEM* schitem = aList->LastDrawList();
227 
228  while( schitem && m_nbsheets < NB_MAX_SHEET )
229  {
230  if( schitem->Type() == SCH_SHEET_T )
231  {
232  SCH_SHEET* sheet = (SCH_SHEET*) schitem;
233  m_nbsheets++;
234  wxTreeItemId menu;
235  menu = m_Tree->AppendItem( *aPreviousmenu, sheet->GetName(), 0, 1 );
236  aList->push_back( sheet );
237  m_Tree->SetItemData( menu, new TreeItemData( *aList ) );
238 
239  if( *aList == m_currSheet )
240  {
241  m_Tree->EnsureVisible( menu );
242  m_Tree->SelectItem( menu );
243  }
244 
245  buildHierarchyTree( aList, &menu );
246 
247  aList->pop_back();
248  }
249 
250  schitem = schitem->Next();
251  }
252 }
253 
254 
255 void HIERARCHY_NAVIG_DLG::onSelectSheetPath( wxTreeEvent& event )
256 {
257  wxTreeItemId ItemSel = m_Tree->GetSelection();
258  m_SchFrameEditor->SetCurrentSheet(( (TreeItemData*) m_Tree->GetItemData( ItemSel ) )->m_SheetPath );
260  Close( true );
261 }
262 
263 
265 {
266  SetRepeatItem( NULL );
267  ClearMsgPanel();
268 
269  SCH_SCREEN* screen = m_CurrentSheet->LastScreen();
270 
271  // Switch to current sheet,
272  // and update the grid size, because it can be modified in latest screen
273  SetScreen( screen );
274  GetScreen()->SetGrid( m_LastGridSizeId + ID_POPUP_GRID_LEVEL_1000 );
275 
276  // update the References
277  m_CurrentSheet->UpdateAllScreenReferences();
278  SetSheetNumberAndCount();
279  m_canvas->SetCanStartBlock( -1 );
280 
281  if( screen->m_FirstRedraw )
282  {
283  Zoom_Automatique( false );
284  screen->m_FirstRedraw = false;
285  SetCrossHairPosition( GetScrollCenterPosition() );
286  m_canvas->MoveCursorToCrossHair();
287 
288  // Ensure the schematic is fully segmented on first display
289  BreakSegmentsOnJunctions();
290  SchematicCleanUp( true );
291  screen->ClearUndoORRedoList( screen->m_UndoList, 1 );
292 
293  screen->TestDanglingEnds();
294  }
295  else
296  {
297  RedrawScreen( GetScrollCenterPosition(), true );
298  }
299 
300  // Some items (wires, labels) can be highlighted. So prepare the highlight flag:
301  SetCurrentSheetHighlightFlags();
302 
303  // Now refresh m_canvas. Should be not necessary, but because screen has changed
304  // the previous refresh has set all new draw parameters (scroll position ..)
305  // but most of time there were some inconsitencies about cursor parameters
306  // ( previous position of cursor ...) and artefacts can happen
307  // mainly when sheet size has changed
308  // This second refresh clears artefacts because at this point,
309  // all parameters are now updated
310  m_canvas->Refresh();
311 }
SCH_ITEM * LastDrawList() const
Function LastDrawList.
void SetCurrentSheet(const SCH_SHEET_PATH &aSheet)
Definition of the SCH_SHEET class for Eeschema.
void onSelectSheetPath(wxTreeEvent &event)
Open the selected sheet and display the corresponding screen when a tree item is selected.
Definition: hierarch.cpp:255
KICAD_T Type() const
Function Type()
Definition: base_struct.h:209
#define NB_MAX_SHEET
Max number of sheets in a hierarchy project.
Definition: sch_screen.h:64
wxImageList * imageList
Definition: hierarch.cpp:74
This file is part of the common library.
Store an SCH_SHEET_PATH of each sheet in hierarchy.
Definition: hierarch.cpp:55
HIERARCHY_TREE * m_Tree
Definition: hierarch.cpp:107
Schematic editor (Eeschema) main window.
Handle hierarchy tree control.
Definition: hierarch.cpp:70
Class DIALOG_SHIM may sit in the inheritance tree between wxDialog and any class written by wxFormBui...
Definition: dialog_shim.h:70
void DisplayCurrentSheet()
Draw the current sheet on the display.
Definition: hierarch.cpp:264
SCH_EDIT_FRAME * m_SchFrameEditor
Definition: hierarch.cpp:106
SCH_ITEM * Next() const
void InstallHierarchyFrame(wxPoint &pos)
Definition: hierarch.cpp:139
TreeItemData(SCH_SHEET_PATH &sheet)
Definition: hierarch.cpp:60
SCH_SHEET_PATH m_currSheet
Definition: hierarch.cpp:111
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Function KiBitmap constructs a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:78
bool m_FirstRedraw
Definition: base_screen.h:207
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:55
UNDO_REDO_CONTAINER m_UndoList
Objects list for the undo command (old data)
Definition: base_screen.h:210
int ShowQuasiModal()
SCH_SHEET_PATH & GetCurrentSheet()
void onChar(wxKeyEvent &event)
Definition: hierarch.cpp:213
Class SCH_SHEET_PATH.
SCH_SHEET * Last() const
Function Last returns a pointer to the last sheet of the list One can see the others sheet as the "pa...
HIERARCHY_TREE(HIERARCHY_NAVIG_DLG *parent)
Definition: hierarch.cpp:84
void buildHierarchyTree(SCH_SHEET_PATH *aList, wxTreeItemId *aPreviousmenu)
Create the hierarchical tree of the schematic.
Definition: hierarch.cpp:222
HIERARCHY_NAVIG_DLG(SCH_EDIT_FRAME *aParent, const wxPoint &aPos)
Definition: hierarch.cpp:148
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:209
#define max(a, b)
Definition: auxiliary.h:86
bool TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
Definition: sch_screen.cpp:913
HIERARCHY_NAVIG_DLG * m_parent
Definition: hierarch.cpp:73
virtual void ClearUndoORRedoList(UNDO_REDO_CONTAINER &aList, int aItemCount=-1) override
Free the undo or redo list from aList element.
Definition: sch_screen.cpp:567
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
Definition of the NETLIST_OBJECT class.
wxString GetName() const
Definition: sch_sheet.h:267
SCH_SHEET_PATH m_SheetPath
Definition: hierarch.cpp:58
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...