KiCad PCB EDA Suite
gerbview_control.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-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 #include <confirm.h>
23 #include <export_to_pcbnew.h>
24 #include <gerber_file_image.h>
25 #include <gerber_file_image_list.h>
26 #include <gerbview_painter.h>
27 #include <gerbview_frame.h>
28 #include <kicad_string.h>
29 #include <excellon_image.h>
30 #include <menus_helpers.h>
31 #include <tool/tool_manager.h>
32 #include <view/view.h>
34 #include <wx/filedlg.h>
35 
36 #include "gerbview_actions.h"
37 #include "gerbview_control.h"
39 
40 
41 GERBVIEW_CONTROL::GERBVIEW_CONTROL() : TOOL_INTERACTIVE( "gerbview.Control" ), m_frame( nullptr )
42 {
43 }
44 
45 
47 {
48  m_frame = getEditFrame<GERBVIEW_FRAME>();
49 }
50 
51 
53 {
54  m_frame->LoadGerberFiles( wxEmptyString );
55  // loadListOfGerberAndDrillFiles() refreshes the canvas
56 
57  return 0;
58 }
59 
60 
62 {
63  m_frame->LoadExcellonFiles( wxEmptyString );
64  canvas()->Refresh();
65 
66  return 0;
67 }
68 
69 
71 {
72  m_frame->LoadGerberJobFile( wxEmptyString );
73  canvas()->Refresh();
74 
75  return 0;
76 }
77 
78 
80 {
81  m_frame->LoadZipArchiveFile( wxEmptyString );
82  canvas()->Refresh();
83 
84  return 0;
85 }
86 
87 
89 {
91 
92  return 0;
93 }
94 
95 
97 {
98  int layercount = 0;
99 
101 
102  // Count the Gerber layers which are actually currently used
103  for( LAYER_NUM ii = 0; ii < (LAYER_NUM)images->ImagesMaxCount(); ++ii )
104  {
105  if( images->GetGbrImage( ii ) )
106  layercount++;
107  }
108 
109  if( layercount == 0 )
110  {
111  DisplayInfoMessage( m_frame, _( "None of the Gerber layers contain any data" ) );
112  return 0;
113  }
114 
115  wxString fileDialogName( wxT( "noname." ) + KiCadPcbFileExtension );
116  wxString path = m_frame->GetMruPath();
117 
118  wxFileDialog filedlg( m_frame, _( "Board File Name" ), path, fileDialogName, PcbFileWildcard(),
119  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
120 
121  if( filedlg.ShowModal() == wxID_CANCEL )
122  return 0;
123 
124  wxFileName fileName = filedlg.GetPath();
125 
126  /* Install a dialog frame to choose the mapping
127  * between gerber layers and Pcbnew layers
128  */
129  LAYERS_MAP_DIALOG* layerdlg = new LAYERS_MAP_DIALOG( m_frame );
130  int ok = layerdlg->ShowModal();
131  layerdlg->Destroy();
132 
133  if( ok != wxID_OK )
134  return 0;
135 
136  // If no extension was entered, then force the extension to be a KiCad PCB file
137  if( !fileName.HasExt() )
138  fileName.SetExt( KiCadPcbFileExtension );
139 
140  m_frame->SetMruPath( fileName.GetPath() );
141 
142  GBR_TO_PCB_EXPORTER gbr_exporter( m_frame, fileName.GetFullPath() );
143 
144  gbr_exporter.ExportPcb( layerdlg->GetLayersLookUpTable(), layerdlg->GetCopperLayersCount() );
145 
146  return 0;
147 }
148 
149 
151 {
152  auto settings = static_cast<KIGFX::GERBVIEW_PAINTER*>( getView()->GetPainter() )->GetSettings();
153  const auto& selection = m_toolMgr->GetTool<GERBVIEW_SELECTION_TOOL>()->GetSelection();
154  GERBER_DRAW_ITEM* item = nullptr;
155 
156  if( selection.Size() == 1 )
157  {
158  item = static_cast<GERBER_DRAW_ITEM*>( selection[0] );
159  }
160 
162  {
163  m_frame->m_SelComponentBox->SetSelection( 0 );
164  m_frame->m_SelNetnameBox->SetSelection( 0 );
165  m_frame->m_SelAperAttributesBox->SetSelection( 0 );
166 
167  settings->m_netHighlightString = "";
168  settings->m_componentHighlightString = "";
169  settings->m_attributeHighlightString = "";
170  settings->m_dcodeHighlightValue = -1;
171 
173 
174  if( gerber )
175  gerber->m_Selected_Tool = settings->m_dcodeHighlightValue;
176  }
177  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightNet ) )
178  {
179  wxString net_name = item->GetNetAttributes().m_Netname;
180  settings->m_netHighlightString = net_name;
181  m_frame->m_SelNetnameBox->SetStringSelection( UnescapeString( net_name ) );
182  }
183  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightComponent ) )
184  {
185  wxString net_attr = item->GetNetAttributes().m_Cmpref;
186  settings->m_componentHighlightString = net_attr;
187  m_frame->m_SelComponentBox->SetStringSelection( net_attr );
188  }
189  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightAttribute ) )
190  {
191  D_CODE* apertDescr = item->GetDcodeDescr();
192 
193  if( apertDescr )
194  {
195  wxString ap_name = apertDescr->m_AperFunction;
196  settings->m_attributeHighlightString = ap_name;
197  m_frame->m_SelAperAttributesBox->SetStringSelection( ap_name );
198  }
199  }
200  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightDCode ) )
201  {
202  D_CODE* apertDescr = item->GetDcodeDescr();
203 
204  if( apertDescr )
205  {
206  int dcodeSelected = -1;
208 
209  if( gerber )
210  dcodeSelected = apertDescr->m_Num_Dcode;
211 
212  if( dcodeSelected > 0 )
213  {
214  settings->m_dcodeHighlightValue = dcodeSelected;
215  gerber->m_Selected_Tool = dcodeSelected;
216  m_frame->syncLayerBox( false );
217  }
218  }
219  }
220 
222  canvas()->Refresh();
223 
224  return 0;
225 }
226 
227 
229 {
230  bool state;
231  bool needs_refresh = false;
232  auto options = m_frame->GetDisplayOptions();
233 
235  {
236  options.m_DisplayLinesFill = !options.m_DisplayLinesFill;
237  needs_refresh = true;
238  }
240  {
241  options.m_DisplayFlashedItemsFill = !options.m_DisplayFlashedItemsFill;
242  needs_refresh = true;
243  }
245  {
246  options.m_DisplayPolygonsFill = !options.m_DisplayPolygonsFill;
247  needs_refresh = true;
248  }
250  {
253  }
254  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::dcodeDisplay ) )
255  {
258  }
259  else if( aEvent.IsAction( &ACTIONS::highContrastMode ) )
260  {
261  options.m_HighContrastMode = !options.m_HighContrastMode;
262  needs_refresh = true;
263  }
264  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::toggleDiffMode ) )
265  {
266  options.m_DiffMode = !options.m_DiffMode;
267  needs_refresh = true;
268  }
269  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::flipGerberView ) )
270  {
271  options.m_FlipGerberView = !options.m_FlipGerberView;
272 
273  KIGFX::VIEW* view = canvas()->GetView();
274  view->SetMirror( options.m_FlipGerberView, false );
275  needs_refresh = true;
276  }
277 
278  if( needs_refresh )
279  m_frame->UpdateDisplayOptions( options );
280 
281  return 0;
282 }
283 
284 
286 {
287  int layer = m_frame->GetActiveLayer();
288 
289  if( layer < GERBER_DRAWLAYERS_COUNT - 1 )
290  m_frame->SetActiveLayer( layer + 1, true );
291 
292  return 0;
293 }
294 
295 
297 {
298  int layer = m_frame->GetActiveLayer();
299 
300  if( layer > 0 )
301  m_frame->SetActiveLayer( layer - 1, true );
302 
303  return 0;
304 }
305 
306 
308 {
311 
312  return 0;
313 }
314 
315 
317 {
318  m_frame->Clear_DrawLayers( false );
320  canvas()->Refresh();
322 
323  return 0;
324 }
325 
326 
328 {
329  // Store filenames
330  wxArrayString listOfGerberFiles;
331  std::vector<int> fileType;
333 
334  for( unsigned i = 0; i < list->ImagesMaxCount(); i++ )
335  {
336  if( list->GetGbrImage( i ) == nullptr )
337  continue;
338 
339  if( !list->GetGbrImage( i )->m_InUse )
340  continue;
341 
342  EXCELLON_IMAGE* drill_file = dynamic_cast<EXCELLON_IMAGE*>( list->GetGbrImage( i ) );
343 
344  if( drill_file )
345  fileType.push_back( 1 );
346  else
347  fileType.push_back( 0 );
348 
349  listOfGerberFiles.Add( list->GetGbrImage( i )->m_FileName );
350  }
351 
352  // Clear all layers
353  m_frame->Clear_DrawLayers( false );
355 
356  // Load the layers from stored paths
357  wxBusyCursor wait;
358  m_frame->LoadListOfGerberAndDrillFiles( wxEmptyString, listOfGerberFiles, &fileType );
359 
360  return 0;
361 }
362 
363 
365 {
367  GERBVIEW_SELECTION& selection = selTool->GetSelection();
368 
369  if( selection.GetSize() == 1 )
370  {
371  EDA_ITEM* item = (EDA_ITEM*) selection.Front();
372 
373  MSG_PANEL_ITEMS msgItems;
374  item->GetMsgPanelInfo( m_frame, msgItems );
375  m_frame->SetMsgPanel( msgItems );
376  }
377  else
378  {
379  m_frame->EraseMsgBox();
380  }
381 
382  return 0;
383 }
384 
385 
387 {
394  Go( &GERBVIEW_CONTROL::Print, ACTIONS::print.MakeEvent() );
395 
401 
407 
416 
420 }
int OpenJobFile(const TOOL_EVENT &aEvent)
int OpenGerber(const TOOL_EVENT &aEvent)
static const TOOL_EVENT SelectedEvent
Definition: actions.h:201
D_CODE * GetDcodeDescr() const
Return the GetDcodeDescr of this object, or NULL.
bool Clear_DrawLayers(bool query)
static TOOL_ACTION openDrillFile
GERBVIEW_FRAME * m_frame
void SetMruPath(const wxString &aPath)
static TOOL_ACTION openGerber
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:202
int OpenZipFile(const TOOL_EVENT &aEvent)
This file is part of the common library.
void syncLayerBox(bool aRebuildLayerBox=false)
Update the currently "selected" layer within m_SelLayerBox.
int Print(const TOOL_EVENT &aEvent)
Set up handlers for various events.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
static TOOL_ACTION clearAllLayers
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition: view.cpp:1415
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int LayerPrev(const TOOL_EVENT &aEvent)
Hold the image data and parameters for one gerber file and layer parameters.
void SetActiveLayer(int aLayer, bool doLayerWidgetUpdate=true)
change the currently active layer to aLayer and update the GERBER_LAYER_WIDGET.
static TOOL_ACTION layerNext
static TOOL_ACTION zoomFitScreen
Definition: actions.h:99
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
wxString m_Cmpref
the component reference parent of the data
const GBR_DISPLAY_OPTIONS & GetDisplayOptions() const
static TOOL_ACTION exportToPcbnew
static TOOL_ACTION toggleLayerManager
const std::string KiCadPcbFileExtension
int UpdateMessagePanel(const TOOL_EVENT &aEvent)
static TOOL_ACTION print
Definition: actions.h:60
void SetMirror(bool aMirrorX, bool aMirrorY)
Control the mirroring of the VIEW.
Definition: view.cpp:541
Color has changed.
Definition: view_item.h:53
void Erase_Current_DrawLayer(bool query)
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
int HighlightControl(const TOOL_EVENT &aEvent)
static TOOL_ACTION highlightNet
int ClearLayer(const TOOL_EVENT &aEvent)
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).
static TOOL_ACTION layerPrev
static TOOL_ACTION dcodeDisplay
static TOOL_ACTION negativeObjectDisplay
wxChoice * m_SelNetnameBox
bool m_DisplayLinesFill
Option to draw line items (filled/sketch)
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
Definition: tool_event.cpp:70
static TOOL_ACTION toggleDiffMode
bool LoadGerberJobFile(const wxString &aFileName)
Load a Gerber job file, and load gerber files found in job files.
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
wxString GetMruPath() const
static TOOL_ACTION flipGerberView
void UpdateDisplayOptions(const GBR_DISPLAY_OPTIONS &aOptions)
Update the display options and refreshes the view as needed.
int ReloadAllLayers(const TOOL_EVENT &aEvent)
#define GERBER_DRAWLAYERS_COUNT
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
GERBER_FILE_IMAGE * GetGbrImage(int aIdx)
bool LoadGerberFiles(const wxString &aFileName)
Load a photoplot (Gerber) file or many files.
bool LoadListOfGerberAndDrillFiles(const wxString &aPath, const wxArrayString &aFilenameList, const std::vector< int > *aFileType=nullptr)
Load a list of Gerber and NC drill files and updates the view based on them.
static TOOL_ACTION highlightAttribute
GERBER_FILE_IMAGE * GetGbrImage(int aIdx) const
virtual void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: eda_item.h:264
bool LoadZipArchiveFile(const wxString &aFileName)
Load a zipped archive file.
static TOOL_ACTION linesDisplayOutlines
int m_Num_Dcode
D code value ( >= 10 )
Definition: dcode.h:96
Generic, UI-independent tool event.
Definition: tool_event.h:173
static TOOL_ACTION openJobFile
Definition of file extensions used in Kicad.
bool IsElementVisible(int aLayerID) const
Test whether a given element category is visible.
wxString m_Netname
for items associated to a net: the netname
virtual KIGFX::VIEW * GetView() const
Return a pointer to the #VIEW instance used in the panel.
static const TOOL_EVENT ClearedEvent
Selected item had a property changed (except movement)
Definition: actions.h:203
const GBR_NETLIST_METADATA & GetNetAttributes() const
GERBVIEW_SELECTION & GetSelection()
Return the set of currently selected items.
FormatType fileType(const char *aFileName)
Definition: loadmodel.cpp:273
virtual void ClearMsgPanel()
Clear all messages from the message panel.
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
int LAYER_NUM
This can be replaced with int and removed.
wxString m_AperFunction
the aperture attribute (created by a TA.AperFunction command) attached to the D_CODE
Definition: dcode.h:105
static TOOL_ACTION flashedDisplayOutlines
GBR_LAYOUT * GetGerberLayout() const
static TOOL_ACTION clearLayer
int GetActiveLayer() const
Return the active layer.
Selection tool for GerbView, based on the one in Pcbnew.
wxChoice * m_SelAperAttributesBox
D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
int LayerNext(const TOOL_EVENT &aEvent)
static TOOL_ACTION highlightClear
#define _(s)
Definition: 3d_actions.cpp:33
int OpenDrillFile(const TOOL_EVENT &aEvent)
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:151
static TOOL_ACTION polygonsDisplayOutlines
int ExportToPcbnew(const TOOL_EVENT &aEvent)
EDA_DRAW_PANEL_GAL * canvas()
GERBER_FILE_IMAGE_LIST * GetImagesList() const
Definition: gbr_layout.cpp:41
wxString PcbFileWildcard()
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
std::vector< MSG_PANEL_ITEM > MSG_PANEL_ITEMS
Definition: msgpanel.h:97
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
wxChoice * m_SelComponentBox
static TOOL_ACTION highlightDCode
bool LoadExcellonFiles(const wxString &aFileName)
Load a drill (EXCELLON) file or many files.
bool ExportPcb(const LAYER_NUM *aLayerLookUpTable, int aCopperLayers)
Function ExportPcb saves a board from a set of Gerber images.
int DisplayControl(const TOOL_EVENT &aEvent)
int ToggleLayerManager(const TOOL_EVENT &aEvent)
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:67
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:280
static TOOL_ACTION highContrastMode
Definition: actions.h:106
GERBER_FILE_IMAGE_LIST * GetImagesList() const
Accessors to GERBER_FILE_IMAGE_LIST and GERBER_FILE_IMAGE data.
A helper class to export a Gerber set of files to Pcbnew.
void SetElementVisibility(int aLayerID, bool aNewState)
Change the visibility of an element category.
int ClearAllLayers(const TOOL_EVENT &aEvent)
static TOOL_ACTION reloadAllLayers
static TOOL_ACTION openZipFile
static TOOL_ACTION highlightComponent