Merge pull request #33950 from DelazJ/renameMapTheme

[feature] Allow renaming of the current map theme
This commit is contained in:
Matthias Kuhn 2020-04-23 16:55:17 +02:00 committed by GitHub
commit 5d45b71421
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 144 additions and 4 deletions

View File

@ -186,14 +186,22 @@ Updates a map theme within the collection.
void removeMapTheme( const QString &name );
%Docstring
Remove an existing map theme from collection.
Removes an existing map theme from collection.
.. versionadded:: 3.0
%End
bool renameMapTheme( const QString &name, const QString &newName );
%Docstring
Renames the existing map theme called ``name`` to ``newName``.
Returns ``True`` if the rename was successful, or ``False`` if it failed (e.g. due to a duplicate name for ``newName``).
.. versionadded:: 3.14
%End
void clear();
%Docstring
Remove all map themes from the collection.
Removes all map themes from the collection.
%End
QStringList mapThemes() const;
@ -324,6 +332,13 @@ Emitted when map themes within the collection are changed.
Emitted when a map theme changes definition.
.. versionadded:: 3.0
%End
void mapThemeRenamed( const QString &name, const QString &newName );
%Docstring
Emitted when a map theme within the collection is renamed.
.. versionadded:: 3.14
%End
void projectChanged();

View File

@ -104,6 +104,7 @@ Qgs3DMapCanvasDockWidget::Qgs3DMapCanvasDockWidget( QWidget *parent )
// Map Theme Menu
mMapThemeMenu = new QMenu();
connect( mMapThemeMenu, &QMenu::aboutToShow, this, &Qgs3DMapCanvasDockWidget::mapThemeMenuAboutToShow );
connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemeRenamed, this, &Qgs3DMapCanvasDockWidget::currentMapThemeRenamed );
mBtnMapThemes = new QToolButton();
mBtnMapThemes->setAutoRaise( true );
@ -345,3 +346,11 @@ void Qgs3DMapCanvasDockWidget::mapThemeMenuAboutToShow()
}
mMapThemeMenu->addActions( mMapThemeMenuPresetActions );
}
void Qgs3DMapCanvasDockWidget::currentMapThemeRenamed( const QString &theme, const QString &newTheme )
{
if ( theme == mCanvas->map()->terrainMapTheme() )
{
mCanvas->map()->setTerrainMapTheme( newTheme );
}
}

View File

@ -65,6 +65,8 @@ class APP_EXPORT Qgs3DMapCanvasDockWidget : public QgsDockWidget
void onMainCanvasColorChanged();
void onTotalPendingJobsCountChanged();
void mapThemeMenuAboutToShow();
//! Renames the active map theme called \a theme to \a newTheme
void currentMapThemeRenamed( const QString &theme, const QString &newTheme );
private:
Qgs3DMapCanvas *mCanvas = nullptr;

View File

