[QGIS Commit] r13476 - in trunk/qgis/src: app app/composer
app/legend core core/composer gui ui
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Thu May 13 17:01:36 EDT 2010
Author: mhugent
Date: 2010-05-13 17:01:35 -0400 (Thu, 13 May 2010)
New Revision: 13476
Added:
trunk/qgis/src/core/composer/qgscomposerlegenditem.cpp
trunk/qgis/src/core/composer/qgscomposerlegenditem.h
Modified:
trunk/qgis/src/app/composer/qgscomposerlegendwidget.cpp
trunk/qgis/src/app/composer/qgscomposerlegendwidget.h
trunk/qgis/src/app/legend/qgsapplegendinterface.cpp
trunk/qgis/src/app/legend/qgsapplegendinterface.h
trunk/qgis/src/app/legend/qgslegend.cpp
trunk/qgis/src/app/legend/qgslegend.h
trunk/qgis/src/app/qgisapp.h
trunk/qgis/src/core/CMakeLists.txt
trunk/qgis/src/core/composer/qgscomposerlegend.cpp
trunk/qgis/src/core/composer/qgscomposerlegend.h
trunk/qgis/src/core/composer/qgslegendmodel.cpp
trunk/qgis/src/core/composer/qgslegendmodel.h
trunk/qgis/src/gui/qgslegendinterface.h
trunk/qgis/src/ui/qgscomposerlegendwidgetbase.ui
Log:
[FEATURE]: Export legend groups and layers with legendinterface and use this information to display groups in the composer legend. Todo: fix drag and frop in composer legend, readXML, cleanups in composer legend model
Modified: trunk/qgis/src/app/composer/qgscomposerlegendwidget.cpp
===================================================================
--- trunk/qgis/src/app/composer/qgscomposerlegendwidget.cpp 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/app/composer/qgscomposerlegendwidget.cpp 2010-05-13 21:01:35 UTC (rev 13476)
@@ -21,6 +21,11 @@
#include "qgscomposeritemwidget.h"
#include <QFontDialog>
+#include "qgsapplegendinterface.h"
+#include "qgisapp.h"
+#include "qgsmapcanvas.h"
+#include "qgsmaprenderer.h"
+
QgsComposerLegendWidget::QgsComposerLegendWidget( QgsComposerLegend* legend ): mLegend( legend )
{
setupUi( this );
@@ -34,6 +39,14 @@
mItemTreeView->setModel( legend->model() );
}
+ updateLegend();
+
+ mItemTreeView->setDragEnabled( true );
+ mItemTreeView->setAcceptDrops( true );
+ mItemTreeView->setDropIndicatorShown( true );
+ mItemTreeView->setDefaultDropAction( Qt::MoveAction );
+ mItemTreeView->setDragDropMode( QAbstractItemView::InternalMove );
+
setGuiElements();
}
@@ -147,6 +160,26 @@
}
}
+void QgsComposerLegendWidget::on_mGroupFontButton_clicked()
+{
+ if ( mLegend )
+ {
+ bool ok;
+#if defined(Q_WS_MAC) && QT_VERSION >= 0x040500 && !defined(__LP64__)
+ // Native Mac dialog works only for 64 bit Cocoa (observed in Qt 4.5.2, probably a Qt bug)
+ QFont newFont = QFontDialog::getFont( &ok, mLegend->groupFont(), this, QString(), QFontDialog::DontUseNativeDialog );
+#else
+ QFont newFont = QFontDialog::getFont( &ok, mLegend->groupFont() );
+#endif
+ if ( ok )
+ {
+ mLegend->setGroupFont( newFont );
+ mLegend->adjustBoxSize();
+ mLegend->update();
+ }
+ }
+}
+
void QgsComposerLegendWidget::on_mLayerFontButton_clicked()
{
if ( mLegend )
@@ -388,8 +421,43 @@
void QgsComposerLegendWidget::on_mUpdateAllPushButton_clicked()
{
+ updateLegend();
+}
+
+void QgsComposerLegendWidget::on_mAddGroupButton_clicked()
+{
+ if ( mLegend && mLegend->model() )
+ {
+ mLegend->model()->addGroup();
+ mLegend->update();
+ }
+}
+
+void QgsComposerLegendWidget::updateLegend()
+{
if ( mLegend )
{
- mLegend->updateLegend();
+ QgisApp* app = QgisApp::instance();
+ if ( !app )
+ {
+ return;
+ }
+
+ //get layer id list
+ QStringList layerIdList;
+ QgsMapCanvas* canvas = app->mapCanvas();
+ if ( canvas )
+ {
+ QgsMapRenderer* renderer = canvas->mapRenderer();
+ if ( renderer )
+ {
+ layerIdList = renderer->layerSet();
+ }
+ }
+
+ //and also group info
+ QgsAppLegendInterface legendIface( app->legend() );
+ QList< GroupLayerInfo > groupInfo = legendIface.groupLayerRelationship();
+ mLegend->model()->setLayerSetAndGroups( layerIdList, groupInfo );
}
}
Modified: trunk/qgis/src/app/composer/qgscomposerlegendwidget.h
===================================================================
--- trunk/qgis/src/app/composer/qgscomposerlegendwidget.h 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/app/composer/qgscomposerlegendwidget.h 2010-05-13 21:01:35 UTC (rev 13476)
@@ -43,6 +43,7 @@
void on_mSymbolSpaceSpinBox_valueChanged( double d );
void on_mIconLabelSpaceSpinBox_valueChanged( double d );
void on_mTitleFontButton_clicked();
+ void on_mGroupFontButton_clicked();
void on_mLayerFontButton_clicked();
void on_mItemFontButton_clicked();
void on_mBoxSpaceSpinBox_valueChanged( double d );
@@ -54,11 +55,14 @@
void on_mEditPushButton_clicked();
void on_mUpdatePushButton_clicked();
void on_mUpdateAllPushButton_clicked();
+ void on_mAddGroupButton_clicked();
private:
QgsComposerLegendWidget();
/**Sets GUI according to state of mLegend*/
void setGuiElements();
+ /**Updates the legend layers and groups*/
+ void updateLegend();
QgsComposerLegend* mLegend;
};
Modified: trunk/qgis/src/app/legend/qgsapplegendinterface.cpp
===================================================================
--- trunk/qgis/src/app/legend/qgsapplegendinterface.cpp 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/app/legend/qgsapplegendinterface.cpp 2010-05-13 21:01:35 UTC (rev 13476)
@@ -80,6 +80,15 @@
return mLegend->groups();
}
+QList< GroupLayerInfo > QgsAppLegendInterface::groupLayerRelationship()
+{
+ if ( mLegend )
+ {
+ return mLegend->groupLayerRelationship();
+ }
+ return QList< GroupLayerInfo >();
+}
+
bool QgsAppLegendInterface::groupExists( int groupIndex )
{
QModelIndex mi = mLegend->model()->index( groupIndex, 0 );
Modified: trunk/qgis/src/app/legend/qgsapplegendinterface.h
===================================================================
--- trunk/qgis/src/app/legend/qgsapplegendinterface.h 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/app/legend/qgsapplegendinterface.h 2010-05-13 21:01:35 UTC (rev 13476)
@@ -44,6 +44,9 @@
//! Return a string list of groups
QStringList groups();
+ //! Return the relationship between groups and layers in the legend
+ QList< GroupLayerInfo > groupLayerRelationship();
+
//! Return all layers in the project in legend order
QList< QgsMapLayer * > layers() const;
Modified: trunk/qgis/src/app/legend/qgslegend.cpp
===================================================================
--- trunk/qgis/src/app/legend/qgslegend.cpp 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/app/legend/qgslegend.cpp 2010-05-13 21:01:35 UTC (rev 13476)
@@ -1240,6 +1240,51 @@
return groupList;
}
+QList< GroupLayerInfo > QgsLegend::groupLayerRelationship()
+{
+ QList< GroupLayerInfo > groupLayerList;
+
+ int nTopLevelItems = topLevelItemCount();
+ QTreeWidgetItem* currentTopLevelItem = 0;
+
+ for ( int i = 0; i < nTopLevelItems; ++i )
+ {
+ currentTopLevelItem = topLevelItem( i );
+ //layer?
+ QgsLegendLayer* lLayer = dynamic_cast<QgsLegendLayer*>( currentTopLevelItem );
+ if ( lLayer )
+ {
+ if ( lLayer->layer() )
+ {
+ QList<QString> layerList;
+ layerList.push_back( lLayer->layer()->getLayerID() );
+ groupLayerList.push_back( qMakePair( QString(), layerList ) );
+ }
+ }
+ //group?
+ QgsLegendGroup* lGroup = dynamic_cast<QgsLegendGroup*>( currentTopLevelItem );
+ if ( lGroup )
+ {
+ int nLayers = lGroup->childCount();
+ QList<QString> layerList;
+ for ( int i = 0; i < nLayers; ++i )
+ {
+ QgsLegendLayer* lLayer = dynamic_cast<QgsLegendLayer*>( lGroup->child( i ) );
+ if ( lLayer )
+ {
+ if ( lLayer->layer() )
+ {
+ layerList.push_back( lLayer->layer()->getLayerID() );
+ }
+ }
+ }
+ groupLayerList.push_back( qMakePair( lGroup->text( 0 ), layerList ) );
+ }
+ }
+
+ return groupLayerList;
+}
+
/**Returns the first item in the hierarchy*/
QTreeWidgetItem* QgsLegend::firstItem()
{
Modified: trunk/qgis/src/app/legend/qgslegend.h
===================================================================
--- trunk/qgis/src/app/legend/qgslegend.h 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/app/legend/qgslegend.h 2010-05-13 21:01:35 UTC (rev 13476)
@@ -36,6 +36,11 @@
class QMouseEvent;
class QTreeWidgetItem;
+//Information about relationship between groups and layers
+//key: group name (or null strings for single layers without groups)
+//value: containter with layer ids contained in the group
+typedef QPair< QString, QList<QString> > GroupLayerInfo;
+
/**
\class QgsLegend
\brief A Legend treeview for QGIS
@@ -123,6 +128,9 @@
/**Returns a string list of groups*/
QStringList groups();
+ //! Return the relationship between groups and layers in the legend
+ QList< GroupLayerInfo > groupLayerRelationship();
+
/**Returns the first item in the hierarchy*/
QTreeWidgetItem* firstItem();
Modified: trunk/qgis/src/app/qgisapp.h
===================================================================
--- trunk/qgis/src/app/qgisapp.h 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/app/qgisapp.h 2010-05-13 21:01:35 UTC (rev 13476)
@@ -155,6 +155,9 @@
/** Get the mapcanvas object from the app */
QgsMapCanvas * mapCanvas() { return mMapCanvas; };
+ //! returns pointer to map legend
+ QgsLegend *legend() { return mMapLegend; }
+
//! Set theme (icons)
void setTheme( QString themeName = "default" );
//! Setup the toolbar popup menus for a given theme
@@ -586,8 +589,6 @@
//! refresh map canvas
void refreshMapCanvas();
- //! returns pointer to map legend
- QgsLegend *legend() { return mMapLegend; }
//! starts/stops editing mode of the current layer
void toggleEditing();
Modified: trunk/qgis/src/core/CMakeLists.txt
===================================================================
--- trunk/qgis/src/core/CMakeLists.txt 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/core/CMakeLists.txt 2010-05-13 21:01:35 UTC (rev 13476)
@@ -94,6 +94,7 @@
composer/qgscomposeritem.cpp
composer/qgscomposeritemgroup.cpp
composer/qgscomposerlabel.cpp
+ composer/qgscomposerlegenditem.cpp
composer/qgscomposerpicture.cpp
composer/qgscomposermap.cpp
composer/qgscomposertable.cpp
Modified: trunk/qgis/src/core/composer/qgscomposerlegend.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgscomposerlegend.cpp 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/core/composer/qgscomposerlegend.cpp 2010-05-13 21:01:35 UTC (rev 13476)
@@ -16,6 +16,7 @@
***************************************************************************/
#include "qgscomposerlegend.h"
+#include "qgscomposerlegenditem.h"
#include "qgsmaplayer.h"
#include "qgsmaplayerregistry.h"
#include "qgsmaprenderer.h"
@@ -28,10 +29,11 @@
QgsComposerLegend::QgsComposerLegend( QgsComposition* composition ): QgsComposerItem( composition ), mTitle( tr( "Legend" ) ), mBoxSpace( 2 ), mLayerSpace( 3 ), mSymbolSpace( 2 ), mIconLabelSpace( 2 )
{
- QStringList idList = layerIdList();
- mLegendModel.setLayerSet( idList );
+ //QStringList idList = layerIdList();
+ //mLegendModel.setLayerSet( idList );
- mTitleFont.setPointSizeF( 14.0 );
+ mTitleFont.setPointSizeF( 16.0 );
+ mGroupFont.setPointSizeF( 14.0 );
mLayerFont.setPointSizeF( 12.0 );
mItemFont.setPointSizeF( 12.0 );
@@ -95,48 +97,20 @@
maxXCoord = 2 * mBoxSpace + textWidthMillimeters( mTitleFont, mTitle );
- //draw only visible layer items
- QgsMapRenderer* theMapRenderer = mComposition->mapRenderer();
- QStringList visibleLayerIds;
- if ( theMapRenderer )
- {
- visibleLayerIds = theMapRenderer->layerSet();
- }
-
-
for ( int i = 0; i < numLayerItems; ++i )
{
currentLayerItem = rootItem->child( i );
- if ( currentLayerItem )
+ QgsComposerLegendItem* currentLegendItem = dynamic_cast<QgsComposerLegendItem*>( currentLayerItem );
+ if ( currentLegendItem )
{
- QString currentLayerId = currentLayerItem->data().toString();
- int opacity = 255;
- QgsMapLayer* currentLayer = QgsMapLayerRegistry::instance()->mapLayer( currentLayerId );
- if ( currentLayer )
+ QgsComposerLegendItem::ItemType type = currentLegendItem->itemType();
+ if ( type == QgsComposerLegendItem::GroupItem )
{
- opacity = currentLayer->getTransparency();
+ drawGroupItem( painter, dynamic_cast<QgsComposerGroupItem*>( currentLegendItem ), currentYCoordinate, maxXCoord );
}
-
- if ( visibleLayerIds.contains( currentLayerId ) )
+ else if ( type == QgsComposerLegendItem::LayerItem )
{
- //Let the user omit the layer title item by having an empty layer title string
- if ( !currentLayerItem->text().isEmpty() )
- {
- currentYCoordinate += mLayerSpace;
- currentYCoordinate += fontAscentMillimeters( mLayerFont );
-
- //draw layer Item
- if ( painter )
- {
- painter->setPen( QColor( 0, 0, 0 ) );
- drawText( painter, mBoxSpace, currentYCoordinate, currentLayerItem->text(), mLayerFont );
- }
- }
-
- maxXCoord = std::max( maxXCoord, 2 * mBoxSpace + textWidthMillimeters( mLayerFont, currentLayerItem->text() ) );
-
- //and child items
- drawLayerChildItems( painter, currentLayerItem, currentYCoordinate, maxXCoord, opacity );
+ drawLayerItem( painter, dynamic_cast<QgsComposerLayerItem*>( currentLegendItem ), currentYCoordinate, maxXCoord );
}
}
}
@@ -171,6 +145,74 @@
return size;
}
+void QgsComposerLegend::drawGroupItem( QPainter* p, QgsComposerGroupItem* groupItem, double& currentYCoord, double& maxXCoord )
+{
+ if ( !p || !groupItem )
+ {
+ return;
+ }
+
+ currentYCoord += mLayerSpace;
+ currentYCoord += fontAscentMillimeters( mGroupFont );
+
+ p->setPen( QColor( 0, 0, 0 ) );
+ drawText( p, mBoxSpace, currentYCoord, groupItem->text(), mGroupFont );
+ maxXCoord = std::max( maxXCoord, 2 * mBoxSpace + textWidthMillimeters( mGroupFont, groupItem->text() ) );
+
+ //children can be other group items or layer items
+ int numChildItems = groupItem->rowCount();
+ QStandardItem* currentChildItem = 0;
+
+ for ( int i = 0; i < numChildItems; ++i )
+ {
+ currentChildItem = groupItem->child( i );
+ QgsComposerLegendItem* currentLegendItem = dynamic_cast<QgsComposerLegendItem*>( currentChildItem );
+ QgsComposerLegendItem::ItemType type = currentLegendItem->itemType();
+ if ( type == QgsComposerLegendItem::GroupItem )
+ {
+ drawGroupItem( p, dynamic_cast<QgsComposerGroupItem*>( currentLegendItem ), currentYCoord, maxXCoord );
+ }
+ else if ( type == QgsComposerLegendItem::LayerItem )
+ {
+ drawLayerItem( p, dynamic_cast<QgsComposerLayerItem*>( currentLegendItem ), currentYCoord, maxXCoord );
+ }
+ }
+}
+
+void QgsComposerLegend::drawLayerItem( QPainter* p, QgsComposerLayerItem* layerItem, double& currentYCoord, double& maxXCoord )
+{
+ if ( !layerItem )
+ {
+ return;
+ }
+
+ int opacity = 255;
+ QgsMapLayer* currentLayer = QgsMapLayerRegistry::instance()->mapLayer( layerItem->layerID() );
+ if ( currentLayer )
+ {
+ opacity = currentLayer->getTransparency();
+ }
+
+ //Let the user omit the layer title item by having an empty layer title string
+ if ( !layerItem->text().isEmpty() )
+ {
+ currentYCoord += mLayerSpace;
+ currentYCoord += fontAscentMillimeters( mLayerFont );
+
+ //draw layer Item
+ if ( p )
+ {
+ p->setPen( QColor( 0, 0, 0 ) );
+ drawText( p, mBoxSpace, currentYCoord, layerItem->text(), mLayerFont );
+ }
+
+ maxXCoord = std::max( maxXCoord, 2 * mBoxSpace + textWidthMillimeters( mLayerFont, layerItem->text() ) );
+
+ //and child items
+ drawLayerChildItems( p, layerItem, currentYCoord, maxXCoord, opacity );
+ }
+}
+
void QgsComposerLegend::adjustBoxSize()
{
QSizeF size = paintAndDetermineSize( 0 );
@@ -210,22 +252,18 @@
continue;
}
- //take QgsSymbol* from user data
- QVariant symbolVariant = currentItem->data();
QgsSymbol* symbol = 0;
- if ( symbolVariant.canConvert<void*>() )
+ QgsComposerSymbolItem* symbolItem = dynamic_cast<QgsComposerSymbolItem*>( currentItem );
+ if ( symbolItem )
{
- void* symbolData = symbolVariant.value<void*>();
- symbol = ( QgsSymbol* )( symbolData );
+ symbol = symbolItem->symbol();
}
- //take QgsSymbolV2* from user data if there
- QVariant symbolNgVariant = currentItem->data( Qt::UserRole + 2 );
QgsSymbolV2* symbolNg = 0;
- if ( symbolNgVariant.canConvert<void*>() )
+ QgsComposerSymbolV2Item* symbolV2Item = dynamic_cast<QgsComposerSymbolV2Item*>( currentItem );
+ if ( symbolV2Item )
{
- void* symbolNgData = symbolNgVariant.value<void*>();
- symbolNg = ( QgsSymbolV2* )symbolNgData;
+ symbolNg = symbolV2Item->symbolV2();
}
if ( symbol ) //item with symbol?
@@ -416,16 +454,16 @@
QStringList QgsComposerLegend::layerIdList() const
{
- QStringList layerIdList;
- QMap<QString, QgsMapLayer*> layerMap = QgsMapLayerRegistry::instance()->mapLayers();
- QMap<QString, QgsMapLayer*>::const_iterator mapIt = layerMap.constBegin();
-
- for ( ; mapIt != layerMap.constEnd(); ++mapIt )
+ //take layer list from map renderer (to have legend order)
+ if ( mComposition )
{
- layerIdList.push_back( mapIt.key() );
+ QgsMapRenderer* r = mComposition->mapRenderer();
+ if ( r )
+ {
+ return r->layerSet();
+ }
}
-
- return layerIdList;
+ return QStringList();
}
void QgsComposerLegend::synchronizeWithModel()
@@ -441,6 +479,13 @@
update();
}
+void QgsComposerLegend::setGroupFont( const QFont& f )
+{
+ mGroupFont = f;
+ adjustBoxSize();
+ update();
+}
+
void QgsComposerLegend::setLayerFont( const QFont& f )
{
mLayerFont = f;
@@ -460,6 +505,11 @@
return mTitleFont;
}
+QFont QgsComposerLegend::groupFont() const
+{
+ return mGroupFont;
+}
+
QFont QgsComposerLegend::layerFont() const
{
return mLayerFont;
@@ -489,6 +539,7 @@
//write general properties
composerLegendElem.setAttribute( "title", mTitle );
composerLegendElem.setAttribute( "titleFont", mTitleFont.toString() );
+ composerLegendElem.setAttribute( "groupFont", mGroupFont.toString() );
composerLegendElem.setAttribute( "layerFont", mLayerFont.toString() );
composerLegendElem.setAttribute( "itemFont", mItemFont.toString() );
composerLegendElem.setAttribute( "boxSpace", QString::number( mBoxSpace ) );
@@ -520,6 +571,13 @@
{
mTitleFont.fromString( titleFontString );
}
+ //group font
+ QString groupFontString = itemElem.attribute( "groupFont" );
+ if ( !groupFontString.isEmpty() )
+ {
+ mGroupFont.fromString( groupFontString );
+ }
+
//layer font
QString layerFontString = itemElem.attribute( "layerFont" );
if ( !layerFontString.isEmpty() )
Modified: trunk/qgis/src/core/composer/qgscomposerlegend.h
===================================================================
--- trunk/qgis/src/core/composer/qgscomposerlegend.h 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/core/composer/qgscomposerlegend.h 2010-05-13 21:01:35 UTC (rev 13476)
@@ -23,6 +23,8 @@
class QgsSymbol;
class QgsSymbolV2;
+class QgsComposerGroupItem;
+class QgsComposerLayerItem;
/** \ingroup MapComposer
* A legend that can be placed onto a map composition
@@ -54,6 +56,9 @@
QFont titleFont() const;
void setTitleFont( const QFont& f );
+ QFont groupFont() const;
+ void setGroupFont( const QFont& f );
+
QFont layerFont() const;
void setLayerFont( const QFont& f );
@@ -101,6 +106,7 @@
//different fonts for entries
QFont mTitleFont;
+ QFont mGroupFont;
QFont mLayerFont;
QFont mItemFont;
@@ -123,6 +129,11 @@
private:
QgsComposerLegend(); //forbidden
+ /**Draws a group item and all subitems*/
+ void drawGroupItem( QPainter* p, QgsComposerGroupItem* groupItem, double& currentYCoord, double& maxXCoord );
+ /**Draws a layer item and all subitems*/
+ void drawLayerItem( QPainter* p, QgsComposerLayerItem* layerItem, double& currentYCoord, double& maxXCoord );
+
/**Draws child items of a layer item
@param layerItem parent model item (layer)
@param currentYCoord in/out: current y position of legend item
Added: trunk/qgis/src/core/composer/qgscomposerlegenditem.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgscomposerlegenditem.cpp (rev 0)
+++ trunk/qgis/src/core/composer/qgscomposerlegenditem.cpp 2010-05-13 21:01:35 UTC (rev 13476)
@@ -0,0 +1,233 @@
+/***************************************************************************
+ qgscomposerlegenditem.cpp - description
+ -------------------------
+ begin : May 2010
+ copyright : (C) 2010 by Marco Hugentobler
+ email : marco dot hugentobler at sourcepole dot ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 "qgscomposerlegenditem.h"
+#include "qgssymbol.h"
+#include "qgssymbolv2.h"
+#include "qgssymbollayerv2utils.h"
+#include <QDomDocument>
+#include <QDomElement>
+
+QgsComposerLegendItem::QgsComposerLegendItem(): QStandardItem()
+{
+}
+
+QgsComposerLegendItem::QgsComposerLegendItem( const QString& text ): QStandardItem( text )
+{
+}
+
+QgsComposerLegendItem::QgsComposerLegendItem( const QIcon& icon, const QString& text ): QStandardItem( icon, text )
+{
+}
+
+QgsComposerLegendItem::~QgsComposerLegendItem()
+{
+}
+
+void QgsComposerLegendItem::writeXMLChildren( QDomElement& elem, QDomDocument& doc ) const
+{
+ int numRows = rowCount();
+ QgsComposerLegendItem* currentItem = 0;
+ for ( int i = 0; i < numRows; ++i )
+ {
+ currentItem = dynamic_cast<QgsComposerLegendItem*>( child( i, 0 ) );
+ if ( currentItem )
+ {
+ currentItem->writeXML( elem, doc );
+ }
+ }
+}
+
+//////////////////////////////QgsComposerSymbolItem
+
+QgsComposerSymbolItem::QgsComposerSymbolItem(): QgsComposerLegendItem(), mSymbol( 0 )
+{
+}
+
+QgsComposerSymbolItem::QgsComposerSymbolItem( const QString& text ): QgsComposerLegendItem( text ), mSymbol( 0 )
+{
+}
+
+QgsComposerSymbolItem::QgsComposerSymbolItem( const QIcon& icon, const QString& text ): QgsComposerLegendItem( icon, text ), mSymbol( 0 )
+{
+}
+
+QgsComposerSymbolItem::~QgsComposerSymbolItem()
+{
+ delete mSymbol;
+}
+
+void QgsComposerSymbolItem::setSymbol( QgsSymbol* s )
+{
+ delete mSymbol;
+ mSymbol = s;
+}
+
+QStandardItem* QgsComposerSymbolItem::clone() const
+{
+ qWarning( "QgsComposerSymbolItem::clone" );
+ QgsComposerSymbolItem* cloneItem = new QgsComposerSymbolItem();
+ *cloneItem = *this;
+ if ( mSymbol )
+ {
+ cloneItem->setSymbol( new QgsSymbol( *mSymbol ) );
+ }
+ return cloneItem;
+}
+
+void QgsComposerSymbolItem::writeXML( QDomElement& elem, QDomDocument& doc ) const
+{
+ QDomElement vectorClassElem = doc.createElement( "VectorClassificationItem" );
+ if ( mSymbol )
+ {
+ mSymbol->writeXML( vectorClassElem, doc, 0 );
+ }
+ vectorClassElem.setAttribute( "text", text() );
+ elem.appendChild( vectorClassElem );
+}
+
+void QgsComposerSymbolItem::readXML( const QDomElement& itemElem )
+{
+ //soon...
+}
+
+////////////////QgsComposerSymbolV2Item
+
+#include "qgssymbolv2.h"
+
+QgsComposerSymbolV2Item::QgsComposerSymbolV2Item(): QgsComposerLegendItem(), mSymbolV2( 0 )
+{
+}
+
+QgsComposerSymbolV2Item::QgsComposerSymbolV2Item( const QString& text ): QgsComposerLegendItem( text ), mSymbolV2( 0 )
+{
+}
+
+QgsComposerSymbolV2Item::QgsComposerSymbolV2Item( const QIcon& icon, const QString& text ): QgsComposerLegendItem( icon, text ), mSymbolV2( 0 )
+{
+}
+
+QgsComposerSymbolV2Item::~QgsComposerSymbolV2Item()
+{
+ delete mSymbolV2;
+}
+
+QStandardItem* QgsComposerSymbolV2Item::clone() const
+{
+ QgsComposerSymbolV2Item* cloneItem = new QgsComposerSymbolV2Item();
+ *cloneItem = *this;
+ if ( mSymbolV2 )
+ {
+ cloneItem->setSymbolV2( mSymbolV2->clone() );
+ }
+ return cloneItem;
+}
+
+void QgsComposerSymbolV2Item::writeXML( QDomElement& elem, QDomDocument& doc ) const
+{
+ QDomElement vectorClassElem = doc.createElement( "VectorClassificationItemNg" );
+ if ( mSymbolV2 )
+ {
+ QgsSymbolV2Map saveSymbolMap;
+ saveSymbolMap.insert( "classificationSymbol", mSymbolV2 );
+ QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( saveSymbolMap, "symbols", doc );
+ vectorClassElem.appendChild( symbolsElem );
+ }
+ vectorClassElem.setAttribute( "text", text() );
+ elem.appendChild( vectorClassElem );
+}
+
+void QgsComposerSymbolV2Item::readXML( const QDomElement& itemElem )
+{
+ //soon...
+}
+
+void QgsComposerSymbolV2Item::setSymbolV2( QgsSymbolV2* s )
+{
+ delete mSymbolV2;
+ mSymbolV2 = s;
+}
+
+////////////////////QgsComposerLayerItem
+
+QgsComposerLayerItem::QgsComposerLayerItem(): QgsComposerLegendItem()
+{
+}
+
+QgsComposerLayerItem::QgsComposerLayerItem( const QString& text ): QgsComposerLegendItem( text )
+{
+}
+
+QgsComposerLayerItem::~QgsComposerLayerItem()
+{
+}
+
+QStandardItem* QgsComposerLayerItem::clone() const
+{
+ QgsComposerLayerItem* cloneItem = new QgsComposerLayerItem();
+ *cloneItem = *this;
+ cloneItem->setLayerID( mLayerID );
+ return cloneItem;
+}
+
+void QgsComposerLayerItem::writeXML( QDomElement& elem, QDomDocument& doc ) const
+{
+ QDomElement layerItemElem = doc.createElement( "LayerItem" );
+ layerItemElem.setAttribute( "layerId", mLayerID );
+ layerItemElem.setAttribute( "text", text() );
+ writeXMLChildren( layerItemElem, doc );
+ elem.appendChild( layerItemElem );
+}
+
+void QgsComposerLayerItem::readXML( const QDomElement& itemElem )
+{
+ //soon...
+}
+
+////////////////////QgsComposerGroupItem
+
+QgsComposerGroupItem::QgsComposerGroupItem(): QgsComposerLegendItem()
+{
+}
+
+QgsComposerGroupItem::QgsComposerGroupItem( const QString& text ): QgsComposerLegendItem( text )
+{
+}
+
+QgsComposerGroupItem::~QgsComposerGroupItem()
+{
+}
+
+QStandardItem* QgsComposerGroupItem::clone() const
+{
+ QgsComposerGroupItem* cloneItem = new QgsComposerGroupItem();
+ *cloneItem = *this;
+ return cloneItem;
+}
+
+void QgsComposerGroupItem::writeXML( QDomElement& elem, QDomDocument& doc ) const
+{
+ QDomElement layerGroupElem = doc.createElement( "GroupItem" );
+ layerGroupElem.setAttribute( "text", text() );
+ writeXMLChildren( layerGroupElem, doc );
+ elem.appendChild( layerGroupElem );
+}
+
+void QgsComposerGroupItem::readXML( const QDomElement& itemElem )
+{
+ //soon...
+}
Added: trunk/qgis/src/core/composer/qgscomposerlegenditem.h
===================================================================
--- trunk/qgis/src/core/composer/qgscomposerlegenditem.h (rev 0)
+++ trunk/qgis/src/core/composer/qgscomposerlegenditem.h 2010-05-13 21:01:35 UTC (rev 13476)
@@ -0,0 +1,137 @@
+/***************************************************************************
+ qgscomposerlegenditem.h - description
+ ------------------------
+ begin : May 2010
+ copyright : (C) 2010 by Marco Hugentobler
+ email : marco dot hugentobler at sourcepole dot ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 QGSCOMPOSERLEGENDITEM_H
+#define QGSCOMPOSERLEGENDITEM_H
+
+#include <QStandardItem>
+class QDomDocument;
+class QDomElement;
+
+/**Abstract base class for the legend item types*/
+class CORE_EXPORT QgsComposerLegendItem: public QStandardItem
+{
+ public:
+
+ QgsComposerLegendItem();
+ QgsComposerLegendItem( const QString& text );
+ QgsComposerLegendItem( const QIcon& icon, const QString& text );
+ virtual ~QgsComposerLegendItem();
+
+ enum ItemType
+ {
+ GroupItem = QStandardItem::UserType,
+ LayerItem,
+ SymbologyItem,
+ SymbologyV2Item
+ };
+
+ virtual void writeXML( QDomElement& elem, QDomDocument& doc ) const = 0;
+ virtual void readXML( const QDomElement& itemElem ) = 0;
+
+ virtual ItemType itemType() const = 0;
+ virtual QStandardItem* clone() const = 0;
+
+ protected:
+ void writeXMLChildren( QDomElement& elem, QDomDocument& doc ) const;
+};
+
+class QgsSymbol;
+
+class CORE_EXPORT QgsComposerSymbolItem: public QgsComposerLegendItem
+{
+ public:
+ QgsComposerSymbolItem();
+ QgsComposerSymbolItem( const QString& text );
+ QgsComposerSymbolItem( const QIcon& icon, const QString& text );
+ virtual ~QgsComposerSymbolItem();
+
+ virtual QStandardItem* clone() const;
+
+ virtual void writeXML( QDomElement& elem, QDomDocument& doc ) const;
+ virtual void readXML( const QDomElement& itemElem );
+
+ /**Set symbol (takes ownership)*/
+ void setSymbol( QgsSymbol* s );
+ QgsSymbol* symbol() {return mSymbol;}
+
+ ItemType itemType() const { return SymbologyItem; }
+
+ private:
+ QgsSymbol* mSymbol;
+};
+
+class QgsSymbolV2;
+
+class CORE_EXPORT QgsComposerSymbolV2Item: public QgsComposerLegendItem
+{
+ public:
+ QgsComposerSymbolV2Item();
+ QgsComposerSymbolV2Item( const QString& text );
+ QgsComposerSymbolV2Item( const QIcon& icon, const QString& text );
+ virtual ~QgsComposerSymbolV2Item();
+
+ virtual QStandardItem* clone() const;
+
+ virtual void writeXML( QDomElement& elem, QDomDocument& doc ) const;
+ virtual void readXML( const QDomElement& itemElem );
+
+ /**Set symbol (takes ownership)*/
+ void setSymbolV2( QgsSymbolV2* s );
+ QgsSymbolV2* symbolV2() {return mSymbolV2;}
+
+ ItemType itemType() const { return SymbologyV2Item; }
+
+ private:
+ QgsSymbolV2* mSymbolV2;
+};
+
+class CORE_EXPORT QgsComposerLayerItem: public QgsComposerLegendItem
+{
+ public:
+ QgsComposerLayerItem();
+ QgsComposerLayerItem( const QString& text );
+ virtual ~QgsComposerLayerItem();
+ virtual QStandardItem* clone() const;
+
+ virtual void writeXML( QDomElement& elem, QDomDocument& doc ) const;
+ virtual void readXML( const QDomElement& itemElem );
+
+ ItemType itemType() const { return LayerItem; }
+
+ void setLayerID( const QString& id ) { mLayerID = id; }
+ QString layerID() const { return mLayerID; }
+
+ private:
+ QString mLayerID;
+};
+
+class CORE_EXPORT QgsComposerGroupItem: public QgsComposerLegendItem
+{
+ public:
+ QgsComposerGroupItem();
+ QgsComposerGroupItem( const QString& text );
+ virtual ~QgsComposerGroupItem();
+ virtual QStandardItem* clone() const;
+
+ virtual void writeXML( QDomElement& elem, QDomDocument& doc ) const;
+ virtual void readXML( const QDomElement& itemElem );
+
+ ItemType itemType() const { return GroupItem; }
+};
+
+#endif // QGSCOMPOSERLEGENDITEM_H
Modified: trunk/qgis/src/core/composer/qgslegendmodel.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgslegendmodel.cpp 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/core/composer/qgslegendmodel.cpp 2010-05-13 21:01:35 UTC (rev 13476)
@@ -16,6 +16,7 @@
***************************************************************************/
#include "qgslegendmodel.h"
+#include "qgscomposerlegenditem.h"
#include "qgsfield.h"
#include "qgsmaplayer.h"
#include "qgsmaplayerregistry.h"
@@ -37,22 +38,68 @@
connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( removeLayer( const QString& ) ) );
connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWasAdded( QgsMapLayer* ) ), this, SLOT( addLayer( QgsMapLayer* ) ) );
}
+ setItemPrototype( new QgsComposerSymbolItem() );
}
QgsLegendModel::~QgsLegendModel()
{
- removeAllSymbols();
- removeAllSymbolsV2();
}
+void QgsLegendModel::setLayerSetAndGroups( const QStringList& layerIds, const QList< GroupLayerInfo >& groupInfo )
+{
+ setLayerSet( layerIds );
+
+ QStandardItem* currentItem = 0;
+ QStandardItem* currentGroupItem = 0;
+ int i = 0;
+
+ QList< GroupLayerInfo >::const_iterator infoIt = groupInfo.constBegin();
+ for ( ; infoIt != groupInfo.constEnd() && i < invisibleRootItem()->rowCount(); )
+ {
+ currentItem = invisibleRootItem()->child( i, 0 );
+ QString infoKey = infoIt->first;
+ if ( infoKey.isNull() ) //a toplevel layer
+ {
+ ++i;
+ }
+ else //a group
+ {
+ currentGroupItem = addGroup( infoKey, i );
+ ++i;
+ QList<QString> layerList = infoIt->second;
+ QList<QString>::const_iterator groupLayerIt = layerList.constBegin();
+ for ( ; currentItem && ( groupLayerIt != layerList.constEnd() ); ++groupLayerIt )
+ {
+ //check if current item is contained in this group
+ QgsComposerLayerItem* layerItem = dynamic_cast<QgsComposerLayerItem*>( currentItem );
+ if ( !layerItem )
+ {
+ return; //should never happen
+ }
+ //QString layerID = currentItem->data(Qt::UserRole + 2).toString();
+ QString layerID = layerItem->layerID();
+ if ( layerList.contains( layerID ) )
+ {
+ takeRow( i );
+ currentGroupItem->setChild( currentGroupItem->rowCount(), 0, currentItem );
+ }
+ else
+ {
+ ++i;
+ }
+ currentItem = invisibleRootItem()->child( i, 0 );
+ }
+ }
+ ++infoIt;
+ }
+}
+
void QgsLegendModel::setLayerSet( const QStringList& layerIds )
{
mLayerIds = layerIds;
//for now clear the model and add the new entries
clear();
- removeAllSymbols();
- removeAllSymbolsV2();
QStringList::const_iterator idIter = mLayerIds.constBegin();
QgsMapLayer* currentLayer = 0;
@@ -62,9 +109,8 @@
currentLayer = QgsMapLayerRegistry::instance()->mapLayer( *idIter );
//addItem for layer
- QStandardItem* layerItem = new QStandardItem( currentLayer->name() );
- //set layer id as user data into the item
- layerItem->setData( QVariant( currentLayer->getLayerID() ) );
+ QgsComposerLayerItem* layerItem = new QgsComposerLayerItem( currentLayer->name() );
+ layerItem->setLayerID( currentLayer->getLayerID() );
layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
invisibleRootItem()->setChild( invisibleRootItem()->rowCount(), layerItem );
@@ -97,6 +143,20 @@
}
+QStandardItem* QgsLegendModel::addGroup( QString text, int position )
+{
+ QgsComposerGroupItem* groupItem = new QgsComposerGroupItem( text );
+ if ( position == -1 )
+ {
+ invisibleRootItem()->insertRow( invisibleRootItem()->rowCount(), groupItem );
+ }
+ else
+ {
+ invisibleRootItem()->insertRow( position, groupItem );
+ }
+ return groupItem;
+}
+
int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLayer* vlayer )
{
if ( !layerItem || !vlayer )
@@ -114,16 +174,13 @@
QgsLegendSymbolList::const_iterator symbolIt = lst.constBegin();
for ( ; symbolIt != lst.constEnd(); ++symbolIt )
{
- QStandardItem* currentSymbolItem = new QStandardItem( symbolIt->first );
+ QgsComposerSymbolV2Item* currentSymbolItem = new QgsComposerSymbolV2Item( symbolIt->first );
+ currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
if ( symbolIt->second )
{
currentSymbolItem->setIcon( QgsSymbolLayerV2Utils::symbolPreviewIcon( symbolIt->second, QSize( 30, 30 ) ) );
- //reserve Qt::UserRole + 2 for symbology-ng
- QgsSymbolV2* newSymbol = symbolIt->second->clone();
- insertSymbolV2( newSymbol );
- currentSymbolItem->setData( QVariant::fromValue(( void* )( newSymbol ) ), Qt::UserRole + 2 );
+ currentSymbolItem->setSymbolV2( symbolIt->second->clone() );
}
- currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
layerItem->setChild( layerItem->rowCount(), 0, currentSymbolItem );
}
@@ -159,6 +216,8 @@
{
QString attributeName = vlayer->attributeDisplayName( fieldIt.key() );
QStandardItem* attributeItem = new QStandardItem( attributeName );
+ attributeItem->setData( QgsLegendModel::ClassificationItem, Qt::UserRole + 1 ); //first user data stores the item type
+ attributeItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
layerItem->setChild( layerItem->rowCount(), 0, attributeItem );
}
}
@@ -201,6 +260,7 @@
}
QStandardItem* currentSymbolItem = new QStandardItem( QIcon( rasterLayer->legendAsPixmap( true ) ), "" );
+ currentSymbolItem->setData( QgsLegendModel::ClassificationItem, Qt::UserRole + 1 ); //first user data stores the item type
int currentRowCount = layerItem->rowCount();
layerItem->setChild( currentRowCount, 0, currentSymbolItem );
@@ -208,58 +268,9 @@
return 0;
}
-void QgsLegendModel::insertSymbol( QgsSymbol* s )
-{
- QSet<QgsSymbol*>::iterator it = mSymbols.find( s );
- if ( it != mSymbols.end() )
- {
- delete( *it ); //very unlikely
- }
- mSymbols.insert( s );
-}
-
-void QgsLegendModel::insertSymbolV2( QgsSymbolV2* s )
-{
- QSet<QgsSymbolV2*>::iterator it = mSymbolsV2.find( s );
- if ( it != mSymbolsV2.end() )
- {
- delete( *it ); //very unlikely
- }
- mSymbolsV2.insert( s );
-}
-
-void QgsLegendModel::removeSymbol( QgsSymbol* s )
-{
- mSymbols.remove( s );
-}
-
-void QgsLegendModel::removeSymbolV2( QgsSymbolV2* s )
-{
- mSymbolsV2.remove( s );
-}
-
-void QgsLegendModel::removeAllSymbols()
-{
- QSet<QgsSymbol*>::iterator it = mSymbols.begin();
- for ( ; it != mSymbols.end(); ++it )
- {
- delete *it;
- }
- mSymbols.clear();
-}
-
-void QgsLegendModel::removeAllSymbolsV2()
-{
- QSet<QgsSymbolV2*>::iterator it = mSymbolsV2.begin();
- for ( ; it != mSymbolsV2.end(); ++it )
- {
- delete *it;
- }
- mSymbolsV2.clear();
-}
-
void QgsLegendModel::updateItem( QStandardItem* item )
{
+#if 0
if ( !item )
{
return;
@@ -274,7 +285,7 @@
}
//take QgsSymbol* from user data
- QVariant symbolVariant = item->data();
+ QVariant symbolVariant = item->data( Qt::UserRole + 2 );
QgsSymbol* symbol = 0;
if ( symbolVariant.canConvert<void*>() )
{
@@ -282,7 +293,7 @@
symbol = ( QgsSymbol* )( symbolData );
}
- QVariant symbolNgVariant = item->data( Qt::UserRole + 2 );
+ QVariant symbolNgVariant = item->data( Qt::UserRole + 3 );
QgsSymbolV2* symbolNg = 0;
if ( symbolNgVariant.canConvert<void*>() )
{
@@ -302,16 +313,18 @@
{
updateRasterClassificationItem( item );
}
+#endif //0
}
void QgsLegendModel::updateLayer( QStandardItem* layerItem )
{
+#if 0
if ( !layerItem )
{
return;
}
- QString layerId = layerItem->data().toString();
+ QString layerId = layerItem->data( Qt::UserRole + 2 ).toString();
QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( layerId );
if ( mapLayer )
{
@@ -348,10 +361,12 @@
break;
}
}
+#endif //0
}
void QgsLegendModel::updateVectorClassificationItem( QStandardItem* classificationItem, QgsSymbol* symbol, QString itemText )
{
+#if 0
//this function uses the following logic to find a classification match:
//first test if there is a symbol where lowerbound - upperbound equels itemText
//if no match found, test if there is a symbol where label equals itemText
@@ -365,7 +380,7 @@
}
//get maplayer object from parent item
- QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( parentItem->data().toString() );
+ QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( parentItem->data( Qt::UserRole + 2 ).toString() );
if ( !ml )
{
return;
@@ -394,7 +409,6 @@
currentSymbol = *symbolIt;
if ( currentSymbol->lowerValue() + " - " + currentSymbol->upperValue() == itemText )
{
- removeSymbol( symbol );
parentItem->insertRow( classificationItem->row(), itemFromSymbol( currentSymbol, opacity ) );
parentItem->removeRow( classificationItem->row() );
return;
@@ -408,7 +422,6 @@
currentSymbol = *symbolIt;
if ( currentSymbol->lowerValue() == itemText )
{
- removeSymbol( symbol );
parentItem->insertRow( classificationItem->row(), itemFromSymbol( currentSymbol, opacity ) );
parentItem->removeRow( classificationItem->row() );
return;
@@ -428,6 +441,7 @@
return;
}
}
+#endif //0
}
void QgsLegendModel::updateVectorV2ClassificationItem( QStandardItem* classificationItem, QgsSymbolV2* symbol, QString itemText )
@@ -438,6 +452,7 @@
void QgsLegendModel::updateRasterClassificationItem( QStandardItem* classificationItem )
{
+#if 0
if ( !classificationItem )
{
return;
@@ -449,7 +464,7 @@
return;
}
- QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( parentItem->data().toString() );
+ QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( parentItem->data( Qt::UserRole + 2 ).toString() );
if ( !ml )
{
return;
@@ -462,8 +477,10 @@
}
QStandardItem* currentSymbolItem = new QStandardItem( QIcon( rl->legendAsPixmap( true ) ), "" );
+ currentSymbolItem->setData( QgsLegendModel::ClassificationItem, Qt::UserRole + 1 ); //first user data stores the item type
parentItem->insertRow( 0, currentSymbolItem );
parentItem->removeRow( 1 );
+#endif //0
}
void QgsLegendModel::removeLayer( const QString& layerId )
@@ -479,7 +496,7 @@
continue;
}
- QString currentId = currentLayerItem->data().toString();
+ QString currentId = currentLayerItem->data( Qt::UserRole + 2 ).toString();
if ( currentId == layerId )
{
removeRow( i ); //todo: also remove the subitems and their symbols...
@@ -498,8 +515,8 @@
//append new layer item
QStandardItem* layerItem = new QStandardItem( theMapLayer->name() );
- //set layer id as user data into the item
- layerItem->setData( QVariant( theMapLayer->getLayerID() ) );
+ layerItem->setData( QgsLegendModel::LayerItem, Qt::UserRole + 1 ); //first user data stores the item type
+ layerItem->setData( QVariant( theMapLayer->getLayerID() ), Qt::UserRole + 2 );
layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
invisibleRootItem()->setChild( invisibleRootItem()->rowCount(), layerItem );
@@ -533,7 +550,7 @@
QStandardItem* QgsLegendModel::itemFromSymbol( QgsSymbol* s, int opacity )
{
- QStandardItem* currentSymbolItem = 0;
+ QgsComposerSymbolItem* currentSymbolItem = 0;
//label
QString itemText;
@@ -591,18 +608,17 @@
}
}
- currentSymbolItem = new QStandardItem( QIcon( QPixmap::fromImage( symbolImage ) ), itemText );
+ currentSymbolItem = new QgsComposerSymbolItem( QIcon( QPixmap::fromImage( symbolImage ) ), itemText );
if ( !currentSymbolItem )
{
return 0;
}
+ currentSymbolItem->setData( QgsLegendModel::ClassificationItem, Qt::UserRole + 1 ); //first user data stores the item type
//Pass deep copy of QgsSymbol as user data. Cast to void* necessary such that QMetaType handles it
QgsSymbol* symbolCopy = new QgsSymbol( *s );
- currentSymbolItem->setData( QVariant::fromValue(( void* )symbolCopy ) );
- insertSymbol( symbolCopy );
-
+ currentSymbolItem->setSymbol( symbolCopy );
currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
return currentSymbolItem;
}
@@ -615,81 +631,18 @@
}
QDomElement legendModelElem = doc.createElement( "Model" );
+ int nTopLevelItems = invisibleRootItem()->rowCount();
+ QStandardItem* currentItem = 0;
+ QgsComposerLegendItem* currentLegendItem = 0;
- //iterate over all items...
- QStandardItem* currentLayerItem = 0;
- QStandardItem* currentClassificationItem = 0;
- int numRootItems = rowCount();
-
- for ( int i = 0; i < numRootItems; ++i )
+ for ( int i = 0; i < nTopLevelItems; ++i )
{
- currentLayerItem = item( i );
- QDomElement newLayerItem = doc.createElement( "LayerItem" );
- newLayerItem.setAttribute( "layerId", currentLayerItem->data().toString() );
- newLayerItem.setAttribute( "text", currentLayerItem->text() );
-
- //add layer/classification items
- int numClassItems = currentLayerItem->rowCount();
- for ( int j = 0; j < numClassItems; ++j )
+ currentItem = invisibleRootItem()->child( i, 0 );
+ currentLegendItem = dynamic_cast<QgsComposerLegendItem*>( currentItem );
+ if ( currentItem )
{
- currentClassificationItem = currentLayerItem->child( j );
-
- //store text and QgsSymbol for vector classification items
- QVariant symbolVariant = currentClassificationItem->data();
- QVariant symbolNgVariant = currentClassificationItem->data( Qt::UserRole + 2 );
- QgsSymbol* symbol = 0;
- QgsSymbolV2* symbolNg = 0;
-
- if ( symbolVariant.canConvert<void*>() )
- {
- void* symbolData = symbolVariant.value<void*>();
- symbol = ( QgsSymbol* )symbolData;
- }
- else if ( symbolNgVariant.canConvert<void*>() )
- {
- void* symbolNgData = symbolNgVariant.value<void*>();
- symbolNg = ( QgsSymbolV2* )symbolNgData;
- }
-
- if ( symbol || symbolNg )
- {
- QDomElement vectorClassElem;
- if ( symbol )
- {
- vectorClassElem = doc.createElement( "VectorClassificationItem" );
- symbol->writeXML( vectorClassElem, doc, 0 );
- }
- else if ( symbolNg )
- {
- vectorClassElem = doc.createElement( "VectorClassificationItemNg" );
- QgsSymbolV2Map saveSymbolMap;
- saveSymbolMap.insert( "classificationSymbol", symbolNg );
- QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( saveSymbolMap, "symbols", doc );
- vectorClassElem.appendChild( symbolsElem );
- }
- vectorClassElem.setAttribute( "text", currentClassificationItem->text() );
- newLayerItem.appendChild( vectorClassElem );
- continue;
- }
-
- //a text item
- if ( currentClassificationItem->icon().isNull() )
- {
- QDomElement textItemElem = doc.createElement( "TextItem" );
- textItemElem.setAttribute( "text", currentClassificationItem->text() );
- newLayerItem.appendChild( textItemElem );
- }
- else //else it can only be a raster item
- {
- QDomElement rasterClassElem = doc.createElement( "RasterItem" );
- rasterClassElem.setAttribute( "text", currentClassificationItem->text() );
- //storing the layer id also in the raster item makes parsing easier
- rasterClassElem.setAttribute( "layerId", currentLayerItem->data().toString() );
- newLayerItem.appendChild( rasterClassElem );
- }
+ currentLegendItem->writeXML( legendModelElem, doc );
}
-
- legendModelElem.appendChild( newLayerItem );
}
composerLegendElem.appendChild( legendModelElem );
@@ -703,109 +656,169 @@
return false;
}
- //delete all stored symbols first
- removeAllSymbols();
+ return false;
+ //todo: adapt to new legend item structure
+ /*
+ //iterate over layer items
+ QDomNodeList layerItemList = legendModelElem.elementsByTagName( "LayerItem" );
+ QgsMapLayer* currentLayer = 0; //store current layer to get
- //iterate over layer items
- QDomNodeList layerItemList = legendModelElem.elementsByTagName( "LayerItem" );
- QgsMapLayer* currentLayer = 0; //store current layer to get
+ for ( int i = 0; i < layerItemList.size(); ++i )
+ {
+ QDomElement layerItemElem = layerItemList.at( i ).toElement();
+ QString layerId = layerItemElem.attribute( "layerId" );
- for ( int i = 0; i < layerItemList.size(); ++i )
- {
- QDomElement layerItemElem = layerItemList.at( i ).toElement();
- QString layerId = layerItemElem.attribute( "layerId" );
+ QStandardItem* layerItem = new QStandardItem( layerItemElem.attribute( "text" ) );
- QStandardItem* layerItem = new QStandardItem( layerItemElem.attribute( "text" ) );
+ //set layer id as user data into the item
+ layerItem->setData( QVariant( layerId ) );
+ layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
- //set layer id as user data into the item
- layerItem->setData( QVariant( layerId ) );
- layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
+ currentLayer = QgsMapLayerRegistry::instance()->mapLayer( layerId );
- currentLayer = QgsMapLayerRegistry::instance()->mapLayer( layerId );
-
- //go through all children of layerItemElem
- QDomElement currentChildElement = layerItemElem.firstChildElement();
- while ( !currentChildElement.isNull() )
- {
- QStandardItem* childItem = new QStandardItem( currentChildElement.attribute( "text" ) );
- if ( currentChildElement.tagName() == "RasterItem" )
+ //go through all children of layerItemElem
+ QDomElement currentChildElement = layerItemElem.firstChildElement();
+ while ( !currentChildElement.isNull() )
{
- //get icon from current layer
- QgsRasterLayer* rasterLayer = qobject_cast<QgsRasterLayer *>( currentLayer );
- if ( rasterLayer )
+ QStandardItem* childItem = new QStandardItem( currentChildElement.attribute( "text" ) );
+ if ( currentChildElement.tagName() == "RasterItem" )
{
- childItem->setIcon( QIcon( rasterLayer->legendAsPixmap( true ) ) );
+ //get icon from current layer
+ QgsRasterLayer* rasterLayer = qobject_cast<QgsRasterLayer *>( currentLayer );
+ if ( rasterLayer )
+ {
+ childItem->setIcon( QIcon( rasterLayer->legendAsPixmap( true ) ) );
+ }
+ layerItem->setChild( layerItem->rowCount(), 0, childItem );
}
- layerItem->setChild( layerItem->rowCount(), 0, childItem );
- }
- else if ( currentChildElement.tagName() == "VectorClassificationItem" )
- {
- //read QgsSymbol from xml and get icon
- QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer *>( currentLayer );
- if ( vectorLayer )
+ else if ( currentChildElement.tagName() == "VectorClassificationItem" )
{
- //look for symbol
- QDomNodeList symbolNodeList = currentChildElement.elementsByTagName( "symbol" );
- if ( symbolNodeList.size() > 0 )
+ //read QgsSymbol from xml and get icon
+ QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer *>( currentLayer );
+ if ( vectorLayer )
{
- QgsSymbol* symbol = new QgsSymbol( vectorLayer->geometryType() );
- QDomNode symbolNode = symbolNodeList.at( 0 );
- symbol->readXML( symbolNode, vectorLayer );
- childItem->setData( QVariant::fromValue(( void* )symbol ) );
+ //look for symbol
+ QDomNodeList symbolNodeList = currentChildElement.elementsByTagName( "symbol" );
+ if ( symbolNodeList.size() > 0 )
+ {
+ QgsSymbol* symbol = new QgsSymbol( vectorLayer->geometryType() );
+ QDomNode symbolNode = symbolNodeList.at( 0 );
+ symbol->readXML( symbolNode, vectorLayer );
+ childItem->setData( QVariant::fromValue(( void* )symbol ) );
- //add icon
- switch ( symbol->type() )
- {
- case QGis::Point:
- childItem->setIcon( QIcon( QPixmap::fromImage( symbol->getPointSymbolAsImage() ) ) );
- break;
- case QGis::Line:
- childItem->setIcon( QIcon( QPixmap::fromImage( symbol->getLineSymbolAsImage() ) ) );
- break;
- case QGis::Polygon:
- childItem->setIcon( QIcon( QPixmap::fromImage( symbol->getPolygonSymbolAsImage() ) ) );
- break;
- case QGis::UnknownGeometry:
- // should not occur
- break;
+ //add icon
+ switch ( symbol->type() )
+ {
+ case QGis::Point:
+ childItem->setIcon( QIcon( QPixmap::fromImage( symbol->getPointSymbolAsImage() ) ) );
+ break;
+ case QGis::Line:
+ childItem->setIcon( QIcon( QPixmap::fromImage( symbol->getLineSymbolAsImage() ) ) );
+ break;
+ case QGis::Polygon:
+ childItem->setIcon( QIcon( QPixmap::fromImage( symbol->getPolygonSymbolAsImage() ) ) );
+ break;
+ case QGis::UnknownGeometry:
+ // should not occur
+ break;
+ }
+ insertSymbol( symbol );
}
- insertSymbol( symbol );
}
+ layerItem->setChild( layerItem->rowCount(), 0, childItem );
}
- layerItem->setChild( layerItem->rowCount(), 0, childItem );
- }
- else if ( currentChildElement.tagName() == "VectorClassificationItemNg" )
- {
- QDomElement symbolNgElem = currentChildElement.firstChildElement( "symbols" );
- if ( !symbolNgElem.isNull() )
+ else if ( currentChildElement.tagName() == "VectorClassificationItemNg" )
{
- QgsSymbolV2Map loadSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolNgElem );
- //we assume there is only one symbol in the map...
- QgsSymbolV2Map::iterator mapIt = loadSymbolMap.begin();
- if ( mapIt != loadSymbolMap.end() )
+ QDomElement symbolNgElem = currentChildElement.firstChildElement( "symbols" );
+ if ( !symbolNgElem.isNull() )
{
- QgsSymbolV2* symbolNg = mapIt.value();
- insertSymbolV2( symbolNg );
- childItem->setData( QVariant::fromValue(( void* )symbolNg ), Qt::UserRole + 2 );
- childItem->setIcon( QgsSymbolLayerV2Utils::symbolPreviewIcon( symbolNg, QSize( 30, 30 ) ) );
+ QgsSymbolV2Map loadSymbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolNgElem );
+ //we assume there is only one symbol in the map...
+ QgsSymbolV2Map::iterator mapIt = loadSymbolMap.begin();
+ if ( mapIt != loadSymbolMap.end() )
+ {
+ QgsSymbolV2* symbolNg = mapIt.value();
+ insertSymbolV2( symbolNg );
+ childItem->setData( QVariant::fromValue(( void* )symbolNg ), Qt::UserRole + 2 );
+ childItem->setIcon( QgsSymbolLayerV2Utils::symbolPreviewIcon( symbolNg, QSize( 30, 30 ) ) );
+ }
+ layerItem->setChild( layerItem->rowCount(), 0, childItem );
}
+ }
+ else if ( currentChildElement.tagName() == "TextItem" )
+ {
layerItem->setChild( layerItem->rowCount(), 0, childItem );
}
+ else //unknown tag name, don't add item
+ {
+ delete childItem;
+ }
+
+ currentChildElement = currentChildElement.nextSiblingElement();
}
- else if ( currentChildElement.tagName() == "TextItem" )
- {
- layerItem->setChild( layerItem->rowCount(), 0, childItem );
- }
- else //unknown tag name, don't add item
- {
- delete childItem;
- }
- currentChildElement = currentChildElement.nextSiblingElement();
+ invisibleRootItem()->setChild( invisibleRootItem()->rowCount(), layerItem );
}
- invisibleRootItem()->setChild( invisibleRootItem()->rowCount(), layerItem );
+ return true;
+ */
+}
+
+Qt::DropActions QgsLegendModel::supportedDropActions() const
+{
+ return Qt::MoveAction;
+}
+
+Qt::ItemFlags QgsLegendModel::flags( const QModelIndex &index ) const
+{
+ Qt::ItemFlags flags = QStandardItemModel::flags( index );
+
+ QStandardItem* item = itemFromIndex( index );
+ if ( item )
+ {
+ ItemType type = itemType( *item );
+ if ( type == QgsLegendModel::GroupItem )
+ {
+ flags |= Qt::ItemIsDragEnabled;
+ flags |= Qt::ItemIsDropEnabled;
+ }
+ else if ( type == QgsLegendModel::LayerItem )
+ {
+ flags |= Qt::ItemIsDragEnabled;
+ }
}
+ return flags;
+}
+bool QgsLegendModel::removeRows( int row, int count, const QModelIndex & parent )
+{
+ if ( count < 1 )
+ {
+ return false;
+ }
+
+ if ( parent.isValid() )
+ {
+ for ( int i = row + count - 1; i >= row; --i )
+ {
+ QStandardItem* item = itemFromIndex( parent );
+ if ( item )
+ {
+ item->takeRow( i );
+ }
+ }
+ }
+ else
+ {
+ for ( int i = row + count - 1; i >= row; --i )
+ {
+ takeRow( i );
+ }
+ }
return true;
}
+
+QgsLegendModel::ItemType QgsLegendModel::itemType( const QStandardItem& item ) const
+{
+ return ( QgsLegendModel::ItemType )item.data( Qt::UserRole + 1 ).toInt();
+}
Modified: trunk/qgis/src/core/composer/qgslegendmodel.h
===================================================================
--- trunk/qgis/src/core/composer/qgslegendmodel.h 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/core/composer/qgslegendmodel.h 2010-05-13 21:01:35 UTC (rev 13476)
@@ -29,19 +29,35 @@
class QgsSymbolV2;
class QgsVectorLayer;
+//Information about relationship between groups and layers
+//key: group name (or null strings for single layers without groups)
+//value: containter with layer ids contained in the group
+typedef QPair< QString, QList<QString> > GroupLayerInfo;
+
/** \ingroup MapComposer
- * A model that provides layers as root items. The classification items are
- * children of the layer items.
+ * A model that provides group, layer and classification items.
*/
class CORE_EXPORT QgsLegendModel: public QStandardItemModel
{
Q_OBJECT
public:
+
+ enum ItemType
+ {
+ GroupItem = 0,
+ LayerItem,
+ ClassificationItem
+ };
+
QgsLegendModel();
~QgsLegendModel();
+ /**Sets layer set and groups*/
+ void setLayerSetAndGroups( const QStringList& layerIds, const QList< GroupLayerInfo >& groupInfo );
void setLayerSet( const QStringList& layerIds );
+ /**Adds a group to a toplevel position (or -1 if it should be placed at the end of the legend). Returns a pointer to the added group*/
+ QStandardItem* addGroup( QString text = tr( "Group" ), int position = -1 );
/**Tries to automatically update a model entry (e.g. a whole layer or only a single item)*/
void updateItem( QStandardItem* item );
@@ -55,6 +71,14 @@
bool writeXML( QDomElement& composerLegendElem, QDomDocument& doc ) const;
bool readXML( const QDomElement& legendModelElem, const QDomDocument& doc );
+ Qt::DropActions supportedDropActions() const;
+ Qt::ItemFlags flags( const QModelIndex &index ) const;
+
+ /**Implemented to support drag operations*/
+ virtual bool removeRows( int row, int count, const QModelIndex & parent = QModelIndex() );
+
+ QgsLegendModel::ItemType itemType( const QStandardItem& item ) const;
+
public slots:
void removeLayer( const QString& layerId );
void addLayer( QgsMapLayer* theMapLayer );
@@ -74,24 +98,9 @@
@return 0 in case of success*/
int addRasterLayerItem( QStandardItem* layerItem, QgsMapLayer* rlayer );
- /**Insert a symbol into QgsLegendModel symbol storage*/
- void insertSymbol( QgsSymbol* s );
- void insertSymbolV2( QgsSymbolV2* s );
- /**Removes and deletes a symbol*/
- void removeSymbol( QgsSymbol* s );
- void removeSymbolV2( QgsSymbolV2* s );
- /**Removes and deletes all stored symbols*/
- void removeAllSymbols();
- void removeAllSymbolsV2();
-
/**Creates a model item for a vector symbol. The calling function takes ownership*/
QStandardItem* itemFromSymbol( QgsSymbol* s, int opacity );
- /**Keep track of copied symbols to delete them if not used anymore*/
- QSet<QgsSymbol*> mSymbols;
- /**Keep track of copied symbols v2*/
- QSet<QgsSymbolV2*> mSymbolsV2;
-
protected:
QStringList mLayerIds;
};
Modified: trunk/qgis/src/gui/qgslegendinterface.h
===================================================================
--- trunk/qgis/src/gui/qgslegendinterface.h 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/gui/qgslegendinterface.h 2010-05-13 21:01:35 UTC (rev 13476)
@@ -19,10 +19,16 @@
#define QGSLEGENDINTERFACE_H
#include <QObject>
+#include <QPair>
#include <QStringList>
class QgsMapLayer;
+//Information about relationship between groups and layers
+//key: group name (or null strings for single layers without groups)
+//value: containter with layer ids contained in the group
+typedef QPair< QString, QList<QString> > GroupLayerInfo;
+
/** \ingroup gui
* QgsLegendInterface
* Abstract base class to make QgsLegend available to plugins.
@@ -44,6 +50,9 @@
//! Return a string list of groups
virtual QStringList groups() = 0;
+ //! Return the relationship between groups and layers in the legend
+ virtual QList< GroupLayerInfo > groupLayerRelationship() {}
+
//! Return all layers in the project in legend order
//! @note added in 1.5
virtual QList< QgsMapLayer * > layers() const = 0;
Modified: trunk/qgis/src/ui/qgscomposerlegendwidgetbase.ui
===================================================================
--- trunk/qgis/src/ui/qgscomposerlegendwidgetbase.ui 2010-05-13 16:51:23 UTC (rev 13475)
+++ trunk/qgis/src/ui/qgscomposerlegendwidgetbase.ui 2010-05-13 21:01:35 UTC (rev 13476)
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>354</width>
- <height>474</height>
+ <width>369</width>
+ <height>471</height>
</rect>
</property>
<property name="sizePolicy">
@@ -33,8 +33,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>348</width>
- <height>468</height>
+ <width>365</width>
+ <height>467</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
@@ -48,8 +48,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>180</width>
- <height>347</height>
+ <width>347</width>
+ <height>393</height>
</rect>
</property>
<attribute name="label">
@@ -83,20 +83,27 @@
</widget>
</item>
<item row="3" column="0">
+ <widget class="QPushButton" name="mGroupFontButton">
+ <property name="text">
+ <string>Group Font...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
<widget class="QPushButton" name="mLayerFontButton">
<property name="text">
<string>Layer Font...</string>
</property>
</widget>
</item>
- <item row="4" column="0">
+ <item row="5" column="0">
<widget class="QPushButton" name="mItemFontButton">
<property name="text">
<string>Item Font...</string>
</property>
</widget>
</item>
- <item row="5" column="0">
+ <item row="6" column="0">
<widget class="QDoubleSpinBox" name="mSymbolWidthSpinBox">
<property name="prefix">
<string>Symbol width </string>
@@ -106,7 +113,7 @@
</property>
</widget>
</item>
- <item row="6" column="0">
+ <item row="7" column="0">
<widget class="QDoubleSpinBox" name="mSymbolHeightSpinBox">
<property name="prefix">
<string>Symbol height </string>
@@ -116,7 +123,7 @@
</property>
</widget>
</item>
- <item row="7" column="0">
+ <item row="8" column="0">
<widget class="QDoubleSpinBox" name="mLayerSpaceSpinBox">
<property name="prefix">
<string>Layer space </string>
@@ -126,7 +133,7 @@
</property>
</widget>
</item>
- <item row="8" column="0">
+ <item row="9" column="0">
<widget class="QDoubleSpinBox" name="mSymbolSpaceSpinBox">
<property name="prefix">
<string>Symbol space </string>
@@ -136,7 +143,7 @@
</property>
</widget>
</item>
- <item row="9" column="0">
+ <item row="10" column="0">
<widget class="QDoubleSpinBox" name="mIconLabelSpaceSpinBox">
<property name="prefix">
<string>Icon label space </string>
@@ -146,7 +153,7 @@
</property>
</widget>
</item>
- <item row="10" column="0">
+ <item row="11" column="0">
<widget class="QDoubleSpinBox" name="mBoxSpaceSpinBox">
<property name="prefix">
<string>Box space </string>
@@ -156,7 +163,7 @@
</property>
</widget>
</item>
- <item row="11" column="0">
+ <item row="12" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -176,15 +183,15 @@
<rect>
<x>0</x>
<y>0</y>
- <width>330</width>
- <height>390</height>
+ <width>347</width>
+ <height>393</height>
</rect>
</property>
<attribute name="label">
<string>Legend items</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0" colspan="6">
+ <item row="0" column="0" colspan="7">
<widget class="QTreeView" name="mItemTreeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
@@ -239,6 +246,13 @@
</property>
</widget>
</item>
+ <item row="1" column="6">
+ <widget class="QToolButton" name="mAddGroupButton">
+ <property name="text">
+ <string>Add group</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</widget>
More information about the QGIS-commit
mailing list