QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsattributetableconfig.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsattributetableconfig.cpp - QgsAttributeTableConfig
3
4 ---------------------
5 begin : 27.4.2016
6 copyright : (C) 2016 by mku
7 email : [your-email-here]
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
17
18#include "qgsfields.h"
19
20#include <QString>
21#include <QStringList>
22
23using namespace Qt::StringLiterals;
24
25QVector<QgsAttributeTableConfig::ColumnConfig> QgsAttributeTableConfig::columns() const
26{
27 return mColumns;
28}
29
31{
32 return mColumns.isEmpty();
33}
34
36{
37 return mColumns.size();
38}
39
41{
42 for ( int i = 0; i < mColumns.size(); ++i )
43 {
44 if ( mColumns.at( i ).hidden )
45 {
46 visibleColumn++;
47 continue;
48 }
49 if ( visibleColumn == i )
50 return i;
51 }
52 return -1;
53}
54
55void QgsAttributeTableConfig::setColumns( const QVector<ColumnConfig> &columns )
56{
57 mColumns = columns;
58}
59
61{
62 QStringList columns;
63
64 bool containsActionColumn = false;
65
66 for ( int i = mColumns.count() - 1; i >= 0; --i )
67 {
68 const ColumnConfig &column = mColumns.at( i );
69 if ( column.type == Field )
70 {
71 if ( fields.indexOf( column.name ) == -1 )
72 {
73 mColumns.remove( i );
74 }
75 else
76 {
77 columns.append( column.name );
78 }
79 }
80 else if ( column.type == Action )
81 {
82 containsActionColumn = true;
83 }
84 }
85
86 for ( const auto &field : fields )
87 {
88 if ( !columns.contains( field.name() ) )
89 {
90 ColumnConfig newColumn;
91 newColumn.hidden = false;
92 newColumn.type = Field;
93 newColumn.name = field.name();
94 if ( containsActionColumn )
95 {
96 mColumns.insert( mColumns.size() - 1, newColumn );
97 }
98 else
99 {
100 mColumns.append( newColumn );
101 }
102 }
103 }
104
105 if ( !containsActionColumn )
106 {
107 ColumnConfig actionConfig;
108
109 actionConfig.type = Action;
110 actionConfig.hidden = true;
111
112 mColumns.append( actionConfig );
113 }
114}
115
117{
118 const auto constMColumns = mColumns;
119 for ( const ColumnConfig &columnConfig : constMColumns )
120 {
121 if ( columnConfig.type == Action && !columnConfig.hidden )
122 return true;
123 }
124 return false;
125}
126
128{
129 for ( int i = 0; i < mColumns.size(); ++i )
130 {
131 if ( mColumns.at( i ).type == Action )
132 {
133 mColumns[i].hidden = !visible;
134 }
135 }
136}
137
142
147
148
149void QgsAttributeTableConfig::readXml( const QDomNode &node )
150{
151 mColumns.clear();
152
153 const QDomNode configNode = node.namedItem( u"attributetableconfig"_s );
154 if ( !configNode.isNull() )
155 {
156 const QDomNode columnsNode = configNode.toElement().namedItem( u"columns"_s );
157
158 const QDomNodeList columns = columnsNode.childNodes();
159
160 for ( int i = 0; i < columns.size(); ++i )
161 {
162 const QDomElement columnElement = columns.at( i ).toElement();
163
164 ColumnConfig column;
165
166 if ( columnElement.attribute( u"type"_s ) == "actions"_L1 )
167 {
168 column.type = Action;
169 }
170 else
171 {
172 column.type = Field;
173 column.name = columnElement.attribute( u"name"_s );
174 }
175
176 column.hidden = columnElement.attribute( u"hidden"_s ) == "1"_L1;
177 column.width = columnElement.attribute( u"width"_s, u"-1"_s ).toDouble();
178
179 mColumns.append( column );
180 }
181
182 if ( configNode.toElement().attribute( u"actionWidgetStyle"_s ) == "buttonList"_L1 )
183 mActionWidgetStyle = ButtonList;
184 else
185 mActionWidgetStyle = DropDown;
186 }
187 else
188 {
189 // Before QGIS 2.16 the attribute table would hide "Hidden" widgets.
190 // They are migrated to hidden columns here.
191 const QDomNodeList editTypeNodes = node.namedItem( u"edittypes"_s ).childNodes();
192
193 for ( int i = 0; i < editTypeNodes.size(); i++ )
194 {
195 const QDomElement editTypeElement = editTypeNodes.at( i ).toElement();
196
197 if ( editTypeElement.attribute( u"widgetv2type"_s ) == "Hidden"_L1 )
198 {
199 ColumnConfig column;
200
201 column.name = editTypeElement.attribute( u"name"_s );
202 column.hidden = true;
203 column.type = Field;
204 mColumns.append( column );
205 }
206 }
207 }
208
209 mSortExpression = configNode.toElement().attribute( u"sortExpression"_s );
210 const Qt::SortOrder sortOrder = static_cast<Qt::SortOrder>( configNode.toElement().attribute( u"sortOrder"_s ).toInt() );
212}
213
215{
216 return mSortExpression;
217}
218
220{
221 mSortExpression = sortExpression;
222}
223
225{
226 return mColumns.at( column ).width;
227}
228
229void QgsAttributeTableConfig::setColumnWidth( int column, int width )
230{
231 mColumns[ column ].width = width;
232}
233
235{
236 return mColumns.at( column ).hidden;
237}
238
239void QgsAttributeTableConfig::setColumnHidden( int column, bool hidden )
240{
241 mColumns[ column ].hidden = hidden;
242}
243
245{
246 return mSortExpression != other.mSortExpression || mColumns != other.mColumns || mActionWidgetStyle != other.mActionWidgetStyle || mSortOrder != other.mSortOrder;
247}
248
250{
251 return mSortOrder;
252}
253
255{
256 // fix https://hub.qgis.org/issues/15803
257 if ( sortOrder != Qt::AscendingOrder && sortOrder != Qt::DescendingOrder )
258 {
259 sortOrder = Qt::AscendingOrder;
260 }
261
262 mSortOrder = sortOrder;
263}
264
265void QgsAttributeTableConfig::writeXml( QDomNode &node ) const
266{
267 QDomDocument doc( node.ownerDocument() );
268
269 QDomElement configElement = doc.createElement( u"attributetableconfig"_s );
270 configElement.setAttribute( u"actionWidgetStyle"_s, mActionWidgetStyle == ButtonList ? "buttonList" : "dropDown" );
271
272 configElement.setAttribute( u"sortExpression"_s, mSortExpression );
273
274 configElement.setAttribute( u"sortOrder"_s, mSortOrder );
275
276 QDomElement columnsElement = doc.createElement( u"columns"_s );
277
278 const auto constMColumns = mColumns;
279 for ( const ColumnConfig &column : constMColumns )
280 {
281 QDomElement columnElement = doc.createElement( u"column"_s );
282
283 if ( column.type == Action )
284 {
285 columnElement.setAttribute( u"type"_s, u"actions"_s );
286 }
287 else
288 {
289 columnElement.setAttribute( u"type"_s, u"field"_s );
290 columnElement.setAttribute( u"name"_s, column.name );
291 }
292
293 columnElement.setAttribute( u"hidden"_s, column.hidden );
294 columnElement.setAttribute( u"width"_s, QString::number( column.width ) );
295
296 columnsElement.appendChild( columnElement );
297 }
298
299 configElement.appendChild( columnsElement );
300
301 node.appendChild( configElement );
302}
303
305{
306 if ( columns().size() == other.columns().size() )
307 {
308 for ( int i = 0; i < columns().size(); i++ )
309 {
310 if ( columns().at( i ).name != other.columns().at( i ).name ||
311 columns().at( i ).type != other.columns().at( i ).type ||
312 columns().at( i ).hidden != other.columns().at( i ).hidden )
313 {
314 return false;
315 }
316 }
317 return true;
318 }
319
320 return false;
321}
322
324{
325 return type == other.type && name == other.name && hidden == other.hidden && width == other.width;
326}
void setActionWidgetVisible(bool visible)
Set if the action widget is visible.
bool isEmpty() const
Returns true if the configuration is empty, ie it contains no columns.
void setSortExpression(const QString &sortExpression)
Set the sort expression used for sorting.
@ Action
This column represents an action widget.
@ Field
This column represents a field.
void readXml(const QDomNode &node)
Deserialize to XML on layer load.
Qt::SortOrder sortOrder() const
Gets the sort order.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Gets the list with all columns and their configuration.
int mapVisibleColumnToIndex(int visibleColumn) const
Maps a visible column index to its original column index.
void update(const QgsFields &fields)
Update the configuration with the given fields.
ActionWidgetStyle
The style of the action widget in the attribute table.
@ DropDown
A tool button with a drop-down to select the current action.
bool actionWidgetVisible() const
Returns true if the action widget is visible.
void setActionWidgetStyle(ActionWidgetStyle actionWidgetStyle)
Set the style of the action widget.
void setSortOrder(Qt::SortOrder sortOrder)
Set the sort order.
int columnWidth(int column) const
Returns the width of a column, or -1 if column should use default width.
QgsAttributeTableConfig()=default
void setColumns(const QVector< QgsAttributeTableConfig::ColumnConfig > &columns)
Set the list of columns visible in the attribute table.
bool columnHidden(int column) const
Returns true if the specified column is hidden.
void setColumnHidden(int column, bool hidden)
Sets whether the specified column should be hidden.
bool operator!=(const QgsAttributeTableConfig &other) const
ActionWidgetStyle actionWidgetStyle() const
Gets the style of the action widget.
QString sortExpression() const
Gets the expression used for sorting.
void setColumnWidth(int column, int width)
Sets the width of a column.
void writeXml(QDomNode &node) const
Serialize to XML on layer save.
bool hasSameColumns(const QgsAttributeTableConfig &other) const
Compare this configuration's columns name, type, and order to other.
int size() const
Returns the number of columns in the configuration.
Container of fields for a vector layer.
Definition qgsfields.h:46
Q_INVOKABLE int indexOf(const QString &fieldName) const
Gets the field index from the field name.
Defines the configuration of a column in the attribute table.
QgsAttributeTableConfig::Type type
The type of this column.
bool operator==(const QgsAttributeTableConfig::ColumnConfig &other) const
bool hidden
Flag that controls if the column is hidden.
int width
Width of column, or -1 for default width.
QString name
The name of the attribute if this column represents a field.