@ -227,6 +227,8 @@ QgsMapCanvasDockWidget::QgsMapCanvasDockWidget( const QString &name, QWidget *pa
if ( mSyncExtentRadio->isChecked() )
syncViewCenter( mMainCanvas );
} );
connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemeRenamed, this, &QgsMapCanvasDockWidget::currentMapThemeRenamed );
}
void QgsMapCanvasDockWidget::setMainCanvas( QgsMapCanvas *canvas )
@ -441,6 +443,14 @@ void QgsMapCanvasDockWidget::menuAboutToShow()
mMenu->addActions( mMenuPresetActions );
}
void QgsMapCanvasDockWidget::currentMapThemeRenamed( const QString &theme, const QString &newTheme )
{
if ( theme == mMapCanvas->theme() )
{
mMapCanvas->setTheme( newTheme );
}
}
void QgsMapCanvasDockWidget::settingsMenuAboutToShow()
{
whileBlocking( mActionShowAnnotations )->setChecked( mMapCanvas->annotationsVisible() );

View File

@ -157,6 +157,8 @@ class APP_EXPORT QgsMapCanvasDockWidget : public QgsDockWidget, private Ui::QgsM
void mapExtentChanged();
void mapCrsChanged();
void menuAboutToShow();
//! Renames the active map theme called \a theme to \a newTheme
void currentMapThemeRenamed( const QString &theme, const QString &newTheme );
void settingsMenuAboutToShow();
void syncMarker( const QgsPointXY &p );
void mapScaleChanged();

View File

@ -49,6 +49,7 @@ QgsMapThemes::QgsMapThemes()
mReplaceMenu = new QMenu( tr( "Replace Theme" ) );
mMenu->addMenu( mReplaceMenu );
mActionRenameCurrentPreset = mMenu->addAction( tr( "Rename Current Theme…" ), this, &QgsMapThemes::renameCurrentPreset );
mActionAddPreset = mMenu->addAction( tr( "Add Theme…" ), this, [ = ] { addPreset(); } );
mMenuSeparator = mMenu->addSeparator();
@ -140,6 +141,32 @@ void QgsMapThemes::applyState( const QString &presetName )
QgsProject::instance()->mapThemeCollection()->applyTheme( presetName, root, model );
}
void QgsMapThemes::renameCurrentPreset()
{
QgsMapThemeCollection::MapThemeRecord mapTheme = currentState();
QStringList existingNames = QgsProject::instance()->mapThemeCollection()->mapThemes();
for ( QAction *actionPreset : qgis::as_const( mMenuPresetActions ) )
{
if ( actionPreset->isChecked() )
{
QgsNewNameDialog dlg(
tr( "theme" ),
tr( "%1" ).arg( actionPreset->text() ),
QStringList(), existingNames, QRegExp(), Qt::CaseInsensitive, mMenu );
dlg.setWindowTitle( tr( "Rename Map Theme" ) );
dlg.setHintString( tr( "Enter the new name of the map theme" ) );
dlg.setOverwriteEnabled( false );
dlg.setConflictingNameWarning( tr( "A theme with this name already exists." ) );
if ( dlg.exec() != QDialog::Accepted || dlg.name().isEmpty() )
return;
QgsProject::instance()->mapThemeCollection()->renameMapTheme( actionPreset->text(), dlg.name() );
}
}
}
void QgsMapThemes::removeCurrentPreset()
{
for ( QAction *actionPreset : qgis::as_const( mMenuPresetActions ) )
@ -189,4 +216,5 @@ void QgsMapThemes::menuAboutToShow()
mActionAddPreset->setEnabled( !hasCurrent );
mActionRemoveCurrentPreset->setEnabled( hasCurrent );
mActionRenameCurrentPreset->setEnabled( hasCurrent );
}

View File

@ -65,6 +65,9 @@ class APP_EXPORT QgsMapThemes : public QObject
//! Handles removal of current preset from the project's collection
void removeCurrentPreset();
//! Handles renaming of the current map theme
void renameCurrentPreset();
//! Handles creation of preset menu
void menuAboutToShow();
@ -91,6 +94,7 @@ class APP_EXPORT QgsMapThemes : public QObject
QAction *mMenuSeparator = nullptr;
QAction *mActionAddPreset = nullptr;
QAction *mActionRemoveCurrentPreset = nullptr;
QAction *mActionRenameCurrentPreset = nullptr;
QList<QAction *> mMenuPresetActions;
QList<QAction *> mMenuReplaceActions;
};

View File

@ -1825,6 +1825,14 @@ void QgsLayoutItemMap::mapThemeChanged( const QString &theme )
mCachedLayerStyleOverridesPresetName.clear(); // force cache regeneration at next redraw
}
void QgsLayoutItemMap::currentMapThemeRenamed( const QString &theme, const QString &newTheme )
{
if ( theme == mFollowVisibilityPresetName )
{
mFollowVisibilityPresetName = newTheme;
}
}
void QgsLayoutItemMap::connectUpdateSlot()
{
//connect signal from layer registry to update in case of new or deleted layers
@ -1867,6 +1875,7 @@ void QgsLayoutItemMap::connectUpdateSlot()
} );
connect( project->mapThemeCollection(), &QgsMapThemeCollection::mapThemeChanged, this, &QgsLayoutItemMap::mapThemeChanged );
connect( project->mapThemeCollection(), &QgsMapThemeCollection::mapThemeRenamed, this, &QgsLayoutItemMap::currentMapThemeRenamed );
}
QTransform QgsLayoutItemMap::layoutToMapCoordsTransform() const

View File

@ -637,6 +637,9 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem, public QgsTemporalRan
void mapThemeChanged( const QString &theme );
//! Renames the active map theme called \a theme to \a newTheme
void currentMapThemeRenamed( const QString &theme, const QString &newTheme );
//! Create cache image
void recreateCachedImageInBackground();

