[QGIS Commit] r12682 - in trunk/qgis/src: app app/composer core core/composer gui ui

svn_qgis at osgeo.org svn_qgis at osgeo.org
Wed Jan 6 13:06:47 EST 2010


Author: mhugent
Date: 2010-01-06 13:06:45 -0500 (Wed, 06 Jan 2010)
New Revision: 12682

Added:
   trunk/qgis/src/app/composer/qgscomposertablewidget.cpp
   trunk/qgis/src/app/composer/qgscomposertablewidget.h
   trunk/qgis/src/core/composer/qgscomposertable.cpp
   trunk/qgis/src/core/composer/qgscomposertable.h
   trunk/qgis/src/ui/qgscomposertablewidgetbase.ui
Modified:
   trunk/qgis/src/app/CMakeLists.txt
   trunk/qgis/src/app/composer/qgscomposer.cpp
   trunk/qgis/src/app/composer/qgscomposer.h
   trunk/qgis/src/core/CMakeLists.txt
   trunk/qgis/src/core/composer/qgscomposeritem.cpp
   trunk/qgis/src/core/composer/qgscomposeritem.h
   trunk/qgis/src/gui/qgscomposerview.cpp
   trunk/qgis/src/gui/qgscomposerview.h
   trunk/qgis/src/ui/qgscomposerbase.ui
Log:
[FEATURE]: A table widget to display feature attributes in the composer (but it still needs a bit more settings...)

Modified: trunk/qgis/src/app/CMakeLists.txt
===================================================================
--- trunk/qgis/src/app/CMakeLists.txt	2010-01-06 13:24:33 UTC (rev 12681)
+++ trunk/qgis/src/app/CMakeLists.txt	2010-01-06 18:06:45 UTC (rev 12682)
@@ -83,6 +83,7 @@
   composer/qgscomposermapwidget.cpp
   composer/qgscomposerscalebarwidget.cpp
   composer/qgscomposershapewidget.cpp
+  composer/qgscomposertablewidget.cpp
   composer/qgscomposerlegenditemdialog.cpp
   composer/qgscomposerlegendwidget.cpp
   composer/qgscompositionwidget.cpp
@@ -184,6 +185,7 @@
   composer/qgscomposermapwidget.h
   composer/qgscomposerpicturewidget.h
   composer/qgscomposerscalebarwidget.h
+  composer/qgscomposertablewidget.h
   composer/qgscomposershapewidget.h
   composer/qgscompositionwidget.h
   composer/qgsitempositiondialog.h

Modified: trunk/qgis/src/app/composer/qgscomposer.cpp
===================================================================
--- trunk/qgis/src/app/composer/qgscomposer.cpp	2010-01-06 13:24:33 UTC (rev 12681)
+++ trunk/qgis/src/app/composer/qgscomposer.cpp	2010-01-06 18:06:45 UTC (rev 12682)
@@ -35,6 +35,8 @@
 #include "qgscomposerscalebarwidget.h"
 #include "qgscomposershape.h"
 #include "qgscomposershapewidget.h"
+#include "qgscomposertable.h"
+#include "qgscomposertablewidget.h"
 #include "qgsexception.h"
 #include "qgsproject.h"
 #include "qgsmapcanvas.h"
@@ -112,6 +114,7 @@
   toggleActionGroup->addAction( mActionSelectMoveItem );
   toggleActionGroup->addAction( mActionAddBasicShape );
   toggleActionGroup->addAction( mActionAddArrow );
+  toggleActionGroup->addAction( mActionAddTable );
   toggleActionGroup->setExclusive( true );
 
   mActionAddNewMap->setCheckable( true );
@@ -160,6 +163,7 @@
   layoutMenu->addAction( mActionMoveItemContent );
   layoutMenu->addAction( mActionAddBasicShape );
   layoutMenu->addAction( mActionAddArrow );
+  layoutMenu->addAction( mActionAddTable );
   layoutMenu->addSeparator();
   layoutMenu->addAction( mActionGroupItems );
   layoutMenu->addAction( mActionUngroupItems );
@@ -255,6 +259,7 @@
   mActionAddNewScalebar->setIcon( QgisApp::getThemeIcon( "/mActionScaleBar.png" ) );
   mActionAddBasicShape->setIcon( QgisApp::getThemeIcon( "/mActionAddBasicShape.png" ) );
   mActionAddArrow->setIcon( QgisApp::getThemeIcon( "/mActionAddArrow.png" ) );
+  mActionAddTable->setIcon( QgisApp::getThemeIcon( "/mActionOpenTable.png" ) );
   mActionSelectMoveItem->setIcon( QgisApp::getThemeIcon( "/mActionSelectPan.png" ) );
   mActionMoveItemContent->setIcon( QgisApp::getThemeIcon( "/mActionMoveItemContent.png" ) );
   mActionGroupItems->setIcon( QgisApp::getThemeIcon( "/mActionGroupItems.png" ) );
@@ -282,6 +287,7 @@
   connect( mView, SIGNAL( composerPictureAdded( QgsComposerPicture* ) ), this, SLOT( addComposerPicture( QgsComposerPicture* ) ) );
   connect( mView, SIGNAL( composerShapeAdded( QgsComposerShape* ) ), this, SLOT( addComposerShape( QgsComposerShape* ) ) );
   connect( mView, SIGNAL( composerArrowAdded( QgsComposerArrow* ) ), this, SLOT( addComposerArrow( QgsComposerArrow* ) ) );
