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>
32 #include <pgm_base.h>
35 #include <tool/tool_event.h>
36 #include <tool/tool_manager.h>
37 #include <view/view.h>
38 #include <view/view_controls.h>
39 #include <view/view_group.h>
40 #include <wx/msgdlg.h>
41 #include <wx/textdlg.h>
42 #include <wx/choicdlg.h>
43 
44 
46  TOOL_INTERACTIVE( "gerbview.Inspection" ),
47  m_frame( nullptr )
48 {
49 }
50 
51 
53 {
54 }
55 
56 
58 {
59  return true;
60 }
61 
62 
64 {
65  m_frame = getEditFrame<GERBVIEW_FRAME>();
66 }
67 
68 
70 {
71  int ii, jj;
72  wxString Line;
73  wxArrayString list;
74  int curr_layer = m_frame->GetActiveLayer();
75 
76  double scale = 1.0;
77  wxString units;
78 
79  switch( m_frame->GetUserUnits() )
80  {
82  scale = IU_PER_MM;
83  units = "mm";
84  break;
85 
86  case EDA_UNITS::INCHES:
87  scale = IU_PER_MILS * 1000;
88  units = "in";
89  break;
90 
91  case EDA_UNITS::MILS:
93  units = "mil";
94  break;
95 
96  default:
97  wxASSERT_MSG( false, "Invalid units" );
98  }
99 
100  for( unsigned int layer = 0; layer < m_frame->ImagesMaxCount(); ++layer )
101  {
102  GERBER_FILE_IMAGE* gerber = m_frame->GetGbrImage( layer );
103 
104  if( !gerber )
105  continue;
106 
107  if( gerber->GetDcodesCount() == 0 )
108  continue;
109 
110  if( curr_layer == static_cast<int>( layer ) )
111  Line.Printf( wxT( "*** Active layer (%2.2d) ***" ), layer + 1 );
112  else
113  Line.Printf( wxT( "*** layer %2.2d ***" ), layer + 1 );
114 
115  list.Add( Line );
116 
117  for( ii = 0, jj = 1; ii < TOOLS_MAX_COUNT; ii++ )
118  {
119  D_CODE* pt_D_code = gerber->GetDCODE( ii + FIRST_DCODE );
120 
121  if( pt_D_code == NULL )
122  continue;
123 
124  if( !pt_D_code->m_InUse && !pt_D_code->m_Defined )
125  continue;
126 
127  Line.Printf( wxT( "tool %2.2d: D%2.2d V %.4f %s H %.4f %s %s attribute '%s'" ),
128  jj,
129  pt_D_code->m_Num_Dcode,
130  pt_D_code->m_Size.y / scale, units,
131  pt_D_code->m_Size.x / scale, units,
132  D_CODE::ShowApertureType( pt_D_code->m_Shape ),
133  pt_D_code->m_AperFunction.IsEmpty()? wxT( "none" ) : pt_D_code->m_AperFunction
134  );
135 
136  if( !pt_D_code->m_Defined )
137  Line += wxT( " (not defined)" );
138 
139  if( pt_D_code->m_InUse )
140  Line += wxT( " (in use)" );
141 
142  list.Add( Line );
143  jj++;
144  }
145  }
146 
147  wxSingleChoiceDialog dlg( m_frame, wxEmptyString, _( "D Codes" ), list, (void**) NULL,
148  wxCHOICEDLG_STYLE & ~wxCANCEL );
149 
150  dlg.ShowModal();
151 
152  return 0;
153 }
154 
155 
157 {
158  int layer = m_frame->GetActiveLayer();
159  GERBER_FILE_IMAGE* gerber_layer = m_frame->GetGbrImage( layer );
160 
161  if( gerber_layer )
162  {
163  wxString editorname = Pgm().GetEditorName();
164 
165  if( !editorname.IsEmpty() )
166  {
167  wxFileName fn( gerber_layer->m_FileName );
168 
169  // Call the editor only if the Gerber/drill source file is available.
170  // This is not always the case, because it can be a temporary file
171  // if it comes from a zip archive.
172  if( !fn.FileExists() )
173  {
174  wxString msg;
175  msg.Printf( _( "Source file '%s' not found." ), fn.GetFullPath() );
176  wxMessageBox( msg );
177  }
178  else
179  {
180  ExecuteFile( m_frame, editorname, QuoteFullPath( fn ) );
181  }
182  }
183  else
184  {
185  wxMessageBox( _( "No editor defined. Please select one." ) );
186  }
187  }
188  else
189  {
190  wxString msg;
191  msg.Printf( _( "No file loaded on the active layer %d." ), layer + 1 );
192  wxMessageBox( msg );
193  }
194 
195  return 0;
196 }
197 
198 
200 {
201  KIGFX::VIEW& view = *getView();
202  KIGFX::VIEW_CONTROLS& controls = *getViewControls();
203  KIGFX::VC_SETTINGS previous_settings = controls.GetSettings();
204 
205  std::string tool = aEvent.GetCommandStr().get();
206  m_frame->PushTool( tool );
207  Activate();
208 
210 
211  EDA_UNITS units = m_frame->GetUserUnits();
212  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units );
213 
214  view.Add( &ruler );
215  view.SetVisible( &ruler, false );
216 
217  bool originSet = false;
218 
219  controls.ShowCursor( true );
220 
221  auto setCursor =
222  [&]()
223  {
225  };
226 
227  // Set initial cursor
228  setCursor();
229 
230  while( TOOL_EVENT* evt = Wait() )
231  {
232  setCursor();
233  const VECTOR2I cursorPos = controls.GetCursorPosition();
234 
235  auto clearRuler =
236  [&] ()
237  {
238  view.SetVisible( &ruler, false );
239  controls.SetAutoPan( false );
240  controls.CaptureCursor( false );
241  originSet = false;
242  };
243 
244  if( evt->IsCancelInteractive() )
245  {
246  if( originSet )
247  {
248  clearRuler();
249  }
250  else
251  {
252  m_frame->PopTool( tool );
253  break;
254  }
255  }
256  else if( evt->IsActivate() )
257  {
258  if( originSet )
259  clearRuler();
260 
261  if( evt->IsMoveTool() )
262  {
263  // leave ourselves on the stack so we come back after the move
264  break;
265  }
266  else
267  {
268  m_frame->PopTool( tool );
269  break;
270  }
271  }
272  // click or drag starts
273  else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
274  {
275  twoPtMgr.SetOrigin( cursorPos );
276  twoPtMgr.SetEnd( cursorPos );
277 
278  controls.CaptureCursor( true );
279  controls.SetAutoPan( true );
280 
281  originSet = true;
282  }
283  // second click or mouse up after drag ends
284  else if( originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
285  {
286  originSet = false;
287 
288  controls.SetAutoPan( false );
289  controls.CaptureCursor( false );
290  }
291  // move or drag when origin set updates rules
292  else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
293  {
294  twoPtMgr.SetAngleSnap( evt->Modifier( MD_SHIFT ) );
295  twoPtMgr.SetEnd( cursorPos );
296 
297  view.SetVisible( &ruler, true );
298  view.Update( &ruler, KIGFX::GEOMETRY );
299  }
300  else if( evt->IsAction( &ACTIONS::updateUnits ) )
301  {
302  if( m_frame->GetUserUnits() != units )
303  {
304  units = m_frame->GetUserUnits();
305  ruler.SwitchUnits( units );
306  view.Update( &ruler, KIGFX::GEOMETRY );
307  }
308  evt->SetPassEvent();
309  }
310  else if( evt->IsClick( BUT_RIGHT ) )
311  {
313  }
314  else
315  {
316  evt->SetPassEvent();
317  }
318  }
319 
320  view.SetVisible( &ruler, false );
321  view.Remove( &ruler );
322 
323  controls.ApplySettings( previous_settings );
325  return 0;
326 }
327 
328 
330 {
334 }
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 SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
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:188
static TOOL_ACTION showSource
static constexpr double IU_PER_MM
Mock up a conversion function.
bool m_InUse
false if the aperture (previously defined) is not used to draw something
Definition: dcode.h:197
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:189
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:352
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 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:154
bool m_Defined
false if the aperture is not defined in the header
Definition: dcode.h:199
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:70
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:190
Generic, UI-independent tool event.
Definition: tool_event.h:152
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)
Return a character string telling what type of aperture type aType is.
Definition: dcode.cpp:87
An interface for classes handling user events controlling the view behavior such as zooming,...
#define _(s)
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).
Definition: dcode.h:200
EDA_UNITS
Definition: eda_units.h:38
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:455
int GetActiveLayer() const
Return the active layer.
static TOOL_ACTION updateUnits
Definition: actions.h:147
const int scale
see class PGM_BASE
A gerber DCODE (also called Aperture) definition.
Definition: dcode.h:80
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 TOOLS_MAX_COUNT
Definition: dcode.h:72
#define IU_PER_MILS
Definition: plotter.cpp:137
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:77
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition: view.cpp:1450
void Activate()
Run the tool.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:322
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:1504
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