Remove language from .sib file via code

All announcements, questions and issues related to the TsiLang Components Suite.
Post Reply
bigstar
Posts: 11
Joined: Tue Aug 02, 2005 1:09 am

Remove language from .sib file via code

Post by bigstar »

I decided to have seperate language files for each translation, The translator adds their language to the .sib file. When I recieve the .sib file from the translator I manually remove the default language leaving only their translated language in the .sib file.

What I'd like to do is automate this task by writting a special program that can remove my default language from the .sib file.

I don't see any way to do this directly from within the TsiLang components.

Any suggestions or comments would be appreciated.
isiticov
Site Admin
Posts: 2383
Joined: Thu Nov 21, 2002 3:17 pm

Post by isiticov »

Unit siComp contains the TSIBFileManager object, which will help you to manage SIB files. Some properties and methods that might be useful for your case:
1. CompCount - amount of forms (TsiLang(s)) in SIB file.
2. siComponents[Index]: TsiCustomLang - returns TsiCustomLang depending on Index value.
3. LoadAllFromFile() - loads data from file.
4. SaveToFile() - saves data to file.

After loading SIB file to TSIBFileManager you can iterate through all TsiLangs included and manage language information. After that just save back to file and you will have updated SIB file.

Please let me know if this helps.
Best regards,
Igor Siticov.
bigstar
Posts: 11
Joined: Tue Aug 02, 2005 1:09 am

Post by bigstar »

Thanks for your advice.

Once I have the SIB file loaded into the TSIBFileManager, How do I go about removing a language from the TSIBFileManager.siComponents[] (TsiCustomLang)?

I thought maybe I could remove the LangName from the list and it would exclude it from all of the properties but that didn't work.
isiticov
Site Admin
Posts: 2383
Joined: Thu Nov 21, 2002 3:17 pm

Post by isiticov »

Sorry, you're right, not very easy task :)
Below are the sample steps to perform this action (I suppose that yopu have 2 languages and need to delete first one):
1. You need to iterate through all TsiLang's properties using GetPropListByType()
2. Having each list you need to place value for second language into first one using ExtractTranslation() from MemIni and ReplaceStringValue() method of TsiLang.
3. After that you need to change language name for first language and set it to value of second language.
4. And set NumOfLanguages to 1.
Something like this:

Code: Select all

procedure RemoveFirstOfTwoLanguages(const siLang: TsiCustomLang);
var
   ST: TStringsType;
   I: Integer;
   List: TStrings;
   S: string;
begin
  for ST := Low(TStringsType) to High(TStringsType) do
  begin
    List := siLang.GetPropListByType(ST);
    if List = nil then Continue;
    for I := 0 to Pred(List.Count) do
    begin
      S := ExtractTranslation(List[I], siLang.LangDelim, 2);
      siLang.ReplaceStringValue(List, S, ExtractTranslation(List[I], siLang.LangDelim, 0), 1);
    end;
  end;
  siLang.LangNames[0] := siLang.LangNames[1];
  siLang.NumOfLanguages := 1;
end;
Please let me know if this works :)
Best regards,
Igor Siticov.
bigstar
Posts: 11
Joined: Tue Aug 02, 2005 1:09 am

Post by bigstar »

Thanks for the example.

For some odd reason after I do this some of my translated text no longer appears translated. Specifically some resource strings..

I also did a test where I used

siLang.ReplaceStringValue(List, EmptyStr, ExtractTranslation(List, siLang.LangDelim, 0), 1);

not removing the first language but only making it blank and the translated language was still # 2 and I got the same results.
isiticov
Site Admin
Posts: 2383
Joined: Thu Nov 21, 2002 3:17 pm

Post by isiticov »

siLang.ReplaceStringValue(List, EmptyStr, ExtractTranslation(List, siLang.LangDelim, 0), 1);

This makes value for first language empty.

siLang.NumOfLanguages := 1;


Deletes second language. So with connection of replacing first language value with value from second language will (OK, must ;)) perform what is needed.

Does my example work for all strings except "Strings" section?
Best regards,
Igor Siticov.
bigstar
Posts: 11
Joined: Tue Aug 02, 2005 1:09 am

Post by bigstar »

Sorry I forgot to mention I also commented that line out as well as "siLang.LangNames[0] := siLang.LangNames[1];"

Yes, your example appears to work for every section but the "Strings" section.

When I load the .SIB file into the TsiLang File Edior everything looks ok. I also tried re-saving the .SIB to see if it would help any. It didn't.

Is there any way I can get this to work for the "Strings" section too? I have 503 entries in my "strings" section.
isiticov
Site Admin
Posts: 2383
Joined: Thu Nov 21, 2002 3:17 pm

Post by isiticov »

Code: Select all

procedure siRemoveLanguage(const siLang: TsiCustomLang; const LangID: Integer);
var
   ST: TStringsType;
   I, J: Integer;
   List: TStrings;
   S: string;
begin
  if (LangID < 1) or (LangID > siLang.NumOfLanguages) then Exit;
  if LangID = siLang.NumOfLanguages then
  begin
    siLang.NumOfLanguages := siLang.NumOfLanguages - 1;
    Exit;
  end;
  for ST := Low(TStringsType) to High(TStringsType) do
  begin
    List := siLang.GetPropListByType(ST);
    if List = nil then Continue;
    for J := LangID + 1 to siLang.NumOfLanguages do
    begin
      for I := 0 to Pred(List.Count) do
      begin
        S := ExtractTranslation(List[I], siLang.LangDelim, J);
        siLang.ReplaceStringValue(List, S, ExtractTranslation(List[I], siLang.LangDelim, 0), J - 1);
      end;
      siLang.LangNames[LangID - 1] := siLang.LangNames[LangID];
    end;
  end;
  for I := 0 to siLang.FStringsColl.Count - 1 do
    if siLang.FStringsColl[I].Values.Count > LangID - 1 then
      siLang.FStringsColl[I].Values.Delete(LangID - 1);
  siLang.NumOfLanguages := siLang.NumOfLanguages - 1;
end;
Just add this procedure to the siComp.pas unit and declare it in interface section of siComp.pas.
Please let me know if this works now.

This will be included into update release scheduled to the next few days.
Best regards,
Igor Siticov.
bigstar
Posts: 11
Joined: Tue Aug 02, 2005 1:09 am

Post by bigstar »

I did some more tests and I'm starting to think the problem isn't with the updated SIB file but rather a problem when loading the new language file from within my program. Because even your new code doesn't allow my application to use the updated resource strings. Quite puzzling.

The SIB file looks perfect as far as I can tell.

In my case I am loading everything at run time and your new code didn't work at first. I had to include "TsiLang.UpdateStrCollections" to populate FStringsColl

I guess what I need to figure out is why my application isn't using the resource strings once the new language file is loaded.

I'm using the following in my application, Do I need to do any other steps to get the new resource strings to work?

I tried also using "TsiLang.UpdateStrCollections" here and that didn't help.

Code: Select all

     siLangDispatcher1.ActiveLanguage := 1;
     siLangDispatcher1.Filename := Filename;
     siLangDispatcher1.LoadAllFromFile(Filename);
isiticov
Site Admin
Posts: 2383
Joined: Thu Nov 21, 2002 3:17 pm

Post by isiticov »

Could you please reproduce the problem on some simple project and send it to us at support [at] sicomponents dot com and we will try to investigate deeper?
I think this would be the best way to solve this.
Best regards,
Igor Siticov.
Post Reply