Skip to content
Permalink
Browse files

working translation of project from qm file

Translated objects and tests included:
- [x] layer names
- [x] layer group names
- [x] relation names
- [x] attribute alias (if no alias, then the field translation)
- [x] forms group box titles
- [x] forms sub group box titles

included restructured with QTranslator object.

Updated test-data used for the test.
  • Loading branch information
signedav committed Aug 7, 2018
1 parent 628292b commit 1bccedd1d1b1260b340b862caa5859f1b40e715b
@@ -264,7 +264,7 @@ Write XML information
Serialize on project save
%End

QgsAttributeEditorElement *attributeEditorElementFromDomElement( QDomElement &elem, QgsAttributeEditorElement *parent, const QString &layerId = 0 );
QgsAttributeEditorElement *attributeEditorElementFromDomElement( QDomElement &elem, QgsAttributeEditorElement *parent );
%Docstring
Deserialize drag and drop designer elements.
%End
@@ -135,14 +135,6 @@ Returns last modified time of the project file as returned by the file system (o
Returns full absolute path to the project file if the project is stored in a file system - derived from fileName().
Returns empty string when the project is stored in a project storage (there is no concept of paths for custom project storages).

.. versionadded:: 3.2
%End

QString absolutePath() const;
%Docstring
Returns full absolute path to the project folder if the project is stored in a file system - derived from fileName().
Returns empty string when the project is stored in a project storage (there is no concept of paths for custom project storages).

.. versionadded:: 3.2
%End

@@ -991,25 +983,6 @@ and it is mainly a hint for the user interface to protect users from removing la
in the project. The removeMapLayer(), removeMapLayers() calls do not block removal of layers listed here.

.. versionadded:: 3.2
%End

void generateTsFile( const QString &locale );
%Docstring
Triggers the collection strings of .qgs to be included in ts file and calls writeTsFile()

.. versionadded:: 3.2
%End

QString translate( const QString &context, const QString &sourceText, const char *disambiguation = 0, int n = -1 );
%Docstring
Translates the project with QTranslator and qm file

:return: the result string (in case there is no QTranslator loaded the sourceText)

:param context: describing layer etc.
:param sourceText: is the identifier of this text
:param disambiguation: it's the disambiguation
:param n: if -1 uses the appropriate form
%End

signals:
@@ -1362,16 +1335,6 @@ home path will be automatically determined from the project's file path.
.. seealso:: :py:func:`homePathChanged`

.. versionadded:: 3.2
%End

void registerTranslatableObjects( QgsTranslationContext *translationContext );
%Docstring
Registers the translatable objects into the tranlationContext
so there can be created a ts file these values

.. versionadded:: 3.2

:param translationContext: where the objects will be registered
%End

};

This file was deleted.

@@ -5950,10 +5950,10 @@ void QgisApp::fileSaveAs()
return;

QFileInfo fullPath( path );

settings.setValue( QStringLiteral( "UI/lastProjectDir" ), fullPath.path() );

if ( filter == zipExt )

{
if ( fullPath.suffix().compare( QLatin1String( "qgz" ), Qt::CaseInsensitive ) != 0 )
fullPath.setFile( fullPath.filePath() + ".qgz" );
@@ -850,7 +850,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
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() ) );
cbtsLocale->setCurrentIndex( cbtsLocale->findData( settings.value( QStringLiteral( "locale/userLocale" ), QString() ).toString() ) );

connect( generateTsFileButton, &QPushButton::clicked, this, &QgsProjectProperties::generateTsFileButton_clicked );

@@ -37,7 +37,6 @@
#include "qgsrectangle.h"
#include "qgsrelationmanager.h"
#include "qgsannotationmanager.h"
#include "qgsvectorlayer.h"
#include "qgsvectorlayerjoininfo.h"
#include "qgsmapthemecollection.h"
#include "qgslayerdefinition.h"
@@ -367,9 +366,6 @@ QgsProject::QgsProject( QObject *parent )
connect( mLayerStore.get(), &QgsMapLayerStore::layersAdded, this, &QgsProject::layersAdded );
connect( mLayerStore.get(), &QgsMapLayerStore::layerWasAdded, this, &QgsProject::layerWasAdded );
connect( QgsApplication::instance(), &QgsApplication::requestForTranslatableObjects, this, &QgsProject::registerTranslatableObjects );

mTranslator = new QTranslator();

}


@@ -445,6 +441,24 @@ void QgsProject::setPresetHomePath( const QString &path )
setDirty( true );
}

void QgsProject::registerTranslatableContainers( QgsTranslationContext *translationContext, QgsAttributeEditorContainer *parent, const QString &layerId )
{
QList<QgsAttributeEditorElement *> elements = parent->children();

for ( QgsAttributeEditorElement *element : elements )
{
if ( element->type() == QgsAttributeEditorElement::AeTypeContainer )
{
QgsAttributeEditorContainer *container = dynamic_cast<QgsAttributeEditorContainer *>( element );

translationContext->registerTranslation( QStringLiteral( "project:layers:%1:formcontainers" ).arg( layerId ), container->name() );

if ( container->children().size() > 0 )
registerTranslatableContainers( translationContext, container, layerId );
}
}
}

