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