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.
This commit is contained in:
signedav 2018-07-23 18:21:02 +02:00
parent 628292b974
commit 1bccedd1d1
11 changed files with 386 additions and 357 deletions

View File

@ -264,7 +264,7 @@ Write XML information
Serialize on project save Serialize on project save
%End %End
QgsAttributeEditorElement *attributeEditorElementFromDomElement( QDomElement &elem, QgsAttributeEditorElement *parent, const QString &layerId = 0 ); QgsAttributeEditorElement *attributeEditorElementFromDomElement( QDomElement &elem, QgsAttributeEditorElement *parent );
%Docstring %Docstring
Deserialize drag and drop designer elements. Deserialize drag and drop designer elements.
%End %End

View File

@ -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 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). 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 .. versionadded:: 3.2
%End %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. in the project. The removeMapLayer(), removeMapLayers() calls do not block removal of layers listed here.
.. versionadded:: 3.2 .. 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 %End
signals: signals:
@ -1362,16 +1335,6 @@ home path will be automatically determined from the project's file path.
.. seealso:: :py:func:`homePathChanged` .. seealso:: :py:func:`homePathChanged`
.. versionadded:: 3.2 .. 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 %End
}; };

View File

@ -1,79 +0,0 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgstranslationcontext.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsTranslationContext
{
%Docstring
used for the collecting of strings of .qgs to be translated and writing of ts file
.. versionadded:: 3.2
%End
%TypeHeaderCode
#include "qgstranslationcontext.h"
%End
public:
QgsTranslationContext( );
%Docstring
Constructor
%End
QgsProject *project() const;
%Docstring
Returns the project
.. seealso:: :py:func:`setProject`
%End
void setProject( QgsProject *project );
%Docstring
Sets the ``project`` where the translation need to be done for
.. seealso:: :py:func:`project`
%End
QString fileName() const;
%Docstring
Returns the TS fileName
.. seealso:: :py:func:`setFileName`
%End
void setFileName( const QString &fileName );
%Docstring
Sets the ``name`` of the TS file
.. seealso:: :py:func:`fileName`
%End
void registerTranslation( const QString &context, const QString &source );
%Docstring
Registers the ``string`` to be translated
:param translationString: name and path of the object need to be translated
:param layerName: the name of the layer
%End
void writeTsFile( const QString &locale );
%Docstring
Writes the Ts-file
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgstranslationcontext.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -5950,10 +5950,10 @@ void QgisApp::fileSaveAs()
return; return;
QFileInfo fullPath( path ); QFileInfo fullPath( path );
settings.setValue( QStringLiteral( "UI/lastProjectDir" ), fullPath.path() ); settings.setValue( QStringLiteral( "UI/lastProjectDir" ), fullPath.path() );
if ( filter == zipExt ) if ( filter == zipExt )
{ {
if ( fullPath.suffix().compare( QLatin1String( "qgz" ), Qt::CaseInsensitive ) != 0 ) if ( fullPath.suffix().compare( QLatin1String( "qgz" ), Qt::CaseInsensitive ) != 0 )
fullPath.setFile( fullPath.filePath() + ".qgz" ); fullPath.setFile( fullPath.filePath() + ".qgz" );

View File

@ -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( l ) ), displayName, l );
} }
cbtsLocale->addItem( QIcon( QString( ":/images/flags/%1.svg" ).arg( QStringLiteral( "en_US" ) ) ), QLocale( QStringLiteral( "en_US" ) ).nativeLanguageName(), QStringLiteral( "en_US" ) ); 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 ); connect( generateTsFileButton, &QPushButton::clicked, this, &QgsProjectProperties::generateTsFileButton_clicked );

View File

@ -37,7 +37,6 @@
#include "qgsrectangle.h" #include "qgsrectangle.h"
#include "qgsrelationmanager.h" #include "qgsrelationmanager.h"
#include "qgsannotationmanager.h" #include "qgsannotationmanager.h"
#include "qgsvectorlayer.h"
#include "qgsvectorlayerjoininfo.h" #include "qgsvectorlayerjoininfo.h"
#include "qgsmapthemecollection.h" #include "qgsmapthemecollection.h"
#include "qgslayerdefinition.h" #include "qgslayerdefinition.h"
@ -367,9 +366,6 @@ QgsProject::QgsProject( QObject *parent )
connect( mLayerStore.get(), &QgsMapLayerStore::layersAdded, this, &QgsProject::layersAdded ); connect( mLayerStore.get(), &QgsMapLayerStore::layersAdded, this, &QgsProject::layersAdded );
connect( mLayerStore.get(), &QgsMapLayerStore::layerWasAdded, this, &QgsProject::layerWasAdded ); connect( mLayerStore.get(), &QgsMapLayerStore::layerWasAdded, this, &QgsProject::layerWasAdded );
connect( QgsApplication::instance(), &QgsApplication::requestForTranslatableObjects, this, &QgsProject::registerTranslatableObjects ); connect( QgsApplication::instance(), &QgsApplication::requestForTranslatableObjects, this, &QgsProject::registerTranslatableObjects );
mTranslator = new QTranslator();
} }
@ -445,6 +441,24 @@ void QgsProject::setPresetHomePath( const QString &path )
setDirty( true ); 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 ) void QgsProject::registerTranslatableObjects( QgsTranslationContext *translationContext )
{ {
//register layers //register layers
@ -457,6 +471,7 @@ void QgsProject::registerTranslatableObjects( QgsTranslationContext *translation
{ {
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mapLayer ); QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mapLayer );
//register aliases and fields
const QgsFields fields = vlayer->fields(); const QgsFields fields = vlayer->fields();
for ( const QgsField &field : fields ) for ( const QgsField &field : fields )
{ {
@ -465,6 +480,10 @@ void QgsProject::registerTranslatableObjects( QgsTranslationContext *translation
else else
translationContext->registerTranslation( QStringLiteral( "project:layers:%1:fieldaliases" ).arg( vlayer->id() ), field.alias() ); 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(); QString filename = mFile.fileName();
bool rc; bool rc;
//dave dirty hack
delete mTranslator;
mTranslator = new QTranslator();
if ( QgsProjectStorage *storage = projectStorage() ) if ( QgsProjectStorage *storage = projectStorage() )
{ {
QTemporaryFile inDevice; QTemporaryFile inDevice;
@ -969,10 +984,15 @@ bool QgsProject::read()
} }
//on translation we should not change the filename back //on translation we should not change the filename back
if ( mTranslator->isEmpty() ) if ( !mTranslator )
{ {
mFile.setFileName( filename ); mFile.setFileName( filename );
} }
else
{
//but delete the translator
delete mTranslator;
}
return rc; 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() ) if ( QFile( QStringLiteral( "%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
{ {
mTranslator = new QTranslator();
if ( mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() ) ) if ( mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() ) )
{ {
QgsDebugMsg( "Translation loaded" ); QgsDebugMsg( "Translation loaded" );
@ -1290,7 +1311,7 @@ bool QgsProject::readProjectFile( const QString &filename )
emit nonIdentifiableLayersChanged( nonIdentifiableLayers() ); emit nonIdentifiableLayersChanged( nonIdentifiableLayers() );
if ( !mTranslator->isEmpty() ) if ( mTranslator )
{ {
//project possibly translated -> rename it with locale postfix //project possibly translated -> rename it with locale postfix
QString newFileName( QStringLiteral( "%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ); 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 ) QString QgsProject::translate( const QString &context, const QString &sourceText, const char *disambiguation, int n )
{ {
if ( mTranslator->isEmpty() ) if ( !mTranslator )
{ {
return sourceText; return sourceText;
} }

View File

@ -46,6 +46,7 @@
#include "qgsreadwritecontext.h" #include "qgsreadwritecontext.h"
#include "qgsprojectmetadata.h" #include "qgsprojectmetadata.h"
#include "qgstranslationcontext.h" #include "qgstranslationcontext.h"
#include "qgsvectorlayer.h"
class QFileInfo; class QFileInfo;
class QDomDocument; class QDomDocument;
@ -97,7 +98,6 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
Q_PROPERTY( QgsRelationManager *relationManager READ relationManager ) Q_PROPERTY( QgsRelationManager *relationManager READ relationManager )
Q_PROPERTY( QList<QgsVectorLayer *> avoidIntersectionsLayers READ avoidIntersectionsLayers WRITE setAvoidIntersectionsLayers NOTIFY avoidIntersectionsLayersChanged ) Q_PROPERTY( QList<QgsVectorLayer *> avoidIntersectionsLayers READ avoidIntersectionsLayers WRITE setAvoidIntersectionsLayers NOTIFY avoidIntersectionsLayersChanged )
Q_PROPERTY( QgsProjectMetadata metadata READ metadata WRITE setMetadata NOTIFY metadataChanged ) Q_PROPERTY( QgsProjectMetadata metadata READ metadata WRITE setMetadata NOTIFY metadataChanged )
//dave to do Q_PROPERTY( QTranslator translator READ translator )
public: public:
//! Returns the QgsProject singleton instance //! Returns the QgsProject singleton instance
@ -1296,6 +1296,16 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
*/ */
void setPresetHomePath( const QString &path ); 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 * Registers the translatable objects into the tranlationContext
* so there can be created a ts file these values * so there can be created a ts file these values

View File

@ -1907,15 +1907,15 @@ bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMes
if ( !aliasElem.attribute( QStringLiteral( "name" ) ).isEmpty() ) if ( !aliasElem.attribute( QStringLiteral( "name" ) ).isEmpty() )
{ {
//if it has alias //if it has alias
alias = QgsProject::instance()->translate( QStringLiteral( "project:layers:%1:fieldaliases" ).arg( this->name() ), aliasElem.attribute( QStringLiteral( "name" ) ) ); 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( this->name() ) + " source " + aliasElem.attribute( QStringLiteral( "name" ) ), 1 ); QgsDebugMsgLevel( "context" + QStringLiteral( "project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral( "id" ) ).toElement().text() ) + " source " + aliasElem.attribute( QStringLiteral( "name" ) ), 1 );
} }
else else
{ {
//if it has no alias, but alias is should be the fields translation //if it has no alias, it should be the fields translation
alias = QgsProject::instance()->translate( QStringLiteral( "project:layers:%1:fieldaliases" ).arg( this->name() ), aliasElem.attribute( QStringLiteral( "name" ) ) ); 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( this->name() ) + " source " + field, 1 ); 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 (no translation loaded); //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" ) ) ) if ( alias == aliasElem.attribute( QStringLiteral( "field" ) ) )
alias.clear(); alias.clear();
} }

View File

@ -24,6 +24,9 @@
#include "qgssettings.h" #include "qgssettings.h"
#include <qgsmaplayer.h> #include <qgsmaplayer.h>
#include <qgsvectorlayer.h> #include <qgsvectorlayer.h>
#include <qgslayertree.h>
#include <qgslayertreegroup.h>
#include "qgsrelationmanager.h"
class TestQgsTranslateProject : public QObject class TestQgsTranslateProject : public QObject
{ {
@ -48,12 +51,11 @@ class TestQgsTranslateProject : public QObject
void TestQgsTranslateProject::initTestCase() void TestQgsTranslateProject::initTestCase()
{ {
//start application in german //start application
QgsApplication::init(); QgsApplication::init();
QgsApplication::initQgis(); QgsApplication::initQgis();
original_locale = settings.value( QStringLiteral( "locale/userLocale" ), "" ).toString() ; original_locale = settings.value( QStringLiteral( "locale/userLocale" ), "" ).toString() ;
settings.setValue( QStringLiteral( "locale/userLocale" ), "de" );
} }
void TestQgsTranslateProject::cleanupTestCase() void TestQgsTranslateProject::cleanupTestCase()
@ -76,10 +78,7 @@ void TestQgsTranslateProject::cleanupTestCase()
void TestQgsTranslateProject::init() void TestQgsTranslateProject::init()
{ {
//open project //not needed
QString projectFileName( TEST_DATA_DIR );
projectFileName = projectFileName + "/project_translation/points_translation.qgs";
QgsProject::instance()->read( projectFileName );
} }
void TestQgsTranslateProject::cleanup() void TestQgsTranslateProject::cleanup()
@ -89,15 +88,18 @@ void TestQgsTranslateProject::cleanup()
void TestQgsTranslateProject::createTsFile() void TestQgsTranslateProject::createTsFile()
{ {
//the base is points_translation_de.qgs and with german values //open project in english
//then we generate a ts file for spanish and the ts file with additional es postfix is created settings.setValue( QStringLiteral( "locale/userLocale" ), "en" );
QString projectFileName( TEST_DATA_DIR );
projectFileName = projectFileName + "/project_translation/points_translation.qgs";
QgsProject::instance()->read( projectFileName );
//create ts-file //create ts file for german
QgsProject::instance()->generateTsFile( "es" ); QgsProject::instance()->generateTsFile( "de" );
//check if ts file is created //check if ts file is created
QString tsFileName( TEST_DATA_DIR ); QString tsFileName( TEST_DATA_DIR );
tsFileName = tsFileName + "/project_translation/points_translation_de_es.ts"; tsFileName = tsFileName + "/project_translation/points_translation_de.ts";
QFile tsFile( tsFileName ); QFile tsFile( tsFileName );
QVERIFY( tsFile.exists() ); QVERIFY( tsFile.exists() );
@ -105,46 +107,130 @@ void TestQgsTranslateProject::createTsFile()
QString tsFileContent( tsFile.readAll() ); QString tsFileContent( tsFile.readAll() );
//check if tsFile contains layer name Punkte //LAYER NAMES
QVERIFY( tsFileContent.contains( "<source>Punkte</source>" ) ); //lines
QVERIFY( tsFileContent.contains( "<source>lines</source>" ) );
//points
QVERIFY( tsFileContent.contains( "<source>points</source>" ) );
//check if tsFile contains layer group name //LAYER GROUPS AND SUBGROUPS
//Points:
//Planes and Roads
QVERIFY( tsFileContent.contains( "<source>Planes and Roads</source>" ) );
//Little bit of nothing
QVERIFY( tsFileContent.contains( "<source>Little bit of nothing</source>" ) );
//check if tsFile contains alias value //FIELDS AND ALIASES
//Lines:
//Name (Alias: Runwayid)
QVERIFY( tsFileContent.contains( "<source>Runwayid</source>" ) );
//Value (Alias: Name)
QVERIFY( tsFileContent.contains( "<source>Name</source>" ) );
//check if tsFile contains field name //Points:
// QVERIFY( tsFileContent.contains( "<source>klaso</source>" ) ); //Class (Alias: Level)
QVERIFY( tsFileContent.contains( "<source>Level</source>" ) );
//Heading
QVERIFY( tsFileContent.contains( "<source>Heading</source>" ) );
//Importance
QVERIFY( tsFileContent.contains( "<source>Importance</source>" ) );
//Pilots
QVERIFY( tsFileContent.contains( "<source>Pilots</source>" ) );
//Cabin Crew
QVERIFY( tsFileContent.contains( "<source>Cabin Crew</source>" ) );
//Staff
QVERIFY( tsFileContent.contains( "<source>Staff</source>" ) );
//check if tsFile contains relation name //FORMCONTAINERS
//Plane
QVERIFY( tsFileContent.contains( "<source>Plane</source>" ) );
//Employees
QVERIFY( tsFileContent.contains( "<source>Employees</source>" ) );
//Flightattends
QVERIFY( tsFileContent.contains( "<source>Flightattends</source>" ) );
//RELATIONS
//Runway
QVERIFY( tsFileContent.contains( "<source>Runway</source>" ) );
//Sheepwalk
QVERIFY( tsFileContent.contains( "<source>Sheepwalk</source>" ) );
tsFile.close(); tsFile.close();
} }
void TestQgsTranslateProject::translateProject() void TestQgsTranslateProject::translateProject()
{ {
//open project in german
settings.setValue( QStringLiteral( "locale/userLocale" ), "de" );
QString projectFileName( TEST_DATA_DIR );
projectFileName = projectFileName + "/project_translation/points_translation.qgs";
QgsProject::instance()->read( projectFileName );
//with the qm file containing translation from en to de, the project should be in german and renamed with postfix .de //with the qm file containing translation from en to de, the project should be in german and renamed with postfix .de
QgsVectorLayer *points_layer = qobject_cast<QgsVectorLayer *>( QgsProject::instance()->mapLayer( "points_240d6bd6_9203_470a_994a_aae13cd9fa04" ) ); QgsVectorLayer *points_layer = qobject_cast<QgsVectorLayer *>( QgsProject::instance()->mapLayer( "points_240d6bd6_9203_470a_994a_aae13cd9fa04" ) );
QgsVectorLayer *lines_layer = qobject_cast<QgsVectorLayer *>( QgsProject::instance()->mapLayer( "lines_a677672a_bf5d_410d_98c9_d326a5719a1b" ) ); QgsVectorLayer *lines_layer = qobject_cast<QgsVectorLayer *>( QgsProject::instance()->mapLayer( "lines_a677672a_bf5d_410d_98c9_d326a5719a1b" ) );
//check if layer names translated //LAYER NAMES
QCOMPARE( points_layer->name(), QStringLiteral( "Punkte" ) ); //lines -> Linien
QCOMPARE( lines_layer->name(), QStringLiteral( "Linien" ) ); QCOMPARE( lines_layer->name(), QStringLiteral( "Linien" ) );
//points -> Punkte
QCOMPARE( points_layer->name(), QStringLiteral( "Punkte" ) );
//check if group name translated //LAYER GROUPS AND SUBGROUPS
//Points:
//Planes and Roads -> Flugzeuge und Strassen
QVERIFY( QgsProject::instance()->layerTreeRoot()->findGroup( QStringLiteral( "Flugzeuge und Strassen" ) ) );
//Little bit of nothing -> Bisschen nichts
QVERIFY( QgsProject::instance()->layerTreeRoot()->findGroup( QStringLiteral( "Bisschen nichts" ) ) );
//check if second group name translated //FIELDS AND ALIASES
//Lines:
const QgsFields lines_fields = lines_layer->fields();
//Name (Alias: Runwayid) -> Pistenid
QCOMPARE( lines_fields.field( QStringLiteral( "Name" ) ).alias(), QStringLiteral( "Pistenid" ) );
//Value (Alias: Name) -> Pistenname
QCOMPARE( lines_fields.field( QStringLiteral( "Value" ) ).alias(), QStringLiteral( "Pistenname" ) );
//check if first alias value translated //Points:
const QgsFields points_fields = points_layer->fields();
//Class (Alias: Level) -> Klasse
QCOMPARE( points_fields.field( QStringLiteral( "Class" ) ).alias(), QStringLiteral( "Klasse" ) );
//Heading -> Titel
QCOMPARE( points_fields.field( QStringLiteral( "Heading" ) ).alias(), QStringLiteral( "Titel" ) );
//Importance -> Wichtigkeit
QCOMPARE( points_fields.field( QStringLiteral( "Importance" ) ).alias(), QStringLiteral( "Wichtigkeit" ) );
//Pilots -> Piloten
QCOMPARE( points_fields.field( QStringLiteral( "Pilots" ) ).alias(), QStringLiteral( "Piloten" ) );
//Cabin Crew -> Kabinenpersonal
QCOMPARE( points_fields.field( QStringLiteral( "Cabin Crew" ) ).alias(), QStringLiteral( "Kabinenpersonal" ) );
//Staff -> Mitarbeiter
QCOMPARE( points_fields.field( QStringLiteral( "Staff" ) ).alias(), QStringLiteral( "Mitarbeiter" ) );
//check if second alias value translated //FORMCONTAINERS
QList<QgsAttributeEditorElement *> elements = points_layer->editFormConfig().invisibleRootContainer()->children();
QList<QgsAttributeEditorContainer *> containers;
for ( QgsAttributeEditorElement *element : elements )
{
if ( element->type() == QgsAttributeEditorElement::AeTypeContainer )
containers.append( dynamic_cast<QgsAttributeEditorContainer *>( element ) );
}
//check if first field name translated to the alias //Plane -> Flugzeug
QCOMPARE( containers.at( 0 )->name(), QStringLiteral( "Flugzeug" ) );
//Employees -> Angestellte
QCOMPARE( containers.at( 1 )->name(), QStringLiteral( "Angestellte" ) );
//Flightattends -> Flugbegleitung
for ( QgsAttributeEditorElement *element : containers.at( 1 )->children() )
{
if ( element->type() == QgsAttributeEditorElement::AeTypeContainer )
QCOMPARE( element->name(), QStringLiteral( "Flugbegleitung" ) );
}
//check if second field name translated to the alias //RELATIONS
//Runway -> Piste
//check if first relation name translated QCOMPARE( QgsProject::instance()->relationManager()->relation( QStringLiteral( "points_240_Importance_lines_a677_Value" ) ).name(), QStringLiteral( "Piste" ) );
//Sheepwalk -> Schafweide
//check if second relation name translated QCOMPARE( QgsProject::instance()->relationManager()->relation( QStringLiteral( "points_240_Importance_lines_a677_Value_1" ) ).name(), QStringLiteral( "Schafweide" ) );
QString deProjectFileName( TEST_DATA_DIR ); QString deProjectFileName( TEST_DATA_DIR );
deProjectFileName = deProjectFileName + "/project_translation/points_translation_de.qgs"; deProjectFileName = deProjectFileName + "/project_translation/points_translation_de.qgs";

View File

@ -1,5 +1,5 @@
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'> <!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
<qgis projectname="" version="3.1.0-Master"> <qgis version="3.1.0-Master" projectname="">
<homePath path=""/> <homePath path=""/>
<title></title> <title></title>
<autotransaction active="0"/> <autotransaction active="0"/>
@ -19,29 +19,38 @@
</projectCrs> </projectCrs>
<layer-tree-group> <layer-tree-group>
<customproperties/> <customproperties/>
<layer-tree-layer name="lines" source="../lines.shp" expanded="1" checked="Qt::Checked" id="lines_a677672a_bf5d_410d_98c9_d326a5719a1b" providerKey="ogr"> <layer-tree-group expanded="1" name="Planes and Roads" checked="Qt::Checked">
<customproperties/>
<layer-tree-layer expanded="1" name="lines" id="lines_a677672a_bf5d_410d_98c9_d326a5719a1b" providerKey="ogr" checked="Qt::Checked" source="../lines.shp">
<customproperties/> <customproperties/>
</layer-tree-layer> </layer-tree-layer>
<layer-tree-layer name="points" source="../points.shp" expanded="1" checked="Qt::Checked" id="points_240d6bd6_9203_470a_994a_aae13cd9fa04" providerKey="ogr"> <layer-tree-layer expanded="0" name="points" id="points_240d6bd6_9203_470a_994a_aae13cd9fa04" providerKey="ogr" checked="Qt::Checked" source="../points.shp">
<customproperties/> <customproperties/>
</layer-tree-layer> </layer-tree-layer>
</layer-tree-group>
<layer-tree-group expanded="1" name="Little bit of nothing" checked="Qt::Checked">
<customproperties/>
</layer-tree-group>
<custom-order enabled="0"> <custom-order enabled="0">
<item>points_240d6bd6_9203_470a_994a_aae13cd9fa04</item> <item>points_240d6bd6_9203_470a_994a_aae13cd9fa04</item>
<item>lines_a677672a_bf5d_410d_98c9_d326a5719a1b</item> <item>lines_a677672a_bf5d_410d_98c9_d326a5719a1b</item>
</custom-order> </custom-order>
</layer-tree-group> </layer-tree-group>
<snapping-settings intersection-snapping="0" enabled="0" type="1" mode="2" unit="2" tolerance="0"> <snapping-settings mode="2" tolerance="0" unit="2" intersection-snapping="0" enabled="0" type="1">
<individual-layer-settings> <individual-layer-settings>
<layer-setting units="2" enabled="0" type="1" id="lines_a677672a_bf5d_410d_98c9_d326a5719a1b" tolerance="0"/> <layer-setting tolerance="0" units="2" enabled="0" id="points_240d6bd6_9203_470a_994a_aae13cd9fa04" type="1"/>
<layer-setting units="2" enabled="0" type="1" id="points_240d6bd6_9203_470a_994a_aae13cd9fa04" tolerance="0"/> <layer-setting tolerance="0" units="2" enabled="0" id="lines_a677672a_bf5d_410d_98c9_d326a5719a1b" type="1"/>
</individual-layer-settings> </individual-layer-settings>
</snapping-settings> </snapping-settings>
<relations> <relations>
<relation strength="Association" referencedLayer="lines_a677672a_bf5d_410d_98c9_d326a5719a1b" name="Runway" id="points_240_Importance_lines_a677_Value" referencingLayer="points_240d6bd6_9203_470a_994a_aae13cd9fa04"> <relation referencedLayer="lines_a677672a_bf5d_410d_98c9_d326a5719a1b" strength="Association" name="Runway" id="points_240_Importance_lines_a677_Value" referencingLayer="points_240d6bd6_9203_470a_994a_aae13cd9fa04">
<fieldRef referencedField="Value" referencingField="Importance"/> <fieldRef referencingField="Importance" referencedField="Value"/>
</relation>
<relation referencedLayer="lines_a677672a_bf5d_410d_98c9_d326a5719a1b" strength="Association" name="Sheepwalk" id="points_240_Importance_lines_a677_Value_1" referencingLayer="points_240d6bd6_9203_470a_994a_aae13cd9fa04">
<fieldRef referencingField="Importance" referencedField="Value"/>
</relation> </relation>
</relations> </relations>
<mapcanvas name="theMapCanvas" annotationsVisible="1"> <mapcanvas annotationsVisible="1" name="theMapCanvas">
<units>degrees</units> <units>degrees</units>
<extent> <extent>
<xmin>-119.77777777777767199</xmin> <xmin>-119.77777777777767199</xmin>
@ -65,20 +74,23 @@
<rendermaptile>0</rendermaptile> <rendermaptile>0</rendermaptile>
</mapcanvas> </mapcanvas>
<legend updateDrawingOrder="true"> <legend updateDrawingOrder="true">
<legendlayer drawingOrder="-1" open="true" name="lines" checked="Qt::Checked" showFeatureCount="0"> <legendgroup open="true" name="Planes and Roads" checked="Qt::Checked">
<legendlayer open="true" name="lines" drawingOrder="-1" checked="Qt::Checked" showFeatureCount="0">
<filegroup open="true" hidden="false"> <filegroup open="true" hidden="false">
<legendlayerfile isInOverview="0" visible="1" layerid="lines_a677672a_bf5d_410d_98c9_d326a5719a1b"/> <legendlayerfile visible="1" isInOverview="0" layerid="lines_a677672a_bf5d_410d_98c9_d326a5719a1b"/>
</filegroup> </filegroup>
</legendlayer> </legendlayer>
<legendlayer drawingOrder="-1" open="true" name="points" checked="Qt::Checked" showFeatureCount="0"> <legendlayer open="false" name="points" drawingOrder="-1" checked="Qt::Checked" showFeatureCount="0">
<filegroup open="true" hidden="false"> <filegroup open="false" hidden="false">
<legendlayerfile isInOverview="0" visible="1" layerid="points_240d6bd6_9203_470a_994a_aae13cd9fa04"/> <legendlayerfile visible="1" isInOverview="0" layerid="points_240d6bd6_9203_470a_994a_aae13cd9fa04"/>
</filegroup> </filegroup>
</legendlayer> </legendlayer>
</legendgroup>
<legendgroup open="true" name="Little bit of nothing" checked="Qt::Checked"/>
</legend> </legend>
<mapViewDocks/> <mapViewDocks/>
<projectlayers> <projectlayers>
<maplayer readOnly="0" hasScaleBasedVisibilityFlag="0" type="vector" simplifyAlgorithm="0" simplifyMaxScale="1" maxScale="1" simplifyDrawingHints="1" minScale="1e+8" autoRefreshTime="0" refreshOnNotifyMessage="" autoRefreshEnabled="0" refreshOnNotifyEnabled="0" simplifyDrawingTol="1" labelsEnabled="0" geometry="Line" simplifyLocal="1"> <maplayer autoRefreshTime="0" maxScale="1" readOnly="0" geometry="Line" labelsEnabled="0" simplifyDrawingTol="1" type="vector" hasScaleBasedVisibilityFlag="0" minScale="1e+8" refreshOnNotifyMessage="" autoRefreshEnabled="0" simplifyDrawingHints="1" simplifyAlgorithm="0" simplifyLocal="1" refreshOnNotifyEnabled="0" simplifyMaxScale="1">
<extent> <extent>
<xmin>-117.62319839219053108</xmin> <xmin>-117.62319839219053108</xmin>
<ymin>23.20820580488508966</ymin> <ymin>23.20820580488508966</ymin>
@ -131,11 +143,11 @@
<description></description> <description></description>
<projectionacronym></projectionacronym> <projectionacronym></projectionacronym>
<ellipsoidacronym></ellipsoidacronym> <ellipsoidacronym></ellipsoidacronym>
<geographicflag>true</geographicflag> <geographicflag>false</geographicflag>
</spatialrefsys> </spatialrefsys>
</crs> </crs>
<extent> <extent>
<spatial crs="" maxz="0" maxy="0" minx="0" miny="0" dimensions="2" minz="0" maxx="0"/> <spatial dimensions="2" maxx="0" maxy="0" maxz="0" minx="0" minz="0" crs="" miny="0"/>
<temporal> <temporal>
<period> <period>
<start></start> <start></start>
@ -154,14 +166,14 @@
<map-layer-style name="default"/> <map-layer-style name="default"/>
</map-layer-style-manager> </map-layer-style-manager>
<auxiliaryLayer/> <auxiliaryLayer/>
<renderer-v2 type="categorizedSymbol" symbollevels="0" forceraster="0" attr="Name" enableorderby="0"> <renderer-v2 type="categorizedSymbol" forceraster="0" enableorderby="0" symbollevels="0" attr="Name">
<categories> <categories>
<category render="true" label="Arterial" value="Arterial" symbol="0"/> <category render="true" symbol="0" label="Arterial" value="Arterial"/>
<category render="true" label="Highway" value="Highway" symbol="1"/> <category render="true" symbol="1" label="Highway" value="Highway"/>
</categories> </categories>
<symbols> <symbols>
<symbol alpha="1" type="line" name="0" clip_to_extent="1"> <symbol name="0" type="line" clip_to_extent="1" alpha="1">
<layer pass="0" enabled="1" class="SimpleLine" locked="0"> <layer enabled="1" locked="0" pass="0" class="SimpleLine">
<prop k="capstyle" v="square"/> <prop k="capstyle" v="square"/>
<prop k="customdash" v="5;2"/> <prop k="customdash" v="5;2"/>
<prop k="customdash_map_unit_scale" v="3x:0,0,0,0,0,0"/> <prop k="customdash_map_unit_scale" v="3x:0,0,0,0,0,0"/>
@ -179,15 +191,15 @@
<prop k="width_map_unit_scale" v="3x:0,0,0,0,0,0"/> <prop k="width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
<data_defined_properties> <data_defined_properties>
<Option type="Map"> <Option type="Map">
<Option type="QString" name="name" value=""/> <Option name="name" type="QString" value=""/>
<Option name="properties"/> <Option name="properties"/>
<Option type="QString" name="type" value="collection"/> <Option name="type" type="QString" value="collection"/>
</Option> </Option>
</data_defined_properties> </data_defined_properties>
</layer> </layer>
</symbol> </symbol>
<symbol alpha="1" type="line" name="1" clip_to_extent="1"> <symbol name="1" type="line" clip_to_extent="1" alpha="1">
<layer pass="0" enabled="1" class="SimpleLine" locked="0"> <layer enabled="1" locked="0" pass="0" class="SimpleLine">
<prop k="capstyle" v="square"/> <prop k="capstyle" v="square"/>
<prop k="customdash" v="5;2"/> <prop k="customdash" v="5;2"/>
<prop k="customdash_map_unit_scale" v="3x:0,0,0,0,0,0"/> <prop k="customdash_map_unit_scale" v="3x:0,0,0,0,0,0"/>
@ -205,9 +217,9 @@
<prop k="width_map_unit_scale" v="3x:0,0,0,0,0,0"/> <prop k="width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
<data_defined_properties> <data_defined_properties>
<Option type="Map"> <Option type="Map">
<Option type="QString" name="name" value=""/> <Option name="name" type="QString" value=""/>
<Option name="properties"/> <Option name="properties"/>
<Option type="QString" name="type" value="collection"/> <Option name="type" type="QString" value="collection"/>
</Option> </Option>
</data_defined_properties> </data_defined_properties>
</layer> </layer>
@ -225,17 +237,17 @@
<featureBlendMode>0</featureBlendMode> <featureBlendMode>0</featureBlendMode>
<layerOpacity>1</layerOpacity> <layerOpacity>1</layerOpacity>
<SingleCategoryDiagramRenderer attributeLegend="1" diagramType="Histogram"> <SingleCategoryDiagramRenderer attributeLegend="1" diagramType="Histogram">
<DiagramCategory labelPlacementMethod="XHeight" lineSizeType="MM" backgroundAlpha="255" scaleDependency="Area" penWidth="0" height="15" penAlpha="255" maxScaleDenominator="1e+8" lineSizeScale="3x:0,0,0,0,0,0" minimumSize="0" enabled="0" sizeScale="3x:0,0,0,0,0,0" backgroundColor="#ffffff" minScaleDenominator="1" rotationOffset="270" penColor="#000000" width="15" opacity="1" scaleBasedVisibility="0" sizeType="MM" barWidth="5" diagramOrientation="Up"> <DiagramCategory opacity="1" penAlpha="255" enabled="0" labelPlacementMethod="XHeight" backgroundColor="#ffffff" diagramOrientation="Up" minimumSize="0" backgroundAlpha="255" scaleBasedVisibility="0" penColor="#000000" maxScaleDenominator="1e+8" lineSizeType="MM" height="15" penWidth="0" width="15" sizeType="MM" sizeScale="3x:0,0,0,0,0,0" scaleDependency="Area" rotationOffset="270" barWidth="5" minScaleDenominator="1" lineSizeScale="3x:0,0,0,0,0,0">
<fontProperties description="Noto Sans,10,-1,5,50,0,0,0,0,0" style=""/> <fontProperties description="Noto Sans,10,-1,5,50,0,0,0,0,0" style=""/>
<attribute color="#000000" label="" field=""/> <attribute field="" color="#000000" label=""/>
</DiagramCategory> </DiagramCategory>
</SingleCategoryDiagramRenderer> </SingleCategoryDiagramRenderer>
<DiagramLayerSettings dist="0" priority="0" showAll="1" obstacle="0" zIndex="0" placement="2" linePlacementFlags="2"> <DiagramLayerSettings showAll="1" priority="0" zIndex="0" linePlacementFlags="2" dist="0" placement="2" obstacle="0">
<properties> <properties>
<Option type="Map"> <Option type="Map">
<Option type="QString" name="name" value=""/> <Option name="name" type="QString" value=""/>
<Option name="properties"/> <Option name="properties"/>
<Option type="QString" name="type" value="collection"/> <Option name="type" type="QString" value="collection"/>
</Option> </Option>
</properties> </properties>
</DiagramLayerSettings> </DiagramLayerSettings>
@ -243,44 +255,50 @@
<field name="Name"> <field name="Name">
<editWidget type="TextEdit"> <editWidget type="TextEdit">
<config> <config>
<Option/> <Option type="Map">
<Option name="IsMultiline" type="bool" value="false"/>
<Option name="UseHtml" type="bool" value="false"/>
</Option>
</config> </config>
</editWidget> </editWidget>
</field> </field>
<field name="Value"> <field name="Value">
<editWidget type="TextEdit"> <editWidget type="TextEdit">
<config> <config>
<Option/> <Option type="Map">
<Option name="IsMultiline" type="bool" value="false"/>
<Option name="UseHtml" type="bool" value="false"/>
</Option>
</config> </config>
</editWidget> </editWidget>
</field> </field>
</fieldConfiguration> </fieldConfiguration>
<aliases> <aliases>
<alias index="0" name="" field="Name"/> <alias index="0" field="Name" name="Runwayid"/>
<alias index="1" name="" field="Value"/> <alias index="1" field="Value" name="Name"/>
</aliases> </aliases>
<excludeAttributesWMS/> <excludeAttributesWMS/>
<excludeAttributesWFS/> <excludeAttributesWFS/>
<defaults> <defaults>
<default expression="" applyOnUpdate="0" field="Name"/> <default field="Name" expression="" applyOnUpdate="0"/>
<default expression="" applyOnUpdate="0" field="Value"/> <default field="Value" expression="" applyOnUpdate="0"/>
</defaults> </defaults>
<constraints> <constraints>
<constraint exp_strength="0" constraints="0" unique_strength="0" notnull_strength="0" field="Name"/> <constraint field="Name" exp_strength="0" constraints="0" notnull_strength="0" unique_strength="0"/>
<constraint exp_strength="0" constraints="0" unique_strength="0" notnull_strength="0" field="Value"/> <constraint field="Value" exp_strength="0" constraints="0" notnull_strength="0" unique_strength="0"/>
</constraints> </constraints>
<constraintExpressions> <constraintExpressions>
<constraint desc="" exp="" field="Name"/> <constraint field="Name" desc="" exp=""/>
<constraint desc="" exp="" field="Value"/> <constraint field="Value" desc="" exp=""/>
</constraintExpressions> </constraintExpressions>
<attributeactions> <attributeactions>
<defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/> <defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/>
</attributeactions> </attributeactions>
<attributetableconfig actionWidgetStyle="dropDown" sortExpression="" sortOrder="0"> <attributetableconfig sortExpression="" sortOrder="0" actionWidgetStyle="dropDown">
<columns> <columns>
<column type="field" name="Name" width="-1" hidden="0"/> <column width="-1" name="Name" type="field" hidden="0"/>
<column type="field" name="Value" width="-1" hidden="0"/> <column width="-1" name="Value" type="field" hidden="0"/>
<column type="actions" width="-1" hidden="1"/> <column width="-1" type="actions" hidden="1"/>
</columns> </columns>
</attributetableconfig> </attributetableconfig>
<editform>.</editform> <editform>.</editform>
@ -317,7 +335,12 @@ def my_form_open(dialog, layer, feature):
<widgets> <widgets>
<widget name="points_240_Importance_lines_a677_Value"> <widget name="points_240_Importance_lines_a677_Value">
<config type="Map"> <config type="Map">
<Option type="QString" name="nm-rel" value=""/> <Option name="nm-rel" type="QString" value=""/>
</config>
</widget>
<widget name="points_240_Importance_lines_a677_Value_1">
<config type="Map">
<Option name="nm-rel" type="QString" value=""/>
</config> </config>
</widget> </widget>
</widgets> </widgets>
@ -326,10 +349,10 @@ def my_form_open(dialog, layer, feature):
<fieldstyles/> <fieldstyles/>
</conditionalstyles> </conditionalstyles>
<expressionfields/> <expressionfields/>
<previewExpression>Name</previewExpression> <previewExpression>Value</previewExpression>
<mapTip></mapTip> <mapTip></mapTip>
</maplayer> </maplayer>
<maplayer readOnly="0" hasScaleBasedVisibilityFlag="0" type="vector" simplifyAlgorithm="0" simplifyMaxScale="1" maxScale="1" simplifyDrawingHints="0" minScale="1e+8" autoRefreshTime="0" refreshOnNotifyMessage="" autoRefreshEnabled="0" refreshOnNotifyEnabled="0" simplifyDrawingTol="1" labelsEnabled="0" geometry="Point" simplifyLocal="1"> <maplayer autoRefreshTime="0" maxScale="1" readOnly="0" geometry="Point" labelsEnabled="0" simplifyDrawingTol="1" type="vector" hasScaleBasedVisibilityFlag="0" minScale="1e+8" refreshOnNotifyMessage="" autoRefreshEnabled="0" simplifyDrawingHints="0" simplifyAlgorithm="0" simplifyLocal="1" refreshOnNotifyEnabled="0" simplifyMaxScale="1">
<extent> <extent>
<xmin>-118.88888888888877204</xmin> <xmin>-118.88888888888877204</xmin>
<ymin>22.80020703933767834</ymin> <ymin>22.80020703933767834</ymin>
@ -386,7 +409,7 @@ def my_form_open(dialog, layer, feature):
</spatialrefsys> </spatialrefsys>
</crs> </crs>
<extent> <extent>
<spatial crs="" maxz="0" maxy="0" minx="0" miny="0" dimensions="2" minz="0" maxx="0"/> <spatial dimensions="2" maxx="0" maxy="0" maxz="0" minx="0" minz="0" crs="" miny="0"/>
<temporal> <temporal>
<period> <period>
<start></start> <start></start>
@ -405,15 +428,15 @@ def my_form_open(dialog, layer, feature):
<map-layer-style name="default"/> <map-layer-style name="default"/>
</map-layer-style-manager> </map-layer-style-manager>
<auxiliaryLayer/> <auxiliaryLayer/>
<renderer-v2 type="categorizedSymbol" symbollevels="0" forceraster="0" attr="Class" enableorderby="0"> <renderer-v2 type="categorizedSymbol" forceraster="0" enableorderby="0" symbollevels="0" attr="Class">
<categories> <categories>
<category render="true" label="B52" value="B52" symbol="0"/> <category render="true" symbol="0" label="B52" value="B52"/>
<category render="true" label="Biplane" value="Biplane" symbol="1"/> <category render="true" symbol="1" label="Biplane" value="Biplane"/>
<category render="true" label="Jet" value="Jet" symbol="2"/> <category render="true" symbol="2" label="Jet" value="Jet"/>
</categories> </categories>
<symbols> <symbols>
<symbol alpha="1" type="marker" name="0" clip_to_extent="1"> <symbol name="0" type="marker" clip_to_extent="1" alpha="1">
<layer pass="0" enabled="1" class="SvgMarker" locked="0"> <layer enabled="1" locked="0" pass="0" class="SvgMarker">
<prop k="angle" v="0"/> <prop k="angle" v="0"/>
<prop k="color" v="0,0,0,255"/> <prop k="color" v="0,0,0,255"/>
<prop k="fixedAspectRatio" v="0"/> <prop k="fixedAspectRatio" v="0"/>
@ -433,15 +456,15 @@ def my_form_open(dialog, layer, feature):
<prop k="vertical_anchor_point" v="1"/> <prop k="vertical_anchor_point" v="1"/>
<data_defined_properties> <data_defined_properties>
<Option type="Map"> <Option type="Map">
<Option type="QString" name="name" value=""/> <Option name="name" type="QString" value=""/>
<Option name="properties"/> <Option name="properties"/>
<Option type="QString" name="type" value="collection"/> <Option name="type" type="QString" value="collection"/>
</Option> </Option>
</data_defined_properties> </data_defined_properties>
</layer> </layer>
</symbol> </symbol>
<symbol alpha="1" type="marker" name="1" clip_to_extent="1"> <symbol name="1" type="marker" clip_to_extent="1" alpha="1">
<layer pass="0" enabled="1" class="SvgMarker" locked="0"> <layer enabled="1" locked="0" pass="0" class="SvgMarker">
<prop k="angle" v="0"/> <prop k="angle" v="0"/>
<prop k="color" v="0,0,0,255"/> <prop k="color" v="0,0,0,255"/>
<prop k="fixedAspectRatio" v="0"/> <prop k="fixedAspectRatio" v="0"/>
@ -461,15 +484,15 @@ def my_form_open(dialog, layer, feature):
<prop k="vertical_anchor_point" v="1"/> <prop k="vertical_anchor_point" v="1"/>
<data_defined_properties> <data_defined_properties>
<Option type="Map"> <Option type="Map">
<Option type="QString" name="name" value=""/> <Option name="name" type="QString" value=""/>
<Option name="properties"/> <Option name="properties"/>
<Option type="QString" name="type" value="collection"/> <Option name="type" type="QString" value="collection"/>
</Option> </Option>
</data_defined_properties> </data_defined_properties>
</layer> </layer>
</symbol> </symbol>
<symbol alpha="1" type="marker" name="2" clip_to_extent="1"> <symbol name="2" type="marker" clip_to_extent="1" alpha="1">
<layer pass="0" enabled="1" class="SvgMarker" locked="0"> <layer enabled="1" locked="0" pass="0" class="SvgMarker">
<prop k="angle" v="0"/> <prop k="angle" v="0"/>
<prop k="color" v="0,0,0,255"/> <prop k="color" v="0,0,0,255"/>
<prop k="fixedAspectRatio" v="0"/> <prop k="fixedAspectRatio" v="0"/>
@ -489,9 +512,9 @@ def my_form_open(dialog, layer, feature):
<prop k="vertical_anchor_point" v="1"/> <prop k="vertical_anchor_point" v="1"/>
<data_defined_properties> <data_defined_properties>
<Option type="Map"> <Option type="Map">
<Option type="QString" name="name" value=""/> <Option name="name" type="QString" value=""/>
<Option name="properties"/> <Option name="properties"/>
<Option type="QString" name="type" value="collection"/> <Option name="type" type="QString" value="collection"/>
</Option> </Option>
</data_defined_properties> </data_defined_properties>
</layer> </layer>
@ -509,17 +532,17 @@ def my_form_open(dialog, layer, feature):
<featureBlendMode>0</featureBlendMode> <featureBlendMode>0</featureBlendMode>
<layerOpacity>1</layerOpacity> <layerOpacity>1</layerOpacity>
<SingleCategoryDiagramRenderer attributeLegend="1" diagramType="Histogram"> <SingleCategoryDiagramRenderer attributeLegend="1" diagramType="Histogram">
<DiagramCategory labelPlacementMethod="XHeight" lineSizeType="MM" backgroundAlpha="255" scaleDependency="Area" penWidth="0" height="15" penAlpha="255" maxScaleDenominator="1e+8" lineSizeScale="3x:0,0,0,0,0,0" minimumSize="0" enabled="0" sizeScale="3x:0,0,0,0,0,0" backgroundColor="#ffffff" minScaleDenominator="1" rotationOffset="270" penColor="#000000" width="15" opacity="1" scaleBasedVisibility="0" sizeType="MM" barWidth="5" diagramOrientation="Up"> <DiagramCategory opacity="1" penAlpha="255" enabled="0" labelPlacementMethod="XHeight" backgroundColor="#ffffff" diagramOrientation="Up" minimumSize="0" backgroundAlpha="255" scaleBasedVisibility="0" penColor="#000000" maxScaleDenominator="1e+8" lineSizeType="MM" height="15" penWidth="0" width="15" sizeType="MM" sizeScale="3x:0,0,0,0,0,0" scaleDependency="Area" rotationOffset="270" barWidth="5" minScaleDenominator="1" lineSizeScale="3x:0,0,0,0,0,0">
<fontProperties description="Noto Sans,10,-1,5,50,0,0,0,0,0" style=""/> <fontProperties description="Noto Sans,10,-1,5,50,0,0,0,0,0" style=""/>
<attribute color="#000000" label="" field=""/> <attribute field="" color="#000000" label=""/>
</DiagramCategory> </DiagramCategory>
</SingleCategoryDiagramRenderer> </SingleCategoryDiagramRenderer>
<DiagramLayerSettings dist="0" priority="0" showAll="1" obstacle="0" zIndex="0" placement="0" linePlacementFlags="2"> <DiagramLayerSettings showAll="1" priority="0" zIndex="0" linePlacementFlags="2" dist="0" placement="0" obstacle="0">
<properties> <properties>
<Option type="Map"> <Option type="Map">
<Option type="QString" name="name" value=""/> <Option name="name" type="QString" value=""/>
<Option name="properties"/> <Option name="properties"/>
<Option type="QString" name="type" value="collection"/> <Option name="type" type="QString" value="collection"/>
</Option> </Option>
</properties> </properties>
</DiagramLayerSettings> </DiagramLayerSettings>
@ -527,7 +550,10 @@ def my_form_open(dialog, layer, feature):
<field name="Class"> <field name="Class">
<editWidget type="TextEdit"> <editWidget type="TextEdit">
<config> <config>
<Option/> <Option type="Map">
<Option name="IsMultiline" type="bool" value="false"/>
<Option name="UseHtml" type="bool" value="false"/>
</Option>
</config> </config>
</editWidget> </editWidget>
</field> </field>
@ -568,51 +594,51 @@ def my_form_open(dialog, layer, feature):
</field> </field>
</fieldConfiguration> </fieldConfiguration>
<aliases> <aliases>
<alias index="0" name="" field="Class"/> <alias index="0" field="Class" name="Level"/>
<alias index="1" name="" field="Heading"/> <alias index="1" field="Heading" name=""/>
<alias index="2" name="" field="Importance"/> <alias index="2" field="Importance" name=""/>
<alias index="3" name="" field="Pilots"/> <alias index="3" field="Pilots" name=""/>
<alias index="4" name="" field="Cabin Crew"/> <alias index="4" field="Cabin Crew" name=""/>
<alias index="5" name="" field="Staff"/> <alias index="5" field="Staff" name=""/>
</aliases> </aliases>
<excludeAttributesWMS/> <excludeAttributesWMS/>
<excludeAttributesWFS/> <excludeAttributesWFS/>
<defaults> <defaults>
<default expression="" applyOnUpdate="0" field="Class"/> <default field="Class" expression="" applyOnUpdate="0"/>
<default expression="" applyOnUpdate="0" field="Heading"/> <default field="Heading" expression="" applyOnUpdate="0"/>
<default expression="" applyOnUpdate="0" field="Importance"/> <default field="Importance" expression="" applyOnUpdate="0"/>
<default expression="" applyOnUpdate="0" field="Pilots"/> <default field="Pilots" expression="" applyOnUpdate="0"/>
<default expression="" applyOnUpdate="0" field="Cabin Crew"/> <default field="Cabin Crew" expression="" applyOnUpdate="0"/>
<default expression="" applyOnUpdate="0" field="Staff"/> <default field="Staff" expression="" applyOnUpdate="0"/>
</defaults> </defaults>
<constraints> <constraints>
<constraint exp_strength="0" constraints="0" unique_strength="0" notnull_strength="0" field="Class"/> <constraint field="Class" exp_strength="0" constraints="0" notnull_strength="0" unique_strength="0"/>
<constraint exp_strength="0" constraints="0" unique_strength="0" notnull_strength="0" field="Heading"/> <constraint field="Heading" exp_strength="0" constraints="0" notnull_strength="0" unique_strength="0"/>
<constraint exp_strength="0" constraints="0" unique_strength="0" notnull_strength="0" field="Importance"/> <constraint field="Importance" exp_strength="0" constraints="0" notnull_strength="0" unique_strength="0"/>
<constraint exp_strength="0" constraints="0" unique_strength="0" notnull_strength="0" field="Pilots"/> <constraint field="Pilots" exp_strength="0" constraints="0" notnull_strength="0" unique_strength="0"/>
<constraint exp_strength="0" constraints="0" unique_strength="0" notnull_strength="0" field="Cabin Crew"/> <constraint field="Cabin Crew" exp_strength="0" constraints="0" notnull_strength="0" unique_strength="0"/>
<constraint exp_strength="0" constraints="0" unique_strength="0" notnull_strength="0" field="Staff"/> <constraint field="Staff" exp_strength="0" constraints="0" notnull_strength="0" unique_strength="0"/>
</constraints> </constraints>
<constraintExpressions> <constraintExpressions>
<constraint desc="" exp="" field="Class"/> <constraint field="Class" desc="" exp=""/>
<constraint desc="" exp="" field="Heading"/> <constraint field="Heading" desc="" exp=""/>
<constraint desc="" exp="" field="Importance"/> <constraint field="Importance" desc="" exp=""/>
<constraint desc="" exp="" field="Pilots"/> <constraint field="Pilots" desc="" exp=""/>
<constraint desc="" exp="" field="Cabin Crew"/> <constraint field="Cabin Crew" desc="" exp=""/>
<constraint desc="" exp="" field="Staff"/> <constraint field="Staff" desc="" exp=""/>
</constraintExpressions> </constraintExpressions>
<attributeactions> <attributeactions>
<defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/> <defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/>
</attributeactions> </attributeactions>
<attributetableconfig actionWidgetStyle="dropDown" sortExpression="" sortOrder="0"> <attributetableconfig sortExpression="" sortOrder="0" actionWidgetStyle="dropDown">
<columns> <columns>
<column type="field" name="Class" width="-1" hidden="0"/> <column width="-1" name="Class" type="field" hidden="0"/>
<column type="field" name="Heading" width="-1" hidden="0"/> <column width="-1" name="Heading" type="field" hidden="0"/>
<column type="field" name="Importance" width="-1" hidden="0"/> <column width="-1" name="Importance" type="field" hidden="0"/>
<column type="field" name="Pilots" width="-1" hidden="0"/> <column width="-1" name="Pilots" type="field" hidden="0"/>
<column type="field" name="Cabin Crew" width="-1" hidden="0"/> <column width="-1" name="Cabin Crew" type="field" hidden="0"/>
<column type="field" name="Staff" width="-1" hidden="0"/> <column width="-1" name="Staff" type="field" hidden="0"/>
<column type="actions" width="-1" hidden="1"/> <column width="-1" type="actions" hidden="1"/>
</columns> </columns>
</attributetableconfig> </attributetableconfig>
<editform>.</editform> <editform>.</editform>
@ -639,15 +665,17 @@ def my_form_open(dialog, layer, feature):
<featformsuppress>0</featformsuppress> <featformsuppress>0</featformsuppress>
<editorlayout>tablayout</editorlayout> <editorlayout>tablayout</editorlayout>
<attributeEditorForm> <attributeEditorForm>
<attributeEditorContainer visibilityExpressionEnabled="0" name="Plane" showLabel="1" columnCount="1" visibilityExpression="" groupBox="0"> <attributeEditorContainer name="Plane" groupBox="0" columnCount="1" visibilityExpressionEnabled="0" showLabel="1" visibilityExpression="">
<attributeEditorField index="0" name="Class" showLabel="1"/> <attributeEditorField index="0" name="Class" showLabel="1"/>
<attributeEditorField index="1" name="Heading" showLabel="1"/> <attributeEditorField index="1" name="Heading" showLabel="1"/>
<attributeEditorField index="2" name="Importance" showLabel="1"/> <attributeEditorField index="2" name="Importance" showLabel="1"/>
</attributeEditorContainer> </attributeEditorContainer>
<attributeEditorContainer visibilityExpressionEnabled="0" name="Employees" showLabel="1" columnCount="1" visibilityExpression="" groupBox="0"> <attributeEditorContainer name="Employees" groupBox="0" columnCount="1" visibilityExpressionEnabled="0" showLabel="1" visibilityExpression="">
<attributeEditorField index="3" name="Pilots" showLabel="1"/> <attributeEditorField index="3" name="Pilots" showLabel="1"/>
<attributeEditorField index="4" name="Cabin Crew" showLabel="1"/>
<attributeEditorField index="5" name="Staff" showLabel="1"/> <attributeEditorField index="5" name="Staff" showLabel="1"/>
<attributeEditorContainer name="Flightattends" groupBox="1" columnCount="1" visibilityExpressionEnabled="0" showLabel="1" visibilityExpression="">
<attributeEditorField index="4" name="Cabin Crew" showLabel="1"/>
</attributeEditorContainer>
</attributeEditorContainer> </attributeEditorContainer>
</attributeEditorForm> </attributeEditorForm>
<editable> <editable>
@ -681,94 +709,94 @@ def my_form_open(dialog, layer, feature):
<layer id="lines_a677672a_bf5d_410d_98c9_d326a5719a1b"/> <layer id="lines_a677672a_bf5d_410d_98c9_d326a5719a1b"/>
</layerorder> </layerorder>
<properties> <properties>
<PositionPrecision>
<DegreeFormat type="QString">MU</DegreeFormat>
<Automatic type="bool">true</Automatic>
<DecimalPlaces type="int">2</DecimalPlaces>
</PositionPrecision>
<WMSContactOrganization type="QString"></WMSContactOrganization>
<SpatialRefSys>
<ProjectionsEnabled type="int">1</ProjectionsEnabled>
</SpatialRefSys>
<WMSServiceTitle type="QString"></WMSServiceTitle>
<Macros>
<pythonCode type="QString"></pythonCode>
</Macros>
<WFSUrl type="QString"></WFSUrl> <WFSUrl type="QString"></WFSUrl>
<WMSContactPhone type="QString"></WMSContactPhone> <WMSAccessConstraints type="QString">None</WMSAccessConstraints>
<WMSFees type="QString">conditions unknown</WMSFees> <WMSOnlineResource type="QString"></WMSOnlineResource>
<Paths> <WMSContactPerson type="QString"></WMSContactPerson>
<Absolute type="bool">false</Absolute>
</Paths>
<WFSLayers type="QStringList"/>
<WMSKeywordList type="QStringList">
<value></value>
</WMSKeywordList>
<WMSUseLayerIDs type="bool">false</WMSUseLayerIDs>
<PAL>
<CandidatesPoint type="int">16</CandidatesPoint>
<ShowingPartialsLabels type="bool">true</ShowingPartialsLabels>
<ShowingCandidates type="bool">false</ShowingCandidates>
<DrawRectOnly type="bool">false</DrawRectOnly>
<CandidatesPolygon type="int">30</CandidatesPolygon>
<ShowingAllLabels type="bool">false</ShowingAllLabels>
<DrawOutlineLabels type="bool">true</DrawOutlineLabels>
<SearchMethod type="int">0</SearchMethod>
<CandidatesLine type="int">50</CandidatesLine>
</PAL>
<WMSContactPosition type="QString"></WMSContactPosition>
<Legend>
<filterByMap type="bool">false</filterByMap>
</Legend>
<WMSPrecision type="QString">8</WMSPrecision>
<WCSLayers type="QStringList"/>
<RequiredLayers>
<Layers type="QStringList"/>
</RequiredLayers>
<Measure>
<Ellipsoid type="QString">WGS84</Ellipsoid>
</Measure>
<WCSUrl type="QString"></WCSUrl>
<Measurement>
<DistanceUnits type="QString">meters</DistanceUnits>
<AreaUnits type="QString">m2</AreaUnits>
</Measurement>
<Gui>
<CanvasColorBluePart type="int">255</CanvasColorBluePart>
<SelectionColorAlphaPart type="int">255</SelectionColorAlphaPart>
<SelectionColorRedPart type="int">255</SelectionColorRedPart>
<SelectionColorGreenPart type="int">255</SelectionColorGreenPart>
<SelectionColorBluePart type="int">0</SelectionColorBluePart>
<CanvasColorRedPart type="int">255</CanvasColorRedPart>
<CanvasColorGreenPart type="int">255</CanvasColorGreenPart>
</Gui>
<WMSServiceCapabilities type="bool">false</WMSServiceCapabilities>
<WMSImageQuality type="int">90</WMSImageQuality>
<WMSServiceAbstract type="QString"></WMSServiceAbstract>
<WMSRequestDefinedDataSources type="bool">false</WMSRequestDefinedDataSources>
<WMSAddWktGeometry type="bool">false</WMSAddWktGeometry>
<WMSContactMail type="QString"></WMSContactMail>
<WMSSegmentizeFeatureInfoGeometry type="bool">false</WMSSegmentizeFeatureInfoGeometry>
<DefaultStyles> <DefaultStyles>
<Fill type="QString"></Fill> <Fill type="QString"></Fill>
<RandomColors type="bool">true</RandomColors> <RandomColors type="bool">true</RandomColors>
<Opacity type="double">1</Opacity>
<Line type="QString"></Line> <Line type="QString"></Line>
<Marker type="QString"></Marker> <Marker type="QString"></Marker>
<ColorRamp type="QString"></ColorRamp> <ColorRamp type="QString"></ColorRamp>
<Opacity type="double">1</Opacity>
</DefaultStyles> </DefaultStyles>
<WMSContactPerson type="QString"></WMSContactPerson> <WMSServiceAbstract type="QString"></WMSServiceAbstract>
<WMSOnlineResource type="QString"></WMSOnlineResource> <RequiredLayers>
<Layers type="QStringList"/>
</RequiredLayers>
<WMSServiceCapabilities type="bool">false</WMSServiceCapabilities>
<Identify> <Identify>
<disabledLayers type="QStringList"/> <disabledLayers type="QStringList"/>
</Identify> </Identify>
<WMSUrl type="QString"></WMSUrl> <Macros>
<pythonCode type="QString"></pythonCode>
</Macros>
<WMSImageQuality type="int">90</WMSImageQuality>
<PAL>
<DrawRectOnly type="bool">false</DrawRectOnly>
<CandidatesPolygon type="int">30</CandidatesPolygon>
<CandidatesPoint type="int">16</CandidatesPoint>
<ShowingPartialsLabels type="bool">true</ShowingPartialsLabels>
<SearchMethod type="int">0</SearchMethod>
<ShowingAllLabels type="bool">false</ShowingAllLabels>
<DrawOutlineLabels type="bool">true</DrawOutlineLabels>
<ShowingCandidates type="bool">false</ShowingCandidates>
<CandidatesLine type="int">50</CandidatesLine>
</PAL>
<Paths>
<Absolute type="bool">false</Absolute>
</Paths>
<WMSPrecision type="QString">8</WMSPrecision>
<WMSContactPosition type="QString"></WMSContactPosition>
<WMSContactMail type="QString"></WMSContactMail>
<WFSLayers type="QStringList"/>
<WMSServiceTitle type="QString"></WMSServiceTitle>
<Gui>
<CanvasColorRedPart type="int">255</CanvasColorRedPart>
<SelectionColorBluePart type="int">0</SelectionColorBluePart>
<SelectionColorGreenPart type="int">255</SelectionColorGreenPart>
<CanvasColorGreenPart type="int">255</CanvasColorGreenPart>
<CanvasColorBluePart type="int">255</CanvasColorBluePart>
<SelectionColorRedPart type="int">255</SelectionColorRedPart>
<SelectionColorAlphaPart type="int">255</SelectionColorAlphaPart>
</Gui>
<WFSTLayers> <WFSTLayers>
<Insert type="QStringList"/>
<Delete type="QStringList"/>
<Update type="QStringList"/> <Update type="QStringList"/>
<Delete type="QStringList"/>
<Insert type="QStringList"/>
</WFSTLayers> </WFSTLayers>
<WMSAccessConstraints type="QString">None</WMSAccessConstraints> <WMSKeywordList type="QStringList">
<value></value>
</WMSKeywordList>
<WMSFees type="QString">conditions unknown</WMSFees>
<WCSUrl type="QString"></WCSUrl>
<Measure>
<Ellipsoid type="QString">WGS84</Ellipsoid>
</Measure>
<WMSUseLayerIDs type="bool">false</WMSUseLayerIDs>
<WMSSegmentizeFeatureInfoGeometry type="bool">false</WMSSegmentizeFeatureInfoGeometry>
<Measurement>
<AreaUnits type="QString">m2</AreaUnits>
<DistanceUnits type="QString">meters</DistanceUnits>
</Measurement>
<SpatialRefSys>
<ProjectionsEnabled type="int">1</ProjectionsEnabled>
</SpatialRefSys>
<WMSContactOrganization type="QString"></WMSContactOrganization>
<WMSRequestDefinedDataSources type="bool">false</WMSRequestDefinedDataSources>
<WMSUrl type="QString"></WMSUrl>
<WMSAddWktGeometry type="bool">false</WMSAddWktGeometry>
<WCSLayers type="QStringList"/>
<PositionPrecision>
<Automatic type="bool">true</Automatic>
<DegreeFormat type="QString">MU</DegreeFormat>
<DecimalPlaces type="int">2</DecimalPlaces>
</PositionPrecision>
<Legend>
<filterByMap type="bool">false</filterByMap>
</Legend>
<WMSContactPhone type="QString"></WMSContactPhone>
</properties> </properties>
<visibility-presets/> <visibility-presets/>
<transformContext/> <transformContext/>