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 
35 #include "gerbview_actions.h"
36 #include "gerbview_control.h"
38 
39 
40 GERBVIEW_CONTROL::GERBVIEW_CONTROL() : TOOL_INTERACTIVE( "gerbview.Control" ), m_frame( nullptr )
41 {
42 }
43 
44 
46 {
47  m_frame = getEditFrame<GERBVIEW_FRAME>();
48 }
49 
50 
52 {
53  m_frame->LoadGerberFiles( wxEmptyString );
54  // loadListOfGerberAndDrillFiles() refreshes the canvas
55 
56  return 0;
57 }
58 
59 
61 {
62  m_frame->LoadExcellonFiles( wxEmptyString );
63  canvas()->Refresh();
64 
65  return 0;
66 }
67 
68 
70 {
71  m_frame->LoadGerberJobFile( wxEmptyString );
72  canvas()->Refresh();
73 
74  return 0;
75 }
76 
77 
79 {
80  m_frame->LoadZipArchiveFile( wxEmptyString );
81  canvas()->Refresh();
82 
83  return 0;
84 }
85 
86 
88 {
90 
91  return 0;
92 }
93 
94 
96 {
97  int layercount = 0;
98 
100 
101  // Count the Gerber layers which are actually currently used
102  for( LAYER_NUM ii = 0; ii < (LAYER_NUM)images->ImagesMaxCount(); ++ii )
103  {
104  if( images->GetGbrImage( ii ) )
105  layercount++;
106  }
107 
108  if( layercount == 0 )
109  {
110  DisplayInfoMessage( m_frame, _( "None of the Gerber layers contain any data" ) );
111  return 0;
112  }
113 
114  wxString fileDialogName( wxT( "noname." ) + KiCadPcbFileExtension );
115  wxString path = m_frame->GetMruPath();
116 
117  wxFileDialog filedlg( m_frame, _( "Board File Name" ), path, fileDialogName, PcbFileWildcard(),
118  wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
119 
120  if( filedlg.ShowModal() == wxID_CANCEL )
121  return 0;
122 
123  wxFileName fileName = filedlg.GetPath();
124 
125  /* Install a dialog frame to choose the mapping
126  * between gerber layers and Pcbnew layers
127  */
128  LAYERS_MAP_DIALOG* layerdlg = new LAYERS_MAP_DIALOG( m_frame );
129  int ok = layerdlg->ShowModal();
130  layerdlg->Destroy();
131 
132  if( ok != wxID_OK )
133  return 0;
134 
135  // If no extension was entered, then force the extension to be a KiCad PCB file
136  if( !fileName.HasExt() )
137  fileName.SetExt( KiCadPcbFileExtension );
138 
139  m_frame->SetMruPath( fileName.GetPath() );
140 
141  GBR_TO_PCB_EXPORTER gbr_exporter( m_frame, fileName.GetFullPath() );
142 
143  gbr_exporter.ExportPcb( layerdlg->GetLayersLookUpTable(), layerdlg->GetCopperLayersCount() );
144 
145  return 0;
146 }
147 
148 
150 {
151  auto settings = static_cast<KIGFX::GERBVIEW_PAINTER*>( getView()->GetPainter() )->GetSettings();
152  const auto& selection = m_toolMgr->GetTool<GERBVIEW_SELECTION_TOOL>()->GetSelection();
153  GERBER_DRAW_ITEM* item = nullptr;
154 
155  if( selection.Size() == 1 )
156  {
157  item = static_cast<GERBER_DRAW_ITEM*>( selection[0] );
158  }
159 
161  {
162  m_frame->m_SelComponentBox->SetSelection( 0 );
163  m_frame->m_SelNetnameBox->SetSelection( 0 );
164  m_frame->m_SelAperAttributesBox->SetSelection( 0 );
165 
166  settings->m_netHighlightString = "";
167  settings->m_componentHighlightString = "";
168  settings->m_attributeHighlightString = "";
169  }
170  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightNet ) )
171  {
172  auto string = item->GetNetAttributes().m_Netname;
173  settings->m_netHighlightString = string;
174  m_frame->m_SelNetnameBox->SetStringSelection( UnescapeString( string ) );
175  }
176  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightComponent ) )
177  {
178  auto string = item->GetNetAttributes().m_Cmpref;
179  settings->m_componentHighlightString = string;
180  m_frame->m_SelComponentBox->SetStringSelection( string );
181  }
182  else if( item && aEvent.IsAction( &GERBVIEW_ACTIONS::highlightAttribute ) )
183  {
184  D_CODE* apertDescr = item->GetDcodeDescr();
185 
186  if( apertDescr )
187  {
188  auto string = apertDescr->m_AperFunction;
189  settings->m_attributeHighlightString = string;
190  m_frame->m_SelAperAttributesBox->SetStringSelection( string );
191  }
192  }
193 
195  canvas()->Refresh();
196 
197  return 0;
198 }
199 
200 
202 {
203  bool state;
204  bool needs_refresh = false;
205  auto options = m_frame->GetDisplayOptions();
206 
208  {
209  options.m_DisplayLinesFill = !options.m_DisplayLinesFill;
210  needs_refresh = true;
211  }
213  {
214  options.m_DisplayFlashedItemsFill = !options.m_DisplayFlashedItemsFill;
215  needs_refresh = true;
216  }
218  {
219  options.m_DisplayPolygonsFill = !options.m_DisplayPolygonsFill;
220  needs_refresh = true;
221  }
223  {
226  }
227  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::dcodeDisplay ) )
228  {
231  }
232  else if( aEvent.IsAction( &ACTIONS::highContrastMode ) )
233  {
234  options.m_HighContrastMode = !options.m_HighContrastMode;
235  needs_refresh = true;
236  }
237  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::toggleDiffMode ) )
238  {
239  options.m_DiffMode = !options.m_DiffMode;
240  needs_refresh = true;
241  }
242  else if( aEvent.IsAction( &GERBVIEW_ACTIONS::flipGerberView ) )
243  {
244  options.m_FlipGerberView = !options.m_FlipGerberView;
245 
246  KIGFX::VIEW* view = canvas()->GetView();
247  view->SetMirror( options.m_FlipGerberView, false );
248  needs_refresh = true;
249  }
250 
251  if( needs_refresh )
252  m_frame->UpdateDisplayOptions( options );
253 
254  return 0;
255 }
256 
257 
259 {
260  int layer = m_frame->GetActiveLayer();
261 
262  if( layer < GERBER_DRAWLAYERS_COUNT - 1 )
263  m_frame->SetActiveLayer( layer + 1, true );
264 
265  return 0;
266 }
267 
268 
270 {
271  int layer = m_frame->GetActiveLayer();
272 
273  if( layer > 0 )
274  m_frame->SetActiveLayer( layer - 1, true );
275 
276  return 0;
277 }
278 
279 
281 {
284 
285  return 0;
286 }
287 
288 
290 {
291  m_frame->Clear_DrawLayers( false );
293  canvas()->Refresh();
295 
296  return 0;
297 }
298 
299 
301 {
302  // Store filenames
303  wxArrayString listOfGerberFiles;
304  std::vector<int> fileType;
306 
307  for( unsigned i = 0; i < list->ImagesMaxCount(); i++ )
308  {
309  if( list->GetGbrImage( i ) == nullptr )
310  continue;
311 
312  if( !list->GetGbrImage( i )->m_InUse )
313  continue;
314 
315  EXCELLON_IMAGE* drill_file = dynamic_cast<EXCELLON_IMAGE*>( list->GetGbrImage( i ) );
316 
317  if( drill_file )
318  fileType.push_back( 1 );
319  else
320  fileType.push_back( 0 );
321 
322  listOfGerberFiles.Add( list->GetGbrImage( i )->m_FileName );
323  }
324 
325  // Clear all layers
326  m_frame->Clear_DrawLayers( false );
328 
329  // Load the layers from stored paths
330  wxBusyCursor wait;
331  m_frame->LoadListOfGerberAndDrillFiles( wxEmptyString, listOfGerberFiles, &fileType );
332 
333  return 0;
334 }
335 
336 
338 {
340  GERBVIEW_SELECTION& selection = selTool->GetSelection();
341 
342  if( selection.GetSize() == 1 )
343  {
344  EDA_ITEM* item = (EDA_ITEM*) selection.Front();
345 
346  MSG_PANEL_ITEMS msgItems;
347  item->GetMsgPanelInfo( m_frame, msgItems );
348  m_frame->SetMsgPanel( msgItems );
349  }
350  else
351  {
352  m_frame->EraseMsgBox();
353  }
354 
355  return 0;
356 }
357 
358 
360 {
367  Go( &GERBVIEW_CONTROL::Print, ACTIONS::print.MakeEvent() );
368 
373 
379 
388 
392 }
int OpenJobFile(const TOOL_EVENT &aEvent)
int OpenGerber(const TOOL_EVENT &aEvent)
static const TOOL_EVENT SelectedEvent
Definition: actions.h:209
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:210
int OpenZipFile(const TOOL_EVENT &aEvent)
This file is part of the common library.
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:1412
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
int LayerPrev(const TOOL_EVENT &aEvent)
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: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: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
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:263
bool LoadZipArchiveFile(const wxString &aFileName)
Load a zipped archive file.
static TOOL_ACTION linesDisplayOutlines
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:211
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:150
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:149
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
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:281
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