Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translated string as property init value causes invalid calculation of label width #9564

Open
mbgonicus opened this issue Aug 30, 2018 · 0 comments

Comments

Projects
None yet
1 participant
@mbgonicus
Copy link
Contributor

commented Aug 30, 2018

This issue is caused at load time, thus it is not reproducible in the playground. The code below must be used in a "real" qx project in order to invoke the bug.

Preconditions:

  • The init value of a property is a LocalizedString object, i.e. the return value of qx.locale.Manager.tr.
  • This init value is used as a value of a label widget.
  • The translation of that string/messageId is significantly longer than the original (message id).

Expectation: The width of the label is calculated based on the translation.
Screenshot:
should

Is: The width of the label is based on the untranslated string although showing the translated one.
Screenshot:
is

This code will reproduce it. Don't forget the translation for the locale you're using.

qx.Class.define("foo.Application", {
  extend : qx.application.Standalone,

  properties: {
    labelText: {
      init: qx.locale.Manager.tr("A long string")
    }
  },

  members: {
    main : function() {
      this.base(arguments);
      var lbl = new qx.ui.basic.Label(this.getLabelText());
      lbl.setBackgroundColor("#ccc");
      this.getRoot().add(lbl, {top: 10, left: 10});
    }
  }
});
msgid "A long string"
msgstr "Ein sehr, sehr, sehr langer String"

Explanation:
The problem is that when the class/property is loaded, the init value gets evaluated. The tr function returns a qx.locale.LocalizedString object which usually is translated. But at this point in the loading process, the translations have not been loaded yet. Thus, the LocalizedString object uses the untranslated message id as a fallback.

So when assigned as a value to the qx.ui.basic.Label instance, the LocalizedString is not translated. In the label, when the value is written to the content element, it will be translated (see qx/ui/basic/Label.js#L541). Thus the translated string is visible. However, the size computation is still based on the value of the qx.ui.basic.Label instance, which is untranslated (see qx/ui/basic/Label.js#L388).

So the computed width is based on the untranslated string while showing the translated one.

Workarounds/Possible fixes

  1. One option would be to explicitly call the translate method on the LocalizedString when assigning the value to the label (new qx.ui.basic.Label(this.getLabelText().translate())). But any user of the framework must be aware of this and can forget to do it in some cases.

  2. Another option would be to invoke the changeLocale event on the qx.locale.Manager instance. This would cause the LocalizedString objects to re-translate their value. I'm unsure where the best place for this would be, but placing this code at the end of qx.locale.Manager#construct does the trick:

    qx.bom.Lifecycle.onReady(function() {
      this.fireDataEvent("changeLocale", this.getLocale(), null);
    }, this);

    The obvious downside is the additional event which is fired after the application is loaded and that qx.dynlocale must be set to true. If the dynamic locales are not enabled, this will not work, obviously.

  3. The order at load time must be changed in that the translations are loaded before the individual classes. I don't know if this is even possible or if it would be a good idea. Maybe someone with more insight into the load process could evaluate?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.