KiCad PCB EDA Suite
eeschema/onleftclick.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) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.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 <kiway.h>
32 #include <eeschema_id.h>
33 #include <class_drawpanel.h>
34 #include <confirm.h>
35 #include <schframe.h>
36 #include <sim/sim_plot_frame.h>
37 #include <menus_helpers.h>
38 
39 #include <sch_bus_entry.h>
40 #include <sch_text.h>
41 #include <sch_marker.h>
42 #include <sch_junction.h>
43 #include <sch_line.h>
44 #include <sch_no_connect.h>
45 #include <sch_component.h>
46 #include <sch_sheet.h>
47 #include <sch_sheet_path.h>
48 #include <sch_bitmap.h>
49 
50 #include <class_netlist_object.h>
51 #include <class_library.h> // fo class SCHLIB_FILTER to filter power parts
52 
53 
54 // TODO(hzeller): These pairs of elmenets should be represented by an object, but don't want
55 // to refactor too much right now to not get in the way with other code changes.
58 
59 
60 void SCH_EDIT_FRAME::OnLeftClick( wxDC* aDC, const wxPoint& aPosition )
61 {
62  SCH_ITEM* item = GetScreen()->GetCurItem();
63  wxPoint gridPosition = GetGridPosition( aPosition );
64 
65  if( ( GetToolId() == ID_NO_TOOL_SELECTED ) || ( item && item->GetFlags() ) )
66  {
67  m_canvas->SetAutoPanRequest( false );
68  SetRepeatItem( NULL );
69 
70  if( item && item->GetFlags() )
71  {
72  switch( item->Type() )
73  {
74  case SCH_LABEL_T:
75  case SCH_GLOBAL_LABEL_T:
77  case SCH_TEXT_T:
78  case SCH_SHEET_PIN_T:
79  case SCH_SHEET_T:
82  case SCH_JUNCTION_T:
83  case SCH_COMPONENT_T:
84  case SCH_FIELD_T:
85  case SCH_BITMAP_T:
86  case SCH_NO_CONNECT_T:
88  return;
89 
90  case SCH_LINE_T: // May already be drawing segment.
91  break;
92 
93  default:
94  wxFAIL_MSG( wxT( "SCH_EDIT_FRAME::OnLeftClick error. Item type <" ) +
95  item->GetClass() + wxT( "> is already being edited." ) );
96  item->ClearFlags();
97  break;
98  }
99  }
100  else
101  {
102  item = LocateAndShowItem( aPosition );
103  }
104  }
105 
106  switch( GetToolId() )
107  {
108  case ID_NO_TOOL_SELECTED:
109  break;
110 
111  case ID_HIGHLIGHT:
112  HighlightConnectionAtPosition( aPosition );
113  break;
114 
116  if( ( item && item->GetFlags() ) || ( g_RootSheet->CountSheets() == 0 ) )
117  break;
118 
119  item = LocateAndShowItem( aPosition, SCH_COLLECTOR::SheetsOnly );
120 
121  if( item ) // The user has clicked on a sheet: this is an enter sheet command
122  {
123  m_CurrentSheet->push_back( (SCH_SHEET*) item );
125  }
126  else if( m_CurrentSheet->Last() != g_RootSheet )
127  { // The user has clicked ouside a sheet:this is an leave sheet command
128  m_CurrentSheet->pop_back();
130  }
131  break;
132 
133  case ID_NOCONN_BUTT:
134  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
135  {
136  if( GetScreen()->GetItem( gridPosition, 0, SCH_NO_CONNECT_T ) == NULL )
137  {
138  SCH_NO_CONNECT* no_connect = AddNoConnect( aDC, gridPosition );
139  SetRepeatItem( no_connect );
140  GetScreen()->SetCurItem( no_connect );
141  m_canvas->SetAutoPanRequest( true );
142  }
143  }
144  else
145  {
147  }
148  break;
149 
150  case ID_JUNCTION_BUTT:
151  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
152  {
153  if( GetScreen()->GetItem( gridPosition, 0, SCH_JUNCTION_T ) == NULL )
154  {
155  SCH_JUNCTION* junction = AddJunction( aDC, gridPosition, true );
156  SetRepeatItem( junction );
157  GetScreen()->SetCurItem( junction );
158  m_canvas->SetAutoPanRequest( true );
159  }
160  }
161  else
162  {
164  }
165  break;
166 
168  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
169  {
171  m_canvas->SetAutoPanRequest( true );
172  }
173  else
174  {
176  }
177  break;
178 
180  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
181  {
183  m_canvas->SetAutoPanRequest( true );
184  }
185  else
186  {
188  }
189  break;
190 
192  DeleteItemAtCrossHair( aDC );
193  break;
194 
195  case ID_WIRE_BUTT:
196  BeginSegment( aDC, LAYER_WIRE );
197  m_canvas->SetAutoPanRequest( true );
198  break;
199 
200  case ID_BUS_BUTT:
201  BeginSegment( aDC, LAYER_BUS );
202  m_canvas->SetAutoPanRequest( true );
203  break;
204 
206  BeginSegment( aDC, LAYER_NOTES );
207  m_canvas->SetAutoPanRequest( true );
208  break;
209 
211  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
212  {
214  m_canvas->SetAutoPanRequest( true );
215  }
216  else
217  {
219  }
220  break;
221 
222  case ID_ADD_IMAGE_BUTT:
223  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
224  {
225  GetScreen()->SetCurItem( CreateNewImage( aDC ) );
226  m_canvas->SetAutoPanRequest( true );
227  }
228  else
229  {
231  }
232  break;
233 
234  case ID_LABEL_BUTT:
235  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
236  {
238  m_canvas->SetAutoPanRequest( true );
239  }
240  else
241  {
243  }
244  break;
245 
246  case ID_GLABEL_BUTT:
247  case ID_HIERLABEL_BUTT:
248  if( (item == NULL) || (item->GetFlags() == 0) )
249  {
250  if( GetToolId() == ID_GLABEL_BUTT )
252 
253  if( GetToolId() == ID_HIERLABEL_BUTT )
255 
256  m_canvas->SetAutoPanRequest( true );
257  }
258  else
259  {
261  }
262  break;
263 
265  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
266  {
267  item = CreateSheet( aDC );
268 
269  if( item != NULL )
270  {
271  GetScreen()->SetCurItem( item );
272  m_canvas->SetAutoPanRequest( true );
273  }
274  }
275  else
276  {
278  }
279  break;
280 
282  case ID_SHEET_PIN_BUTT:
283  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
285 
286  if( item == NULL )
287  break;
288 
289  if( (item->Type() == SCH_SHEET_T) && (item->GetFlags() == 0) )
290  {
292  GetScreen()->SetCurItem( ImportSheetPin( (SCH_SHEET*) item, aDC ) );
293  else
294  GetScreen()->SetCurItem( CreateSheetPin( (SCH_SHEET*) item, aDC ) );
295  }
296  else if( (item->Type() == SCH_SHEET_PIN_T) && (item->GetFlags() != 0) )
297  {
299  }
300  break;
301 
303  if( (item == NULL) || (item->GetFlags() == 0) )
304  {
305  GetScreen()->SetCurItem( Load_Component( aDC, NULL,
306  s_CmpNameList, true ) );
307  m_canvas->SetAutoPanRequest( true );
308  }
309  else
310  {
312  }
313  break;
314 
315  case ID_PLACE_POWER_BUTT:
316  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
317  {
318  SCHLIB_FILTER filter;
319  filter.FilterPowerParts( true );
320  GetScreen()->SetCurItem( Load_Component( aDC, &filter,
321  s_PowerNameList, false ) );
322  m_canvas->SetAutoPanRequest( true );
323  }
324  else
325  {
327  }
328  break;
329 
330 #ifdef KICAD_SPICE
331  case ID_SIM_PROBE:
332  {
333  const KICAD_T wiresAndComponents[] = { SCH_LINE_T, SCH_COMPONENT_T, SCH_SHEET_PIN_T };
334  item = LocateAndShowItem( aPosition, wiresAndComponents );
335 
336  if( !item )
337  break;
338 
340 
341  for( NETLIST_OBJECT* obj : *netlist )
342  {
343  if( obj->m_Comp == item )
344  {
345  SIM_PLOT_FRAME* simFrame = (SIM_PLOT_FRAME*) Kiway().Player( FRAME_SIMULATOR, false );
346 
347  if( simFrame )
348  simFrame->AddVoltagePlot( obj->GetNetName() );
349 
350  break;
351  }
352  }
353  }
354  break;
355 
356  case ID_SIM_TUNE:
357  {
358  const KICAD_T fieldsAndComponents[] = { SCH_COMPONENT_T, SCH_FIELD_T };
359  item = LocateAndShowItem( aPosition, fieldsAndComponents );
360 
361  if( !item )
362  return;
363 
364  if( item->Type() != SCH_COMPONENT_T )
365  {
366  item = static_cast<SCH_ITEM*>( item->GetParent() );
367 
368  if( item->Type() != SCH_COMPONENT_T )
369  return;
370  }
371 
372  SIM_PLOT_FRAME* simFrame = (SIM_PLOT_FRAME*) Kiway().Player( FRAME_SIMULATOR, false );
373 
374  if( simFrame )
375  simFrame->AddTuner( static_cast<SCH_COMPONENT*>( item ) );
376  }
377  break;
378 #endif /* KICAD_SPICE */
379 
380  default:
382  wxFAIL_MSG( wxT( "SCH_EDIT_FRAME::OnLeftClick invalid tool ID <" ) +
383  wxString::Format( wxT( "%d> selected." ), GetToolId() ) );
384  }
385 }
386 
387 
396 void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition )
397 
398 {
399  EDA_ITEM* item = GetScreen()->GetCurItem();
400 
401  switch( GetToolId() )
402  {
403  case ID_NO_TOOL_SELECTED:
404  if( ( item == NULL ) || ( item->GetFlags() == 0 ) )
405  {
406  item = LocateAndShowItem( aPosition );
407  }
408 
409  if( ( item == NULL ) || ( item->GetFlags() != 0 ) )
410  break;
411 
412  switch( item->Type() )
413  {
414  case SCH_SHEET_T:
415  m_CurrentSheet->push_back( (SCH_SHEET*) item );
417  break;
418 
419  case SCH_COMPONENT_T:
420  EditComponent( (SCH_COMPONENT*) item );
422 
423  if( item->GetFlags() == 0 )
424  GetScreen()->SetCurItem( NULL );
425 
426  GetCanvas()->Refresh();
427  break;
428 
429  case SCH_TEXT_T:
430  case SCH_LABEL_T:
431  case SCH_GLOBAL_LABEL_T:
433  EditSchematicText( (SCH_TEXT*) item );
434  break;
435 
436  case SCH_BITMAP_T:
437  EditImage( (SCH_BITMAP*) item );
438  break;
439 
440  case SCH_FIELD_T:
443  break;
444 
445  case SCH_MARKER_T:
446  ( (SCH_MARKER*) item )->DisplayMarkerInfo( this );
447  break;
448 
449  default:
450  break;
451  }
452 
453  break;
454 
455  case ID_BUS_BUTT:
456  case ID_WIRE_BUTT:
458  if( item && item->IsNew() )
459  EndSegment( aDC );
460 
461  break;
462  }
463 }
Definition of the SCH_SHEET class for Eeschema.
SCH_NO_CONNECT * AddNoConnect(wxDC *aDC, const wxPoint &aPosition)
Function AddNoConnect add a no connect item to the current schematic sheet at aPosition.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
Class SCH_FIELD instances are attached to a component and provide a place for the component's value...
Definition: sch_field.h:56
void EditComponent(SCH_COMPONENT *aComponent)
Function EditComponent displays the edit component dialog to edit the parameters of aComponent...
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:255
static const KICAD_T SheetsAndSheetLabels[]
A scan list for schematic sheet and sheet label items.
NETLIST_OBJECT_LIST * BuildNetListBase(bool updateStatusText=true)
BuildNetListBase netlist generation: Creates a flat list which stores all connected objects...
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_player.h:60
SCH_JUNCTION * AddJunction(wxDC *aDC, const wxPoint &aPosition, bool aPutInUndoList=false)
Function AddJunction adds a new junction at aPosition.
void FilterPowerParts(bool aFilterEnable)
set the filtering of power parts
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Definition: draw_panel.cpp:326
This file is part of the common library.
bool IsNew() const
Definition: base_struct.h:216
wxPoint GetGridPosition(const wxPoint &aPosition) const
Function GetGridPosition returns the nearest grid position to aPosition if a screen is defined and sn...
Definition: draw_frame.cpp:556
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:299
int CountSheets()
Function CountSheets calculates the number of sheets found in "this" this number includes the full su...
Definition: sch_sheet.cpp:828
void addCurrentItemToList(bool aRedraw=true)
Function addCurrentItemToList adds the item currently being edited to the schematic and adds the chan...
Definition: schframe.cpp:1268
EDA_ITEM * GetParent() const
Definition: base_struct.h:208
std::vector< COMPONENT_SELECTION > HISTORY_LIST
void AddVoltagePlot(const wxString &aNetName)
Adds a voltage plot for a given net name.
void BeginSegment(wxDC *DC, int type)
Function BeginSegment creates a new segment ( WIRE, BUS ) or terminates the current segment in progre...
SCH_TEXT * CreateNewText(wxDC *aDC, int aType)
Definition: edit_label.cpp:66
void DisplayCurrentSheet()
Function DisplayCurrentSheet draws the current sheet on the display.
Definition: hierarch.cpp:279
void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Definition: draw_panel.cpp:348
void EditComponentFieldText(SCH_FIELD *aField)
Function EditComponentFieldText displays the edit field dialog to edit the parameters of aField...
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:90
void SetRepeatItem(SCH_ITEM *aItem)
Function SetRepeatItem clones aItem and owns that clone in this container.
Definition: schframe.cpp:459
Class NETLIST_OBJECT_LIST is a container holding and owning NETLIST_OBJECTs, which are connected item...
SCH_SHEET_PIN * CreateSheetPin(SCH_SHEET *aSheet, wxDC *aDC)
Function CreateSheetPin creates a new SCH_SHEET_PIN object and add it to aSheet at the current cursor...
Definition: sheetlab.cpp:110
SCH_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
Definition: schframe.cpp:520
void EndSegment(wxDC *DC)
Function EndSegment called to terminate a bus, wire, or line creation.
SCH_SHEET_PATH * m_CurrentSheet
which sheet we are presently working on.
Definition: schframe.h:120
SCH_BUS_BUS_ENTRY * CreateBusBusEntry()
Definition: busentry.cpp:42
SCH_ITEM * LocateAndShowItem(const wxPoint &aPosition, const KICAD_T aFilterList[]=SCH_COLLECTOR::AllItems, int aHotKeyCommandId=0)
Function LocateAndShowItem checks the schematic at aPosition in logical (drawing) units for a item ma...
static SCH_BASE_FRAME::HISTORY_LIST s_PowerNameList
SCH_SHEET * CreateSheet(wxDC *DC)
Definition: sheet.cpp:352
VTBL_ENTRY KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, KIWAY_PLAYER *aParent=NULL)
Function Player returns the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:302
SCH_SHEET * g_RootSheet
Definition: eeschema.cpp:54
bool HighlightConnectionAtPosition(wxPoint aPosition)
Function HighlightConnectionAtPosition Highlight the connection found at aPosition.
bool DeleteItemAtCrossHair(wxDC *aDC)
Function DeleteItemAtCrossHair delete the item found under the cross hair.
Definition: schedit.cpp:666
SCH_ITEM * GetCurItem() const
Function GetCurItem returns the currently selected SCH_ITEM, overriding BASE_SCREEN::GetCurItem().
static SCH_BASE_FRAME::HISTORY_LIST s_CmpNameList
void SetAutoPanRequest(bool aEnable)
virtual void SetToolID(int aId, int aCursor, const wxString &aToolMsg)
Function SetToolID sets the tool command ID to aId and sets the cursor to aCursor.
Definition: draw_frame.cpp:535
void EditSchematicText(SCH_TEXT *TextStruct)
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...
SCH_BITMAP * CreateNewImage(wxDC *aDC)
Implementing SIM_PLOT_FRAME_BASE.
Class SCH_SHEET is the sheet symbol placed in a schematic, and is the entry point for a sub schematic...
Definition: sch_sheet.h:216
Definition of the NETLIST_OBJECT class.
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:92
Definition the SCH_COMPONENT class for Eeschema.
SCH_COMPONENT * Load_Component(wxDC *aDC, const SCHLIB_FILTER *aFilter, SCH_BASE_FRAME::HISTORY_LIST &aHistoryList, bool aUseLibBrowser)
Function Load_Component loads from a library and places a component.
Definition: getpart.cpp:196
void OnLeftDClick(wxDC *aDC, const wxPoint &aPosition) override
Function OnLeftDClick called on a double click event from the drawpanel mouse handler if an editable ...
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
SCH_ITEM * GetItem(const wxPoint &aPosition, int aAccuracy=0, KICAD_T aType=NOT_USED) const
Function GetItem checks aPosition within a distance of aAccuracy for items of type aFilter...
Definition: sch_screen.cpp:203
void OnLeftClick(wxDC *aDC, const wxPoint &aPosition) override
int GetToolId() const
Definition: draw_frame.h:406
void SetCurItem(SCH_ITEM *aItem)
Function SetCurItem sets the currently selected object, m_CurrentItem.
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:68
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:151
static const KICAD_T SheetsOnly[]
A scan list for schematic sheet items only.
void EditImage(SCH_BITMAP *aItem)
virtual wxString GetClass() const override
Function GetClass returns the class name.
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:254
SCH_SHEET_PIN * ImportSheetPin(SCH_SHEET *aSheet, wxDC *aDC)
Function ImportSheetPin automatically creates a sheet pin from the hierarchical labels in the schemat...
Definition: sheetlab.cpp:140
Definition for part library class.
void AddTuner(SCH_COMPONENT *aComponent)
Adds a tuner for a component.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
SCH_BUS_WIRE_ENTRY * CreateBusWireEntry()
Definition: busentry.cpp:53
int GetDefaultCursor() const
Function GetDefaultCursor return the default cursor shape.
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
Implementation of the label properties dialog.