PDA

View Full Version : Arabic text rendering; issues with parentheses



TropicalPenguin
1st February 2011, 20:15
When I set the current language to Arabic in my UI, just for testing purposes, I see that some English strings (displayed in a language selection dialog, if you're wondering why) are rendered in a way I'm not sure will be appropriate. With the non-Arabic translations, for example, a string that would display as "English (United Kingdom)" will be rendered as "(English (United Kingdom" when the Arabic translator is loaded.

Does anyone know an appropriate way to handle this?

These strings are added to a QComboBox by asking a QTranslator for the translation of the word "English" (something I've used as a hook for finding the name of the language provided by the translation (just as the 'i18n' example did)):



QComboBox* languageCombo = new QComboBox(this);

Translator test;
QStringList translations = test.availableTranslations();
QString translation;
foreach (translation, translations) {
// Remove .qm suffix
translation.chop(3);
test.load(translation);
languageCombo->addItem(test.languageName(), translation);
}

Client* client = Client::instance();

languageCombo->setCurrentIndex(
languageCombo->findText(client->translator()->languageName()));


Where languageName() just has:


return translate("Translator", SourceLanguage, 0, -1);

Where SourceLanguage is just


static const char* SourceLanguage = QT_TRANSLATE_NOOP("Translator", "English");

Any insights much appreciated.

TropicalPenguin
2nd February 2011, 18:01
Looked in to it a bit more, and found the stuff about determining layout direction of particular translations http://www.qtcentre.org/threads/11372-LayoutDirection-autodetection, so this leads me to wonder:

Are the item text and item data by default stored in columns 0 and 1 of the default model of QComboBox?

Currently I have the name of the translation file set as the 'item data', so is there any more of a shortcut way to setting the layout direction for particular items in the combo box than by setting a custom item delegate, loading a QTranslator for this item data, and checking the translation for "QT_LAYOUT_DIRECTION" (or whatever other key I use myself).

Since I've loaded the translator in putting the items in the list, it just seems a waste to have a delegate check this information every time the items are displayed.

If it is necessary that I use a custom delegate, I'm not even quite sure how to customise this aspect of the display: I've taken a look at the QAbstractItemDelegate documentation and seen it's example paint() method, which calls


QApplication::style()->drawControl(QStyle::CE_ProgressBar,
&progressBarOption, painter);

To draw a progress bar... how would I set LTR or RTL rendering for the item text of the items in a QComboBox?

... Actually, just looked further and found QStyle::CE_ComboBoxLabel, which apparently takes a regular QStyleOption (since it's not in the table in drawControl()'s docs...whew), and I see that has a QLayoutDirection member. I suppose that's right?

So, I suppose any shortcut that may exist (outside setting a custom delegate, which seems wasteful) would be through setting a QStyle::CE_ComboBoxLabel QStyleOption on particular items that I add to the combo box.

Is there any way to do this?

EDIT:

I see that someone has noted here http://comments.gmane.org/gmane.comp.lib.qt.general/31052 that "However, If you want to do this for a non loadede language, IMHO, loading the translation for that language is an overkill, and your hack is 'good enough'.", which is why it seems preferable to do this outside a delegate.

TropicalPenguin
3rd February 2011, 14:19
For anyone interested, I reached a solution, described below (took half a day to figure out *sigh*, but then I'm new to this).

I installed a custom delegate on the combo box that would render the strings of LTR languages LTR, and the strings of RTL languages RTL.

To do this, rather than just setting the path of the translation as the item data, I set a custom structure containing the path and a boolean value (since I'd loaded the translation to add it to the combo box, I didn't want to load it every time the delegate painted to figure out which direction the translation was).

This structure of course had to be registered with QMetaType using Q_REGISTER_METATYPE, so that it would work with QVariant.

Finally, the delegate was a subclass of QStyledItemDelegate, with the contents of its paint() method as follows:



initStyleOption(&directionOption, index);
directionOption = option;

InterfaceTranslationInfo info = qvariant_cast<InterfaceTranslationInfo> (index.data(Qt::UserRole));
if (info.rtl) {
directionOption.direction = Qt::RightToLeft;
} else {
directionOption.direction = Qt::LeftToRight;
}

QStyledItemDelegate::paint(painter, directionOption, index);


Seems easy, but met a lot of dead-ends on the way. If anyone could point me to better ways of doing this, it would still be much appreciated, but perhaps this can be of use to someone.

srazi
4th February 2011, 15:49
... for example, a string that would display as "English (United Kingdom)" will be rendered as "(English (United Kingdom" when the Arabic translator is loaded.

one solution is using "Unicode control character". For this example I mean "LRM".

LRM:
Code:U+200E LEFT-TO-RIGHT MARK: Left-to-right zero-width character

for example:
WITHOUT <LRM>:
‫زبان English (United Kingdom) انگلیسی

WITH <LRM>:
‫زبان English (United Kingdom)‎ انگلیسی

I use <LRM> after closed parenthesis:
‫زبان English (United Kingdom)<LRM>‎ انگلیسی

for more info. on bidirectional algorithm see this:
Unicode Standard Annex #9: UNICODE BIDIRECTIONAL ALGORITHM (http://unicode.org/reports/tr9/)

kishore7771
10th September 2013, 09:53
one solution is using "Unicode control character". For this example I mean "LRM".

LRM:
Code:U+200E LEFT-TO-RIGHT MARK: Left-to-right zero-width character

for example:
WITHOUT <LRM>:
‫زبان English (United Kingdom) انگلیسی

WITH <LRM>:
‫زبان English (United Kingdom)‎ انگلیسی

I use <LRM> after closed parenthesis:
‫زبان English (United Kingdom)<LRM>‎ انگلیسی

for more info. on bidirectional algorithm see this:
Unicode Standard Annex #9: UNICODE BIDIRECTIONAL ALGORITHM (http://unicode.org/reports/tr9/)



Thanks for the reply. LRM is causing eliding issue.
With out LRM string eliding is correct on right side if string is too long to fit in the given widget.
After inserting LRM "(" ")" open close parenthesis is working fine. But ellipsis are getting added on left side which is not giving correct meaning for an Arabic reading person.

Is it possible to resolve this with out using LRM?