Random rants from a KDE user which also works on making KDE more Hebrew friendly.

Friday, October 3, 2008

QTextEdit and QTextCursor fun

My problem is simple: when I open lokalize, it's using the RTL interface and I see the original English text in RTL mode. This just looks bad, as it always needs to be LTR. Should be simple, not?

So I started writing some small tests (yes David, I do small scale tests!). In this test I am doing the exact opposite: I am forcing an RTL paragraph on an LTR interface.

First test:
QTextEdit *e1 = new QTextEdit;
QTextOption o;

o = e1->document()->defaultTextOption();
o.setAlignment(Qt::AlignLeft);
o.setTextDirection(Qt::RightToLeft);
e1->document()->setDefaultTextOption(o);
e1->setText( QLatin1String("1) Currect direction on QTextEdit, wanted RTL!") );

This seems to work fine. However, lokalize creates a QTextCursor and inserts text to that cursor. Ok, second test:
QTextEdit *e2 = new QTextEdit;
QTextCursor tc = e2->textCursor();
QTextCharFormat tcf = tc.blockCharFormat();

tcf.setLayoutDirection( Qt::RightToLeft );
tc.insertText( QLatin1String("2) Wrong direction on QTextEdit, wanted RTL!"), tcf );
e2->setTextCursor(tc);

This does not work. The text is still LTR, even tough I modified the text char format of this text cursor. I sent a bug to Nokia with this mini-application, and it's marked there as N229677.

I talked with a fellow hacker here, and he sent me this piece of code (which does work), third test:
QTextEdit *e3 = new QTextEdit;
QTextCursor tc = e3->textCursor();
QTextBlockFormat tbf = tc.blockFormat();

tbf.setLayoutDirection( Qt::RightToLeft );
tc.setBlockFormat(tbf);
tc.insertText( QLatin1String("3) Correct direction on QTextEdit, wanted RTL!") );
e3->setTextCursor(tc);
Now, I don't really understand why the second test does not work. IMHO, the higher level API used in the second test should work, but I assume that using this low level (which is used in the third test) is fine as well... I will commit this to lokalize as soon as I test on a live lokalize, but it's just crashing on startup since 3 days ago (yes, I am using runk). Is this a known issue?

5 comments:

idkn said...

Diego, you have "auto" alignment that is determined by the chars. But what happen when you wish to force the direction of the text to right, or force it to the left ?

What should be stronger ? The instructions you provide or the character type ?

slougi said...

Try this:

QTextCharFormat tcf = tc.blockCharFormat();
tcf.setLayoutDirection( Qt::RightToLeft );
tc.setBlockCharFormat(tcf); // This is the important bit

elcuco said...

slougi, do you meant this? (this does not work):

QTextCursor tc = e2->textCursor();
QTextCharFormat tcf = tc.blockCharFormat();
tcf.setLayoutDirection( Qt::RightToLeft );
tc.setBlockCharFormat(tcf);
tc.insertText( QLatin1String("2) Wrong direction on QTextEdit, wanted RTL!") );
e2->setTextCursor(tc);

Besides, this is more or less what I tried in the second test. You force the text char format before the "insertText()" I do it while doing it.

idkn,
In this example I force the initial paragraph direction to RTL. When I happy with the results I will move to auto-direction+alignment. But even then, you will be able to override by pressing control+shift, as always. Nothing changed... (/me needs to fix kate asap).

Girish Ramakrishnan said...

I think forcing the layout direction is supported only at the block level and not at the fragment level. On a fragment level, the direction is auto detected by the script engine.

In the first case, you are setting up the default text option, which is used in QTextLayout which operates at the block level and hence works. The same is true for the third case which operates on the block.

Your second case works on fragments.

The setLayoutDirection is inherited from QTextFormat and is not necessarily supported in all its derivates :) For example, it has setBackground too but that doesn't work on blocks.

Don't take my work for the above, just guessing :) Please let me know what support@nokia says, I am interested.

Nick Shaforostoff said...

please mail me a backtrace.