My goal for this discussion is to share this information with others who are struggling with multiple-form projects and want to read all their data from a single SIL or SIB data file.
SECTION ONE
INITIAL COMPONENT SETUP
Many of the steps that I will be describing to you in this section can be automated by the TsiLang Expert. It helped me to step through them manually the first time in order to learn how these components work. So this is how I will approach the steps in this topic. Later in this dicussion we will approach and examine the Expert, which is quite a powerful tool. It just takes a little getting used to. Once you understand what it does, you will probably find yourself relying on it to automate a lot of conversion tasks.
STEP 1
Drop a TsiLangRT and TsiLangDispatcher on a master form. (Mine is on form_main.)
About TsiLangRT: This is a language component that controls setting the language text in each component and control, etc. at run time. It will also allow your users to modify the languages at run time if you want them to. I don't want that capability now. But I may in the future, so I'm using TsiLangRT just in case I change my mind.
About TsiLangDispatcher: This is the component with the glasses in the icon image. The purpose of the Language Dispatcher is to create one central location for controlling the Language Components used
in each forms. There should only be one Language Dispatcher in a project.
The dispatcher controls which language is active from one location. Set the dispatcher to ActiveLanguage 2, for example, and all the language components (TsiLangRT) in all the forms change languages.
As you will see, I chose to put my dispatcher in the main form. It does not have to be placed there. You can put it in any single form in the project. You will see below how to reference the dispatcher from any other form in the project.
STEP 2
Using the Delphi Object Inspector, set siLangRT's LangDispatcher property to to siLangDispatcher(or whatever you've named it.) This is a pointer to the dispatcher component object.
STEP 3
Set siLangRT's LoadOnCreate property to TRUE. No code will be necessary to load the language data file.
STEP 4
Select the dispatcher component on the screen, then move to the Object Inspector. In the Language property, enter the main (first) language name. Mine says "English'.
STEP 5
In the LangNames stringlist, set a couple of standard languages starting with the main language first. English, German, Spanish, French, Swahili - whatever you want. (This can be added to by the translator in the SILEditor program later - by you or the translator, or even the end-user.) Mine says English and German for now.
STEP 6
In the FileName property, set a relative path to the location of the language file that you will always use. For this program, my entry reads ".\language\fiftranslator.sib". Those of you familar with the DOS way of indicating paths will recognize the dot-slash way of indicating "the current directory or folder". This will give us the flexibility that we need in allowing the user to install the software in any folder selected during program installation without fixing the path to an absolute location relative to the root of a drive. What I did fix is the location of the language folder relative to the folder in which the installation program put my program.
(Note: The "SIB" extension is the default extension that Siticov and Serghei used to indicate a BINARY file. Binary files are compressed and load much faster compared to SIL files. SIL files are text files that represent the same data, but in a readable format.)
STEP 7
Now display one of the other forms in the project. Drop a siLangRT component in that form.
STEP 8
Be sure the form has the the main form's unit name in the uses list after the "implementation" keyword.
Code: Select all
implementation
{$R *.DFM}
uses
FormMain;
Select the siLangRT and then in the Object Inspector, find the LangDispatcher property. Choose the main form's siLangDispatcher in the pull-down box. (Mine says "Form_Main.siLangDispatcher") It should be the only choice in the pull-down list. (Just like in the TsiLangRT in the main form, this is the pointer to the dispatcher object in the main form that controls which language is active.) If it is not there, then you will need to check to be sure that you performed step 8 properly.
STEP 10
While still in the Object Inspector, set the LoadOnCreate to TRUE.
Note About duplicating these steps with the EXPERT
- - The EXPERT feature of the TsiLang Component Suite can automatically insert the TsiLangRT component in every form that must be translated. We just performed a manual insertion in two forms in the project.
- The EXPERT will NOT insert the TsiLangDispatcher component and set it up for you in the single form into which it is dropped. You must put the dispatcher component on a form of your choosing manually.
- The EXPERT will NOT set the TsiLangRT property values of LangDispatcher and LoadOnCreate for you.
- The EXPERT will NOT automatically add the form in which the dispatcher is placed in all the other form's USEs clause under implementation. You must do that manually.
CREATING THE SIL or SIB DATA FILE
We can run the program now, but our goal is to reference a language data file when the program loads. So you will need to create SIL or SIB file and place it in the ".\language" folder (or whatever you've named it). You can create any folder anywhere, and use any filename for the language file. The goal in this section is to create the language data file that you have indicated in the dispatcher's FileName property on the main form. These are the assumptions I will make for the way I am using the component. (Of course, you can modify this by adding further flexibility to your code.)
- - My language file will be always be located in the "language" folder under the main executable's folder.
- This language data filename will always be "FIFTranslator.sib".
- FIFTranslator.sib will contain information for all languages.
- FIFTranslator.sib will contain data for all the forms for the entire project.
The Expert is very powerful:
- - It automatically finds all the forms in your project.
- You can translate one at a time, or all of them using multiple-line selection in the grid.
- You can even move the strings used in your code into a form's TsiLangRT component Strings property automatically. This allows for translation of what were fixed strings inside your code.
- You can even convert your constants (under the const section in a pas file) this way.
- Then, when you are finished with the initial translation, you can save all of this data from all of the forms into the single language data file.
STEP 1
In the Tools/Options menu, choose the type of language component to use as default: I chose TsiLangRT. This is the only item I changed in the initial setup of the Expert.
STEP 2
Now select the form(s) to translate. I recommend that you start by double-clicking on one form to translate it alone. The Expert will load the form.
If the TsiLangRT component isn't already in the form being translated, then the Expert will insert it for you automatically. If this happens, be sure to manually set the two properties that must be set manually in this component when you are finished in the Expert (later) (See the end of SECTION 1).
If you want to trust Expert to do all the forms at one time, select multiple forms (Ctrl-A) in the Expert grid and press the Translate toolbar button in the upper left. If you select mulitple forms in this list and press Translate, be ready for a lot of activity. The expert will load all your forms and translate them.
STEP 3
After the initial translation is complete, I use the File>Save/Load Translation> Save Project to save one large SIB file with the name of your choosing. You can save the file as SIL or SIB file type. (Remember, the SIL filetype is like a text INI file and is less compact and effecient than the SIB type.) This is the default file-type in the save as file dialog. If you want, you can save it as a SIB file, by choosing the SIB Save as type in the dialog. (Once again, SIB files are smaller and load a lot faster than SIL files. You just can't read SIB file in a text editor like you can a SIL file.)
I used the standard delimiter that the program suggests ("~!@#$"). It seems to work better than trying to assign one myself.
SECTION THREE
TEST THE PROGRAM
Now test your program by changing something in the SIB file using the SILEditor (while your program is NOT running).
SILEditor: The SILEditor.exe program can be downloaded from the SICOMPONENTS site. It is a stand-alone program that does not appear to require any extra support files to run. This file can be distributed with your program. I put SILEditor.exe in the language folder next to the FIFTranslator.sib file since it's purpose is to load and edit either SIB or SIL files.
Inside SILEditor you will need to open the SIB file. The first language will appear in the first column, the second language in column two, etc. For the newer SILEditor program, you need to select one of the expandable sections on the left that is organized by Pascal units (like TForm_Main).
I recommend that you change one of the words in the main language section. For example, if you have a File menu, then you rename the word "File" to something like "Hi".
Save the changes back to the SIB file, then run your executable program, and you should see "Hi" where "File" used to be. This is because your TsiLangRT components have LoadOnCreate set to true, and they all reference the same dispatcher component with the same SIB filename.
Note: If you do not see a change in the caption or text in your form, then check the path and filename for the SIB file you've created. Also, be sure that you actually saved the SIB file from the SILEditor before you ran your program.
SECTION FOUR
SAVE AND RECALL THE STATE
You can save the language state using the INI file standard (as an integer). Or you can save it to the Registry if that's more convenient for you. This is an INI example:
Code: Select all
WriteInteger (Const_LanguageSection, Const_LanguageNumber, siLangDispatcher.ActiveLanguage);
Code: Select all
siLangDispatcher.ActiveLanguage := ReadInteger(Const_LanguageSection, Const_LanguageNumber, 1);
SECTION FIVE
CHANGING THE LANGUAGE STATE WHILE RUNNING
I have a form with a combobox component and an OK button for changing languages. Call the form from your main form after propagating the language names (stringlist) into the ComboBox stringlist, then setting the correct ItemIndex in the ComboBox. (Remember that the ActiveLanguage is 1-based - so be sure to subtract one from the ActiveLanguage when assigning ItemIndex)
This is how to propagate (assign) the ComboBox with the available languages in order to make a selection for the ActiveLanguage:
Code: Select all
Form_LanguageSetup.ComboBox_Languages.Items.Assign(siLangDispatcher.LangNames);
Form_LanguageSetup.ComboBox_Languages.ItemIndex := siLangDispatcher.ActiveLanguage-1;
Form_LanguageSetup.ShowModal;
siLangDispatcher.ActiveLanguage := Form_LanguageSetup.ComboBox_Languages.ItemIndex + 1;
SECTION SIX
IGNORING AND EXCLUDING TRANSLATIONS
Be sure to read the PDF about ignoring and excluding translations. Some items you certainly don't want translated - and you don't want others translating them for you. (Also there is some helpful discussion about that in the forum.)
SECTION SEVEN
INTERNAL Object Names (and RENAMING)
Object naming becomes important with this translator because your end-user (or at least your translator) will see your object names. For example he/she may see Label15 in the list, when it would probably be better to display Label_OptionSetup (or at least something more descriptive/professional). This is my least favorite task of the whole translation project - resetting our component names. From now on, we plan on paying better attention to our object names at creation time.
I hope this helps other users. The struggle is certainly worth it as this is a decent/reliable component (especially for the price!).