Recent

Author Topic: Is BiDiMode detected when a right to left language is used?  (Read 9850 times)

Windsurfer

  • Sr. Member
  • ****
  • Posts: 368
    • Windsurfer
Is BiDiMode detected when a right to left language is used?
« on: November 26, 2013, 02:59:12 pm »
I am learning how to use multiple languages in a small application, using the DefaultTranslations unit (thanks #wp) and have now reached BidiMode.

Is bidiMode automatically detected when the default language is changed, or must the programmer find a way to test for it?

If the latter case, I guess the obvious place is to include the information in the .po file header.

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Is BiDiMode detected when a right to left language is used?
« Reply #1 on: November 26, 2013, 03:38:59 pm »
Welcome to my world :)

This is what I use.  I hope it helps.

Code: [Select]
const
  AR_XX: LongWord = $0401;  //Arabic
  FA_XX: LongWord = $0429;  //Farsi
  HE_IL: LongWord = $040D;  //Hebrew
  UR_XX: LongWord = $0420;  //Urdu

function R2Llang(Lang: Integer): Boolean;
begin
  Result:= False;
  if (Lang=AR_XX)or(Lang=FA_XX)or(Lang=HE_IL)or(Lang=UR_XX) then
    Result:= True;
end;

I know there are other R2L languages but I don't know which ones.  Hopefully someone can add to the list.

Someplace in Lazarus code there is a routine to test for R2L but I don't use it and can't find it right now.  If I do find it, I'll let you know.

Edit: I just found it.  Look for 'function TApplication.IsRTLLang(ALang: String): Boolean;' in Application.inc
« Last Edit: November 26, 2013, 03:42:17 pm by Avishai »
Lazarus Trunk / fpc 2.6.2 / Win32

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Is BiDiMode detected when a right to left language is used?
« Reply #2 on: November 26, 2013, 04:12:51 pm »
Windsurfer, I think I should warn you about BiDiMode with Lazarus.  On MSWindows platform Lazarus does not truly support RightToLeft.  What *should* happen is that TForm would be Mirrored so that the 'Close/Restore/Minimize' buttons are on the Left and the Icon/Caption are on the Right.  Also the TForm.Canvas *should* be mirrored so that painting is from RightToLeft. 

Also, most controls can not draw themselves RightToLeft.  There's more to RightToLeft than just the Text.  TPageControl is a good example.

Lazarus Trunk / fpc 2.6.2 / Win32

Windsurfer

  • Sr. Member
  • ****
  • Posts: 368
    • Windsurfer
Re: Is BiDiMode detected when a right to left language is used?
« Reply #3 on: November 26, 2013, 07:18:13 pm »
Thanks Avishai,

My application has some stringgrids and a bitmap that plots a seres of GPS points. It will be interesting to see what happens.

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Is BiDiMode detected when a right to left language is used?
« Reply #4 on: November 26, 2013, 07:23:14 pm »
It sounds like you may be in luck.  TStringGrid is one of the few Lazarus components that does a very good job with BiDiMode.  There's a tiny problem with the cell editor but it isn't so bad that you can't use it.
Lazarus Trunk / fpc 2.6.2 / Win32

Windsurfer

  • Sr. Member
  • ****
  • Posts: 368
    • Windsurfer
Re: Is BiDiMode detected when a right to left language is used?
« Reply #5 on: November 26, 2013, 07:31:30 pm »
It also has a few statements like:

StringGrid1.Cells[1, I] := Formatdatetime('yyyy/mm/dd hh:mm:ss', aySpeed[I - 1].Datetime);

I have not created resource strings for the formatting string, to ensure the data is handled properly.

Do I need to change the order of the date display?

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Is BiDiMode detected when a right to left language is used?
« Reply #6 on: November 26, 2013, 07:41:56 pm »
Yes there are a few things with Dates.  You may need some of this code, maybe not.  But this is ONLY for MSWindows.  I'm afraid I can't help you with any other OS.

Code: [Select]
procedure FixHebShortDayNames; 
// This is only good for Hebrew
var
  HebShortDayNames: TWeekNameArray = ('א','ב','ג','ד','ה','ו','ש');
begin
  if SysLocale.DefaultLCID = HE_IL then
    ShortDayNames:= HebShortDayNames;
end;

function GetLongMonthNames(I: Integer): String;
begin
  Result:= AnsiToUTF8(FormatSettings.LongMonthNames[I]);
end;

function GetShortMonthNames(I: Integer): String;
begin
  Result:= AnsiToUTF8(FormatSettings.ShortMonthNames[I]);
end;

function GetLongDayNames(I: Integer): String;
begin
  Result:= AnsiToUTF8(FormatSettings.LongDayNames[I]);
end;

function GetShortDayNames(I: Integer): String;
begin
  Result:= AnsiToUTF8(FormatSettings.ShortDayNames[I]);
end;

function GetCurrencyString: String;
begin
  Result:= AnsiToUTF8(CurrencyString);
end;

function GetHebLongDate(ADate: TDate): String;
begin
  Result:= IntToStr(DayOf(ADate))+AnsiToUTF8(' ב')+
    AnsiToUTF8(FormatDateTime('MMMM, YYYY',ADate));
end;

Edit:  Oops.  I just noticed that GetHebLongDate is only for Hebrew as well.
« Last Edit: November 26, 2013, 10:30:37 pm by Avishai »
Lazarus Trunk / fpc 2.6.2 / Win32

wp

  • Hero Member
  • *****
  • Posts: 12920
Re: Is BiDiMode detected when a right to left language is used?
« Reply #7 on: November 26, 2013, 09:03:17 pm »
No need to hard-code formatstrings. You can use the LCID to find the correct formatsettings:

Code: [Select]
  GetLocaleFormatSettings(LCID_code, DefaultFormatSettings);

No idea, though, how to do this in Linux. There is another problem even in Windows that I don't know how to relate the LCID with the language code as used by Lazarus ('de', 'en', etc.).

Therefore, I modified the DefaultTranslator unit to build up a language list for getting access to all the necessary information. Essentially, you just add this unit to your uses list and call the procedure "SetLanguage" to set the language according to your wishes; it also sets the DefaultFormatSettings as needed. SetLanguage can also be used in code writing to a configuration file to store the selected language. The "opposite" of Setlanguage is GetLanguage to be called when reading the config file.

Additionally, you can use "PopulateLanguageStrings" to populate a stringlist for a combobox, listbox etc. with all the translations available.  Use "GetLangIDOfListIndex" to convert the ItemIndex of the combobox to the language abbrevation of the selected language, or "GetListIndexOfLang" to find the index of a given language for selecting it in the combo-/listbox.

I hope that everything works out; the unit is used in a larger project of mine, and I am not sure if it works separately. Also be warned - my description may not be correct here and there. So: no warranty...

One thing that you may have to change is the last (optional) parameter of "RegisterLanguage" as it is called by "CreateLanguages": this is the index to an image list containing the flag images for each language. Free icons can be found at http://www.famfamfam.com/lab/icons/flags/.

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Is BiDiMode detected when a right to left language is used?
« Reply #8 on: November 26, 2013, 10:40:55 pm »
This is another MSWindows ONLY routine you might need for setting the Keyboard Language.

Code: [Select]
function GetKBD: Word;
begin
  Result:= GetKeyboardLayout(0);
End;

function SetKBD(LangID: HKL): Word;
begin
  if not(ActivateKeyboardLayout(LangID, $1)) then
    LoadKeyboardLayoutA(PChar(IntToHex(LangID,$1)),KLF_ACTIVATE);
  Result:= GetKBD;
end;
Lazarus Trunk / fpc 2.6.2 / Win32

Windsurfer

  • Sr. Member
  • ****
  • Posts: 368
    • Windsurfer
Re: Is BiDiMode detected when a right to left language is used?
« Reply #9 on: November 27, 2013, 12:07:34 am »
Thanks for the help. It will keep me quiet for a while, as I absorb it.

wp I submitted the attachment into the Bugtracker today, for inclusion as an example. It does not include BidiMode. I removed an arabic translation because it was unreliable.

I also found this ISO standard for language identifiers. I guess that it should be the guide for all software producers. http://www.iso.org/iso/home/standards/language_codes.htm I looked for it because I realised that many countries speak arabic, so country codes were too restrictive.

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Is BiDiMode detected when a right to left language is used?
« Reply #10 on: November 27, 2013, 05:42:02 am »
If you look in ..\FPC\2.6.2\source\rtl\win\wininc\defines.inc near Line# 4135 you should find where the languages are defined for MSWindows.
Lazarus Trunk / fpc 2.6.2 / Win32

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Is BiDiMode detected when a right to left language is used?
« Reply #11 on: November 27, 2013, 05:50:27 pm »
Windsurfer, I've given this a little thought and this code may be what you are looking for.

Code: [Select]
procedure TForm1.FormCreate(Sender: TObject);
begin
  if SysLocale.MiddleEast then begin
    Self.BiDiMode:= bdRightToLeft;
    Self.FlipChildren(True);
  end;
end;
« Last Edit: November 27, 2013, 06:20:45 pm by Avishai »
Lazarus Trunk / fpc 2.6.2 / Win32

Windsurfer

  • Sr. Member
  • ****
  • Posts: 368
    • Windsurfer
Re: Is BiDiMode detected when a right to left language is used?
« Reply #12 on: December 01, 2013, 08:51:22 pm »
Thanks Avishai,

I'll try it.

Avishai

  • Hero Member
  • *****
  • Posts: 1021
Re: Is BiDiMode detected when a right to left language is used?
« Reply #13 on: December 07, 2013, 08:07:30 pm »
There is another function just below TApplication.IsRTLLang

Code: [Select]
function TApplication.Direction(ALang: String): TBiDiMode;
const
  BidiModeMap: array[Boolean] of TBiDiMode = (bdLeftToRight, bdRightToLeft);
begin
  Result := BidiModeMap[IsRTLLang(ALang)];
end;


So you can have:

Code: [Select]
Application.BiDiMode:= Application.Direction('he');

« Last Edit: December 07, 2013, 08:11:53 pm by Avishai »
Lazarus Trunk / fpc 2.6.2 / Win32

 

TinyPortal © 2005-2018