QGIS API Documentation  3.6.0-Noosa (5873452)
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  Q_FOREACH ( const ColumnConfig &columnConfig, mColumns )
103  {
104  if ( columnConfig.type == Action && !columnConfig.hidden )
105  return true;
106  }
107  return false;
108 }
109 
111 {
112  for ( int i = 0; i < mColumns.size(); ++i )
113  {
114  if ( mColumns.at( i ).type == Action )
115  {
116  mColumns[i].hidden = !visible;
117  }
118  }
119 }
120 
122 {
123  return mActionWidgetStyle;
124 }
125 
127 {
128  mActionWidgetStyle = actionWidgetStyle;
129 }
130 
131 
132 void QgsAttributeTableConfig::readXml( const QDomNode &node )
133 {
134  mColumns.clear();
135 
136  QDomNode configNode = node.namedItem( QStringLiteral( "attributetableconfig" ) );
137  if ( !configNode.isNull() )
138  {
139  QDomNode columnsNode = configNode.toElement().namedItem( QStringLiteral( "columns" ) );
140 
141  QDomNodeList columns = columnsNode.childNodes();
142 
143  for ( int i = 0; i < columns.size(); ++i )
144  {
145  QDomElement columnElement = columns.at( i ).toElement();
146 
147  ColumnConfig column;
148 
149  if ( columnElement.attribute( QStringLiteral( "type" ) ) == QLatin1String( "actions" ) )
150  {
151  column.type = Action;
152  }
153  else
154  {
155  column.type = Field;
156  column.name = columnElement.attribute( QStringLiteral( "name" ) );
157  }
158 
159  column.hidden = columnElement.attribute( QStringLiteral( "hidden" ) ) == QLatin1String( "1" );
160  column.width = columnElement.attribute( QStringLiteral( "width" ), QStringLiteral( "-1" ) ).toDouble();
161 
162  mColumns.append( column );
163  }
164 
165  if ( configNode.toElement().attribute( QStringLiteral( "actionWidgetStyle" ) ) == QLatin1String( "buttonList" ) )
166  mActionWidgetStyle = ButtonList;
167  else
168  mActionWidgetStyle = DropDown;
169  }
170  else
171  {
172  // Before QGIS 2.16 the attribute table would hide "Hidden" widgets.
173  // They are migrated to hidden columns here.
174  QDomNodeList editTypeNodes = node.namedItem( QStringLiteral( "edittypes" ) ).childNodes();
175 
176  for ( int i = 0; i < editTypeNodes.size(); i++ )
177  {
178  QDomElement editTypeElement = editTypeNodes.at( i ).toElement();
179 
180  if ( editTypeElement.attribute( QStringLiteral( "widgetv2type" ) ) == QLatin1String( "Hidden" ) )
181  {
182  ColumnConfig column;
183 
184  column.name = editTypeElement.attribute( QStringLiteral( "name" ) );
185  column.hidden = true;
186  column.type = Field;
187  mColumns.append( column );
188  }
189  }
190  }
191 
192  mSortExpression = configNode.toElement().attribute( QStringLiteral( "sortExpression" ) );
193  Qt::SortOrder sortOrder = static_cast<Qt::SortOrder>( configNode.toElement().attribute( QStringLiteral( "sortOrder" ) ).toInt() );
194  setSortOrder( sortOrder );
195 }
196 
198 {
199  return mSortExpression;
200 }
201 
203 {
204  mSortExpression = sortExpression;
205 }
206 
208 {
209  return mColumns.at( column ).width;
210 }
211 
212 void QgsAttributeTableConfig::setColumnWidth( int column, int width )
213 {
214  mColumns[ column ].width = width;
215 }
216 
218 {
219  return mColumns.at( column ).hidden;
220 }
221 
222 void QgsAttributeTableConfig::setColumnHidden( int column, bool hidden )
223 {
224  mColumns[ column ].hidden = hidden;
225 }
226 
228 {
229  return mSortExpression != other.mSortExpression || mColumns != other.mColumns || mActionWidgetStyle != other.mActionWidgetStyle || mSortOrder != other.mSortOrder;
230 }
231 
233 {
234  return mSortOrder;
235 }
236 
238 {
239  // fix https://hub.qgis.org/issues/15803
240  if ( sortOrder != Qt::AscendingOrder && sortOrder != Qt::DescendingOrder )
241  {
242  sortOrder = Qt::AscendingOrder;
243  }
244 
245  mSortOrder = sortOrder;
246 }
247 
248 void QgsAttributeTableConfig::writeXml( QDomNode &node ) const
249 {
250  QDomDocument doc( node.ownerDocument() );
251 
252  QDomElement configElement = doc.createElement( QStringLiteral( "attributetableconfig" ) );
253  configElement.setAttribute( QStringLiteral( "actionWidgetStyle" ), mActionWidgetStyle == ButtonList ? "buttonList" : "dropDown" );
254 
255  configElement.setAttribute( QStringLiteral( "sortExpression" ), mSortExpression );
256 
257  configElement.setAttribute( QStringLiteral( "sortOrder" ), mSortOrder );
258 
259  QDomElement columnsElement = doc.createElement( QStringLiteral( "columns" ) );
260 
261  Q_FOREACH ( const ColumnConfig &column, mColumns )
262  {
263  QDomElement columnElement = doc.createElement( QStringLiteral( "column" ) );
264 
265  if ( column.type == Action )
266  {
267  columnElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "actions" ) );
268  }
269  else
270  {
271  columnElement.setAttribute( QStringLiteral( "type" ), QStringLiteral( "field" ) );
272  columnElement.setAttribute( QStringLiteral( "name" ), column.name );
273  }
274 
275  columnElement.setAttribute( QStringLiteral( "hidden" ), column.hidden );
276  columnElement.setAttribute( QStringLiteral( "width" ), QString::number( column.width ) );
277 
278  columnsElement.appendChild( columnElement );
279  }
280 
281  configElement.appendChild( columnsElement );
282 
283  node.appendChild( configElement );
284 }
285 
287 {
288  if ( columns().size() == other.columns().size() )
289  {
290  for ( int i = 0; i < columns().size(); i++ )
291  {
292  if ( columns().at( i ).name != other.columns().at( i ).name ||
293  columns().at( i ).type != other.columns().at( i ).type ||
294  columns().at( i ).hidden != other.columns().at( i ).hidden )
295  {
296  return false;
297  }
298  }
299  return true;
300  }
301 
302  return false;
303 }
304 
306 {
307  return type == other.type && name == other.name && hidden == other.hidden && width == other.width;
308 }
QgsAttributeTableConfig::Type type
The type of this column.
void setSortExpression(const QString &sortExpression)
Set the sort expression used for sorting.
void update(const QgsFields &fields)
Update the configuration with the given fields.
bool actionWidgetVisible() const
Returns true if the action widget is visible.
void setSortOrder(Qt::SortOrder sortOrder)
Set the sort order.
bool columnHidden(int column) const
Returns true if the specified column is hidden.
int columnWidth(int column) const
Returns the width of a column, or -1 if column should use default width.
Container of fields for a vector layer.
Definition: qgsfields.h:42
This column represents an action widget.
int mapVisibleColumnToIndex(int visibleColumn) const
Maps a visible column index to its original column index.
ActionWidgetStyle
The style of the action widget in the attribute table.
void setActionWidgetStyle(ActionWidgetStyle actionWidgetStyle)
Set the style of the action widget.
void setActionWidgetVisible(bool visible)
Set if the action widget is visible.
void setColumnWidth(int column, int width)
Sets the width of a column.
ActionWidgetStyle actionWidgetStyle() const
Gets the style of the action widget.
bool hidden
Flag that controls if the column is hidden.
QString name
The name of the attribute if this column represents a field.
void writeXml(QDomNode &node) const
Serialize to XML on layer save.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Gets the list with all columns and their configuration.
bool operator==(const QgsAttributeTableConfig::ColumnConfig &other) const
int width
Width of column, or -1 for default width.
bool isEmpty() const
Returns true if the configuration is empty, ie it contains no columns.
void setColumns(const QVector< QgsAttributeTableConfig::ColumnConfig > &columns)
Set the list of columns visible in the attribute table.
int indexOf(const QString &fieldName) const
Gets the field index from the field name.
Definition: qgsfields.cpp:207
A tool button with a drop-down to select the current action.
void setColumnHidden(int column, bool hidden)
Sets whether the specified column should be hidden.
This column represents a field.
Defines the configuration of a column in the attribute table.
bool operator!=(const QgsAttributeTableConfig &other) const
Compare this configuration to other.
This is a container for configuration of the attribute table.
Qt::SortOrder sortOrder() const
Gets the sort order.
QString sortExpression() const
Gets the expression used for sorting.
bool hasSameColumns(const QgsAttributeTableConfig &other) const
Compare this configuration&#39;s columns name, type, and order to other.
void readXml(const QDomNode &node)
Deserialize to XML on layer load.