diff --git a/doc/api_break.dox b/doc/api_break.dox index 3e0a804fca6..494461c0fa1 100644 --- a/doc/api_break.dox +++ b/doc/api_break.dox @@ -1467,6 +1467,8 @@ in code which previously passed a null pointer to QgsVectorLayerImport. \subsection qgis_api_break_3_0_QgsVectorFileWriter QgsVectorFileWriter diff --git a/python/core/qgsmapthemecollection.sip b/python/core/qgsmapthemecollection.sip index e0377bb3197..490731d444a 100644 --- a/python/core/qgsmapthemecollection.sip +++ b/python/core/qgsmapthemecollection.sip @@ -1,9 +1,9 @@ /** \class QgsMapThemeCollection \ingroup core - \brief Container class that allows storage of visibility presets consisting of visible + \brief Container class that allows storage of map themes consisting of visible map layers and layer styles. - \note added in QGIS 2.12 + \note Added in QGIS 2.12, renamed for QGIS 3.0 */ class QgsMapThemeCollection : QObject @@ -13,119 +13,134 @@ class QgsMapThemeCollection : QObject %End public: - /** Individual preset record of visible layers and styles. + /** \ingroup core + * Individual map theme record of visible layers and styles. */ - class PresetRecord + class MapThemeRecord { public: - bool operator==( const QgsMapThemeCollection::PresetRecord& other ) const; - bool operator!=( const QgsMapThemeCollection::PresetRecord& other ) const; + bool operator==( const QgsMapThemeCollection::MapThemeRecord& other ) const; + bool operator!=( const QgsMapThemeCollection::MapThemeRecord& other ) const; - //! Ordered list of layers that are visible - QStringList mVisibleLayerIDs; - /** For layers that have checkable legend symbols and not all symbols are checked - list which ones are + /** + * Ordered list of visible layers + */ + QStringList visibleLayerIds() const; + + /** + * Ordered list of visible layers + */ + void setVisibleLayerIds( const QStringList& visibleLayerIds ); + + /** + * Lists which legend symbols are checked for layers which support this and where + * not all symbols are checked. * @note not available in Python bindings */ - //QMap > mPerLayerCheckedLegendSymbols; - //! For layers that use multiple styles - which one is currently selected - QMap mPerLayerCurrentStyle; +// QMap > perLayerCheckedLegendSymbols() const; + + /** + * Lists which legend symbols are checked for layers which support this and where + * not all symbols are checked. + * @note not available in Python bindings + */ +// void setPerLayerCheckedLegendSymbols(const QMap >& perLayerCheckedLegendSymbols); + + /** + * The currently used style name for layers with multiple styles. + * The map has layer ids as keys and style names as values. + */ + QMap perLayerCurrentStyle() const; + + /** + * The currently used style name for layers with multiple styles. + * The map has layer ids as keys and style names as values. + */ + void setPerLayerCurrentStyle(const QMap& perLayerCurrentStyle); + }; QgsMapThemeCollection(); - /** Returns whether a preset with a matching name exists. - * @param name name of preset to check - * @returns true if preset exists + /** + * Returns whether a map theme with a matching name exists. */ - bool hasPreset( const QString& name ) const; + bool hasMapTheme( const QString& name ) const; - /** Inserts a new preset to the collection. - * @param name name of preset - * @param state preset record + /** + * Inserts a new map theme to the collection. * @see update() */ - void insert( const QString& name, const PresetRecord& state ); + void insert( const QString& name, const MapThemeRecord& state ); - /** Updates a preset within the collection. - * @param name name of preset to update - * @param state preset record to replace existing preset + /** + * Updates a map theme within the collection. + * @param name name of map theme to update + * @param state map theme record to replace existing map theme * @see insert() */ - void update( const QString& name, const PresetRecord& state ); + void update( const QString& name, const MapThemeRecord& state ); - /** Remove existing preset from collection. - * @param name preset name + /** + * Remove an existing map theme from collection. */ - void removePreset( const QString& name ); + void removeMapTheme( const QString& name ); - //! Remove all presets from the collection. + //! Remove all map themes from the collection. void clear(); - //! Returns a list of existing preset names. - QStringList presets() const; + //! Returns a list of existing map theme names. + QStringList mapThemes() const; - /** Returns the recorded state of a preset. - * @param name name of preset + /** + * Returns the recorded state of a map theme. */ - PresetRecord presetState( const QString& name ) const; + MapThemeRecord mapThemeState( const QString& name ) const; - /** Returns the list of layer IDs that should be visible for the specified preset. + /** + * Returns the list of layer IDs that are visible for the specified map theme. + * * @note The order of the returned list is not guaranteed to reflect the order of layers * in the canvas. - * @param name preset name */ - QStringList presetVisibleLayers( const QString& name ) const; + QStringList mapThemeVisibleLayers( const QString& name ) const; - /** Apply check states of legend nodes of a given layer as defined in the preset. - * @param name preset name - * @param layerID layer ID + /** + * Apply check states of legend nodes of a given layer as defined in the map theme. */ - void applyPresetCheckedLegendNodesToLayer( const QString& name, const QString& layerID ); + void applyMapThemeCheckedLegendNodesToLayer( const QString& name, const QString& layerID ); - /** Get layer style overrides (for QgsMapSettings) of the visible layers for given preset. - * @param name preset name + /** + * Get layer style overrides (for QgsMapSettings) of the visible layers for given map theme. */ - QMap presetStyleOverrides( const QString& name ); + QMap mapThemeStyleOverride( const QString& name ); - /** Reads the preset collection state from XML + /** + * Reads the map theme collection state from XML * @param doc DOM document - * @see writeXML + * @see writeXml */ void readXml( const QDomDocument& doc ); - /** Writes the preset collection state to XML. + /** Writes the map theme collection state to XML. * @param doc DOM document - * @see readXML + * @see readXml */ void writeXml( QDomDocument& doc ); - /** Static method for adding visible layers from a layer tree group to a preset + /** + * Static method for adding visible layers from a layer tree group to a map theme * record. * @param parent layer tree group parent - * @param rec preset record to amend + * @param rec map theme record to amend */ - static void addVisibleLayersToPreset( QgsLayerTreeGroup* parent, PresetRecord& rec ); + static void addVisibleLayersToMapTheme( QgsLayerTreeGroup* parent, MapThemeRecord& rec ); signals: - /** Emitted when presets within the collection are changed. + /** Emitted when map themes within the collection are changed. */ - void presetsChanged(); - - protected slots: - - /** Handles updates of the preset collection when layers are removed from the registry - */ - void registryLayersRemoved( const QStringList& layerIDs ); - - //! Update style name if a stored style gets renamed - void layerStyleRenamed( const QString& oldName, const QString& newName ); - - protected: - - /** Reconnects all preset layers to handle style renames - */ - void reconnectToLayersStyleManager(); + void mapThemesChanged(); }; diff --git a/src/app/composer/qgscomposermapwidget.cpp b/src/app/composer/qgscomposermapwidget.cpp index 9883e813bae..e43ac8978ac 100644 --- a/src/app/composer/qgscomposermapwidget.cpp +++ b/src/app/composer/qgscomposermapwidget.cpp @@ -158,7 +158,7 @@ void QgsComposerMapWidget::aboutToShowKeepLayersVisibilityPresetsMenu() return; menu->clear(); - Q_FOREACH ( const QString& presetName, QgsProject::instance()->mapThemeCollection()->presets() ) + Q_FOREACH ( const QString& presetName, QgsProject::instance()->mapThemeCollection()->mapThemes() ) { menu->addAction( presetName, this, SLOT( keepLayersVisibilityPresetSelected() ) ); } @@ -206,7 +206,7 @@ void QgsComposerMapWidget::keepLayersVisibilityPresetSelected() mKeepLayerStylesCheckBox->setChecked( true ); - mComposerMap->setLayerStyleOverrides( QgsProject::instance()->mapThemeCollection()->presetStyleOverrides( presetName ) ); + mComposerMap->setLayerStyleOverrides( QgsProject::instance()->mapThemeCollection()->mapThemeStyleOverride( presetName ) ); mComposerMap->cache(); mComposerMap->update(); @@ -219,7 +219,7 @@ void QgsComposerMapWidget::onPresetsChanged() { QStringList lst; lst.append( tr( "(none)" ) ); - lst += QgsProject::instance()->mapThemeCollection()->presets(); + lst += QgsProject::instance()->mapThemeCollection()->mapThemes(); model->setStringList( lst ); // select the previously selected item again diff --git a/src/app/main.cpp b/src/app/main.cpp index c67fdeda7e0..6b671995f92 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -1200,7 +1200,7 @@ int main( int argc, char *argv[] ) QList< QPair > layers; if ( !dxfPreset.isEmpty() ) { - Q_FOREACH ( const QString& layer, QgsProject::instance()->mapThemeCollection()->presetVisibleLayers( dxfPreset ) ) + Q_FOREACH ( const QString& layer, QgsProject::instance()->mapThemeCollection()->mapThemeVisibleLayers( dxfPreset ) ) { QgsVectorLayer *vl = qobject_cast( QgsMapLayerRegistry::instance()->mapLayer( layer ) ); if ( !vl ) diff --git a/src/app/qgsdxfexportdialog.cpp b/src/app/qgsdxfexportdialog.cpp index f1a0f90f94c..580b9d60708 100644 --- a/src/app/qgsdxfexportdialog.cpp +++ b/src/app/qgsdxfexportdialog.cpp @@ -346,7 +346,7 @@ void QgsVectorLayerAndAttributeModel::applyVisibilityPreset( const QString &name } else { - visibleLayers = QgsProject::instance()->mapThemeCollection()->presetVisibleLayers( name ).toSet(); + visibleLayers = QgsProject::instance()->mapThemeCollection()->mapThemeVisibleLayers( name ).toSet(); } if ( visibleLayers.isEmpty() ) @@ -452,7 +452,7 @@ QgsDxfExportDialog::QgsDxfExportDialog( QWidget *parent, Qt::WindowFlags f ) mLayerTitleAsName->setChecked( QgsProject::instance()->readEntry( "dxf", "/lastDxfLayerTitleAsName", s.value( "qgis/lastDxfLayerTitleAsName", "false" ).toString() ) != "false" ); mMapExtentCheckBox->setChecked( QgsProject::instance()->readEntry( "dxf", "/lastDxfMapRectangle", s.value( "qgis/lastDxfMapRectangle", "false" ).toString() ) != "false" ); - QStringList ids = QgsProject::instance()->mapThemeCollection()->presets(); + QStringList ids = QgsProject::instance()->mapThemeCollection()->mapThemes(); ids.prepend( "" ); mVisibilityPresets->addItems( ids ); mVisibilityPresets->setCurrentIndex( mVisibilityPresets->findText( QgsProject::instance()->readEntry( "dxf", "/lastVisibliltyPreset", "" ) ) ); diff --git a/src/app/qgsmapthemes.cpp b/src/app/qgsmapthemes.cpp index 404804828ba..5408ce012f3 100644 --- a/src/app/qgsmapthemes.cpp +++ b/src/app/qgsmapthemes.cpp @@ -55,11 +55,11 @@ QgsMapThemes::QgsMapThemes() connect( mMenu, SIGNAL( aboutToShow() ), this, SLOT( menuAboutToShow() ) ); } -void QgsMapThemes::addPerLayerCheckedLegendSymbols( QgsMapThemeCollection::PresetRecord& rec ) +void QgsMapThemes::addPerLayerCheckedLegendSymbols( QgsMapThemeCollection::MapThemeRecord& rec ) { QgsLayerTreeModel* model = QgisApp::instance()->layerTreeView()->layerTreeModel(); - Q_FOREACH ( const QString& layerID, rec.mVisibleLayerIDs ) + Q_FOREACH ( const QString& layerID, rec.visibleLayerIds() ) { QgsLayerTreeLayer* nodeLayer = model->rootGroup()->findLayer( layerID ); if ( !nodeLayer ) @@ -81,30 +81,37 @@ void QgsMapThemes::addPerLayerCheckedLegendSymbols( QgsMapThemeCollection::Prese } } + QMap > checkedSymbols = rec.perLayerCheckedLegendSymbols(); + if ( hasCheckableItems && someItemsUnchecked ) - rec.mPerLayerCheckedLegendSymbols.insert( nodeLayer->layerId(), checkedItems ); + checkedSymbols.insert( nodeLayer->layerId(), checkedItems ); + + rec.setPerLayerCheckedLegendSymbols( checkedSymbols ); } } -void QgsMapThemes::addPerLayerCurrentStyle( QgsMapThemeCollection::PresetRecord& rec ) +void QgsMapThemes::addPerLayerCurrentStyle( QgsMapThemeCollection::MapThemeRecord& rec ) { QgsLayerTreeModel* model = QgisApp::instance()->layerTreeView()->layerTreeModel(); - Q_FOREACH ( const QString& layerID, rec.mVisibleLayerIDs ) + QMap styles = rec.perLayerCurrentStyle(); + + Q_FOREACH ( const QString& layerID, rec.visibleLayerIds() ) { QgsLayerTreeLayer* nodeLayer = model->rootGroup()->findLayer( layerID ); if ( !nodeLayer ) continue; - rec.mPerLayerCurrentStyle[layerID] = nodeLayer->layer()->styleManager()->currentStyle(); + styles[layerID] = nodeLayer->layer()->styleManager()->currentStyle(); } + rec.setPerLayerCurrentStyle( styles ); } -QgsMapThemeCollection::PresetRecord QgsMapThemes::currentState() +QgsMapThemeCollection::MapThemeRecord QgsMapThemes::currentState() { - QgsMapThemeCollection::PresetRecord rec; + QgsMapThemeCollection::MapThemeRecord rec; QgsLayerTreeGroup* root = QgsProject::instance()->layerTreeRoot(); - QgsMapThemeCollection::addVisibleLayersToPreset( root, rec ); + QgsMapThemeCollection::addVisibleLayersToMapTheme( root, rec ); addPerLayerCheckedLegendSymbols( rec ); addPerLayerCurrentStyle( rec ); return rec; @@ -130,7 +137,7 @@ void QgsMapThemes::updatePreset( const QString& name ) QStringList QgsMapThemes::orderedPresetVisibleLayers( const QString& name ) const { - QStringList visibleIds = QgsProject::instance()->mapThemeCollection()->presetVisibleLayers( name ); + QStringList visibleIds = QgsProject::instance()->mapThemeCollection()->mapThemeVisibleLayers( name ); // also make sure to order the layers according to map canvas order QgsLayerTreeMapCanvasBridge* bridge = QgisApp::instance()->layerTreeCanvasBridge(); @@ -153,7 +160,7 @@ QMenu* QgsMapThemes::menu() void QgsMapThemes::addPreset() { - QStringList existingNames = QgsProject::instance()->mapThemeCollection()->presets(); + QStringList existingNames = QgsProject::instance()->mapThemeCollection()->mapThemes(); QgsNewNameDialog dlg( tr( "theme" ) , tr( "Theme" ), QStringList(), existingNames, QRegExp(), Qt::CaseInsensitive, mMenu ); dlg.setWindowTitle( tr( "Map Themes" ) ); dlg.setHintString( tr( "Name of the new theme" ) ); @@ -185,7 +192,7 @@ void QgsMapThemes::replaceTriggered() addPreset( actionPreset->text() ); } -void QgsMapThemes::applyStateToLayerTreeGroup( QgsLayerTreeGroup* parent, const QgsMapThemeCollection::PresetRecord& rec ) +void QgsMapThemes::applyStateToLayerTreeGroup( QgsLayerTreeGroup* parent, const QgsMapThemeCollection::MapThemeRecord& rec ) { Q_FOREACH ( QgsLayerTreeNode* node, parent->children() ) { @@ -194,21 +201,21 @@ void QgsMapThemes::applyStateToLayerTreeGroup( QgsLayerTreeGroup* parent, const else if ( QgsLayerTree::isLayer( node ) ) { QgsLayerTreeLayer* nodeLayer = QgsLayerTree::toLayer( node ); - bool isVisible = rec.mVisibleLayerIDs.contains( nodeLayer->layerId() ); + bool isVisible = rec.visibleLayerIds().contains( nodeLayer->layerId() ); nodeLayer->setVisible( isVisible ? Qt::Checked : Qt::Unchecked ); if ( isVisible ) { - if ( rec.mPerLayerCurrentStyle.contains( nodeLayer->layerId() ) ) + if ( rec.perLayerCurrentStyle().contains( nodeLayer->layerId() ) ) { // apply desired style first - nodeLayer->layer()->styleManager()->setCurrentStyle( rec.mPerLayerCurrentStyle[nodeLayer->layerId()] ); + nodeLayer->layer()->styleManager()->setCurrentStyle( rec.perLayerCurrentStyle().value( nodeLayer->layerId() ) ); } QgsLayerTreeModel* model = QgisApp::instance()->layerTreeView()->layerTreeModel(); - if ( rec.mPerLayerCheckedLegendSymbols.contains( nodeLayer->layerId() ) ) + if ( rec.perLayerCheckedLegendSymbols().contains( nodeLayer->layerId() ) ) { - const QSet& checkedNodes = rec.mPerLayerCheckedLegendSymbols[nodeLayer->layerId()]; + const QSet& checkedNodes = rec.perLayerCheckedLegendSymbols().value( nodeLayer->layerId() ); // some nodes are not checked Q_FOREACH ( QgsLayerTreeModelLegendNode* legendNode, model->layerLegendNodes( nodeLayer ) ) { @@ -236,10 +243,10 @@ void QgsMapThemes::applyStateToLayerTreeGroup( QgsLayerTreeGroup* parent, const void QgsMapThemes::applyState( const QString& presetName ) { - if ( !QgsProject::instance()->mapThemeCollection()->hasPreset( presetName ) ) + if ( !QgsProject::instance()->mapThemeCollection()->hasMapTheme( presetName ) ) return; - applyStateToLayerTreeGroup( QgsProject::instance()->layerTreeRoot(), QgsProject::instance()->mapThemeCollection()->presetState( presetName ) ); + applyStateToLayerTreeGroup( QgsProject::instance()->layerTreeRoot(), QgsProject::instance()->mapThemeCollection()->mapThemeState( presetName ) ); // also make sure that the preset is up-to-date (not containing any non-existent legend items) QgsProject::instance()->mapThemeCollection()->update( presetName, currentState() ); @@ -251,7 +258,7 @@ void QgsMapThemes::removeCurrentPreset() { if ( a->isChecked() ) { - QgsProject::instance()->mapThemeCollection()->removePreset( a->text() ); + QgsProject::instance()->mapThemeCollection()->removeMapTheme( a->text() ); break; } } @@ -265,14 +272,14 @@ void QgsMapThemes::menuAboutToShow() qDeleteAll( mMenuReplaceActions ); mMenuReplaceActions.clear(); - QgsMapThemeCollection::PresetRecord rec = currentState(); + QgsMapThemeCollection::MapThemeRecord rec = currentState(); bool hasCurrent = false; - Q_FOREACH ( const QString& grpName, QgsProject::instance()->mapThemeCollection()->presets() ) + Q_FOREACH ( const QString& grpName, QgsProject::instance()->mapThemeCollection()->mapThemes() ) { QAction* a = new QAction( grpName, mMenu ); a->setCheckable( true ); - if ( !hasCurrent && rec == QgsProject::instance()->mapThemeCollection()->presetState( grpName ) ) + if ( !hasCurrent && rec == QgsProject::instance()->mapThemeCollection()->mapThemeState( grpName ) ) { a->setChecked( true ); hasCurrent = true; diff --git a/src/app/qgsmapthemes.h b/src/app/qgsmapthemes.h index 8af5b7b3eff..3b2fa802c42 100644 --- a/src/app/qgsmapthemes.h +++ b/src/app/qgsmapthemes.h @@ -74,14 +74,14 @@ class APP_EXPORT QgsMapThemes : public QObject QgsMapThemes(); // singleton //! Applies current layer state to a preset record - void applyStateToLayerTreeGroup( QgsLayerTreeGroup* parent, const QgsMapThemeCollection::PresetRecord& rec ); + void applyStateToLayerTreeGroup( QgsLayerTreeGroup* parent, const QgsMapThemeCollection::MapThemeRecord& rec ); //! Applies layer checked legend symbols to a preset record - void addPerLayerCheckedLegendSymbols( QgsMapThemeCollection::PresetRecord& rec ); + void addPerLayerCheckedLegendSymbols( QgsMapThemeCollection::MapThemeRecord& rec ); //! Applies current layer styles to a preset record - void addPerLayerCurrentStyle( QgsMapThemeCollection::PresetRecord& rec ); + void addPerLayerCurrentStyle( QgsMapThemeCollection::MapThemeRecord& rec ); //! Returns the current state of the map canvas as a preset record - QgsMapThemeCollection::PresetRecord currentState(); + QgsMapThemeCollection::MapThemeRecord currentState(); //! Applies a preset for the project's collection to the canvas void applyState( const QString& presetName ); diff --git a/src/core/composer/qgscomposermap.cpp b/src/core/composer/qgscomposermap.cpp index cb7942c1143..7b1ddb35ffa 100644 --- a/src/core/composer/qgscomposermap.cpp +++ b/src/core/composer/qgscomposermap.cpp @@ -537,8 +537,8 @@ QStringList QgsComposerMap::layersToRender( const QgsExpressionContext* context presetName = exprVal.toString(); } - if ( QgsProject::instance()->mapThemeCollection()->hasPreset( presetName ) ) - renderLayerSet = QgsProject::instance()->mapThemeCollection()->presetVisibleLayers( presetName ); + if ( QgsProject::instance()->mapThemeCollection()->hasMapTheme( presetName ) ) + renderLayerSet = QgsProject::instance()->mapThemeCollection()->mapThemeVisibleLayers( presetName ); else // fallback to using map canvas layers renderLayerSet = mComposition->mapSettings().layers(); } @@ -598,8 +598,8 @@ QMap QgsComposerMap::layerStyleOverridesToRender( const QgsExp presetName = exprVal.toString(); } - if ( QgsProject::instance()->mapThemeCollection()->hasPreset( presetName ) ) - return QgsProject::instance()->mapThemeCollection()->presetStyleOverrides( presetName ); + if ( QgsProject::instance()->mapThemeCollection()->hasMapTheme( presetName ) ) + return QgsProject::instance()->mapThemeCollection()->mapThemeStyleOverride( presetName ); else return QMap(); } diff --git a/src/core/qgsmapthemecollection.cpp b/src/core/qgsmapthemecollection.cpp index 60b07404d25..41e742ef2e5 100644 --- a/src/core/qgsmapthemecollection.cpp +++ b/src/core/qgsmapthemecollection.cpp @@ -32,85 +32,85 @@ QgsMapThemeCollection::QgsMapThemeCollection() this, SLOT( registryLayersRemoved( QStringList ) ) ); } -void QgsMapThemeCollection::addVisibleLayersToPreset( QgsLayerTreeGroup* parent, QgsMapThemeCollection::PresetRecord& rec ) +void QgsMapThemeCollection::addVisibleLayersToMapTheme( QgsLayerTreeGroup* parent, QgsMapThemeCollection::MapThemeRecord& rec ) { Q_FOREACH ( QgsLayerTreeNode* node, parent->children() ) { if ( QgsLayerTree::isGroup( node ) ) - addVisibleLayersToPreset( QgsLayerTree::toGroup( node ), rec ); + addVisibleLayersToMapTheme( QgsLayerTree::toGroup( node ), rec ); else if ( QgsLayerTree::isLayer( node ) ) { QgsLayerTreeLayer* nodeLayer = QgsLayerTree::toLayer( node ); if ( nodeLayer->isVisible() ) - rec.mVisibleLayerIDs << nodeLayer->layerId(); + rec.mVisibleLayerIds << nodeLayer->layerId(); } } } -bool QgsMapThemeCollection::hasPreset( const QString& name ) const +bool QgsMapThemeCollection::hasMapTheme( const QString& name ) const { - return mPresets.contains( name ); + return mMapThemes.contains( name ); } -void QgsMapThemeCollection::insert( const QString& name, const QgsMapThemeCollection::PresetRecord& state ) +void QgsMapThemeCollection::insert( const QString& name, const QgsMapThemeCollection::MapThemeRecord& state ) { - mPresets.insert( name, state ); + mMapThemes.insert( name, state ); reconnectToLayersStyleManager(); - emit presetsChanged(); + emit mapThemesChanged(); } -void QgsMapThemeCollection::update( const QString& name, const PresetRecord& state ) +void QgsMapThemeCollection::update( const QString& name, const MapThemeRecord& state ) { - if ( !mPresets.contains( name ) ) + if ( !mMapThemes.contains( name ) ) return; - mPresets[name] = state; + mMapThemes[name] = state; reconnectToLayersStyleManager(); - emit presetsChanged(); + emit mapThemesChanged(); } -void QgsMapThemeCollection::removePreset( const QString& name ) +void QgsMapThemeCollection::removeMapTheme( const QString& name ) { - if ( !mPresets.contains( name ) ) + if ( !mMapThemes.contains( name ) ) return; - mPresets.remove( name ); + mMapThemes.remove( name ); reconnectToLayersStyleManager(); - emit presetsChanged(); + emit mapThemesChanged(); } void QgsMapThemeCollection::clear() { - mPresets.clear(); + mMapThemes.clear(); reconnectToLayersStyleManager(); - emit presetsChanged(); + emit mapThemesChanged(); } -QStringList QgsMapThemeCollection::presets() const +QStringList QgsMapThemeCollection::mapThemes() const { - return mPresets.keys(); + return mMapThemes.keys(); } -QStringList QgsMapThemeCollection::presetVisibleLayers( const QString& name ) const +QStringList QgsMapThemeCollection::mapThemeVisibleLayers( const QString& name ) const { - return mPresets.value( name ).mVisibleLayerIDs; + return mMapThemes.value( name ).mVisibleLayerIds; } -void QgsMapThemeCollection::applyPresetCheckedLegendNodesToLayer( const QString& name, const QString& layerID ) +void QgsMapThemeCollection::applyMapThemeCheckedLegendNodesToLayer( const QString& name, const QString& layerID ) { - if ( !mPresets.contains( name ) ) + if ( !mMapThemes.contains( name ) ) return; QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerID ); if ( !layer ) return; - const PresetRecord& rec = mPresets[name]; + const MapThemeRecord& rec = mMapThemes[name]; QgsVectorLayer* vlayer = qobject_cast( layer ); if ( !vlayer || !vlayer->renderer() ) @@ -131,14 +131,14 @@ void QgsMapThemeCollection::applyPresetCheckedLegendNodesToLayer( const QString& } -QMap QgsMapThemeCollection::presetStyleOverrides( const QString& presetName ) +QMap QgsMapThemeCollection::mapThemeStyleOverride( const QString& presetName ) { QMap styleOverrides; - if ( !mPresets.contains( presetName ) ) + if ( !mMapThemes.contains( presetName ) ) return styleOverrides; - QStringList lst = presetVisibleLayers( presetName ); - const QgsMapThemeCollection::PresetRecord& rec = mPresets[presetName]; + QStringList lst = mapThemeVisibleLayers( presetName ); + const QgsMapThemeCollection::MapThemeRecord& rec = mMapThemes[presetName]; Q_FOREACH ( const QString& layerID, lst ) { QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerID ); @@ -152,7 +152,7 @@ QMap QgsMapThemeCollection::presetStyleOverrides( const QStrin layer->styleManager()->setOverrideStyle( overrideStyleName ); // set the checked legend nodes - applyPresetCheckedLegendNodesToLayer( presetName, layerID ); + applyMapThemeCheckedLegendNodesToLayer( presetName, layerID ); // save to overrides QgsMapLayerStyle layerStyle; @@ -169,10 +169,10 @@ void QgsMapThemeCollection::reconnectToLayersStyleManager() // disconnect( 0, 0, this, SLOT( layerStyleRenamed( QString, QString ) ) ); QSet layerIDs; - PresetRecordMap::const_iterator it = mPresets.constBegin(); - for ( ; it != mPresets.constEnd(); ++it ) + MapThemeRecordMap::const_iterator it = mMapThemes.constBegin(); + for ( ; it != mMapThemes.constEnd(); ++it ) { - const PresetRecord& rec = it.value(); + const MapThemeRecord& rec = it.value(); QMap::const_iterator layerIt = rec.mPerLayerCurrentStyle.constBegin(); for ( ; layerIt != rec.mPerLayerCurrentStyle.constEnd(); ++layerIt ) layerIDs << layerIt.key(); @@ -197,14 +197,14 @@ void QgsMapThemeCollection::readXml( const QDomDocument& doc ) while ( !visPresetElem.isNull() ) { QString presetName = visPresetElem.attribute( "name" ); - PresetRecord rec; + MapThemeRecord rec; QDomElement visPresetLayerElem = visPresetElem.firstChildElement( "layer" ); while ( !visPresetLayerElem.isNull() ) { QString layerID = visPresetLayerElem.attribute( "id" ); if ( QgsMapLayerRegistry::instance()->mapLayer( layerID ) ) { - rec.mVisibleLayerIDs << layerID; // only use valid layer IDs + rec.mVisibleLayerIds << layerID; // only use valid layer IDs if ( visPresetLayerElem.hasAttribute( "style" ) ) rec.mPerLayerCurrentStyle[layerID] = visPresetLayerElem.attribute( "style" ); } @@ -229,26 +229,26 @@ void QgsMapThemeCollection::readXml( const QDomDocument& doc ) checkedLegendNodesElem = checkedLegendNodesElem.nextSiblingElement( "checked-legend-nodes" ); } - mPresets.insert( presetName, rec ); + mMapThemes.insert( presetName, rec ); visPresetElem = visPresetElem.nextSiblingElement( "visibility-preset" ); } reconnectToLayersStyleManager(); - emit presetsChanged(); + emit mapThemesChanged(); } void QgsMapThemeCollection::writeXml( QDomDocument& doc ) { QDomElement visPresetsElem = doc.createElement( "visibility-presets" ); - PresetRecordMap::const_iterator it = mPresets.constBegin(); - for ( ; it != mPresets.constEnd(); ++ it ) + MapThemeRecordMap::const_iterator it = mMapThemes.constBegin(); + for ( ; it != mMapThemes.constEnd(); ++ it ) { QString grpName = it.key(); - const PresetRecord& rec = it.value(); + const MapThemeRecord& rec = it.value(); QDomElement visPresetElem = doc.createElement( "visibility-preset" ); visPresetElem.setAttribute( "name", grpName ); - Q_FOREACH ( const QString& layerID, rec.mVisibleLayerIDs ) + Q_FOREACH ( const QString& layerID, rec.mVisibleLayerIds ) { QDomElement layerElem = doc.createElement( "layer" ); layerElem.setAttribute( "id", layerID ); @@ -282,16 +282,16 @@ void QgsMapThemeCollection::registryLayersRemoved( const QStringList& layerIDs ) { Q_FOREACH ( const QString& layerID, layerIDs ) { - PresetRecordMap::iterator it = mPresets.begin(); - for ( ; it != mPresets.end(); ++it ) + MapThemeRecordMap::iterator it = mMapThemes.begin(); + for ( ; it != mMapThemes.end(); ++it ) { - PresetRecord& rec = it.value(); - rec.mVisibleLayerIDs.removeAll( layerID ); + MapThemeRecord& rec = it.value(); + rec.mVisibleLayerIds.removeAll( layerID ); rec.mPerLayerCheckedLegendSymbols.remove( layerID ); rec.mPerLayerCurrentStyle.remove( layerID ); } } - emit presetsChanged(); + emit mapThemesChanged(); } void QgsMapThemeCollection::layerStyleRenamed( const QString& oldName, const QString& newName ) @@ -302,10 +302,10 @@ void QgsMapThemeCollection::layerStyleRenamed( const QString& oldName, const QSt QString layerID = styleMgr->layer()->id(); - PresetRecordMap::iterator it = mPresets.begin(); - for ( ; it != mPresets.end(); ++it ) + MapThemeRecordMap::iterator it = mMapThemes.begin(); + for ( ; it != mMapThemes.end(); ++it ) { - PresetRecord& rec = it.value(); + MapThemeRecord& rec = it.value(); if ( rec.mPerLayerCurrentStyle.contains( layerID ) ) { @@ -314,5 +314,35 @@ void QgsMapThemeCollection::layerStyleRenamed( const QString& oldName, const QSt rec.mPerLayerCurrentStyle[layerID] = newName; } } - emit presetsChanged(); + emit mapThemesChanged(); +} + +QStringList QgsMapThemeCollection::MapThemeRecord::visibleLayerIds() const +{ + return mVisibleLayerIds; +} + +void QgsMapThemeCollection::MapThemeRecord::setVisibleLayerIds( const QStringList& visibleLayerIds ) +{ + mVisibleLayerIds = visibleLayerIds; +} + +QMap > QgsMapThemeCollection::MapThemeRecord::perLayerCheckedLegendSymbols() const +{ + return mPerLayerCheckedLegendSymbols; +} + +void QgsMapThemeCollection::MapThemeRecord::setPerLayerCheckedLegendSymbols( const QMap >& perLayerCheckedLegendSymbols ) +{ + mPerLayerCheckedLegendSymbols = perLayerCheckedLegendSymbols; +} + +QMap QgsMapThemeCollection::MapThemeRecord::perLayerCurrentStyle() const +{ + return mPerLayerCurrentStyle; +} + +void QgsMapThemeCollection::MapThemeRecord::setPerLayerCurrentStyle( const QMap& perLayerCurrentStyle ) +{ + mPerLayerCurrentStyle = perLayerCurrentStyle; } diff --git a/src/core/qgsmapthemecollection.h b/src/core/qgsmapthemecollection.h index ddb02ae9bf3..b203f38f42c 100644 --- a/src/core/qgsmapthemecollection.h +++ b/src/core/qgsmapthemecollection.h @@ -37,134 +37,193 @@ class CORE_EXPORT QgsMapThemeCollection : public QObject { Q_OBJECT + Q_PROPERTY( QStringList mapThemes READ mapThemes NOTIFY mapThemesChanged ) + public: - /** \ingroup core - * Individual preset record of visible layers and styles. + /** + * \ingroup core + * Individual map theme record of visible layers and styles. + * + * @note Added in QGIS 3.0, Previously called PresetRecord */ - class PresetRecord + class MapThemeRecord { public: - bool operator==( const PresetRecord& other ) const + bool operator==( const MapThemeRecord& other ) const { - return mVisibleLayerIDs.toSet() == other.mVisibleLayerIDs.toSet() + return mVisibleLayerIds.toSet() == other.mVisibleLayerIds.toSet() && mPerLayerCheckedLegendSymbols == other.mPerLayerCheckedLegendSymbols && mPerLayerCurrentStyle == other.mPerLayerCurrentStyle; } - bool operator!=( const PresetRecord& other ) const + bool operator!=( const MapThemeRecord& other ) const { return !( *this == other ); } - //! Ordered list of layers that are visible - QStringList mVisibleLayerIDs; - /** For layers that have checkable legend symbols and not all symbols are checked - list which ones are - * @note not available in Python bindings + /** + * Ordered list of visible layers + * @note Added in QGIS 3.0 */ + QStringList visibleLayerIds() const; + + /** + * Ordered list of visible layers + * @note Added in QGIS 3.0 + */ + void setVisibleLayerIds( const QStringList& visibleLayerIds ); + + /** + * Lists which legend symbols are checked for layers which support this and where + * not all symbols are checked. + * @note not available in Python bindings + * @note Added in QGIS 3.0 + */ + QMap > perLayerCheckedLegendSymbols() const; + + /** + * Lists which legend symbols are checked for layers which support this and where + * not all symbols are checked. + * @note not available in Python bindings + * @note Added in QGIS 3.0 + */ + void setPerLayerCheckedLegendSymbols( const QMap >& perLayerCheckedLegendSymbols ); + + /** + * The currently used style name for layers with multiple styles. + * The map has layer ids as keys and style names as values. + * @note Added in QGIS 3.0 + */ + QMap perLayerCurrentStyle() const; + + /** + * The currently used style name for layers with multiple styles. + * The map has layer ids as keys and style names as values. + * @note Added in QGIS 3.0 + */ + void setPerLayerCurrentStyle( const QMap& perLayerCurrentStyle ); + + private: + QStringList mVisibleLayerIds; QMap > mPerLayerCheckedLegendSymbols; - //! For layers that use multiple styles - which one is currently selected QMap mPerLayerCurrentStyle; + + friend class QgsMapThemeCollection; }; QgsMapThemeCollection(); - /** Returns whether a preset with a matching name exists. - * @param name name of preset to check - * @returns true if preset exists + /** + * Returns whether a map theme with a matching name exists. + * @note Added in QGIS 3.0 */ - bool hasPreset( const QString& name ) const; + bool hasMapTheme( const QString& name ) const; - /** Inserts a new preset to the collection. - * @param name name of preset - * @param state preset record + /** + * Inserts a new map theme to the collection. * @see update() */ - void insert( const QString& name, const PresetRecord& state ); + void insert( const QString& name, const MapThemeRecord& state ); - /** Updates a preset within the collection. - * @param name name of preset to update - * @param state preset record to replace existing preset + /** + * Updates a map theme within the collection. + * @param name name of map theme to update + * @param state map theme record to replace existing map theme * @see insert() */ - void update( const QString& name, const PresetRecord& state ); + void update( const QString& name, const MapThemeRecord& state ); - /** Remove existing preset from collection. - * @param name preset name + /** + * Remove an existing map theme from collection. + * @note Added in QGIS 3.0 */ - void removePreset( const QString& name ); + void removeMapTheme( const QString& name ); - //! Remove all presets from the collection. + //! Remove all map themes from the collection. void clear(); - //! Returns a list of existing preset names. - QStringList presets() const; - - /** Returns the recorded state of a preset. - * @param name name of preset + /** + * Returns a list of existing map theme names. + * @note Added in QGIS 3.0 */ - PresetRecord presetState( const QString& name ) const { return mPresets[name]; } + QStringList mapThemes() const; - /** Returns the list of layer IDs that should be visible for the specified preset. + /** + * Returns the recorded state of a map theme. + * @note Added in QGIS 3.0 + */ + MapThemeRecord mapThemeState( const QString& name ) const { return mMapThemes[name]; } + + /** + * Returns the list of layer IDs that are visible for the specified map theme. + * * @note The order of the returned list is not guaranteed to reflect the order of layers * in the canvas. - * @param name preset name + * @note Added in QGIS 3.0 */ - QStringList presetVisibleLayers( const QString& name ) const; + QStringList mapThemeVisibleLayers( const QString& name ) const; - /** Apply check states of legend nodes of a given layer as defined in the preset. - * @param name preset name - * @param layerID layer ID + /** + * Apply check states of legend nodes of a given layer as defined in the map theme. + * @note Added in QGIS 3.0 */ - void applyPresetCheckedLegendNodesToLayer( const QString& name, const QString& layerID ); + void applyMapThemeCheckedLegendNodesToLayer( const QString& name, const QString& layerID ); - /** Get layer style overrides (for QgsMapSettings) of the visible layers for given preset. - * @param name preset name + /** + * Get layer style overrides (for QgsMapSettings) of the visible layers for given map theme. + * @note Added in QGIS 3.0 */ - QMap presetStyleOverrides( const QString& name ); + QMap mapThemeStyleOverride( const QString& name ); - /** Reads the preset collection state from XML + /** + * Reads the map theme collection state from XML * @param doc DOM document * @see writeXml */ void readXml( const QDomDocument& doc ); - /** Writes the preset collection state to XML. + /** Writes the map theme collection state to XML. * @param doc DOM document * @see readXml */ void writeXml( QDomDocument& doc ); - /** Static method for adding visible layers from a layer tree group to a preset + /** + * Static method for adding visible layers from a layer tree group to a map theme * record. * @param parent layer tree group parent - * @param rec preset record to amend + * @param rec map theme record to amend */ - static void addVisibleLayersToPreset( QgsLayerTreeGroup* parent, PresetRecord& rec ); + static void addVisibleLayersToMapTheme( QgsLayerTreeGroup* parent, MapThemeRecord& rec ); signals: - /** Emitted when presets within the collection are changed. + /** + * Emitted when map themes within the collection are changed. + * @note Added in QGIS 3.0 */ - void presetsChanged(); + void mapThemesChanged(); - protected slots: + private slots: - /** Handles updates of the preset collection when layers are removed from the registry + /** + * Handles updates of the map theme collection when layers are removed from the registry */ void registryLayersRemoved( const QStringList& layerIDs ); //! Update style name if a stored style gets renamed void layerStyleRenamed( const QString& oldName, const QString& newName ); - protected: + private: - /** Reconnects all preset layers to handle style renames + /** + * Reconnects all map theme layers to handle style renames */ void reconnectToLayersStyleManager(); - typedef QMap PresetRecordMap; - PresetRecordMap mPresets; + typedef QMap MapThemeRecordMap; + MapThemeRecordMap mMapThemes; }; diff --git a/src/core/qgsproject.cpp b/src/core/qgsproject.cpp index 04d3f84c722..48cbfb9f660 100644 --- a/src/core/qgsproject.cpp +++ b/src/core/qgsproject.cpp @@ -480,7 +480,7 @@ void QgsProject::clear() mEmbeddedLayers.clear(); mRelationManager->clear(); - mVisibilityPresetCollection.reset( new QgsMapThemeCollection() ); + mMapThemeCollection.reset( new QgsMapThemeCollection() ); mRootGroup->removeAllChildren(); @@ -916,8 +916,8 @@ bool QgsProject::read() mRootGroup->removeCustomProperty( "loading" ); - mVisibilityPresetCollection.reset( new QgsMapThemeCollection() ); - mVisibilityPresetCollection->readXml( *doc ); + mMapThemeCollection.reset( new QgsMapThemeCollection() ); + mMapThemeCollection->readXml( *doc ); // reassign change dependencies now that all layers are loaded QMap existingMaps = QgsMapLayerRegistry::instance()->mapLayers(); @@ -1203,7 +1203,7 @@ bool QgsProject::write() imp_->properties_.writeXml( "properties", qgisNode, *doc ); } - mVisibilityPresetCollection->writeXml( *doc ); + mMapThemeCollection->writeXml( *doc ); // now wrap it up and ship it to the project file doc->normalize(); // XXX I'm not entirely sure what this does @@ -2195,7 +2195,7 @@ QgsLayerTreeGroup *QgsProject::layerTreeRoot() const QgsMapThemeCollection* QgsProject::mapThemeCollection() { - return mVisibilityPresetCollection.data(); + return mMapThemeCollection.data(); } void QgsProject::setNonIdentifiableLayers( QList layers ) diff --git a/src/core/qgsproject.h b/src/core/qgsproject.h index b912b753290..5905fba5868 100644 --- a/src/core/qgsproject.h +++ b/src/core/qgsproject.h @@ -76,6 +76,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera Q_PROPERTY( QString fileName READ fileName WRITE setFileName NOTIFY fileNameChanged ) Q_PROPERTY( QString homePath READ homePath NOTIFY homePathChanged ) Q_PROPERTY( QgsCoordinateReferenceSystem crs READ crs WRITE setCrs ) + Q_PROPERTY( QgsMapThemeCollection* mapThemeCollection READ mapThemeCollection ) public: @@ -615,7 +616,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera //! map of transaction group: QPair( providerKey, connString ) -> transactionGroup QMap< QPair< QString, QString>, QgsTransactionGroup*> mTransactionGroups; - QScopedPointer mVisibilityPresetCollection; + QScopedPointer mMapThemeCollection; }; diff --git a/tests/src/core/testqgscomposermap.cpp b/tests/src/core/testqgscomposermap.cpp index 4a6df1b01ec..8bbfe727d05 100644 --- a/tests/src/core/testqgscomposermap.cpp +++ b/tests/src/core/testqgscomposermap.cpp @@ -349,9 +349,8 @@ void TestQgsComposerMap::dataDefinedStyles() mComposerMap->setFrameEnabled( true ); mComposition->addComposerMap( mComposerMap ); - QgsMapThemeCollection::PresetRecord rec; - rec.mVisibleLayerIDs << mPointsLayer->id(); - rec.mVisibleLayerIDs << mLinesLayer->id(); + QgsMapThemeCollection::MapThemeRecord rec; + rec.setVisibleLayerIds( QStringList() << mPointsLayer->id() << mLinesLayer->id() ); QgsProject::instance()->mapThemeCollection()->insert( "test preset", rec );