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#include <sch_reference_list.h>
20#include <wx/grid.h>
21#include <widgets/wx_grid.h>
22
23// The field name in the data model (translated)
24#define DISPLAY_NAME_COLUMN 0
25
26// The field name's label for exporting (CSV, etc.)
27#define LABEL_COLUMN 1
28#define SHOW_FIELD_COLUMN 2
29#define GROUP_BY_COLUMN 3
30
31// The internal field name (untranslated)
32#define FIELD_NAME_COLUMN 4
33
34struct BOM_FIELD;
35struct BOM_PRESET;
36struct BOM_FMT_PRESET;
37
39{
45};
46
47
49{
50 DATA_MODEL_ROW( const SCH_REFERENCE& aFirstReference, GROUP_TYPE aType )
51 {
52 m_ItemNumber = 0;
53 m_Refs.push_back( aFirstReference );
54 m_Flag = aType;
55 }
56
59 std::vector<SCH_REFERENCE> m_Refs;
60};
61
62
64{
65 wxString m_fieldName;
66 wxString m_label;
68 bool m_show;
69 bool m_group;
70};
71
72
74{
75public:
76 enum SCOPE : int
77 {
81 };
82
83 FIELDS_EDITOR_GRID_DATA_MODEL( SCH_REFERENCE_LIST& aSymbolsList, wxGridCellAttr* aURLEditor ) :
84 m_symbolsList( aSymbolsList ),
85 m_edited( false ),
86 m_sortColumn( 0 ),
87 m_sortAscending( false ),
89 m_groupingEnabled( false ),
90 m_excludeDNP( false ),
91 m_includeExcluded( false ),
92 m_rebuildsEnabled( true ),
93 m_urlEditor( aURLEditor )
94 {
96 }
97
99 {
100 wxSafeDecRef( m_urlEditor );
101
102 for( const auto& [col, attr] : m_colAttrs )
103 wxSafeDecRef( attr );
104 }
105
106 static const wxString QUANTITY_VARIABLE;
107 static const wxString ITEM_NUMBER_VARIABLE;
108
109 void AddColumn( const wxString& aFieldName, const wxString& aLabel, bool aAddedByUser );
110 void RemoveColumn( int aCol );
111 void RenameColumn( int aCol, const wxString& newName );
112
113 void MoveColumn( int aCol, int aNewPos )
114 {
115 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
116
117 if( aCol == aNewPos )
118 {
119 return;
120 }
121 else if( aCol < aNewPos )
122 {
123 std::rotate( std::begin( m_cols ) + aCol, std::begin( m_cols ) + aCol + 1,
124 std::begin( m_cols ) + aNewPos + 1 );
125 }
126 else
127 {
128 std::rotate( std::begin( m_cols ) + aNewPos, std::begin( m_cols ) + aCol,
129 std::begin( m_cols ) + aCol + 1 );
130 }
131 }
132
133 int GetNumberRows() override { return (int) m_rows.size(); }
134 int GetNumberCols() override { return (int) m_cols.size(); }
135
136 void SetColLabelValue( int aCol, const wxString& aLabel ) override
137 {
138 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
139 m_cols[aCol].m_label = aLabel;
140 }
141
142
143 wxString GetColLabelValue( int aCol ) override
144 {
145 wxCHECK( aCol >= 0 && aCol < (int) m_cols.size(), wxString() );
146 return m_cols[aCol].m_label;
147 }
148
149 wxString GetColFieldName( int aCol )
150 {
151 wxCHECK( aCol >= 0 && aCol < (int) m_cols.size(), wxString() );
152 return m_cols[aCol].m_fieldName;
153 }
154
155 int GetFieldNameCol( const wxString& aFieldName );
156
157 const std::vector<BOM_FIELD> GetFieldsOrdered();
158 void SetFieldsOrder( const std::vector<wxString>& aNewOrder );
159
160 bool IsEmptyCell( int aRow, int aCol ) override
161 {
162 return false; // don't allow adjacent cell overflow, even if we are actually empty
163 }
164
165 wxString GetValue( int aRow, int aCol ) override;
166 wxGridCellAttr* GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind ) override;
167
168 wxString GetValue( const DATA_MODEL_ROW& group, int aCol,
169 const wxString& refDelimiter = wxT( ", " ),
170 const wxString& refRangDelimiter = wxT( "-" ),
171 bool resolveVars = false,
172 bool listMixedValues = false );
173
174 wxString GetExportValue( int aRow, int aCol, const wxString& refDelimiter,
175 const wxString& refRangeDelimiter )
176 {
177 return GetValue( m_rows[aRow], aCol, refDelimiter, refRangeDelimiter, true, true );
178 }
179
180 void SetValue( int aRow, int aCol, const wxString& aValue ) override;
181
182 GROUP_TYPE GetRowFlags( int aRow ) { return m_rows[aRow].m_Flag; }
183
184 std::vector<SCH_REFERENCE> GetRowReferences( int aRow ) const
185 {
186 wxCHECK( aRow >= 0 && aRow < (int) m_rows.size(), std::vector<SCH_REFERENCE>() );
187 return m_rows[aRow].m_Refs;
188 }
189
190 bool ColIsReference( int aCol );
191 bool ColIsValue( int aCol );
192 bool ColIsQuantity( int aCol );
193 bool ColIsItemNumber( int aCol );
194 bool ColIsAttribute( int aCol );
195
196 void SetSorting( int aCol, bool ascending )
197 {
198 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
199 m_sortColumn = aCol;
200 m_sortAscending = ascending;
201 }
202
203 int GetSortCol() { return m_sortColumn; }
204 bool GetSortAsc() { return m_sortAscending; }
205
206 // These are used to disable the RebuildRows functionality while we're generating
207 // lots of events in the UI, e.g. applying a BOM preset, that would thrash the grid.
208 void EnableRebuilds();
209 void DisableRebuilds();
210 void RebuildRows();
211
212 void ExpandRow( int aRow );
213 void CollapseRow( int aRow );
214 void ExpandCollapseRow( int aRow );
215 void CollapseForSort();
216 void ExpandAfterSort();
217
218 void ApplyData( SCH_COMMIT& aCommit );
219
220 bool IsEdited() { return m_edited; }
221
222 int GetDataWidth( int aCol );
223
224 void SetFilter( const wxString& aFilter ) { m_filter = aFilter; }
225 const wxString& GetFilter() { return m_filter; }
226
227 void SetScope( SCOPE aScope ) { m_scope = aScope; }
228 SCOPE GetScope() { return m_scope; }
229
230 void SetPath( const SCH_SHEET_PATH& aPath ) { m_path = aPath; }
231 const SCH_SHEET_PATH& GetPath() { return m_path; }
232
235
236 /* These contradictorily named functions force including symbols that
237 * have the Exclude from BOM check box ticked. This is needed so we can view
238 * these parts in the symbol fields table dialog, while also excluding from the
239 * BOM export */
240 void SetIncludeExcludedFromBOM( bool include ) { m_includeExcluded = include; }
242
243 void SetExcludeDNP( bool exclude ) { m_excludeDNP = exclude; }
244 bool GetExcludeDNP() { return m_excludeDNP; }
245
246 void SetGroupColumn( int aCol, bool group )
247 {
248 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
249 m_cols[aCol].m_group = group;
250 }
251
252 bool GetGroupColumn( int aCol )
253 {
254 wxCHECK_MSG( aCol >= 0 && aCol < (int) m_cols.size(), false, "Invalid Column Number" );
255 return m_cols[aCol].m_group;
256 }
257
258 void SetShowColumn( int aCol, bool show )
259 {
260 wxCHECK_RET( aCol >= 0 && aCol < (int) m_cols.size(), "Invalid Column Number" );
261 m_cols[aCol].m_show = show;
262 }
263
264 bool GetShowColumn( int aCol )
265 {
266 wxCHECK_MSG( aCol >= 0 && aCol < (int) m_cols.size(), false, "Invalid Column Number" );
267 return m_cols[aCol].m_show;
268 }
269
270 void ApplyBomPreset( const BOM_PRESET& preset );
272 wxString Export( const BOM_FMT_PRESET& settings );
273
274 void AddReferences( const SCH_REFERENCE_LIST& aRefs );
275 void RemoveReferences( const SCH_REFERENCE_LIST& aRefs );
276 void RemoveSymbol( const SCH_SYMBOL& aSymbol );
277 void UpdateReferences( const SCH_REFERENCE_LIST& aRefs );
278
279 void SetColAttr( wxGridCellAttr* aAttr, int aCol ) override
280 {
281 wxSafeDecRef( m_colAttrs[aCol] );
282 m_colAttrs[aCol] = aAttr;
283 }
284
285private:
286 static bool cmp( const DATA_MODEL_ROW& lhGroup, const DATA_MODEL_ROW& rhGroup,
287 FIELDS_EDITOR_GRID_DATA_MODEL* dataModel, int sortCol, bool ascending );
288 bool unitMatch( const SCH_REFERENCE& lhRef, const SCH_REFERENCE& rhRef );
289 bool groupMatch( const SCH_REFERENCE& lhRef, const SCH_REFERENCE& rhRef );
290
291 // Helper functions to deal with translating wxGrid values to and from
292 // named field values like ${DNP}
293 bool isAttribute( const wxString& aFieldName );
294 wxString getAttributeValue( const SCH_SYMBOL&, const wxString& aAttributeName );
295 void setAttributeValue( SCH_SYMBOL& aSymbol, const wxString& aAttributeName,
296 const wxString& aValue );
297
298 /* Helper function to get the resolved field value.
299 * Handles symbols that are missing fields that would have a variable
300 * in their value because their name is the same as a variable.
301 * Example: BOM template provides ${DNP} as a field, but they symbol doesn't have the field. */
302 wxString getFieldShownText( const SCH_REFERENCE& aRef, const wxString& aFieldName );
303
304 void Sort();
305
308 void updateDataStoreSymbolField( const SCH_SYMBOL& aSymbol, const wxString& aFieldName );
309
310protected:
315 wxString m_filter;
322
323 wxGridCellAttr* m_urlEditor;
324 std::map<int, wxGridCellAttr*> m_colAttrs;
325
326 std::vector<DATA_MODEL_COL> m_cols;
327 std::vector<DATA_MODEL_ROW> m_rows;
328
329 // Data store
330 // The data model is fundamentally m_componentRefs X m_fieldNames.
331 // A map of compID : fieldSet, where fieldSet is a map of fieldName : fieldValue
332 std::map<KIID, std::map<wxString, wxString>> m_dataStore;
333};
wxString GetColFieldName(int aCol)
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 getSymbolReferences(SCH_SYMBOL *aSymbol)
wxString getAttributeValue(const SCH_SYMBOL &, const wxString &aAttributeName)
void updateDataStoreSymbolField(const SCH_SYMBOL &aSymbol, const wxString &aFieldName)
int GetFieldNameCol(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)
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)
void SetColAttr(wxGridCellAttr *aAttr, int aCol) override
std::map< int, wxGridCellAttr * > m_colAttrs
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
void UpdateReferences(const SCH_REFERENCE_LIST &aRefs)
void ApplyData(SCH_COMMIT &aCommit)
GROUP_TYPE GetRowFlags(int aRow)
std::map< KIID, std::map< wxString, wxString > > m_dataStore
static const wxString QUANTITY_VARIABLE
void SetGroupColumn(int aCol, bool group)
FIELDS_EDITOR_GRID_DATA_MODEL(SCH_REFERENCE_LIST &aSymbolsList, wxGridCellAttr *aURLEditor)
void RemoveSymbol(const SCH_SYMBOL &aSymbol)
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 storeReferenceFields(SCH_REFERENCE &aRef)
void setAttributeValue(SCH_SYMBOL &aSymbol, const wxString &aAttributeName, const wxString &aValue)
void AddReferences(const SCH_REFERENCE_LIST &aRefs)
const std::vector< BOM_FIELD > GetFieldsOrdered()
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
void SplitReferences()
Attempt to split all reference designators into a name (U) and number (1).
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:77
GROUP_TYPE
@ GROUP_COLLAPSED_DURING_SORT
@ GROUP_EXPANDED
@ GROUP_COLLAPSED
@ GROUP_SINGLETON
@ CHILD_ITEM
std::vector< SCH_REFERENCE > m_Refs
DATA_MODEL_ROW(const SCH_REFERENCE &aFirstReference, GROUP_TYPE aType)