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
17 * along with this program. If not, see <https://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;
30class SCH_SYMBOL;
31
32
34{
37 wxString reference;
38 wxString caseFoldedKey;
39 std::vector<std::pair<wxString, wxString>> variants;
40};
41
42
43std::vector<FIELD_CASE_CONFLICT> DetectFieldCaseConflicts( const SCH_REFERENCE_LIST& aSymbols );
44
45
47{
48 DATA_MODEL_ROW( const SCH_REFERENCE& aFirstReference, GROUP_TYPE aType )
49 {
50 m_ItemNumber = 0;
51 m_Refs.push_back( aFirstReference );
52 m_Flag = aType;
53 }
54
57 std::vector<SCH_REFERENCE> m_Refs;
58};
59
60
62{
63 wxString m_fieldName;
64 wxString m_label;
66 bool m_show;
67 bool m_group;
68};
69
70
72{
73public:
80
81 FIELDS_EDITOR_GRID_DATA_MODEL( const SCH_REFERENCE_LIST& aSymbolsList, wxGridCellAttr* aURLEditor ) :
82 m_symbolsList( aSymbolsList ),
83 m_edited( false ),
84 m_sortColumn( 0 ),
85 m_sortAscending( false ),
87 m_groupingEnabled( false ),
88 m_excludeDNP( false ),
89 m_includeExcluded( false ),
90 m_rebuildsEnabled( true ),
91 m_urlEditor( aURLEditor ),
92 m_textVarRenderer( nullptr )
93 {
94 m_symbolsList.SplitReferences();
95 }
96
98 {
99 wxSafeDecRef( m_urlEditor );
100 wxSafeDecRef( m_textVarRenderer );
101 }
102
103 static const wxString QUANTITY_VARIABLE;
104 static const wxString ITEM_NUMBER_VARIABLE;
105
106 void AddColumn( const wxString& aFieldName, const wxString& aLabel, bool aAddedByUser );
107 void RemoveColumn( int aCol );
108 void RenameColumn( int aCol, const wxString& newName );
109
110 void MoveColumn( int aCol, int aNewPos )
111 {
112 wxCHECK_RET( aCol >= 0 && aCol < static_cast<int>( m_cols.size() ), "Invalid Column Number" );
113
114 if( aCol == aNewPos )
115 {
116 return;
117 }
118 else if( aCol < aNewPos )
119 {
120 std::rotate( std::begin( m_cols ) + aCol, std::begin( m_cols ) + aCol + 1,
121 std::begin( m_cols ) + aNewPos + 1 );
122 }
123 else
124 {
125 std::rotate( std::begin( m_cols ) + aNewPos, std::begin( m_cols ) + aCol,
126 std::begin( m_cols ) + aCol + 1 );
127 }
128 }
129
130 int GetNumberRows() override { return (int) m_rows.size(); }
131 int GetNumberCols() override { return (int) m_cols.size(); }
132
133 void SetColLabelValue( int aCol, const wxString& aLabel ) override
134 {
135 wxCHECK_RET( aCol >= 0 && aCol < static_cast<int>( m_cols.size() ), "Invalid Column Number" );
136 m_cols[aCol].m_label = aLabel;
137 }
138
139 wxString GetColLabelValue( int aCol ) override
140 {
141 wxCHECK( aCol >= 0 && aCol < static_cast<int>( m_cols.size() ), wxString() );
142 return m_cols[aCol].m_label;
143 }
144
145 wxString GetColFieldName( int aCol )
146 {
147 wxCHECK( aCol >= 0 && aCol < static_cast<int>( m_cols.size() ), wxString() );
148 return m_cols[aCol].m_fieldName;
149 }
150
151 int GetFieldNameCol( const wxString& aFieldName ) const;
152
153 std::vector<BOM_FIELD> GetFieldsOrdered();
154 void SetFieldsOrder( const std::vector<wxString>& aNewOrder );
155
156 bool IsEmptyCell( int aRow, int aCol ) override
157 {
158 return false; // don't allow adjacent cell overflow, even if we are actually empty
159 }
160
161 wxString GetValue( int aRow, int aCol ) override;
162 wxString GetResolvedValue( int aRow, int aCol );
163 wxGridCellAttr* GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind ) override;
164
165 wxString GetValue( const DATA_MODEL_ROW& group, int aCol,
166 const wxString& refDelimiter = wxT( ", " ),
167 const wxString& refRangDelimiter = wxT( "-" ),
168 bool resolveVars = false,
169 bool listMixedValues = false );
170
171 wxString GetExportValue( int aRow, int aCol, const wxString& refDelimiter,
172 const wxString& refRangeDelimiter )
173 {
174 return GetValue( m_rows[aRow], aCol, refDelimiter, refRangeDelimiter, true, true );
175 }
176
177 void SetValue( int aRow, int aCol, const wxString& aValue ) override;
178
179 GROUP_TYPE GetRowFlags( int aRow ) { return m_rows[aRow].m_Flag; }
180
181 std::vector<SCH_REFERENCE> GetRowReferences( int aRow ) const
182 {
183 wxCHECK( aRow >= 0 && aRow < (int) m_rows.size(), std::vector<SCH_REFERENCE>() );
184 return m_rows[aRow].m_Refs;
185 }
186
187 bool ColIsReference( int aCol );
188 bool ColIsValue( int aCol );
189 bool ColIsQuantity( int aCol );
190 bool ColIsItemNumber( int aCol );
191 bool ColIsAttribute( int aCol );
192
193 bool IsExpanderColumn( int aCol ) const override;
194 GROUP_TYPE GetGroupType( int aRow ) const override
195 {
196 return m_rows[aRow].m_Flag;
197 }
198
199 void SetSorting( int aCol, bool ascending )
200 {
201 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
202 m_sortColumn = aCol;
203 m_sortAscending = ascending;
204 }
205
206 int GetSortCol() { return m_sortColumn; }
207 bool GetSortAsc() { return m_sortAscending; }
208
209 // These are used to disable the RebuildRows functionality while we're generating
210 // lots of events in the UI, e.g. applying a BOM preset, that would thrash the grid.
211 void EnableRebuilds();
212 void DisableRebuilds();
213 void RebuildRows();
214
215 void ExpandRow( int aRow );
216 void CollapseRow( int aRow );
217 void ExpandCollapseRow( int aRow );
218 void CollapseForSort();
219 void ExpandAfterSort();
220
221 void ApplyData( SCH_COMMIT& aCommit, TEMPLATES& aTemplateFieldnames, const wxString& aVariantName );
222
223 bool IsEdited() { return m_edited; }
224
225 int GetDataWidth( int aCol );
226
227 void SetFilter( const wxString& aFilter ) { m_filter = aFilter; }
228 const wxString& GetFilter() { return m_filter; }
229
230 void SetScope( SCOPE aScope ) { m_scope = aScope; }
231 SCOPE GetScope() { return m_scope; }
232
233 void SetPath( const SCH_SHEET_PATH& aPath ) { m_path = aPath; }
234 const SCH_SHEET_PATH& GetPath() { return m_path; }
235
238
239 /* These contradictorily named functions force including symbols that
240 * have the Exclude from BOM check box ticked. This is needed so we can view
241 * these parts in the symbol fields table dialog, while also excluding from the
242 * BOM export */
243 void SetIncludeExcludedFromBOM( bool include ) { m_includeExcluded = include; }
245
246 void SetExcludeDNP( bool exclude ) { m_excludeDNP = exclude; }
247 bool GetExcludeDNP() { return m_excludeDNP; }
248
249 void SetGroupColumn( int aCol, bool group )
250 {
251 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
252 m_cols[aCol].m_group = group;
253 }
254
255 bool GetGroupColumn( int aCol )
256 {
257 wxCHECK_MSG( aCol >= 0 && aCol < (int) m_cols.size(), false, "Invalid Column Number" );
258 return m_cols[aCol].m_group;
259 }
260
261 void SetShowColumn( int aCol, bool show )
262 {
263 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
264 m_cols[aCol].m_show = show;
265 }
266
267 bool GetShowColumn( int aCol )
268 {
269 wxCHECK_MSG( aCol >= 0 && aCol < (int) m_cols.size(), false, "Invalid Column Number" );
270 return m_cols[aCol].m_show;
271 }
272
273 void ApplyBomPreset( const BOM_PRESET& preset );
275 wxString Export( const BOM_FMT_PRESET& settings );
276
277 void AddReferences( const SCH_REFERENCE_LIST& aRefs );
278 void RemoveReferences( const SCH_REFERENCE_LIST& aRefs );
279 void RemoveSymbol( const SCH_SYMBOL& aSymbol );
280 void UpdateReferences( const SCH_REFERENCE_LIST& aRefs );
281
282 // Identity-based undo serialization (keyed by symbol, not row position) for the dialog's
283 // Ctrl+Z, so it stays correct as rows are grouped/sorted/reordered.
284 bool HasUndoStateSerialization() const override { return true; }
285 wxString SerializeUndoState() const override;
286 void RestoreUndoState( const wxString& aState ) override;
287
288 bool DeleteRows( size_t aPosition = 0, size_t aNumRows = 1 ) override;
289
291
300 void SetCurrentVariant( const wxString& aVariantName ) { m_currentVariant = aVariantName; }
301 const wxString& GetCurrentVariant() const { return m_currentVariant; }
302
303 void SetVariantNames( const std::vector<wxString>& aVariantNames ) { m_variantNames = aVariantNames; }
304 const std::vector<wxString>& GetVariantNames() const { return m_variantNames; }
305
306private:
307 static bool cmp( const DATA_MODEL_ROW& lhGroup, const DATA_MODEL_ROW& rhGroup,
308 FIELDS_EDITOR_GRID_DATA_MODEL* dataModel, int sortCol, bool ascending );
309
310 bool unitMatch( const SCH_REFERENCE& lhRef, const SCH_REFERENCE& rhRef );
311 bool groupMatch( const SCH_REFERENCE& lhRef, const SCH_REFERENCE& rhRef );
312
313 // Helper functions to deal with translating wxGrid values to and from
314 // named field values like ${DNP}
315 bool isAttribute( const wxString& aFieldName );
316
317 // True when an ancestor sheet forces this attribute on, not the symbol itself.
318 bool attributeInheritedFromSheet( const SCH_REFERENCE& aRef, const wxString& aAttributeName ) const;
319 bool rowAttributeInheritedFromSheet( const DATA_MODEL_ROW& aGroup, int aCol );
320
321 wxString getAttributeValue( const SCH_REFERENCE& aRef, const wxString& aAttributeName,
322 const wxString& aVariantNames );
323
333 wxString getDefaultFieldValue( const SCH_REFERENCE& aRef, const wxString& aFieldName );
334
345 bool setAttributeValue( SCH_REFERENCE& aRef, const wxString& aAttributeName, const wxString& aValue,
346 const wxString& aVariantName = wxEmptyString );
347
348 /* Helper function to get the resolved field value.
349 * Handles symbols that are missing fields that would have a variable
350 * in their value because their name is the same as a variable.
351 * Example: BOM template provides ${DNP} as a field, but they symbol doesn't have the field. */
352 wxString getFieldShownText( const SCH_REFERENCE& aRef, const wxString& aFieldName );
353
354 void Sort();
355
356 void updateDataStoreSymbolField( const SCH_REFERENCE& aSymbolRef, const wxString& aFieldName );
357
358protected:
369 wxString m_filter;
376 wxGridCellAttr* m_urlEditor;
377 wxGridCellRenderer* m_textVarRenderer;
379 std::vector<wxString> m_variantNames;
380
381 std::vector<DATA_MODEL_COL> m_cols;
382 std::vector<DATA_MODEL_ROW> m_rows;
383
384 // Data store
385 // The data model is fundamentally m_componentRefs X m_fieldNames.
386 // A map of compID : fieldSet, where fieldSet is a map of fieldName : fieldValue
387 // The compID is now the full KIID_PATH (sheet path + symbol UUID) as a string
388 std::map<KIID_PATH, std::map<wxString, wxString>> m_dataStore;
389};
int GetFieldNameCol(const wxString &aFieldName) const
std::vector< DATA_MODEL_ROW > m_rows
bool HasUndoStateSerialization() const override
Optional identity-based serialization for the host dialog's Ctrl+Z/Ctrl+Y.
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.
wxGridCellRenderer * m_textVarRenderer
Renderer for cells with text variable references.
wxString m_currentVariant
Current variant name for highlighting.
bool DeleteRows(size_t aPosition=0, size_t aNumRows=1) override
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 SerializeUndoState() const override
wxString getAttributeValue(const SCH_REFERENCE &aRef, const wxString &aAttributeName, const wxString &aVariantNames)
wxString GetExportValue(int aRow, int aCol, const wxString &refDelimiter, const wxString &refRangeDelimiter)
wxString getDefaultFieldValue(const SCH_REFERENCE &aRef, const wxString &aFieldName)
Get the default (non-variant) value for a field.
void SetPath(const SCH_SHEET_PATH &aPath)
wxString getFieldShownText(const SCH_REFERENCE &aRef, const wxString &aFieldName)
bool IsEmptyCell(int aRow, int aCol) override
wxString GetResolvedValue(int aRow, int aCol)
GROUP_TYPE GetGroupType(int aRow) const override
void RenameColumn(int aCol, const wxString &newName)
FIELDS_EDITOR_GRID_DATA_MODEL(const SCH_REFERENCE_LIST &aSymbolsList, wxGridCellAttr *aURLEditor)
bool IsExpanderColumn(int aCol) const override
wxString Export(const BOM_FMT_PRESET &settings)
void AddColumn(const wxString &aFieldName, const wxString &aLabel, bool aAddedByUser)
std::vector< wxString > m_variantNames
Variant names for multi-variant DNP filtering.
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_REFERENCE &aRef, const wxString &aAttributeName, const wxString &aValue, const wxString &aVariantName=wxEmptyString)
Set the attribute value.
void RestoreUndoState(const wxString &aState) override
const wxString & GetCurrentVariant() const
bool attributeInheritedFromSheet(const SCH_REFERENCE &aRef, const wxString &aAttributeName) const
void updateDataStoreSymbolField(const SCH_REFERENCE &aSymbolRef, const wxString &aFieldName)
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 SetIncludeExcludedFromBOM(bool include)
bool isAttribute(const wxString &aFieldName)
wxString GetValue(int aRow, int aCol) override
bool rowAttributeInheritedFromSheet(const DATA_MODEL_ROW &aGroup, int aCol)
void UpdateReferences(const SCH_REFERENCE_LIST &aRefs)
const SCH_REFERENCE_LIST & GetReferenceList() const
void SetVariantNames(const std::vector< wxString > &aVariantNames)
const std::vector< wxString > & GetVariantNames() const
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
std::map< KIID_PATH, std::map< wxString, wxString > > m_dataStore
void ApplyData(SCH_COMMIT &aCommit, TEMPLATES &aTemplateFieldnames, const wxString &aVariantName)
void SetColLabelValue(int aCol, const wxString &aLabel) override
void SetCurrentVariant(const wxString &aVariantName)
Set the current variant name for highlighting purposes.
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:69
std::vector< FIELD_CASE_CONFLICT > DetectFieldCaseConflicts(const SCH_REFERENCE_LIST &aSymbols)
std::vector< SCH_REFERENCE > m_Refs
DATA_MODEL_ROW(const SCH_REFERENCE &aFirstReference, GROUP_TYPE aType)
SCH_SHEET_PATH sheetPath
std::vector< std::pair< wxString, wxString > > variants
enum KICOMMON_API GROUP_TYPE
Definition wx_grid.h:40