<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://wiki2.linuxformat.ru/skins/common/feed.css?97"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF111%3AKDE4</id>
		<title>LXF111:KDE4 - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF111%3AKDE4"/>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF111:KDE4&amp;action=history"/>
		<updated>2026-05-14T03:44:40Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.11.1</generator>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF111:KDE4&amp;diff=8800&amp;oldid=prev</id>
		<title>Crazy Rebel: викификация, оформление, иллюстрация</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF111:KDE4&amp;diff=8800&amp;oldid=prev"/>
				<updated>2009-10-02T05:46:55Z</updated>
		
		<summary type="html">&lt;p&gt;викификация, оформление, иллюстрация&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая статья&lt;/b&gt;&lt;/p&gt;&lt;div&gt;: '''KDE 4''' Создаем приложения для самого современного рабочего стола в Linux. [[Категория:Учебники]]&lt;br /&gt;
&lt;br /&gt;
==На всех языках мира==&lt;br /&gt;
&lt;br /&gt;
{{Цикл/KDE4}}&lt;br /&gt;
&lt;br /&gt;
: '''ЧАСТЬ 4''' Угадайте, какая тема неизменно замалчивается западными авторами учебников по компьютерным технологиям? Правильно – интернационализация! '''Андрей Боровский''' спешит заполнить данный пробел.&lt;br /&gt;
&lt;br /&gt;
{{Врезка|left|Заголовок=О терминах|Содержание=   Под интернационализацией мы подразумеваем подготовку&lt;br /&gt;
программ к переводу на различные языки. Локализация – это&lt;br /&gt;
собственно перевод на определенный язык (а также адаптация&lt;br /&gt;
программы к правилам написания чисел и дат, принятым в целевой стране, местной системе мер, используемым денежным единицам и т.п.). Интернационализация выполняется на этапе разработки программы, а локализация может быть выполнена после&lt;br /&gt;
того, как приложение уже собрано.|Ширина=200px}}&lt;br /&gt;
&lt;br /&gt;
Кем бы был Джон Рональд Руэл Толкиен, если бы ему довелось дожить до наших дней? Я просто уверен, что Профессор входил бы в команду интернационализации KDE. Чтобы понять это, достаточно прочесть его руководство по переводу топонимов и омонимов для собственных произведений.&lt;br /&gt;
&lt;br /&gt;
На данном уроке мы сосредоточим свое внимание на специфике интернационализации и локализации программ в KDE 4. Система интернационализации KDE 4 основана на стандартном для Linux пакете ''GNU gettext'' (http://www.gnu.org/software/gettext), так что если вы хотите изучить вопрос более подробно, рекомендую обратиться к его документации.&lt;br /&gt;
&lt;br /&gt;
Если вы выполняли интернационализацию и локализацию в KDE 3.x, то обнаружите, что изменения, привнесенные в KDE 4.x, невелики, но&lt;br /&gt;
учитывать их надо. Появилась новая среда сборки программ (она теперь основана на ''CMake''), в архитектуру библиотек ''Qt/KDE'' также были внесены изменения. Да и сама система интернационализации обзавелась&lt;br /&gt;
новыми функциями. В качестве упражнения мы выполним интернационализацию и русскую локализацию программы, которую создает по&lt;br /&gt;
умолчанию генератор ''kapptemplate''.&lt;br /&gt;
&lt;br /&gt;
===Подготовим исходники===&lt;br /&gt;
&lt;br /&gt;
Функции и макросы, необходимые для интернационализации KDE-&lt;br /&gt;
программы, становятся доступны при включении в исходные тексты&lt;br /&gt;
заголовочного файла '''klocale.h'''; генератор шаблонов ''kapptemplate'' делает&lt;br /&gt;
это автоматически. Основой интернационализации, как и прежде, являются функция '''i18n()''' и макрос '''I18N_NOOP()'''. Напомню, что функция '''i18n()''' получает в качестве параметра строку '''char *''' в кодировке UTF-8&lt;br /&gt;
и заменяет ее на аналог из каталога переведенных строк. Макрос '''I18N_NOOP()''' используется там, где функция '''i18n()''' применяться не может (она становится доступна только после создания объекта '''KApplication''').&lt;br /&gt;
Таким образом, в первом приближении задача подготовки исходных&lt;br /&gt;
текстов к интернационализации сводится к «оборачиванию» строк английского текста функцией '''i18n()''' и макросом '''I18N_NOOP()''' (если вы посмотрите исходные тексты программы ''i18demo'', то увидите, что это&lt;br /&gt;
уже сделано). Далее мы извлекаем из файлов исходных текстов строки,&lt;br /&gt;
подлежащие переводу, с помощью утилиты ''xgettext'', например:&lt;br /&gt;
&lt;br /&gt;
 xgettext -C -ki18n -kI18N_NOOP *.cpp&lt;br /&gt;
&lt;br /&gt;
Ключ '''-C''' указывает команде, что она обрабатывает исходные тексты на ''C/C++''. Параметры '''-ki18n''' и '''-kI18N_NOOP''' сообщают, что нужно искать строки, обернутые '''i18n''' и '''I18N_NOOP''' (формат: '''-k''' + имя функции или макроса). В результате на диске появляется файл ''messages.po'', который содержит все помеченные для перевода строки из файлов с расширением '''.cpp'''. Затем их нужно перевести на целевые языки и скомпилировать в '''mo'''-каталоги. Теперь, чтобы программа «заговорила» на иностранном языке, достаточно просто скопировать эти файлы в нужную директорию.&lt;br /&gt;
&lt;br /&gt;
Однако не все так просто. Наша демонстрационная программа отсчитывает и показывает в специальном окне число дней, прошедших с момента создания проекта. В ситуации, когда программа выводит сообщение о количестве чего-то, мы должны позаботиться о правильном&lt;br /&gt;
 использовании грамматических форм единственного и множественного числа. Допустим, у нас есть фраза вида «'''прошу выделить мне %1 кочерги'''», где спецификатор '''%1''' во время выполнения программы заменяется на некое целое число (подробнее о форматировании строк можно прочитать в документации по ''Qt''). Можно, конечно, упростить себе жизнь и написать по-канцелярски: «'''прошу выделить мне изделие “кочерга” в количестве %1 штук'''». Однако в наше время высоких технологий пользователь вправе ожидать, что компьютеры будут говорить, как люди. Мы хотим, чтобы форма слова «кочерги» менялась в зависимости от количества (1 кочергу, 2 кочерги...). Эту задачу можно решить с помощью кода на ''C++'' и учебника грамматики, но такой подход будет работать только для одной группы языков. Многие программы, обработка множественного числа и других языковых особенностей в которых «зашита» в код, по умолчанию поддерживают только правила английского языка. Эти правила также справедливы для некоторых западноевропейских языков, но не для восточноевропейских, что существенно затрудняет (а иногда и делает невозможной) локализацию программ. Основное правило написания программы, предназначенной для перевода на другие языки: никаких предположений касательно грамматики.&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Заголовок=Вредные советы|Содержание=Некоторые конструкции могут затруднить подготовку программы к переводу на другие языки. Самый распространенный пример того, чего не следует делать – это сборка строки из нескольких кусков: '''i18n(“Time left is”) + seconds + i18n(“seconds”)'''. В таком варианте функция '''i18n()''' не будет правильно работать с&lt;br /&gt;
множественным числом. В программе, предполагающей перевод на другие языки, не следует рассчитывать на то, что текст всегда&lt;br /&gt;
будет выводится слева направо, и уж конечно, не следует проектировать интерфейсы, исходя из длины строк в пикселях.|Ширина=200px}}&lt;br /&gt;
&lt;br /&gt;
На первый взгляд, задача построения системы интернационализации, которая бы подходила для любого языка, кажется неразрешимой. Тем не менее, разработчики ''GNU gettext'' с честью справились с этой проблемой, а программисты KDE создали удобные инструменты для ее решения на своей платформе. Для обработки строк, написание которых должно меняться в зависимости от значения целочисленного аргумента, в систему интернационализации KDE добавлена функция '''i18np()'''. В исходном в файле '''i18ndemoview.cpp''' заменяем строку&lt;br /&gt;
&lt;br /&gt;
  i18n(&amp;quot;This project is %1 days old&amp;quot;, Settings::val_time())&lt;br /&gt;
&lt;br /&gt;
на&lt;br /&gt;
&lt;br /&gt;
  i18np(&amp;quot;This project is %1 day old&amp;quot;, &amp;quot;This project is %1 days old&amp;quot;,  Settings::val_time())&lt;br /&gt;
&lt;br /&gt;
Кстати, обратите внимание на то, что функции '''i18n()''' и '''i18np()''' позволяют форматировать строки, заменяя спецификаторы вида '''%n''' значениями переменных, подобно методу '''QString::arg()'''. У функции '''i18np()''' должно быть как минимум три параметра: строка, в которой об исчисляемом предмете говорится в единственном числе, строка, в которой исчисляемый предмет упомянут во множественном числе, и целочисленная переменная, играющая роль управляющего числительного. Проницательный&lt;br /&gt;
читатель заметит, что описанный синтаксис вызова '''i18np()''' предполагает&lt;br /&gt;
использование всего лишь одной формы для множественного числа,&lt;br /&gt;
тогда как в русском языке их больше. На самом деле беспокоиться&lt;br /&gt;
не о чем. Интерфейс программы мы пишем по-английски, и вполне&lt;br /&gt;
естественно, что мы ориентируемся на грамматику английского языка.&lt;br /&gt;
Особенности русской грамматики будут учтены в ходе локализации.&lt;br /&gt;
&lt;br /&gt;
===Сосчитай до ста===&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Заголовок=Особенности национальной грамматики|Ширина=200px|Содержание=   О сочетании существительных и числительных в русском языке написаны целые трактаты, и если вы думаете, что знаете об&lt;br /&gt;
этом все, то наверняка ошибаетесь (подумайте, например, как&lt;br /&gt;
правильно сочетаются существительное «сутки» и числительное «двадцать два»). В большинстве случаев мы пользуемся тем&lt;br /&gt;
фактом, что управляемое числительным имя существительное&lt;br /&gt;
может находиться в одной из трех форм. Первая форма – для&lt;br /&gt;
единственного числа и всех числительных, заканчивающихся на&lt;br /&gt;
«один», вторая форма – для всех числительных, оканчивающихся на «два», «три» и «четыре», третья форма – для всех числительных, оканчивающихся на «пять», «шесть», «семь», «восемь», «девять», а так же для числительных, содержащих в двух младших разрядах 11–19, и всех числительных, соответствующих цифрам, у которых в младшем разряде находится 0 (сами формы&lt;br /&gt;
для разных существительных выглядят по-разному, но с этим у читателей русского LXF не должно возникнуть проблем).}}&lt;br /&gt;
&lt;br /&gt;
Мы подготовили исходный текст программы для интернационализации&lt;br /&gt;
и можем вызвать утилиту ''xgettext'' для генерации каталога фраз, предназначенных для перевода. Теперь вызов ''xgettext'' будет выглядеть так:&lt;br /&gt;
&lt;br /&gt;
 xgettext -C -ki18n -kI18N_NOOP -ki18np:1,2 *.cpp&lt;br /&gt;
