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  ExecuteFile( m_frame, editorname, QuoteFullPath( fn ) );
177  }
178  else
179  wxMessageBox( _( "No editor defined. Please select one" ) );
180  }
181  else
182  {
183  wxString msg;
184  msg.Printf( _( "No file loaded on the active layer %d" ), layer + 1 );
185  wxMessageBox( msg );
186  }
187 
188  return 0;
189 }
190 
191 
193 {
194  KIGFX::VIEW& view = *getView();
195  KIGFX::VIEW_CONTROLS& controls = *getViewControls();
196  KIGFX::VC_SETTINGS previous_settings = controls.GetSettings();
197 
198  std::string tool = aEvent.GetCommandStr().get();
199  m_frame->PushTool( tool );
200  Activate();
201 
203 
204  EDA_UNITS units = m_frame->GetUserUnits();
205  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units );
206 
207  view.Add( &ruler );
208  view.SetVisible( &ruler, false );
209 
210  bool originSet = false;
211 
212  controls.ShowCursor( true );
213 
214  auto setCursor =
215  [&]()
216  {
218  };
219 
220  // Set initial cursor
221  setCursor();
222 
223  while( TOOL_EVENT* evt = Wait() )
224  {
225  setCursor();
226  const VECTOR2I cursorPos = controls.GetCursorPosition();
227 
228  auto clearRuler =
229  [&] ()
230  {
231  view.SetVisible( &ruler, false );
232  controls.SetAutoPan( false );
233  controls.CaptureCursor( false );
234  originSet = false;
235  };
236 
237  if( evt->IsCancelInteractive() )
238  {
239  if( originSet )
240  {
241  clearRuler();
242  }
243  else
244  {
245  m_frame->PopTool( tool );
246  break;
247  }
248  }
249  else if( evt->IsActivate() )
250  {
251  if( originSet )
252  clearRuler();
253 
254  if( evt->IsMoveTool() )
255  {
256  // leave ourselves on the stack so we come back after the move
257  break;
258  }
259  else
260  {
261  m_frame->PopTool( tool );
262  break;
263  }
264  }
265  // click or drag starts
266  else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
267  {
268  twoPtMgr.SetOrigin( cursorPos );
269  twoPtMgr.SetEnd( cursorPos );
270 
271  controls.CaptureCursor( true );
272  controls.SetAutoPan( true );
273 
274  originSet = true;
275  }
276  // second click or mouse up after drag ends
277  else if( originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
278  {
279  originSet = false;
280 
281  controls.SetAutoPan( false );
282  controls.CaptureCursor( false );
283  }
284  // move or drag when origin set updates rules
285  else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
286  {
287  twoPtMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
288  twoPtMgr.SetEnd( cursorPos );
289 
290  view.SetVisible( &ruler, true );
291  view.Update( &ruler, KIGFX::GEOMETRY );
292  }
293  else if( evt->IsAction( &ACTIONS::updateUnits ) )
294  {
295  if( m_frame->GetUserUnits() != units )
296  {
297  units = m_frame->GetUserUnits();
298  ruler.SwitchUnits( units );
299  view.Update( &ruler, KIGFX::GEOMETRY );
300  }
301  evt->SetPassEvent();
302  }
303  else if( evt->IsClick( BUT_RIGHT ) )
304  {
306  }
307  else
308  {
309  evt->SetPassEvent();
310  }
311  }
312 
313  view.SetVisible( &ruler, false );
314  view.Remove( &ruler );
315 
316  controls.ApplySettings( previous_settings );
318  return 0;
319 }
320 
321 
323 {
327 }
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
TOOL_MENU m_menu
functions below are not yet implemented - their interface may change
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
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.
VIEW_CONTROLS class definition.
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)
Applies VIEW_CONTROLS settings from an object
APERTURE_T m_Shape
shape ( Line, rectangle, circle , oval .. )
Definition: dcode.h:95
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)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:357
D_CODE * GetDCODE(int aDCODE) const
Function GetDCODE returns a pointer to the D_CODE within this GERBER for the given aDCODE.
GERBER_FILE_IMAGE holds the Image data and parameters for one gerber file and layer parameters (TODO:...
void SwitchUnits(EDA_UNITS aUnits)
Switch the ruler units.
Definition: ruler_item.h:78
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:102
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void SetCurrentCursor(KICURSOR cursor)
Function SetCurrentCursor Set the current cursor shape for this panel.
void setTransitions() override
Sets up handlers for various events.
const VC_SETTINGS & GetSettings() const
Returns the current VIEW_CONTROLS settings
static TOOL_ACTION measureTool
Definition: actions.h:152
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)
Launches a tool to measure between points
#define FIRST_DCODE
Definition: dcode.h:71
virtual void PopTool(const std::string &actionName)
virtual void CaptureCursor(bool aEnabled)
Function CaptureCursor() Forces 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
TOOL_EVENT.
Definition: tool_event.h:171
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:55
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
VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (such a...
VIEW_GROUP extends VIEW_ITEM by possibility of grouping items into a single object.
int ShowSource(const TOOL_EVENT &aEvent)
Show the source for the gerber file
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:36
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg.
bool Init() override
Function Init() 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:463
int GetActiveLayer() const
Function SetActiveLayer returns the active layer.
static TOOL_ACTION updateUnits
Definition: actions.h:145
const int scale
D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
int ShowDCodes(const TOOL_EVENT &aEvent)
Show a list of the DCodes
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
Determines the reason of reset for a tool
Definition: tool_base.h:79
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1459
void Activate()
Function Activate() Runs the tool.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:327
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:42
VIEW.
Definition: view.h:63
static TOOL_ACTION showDCodes
int ExecuteFile(wxWindow *frame, const wxString &ExecFile, const wxString &param, wxProcess *callback)
Function ExecuteFile calls the executable file ExecFile with the command line parameters param.
Definition: gestfich.cpp:165
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:59
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
VECTOR2D GetCursorPosition() const
Returns the current cursor position in world coordinates.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1513
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the end that moves with the cursor.
Color has changed.
Definition: view_item.h:59