# El manual de &ksplash;

&Teemu.Rytilahti; &Teemu.Rytilahti.mail;
&Brian.C.Ledbetter; &Brian.C.Ledbetter.mail;
&Ravikiran.Rajagopal; &Ravikiran.Rajagopal.mail;
Antoni
Bella

    bella5@teleline.es

Traductor
2003
Teemu Rytilahti
2003-04
Ravikiran Rajagopal
&FDLNotice;
2003-01-10
1.01.00

&ksplash; és una bella pantalla d'inici que mostra el progrés d'una aplicació mentre aquesta s'està carregant.

KDE
kdebase
ksplash
ksplashml
pantalla d'inici
afegit visual

## Introducció

&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;:

- Amb temes
- Empra connectors per a completar la capacitat de personalització
- Pot ser usat per qualsevol aplicació que empri DCOP

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++.

## Ús de temes

Per emprar temes de KDE-Look, feu-ne la extracció a `~/.kde/share/apps/ksplash/Themes/` per a l'ús d'un únic usuari, o a `$`KDEDIR`/share/apps/ksplash/Themes/` per a que resti a l'abast de tots els usuaris del vostre sistema.

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

### Usar el mòdul de &kcontrol;

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

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 Bé o Aplica. Premeu Cancel·la per sortir del mòdul sense aplicar cap canvi, i Omissió per a restaurar la pantalla d'inici per omissió del sistema.

Per instal·lar nous mòduls, premeu Afegeix... 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 Bé o Aplica.

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ó Prova.

Podeu eliminar els temes que ja no us calguin seleccionant-los i prement el botó Elimina. 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 Omissió.

## Com crear temes per a &ksplash;

### General

Crear els vostres propis temes per a &ksplash; és fàcil. Una vegada els hageu finalitzat envieu-los a KDE-Look a on en trobareu d'altres de disponibles.

#### Identificar el vostre tema

Us permet crear un tema anomenat `MyCoolTheme`. Per a que el tema sigui reconegut per &ksplash;, aquest haurà de ser desat en una carpeta anomenada `MyCoolTheme` sota `~/.kde/apps/ksplash/Themes/`. Aquesta haurà de contenir un fitxer anomenat `Theme.rc`, 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 `Theme.rc` és `[opció] = [valor]`. Podeu trobar les definicions de les diverses opcions en les següents seccions.

##### Fitxer `Theme.rc` simple

    [KSplash Theme: MyCoolTheme]
    Name = MyCoolTheme
    Description = Un bonic tema que empra l'enginy XpLike
    Version = 1.0
    Author = Nom real <correu_real@mail.com>
    ## Empra l'enginy XpLike per aquest tema.
    Engine = XpLike
    Show Icon = false
    Welcome Text = S'està carregant el KDE

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.

És important que el noms siguin idèntics: el directori sota el que deixeu els fitxers del tema (en el nostre cas seria `~/.kde/apps/ksplash/Themes/MyCoolTheme`) i l'identificador (en el nostre cas seria `[KSplash Theme: MyCoolTheme]` ), tot amb el fitxer `Theme.rc`. D'altra manera &ksplash; no el reconeixerà.

#### Fitxers de fons

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: `Background-AAAxaaa.png`.

Per exemple, hauríeu d'emprar un fitxer anomenat `Background-1024x768`. Si no es troba la imatge de fons per a la vostra resolució de pantalla, aquest intentarà redimensionar el `Background.png` original o el fitxer especificat a `Theme.rc` 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.

### Opcions per als enginys de tema

#### El tema estàndard

##### Opcions per al tema estàndard

Nom | Argument | Explicació
Statusbar Position | [top/bottom] | Alterna la posició de la barra d'estat sobre la pantalla. Per omissió és bottom (a la part inferior).
Statusbar Visible | [true/false] | Indica quan s'haurà de mostrar la barra d'estat. Per omissió és true (verdader).
Progress Visible | [true/false] | Indica quan s'haurà de mostrar el progrés de càrrega. Per omissió és true (verdader).
Statusbar Font | [nom_de_font] | La font emprada a la barra d'estat. Per omissió és Helvetica.
Statusbar Font Size | [mida] | La mida de font emprada per la barra d'estat. Per omissió és 16.
Statusbar Font Bold | [true/false] | Indica quan la barra d'estat haurà d'estar en negreta. Per omissió és true (verdader).
Statusbar Font Italic | [true/false] | Indica quan la barra d'estat haurà d'estar en cursiva. Per omissió és false (fals).
Statusbar Foreground | [color] | El color de primer pla de la barra d'estat. Per omissió és white (blanc).
Statusbar Background | [color] | El color de fons de la barra d'estat. Per omissió és black (negre).
Statusbar Icon | [true/false] | Indica quan la barra d'estat haurà de contenir una icona.
Icons Visible | [true/false] | Indica quan hauran de ser visibles les icones. Per omissió és true (verdader).
Icons Jumping | [true/false] | Indica quan hauran de saltar les icones. Per omissió és true (verdader).
Icon Position | [0-3,10-13] | La posició a on s'hauran de mostrar les les icones. Per omissió és bottom-left (a la part inferior esquerra).
Splash Screen | [nom] | Canvia la imatge de la pantalla d'inici que es mostrarà.

