KiCad PCB EDA Suite
grid_text_button_helpers.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) 2018 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <wx/combo.h>
25 #include <bitmap_types.h>
26 #include <bitmaps.h>
27 #include <kiway.h>
28 #include <kiway_player.h>
29 #include <dialog_shim.h>
30 
32 #include <eda_doc.h>
33 
34 
35 //-------- Renderer ---------------------------------------------------------------------
36 // None required; just render as normal text.
37 
38 
39 
40 //-------- Editor Base Class ------------------------------------------------------------
41 //
42 // Note: this implementation is an adaptation of wxGridCellChoiceEditor
43 
44 
46 {
47  return Combo()->GetValue();
48 }
49 
50 void GRID_CELL_TEXT_BUTTON::SetSize( const wxRect& aRect )
51 {
52  wxRect rect( aRect );
53  rect.Inflate( -1 );
54 
55 #if defined( __WXMAC__ )
56  rect.Inflate( 3 ); // no FOCUS_RING, even on Mac
57 #endif
58 
59  Combo()->SetSize( rect, wxSIZE_ALLOW_MINUS_ONE );
60 }
61 
62 
63 void GRID_CELL_TEXT_BUTTON::StartingKey( wxKeyEvent& event )
64 {
65  // Note: this is a copy of wxGridCellTextEditor's StartingKey()
66 
67  // Since this is now happening in the EVT_CHAR event EmulateKeyPress is no
68  // longer an appropriate way to get the character into the text control.
69  // Do it ourselves instead. We know that if we get this far that we have
70  // a valid character, so not a whole lot of testing needs to be done.
71 
72  wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( Combo() );
73  int ch;
74 
75  bool isPrintable;
76 
77 #if wxUSE_UNICODE
78  ch = event.GetUnicodeKey();
79  if ( ch != WXK_NONE )
80  isPrintable = true;
81  else
82 #endif // wxUSE_UNICODE
83  {
84  ch = event.GetKeyCode();
85  isPrintable = ch >= WXK_SPACE && ch < WXK_START;
86  }
87 
88  switch (ch)
89  {
90  case WXK_DELETE:
91  // Delete the initial character when starting to edit with DELETE.
92  textEntry->Remove(0, 1);
93  break;
94 
95  case WXK_BACK:
96  // Delete the last character when starting to edit with BACKSPACE.
97  {
98  const long pos = textEntry->GetLastPosition();
99  textEntry->Remove(pos - 1, pos);
100  }
101  break;
102 
103  default:
104  if ( isPrintable )
105  textEntry->WriteText(static_cast<wxChar>(ch));
106  break;
107  }
108 }
109 
110 
111 void GRID_CELL_TEXT_BUTTON::BeginEdit( int aRow, int aCol, wxGrid* aGrid )
112 {
113  auto evtHandler = static_cast<wxGridCellEditorEvtHandler*>( m_control->GetEventHandler() );
114 
115  // Don't immediately end if we get a kill focus event within BeginEdit
116  evtHandler->SetInSetFocus( true );
117 
118  m_value = aGrid->GetTable()->GetValue( aRow, aCol );
119 
120  Combo()->SetValue( m_value );
121  Combo()->SetFocus();
122 }
123 
124 
125 bool GRID_CELL_TEXT_BUTTON::EndEdit( int , int , const wxGrid* , const wxString& , wxString *aNewVal )
126 {
127  const wxString value = Combo()->GetValue();
128 
129  if( value == m_value )
130  return false;
131 
132  m_value = value;
133 
134  if( aNewVal )
135  *aNewVal = value;
136 
137  return true;
138 }
139 
140 
141 void GRID_CELL_TEXT_BUTTON::ApplyEdit( int aRow, int aCol, wxGrid* aGrid )
142 {
143  aGrid->GetTable()->SetValue( aRow, aCol, m_value );
144 }
145 
146 
148 {
149 }
150 
151 
156 class TEXT_BUTTON_SYMBOL_CHOOSER : public wxComboCtrl
157 {
158 public:
159  TEXT_BUTTON_SYMBOL_CHOOSER( wxWindow* aParent, DIALOG_SHIM* aParentDlg ) :
160  wxComboCtrl( aParent ),
161  m_dlg( aParentDlg )
162  {
163  SetButtonBitmaps( KiBitmap( small_library_xpm ) );
164  }
165 
166 protected:
167  void DoSetPopupControl( wxComboPopup* popup ) override
168  {
169  m_popup = nullptr;
170  }
171 
172  void OnButtonClick() override
173  {
174  // pick a footprint using the footprint picker.
175  wxString compid = GetValue();
176  KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_SCH_VIEWER_MODAL, true, m_dlg );
177 
178  if( frame->ShowModal( &compid, m_dlg ) )
179  SetValue( compid );
180 
181  frame->Destroy();
182  }
183 
185 };
186 
187 
188 void GRID_CELL_SYMBOL_ID_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
189  wxEvtHandler* aEventHandler )
190 {
191  m_control = new TEXT_BUTTON_SYMBOL_CHOOSER( aParent, m_dlg );
192 
193  wxGridCellEditor::Create(aParent, aId, aEventHandler);
194 }
195 
196 
201 class TEXT_BUTTON_FP_CHOOSER : public wxComboCtrl
202 {
203 public:
204  TEXT_BUTTON_FP_CHOOSER( wxWindow* aParent, DIALOG_SHIM* aParentDlg ) :
205  wxComboCtrl( aParent ),
206  m_dlg( aParentDlg )
207  {
208  SetButtonBitmaps( KiBitmap( small_library_xpm ) );
209  }
210 
211 protected:
212  void DoSetPopupControl( wxComboPopup* popup ) override
213  {
214  m_popup = nullptr;
215  }
216 
217  void OnButtonClick() override
218  {
219  // pick a footprint using the footprint picker.
220  wxString fpid = GetValue();
221  KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_PCB_MODULE_VIEWER_MODAL, true, m_dlg );
222 
223  if( frame->ShowModal( &fpid, m_dlg ) )
224  SetValue( fpid );
225 
226  frame->Destroy();
227  }
228 
230 };
231 
232 
233 void GRID_CELL_FOOTPRINT_ID_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
234  wxEvtHandler* aEventHandler )
235 {
236  m_control = new TEXT_BUTTON_FP_CHOOSER( aParent, m_dlg );
237 
238  wxGridCellEditor::Create(aParent, aId, aEventHandler);
239 }
240 
241 
246 class TEXT_BUTTON_URL : public wxComboCtrl
247 {
248 public:
249  TEXT_BUTTON_URL( wxWindow* aParent, DIALOG_SHIM* aParentDlg ) :
250  wxComboCtrl( aParent ),
251  m_dlg( aParentDlg )
252  {
253  SetButtonBitmaps( KiBitmap( www_xpm ) );
254  }
255 
256 protected:
257  void DoSetPopupControl( wxComboPopup* popup ) override
258  {
259  m_popup = nullptr;
260  }
261 
262  void OnButtonClick() override
263  {
264  wxString filename = GetValue();
265 
266  if( !filename.IsEmpty() && filename != wxT( "~" ) )
267  {
268  wxString uri = ResolveUriByEnvVars( GetValue() );
269  GetAssociatedDocument( m_dlg, uri );
270  }
271  }
272 
274 };
275 
276 
277 void GRID_CELL_URL_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
278  wxEvtHandler* aEventHandler )
279 {
280  m_control = new TEXT_BUTTON_URL( aParent, m_dlg );
281 
282  wxGridCellEditor::Create(aParent, aId, aEventHandler);
283 }
284 
285 
290 class TEXT_BUTTON_FILE_BROWSER : public wxComboCtrl
291 {
292 public:
293  TEXT_BUTTON_FILE_BROWSER( wxWindow* aParent, DIALOG_SHIM* aParentDlg, wxString* aCurrentDir ) :
294  wxComboCtrl( aParent ),
295  m_dlg( aParentDlg ),
296  m_currentDir( aCurrentDir )
297  {
298  SetButtonBitmaps( KiBitmap( folder_xpm ) );
299  }
300 
301 protected:
302  void DoSetPopupControl( wxComboPopup* popup ) override
303  {
304  m_popup = nullptr;
305  }
306 
307  void OnButtonClick() override
308  {
309  wxString path = GetValue();
310 
311  if( path.IsEmpty() )
312  path = *m_currentDir;
313  else
314  path = ExpandEnvVarSubstitutions( path );
315 
316  wxDirDialog dlg( nullptr, _( "Select Path" ), path,
317  wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST );
318 
319  if( dlg.ShowModal() == wxID_OK )
320  {
321  SetValue( dlg.GetPath() );
322  *m_currentDir = dlg.GetPath();
323  }
324  }
325 
327  wxString* m_currentDir;
328 };
329 
330 
331 void GRID_CELL_PATH_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
332  wxEvtHandler* aEventHandler )
333 {
334  m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_currentDir );
335 
336  wxGridCellEditor::Create(aParent, aId, aEventHandler);
337 }
338 
339 
Class KIWAY_PLAYER is a wxFrame capable of the OpenProjectFiles function, meaning it can load a porti...
Definition: kiway_player.h:120
KIWAY & Kiway() const
Function Kiway returns a reference to the KIWAY that this object has an opportunity to participate in...
Definition: kiway_player.h:60
const wxString ResolveUriByEnvVars(const wxString &aUri)
Replace any environment variables in file-path uris (leaving network-path URIs alone).
Definition: common.cpp:456
void StartingKey(wxKeyEvent &event) override
This file is part of the common library.
void Create(wxWindow *aParent, wxWindowID aId, wxEvtHandler *aEventHandler) override
void Create(wxWindow *aParent, wxWindowID aId, wxEvtHandler *aEventHandler) override
TEXT_BUTTON_FILE_BROWSER(wxWindow *aParent, DIALOG_SHIM *aParentDlg, wxString *aCurrentDir)
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, const wxPathList *aPaths)
Function GetAssociatedDocument open a document (file) with the suitable browser.
Definition: eda_doc.cpp:87
Class DIALOG_SHIM may sit in the inheritance tree between wxDialog and any class written by wxFormBui...
Definition: dialog_shim.h:82
TEXT_BUTTON_URL(wxWindow *aParent, DIALOG_SHIM *aParentDlg)
void DoSetPopupControl(wxComboPopup *popup) override
TEXT_BUTTON_SYMBOL_CHOOSER(wxWindow *aParent, DIALOG_SHIM *aParentDlg)
void SetSize(const wxRect &aRect) override
TEXT_BUTTON_FP_CHOOSER(wxWindow *aParent, DIALOG_SHIM *aParentDlg)
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:79
void BeginEdit(int aRow, int aCol, wxGrid *aGrid) override
const wxString ExpandEnvVarSubstitutions(const wxString &aString)
Replace any environment variable references with their values.
Definition: common.cpp:442
VTBL_ENTRY KIWAY_PLAYER * Player(FRAME_T aFrameType, bool doCreate=true, wxTopLevelWindow *aParent=NULL)
Function Player returns the KIWAY_PLAYER* given a FRAME_T.
Definition: kiway.cpp:300
void DoSetPopupControl(wxComboPopup *popup) override
wxComboCtrl * Combo() const
void DoSetPopupControl(wxComboPopup *popup) override
wxString GetValue() const override
void Create(wxWindow *aParent, wxWindowID aId, wxEvtHandler *aEventHandler) override
void ApplyEdit(int aRow, int aCol, wxGrid *aGrid) override
void DoSetPopupControl(wxComboPopup *popup) override
bool Destroy() override
Our version of Destroy() which is virtual from wxWidgets.
void Create(wxWindow *aParent, wxWindowID aId, wxEvtHandler *aEventHandler) override
bool EndEdit(int, int, const wxGrid *, const wxString &, wxString *aNewVal) override
VTBL_ENTRY bool ShowModal(wxString *aResult=NULL, wxWindow *aResultantFocusWindow=NULL)
Function ShowModal puts up this wxFrame as if it were a modal dialog, with all other instantiated wxF...