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 <string_utils.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->ClearHighlightSelections();
169 
171 
172  if( gerber )
173  gerber->m_Selected_Tool = settings->m_dcodeHighlightValue;
174  }
175  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightNet ) )
176  {
177  wxString net_name = item->GetNetAttributes().m_Netname;
178  settings->m_netHighlightString = net_name;
179  m_frame->m_SelNetnameBox->SetStringSelection( UnescapeString( net_name ) );
180  }
181  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightComponent ) )
182  {
183  wxString net_attr = item->GetNetAttributes().m_Cmpref;
184  settings->m_componentHighlightString = net_attr;
185  m_frame->m_SelComponentBox->SetStringSelection( net_attr );
186  }
187  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightAttribute ) )
188  {
189  D_CODE* apertDescr = item->GetDcodeDescr();
190 
191  if( apertDescr )
192  {
193  wxString ap_name = apertDescr->m_AperFunction;
194  settings->m_attributeHighlightString = ap_name;
195  m_frame->m_SelAperAttributesBox->SetStringSelection( ap_name );
196  }
197  }
198  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightDCode ) )
199  {
200  D_CODE* apertDescr = item->GetDcodeDescr();
201 
202  if( apertDescr )
203  {
204  int dcodeSelected = -1;
206 
207  if( gerber )
208  dcodeSelected = apertDescr->m_Num_Dcode;
209 
210  if( dcodeSelected > 0 )
211  {
212  settings->m_dcodeHighlightValue = dcodeSelected;
213  gerber->m_Selected_Tool = dcodeSelected;
214  m_frame->syncLayerBox( false );
215  }
216  }
217  }
218 
220  canvas()->Refresh();
221 
222  return 0;
223 }
224 
225 
227 {
228  bool state;
229  bool needs_refresh = false;
230  auto options = m_frame->GetDisplayOptions();
231 
233  {
234  options.m_DisplayLinesFill = !options.m_DisplayLinesFill;
235  needs_refresh = true;
236  }
238  {
239  options.m_DisplayFlashedItemsFill = !options.m_DisplayFlashedItemsFill;
240  needs_refresh = true;
241  }
243  {
244  options.m_DisplayPolygonsFill = !options.m_DisplayPolygonsFill;
245  needs_refresh = true;
246  }
248  {
251  }
252  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::dcodeDisplay ) )
253  {
256  }
257  else if( aEvent.IsAction( &ACTIONS::highContrastMode ) )
258  {
259  options.m_HighContrastMode = !options.m_HighContrastMode;
260  needs_refresh = true;
261  }
262  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::toggleDiffMode ) )
263  {
264  options.m_DiffMode = !options.m_DiffMode;
265  needs_refresh = true;
266  }
267  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::flipGerberView ) )
268  {
269  options.m_FlipGerberView = !options.m_FlipGerberView;
270 
271  KIGFX::VIEW* view = canvas()->GetView();
272  view->SetMirror( options.m_FlipGerberView, false );
273  needs_refresh = true;
274  }
275 
276  if( needs_refresh )
277  m_frame->UpdateDisplayOptions( options );
278 
279  return 0;
280 }
281 
282 
284 {
285  int layer = m_frame->GetActiveLayer();
286 
287  if( layer < GERBER_DRAWLAYERS_COUNT - 1 )
288  m_frame->SetActiveLayer( layer + 1, true );
289 
290  return 0;
291 }
292 
293 
295 {
296  int layer = m_frame->GetActiveLayer();
297 
298  if( layer > 0 )
299  m_frame->SetActiveLayer( layer - 1, true );
300 
301  return 0;
302 }
303 
304 
306 {
309 
310  return 0;
311 }
312 
313 
315 {
316  m_frame->Clear_DrawLayers( false );
318  canvas()->Refresh();
320 
321  // Clear pending highlight selections, now outdated
323  static_cast<KIGFX::GERBVIEW_PAINTER*>( getView()->GetPainter() )->GetSettings();
324  settings->ClearHighlightSelections();
325 
326  return 0;
327 }
328 
329 
331 {
332  // Store filenames
333  wxArrayString listOfGerberFiles;
334  std::vector<int> fileType;
336 
337  for( unsigned i = 0; i < list->ImagesMaxCount(); i++ )
338  {
339  if( list->GetGbrImage( i ) == nullptr )
340  continue;
341 
342  if( !list->GetGbrImage( i )->m_InUse )
343  continue;
344 
345  EXCELLON_IMAGE* drill_file = dynamic_cast<EXCELLON_IMAGE*>( list->GetGbrImage( i ) );
346 
347  if( drill_file )
348  fileType.push_back( 1 );
349  else
350  fileType.push_back( 0 );
351 
352  listOfGerberFiles.Add( list->GetGbrImage( i )->m_FileName );
353  }
354 
355  // Clear all layers
356  m_frame->Clear_DrawLayers( false );
358 
359  // Load the layers from stored paths
360  wxBusyCursor wait;
361  m_frame->LoadListOfGerberAndDrillFiles( wxEmptyString, listOfGerberFiles, &fileType );
362 
363  return 0;
364 }
365 
366 
368 {
370  GERBVIEW_SELECTION& selection = selTool->GetSelection();
371 
372  if( selection.GetSize() == 1 )
373  {
374  EDA_ITEM* item = (EDA_ITEM*) selection.Front();
375 
376  std::vector<MSG_PANEL_ITEM> msgItems;
377  item->GetMsgPanelInfo( m_frame, msgItems );
378  m_frame->SetMsgPanel( msgItems );
379  }
380  else
381  {
382  m_frame->EraseMsgBox();
383  }
384 
385  return 0;
386 }
387 
388 
390 {
397  Go( &GERBVIEW_CONTROL::Print, ACTIONS::print.MakeEvent() );
398 
404 
410 
419 
423 }
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:1424
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
int LAYER_NUM
This can be replaced with int and removed.
Definition: layer_ids.h:41
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:537
Color has changed.
Definition: view_item.h:48
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.
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 given Gerber file or selected file(s), if the filename is empty.
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
#define GERBER_DRAWLAYERS_COUNT
Definition: layer_ids.h:378
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
void ClearHighlightSelections()
Clear all highlight selections (dcode, net, component, attribute selection)
const GBR_NETLIST_METADATA & GetNetAttributes() const
GERBVIEW_SELECTION & GetSelection()
Return the set of currently selected items.
FormatType fileType(const char *aFileName)
Definition: loadmodel.cpp:278
Store GerbView specific render settings.
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
wxString UnescapeString(const wxString &aSource)
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)
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
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:68
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:307
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