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 <project.h>
33 #include <view/view.h>
35 #include <wx/filedlg.h>
36 
37 #include "gerbview_actions.h"
38 #include "gerbview_control.h"
40 
41 
42 GERBVIEW_CONTROL::GERBVIEW_CONTROL() : TOOL_INTERACTIVE( "gerbview.Control" ), m_frame( nullptr )
43 {
44 }
45 
46 
48 {
49  m_frame = getEditFrame<GERBVIEW_FRAME>();
50 }
51 
52 
54 {
55  m_frame->LoadGerberFiles( wxEmptyString );
56  // loadListOfGerberAndDrillFiles() refreshes the canvas
57 
58  return 0;
59 }
60 
61 
63 {
64  m_frame->LoadExcellonFiles( wxEmptyString );
65  canvas()->Refresh();
66 
67  return 0;
68 }
69 
70 
72 {
73  m_frame->LoadGerberJobFile( wxEmptyString );
74  canvas()->Refresh();
75 
76  return 0;
77 }
78 
79 
81 {
82  m_frame->LoadZipArchiveFile( wxEmptyString );
83  canvas()->Refresh();
84 
85  return 0;
86 }
87 
88 
90 {
92 
93  return 0;
94 }
95 
96 
98 {
99  int layercount = 0;
100 
102 
103  // Count the Gerber layers which are actually currently used
104  for( LAYER_NUM ii = 0; ii < (LAYER_NUM)images->ImagesMaxCount(); ++ii )
105  {
106  if( images->GetGbrImage( ii ) )
107  layercount++;
108  }
109 
110  if( layercount == 0 )
111  {
112  DisplayInfoMessage( m_frame, _( "None of the Gerber layers contain any data" ) );
113  return 0;
114  }
115 
116  wxString fileDialogName( NAMELESS_PROJECT + wxT( "." ) + KiCadPcbFileExtension );
117  wxString path = m_frame->GetMruPath();
118 
119  wxFileDialog filedlg( m_frame, _( "Board File Name" ), path, fileDialogName, PcbFileWildcard(),
120  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
121 
122  if( filedlg.ShowModal() == wxID_CANCEL )
123  return 0;
124 
125  wxFileName fileName = filedlg.GetPath();
126 
127  /* Install a dialog frame to choose the mapping
128  * between gerber layers and Pcbnew layers
129  */
130  LAYERS_MAP_DIALOG* layerdlg = new LAYERS_MAP_DIALOG( m_frame );
131  int ok = layerdlg->ShowModal();
132  layerdlg->Destroy();
133 
134  if( ok != wxID_OK )
135  return 0;
136 
137  // If no extension was entered, then force the extension to be a KiCad PCB file
138  if( !fileName.HasExt() )
139  fileName.SetExt( KiCadPcbFileExtension );
140 
141  m_frame->SetMruPath( fileName.GetPath() );
142 
143  GBR_TO_PCB_EXPORTER gbr_exporter( m_frame, fileName.GetFullPath() );
144 
145  gbr_exporter.ExportPcb( layerdlg->GetLayersLookUpTable(), layerdlg->GetCopperLayersCount() );
146 
147  return 0;
148 }
149 
150 
152 {
153  auto settings = static_cast<KIGFX::GERBVIEW_PAINTER*>( getView()->GetPainter() )->GetSettings();
154  const auto& selection = m_toolMgr->GetTool<GERBVIEW_SELECTION_TOOL>()->GetSelection();
155  GERBER_DRAW_ITEM* item = nullptr;
156 
157  if( selection.Size() == 1 )
158  {
159  item = static_cast<GERBER_DRAW_ITEM*>( selection[0] );
160  }
161 
163  {
164  m_frame->m_SelComponentBox->SetSelection( 0 );
165  m_frame->m_SelNetnameBox->SetSelection( 0 );
166  m_frame->m_SelAperAttributesBox->SetSelection( 0 );
167 
168  settings->m_netHighlightString = "";
169  settings->m_componentHighlightString = "";
170  settings->m_attributeHighlightString = "";
171  settings->m_dcodeHighlightValue = -1;
172 
174 
175  if( gerber )
176  gerber->m_Selected_Tool = settings->m_dcodeHighlightValue;
177  }
178  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightNet ) )
179  {
180  wxString net_name = item->GetNetAttributes().m_Netname;
181  settings->m_netHighlightString = net_name;
182  m_frame->m_SelNetnameBox->SetStringSelection( UnescapeString( net_name ) );
183  }
184  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightComponent ) )
185  {
186  wxString net_attr = item->GetNetAttributes().m_Cmpref;
187  settings->m_componentHighlightString = net_attr;
188  m_frame->m_SelComponentBox->SetStringSelection( net_attr );
189  }
190  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightAttribute ) )
191  {
192  D_CODE* apertDescr = item->GetDcodeDescr();
193 
194  if( apertDescr )
195  {
196  wxString ap_name = apertDescr->m_AperFunction;
197  settings->m_attributeHighlightString = ap_name;
198  m_frame->m_SelAperAttributesBox->SetStringSelection( ap_name );
199  }
200  }
201  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightDCode ) )
202  {
203  D_CODE* apertDescr = item->GetDcodeDescr();
204 
205  if( apertDescr )
206  {
207  int dcodeSelected = -1;
209 
210  if( gerber )
211  dcodeSelected = apertDescr->m_Num_Dcode;
212 
213  if( dcodeSelected > 0 )
214  {
215  settings->m_dcodeHighlightValue = dcodeSelected;
216  gerber->m_Selected_Tool = dcodeSelected;
217  m_frame->syncLayerBox( false );
218  }
219  }
220  }
221 
223  canvas()->Refresh();
224 
225  return 0;
226 }
227 
228 
230 {
231  bool state;
232  bool needs_refresh = false;
233  auto options = m_frame->GetDisplayOptions();
234 
236  {
237  options.m_DisplayLinesFill = !options.m_DisplayLinesFill;
238  needs_refresh = true;
239  }
241  {
242  options.m_DisplayFlashedItemsFill = !options.m_DisplayFlashedItemsFill;
243  needs_refresh = true;
244  }
246  {
247  options.m_DisplayPolygonsFill = !options.m_DisplayPolygonsFill;
248  needs_refresh = true;
249  }
251  {
254  }
255  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::dcodeDisplay ) )
256  {
259  }
260  else if( aEvent.IsAction( &ACTIONS::highContrastMode ) )
261  {
262  options.m_HighContrastMode = !options.m_HighContrastMode;
263  needs_refresh = true;
264  }
265  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::toggleDiffMode ) )
266  {
267  options.m_DiffMode = !options.m_DiffMode;
268  needs_refresh = true;
269  }
270  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::flipGerberView ) )
271  {
272  options.m_FlipGerberView = !options.m_FlipGerberView;
273 
274  KIGFX::VIEW* view = canvas()->GetView();
275  view->SetMirror( options.m_FlipGerberView, false );
276  needs_refresh = true;
277  }
278 
279  if( needs_refresh )
280  m_frame->UpdateDisplayOptions( options );
281 
282  return 0;
283 }
284 
285 
287 {
288  int layer = m_frame->GetActiveLayer();
289 
290  if( layer < GERBER_DRAWLAYERS_COUNT - 1 )
291  m_frame->SetActiveLayer( layer + 1, true );
292 
293  return 0;
294 }
295 
296 
298 {
299  int layer = m_frame->GetActiveLayer();
300 
301  if( layer > 0 )
302  m_frame->SetActiveLayer( layer - 1, true );
303 
304  return 0;
305 }
306 
307 
309 {
312 
313  return 0;
314 }
315 
316 
318 {
319  m_frame->Clear_DrawLayers( false );
321  canvas()->Refresh();
323 
324  return 0;
325 }
326 
327 
329 {
330  // Store filenames
331  wxArrayString listOfGerberFiles;
332  std::vector<int> fileType;
334 
335  for( unsigned i = 0; i < list->ImagesMaxCount(); i++ )
336  {
337  if( list->GetGbrImage( i ) == nullptr )
338  continue;
339 
340  if( !list->GetGbrImage( i )->m_InUse )
341  continue;
342 
343  EXCELLON_IMAGE* drill_file = dynamic_cast<EXCELLON_IMAGE*>( list->GetGbrImage( i ) );
344 
345  if( drill_file )
346  fileType.push_back( 1 );
347  else
348  fileType.push_back( 0 );
349 
350  listOfGerberFiles.Add( list->GetGbrImage( i )->m_FileName );
351  }
352 
353  // Clear all layers
354  m_frame->Clear_DrawLayers( false );
356 
357  // Load the layers from stored paths
358  wxBusyCursor wait;
359  m_frame->LoadListOfGerberAndDrillFiles( wxEmptyString, listOfGerberFiles, &fileType );
360 
361  return 0;
362 }
363 
364 
366 {
368  GERBVIEW_SELECTION& selection = selTool->GetSelection();
369 
370  if( selection.GetSize() == 1 )
371  {
372  EDA_ITEM* item = (EDA_ITEM*) selection.Front();
373 
374  MSG_PANEL_ITEMS msgItems;
375  item->GetMsgPanelInfo( m_frame, msgItems );
376  m_frame->SetMsgPanel( msgItems );
377  }
378  else
379  {
380  m_frame->EraseMsgBox();
381  }
382 
383  return 0;
384 }
385 
386 
388 {
395  Go( &GERBVIEW_CONTROL::Print, ACTIONS::print.MakeEvent() );
396 
402 
408 
417 
421 }
int OpenJobFile(const TOOL_EVENT &aEvent)
int OpenGerber(const TOOL_EVENT &aEvent)
static const TOOL_EVENT SelectedEvent
Definition: actions.h:199
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:200
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:214
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:96
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:143
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:57
void SetMirror(bool aMirrorX, bool aMirrorY)
Control the mirroring of the VIEW.
Definition: view.cpp:540
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:88
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)
Show the Gerber files loaded and allow the user to choose between Gerber layers and pcb layers.
#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:214
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:190
Generic, UI-independent tool event.
Definition: tool_event.h:152
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
#define _(s)
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:201
const GBR_NETLIST_METADATA & GetNetAttributes() const
GERBVIEW_SELECTION & GetSelection()
Return the set of currently selected items.
FormatType fileType(const char *aFileName)
Definition: loadmodel.cpp:274
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
int LAYER_NUM
This can be replaced with int and removed.
wxString m_AperFunction
the aperture attribute (created by a TA.AperFunction command).
Definition: dcode.h:200
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
A gerber DCODE (also called Aperture) definition.
Definition: dcode.h:80
Handle a drill image.
int LayerNext(const TOOL_EVENT &aEvent)
static TOOL_ACTION highlightClear
int OpenDrillFile(const TOOL_EVENT &aEvent)
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:222
static TOOL_ACTION polygonsDisplayOutlines
int ExportToPcbnew(const TOOL_EVENT &aEvent)
#define NAMELESS_PROJECT
default name for nameless projects
Definition: project.h:41
EDA_DRAW_PANEL_GAL * canvas()
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
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:100
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:77
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)
Save 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:275
static TOOL_ACTION highContrastMode
Definition: actions.h:103
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