+  connect( mView, SIGNAL( composerTableAdded( QgsComposerTable* ) ), this, SLOT( addComposerTable( QgsComposerTable* ) ) );
   connect( mView, SIGNAL( actionFinished() ), this, SLOT( setSelectionTool() ) );
 }
 
@@ -826,6 +832,14 @@
   }
 }
 
+void QgsComposer::on_mActionAddTable_triggered()
+{
+  if ( mView )
+  {
+    mView->setCurrentTool( QgsComposerView::AddTable );
+  }
+}
+
 void QgsComposer::on_mActionAddArrow_triggered()
 {
   if ( mView )
@@ -1260,6 +1274,21 @@
     showItemOptions( newArrow );
   }
 
+  //composer tables
+  QDomNodeList composerTableList = composerElem.elementsByTagName( "ComposerTable" );
+  for ( int i = 0; i < composerTableList.size(); ++i )
+  {
+    QDomElement currentTableElem = composerTableList.at( i ).toElement();
+    QgsComposerTable* newTable = new QgsComposerTable( mComposition );
+    newTable->readXML( currentTableElem, doc );
+    addComposerTable( newTable );
+    mComposition->addItem( newTable );
+    mComposition->update();
+    mComposition->clearSelection();
+    newTable->setSelected( true );
+    showItemOptions( newTable );
+  }
+
   mComposition->sortZList();
   mView->setComposition( mComposition );
 
@@ -1355,6 +1384,16 @@
   mItemWidgetMap.insert( shape, sWidget );
 }
 
+void QgsComposer::addComposerTable( QgsComposerTable* table )
+{
+  if ( !table )
+  {
+    return;
+  }
+  QgsComposerTableWidget* tWidget = new QgsComposerTableWidget( table );
+  mItemWidgetMap.insert( table, tWidget );
+}
+
 void QgsComposer::deleteItem( QgsComposerItem* item )
 {
   QMap<QgsComposerItem*, QWidget*>::iterator it = mItemWidgetMap.find( item );

Modified: trunk/qgis/src/app/composer/qgscomposer.h
===================================================================
--- trunk/qgis/src/app/composer/qgscomposer.h	2010-01-06 13:24:33 UTC (rev 12681)
+++ trunk/qgis/src/app/composer/qgscomposer.h	2010-01-06 18:06:45 UTC (rev 12682)
@@ -29,6 +29,7 @@
 class QgsComposerPicture;
 class QgsComposerScaleBar;
 class QgsComposerShape;
+class QgsComposerTable;
 class QgsComposerView;
 class QgsComposition;
 class QgsMapCanvas;
@@ -150,6 +151,9 @@
     //! Add ellipse shape item
     void on_mActionAddBasicShape_triggered();
 
+    //! Add attribute table
+    void on_mActionAddTable_triggered();
+
     //! Save composer as template
     void on_mActionSaveAsTemplate_triggered();
 
@@ -218,6 +222,9 @@
     /**Adds a composer shape to the item/widget map and creates a configuration widget*/
     void addComposerShape( QgsComposerShape* shape );
 
+    /**Adds a composer table to the item/widget map and creates a configuration widget*/
+    void addComposerTable( QgsComposerTable* table );
+
     /**Removes item from the item/widget map and deletes the configuration widget*/
     void deleteItem( QgsComposerItem* item );
 

Added: trunk/qgis/src/app/composer/qgscomposertablewidget.cpp
===================================================================
--- trunk/qgis/src/app/composer/qgscomposertablewidget.cpp	                        (rev 0)
+++ trunk/qgis/src/app/composer/qgscomposertablewidget.cpp	2010-01-06 18:06:45 UTC (rev 12682)
@@ -0,0 +1,214 @@
+/***************************************************************************
+                         qgscomposertablewidget.cpp
+                         --------------------------
+    begin                : January 2010
+    copyright            : (C) 2010 by Marco Hugentobler
+    email                : marco at hugis dot net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "qgscomposertablewidget.h"
+#include "qgscomposeritemwidget.h"
+#include "qgscomposertable.h"
+#include "qgscomposermap.h"
+#include "qgsmaplayerregistry.h"
+#include "qgsvectorlayer.h"
+#include <QFontDialog>
+
+QgsComposerTableWidget::QgsComposerTableWidget( QgsComposerTable* table ): QWidget( 0 ), mComposerTable( table )
+{
+  setupUi( this );
+  //add widget for general composer item properties
+  QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, mComposerTable );
+  mToolBox->addItem( itemPropertiesWidget, tr( "General options" ) );
+
+  //insert vector layers into combo
+  QMap<QString, QgsMapLayer*> layerMap =  QgsMapLayerRegistry::instance()->mapLayers();
+  QMap<QString, QgsMapLayer*>::const_iterator mapIt = layerMap.constBegin();
+
+  for ( ; mapIt != layerMap.constEnd(); ++mapIt )
+  {
+    QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( mapIt.value() );
+    if ( vl )
+    {
+      mLayerComboBox->addItem( vl->name(), mapIt.key() );
+    }
+  }
+
+  //insert composer maps into combo
+  if ( mComposerTable )
+  {
+    const QgsComposition* tableComposition = mComposerTable->composition();
+    if ( tableComposition )
+    {
+      QList<const QgsComposerMap*> mapList = tableComposition->composerMapItems();
+      QList<const QgsComposerMap*>::const_iterator mapIt = mapList.constBegin();
+      for ( ; mapIt != mapList.constEnd(); ++mapIt )
+      {
+        int mapId = ( *mapIt )->id();
+        mComposerMapComboBox->addItem( tr( "Map %1" ).arg( mapId ), mapId );
+      }
+    }
+  }
+
+  updateGuiElements();
+}
+
+QgsComposerTableWidget::~QgsComposerTableWidget()
+{
+
+}
+
+void QgsComposerTableWidget::on_mLayerComboBox_currentIndexChanged( int index )
+{
+  if ( !mComposerTable )
+  {
+    return;
+  }
+
+  //set new layer to table item
+  QVariant itemData = mLayerComboBox->itemData( index );
+  if ( itemData.type() == QVariant::Invalid )
+  {
+    return;
+  }
+
+  QString layerId = itemData.toString();
+  QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );
+  if ( ml )
+  {
+    QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( ml );
+    if ( vl )
+    {
+      mComposerTable->setVectorLayer( vl );
+      mComposerTable->update();
+    }
+  }
+}
+
+void QgsComposerTableWidget::on_mComposerMapComboBox_currentIndexChanged( int index )
+{
+  if ( !mComposerTable )
+  {
+    return;
+  }
+
+  QVariant itemData = mComposerMapComboBox->itemData( index );
+  if ( itemData.type() == QVariant::Invalid )
+  {
+    return;
+  }
+
+  int mapId = itemData.toInt();
+  const QgsComposition* tableComposition = mComposerTable->composition();
+  if ( tableComposition )
+  {
+    mComposerTable->setComposerMap( tableComposition->getComposerMapById( mapId ) );
+    mComposerTable->update();
+  }
+}
+
+void QgsComposerTableWidget::on_mMaximumColumnsSpinBox_valueChanged( int i )
+{
+  if ( !mComposerTable )
+  {
+    return;
+  }
+
+  mComposerTable->setMaximumNumberOfFeatures( i );
+  mComposerTable->update();
+}
+
+void QgsComposerTableWidget::on_mMarginSpinBox_valueChanged( double d )
+{
+  if ( !mComposerTable )
+  {
+    return;
+  }
+  mComposerTable->setLineTextDistance( d );
+  mComposerTable->update();
+}
+
+void QgsComposerTableWidget::on_mHeaderFontPushButton_clicked()
+{
+  if ( !mComposerTable )
+  {
+    return;
+  }
+
+  bool ok;
+  QFont newFont = QFontDialog::getFont( &ok, mComposerTable->headerFont(), 0, tr( "Select Font" ) );
+  if ( ok )
+  {
+    mComposerTable->setHeaderFont( newFont );
+  }
+}
+
+void QgsComposerTableWidget::on_mContentFontPushButton_clicked()
+{
+  if ( !mComposerTable )
+  {
+    return;
+  }
+
+  bool ok;
+  QFont newFont = QFontDialog::getFont( &ok, mComposerTable->contentFont(), 0, tr( "Select Font" ) );
+  if ( ok )
+  {
+    mComposerTable->setContentFont( newFont );
+  }
+}
+
+void QgsComposerTableWidget::updateGuiElements()
+{
+  if ( !mComposerTable )
+  {
+    return;
+  }
+
+  blockAllSignals( true );
+
+  //layer combo box
+  const QgsVectorLayer* vl = mComposerTable->vectorLayer();
+  if ( vl )
+  {
+    int layerIndex = mLayerComboBox->findText( vl->name() );
+    if ( layerIndex != -1 )
+    {
+      mLayerComboBox->setCurrentIndex( layerIndex );
+    }
+  }
+
+  //map combo box
+  const QgsComposerMap* cm = mComposerTable->composerMap();
+  if ( cm )
+  {
+    int mapIndex = mComposerMapComboBox->findText( tr( "Map %1" ).arg( cm->id() ) );
+    if ( mapIndex != -1 )
+    {
+      mComposerMapComboBox->setCurrentIndex( mapIndex );
+    }
+  }
+  mMaximumColumnsSpinBox->setValue( mComposerTable->maximumNumberOfFeatures() );
+  mMarginSpinBox->setValue( mComposerTable->lineTextDistance() );
+  blockAllSignals( false );
+}
+
+void QgsComposerTableWidget::blockAllSignals( bool b )
+{
+  mLayerComboBox->blockSignals( b );
+  mComposerMapComboBox->blockSignals( b );
+  mMaximumColumnsSpinBox->blockSignals( b );
+  mMarginSpinBox->blockSignals( b );
+}
+
+
+

Added: trunk/qgis/src/app/composer/qgscomposertablewidget.h
===================================================================
--- trunk/qgis/src/app/composer/qgscomposertablewidget.h	                        (rev 0)
+++ trunk/qgis/src/app/composer/qgscomposertablewidget.h	2010-01-06 18:06:45 UTC (rev 12682)
@@ -0,0 +1,49 @@
+/***************************************************************************
+                         qgscomposertablewidget.h
+                         ------------------------
+    begin                : January 2010
+    copyright            : (C) 2010 by Marco Hugentobler
+    email                : marco at hugis dot net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef QGSCOMPOSERTABLEWIDGET_H
+#define QGSCOMPOSERTABLEWIDGET_H
+
+#include "ui_qgscomposertablewidgetbase.h"
+
+class QgsComposerTable;
+
+class QgsComposerTableWidget: public QWidget, private Ui::QgsComposerTableWidgetBase
+{
+    Q_OBJECT
+  public:
+    QgsComposerTableWidget( QgsComposerTable* table );
+    ~QgsComposerTableWidget();
+
+  private:
+    QgsComposerTable* mComposerTable;
+
+    /**Sets the GUI elements to the values of mComposerTable*/
+    void updateGuiElements();
+    /**Blocks / unblocks the signals of all GUI elements*/
+    void blockAllSignals( bool b );
+
+  private slots:
+    void on_mLayerComboBox_currentIndexChanged( int index );
+    void on_mComposerMapComboBox_currentIndexChanged( int index );
+    void on_mMaximumColumnsSpinBox_valueChanged( int i );
+    void on_mMarginSpinBox_valueChanged( double d );
+    void on_mHeaderFontPushButton_clicked();
+    void on_mContentFontPushButton_clicked();
+};
+
+#endif // QGSCOMPOSERTABLEWIDGET_H

