mitchcurtis / slate

Pixel Art Editor
GNU General Public License v3.0
1.07k stars 103 forks source link

Look into translations #122

Closed mitchcurtis closed 5 years ago

naj59 commented 5 years ago

So it seems that normal user interface strings have an equivalent to tr("My Text"); in QML. It is qsTr() and can just applied into the qml file. For example:

Text {
    id: txt;
    text: qsTr("This sentence can be translated.");
}

To help the translator there is a possibility to add some comments:

//: This is a comment displayed to the translator

The thing which comes up here is that lupdate is used. lupdate creates translation files out of source files (extracts strings from there). The thing is that we'll need to add a conditional to the .pro file:

lupdate_only {
    SOURCES += MyWindow.qml \
               MyButton.qml
}

We do that because normally qmake registers SOURCES as C++ files and tries to compile it later on. This is not possible while we're in the qml world.

Then we can add translations to the .pro file:

TRANSLATIONS += slate_fr.ts
TRANSLATIONS += slate_de.ts

Then lupdate over the .pro file, it generates the .ts files and translators can open them up in Qt Linguist. Later on lrelease is used to create .qm files (binary format of .ts files, only used when shipping software).

Enabling translations is done in the main entry point. Example (taken from Qt website):

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QTranslator qtTranslator;
    qtTranslator.load("qt_" + QLocale::system().name(),
            QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    app.installTranslator(&qtTranslator);

    QTranslator myappTranslator;
    myappTranslator.load("myapp_" + QLocale::system().name());
    app.installTranslator(&myappTranslator);

    return app.exec();
},

EDIT: Can be also done in application.cpp, but somewhere before the first window is shown.

mitchcurtis commented 5 years ago

Thanks for the write-up!

So it seems that normal user interface strings have an equivalent to tr("My Text"); in QML. It is qsTr() and can just applied into the qml file. For example:

I've tried to do this with most user-facing strings, but I've probably missed some here and there.

The thing which comes up here is that lupdate is used. lupdate creates translation files out of source files (extracts strings from there). The thing is that we'll need to add a conditional to the .pro file:

I see that we now already have two copies of the list of QML files:

It would be great to somehow consolidate these into one, because it seems like we'll need to add one more for the lupdate_only SOURCES. Though I guess eventually there will only be one if/when we move everything over to CMake. I guess it's not that important for now, but it's easy to update one list and forget to update the other. :)

On the other hand, we're not using qmake anymore, so we need to find out how it's done in Qbs and/or CMake.

naj59 commented 5 years ago

Not into CMake so I'm out there (I love qmake btw). Probably take a look here?

In Qbs we can take something from tiled: https://github.com/bjorn/tiled/blob/master/translations/translations.qbs

mitchcurtis commented 5 years ago

@bjorn: Hey, did you ever manage to get lupdate working with Qbs? From looking at QBS-486 it seems like it still doesn't work, so are you using translations.pro to generate the translation files?

bjorn commented 5 years ago

@mitchcurtis It is the last remaining item on the list for bjorn/tiled#1484... Indeed I am still relying on this cryptic translations.pro file for doing make ts, with lupdate relying on parsing the various .pro files to find out which files to process. If this would be supported by Qbs properly I could finally remove the qmake stuff. :-/

mitchcurtis commented 5 years ago

Ah, bummer. I wonder if it's enough to just add a .pro in the translations directory simply for translation purposes... I've already got two build systems going at the moment. Not too thrilled about adding a third, haha.

Edit: I guess that won't work because you still have to list the sources somewhere... ugh.

mitchcurtis commented 5 years ago

OK, I didn't actually know this (having never used lupdate before), but lupdate can be passed a directory:

Two tools are provided for the release manager, lupdate and lrelease. These tools can process qmake project files, or operate directly on the file system.

So we can still do translations, just not as part of the build process.

bjorn commented 5 years ago

@mitchcurtis Whoa! I noticed my translations.pro was just passing the src directory as argument to lupdate, but I thought lupdate was finding and parsing the .pro files within that directory! Well, it might do that, but indeed it can find all the translations also after deleting all those .pro files.

So yeah, I'll definitely be replacing that with a simple shell script. Thanks! :)

Now unfortunately I also just realized that my snap package still relies on qmake, so before I can remove all the .pro files I'll need to look into using qbs there...

mitchcurtis commented 5 years ago

For anyone that might be curious, I created a task to improve Qt's documentation in this area, and the task itself lists some examples of how to do translations without a .pro file:

https://bugreports.qt.io/browse/QTBUG-76289

mitchcurtis commented 5 years ago

https://github.com/mitchcurtis/slate/commit/e76617fa64b6c592734c05f0ede285d38a417212 adds the stuff necessary to add translations.