&lt;br /&gt;
В результате на диске появится файл ''messages.po'' (имя можно изменить&lt;br /&gt;
с помощью ключа '''-o'''). Если мы откроем его в текстовом редакторе, то,&lt;br /&gt;
помимо прочего, увидим в нем следующее:&lt;br /&gt;
&lt;br /&gt;
 msgid &amp;quot;This project is 1 day old&amp;quot;&lt;br /&gt;
 msgid_plural &amp;quot;This project is %1 days old&amp;quot;&lt;br /&gt;
&lt;br /&gt;
то есть в каталог сообщений добавлены обе формы. Для перевода строк&lt;br /&gt;
на русский язык файл messages.po придется «обработать напильником».&lt;br /&gt;
Найдите в заголовке файла строку&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
и замените ее на&lt;br /&gt;
&lt;br /&gt;
 &amp;quot;Plural-Forms: nplurals=3; plural=(n%10==1 &amp;amp;&amp;amp; n%100!=11 ? 0 : n%10&amp;gt;=2&lt;br /&gt;
 &amp;amp;&amp;amp; n%10&amp;lt;=4 &amp;amp;&amp;amp; (n%100&amp;lt;10 || n%100&amp;gt;=20) ? 1 : 2);\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Здесь мы указываем, что общее количество форм множественного&lt;br /&gt;
