<?xml version="1.0" ?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
  <!ENTITY kappname "&ksplash;">
  <!ENTITY package "kdebase">
  <!ENTITY % addindex "IGNORE">
  <!ENTITY % Russian "INCLUDE">
]>

<book lang="&language;">

<bookinfo>
<title
>Руководство &ksplash;</title>

<authorgroup>
<author
>&Teemu.Rytilahti; &Teemu.Rytilahti.mail; </author>

<othercredit role="developer"
>&Brian.C.Ledbetter; &Brian.C.Ledbetter.mail; </othercredit>

<othercredit role="developer"
>&Ravikiran.Rajagopal; &Ravikiran.Rajagopal.mail; </othercredit>

<othercredit role="translator"
><firstname
>Иван</firstname
><surname
>Кашуков</surname
><affiliation
><address
><email
>dolphin210@yandex.ru</email
></address
></affiliation
><contrib
>Перевод на русский</contrib
></othercredit
><othercredit role="translator"
><firstname
>Николай</firstname
><surname
>Шафоростов</surname
><affiliation
><address
><email
>shafff@ukr.net</email
></address
></affiliation
><contrib
>Обновление русского перевода</contrib
></othercredit
> 

</authorgroup>

<copyright>
<year
>2003</year>
<holder
>Teemu Rytilahti</holder>
</copyright>
<copyright>
<year
>2003-04</year>
<holder
>Ravikiran Rajagopal</holder>
</copyright>
<legalnotice
>&FDLNotice;</legalnotice>

<date
>2003-01-10</date>
<releaseinfo
>1.01.00</releaseinfo>

<abstract>
<para
>&ksplash; &mdash; симпатичный экран, показывающий процесс загрузки приложения</para>
</abstract>

<keywordset>
<keyword
>KDE</keyword>
<keyword
>kdebase</keyword>
<keyword
>ksplash</keyword>
<keyword
>ksplashml</keyword>
<keyword
>splashscreen</keyword>
<keyword
>eye candy</keyword>
</keywordset>

</bookinfo>

<chapter id="introduction">
<title
>Введение</title>

<para
>&ksplash; &mdash; симпатичный экран, показывающий процесс загрузки приложения. Вопросы и пожелания отправляйте в списки рассылки &kde;. Отличительные особенности &ksplash;: </para>
<simplelist>
<member
>Возможность применения тем</member>
<member
>Высокая гибкость в настройке обеспечивается использованием подключаемых модулей</member>
<member
>Программа может быть использована любым приложением, которое работает с DCOP</member>
</simplelist>

<para
>Это руководство объясняет, как создавать темы для использования с уже доступными подключаемыми модулями. Если ни один из доступных модулей не удовлетворяет вашему вкусу, вы можете научиться полностью настраивать внешний вид &ksplash;, создавая подключаемые модули на C++. </para>
</chapter>

<chapter id="using-themes">
<title
>Использование тем</title>

<para
>Чтобы использовать темы с <ulink url="http://www.kde-look.org"
>KDE-Look</ulink
>, скопируйте их в <filename
>~/.kde/apps/ksplash/Themes/</filename
> (для одного пользователя) или в <filename
>$<envar
>KDEDIR</envar
>/share/apps/ksplash/Themes/</filename
> (чтобы сделать их доступными для всех пользователей вашей системы).</para>

<para
>Чтобы сделать это автоматически, используйте модуль <guilabel
>Экран загрузки</guilabel
> раздела <guilabel
>Внешний вид</guilabel
> Центра управления &kde;.</para>

<sect1 id="using-kcontrol-module">
<title
>Модуль Центра управления</title>

<para
>Этот модуль позволяет устанавливать, тестировать и удалять темы &ksplash;.</para>

<para
>Внизу расположен список доступных тем &ksplash;. При выборе одной из последних, её предварительный просмотр появится в соответствующей части окна. Чтобы активировать тему, нажмите <guibutton
>OK</guibutton
> или <guibutton
>Применить</guibutton
>.</para>

<para
>Чтобы установить новые модули, нажмите <guibutton
>Добавить...</guibutton
>. Не нужно распаковывать файлы тем, они могут обрабатываться и в сжатом виде.</para>

<para
>Для просмотра анимации темы, нажмите кнопку<guibutton
>Тест</guibutton
>.</para>

<para
>Чтобы удалить тему, воспользуйтесь кнопкой <guibutton
>Удалить</guibutton
>. Если тема установлена для всех пользователей, то удалять её нужно с правами администратора. Также, мы не рекомендуем удалять тему <guilabel
>по умолчанию</guilabel
>.</para>

</sect1>

</chapter>

<chapter id="themes">
<title
>Как создавать темы для &ksplash;</title>
<sect1 id="themes-general">
<title
>Основные положения</title>
<para
>Создавать свои собственные темы для &ksplash; достаточно легко. Когда вы закончили свою тему, вы можете отослать её в <ulink url="http://www.kde-look.org"
>KDE-Look</ulink
>, чтобы её могли использовать другие.</para>

<sect2 id="theme-syntax">
<title
>Определение своей темы</title>

<para
>Давайте создадим тему под названием <literal
>MyCoolTheme</literal
>. Чтобы тема была распознана &ksplash;, следует поместить её в папку <filename class="directory"
>MyCoolTheme</filename
> в каталоге <filename class="directory"
>~/.kde/apps/ksplash/Themes/</filename
>. В ней должен содержаться файл <filename
>Theme.rc</filename
>, содержащий настройки темы. Вы можете установить множество особенностей для темы, изменить движок подключаемых модулей и т. д. Не обязательно использовать все доступные настройки, обычно используются только некоторые. Синтаксис записей файла <filename
>Theme.rc</filename
>: <literal
>[опция] = [значение]</literal
>. В последующих секциях определяется множество опций.</para>

