<?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 % Catalan  "INCLUDE">
]>

<book lang="&language;">

<bookinfo>
<title
>El manual de &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
>Antoni</firstname
><surname
>Bella</surname
><affiliation
><address
><email
>bella5@teleline.es</email
></address
></affiliation
><contrib
>Traductor</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; és una bella pantalla d'inici que mostra el progrés d'una aplicació mentre aquesta s'està carregant.</para>
</abstract>

<keywordset>
<keyword
>KDE</keyword>
<keyword
>kdebase</keyword>
<keyword
>ksplash</keyword>
<keyword
>ksplashml</keyword>
<keyword
>pantalla d'inici</keyword>
<keyword
>afegit visual</keyword>
</keywordset>

</bookinfo>

<chapter id="introduction">
<title
>Introducció</title>

<para
>&ksplash; és una bella pantalla d'inici que mostra el progrés d'una aplicació mentre aquesta s'està carregant. Si us plau, informeu de qualsevol problema o requeriment de característica a les llistes de correu del &kde;. Les principals característiques de &ksplash;: </para>
<simplelist>
<member
>Amb temes</member>
<member
>Empra connectors per a completar la capacitat de personalització</member>
<member
>Pot ser usat per qualsevol aplicació que empri DCOP</member>
</simplelist>

<para
>Aquest manual us ensenyarà com crear temes per usar-los amb connectors que ja estan disponibles. Si cap dels connectors disponibles us satisfà, podeu aprendre a personalitzar l'aparença de &ksplash; escrivint completament un connector en C++. </para>
</chapter>

<chapter id="using-themes">
<title
>Ús de temes</title>

<para
>Per emprar temes de <ulink url="http://www.kde-look.org"
>KDE-Look</ulink
>, feu-ne la extracció a <filename
>~/.kde/share/apps/ksplash/Themes/</filename
> per a l'ús d'un únic usuari, o a <filename
>$<envar
>KDEDIR</envar
>/share/apps/ksplash/Themes/</filename
> per a que resti a l'abast de tots els usuaris del vostre sistema.</para>

<para
>També podeu emprar el mòdul <guilabel
>Pantalla d'inici</guilabel
> que es troba sota la pestanya <guilabel
>Aparença</guilabel
> en el centre de control de &kde; per a fer-ho automàticament.</para>

<sect1 id="using-kcontrol-module">
<title
>Usar el mòdul de &kcontrol;</title>

<para
>Aquest mòdul us permet instal·lar, provar i eliminar temes de &ksplash;.</para>

<para
>A l'esquerra del mòdul hi ha un llistat dels temes disponibles per a &ksplash;. Tan aviat com en seleccioneu un, es mostrarà una vista prèvia a la part principal de la finestra. Quan hageu fet la tria premeu <guibutton
>Bé</guibutton
> o <guibutton
>Aplica</guibutton
>. Premeu <guibutton
>Cancel·la</guibutton
> per sortir del mòdul sense aplicar cap canvi, i <guibutton
>Omissió</guibutton
> per a restaurar la pantalla d'inici per omissió del sistema.</para>

<para
>Per instal·lar nous mòduls, premeu <guibutton
>Afegeix...</guibutton
> i cerqueu el tema al vostre ordinador. No cal que descomprimiu els fitxers del tema, seleccioneu el fitxer comprimit. Tingueu present que no n'hi ha prou amb instal·lar el tema doncs l'haureu de seleccionar i prémer un dels botons <guibutton
>Bé</guibutton
> o <guibutton
>Aplica</guibutton
>.</para>

<para
>Podeu veure la vista prèvia de la pantalla d'inici per tal de decidir si us agrada l'aparença de la mateixa. Podeu provar els temes seleccionant-los en la llista i després fent clic en el botó <guibutton
>Prova</guibutton
>.</para>

<para
>Podeu eliminar els temes que ja no us calguin seleccionant-los i prement el botó <guibutton
>Elimina</guibutton
>. Tingueu present que des del vostre compte d'usuari no teniu prou permisos per eliminar els temes que estiguin instal·lats a tot el sistema. També és molt recomanable que no desinstal·leu la pantalla d'inici <guilabel
>Omissió</guilabel
>.</para>

</sect1>

</chapter>

<chapter id="themes">
<title
>Com crear temes per a &ksplash;</title>
<sect1 id="themes-general">
<title
>General</title>
<para
>Crear els vostres propis temes per a &ksplash; és fàcil. Una vegada els hageu finalitzat envieu-los a <ulink url="http://www.kde-look.org"
>KDE-Look</ulink
> a on en trobareu d'altres de disponibles.</para>

<sect2 id="theme-syntax">
<title
>Identificar el vostre tema</title>

<para
>Us permet crear un tema anomenat <literal
>MyCoolTheme</literal
>. Per a que el tema sigui reconegut per &ksplash;, aquest haurà de ser desat en una carpeta anomenada <filename class="directory"
>MyCoolTheme</filename
> sota <filename class="directory"
>~/.kde/apps/ksplash/Themes/</filename
>. Aquesta haurà de contenir un fitxer anomenat <filename
>Theme.rc</filename
>, que contingui les opcions del tema. Podeu especificar un llarg nombre de coses especials per al tema, canviar l'enginy de connectors a usar, i molt més. No haureu pas d'emprar totes les opcions disponibles, usualment, les opcions tenen un valor per omissió força acceptable. La sintaxi de base per a les entrades en el fitxer <filename
>Theme.rc</filename
> és <literal
>[opció] = [valor]</literal
>. Podeu trobar les definicions de les diverses opcions en les següents seccions.</para>

<example>
<title
>Fitxer <filename
>Theme.rc</filename
> simple</title>
<programlisting
>[KSplash Theme: MyCoolTheme]
Name = MyCoolTheme
Description = Un bonic tema que empra l'enginy XpLike
Version = 1.0
Author = Nom real &lt;correu_real@mail.com&gt;
## Empra l'enginy XpLike per aquest tema.
Engine = XpLike
Show Icon = false
Welcome Text = S'està carregant el KDE
</programlisting>
</example>

<para
>Després d'especificar el nom, la descripció i l'autor del tema, primer haureu de triar un enginy de tema (també conegut com a connector). Llavores, podreu personalitzar diverses característiques de l'enginy del tema assignant valors clau semblants a l'anterior fitxer d'exemple.</para>

<important>
<para
>Assegureu-vos que el noms siguin idèntics: El directori sota el que deixeu els fitxers del tema (en el nostre cas seria <filename class="directory"
>~/.kde/apps/ksplash/Themes/MyCoolTheme</filename
>) i l'identificador (en el nostre cas seria <literal
>[KSplash Theme: MyCoolTheme] </literal
>), tot amb el fitxer <filename
>Theme.rc</filename
>. D'altra manera &ksplash; no el reconeixerà.</para>
</important>

</sect2>

<sect2 id="theme-files">
<title
>Fitxers de fons</title>

<para
>Quan s'inicia &ksplash;, aquest intenta trobar una imatge de fons adequada per a la vostra resolució de pantalla, sempre que l'enginy del tema n'empri una. El fitxer imatge de fons haurà d'estar anomenat en el següent format: <filename
>Background-<replaceable
>AAAxaaa</replaceable
>.png</filename
>.</para>

<para
>Per exemple, hauríeu d'emprar un fitxer anomenat <filename
>Background-1024x768</filename
>. Si no es troba la imatge de fons per a la vostra resolució de pantalla, aquest intentarà redimensionar el <filename
>Background.png</filename
> original o el fitxer especificat a <filename
>Theme.rc</filename
> per adaptar-lo a la resolució actual. El redimensionament al vol es prendrà un cert temps, de manera que hauríeu de proveir imatges de fons per almenys les següents mides: 1280x1024, 1024x768 i 800x600.</para>
</sect2>
</sect1>

<sect1 id="theme-engines">
<title
>Opcions per als enginys de tema</title>

<sect2 id="default-themes">
<title
>Tema per omissió</title>
<table>
<title
>Opcions per al tema per omissió</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Nom</entry>
<entry
>Argument</entry>
<entry
>Explicació</entry>
</row>
<!-- Statusbar -->
<row>
<entry
>Always Show Progress</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan s'haurà de mostrar el progrés de càrrega. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Label Foreground</entry>
<entry
>[color]</entry>
<entry
>Determina quin color usar per al text de la barra d'estat. Per omissió és #FFFFFF (blanc).</entry>
</row>
<!-- Misc. things -->
<row>
<entry
>Icons Flashing</entry>
<entry
>[true/false]</entry>
<entry
>Indica si s'hauran de mostrar el <quote
>parpelleig</quote
> de les icones. Per omissió és <quote
>true</quote
> (vertader).</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>

<sect2 id="standard-themes">
<title
>Standard Theme</title>
<table>
<title
>Opcions per al tema estàndard</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Nom</entry>
<entry
>Argument</entry>
<entry
>Explicació</entry>
</row>
<!-- Statusbar -->
<row>
<entry
>Statusbar Position</entry>
<entry
>[top/bottom]</entry>
<entry
>Alterna la posició de la barra d'estat sobre la pantalla. Per omissió és <quote
>bottom</quote
> (a la part inferior).</entry>
</row>
<row>
<entry
>Statusbar Visible</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan s'haurà de mostrar la barra d'estat. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Progress Visible</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan s'haurà de mostrar el progrés de càrrega. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<!-- Fonts -->
<row>
<entry
>Statusbar Font</entry>
<entry
>[nom_de_font]</entry>
<entry
>La font emprada a la barra d'estat. Per omissió és Helvetica.</entry>
</row>
<row>
<entry
>Statusbar Font Size</entry>
<entry
>[mida]</entry>
<entry
>La mida de font emprada per la barra d'estat. Per omissió és 16.</entry>
</row>
<row>
<entry
>Statusbar Font Bold</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan la barra d'estat haurà d'estar en negreta. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Statusbar Font Italic</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan la barra d'estat haurà d'estar en cursiva. Per omissió és <quote
>false</quote
> (fals).</entry>
</row>
<!-- Misc. things -->
<row>
<entry
>Statusbar Foreground</entry>
<entry
>[color]</entry>
<entry
>El color de primer pla de la barra d'estat. Per omissió és <quote
>white</quote
> (blanc).</entry>
</row>
<row>
<entry
>Statusbar Background</entry>
<entry
>[color]</entry>
<entry
>El color de fons de la barra d'estat. Per omissió és <quote
>black</quote
> (negre).</entry>
</row>
<row>
<entry
>Statusbar Icon</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan la barra d'estat haurà de contenir una icona.</entry>
</row>
<row>
<entry
>Icons Visible</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan hauran de ser visibles les icones. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Icons Jumping</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan hauran de saltar les icones. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Icon Position</entry>
<entry
>[0-3,10-13]</entry>
<entry
>La posició a on s'hauran de mostrar les les icones. Per omissió és <quote
>bottom-left</quote
> (a la part inferior esquerra).</entry>
</row>
<row>
<entry
>Splash Screen</entry>
<entry
>[nom]</entry>
<entry
>Canvia la imatge de la pantalla d'inici que es mostrarà.</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>