числа равно трем (значение параметра '''nplurals'''), и присваиваем параметру '''plural''' однострочное выражение на ''C'', которое позволяет выбрать нужную форму в зависимости от значения управляющей переменной.&lt;br /&gt;
Это выражение взято из документа, который можно найти по ссылке http://www.gnu.org/software/automake/manual/gettext/Plural-forms.html. Там же приведены аналогичные выражения для других языков. Обратите&lt;br /&gt;
внимание на последовательность форм, которая задается выражением&lt;br /&gt;
'''plural'''. Первая форма (индекс 0) соответствует единственному числу и&lt;br /&gt;
всем числительным, заканчивающимся на 1 (см. врезку). Вторая форма (индекс 1) – числительным, оканчивающимся на 4–9 и 11–19, третья форма – всем остальным числительным.&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF111_86_1.jpg|300px|Рис. 1]]Рис. 1. Программа ''Lokalize'' – наследник ''KBabel''.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Теперь, наконец, приступим к самому переводу. Редактирование с этой целью строк, собранных в каталогах po, можно выполнить в любом&lt;br /&gt;
текстовом редакторе, но KDE, по традиции, предоставляет нам специальный инструмент. В предыдущих версиях KDE данную функцию выпол-&lt;br /&gt;
няла программа ''KBabel'', а начиная с KDE 4.1 нужная утилита называется ''Lokalize'' (рис. 1).&lt;br /&gt;
&lt;br /&gt;
Если открыть файл каталога в программе ''Lokalize'', в списке слева (окно «'''Содержание'''») появятся строки, импортированные утилитой&lt;br /&gt;
''xgettext'' с переводами на другой язык, если таковые уже имеются. Новые&lt;br /&gt;
переводы добавляются в окне справа. Интересно поведение программы&lt;br /&gt;
''Lokalize'' в случае, когда мы выбираем строку с несколькими формами&lt;br /&gt;
для передачи множественного числа. При этом в окне переводов открывается несколько вкладок (как показано на рисунке). Их число соответствует значению '''nplurals''' в заголовке файла каталога (в нашем случае их&lt;br /&gt;
будет три). Последовательность вкладок соответствует последовательности значений, возвращаемых выражением '''plural'''. В каждой из этих вкладок мы вводим перевод, не забывая указывать спецификатор '''%1''' в&lt;br /&gt;
подобающем ему месте.&lt;br /&gt;
&lt;br /&gt;
После завершения следует должны скомпилировать файл каталога '''po''' в двоичный файл с расширением '''mo'''. Это делается с помощью утилиты ''msgfmt'':&lt;br /&gt;
&lt;br /&gt;
 msgfmt messages.po -o i18ndemo.mo&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF111_86_2.jpg|200px|Рис. 2]] Рис. 2. Результат локализации налицо.|Ширина=200px}}&lt;br /&gt;