#### El tema Redmond

##### Opcions per al tema Redmond

Nom | Argument | Explicació
Background Image | [nom_de_fitxer] | Usa la imatge de fons definida.
User Icon | [nom_icona] | El nom de la icona estàndard a mostrar. Per omissió és `go`.
Welcome Text | [text] | El text a mostrar a la pantalla d'inici. Per omissió és Welcome (Benvingut).
Username Text | [text] | El text a mostrar en comptes del nom real de l'usuari.
Welcome Text Position | [x,y] | Posició sobre la pantalla a on es mostrarà el Welcome Text.
Username Text Position | [x,y] | La posició a la pantalla a on es mostrarà el nom d'usuari.
Action Text Position | [x,y] | La posició a la pantalla a on es mostrarà el text de l'acció actual.
Icon Position | [x,y] | La posició a la pantalla a on es mostrarà la icona d'usuari.
Show Welcome Text | [true/false] | Alterna el mostrar el text de benvinguda. Per omissió és true (verdader).
Show Welcome Shadow | [true/false] | Alterna el mostrar l'ombra del text de benvinguda. Per omissió és true (verdader).
Show Username | [true/false] | Alterna el mostrar el nom d'usuari. Per omissió és true (verdader).
Show Action | [true/false] | Alterna el mostrar de l'acció actualment en curs. El valor per omissió és true (verdader).
Show Icon | [true/false] | Alterna quan s'haurà de mostrar la icona. Per omissió és true (verdader).
Use KDM User Icon | [true/false] | Mostra la icona d'accés de l'usuari. Per omissió és true (verdader).

#### El tema MacX

##### Opcions per al tema MacX

Nom | Argument | Explicació
Icon Size Minimum | [mida] | Assigna la mida mínima per a les icones. Per omissió és 16.
Icon Size Maximum | [mida] | Assigna la mida màxima per a les icones. Per omissió és 64.
Optimized Icon Rendering | [true/false] | Optimitza el renderitzat de la icona. Per omissió és true (verdader).
Progress Bar Visible | [true/false] | Per omissió és true (verdader).
Progress Bar Position | [top/bottom] | Alterna quan la barra d'estat haurà d'estar a baix o dalt. Per omissió és bottom (a la part inferior).
Icons Jumping | [true/false] | Indica quan hauran de saltar les icones. Per omissió és false (fals).

#### El tema MacClassic

##### Opcions per al tema MacClassic

Nom | Argument | Explicació
Icon Position | [0-3,10-13] | La posició de les icones sobre la pantalla. Per omissió és bottom left (a la part inferior esquerra).
Icons Jumping | [true/false] | Indica quan hauran de saltar les icones. Per omissió és false (fals).
Icons Visible | [true/false] | Indica quan hauran de ser visibles les icones. Per omissió és true (verdader).
Splash Screen | [nom] | Canvia la imatge de la pantalla d'inici que es mostrarà.

#### El tema 2k

##### Opcions per al tema 2k

Nom | Argument | Explicació
Title Background Color | [color] | El color de fons del títol. Per omissió és dark blue (blau fosc).
Title Foreground Color | [color] | El color de primer pla del títol. Per omissió és white (blanc).
Status Text Color | [color] | El color dels texts d'estatus. Per omissió és el mateix que a Title Background Color.
Rotator Color 1 | [color] | Defineix el primer color de rotació. El valor per omissió és dark blue (blau fosc).
Rotator Color 2 | [color] | Defineix el segon color de rotació. El valor per omissió és cyan (cian).
Rotator Speed | [valor] | Defineix la velocitat de rotació. El valor per omissió és 30.
Window Title | [text] | Especifica el text del títol de la finestra.
Logo File | [nom_de_fitxer] | Defineix el logo emprat.

## L'ús de &ksplash; des de la vostra pròpia aplicació

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

### Requeriments bàsics