<sect2 id="redmond-themes">
<title
>El tema Redmond</title>
<table>
<title
>Opcions per al tema Redmond</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Nom</entry>
<entry
>Argument</entry>
<entry
>Explicació</entry>
</row>
<!-- Main elements -->
<row>
<entry
>Background Image</entry>
<entry
>[nom_de_fitxer]</entry>
<entry
>Usa la imatge de fons definida.</entry>
</row>
<row>
<entry
>User Icon</entry>
<entry
>[nom_icona]</entry>
<entry
>El nom de la icona estàndard a mostrar. Per omissió és <constant
>go</constant
>.</entry>
</row>
<row>
<entry
>Welcome Text</entry>
<entry
>[text]</entry>
<entry
>El text a mostrar a la pantalla d'inici. Per omissió és <quote
>Welcome</quote
> (Benvingut).</entry>
</row>
<row>
<entry
>Username Text</entry>
<entry
>[text]</entry>
<entry
>El text a mostrar en comptes del nom real de l'usuari.</entry>
</row>
<!-- Positioning elements -->
<row>
<entry
>Welcome Text Position</entry>
<entry
>[x,y]</entry>
<entry
>Posició sobre la pantalla a on es mostrarà el Welcome Text.</entry>
</row>
<row>
<entry
>Username Text Position</entry>
<entry
>[x,y]</entry>
<entry
>La posició a la pantalla a on es mostrarà el nom d'usuari.</entry>
</row>
<row>
<entry
>Action Text Position</entry>
<entry
>[x,y]</entry>
<entry
>La posició a la pantalla a on es mostrarà el text de l'acció actual.</entry>
</row>
<row>
<entry
>Icon Position</entry>
<entry
>[x,y]</entry>
<entry
>La posició a la pantalla a on es mostrarà la icona d'usuari.</entry>
</row>
<!-- Show to show.. -->
<row>
<entry
>Show Welcome Text</entry>
<entry
>[true/false]</entry>
<entry
>Alterna el mostrar el text de benvinguda. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Show Welcome Shadow</entry>
<entry
>[true/false]</entry>
<entry
>Alterna el mostrar l'ombra del text de benvinguda. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Show Username</entry>
<entry
>[true/false]</entry>
<entry
>Alterna el mostrar el nom d'usuari. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Show Action</entry>
<entry
>[true/false]</entry>
<entry
>Alterna el mostrar de l'acció actualment en curs. El valor per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Show Icon</entry>
<entry
>[true/false]</entry>
<entry
>Alterna quan s'haurà de mostrar la icona. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Use KDM User Icon</entry>
<entry
>[true/false]</entry>
<entry
>Mostra la icona d'accés de l'usuari. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>

<sect2 id="macx-themes">
<title
>El tema MacX</title>
<table>
<title
>Opcions per al tema MacX</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Nom</entry>
<entry
>Argument</entry>
<entry
>Explicació</entry>
</row>
<row>
<entry
>Icon Size Minimum</entry>
<entry
>[mida]</entry>
<entry
>Assigna la mida mínima per a les icones. Per omissió és 16.</entry>
</row>
<row>
<entry
>Icon Size Maximum</entry>
<entry
>[mida]</entry>
<entry
>Assigna la mida màxima per a les icones. Per omissió és 64.</entry>
</row>
<row>
<entry
>Optimized Icon Rendering</entry>
<entry
>[true/false]</entry>
<entry
>Optimitza el renderitzat de la icona. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Progress Bar Visible</entry>
<entry
>[true/false]</entry>
<entry
>Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Progress Bar Position</entry>
<entry
>[top/bottom]</entry>
<entry
>Alterna quan la barra d'estat haurà d'estar a baix o dalt. Per omissió és <quote
>bottom</quote
> (a la part inferior).</entry>
</row>
<row>
<entry
>Icons Jumping</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan hauran de saltar les icones. Per omissió és <quote
>false</quote
> (fals).</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>

<sect2 id="mac-classic-themes">
<title
>El tema MacClassic</title>
<table>
<title
>Opcions per al tema MacClassic</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Nom</entry>
<entry
>Argument</entry>
<entry
>Explicació</entry>
</row>
<row>
<entry
>Icon Position</entry>
<entry
>[0-3,10-13]</entry>
<entry
>La posició de les icones sobre la pantalla. Per omissió és <quote
>bottom left</quote
> (a la part inferior esquerra).</entry>
</row>
<row>
<entry
>Icons Jumping</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan hauran de saltar les icones. Per omissió és <quote
>false</quote
> (fals).</entry>
</row>
<row>
<entry
>Icons Visible</entry>
<entry
>[true/false]</entry>
<entry
>Indica quan hauran de ser visibles les icones. Per omissió és <quote
>true</quote
> (verdader).</entry>
</row>
<row>
<entry
>Splash Screen</entry>
<entry
>[nom]</entry>
<entry
>Canvia la imatge de la pantalla d'inici que es mostrarà.</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>