Modified: trunk/qgis/src/core/CMakeLists.txt
===================================================================
--- trunk/qgis/src/core/CMakeLists.txt	2010-01-06 13:24:33 UTC (rev 12681)
+++ trunk/qgis/src/core/CMakeLists.txt	2010-01-06 18:06:45 UTC (rev 12682)
@@ -76,6 +76,7 @@
   composer/qgscomposerlabel.cpp
   composer/qgscomposerpicture.cpp
   composer/qgscomposermap.cpp
+  composer/qgscomposertable.cpp
   composer/qgscomposerscalebar.cpp
   composer/qgscomposershape.cpp
   composer/qgslegendmodel.cpp

Modified: trunk/qgis/src/core/composer/qgscomposeritem.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgscomposeritem.cpp	2010-01-06 13:24:33 UTC (rev 12681)
+++ trunk/qgis/src/core/composer/qgscomposeritem.cpp	2010-01-06 18:06:45 UTC (rev 12682)
@@ -995,3 +995,8 @@
   x = xRot;
   y = yRot;
 }
+
+void QgsComposerItem::repaint()
+{
+  update();
+}

Modified: trunk/qgis/src/core/composer/qgscomposeritem.h
===================================================================
--- trunk/qgis/src/core/composer/qgscomposeritem.h	2010-01-06 13:24:33 UTC (rev 12681)
+++ trunk/qgis/src/core/composer/qgscomposeritem.h	2010-01-06 18:06:45 UTC (rev 12682)
@@ -173,6 +173,7 @@
 
   public slots:
     virtual void setRotation( double r );
+    void repaint();
 
   protected:
 

