KiCad PCB EDA Suite
panel_text_variables.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) 2020-2021 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
25
26#include <bitmaps.h>
27#include <confirm.h>
28#include <validators.h>
29#include <project.h>
30#include <grid_tricks.h>
31#include <widgets/wx_grid.h>
32
33#include <algorithm>
34
36{
39};
40
41
42PANEL_TEXT_VARIABLES::PANEL_TEXT_VARIABLES( wxWindow* aParent, PROJECT* aProject ) :
44 m_project( aProject ),
45 m_errorRow( -1 ), m_errorCol( -1 ),
46 m_gridWidthsDirty( true )
47{
50
52
53 // prohibit these characters in the alias names: []{}()%~<>"='`;:.,&?/\|$
54 m_nameValidator.SetStyle( wxFILTER_EXCLUDE_CHAR_LIST );
55 m_nameValidator.SetCharExcludes( wxT( "{}[]()%~<>\"='`;:.,&?/\\|$" ) );
56
57 m_TextVars->PushEventHandler( new GRID_TRICKS( m_TextVars, [this]( wxCommandEvent& aEvent )
58 {
59 OnAddTextVar( aEvent );
60 } ) );
61 m_TextVars->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows );
62
63 // wxFormBuilder doesn't include this event...
64 m_TextVars->Connect( wxEVT_GRID_CELL_CHANGING,
65 wxGridEventHandler( PANEL_TEXT_VARIABLES::OnGridCellChanging ),
66 nullptr, this );
67}
68
69
71{
72 // Delete the GRID_TRICKS.
73 m_TextVars->PopEventHandler( true );
74
75 m_TextVars->Disconnect( wxEVT_GRID_CELL_CHANGING,
76 wxGridEventHandler( PANEL_TEXT_VARIABLES::OnGridCellChanging ),
77 nullptr, this );
78}
79
80
82{
83 std::map<wxString, wxString>& variables = m_project->GetTextVars();
84
85 for( const auto& var : variables )
86 AppendTextVar( var.first, var.second );
87
88 return true;
89}
90
91
92void PANEL_TEXT_VARIABLES::AppendTextVar( const wxString& aName, const wxString& aValue )
93{
94 int i = m_TextVars->GetNumberRows();
95
96 m_TextVars->AppendRows( 1 );
97
98 m_TextVars->SetCellValue( i, TV_NAME_COL, aName );
99
100 wxGridCellAttr* nameCellAttr = m_TextVars->GetOrCreateCellAttr( i, TV_NAME_COL );
101 wxGridCellTextEditor* nameTextEditor = new GRID_CELL_TEXT_EDITOR();
102 nameTextEditor->SetValidator( m_nameValidator );
103 nameCellAttr->SetEditor( nameTextEditor );
104 nameCellAttr->DecRef();
105
106 m_TextVars->SetCellValue( i, TV_VALUE_COL, aValue );
107}
108
109
111{
113 return false;
114
115 for( int row = 0; row < m_TextVars->GetNumberRows(); ++row )
116 {
117 if( m_TextVars->GetCellValue( row, TV_NAME_COL ).IsEmpty() )
118 {
119 m_errorRow = row;
121 m_errorMsg = _( "Variable name cannot be empty." );
122 return false;
123 }
124 }
125
126 std::map<wxString, wxString>& variables = m_project->GetTextVars();
127
128 variables.clear();
129
130 for( int row = 0; row < m_TextVars->GetNumberRows(); ++row )
131 {
132 wxString name = m_TextVars->GetCellValue( row, TV_NAME_COL );
133 wxString value = m_TextVars->GetCellValue( row, TV_VALUE_COL );
134 variables[ name ] = value;
135 }
136
137 return true;
138}
139
140
142{
143 int row = event.GetRow();
144 int col = event.GetCol();
145 wxString text = event.GetString();
146
147 if( text.IsEmpty() && col == TV_NAME_COL )
148 {
149 m_errorMsg = _( "Variable name cannot be empty." );
150 m_errorRow = row;
151 m_errorCol = col;
152
153 event.Veto();
154 }
155}
156
157
158void PANEL_TEXT_VARIABLES::OnAddTextVar( wxCommandEvent& event )
159{
161 return;
162
163 AppendTextVar( wxEmptyString, wxEmptyString );
164
165 m_TextVars->MakeCellVisible( m_TextVars->GetNumberRows() - 1, TV_NAME_COL );
166 m_TextVars->SetGridCursor( m_TextVars->GetNumberRows() - 1, TV_NAME_COL );
167
168 m_TextVars->EnableCellEditControl( true );
169 m_TextVars->ShowCellEditControl();
170}
171
172
173void PANEL_TEXT_VARIABLES::OnRemoveTextVar( wxCommandEvent& event )
174{
175 int curRow = m_TextVars->GetGridCursorRow();
176
177 if( curRow < 0 || m_TextVars->GetNumberRows() <= curRow )
178 return;
179
180 m_TextVars->CommitPendingChanges( true /* silent mode; we don't care if it's valid */ );
181 m_TextVars->DeleteRows( curRow, 1 );
182
183 m_TextVars->MakeCellVisible( std::max( 0, curRow-1 ), m_TextVars->GetGridCursorCol() );
184 m_TextVars->SetGridCursor( std::max( 0, curRow-1 ), m_TextVars->GetGridCursorCol() );
185}
186
187
188void PANEL_TEXT_VARIABLES::OnGridCellChange( wxGridEvent& aEvent )
189{
190 m_gridWidthsDirty = true;
191
192 aEvent.Skip();
193}
194
195
196void PANEL_TEXT_VARIABLES::OnUpdateUI( wxUpdateUIEvent& event )
197{
199 {
200 int width = m_TextVars->GetClientRect().GetWidth();
201
202 m_TextVars->AutoSizeColumn( TV_NAME_COL );
203 m_TextVars->SetColSize( TV_NAME_COL, std::max( m_TextVars->GetColSize( TV_NAME_COL ),
204 120 ) );
205
206 m_TextVars->SetColSize( TV_VALUE_COL, width - m_TextVars->GetColSize( TV_NAME_COL ) );
207 m_gridWidthsDirty = false;
208 }
209
210 // Handle a grid error. This is delayed to OnUpdateUI so that we can change focus
211 // even when the original validation was triggered from a killFocus event (and for
212 // dialog with notebooks, so that the corresponding notebook page can be shown in
213 // the background when triggered from an OK).
214 if( !m_errorMsg.IsEmpty() )
215 {
216 // We will re-enter this routine when the error dialog is displayed, so make
217 // sure we don't keep putting up more dialogs.
218 wxString errorMsg = m_errorMsg;
219 m_errorMsg = wxEmptyString;
220
221 DisplayErrorMessage( this, errorMsg );
222
223 m_TextVars->SetFocus();
224 m_TextVars->MakeCellVisible( m_errorRow, m_errorCol );
225 m_TextVars->SetGridCursor( m_errorRow, m_errorCol );
226
227 m_TextVars->EnableCellEditControl( true );
228 m_TextVars->ShowCellEditControl();
229 }
230}
231
232
233void PANEL_TEXT_VARIABLES::OnGridSize( wxSizeEvent& event )
234{
235 m_gridWidthsDirty = true;
236
237 event.Skip();
238}
239
const char * name
Definition: DXF_plotter.cpp:56
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:105
This class works around a bug in wxGrid where the first keystroke doesn't get sent through the valida...
Definition: validators.h:45
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
Class PANEL_TEXT_VARIABLES_BASE.
bool TransferDataToWindow() override
void OnGridCellChanging(wxGridEvent &event)
void OnUpdateUI(wxUpdateUIEvent &event) override
void OnRemoveTextVar(wxCommandEvent &event) override
bool TransferDataFromWindow() override
void OnAddTextVar(wxCommandEvent &event) override
void OnGridSize(wxSizeEvent &event) override
void AppendTextVar(const wxString &aName, const wxString &aValue)
void OnGridCellChange(wxGridEvent &event) override
wxTextValidator m_nameValidator
PANEL_TEXT_VARIABLES(wxWindow *aParent, PROJECT *aProject)
Container for project specific data.
Definition: project.h:63
virtual std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:82
void ClearRows()
wxWidgets recently added an ASSERT which fires if the position is greater than or equal to the number...
Definition: wx_grid.h:133
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:280
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:299
This file is part of the common library.
#define _(s)
@ TV_VALUE_COL
Custom text control validator definitions.