diff --git a/images/images.qrc b/images/images.qrc index 5e08dd3a9687..48bde211e4f0 100644 --- a/images/images.qrc +++ b/images/images.qrc @@ -121,6 +121,7 @@ themes/default/mActionAddArrow.png themes/default/mActionAddBasicShape.png themes/default/mActionAddGPSLayer.png + themes/default/mActionAddGroup.png themes/default/mActionAddHtml.png themes/default/mActionAddImage.png themes/default/mActionAddLayer.png diff --git a/images/themes/default/mActionAddGroup.png b/images/themes/default/mActionAddGroup.png new file mode 100644 index 000000000000..dc1f6e825f3a Binary files /dev/null and b/images/themes/default/mActionAddGroup.png differ diff --git a/src/app/composer/qgscomposerlegendwidget.cpp b/src/app/composer/qgscomposerlegendwidget.cpp index 46c043a45bd6..8db3332dce48 100644 --- a/src/app/composer/qgscomposerlegendwidget.cpp +++ b/src/app/composer/qgscomposerlegendwidget.cpp @@ -716,7 +716,7 @@ void QgsComposerLegendWidget::on_mEditPushButton_clicked() return; } - QStandardItem* currentItem = itemModel->itemFromIndex( currentIndex ); + QgsComposerLegendItem* currentItem = dynamic_cast( itemModel->itemFromIndex( currentIndex ) ); if ( !currentItem ) { return; @@ -725,7 +725,8 @@ void QgsComposerLegendWidget::on_mEditPushButton_clicked() QgsComposerLegendItemDialog itemDialog( currentItem ); if ( itemDialog.exec() == QDialog::Accepted ) { - currentItem->setText( itemDialog.itemText() ); + currentItem->setUserText( itemDialog.itemText() ); + mLegend->model()->updateItemText( currentItem ); } mLegend->beginCommand( tr( "Legend item edited" ) ); @@ -822,7 +823,7 @@ void QgsComposerLegendWidget::on_mUpdateAllPushButton_clicked() updateLegend(); } -void QgsComposerLegendWidget::on_mAddGroupButton_clicked() +void QgsComposerLegendWidget::on_mAddGroupToolButton_clicked() { if ( mLegend && mLegend->model() ) { diff --git a/src/app/composer/qgscomposerlegendwidget.h b/src/app/composer/qgscomposerlegendwidget.h index 07f3aca8be36..de64284a6b3a 100644 --- a/src/app/composer/qgscomposerlegendwidget.h +++ b/src/app/composer/qgscomposerlegendwidget.h @@ -82,7 +82,7 @@ class QgsComposerLegendWidget: public QWidget, private Ui::QgsComposerLegendWidg void on_mCountToolButton_clicked( bool checked ); void on_mUpdatePushButton_clicked(); void on_mUpdateAllPushButton_clicked(); - void on_mAddGroupButton_clicked(); + void on_mAddGroupToolButton_clicked(); void selectedChanged( const QModelIndex & current, const QModelIndex & previous ); diff --git a/src/core/composer/qgscomposerlegenditem.cpp b/src/core/composer/qgscomposerlegenditem.cpp index 93516e1cc526..40a7c9617ba5 100644 --- a/src/core/composer/qgscomposerlegenditem.cpp +++ b/src/core/composer/qgscomposerlegenditem.cpp @@ -105,6 +105,7 @@ void QgsComposerSymbolV2Item::writeXML( QDomElement& elem, QDomDocument& doc ) c vectorClassElem.appendChild( symbolsElem ); } vectorClassElem.setAttribute( "text", text() ); + vectorClassElem.setAttribute( "userText", userText() ); elem.appendChild( vectorClassElem ); } @@ -116,6 +117,7 @@ void QgsComposerSymbolV2Item::readXML( const QDomElement& itemElem, bool xServer } setText( itemElem.attribute( "text", "" ) ); + setUserText( itemElem.attribute( "userText", "" ) ); QDomElement symbolsElem = itemElem.firstChildElement( "symbols" ); if ( !symbolsElem.isNull() ) { @@ -174,6 +176,7 @@ void QgsComposerRasterSymbolItem::writeXML( QDomElement& elem, QDomDocument& doc QDomElement rasterClassElem = doc.createElement( "RasterClassificationItem" ); rasterClassElem.setAttribute( "layerId", mLayerID ); rasterClassElem.setAttribute( "text", text() ); + rasterClassElem.setAttribute( "userText", userText() ); rasterClassElem.setAttribute( "color", mColor.name() ); elem.appendChild( rasterClassElem ); } @@ -185,6 +188,7 @@ void QgsComposerRasterSymbolItem::readXML( const QDomElement& itemElem, bool xSe return; } setText( itemElem.attribute( "text", "" ) ); + setUserText( itemElem.attribute( "userText", "" ) ); setLayerID( itemElem.attribute( "layerId", "" ) ); setColor( QColor( itemElem.attribute( "color" ) ) ); @@ -225,6 +229,7 @@ void QgsComposerLayerItem::writeXML( QDomElement& elem, QDomDocument& doc ) cons QDomElement layerItemElem = doc.createElement( "LayerItem" ); layerItemElem.setAttribute( "layerId", mLayerID ); layerItemElem.setAttribute( "text", text() ); + layerItemElem.setAttribute( "userText", userText() ); layerItemElem.setAttribute( "showFeatureCount", showFeatureCount() ); layerItemElem.setAttribute( "style", QgsComposerLegendStyle::styleName( mStyle ) ); writeXMLChildren( layerItemElem, doc ); @@ -238,6 +243,7 @@ void QgsComposerLayerItem::readXML( const QDomElement& itemElem, bool xServerAva return; } setText( itemElem.attribute( "text", "" ) ); + setUserText( itemElem.attribute( "userText", "" ) ); setLayerID( itemElem.attribute( "layerId", "" ) ); setShowFeatureCount( itemElem.attribute( "showFeatureCount", "" ) == "1" ? true : false ); setStyle( QgsComposerLegendStyle::styleFromName( itemElem.attribute( "style", "subgroup" ) ) ); @@ -327,7 +333,9 @@ QStandardItem* QgsComposerGroupItem::clone() const void QgsComposerGroupItem::writeXML( QDomElement& elem, QDomDocument& doc ) const { QDomElement layerGroupElem = doc.createElement( "GroupItem" ); + // text is always user text, but for forward compatibility for now write both layerGroupElem.setAttribute( "text", text() ); + layerGroupElem.setAttribute( "userText", userText() ); layerGroupElem.setAttribute( "style", QgsComposerLegendStyle::styleName( mStyle ) ); writeXMLChildren( layerGroupElem, doc ); elem.appendChild( layerGroupElem ); @@ -339,7 +347,14 @@ void QgsComposerGroupItem::readXML( const QDomElement& itemElem, bool xServerAva { return; } - setText( itemElem.attribute( "text", "" ) ); + // text is always user text but for backward compatibility we read also text + QString userText = itemElem.attribute( "userText", "" ); + if ( userText.isEmpty() ) + { + userText = itemElem.attribute( "text", "" ); + } + setText( userText ); + setUserText( userText ); setStyle( QgsComposerLegendStyle::styleFromName( itemElem.attribute( "style", "group" ) ) ); diff --git a/src/core/composer/qgscomposerlegenditem.h b/src/core/composer/qgscomposerlegenditem.h index ce3b9c6314a7..2b29db782e11 100644 --- a/src/core/composer/qgscomposerlegenditem.h +++ b/src/core/composer/qgscomposerlegenditem.h @@ -53,10 +53,19 @@ class CORE_EXPORT QgsComposerLegendItem: public QStandardItem QgsComposerLegendStyle::Style style() const { return mStyle; } void setStyle( QgsComposerLegendStyle::Style style ) { mStyle = style; } + // Get text defined by user + virtual QString userText() const { return mUserText; } + // Set text defined by user + virtual void setUserText( const QString & text ) { mUserText = text; } + + protected: void writeXMLChildren( QDomElement& elem, QDomDocument& doc ) const; QgsComposerLegendStyle::Style mStyle; + + // User defined text + QString mUserText; }; diff --git a/src/core/composer/qgslegendmodel.cpp b/src/core/composer/qgslegendmodel.cpp index cdf0fbfcada6..cc51fd038fc7 100644 --- a/src/core/composer/qgslegendmodel.cpp +++ b/src/core/composer/qgslegendmodel.cpp @@ -121,6 +121,7 @@ QStandardItem* QgsLegendModel::addGroup( QString text, int position ) text = tr( "Group" ); QgsComposerGroupItem* groupItem = new QgsComposerGroupItem( text ); + groupItem->setUserText( text ); if ( position == -1 ) { @@ -159,19 +160,18 @@ int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLa QgsLegendSymbolList lst = renderer->legendSymbolItems(); QgsLegendSymbolList::const_iterator symbolIt = lst.constBegin(); + int row = 0; for ( ; symbolIt != lst.constEnd(); ++symbolIt ) { - QString label = symbolIt->first; - if ( lItem->showFeatureCount() ) + QgsComposerSymbolV2Item* currentSymbolItem = new QgsComposerSymbolV2Item( "" ); + + // Get userText from old item if exists + QgsComposerSymbolV2Item* oldSymbolItem = dynamic_cast( layerItem->child( row, 0 ) ); + if ( oldSymbolItem ) { - // Add counts to multi symbols layers only or labeled single symbols, - // so that single symbol layers are still drawn on single line - if ( lst.size() > 1 || !label.isEmpty() ) - { - label += QString( " [%1]" ).arg( vlayer->featureCount( symbolIt->second ) ); - } + currentSymbolItem->setUserText( oldSymbolItem->userText() ); } - QgsComposerSymbolV2Item* currentSymbolItem = new QgsComposerSymbolV2Item( label ); + currentSymbolItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); if ( symbolIt->second ) { @@ -181,14 +181,23 @@ int QgsLegendModel::addVectorLayerItemsV2( QStandardItem* layerItem, QgsVectorLa } currentSymbolItem->setSymbolV2( symbolIt->second->clone() ); } - layerItem->setChild( layerItem->rowCount(), 0, currentSymbolItem ); + layerItem->setChild( row, 0, currentSymbolItem ); + + // updateSymbolV2ItemText needs layer set + updateSymbolV2ItemText( currentSymbolItem ); + + row++; + } + + // Delete following old items (if current number of items decreased) + for ( int i = layerItem->rowCount() - 1; i >= row; --i ) + { + layerItem->removeRow( i ); } return 0; } - - int QgsLegendModel::addRasterLayerItems( QStandardItem* layerItem, QgsMapLayer* rlayer ) { if ( !layerItem || !rlayer ) @@ -204,9 +213,18 @@ int QgsLegendModel::addRasterLayerItems( QStandardItem* layerItem, QgsMapLayer* QList< QPair< QString, QColor > > rasterItemList = rasterLayer->legendSymbologyItems(); QList< QPair< QString, QColor > >::const_iterator itemIt = rasterItemList.constBegin(); + int row = 0; for ( ; itemIt != rasterItemList.constEnd(); ++itemIt ) { QgsComposerRasterSymbolItem* currentSymbolItem = new QgsComposerRasterSymbolItem( itemIt->first ); + + QgsComposerRasterSymbolItem* oldSymbolItem = dynamic_cast( layerItem->child( row, 0 ) ); + if ( oldSymbolItem ) + { + currentSymbolItem->setUserText( oldSymbolItem->userText() ); + currentSymbolItem->setText( currentSymbolItem->userText() ); + } + if ( mHasTopLevelWindow ) { QPixmap itemPixmap( 20, 20 ); @@ -217,11 +235,76 @@ int QgsLegendModel::addRasterLayerItems( QStandardItem* layerItem, QgsMapLayer* currentSymbolItem->setColor( itemIt->second ); int currentRowCount = layerItem->rowCount(); layerItem->setChild( currentRowCount, 0, currentSymbolItem ); + row++; + } + + // Delete following old items (if current number of items decreased) + for ( int i = layerItem->rowCount() - 1; i >= row; --i ) + { + layerItem->removeRow( i ); } return 0; } +void QgsLegendModel::updateSymbolV2ItemText( QStandardItem* symbolItem ) +{ + QgsComposerSymbolV2Item* sv2Item = dynamic_cast( symbolItem ); + if ( !sv2Item ) return; + + QgsComposerLayerItem* lItem = dynamic_cast( sv2Item->parent() ); + if ( !lItem ) return; + + QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() ); + if ( !mapLayer ) return; + + QgsVectorLayer* vLayer = qobject_cast( mapLayer ); + if ( !vLayer ) return; + + QgsFeatureRendererV2* renderer = vLayer->rendererV2(); + if ( !renderer ) return; + + if ( lItem->showFeatureCount() ) vLayer->countSymbolFeatures(); + + QgsLegendSymbolList symbolList = renderer->legendSymbolItems(); + + QPair symbol = symbolList.value( symbolItem->row() ); + + QString label = sv2Item->userText().isEmpty() ? symbol.first : sv2Item->userText(); + + if ( lItem->showFeatureCount() ) + { + // Add counts to multi symbols layers only or labeled single symbols, + // so that single symbol layers are still drawn on single line + if ( symbolList.size() > 1 || !label.isEmpty() ) + { + label += QString( " [%1]" ).arg( vLayer->featureCount( symbol.second ) ); + } + } + symbolItem->setText( label ); +} + +void QgsLegendModel::updateRasterSymbolItemText( QStandardItem* symbolItem ) +{ + QgsComposerRasterSymbolItem* rItem = dynamic_cast( symbolItem ); + if ( !rItem ) return; + + QgsComposerLayerItem* lItem = dynamic_cast( rItem->parent() ); + if ( !lItem ) return; + + QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() ); + if ( !mapLayer ) return; + + QgsRasterLayer* rLayer = qobject_cast( mapLayer ); + if ( !rLayer ) return; + + QPair< QString, QColor> symbol = rLayer->legendSymbologyItems().value( symbolItem->row() ); + + QString label = rItem->userText().isEmpty() ? symbol.first : rItem->userText(); + + symbolItem->setText( label ); +} + void QgsLegendModel::updateItem( QStandardItem* item ) { if ( !item ) @@ -243,6 +326,45 @@ void QgsLegendModel::updateItem( QStandardItem* item ) } } +void QgsLegendModel::updateItemText( QStandardItem* item ) +{ + if ( !item ) + { + return; + } + + //only layer items are supported for update + QgsComposerLegendItem* cItem = dynamic_cast( item ); + if ( ! cItem ) + { + return; + } + + QgsComposerLayerItem* lItem = dynamic_cast( cItem ); + if ( lItem ) + { + updateLayerItemText( lItem ); + return; + } + + QgsComposerSymbolV2Item* sv2Item = dynamic_cast( cItem ); + if ( sv2Item ) + { + updateSymbolV2ItemText( sv2Item ); + return; + } + + QgsComposerRasterSymbolItem* rItem = dynamic_cast( cItem ); + if ( rItem ) + { + updateRasterSymbolItemText( rItem ); + return; + } + + // group + cItem->setText( cItem->userText() ); +} + void QgsLegendModel::updateLayer( QStandardItem* layerItem ) { QgsDebugMsg( "Entered." ); @@ -252,22 +374,9 @@ void QgsLegendModel::updateLayer( QStandardItem* layerItem ) QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() ); if ( mapLayer ) { - //delete all the entries under layer item - int currentRowCount = lItem->rowCount(); - for ( int i = currentRowCount - 1; i >= 0; --i ) - { - lItem->removeRow( i ); - } - QgsVectorLayer* vLayer = qobject_cast( mapLayer ); - //set layer name as item text - QString label = mapLayer->name(); - if ( vLayer && lItem->showFeatureCount() ) - { - label += QString( " [%1]" ).arg( vLayer->featureCount() ); - } - layerItem->setText( label ); + updateLayerItemText( lItem ); if ( vLayer ) { @@ -283,6 +392,26 @@ void QgsLegendModel::updateLayer( QStandardItem* layerItem ) } } +void QgsLegendModel::updateLayerItemText( QStandardItem* layerItem ) +{ + QgsComposerLayerItem* lItem = dynamic_cast( layerItem ); + if ( !lItem ) return; + + QgsMapLayer* mapLayer = QgsMapLayerRegistry::instance()->mapLayer( lItem->layerID() ); + if ( !mapLayer ) return; + + QgsVectorLayer* vLayer = qobject_cast( mapLayer ); + if ( !vLayer ) return; + + QString label = lItem->userText().isEmpty() ? mapLayer->name() : lItem->userText(); + + if ( vLayer && lItem->showFeatureCount() ) + { + label += QString( " [%1]" ).arg( vLayer->featureCount() ); + } + lItem->setText( label ); +} + void QgsLegendModel::removeLayer( const QString& layerId ) { int numRootItems = rowCount(); diff --git a/src/core/composer/qgslegendmodel.h b/src/core/composer/qgslegendmodel.h index 7f400a844b23..d13dbcf007ee 100644 --- a/src/core/composer/qgslegendmodel.h +++ b/src/core/composer/qgslegendmodel.h @@ -72,6 +72,10 @@ class CORE_EXPORT QgsLegendModel: public QStandardItemModel void updateRasterClassificationItem( QStandardItem* classificationItem ) { Q_UNUSED( classificationItem ); } + /** Update single item text using item userText and other properties like showFeatureCount */ + void updateItemText( QStandardItem* item ); + + bool writeXML( QDomElement& composerLegendElem, QDomDocument& doc ) const; bool readXML( const QDomElement& legendModelElem, const QDomDocument& doc ); @@ -106,6 +110,11 @@ class CORE_EXPORT QgsLegendModel: public QStandardItemModel @return 0 in case of success*/ int addRasterLayerItems( QStandardItem* layerItem, QgsMapLayer* rlayer ); + void updateLayerItemText( QStandardItem* layerItem ); + void updateSymbolV2ItemText( QStandardItem* symbolItem ); + void updateRasterSymbolItemText( QStandardItem* symbolItem ); + + protected: QStringList mLayerIds; /**True if this application has toplevel windows (normally true). If this is false, this means that the application diff --git a/src/ui/qgscomposerlegendwidgetbase.ui b/src/ui/qgscomposerlegendwidgetbase.ui index f143837d6252..db3ad807fcc9 100644 --- a/src/ui/qgscomposerlegendwidgetbase.ui +++ b/src/ui/qgscomposerlegendwidgetbase.ui @@ -54,7 +54,7 @@ 0 - -118 + 0 369 1088 @@ -141,17 +141,13 @@ - - - - Add group - - - + + Update legend. User defined labels are preserved. + - Update + Update item @@ -163,8 +159,11 @@ + + Update whole legend. Layers are added/removed according to main application legend. User defined labels will be deleted. + - All + Update all @@ -247,6 +246,20 @@ + + + + Add group + + + ... + + + + :/images/themes/default/mActionAddGroup.png:/images/themes/default/mActionAddGroup.png + + +