Как стать автором
Обновить

Комментарии 10

Для Borland Builder в ряде продуктов — я делал следуюший функционал — при нажатии на скрытую кнопку — генерился/aпдейтилса XML файл — который хранил в себе структуру и отношения всех контролов приложения — формально это несколько строчек кода.

Переводчики добавлют ноды языка в простом редакторе

<?xml version=«1.0»?>
<Lаbel Name=«English»>
<Trаnslate Name=«Russian»><![CDATA[Метка]]></Trаnslate>
<Trаnslate Name=«French»><![CDATA[Etiquette]]></Trаnslate>
</Lаbel>


При выборе языка из меню — форма мгновенно апдейтится на выбранный язык. Каждый tag контрола хранит адрес нода xml и на refresh/create выбирает нужный язык. Все на лету — все прозрачно — никаких библиотек.
Так тут тоже всё на лету. Менять язык в реалтайме — две команды:
  UseLanguage ('RU');
  Retranslatecomponent(self);
Прозрачно более некуда и здесь — аж один юнит кода. Тут может его больше чем у Вас, но и возможностей больше. Те же домены, множественное число и т.д.
И для перевода не нужно обьяснять переводчику где и как писать перевод, так как он может использовать любой редактор на свой вкус.
Ссылка на исходники у меня не работает, гугл её почему-то отключил.
Странно чем гуглу зип с исходниками не понравился. Исправил.
А чем не устраивает родной переводчик, встроенный в среду? Ведь для локализации не достаточно заменить строки. Очень часто приходится менять размер и положение элементов на странице, а иногда и графику.
1. Не переводит строковые литералы в файлах .pas?
2. В принципе параметром можно было бы прицепить размеры и стиль шрифта. Если перевод сильно длиннее оригинала, то выводить меньшим по размеру шрифтом.
3. В скриптике updatepofiles.cmd надо бы добавитьсохранение default.po в папке locale. Или я что-то не так делаю?

4. Перевод надо запускать по сыбытию OnShow главной формы, а не OnCreate.
Тогда можно перебором всех форм всех их перевести.
Как-то так для Дельфи

//**************************************************
procedure LangIni();
var
  i: integer;
begin
for i := 0 to Application.ComponentCount - 1 do
  begin
    if (Application.Components[i] is TForm)
    then translatecomponent(application.Components[i]);;
  end;
end;


//**************************************************
procedure LangChange();
var
  i: integer;

begin
for i := 0 to Application.ComponentCount - 1 do
  begin
    if (Application.Components[i] is TForm)
    then Retranslatecomponent(application.Components[i]);;
  end;
end;

procedure TForm0.FormShow(Sender: TObject);
var
  i: integer;
begin
 if RadioGroup1.ItemIndex=0 then
 begin
     LangC:='EN';
  UseLanguage ('EN');
 end
  else
  begin
     LangC:='RU';
  UseLanguage ('RU');
  end;
 LangIni();
 end;

1. Что Вы имеете в виду? Перевод делается для DFM и вызовом функций, например
s:=_('Apple');

То есть всюду, где в исходниках присваивается строка, приходится вызывать эти функции.
2. Перевод не может менять шрифт, это всего лишь перевод, текст на входе — текст на выходе. Как выводить переведенный текст должно быть реализовано уже в Вашем приложении, потому как это уж очень кастомизировано у каждого.
3. Вы правы.
4. Переводить на OnShow избыточно если для измения языка нужно перезапускать приложение. А если менять на лету, тогда да. И то, код для перевода можно поместить в событие изменения языка, а не в OnShow формы. Если оставить в OnShow, то можно сравнивать поменялся ли язык и вызывать перевод только если язык формы отличается от текущего языка приложения.

Если форм много, и нужно всюду добавить одинаковый код для перевода, сделайте родительскую форму, поместите общий код туда, а все формы, показываемые юзеру унаследуйте от неё.
1. Да, надо прочитать мануал еще раз )
Но по крайней мере в gorme данные из строк подобных (s:=('Apple'); ) не показывались. И соответственно не переводились.
2. Перевод не может менять шрифт, это всего лишь перевод, текст на входе — текст на выходе. Как выводить переведенный текст должно быть реализовано уже в Вашем приложении, потому как это уж очень кастомизировано у каждого

Ну как бы «только перевод» — да, но… увеличение длины строки это следствие перевода, и если утилита помогает решить эту проблему, то это только в плюс. Простейшее решение — уменьшить размер шрифта.
Но настаивать я не буду, это просто мысль )

4. Там же все равно надо первым вызывать Translate… а при смене языка Retranslate…
В моем случае программа (со всеми формами) уже написана и надо быстренько «прикрутить» туда мультиязычность. Менять структуру программы особой возможности нет.

Но по крайней мере в gorme данные из строк подобных (s:=('Apple'); ) не показывались. И соответственно не переводились.

Да, сами литералы не переведутся. Нужно вызывать функцию для перевода с литералом как параметр.
Менять структуру программы особой возможности нет.

А как насчет родительской формы? Просто ко всем формам добавить (заменить TForm на своего) родителя, и уже OnShow писать на родительской форме. Не нужно будет прописывать событие у каждой формы, да и изменение небольшое в структуре.
Только тогда если уже где-то был OnShow, не забыть добавить inherited.
>Нужно вызывать функцию для перевода с литералом как параметр.

1. мм… да заменил все строки типа s:='Apple'; на s:=_('Apple'); в файле po появились соотв. строки.
А автоматизации никакой для этого нет? В пакете Дельфи конечно есть GrepSearch, но все равно найденные строки пришлось обрабатывать вручную.

2. Так я не добавляю в OnShow каждой формы перевод, только в OnSHow главной формы перебираю в цикле все формы. Это происходит один раз при запуске программы. Ну и в функции переключении языка в runtime.

ps. программа конечно отличная и Вам спасибо за данный пост! В течение 1 дня фактически прикрутил перевод к существующему проекту, причем большую часть времени занимался именно переводом ))

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории