KiCad PCB EDA Suite
Loading...
Searching...
No Matches
fields_data_model.h
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
20#pragma once
21
22#include <sch_reference_list.h>
23#include <wx/grid.h>
24#include <widgets/wx_grid.h>
25
26
27struct BOM_FIELD;
28struct BOM_PRESET;
29struct BOM_FMT_PRESET;
30
31
32// Columns for the View Fields grid
33#define DISPLAY_NAME_COLUMN 0 // The field name in the data model (translated)
34#define LABEL_COLUMN 1 // The field name's label for exporting (CSV, etc.)
35#define SHOW_FIELD_COLUMN 2
36#define GROUP_BY_COLUMN 3
37#define VIEW_FIELDS_COL_COUNT 4
38
39
40// Data model for the list of fields to view (and to group-by) for the Symbol Fields Table
42{
43public:
45 m_forBOM( aForBOM )
46 {}
47
48 ~VIEW_CONTROLS_GRID_DATA_MODEL() override = default;
49
50 int GetNumberRows() override { return (int) m_fields.size(); }
51 int GetNumberCols() override { return VIEW_FIELDS_COL_COUNT; }
52
53 wxString GetColLabelValue( int aCol ) override;
54
55 bool IsEmptyCell( int aRow, int aCol ) override
56 {
57 return false; // don't allow adjacent cell overflow, even if we are actually empty
58 }
59
60 bool CanGetValueAs( int aRow, int aCol, const wxString& aTypeName ) override
61 {
62 switch( aCol )
63 {
65 case LABEL_COLUMN: return aTypeName == wxGRID_VALUE_STRING;
66
68 case GROUP_BY_COLUMN: return aTypeName == wxGRID_VALUE_BOOL;
69
70 default: wxFAIL; return false;
71 }
72 }
73
74 bool CanSetValueAs( int aRow, int aCol, const wxString& aTypeName ) override
75 {
76 return CanGetValueAs( aRow, aCol, aTypeName );
77 }
78
79 wxString GetValue( int aRow, int aCol ) override;
80 bool GetValueAsBool( int aRow, int aCol ) override;
81
82 void SetValue( int aRow, int aCol, const wxString& aValue ) override;
83 void SetValueAsBool( int aRow, int aCol, bool aValue ) override;
84
85 void AppendRow( const wxString& aFieldName, const wxString& aBOMName, bool aShow, bool aGroupBy );
86 void DeleteRow( int aRow );
87
88 wxString GetCanonicalFieldName( int aRow );
89 void SetCanonicalFieldName( int aRow, const wxString& aName );
90
91protected:
93 std::vector<BOM_FIELD> m_fields;
94};
95
96
105
106
108{
109 DATA_MODEL_ROW( const SCH_REFERENCE& aFirstReference, GROUP_TYPE aType )
110 {
111 m_ItemNumber = 0;
112 m_Refs.push_back( aFirstReference );
113 m_Flag = aType;
114 }
115
118 std::vector<SCH_REFERENCE> m_Refs;
119};
120
121
123{
124 wxString m_fieldName;
125 wxString m_label;
127 bool m_show;
129};
130
131
133{
134public:
141
142 FIELDS_EDITOR_GRID_DATA_MODEL( const SCH_REFERENCE_LIST& aSymbolsList, wxGridCellAttr* aURLEditor ) :
143 m_symbolsList( aSymbolsList ),
144 m_edited( false ),
145 m_sortColumn( 0 ),
146 m_sortAscending( false ),
148 m_groupingEnabled( false ),
149 m_excludeDNP( false ),
150 m_includeExcluded( false ),
151 m_rebuildsEnabled( true ),
152 m_urlEditor( aURLEditor )
153 {
154 m_symbolsList.SplitReferences();
155 }
156
158 {
159 wxSafeDecRef( m_urlEditor );
160 }
161
162 static const wxString QUANTITY_VARIABLE;
163 static const wxString ITEM_NUMBER_VARIABLE;
164
165 void AddColumn( const wxString& aFieldName, const wxString& aLabel, bool aAddedByUser );
166 void RemoveColumn( int aCol );
167 void RenameColumn( int aCol, const wxString& newName );
168
169 void MoveColumn( int aCol, int aNewPos )
170 {
171 wxCHECK_RET( aCol >= 0 && aCol < static_cast<int>( m_cols.size() ), "Invalid Column Number" );
172
173 if( aCol == aNewPos )
174 {
175 return;
176 }
177 else if( aCol < aNewPos )
178 {
179 std::rotate( std::begin( m_cols ) + aCol, std::begin( m_cols ) + aCol + 1,
180 std::begin( m_cols ) + aNewPos + 1 );
181 }
182 else
183 {
184 std::rotate( std::begin( m_cols ) + aNewPos, std::begin( m_cols ) + aCol,
185 std::begin( m_cols ) + aCol + 1 );
186 }
187 }
188
189 int GetNumberRows() override { return (int) m_rows.size(); }
190 int GetNumberCols() override { return (int) m_cols.size(); }
191
192 void SetColLabelValue( int aCol, const wxString& aLabel ) override
193 {
194 wxCHECK_RET( aCol >= 0 && aCol < static_cast<int>( m_cols.size() ), "Invalid Column Number" );
195 m_cols[aCol].m_label = aLabel;
196 }
197
198 wxString GetColLabelValue( int aCol ) override
199 {
200 wxCHECK( aCol >= 0 && aCol < static_cast<int>( m_cols.size() ), wxString() );
201 return m_cols[aCol].m_label;
202 }
203
204 wxString GetColFieldName( int aCol )
205 {
206 wxCHECK( aCol >= 0 && aCol < static_cast<int>( m_cols.size() ), wxString() );
207 return m_cols[aCol].m_fieldName;
208 }
209
210 int GetFieldNameCol( const wxString& aFieldName ) const;
211
212 std::vector<BOM_FIELD> GetFieldsOrdered();
213 void SetFieldsOrder( const std::vector<wxString>& aNewOrder );
214
215 bool IsEmptyCell( int aRow, int aCol ) override
216 {
217 return false; // don't allow adjacent cell overflow, even if we are actually empty
218 }
219
220 wxString GetValue( int aRow, int aCol ) override;
221 wxGridCellAttr* GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind ) override;
222
223 wxString GetValue( const DATA_MODEL_ROW& group, int aCol,
224 const wxString& refDelimiter = wxT( ", " ),
225 const wxString& refRangDelimiter = wxT( "-" ),
226 bool resolveVars = false,
227 bool listMixedValues = false );
228
229 wxString GetExportValue( int aRow, int aCol, const wxString& refDelimiter,
230 const wxString& refRangeDelimiter )
231 {
232 return GetValue( m_rows[aRow], aCol, refDelimiter, refRangeDelimiter, true, true );
233 }
234
235 void SetValue( int aRow, int aCol, const wxString& aValue ) override;
236
237 GROUP_TYPE GetRowFlags( int aRow ) { return m_rows[aRow].m_Flag; }
238
239 std::vector<SCH_REFERENCE> GetRowReferences( int aRow ) const
240 {
241 wxCHECK( aRow >= 0 && aRow < (int) m_rows.size(), std::vector<SCH_REFERENCE>() );
242 return m_rows[aRow].m_Refs;
243 }
244
245 bool ColIsReference( int aCol );
246 bool ColIsValue( int aCol );
247 bool ColIsQuantity( int aCol );
248 bool ColIsItemNumber( int aCol );
249 bool ColIsAttribute( int aCol );
250
251 void SetSorting( int aCol, bool ascending )
252 {
253 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
254 m_sortColumn = aCol;
255 m_sortAscending = ascending;
256 }
257
258 int GetSortCol() { return m_sortColumn; }
259 bool GetSortAsc() { return m_sortAscending; }
260
261 // These are used to disable the RebuildRows functionality while we're generating
262 // lots of events in the UI, e.g. applying a BOM preset, that would thrash the grid.
263 void EnableRebuilds();
264 void DisableRebuilds();
265 void RebuildRows();
266
267 void ExpandRow( int aRow );
268 void CollapseRow( int aRow );
269 void ExpandCollapseRow( int aRow );
270 void CollapseForSort();
271 void ExpandAfterSort();
272
273 void ApplyData( SCH_COMMIT& aCommit, TEMPLATES& aTemplateFieldnames );
274
275 bool IsEdited() { return m_edited; }
276
277 int GetDataWidth( int aCol );
278
279 void SetFilter( const wxString& aFilter ) { m_filter = aFilter; }
280 const wxString& GetFilter() { return m_filter; }
281
282 void SetScope( SCOPE aScope ) { m_scope = aScope; }
283 SCOPE GetScope() { return m_scope; }
284
285 void SetPath( const SCH_SHEET_PATH& aPath ) { m_path = aPath; }
286 const SCH_SHEET_PATH& GetPath() { return m_path; }
287
290
291 /* These contradictorily named functions force including symbols that
292 * have the Exclude from BOM check box ticked. This is needed so we can view
293 * these parts in the symbol fields table dialog, while also excluding from the
294 * BOM export */
295 void SetIncludeExcludedFromBOM( bool include ) { m_includeExcluded = include; }
297
298 void SetExcludeDNP( bool exclude ) { m_excludeDNP = exclude; }
299 bool GetExcludeDNP() { return m_excludeDNP; }
300
301 void SetGroupColumn( int aCol, bool group )
302 {
303 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
304 m_cols[aCol].m_group = group;
305 }
306
307 bool GetGroupColumn( int aCol )
308 {
309 wxCHECK_MSG( aCol >= 0 && aCol < (int) m_cols.size(), false, "Invalid Column Number" );
310 return m_cols[aCol].m_group;
311 }
312
313 void SetShowColumn( int aCol, bool show )
314 {
315 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
316 m_cols[aCol].m_show = show;
317 }
318
319 bool GetShowColumn( int aCol )
320 {
321 wxCHECK_MSG( aCol >= 0 && aCol < (int) m_cols.size(), false, "Invalid Column Number" );
322 return m_cols[aCol].m_show;
323 }
324
325 void ApplyBomPreset( const BOM_PRESET& preset );
327 wxString Export( const BOM_FMT_PRESET& settings );
328
329 void AddReferences( const SCH_REFERENCE_LIST& aRefs );
330 void RemoveReferences( const SCH_REFERENCE_LIST& aRefs );
331 void RemoveSymbol( const SCH_SYMBOL& aSymbol );
332 void UpdateReferences( const SCH_REFERENCE_LIST& aRefs );
333
334private:
335 static bool cmp( const DATA_MODEL_ROW& lhGroup, const DATA_MODEL_ROW& rhGroup,
336 FIELDS_EDITOR_GRID_DATA_MODEL* dataModel, int sortCol, bool ascending );
337
338 bool unitMatch( const SCH_REFERENCE& lhRef, const SCH_REFERENCE& rhRef );
339 bool groupMatch( const SCH_REFERENCE& lhRef, const SCH_REFERENCE& rhRef );
340
341 // Helper functions to deal with translating wxGrid values to and from
342 // named field values like ${DNP}
343 bool isAttribute( const wxString& aFieldName );
344 wxString getAttributeValue( const SCH_SYMBOL&, const wxString& aAttributeName );
345
355 bool setAttributeValue( SCH_SYMBOL& aSymbol, const wxString& aAttributeName, const wxString& aValue );
356
357 /* Helper function to get the resolved field value.
358 * Handles symbols that are missing fields that would have a variable
359 * in their value because their name is the same as a variable.
360 * Example: BOM template provides ${DNP} as a field, but they symbol doesn't have the field. */
361 wxString getFieldShownText( const SCH_REFERENCE& aRef, const wxString& aFieldName );
362
363 void Sort();
364
365 void updateDataStoreSymbolField( const SCH_SYMBOL& aSymbol, const wxString& aFieldName );
366
367protected:
378 wxString m_filter;
385 wxGridCellAttr* m_urlEditor;
386
387 std::vector<DATA_MODEL_COL> m_cols;
388 std::vector<DATA_MODEL_ROW> m_rows;
389
390 // Data store
391 // The data model is fundamentally m_componentRefs X m_fieldNames.
392 // A map of compID : fieldSet, where fieldSet is a map of fieldName : fieldValue
393 std::map<KIID, std::map<wxString, wxString>> m_dataStore;
394};
int GetFieldNameCol(const wxString &aFieldName) const
std::vector< DATA_MODEL_ROW > m_rows
void ApplyBomPreset(const BOM_PRESET &preset)
void SetFieldsOrder(const std::vector< wxString > &aNewOrder)
std::vector< SCH_REFERENCE > GetRowReferences(int aRow) const
SCH_REFERENCE_LIST m_symbolsList
The flattened by hierarchy list of symbols.
wxString getAttributeValue(const SCH_SYMBOL &, const wxString &aAttributeName)
void updateDataStoreSymbolField(const SCH_SYMBOL &aSymbol, const wxString &aFieldName)
bool groupMatch(const SCH_REFERENCE &lhRef, const SCH_REFERENCE &rhRef)
const SCH_SHEET_PATH & GetPath()
wxString GetColLabelValue(int aCol) override
bool unitMatch(const SCH_REFERENCE &lhRef, const SCH_REFERENCE &rhRef)
wxString GetExportValue(int aRow, int aCol, const wxString &refDelimiter, const wxString &refRangeDelimiter)
void SetPath(const SCH_SHEET_PATH &aPath)
wxString getFieldShownText(const SCH_REFERENCE &aRef, const wxString &aFieldName)
bool IsEmptyCell(int aRow, int aCol) override
void RenameColumn(int aCol, const wxString &newName)
FIELDS_EDITOR_GRID_DATA_MODEL(const SCH_REFERENCE_LIST &aSymbolsList, wxGridCellAttr *aURLEditor)
wxString Export(const BOM_FMT_PRESET &settings)
void AddColumn(const wxString &aFieldName, const wxString &aLabel, bool aAddedByUser)
std::vector< DATA_MODEL_COL > m_cols
void SetSorting(int aCol, bool ascending)
wxGridCellAttr * GetAttr(int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind) override
void SetFilter(const wxString &aFilter)
bool setAttributeValue(SCH_SYMBOL &aSymbol, const wxString &aAttributeName, const wxString &aValue)
Set the attribute value.
static bool cmp(const DATA_MODEL_ROW &lhGroup, const DATA_MODEL_ROW &rhGroup, FIELDS_EDITOR_GRID_DATA_MODEL *dataModel, int sortCol, bool ascending)
static const wxString ITEM_NUMBER_VARIABLE
void ApplyData(SCH_COMMIT &aCommit, TEMPLATES &aTemplateFieldnames)
void SetIncludeExcludedFromBOM(bool include)
bool isAttribute(const wxString &aFieldName)
wxString GetValue(int aRow, int aCol) override
void UpdateReferences(const SCH_REFERENCE_LIST &aRefs)
std::map< KIID, std::map< wxString, wxString > > m_dataStore
static const wxString QUANTITY_VARIABLE
void SetGroupColumn(int aCol, bool group)
void RemoveSymbol(const SCH_SYMBOL &aSymbol)
std::vector< BOM_FIELD > GetFieldsOrdered()
void SetValue(int aRow, int aCol, const wxString &aValue) override
void SetColLabelValue(int aCol, const wxString &aLabel) override
void MoveColumn(int aCol, int aNewPos)
void RemoveReferences(const SCH_REFERENCE_LIST &aRefs)
void SetShowColumn(int aCol, bool show)
void AddReferences(const SCH_REFERENCE_LIST &aRefs)
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
A helper to define a symbol's reference designator in a schematic.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Schematic symbol object.
Definition sch_symbol.h:75
bool IsEmptyCell(int aRow, int aCol) override
void SetValueAsBool(int aRow, int aCol, bool aValue) override
~VIEW_CONTROLS_GRID_DATA_MODEL() override=default
wxString GetColLabelValue(int aCol) override
std::vector< BOM_FIELD > m_fields
void SetValue(int aRow, int aCol, const wxString &aValue) override
void AppendRow(const wxString &aFieldName, const wxString &aBOMName, bool aShow, bool aGroupBy)
bool CanSetValueAs(int aRow, int aCol, const wxString &aTypeName) override
bool GetValueAsBool(int aRow, int aCol) override
bool CanGetValueAs(int aRow, int aCol, const wxString &aTypeName) override
void SetCanonicalFieldName(int aRow, const wxString &aName)
wxString GetValue(int aRow, int aCol) override
@ GROUP_COLLAPSED_DURING_SORT
@ GROUP_EXPANDED
@ GROUP_COLLAPSED
@ GROUP_SINGLETON
@ CHILD_ITEM
#define LABEL_COLUMN
#define DISPLAY_NAME_COLUMN
#define GROUP_BY_COLUMN
#define SHOW_FIELD_COLUMN
#define VIEW_FIELDS_COL_COUNT
std::vector< SCH_REFERENCE > m_Refs
DATA_MODEL_ROW(const SCH_REFERENCE &aFirstReference, GROUP_TYPE aType)