Skip to content

Commit

Permalink
Legend update function for composer on item level
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@9228 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Aug 31, 2008
1 parent bbd1208 commit fb2e8e4
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 86 deletions.
12 changes: 5 additions & 7 deletions src/app/composer/qgscomposerlegendwidget.cpp
Expand Up @@ -363,13 +363,11 @@ void QgsComposerLegendWidget::on_mUpdatePushButton_clicked()
return;
}

QModelIndex parentIndex = currentIndex.parent();
if ( !parentIndex.isValid() ) // a layer item
{
QString mapLayerId = currentItem->data().toString();
mLegend->model()->updateLayer( mapLayerId );
mLegend->update();
}
if(mLegend->model())
{
mLegend->model()->updateItem(currentItem);
}
mLegend->update();
}

void QgsComposerLegendWidget::on_mUpdateAllPushButton_clicked()
Expand Down
279 changes: 204 additions & 75 deletions src/core/composer/qgslegendmodel.cpp
Expand Up @@ -134,6 +134,7 @@ int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsMapLayer*
continue;
}

#if 0
//label
QString label;
QString lowerValue = ( *symbolIt )->lowerValue();
Expand Down Expand Up @@ -170,12 +171,14 @@ int QgsLegendModel::addVectorLayerItems( QStandardItem* layerItem, QgsMapLayer*
currentSymbolItem->setData( QVariant::fromValue(( void* )symbolCopy ) );
insertSymbol( symbolCopy );

if ( !currentSymbolItem )
{
continue;
}

currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
#endif //0

QStandardItem* currentSymbolItem = itemFromSymbol(*symbolIt);
if(!currentSymbolItem)
{
continue;
}

layerItem->setChild( layerItem->rowCount(), 0, currentSymbolItem );

Expand Down Expand Up @@ -230,103 +233,180 @@ void QgsLegendModel::removeAllSymbols()
mSymbols.clear();
}

#if 0
void QgsLegendModel::updateLayerEntries( const QStringList& newLayerIds )
void QgsLegendModel::updateItem(QStandardItem* item)
{
if ( !invisibleRootItem() )
{
return;
}
if(!item)
{
return;
}

//check for layers to remove
QStandardItem* currentLayerItem = 0;
QSet<int> rowsToRemove;
//is it a toplevel layer item?
QModelIndex itemIndex = indexFromItem(item);
QModelIndex parentIndex = itemIndex.parent();
if ( !parentIndex.isValid() ) // a layer item?
{
updateLayer(item);
}

int numRootItems = rowCount();
for ( int i = 0; i < numRootItems ; ++i )
{
currentLayerItem = item( i );
if ( !currentLayerItem )
//take QgsSymbol* from user data
QVariant symbolVariant = item->data();
QgsSymbol* symbol = 0;
if ( symbolVariant.canConvert<void*>() )
{
continue;
void* symbolData = symbolVariant.value<void*>();
symbol = ( QgsSymbol* )( symbolData );
}

QString layerId = currentLayerItem->data().toString();
if ( symbol ) //vector classification item
{
updateVectorClassificationItem(item, symbol, item->text());
}
else if(!item->icon().isNull()) //raster classification item
{
updateRasterClassificationItem(item);
}
}

if ( !newLayerIds.contains( layerId ) ) //layer has been removed
void QgsLegendModel::updateLayer(QStandardItem* layerItem)
{
if(!layerItem)
{
rowsToRemove.insert( i );
return;
}
}

//remove layers in reverse order
if ( rowsToRemove.size() > 0 )
QString layerId = layerItem->data().toString();
QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer(layerId);
if(mapLayer)
{
//delete all the entries under layer item
for(int i = rowCount() - 1; i >= 0; --i)
{
layerItem->removeRow(i);
}

//and add the new ones...
switch(mapLayer->type())
{
case QgsMapLayer::VECTOR:
addVectorLayerItems(layerItem, mapLayer);
break;
case QgsMapLayer::RASTER:
addRasterLayerItem(layerItem, mapLayer);
break;
default:
break;
}
}
}

void QgsLegendModel::updateVectorClassificationItem(QStandardItem* classificationItem, QgsSymbol* symbol, QString itemText)
{
//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
//still no match found. Test, if there is a symbol with same pen/brush/point symbol

//get parent item
QStandardItem* parentItem = classificationItem->parent();
if(!parentItem)
{
QSet<int>::const_iterator delete_it = --rowsToRemove.constEnd();
for ( ;; --delete_it )
return;
}

//get maplayer object from parent item
QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer(parentItem->data().toString());
if(!ml)
{
removeRow( *delete_it );
if ( delete_it == rowsToRemove.constBegin() )
{
break;
}
return;
}
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>(ml);
if(!vl)
{
return;
}

const QgsRenderer* layerRenderer = vl->renderer();
if(!layerRenderer)
{
return;
}

}
QList<QgsSymbol*> symbolList = layerRenderer->symbols();
QList<QgsSymbol*>::iterator symbolIt;
QgsSymbol* currentSymbol = 0;

//try to find a symbol where lowerbound - upperbound matches item text
symbolIt = symbolList.begin();
for(; symbolIt != symbolList.end(); ++symbolIt)
{
currentSymbol = *symbolIt;
if(currentSymbol->lowerValue() + " - " + currentSymbol->upperValue() == itemText)
{
removeSymbol(symbol);
parentItem->insertRow(classificationItem->row(), itemFromSymbol(currentSymbol));
parentItem->removeRow(classificationItem->row());
return;
}
}