&lt;br /&gt;
Ключ '''-о''' позволяет указать имя результирующего файла, которое по умолчанию должно совпадать с именем собираемой программы. Нам осталось скопировать двоичный файл каталога в директорию, в которой приложения KDE ищут свои ресурсы локализации (программа может загрузить их только из специальной директории и никак иначе – это относится, в&lt;br /&gt;
том числе, и к текущему рабочему каталогу). Система предоставляет две&lt;br /&gt;
директории для размещения ресурсов локализации – глобальную, для&lt;br /&gt;
приложений, установленных в системе, и локальную, для отдельных&lt;br /&gt;
пользователей. Запись файлов в локальную директорию не требует прав&lt;br /&gt;
root. По умолчанию, глобальным каталогом является общая директория&lt;br /&gt;
ресурсов локализации '''/usr/share/locale/''' (в отличие от KDE 3.x, в которой&lt;br /&gt;
использовалась собственная директория). Локальная директория расположена в '''~/.kde4/share/locale/'''. Файлы переводов сообщений на русский язык необходимо размещать в поддиректории '''ru/LC_MESSAGES/''' одной&lt;br /&gt;
из указанных директорий. Теперь наша тестовая программа дружит с падежами (рис. 2).&lt;br /&gt;
&lt;br /&gt;
===Контексты===&lt;br /&gt;
&lt;br /&gt;
В предыдущих версиях Qt/KDE уже были реализованы средства, призванные решить еще одну проблему перевода, связанную с многозначностью слов английского языка. Например, английское слово build может быть существительным «сборка» и глаголом «собрать». Чтобы локализаторы могли предоставить адекватный перевод одного и того же&lt;br /&gt;
слова, используемого в разных значениях, в KDE 4 существует система контекстов. Контекст задается с помощью функции '''i18nc()''', принимающей два аргумента: строку контекста и фразу, подлежащую переводу,&lt;br /&gt;
например: '''i18nc(&amp;quot;noun&amp;quot;, &amp;quot;Build&amp;quot;), i18nc(&amp;quot;verb&amp;quot;, &amp;quot;Build&amp;quot;)'''.&lt;br /&gt;
&lt;br /&gt;
Если одна и та же переводимая строка используется в разных контекстах, каждый из них вносится в файл '''messages.po'''. Разумеется, программа ''Lokalize'' позволяет ввести для каждого контекста свой вариант перевода.&lt;br /&gt;
&lt;br /&gt;
Чтобы извлечь из исходных текстов строки, помеченные для перевода с помощью функции '''i18nc()''', нужно использовать специальный синтаксис ключа '''-k''' утилиты ''xgettext''. Там, где при использовании '''i18n()''' мы&lt;br /&gt;
написали бы '''-ki18n''', в случае с '''i18nc()''' нужно писать '''-ki18nc:1c,2''' (иначе&lt;br /&gt;
говоря, мы указываем, что первым аргументов функции '''i18nc()''' является идентификатор контекста, а вторым – строка, предназначенная для&lt;br /&gt;
перевода). Как вы уже, наверное, поняли, утилита ''xgettext'' ничего не знает о семантике функций '''i18n*''', а при их обработке руководствуется подсказками, которые мы передаем в ключе '''-k'''. Для обработки строк с указанием контекста и несколькими численными формами служит функция '''i18ncp()''', которую можно рассматривать как гибрид '''i18nc()''' и '''i18np()'''. Ее&lt;br /&gt;
первый аргумент – контекст, далее следуют строки для единственного&lt;br /&gt;
и множественного числа и целочисленная переменная. Для извлечения&lt;br /&gt;
строк, помеченных функцией '''i18ncp()''', утилите ''xgettext'' должен быть&lt;br /&gt;
передан ключ '''-ki18ncp:1c,2,3'''.&lt;br /&gt;
&lt;br /&gt;
===KLocale: даты, числа, деньги===&lt;br /&gt;
&lt;br /&gt;
Множество полезных функций локализации сосредоточено в классе&lt;br /&gt;
'''KLocale'''. Его объект, управляющий локалью, создается в программе KDE&lt;br /&gt;
автоматически. Для того чтобы получить указатель на глобальный объект класса '''Klocale''', воспользуемся вызовом '''KGlobal::locale()''':&lt;br /&gt;
&lt;br /&gt;
 KLocale * aLocale = KGlobal::locale();&lt;br /&gt;
