KiCad PCB EDA Suite
dialog_fp_plugin_options.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) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
5  * Copyright (C) 2013 CERN
6  * Copyright (C) 2013-2016 KiCad Developers, see change_log.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 
27 #include <fctsys.h>
28 #include <invoke_pcb_dialog.h>
30 #include <fp_lib_table.h>
31 #include <grid_tricks.h>
32 #include <widgets/wx_grid.h>
33 #include <bitmaps.h>
34 
35 
36 #define INITIAL_HELP \
37  _( "Select an <b>Option Choice</b> in the listbox above, and then click the <b>Append Selected Option</b> button." )
38 
39 
40 using std::string;
41 
42 
50 {
51 
52 public:
53  DIALOG_FP_PLUGIN_OPTIONS( wxWindow* aParent, const wxString& aNickname,
54  const wxString& aPluginType, const wxString& aOptions,
55  wxString* aResult ) :
57  m_callers_options( aOptions ),
58  m_result( aResult ),
60  m_grid_widths_dirty( true )
61  {
62  SetTitle( wxString::Format( _( "Options for Library \"%s\"" ), aNickname ) );
63 
64  // Give a bit more room for combobox editors
65  m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
66 
67  m_grid->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows );
68 
69  // add Cut, Copy, and Paste to wxGrid
70  m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
71 
72  // Option Choices Panel:
73 
74  IO_MGR::PCB_FILE_T pi_type = IO_MGR::EnumFromStr( aPluginType );
75  PLUGIN::RELEASER pi( IO_MGR::PluginFind( pi_type ) );
76 
78 
79  if( m_choices.size() )
80  {
81  unsigned int row = 0;
82  for( PROPERTIES::const_iterator it = m_choices.begin(); it != m_choices.end(); ++it, ++row )
83  {
84  wxString item = FROM_UTF8( it->first.c_str() );
85 
86  m_listbox->InsertItems( 1, &item, row );
87  }
88  }
89 
90  m_html->SetPage( m_initial_help );
91 
92  // Configure button logos
93  m_append_button->SetBitmap( KiBitmap( small_plus_xpm ) );
94  m_delete_button->SetBitmap( KiBitmap( trash_xpm ) );
95 
96  // initial focus on the grid please.
98 
99  m_sdbSizer1OK->SetDefault();
100  }
101 
103  {
104  // destroy GRID_TRICKS before m_grid.
105  m_grid->PopEventHandler( true );
106  }
107 
108  bool TransferDataToWindow() override
109  {
110  if( !DIALOG_SHIM::TransferDataToWindow() )
111  return false;
112 
113  // Fill the grid with existing aOptions
114  string options = TO_UTF8( m_callers_options );
115 
116  PROPERTIES* props = LIB_TABLE::ParseOptions( options );
117 
118  if( props )
119  {
120  if( (int) props->size() > m_grid->GetNumberRows() )
121  m_grid->AppendRows( props->size() - m_grid->GetNumberRows() );
122 
123  int row = 0;
124  for( PROPERTIES::const_iterator it = props->begin(); it != props->end(); ++it, ++row )
125  {
126  m_grid->SetCellValue( row, 0, FROM_UTF8( it->first.c_str() ) );
127  m_grid->SetCellValue( row, 1, it->second );
128  }
129 
130  delete props;
131  }
132 
133  return true;
134  }
135 
136  bool TransferDataFromWindow() override
137  {
138  if( !m_grid->CommitPendingChanges() )
139  return false;
140 
141  if( !DIALOG_SHIM::TransferDataFromWindow() )
142  return false;
143 
144  PROPERTIES props;
145  const int rowCount = m_grid->GetNumberRows();
146 
147  for( int row = 0; row<rowCount; ++row )
148  {
149  string name = TO_UTF8( m_grid->GetCellValue( row, 0 ).Trim( false ).Trim() );
150  UTF8 value = m_grid->GetCellValue( row, 1 ).Trim( false ).Trim();
151 
152  if( name.size() )
153  {
154  props[name] = value;
155  }
156  }
157 
158  *m_result = LIB_TABLE::FormatOptions( &props );
159  return true;
160  }
161 
162 private:
163  const wxString& m_callers_options;
164  wxString* m_result;
166  wxString m_initial_help;
168 
169  int appendRow()
170  {
171  int row = m_grid->GetNumberRows();
172 
173  m_grid->AppendRows( 1 );
174 
175  // wx documentation is wrong, SetGridCursor does not make visible.
176  m_grid->MakeCellVisible( row, 0 );
177  m_grid->SetGridCursor( row, 0 );
178 
179  return row;
180  }
181 
183  {
184  int selected_row = m_listbox->GetSelection();
185  if( selected_row != wxNOT_FOUND )
186  {
187  wxString option = m_listbox->GetString( selected_row );
188 
189  int row_count = m_grid->GetNumberRows();
190  int row;
191 
192  for( row=0; row<row_count; ++row )
193  {
194  wxString col0 = m_grid->GetCellValue( row, 0 );
195 
196  if( !col0 ) // empty col0
197  break;
198  }
199 
200  if( row == row_count )
201  row = appendRow();
202 
203  m_grid->SetCellValue( row, 0, option );
204  m_grid_widths_dirty = true;
205  }
206  }
207 
208  //-----<event handlers>------------------------------------------------------
209 
210  void onListBoxItemSelected( wxCommandEvent& event ) override
211  {
212  // change the help text based on the m_listbox selection:
213  if( event.IsSelection() )
214  {
215  string option = TO_UTF8( event.GetString() );
216  UTF8 help_text;
217 
218  if( m_choices.Value( option.c_str(), &help_text ) )
219  m_html->SetPage( help_text );
220  else
221  m_html->SetPage( m_initial_help );
222  }
223  }
224 
225  void onListBoxItemDoubleClicked( wxCommandEvent& event ) override
226  {
227  appendOption();
228  }
229 
230  void onAppendOption( wxCommandEvent& ) override
231  {
232  if( !m_grid->CommitPendingChanges() )
233  return;
234 
235  appendOption();
236  }
237 
238  void onAppendRow( wxCommandEvent& ) override
239  {
240  if( !m_grid->CommitPendingChanges() )
241  return;
242 
243  appendRow();
244  }
245 
246  void onDeleteRow( wxCommandEvent& ) override
247  {
248  if( !m_grid->CommitPendingChanges() )
249  return;
250 
251  int curRow = m_grid->GetGridCursorRow();
252 
253  m_grid->DeleteRows( curRow );
254  m_grid_widths_dirty = true;
255 
256  curRow = std::max( 0, curRow - 1 );
257  m_grid->MakeCellVisible( curRow, m_grid->GetGridCursorCol() );
258  m_grid->SetGridCursor( curRow, m_grid->GetGridCursorCol() );
259  }
260 
261  void onGridCellChange( wxGridEvent& aEvent ) override
262  {
263  m_grid_widths_dirty = true;
264 
265  aEvent.Skip();
266  }
267 
268  void onUpdateUI( wxUpdateUIEvent& ) override
269  {
270  if( m_grid_widths_dirty && !m_grid->IsCellEditControlShown() )
271  {
272  int width = m_grid->GetClientRect().GetWidth();
273 
274  m_grid->AutoSizeColumn( 0 );
275  m_grid->SetColSize( 0, std::max( 120, m_grid->GetColSize( 0 ) ) );
276 
277  m_grid->SetColSize( 1, width - m_grid->GetColSize( 0 ) );
278 
279  m_grid_widths_dirty = false;
280  }
281  }
282 
283  void onSize( wxSizeEvent& aEvent ) override
284  {
285  m_grid_widths_dirty = true;
286 
287  aEvent.Skip();
288  }
289 };
290 
291 
292 void InvokePluginOptionsEditor( wxWindow* aCaller, const wxString& aNickname,
293  const wxString& aPluginType, const wxString& aOptions,
294  wxString* aResult )
295 {
296  DIALOG_FP_PLUGIN_OPTIONS dlg( aCaller, aNickname, aPluginType, aOptions, aResult );
297 
298  dlg.ShowModal();
299 }
Class UTF8 is an 8 bit string that is assuredly encoded in UTF8, and supplies special conversion supp...
Definition: utf8.h:73
void onGridCellChange(wxGridEvent &aEvent) override
DIALOG_FP_PLUGIN_OPTIONS(wxWindow *aParent, const wxString &aNickname, const wxString &aPluginType, const wxString &aOptions, wxString *aResult)
Class DIALOG_FP_PLUGIN_OPTIONS_BASE.
void InvokePluginOptionsEditor(wxWindow *aCaller, const wxString &aNickname, const wxString &aPluginType, const wxString &aOptions, wxString *aResult)
Function InvokePluginOptionsEditor calls DIALOG_FP_PLUGIN_OPTIONS dialog so that plugin options set c...
static wxString FROM_UTF8(const char *cstring)
function FROM_UTF8 converts a UTF8 encoded C string to a wxString for all wxWidgets build modes...
Definition: macros.h:53
void onSize(wxSizeEvent &aEvent) override
#define INITIAL_HELP
bool Value(const char *aName, UTF8 *aFetchedValue=NULL) const
Function Value fetches a property by aName and returns true if that property was found, else false.
Definition: properties.cpp:24
Class GRID_TRICKS is used to add cut, copy, and paste to an otherwise unmodied wxGrid instance...
Definition: grid_tricks.h:51
void onAppendOption(wxCommandEvent &) override
Class PROPERTIES is a name/value tuple with unique names and optional values.
Definition: properties.h:34
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:86
static UTF8 FormatOptions(const PROPERTIES *aProperties)
Returns a list of options from the aProperties parameter.
Class RELEASER releases a PLUGIN in the context of a potential thrown exception, through its destruct...
Definition: io_mgr.h:563
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes...
Definition: macros.h:47
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
static PROPERTIES * ParseOptions(const std::string &aOptionsList)
Parses aOptionsList and places the result into a PROPERTIES object which is returned.
static PCB_FILE_T EnumFromStr(const wxString &aFileType)
Function EnumFromStr returns the PCB_FILE_T from the corresponding plugin type name: "kicad"...
Definition: io_mgr.cpp:93
Class DIALOG_FP_PLUGIN_OPTIONS is an options editor in the form of a two column name/value spreadshee...
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:156
void onDeleteRow(wxCommandEvent &) override
void onUpdateUI(wxUpdateUIEvent &) override
void onListBoxItemSelected(wxCommandEvent &event) override
const char * name
Definition: DXF_plotter.cpp:61
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define max(a, b)
Definition: auxiliary.h:86
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Function PluginFind returns a PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: io_mgr.cpp:58
void onAppendRow(wxCommandEvent &) override
void onListBoxItemDoubleClicked(wxCommandEvent &event) override
PCB_FILE_T
Enum PCB_FILE_T is a set of file types that the IO_MGR knows about, and for which there has been a pl...
Definition: io_mgr.h:52
virtual void FootprintLibOptions(PROPERTIES *aListToAppendTo) const
Function FootprintLibOptions appends supported PLUGIN options to aListToAppenTo along with internatio...
Definition: plugin.cpp:132