mLayerIds = newLayerIds;
}
#endif //0
//try to find a symbol where lower value matches item text (non-numeric classifications)
symbolIt = symbolList.begin();
for(; symbolIt != symbolList.end(); ++symbolIt)
{
currentSymbol = *symbolIt;
if(currentSymbol->lowerValue() == itemText)
{
removeSymbol(symbol);
parentItem->insertRow(classificationItem->row(), itemFromSymbol(currentSymbol));
parentItem->removeRow(classificationItem->row());
return;
}
}

void QgsLegendModel::updateLayer( const QString& layerId )
{
//find layer item
QStandardItem* layerItem = 0;
QStandardItem* currentLayerItem = 0;
//try to find a symbol where label matches item text
symbolIt = symbolList.begin();
for(; symbolIt != symbolList.end(); ++symbolIt)
{
currentSymbol = *symbolIt;
if(currentSymbol->label() == itemText)
{
removeSymbol(symbol);
parentItem->insertRow(classificationItem->row(), itemFromSymbol(currentSymbol));
parentItem->removeRow(classificationItem->row());
return;
}
}
}


int numRootItems = rowCount();
for ( int i = 0; i < numRootItems ; ++i )
{
currentLayerItem = item( i );
if ( !currentLayerItem )
void QgsLegendModel::updateRasterClassificationItem(QStandardItem* classificationItem)
{
if(!classificationItem)
{
continue;
return;
}

QString currentId = currentLayerItem->data().toString();
if ( currentId == layerId )
QStandardItem* parentItem = classificationItem->parent();
if(!parentItem)
{
layerItem = currentLayerItem;
break;
return;
}
}

if ( layerItem )
{
QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( layerId );
if ( mapLayer )
QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer(parentItem->data().toString());
if(!ml)
{
//delete all the entries under layer item
for ( int i = rowCount() - 1; i >= 0; --i )
{
layerItem->removeRow( i );
}
return;
}

//and add the new ones...
switch ( mapLayer->type() )
{
case QgsMapLayer::VECTOR:
addVectorLayerItems( layerItem, mapLayer );
break;
case QgsMapLayer::RASTER:
addRasterLayerItem( layerItem, mapLayer );
break;
default:
break;
}
QgsRasterLayer* rl = dynamic_cast<QgsRasterLayer*>(ml);
if(!rl)
{
return;
}
}

QStandardItem* currentSymbolItem = new QStandardItem( QIcon( rl->getLegendQPixmap( true ) ), "" );
parentItem->insertRow(0, currentSymbolItem);
parentItem->removeRow(1);
}

void QgsLegendModel::removeLayer( const QString& layerId )
Expand Down Expand Up @@ -380,6 +460,55 @@ void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer )
}
emit layersChanged();
}

QStandardItem* QgsLegendModel::itemFromSymbol(QgsSymbol* s)
{
QStandardItem* currentSymbolItem = 0;

//label
QString label;
QString lowerValue = s->lowerValue();
QString upperValue = s->upperValue();

if ( lowerValue == upperValue || upperValue.isEmpty() )
{
label = lowerValue;
}
else
{
label = lowerValue + " - " + upperValue;
}

//icon item
switch (s->type())
{
case QGis::Point:
currentSymbolItem = new QStandardItem( QIcon( QPixmap::fromImage(s->getPointSymbolAsImage() ) ), label );
break;
case QGis::Line:
currentSymbolItem = new QStandardItem( QIcon( QPixmap::fromImage(s->getLineSymbolAsImage() ) ), label );
break;
case QGis::Polygon:
currentSymbolItem = new QStandardItem( QIcon( QPixmap::fromImage(s->getPolygonSymbolAsImage() ) ), label );
break;
default:
currentSymbolItem = 0;
break;
}

if(!currentSymbolItem)
{
return 0;
}

//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->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
return currentSymbolItem;
}

bool QgsLegendModel::writeXML( QDomElement& composerLegendElem, QDomDocument& doc )
{
Expand Down
14 changes: 10 additions & 4 deletions src/core/composer/qgslegendmodel.h
Expand Up @@ -40,11 +40,14 @@ class CORE_EXPORT QgsLegendModel: public QStandardItemModel
~QgsLegendModel();

void setLayerSet( const QStringList& layerIds );
/**Apply added or removed layers to the model*/
//void updateLayerEntries( const QStringList& newLayerIds );

/**Updates the symbology of a single layer*/
void updateLayer( const QString& layerId );
/**Tries to automatically update a model entry (e.g. a whole layer or only a single item)*/
void updateItem(QStandardItem* item);
/**Updates the whole symbology of a layer*/
void updateLayer(QStandardItem* layerItem);
/**Tries to update a single classification item*/
void updateVectorClassificationItem(QStandardItem* classificationItem, QgsSymbol* symbol, QString itemText);
void updateRasterClassificationItem(QStandardItem* classificationItem);

bool writeXML( QDomElement& composerLegendElem, QDomDocument& doc );
bool readXML( const QDomElement& legendModelElem, const QDomDocument& doc );
Expand Down Expand Up @@ -72,6 +75,9 @@ class CORE_EXPORT QgsLegendModel: public QStandardItemModel
/**Removes and deletes all stored symbols*/
void removeAllSymbols();

/**Creates a model item for a vector symbol. The calling function takes ownership*/
QStandardItem* itemFromSymbol(QgsSymbol* s);

/**Keep track of copied symbols to delete them if not used anymore*/
QSet<QgsSymbol*> mSymbols;

Expand Down

0 comments on commit fb2e8e4

Please sign in to comment.