View File

@ -281,6 +281,19 @@ void QgsMapThemeCollection::update( const QString &name, const MapThemeRecord &s
emit mapThemesChanged();
}
bool QgsMapThemeCollection::renameMapTheme( const QString &name, const QString &newName )
{
if ( !mMapThemes.contains( name ) || mMapThemes.contains( newName ) )
return false;
const MapThemeRecord state = mMapThemes[name];
const MapThemeRecord newState = state;
insert( newName, newState );
emit mapThemeRenamed( name, newName );
removeMapTheme( name );
return true;
}
void QgsMapThemeCollection::removeMapTheme( const QString &name )
{
if ( !mMapThemes.contains( name ) )

View File

@ -257,12 +257,19 @@ class CORE_EXPORT QgsMapThemeCollection : public QObject
void update( const QString &name, const QgsMapThemeCollection::MapThemeRecord &state );
/**
* Remove an existing map theme from collection.
* Removes an existing map theme from collection.
* \since QGIS 3.0
*/
void removeMapTheme( const QString &name );
//! Remove all map themes from the collection.
/**
* Renames the existing map theme called \a name to \a newName.
* Returns TRUE if the rename was successful, or FALSE if it failed (e.g. due to a duplicate name for \a newName).
* \since QGIS 3.14
*/
bool renameMapTheme( const QString &name, const QString &newName );
//! Removes all map themes from the collection.
void clear();
/**
@ -373,6 +380,12 @@ class CORE_EXPORT QgsMapThemeCollection : public QObject
*/
void mapThemeChanged( const QString &theme );
/**
* Emitted when a map theme within the collection is renamed.
* \since QGIS 3.14
*/
void mapThemeRenamed( const QString &name, const QString &newName );
/**
* Emitted when the project changes
*

View File

@ -138,6 +138,7 @@ QgsMapCanvas::QgsMapCanvas( QWidget *parent )
this, &QgsMapCanvas::writeProject );
connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemeChanged, this, &QgsMapCanvas::mapThemeChanged );
connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemeRenamed, this, &QgsMapCanvas::mapThemeRenamed );
connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemesChanged, this, &QgsMapCanvas::projectThemesChanged );
mSettings.setFlag( QgsMapSettings::DrawEditingInfo );
@ -615,6 +616,17 @@ void QgsMapCanvas::mapThemeChanged( const QString &theme )
}
}
void QgsMapCanvas::mapThemeRenamed( const QString &theme, const QString &newTheme )
{
if ( mTheme.isEmpty() || theme != mTheme )
{
return;
}
setTheme( newTheme );
refresh();
}
void QgsMapCanvas::rendererJobFinished()
{
QgsDebugMsgLevel( QStringLiteral( "CANVAS finish! %1" ).arg( !mJobCanceled ), 2 );

View File

@ -835,6 +835,8 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
void refreshMap();
void mapThemeChanged( const QString &theme );
//! Renames the active map theme called \a theme to \a newTheme
void mapThemeRenamed( const QString &theme, const QString &newTheme );
signals:

View File

@ -331,6 +331,24 @@ class TestQgsMapCanvas(unittest.TestCase):
# should be different - we should now render project layers
self.assertFalse(self.canvasImageCheck('theme4', 'theme4', canvas))
# set canvas to theme1
canvas.setTheme('theme1')
canvas.refresh()
canvas.waitWhileRendering()
self.assertEqual(canvas.theme(), 'theme1')
themeLayers = theme1.layerRecords()
# rename the active theme
QgsProject.instance().mapThemeCollection().renameMapTheme('theme1', 'theme5')
# canvas theme should now be set to theme5
canvas.refresh()
canvas.waitWhileRendering()
self.assertEqual(canvas.theme(), 'theme5')
# theme5 should render as theme1
theme5 = QgsProject.instance().mapThemeCollection().mapThemeState('theme5')
theme5Layers = theme5.layerRecords()
self.assertEqual(themeLayers, theme5Layers, 'themes are different')
#self.assertTrue(self.canvasImageCheck('theme5', 'theme5', canvas))
def canvasImageCheck(self, name, reference_image, canvas):
self.report += "<h2>Render {}</h2>\n".format(name)
temp_dir = QDir.tempPath() + '/'