La vostra aplicació &kde; haurà d'entendre &DCOP;. &DCOP; és la tecnologia emprada pel &kde; per a la comunicació entre aplicacions. Si empreu l'entorn de treball estàndard per aplicacions &kde;, 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 Racó dels desenvolupadors de &kde;.

### Iniciar &ksplash;

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:

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

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;.

### Mostrar els missatges

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

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

Si voleu afegir un missatge a mostrar amb una icona, useu

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

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

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

Això és tot! No us caldrà res més per a prendre l'avantatge de tot el que &ksplash; us ofereix.

## Escriure nous connectors per a &ksplash;

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.

### Requeriments bàsics

Crearem un connector anomenat `2k`. 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:

- La biblioteca s'haurà d'anomenar com `ksplash+nom_del_tema_en_minúscules`. Per al nostre tema, aquest serà `ksplash2k`.
- Aquesta haurà de tenir un fitxer desktop corresponent anomenat `ksplash+nom_del_tema_en_minúscules.desktop`. Per al nostre tema, aquest serà `ksplash2k.desktop`.
- Finalment, l'objecte que serà retornat per la biblioteca haurà de ser una classe anomenada `Theme+nom_del_tema`. Per al nostre exemple, aquesta serà `Theme2k`.

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 `ThemeEngine`.

### Construir l'esquelet de l'entorn de treball

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 `kdesdk`. Executeu el comandament `kapptemplate` 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 `2k`. Aneu-hi i esborreu tots els fitxers que hi hagi. Ara disposarem de l'esquelet requerit.

La següent passa serà crear un fitxer `.desktop`, una vegada instal·lat, li indicarà a &ksplash; que el nostre connector està disponible. Consistent en les convencions anomenades en la secció precedent, creeu un fitxer anomenat `ksplash2k.desktop` en aquesta carpeta. Aquest haurà de contenir les següents línies:

    [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

Les línies `Encoding`, `Type`, `Comment` i `ServiceTypes` 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 `X-KSplash-Default` 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 `true`.

### Declaració de la classe del connector

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.

1. Les classes del connector hereta la classe `ThemeEngine`.

2. Les classes del connector s'hauran d'anomenar d'acord a la regla: `Theme+NomConnector`.

3. Les classes del connector hauran de proveir una funció `static` anomenada `names` que retorni una llista de noms per als quals ha estat invocada.

4. Si el connector es pot configurar en el mòdul del centre de control, aquest haurà de proveir una classe `ThemeEngineConfig` per a la configuració.

5. La classe del connector haurà de solapar a almenys una de les funcions virtuals `slotSetText`, `slotSetPixmap`, `slotUpdateProgress` i `slotUpdateSteps` per a fer-se usable.

6. El constructor ha de prendre la forma `ThemeEngine( QWidget *parent, const char *name, const QStringList &args )` de manera que sigui emprat amb `KGenericFactory`.

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.

### Codi per al fitxer de capçalera

Tinguen en compte les constants, ara veurem que el fitxer de capçalera `theme2k.h` s'assembla a això:

#### Llistat de `theme2k.h`

    #ifndef __THEME2K_H__
    #define __THEME2K_H__

    #include <qlabel.h>
    #include <qwidget.h>

    #include <kdialogbase.h>
    #include <kpixmap.h>
    #include <ksplash/themeengine.h>

    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& );

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

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

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

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

    #endif

Analitzem l'anterior llistat. La classe `Theme2k` satisfà les convencions de nom, i és inherent de `ThemeEngine`. Aquesta proveeix un `Theme2k::names()`, i disposa d'un constructor que pren els paràmetres requerits: `Theme2k( QWidget *, const char *, const QStringList& );` i també proveeix d'un mètode `Theme2k::slotSetText()` simple. De moment, no us preocupeu per la classe `RotWidget`. 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ó `slotSetPixmap`. Existeixen funcions similars per establir el rang de la barra de progrés (`slotUpdateSteps`) i l'increment de la passa actual (`slotUpdateProgress`).

### Implementació del connector

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:

#### Requeriment de la biblioteca

    K_EXPORT_COMPONENT_FACTORY( ksplash2k, KGenericFactory<Theme2k> );

La macro `K_EXPORT_COMPONENT_FACTORY` està declarada dintre de `kgenericfactory.h`. D'ara en endavant el constructor! Atès que aquest és un connector molt simple, el constructor serà molt minimalista.

#### Constructor del connector

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

El mètode `readSettings()` 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?)

#### Obtenir les opcions del tema

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

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

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

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

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

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

      mRotSpeed = cfg->readNumEntry( "Rotator Speed", 30 );
      mWndTitle = cfg->readEntry( "Window Title", i18n("Please wait...") );
      mLogoFile = cfg->readEntry( "Logo File", QString::null );
    }

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 `initUI()` no és gaire interessant, ja que ell essencialment construeix els estris. Si us plau, per a detalls consulteu l'apèndix.