Added: trunk/qgis/src/core/composer/qgscomposertable.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgscomposertable.cpp	                        (rev 0)
+++ trunk/qgis/src/core/composer/qgscomposertable.cpp	2010-01-06 18:06:45 UTC (rev 12682)
@@ -0,0 +1,306 @@
+/***************************************************************************
+                         qgscomposertable.cpp
+                         --------------------
+    begin                : January 2010
+    copyright            : (C) 2010 by Marco Hugentobler
+    email                : marco at hugis dot net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "qgscomposertable.h"
+#include "qgscomposermap.h"
+#include "qgslogger.h"
+#include "qgsmaplayerregistry.h"
+#include "qgsvectorlayer.h"
+#include <QPainter>
+
+QgsComposerTable::QgsComposerTable( QgsComposition* composition ): QgsComposerItem( composition ), mVectorLayer( 0 ), mComposerMap( 0 ), mMaximumNumberOfFeatures( 5 )
+{
+  mLineTextDistance = 1;
+}
+
+QgsComposerTable::~QgsComposerTable()
+{
+
+}
+
+void QgsComposerTable::setComposerMap( const QgsComposerMap* map )
+{
+  if ( mComposerMap )
+  {
+    QObject::disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( repaint() ) );
+  }
+  mComposerMap = map;
+  if ( mComposerMap )
+  {
+    QObject::connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( repaint() ) );
+  }
+}
+
+void QgsComposerTable::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
+{
+  if ( !painter )
+  {
+    return;
+  }
+
+  if ( mComposerMap && mComposerMap->isDrawing() )
+  {
+    return;
+  }
+
+  //getFeatureAttributes
+  QList<QgsAttributeMap> attributeList;
+  if ( !getFeatureAttributes( attributeList ) )
+  {
+    return;
+  }
+
+  QMap<int, double> maxColumnWidthMap;
+  //check how much space each column needs
+  calculateMaxColumnWidths( maxColumnWidthMap, attributeList );
+  //adapt item fram to max width / height
+  adaptItemFrame( maxColumnWidthMap, attributeList );
+
+  //now draw the text
+  double currentX = 0;
+  double currentY;
+
+  QgsFieldMap vectorFields = mVectorLayer->pendingFields();
+  QgsFieldMap::const_iterator fieldIt = vectorFields.constBegin();
+  for ( ; fieldIt != vectorFields.constEnd(); ++fieldIt )
+  {
+    currentY = 0;
+    currentY += mLineTextDistance;
+    currentY += fontAscentMillimeters( mHeaderFont );
+    currentX += mLineTextDistance;
+    drawText( painter, currentX, currentY, fieldIt.value().name(), mHeaderFont );
+
+    currentY += mLineTextDistance;
+
+    //draw the attribute values
+    QList<QgsAttributeMap>::const_iterator attIt = attributeList.begin();
+    for ( ; attIt != attributeList.end(); ++attIt )
+    {
+      currentY += fontAscentMillimeters( mContentFont );
+      currentY += mLineTextDistance;
+
+      QgsAttributeMap currentAttributeMap = *attIt;
+      QgsAttributeMap::const_iterator attMapIt = currentAttributeMap.find( fieldIt.key() );
+      if ( attMapIt != currentAttributeMap.constEnd() )
+      {
+        drawText( painter, currentX, currentY, attMapIt.value().toString(), mContentFont );
+      }
+
+      currentY += mLineTextDistance;
+    }
+
+    currentX += mLineTextDistance;
+    currentX += maxColumnWidthMap[fieldIt.key()];
+  }
+
+  //and the borders
+  painter->setPen( mGridPen );
+  drawHorizontalGridLines( painter, attributeList.size() );
+  drawVerticalGridLines( painter, maxColumnWidthMap );
+
+  //draw frame and selection boxes if necessary
+  drawFrame( painter );
+  if ( isSelected() )
+  {
+    drawSelectionBoxes( painter );
+  }
+}
+
+bool QgsComposerTable::writeXML( QDomElement& elem, QDomDocument & doc ) const
+{
+  QDomElement composerTableElem = doc.createElement( "ComposerTable" );
+  composerTableElem.setAttribute( "maxFeatures", mMaximumNumberOfFeatures );
+  composerTableElem.setAttribute( "lineTextDist", mLineTextDistance );
+  composerTableElem.setAttribute( "headerFont", mHeaderFont.toString() );
+  composerTableElem.setAttribute( "contentFont", mContentFont.toString() );
+  if ( mComposerMap )
+  {
+    composerTableElem.setAttribute( "composerMap", mComposerMap->id() );
+  }
+  else
+  {
+    composerTableElem.setAttribute( "composerMap", -1 );
+  }
+  if ( mVectorLayer )
+  {
+    composerTableElem.setAttribute( "vectorLayer", mVectorLayer->getLayerID() );
+  }
+  elem.appendChild( composerTableElem );
+  return _writeXML( composerTableElem, doc );;
+}
+
+bool QgsComposerTable::readXML( const QDomElement& itemElem, const QDomDocument& doc )
+{
+  if ( itemElem.isNull() )
+  {
+    return false;
+  }
+
+  mMaximumNumberOfFeatures = itemElem.attribute( "maxFeatures", "5" ).toInt();
+  mHeaderFont.fromString( itemElem.attribute( "headerFont", "" ) );
+  mContentFont.fromString( itemElem.attribute( "contentFont", "" ) );
+  mLineTextDistance = itemElem.attribute( "lineTextDist", "1.0" ).toDouble();
+
+  //composer map
+  int composerMapId = itemElem.attribute( "composerMap", "-1" ).toInt();
+  if ( composerMapId == -1 )
+  {
+    mComposerMap = 0;
+  }
+
+  if ( composition() )
+  {
+    mComposerMap = composition()->getComposerMapById( composerMapId );
+  }
+  else
+  {
+    mComposerMap = 0;
+  }
+
+  //vector layer
+  QString layerId = itemElem.attribute( "vectorLayer", "not_existing" );
+  if ( layerId == "not_existing" )
+  {
+    mVectorLayer = 0;
+  }
+  else
+  {
+    QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );
+    if ( ml )
+    {
+      mVectorLayer = dynamic_cast<QgsVectorLayer*>( ml );
+    }
+  }
+
+  //restore general composer item properties
+  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
+  if ( composerItemList.size() > 0 )
+  {
+    QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
+    _readXML( composerItemElem, doc );
+  }
+  return true;
+}
+
+bool QgsComposerTable::getFeatureAttributes( QList<QgsAttributeMap>& attributes )
+{
+  if ( !mVectorLayer )
+  {
+    return false;
+  }
+  attributes.clear();
+
+  QgsRectangle selectionRect;
+  if ( mComposerMap )
+  {
+    selectionRect = mComposerMap->extent();
+  }
+
+  mVectorLayer->select( mVectorLayer->pendingAllAttributesList(), selectionRect, false, true );
+  QgsFeature f;
+  int counter = 0;
+  while ( mVectorLayer->nextFeature( f ) && counter < mMaximumNumberOfFeatures )
+  {
+    attributes.push_back( f.attributeMap() );
+    ++counter;
+  }
+  return true;
+}
+
+bool QgsComposerTable::calculateMaxColumnWidths( QMap<int, double>& maxWidthMap, const QList<QgsAttributeMap>& attributeList ) const
+{
+  maxWidthMap.clear();
+  if ( !mVectorLayer )
+  {
+    return false;
+  }
+
+  QgsFieldMap vectorFields = mVectorLayer->pendingFields();
+
+  //initialize max width map with attribute names
+  QgsFieldMap::const_iterator fieldIt = vectorFields.constBegin();
+  for ( ; fieldIt != vectorFields.constEnd(); ++fieldIt )
+  {
+    maxWidthMap.insert( fieldIt.key(), textWidthMillimeters( mHeaderFont, fieldIt.value().name() ) );
+  }
+
+  //go through all the attributes and adapt the max width values
+  QList<QgsAttributeMap>::const_iterator attIt = attributeList.constBegin();
+
+  QgsAttributeMap currentAttributeMap;
+  double currentAttributeTextWidth;
+
+  for ( ; attIt != attributeList.constEnd(); ++attIt )
+  {
+    currentAttributeMap = *attIt;
+    QgsAttributeMap::const_iterator attMapIt = currentAttributeMap.constBegin();
+    for ( ; attMapIt != currentAttributeMap.constEnd(); ++attMapIt )
+    {
+      currentAttributeTextWidth = textWidthMillimeters( mContentFont, attMapIt.value().toString() );
+      if ( currentAttributeTextWidth > maxWidthMap[attMapIt.key()] )
+      {
+        maxWidthMap[attMapIt.key()] = currentAttributeTextWidth;
+      }
+    }
+  }
+  return true;
+}
+
+void QgsComposerTable::adaptItemFrame( const QMap<int, double>& maxWidthMap, const QList<QgsAttributeMap>& attributeList )
+{
+  //calculate height
+  double totalHeight = fontAscentMillimeters( mHeaderFont ) + attributeList.size() * fontAscentMillimeters( mContentFont ) + ( attributeList.size() + 1 ) * mLineTextDistance * 2;
+
+  //adapt frame to total width
+  double totalWidth = 0;
+  QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin();
+  for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt )
+  {
+    totalWidth += maxColWidthIt.value();
+  }
+  totalWidth += ( 2 * maxWidthMap.size() * mLineTextDistance );
+  QTransform t = transform();
+  setSceneRect( QRectF( t.dx(), t.dy(), totalWidth, totalHeight ) );
+}
+
+void QgsComposerTable::drawHorizontalGridLines( QPainter* p, int nAttributes )
+{
+  //horizontal lines
+  double currentY = 0;
+  p->drawLine( QPointF( 0, currentY ), QPointF( rect().width(), currentY ) );
+  currentY += ( fontAscentMillimeters( mHeaderFont ) + 2 * mLineTextDistance );
+  for ( int i = 0; i < nAttributes; ++i )
+  {
+    p->drawLine( QPointF( 0, currentY ), QPointF( rect().width(), currentY ) );
+    currentY += ( fontAscentMillimeters( mContentFont ) + 2 * mLineTextDistance );
+  }
+  p->drawLine( QPointF( 0, currentY ), QPointF( rect().width(), currentY ) );
+}
+
+void QgsComposerTable::drawVerticalGridLines( QPainter* p, const QMap<int, double>& maxWidthMap )
+{
+  //vertical lines
+  double currentX = 0;
+  p->drawLine( QPointF( currentX, 0 ), QPointF( currentX, rect().height() ) );
+  QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin();
+  for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt )
+  {
+    currentX += ( maxColWidthIt.value() + 2 * mLineTextDistance );
+    p->drawLine( QPointF( currentX, 0 ), QPointF( currentX, rect().height() ) );
+  }
+}
+

Added: trunk/qgis/src/core/composer/qgscomposertable.h
===================================================================
--- trunk/qgis/src/core/composer/qgscomposertable.h	                        (rev 0)
+++ trunk/qgis/src/core/composer/qgscomposertable.h	2010-01-06 18:06:45 UTC (rev 12682)
@@ -0,0 +1,81 @@
+/***************************************************************************
+                         qgscomposertable.h
+                         ------------------
+    begin                : January 2010
+    copyright            : (C) 2010 by Marco Hugentobler
+    email                : marco at hugis dot net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef QGSCOMPOSERTABLE_H
+#define QGSCOMPOSERTABLE_H
+
+#include "qgscomposeritem.h"
+#include "qgsfeature.h"
+
+class QgsComposerMap;
+class QgsVectorLayer;
+
+/**A class to display feature attributes in the print composer*/
+class QgsComposerTable: public QgsComposerItem
+{
+  public:
+    QgsComposerTable( QgsComposition* composition );
+    ~QgsComposerTable();
+
+    /** \brief Reimplementation of QCanvasItem::paint*/
+    void paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget );
+
+    bool writeXML( QDomElement& elem, QDomDocument & doc ) const;
+    bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
+
+    void setVectorLayer( QgsVectorLayer* vl ) { mVectorLayer = vl; }
+    const QgsVectorLayer* vectorLayer() const { return mVectorLayer; }
+
+    void setComposerMap( const QgsComposerMap* map );
+    const QgsComposerMap* composerMap() const { return mComposerMap; }
+
+    void setMaximumNumberOfFeatures( int nr ) { mMaximumNumberOfFeatures = nr; }
+    int maximumNumberOfFeatures() const { return mMaximumNumberOfFeatures; }
+
+    void setLineTextDistance( double d ) { mLineTextDistance = d; }
+    double lineTextDistance() const { return mLineTextDistance; }
+
+    void setHeaderFont( const QFont& f ) { mHeaderFont = f;}
+    QFont headerFont() const { return mHeaderFont; }
+
+    void setContentFont( const QFont& f ) { mContentFont = f; }
+    QFont contentFont() const { return mContentFont; }
+
+  private:
+    /**Associated vector layer*/
+    QgsVectorLayer* mVectorLayer;
+    /**Associated composer map (used to display the visible features)*/
+    const QgsComposerMap* mComposerMap;
+    /**Maximum number of features that is displayed*/
+    int mMaximumNumberOfFeatures;
+    /**Distance between table lines and text*/
+    double mLineTextDistance;
+    QPen mGridPen;
+    QFont mHeaderFont;
+    QFont mContentFont;
+
+    /**Retrieves feature attributes*/
+    bool getFeatureAttributes( QList<QgsAttributeMap>& attributes );
+    /**Calculate the maximum width values of the vector attributes*/
+    bool calculateMaxColumnWidths( QMap<int, double>& maxWidthMap, const QList<QgsAttributeMap>& attributeList ) const;
+    /**Adapts the size of the item frame to match the content*/
+    void adaptItemFrame( const QMap<int, double>& maxWidthMap, const QList<QgsAttributeMap>& attributeList );
+    void drawHorizontalGridLines( QPainter* p, int nAttributes );
+    void drawVerticalGridLines( QPainter* p, const QMap<int, double>& maxWidthMap );
+};
+
+#endif // QGSCOMPOSERTABLE_H

