Quantum GIS API Documentation  1.7.5-Wroclaw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
qgscomposerattributetable.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposerattributetable.cpp
3  -----------------------------
4  begin : April 2010
5  copyright : (C) 2010 by Marco Hugentobler
6  email : marco at hugis dot net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
19 #include "qgscomposermap.h"
20 #include "qgsmaplayerregistry.h"
21 #include "qgsvectorlayer.h"
22 
23 QgsComposerAttributeTableCompare::QgsComposerAttributeTableCompare(): mCurrentSortColumn( 0 ), mAscending( true )
24 {
25 }
26 
27 
29 {
30  QVariant v1 = m1[mCurrentSortColumn];
31  QVariant v2 = m2[mCurrentSortColumn];
32 
33  bool less = false;
34  if ( v1.type() == QVariant::String && v2.type() == QVariant::String )
35  {
36  less = v1.toString() < v2.toString();
37  }
38  else
39  {
40  less = v1.toDouble() < v2.toDouble();
41  }
42  return ( mAscending ? less : !less );
43 }
44 
45 
46 QgsComposerAttributeTable::QgsComposerAttributeTable( QgsComposition* composition ): QgsComposerTable( composition ), mVectorLayer( 0 ), mComposerMap( 0 ), \
47  mMaximumNumberOfFeatures( 5 ), mShowOnlyVisibleFeatures( true )
48 {
49  //set first vector layer from layer registry as default one
50  QMap<QString, QgsMapLayer*> layerMap = QgsMapLayerRegistry::instance()->mapLayers();
51  QMap<QString, QgsMapLayer*>::const_iterator mapIt = layerMap.constBegin();
52  for ( ; mapIt != layerMap.constEnd(); ++mapIt )
53  {
54  QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( mapIt.value() );
55  if ( vl )
56  {
57  mVectorLayer = vl;
58  break;
59  }
60  }
61  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( removeLayer( const QString& ) ) );
62 }
63 
65 {
66 
67 }
68 
69 void QgsComposerAttributeTable::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
70 {
72  {
73  return;
74  }
75  QgsComposerTable::paint( painter, itemStyle, pWidget );
76 }
77 
79 {
80  mFieldAliasMap.clear();
81  if ( mVectorLayer )
82  {
84  QgsFieldMap::const_iterator it = fieldMap.constBegin();
85  for ( ; it != fieldMap.constEnd(); ++it )
86  {
87  QString currentAlias = mVectorLayer->attributeAlias( it.key() );
88  if ( !currentAlias.isEmpty() )
89  {
90  mFieldAliasMap.insert( it.key(), currentAlias );
91  }
92  }
93  }
94 }
95 
97 {
98  if ( vl != mVectorLayer )
99  {
100  mDisplayAttributes.clear();
101  mVectorLayer = vl;
103  }
104 }
105 
107 {
108  if ( mComposerMap )
109  {
110  QObject::disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( repaint() ) );
111  }
112  mComposerMap = map;
113  if ( mComposerMap )
114  {
115  QObject::connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( repaint() ) );
116  }
117 }
118 
119 bool QgsComposerAttributeTable::getFeatureAttributes( QList<QgsAttributeMap>& attributes )
120 {
121  if ( !mVectorLayer )
122  {
123  return false;
124  }
125  attributes.clear();
126 
127  QgsRectangle selectionRect;
129  {
130  selectionRect = mComposerMap->extent();
131  }
132 
133  if ( mDisplayAttributes.size() < 1 )
134  {
136  }
137  else
138  {
140  }
141  QgsFeature f;
142  int counter = 0;
143  while ( mVectorLayer->nextFeature( f ) && counter < mMaximumNumberOfFeatures )
144  {
145  attributes.push_back( f.attributeMap() );
146  ++counter;
147  }
148 
149  //sort the list, starting with the last attribute
151  for ( int i = mSortInformation.size() - 1; i >= 0; --i )
152  {
153  c.setSortColumn( mSortInformation.at( i ).first );
154  c.setAscending( mSortInformation.at( i ).second );
155  qStableSort( attributes.begin(), attributes.end(), c );
156  }
157  return true;
158 }
159 
161 {
162  QMap<int, QString> header;
163  if ( mVectorLayer )
164  {
165  QgsFieldMap vectorFields = mVectorLayer->pendingFields();
166  QgsFieldMap::const_iterator fieldIt = vectorFields.constBegin();
167  for ( ; fieldIt != vectorFields.constEnd(); ++fieldIt )
168  {
169  if ( mDisplayAttributes.size() > 0 && !mDisplayAttributes.contains( fieldIt.key() ) )
170  {
171  continue;
172  }
173  header.insert( fieldIt.key(), attributeDisplayName( fieldIt.key(), fieldIt.value().name() ) );
174  }
175  }
176  return header;
177 }
178 
179 QString QgsComposerAttributeTable::attributeDisplayName( int attributeIndex, const QString& name ) const
180 {
181  QMap<int, QString>::const_iterator it = mFieldAliasMap.find( attributeIndex );
182  if ( it != mFieldAliasMap.constEnd() )
183  {
184  return it.value();
185  }
186  else
187  {
188  return name;
189  }
190 }
191 
193 {
194  if ( mVectorLayer )
195  {
196  if ( layerId == mVectorLayer->id() )
197  {
198  mVectorLayer = 0;
199  }
200  }
201 }
202 
203 void QgsComposerAttributeTable::setSceneRect( const QRectF& rectangle )
204 {
205  double titleHeight = 2 * mGridStrokeWidth + 2 * mLineTextDistance + fontAscentMillimeters( mHeaderFont );
206  double attributeHeight = mGridStrokeWidth + 2 * mLineTextDistance + fontAscentMillimeters( mContentFont );
207  if (( rectangle.height() - titleHeight ) > 0 )
208  {
209  mMaximumNumberOfFeatures = ( rectangle.height() - titleHeight ) / attributeHeight;
210  }
211  else
212  {
214  }
215  QgsComposerItem::setSceneRect( rectangle );
217 }
218 
219 bool QgsComposerAttributeTable::writeXML( QDomElement& elem, QDomDocument & doc ) const
220 {
221  QDomElement composerTableElem = doc.createElement( "ComposerAttributeTable" );
222  composerTableElem.setAttribute( "showOnlyVisibleFeatures", mShowOnlyVisibleFeatures );
223 
224  if ( mComposerMap )
225  {
226  composerTableElem.setAttribute( "composerMap", mComposerMap->id() );
227  }
228  else
229  {
230  composerTableElem.setAttribute( "composerMap", -1 );
231  }
232  if ( mVectorLayer )
233  {
234  composerTableElem.setAttribute( "vectorLayer", mVectorLayer->id() );
235  }
236 
237  //display attributes
238  QDomElement displayAttributesElem = doc.createElement( "displayAttributes" );
239  QSet<int>::const_iterator attIt = mDisplayAttributes.constBegin();
240  for ( ; attIt != mDisplayAttributes.constEnd(); ++attIt )
241  {
242  QDomElement attributeIndexElem = doc.createElement( "attributeEntry" );
243  attributeIndexElem.setAttribute( "index", *attIt );
244  displayAttributesElem.appendChild( attributeIndexElem );
245  }
246  composerTableElem.appendChild( displayAttributesElem );
247 
248  //alias map
249  QDomElement aliasMapElem = doc.createElement( "attributeAliasMap" );
250  QMap<int, QString>::const_iterator aliasIt = mFieldAliasMap.constBegin();
251  for ( ; aliasIt != mFieldAliasMap.constEnd(); ++aliasIt )
252  {
253  QDomElement mapEntryElem = doc.createElement( "aliasEntry" );
254  mapEntryElem.setAttribute( "key", aliasIt.key() );
255  mapEntryElem.setAttribute( "value", aliasIt.value() );
256  aliasMapElem.appendChild( mapEntryElem );
257  }
258  composerTableElem.appendChild( aliasMapElem );
259 
260  //sort info
261  QDomElement sortColumnsElem = doc.createElement( "sortColumns" );
262  QList< QPair<int, bool> >::const_iterator sortIt = mSortInformation.constBegin();
263  for ( ; sortIt != mSortInformation.constEnd(); ++sortIt )
264  {
265  QDomElement columnElem = doc.createElement( "column" );
266  columnElem.setAttribute( "index", QString::number( sortIt->first ) );
267  columnElem.setAttribute( "ascending", sortIt->second == true ? "true" : "false" );
268  sortColumnsElem.appendChild( columnElem );
269  }
270  composerTableElem.appendChild( sortColumnsElem );
271  elem.appendChild( composerTableElem );
272  bool ok = tableWriteXML( composerTableElem, doc );
273  return ok;
274 }
275 
276 bool QgsComposerAttributeTable::readXML( const QDomElement& itemElem, const QDomDocument& doc )
277 {
278  if ( itemElem.isNull() )
279  {
280  return false;
281  }
282 
283  mMaximumNumberOfFeatures = itemElem.attribute( "maxFeatures", "5" ).toInt();
284  mShowOnlyVisibleFeatures = itemElem.attribute( "showOnlyVisibleFeatures", "1" ).toInt();
285 
286  //composer map
287  int composerMapId = itemElem.attribute( "composerMap", "-1" ).toInt();
288  if ( composerMapId == -1 )
289  {
290  mComposerMap = 0;
291  }
292 
293  if ( composition() )
294  {
295  mComposerMap = composition()->getComposerMapById( composerMapId );
296  }
297  else
298  {
299  mComposerMap = 0;
300  }
301 
302  //vector layer
303  QString layerId = itemElem.attribute( "vectorLayer", "not_existing" );
304  if ( layerId == "not_existing" )
305  {
306  mVectorLayer = 0;
307  }
308  else
309  {
311  if ( ml )
312  {
313  mVectorLayer = dynamic_cast<QgsVectorLayer*>( ml );
314  }
315  }
316 
317  //restore display attribute map
318  mDisplayAttributes.clear();
319  QDomNodeList displayAttributeList = itemElem.elementsByTagName( "displayAttributes" );
320  if ( displayAttributeList.size() > 0 )
321  {
322  QDomElement displayAttributesElem = displayAttributeList.at( 0 ).toElement();
323  QDomNodeList attributeEntryList = displayAttributesElem.elementsByTagName( "attributeEntry" );
324  for ( int i = 0; i < attributeEntryList.size(); ++i )
325  {
326  QDomElement attributeEntryElem = attributeEntryList.at( i ).toElement();
327  int index = attributeEntryElem.attribute( "index", "-1" ).toInt();
328  if ( index != -1 )
329  {
330  mDisplayAttributes.insert( index );
331  }
332  }
333  }
334 
335  //restore alias map
336  mFieldAliasMap.clear();
337  QDomNodeList aliasMapNodeList = itemElem.elementsByTagName( "attributeAliasMap" );
338  if ( aliasMapNodeList.size() > 0 )
339  {
340  QDomElement attributeAliasMapElem = aliasMapNodeList.at( 0 ).toElement();
341  QDomNodeList aliasMepEntryList = attributeAliasMapElem.elementsByTagName( "aliasEntry" );
342  for ( int i = 0; i < aliasMepEntryList.size(); ++i )
343  {
344  QDomElement aliasEntryElem = aliasMepEntryList.at( i ).toElement();
345  int key = aliasEntryElem.attribute( "key", "-1" ).toInt();
346  QString value = aliasEntryElem.attribute( "value", "" );
347  mFieldAliasMap.insert( key, value );
348  }
349  }
350 
351  //restore sort columns
352  mSortInformation.clear();
353  QDomElement sortColumnsElem = itemElem.firstChildElement( "sortColumns" );
354  if ( !sortColumnsElem.isNull() )
355  {
356  QDomNodeList columns = sortColumnsElem.elementsByTagName( "column" );
357  for ( int i = 0; i < columns.size(); ++i )
358  {
359  QDomElement columnElem = columns.at( i ).toElement();
360  int attribute = columnElem.attribute( "index" ).toInt();
361  bool ascending = columnElem.attribute( "ascending" ) == "true" ? true : false;
362  mSortInformation.push_back( qMakePair( attribute, ascending ) );
363  }
364  }
365  bool success = tableReadXML( itemElem, doc );
366  emit itemChanged();
367  return success;
368 }