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 <schframe.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 <libeditframe.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 {
55  SCH_ITEM* item;
56  LIB_PIN* Pin = NULL;
57  SCH_COMPONENT* component = NULL;
58  wxPoint gridPosition = GetNearestGridPosition( aPosition );
59 
60  // Check the on grid position first. There is more likely to be multiple items on
61  // grid than off grid.
62  item = LocateItem( gridPosition, aFilterList, aHotKeyCommandId );
63 
64  // If the user aborted the clarification context menu, don't show it again at the
65  // off grid position.
66  if( !item && m_canvas->GetAbortRequest() )
67  {
68  m_canvas->SetAbortRequest( false );
69  return NULL;
70  }
71 
72  if( !item && (aPosition != gridPosition) )
73  item = LocateItem( aPosition, aFilterList, aHotKeyCommandId );
74 
75  if( !item )
76  {
77  m_canvas->SetAbortRequest( false ); // Just in case the user aborted the context menu.
78  return NULL;
79  }
80 
81  // Cross probing to Pcbnew if a pin or a component is found
82  switch( item->Type() )
83  {
84  case SCH_FIELD_T:
85  case LIB_FIELD_T:
86  component = (SCH_COMPONENT*) item->GetParent();
87  SendMessageToPCBNEW( item, component );
88  break;
89 
90  case SCH_SHEET_T:
91  SendMessageToPCBNEW( item, nullptr );
92  break;
93 
94  case SCH_COMPONENT_T:
95  component = (SCH_COMPONENT*) item;
96  SendMessageToPCBNEW( item, component );
97  break;
98 
99  case LIB_PIN_T:
100  Pin = (LIB_PIN*) item;
101  component = (SCH_COMPONENT*) LocateItem( aPosition, SCH_COLLECTOR::ComponentsOnly );
102  break;
103 
104  default:
105  ;
106  }
107 
108  if( Pin )
109  {
110  // Force display pin information (the previous display could be a component info)
111  MSG_PANEL_ITEMS items;
112 
113  Pin->GetMsgPanelInfo( items, component );
114 
115  SetMsgPanel( items );
116 
117  // Cross probing:2 - pin found, and send a locate pin command to Pcbnew (highlight net)
118  SendMessageToPCBNEW( Pin, component );
119  }
120 
121  return item;
122 }
123 
124 
125 SCH_ITEM* SCH_EDIT_FRAME::LocateItem( const wxPoint& aPosition, const KICAD_T aFilterList[],
126  int aHotKeyCommandId )
127 {
128  SCH_ITEM* item = NULL;
129 
130  m_collectedItems.Collect( GetScreen()->GetDrawItems(), aFilterList, aPosition );
131 
132  if( m_collectedItems.GetCount() == 0 )
133  {
134  ClearMsgPanel();
135  }
136  else if( m_collectedItems.GetCount() == 1 )
137  {
138  item = m_collectedItems[0];
139  }
140  else
141  {
142  // There are certain combinations of items that do not need clarification such as
143  // a corner were two lines meet or all the items form a junction.
144  if( aHotKeyCommandId )
145  {
146  switch( aHotKeyCommandId )
147  {
148  case HK_DRAG:
151  {
152  item = m_collectedItems[0];
153  }
154  break;
155 
157  if( m_collectedItems.GetCount() == 2 &&
158  dynamic_cast< SCH_SHEET_PIN * >( m_collectedItems[0] ) &&
159  dynamic_cast< SCH_SHEET * >( m_collectedItems[1] ) )
160  {
161  item = m_collectedItems[0];
162  }
163  break;
164 
165  default:
166  ;
167  }
168  }
169 
170  if( item == NULL )
171  {
172  wxASSERT_MSG( m_collectedItems.GetCount() <= MAX_SELECT_ITEM_IDS,
173  wxT( "Select item clarification context menu size limit exceeded." ) );
174 
175  wxMenu selectMenu;
176 
177  AddMenuItem( &selectMenu, wxID_NONE, _( "Clarify Selection" ),
178  KiBitmap( info_xpm ) );
179  selectMenu.AppendSeparator();
180 
181  for( int i = 0; i < m_collectedItems.GetCount() && i < MAX_SELECT_ITEM_IDS; i++ )
182  {
183  wxString text = m_collectedItems[i]->GetSelectMenuText();
184  BITMAP_DEF xpm = m_collectedItems[i]->GetMenuImage();
185  AddMenuItem( &selectMenu, ID_SELECT_ITEM_START + i, text, KiBitmap( xpm ) );
186  }
187 
188  // Set to NULL in case the user aborts the clarification context menu.
189  GetScreen()->SetCurItem( NULL );
190  m_canvas->SetAbortRequest( true ); // Changed to false if an item is selected
191  PopupMenu( &selectMenu );
193  item = GetScreen()->GetCurItem();
194  }
195  }
196 
197  GetScreen()->SetCurItem( item );
198 
199  if( item )
200  {
201  if( item->Type() == SCH_COMPONENT_T )
202  ( (SCH_COMPONENT*) item )->SetCurrentSheetPath( &GetCurrentSheet() );
203 
204  MSG_PANEL_ITEMS items;
205  item->GetMsgPanelInfo( items );
206  SetMsgPanel( items );
207  }
208  else
209  {
210  ClearMsgPanel();
211  }
212 
213  return item;
214 }
215 
216 
217 bool SCH_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
218 {
219  bool eventHandled = true;
220 
221  // Filter out the 'fake' mouse motion after a keyboard movement
222  if( !aHotKey && m_movingCursorWithKeyboard )
223  {
225  return false;
226  }
227 
228  // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
229  // for next cursor position
230  // ( shift or ctrl key down are PAN command with mouse wheel)
231  bool snapToGrid = true;
232 
233  if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
234  snapToGrid = false;
235 
236  // Cursor is left off grid only if no block in progress
237  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
238  snapToGrid = true;
239 
240  wxPoint pos = aPosition;
241  wxPoint oldpos = GetCrossHairPosition();
242  GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
243 
244  // Update cursor position.
245  SetCrossHairPosition( pos, snapToGrid );
246  RefreshCrossHair( oldpos, aPosition, aDC );
247 
248  if( aHotKey )
249  {
250  SCH_SCREEN* screen = GetScreen();
251 
252  if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
253  eventHandled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
254  else
255  eventHandled = OnHotKey( aDC, aHotKey, aPosition, NULL );
256  }
257 
258  UpdateStatusBar(); /* Display cursor coordinates info */
259 
260  return eventHandled;
261 }
262 
263 
264 bool LIB_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
265 {
266  bool eventHandled = true;
267 
268  // Filter out the 'fake' mouse motion after a keyboard movement
269  if( !aHotKey && m_movingCursorWithKeyboard )
270  {
272  return false;
273  }
274 
275  // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
276  // for next cursor position
277  // ( shift or ctrl key down are PAN command with mouse wheel)
278  bool snapToGrid = true;
279 
280  if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
281  snapToGrid = false;
282 
283  // Cursor is left off grid only if no block in progress
284  if( GetScreen()->m_BlockLocate.GetState() != STATE_NO_BLOCK )
285  snapToGrid = true;
286 
287  wxPoint pos = aPosition;
288  wxPoint oldpos = GetCrossHairPosition();
289  GeneralControlKeyMovement( aHotKey, &pos, snapToGrid );
290 
291  // Update the cursor position.
292  SetCrossHairPosition( pos, snapToGrid );
293  RefreshCrossHair( oldpos, aPosition, aDC );
294 
295  if( aHotKey )
296  {
297  eventHandled = OnHotKey( aDC, aHotKey, aPosition, NULL );
298  }
299 
300  UpdateStatusBar();
301 
302  return eventHandled;
303 }
304 
305 
306 bool LIB_VIEW_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey )
307 {
308  bool eventHandled = true;
309 
310  // Filter out the 'fake' mouse motion after a keyboard movement
311  if( !aHotKey && m_movingCursorWithKeyboard )
312  {
314  return false;
315  }
316 
317  wxPoint pos = aPosition;
318  wxPoint oldpos = GetCrossHairPosition();
319  GeneralControlKeyMovement( aHotKey, &pos, true );
320 
321  // Update cursor position.
322  SetCrossHairPosition( pos, true );
323  RefreshCrossHair( oldpos, aPosition, aDC );
324 
325  if( aHotKey )
326  {
327  SCH_SCREEN* screen = GetScreen();
328 
329  if( screen->GetCurItem() && screen->GetCurItem()->GetFlags() )
330  eventHandled = OnHotKey( aDC, aHotKey, aPosition, screen->GetCurItem() );
331  else
332  eventHandled = OnHotKey( aDC, aHotKey, aPosition, NULL );
333  }
334 
335  UpdateStatusBar(); // Display cursor coordinates info.
336 
337  return eventHandled;
338 }
Definition of the SCH_SHEET class for Eeschema.
int GetCount() const
Function GetCount returns the number of objects in the list.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:198
bool OnHotKey(wxDC *aDC, int aHotKey, const wxPoint &aPosition, EDA_ITEM *aItem=NULL) override
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:255
DDE server & client.
bool OnHotKey(wxDC *aDC, int aHotKey, const wxPoint &aPosition, EDA_ITEM *aItem=NULL) override
PNG memory record (file in memory).
Definition: bitmap_types.h:38
#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:55
SCH_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
void Collect(SCH_ITEM *aItem, const KICAD_T aFilterList[], const wxPoint &aPosition)
Function Collect scans a SCH_ITEM using this class'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.
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo displays basic info (type, part and convert) about the current item in messa...
Definition: lib_pin.cpp:2117
SCH_COLLECTOR m_collectedItems
List of collected items.
Definition: schframe.h:142
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:348
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)
Function LocateItem checks 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:90
SCH_SCREEN * GetScreen() const override
Function GetScreen returns a pointer to a BASE_SCREEN or one of its derivatives.
Definition: schframe.cpp:521
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Function KiBitmap constructs a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:36
void SendMessageToPCBNEW(EDA_ITEM *aObjectToSync, SCH_COMPONENT *aPart)
Function SendMessageToPcbnew send a remote to Pcbnew via a socket connection.
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...
bool IsDraggableJunction() const
Function IsDraggableJunction tests to see if the collected items form a draggable junction...
bool OnHotKey(wxDC *aDC, int aHotKey, const wxPoint &aPosition, EDA_ITEM *aItem=NULL) override
Function OnHotKey handle hot key events.
void RefreshCrossHair(const wxPoint &aOldPos, const wxPoint &aEvtPos, wxDC *aDC)
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:773
bool IsCorner() const
Function IsCorner tests if the collected items forms as corner of two line segments.
SCH_ITEM * GetCurItem() const
Function GetCurItem returns the currently selected SCH_ITEM, overriding BASE_SCREEN::GetCurItem().
SCH_SHEET_PATH & GetCurrentSheet()
Definition: schframe.cpp:566
uint32_t EDA_KEY
Definition: common.h:52
Class SCH_SHEET_PIN defines a sheet pin (label) used in sheets to create hierarchical schematics...
Definition: sch_sheet.h:62
virtual void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList)
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: base_struct.h:277
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:92
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 GeneralControlKeyMovement(int aHotKey, wxPoint *aPos, bool aSnapToGrid)
Function GeneralControlKeyMovement Handle the common part of GeneralControl dedicated to global curso...
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:69
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:102
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:138
void ClearMsgPanel(void)
Clear all messages from the message panel.
Definition: draw_frame.cpp:764
Definition of class LIB_EDIT_FRAME.