KiCad PCB EDA Suite
eeschema/controle.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, jaen-pierre.charras@gipsa-lab.inpg.com
5  * Copyright (C) 2008-2011 Wayne Stambaugh <stambaughw@verizon.net>
6  * Copyright (C) 2004-2016 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 <gr_basic.h>
32 #include <sch_draw_panel.h>
33 #include <eda_dde.h>
34 #include <sch_edit_frame.h>
35 #include <menus_helpers.h>
36 #include <msgpanel.h>
37 #include <bitmaps.h>
38 
39 #include <eeschema_id.h>
40 #include <general.h>
41 #include <hotkeys.h>
42 #include <lib_edit_frame.h>
43 #include <viewlib_frame.h>
44 #include <lib_draw_item.h>
45 #include <lib_pin.h>
46 #include <sch_sheet.h>
47 #include <sch_sheet_path.h>
48 #include <sch_marker.h>
49 #include <sch_component.h>
50 
51 
52 SCH_ITEM* SCH_EDIT_FRAME::LocateAndShowItem( const wxPoint& aPosition, const KICAD_T aFilterList[],
53  int aHotKeyCommandId,
54  bool* aClarificationMenuCancelled )
55 {
56  SCH_ITEM* item;
57  LIB_PIN* Pin = NULL;
58  SCH_COMPONENT* component = NULL;
59  wxPoint gridPosition = GetNearestGridPosition( aPosition );
60 
61  // Check the on grid position first. There is more likely to be multiple items on
62  // grid than off grid.
63  m_canvas->SetAbortRequest( false ); // be sure a old abort request in not pending
64  item = LocateItem( gridPosition, aFilterList, aHotKeyCommandId );
65 
66  // If the user aborted the clarification context menu, don't show it again at the
67  // off grid position.
68  if( !item && m_canvas->GetAbortRequest() )
69  {
70  if( aClarificationMenuCancelled )
71  *aClarificationMenuCancelled = true;
72 
73  m_canvas->SetAbortRequest( false );
74  return NULL;
75  }
76 
77  if( !item && (aPosition != gridPosition) )
78  item = LocateItem( aPosition, aFilterList, aHotKeyCommandId );
79 
80  if( !item )
81  {
82  if( aClarificationMenuCancelled )
83  *aClarificationMenuCancelled = m_canvas->GetAbortRequest();
84 
85  m_canvas->SetAbortRequest( false ); // Just in case the user aborted the context menu.
86  return NULL;
87  }
88 
89  // Cross probing to Pcbnew if a pin or a component is found
90  switch( item->Type() )
91  {
92  case SCH_FIELD_T:
93  case LIB_FIELD_T:
94  component = (SCH_COMPONENT*) item->GetParent();
95  SendMessageToPCBNEW( item, component );
96  break;
97 
98  case SCH_COMPONENT_T:
99  component = (SCH_COMPONENT*) item;
100  SendMessageToPCBNEW( item, component );
101  break;
102 
103  case LIB_PIN_T:
104  Pin = (LIB_PIN*) item;
105  component = (SCH_COMPONENT*) LocateItem( aPosition, SCH_COLLECTOR::ComponentsOnly );
106  break;
107 
108  /* case SCH_SHEET_T: */
109  /* // This may lag on larger projects */
110  /* SendMessageToPCBNEW( item, nullptr ); */
111  /* break; */
112  default:
113  ;
114  }
115 
116  if( Pin )
117  {
118  // Force display pin information (the previous display could be a component info)
119  MSG_PANEL_ITEMS items;
120 
121  Pin->GetMsgPanelInfo( m_UserUnits, items, component );
122 
123  SetMsgPanel( items );
124 
125  // Cross probing:2 - pin found, and send a locate pin command to Pcbnew (highlight net)
126  SendMessageToPCBNEW( Pin, component );
127  }
128 
129  return item;
130 }
131 
132 
133 SCH_ITEM* SCH_EDIT_FRAME::LocateItem( const wxPoint& aPosition, const KICAD_T aFilterList[],
134  int aHotKeyCommandId )
135 {
136  SCH_ITEM* item = NULL;
137 
138  m_collectedItems.Collect( GetScreen()->GetDrawItems(), aFilterList, aPosition );
139 
140  if( m_collectedItems.GetCount() == 0 )
141  {
142  ClearMsgPanel();
143  }
144  else if( m_collectedItems.GetCount() == 1 )
145  {
146  item = m_collectedItems[0];
147  }
148  else
149  {
150  // There are certain parent/child and enclosure combinations that can be handled
151  // automatically. Since schematics are meant to be human-readable we don't have
152  // all the various overlap and coverage issues that we do in Pcbnew.
153  if( m_collectedItems.GetCount() == 2 )
154  {
155  SCH_ITEM* a = m_collectedItems[ 0 ];
156  SCH_ITEM* b = m_collectedItems[ 1 ];
157 
158  if( a->GetParent() == b )
159  item = a;
160  else if( a == b->GetParent() )
161  item = b;
162  else if( a->Type() == SCH_SHEET_T && b->Type() != SCH_SHEET_T )
163  item = b;
164  else if( b->Type() == SCH_SHEET_T && a->Type() != SCH_SHEET_T )
165  item = a;
166  }
167 
168  // There are certain combinations of items that do not need clarification such as
169  // a corner were two lines meet or all the items form a junction.
170  if( aHotKeyCommandId )
171  {
172  switch( aHotKeyCommandId )
173  {
174  case HK_DRAG:
177  {
178  item = m_collectedItems[0];
179  }
180  break;
181 
183  if( m_collectedItems.GetCount() == 2 &&
184  dynamic_cast< SCH_SHEET_PIN * >( m_collectedItems[0] ) &&
185  dynamic_cast< SCH_SHEET * >( m_collectedItems[1] ) )
186  {
187  item = m_collectedItems[0];
188  }
189  break;
190 
191  default:
192  ;
193  }
194  }
195 
196  if( item == NULL )
197  {
198  wxASSERT_MSG( m_collectedItems.GetCount() <= MAX_SELECT_ITEM_IDS,
199  wxT( "Select item clarification context menu size limit exceeded." ) );
200 
201  wxMenu selectMenu;
202 
203  AddMenuItem( &selectMenu, wxID_NONE, _( "Clarify Selection" ), KiBitmap( info_xpm ) );
204  selectMenu.AppendSeparator();
205 
206  for( int i = 0; i < m_collectedItems.GetCount() && i < MAX_SELECT_ITEM_IDS; i++ )
207  {
208  wxString text = m_collectedItems[i]->GetSelectMenuText( m_UserUnits );
209  BITMAP_DEF xpm = m_collectedItems[i]->GetMenuImage();
210  AddMenuItem( &selectMenu, ID_SELECT_ITEM_START + i, text, KiBitmap( xpm ) );
211  }
212 
213  // Set to NULL in case the user aborts the clarification context menu.
214  GetScreen()->SetCurItem( NULL );
215  m_canvas->SetAbortRequest( true ); // Changed to false if an item is selected
216  PopupMenu( &selectMenu );
217 
218  if( !m_canvas->GetAbortRequest() )
219  {
221  item = GetScreen()->GetCurItem();
222  }
223  }
224  }
225 
226  GetScreen()->SetCurItem( item );
227 
228  if( item )
229  {
230  if( item->Type() == SCH_COMPONENT_T )
231  ( (SCH_COMPONENT*) item )->SetCurrentSheetPath( &GetCurrentSheet() );
232 
233  MSG_PANEL_ITEMS items;
234  item->GetMsgPanelInfo( m_UserUnits, items );
235  SetMsgPanel( items );
236  }
237  else
238  {
239  ClearMsgPanel();
240  }
241 
242  return item;
243 }
244 
245 
246 bool SCH_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
247 {
248  // Filter out the 'fake' mouse motion after a keyboard movement
249  if( !aHotKey && m_movingCursorWithKeyboard )
250  {
252  return false;
253  }
254 
255 
256  // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
257  // for next cursor position
258  // ( shift or ctrl key down are PAN command with mouse wheel)
259  bool snapToGrid = true;
260 
261  if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
262  snapToGrid = false;
263 
264  // Cursor is left off grid only if no block in progress
265  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
266  snapToGrid = true;
267 
268  wxPoint pos = aPosition;
269  bool keyHandled = GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
270 
271  if( GetToolId() == ID_NO_TOOL_SELECTED )
272  m_canvas->CrossHairOff( aDC );
273  else
274  m_canvas->CrossHairOn( aDC );
275 
276  SetCrossHairPosition( pos, snapToGrid );
277 
278  if( m_canvas->IsMouseCaptured() )
279  m_canvas->CallMouseCapture( aDC, aPosition, true );
280 
281  if( aHotKey )
282  {
283  SCH_SCREEN* screen = GetScreen();
284  bool hk_handled;
285 
286  if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
287  hk_handled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
288  else
289  hk_handled = OnHotKey( aDC, aHotKey, aPosition, NULL );
290 
291  if( hk_handled )
292  keyHandled = true;
293  }
294 
295  UpdateStatusBar(); /* Display cursor coordinates info */
296 
297  return keyHandled;
298 }
299 
300 
301 
302 bool LIB_VIEW_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
303 {
304  bool eventHandled = true;
305 
306  // Filter out the 'fake' mouse motion after a keyboard movement
307  if( !aHotKey && m_movingCursorWithKeyboard )
308  {
310  return false;
311  }
312 
313  wxPoint pos = aPosition;
314  wxPoint oldpos = GetCrossHairPosition();
315  GeneralControlKeyMovement( aHotKey, &pos, true );
316 
317  // Update cursor position.
318  SetCrossHairPosition( pos, true );
319  RefreshCrossHair( oldpos, aPosition, aDC );
320 
321  if( aHotKey )
322  {
323  SCH_SCREEN* screen = GetScreen();
324 
325  if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
326  eventHandled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
327  else
328  eventHandled = OnHotKey( aDC, aHotKey, aPosition, NULL );
329  }
330 
331  UpdateStatusBar(); // Display cursor coordinates info.
332 
333  return eventHandled;
334 }
Definition of the SCH_SHEET class for Eeschema.
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:106
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:255
DDE server & client.
PNG memory record (file in memory).
Definition: bitmap_types.h:41
#define MAX_SELECT_ITEM_IDS
The maximum number of items in the clarify selection context menu.
Definition: eeschema_id.h:42
bool GeneralControl(wxDC *aDC, const wxPoint &aPosition, EDA_KEY aHotKey) override
Function GeneralControl performs application specific control using aDC at aPosition in logical units...
wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmap &aImage, wxItemKind aType=wxITEM_NORMAL)
Function AddMenuItem is an inline helper function to create and insert a menu item with an icon into ...
Definition: bitmap.cpp:194
bool OnHotKey(wxDC *aDC, int aHotKey, const wxPoint &aPosition, EDA_ITEM *aItem) override
void Collect(SCH_ITEM *aItem, const KICAD_T aFilterList[], const wxPoint &aPosition)
Function Collect scans a SCH_ITEM using this class&#39;s Inspector method, which does the collection...
EDA_ITEM * GetParent() const
Definition: base_struct.h:208
static const KICAD_T ComponentsOnly[]
A scan list for schematic component items only.
SCH_COLLECTOR m_collectedItems
List of collected items.
virtual void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
int GetState(int type) const
Definition: base_struct.h:237
SCH_ITEM * LocateItem(const wxPoint &aPosition, const KICAD_T aFilterList[]=SCH_COLLECTOR::AllItems, int aHotKeyCommandId=0)
Check for items at aPosition matching the types in aFilterList.
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
bool GeneralControlKeyMovement(int aHotKey, wxPoint *aPos, bool aSnapToGrid)
Function GeneralControlKeyMovement Handle the common part of GeneralControl dedicated to global curso...
SCH_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Function KiBitmap constructs a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:78
void SendMessageToPCBNEW(EDA_ITEM *aObjectToSync, SCH_COMPONENT *aPart)
Send a message to Pcbnew via a socket connection.
bool IsDraggableJunction() const
Function IsDraggableJunction tests to see if the collected items form a draggable junction...
void RefreshCrossHair(const wxPoint &aOldPos, const wxPoint &aEvtPos, wxDC *aDC)
Move and refresh the crosshair after movement and call the mouse capture function.
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Function SetMsgPanel clears the message panel and populates it with the contents of aList...
bool IsCorner() const
Function IsCorner tests if the collected items forms as corner of two line segments.
SCH_ITEM * GetCurItem() const
Return the currently selected SCH_ITEM, overriding BASE_SCREEN::GetCurItem().
Definition: sch_screen.h:196
virtual void CrossHairOn(wxDC *DC=nullptr)
SCH_SHEET_PATH & GetCurrentSheet()
virtual void CallMouseCapture(wxDC *aDC, const wxPoint &aPosition, bool aErase)
Function CallMouseCapture calls the mouse capture callback.
virtual void CrossHairOff(wxDC *DC=nullptr)
uint32_t EDA_KEY
Definition: common.h:73
void GetMsgPanelInfo(EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:61
virtual void GetMsgPanelInfo(EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM > &aList)
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it&#39;s internal state for displ...
Definition: base_struct.h:294
SCH_ITEM * LocateAndShowItem(const wxPoint &aPosition, const KICAD_T aFilterList[]=SCH_COLLECTOR::AllItems, int aHotKeyCommandId=0, bool *aClarifySelectionMenuCancelled=nullptr)
Check the schematic at aPosition in logical (drawing) units for a item matching the types in aFilterL...
void SetAbortRequest(bool aAbortRequest)
void UpdateStatusBar() override
Function UpdateStatusBar updates the status bar information.
bool IsNode(bool aIncludePins=true) const
Function IsNode tests if the collected items form a node.
EDA_DRAW_PANEL * m_canvas
The area to draw on.
Definition: draw_frame.h:108
Definition the SCH_COMPONENT class for Eeschema.
wxPoint GetNearestGridPosition(const wxPoint &aPosition, wxRealPoint *aGridSize=NULL) const
Function GetNearestGridPosition returns the nearest aGridSize location to aPosition.
int GetToolId() const
Definition: draw_frame.h:512
void SetCurItem(SCH_ITEM *aItem)
Sets the currently selected object, m_CurrentItem.
Definition: sch_screen.h:204
size_t i
Definition: json11.cpp:597
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:102
Definition of class LIB_EDIT_FRAME.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
void SetCrossHairPosition(const wxPoint &aPosition, bool aSnapToGrid=true)
Function SetCrossHairPosition sets the screen cross hair position to aPosition in logical (drawing) u...
Message panel definition file.
EDA_UNITS_T m_UserUnits
Definition: draw_frame.h:105
wxPoint GetCrossHairPosition(bool aInvertY=false) const
Function GetCrossHairPosition return the current cross hair position in logical (drawing) coordinates...
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
bool m_movingCursorWithKeyboard
One-shot to avoid a recursive mouse event during hotkey movement.
Definition: draw_frame.h:158
void ClearMsgPanel(void)
Clear all messages from the message panel.
bool GeneralControl(wxDC *aDC, const wxPoint &aPosition, EDA_KEY aHotKey) override
Function GeneralControl performs application specific control using aDC at aPosition in logical units...