<sect2 id="themes-2k">
<title
>El tema 2k</title>
<table>
<title
>Opcions per al tema 2k</title>
<tgroup cols="3">
<tbody>
<row>
<entry
>Nom</entry>
<entry
>Argument</entry>
<entry
>Explicació</entry>
</row>
<row>
<entry
>Title Background Color</entry>
<entry
>[color]</entry>
<entry
>El color de fons del títol. Per omissió és <quote
>dark blue</quote
> (blau fosc).</entry>
</row>
<row>
<entry
>Title Foreground Color</entry>
<entry
>[color]</entry>
<entry
>El color de primer pla del títol. Per omissió és <quote
>white</quote
> (blanc).</entry>
</row>
<row>
<entry
>Status Text Color</entry>
<entry
>[color]</entry>
<entry
>El color dels texts d'estatus. Per omissió és el mateix que a Title Background Color.</entry>
</row>
<row>
<entry
>Rotator Color 1</entry>
<entry
>[color]</entry>
<entry
>Defineix el primer color de rotació. El valor per omissió és <quote
>dark blue</quote
> (blau fosc).</entry>
</row>
<row>
<entry
>Rotator Color 2</entry>
<entry
>[color]</entry>
<entry
>Defineix el segon color de rotació. El valor per omissió és <quote
>cyan</quote
> (cian).</entry>
</row>
<row>
<entry
>Rotator Speed</entry>
<entry
>[valor]</entry>
<entry
>Defineix la velocitat de rotació. El valor per omissió és 30.</entry>
</row>
<row>
<entry
>Window Title</entry>
<entry
>[text]</entry>
<entry
>Especifica el text del títol de la finestra.</entry>
</row>
<row>
<entry
>Logo File</entry>
<entry
>[nom_de_fitxer]</entry>
<entry
>Defineix el logo emprat.</entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
</sect1>
</chapter>

<chapter id="from-other-applications">
<title
>L'ús de &ksplash; des de la vostra pròpia aplicació</title>

<para
>En aquest capítol descriurem un mètode simple per usar &ksplash; com a pantalla d'inici per a la vostra aplicació &kde;. Si no desenvolupeu aplicacions per al &kde; podeu ometre aquest capítol.</para>

<sect1 id="basic-other-reqs">
<title
>Requeriments bàsics</title>

<para
>La vostra aplicació &kde; haurà d'entendre &DCOP;. &DCOP; és la tecnologia emprada pel &kde; per a la comunicació entre aplicacions. Si empreu l'<ulink url="http://developer.kde.org"
>entorn de treball estàndard per aplicacions &kde;</ulink
>, aquest se'n farà càrrec automàticament. Per a més informació quant a &DCOP; i les tecnologies &kde; relacionades, si us plau, visiteu el <ulink url="http://developer.kde.org"
>Racó dels desenvolupadors de &kde;</ulink
>.</para>
</sect1>

<sect1 id="other-using">
<title
>Iniciar &ksplash;</title>

<para
>Abans de que la vostra aplicació comenci un intensiu treball de càlcul, o abans de que comenci a carregar els connectors, &etc;, invoqueu a &ksplash; tal i com segueix:</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
>Assumirem que només hi ha en execució una sola instància de &ksplash;. En els altres casos és significativament més complex. Si us plau, per a més detalls consulteu la documentació de &DCOP;.</para>
</sect1>

<sect1 id="show-messages">
<title
>Mostrar els missatges</title>

<para
>Abans de mostrar cap missatge, necessitareu establir les passes que es mostraran. Per exemple, L'inici del &kde; procedeix emprant 7 passes.</para>

