KiCad PCB EDA Suite
Loading...
Searching...
No Matches
lib_table_grid_data_model.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
21#include <string_utils.h>
23#include <widgets/grid_button.h>
24#include <bitmaps.h>
26
27
29 const LIBRARY_TABLE& aTableToEdit,
31 const wxArrayString& aPluginChoices,
32 wxString* aMRUDirectory, const wxString& aProjectPath ) :
33 m_table( aTableToEdit ),
34 m_adapter( aAdapter )
35{
36 m_uriEditor = new wxGridCellAttr;
37 m_uriEditor->SetEditor( new GRID_CELL_PATH_EDITOR( aDialog, aGrid, aMRUDirectory, !aProjectPath.IsEmpty(),
38 aProjectPath,
39 [this]( WX_GRID* aCurrGrid, int aRow ) -> wxString
40 {
41 return getFileTypes( aCurrGrid, aRow );
42 } ) );
43
44 m_typesEditor = new wxGridCellAttr;
45 m_typesEditor->SetEditor( new wxGridCellChoiceEditor( aPluginChoices ) );
46
47 m_boolAttr = new wxGridCellAttr;
48 m_boolAttr->SetRenderer( new wxGridCellBoolRenderer() );
49 m_boolAttr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
50 m_boolAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
51
52 m_warningAttr = new wxGridCellAttr;
54 m_warningAttr->SetReadOnly();
55 m_warningAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
56
57 m_noStatusAttr = new wxGridCellAttr;
58 m_noStatusAttr->SetReadOnly();
59 m_noStatusAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
60
61 m_editSettingsAttr = new wxGridCellAttr;
63 m_editSettingsAttr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
64 m_editSettingsAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
65
66 m_openTableAttr = new wxGridCellAttr;
68 m_openTableAttr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
69 m_openTableAttr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
70}
71
72
74{
75 m_uriEditor->DecRef();
76 m_typesEditor->DecRef();
77 m_boolAttr->DecRef();
78 m_warningAttr->DecRef();
79 m_noStatusAttr->DecRef();
80 m_editSettingsAttr->DecRef();
81 m_openTableAttr->DecRef();
82}
83
84
85bool LIB_TABLE_GRID_DATA_MODEL::badCoords( int aRow, int aCol )
86{
87 if( aRow < 0 || aRow >= (int) size() )
88 return true;
89
90 if( aCol < 0 || aCol >= GetNumberCols() )
91 return true;
92
93 return false;
94}
95
96
97wxString LIB_TABLE_GRID_DATA_MODEL::GetValue( int aRow, int aCol )
98{
99 if( badCoords( aRow, aCol ) )
100 return wxEmptyString;
101
102 const LIBRARY_TABLE_ROW& r = at( aRow );
103
104 switch( aCol )
105 {
106 case COL_NICKNAME: return UnescapeString( r.Nickname() );
107 case COL_URI: return r.URI();
108 case COL_TYPE: return r.Type();
109 case COL_OPTIONS: return r.Options();
110 case COL_DESCR: return r.Description();
111 case COL_ENABLED: return r.Disabled() ? wxT( "0" ) : wxT( "1" );
112 case COL_VISIBLE: return r.Hidden() ? wxT( "0" ) : wxT( "1" );
113
114 case COL_STATUS:
115 if( !r.IsOk() )
116 return r.ErrorDescription();
117
118 if( std::optional<LIBRARY_ERROR> error = m_adapter->LibraryError( r.Nickname() ) )
119 return error->message;
120
121 if( m_adapter->SupportsConfigurationDialog( r.Nickname() ) )
122 return _( "Edit settings" );
124 return _( "Open library table" );
125
126 return wxEmptyString;
127
128 default:
129 return wxEmptyString;
130 }
131}
132
133
134wxGridCellAttr* LIB_TABLE_GRID_DATA_MODEL::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind )
135{
136 if( badCoords( aRow, aCol ) )
137 return enhanceAttr( nullptr, aRow, aCol, aKind );
138
139 LIBRARY_TABLE_ROW& tableRow = at( aRow );
140
141 switch( aCol )
142 {
143 case COL_URI:
144 m_uriEditor->IncRef();
145 return enhanceAttr( m_uriEditor, aRow, aCol, aKind );
146
147 case COL_TYPE:
148 m_typesEditor->IncRef();
149 return enhanceAttr( m_typesEditor, aRow, aCol, aKind );
150
151 case COL_ENABLED:
152 case COL_VISIBLE:
153 m_boolAttr->IncRef();
154 return enhanceAttr( m_boolAttr, aRow, aCol, aKind );
155
156 case COL_STATUS:
157 if( !tableRow.IsOk() )
158 {
159 m_warningAttr->IncRef();
160 return enhanceAttr( m_warningAttr, aRow, aCol, aKind );
161 }
162
163 if( std::optional<LIBRARY_ERROR> error = m_adapter->LibraryError( tableRow.Nickname() ) )
164 {
165 m_warningAttr->IncRef();
166 return enhanceAttr( m_warningAttr, aRow, aCol, aKind );
167 }
168
169 if( m_adapter->SupportsConfigurationDialog( tableRow.Nickname() ) )
170 {
171 m_editSettingsAttr->IncRef();
172 return enhanceAttr( m_editSettingsAttr, aRow, aCol, aKind );
173 }
174 else if( tableRow.Type() == LIBRARY_TABLE_ROW::TABLE_TYPE_NAME )
175 {
176 m_openTableAttr->IncRef();
177 return enhanceAttr( m_openTableAttr, aRow, aCol, aKind );
178 }
179
180 m_noStatusAttr->IncRef();
181 return enhanceAttr( m_noStatusAttr, aRow, aCol, aKind );
182
183 case COL_NICKNAME:
184 case COL_OPTIONS:
185 case COL_DESCR:
186 default:
187 return enhanceAttr( nullptr, aRow, aCol, aKind );
188 }
189}
190
191
192bool LIB_TABLE_GRID_DATA_MODEL::CanGetValueAs( int aRow, int aCol, const wxString& aTypeName )
193{
194 if( badCoords( aRow, aCol ) )
195 return false;
196
197 switch( aCol )
198 {
199 case COL_ENABLED:
200 case COL_VISIBLE:
201 return aTypeName == wxGRID_VALUE_BOOL;
202
203 default:
204 return aTypeName == wxGRID_VALUE_STRING;
205 }
206}
207
208
210{
211 if( badCoords( aRow, aCol ) )
212 return false;
213
214 if( aCol == COL_ENABLED )
215 return !at( aRow ).Disabled();
216 else if( aCol == COL_VISIBLE )
217 return !at( aRow ).Hidden();
218 else
219 return false;
220}
221
222
223void LIB_TABLE_GRID_DATA_MODEL::SetValue( int aRow, int aCol, const wxString& aValue )
224{
225 if( badCoords( aRow, aCol ) )
226 return;
227
228 LIBRARY_TABLE_ROW& lrow = at( aRow );
229
230 switch( aCol )
231 {
232 case COL_NICKNAME: lrow.SetNickname( EscapeString( aValue, CTX_LIBID ) ); break;
233 case COL_URI: lrow.SetURI( aValue ); break;
234 case COL_TYPE: lrow.SetType( aValue ); break;
235 case COL_OPTIONS: lrow.SetOptions( aValue ); break;
236 case COL_DESCR: lrow.SetDescription( aValue ); break;
237 case COL_ENABLED: lrow.SetDisabled( aValue == wxT( "0" ) ); break;
238 case COL_VISIBLE: lrow.SetHidden( aValue == wxT( "0" ) ); break;
239 case COL_STATUS: break;
240 }
241
242 if( aCol == COL_URI || aCol == COL_TYPE || aCol == COL_OPTIONS )
243 {
244 GetView()->CallAfter(
245 [this, aRow, aCol]()
246 {
247 if( badCoords( aRow, aCol ) )
248 return;
249
250 LIBRARY_TABLE_ROW& r = at( aRow );
251
252 m_adapter->CheckTableRow( r );
253
254 GetView()->RefreshBlock( aRow, COL_STATUS, aRow, COL_STATUS );
255 } );
256 }
257}
258
259
260void LIB_TABLE_GRID_DATA_MODEL::SetValueAsBool( int aRow, int aCol, bool aValue )
261{
262 if( badCoords( aRow, aCol ) )
263 return;
264
265 if( aCol == COL_ENABLED )
266 at( aRow ).SetDisabled( !aValue );
267 else if( aCol == COL_VISIBLE )
268 at( aRow ).SetHidden( !aValue );
269}
270
271
272bool LIB_TABLE_GRID_DATA_MODEL::InsertRows( size_t aPos, size_t aNumRows )
273{
274 if( aPos < size() )
275 {
276 for( size_t i = 0; i < aNumRows; i++ )
277 insert( begin() + i, makeNewRow() );
278
279 // use the (wxGridStringTable) source Luke.
280 if( GetView() )
281 {
282 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_INSERTED, aPos, aNumRows );
283 GetView()->ProcessTableMessage( msg );
284 }
285
286 return true;
287 }
288
289 return false;
290}
291
292
294{
295 // do not modify aNumRows, original value needed for wxGridTableMessage below
296 for( int i = aNumRows; i; --i )
298
299 if( GetView() )
300 {
301 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, aNumRows );
302 GetView()->ProcessTableMessage( msg );
303 }
304
305 return true;
306}
307
308
309bool LIB_TABLE_GRID_DATA_MODEL::DeleteRows( size_t aPos, size_t aNumRows )
310{
311 // aPos may be a large positive, e.g. size_t(-1), and the sum of
312 // aPos+aNumRows may wrap here, so both ends of the range are tested.
313 if( aPos < size() && aPos + aNumRows <= size() )
314 {
315 LIBRARY_TABLE_ROWS_ITER start = begin() + aPos;
316 erase( start, start + aNumRows );
317
318 if( GetView() )
319 {
320 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aPos, aNumRows );
321 GetView()->ProcessTableMessage( msg );
322 }
323
324 return true;
325 }
326
327 return false;
328}
329
330
332{
333 switch( aCol )
334 {
335 case COL_NICKNAME: return _( "Nickname" );
336 case COL_URI: return _( "Library Path" );
337
338 // keep this "Library Format" text fairly long so column is sized wide enough
339 case COL_TYPE: return _( "Library Format" );
340 case COL_OPTIONS: return _( "Options" );
341 case COL_DESCR: return _( "Description" );
342 case COL_ENABLED: return _( "Enable" );
343 case COL_VISIBLE: return _( "Show" );
344 case COL_STATUS: return wxEmptyString;
345
346 default: return wxEmptyString;
347 }
348}
349
350
351bool LIB_TABLE_GRID_DATA_MODEL::ContainsNickname( const wxString& aNickname )
352{
353 for( size_t i = 0; i < size(); ++i )
354 {
355 LIBRARY_TABLE_ROW& row = at( i );
356
357 if( row.Nickname() == aNickname )
358 return true;
359 }
360 return false;
361}
362
363
365{
366 return m_table.Rows().at( aIndex );
367}
368
369
371{
372 return m_table.Rows().size();
373}
374
375
380
381
386
387
389 const LIBRARY_TABLE_ROW& aRow )
390{
391 return m_table.Rows().insert( aIterator, aRow );
392}
393
394
396{
397 m_table.Rows().push_back( aRow );
398}
399
400
403{
404 return m_table.Rows().erase( aFirst, aLast );
405}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:110
@ small_new_window
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition dialog_shim.h:68
Editor for wxGrid cells that adds a file/folder browser to the grid input field.
The interface used by the classes that actually can load IO plugins for the different parts of KiCad ...
void SetOptions(const wxString &aOptions)
void SetNickname(const wxString &aNickname)
void SetType(const wxString &aType)
bool Disabled() const
const wxString & ErrorDescription() const
void SetDescription(const wxString &aDescription)
const wxString & Type() const
static const wxString TABLE_TYPE_NAME
void SetURI(const wxString &aUri)
const wxString & Description() const
void SetDisabled(bool aDisabled=true)
bool Hidden() const
void SetHidden(bool aHidden=true)
bool IsOk() const
const wxString & URI() const
const wxString & Nickname() const
const wxString & Options() const
virtual LIBRARY_TABLE_ROWS_ITER begin()
bool AppendRows(size_t aNumRows=1) override
virtual LIBRARY_TABLE_ROW & at(size_t aIndex)
bool ContainsNickname(const wxString &aNickname)
virtual LIBRARY_TABLE_ROWS_ITER erase(LIBRARY_TABLE_ROWS_ITER aFirst, LIBRARY_TABLE_ROWS_ITER aLast)
void SetValueAsBool(int aRow, int aCol, bool aValue) override
virtual LIBRARY_TABLE_ROWS_ITER insert(LIBRARY_TABLE_ROWS_ITER aIterator, const LIBRARY_TABLE_ROW &aRow)
wxString GetValue(int aRow, int aCol) override
wxString GetColLabelValue(int aCol) override
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind) override
bool CanGetValueAs(int aRow, int aCol, const wxString &aTypeName) override
bool GetValueAsBool(int aRow, int aCol) override
bool DeleteRows(size_t aPos, size_t aNumRows) override
virtual void push_back(const LIBRARY_TABLE_ROW &aRow)
bool InsertRows(size_t aPos=0, size_t aNumRows=1) override
LIBRARY_MANAGER_ADAPTER * m_adapter
Handle to the adapter for the type of table this grid represents (may be null)
void SetValue(int aRow, int aCol, const wxString &aValue) override
LIBRARY_TABLE m_table
Working copy of a table.
LIB_TABLE_GRID_DATA_MODEL(DIALOG_SHIM *aParent, WX_GRID *aGrid, const LIBRARY_TABLE &aTableToEdit, LIBRARY_MANAGER_ADAPTER *aAdapter, const wxArrayString &aPluginChoices, wxString *aMRUDirectory, const wxString &aProjectPath)
virtual LIBRARY_TABLE_ROW makeNewRow()
wxGridCellAttr * enhanceAttr(wxGridCellAttr *aInputAttr, int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind)
Definition wx_grid.cpp:46
#define _(s)
std::vector< LIBRARY_TABLE_ROW >::iterator LIBRARY_TABLE_ROWS_ITER
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_LIBID