QGIS API Documentation  3.20.0-Odense (decaadbb31)
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 #include "qgsfields.h"
18 #include <QStringList>
19 
20 QVector<QgsAttributeTableConfig::ColumnConfig> QgsAttributeTableConfig::columns() const
21 {
22  return mColumns;
23 }
24 
26 {
27  return mColumns.isEmpty();
28 }
29 
31 {
32  for ( int i = 0; i < mColumns.size(); ++i )
33  {
34  if ( mColumns.at( i ).hidden )
35  {
36  visibleColumn++;
37  continue;
38  }
39  if ( visibleColumn == i )
40  return i;
41  }
42  return -1;
43 }
44 
45 void QgsAttributeTableConfig::setColumns( const QVector<ColumnConfig> &columns )
46 {
47  mColumns = columns;
48 }
49 
51 {
52  QStringList columns;
53 
54  bool containsActionColumn = false;
55 
56  for ( int i = mColumns.count() - 1; i >= 0; --i )
57  {
58  const ColumnConfig &column = mColumns.at( i );
59  if ( column.type == Field )
60  {
61  if ( fields.indexOf( column.name ) == -1 )
62  {
63  mColumns.remove( i );
64  }
65  else
66  {
67  columns.append( column.name );
68  }
69  }
70  else if ( column.type == Action )
71  {
72  containsActionColumn = true;
73  }
74  }
75 
76  for ( const auto &field : fields )
77  {
78  if ( !columns.contains( field.name() ) )
79  {
80  ColumnConfig newColumn;
81  newColumn.hidden = false;
82  newColumn.type = Field;
83  newColumn.name = field.name();
84 
85  mColumns.append( newColumn );
86  }
87  }
88 
89  if ( !containsActionColumn )
90  {
91  ColumnConfig actionConfig;
92 
93  actionConfig.type = Action;
94  actionConfig.hidden = true;
95 
96  mColumns.append( actionConfig );
97  }
98 }
99 
101 {
102  const auto constMColumns = mColumns;
103  for ( const ColumnConfig &columnConfig : constMColumns )
104  {
105  if ( columnConfig.type == Action && !columnConfig.hidden )
106  return true;
107  }
108  return false;
109 }
110 
112 {
113  for ( int i = 0; i < mColumns.size(); ++i )
114  {
115  if ( mColumns.at( i ).type == Action )
116  {
117  mColumns[i].hidden = !visible;
118  }
119  }
120 }
121 
123 {
124  return mActionWidgetStyle;
125 }
126 
128 {
129  mActionWidgetStyle = actionWidgetStyle;
130 }
131 
132 
133 void QgsAttributeTableConfig::readXml( const QDomNode &node )
134 {
135  mColumns.clear();
136 
137  QDomNode configNode = node.namedItem( QStringLiteral( "attributetableconfig" ) );
138  if ( !configNode.isNull() )
139  {
140  QDomNode columnsNode = configNode.toElement().namedItem( QStringLiteral( "columns" ) );
141 
142  QDomNodeList columns = columnsNode.childNodes();
143 
144  for ( int i = 0; i < columns.size(); ++i )
145  {
146  QDomElement columnElement = columns.at( i ).toElement();
147 
148  ColumnConfig column;
149 
150  if ( columnElement.attribute( QStringLiteral( "type" ) ) == QLatin1String( "actions" ) )
151  {
152  column.type = Action;
153  }
154  else
155  {
156  column.type = Field;
157  column.name = columnElement.attribute( QStringLiteral( "name" ) );
158  }
159 
160  column.hidden = columnElement.attribute( QStringLiteral( "hidden" ) ) == QLatin1String( "1" );
161  column.width = columnElement.attribute( QStringLiteral( "width" ), QStringLiteral( "-1" ) ).toDouble();
162 
163  mColumns.append( column );
164  }
165 
166  if ( configNode.toElement().attribute( QStringLiteral( "actionWidgetStyle" ) ) == QLatin1String( "buttonList" ) )
167  mActionWidgetStyle = ButtonList;
168  else
169  mActionWidgetStyle = DropDown;
170  }
171  else
172  {
173  // Before QGIS 2.16 the attribute table would hide "Hidden" widgets.
174  // They are migrated to hidden columns here.
175  QDomNodeList editTypeNodes = node.namedItem( QStringLiteral( "edittypes" ) ).childNodes();
176 
177  for ( int i = 0; i < editTypeNodes.size(); i++ )
178  {
179  QDomElement editTypeElement = editTypeNodes.at( i ).toElement();
180 
181  if ( editTypeElement.attribute( QStringLiteral( "widgetv2type" ) ) == QLatin1String( "Hidden" ) )
182  {
183  ColumnConfig column;
184 
185  column.name = editTypeElement.attribute( QStringLiteral( "name" ) );
186  column.hidden = true;
187  column.type = Field;
188  mColumns.append( column );
189  }
190  }
191  }
192 
193  mSortExpression = configNode.toElement().attribute( QStringLiteral( "sortExpression" ) );
194  Qt::SortOrder sortOrder = static_cast<Qt::SortOrder>( configNode.toElement().attribute( QStringLiteral( "sortOrder" ) ).toInt() );
196 }
197 
199 {
200  return mSortExpression;
201 }
202 
203 void QgsAttributeTableConfig::setSortExpression( const QString &sortExpression )
204 {
205  mSortExpression = sortExpression;
206 }
207 
209 {
210  return mColumns.at( column ).width;
211 }
212 
213 void QgsAttributeTableConfig::setColumnWidth( int column, int width )
214 {
215  mColumns[ column ].width = width;
216 }
217 
219 {
220  return mColumns.at( column ).hidden;
221 }
222 
223 void QgsAttributeTableConfig::setColumnHidden( int column, bool hidden )
224 {
225  mColumns[ column ].hidden = hidden;
226 }
227 
229 {
230  return mSortExpression != other.mSortExpression || mColumns != other.mColumns || mActionWidgetStyle != other.mActionWidgetStyle || mSortOrder != other.mSortOrder;
231 }
232 
234 {
235  return mSortOrder;
236 }
237 
238 void QgsAttributeTableConfig::setSortOrder( Qt::SortOrder sortOrder )
239 {
240  // fix https://hub.qgis.org/issues/15803
241  if ( sortOrder != Qt::AscendingOrder && sortOrder != Qt::DescendingOrder )
242  {
243  sortOrder = Qt::AscendingOrder;
244  }
245 
246  mSortOrder = sortOrder;
247 }
248 
249 void QgsAttributeTableConfig::writeXml( QDomNode &node ) const
250 {
251  QDomDocument doc( node.ownerDocument() );
252 
253  QDomElement configElement = doc.createElement( QStringLiteral( "attributetableconfig" ) );
254  configElement.setAttribute( QStringLiteral( "actionWidgetStyle" ), mActionWidgetStyle == ButtonList ? "buttonList" : "dropDown" );
255 
256  configElement.setAttribute( QStringLiteral( "sortExpression" ), mSortExpression );
257 
258  configElement.setAttribute( QStringLiteral( "sortOrder" ), mSortOrder );
259 
260  QDomElement columnsElement = doc.createElement( QStringLiteral( "columns" ) );
261 
262  const auto constMColumns = mColumns;
263  for ( const ColumnConfig &column : constMColumns )
264  {
265  QDomElement columnElement = doc.createElement( QStringLiteral( "column" ) );
266 
267  if ( column.type == Action )
268  {
269  columnElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "actions" ) );
270  }
271  else
272  {
273  columnElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "field" ) );
274  columnElement.setAttribute( QStringLiteral( "name" ), column.name );
275  }
276 
277  columnElement.setAttribute( QStringLiteral( "hidden" ), column.hidden );
278  columnElement.setAttribute( QStringLiteral( "width" ), QString::number( column.width ) );
279 
280  columnsElement.appendChild( columnElement );
281  }
282 
283  configElement.appendChild( columnsElement );
284 
285  node.appendChild( configElement );
286 }
287 
289 {
290  if ( columns().size() == other.columns().size() )
291  {
292  for ( int i = 0; i < columns().size(); i++ )
293  {
294  if ( columns().at( i ).name != other.columns().at( i ).name ||
295  columns().at( i ).type != other.columns().at( i ).type ||
296  columns().at( i ).hidden != other.columns().at( i ).hidden )
297  {
298  return false;
299  }
300  }
301  return true;
302  }
303 
304  return false;
305 }
306 
308 {
309  return type == other.type && name == other.name && hidden == other.hidden && width == other.width;
310 }
This is a container for configuration of the attribute table.
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.
@ ButtonList
A list of buttons.
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.
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
Compare this configuration to other.
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.
QString name
Definition: qgsfield.h:60
Container of fields for a vector layer.
Definition: qgsfields.h:45
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:207
const QgsField & field
Definition: qgsfield.h:463
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.