KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 <[email protected]>
5 * Copyright (C) 2017-2021 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>
26#include <gestfich.h>
27#include <gerber_file_image.h>
28#include <gerbview_id.h>
30#include "gerbview_actions.h"
31#include <gal/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 {
81 case EDA_UNITS::MILLIMETRES:
83 units = wxT( "mm" );
84 break;
85
86 case EDA_UNITS::INCHES:
88 units = wxT( "in" );
89 break;
90
91 case EDA_UNITS::MILS:
93 units = wxT( "mil" );
94 break;
95
96 default:
97 wxASSERT_MSG( false, wxT( "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 == nullptr )
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,
133 pt_D_code->m_AperFunction.IsEmpty()? wxString( 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**) nullptr,
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().GetTextEditor();
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( editorname, fn.GetFullPath() );
181 }
182 }
183 else
184 {
185 wxMessageBox( _( "No text editor selected in KiCad. Please choose 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
203{
205 bool originSet = false;
207 EDA_UNITS units = m_frame->GetUserUnits();
208 KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, gerbIUScale, units, false, false );
209
210 m_frame->PushTool( aEvent );
211
212 auto setCursor =
213 [&]()
214 {
215 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MEASURE );
216 };
217
218 auto cleanup =
219 [&] ()
220 {
221 getView()->SetVisible( &ruler, false );
222 controls.SetAutoPan( false );
223 controls.CaptureCursor( false );
224 originSet = false;
225 };
226
227 Activate();
228 // Must be done after Activate() so that it gets set into the correct context
229 controls.ShowCursor( true );
230 // Set initial cursor
231 setCursor();
232
233 getView()->Add( &ruler );
234 getView()->SetVisible( &ruler, false );
235
236 while( TOOL_EVENT* evt = Wait() )
237 {
238 setCursor();
239 const VECTOR2I cursorPos = controls.GetCursorPosition();
240
241 if( evt->IsCancelInteractive() )
242 {
243 if( originSet )
244 {
245 cleanup();
246 }
247 else
248 {
249 m_frame->PopTool( aEvent );
250 break;
251 }
252 }
253 else if( evt->IsActivate() )
254 {
255 if( originSet )
256 cleanup();
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( aEvent );
266 break;
267 }
268 }
269 else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
270 {
271 // click or drag starts
272 twoPtMgr.SetOrigin( cursorPos );
273 twoPtMgr.SetEnd( cursorPos );
274
275 controls.CaptureCursor( true );
276 controls.SetAutoPan( true );
277
278 originSet = true;
279 }
280 else if( originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
281 {
282 // second click or mouse up after drag ends
283 originSet = false;
284
285 controls.SetAutoPan( false );
286 controls.CaptureCursor( false );
287 }
288 else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
289 {
290 // move or drag when origin set updates rules
291 twoPtMgr.SetAngleSnap( evt->Modifier( MD_SHIFT ) );
292 twoPtMgr.SetEnd( cursorPos );
293
294 getView()->SetVisible( &ruler, true );
295 getView()->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 getView()->Update( &ruler, KIGFX::GEOMETRY );
304 }
305 evt->SetPassEvent();
306 }
307 else if( evt->IsClick( BUT_RIGHT ) )
308 {
309 m_menu->ShowContextMenu( m_frame->GetCurrentSelection() );
310 }
311 else
312 {
313 evt->SetPassEvent();
314 }
315 }
316
317 getView()->SetVisible( &ruler, false );
318 getView()->Remove( &ruler );
319
320 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
321 return 0;
322}
323
324
326{
330}
constexpr EDA_IU_SCALE gerbIUScale
Definition: base_units.h:107
static TOOL_ACTION updateUnits
Definition: actions.h:194
static TOOL_ACTION measureTool
Definition: actions.h:201
A gerber DCODE (also called Aperture) definition.
Definition: dcode.h:80
wxString m_AperFunction
the aperture attribute (created by a TA.AperFunction command).
Definition: dcode.h:203
int m_Num_Dcode
D code value ( >= 10 )
Definition: dcode.h:193
static const wxChar * ShowApertureType(APERTURE_T aType)
Return a character string telling what type of aperture type aType is.
Definition: dcode.cpp:86
VECTOR2I m_Size
Horizontal and vertical dimensions.
Definition: dcode.h:190
APERTURE_T m_ApertType
Aperture type ( Line, rectangle, circle, oval poly, macro )
Definition: dcode.h:191
bool m_Defined
false if the aperture is not defined in the header
Definition: dcode.h:202
bool m_InUse
false if the aperture (previously defined) is not used to draw something
Definition: dcode.h:200
virtual EDA_DRAW_PANEL_GAL * GetCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
Hold the image data and parameters for one gerber file and layer parameters.
wxString m_FileName
Full File Name for this layer.
D_CODE * GetDCODE(int aDCODE) const
Return a pointer to the D_CODE within this GERBER for the given aDCODE.
static TOOL_ACTION showDCodes
static TOOL_ACTION showSource
int GetActiveLayer() const
Return the active layer.
unsigned ImagesMaxCount() const
The max number of file images.
SELECTION & GetCurrentSelection() override
Get the current selection from the canvas area.
GERBER_FILE_IMAGE * GetGbrImage(int aIdx) const
bool Init() override
Init() is called once upon a registration of the tool.
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int ShowSource(const TOOL_EVENT &aEvent)
Set up handlers for various events.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
int ShowDCodes(const TOOL_EVENT &aEvent)
Show the source for the gerber file.
int MeasureTool(const TOOL_EVENT &aEvent)
Show a list of the DCodes.
A drawn ruler item for showing the distance between two points.
Definition: ruler_item.h:42
void SwitchUnits(EDA_UNITS aUnits)
Switch the ruler units.
Definition: ruler_item.h:77
Represent a very simple geometry manager for items that have a start and end point.
void SetOrigin(const VECTOR2I &aOrigin)
< Set the origin of the ruler (the fixed end)
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the end that moves with the cursor.
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual void CaptureCursor(bool aEnabled)
Force the cursor to stay within the drawing panel area.
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:317
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:357
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:1687
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition: view.cpp:1614
virtual const wxString & GetTextEditor(bool aCanShowFileChooser=true)
Return the path to the preferred text editor application.
Definition: pgm_base.cpp:196
virtual void PopTool(const TOOL_EVENT &aEvent)
Pops a tool from the stack.
virtual void PushTool(const TOOL_EVENT &aEvent)
NB: the definition of "tool" is different at the user level.
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
Generic, UI-independent tool event.
Definition: tool_event.h:167
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).
std::unique_ptr< TOOL_MENU > m_menu
The functions below are not yet implemented - their interface may change.
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.
void Activate()
Run the tool.
EDA_UNITS GetUserUnits() const
#define FIRST_DCODE
Definition: dcode.h:69
#define TOOLS_MAX_COUNT
Definition: dcode.h:71
#define _(s)
EDA_UNITS
Definition: eda_units.h:46
int ExecuteFile(const wxString &aEditorName, const wxString &aFileName, wxProcess *aCallback, bool aFileForKicad)
Call the executable file aEditorName with the parameter aFileName.
Definition: gestfich.cpp:143
@ GEOMETRY
Position or shape has changed.
Definition: view_item.h:54
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
const int scale
const double IU_PER_MM
Definition: base_units.h:76
const double IU_PER_MILS
Definition: base_units.h:77
@ MD_SHIFT
Definition: tool_event.h:142
@ BUT_LEFT
Definition: tool_event.h:131
@ BUT_RIGHT
Definition: tool_event.h:132