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 <class_drawpanel.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* clarificationMenuCancelled )
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  item = LocateItem( gridPosition, aFilterList, aHotKeyCommandId );
64 
65  // If the user aborted the clarification context menu, don't show it again at the
66  // off grid position.
67  if( !item && m_canvas->GetAbortRequest() )
68  {
69  if( clarificationMenuCancelled )
70  *clarificationMenuCancelled = true;
71 
72  m_canvas->SetAbortRequest( false );
73  return NULL;
74  }
75 
76  if( !item && (aPosition != gridPosition) )
77  item = LocateItem( aPosition, aFilterList, aHotKeyCommandId );
78 
79  if( !item )
80  {
81  if( clarificationMenuCancelled )
82  *clarificationMenuCancelled = m_canvas->GetAbortRequest();
83 
84  m_canvas->SetAbortRequest( false ); // Just in case the user aborted the context menu.
85  return NULL;
86  }
87 
88  // Cross probing to Pcbnew if a pin or a component is found
89  switch( item->Type() )
90  {
91  case SCH_FIELD_T:
92  case LIB_FIELD_T:
93  component = (SCH_COMPONENT*) item->GetParent();
94  SendMessageToPCBNEW( item, component );
95  break;
96 
97  case SCH_COMPONENT_T:
98  component = (SCH_COMPONENT*) item;
99  SendMessageToPCBNEW( item, component );
100  break;
101 
102  case LIB_PIN_T:
103  Pin = (LIB_PIN*) item;
104  component = (SCH_COMPONENT*) LocateItem( aPosition, SCH_COLLECTOR::ComponentsOnly );
105  break;
106 
107  /* case SCH_SHEET_T: */
108  /* // This may lag on larger projects */
109  /* SendMessageToPCBNEW( item, nullptr ); */
110  /* break; */
111  default:
112  ;
113  }
114 
115  if( Pin )
116  {
117  // Force display pin information (the previous display could be a component info)
118  MSG_PANEL_ITEMS items;
119 
120  Pin->GetMsgPanelInfo( items, component );
121 
122  SetMsgPanel( items );
123 
124  // Cross probing:2 - pin found, and send a locate pin command to Pcbnew (highlight net)
125  SendMessageToPCBNEW( Pin, component );
126  }
127 
128  return item;
129 }
130 
131 
132 SCH_ITEM* SCH_EDIT_FRAME::LocateItem( const wxPoint& aPosition, const KICAD_T aFilterList[],
133  int aHotKeyCommandId )
134 {
135  SCH_ITEM* item = NULL;
136 
137  m_collectedItems.Collect( GetScreen()->GetDrawItems(), aFilterList, aPosition );
138 
139  if( m_collectedItems.GetCount() == 0 )
140  {
141  ClearMsgPanel();
142  }
143  else if( m_collectedItems.GetCount() == 1 )
144  {
145  item = m_collectedItems[0];
146  }
147  else
148  {
149  // There are certain combinations of items that do not need clarification such as
150  // a corner were two lines meet or all the items form a junction.
151  if( aHotKeyCommandId )
152  {
153  switch( aHotKeyCommandId )
154  {
155  case HK_DRAG:
158  {
159  item = m_collectedItems[0];
160  }
161  break;
162 
164  if( m_collectedItems.GetCount() == 2 &&
165  dynamic_cast< SCH_SHEET_PIN * >( m_collectedItems[0] ) &&
166  dynamic_cast< SCH_SHEET * >( m_collectedItems[1] ) )
167  {
168  item = m_collectedItems[0];
169  }
170  break;
171 
172  default:
173  ;
174  }
175  }
176 
177  if( item == NULL )
178  {
179  wxASSERT_MSG( m_collectedItems.GetCount() <= MAX_SELECT_ITEM_IDS,
180  wxT( "Select item clarification context menu size limit exceeded." ) );
181 
182  wxMenu selectMenu;
183 
184  AddMenuItem( &selectMenu, wxID_NONE, _( "Clarify Selection" ),
185  KiBitmap( info_xpm ) );
186  selectMenu.AppendSeparator();
187 
188  for( int i = 0; i < m_collectedItems.GetCount() && i < MAX_SELECT_ITEM_IDS; i++ )
189  {
190  wxString text = m_collectedItems[i]->GetSelectMenuText();
191  BITMAP_DEF xpm = m_collectedItems[i]->GetMenuImage();
192  AddMenuItem( &selectMenu, ID_SELECT_ITEM_START + i, text, KiBitmap( xpm ) );
193  }
194 
195  // Set to NULL in case the user aborts the clarification context menu.
196  GetScreen()->SetCurItem( NULL );
197  m_canvas->SetAbortRequest( true ); // Changed to false if an item is selected
198  PopupMenu( &selectMenu );
199 
200  if( !m_canvas->GetAbortRequest() )
201  {
203  item = GetScreen()->GetCurItem();
204  }
205  }
206  }
207 
208  GetScreen()->SetCurItem( item );
209 
210  if( item )
211  {
212  if( item->Type() == SCH_COMPONENT_T )
213  ( (SCH_COMPONENT*) item )->SetCurrentSheetPath( &GetCurrentSheet() );
214 
215  MSG_PANEL_ITEMS items;
216  item->GetMsgPanelInfo( items );
217  SetMsgPanel( items );
218  }
219  else
220  {
221  ClearMsgPanel();
222  }
223 
224  return item;
225 }
226 
227 
228 bool SCH_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
229 {
230  // Filter out the 'fake' mouse motion after a keyboard movement
231  if( !aHotKey && m_movingCursorWithKeyboard )
232  {
234  return false;
235  }
236 
237  // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
238  // for next cursor position
239  // ( shift or ctrl key down are PAN command with mouse wheel)
240  bool snapToGrid = true;
241 
242  if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
243  snapToGrid = false;
244 
245  // Cursor is left off grid only if no block in progress
246  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
247  snapToGrid = true;
248 
249  wxPoint pos = aPosition;
250  wxPoint oldpos = GetCrossHairPosition();
251  bool keyHandled = GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
252 
253  // Update cursor position.
254  SetCrossHairPosition( pos, snapToGrid );
255  RefreshCrossHair( oldpos, aPosition, aDC );
256 
257  if( aHotKey )
258  {
259  SCH_SCREEN* screen = GetScreen();
260  bool hk_handled;
261 
262  if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
263  hk_handled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
264  else
265  hk_handled = OnHotKey( aDC, aHotKey, aPosition, NULL );
266 
267  if( hk_handled )
268  keyHandled = true;
269  }
270 
271  UpdateStatusBar(); /* Display cursor coordinates info */
272 
273  return keyHandled;
274 }
275 
276 
277 bool LIB_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
278 {
279  // Filter out the 'fake' mouse motion after a keyboard movement
280  if( !aHotKey && m_movingCursorWithKeyboard )
281  {
283  return false;
284  }
285 
286  // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
287  // for next cursor position
288  // ( shift or ctrl key down are PAN command with mouse wheel)
289  bool snapToGrid = true;
290 
291  if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
292  snapToGrid = false;
293 
294  // Cursor is left off grid only if no block in progress
295  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
296  snapToGrid = true;
297 
298  wxPoint pos = aPosition;
299  wxPoint oldpos = GetCrossHairPosition();
300  bool keyHandled = GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
301 
302  // Update the cursor position.
303  SetCrossHairPosition( pos, snapToGrid );
304  RefreshCrossHair( oldpos, aPosition, aDC );
305 
306  if( aHotKey && OnHotKey( aDC, aHotKey, aPosition, NULL ) )
307  {
308  keyHandled = true;
309  }
310 
311  // Make sure current-part highlighting doesn't get lost in seleciton highlighting
312  ClearSearchTreeSelection();
313 
314  UpdateStatusBar();
315 
316  return keyHandled;
317 }
318 
319 
320 bool LIB_VIEW_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
321 {
322  bool eventHandled = true;
323 
324  // Filter out the 'fake' mouse motion after a keyboard movement
325  if( !aHotKey && m_movingCursorWithKeyboard )
326  {
328  return false;
329  }
330 
331  wxPoint pos = aPosition;
332  wxPoint oldpos = GetCrossHairPosition();
333  GeneralControlKeyMovement( aHotKey, &pos, true );
334 
335  // Update cursor position.
336  SetCrossHairPosition( pos, true );
337  RefreshCrossHair( oldpos, aPosition, aDC );
338 
339  if( aHotKey )
340  {
341  SCH_SCREEN* screen = GetScreen();
342 
343  if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
344  eventHandled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
345  else
346  eventHandled = OnHotKey( aDC, aHotKey, aPosition, NULL );
347  }
348 
349  UpdateStatusBar(); // Display cursor coordinates info.
350 
351  return eventHandled;
352 }
Definition of the SCH_SHEET class for Eeschema.
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:107
KICAD_T Type() const
Function Type()
Definition: base_struct.h:227
bool OnHotKey(wxDC *aDC, int aHotKey, const wxPoint &aPosition, EDA_ITEM *aItem=NULL) override
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:284
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:41
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:174
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:237
static const KICAD_T ComponentsOnly[]
A scan list for schematic component items only.
SCH_ITEM * LocateAndShowItem(const wxPoint &aPosition, const KICAD_T aFilterList[]=SCH_COLLECTOR::AllItems, int aHotKeyCommandId=0, bool *clarifySelectionMenuCancelled=nullptr)
Check the schematic at aPosition in logical (drawing) units for a item matching the types in aFilterL...
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
Definition: lib_pin.cpp:1729
SCH_COLLECTOR m_collectedItems
List of collected items.
bool GeneralControl(wxDC *aDC, const wxPoint &aPosition, EDA_KEY aHotKey=0) override
Function GeneralControl performs application specific control using aDC at aPosition in logical units...
void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Definition: draw_panel.cpp:361
int GetState(int type) const
Definition: base_struct.h:266
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...
Definition: draw_frame.cpp:790
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:174
SCH_SHEET_PATH & GetCurrentSheet()
uint32_t EDA_KEY
Definition: common.h:52
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:61
virtual void GetMsgPanelInfo(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:306
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:93
bool GetAbortRequest() const
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.
void SetCurItem(SCH_ITEM *aItem)
Sets the currently selected object, m_CurrentItem.
Definition: sch_screen.h:182
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.
bool GeneralControl(wxDC *aDC, const wxPoint &aPosition, EDA_KEY aHotKey=0) override
Function GeneralControl performs application specific control using aDC at aPosition in logical units...
bool GeneralControl(wxDC *aDC, const wxPoint &aPosition, EDA_KEY aHotKey=0) override
Function GeneralControl performs application specific control using aDC at aPosition in logical units...
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.
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:142
void ClearMsgPanel(void)
Clear all messages from the message panel.
Definition: draw_frame.cpp:781