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* 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( 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 combinations of items that do not need clarification such as
151  // a corner were two lines meet or all the items form a junction.
152  if( aHotKeyCommandId )
153  {
154  switch( aHotKeyCommandId )
155  {
156  case HK_DRAG:
159  {
160  item = m_collectedItems[0];
161  }
162  break;
163 
165  if( m_collectedItems.GetCount() == 2 &&
166  dynamic_cast< SCH_SHEET_PIN * >( m_collectedItems[0] ) &&
167  dynamic_cast< SCH_SHEET * >( m_collectedItems[1] ) )
168  {
169  item = m_collectedItems[0];
170  }
171  break;
172 
173  default:
174  ;
175  }
176  }
177 
178  if( item == NULL )
179  {
180  wxASSERT_MSG( m_collectedItems.GetCount() <= MAX_SELECT_ITEM_IDS,
181  wxT( "Select item clarification context menu size limit exceeded." ) );
182 
183  wxMenu selectMenu;
184 
185  AddMenuItem( &selectMenu, wxID_NONE, _( "Clarify Selection" ),
186  KiBitmap( info_xpm ) );
187  selectMenu.AppendSeparator();
188 
189  for( int i = 0; i < m_collectedItems.GetCount() && i < MAX_SELECT_ITEM_IDS; i++ )
190  {
191  wxString text = m_collectedItems[i]->GetSelectMenuText();
192  BITMAP_DEF xpm = m_collectedItems[i]->GetMenuImage();
193  AddMenuItem( &selectMenu, ID_SELECT_ITEM_START + i, text, KiBitmap( xpm ) );
194  }
195 
196  // Set to NULL in case the user aborts the clarification context menu.
197  GetScreen()->SetCurItem( NULL );
198  m_canvas->SetAbortRequest( true ); // Changed to false if an item is selected
199  PopupMenu( &selectMenu );
200 
201  if( !m_canvas->GetAbortRequest() )
202  {
204  item = GetScreen()->GetCurItem();
205  }
206  }
207  }
208 
209  GetScreen()->SetCurItem( item );
210 
211  if( item )
212  {
213  if( item->Type() == SCH_COMPONENT_T )
214  ( (SCH_COMPONENT*) item )->SetCurrentSheetPath( &GetCurrentSheet() );
215 
216  MSG_PANEL_ITEMS items;
217  item->GetMsgPanelInfo( items );
218  SetMsgPanel( items );
219  }
220  else
221  {
222  ClearMsgPanel();
223  }
224 
225  return item;
226 }
227 
228 
229 bool SCH_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
230 {
231  // Filter out the 'fake' mouse motion after a keyboard movement
232  if( !aHotKey && m_movingCursorWithKeyboard )
233  {
235  return false;
236  }
237 
238  // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
239  // for next cursor position
240  // ( shift or ctrl key down are PAN command with mouse wheel)
241  bool snapToGrid = true;
242 
243  if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
244  snapToGrid = false;
245 
246  // Cursor is left off grid only if no block in progress
247  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
248  snapToGrid = true;
249 
250  wxPoint pos = aPosition;
251  wxPoint oldpos = GetCrossHairPosition();
252  bool keyHandled = GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
253 
254  // Update cursor position.
255  SetCrossHairPosition( pos, snapToGrid );
256  RefreshCrossHair( oldpos, aPosition, aDC );
257 
258  if( aHotKey )
259  {
260  SCH_SCREEN* screen = GetScreen();
261  bool hk_handled;
262 
263  if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
264  hk_handled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
265  else
266  hk_handled = OnHotKey( aDC, aHotKey, aPosition, NULL );
267 
268  if( hk_handled )
269  keyHandled = true;
270  }
271 
272  UpdateStatusBar(); /* Display cursor coordinates info */
273 
274  return keyHandled;
275 }
276 
277 
278 bool LIB_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
279 {
280  // Filter out the 'fake' mouse motion after a keyboard movement
281  if( !aHotKey && m_movingCursorWithKeyboard )
282  {
284  return false;
285  }
286 
287  // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
288  // for next cursor position
289  // ( shift or ctrl key down are PAN command with mouse wheel)
290  bool snapToGrid = true;
291 
292  if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
293  snapToGrid = false;
294 
295  // Cursor is left off grid only if no block in progress
296  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
297  snapToGrid = true;
298 
299  wxPoint pos = aPosition;
300  wxPoint oldpos = GetCrossHairPosition();
301  bool keyHandled = GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
302 
303  // Update the cursor position.
304  SetCrossHairPosition( pos, snapToGrid );
305  RefreshCrossHair( oldpos, aPosition, aDC );
306 
307  if( aHotKey && OnHotKey( aDC, aHotKey, aPosition, NULL ) )
308  {
309  keyHandled = true;
310  }
311 
312  // Make sure current-part highlighting doesn't get lost in seleciton highlighting
313  ClearSearchTreeSelection();
314 
315  UpdateStatusBar();
316 
317  return keyHandled;
318 }
319 
320 
321 bool LIB_VIEW_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
322 {
323  bool eventHandled = true;
324 
325  // Filter out the 'fake' mouse motion after a keyboard movement
326  if( !aHotKey && m_movingCursorWithKeyboard )
327  {
329  return false;
330  }
331 
332  wxPoint pos = aPosition;
333  wxPoint oldpos = GetCrossHairPosition();
334  GeneralControlKeyMovement( aHotKey, &pos, true );
335 
336  // Update cursor position.
337  SetCrossHairPosition( pos, true );
338  RefreshCrossHair( oldpos, aPosition, aDC );
339 
340  if( aHotKey )
341  {
342  SCH_SCREEN* screen = GetScreen();
343 
344  if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
345  eventHandled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
346  else
347  eventHandled = OnHotKey( aDC, aHotKey, aPosition, NULL );
348  }
349 
350  UpdateStatusBar(); // Display cursor coordinates info.
351 
352  return eventHandled;
353 }
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:209
bool OnHotKey(wxDC *aDC, int aHotKey, const wxPoint &aPosition, EDA_ITEM *aItem=NULL) override
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:266
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:219
static const KICAD_T ComponentsOnly[]
A scan list for schematic component items only.
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:1734
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:360
int GetState(int type) const
Definition: base_struct.h:248
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:831
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
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...
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:288
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:106
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
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.
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:159
void ClearMsgPanel(void)
Clear all messages from the message panel.
Definition: draw_frame.cpp:822