<programlisting
>QByteArray data;
    QDataStream arg(data,IO_WriteOnly);
    arg &lt;&lt; someNumber;
    if (!(c-&gt;send(KSplashName, "KSplashIface", "setStartupItemCount(int)",
data))
      // Some error processing here.
</programlisting>

<para
>Si voleu afegir un missatge a mostrar amb una icona, useu</para>

<programlisting
>arg &lt;&lt; QString("iconName") &lt;&lt; QString("programName") &lt;&lt;
QString("Some description");
    if (!(c-&gt;send(KSplashName, "KSplashIface",
"programStarted(QString,QString,QString)", data))
    {
      // Some error processing here.
    }
</programlisting>

<para
>Cada vegada que crideu <constant
>programStarted</constant
>, les passes completades s'incrementaran. Quan el vostre programa hagi finalitzat el seu inici, feu el següent per eliminar la pantalla d'inici:</para>

<programlisting
>if (!(c-&gt;send(KSplashName, "KSplashIface", "startupComplete()", data))
    {
      // Some error processing here.
    }
</programlisting>

<para
>Això és tot! No us caldrà res més per a prendre l'avantatge de tot el que &ksplash; us ofereix.</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
>Escriure nous connectors per a &ksplash;</title>

<para
>L'escriptura de nous connectors per a &ksplash; no és pas difícil. En aquest capítol, escriurem un simple connector que emularà la pantalla d'inici d'un conegut sistema operatiu. Aquest tutorial assumeix que coneixeu les bases de C++, i una mica de programació KDE/Qt.</para>

<sect1 id="basic-requirements">
<title
>Requeriments bàsics</title>
<para
>Crearem un connector anomenat <literal
>2k</literal
>. El nom del connector serà usat a diversos indrets, i és important que n'useu un de coherent de manera que sigui reconegut per &ksplash;. Els connectors de &ksplash; actualment són biblioteques carregables dinàmicament amb la següent convenció de noms: </para>
<simplelist>
<member
>La biblioteca s'haurà d'anomenar com <filename
>ksplash+nom_del_tema_en_minúscules</filename
>. Per al nostre tema, aquest serà <filename
>ksplash2k</filename
>.</member>
<member
>Aquesta haurà de tenir un fitxer desktop corresponent anomenat <filename
>ksplash+nom_del_tema_en_minúscules.desktop</filename
>. Per al nostre tema, aquest serà <filename
>ksplash2k.desktop</filename
>. </member>
<member
>Finalment, l'objecte que serà retornat per la biblioteca haurà de ser una classe anomenada <literal
>Theme+nom_del_tema</literal
>. Per al nostre exemple, aquesta serà <literal
>Theme2k</literal
>.</member>
</simplelist>
<para
>No us preocupeu per si no compreneu tot el que s'ha explicat. Considerarem cadascun d'aquests punts més endavant. L'altre detall molt important és que la classe del connector hauria d'estar derivada de <literal
>ThemeEngine</literal
>. </para>
</sect1>
<sect1 id="skeleton">
<title
>Construir l'esquelet de l'entorn de treball</title>
<para
>Nosaltres emprarem l'entorn de treball de les aplicacions &kde;, el qual té cura de construir el connector proveint-lo d'un ús independent de la plataforma sense cap treball per la nostra part. Per a fer això, primer assegureu-vos de tenir instal·lat el paquet <filename
>kdesdk</filename
>. Executeu el comandament <literal
>kapptemplate</literal
> per a produir una aplicació anomenada "2k". Aquest crearà una carpeta de primer nivell continguen fitxers genèrics com AUTHORS, &etc; Nosaltres estem més interessats en la subcarpeta anomenada <filename class="directory"
>2k</filename
>. Aneu-hi i esborreu tots els fitxers que hi hagi. Ara disposarem de l'esquelet requerit. </para>
<para
>La següent passa serà crear un fitxer <filename
>.desktop</filename
>, una vegada instal·lat, li indicarà a &ksplash; que el nostre connector està disponible. Consistent en les convencions anomenades en <link linkend="basic-requirements"
>la secció precedent</link
>, creeu un fitxer anomenat <filename
>ksplash2k.desktop</filename
> en aquesta carpeta. Aquest haurà de contenir les següents línies: </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
>Les línies <literal
>Encoding</literal
>, <literal
>Type</literal
>, <literal
>Comment</literal
> i <literal
>ServiceTypes</literal
> són les mateixes per a tots els connectors. El nom del connector i el de la biblioteca segueixen les convencions anotades anteriorment. L'entrada <literal
>X-KSplash-Default</literal
> pren un valor booleà que determinarà si aquest es mostrarà per omissió en el mòdul de configuració del plafó de control. Excepte per alguns casos rars, aquest valor hauria de ser <constant
>true</constant
>. </para>
</sect1>
<sect1 id="headerfile">
<title
>Declaració de la classe del connector</title>
<para
>Ara que ja tenim feta la feina preliminar, procedirem amb la part verdaderament divertida -crear una classe que proveeixi del comportament que desitgem-. Tot i que som ben lliures de crear aquesta classe per a que faci el que vulguem, hi ha algunes restriccions.</para>
<orderedlist>
<listitem
><para
>Les classes del connector hereta la classe <constant
>ThemeEngine</constant
>.</para
></listitem>
<listitem
><para
>Les classes del connector s'hauran d'anomenar d'acord a la regla: <classname
>Theme+NomConnector</classname
>.</para
></listitem>
<listitem
><para
>Les classes del connector hauran de proveir una funció <literal
>static</literal
> anomenada <function
>names</function
> que retorni una llista de noms per als quals ha estat invocada.</para
></listitem>
<listitem
><para
>Si el connector es pot configurar en el mòdul del centre de control, aquest haurà de proveir una classe <literal
>ThemeEngineConfig</literal
> per a la configuració.</para
></listitem>
<listitem
><para
>La classe del connector haurà de solapar a almenys una de les funcions virtuals <function
>slotSetText</function
>, <function
>slotSetPixmap</function
>, <function
>slotUpdateProgress</function
> i <function
>slotUpdateSteps</function
> per a fer-se usable.</para
></listitem>
<listitem
><para
>El constructor ha de prendre la forma <literal
>ThemeEngine( QWidget *parent, const char *name, const QStringList &amp;args )</literal
> de manera que sigui emprat amb <classname
>KGenericFactory</classname
>.</para
></listitem>
</orderedlist>
<para
>L'últim requeriment podria ser complicat, però, tal i com veurem més endavant, afegint una simple línia als vostres fitxers font, usualment podreu ignorar-lo.</para>
</sect1>
<sect1 id="headercode">
<title
>Codi per al fitxer de capçalera</title>
<para
>Tinguen en compte les constants, ara veurem que el fitxer de capçalera <filename
>theme2k.h</filename
> s'assembla a això:</para>
<example>
<title
>Llistat de <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
>Analitzem l'anterior llistat. La classe <classname
>Theme2k</classname
> satisfà les convencions de nom, i és inherent de <classname
>ThemeEngine</classname
>. Aquesta proveeix un <methodname
>Theme2k::names()</methodname
>, i disposa d'un constructor que pren els paràmetres requerits: <function
>Theme2k( QWidget *, const char *, const QStringList&amp; );</function
> i també proveeix d'un mètode <methodname
>Theme2k::slotSetText()</methodname
> simple. De moment, no us preocupeu per la classe <classname
>RotWidget</classname
>. Aquesta és un petit estri (en anglès "widjet") que proveeix d'alguns afegits visuals per l'usuari. El nostre connector és molt simple i no mostra cap icona o barra de progrés. Si us agradaria mostrar icones, solapeu la funció <function
>slotSetPixmap</function
>. Existeixen funcions similars per establir el rang de la barra de progrés (<function
>slotUpdateSteps</function
>) i l'increment de la passa actual (<function
>slotUpdateProgress</function
>). </para>
</sect1>
<sect1 id="Implementation">
<title
>Implementació del connector</title>
<para
>Nosaltres tan sols examinarem les parts significatives de la implementació. Per a un llistat complet, si us plau, consulteu l'apèndix. La primera cosa que farem serà treure el requeriment de la biblioteca de la manera:</para>
<example>
<title
>Requeriment de la biblioteca</title>
<programlisting
>K_EXPORT_COMPONENT_FACTORY( ksplash2k, KGenericFactory&lt;Theme2k&gt; );
</programlisting>
</example>
<para
>La macro <constant
>K_EXPORT_COMPONENT_FACTORY</constant
> està declarada dintre de <filename
>kgenericfactory.h</filename
>. D'ara en endavant el constructor! Atès que aquest és un connector molt simple, el constructor serà molt minimalista.</para>
<example>
<title
>Constructor del connector</title>
<programlisting
>Theme2k::Theme2k( QWidget *parent, const char *name, const QStringList &amp;args
 )
    :ThemeEngine( parent, name, args )
{
  readSettings();
  initUi();
}
</programlisting>
</example>
<para
>El mètode <function
>readSettings()</function
> il·lustra la manera adequada d'obtenir les opcions del vostre tema. (Voldreu que la gent usi els vostres connectors en els seus temes, voleu?)</para>
<example>
<title
>Obtenir les opcions del tema</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
>Ja que ens agraden els nostres usuaris, s'hom sensibles i proveïm de paràmetres per omissió que no són presents en el fitxer de tema. Tingueu en compte que també hauríeu d'establir el nostre grup a "KSplash Theme: nom_del_tema" per a romandre compatible amb les futures especificacions de tema. El mètode <function
>initUI()</function
> no és gaire interessant, ja que ell essencialment construeix els estris. Si us plau, per a detalls consulteu l'apèndix. </para>
</sect1>
<sect1 id="compilingfile">
<title
>Compilar el connector</title>
<para
>Ja que hem optat per emprar l'entorn de treball &kde; per a compilar el connector, necessitarem crear un <filename
>Makefile.am</filename
>. Aquest s'haurà d'assemblar a això:</para>
<example>
<title
>Llistat del <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
>Per a més informació a sobre de l'escriptura de fitxers <filename
>Makefile.am</filename
> per al &kde;, si us plau, consulteu el <ulink url="http://developer.kde.org/documentation/other/makefile_am_howto.html"
>lloc web</ulink
> per als desenvolupadors de &kde;. L'única cosa a fer notar és que proveïm d'un tema per omissió basat en aquest connector, així com d'una imatge per al mateix. Per cortesia cap als vostres usuaris, hauríeu de proveir d'un fitxer exemple <filename
>Theme.rc</filename
>, il·lustrant l'ús de les diverses opcions.</para>
</sect1>
</chapter>

<chapter id="faq">
<title
>Preguntes i respostes</title>
&reporting.bugs; &updating.documentation; <qandaset id="faqlist">
<qandaentry>
<question>
<para
>No poc trobar cap tema que funcioni en &ksplash;. Què està passant?</para>
</question>
<answer>
<para
>Probablement no disposeu dels connectors correctes per al tema. Els connectors estan en el paquet <literal
>kde-artwork</literal
>. Feu-ne la descàrrega, instal·leu-lo i torneu-ho a provar.</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para
>Quin és el fitxer <filename
>Theme.rc</filename
> i com puc crear-ne un?</para>
</question>
<answer>
<para
><filename
>Theme.rc</filename
> és el fitxer a on especifiqueu les opcions d'un tema. Per a més informació, feu un cop d'ull a <link linkend="themes"
>Com crear temes per a &ksplash;</link
>. </para>
</answer>
</qandaentry>
</qandaset>
</chapter>

<chapter id="credits">
<title
>Crèdits i llicència</title>

<para
>&ksplash;</para>

<para
>Copyright del programa &copy; 2003 &Ravikiran.Rajagopal; &Ravikiran.Rajagopal.mail;</para>

<itemizedlist>
<title
>Col·laboradors</title>
<listitem
><para
>&Brian.C.Ledbetter; &Brian.C.Ledbetter.mail;</para>
</listitem>
</itemizedlist>

<para
>Copyright de la documentació &copy; 2003 &Teemu.Rytilahti; &Teemu.Rytilahti.mail;</para>
&underFDL; &underGPL; </chapter>

<appendix id="installation">
<title
>Instal·lació</title>

<sect1 id="requirements">
<title
>Requeriments</title>

<para
>Per tal d'emprar &ksplash; amb èxit, necessitareu &kde; versió 3.2 o superior. Alguns temes poden requerir de connectors específics. Si un tema no funciona, si us plau, contacteu amb l'autor del tema per mirar d'obtenir el connector apropiat.</para>

</sect1>

<sect1 id="compilation">
<title
>Compilació i instal·lació</title>
&install.compile.documentation; </sect1>
</appendix>
<appendix id="srccode">
<title
>Codi font</title>
<sect1 id="theme2kcpp">
<title
>Llistat de <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
>Llistat de <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
>Llistat de <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
-->
