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 The 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
18 * along with this program. If not, see <https://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
55
56
58{
59 return true;
60}
61
62
67
68
70{
71 wxString Line;
72 wxArrayString list;
73 int curr_layer = m_frame->GetActiveLayer();
74
75 double scale = 1.0;
76 wxString units;
77
78 switch( m_frame->GetUserUnits() )
79 {
80 case EDA_UNITS::MM:
81 scale = gerbIUScale.IU_PER_MM;
82 units = wxT( "mm" );
83 break;
84
85 case EDA_UNITS::INCH:
86 scale = gerbIUScale.IU_PER_MILS * 1000;
87 units = wxT( "in" );
88 break;
89
90 case EDA_UNITS::MILS:
91 scale = gerbIUScale.IU_PER_MILS;
92 units = wxT( "mil" );
93 break;
94
95 default:
96 wxASSERT_MSG( false, wxT( "Invalid units" ) );
97 }
98
99 for( unsigned int layer = 0; layer < m_frame->ImagesMaxCount(); ++layer )
100 {
101 GERBER_FILE_IMAGE* gerber = m_frame->GetGbrImage( layer );
102
103 if( !gerber )
104 continue;
105
106 if( gerber->GetDcodesCount() == 0 )
107 continue;
108
109 if( curr_layer == static_cast<int>( layer ) )
110 Line.Printf( wxT( "*** Active layer (%2.2d) ***" ), layer + 1 );
111 else
112 Line.Printf( wxT( "*** layer %2.2d ***" ), layer + 1 );
113
114 list.Add( Line );
115
116 int ii = 1;
117 for( const auto &[_, pt_D_code] : gerber->m_ApertureList )
118 {
119 if( pt_D_code == nullptr )
120 continue;
121
122 if( !pt_D_code->m_InUse && !pt_D_code->m_Defined )
123 continue;
124
125 Line.Printf( wxT( "tool %d: Dcode D%d V %.4f %s H %.4f %s %s attribute '%s'" ),
126 ii,
127 pt_D_code->m_Num_Dcode,
128 pt_D_code->m_Size.y / scale, units,
129 pt_D_code->m_Size.x / scale, units,
130 D_CODE::ShowApertureType( pt_D_code->m_ApertType ),
131 pt_D_code->m_AperFunction.IsEmpty()? wxString( wxT( "none" ) ) : pt_D_code->m_AperFunction
132 );
133
134 if( !pt_D_code->m_Defined )
135 Line += wxT( " (not defined)" );
136
137 if( pt_D_code->m_InUse )
138 Line += wxT( " (in use)" );
139
140 list.Add( Line );
141 ii++;
142 }
143 }
144
145 wxSingleChoiceDialog dlg( m_frame, wxEmptyString, _( "D Codes" ), list, (void**) nullptr,
146 wxCHOICEDLG_STYLE & ~wxCANCEL );
147
148 dlg.ShowModal();
149
150 return 0;
151}
152
153
155{
156 int layer = m_frame->GetActiveLayer();
157 GERBER_FILE_IMAGE* gerber_layer = m_frame->GetGbrImage( layer );
158
159 if( gerber_layer )
160 {
161 wxString editorname = Pgm().GetTextEditor();
162
163 if( !editorname.IsEmpty() )
164 {
165 wxFileName fn( gerber_layer->m_FileName );
166
167 // Call the editor only if the Gerber/drill source file is available.
168 // This is not always the case, because it can be a temporary file
169 // if it comes from a zip archive.
170 if( !fn.FileExists() )
171 {
172 wxString msg;
173 msg.Printf( _( "Source file '%s' not found." ), fn.GetFullPath() );
174 wxMessageBox( msg );
175 }
176 else
177 {
178 ExecuteFile( editorname, fn.GetFullPath() );
179 }
180 }
181 else
182 {
183 wxMessageBox( _( "No text editor selected in KiCad. Please choose one." ) );
184 }
185 }
186 else
187 {
188 wxString msg;
189 msg.Printf( _( "No file loaded on the active layer %d." ), layer + 1 );
190 wxMessageBox( msg );
191 }
192
193 return 0;
194}
195
196
198
199
201{
203 bool originSet = false;
205 EDA_UNITS units = m_frame->GetUserUnits();
206 KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, gerbIUScale, units, false, false );
207
208 TOOL_EVENT originalEvent = aEvent; // This can change out from under us when the event loop runs
209 SCOPED_TOOL_PUSHER raii( m_frame, originalEvent );
210
211 auto setCursor =
212 [&]()
213 {
214 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MEASURE );
215 };
216
217 auto cleanup =
218 [&]()
219 {
220 getView()->SetVisible( &ruler, false );
221 controls.SetAutoPan( false );
222 controls.CaptureCursor( false );
223 originSet = false;
224 };
225
226 Activate();
227 // Must be done after Activate() so that it gets set into the correct context
228 controls.ShowCursor( true );
229 // Set initial cursor
230 setCursor();
231
232 getView()->Add( &ruler );
233 getView()->SetVisible( &ruler, false );
234
235 while( TOOL_EVENT* evt = Wait() )
236 {
237 setCursor();
238 const VECTOR2I cursorPos = controls.GetCursorPosition();
239
240 if( evt->IsCancelInteractive() )
241 {
242 if( originSet )
243 cleanup();
244 else
245 break;
246 }
247 else if( evt->IsActivate() )
248 {
249 if( originSet )
250 cleanup();
251
252 if( evt->IsMoveTool() )
253 {
254 // Make sure we come back after the move tool runs
255 m_frame->PushTool( originalEvent );
256 }
257
258 break;
259 }
260 else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
261 {
262 // click or drag starts
263 twoPtMgr.SetOrigin( cursorPos );
264 twoPtMgr.SetEnd( cursorPos );
265
266 controls.CaptureCursor( true );
267 controls.SetAutoPan( true );
268
269 originSet = true;
270 }
271 else if( originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
272 {
273 // second click or mouse up after drag ends
274 originSet = false;
275
276 controls.SetAutoPan( false );
277 controls.CaptureCursor( false );
278 }
279 else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
280 {
281 // move or drag when origin set updates rules
282 twoPtMgr.SetAngleSnap( evt->Modifier( MD_SHIFT ) ? LEADER_MODE::DEG45
284 twoPtMgr.SetEnd( cursorPos );
285
286 getView()->SetVisible( &ruler, true );
287 getView()->Update( &ruler, KIGFX::GEOMETRY );
288 }
289 else if( evt->IsAction( &ACTIONS::updateUnits ) )
290 {
291 if( m_frame->GetUserUnits() != units )
292 {
293 units = m_frame->GetUserUnits();
294 ruler.SwitchUnits( units );
295 getView()->Update( &ruler, KIGFX::GEOMETRY );
296 }
297 evt->SetPassEvent();
298 }
299 else if( evt->IsClick( BUT_RIGHT ) )
300 {
301 m_menu->ShowContextMenu( m_frame->GetCurrentSelection() );
302 }
303 else
304 {
305 evt->SetPassEvent();
306 }
307 }
308
309 getView()->SetVisible( &ruler, false );
310 getView()->Remove( &ruler );
311
312 m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
313 return 0;
314}
315
316
constexpr EDA_IU_SCALE gerbIUScale
Definition base_units.h:120
static TOOL_ACTION updateUnits
Definition actions.h:203
static TOOL_ACTION measureTool
Definition actions.h:248
static const wxChar * ShowApertureType(APERTURE_T aType)
Return a character string telling what type of aperture type aType is.
Definition dcode.cpp:82
Hold the image data and parameters for one gerber file and layer parameters.
wxString m_FileName
Full File Name for this layer.
std::map< int, D_CODE * > m_ApertureList
Dcode (Aperture) List for this layer (see dcode.h)
static TOOL_ACTION showDCodes
static TOOL_ACTION showSource
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:88
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:301
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:416
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:1852
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition view.cpp:1773
virtual const wxString & GetTextEditor(bool aCanShowFileChooser=true)
Return the path to the preferred text editor application.
Definition pgm_base.cpp:216
T * getEditFrame() const
Return the application window object, casted to requested user type.
Definition tool_base.h:182
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition tool_base.cpp:40
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition tool_base.cpp:34
RESET_REASON
Determine the reason of reset for a tool.
Definition tool_base.h:74
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_INTERACTIVE(TOOL_ID aId, const std::string &aName)
Create a tool with given id & name.
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.
@ MEASURE
Definition cursors.h:64
@ ARROW
Definition cursors.h:42
#define _(s)
EDA_UNITS
Definition eda_units.h:44
@ DEG45
45 Degree only
@ DIRECT
Unconstrained point-to-point.
int ExecuteFile(const wxString &aEditorName, const wxString &aFileName, wxProcess *aCallback, bool aFileForKicad)
Call the executable file aEditorName with the parameter aFileName.
Definition gestfich.cpp:161
@ GEOMETRY
Position or shape has changed.
Definition view_item.h:51
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
const int scale
@ MD_SHIFT
Definition tool_event.h:139
@ BUT_LEFT
Definition tool_event.h:128
@ BUT_RIGHT
Definition tool_event.h:129
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683