QGIS API Documentation  3.25.0-Master (dec16ba68b)
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  if ( containsActionColumn )
90  {
91  mColumns.insert( mColumns.size() - 1, newColumn );
92  }
93  else
94  {
95  mColumns.append( newColumn );
96  }
97  }
98  }
99 
100  if ( !containsActionColumn )
101  {
102  ColumnConfig actionConfig;
103 
104  actionConfig.type = Action;
105  actionConfig.hidden = true;
106 
107  mColumns.append( actionConfig );
108  }
109 }
110 
112 {
113  const auto constMColumns = mColumns;
114  for ( const ColumnConfig &columnConfig : constMColumns )
115  {
116  if ( columnConfig.type == Action && !columnConfig.hidden )
117  return true;
118  }
119  return false;
120 }
121 
123 {
124  for ( int i = 0; i < mColumns.size(); ++i )
125  {
126  if ( mColumns.at( i ).type == Action )
127  {
128  mColumns[i].hidden = !visible;
129  }
130  }
131 }
132 
134 {
135  return mActionWidgetStyle;
136 }
137 
139 {
140  mActionWidgetStyle = actionWidgetStyle;
141 }
142 
143 
144 void QgsAttributeTableConfig::readXml( const QDomNode &node )
145 {
146  mColumns.clear();
147 
148  const QDomNode configNode = node.namedItem( QStringLiteral( "attributetableconfig" ) );
149  if ( !configNode.isNull() )
150  {
151  const QDomNode columnsNode = configNode.toElement().namedItem( QStringLiteral( "columns" ) );
152 
153  const QDomNodeList columns = columnsNode.childNodes();
154 
155  for ( int i = 0; i < columns.size(); ++i )
156  {
157  const QDomElement columnElement = columns.at( i ).toElement();
158 
159  ColumnConfig column;
160 
161  if ( columnElement.attribute( QStringLiteral( "type" ) ) == QLatin1String( "actions" ) )
162  {
163  column.type = Action;
164  }
165  else
166  {
167  column.type = Field;
168  column.name = columnElement.attribute( QStringLiteral( "name" ) );
169  }
170 
171  column.hidden = columnElement.attribute( QStringLiteral( "hidden" ) ) == QLatin1String( "1" );
172  column.width = columnElement.attribute( QStringLiteral( "width" ), QStringLiteral( "-1" ) ).toDouble();
173 
174  mColumns.append( column );
175  }
176 
177  if ( configNode.toElement().attribute( QStringLiteral( "actionWidgetStyle" ) ) == QLatin1String( "buttonList" ) )
178  mActionWidgetStyle = ButtonList;
179  else
180  mActionWidgetStyle = DropDown;
181  }
182  else
183  {
184  // Before QGIS 2.16 the attribute table would hide "Hidden" widgets.
185  // They are migrated to hidden columns here.
186  const QDomNodeList editTypeNodes = node.namedItem( QStringLiteral( "edittypes" ) ).childNodes();
187 
188  for ( int i = 0; i < editTypeNodes.size(); i++ )
189  {
190  const QDomElement editTypeElement = editTypeNodes.at( i ).toElement();
191 
192  if ( editTypeElement.attribute( QStringLiteral( "widgetv2type" ) ) == QLatin1String( "Hidden" ) )
193  {
194  ColumnConfig column;
195 
196  column.name = editTypeElement.attribute( QStringLiteral( "name" ) );
197  column.hidden = true;
198  column.type = Field;
199  mColumns.append( column );
200  }
201  }
202  }
203 
204  mSortExpression = configNode.toElement().attribute( QStringLiteral( "sortExpression" ) );
205  const Qt::SortOrder sortOrder = static_cast<Qt::SortOrder>( configNode.toElement().attribute( QStringLiteral( "sortOrder" ) ).toInt() );
207 }
208 
210 {
211  return mSortExpression;
212 }
213 
214 void QgsAttributeTableConfig::setSortExpression( const QString &sortExpression )
215 {
216  mSortExpression = sortExpression;
217 }
218 
220 {
221  return mColumns.at( column ).width;
222 }
223 
224 void QgsAttributeTableConfig::setColumnWidth( int column, int width )
225 {
226  mColumns[ column ].width = width;
227 }
228 
230 {
231  return mColumns.at( column ).hidden;
232 }
233 
234 void QgsAttributeTableConfig::setColumnHidden( int column, bool hidden )
235 {
236  mColumns[ column ].hidden = hidden;
237 }
238 
240 {
241  return mSortExpression != other.mSortExpression || mColumns != other.mColumns || mActionWidgetStyle != other.mActionWidgetStyle || mSortOrder != other.mSortOrder;
242 }
243 
245 {
246  return mSortOrder;
247 }
248 
249 void QgsAttributeTableConfig::setSortOrder( Qt::SortOrder sortOrder )
250 {
251  // fix https://hub.qgis.org/issues/15803
252  if ( sortOrder != Qt::AscendingOrder && sortOrder != Qt::DescendingOrder )
253  {
254  sortOrder = Qt::AscendingOrder;
255  }
256 
257  mSortOrder = sortOrder;
258 }
259 
260 void QgsAttributeTableConfig::writeXml( QDomNode &node ) const
261 {
262  QDomDocument doc( node.ownerDocument() );
263 
264  QDomElement configElement = doc.createElement( QStringLiteral( "attributetableconfig" ) );
265  configElement.setAttribute( QStringLiteral( "actionWidgetStyle" ), mActionWidgetStyle == ButtonList ? "buttonList" : "dropDown" );
266 
267  configElement.setAttribute( QStringLiteral( "sortExpression" ), mSortExpression );
268 
269  configElement.setAttribute( QStringLiteral( "sortOrder" ), mSortOrder );
270 
271  QDomElement columnsElement = doc.createElement( QStringLiteral( "columns" ) );
272 
273  const auto constMColumns = mColumns;
274  for ( const ColumnConfig &column : constMColumns )
275  {
276  QDomElement columnElement = doc.createElement( QStringLiteral( "column" ) );
277 
278  if ( column.type == Action )
279  {
280  columnElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "actions" ) );
281  }
282  else
283  {
284  columnElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "field" ) );
285  columnElement.setAttribute( QStringLiteral( "name" ), column.name );
286  }
287 
288  columnElement.setAttribute( QStringLiteral( "hidden" ), column.hidden );
289  columnElement.setAttribute( QStringLiteral( "width" ), QString::number( column.width ) );
290 
291  columnsElement.appendChild( columnElement );
292  }
293 
294  configElement.appendChild( columnsElement );
295 
296  node.appendChild( configElement );
297 }
298 
300 {
301  if ( columns().size() == other.columns().size() )
302  {
303  for ( int i = 0; i < columns().size(); i++ )
304  {
305  if ( columns().at( i ).name != other.columns().at( i ).name ||
306  columns().at( i ).type != other.columns().at( i ).type ||
307  columns().at( i ).hidden != other.columns().at( i ).hidden )
308  {
309  return false;
310  }
311  }
312  return true;
313  }
314 
315  return false;
316 }
317 
319 {
320  return type == other.type && name == other.name && hidden == other.hidden && width == other.width;
321 }
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.