<example>
<title
>Простой файл <filename
>Theme.rc</filename
></title>
<programlisting
>[KSplash Theme: MyCoolTheme]
Name = MyCoolTheme
Description = Симпатичная тема, использующая движок XpLike
Version = 1.0
Author = Настоящее имя &lt;имя_пользователя@имя_сервера.домен&gt;
## Use the XpLike engine for this theme.
Engine = XpLike
Show Icon = false
Welcome Text = Загрузка KDE
</programlisting>
</example>

<para
>После того как вы задали имя, описание и автора темы, вам следует выбрать движок темы (подключаемый модуль). Затем вы сможете настроить разнообразные характеристики движка темы, устанавливая пары опция=значение, как в вышеприведённом файле.</para>

<para
>Важно чтобы имя папки, в которой хранятся файлы темы (<filename class="directory"
>~/.kde/apps/ksplash/Themes/MyCoolTheme</filename
>) и идентификатор (<literal
>[KSplash Theme: MyCoolTheme] </literal
>) в <filename
>Theme.rc</filename
> совпадали. </para>

</sect2>

<sect2 id="theme-files">
<title
>Файлы фона</title>

<para
>При запуске &ksplash; пытается найти файл фона, соответствующий текущему разрешению экрана (если файл используется движком темы). Формат названия файла фона: <filename
>Background-<replaceable
>WWWxHHH</replaceable
>.png</filename
>.</para>

<para
>Например, вам надо использовать файл <filename
>Background-1024x768</filename
>. Если файл, соответствующий текущему разрешению экрана, не найден, программа пытается изменить размер файла <filename
>Background.png</filename
> (или другого, заданного в <filename
>Theme.rc</filename
>) так, чтобы он соответствовал разрешению. Изменение размера <quote
>на лету</quote
> занимает некоторое время, так что вам следует создать файлы как минимум для следующих разрешений экрана: 1280x1024, 1024x768 и 800x600.</para>
</sect2>
</sect1>

<sect1 id="theme-engines">
<title
>Опции движков тем</title>

<sect2 id="standard-themes">
<title
>Стандартная тема</title>
<table>
<title
>Опции стандартной темы</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Название</entry>
<entry
>Аргумент</entry>
<entry
>Значение</entry>
</row>
<!-- Statusbar -->
<row>
<entry
>Statusbar Position</entry>
<entry
>[top/bottom]</entry>
<entry
>Определяет расположение индикатора состояния на экране. Значение по умолчанию &mdash; bottom (внизу).</entry>
</row>
<row>
<entry
>Statusbar Visible</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли индикатор состояния видимым. Значение по умолчанию &mdash; true (истина).</entry>
</row>
<row>
<entry
>Progress Visible</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли показан прогресс загрузки. Значение по умолчанию &mdash; true.</entry>
</row>
<!-- Fonts -->
<row>
<entry
>Statusbar Font</entry>
<entry
>[название_шрифта]</entry>
<entry
>Шрифт, используемый в индикаторе состояния (по умолчанию &mdash; Helvetica).</entry>
</row>
<row>
<entry
>Statusbar Font Size</entry>
<entry
>[размер]</entry>
<entry
>Размер шрифта индикатора состояния (по умолчанию &mdash; 16).</entry>
</row>
<row>
<entry
>Statusbar Font Bold</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли шрифт индикатора состояния полужирным (по умолчанию &mdash; true).</entry>
</row>
<row>
<entry
>Statusbar Font Italic</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли шрифт индикатора состояния наклонным (по умолчанию -true).</entry>
</row>
<!-- Misc. things -->
<row>
<entry
>Statusbar Foreground</entry>
<entry
>[цвет]</entry>
<entry
>Цвет переднего плана индикатора состояния. Значение по умолчанию &mdash; white (белый).</entry>
</row>
<row>
<entry
>Statusbar Background</entry>
<entry
>[цвет]</entry>
<entry
>Цвет фона индикатора состояния. Значение по умолчанию &mdash; black (чёрный).</entry>
</row>
<row>
<entry
>Statusbar Icon</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли пиктограмма у индикатора состояния.</entry>
</row>
<row>
<entry
>Icons Visible</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будут ли пиктограммы видимыми. Значение по умолчанию &mdash; true.</entry>
</row>
<row>
<entry
>Icons Jumping</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будут ли пиктограммы прыгающими. Значение по умолчанию &mdash; true.</entry>
</row>
<row>
<entry
>Icon Position</entry>
<entry
>[0-3, 10-13]</entry>
<entry
>Расположение пиктограмм (по умолчанию &mdash; вверху слева).</entry>
</row>
<row>
<entry
>Splash Screen</entry>
<entry
>[название]</entry>
<entry
>Изменяет образ отображаемого экрана.</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>

