<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>On Tue, Mar 18, 2014, at 9:49, Aurélien Gâteau wrote:<br></div>
<blockquote type="cite"><div>On Tue, Mar 18, 2014, at 9:07, Aleix Pol wrote:<br></div>
<blockquote type="cite"><div dir="ltr"><div><div><div>On Tue, Mar 18, 2014 at 4:12 PM, Aurélien Gâteau <span dir="ltr"><<a href="mailto:agateau@kde.org" target="_blank">agateau@kde.org</a>></span> wrote:<br></div>
<div> <br></div>
<blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><u></u>
<br></div>
<div><div><div><div>On Tue, Mar 18, 2014, at 6:20, Aleix Pol wrote:<br></div>
<blockquote type="cite"><div dir="ltr"><div><div><div>On Tue, Mar 18, 2014 at 2:05 PM, Aurélien Gâteau <span dir="ltr"><<a href="mailto:agateau@kde.org" target="_blank">agateau@kde.org</a>></span> wrote:<br></div>
<div> <br></div>
<blockquote style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>Hi,<br></div>
<div> <br></div>
<div>
I started working on how to handle Qt based translations, and make it as<br></div>
<div>
simple as possible to work with for framework maintainers as well as<br></div>
<div>
framework users.<br></div>
<div> <br></div>
<div>
I picked KBookmarks as my guinea pig and got to the point where<br></div>
<div>
kbookmarkdialogtest shows a translated dialog.<br></div>
<div> <br></div>
<div>
Here is how it currently works. All of this is liberally inspired from<br></div>
<div>
the way Trojita works:<br></div>
<div> <br></div>
<div>
# String extraction<br></div>
<div> <br></div>
<div>
I created a src/Messages.sh which contains the following:<br></div>
<div> <br></div>
<div>
lupdate -silent -recursive . -ts $podir/tmp.ts<br></div>
<div>
lconvert $podir/tmp.ts --sort-contexts --output-format pot -o<br></div>
<div>
$podir/kbookmarks5.pot<br></div>
<div>
rm $podir/tmp.ts<br></div>
<div> <br></div>
<div>
# String compilation<br></div>
<div> <br></div>
<div>
I modified the toplevel CMakeLists.txt, adding these lines:<br></div>
<div> <br></div>
<div>
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/po)<br></div>
<div>
include(${CMAKE_CURRENT_SOURCE_DIR}/QmSupport.cmake)<br></div>
<div>
qm_setup(kbookmarks5 po)<br></div>
<div>
endif()<br></div>
<div> <br></div>
<div>
I created a QmSupport.cmake file, which exposes a qm_setup() function.<br></div>
<div>
This function does three things:<br></div>
<div>
1. Create a "qm" target which turns all .po into .qm files.<br></div>
<div> <br></div>
<div>
2. Call install(FILES...) on the generated qm files, installing them in<br></div>
<div>
share/${name}/locale, where ${name} is the firt argument of qm_setup().<br></div>
<div> <br></div>
<div>
3. Generate a "${name}_translation.h" which contain two inline functions<br></div>
<div>
to make it easy to load the translations.<br></div>
<div>
Using the translation is then just a matter of including<br></div>
<div>
${name}_translation.h and calling ${name}_installTranslator(). If more<br></div>
<div>
control is needed, ${name}_installTranslator() also accepts an optional<br></div>
<div>
argument: the language. For even finer control, the .h also contains a<br></div>
<div>
${name}_createTranslator() function, which returns a QTranslator loaded<br></div>
<div>
with strings for the right language.<br></div>
<div> <br></div>
<div>
# Questions<br></div>
<div> <br></div>
<div>
Does this approach sounds sane to you?<br></div>
<div> <br></div>
<div>
I think QmSupport.cmake should go to extra-cmake-modules. Any<br></div>
<div>
objections?<br></div>
<div> <br></div>
<div>
Right now qm_setup() is very inflexible: it installs files and creates<br></div>
<div>
the _translation.h file based on the name argument, meaning in my<br></div>
<div>
example it creates share/kbookmarks5/locale/kbookmarks5_*.qm and<br></div>
<div>
include/kbookmarks5_translation.h, which contains the functions<br></div>
<div>
kbookmarks5_createTranslator and kbookmarks5_installTranslator.<br></div>
<div> <br></div>
<div>
I think we want to be able to customize the install dir of the<br></div>
<div>
_translation.h file because some frameworks install header files in a<br></div>
<div>
subdir, others do not.<br></div>
<div> <br></div>
<div>
Should we also be able to customize the install data dir for qm files,<br></div>
<div>
as well as the prefix of the function names from _translation.h? I am<br></div>
<div>
tempted to default to ${PROJECT_NAME} for the prefix of the function<br></div>
<div>
names, its lowercase version for the install data dir and add an<br></div>
<div>
optional PROJECT_NAME argument to qm_setup(). Opinions?<br></div>
<div> <br></div>
<div>
I am attaching the diff of the current state. I do not intend to commit<br></div>
<div>
it as is since po files are not supposed to be in the framework<br></div>
<div>
repository, but it should make it easy for you to try it if you are<br></div>
<div>
interested.<br></div>
<div> <br></div>
<div><span><span style="color:rgb(136, 136, 136)" class="colour">
Aurélien</span></span><br></div>
<div> <br></div>
<div>_______________________________________________<br></div>
<div>
Kde-frameworks-devel mailing list<br></div>
<div>
<a href="mailto:Kde-frameworks-devel@kde.org" target="_blank">Kde-frameworks-devel@kde.org</a><br></div>
<div>
<a href="https://mail.kde.org/mailman/listinfo/kde-frameworks-devel" target="_blank">https://mail.kde.org/mailman/listinfo/kde-frameworks-devel</a><br></div>
<div> <br></div>
</blockquote></div>
<div> <br></div>
</div>
<div>Hi Aurélien,<br></div>
<div>Wouldn't it make sense that the library called the createTranslation itself, instead of expecting the application to call it? I can easily see applications forgetting it.<br></div>
<div>Maybe using Q_COREAPP_STARTUP_FUNCTION?<br></div>
</div>
</blockquote><div> <br></div>
</div>
</div>
<div>That could work, but would remove the ability to change the language later (Some Qt apps like to let the user use a different language than the system one for some reason). Not sure we care about this. It certainly sounds more foolproof. On the other hand, you already *must* load translations yourself if you are using any Qt standard dialog, otherwise it won't be translated either.<span><span style="color:rgb(136, 136, 136)" class="colour"></span></span><br></div>
<span><span style="color:rgb(136, 136, 136)" class="colour"><div> <br></div>
<div>Aurélien<br></div>
</span></span></div>
<div> <br></div>
<div>_______________________________________________<br></div>
<div>
Kde-frameworks-devel mailing list<br></div>
<div>
<a href="mailto:Kde-frameworks-devel@kde.org">Kde-frameworks-devel@kde.org</a><br></div>
<div>
<a href="https://mail.kde.org/mailman/listinfo/kde-frameworks-devel" target="_blank">https://mail.kde.org/mailman/listinfo/kde-frameworks-devel</a><br></div>
</blockquote><div> <br></div>
<div>Well, for KI18n changing the language at run-time is not possible.<br></div>
<div> <br></div>
<div>Maybe we can set it up magically for general use and still install the createTranslation thing in case the application likes to do it specifically?<br></div>
</div>
</div>
</div>
</blockquote><div dir="ltr"><div><div><div> <br></div>
<div>That is right. Let's keep it simple then and not provide a feature which is not supported by KI18n-powered frameworks.<br></div>
<div> <br></div>
<div>This means we need to add a generated .cpp file in the framework target(s). Going to look into it.<br></div>
</div>
</div>
</div>
</blockquote><div dir="ltr"><div><div><div> <br></div>
<div>Some feedback on this: using Q_COREAPP_STARTUP_FUNCTION works as expected. I think I have something usable now. Adapting a Qt-translated framework requires the following changes (using kbookmarks as example again):<br></div>
<div> </div>
<div>1. Create src/Messages.sh with the following content:<br></div>
<div> </div>
</div>
</div>
</div>
<div> rm -f $podir/tmp.ts<br></div>
<div> lupdate -silent -recursive . -ts $podir/tmp.ts<br></div>
<div> lconvert $podir/tmp.ts --sort-contexts --output-format pot -o $podir/kbookmarks5.pot<br></div>
<div> rm $podir/tmp.ts<br></div>
<div dir="ltr"><div><div><div> </div>
<div>Note: As much as possible of these lines should move to the l10n scripts to reduce duplication.<br></div>
<div> </div>
<div>2. Edit the top-level CMakeLists.txt, add the following *before* add_subdirectory(src):<br></div>
<div> </div>
</div>
</div>
include(ECMSetupQtTranslations)<br></div>
<div> ecm_setup_qt_translations(<br></div>
<div> PO_DIR po<br></div>
<div> POT_NAME kbookmarks5.pot<br></div>
<div> INSTALL_SUB_DIR kbookmarks<br></div>
<div> CREATE_LOADER)<br></div>
<div> </div>
<div>3. Edit src/CMakelists.txt, add ${ECM_QT_TRANSLATION_LOADER} to kbookmark_SRCS:<br></div>
<div> </div>
<div> set(kbookmarks_SRCS<br></div>
<div> kbookmark.cpp<br> #...<br></div>
<div> ${ECM_QT_TRANSLATION_LOADER}<br></div>
<div> )<br></div>
<div> </div>
<div>This works with the attached ECMSetupQtTranslations.cmake file.<br></div>
<div> </div>
<div>When those changes are done, one gets translations installed and loaded, as long as the source used to build contains a properly populated po/ dir. This should be taken care of by the release scripts.<br></div>
<div> </div>
<div>If this makes sense to you, I am going to propose ECMSetupQtTranslations.cmake for inclusion in extra-cmake-modules.<br></div>
<div> </div>
<div>Aurélien<br></div>
</body>
</html>