void QgsProject::registerTranslatableObjects( QgsTranslationContext *translationContext )
{
//register layers
@@ -457,6 +471,7 @@ void QgsProject::registerTranslatableObjects( QgsTranslationContext *translation
{
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mapLayer );

//register aliases and fields
const QgsFields fields = vlayer->fields();
for ( const QgsField &field : fields )
{
@@ -465,6 +480,10 @@ void QgsProject::registerTranslatableObjects( QgsTranslationContext *translation
else
translationContext->registerTranslation( QStringLiteral( "project:layers:%1:fieldaliases" ).arg( vlayer->id() ), field.alias() );
}

//register formcontainers
registerTranslatableContainers( translationContext, vlayer->editFormConfig().invisibleRootContainer(), vlayer->id() );

}
}

@@ -931,10 +950,6 @@ bool QgsProject::read()
QString filename = mFile.fileName();
bool rc;

//dave dirty hack
delete mTranslator;
mTranslator = new QTranslator();

if ( QgsProjectStorage *storage = projectStorage() )
{
QTemporaryFile inDevice;
@@ -969,10 +984,15 @@ bool QgsProject::read()
}

//on translation we should not change the filename back
if ( mTranslator->isEmpty() )
if ( !mTranslator )
{
mFile.setFileName( filename );
}
else
{
//but delete the translator
delete mTranslator;
}

return rc;
}
@@ -988,6 +1008,7 @@ bool QgsProject::readProjectFile( const QString &filename )

if ( QFile( QStringLiteral( "%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
{
mTranslator = new QTranslator();
if ( mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() ) )
{
QgsDebugMsg( "Translation loaded" );
@@ -1290,7 +1311,7 @@ bool QgsProject::readProjectFile( const QString &filename )

emit nonIdentifiableLayersChanged( nonIdentifiableLayers() );

if ( !mTranslator->isEmpty() )
if ( mTranslator )
{
//project possibly translated -> rename it with locale postfix
QString newFileName( QStringLiteral( "%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
@@ -2800,7 +2821,7 @@ void QgsProject::generateTsFile( const QString &locale )

QString QgsProject::translate( const QString &context, const QString &sourceText, const char *disambiguation, int n )
{
if ( mTranslator->isEmpty() )
if ( !mTranslator )
{
return sourceText;
}
@@ -46,6 +46,7 @@
#include "qgsreadwritecontext.h"
#include "qgsprojectmetadata.h"
#include "qgstranslationcontext.h"
#include "qgsvectorlayer.h"

class QFileInfo;
class QDomDocument;
@@ -97,7 +98,6 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
Q_PROPERTY( QgsRelationManager *relationManager READ relationManager )
Q_PROPERTY( QList<QgsVectorLayer *> avoidIntersectionsLayers READ avoidIntersectionsLayers WRITE setAvoidIntersectionsLayers NOTIFY avoidIntersectionsLayersChanged )
Q_PROPERTY( QgsProjectMetadata metadata READ metadata WRITE setMetadata NOTIFY metadataChanged )
//dave to do Q_PROPERTY( QTranslator translator READ translator )

public:
//! Returns the QgsProject singleton instance
@@ -1296,6 +1296,16 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
*/
void setPresetHomePath( const QString &path );

/**
* Registers the translatable containers into the tranlationContext
* this is a rekursive function to get all the child containers
* \since QGIS 3.2
*
* \param translationContext where the objects will be registered
* \param parent parent-container containing list of children
*/
void registerTranslatableContainers( QgsTranslationContext *translationContext, QgsAttributeEditorContainer *parent, const QString &layerId );

/**
* Registers the translatable objects into the tranlationContext
* so there can be created a ts file these values
@@ -1907,15 +1907,15 @@ bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMes
if ( !aliasElem.attribute( QStringLiteral( "name" ) ).isEmpty() )
{
//if it has alias
alias = QgsProject::instance()->translate( QStringLiteral( "project:layers:%1:fieldaliases" ).arg( this->name() ), aliasElem.attribute( QStringLiteral( "name" ) ) );
QgsDebugMsgLevel( "context" + QStringLiteral( "project:layers:%1:fieldaliases" ).arg( this->name() ) + " source " + aliasElem.attribute( QStringLiteral( "name" ) ), 1 );
alias = QgsProject::instance()->translate( QStringLiteral( "project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral( "id" ) ).toElement().text() ), aliasElem.attribute( QStringLiteral( "name" ) ) );
QgsDebugMsgLevel( "context" + QStringLiteral( "project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral( "id" ) ).toElement().text() ) + " source " + aliasElem.attribute( QStringLiteral( "name" ) ), 1 );
}
else
{
//if it has no alias, but alias is should be the fields translation
alias = QgsProject::instance()->translate( QStringLiteral( "project:layers:%1:fieldaliases" ).arg( this->name() ), aliasElem.attribute( QStringLiteral( "name" ) ) );
QgsDebugMsgLevel( "context" + QStringLiteral( "project:layers:%1:fieldaliases" ).arg( this->name() ) + " source " + field, 1 );
//if it gets the exact field value, there has been no translation (no translation loaded);
//if it has no alias, it should be the fields translation
alias = QgsProject::instance()->translate( QStringLiteral( "project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral( "id" ) ).toElement().text() ), field );
QgsDebugMsgLevel( "context" + QStringLiteral( "project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral( "id" ) ).toElement().text() ) + " source " + field, 1 );
//if it gets the exact field value, there has been no translation (or not even translation loaded) - so no alias should be generated;
if ( alias == aliasElem.attribute( QStringLiteral( "field" ) ) )
alias.clear();
}

0 comments on commit 1bccedd

Please sign in to comment.
You can’t perform that action at this time.