<sect2 id="redmond-themes">
<title
>Тема Redmond</title>
<table>
<title
>Опции темы Redmond</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Название</entry>
<entry
>Аргумент</entry>
<entry
>Значение</entry>
</row>
<!-- Main elements -->
<row>
<entry
>Background Image</entry>
<entry
>[имя_файла]</entry>
<entry
>Определяемый пользователем фоновый рисунок.</entry>
</row>
<row>
<entry
>User Icon</entry>
<entry
>[название]</entry>
<entry
>Название пиктограммы, отображаемой для пользователя. По умолчанию &mdash; <constant
>go</constant
>.</entry>
</row>
<row>
<entry
>Welcome Text</entry>
<entry
>[текст]</entry>
<entry
>Текст, отображающийся на экране. По умолчанию &mdash; "Добро пожаловать".</entry>
</row>
<row>
<entry
>Username Text</entry>
<entry
>[текст]</entry>
<entry
>Текст, замещающий имя пользователя.</entry>
</row>
<!-- Positioning elements -->
<row>
<entry
>Welcome Text Position</entry>
<entry
>[x,y]</entry>
<entry
>Область экрана, в которой отображается текст приглашения (определяемый опцией Welcome Text).</entry>
</row>
<row>
<entry
>Username Text Position</entry>
<entry
>[x,y]</entry>
<entry
>Область экрана, в которой отображается имя пользователя.</entry>
</row>
<row>
<entry
>Action Text Position</entry>
<entry
>[x,y]</entry>
<entry
>Область экрана, в которой отображается текущее действие.</entry>
</row>
<row>
<entry
>Icon Position</entry>
<entry
>[x,y]</entry>
<entry
>Область экрана, в которой отображается пиктограмма пользователя.</entry>
</row>
<!-- Show to show.. -->
<row>
<entry
>Show Welcome Text</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли отображаться текст приглашения (значение по умолчанию &mdash; true).</entry>
</row>
<row>
<entry
>Show Welcome Shadow</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли отображаться тень текста приглашения (значение по умолчанию &mdash; true).</entry>
</row>
<row>
<entry
>Show Username</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли отображаться имя пользователя (значение по умолчанию &mdash; true).</entry>
</row>
<row>
<entry
>Show Action</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли отображаться действие, выполняемое в данный момент. Значение по умолчанию &mdash; true.</entry>
</row>
<row>
<entry
>Show Icon</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли отображаться пиктограмма. Значение по умолчанию &mdash; true.</entry>
</row>
<row>
<entry
>Use KDM User Icon</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будет ли использоваться пиктограмма, соответствующая пользователю при входе в систему. Значение по умолчанию &mdash; true.</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>

<sect2 id="macx-themes">
<title
>Тема MacX</title>
<table>
<title
>Опции темы MacX</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Название</entry>
<entry
>Аргумент</entry>
<entry
>Значение</entry>
</row>
<row>
<entry
>Icon Size Minimum</entry>
<entry
>[размер]</entry>
<entry
>Минимальный размер пиктограммы (по умолчанию &mdash; 16).</entry>
</row>
<row>
<entry
>Icon Size Maximum</entry>
<entry
>[размер]</entry>
<entry
>Максимальный размер пиктограммы (по умолчанию &mdash; 64).</entry>
</row>
<row>
<entry
>Optimized Icon Rendering</entry>
<entry
>[true/false]</entry>
<entry
>Будет ли оптимизироваться отрисовка пиктограмм (значение по умолчанию &mdash; true).</entry>
</row>
<row>
<entry
>Progress Bar Visible</entry>
<entry
>[true/false]</entry>
<entry
>По умолчанию &mdash; true.</entry>
</row>
<row>
<entry
>Progress Bar Position</entry>
<entry
>[top/bottom]</entry>
<entry
>Определяет расположение индикатора состояния (внизу или вверху). По умолчанию - bottom (внизу).</entry>
</row>
<row>
<entry
>Icons Jumping</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будут ли пиктограммы прыгающими (по умолчанию &mdash; false).</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>

<sect2 id="mac-classic-themes">
<title
>Тема MacClassic</title>
<table>
<title
>Опции темы MacClassic</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Название</entry>
<entry
>Аргумент</entry>
<entry
>Значение</entry>
</row>
<row>
<entry
>Icon Position</entry>
<entry
>[0-3, 10-13]</entry>
<entry
>Расположение пиктограмм на экране, по умолчанию &mdash; внизу слева.</entry>
</row>
<row>
<entry
>Icons Jumping</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будут ли пиктограммы прыгающими (по умолчанию &mdash; false).</entry>
</row>
<row>
<entry
>Icons Visible</entry>
<entry
>[true/false]</entry>
<entry
>Определяет, будут ли пиктограммы видимыми. Значение по умолчанию &mdash; true.</entry>
</row>
<row>
<entry
>Splash Screen</entry>
<entry
>[название]</entry>
<entry
>Изменяет образ отображаемого экрана.</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>

<sect2 id="themes-2k">
<title
>Тема 2k</title>
<table>
<title
>Опции темы 2k</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Название</entry>
<entry
>Аргумент</entry>
<entry
>Значение</entry>
</row>
<row>
<entry
>Title Background Color</entry>
<entry
>[цвет]</entry>
<entry
>Фоновый цвет заголовка, по умолчанию &mdash; dark blue (тёмно-синий).</entry>
</row>
<row>
<entry
>Title Foreground Color</entry>
<entry
>[цвет]</entry>
<entry
>Цвет переднего плана заголовка. По умолчанию &mdash; white (белый).</entry>
</row>
<row>
<entry
>Status Text Color</entry>
<entry
>[цвет]</entry>
<entry
>Цвет текста состояния. По умолчанию соответствует фоновому тексту заголовка (определяемому опцией Title Background Color).</entry>
</row>
<row>
<entry
>Rotator Color 1</entry>
<entry
>[цвет]</entry>
<entry
>Определяет цвет индикатора 1. По умолчанию &mdash; dark blue, тёмно-синий.</entry>
</row>
<row>
<entry
>Rotator Color 2</entry>
<entry
>[цвет]</entry>
<entry
>Определяет цвет индикатора 2, по умолчанию &mdash; светло-серый (cyan).</entry>
</row>
<row>
<entry
>Rotator Speed</entry>
<entry
>[значение]</entry>
<entry
>Определяет скорость индикатора, по умолчанию &mdash; 30.</entry>
</row>
<row>
<entry
>Window Title</entry>
<entry
>[текст]</entry>
<entry
>Определяет текст заголовка окна.</entry>
</row>
<row>
<entry
>Logo File</entry>
<entry
>[имя_файла]</entry>
<entry
>Определяет используемый логотип.</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
</sect1>
</chapter>

<chapter id="from-other-applications">
<title
>Использование &ksplash; в вашем собственном приложении</title>

<para
>В этой главе описывается простой метод использования &ksplash; в качестве окна-показателя загрузки в вашем приложении для &kde;. Если вы не разрабатываете приложения для &kde;, вы можете опустить эту главу.</para>

<sect1 id="basic-other-reqs">
<title
>Основные требования</title>

<para
>Ваше приложение &kde; должно работать с &DCOP;. &DCOP; &mdash; это технология &kde;, использующаяся для коммуникации между приложениями. Если вы используете <ulink url="http://developer.kde.org"
>стандартную структуру приложения &kde;</ulink
>, это обеспечивается автоматически. Чтобы получить информацию о &DCOP; и связанных технологиях &kde;, посетите <ulink url="http://developer.kde.org"
>сайт разработчиков &kde;</ulink
>.</para>
</sect1>

<sect1 id="other-using">
<title
>Запуск &ksplash;</title>

<para
>До того, как ваше приложение начнёт вычисления, загрузку подключаемых модулей и т. д., запустите &ksplash;. Образец:</para>

<programlisting
>DCOPClient *c = kapp-&gt;dcopClient();
QString error;
QCString KSplashName;
int pid = 0;
QStringList args;
args &lt;&lt; "--theme=MyCoolTheme" &lt;&lt; "--managed";
if (kapp-&gt;startServiceByDesktopName("ksplash", args, &amp;error, &amp;KSplashName, &amp;pid))
{
  KMessageBox::sorry(0, error, "Unable to invoke KSplash");
  // Some error processing here.
}
</programlisting>

<para
>Мы предполагаем, что запущено только одно окно &ksplash;. Другие случаи немного более сложны. Разъяснения см. в документации &DCOP;.</para>
</sect1>

<sect1 id="show-messages">
<title
>Отображение сообщений</title>

<para
>Перед отображением сообщений вам необходимо установить число шагов. Например, процедура запуска &kde; включает 7 этапов.</para>