### Compilar el connector

Ja que hem optat per emprar l'entorn de treball &kde; per a compilar el connector, necessitarem crear un `Makefile.am`. Aquest s'haurà d'assemblar a això:

#### Llistat del `Makefile.am`

    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

Per a més informació a sobre de l'escriptura de fitxers `Makefile.am` per al &kde;, si us plau, consulteu el lloc web 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 `Theme.rc`, il·lustrant l'ús de les diverses opcions.

## Preguntes i respostes

&reporting.bugs; &updating.documentation;

No poc trobar cap tema que funcioni en &ksplash;. Què està passant?

Probablement no disposeu dels connectors correctes per al tema. Els connectors estan en el paquet `kde-artwork`. Feu-ne la descàrrega, instal·leu-lo i torneu-ho a provar.

Quin és el fitxer `Theme.rc` i com puc crear-ne un?

`Theme.rc` és el fitxer a on especifiqueu les opcions d'un tema. Per a més informació, feu un cop d'ull a Com crear temes per a &ksplash;.

## Crèdits i llicència

&ksplash;

Copyright del programa © 2003 &Ravikiran.Rajagopal; &Ravikiran.Rajagopal.mail;

### Col·laboradors

- &Brian.C.Ledbetter; &Brian.C.Ledbetter.mail;

Copyright de la documentació © 2003 &Teemu.Rytilahti; &Teemu.Rytilahti.mail;

&underFDL; &underGPL;

## Instal·lació

### Requeriments

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.

### Compilació i instal·lació

&install.compile.documentation;

## Codi font

### Llistat de `theme2k.cpp`

    #include <qlabel.h>
    #include <qwidget.h>

    #include <kapplication.h>
    #include <kconfig.h>
    #include <kdebug.h>
    #include <kdialogbase.h>
    #include <kgenericfactory.h>
    #include <kglobalsettings.h>
    #include <klocale.h>
    #include <ksplash/objkstheme.h>
    #include <kstandarddirs.h>

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

    K_EXPORT_COMPONENT_FACTORY( ksplash2k, KGenericFactory<Theme2k> );

    Cfg2k::Cfg2k( KConfig * )
    {}

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

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

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

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

      QString px( locate( "appdata", mTheme->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->setPixmap( pix );
      }
      else
      {
        logo->setText( "<B>KDE</B>2000" );
        logo->setAlignment( AlignCenter|AlignVCenter );
      }

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

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

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

      setFixedSize( vbox->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->themeConfig();
      if( !cfg )
        return;

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

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

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

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

      mRotSpeed = cfg->readNumEntry( "Rotator Speed", 30 );
      mWndTitle = cfg->readEntry( "Window Title", i18n("Please wait...") );
      mLogoFile = cfg->readEntry( "Logo File", QString::null );
    }

### Llistat de `rotwidget.h`

    #ifndef         __ROTWIDGET_H__
    #define         __ROTWIDGET_H__

    #include <qlabel.h>
    #include <qtimer.h>
    #include <qwidget.h>

    #include <kdialogbase.h>
    #include <kpixmap.h>

    /**
     * @short Display a rotating-gradient widget.
     */
    class         RotWidget: public QWidget
    {
      Q_OBJECT
    public:
      RotWidget( QWidget *, const QColor&, const QColor&, 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<KPixmap> m_stepPixmap;
    };

    #endif

### Llistat de `rotwidget.cpp`

    #include <kdebug.h>
    #include <kdialogbase.h>
    #include <kpixmapeffect.h>

    #include <qlabel.h>
    #include <qpainter.h>
    #include <qwidget.h>

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

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

      for( int i = 0; i <= width(); i++ )
        preparePixmap( i );

      m_stepTimer = new QTimer( this );
      connect(m_stepTimer, SIGNAL(timeout()), this, SLOT(stepEvent()));
      m_stepTimer->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 > width() )
        m_step = 0;
      repaint( true );
    }

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

      QRect r = pe->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 <= re->size().width(); i++ )
        preparePixmap( i );
    }

    void RotWidget::preparePixmap( int step )
    {
      if( step < 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( &next, 0, 0, prev, 1, 0, prev->width()-1, prev->height() );
        bitBlt( &next, width()-1, 0, prev, 0, 0, 1, prev->height() );
        KPixmap *n = new KPixmap( next );
        m_stepPixmap.append( n );
      }
    }

&documentation.index;