KiCad PCB EDA Suite
gerbview_inspection_tool.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) 2017 Jon Evans <jon@craftyjon.com>
5  * Copyright (C) 2017-2020 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 
22 #include <eda_item.h>
23 #include <bitmaps.h>
24 #include <class_draw_panel_gal.h>
26 #include <gestfich.h>
27 #include <gerber_file_image.h>
28 #include <gerbview_id.h>
30 #include "gerbview_actions.h"
31 #include <painter.h>
34 #include <tool/tool_event.h>
35 #include <tool/tool_manager.h>
36 #include <view/view.h>
37 #include <view/view_controls.h>
38 #include <view/view_group.h>
39 
40 
41 
43  TOOL_INTERACTIVE( "gerbview.Inspection" ),
44  m_frame( nullptr )
45 {
46 }
47 
48 
50 {
51 }
52 
53 
55 {
56  return true;
57 }
58 
59 
61 {
62  m_frame = getEditFrame<GERBVIEW_FRAME>();
63 }
64 
65 
67 {
68  int ii, jj;
69  wxString Line;
70  wxArrayString list;
71  int curr_layer = m_frame->GetActiveLayer();
72 
73  double scale = 1.0;
74  wxString units;
75 
76  switch( m_frame->GetUserUnits() )
77  {
79  scale = IU_PER_MM;
80  units = "mm";
81  break;
82 
83  case EDA_UNITS::INCHES:
84  scale = IU_PER_MILS * 1000;
85  units = "in";
86  break;
87 
88  case EDA_UNITS::MILS:
90  units = "mil";
91  break;
92 
93  default:
94  wxASSERT_MSG( false, "Invalid units" );
95  }
96 
97  for( unsigned int layer = 0; layer < m_frame->ImagesMaxCount(); ++layer )
98  {
99  GERBER_FILE_IMAGE* gerber = m_frame->GetGbrImage( layer );
100 
101  if( !gerber )
102  continue;
103 
104  if( gerber->GetDcodesCount() == 0 )
105  continue;
106 
107  if( curr_layer == static_cast<int>( layer ) )
108  Line.Printf( wxT( "*** Active layer (%2.2d) ***" ), layer + 1 );
109  else
110  Line.Printf( wxT( "*** layer %2.2d ***" ), layer + 1 );
111 
112  list.Add( Line );
113 
114  for( ii = 0, jj = 1; ii < TOOLS_MAX_COUNT; ii++ )
115  {
116  D_CODE* pt_D_code = gerber->GetDCODE( ii + FIRST_DCODE );
117 
118  if( pt_D_code == NULL )
119  continue;
120 
121  if( !pt_D_code->m_InUse && !pt_D_code->m_Defined )
122  continue;
123 
124  Line.Printf( wxT( "tool %2.2d: D%2.2d V %.4f %s H %.4f %s %s attribute '%s'" ),
125  jj,
126  pt_D_code->m_Num_Dcode,
127  pt_D_code->m_Size.y / scale, units,
128  pt_D_code->m_Size.x / scale, units,
129  D_CODE::ShowApertureType( pt_D_code->m_Shape ),
130  pt_D_code->m_AperFunction.IsEmpty()? wxT( "none" ) : pt_D_code->m_AperFunction
131  );
132 
133  if( !pt_D_code->m_Defined )
134  Line += wxT( " (not defined)" );
135 
136  if( pt_D_code->m_InUse )
137  Line += wxT( " (in use)" );
138 
139  list.Add( Line );
140  jj++;
141  }
142  }
143 
144  wxSingleChoiceDialog dlg( m_frame, wxEmptyString, _( "D Codes" ), list, (void**) NULL,
145  wxCHOICEDLG_STYLE & ~wxCANCEL );
146 
147  dlg.ShowModal();
148 
149  return 0;
150 }
151 
152 
154 {
155  int layer = m_frame->GetActiveLayer();
156  GERBER_FILE_IMAGE* gerber_layer = m_frame->GetGbrImage( layer );
157 
158  if( gerber_layer )
159  {
160  wxString editorname = Pgm().GetEditorName();
161 
162  if( !editorname.IsEmpty() )
163  {
164  wxFileName fn( gerber_layer->m_FileName );
165 
166  // Call the editor only if the Gerber/drill source file is available.
167  // This is not always the case, because it can be a temporary file
168  // if it comes from a zip archive.
169  if( !fn.FileExists() )
170  {
171  wxString msg;
172  msg.Printf( _( "Source file \"%s\" is not available" ), fn.GetFullPath() );
173  wxMessageBox( msg );
174  }
175  else
176  {
177  ExecuteFile( m_frame, editorname, QuoteFullPath( fn ) );
178  }
179  }
180  else
181  {
182  wxMessageBox( _( "No editor defined. Please select one" ) );
183  }
184  }
185  else
186  {
187  wxString msg;
188  msg.Printf( _( "No file loaded on the active layer %d" ), layer + 1 );
189  wxMessageBox( msg );
190  }
191 
192  return 0;
193 }
194 
195 
197 {
198  KIGFX::VIEW& view = *getView();
199  KIGFX::VIEW_CONTROLS& controls = *getViewControls();
200  KIGFX::VC_SETTINGS previous_settings = controls.GetSettings();
201 
202  std::string tool = aEvent.GetCommandStr().get();
203  m_frame->PushTool( tool );
204  Activate();
205 
207 
208  EDA_UNITS units = m_frame->GetUserUnits();
209  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units );
210 
211  view.Add( &ruler );
212  view.SetVisible( &ruler, false );
213 
214  bool originSet = false;
215 
216  controls.ShowCursor( true );
217 
218  auto setCursor =
219  [&]()
220  {
222  };
223 
224  // Set initial cursor
225  setCursor();
226 
227  while( TOOL_EVENT* evt = Wait() )
228  {
229  setCursor();
230  const VECTOR2I cursorPos = controls.GetCursorPosition();
231 
232  auto clearRuler =
233  [&] ()
234  {
235  view.SetVisible( &ruler, false );
236  controls.SetAutoPan( false );
237  controls.CaptureCursor( false );
238  originSet = false;
239  };
240 
241  if( evt->IsCancelInteractive() )
242  {
243  if( originSet )
244  {
245  clearRuler();
246  }
247  else
248  {
249  m_frame->PopTool( tool );
250  break;
251  }
252  }
253  else if( evt->IsActivate() )
254  {
255  if( originSet )
256  clearRuler();
257 
258  if( evt->IsMoveTool() )
259  {
260  // leave ourselves on the stack so we come back after the move
261  break;
262  }
263  else
264  {
265  m_frame->PopTool( tool );
266  break;
267  }
268  }
269  // click or drag starts
270  else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
271  {
272  twoPtMgr.SetOrigin( cursorPos );
273  twoPtMgr.SetEnd( cursorPos );
274 
275  controls.CaptureCursor( true );
276  controls.SetAutoPan( true );
277 
278  originSet = true;
279  }
280  // second click or mouse up after drag ends
281  else if( originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
282  {
283  originSet = false;
284 
285  controls.SetAutoPan( false );
286  controls.CaptureCursor( false );
287  }
288  // move or drag when origin set updates rules
289  else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
290  {
291  twoPtMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
292  twoPtMgr.SetEnd( cursorPos );
293 
294  view.SetVisible( &ruler, true );
295  view.Update( &ruler, KIGFX::GEOMETRY );
296  }
297  else if( evt->IsAction( &ACTIONS::updateUnits ) )
298  {
299  if( m_frame->GetUserUnits() != units )
300  {
301  units = m_frame->GetUserUnits();
302  ruler.SwitchUnits( units );
303  view.Update( &ruler, KIGFX::GEOMETRY );
304  }
305  evt->SetPassEvent();
306  }
307  else if( evt->IsClick( BUT_RIGHT ) )
308  {
310  }
311  else
312  {
313  evt->SetPassEvent();
314  }
315  }
316 
317  view.SetVisible( &ruler, false );
318  view.Remove( &ruler );
319 
320  controls.ApplySettings( previous_settings );
322  return 0;
323 }
324 
325 
327 {
331 }
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Suspend execution of the tool until an event specified in aEventList arrives.
This file is part of the common library TODO brief description.
wxSize m_Size
Horizontal and vertical dimensions.
Definition: dcode.h:94
static TOOL_ACTION showSource
static constexpr double IU_PER_MM
Mock up a conversion function.
bool m_InUse
false if the aperure (previously defined) is not used to draw something
Definition: dcode.h:102
void ApplySettings(const VC_SETTINGS &aSettings)
Load new settings from program common settings.
APERTURE_T m_Shape
shape ( Line, rectangle, circle , oval .. )
Definition: dcode.h:95
Represent a very simple geometry manager for items that have a start and end point.
virtual EDA_DRAW_PANEL_GAL * GetCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:351
D_CODE * GetDCODE(int aDCODE) const
Return a pointer to the D_CODE within this GERBER for the given aDCODE.
Hold the image data and parameters for one gerber file and layer parameters.
void SwitchUnits(EDA_UNITS aUnits)
Switch the ruler units.
Definition: ruler_item.h:76
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
void SetCurrentCursor(KICURSOR cursor)
Set the current cursor shape for this panel.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
const VC_SETTINGS & GetSettings() const
Apply VIEW_CONTROLS settings from an object.
static TOOL_ACTION measureTool
Definition: actions.h:157
bool m_Defined
false if the aperture is not defined in the header
Definition: dcode.h:104
unsigned ImagesMaxCount() const
The max number of file images.
#define NULL
int MeasureTool(const TOOL_EVENT &aEvent)
Show a list of the DCodes.
#define FIRST_DCODE
Definition: dcode.h:71
virtual void PopTool(const std::string &actionName)
virtual void CaptureCursor(bool aEnabled)
Force the cursor to stay within the drawing panel area.
GERBER_FILE_IMAGE * GetGbrImage(int aIdx) const
int m_Num_Dcode
D code value ( >= 10 )
Definition: dcode.h:96
Generic, UI-independent tool event.
Definition: tool_event.h:173
void SetOrigin(const VECTOR2I &aOrigin)
< Set the origin of the ruler (the fixed end)
Structure to keep VIEW_CONTROLS settings for easy store/restore operations.
Definition: view_controls.h:41
static const wxChar * ShowApertureType(APERTURE_T aType)
Function ShowApertureType returns a character string telling what type of aperture type aType is.
Definition: dcode.cpp:92
An interface for classes handling user events controlling the view behavior such as zooming,...
A drawn ruler item for showing the distance between two points.
Definition: ruler_item.h:41
int ShowSource(const TOOL_EVENT &aEvent)
Set up handlers for various events.
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
bool Init() override
Init() is called once upon a registration of the tool.
wxString m_AperFunction
the aperture attribute (created by a TA.AperFunction command) attached to the D_CODE
Definition: dcode.h:105
EDA_UNITS
Definition: eda_units.h:38
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:471
int GetActiveLayer() const
Return the active layer.
static TOOL_ACTION updateUnits
Definition: actions.h:150
const int scale
D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
int ShowDCodes(const TOOL_EVENT &aEvent)
Show the source for the gerber file.
SELECTION & GetCurrentSelection() override
Get the current selection from the canvas area.
wxString QuoteFullPath(wxFileName &fn, wxPathFormat format)
Quote return value of wxFileName::GetFullPath().
Definition: gestfich.cpp:378
#define _(s)
Definition: 3d_actions.cpp:33
#define TOOLS_MAX_COUNT
Definition: dcode.h:73
#define IU_PER_MILS
Definition: plotter.cpp:137
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition: view.cpp:1454
void Activate()
Run the tool.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:321
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
static TOOL_ACTION showDCodes
int ExecuteFile(wxWindow *frame, const wxString &ExecFile, const wxString &param, wxProcess *callback)
Call the executable file ExecFile with the command line parameters param.
Definition: gestfich.cpp:165
void ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:59
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1508
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the end that moves with the cursor.
Position or shape has changed.
Definition: view_item.h:54