<programlisting
>QByteArray data;
    QDataStream arg(data,IO_WriteOnly);
    arg &lt;&lt; someNumber;
    if (!(c-&gt;send(KSplashName, "KSplashIface", "setStartupItemCount(int)", data))
      // Здесь проявляется некоторая ошибка.
</programlisting>

<para
>Если вы хотите, чтобы сообщение отображалось с пиктограммой или без неё, используйте</para>

<programlisting
>arg &lt;&lt; QString("название_пиктограммы") &lt;&lt; QString("название_программы") &lt;&lt; QString("некоторое описание");
    if (!(c-&gt;send(KSplashName, "KSplashIface", "programStarted(QString,QString,QString)", data))
    {
      // Здесь проявляется некоторая ошибка.
    }
</programlisting>

<para
>Каждый раз, когда вы вызываете <constant
>programStarted</constant
>, шаги заканчиваются. Когда ваша программа закончила запуск, выполните следующие команды, чтобы убрать экран загрузки:</para>

<programlisting
>if (!(c-&gt;send(KSplashName, "KSplashIface", "startupComplete()", data))
    {
      // Здесь проявляется некоторая ошибка.
    }
</programlisting>

<para
>Это всё, что вам необходимо, чтобы использовать все преимущества &ksplash;.</para>

</sect1>
</chapter>

<!-- FIXME: Better to leave this out until it's written, or the translators -->
<!-- will have to still translate it ... -->

<chapter id="wrplugins">
<title
>Создание новых подключаемых модулей &ksplash;</title>

<para
>Создавать подключаемые модули &ksplash; нетрудно. В этой главе мы напишем простой модуль, который эмулирует экран загрузки одной очень известной операционной системы. Предполагается, что вы знакомы с основами языка C++, и хотя бы немного &mdash; с программированием для KDE/Qt.</para>

<sect1 id="basic-requirements">
<title
>Основные требования</title>
<para
>Мы создадим модуль с названием <literal
>2k</literal
>. Название используется во многих местах. Важно не исказить его, чтобы модуль был распознан &ksplash;. Модули &ksplash; являются динамически загружаемыми библиотеками со следующими объявлениями: </para>
<simplelist>
<member
>Библиотеку следует называть по образцу: <filename
>ksplash+название_темы_в_нижнем_регистре</filename
>. В нашем случае название будет <filename
>ksplash2k</filename
>.</member>
<member
>Тема должна иметь свой desktop-файл, который следует назвать <filename
>ksplash+название_темы_в_нижнем_регистре.desktop</filename
>. В нашем случае &mdash; <filename
>ksplash2k.desktop</filename
>. </member>
<member
>Наконец, библиотека должна возвращать класс с названием <literal
>Theme+название_темы</literal
>, в нашем случае &mdash; <literal
>Theme2k</literal
>.</member>
</simplelist>
<para
>Не беспокойтесь, если вы не поняли всё вышесказанное. Далее мы рассмотрим каждый шаг в деталях. Важной деталью является то, что класс модуля вы должны взять из <literal
>ThemeEngine</literal
>. </para>
</sect1>
<sect1 id="skeleton">
<title
>Создание основы</title>
<para
>При создании модуля мы будем использовать основу для приложения &kde;, которая обеспечит независимость от платформы во всех частях нашей работы. Убедитесь, что в вашей системе установлен пакет <filename
>kdesdk</filename
>. Выполните команду <literal
>kapptemplate</literal
>, чтобы создать приложение с названием "2k". Будет создана папка, содержащая основные файлы (такие как AUTHORS и т. п.). Нам нужен подкаталог <filename class="directory"
>2k</filename
>. Удалите все файлы в нём, и основа готова. </para>
<para
>На следующем этапе вы должны создать файл <filename
>.desktop</filename
>, который, после установки, сообщит &ksplash;, что подключаемый модуль доступен. В соответствии с правилами наименования файлов, которые даны <link linkend="basic-requirements"
>в предыдущей секции</link
>, создайте файл <filename
>ksplash2k.desktop</filename
> (в каталоге /2k). Он должен содержать следующие строки: </para>
<programlisting
><literal>
[Desktop Entry]
Encoding=UTF-8
Type=Service
Comment=KSplash Plugin
Name=KSplash2k
ServiceTypes=KSplash/Plugin
X-KDE-Library=ksplash2k
X-KSplash-Default=true
X-KSplash-PluginName=2k
X-KSplash-ObjectName=Theme2k
</literal
>
</programlisting>
<para
>Опции <literal
>Encoding</literal
>, <literal
>Type</literal
>, <literal
>Comment</literal
> и <literal
>ServiceTypes</literal
> одинаковы для всех подключаемых модулей. Название модуля и библиотеки следуют вышеописанным правилам. Опция <literal
>X-KSplash-Default</literal
> может принимать одно из двух значений (true или false). Она определяет, будет ли этот модуль показан в Центре управления как модуль по умолчанию. За исключением некоторых очень редких случаев, его значение должно быть <constant
>true</constant
>. </para>
</sect1>
<sect1 id="headerfile">
<title
>Объявление класса подключаемого модуля</title>
<para
>Теперь, когда мы закончили подготовительную работу, начинается действительно интересная часть &mdash; создание класса, который обеспечивает нужное поведение модуля. Хотя мы вольны делать с этим классом всё, что хотим, существует несколько ограничений.</para>
<orderedlist>
<listitem
><para
>Классы модуля должны соответствовать классу <constant
>ThemeEngine</constant
>.</para
></listitem>
<listitem
><para
>Классы модуля следует называть в соответствии с правилом: <classname
>Тема+название_модуля</classname
>.</para
></listitem>
<listitem
><para
>Классы модуля должны обеспечивать <literal
>статическую</literal
> функцию с названием <function
>names</function
>, которая возвращает список названий, под которыми она может быть задействована.</para
></listitem>
<listitem
><para
>Чтобы модуль можно было настраивать из Центра управления, он должен включать класс, основанный на классе <literal
>ThemeEngineConfig</literal
>.</para
></listitem>
<listitem
><para
>Классы модуля должны перекрывать хотя бы одну из следующих виртуальных функций: <function
>slotSetText</function
>, <function
>slotSetPixmap</function
>, <function
>slotUpdateProgress</function
> и <function
>slotUpdateSteps</function
>, чтобы обеспечить возможность использования.</para
></listitem>
<listitem
><para
>Разработчик должен использовать форму <literal
>ThemeEngine( QWidget *parent, символьную постоянную *name, постоянную QStringList &amp;args )</literal
>, чтобы модуль можно было использовать с <classname
>KGenericFactory</classname
>.</para
></listitem>
</orderedlist>
<para
>Последнее требование может показаться сложным, но, как мы увидим позже, вы можете обычно игнорировать его, добавив одну строку к исходным кодам.</para>
</sect1>
<sect1 id="headercode">
<title
>Код файла заголовка</title>
<para
>Присвоив значения константам, мы увидим, что файл заголовков <filename
>theme2k.h</filename
> приобретёт вид вроде этого:</para>
<example>
<title
>Файл <filename
>theme2k.h</filename
></title>
<programlisting
>#ifndef __THEME2K_H__
#define __THEME2K_H__

#include &lt;qlabel.h&gt;
#include &lt;qwidget.h&gt;

#include &lt;kdialogbase.h&gt;
#include &lt;kpixmap.h&gt;
#include &lt;ksplash/themeengine.h&gt;

class RotWidget;

class Cfg2k: public ThemeEngineConfig
{
  Q_OBJECT
public:
  Cfg2k( KConfig * );
};

class ObjKsTheme;
class Theme2k: public ThemeEngine
{
  Q_OBJECT
public:
  Theme2k( QWidget *, const char *, const QStringList&amp; );

  inline const QString name()
  {
    return( QString("KSplash2k") );
  }
  inline const KDialogBase *config( KConfig *kc )
  {
    return new Cfg2k( kc );
  }
  static QStringList names()
  {
    QStringList Names;
    Names &lt;&lt; "KSplash2k";
    Names &lt;&lt; "ks2k";
    Names &lt;&lt; "2k";
    Names &lt;&lt; "2000";
    return( Names );
  };

public slots:
  inline void slotSetText( const QString&amp; s )
  {
    if( mText &amp;&amp; mText-&gt;text() != s ) mText-&gt;setText( s );
  };

private:
  void initUi();
  void readSettings();

  QLabel *mText;
  RotWidget *mRotator;
  QColor mTBgColor, mTFgColor, mRotColor1, mRotColor2, mStatusColor;
  int mRotSpeed;
  QString mWndTitle, mLogoFile;
};

#endif
</programlisting>
</example>
<para
>Давайте проанализируем вышеприведённое. Класс <classname
>Theme2k</classname
>, произведённый от <classname
>ThemeEngine</classname
> удовлетворяет объявлениям. Он обеспечивает метод <methodname
>Theme2k::names()</methodname
>, и имеет конструктор, который принимает необходимые параметры: <function
>Theme2k( QWidget *, const char *, const QStringList&amp; );</function
>, и к тому же обеспечивает простой метод <methodname
>Theme2k::slotSetText()</methodname
>. На данном этапе вам не следует беспокоиться насчёт класса <classname
>RotWidget</classname
>. Это небольшой элемент графического интерфейса, который делает программу более наглядной для пользователя. Наш подключаемый модуль очень прост: он не отображает ни пиктограмм, ни шкалы загрузки. Если вы хотите использовать пиктограммы, перекройте функцию <function
>slotSetPixmap</function
>. Подобные функции есть для установки шкалы загрузки (<function
>slotUpdateSteps</function
>) и увеличения счётчика (<function
>slotUpdateProgress</function
>) текущего шага. </para>
</sect1>
<sect1 id="Implementation">
<title
>Реализация подключаемого модуля</title>
<para
>Мы проверим только связанные части реализации. В приложении находится описание всей реализации. В первую очередь нам необходимо удовлетворить требованиям библиотеки:</para>
<example>
<title
>Требования библиотеки</title>
<programlisting
>K_EXPORT_COMPONENT_FACTORY( ksplash2k, KGenericFactory&lt;Theme2k&gt; );
</programlisting>
</example>
<para
>Объявление макроса <constant
>K_EXPORT_COMPONENT_FACTORY</constant
> содержится в файле <filename
>kgenericfactory.h</filename
>. Теперь перейдём к конструктору. Так как подключаемый модуль совсем прост, конструктор тоже несложен.</para>
<example>
<title
>Конструктор подключаемого модуля</title>
<programlisting
>Theme2k::Theme2k( QWidget *parent, const char *name, const QStringList &amp;args  )
    :ThemeEngine( parent, name, args )
{
  readSettings();
  initUi();
}
</programlisting>
</example>
<para
>Метод <function
>readSettings()</function
> является иллюстрацией подходящего способа получить настройки темы (вы ведь хотите, чтобы люди могли использовать ваш модуль для своих тем?)</para>
<example>
<title
>Получение настроек темы</title>
<programlisting
>void Theme2k::readSettings()
{
  if( !mTheme )
    return;

  KConfig *cfg = mTheme-&gt;themeConfig();
  if( !cfg )
    return;

  cfg-&gt;setGroup( QString("KSplash Theme: %1").arg(mTheme-&gt;theme()) );

  QColor DefaultTBgColor( Qt::darkBlue );
  QColor DefaultTFgColor( Qt::white );

  mTBgColor = cfg-&gt;readColorEntry( "Title Background Color", &amp;DefaultTBgColor );
  mTFgColor = cfg-&gt;readColorEntry( "Title Foreground Color", &amp;DefaultTFgColor );
  mStatusColor = cfg-&gt;readColorEntry("Status Text Color", &amp;mTBgColor );

  QColor DefaultRot1( Qt::darkBlue );
  QColor DefaultRot2( Qt::cyan );
  mRotColor1 = cfg-&gt;readColorEntry( "Rotator Color 1", &amp;DefaultRot1 );
  mRotColor2 = cfg-&gt;readColorEntry( "Rotator Color 2", &amp;DefaultRot2 );

  mRotSpeed = cfg-&gt;readNumEntry( "Rotator Speed", 30 );
  mWndTitle = cfg-&gt;readEntry( "Window Title", i18n("Please wait...") );
  mLogoFile = cfg-&gt;readEntry( "Logo File", QString::null );
}
</programlisting>
</example>
<para
>Так как мы работаем для пользователей, следует обеспечить подходящие настройки по умолчанию для параметров, которые не представлены в файле темы. Обратите внимание, что группу следует устанавливать следующим образом: "KSplash Theme: название_темы", чтобы обеспечить совместимость с будущими спецификациями темы. Метод <function
>initUI()</function
> не представляет большого интереса, он просто организует элементы графического интерфейса. Детали см. в приложении. </para>
</sect1>
<sect1 id="compilingfile">
<title
>Компиляция подключаемого модуля</title>
<para
>Для компиляции модуля мы решили использовать основу &kde;, поэтому необходимо создать файл <filename
>Makefile.am</filename
>. Он должен выглядеть следующим образом:</para>
<example>
<title
>Файл <filename
>Makefile.am</filename
></title>
<programlisting
>INCLUDES = $(all_includes)

kde_module_LTLIBRARIES = ksplash2k.la

ksplash2k_la_SOURCES = theme2k.cpp rotwidget.cpp
ksplash2k_la_LDFLAGS = $(all_libraries) $(KDE_RPATH)
ksplash2k_la_LIBADD = $(LIB_KDEUI) -lksplashthemes

METASOURCES = AUTO

noinst_HEADERS        = theme2k.h rotwidget.h

servicesdir = $(kde_servicesdir)
services_DATA = ksplash2k.desktop

themedir = $(kde_datadir)/ksplash/Themes/2k
theme_DATA = Theme.rc Preview.png
</programlisting>
</example>
<para
>Чтобы получить дальнейшую информацию по созданию <filename
>Makefile.am</filename
>, загляните на <ulink url="http://developer.kde.org/documentation/other/makefile_am_howto.html"
>веб-сайт</ulink
> разработчиков &kde;. Заметим, что мы создаём тему по умолчанию, основанную на этом модуле, и прилагаем к нему графический файл фона. В качестве жеста вежливости по отношению к пользователям создайте файл <filename
>Theme.rc</filename
>, являющийся примером использования опций.</para>
</sect1>
</chapter>

<chapter id="faq">
<title
>Вопросы и ответы</title>
&reporting.bugs; &updating.documentation; <qandaset id="faqlist">
<qandaentry>
<question>
<para
>Я не могу найти ни одной темы, которая работала бы с &ksplash;. Почему?</para>
</question>
<answer>
<para
>Возможно, у вас нет соответствующих подключаемых модулей для тем. Модули содержатся в пакете <literal
>kde-artwork</literal
>. Скачайте, установите его и попытайтесь запустить темы снова.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para
>Что такое файл <filename
>Theme.rc</filename
> и как его создать?</para>
</question>
<answer>
<para
><filename
>Theme.rc</filename
> &mdash; это файл, где вы можете задать настройки темы. Информация по нему находится в разделе <link linkend="themes"
>Как создавать темы для &ksplash;</link
>. </para>
</answer>
</qandaentry>
</qandaset>
</chapter>

<chapter id="credits">
<title
>Благодарности и лицензирование</title>

<para
>&ksplash;</para>

<para
>Авторские права на программу принадлежат &copy; 2003 &Ravikiran.Rajagopal; &Ravikiran.Rajagopal.mail;</para>

<itemizedlist>
<title
>Помощь в разработке</title>
<listitem
><para
>&Brian.C.Ledbetter; &Brian.C.Ledbetter.mail;</para>
</listitem>
</itemizedlist>

<para
>Документация &copy; 2003 &Teemu.Rytilahti; &Teemu.Rytilahti.mail;</para>
&underFDL; &underGPL; </chapter>

<appendix id="installation">
<title
>Установка</title>

<sect1 id="requirements">
<title
>Системные требования</title>

<para
>Чтобы иметь возможность использовать возможности &ksplash; вам необходим оконный менеджер &kde; версии 3.2 или выше. Если тема не работает, свяжитесь с её автором, чтобы выяснить, где можно взять подходящий подключаемый модуль.</para>

</sect1>

<sect1 id="compilation">
<title
>Сборка и установка</title>
&install.compile.documentation; </sect1>
</appendix>
<appendix id="srccode">
<title
>Исходные коды</title>
<sect1 id="theme2kcpp">
<title
>Файл <filename
>theme2k.cpp</filename
></title>
<programlisting
>#include &lt;qlabel.h&gt;
#include &lt;qwidget.h&gt;

#include &lt;kapplication.h&gt;
#include &lt;kconfig.h&gt;
#include &lt;kdebug.h&gt;
#include &lt;kdialogbase.h&gt;
#include &lt;kgenericfactory.h&gt;
#include &lt;kglobalsettings.h&gt;
#include &lt;klocale.h&gt;
#include &lt;ksplash/objkstheme.h&gt;
#include &lt;kstandarddirs.h&gt;

#include "rotwidget.h"
#include "theme2k.h"
#include "theme2k.moc"

K_EXPORT_COMPONENT_FACTORY( ksplash2k, KGenericFactory&lt;Theme2k&gt; );

Cfg2k::Cfg2k( KConfig * )
{}

Theme2k::Theme2k( QWidget *parent, const char *name, const QStringList &amp;args  )
    :ThemeEngine( parent, name, args )
{
  readSettings();
  initUi();
}

void Theme2k::initUi()
{
  QVBox *vbox = new QVBox( this );
  vbox-&gt;setFrameShape( QFrame::WinPanel );
  vbox-&gt;setFrameShadow( QFrame::Raised );

  QHBox *labelBox = new QHBox( vbox );
  labelBox-&gt;setPalette( mTBgColor );
  labelBox-&gt;setMargin( 1 );
  QLabel *lbl = new QLabel( mWndTitle, labelBox );
  lbl-&gt;setFont( QFont( "Arial", 12, QFont::Bold ) );
  lbl-&gt;setPaletteForegroundColor( mTFgColor );

  QLabel *logo = new QLabel( vbox );
  logo-&gt;setPalette( Qt::white );

  QString px( locate( "appdata", mTheme-&gt;themeDir() + (mLogoFile.isNull()?QString("/Logo.png"):mLogoFile) ) );
  if (px.isNull())
    px = locate("appdata","Themes/Default/splash_top.png");
  if( !px.isNull() )
  {
    QPixmap pix( px );
    logo-&gt;setPixmap( pix );
  }
  else
  {
    logo-&gt;setText( "&lt;B&gt;KDE&lt;/B&gt;2000" );
    logo-&gt;setAlignment( AlignCenter|AlignVCenter );
  }

  mRotator = new RotWidget( vbox, mRotColor1, mRotColor2, mRotSpeed );

  QHBox *hbox = new QHBox( vbox );
  labelBox-&gt;setSpacing( 4 );
  labelBox-&gt;setMargin( 4 );

  mText = new QLabel( hbox );
  mText-&gt;setPaletteForegroundColor( mStatusColor );
  mText-&gt;setPaletteBackgroundColor( mTFgColor );
  mText-&gt;setText( mWndTitle );
  mText-&gt;setFixedHeight( 48 );

  setFixedSize( vbox-&gt;sizeHint() );
  QRect rect(KGlobalSettings::splashScreenDesktopGeometry());
  move( rect.x() + (rect.width() - size().width())/2,
        rect.y() + (rect.height() - size().height())/2 );
}

void Theme2k::readSettings()
{
  if( !mTheme )
    return;

  KConfig *cfg = mTheme-&gt;themeConfig();
  if( !cfg )
    return;

  cfg-&gt;setGroup( QString("KSplash Theme: %1").arg(mTheme-&gt;theme()) );

  QColor DefaultTBgColor( Qt::darkBlue );
  QColor DefaultTFgColor( Qt::white );

  mTBgColor = cfg-&gt;readColorEntry( "Title Background Color", &amp;DefaultTBgColor );
  mTFgColor = cfg-&gt;readColorEntry( "Title Foreground Color", &amp;DefaultTFgColor );
  mStatusColor = cfg-&gt;readColorEntry("Status Text Color", &amp;mTBgColor );

  QColor DefaultRot1( Qt::darkBlue );
  QColor DefaultRot2( Qt::cyan );
  mRotColor1 = cfg-&gt;readColorEntry( "Rotator Color 1", &amp;DefaultRot1 );
  mRotColor2 = cfg-&gt;readColorEntry( "Rotator Color 2", &amp;DefaultRot2 );

  mRotSpeed = cfg-&gt;readNumEntry( "Rotator Speed", 30 );
  mWndTitle = cfg-&gt;readEntry( "Window Title", i18n("Please wait...") );
  mLogoFile = cfg-&gt;readEntry( "Logo File", QString::null );
}
</programlisting>
</sect1>
<sect1 id="rotwidgeth">
<title
>Файл <filename
>rotwidget.h</filename
></title>
<programlisting
>#ifndef         __ROTWIDGET_H__
#define         __ROTWIDGET_H__

#include &lt;qlabel.h&gt;
#include &lt;qtimer.h&gt;
#include &lt;qwidget.h&gt;

#include &lt;kdialogbase.h&gt;
#include &lt;kpixmap.h&gt;

/**
 * @short Display a rotating-gradient widget.
 */
class         RotWidget: public QWidget
{
  Q_OBJECT
public:
  RotWidget( QWidget *, const QColor&amp;, const QColor&amp;, int );
  ~RotWidget();

private slots:
  void stepEvent();

protected:
  void        preparePixmap( int );
  void        paintEvent( QPaintEvent * );
  void        resizeEvent( QResizeEvent * );

  QColor m_color1, m_color2;
  int m_step, m_speed;
  QTimer *m_stepTimer;

  QList&lt;KPixmap&gt; m_stepPixmap;
};

#endif
</programlisting>
</sect1>
<sect1 id="rotwidgetcpp">
<title
>Файл <filename
>rotwidget.cpp</filename
></title>
<programlisting
>#include &lt;kdebug.h&gt;
#include &lt;kdialogbase.h&gt;
#include &lt;kpixmapeffect.h&gt;

#include &lt;qlabel.h&gt;
#include &lt;qpainter.h&gt;
#include &lt;qwidget.h&gt;

#include "rotwidget.h"
#include "rotwidget.moc"

RotWidget::RotWidget( QWidget *parent, const QColor&amp; c1, const QColor&amp; c2, int sp )
    :QWidget(parent), m_color1(c1), m_color2(c2), m_step(0), m_speed(sp)
{
  if( (m_speed &lt;= 0) || (m_speed &gt; 20) )
    m_speed = 1;
  setFixedHeight( 6 );

  for( int i = 0; i &lt;= width(); i++ )
    preparePixmap( i );

  m_stepTimer = new QTimer( this );
  connect(m_stepTimer, SIGNAL(timeout()), this, SLOT(stepEvent()));
  m_stepTimer-&gt;start( 50 );
}

RotWidget::~RotWidget()
{
}

void RotWidget::stepEvent()
{
  // This is inefficient as we create too many pixmaps, optimize later.
  m_step += m_speed;
  if( m_step &gt; width() )
    m_step = 0;
  repaint( true );
}

// Todo: Optimize drawing.
void RotWidget::paintEvent( QPaintEvent *pe )
{
  QPainter p;
  p.begin( this );

  QRect r = pe-&gt;rect();

  if( m_stepPixmap.at( m_step ) )
    bitBlt( this, r.x(), r.y(), m_stepPixmap.at( m_step ), r.x(), r.y(), r.width(), r.height() );
  else
    p.fillRect( rect(), Qt::black );
  p.end();
}

void RotWidget::resizeEvent( QResizeEvent *re )
{
  m_stepPixmap.clear();
  for( int i = 0; i &lt;= re-&gt;size().width(); i++ )
    preparePixmap( i );
}

void RotWidget::preparePixmap( int step )
{
  if( step &lt; 0 )
    return;

  // Explicitly draw our first pixmap. The rest we will bitBlt() from here.
  if( step == 0 )
  {
    KPixmap tmp; tmp.resize( size().width() / 2, size().height() );
    KPixmap tmp2(tmp);
    KPixmapEffect::gradient( tmp, m_color1, m_color2, KPixmapEffect::HorizontalGradient );
    KPixmapEffect::gradient( tmp2, m_color2, m_color1, KPixmapEffect::HorizontalGradient );
    KPixmap *px = new KPixmap( size() );
    QPainter p;
    p.begin( px );
    p.drawPixmap( 0, 0, tmp );
    p.drawPixmap( size().width()/2, 0, tmp2 );
    p.end();
    m_stepPixmap.append( px );
  }
  else if( m_stepPixmap.at( step-1 ) )
  {
    QPixmap *prev = m_stepPixmap.at( step-1 );
    QPixmap next; next.resize( size() );
    // convert
    // prev = "[------------]"
    // to
    // next = "------------]["
    bitBlt( &amp;next, 0, 0, prev, 1, 0, prev-&gt;width()-1, prev-&gt;height() );
    bitBlt( &amp;next, width()-1, 0, prev, 0, 0, 1, prev-&gt;height() );
    KPixmap *n = new KPixmap( next );
    m_stepPixmap.append( n );
  }
}
</programlisting>
</sect1>
</appendix>

&documentation.index;
</book>

<!--
Local Variables:
mode: xml
sgml-minimize-attributes:nil
sgml-general-insert-case:lower
sgml-indent-step:0
sgml-indent-data:nil
End:

vim:tabstop=2:shiftwidth=2:expandtab
-->
