QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 <QStringList>
19 
21  : mActionWidgetStyle( DropDown )
22 {
23 
24 }
25 
27 {
28  return mColumns;
29 }
30 
32 {
33  return mColumns.isEmpty();
34 }
35 
37 {
38  for ( int i = 0; i < mColumns.size(); ++i )
39  {
40  if ( mColumns.at( i ).hidden )
41  {
42  visibleColumn++;
43  continue;
44  }
45  if ( visibleColumn == i )
46  return i;
47  }
48  return -1;
49 }
50 
52 {
53  mColumns = columns;
54 }
55 
57 {
59 
60  bool containsActionColumn = false;
61 
62  for ( int i = mColumns.count() - 1; i >= 0; --i )
63  {
64  const ColumnConfig& column = mColumns.at( i );
65  if ( column.type == Field )
66  {
67  if ( fields.indexFromName( column.name ) == -1 )
68  {
69  mColumns.remove( i );
70  }
71  else
72  {
73  columns.append( column.name );
74  }
75  }
76  else if ( column.type == Action )
77  {
78  containsActionColumn = true;
79  }
80  }
81 
82  Q_FOREACH ( const QgsField& field, fields )
83  {
84  if ( !columns.contains( field.name() ) )
85  {
86  ColumnConfig newColumn;
87  newColumn.hidden = false;
88  newColumn.type = Field;
89  newColumn.name = field.name();
90 
91  mColumns.append( newColumn );
92  }
93  }
94 
95  if ( !containsActionColumn )
96  {
97  ColumnConfig actionConfig;
98 
99  actionConfig.type = Action;
100  actionConfig.hidden = true;
101 
102  mColumns.append( actionConfig );
103  }
104 }
105 
107 {
108  Q_FOREACH ( const ColumnConfig& columnConfig, mColumns )
109  {
110  if ( columnConfig.type == Action && columnConfig.hidden == false )
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 
139 {
140  mColumns.clear();
141 
142  QDomNode configNode = node.namedItem( "attributetableconfig" );
143  if ( !configNode.isNull() )
144  {
145  QDomNode columnsNode = configNode.toElement().namedItem( "columns" );
146 
147  QDomNodeList columns = columnsNode.childNodes();
148 
149  for ( int i = 0; i < columns.size(); ++i )
150  {
151  QDomElement columnElement = columns.at( i ).toElement();
152 
153  ColumnConfig column;
154 
155  if ( columnElement.attribute( "type" ) == "actions" )
156  {
157  column.type = Action;
158  }
159  else
160  {
161  column.type = Field;
162  column.name = columnElement.attribute( "name" );
163  }
164 
165  column.hidden = columnElement.attribute( "hidden" ) == "1";
166  column.width = columnElement.attribute( "width", "-1" ).toDouble();
167 
168  mColumns.append( column );
169  }
170 
171  if ( configNode.toElement().attribute( "actionWidgetStyle" ) == "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  QDomNodeList editTypeNodes = node.namedItem( "edittypes" ).childNodes();
181 
182  for ( int i = 0; i < editTypeNodes.size(); i++ )
183  {
184  QDomElement editTypeElement = editTypeNodes.at( i ).toElement();
185 
186  if ( editTypeElement.attribute( "widgetv2type" ) == "Hidden" )
187  {
188  ColumnConfig column;
189 
190  column.name = editTypeElement.attribute( "name" );
191  column.hidden = true;
192  column.type = Field;
193  mColumns.append( column );
194  }
195  }
196  }
197 
198  mSortExpression = configNode.toElement().attribute( "sortExpression" );
199  Qt::SortOrder sortOrder = static_cast<Qt::SortOrder>( configNode.toElement().attribute( "sortOrder" ).toInt() );
200  setSortOrder( sortOrder );
201 }
202 
204 {
205  return mSortExpression;
206 }
207 
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 
244 {
245  // fix https://hub.qgis.org/issues/15803
246  if ( sortOrder != Qt::AscendingOrder && sortOrder != Qt::DescendingOrder )
247  {
248  mSortOrder = Qt::AscendingOrder;
249  }
250  else
251  {
252  mSortOrder = sortOrder;
253  }
254 }
255 
257 {
258  QDomDocument doc( node.ownerDocument() );
259 
260  QDomElement configElement = doc.createElement( "attributetableconfig" );
261  configElement.setAttribute( "actionWidgetStyle", mActionWidgetStyle == ButtonList ? "buttonList" : "dropDown" );
262 
263  configElement.setAttribute( "sortExpression", mSortExpression );
264 
265  configElement.setAttribute( "sortOrder", mSortOrder );
266 
267  QDomElement columnsElement = doc.createElement( "columns" );
268 
269  Q_FOREACH ( const ColumnConfig& column, mColumns )
270  {
271  QDomElement columnElement = doc.createElement( "column" );
272 
273  if ( column.type == Action )
274  {
275  columnElement.setAttribute( "type", "actions" );
276  }
277  else
278  {
279  columnElement.setAttribute( "type", "field" );
280  columnElement.setAttribute( "name", column.name );
281  }
282 
283  columnElement.setAttribute( "hidden", column.hidden );
284  columnElement.setAttribute( "width", QString::number( column.width ) );
285 
286  columnsElement.appendChild( columnElement );
287  }
288 
289  configElement.appendChild( columnsElement );
290 
291  node.appendChild( configElement );
292 }
293 
295 {
296  return type == other.type && name == other.name && hidden == other.hidden && width == other.width;
297 }
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.
QString name
Definition: qgsfield.h:52
void setSortOrder(const Qt::SortOrder &sortOrder)
Set the sort order.
QDomNode appendChild(const QDomNode &newChild)
QString attribute(const QString &name, const QString &defValue) const
bool columnHidden(int column) const
Returns true if the specified column is hidden.
bool contains(const QString &str, Qt::CaseSensitivity cs) const
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: qgsfield.h:252
This column represents an action widget.
int mapVisibleColumnToIndex(int visibleColumn) const
Maps a visible column index to its original column index.
double toDouble(bool *ok) const
QDomNodeList childNodes() const
ActionWidgetStyle
The style of the action widget in the attribute table.
void setActionWidgetStyle(const ActionWidgetStyle &actionWidgetStyle)
Set the style of the action widget.
QDomElement toElement() const
void setActionWidgetVisible(bool visible)
Set if the action widget is visible.
void setColumnWidth(int column, int width)
Sets the width of a column.
QString number(int n, int base)
ActionWidgetStyle actionWidgetStyle() const
Get the style of the action widget.
void append(const T &value)
QDomDocument ownerDocument() const
void setAttribute(const QString &name, const QString &value)
int toInt(bool *ok, int base) const
bool hidden
Flag that controls if the column is hidden.
bool operator==(const ColumnConfig &other) const
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
QString name
The name of the attribute if this column represents a field.
QDomNode namedItem(const QString &name) const
void writeXml(QDomNode &node) const
Serialize to XML on layer save.
QVector< ColumnConfig > columns() const
Get the list with all columns and their configuration.
bool isNull() const
int width
Width of column, or -1 for default width.
int indexFromName(const QString &name) const
Look up field&#39;s index from name. Returns -1 on error.
Definition: qgsfield.cpp:461
bool isEmpty() const
Returns true if the configuration is empty, ie it contains no columns.
A tool button with a dropdown 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.
int size() const
This is a container for configuration of the attribute table.
Qt::SortOrder sortOrder() const
Get the sort order.
QString sortExpression() const
Get the expression used for sorting.
void readXml(const QDomNode &node)
Deserialize to XML on layer load.
QDomNode at(int index) const
void setColumns(const QVector< ColumnConfig > &columns)
Set the list of columns visible in the attribute table.