Working with the Local Translations

When using the LangsHelper library, it should choose what language file should be used in your application at present time. As we will see below, this is necessary for the scenarios when the translation that matches better to the user’s system language has appeared on the server, was downloaded by the library, and should be applied.

The main class that deals with the translations of your application that are already available locally for it is TLocalTranslations. The instance of this class should be created at the beginning of the program’s functioning, before the user interface is shown.

Let us see how this instance is created in Sample Program:
LocalTranslations.reset(
    new TLocalTranslations (AppFolder,
        CurrentVersion,
        &TMainWindow::ApplyTranslationFunc,
        std::vector <TLanguage>(),
        TLocalTranslation (TLanguage(L"English"), L"English.lng"),
        reinterpret_cast(this)
        )
    );
	
// Initialize must be called once the class is created
LocalTranslations->Initialize();
					
LocalTranslations := TLocalTranslations.Create(
    AppFolder,
    CurrentVersion,
    Form1.ApplyTranslationFunc,
    BuiltInLanguages,
    MakeLocalTranslation(MakeLanguage('English'), 'English.lng')
    );
	
// Initialize must be called once the class is created
LocalTranslations.Initialize;
					

AppFolder is the folder with the language files.

CurrentVersion is the version of our application.

The above code passes to the library the pointer to the function, which is called when your app should apply some language file; i.e. switch to some language. This function is passed through the TLocalTranslations class’ constructor, via the ApplyTranslationFunc parameter. When this function is called, your application should load the language file passed to this function via the parameter.

If your application has a built-in translation which does not associate with the files, it should be passed to TLocalTranslations class via the BuiltInLanguages parameter. In our case, we have no built-in translation, and therefore we pass the empty collection.

The next parameter to the class constructor is the default translation. It will be used upon the first program launch, if no translation that matched the system language has been found and in some other cases. As Sample Program is supplied with the pre-installed English.lng language file (located in the Langs subfolder), we pass this translation through the last constructor parameter.

The last parameter to the class constructor is a value, which is passed to the callback function. We are specifying here the pointer to this in order to pass it to the ApplyTranslationFunc fucntion.

The instance of the TLocalTranslations class is used in our app to display the languages that are already available for switching to in our application. They can be viewed using this drop-down list:



As you can see, the translations to English and German are located in the Langs subfolder of the demo application.

Here is the code for obtaining the list of the languages locally available for your application:

std::vector<TLocalTranslation> Translations =
  LocalTranslations->GetAllBestLocalTranslations();
for (size_t i = 0; i < Translations.size(); i++) {
  const TLocalTranslation &Translation = Translations[i];
  AvailableLanguagesCombo.Append(Translation.GetLanguage().ToString());
	
  // Making the active translation's language focused
  if (Translation == LocalTranslations->GetActiveTranslation())
    AvailableLanguagesCombo.Select(static_cast(i));
    }
					
var
  Translations: TLocalTranslationArray;
...  
Translations := LocalTranslations.GetAllBestLocalTranslations;
  for I := Low(Translations) to High(Translations) do
  begin
    ComboBox1.Items.Append(LangsHelper.ToString(Translations[I].Language));
    
    // Making the active translation's language focused
    if (Equal(Translations[I], LocalTranslations.GetActiveTranslation)) then
      ComboBox1.ItemIndex := I;
  end
					

The GetAllBestLocalTranslations class member is used to get the list of all translations available for enabling in your application. If there is more than one translation to some language available in the languages folder, only one of them will be returned by GetAllBestLocalTranslations, whichever one fits better to the app’s version.

Therefore, you may use GetAllBestLocalTranslations in your application’s interface in the place where all languages currently available for enabling is displayed.

When the user wants to switch to another language, they just choose it in the drop-down list. The below code performs the language change:

LRESULT ItemIndex = AvailableLanguagesCombo.GetSelect();
if (ItemIndex == -1)
  return;
std::wstring LanguageName = AvailableLanguagesCombo.GetSelectText();
LocalTranslations->SetPreferredLanguage (
  TMiscFunctions::StringToLanguage (LanguageName));
					
var
  ItemIndex: Integer;
  LanguageName: String;
...
ItemIndex := ComboBox1.ItemIndex;
if (ItemIndex = -1) then
  Exit;
LanguageName := ComboBox1.Items.Strings[ItemIndex];
LocalTranslations.SetPreferredLanguage (
  TMiscFunctions.StringToLanguage (LanguageName));
					

Thus, we are using SetPreferredLanguage to let the class know that we want to activate the specified language. This leads to enabling the translation to the required language, if one is available. Otherwise, the translation to the default language will be enabled and the passed language will be remembered as preferred.


Next step: Creating the Server Interaction Classes