&lt;br /&gt;
По умолчанию программа использует локаль, выбранную в настройках системы. Для указания локали явным образом можно использовать&lt;br /&gt;
метод '''setLanguage()'''. В KDE 3.x ему передавалась одна строка с именем локали. В KDE 4.x мы можем передать методу список '''QStringList''' с&lt;br /&gt;
именами нескольких локалей, из которых система выберет первую, для&lt;br /&gt;
которой сможет найти ресурсы локализации:&lt;br /&gt;
&lt;br /&gt;
 aLocale-&amp;gt;setLanguage(QStringList(&amp;quot;ru&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
Теперь мы можем воспользоваться всеми удобствами класса '''KLocale'''.&lt;br /&gt;
Если нам нужно вывести данные о денежной сумме в формате, соответствующем выбранной локали, к нашим услугам метод '''formatMoney()'''.&lt;br /&gt;
Например, вызов&lt;br /&gt;
&lt;br /&gt;
 aLocale-&amp;gt;formatMoney(&amp;quot;10000.67&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
вернет строку “10.000,67 руб.”. Подобным же образом работает метод '''formatNumber()'''.&lt;br /&gt;
&lt;br /&gt;
Для форматирования значений даты и времени нам предоставлены методы '''formatDate(), formatDateTime(), formatTime()'''. Их первым параметром должно быть значение типа '''QDate, QDateTime''' (или '''KDateTime''')&lt;br /&gt;
и '''QTime''' соответственно. Вторым аргументом у функций '''formatDate()''' и&lt;br /&gt;
'''formatDateTime()''' является одна из констант типа '''DateFormat: ShortDate''' –&lt;br /&gt;
«короткая» дата (с численным обозначением месяца), '''LongDate''' – «длинная» дата (с буквенным обозначением месяца и указанием дня недели), '''FancyShortDate''' или '''FancyLongDate''' – аналоги '''ShortDate''' и '''LongDate''',&lt;br /&gt;
для которых недавние (в пределах недели) даты заменяются словами&lt;br /&gt;
«сегодня», «вчера», «понедельник» и т.д.&lt;br /&gt;
&lt;br /&gt;
Помимо прочего, с помощью глобального объекта '''KLocale''' мы можем&lt;br /&gt;
управлять загрузкой ресурсов интернационализации. Статический метод&lt;br /&gt;
'''setMainCatalogue()''' позволяет задать имя каталога сообщений, используемого по умолчанию. Его нужно вызывать в самом начале функции''' main()''', до того как будет создан глобальный объект '''KLocale'''.&lt;br /&gt;
Обычно программа ищет перевод своего интерфейса в файле, название которого совпадает с ее собственным именем. С помощью метода '''setMainCatalogue()''' мы можем изменить это поведение. Так можно&lt;br /&gt;
поступить, например, в том случае, когда фразы, требующие перевода в&lt;br /&gt;
вашей программе, образуют подмножество строк другого, широко распространенного приложения, скажем, ''Konqueror''. В этом случае, используя каталог сообщений программы ''Konqueror'', вы «бесплатно» получаете&lt;br /&gt;
перевод интерфейса вашего приложения на все поддерживаемые языки.&lt;br /&gt;
Нестатический метод '''insertCatalog()''' класса '''KLocale''' позволяет добавить&lt;br /&gt;
еще один элемент в список каталогов, в которых программа ищет переводы строковых ресурсов. При вызове методов загрузки каталогов имена файлов следует указывать без расширения, например:&lt;br /&gt;
&lt;br /&gt;
 KLocale::setMainCatalogue(&amp;quot;konqueror&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
===Обновление правок===&lt;br /&gt;
&lt;br /&gt;
Предположим, что вы обновляете версию программы, для которой&lt;br /&gt;
когда-то был выполнен перевод на другие языки (и, возможно, не только вами). Вы внесли некоторые изменения в интерфейс программы, но значительная часть строк осталась неизменной. У переводчиков программы хранятся файлы '''PO''' с прежним переводом и они, естественно, не хотят переводить заново то, что уже было переведено. Как перенести&lt;br /&gt;
старый перевод в новый файл '''PO'''? Алгоритм решения таков: сгенерировать новый файл '''PO''' при помощи ''xgettext''; объединить новый файл '''PO''' и старый файл с переводом с помощью утилиты ''msgmerge''; перевести непереведенные строки. В простейшем случае вызов ''msgmerge''&lt;br /&gt;
выглядит так:&lt;br /&gt;
&lt;br /&gt;
 msgmerge старый_файл новый_файл&lt;br /&gt;
&lt;br /&gt;
где старый_файл – файл '''PO''' с уже выполненным переводом, а новый_файл – файл '''PO''', сгенерированный ''xgettext''. По умолчанию утилита выводит результат своей работы в стандартный поток вывода, но ничто не&lt;br /&gt;
мешает нам перенаправить его в файл. Схематично механизм слияния&lt;br /&gt;
можно описать так: для каждой строки нового файла ''msgmerge'' ищет&lt;br /&gt;
перевод в старом файле. Если перевод найден, он добавляется в результирующий текст. Таким образом, если в ходе обновления программы из ее интерфейса была удалена какая-либо строка, она уже не попадет в&lt;br /&gt;
файл, полученный в результате слияния.&lt;br /&gt;
&lt;br /&gt;
Объединять файлы каталогов можно и с помощью ''Lokalize''. Загрузите основной файл каталога в ''Lokalize'' и выберите команду меню&lt;br /&gt;
'''Синхронизация &amp;gt; Открыть файл для синхронизации/объединения'''. В появившемся окне нужно указать файл каталога для объединения с главным. В нижней части окна ''Lokalize'' откроется панель '''Синхронизация'''. На&lt;br /&gt;
ней будут отображаться различия в переводах между вспомогательным&lt;br /&gt;
и основным файлом (для этого в окне '''Содержание''' необходимо выделить строку переводимого текста, для которой различаются переводы). С помощью команд '''Перенести из источника слияния''' и '''Перенести все новые переводы''' можно добавить переводы из вспомогательного файла в основной.&lt;br /&gt;
&lt;br /&gt;
===Перевод из файлов ui===&lt;br /&gt;
&lt;br /&gt;
А как быть с теми строками, которые были заданы в файле описания&lt;br /&gt;
интерфейса (ui)? Утилита ''xgettext'' не справляется с их извлечением, но&lt;br /&gt;
нам на помощь приходит утилита ''extractrc''. Эта программа извлекает&lt;br /&gt;
помеченные для перевода строки из файлов '''UI''' и '''RC''' (имеются в виду&lt;br /&gt;
файлы '''XMLGUI''', а не скрипты '''runcommand''') и генерирует файл ''cpp'', в&lt;br /&gt;
котором эти строки оборачиваются функциями '''i18n()'''. Утилита всегда&lt;br /&gt;
вываливает сгенерированный текст в стандартный поток вывода, но это&lt;br /&gt;
можно изменить перенаправлением.&lt;br /&gt;
&lt;br /&gt;
Я не стал переводить интерфейс диалогового окна настроек программы '''i18ndemo''' – оставляю это вам в качестве домашнего задания&lt;br /&gt;
(подсказка: для объединения существующего перевода и перевода строк интерфейса диалогового окна воспользуйтесь ''msgmerge'' или&lt;br /&gt;
''Lokalize''). '''LXF'''&lt;/div&gt;</summary>
		<author><name>Crazy Rebel</name></author>	</entry>

	</feed>