Re: [Interest] Dynamic translations for mobile apps at runtime?
Ooops. I concretely missed the `virtual`. > Sent: Friday, March 11, 2016 at 11:15 AM > From: "Julien Cugnière" > To: "Jason H" > Cc: "interest@qt-project.org Interest" > Subject: Re: [Interest] Dynamic translations for mobile apps at runtime? > > QTranslator::translate is virtual. Its documentation even says "If you > need to programatically insert translations into a QTranslator, this > function can be reimplemented." :-) > > So you can create a QTranslator based class that returns translations > from your own list if the QM file found nothing. > Julien Cugnière > > > 2016-03-11 17:08 GMT+01:00 Jason H : > > So we had a great thread about "dynamic translations" Its in and working > > well. (Thanks everyone) > > > > And while I have a slick update procedure for adding dictionaries at run > > time, I am wondering about adding translation strings at runtime? > > > > Here's what's happening: > > - App is in a language (Now, can be more than English) > > - User logs in, the user has a language on their profile > > - That profile is selected on the UI > > - The server sends content in that language (JSON) > > > > The reason for this is some of the content is user-configurable, and as a > > result, the server has it's own internal translation tables. Currently, I > > can toggle the UI language, but the server delivered content stays the > > same. It would be nice if I could retranslate both. However the > > lupdate/lrelease workflow won't work someone suggested using localise.biz, > > but then we have to coordinate the strings, and we want to have the web UI > > without dependencies. My backend team won't be happy, but we (really just > > me) . I could then: > > My options are: > > a. could write a binary for direct DB tables-to-QM file translation, load > > the server translations into a QTranslator and have it just work, > > or > > b. use some QTranslator API to dynamically add translations at runtime. > > > > Both don't seem possible as there is no non-private API to write QM files, > > and there is no API to alter the QTranslator. > > > > I'm hoping maybe the QM file format is just some kind of QMap? > > > > > > > > > > ___ > > Interest mailing list > > Interest@qt-project.org > > http://lists.qt-project.org/mailman/listinfo/interest > ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
QTranslator::translate is virtual. Its documentation even says "If you need to programatically insert translations into a QTranslator, this function can be reimplemented." :-) So you can create a QTranslator based class that returns translations from your own list if the QM file found nothing. Julien Cugnière 2016-03-11 17:08 GMT+01:00 Jason H : > So we had a great thread about "dynamic translations" Its in and working > well. (Thanks everyone) > > And while I have a slick update procedure for adding dictionaries at run > time, I am wondering about adding translation strings at runtime? > > Here's what's happening: > - App is in a language (Now, can be more than English) > - User logs in, the user has a language on their profile > - That profile is selected on the UI > - The server sends content in that language (JSON) > > The reason for this is some of the content is user-configurable, and as a > result, the server has it's own internal translation tables. Currently, I can > toggle the UI language, but the server delivered content stays the same. It > would be nice if I could retranslate both. However the lupdate/lrelease > workflow won't work someone suggested using localise.biz, but then we have to > coordinate the strings, and we want to have the web UI without dependencies. > My backend team won't be happy, but we (really just me) . I could then: > My options are: > a. could write a binary for direct DB tables-to-QM file translation, load the > server translations into a QTranslator and have it just work, > or > b. use some QTranslator API to dynamically add translations at runtime. > > Both don't seem possible as there is no non-private API to write QM files, > and there is no API to alter the QTranslator. > > I'm hoping maybe the QM file format is just some kind of QMap? > > > > > ___ > Interest mailing list > Interest@qt-project.org > http://lists.qt-project.org/mailman/listinfo/interest ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
So we had a great thread about "dynamic translations" Its in and working well. (Thanks everyone) And while I have a slick update procedure for adding dictionaries at run time, I am wondering about adding translation strings at runtime? Here's what's happening: - App is in a language (Now, can be more than English) - User logs in, the user has a language on their profile - That profile is selected on the UI - The server sends content in that language (JSON) The reason for this is some of the content is user-configurable, and as a result, the server has it's own internal translation tables. Currently, I can toggle the UI language, but the server delivered content stays the same. It would be nice if I could retranslate both. However the lupdate/lrelease workflow won't work someone suggested using localise.biz, but then we have to coordinate the strings, and we want to have the web UI without dependencies. My backend team won't be happy, but we (really just me) . I could then: My options are: a. could write a binary for direct DB tables-to-QM file translation, load the server translations into a QTranslator and have it just work, or b. use some QTranslator API to dynamically add translations at runtime. Both don't seem possible as there is no non-private API to write QM files, and there is no API to alter the QTranslator. I'm hoping maybe the QM file format is just some kind of QMap? ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
Great clarification, thanks Andre! > Sent: Wednesday, March 09, 2016 at 2:24 AM > From: "André Somers" > To: interest@qt-project.org > Subject: Re: [Interest] Dynamic translations for mobile apps at runtime? > > > > Op 08/03/2016 om 23:21 schreef Jason H: > > Sounds like there should be a qApp->translations() that we can use to > > remove all currently installed translations? Without it, we have to do what > > you do. > Just keep the translators you currently have active around, not all of > them. It is useless to new a QTranslator for languages you are not > actually using. When switching language, you can remove and then delete > the already loaded ones after installing the translations for the newly > selected language. > > So, something like this (untested code, typed in email editor): > > QString m_currentLanguage; > QVector m_currentTranslations; //note that for any language, > you may need multiple translation files! > > void Backend::selectLanguage( QString language ) { >if (language == m_currentLanguage) > return; > >QVector oldTranslators = m_currentTranslations; >m_currentTranslations.clear(); > >//repeat for every translation file you need to install, ie for your own > app, for Qt itself, for libraries... >translator = new QTranslator(this); >translator->load( language, commonPath()+"/translations" ); >qApp->installTranslator(translator); >m_currentTranslations.append(translator); > >//now, get rid of the old translators >foreach(QTranslator* oldTranslator, oldTranslators) { > qApp->removeTranslator(oldTranslator); > delete oldTranslator; >} > } > > > > André > > > > > > >> Sent: Tuesday, March 08, 2016 at 3:44 PM > >> From: Gianluca > >> To: "Jason H" > >> Cc: "interest@qt-project.org" > >> Subject: Re: [Interest] Dynamic translations for mobile apps at runtime? > >> > >> qApp->installTranslator add a new translation into the stack. Does not > >> remove the old ones. > >> So, if the user click 10 times: Italian - English - Italian - English … > >> etc… > >> you got ten translator into the memory. > >> That’s because the translation is searched into the order on which the > >> translator are installed into the stack. > >> > >> That’s why I remove everything so there is only one translators at time > >> into the memory. > >> > >> Il giorno 08/mar/2016, alle ore 18:46, Jason H ha scritto: > >> > >>> I'm wondering why you load all those languages and then remove all but > >>> one of them? Being a mobile app, I have to be somewhat conscience of > >>> memory foot print. Do you see anything wrong with: > >>> > >>> void Backend::selectLanguage( QString language ) { > >>> translator = new QTranslator(this); > >>> translator->load( language, commonPath()+"/translations" ); > >>> qApp->installTranslator(translator); > >>> } > >>> > >>> ? > >>> > >>> > >>>> Hello Jason, > >>>> I got the same issue some times ago … and I found that it’s possible to > >>>> use the translation feature of Qt … that seems static, but it’s not. > >>>> And localize.biz it’s a wonderful site that allow you to modify Qt > >>>> translation files directly on web and download the updated one. > >>>> > >>>> The trick to achieve (summarized) is the following: > >>>> Somewhere in your code maintain and update from remote an array of > >>>> Translators: > >>>> translators["en"] = new QTranslator(this); > >>>> translators["en"]->load( "tr_en", commonPath()+"/translations" ); > >>>> translators["de"] = new QTranslator(this); > >>>> translators["de"]->load( "tr_de", commonPath()+"/translations" ); > >>>> translators["fr"] = new QTranslator(this); > >>>> translators["fr"]->load( "tr_fr", commonPath()+"/translations" ); > >>>> translators["ru"] = new QTranslator(this); > >>>> translators["ru"]->load( "tr_ru", commonPath()+"/translations" ); > >>>> You can change these entry with new files downloaded at runtime. > >>>>
Re: [Interest] Dynamic translations for mobile apps at runtime?
Op 08/03/2016 om 23:21 schreef Jason H: Sounds like there should be a qApp->translations() that we can use to remove all currently installed translations? Without it, we have to do what you do. Just keep the translators you currently have active around, not all of them. It is useless to new a QTranslator for languages you are not actually using. When switching language, you can remove and then delete the already loaded ones after installing the translations for the newly selected language. So, something like this (untested code, typed in email editor): QString m_currentLanguage; QVector m_currentTranslations; //note that for any language, you may need multiple translation files! void Backend::selectLanguage( QString language ) { if (language == m_currentLanguage) return; QVector oldTranslators = m_currentTranslations; m_currentTranslations.clear(); //repeat for every translation file you need to install, ie for your own app, for Qt itself, for libraries... translator = new QTranslator(this); translator->load( language, commonPath()+"/translations" ); qApp->installTranslator(translator); m_currentTranslations.append(translator); //now, get rid of the old translators foreach(QTranslator* oldTranslator, oldTranslators) { qApp->removeTranslator(oldTranslator); delete oldTranslator; } } André Sent: Tuesday, March 08, 2016 at 3:44 PM From: Gianluca To: "Jason H" Cc: "interest@qt-project.org" Subject: Re: [Interest] Dynamic translations for mobile apps at runtime? qApp->installTranslator add a new translation into the stack. Does not remove the old ones. So, if the user click 10 times: Italian - English - Italian - English … etc… you got ten translator into the memory. That’s because the translation is searched into the order on which the translator are installed into the stack. That’s why I remove everything so there is only one translators at time into the memory. Il giorno 08/mar/2016, alle ore 18:46, Jason H ha scritto: I'm wondering why you load all those languages and then remove all but one of them? Being a mobile app, I have to be somewhat conscience of memory foot print. Do you see anything wrong with: void Backend::selectLanguage( QString language ) { translator = new QTranslator(this); translator->load( language, commonPath()+"/translations" ); qApp->installTranslator(translator); } ? Hello Jason, I got the same issue some times ago … and I found that it’s possible to use the translation feature of Qt … that seems static, but it’s not. And localize.biz it’s a wonderful site that allow you to modify Qt translation files directly on web and download the updated one. The trick to achieve (summarized) is the following: Somewhere in your code maintain and update from remote an array of Translators: translators["en"] = new QTranslator(this); translators["en"]->load( "tr_en", commonPath()+"/translations" ); translators["de"] = new QTranslator(this); translators["de"]->load( "tr_de", commonPath()+"/translations" ); translators["fr"] = new QTranslator(this); translators["fr"]->load( "tr_fr", commonPath()+"/translations" ); translators["ru"] = new QTranslator(this); translators["ru"]->load( "tr_ru", commonPath()+"/translations" ); You can change these entry with new files downloaded at runtime. Then you implement a method that you call at runtime for changing the translator, something like that: void Backend::selectLanguage( QString language ) { foreach( QString lang, translators.keys() ) { if ( lang == language ) { qApp->installTranslator( translators[lang] ); } else { qApp->removeTranslator( translators[lang] ); } } this->language = language; emit languageChanged(); } And then there is the final trick: You create a “fake” property that is always an empty string but it’s binded to languageChanged signal: Q_PROPERTY( QString es READ getES NOTIFY languageChanged ) And (the most annoying part), append this empty string to all string you want to change at runtime like that: qsTr("NEWSHUB")+backend.es And close the loop. What will happen is the following: the translator change at runtime and you trigger a languageChanged that trigger an update of all string that got backend.es appended that trigger the call of qsTr that take the new translation from the new translator. ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
Sounds like there should be a qApp->translations() that we can use to remove all currently installed translations? Without it, we have to do what you do. > Sent: Tuesday, March 08, 2016 at 3:44 PM > From: Gianluca > To: "Jason H" > Cc: "interest@qt-project.org" > Subject: Re: [Interest] Dynamic translations for mobile apps at runtime? > > qApp->installTranslator add a new translation into the stack. Does not remove > the old ones. > So, if the user click 10 times: Italian - English - Italian - English … etc… > you got ten translator into the memory. > That’s because the translation is searched into the order on which the > translator are installed into the stack. > > That’s why I remove everything so there is only one translators at time into > the memory. > > Il giorno 08/mar/2016, alle ore 18:46, Jason H ha scritto: > > > I'm wondering why you load all those languages and then remove all but one > > of them? Being a mobile app, I have to be somewhat conscience of memory > > foot print. Do you see anything wrong with: > > > > void Backend::selectLanguage( QString language ) { > >translator = new QTranslator(this); > >translator->load( language, commonPath()+"/translations" ); > >qApp->installTranslator(translator); > > } > > > > ? > > > > > >> Hello Jason, > >> I got the same issue some times ago … and I found that it’s possible to > >> use the translation feature of Qt … that seems static, but it’s not. > >> And localize.biz it’s a wonderful site that allow you to modify Qt > >> translation files directly on web and download the updated one. > >> > >> The trick to achieve (summarized) is the following: > >> Somewhere in your code maintain and update from remote an array of > >> Translators: > >>translators["en"] = new QTranslator(this); > >>translators["en"]->load( "tr_en", commonPath()+"/translations" ); > >>translators["de"] = new QTranslator(this); > >>translators["de"]->load( "tr_de", commonPath()+"/translations" ); > >>translators["fr"] = new QTranslator(this); > >>translators["fr"]->load( "tr_fr", commonPath()+"/translations" ); > >>translators["ru"] = new QTranslator(this); > >>translators["ru"]->load( "tr_ru", commonPath()+"/translations" ); > >> You can change these entry with new files downloaded at runtime. > >> > >> Then you implement a method that you call at runtime for changing the > >> translator, something like that: > >> > >> void Backend::selectLanguage( QString language ) { > >>foreach( QString lang, translators.keys() ) { > >>if ( lang == language ) { > >>qApp->installTranslator( translators[lang] ); > >>} else { > >>qApp->removeTranslator( translators[lang] ); > >>} > >>} > >>this->language = language; > >>emit languageChanged(); > >> } > >> And then there is the final trick: > >> You create a “fake” property that is always an empty string but it’s > >> binded to languageChanged signal: > >> > >> Q_PROPERTY( QString es READ getES NOTIFY languageChanged ) > >> > >> And (the most annoying part), append this empty string to all string you > >> want to change at runtime like that: > >> > >> qsTr("NEWSHUB")+backend.es > >> > >> And close the loop. > >> > >> What will happen is the following: the translator change at runtime and > >> you trigger a languageChanged that trigger an update of all string that > >> got backend.es appended that trigger the call of qsTr that take the new > >> translation from the new translator. > >> > > ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
qApp->installTranslator add a new translation into the stack. Does not remove the old ones. So, if the user click 10 times: Italian - English - Italian - English … etc… you got ten translator into the memory. That’s because the translation is searched into the order on which the translator are installed into the stack. That’s why I remove everything so there is only one translators at time into the memory. Il giorno 08/mar/2016, alle ore 18:46, Jason H ha scritto: > I'm wondering why you load all those languages and then remove all but one of > them? Being a mobile app, I have to be somewhat conscience of memory foot > print. Do you see anything wrong with: > > void Backend::selectLanguage( QString language ) { >translator = new QTranslator(this); >translator->load( language, commonPath()+"/translations" ); >qApp->installTranslator(translator); > } > > ? > > >> Hello Jason, >> I got the same issue some times ago … and I found that it’s possible to use >> the translation feature of Qt … that seems static, but it’s not. >> And localize.biz it’s a wonderful site that allow you to modify Qt >> translation files directly on web and download the updated one. >> >> The trick to achieve (summarized) is the following: >> Somewhere in your code maintain and update from remote an array of >> Translators: >> translators["en"] = new QTranslator(this); >> translators["en"]->load( "tr_en", commonPath()+"/translations" ); >> translators["de"] = new QTranslator(this); >> translators["de"]->load( "tr_de", commonPath()+"/translations" ); >> translators["fr"] = new QTranslator(this); >> translators["fr"]->load( "tr_fr", commonPath()+"/translations" ); >> translators["ru"] = new QTranslator(this); >> translators["ru"]->load( "tr_ru", commonPath()+"/translations" ); >> You can change these entry with new files downloaded at runtime. >> >> Then you implement a method that you call at runtime for changing the >> translator, something like that: >> >> void Backend::selectLanguage( QString language ) { >> foreach( QString lang, translators.keys() ) { >> if ( lang == language ) { >> qApp->installTranslator( translators[lang] ); >> } else { >> qApp->removeTranslator( translators[lang] ); >> } >> } >> this->language = language; >> emit languageChanged(); >> } >> And then there is the final trick: >> You create a “fake” property that is always an empty string but it’s binded >> to languageChanged signal: >> >> Q_PROPERTY( QString es READ getES NOTIFY languageChanged ) >> >> And (the most annoying part), append this empty string to all string you >> want to change at runtime like that: >> >> qsTr("NEWSHUB")+backend.es >> >> And close the loop. >> >> What will happen is the following: the translator change at runtime and you >> trigger a languageChanged that trigger an update of all string that got >> backend.es appended that trigger the call of qsTr that take the new >> translation from the new translator. >> ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
I'm wondering why you load all those languages and then remove all but one of them? Being a mobile app, I have to be somewhat conscience of memory foot print. Do you see anything wrong with: void Backend::selectLanguage( QString language ) { translator = new QTranslator(this); translator->load( language, commonPath()+"/translations" ); qApp->installTranslator(translator); } ? > Hello Jason, > I got the same issue some times ago … and I found that it’s possible to use > the translation feature of Qt … that seems static, but it’s not. > And localize.biz it’s a wonderful site that allow you to modify Qt > translation files directly on web and download the updated one. > > The trick to achieve (summarized) is the following: > Somewhere in your code maintain and update from remote an array of > Translators: > translators["en"] = new QTranslator(this); > translators["en"]->load( "tr_en", commonPath()+"/translations" ); > translators["de"] = new QTranslator(this); > translators["de"]->load( "tr_de", commonPath()+"/translations" ); > translators["fr"] = new QTranslator(this); > translators["fr"]->load( "tr_fr", commonPath()+"/translations" ); > translators["ru"] = new QTranslator(this); > translators["ru"]->load( "tr_ru", commonPath()+"/translations" ); > You can change these entry with new files downloaded at runtime. > > Then you implement a method that you call at runtime for changing the > translator, something like that: > > void Backend::selectLanguage( QString language ) { > foreach( QString lang, translators.keys() ) { > if ( lang == language ) { > qApp->installTranslator( translators[lang] ); > } else { > qApp->removeTranslator( translators[lang] ); > } > } > this->language = language; > emit languageChanged(); > } > And then there is the final trick: > You create a “fake” property that is always an empty string but it’s binded > to languageChanged signal: > > Q_PROPERTY( QString es READ getES NOTIFY languageChanged ) > > And (the most annoying part), append this empty string to all string you want > to change at runtime like that: > > qsTr("NEWSHUB")+backend.es > > And close the loop. > > What will happen is the following: the translator change at runtime and you > trigger a languageChanged that trigger an update of all string that got > backend.es appended that trigger the call of qsTr that take the new > translation from the new translator. > ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
Just to be clear, the lupdate did not found the string and skip it, nothing new is found or updated. The usage after work properly. On Fri, Mar 4, 2016 at 9:06 AM, Jérôme Godbout wrote: > > "-tr-function-alias qsTr=MySingleton.myqsTr" > That's what I tried but it didn't work sadly. That would have solve it > nicely. > > On Thu, Mar 3, 2016 at 5:43 PM, Jason H wrote: > >> What if you did "-tr-function-alias qsTr=MySingleton.myqsTr" ? >> >> *Sent:* Thursday, March 03, 2016 at 5:31 PM >> *From:* "Jérôme Godbout" >> *To:* "Julien Cugnière" >> *Cc:* "interest@qt-project.org" >> *Subject:* Re: [Interest] Dynamic translations for mobile apps at >> runtime? >> I test it out, it work as long as the function is a direct function >> access, you can't use module call like >> >> MySingleton.myqsTr("My String") // don't work, lupdate does get this one >> myqsTr("My String") // work >> >> Could have put the function into it's own javascript .pragma library and >> just import it in needed file. Is their a way to declare a global >> javascript function into the engine with the binding still working? I just >> don't want to add the function on each file if possible: >> >> *function myqsTr(str) { return qsTr(str) + I18n.revaluate; }* >> >> I may try to add the function into the RootItem of the QQuickView and >> hope the context hierarchies will always find it everywhere to see if this >> work. >> >> That's so close to work well... >> >> >> >> On Thu, Mar 3, 2016 at 3:41 PM, Jérôme Godbout >> wrote: >>> >>> Nice, I didn't knew about "-tr-function-alias", indeed this seem like >>> the right thing to do. Will try this out. About speed, for the number of >>> time you use the change language during runtime, it doesn't really matter, >>> if it take a few ms more. >>> >>> Thanks for the tips! >>> >>> On Thu, Mar 3, 2016 at 2:37 PM, Julien Cugnière < >>> julien.cugni...@gmail.com> wrote: >>>> >>>> 2016-03-03 18:50 GMT+01:00 Jérôme Godbout : >>>> > We did the same thing into Qml, we have a C++ singleton equivalent to >>>> your >>>> > backend, that select the current language files and emit the QString >>>> > property changed. >>>> > qsTr("String to convert") + I18n.revaluate >>>> > >>>> > I wish they made underlying hook to revaluate the qsTr() with a signal >>>> > connected like if the qsTr() have changed. This pollute the code all >>>> over, >>>> > only to be able to swap language on the fly. >>>> >>>> Just an idea : you might be able to hide that I18n.revaluate with >>>> something along the lines of : >>>> >>>> function myTr(s) { >>>> return qsTr(s) + I18n.revaluate; >>>> } >>>> >>>> Text { >>>> text: myTr("String to convert") >>>> } >>>> >>>> Then you need to get lupdate to understand "myTr", which can be done >>>> with the command line option "-tr-function-alias qsTr=myTr". >>>> >>>> Although this incurs the overhead of a function call, which might >>>> prevent QML from using its fast path for bindings evaluation. Not sure >>>> if it matters. >>>> >>>> Julien Cugnière >>> >>> ___ Interest mailing list >> Interest@qt-project.org >> http://lists.qt-project.org/mailman/listinfo/interest >> > > ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
> "-tr-function-alias qsTr=MySingleton.myqsTr" That's what I tried but it didn't work sadly. That would have solve it nicely. On Thu, Mar 3, 2016 at 5:43 PM, Jason H wrote: > What if you did "-tr-function-alias qsTr=MySingleton.myqsTr" ? > > *Sent:* Thursday, March 03, 2016 at 5:31 PM > *From:* "Jérôme Godbout" > *To:* "Julien Cugnière" > *Cc:* "interest@qt-project.org" > *Subject:* Re: [Interest] Dynamic translations for mobile apps at runtime? > I test it out, it work as long as the function is a direct function > access, you can't use module call like > > MySingleton.myqsTr("My String") // don't work, lupdate does get this one > myqsTr("My String") // work > > Could have put the function into it's own javascript .pragma library and > just import it in needed file. Is their a way to declare a global > javascript function into the engine with the binding still working? I just > don't want to add the function on each file if possible: > > *function myqsTr(str) { return qsTr(str) + I18n.revaluate; }* > > I may try to add the function into the RootItem of the QQuickView and hope > the context hierarchies will always find it everywhere to see if this work. > > That's so close to work well... > > > > On Thu, Mar 3, 2016 at 3:41 PM, Jérôme Godbout > wrote: >> >> Nice, I didn't knew about "-tr-function-alias", indeed this seem like >> the right thing to do. Will try this out. About speed, for the number of >> time you use the change language during runtime, it doesn't really matter, >> if it take a few ms more. >> >> Thanks for the tips! >> >> On Thu, Mar 3, 2016 at 2:37 PM, Julien Cugnière < >> julien.cugni...@gmail.com> wrote: >>> >>> 2016-03-03 18:50 GMT+01:00 Jérôme Godbout : >>> > We did the same thing into Qml, we have a C++ singleton equivalent to >>> your >>> > backend, that select the current language files and emit the QString >>> > property changed. >>> > qsTr("String to convert") + I18n.revaluate >>> > >>> > I wish they made underlying hook to revaluate the qsTr() with a signal >>> > connected like if the qsTr() have changed. This pollute the code all >>> over, >>> > only to be able to swap language on the fly. >>> >>> Just an idea : you might be able to hide that I18n.revaluate with >>> something along the lines of : >>> >>> function myTr(s) { >>> return qsTr(s) + I18n.revaluate; >>> } >>> >>> Text { >>> text: myTr("String to convert") >>> } >>> >>> Then you need to get lupdate to understand "myTr", which can be done >>> with the command line option "-tr-function-alias qsTr=myTr". >>> >>> Although this incurs the overhead of a function call, which might >>> prevent QML from using its fast path for bindings evaluation. Not sure >>> if it matters. >>> >>> Julien Cugnière >> >> ___ Interest mailing list > Interest@qt-project.org > http://lists.qt-project.org/mailman/listinfo/interest > ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
You will have the same overhead whenever the text to translate changes. If it is static during the application life cycle then this should not be an issue either. On Thu, Mar 3, 2016 at 11:41 PM Jérôme Godbout wrote: > Nice, I didn't knew about "-tr-function-alias", indeed this seem like the > right thing to do. Will try this out. About speed, for the number of time > you use the change language during runtime, it doesn't really matter, if it > take a few ms more. > > Thanks for the tips! > > On Thu, Mar 3, 2016 at 2:37 PM, Julien Cugnière > wrote: > >> 2016-03-03 18:50 GMT+01:00 Jérôme Godbout : >> > We did the same thing into Qml, we have a C++ singleton equivalent to >> your >> > backend, that select the current language files and emit the QString >> > property changed. >> > qsTr("String to convert") + I18n.revaluate >> > >> > I wish they made underlying hook to revaluate the qsTr() with a signal >> > connected like if the qsTr() have changed. This pollute the code all >> over, >> > only to be able to swap language on the fly. >> >> Just an idea : you might be able to hide that I18n.revaluate with >> something along the lines of : >> >> function myTr(s) { >> return qsTr(s) + I18n.revaluate; >> } >> >> Text { >> text: myTr("String to convert") >> } >> >> Then you need to get lupdate to understand "myTr", which can be done >> with the command line option "-tr-function-alias qsTr=myTr". >> >> Although this incurs the overhead of a function call, which might >> prevent QML from using its fast path for bindings evaluation. Not sure >> if it matters. >> >> Julien Cugnière >> > > ___ > Interest mailing list > Interest@qt-project.org > http://lists.qt-project.org/mailman/listinfo/interest > ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
What if you did "-tr-function-alias qsTr=MySingleton.myqsTr" ? Sent: Thursday, March 03, 2016 at 5:31 PM From: "Jérôme Godbout" To: "Julien Cugnière" Cc: "interest@qt-project.org" Subject: Re: [Interest] Dynamic translations for mobile apps at runtime? I test it out, it work as long as the function is a direct function access, you can't use module call like MySingleton.myqsTr("My String") // don't work, lupdate does get this one myqsTr("My String") // work Could have put the function into it's own _javascript_ .pragma library and just import it in needed file. Is their a way to declare a global _javascript_ function into the engine with the binding still working? I just don't want to add the function on each file if possible: function myqsTr(str) { return qsTr(str) + I18n.revaluate; } I may try to add the function into the RootItem of the QQuickView and hope the context hierarchies will always find it everywhere to see if this work. That's so close to work well... On Thu, Mar 3, 2016 at 3:41 PM, Jérôme Godbout <jer...@bodycad.com> wrote: Nice, I didn't knew about "-tr-function-alias", indeed this seem like the right thing to do. Will try this out. About speed, for the number of time you use the change language during runtime, it doesn't really matter, if it take a few ms more. Thanks for the tips! On Thu, Mar 3, 2016 at 2:37 PM, Julien Cugnière <julien.cugni...@gmail.com> wrote: 2016-03-03 18:50 GMT+01:00 Jérôme Godbout <jer...@bodycad.com>: > We did the same thing into Qml, we have a C++ singleton equivalent to your > backend, that select the current language files and emit the QString > property changed. > qsTr("String to convert") + I18n.revaluate > > I wish they made underlying hook to revaluate the qsTr() with a signal > connected like if the qsTr() have changed. This pollute the code all over, > only to be able to swap language on the fly. Just an idea : you might be able to hide that I18n.revaluate with something along the lines of : function myTr(s) { return qsTr(s) + I18n.revaluate; } Text { text: myTr("String to convert") } Then you need to get lupdate to understand "myTr", which can be done with the command line option "-tr-function-alias qsTr=myTr". Although this incurs the overhead of a function call, which might prevent QML from using its fast path for bindings evaluation. Not sure if it matters. Julien Cugnière ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
I test it out, it work as long as the function is a direct function access, you can't use module call like MySingleton.myqsTr("My String") // don't work, lupdate does get this one myqsTr("My String") // work Could have put the function into it's own javascript .pragma library and just import it in needed file. Is their a way to declare a global javascript function into the engine with the binding still working? I just don't want to add the function on each file if possible: *function myqsTr(str) { return qsTr(str) + I18n.revaluate; }* I may try to add the function into the RootItem of the QQuickView and hope the context hierarchies will always find it everywhere to see if this work. That's so close to work well... On Thu, Mar 3, 2016 at 3:41 PM, Jérôme Godbout wrote: > Nice, I didn't knew about "-tr-function-alias", indeed this seem like the > right thing to do. Will try this out. About speed, for the number of time > you use the change language during runtime, it doesn't really matter, if it > take a few ms more. > > Thanks for the tips! > > On Thu, Mar 3, 2016 at 2:37 PM, Julien Cugnière > wrote: > >> 2016-03-03 18:50 GMT+01:00 Jérôme Godbout : >> > We did the same thing into Qml, we have a C++ singleton equivalent to >> your >> > backend, that select the current language files and emit the QString >> > property changed. >> > qsTr("String to convert") + I18n.revaluate >> > >> > I wish they made underlying hook to revaluate the qsTr() with a signal >> > connected like if the qsTr() have changed. This pollute the code all >> over, >> > only to be able to swap language on the fly. >> >> Just an idea : you might be able to hide that I18n.revaluate with >> something along the lines of : >> >> function myTr(s) { >> return qsTr(s) + I18n.revaluate; >> } >> >> Text { >> text: myTr("String to convert") >> } >> >> Then you need to get lupdate to understand "myTr", which can be done >> with the command line option "-tr-function-alias qsTr=myTr". >> >> Although this incurs the overhead of a function call, which might >> prevent QML from using its fast path for bindings evaluation. Not sure >> if it matters. >> >> Julien Cugnière >> > > ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
Nice, I didn't knew about "-tr-function-alias", indeed this seem like the right thing to do. Will try this out. About speed, for the number of time you use the change language during runtime, it doesn't really matter, if it take a few ms more. Thanks for the tips! On Thu, Mar 3, 2016 at 2:37 PM, Julien Cugnière wrote: > 2016-03-03 18:50 GMT+01:00 Jérôme Godbout : > > We did the same thing into Qml, we have a C++ singleton equivalent to > your > > backend, that select the current language files and emit the QString > > property changed. > > qsTr("String to convert") + I18n.revaluate > > > > I wish they made underlying hook to revaluate the qsTr() with a signal > > connected like if the qsTr() have changed. This pollute the code all > over, > > only to be able to swap language on the fly. > > Just an idea : you might be able to hide that I18n.revaluate with > something along the lines of : > > function myTr(s) { > return qsTr(s) + I18n.revaluate; > } > > Text { > text: myTr("String to convert") > } > > Then you need to get lupdate to understand "myTr", which can be done > with the command line option "-tr-function-alias qsTr=myTr". > > Although this incurs the overhead of a function call, which might > prevent QML from using its fast path for bindings evaluation. Not sure > if it matters. > > Julien Cugnière > ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
2016-03-03 18:50 GMT+01:00 Jérôme Godbout : > We did the same thing into Qml, we have a C++ singleton equivalent to your > backend, that select the current language files and emit the QString > property changed. > qsTr("String to convert") + I18n.revaluate > > I wish they made underlying hook to revaluate the qsTr() with a signal > connected like if the qsTr() have changed. This pollute the code all over, > only to be able to swap language on the fly. Just an idea : you might be able to hide that I18n.revaluate with something along the lines of : function myTr(s) { return qsTr(s) + I18n.revaluate; } Text { text: myTr("String to convert") } Then you need to get lupdate to understand "myTr", which can be done with the command line option "-tr-function-alias qsTr=myTr". Although this incurs the overhead of a function call, which might prevent QML from using its fast path for bindings evaluation. Not sure if it matters. Julien Cugnière ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
We did the same thing into Qml, we have a C++ singleton equivalent to your backend, that select the current language files and emit the QString property changed. qsTr("String to convert") + I18n.revaluate I wish they made underlying hook to revaluate the qsTr() with a signal connected like if the qsTr() have changed. This pollute the code all over, only to be able to swap language on the fly. We also maintain a .ts and .qm per Qml module. We made a Visual Studio Task target to rebuild them automatically per application that take the project Language.txt where each wanted i18n wanted is specified 1/line (en, fr, fr-CA, es, etc...). On Thu, Mar 3, 2016 at 11:04 AM, Gian Maxera wrote: > Hello Jason, > I got the same issue some times ago … and I found that it’s possible to > use the translation feature of Qt … that seems static, but it’s not. > And localize.biz it’s a wonderful site that allow you to modify Qt > translation files directly on web and download the updated one. > > The trick to achieve (summarized) is the following: > Somewhere in your code maintain and update from remote an array of > Translators: > translators["en"] = new QTranslator(this); > translators["en"]->load( "tr_en", commonPath()+"/translations" ); > translators["de"] = new QTranslator(this); > translators["de"]->load( "tr_de", commonPath()+"/translations" ); > translators["fr"] = new QTranslator(this); > translators["fr"]->load( "tr_fr", commonPath()+"/translations" ); > translators["ru"] = new QTranslator(this); > translators["ru"]->load( "tr_ru", commonPath()+"/translations" ); > You can change these entry with new files downloaded at runtime. > > Then you implement a method that you call at runtime for changing the > translator, something like that: > > void Backend::selectLanguage( QString language ) { > foreach( QString lang, translators.keys() ) { > if ( lang == language ) { > qApp->installTranslator( translators[lang] ); > } else { > qApp->removeTranslator( translators[lang] ); > } > } > this->language = language; > emit languageChanged(); > } > > And then there is the final trick: > You create a “fake” property that is always an empty string but it’s > binded to languageChanged signal: > > Q_PROPERTY( QString es READ getES NOTIFY languageChanged ) > > And (the most annoying part), append this empty string to all string you > want to change at runtime like that: > > qsTr("NEWSHUB")+backend.es > > And close the loop. > > What will happen is the following: the translator change at runtime and > you trigger a languageChanged that trigger an update of all string that got > backend.es appended that trigger the call of qsTr that take the new > translation from the new translator. > > Ciao, > Gianluca. > > > > On 3 Mar 2016, at 15:51, Jason H wrote: > > > > First, I'm not talking about the standard translation features of Qt. > Those are static - the translation file is generated and deployed with the > app. I now need to support an ever-changing list of translations. I want my > mobile app to download the current set of translations and use that. In > addition, it would be nice if it was some kind of open format. We have a > web app where these will be maintained, because they need to be shared with > the web. The web is backed by a database, and exporting these to JSON would > be ideal, along with Javascript versions for the Web UI, so we don't have > to create and maintain two translation systems. > > > > > > What support is there for this? > > > > > > > > > > ___ > > Interest mailing list > > Interest@qt-project.org > > http://lists.qt-project.org/mailman/listinfo/interest > > ___ > Interest mailing list > Interest@qt-project.org > http://lists.qt-project.org/mailman/listinfo/interest > ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
Absolutely fantastic!!! THANKS! > Sent: Thursday, March 03, 2016 at 11:04 AM > From: "Gian Maxera" > To: "Jason H" > Cc: "interest@qt-project.org" > Subject: Re: [Interest] Dynamic translations for mobile apps at runtime? > > Hello Jason, > I got the same issue some times ago … and I found that it’s possible to use > the translation feature of Qt … that seems static, but it’s not. > And localize.biz it’s a wonderful site that allow you to modify Qt > translation files directly on web and download the updated one. > > The trick to achieve (summarized) is the following: > Somewhere in your code maintain and update from remote an array of > Translators: > translators["en"] = new QTranslator(this); > translators["en"]->load( "tr_en", commonPath()+"/translations" ); > translators["de"] = new QTranslator(this); > translators["de"]->load( "tr_de", commonPath()+"/translations" ); > translators["fr"] = new QTranslator(this); > translators["fr"]->load( "tr_fr", commonPath()+"/translations" ); > translators["ru"] = new QTranslator(this); > translators["ru"]->load( "tr_ru", commonPath()+"/translations" ); > You can change these entry with new files downloaded at runtime. > > Then you implement a method that you call at runtime for changing the > translator, something like that: > > void Backend::selectLanguage( QString language ) { > foreach( QString lang, translators.keys() ) { > if ( lang == language ) { > qApp->installTranslator( translators[lang] ); > } else { > qApp->removeTranslator( translators[lang] ); > } > } > this->language = language; > emit languageChanged(); > } > > And then there is the final trick: > You create a “fake” property that is always an empty string but it’s binded > to languageChanged signal: > > Q_PROPERTY( QString es READ getES NOTIFY languageChanged ) > > And (the most annoying part), append this empty string to all string you want > to change at runtime like that: > > qsTr("NEWSHUB")+backend.es > > And close the loop. > > What will happen is the following: the translator change at runtime and you > trigger a languageChanged that trigger an update of all string that got > backend.es appended that trigger the call of qsTr that take the new > translation from the new translator. > > Ciao, > Gianluca. > > > > On 3 Mar 2016, at 15:51, Jason H wrote: > > > > First, I'm not talking about the standard translation features of Qt. Those > > are static - the translation file is generated and deployed with the app. I > > now need to support an ever-changing list of translations. I want my mobile > > app to download the current set of translations and use that. In addition, > > it would be nice if it was some kind of open format. We have a web app > > where these will be maintained, because they need to be shared with the > > web. The web is backed by a database, and exporting these to JSON would be > > ideal, along with Javascript versions for the Web UI, so we don't have to > > create and maintain two translation systems. > > > > > > What support is there for this? > > > > > > > > > > ___ > > Interest mailing list > > Interest@qt-project.org > > http://lists.qt-project.org/mailman/listinfo/interest > > ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
Re: [Interest] Dynamic translations for mobile apps at runtime?
Hello Jason, I got the same issue some times ago … and I found that it’s possible to use the translation feature of Qt … that seems static, but it’s not. And localize.biz it’s a wonderful site that allow you to modify Qt translation files directly on web and download the updated one. The trick to achieve (summarized) is the following: Somewhere in your code maintain and update from remote an array of Translators: translators["en"] = new QTranslator(this); translators["en"]->load( "tr_en", commonPath()+"/translations" ); translators["de"] = new QTranslator(this); translators["de"]->load( "tr_de", commonPath()+"/translations" ); translators["fr"] = new QTranslator(this); translators["fr"]->load( "tr_fr", commonPath()+"/translations" ); translators["ru"] = new QTranslator(this); translators["ru"]->load( "tr_ru", commonPath()+"/translations" ); You can change these entry with new files downloaded at runtime. Then you implement a method that you call at runtime for changing the translator, something like that: void Backend::selectLanguage( QString language ) { foreach( QString lang, translators.keys() ) { if ( lang == language ) { qApp->installTranslator( translators[lang] ); } else { qApp->removeTranslator( translators[lang] ); } } this->language = language; emit languageChanged(); } And then there is the final trick: You create a “fake” property that is always an empty string but it’s binded to languageChanged signal: Q_PROPERTY( QString es READ getES NOTIFY languageChanged ) And (the most annoying part), append this empty string to all string you want to change at runtime like that: qsTr("NEWSHUB")+backend.es And close the loop. What will happen is the following: the translator change at runtime and you trigger a languageChanged that trigger an update of all string that got backend.es appended that trigger the call of qsTr that take the new translation from the new translator. Ciao, Gianluca. > On 3 Mar 2016, at 15:51, Jason H wrote: > > First, I'm not talking about the standard translation features of Qt. Those > are static - the translation file is generated and deployed with the app. I > now need to support an ever-changing list of translations. I want my mobile > app to download the current set of translations and use that. In addition, it > would be nice if it was some kind of open format. We have a web app where > these will be maintained, because they need to be shared with the web. The > web is backed by a database, and exporting these to JSON would be ideal, > along with Javascript versions for the Web UI, so we don't have to create and > maintain two translation systems. > > > What support is there for this? > > > > > ___ > Interest mailing list > Interest@qt-project.org > http://lists.qt-project.org/mailman/listinfo/interest ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
[Interest] Dynamic translations for mobile apps at runtime?
First, I'm not talking about the standard translation features of Qt. Those are static - the translation file is generated and deployed with the app. I now need to support an ever-changing list of translations. I want my mobile app to download the current set of translations and use that. In addition, it would be nice if it was some kind of open format. We have a web app where these will be maintained, because they need to be shared with the web. The web is backed by a database, and exporting these to JSON would be ideal, along with Javascript versions for the Web UI, so we don't have to create and maintain two translation systems. What support is there for this? ___ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest