diff --git a/python/core/core_auto.sip b/python/core/core_auto.sip index a3ac0746017..981702a00ec 100644 --- a/python/core/core_auto.sip +++ b/python/core/core_auto.sip @@ -352,7 +352,6 @@ %Include auto_generated/qgssnappingconfig.sip %Include auto_generated/qgstaskmanager.sip %Include auto_generated/qgstolerance.sip -%Include auto_generated/qgstranslationcontext.sip %Include auto_generated/qgstrackedvectorlayertools.sip %Include auto_generated/qgstransaction.sip %Include auto_generated/qgstransactiongroup.sip @@ -367,6 +366,7 @@ %Include auto_generated/qgsvectorlayertools.sip %Include auto_generated/qgsvectorsimplifymethod.sip %Include auto_generated/qgssettings.sip +%Include auto_generated/qgsprojecttranslator.sip %Include auto_generated/annotations/qgsannotation.sip %Include auto_generated/annotations/qgsannotationmanager.sip %Include auto_generated/annotations/qgshtmlannotation.sip @@ -442,4 +442,5 @@ %Include auto_generated/layertree/qgslayertreeregistrybridge.sip %Include auto_generated/qgsuserprofilemanager.sip %Include auto_generated/symbology/qgsarrowsymbollayer.sip +%Include auto_generated/qgstranslationcontext.sip %Include auto_generated/qgsuserprofile.sip diff --git a/src/app/qgsprojectproperties.cpp b/src/app/qgsprojectproperties.cpp index 71f34b6ca09..e302ca39122 100644 --- a/src/app/qgsprojectproperties.cpp +++ b/src/app/qgsprojectproperties.cpp @@ -831,24 +831,23 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa connect( titleEdit, &QLineEdit::textChanged, mMetadataWidget, &QgsMetadataWidget::setTitle ); //fill ts language checkbox - //could possibly be taken from QgsOptions - QString myI18nPath = QgsApplication::i18nPath(); - QDir myDir( myI18nPath, QStringLiteral( "qgis*.qm" ) ); - QStringList myFileList = myDir.entryList(); - QStringListIterator myIterator( myFileList ); - while ( myIterator.hasNext() ) + //fill ts language checkbox + QString i18nPath = QgsApplication::i18nPath(); + QDir i18Dir( i18nPath, QStringLiteral( "qgis*.qm" ) ); + const QStringList qmFileList = i18Dir.entryList(); + for ( const QString &qmFile : qmFileList ) { - QString myFileName = myIterator.next(); - // Ignore the 'en' translation file, already added as 'en_US'. - if ( myFileName.compare( QLatin1String( "qgis_en.qm" ) ) == 0 ) continue; + if ( qmFile.compare( QLatin1String( "qgis_en.qm" ) ) == 0 ) continue; - QString l = myFileName.remove( QStringLiteral( "qgis_" ) ).remove( QStringLiteral( ".qm" ) ); + QString qmFileName = qmFile; + QString l = qmFileName.remove( QStringLiteral( "qgis_" ) ).remove( QStringLiteral( ".qm" ) ); // QTBUG-57802: eo locale is improperly handled QString displayName = l.startsWith( QLatin1String( "eo" ) ) ? QLocale::languageToString( QLocale::Esperanto ) : QLocale( l ).nativeLanguageName(); cbtsLocale->addItem( QIcon( QString( ":/images/flags/%1.svg" ).arg( l ) ), displayName, l ); } + cbtsLocale->addItem( QIcon( QString( ":/images/flags/%1.svg" ).arg( QStringLiteral( "en_US" ) ) ), QLocale( QStringLiteral( "en_US" ) ).nativeLanguageName(), QStringLiteral( "en_US" ) ); cbtsLocale->setCurrentIndex( cbtsLocale->findData( settings.value( QStringLiteral( "locale/userLocale" ), QString() ).toString() ) ); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4fa40e3d88b..85edd65aeb2 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -657,6 +657,7 @@ SET(QGIS_CORE_MOC_HDRS qgswebpage.h qgswebview.h qgssettings.h + qgsprojecttranslator.h annotations/qgsannotation.h annotations/qgsannotationmanager.h diff --git a/src/core/layertree/qgslayertreegroup.cpp b/src/core/layertree/qgslayertreegroup.cpp index 80f61e6fc0b..31343107c47 100644 --- a/src/core/layertree/qgslayertreegroup.cpp +++ b/src/core/layertree/qgslayertreegroup.cpp @@ -255,7 +255,8 @@ QgsLayerTreeGroup *QgsLayerTreeGroup::findGroup( const QString &name ) QList QgsLayerTreeGroup::findGroups() const { QList list; - Q_FOREACH ( QgsLayerTreeNode *child, mChildren ) + + for ( QgsLayerTreeNode *child : mChildren ) { if ( QgsLayerTree::isGroup( child ) ) list << QgsLayerTree::toGroup( child ); diff --git a/src/core/layertree/qgslayertreenode.cpp b/src/core/layertree/qgslayertreenode.cpp index ec7ab4cd0d6..1a49e066926 100644 --- a/src/core/layertree/qgslayertreenode.cpp +++ b/src/core/layertree/qgslayertreenode.cpp @@ -65,6 +65,7 @@ QgsLayerTreeNode *QgsLayerTreeNode::readXml( QDomElement &element, const QgsProj if ( project ) resolver = project->pathResolver(); context.setPathResolver( resolver ); + context.setProjectTranslator( ( QgsProject * )project ); QgsLayerTreeNode *node = readXml( element, context ); if ( node ) diff --git a/src/core/layout/qgscompositionconverter.cpp b/src/core/layout/qgscompositionconverter.cpp index 16cbdeb1c78..122f641ef23 100644 --- a/src/core/layout/qgscompositionconverter.cpp +++ b/src/core/layout/qgscompositionconverter.cpp @@ -1193,6 +1193,7 @@ bool QgsCompositionConverter::readLegendXml( QgsLayoutItemLegend *layoutItem, co pathResolver = project->pathResolver(); QgsReadWriteContext context; context.setPathResolver( pathResolver ); + context.setProjectTranslator( ( QgsProject * )project ); //composer map: use uuid QString mapId = itemElem.attribute( QStringLiteral( "map" ), QStringLiteral( "-1" ) ); diff --git a/src/core/qgslayerdefinition.cpp b/src/core/qgslayerdefinition.cpp index 5d7bd48d0a7..83917a4c8a4 100644 --- a/src/core/qgslayerdefinition.cpp +++ b/src/core/qgslayerdefinition.cpp @@ -51,6 +51,7 @@ bool QgsLayerDefinition::loadLayerDefinition( const QString &path, QgsProject *p QgsReadWriteContext context; context.setPathResolver( QgsPathResolver( path ) ); + context.setProjectTranslator( project ); return loadLayerDefinition( doc, project, rootGroup, errorMessage, context ); } @@ -298,6 +299,7 @@ QList QgsLayerDefinition::loadLayerDefinitionLayers( const QStrin QgsReadWriteContext context; context.setPathResolver( QgsPathResolver( qlrfile ) ); + //no projecttranslator defined here return QgsLayerDefinition::loadLayerDefinitionLayers( doc, context ); } diff --git a/src/core/qgsproject.cpp b/src/core/qgsproject.cpp index cc3789b65ce..5013dce7c53 100644 --- a/src/core/qgsproject.cpp +++ b/src/core/qgsproject.cpp @@ -861,6 +861,7 @@ bool QgsProject::_getMapLayers( const QDomDocument &doc, QList &broken { QgsReadWriteContext context; context.setPathResolver( pathResolver() ); + context.setProjectTranslator( this ); if ( !addLayer( element, brokenNodes, context ) ) { returnStatus = false; @@ -960,6 +961,7 @@ bool QgsProject::read() } QgsReadWriteContext context; + context.setProjectTranslator( this ); if ( !storage->readProject( filename, &inDevice, context ) ) { QString err = tr( "Unable to open %1" ).arg( filename ); @@ -1107,6 +1109,7 @@ bool QgsProject::readProjectFile( const QString &filename ) QgsReadWriteContext context; context.setPathResolver( pathResolver() ); + context.setProjectTranslator( this ); //crs QgsCoordinateReferenceSystem projectCrs; @@ -1302,7 +1305,7 @@ bool QgsProject::readProjectFile( const QString &filename ) emit ellipsoidChanged( ellipsoid() ); // read the project: used by map canvas and legend - emit readProject( *doc ); + emit readProject( *doc, context ); emit snappingConfigChanged( mSnappingConfig ); // if all went well, we're allegedly in pristine state @@ -1537,6 +1540,7 @@ bool QgsProject::readLayer( const QDomNode &layerNode ) { QgsReadWriteContext context; context.setPathResolver( pathResolver() ); + context.setProjectTranslator( this ); QList brokenNodes; if ( addLayer( layerNode.toElement(), brokenNodes, context ) ) { @@ -2151,6 +2155,7 @@ bool QgsProject::createEmbeddedLayer( const QString &layerId, const QString &pro QgsReadWriteContext embeddedContext; if ( !useAbsolutePaths ) embeddedContext.setPathResolver( QgsPathResolver( projectFilePath ) ); + embeddedContext.setProjectTranslator( this ); QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral( "projectlayers" ) ); if ( projectLayersElem.isNull() ) @@ -2207,6 +2212,7 @@ QgsLayerTreeGroup *QgsProject::createEmbeddedGroup( const QString &groupName, co QgsReadWriteContext context; context.setPathResolver( pathResolver() ); + context.setProjectTranslator( this ); // store identify disabled layers of the embedded project QSet embeddedIdentifyDisabledLayers; diff --git a/src/core/qgsproject.h b/src/core/qgsproject.h index 4da9f8945a8..dcab7e0fe64 100644 --- a/src/core/qgsproject.h +++ b/src/core/qgsproject.h @@ -997,7 +997,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera /** * Emitted when a project is being read. */ - void readProject( const QDomDocument & ); + void readProject( const QDomDocument &, QgsReadWriteContext &context ); /** * Emitted when the project is being written. diff --git a/src/core/qgsprojecttranslator.h b/src/core/qgsprojecttranslator.h index e87c3a6633d..2274204a3b8 100644 --- a/src/core/qgsprojecttranslator.h +++ b/src/core/qgsprojecttranslator.h @@ -37,6 +37,7 @@ class CORE_EXPORT QgsProjectTranslator * * \since QGIS 3.4 */ + virtual QString translate( const QString &context, const QString &sourceText, const char *disambiguation = nullptr, int n = -1 ) const = 0; virtual ~QgsProjectTranslator() = default; diff --git a/src/core/qgsreadwritecontext.cpp b/src/core/qgsreadwritecontext.cpp index 4baa772c16e..7d2d2713a0a 100644 --- a/src/core/qgsreadwritecontext.cpp +++ b/src/core/qgsreadwritecontext.cpp @@ -14,6 +14,12 @@ ***************************************************************************/ #include "qgsreadwritecontext.h" +QgsReadWriteContext::QgsReadWriteContext() + : mProjectTranslator( &mDefaultTranslator ) +{ + +} + QgsReadWriteContext::~QgsReadWriteContext() { // be sure that categories have been emptied @@ -50,9 +56,22 @@ void QgsReadWriteContext::leaveCategory() mCategories.pop_back(); } +void QgsReadWriteContext::setProjectTranslator( QgsProjectTranslator *projectTranslator ) +{ + mProjectTranslator = projectTranslator; +} + QList QgsReadWriteContext::takeMessages() { QList messages = mMessages; mMessages.clear(); return messages; } + +QString QgsReadWriteContext::DefaultTranslator::translate( const QString &context, const QString &sourceText, const char *disambiguation, int n ) const +{ + Q_UNUSED( context ); + Q_UNUSED( disambiguation ); + Q_UNUSED( n ); + return sourceText; +} diff --git a/src/core/qgsreadwritecontext.h b/src/core/qgsreadwritecontext.h index b22c852484d..dee76979ecc 100644 --- a/src/core/qgsreadwritecontext.h +++ b/src/core/qgsreadwritecontext.h @@ -65,7 +65,7 @@ class CORE_EXPORT QgsReadWriteContext /** * Constructor for QgsReadWriteContext. */ - QgsReadWriteContext() = default; + QgsReadWriteContext(); ~QgsReadWriteContext(); @@ -106,7 +106,17 @@ class CORE_EXPORT QgsReadWriteContext */ const QgsProjectTranslator *projectTranslator( ) const { return mProjectTranslator; } + void setProjectTranslator( QgsProjectTranslator *projectTranslator ); + private: + + class DefaultTranslator : public QgsProjectTranslator + { + // QgsProjectTranslator interface + public: + QString translate( const QString &context, const QString &sourceText, const char *disambiguation, int n ) const; + }; + //! Pop the last category void leaveCategory(); @@ -114,8 +124,8 @@ class CORE_EXPORT QgsReadWriteContext QList mMessages; QStringList mCategories = QStringList(); QgsProjectTranslator *mProjectTranslator; - friend class QgsReadWriteContextCategoryPopper; + DefaultTranslator mDefaultTranslator; }; diff --git a/src/core/qgsrelation.cpp b/src/core/qgsrelation.cpp index 6af6c7a270c..ea761fdbb79 100644 --- a/src/core/qgsrelation.cpp +++ b/src/core/qgsrelation.cpp @@ -21,7 +21,7 @@ #include "qgsproject.h" #include "qgsvectorlayer.h" -QgsRelation QgsRelation::createFromXml( const QDomNode &node ) +QgsRelation QgsRelation::createFromXml( const QDomNode &node, QgsReadWriteContext &context ) { QDomElement elem = node.toElement(); @@ -35,7 +35,7 @@ QgsRelation QgsRelation::createFromXml( const QDomNode &node ) QString referencingLayerId = elem.attribute( QStringLiteral( "referencingLayer" ) ); QString referencedLayerId = elem.attribute( QStringLiteral( "referencedLayer" ) ); QString id = elem.attribute( QStringLiteral( "id" ) ); - QString name = QgsProject::instance()->translate( QStringLiteral( "project:relations" ), elem.attribute( QStringLiteral( "name" ) ) ); + QString name = context.projectTranslator()->translate( QStringLiteral( "project:relations" ), elem.attribute( QStringLiteral( "name" ) ) ); QString strength = elem.attribute( QStringLiteral( "strength" ) ); const QMap &mapLayers = QgsProject::instance()->mapLayers(); diff --git a/src/core/qgsrelation.h b/src/core/qgsrelation.h index b50ac6aaf17..a61fe2e2175 100644 --- a/src/core/qgsrelation.h +++ b/src/core/qgsrelation.h @@ -22,6 +22,7 @@ #include "qgis_core.h" #include "qgsfields.h" +#include "qgsreadwritecontext.h" #include "qgis.h" @@ -100,7 +101,7 @@ class CORE_EXPORT QgsRelation * * \returns A relation */ - static QgsRelation createFromXml( const QDomNode &node ); + static QgsRelation createFromXml( const QDomNode &node, QgsReadWriteContext &context ); /** * Writes a relation to an XML structure. Used for saving .qgs projects diff --git a/src/core/qgsrelationmanager.cpp b/src/core/qgsrelationmanager.cpp index a0c6c722d24..81ca4b2e83a 100644 --- a/src/core/qgsrelationmanager.cpp +++ b/src/core/qgsrelationmanager.cpp @@ -153,7 +153,7 @@ QList QgsRelationManager::referencedRelations( QgsVectorLayer *laye return relations; } -void QgsRelationManager::readProject( const QDomDocument &doc ) +void QgsRelationManager::readProject( const QDomDocument &doc, QgsReadWriteContext &context ) { mRelations.clear(); @@ -165,7 +165,7 @@ void QgsRelationManager::readProject( const QDomDocument &doc ) int relCount = relationNodes.count(); for ( int i = 0; i < relCount; ++i ) { - addRelation( QgsRelation::createFromXml( relationNodes.at( i ) ) ); + addRelation( QgsRelation::createFromXml( relationNodes.at( i ), context ) ); } } else diff --git a/src/core/qgsrelationmanager.h b/src/core/qgsrelationmanager.h index ac37a1d2e8c..9dfabf74c60 100644 --- a/src/core/qgsrelationmanager.h +++ b/src/core/qgsrelationmanager.h @@ -142,7 +142,7 @@ class CORE_EXPORT QgsRelationManager : public QObject void changed(); private slots: - void readProject( const QDomDocument &doc ); + void readProject( const QDomDocument &doc, QgsReadWriteContext &context ); void writeProject( QDomDocument &doc ); void layersRemoved( const QStringList &layers ); diff --git a/src/core/qgstranslationcontext.cpp b/src/core/qgstranslationcontext.cpp index a39ca93635f..4e98848be5e 100644 --- a/src/core/qgstranslationcontext.cpp +++ b/src/core/qgstranslationcontext.cpp @@ -65,7 +65,7 @@ void QgsTranslationContext::writeTsFile( const QString &locale ) tsElement.setAttribute( QStringLiteral( "sourcelanguage" ), settings.value( QStringLiteral( "locale/userLocale" ), "" ).toString() ); doc.appendChild( tsElement ); - for ( TranslatableObject translatableObject : mTranslatableObjects ) + for ( const TranslatableObject &translatableObject : mTranslatableObjects ) { QDomElement contextElement = doc.createElement( QStringLiteral( "context" ) ); tsElement.appendChild( contextElement );