Modified: trunk/qgis/src/gui/qgscomposerview.cpp
===================================================================
--- trunk/qgis/src/gui/qgscomposerview.cpp	2010-01-06 13:24:33 UTC (rev 12681)
+++ trunk/qgis/src/gui/qgscomposerview.cpp	2010-01-06 18:06:45 UTC (rev 12682)
@@ -28,6 +28,7 @@
 #include "qgscomposerpicture.h"
 #include "qgscomposerscalebar.h"
 #include "qgscomposershape.h"
+#include "qgscomposertable.h"
 
 QgsComposerView::QgsComposerView( QWidget* parent, const char* name, Qt::WFlags f ) :
     QGraphicsView( parent ), mShiftKeyPressed( false ), mRubberBandItem( 0 ), mRubberBandLineItem( 0 ), mMoveContentItem( 0 )
@@ -147,6 +148,7 @@
       QgsComposerLegend* newLegend = new QgsComposerLegend( composition() );
       addComposerLegend( newLegend );
       newLegend->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLegend->rect().width(), newLegend->rect().height() ) );
+      emit actionFinished();
       break;
     }
     case AddPicture:
@@ -156,6 +158,13 @@
       newPicture->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 30, 30 ) );
       emit actionFinished();
     }
+    case AddTable:
+    {
+      QgsComposerTable* newTable = new QgsComposerTable( composition() );
+      addComposerTable( newTable );
+      newTable->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 50, 50 ) );
+      emit actionFinished();
+    }
 
     default:
       break;
@@ -499,7 +508,6 @@
   scene()->clearSelection();
   legend->setSelected( true );
   emit selectedItemChanged( legend );
-  emit actionFinished();
 }
 
 void QgsComposerView::addComposerPicture( QgsComposerPicture* picture )
@@ -520,6 +528,15 @@
   emit selectedItemChanged( shape );
 }
 
+void QgsComposerView::addComposerTable( QgsComposerTable* table )
+{
+  scene()->addItem( table );
+  emit composerTableAdded( table );
+  scene()->clearSelection();
+  table->setSelected( true );
+  emit selectedItemChanged( table );
+}
+
 void QgsComposerView::groupItems()
 {
   if ( !composition() )

Modified: trunk/qgis/src/gui/qgscomposerview.h
===================================================================
--- trunk/qgis/src/gui/qgscomposerview.h	2010-01-06 13:24:33 UTC (rev 12681)
+++ trunk/qgis/src/gui/qgscomposerview.h	2010-01-06 18:06:45 UTC (rev 12682)
@@ -32,6 +32,7 @@
 class QgsComposerPicture;
 class QgsComposerScaleBar;
 class QgsComposerShape;
+class QgsComposerTable;
 
 /** \ingroup MapComposer
  * \ingroup gui
@@ -57,6 +58,7 @@
       AddScalebar,     // add scalebar
       AddPicture,       // add raster/vector picture
       AddShape, //add shape item (ellipse, rectangle, triangle)
+      AddTable, //add attribute table
       MoveItemContent //move content of item (e.g. content of map)
     };
 
@@ -88,8 +90,10 @@
     void addComposerLegend( QgsComposerLegend* legend );
     /**Adds picture to the graphics scene and advices composer to create a widget for it (through signal)*/
     void addComposerPicture( QgsComposerPicture* picture );
-    /**Adds a composer shape to the graphics scene and acvices composer to create a widget for it (through signal)*/
+    /**Adds a composer shape to the graphics scene and advices composer to create a widget for it (through signal)*/
     void addComposerShape( QgsComposerShape* shape );
+    /**Adds a composer table to the graphics scene and advices composer to create a widget for it (through signal)*/
+    void addComposerTable( QgsComposerTable* table );
 
     /**Returns the composer main window*/
     QMainWindow* composerWindow();
@@ -141,6 +145,8 @@
     void composerPictureAdded( QgsComposerPicture* picture );
     /**Is emitted when a new composer shape has been added*/
     void composerShapeAdded( QgsComposerShape* shape );
+    /**Is emitted when a new composer table has been added*/
+    void composerTableAdded( QgsComposerTable* table );
     /**Is emitted when a composer item has been removed from the scene*/
     void itemRemoved( QgsComposerItem* );
     /**Current action (e.g. adding composer map) has been finished. The purpose of this signal is that

Modified: trunk/qgis/src/ui/qgscomposerbase.ui
===================================================================
--- trunk/qgis/src/ui/qgscomposerbase.ui	2010-01-06 13:24:33 UTC (rev 12681)
+++ trunk/qgis/src/ui/qgscomposerbase.ui	2010-01-06 18:06:45 UTC (rev 12682)
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>737</width>
+    <width>799</width>
     <height>609</height>
    </rect>
   </property>
@@ -171,6 +171,7 @@
    <addaction name="mActionAddNewScalebar"/>
    <addaction name="mActionAddBasicShape"/>
    <addaction name="mActionAddArrow"/>
+   <addaction name="mActionAddTable"/>
    <addaction name="mActionSelectMoveItem"/>
    <addaction name="mActionMoveItemContent"/>
    <addaction name="mActionGroupItems"/>
@@ -461,6 +462,17 @@
     <string>Add arrow</string>
    </property>
   </action>
+  <action name="mActionAddTable">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Add table</string>
+   </property>
+   <property name="toolTip">
+    <string>Adds attribute table</string>
+   </property>
+  </action>
  </widget>
  <tabstops>
   <tabstop>mCompositionNameComboBox</tabstop>

Added: trunk/qgis/src/ui/qgscomposertablewidgetbase.ui
===================================================================
--- trunk/qgis/src/ui/qgscomposertablewidgetbase.ui	                        (rev 0)
+++ trunk/qgis/src/ui/qgscomposertablewidgetbase.ui	2010-01-06 18:06:45 UTC (rev 12682)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QgsComposerTableWidgetBase</class>
+ <widget class="QWidget" name="QgsComposerTableWidgetBase">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>287</width>
+    <height>238</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_2">
+   <item row="0" column="0">
+    <widget class="QToolBox" name="mToolBox">
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="page">
+      <property name="geometry">
+       <rect>
+        <x>0</x>
+        <y>0</y>
+        <width>269</width>
+        <height>194</height>
+       </rect>
+      </property>
+      <attribute name="label">
+       <string>Table</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout">
+       <item row="0" column="0" colspan="2">
+        <layout class="QHBoxLayout" name="horizontalLayout_4">
+         <item>
+          <widget class="QLabel" name="mLayerLabel">
+           <property name="text">
+            <string>Layer</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="mLayerComboBox"/>
+         </item>
+        </layout>
+       </item>
+       <item row="1" column="0" colspan="2">
+        <layout class="QHBoxLayout" name="horizontalLayout_3">
+         <item>
+          <widget class="QLabel" name="mComposerMapLabel">
+           <property name="text">
+            <string>Composer map</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QComboBox" name="mComposerMapComboBox"/>
+         </item>
+        </layout>
+       </item>
+       <item row="2" column="0" colspan="2">
+        <layout class="QHBoxLayout" name="horizontalLayout_2">
+         <item>
+          <widget class="QLabel" name="mMaxNumFeaturesLabel">
+           <property name="text">
+            <string>Maximum columns</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QSpinBox" name="mMaximumColumnsSpinBox"/>
+         </item>
+        </layout>
+       </item>
+       <item row="3" column="0">
+        <layout class="QHBoxLayout" name="horizontalLayout">
+         <item>
+          <widget class="QLabel" name="mMarginLabel">
+           <property name="text">
+            <string>Margin</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QDoubleSpinBox" name="mMarginSpinBox"/>
+         </item>
+        </layout>
+       </item>
+       <item row="4" column="0">
+        <widget class="QPushButton" name="mHeaderFontPushButton">
+         <property name="text">
+          <string>Header Font...</string>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="1">
+        <widget class="QPushButton" name="mContentFontPushButton">
+         <property name="text">
+          <string>Content Font...</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+      <zorder>mHeaderFontPushButton</zorder>
+      <zorder>mContentFontPushButton</zorder>
+      <zorder></zorder>
+      <zorder></zorder>
+      <zorder></zorder>
+      <zorder></zorder>
+      <zorder></zorder>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>



More information about the QGIS-commit mailing list