# O Manual do &ksplash;

## Introdução

O &ksplash; é um ecrã inicial bonito que mostra o progresso de uma aplicação que está a ser carregada. Por favor comunique quaisquer problemas ou pedidos de funcionalidades às listas de correio do &kde;. As principais funcionalidades do &ksplash; são:

- Temas Configuráveis
- Utiliza 'plugins' para uma personalização completa
- Pode ser usado por qualquer aplicação que utilize o DCOP

Este manual mostrar-lhe-á como criar temas para usar com os 'plugins' que já estão disponíveis. Se nenhum dos 'plugins' disponíveis satisfaz o seu gosto, você poderá aprender como personalizar a aparência do &ksplash; por completo ao criar um 'plugin' em C++.

## Usar os temas

Para usar os temas do KDE-Look, extraia-os para a pasta `~/.kde/share/apps/ksplash/Themes/` para um único utilizador, ou para a `$`KDEDIR`/share/apps/ksplash/Themes/` para os tornar disponíveis para todos os utilizadores do seu sistema.

Você também poderá usar o módulo Ecrã Inicial da Aparência no centro de controlo do &kde; para fazer isto automaticamente.

### Utilizar o Módulo do &kcontrol;

Este módulo permite-lhe instalar, testar e remover temas do &ksplash;.

Ao lado do módulo existe uma lista com os temas disponíveis de momento para o &ksplash;. Quando seleccionar um, irá aparecer uma antevisão na área principal da janela. Quando tiver seleccionado o item que deseja usar, carregue em OK ou em Aplicar. Carregue em Cancelar para sair do módulo sem ter feito nenhuma alteração ou em Predefinições para repor o ecrã inicial por omissão do sistema.

Para instalar novos módulos, carregue em Adicionar... e procure o tema no seu computador. Você não terá de descomprimir os ficheiros dos temas; poderá seleccionar sem problemas o ficheiro de tema comprimido. Se instalar um tema não o torna o tema por omissão, até que você o seleccione na lista e carregue em OK ou em Aplicar.

Ainda que você possa ver uma antevisão do ecrã inicial, você poderá querer ver como é que ele funciona realmente, por exemplo para ver como é que fica a animação. Você poderá testar os temas se os seleccionar na lista e carregar em Testar.

Você também poderá remover os temas que não deseja mais usar, se os seleccionar e carregar em Remover. Lembre-se que a sua conta de utilizador poderá não ter permissões para remover os temas instalados ao nível do sistema. Também é recomendado que não desinstale o ecrã inicial Por omissão.

## Como criar temas para o &ksplash;

### Geral

Criar os seus próprios temas do &ksplash; é simples. Depois de você ter terminado os seus temas poderá publicá-los no KDE-Look para que as outras pessoas os possam usar.

#### Identificar o seu tema

Vamos então criar um tema chamado `OMeuTemaFixe`. Para o tema ser reconhecido pelo &ksplash;, deverá ser guardado numa pasta chamada `OMeuTemaFixe` em `~/.kde/apps/ksplash/Themes/`. Devertá ter um ficheiro chamado `Theme.rc`, o qual contém a configuração do tema. Você poderá indicar várias coisas especiais para o tema, alterar o motor do 'plugin' a usar, e assim por diante. Você não terá de usar todas as configurações disponíveis; normalmente, as configurações têm valores por omissão aceitáveis. A sintaxe básica dos itens no ficheiro `Theme.rc` é `[opção] = [valor]` Você poderá encontrar as definições das várias opções nas seguintes secções.

##### Ficheiro `Theme.rc` simples

    [Tema do KSplash: OMeuTemaFixe]
    Name = OMeuTemaFixe
    Description = Um tema giro usando um motor do tipo XP
    Version = 1.0
    Author = Nome Verdadeiro <nomeverdadeiro@mail.com>
    ## Usar o motor XpLike para este tema.
    Engine = XpLike
    Show Icon = false
    Welcome Text = A carregar o KDE

Depois de indicar o nome, a descrição e o autor do tema, você derá escolher primeiro um motor de temas (também conhecido por 'plugin'). A partir daí, você poderá personalizar várias funcionalidades do motor do tema ao atribuir pares (chave, valor) como no ficheiro de exemplo em cima.

É importante que o nome da directoria onde os ficheiros dos temas são gravados (`~/.kde/apps/ksplash/Themes/OMeuTemaFixe` no nosso caso) e o identificador (`[Tema do KSplash: OMeuTemaFixe]` , também no nosso caso) do tema no ficheiro `Theme.rc` sejam idênticos. Caso contrário, o &ksplash; não irá reconhecer o tema.

#### Ficheiros com fundos

Quando o &ksplash; se inicia, ele tenta procurar uma imagem de fundo para a sua resolução de ecrã actual, se o motor do tema usar uma. O ficheiro com a imagem de fundo deverá ter um nome com o seguinte formato: `Background-`LLLxAAA`.png`, com o LLL sendo a largura em pixels e o AAA, a altura..

Por exemplo, você poderá usar um ficheiro chamado `Background-1024x768`. Se a imagem de fundo para a sua resolução não puder ser encontrada, ele tentará redimensionar o ficheiro original `Background.png` ou o ficheiro indicado no `Theme.rc` para se adequar à resolução actual. O redimensionamento imediato poderá levar algum tempo, como tal você deverá fornecer imagens de fundo para, pelo menos, os seguintes tamanhos: 1280x1024, 1024x768 e 800x600.

### Opções para os Motores de Temas

#### Tema Padrão

#### Opções do Tema Padrão

Nome | Argumento | Explicação
Posição da Barra de Estado | [top/bottom] | Comuta a posição da barra de estado no ecrã: 'top' (em cima) ou 'bottom' (em baixo). O valor por omissão é o 'bottom'.
Barra de Estado Visível | [true/false] | Indica se a barra de estado deverá ser mostrada ('true': sim; 'false': não). O valor por omissão é o 'true'.
Progresso Visível | [true/false] | Indica se o progresso do carregamento deverá ser mostrado ('true': sim; 'false': não). Por omissão é 'true'.
Tipo de Letra da Barra de Estado | [nome do tipo de letra] | O tipo de letra usado na barra de estado. Por omissão é o Helvetica.
Tamanho da Letra da Barra de Estado | [tamanho] | O tamanho da letra usado na barra de estado. Por omissão é igual a 16.
Texto Negrito na Barra de Estado | [true/false] | Indica se o texto da barra de estado deverá aparecer negrito ('true': sim; 'false': não). Por omissão, é igual a 'true'.
Texto Itálico na Barra de Estado | [true/false] | Indica se o texto da barra de estado deverá aparecer em itálico ('true': sim; 'false': não). Por omissão, é igual a 'false'.
Cor do Texto da Barra de Estado | [cor] | A cor do texto na barra de estado. Por omissão é igual a 'white' (branco).
Cor de Fundo da Barra de Estado | [cor] | A cor de fundo na barra de estado. Por omissão é igual a 'black' (preto).
Ícone da Barra de Estado | [true/false] | Indica se a barra de estado deverá ter um ícone.
Ícones Visíveis | [true/false] | Indica se os ícones deverão estar visíveis ('true': sim; 'false': não). Por omissão, está a 'true'.
Ícones Saltitantes | [true/false] | Indica se os ícones deverão estar intermitentes ('true': sim; 'false': não). Por omissão é igual a 'true'.
Posição do Ícone | [0-3,10-13] | Posição onde os ícones são mostrados. Por omissão: 'bottom-left' (em baixo, à esquerda).
Ecrã Inicial | [nome] | Altera imagem do ecrã inicial que é mostrada.

#### Tema do Redmond

#### Opções do tema Redmond

Nome | Argumento | Explicação
Imagem de Fundo | [ficheiro] | A imagem de fundo definida pelo utilizador a usar.
Ícone do Utilizador | [Nome de ícone] | O nome do ícone-padrão a mostrar para o utilizador. Por omissão é o `go`.
Texto de Boas-Vindas | [texto] | O texto mostrado no ecrã inicial. Por omissão é "Bem-vindo".
Texto do Nome do Utilizador | [texto] | O texto que é mostrado em vez do nome verdadeiro do utilizador.
Posição do Texto de Boas-Vindas | [x,y] | A posição no ecrã onde é mostrado o texto de Boas-Vindas.
Posição do Nome do Utilizador | [x,y] | A posição no ecrã onde é mostrado o nome do utilizador.
Posição do Texto da Acção | [x,y] | A posição no ecrã onde é mostrada a acção a decorrer.
Posição do Ícone | [x,y] | A posição no ecrã onde o ícone do utilizador é mostrado.
Mostrar o Texto de Boas-Vindas | [true/false] | Comuta a apresentação do texto de boas-vindas ('true': sim; 'false': não). Por omissão, é igual a 'true'.
Mostrar a Sombra das Boas-Vindas | [true/false] | Comuta a apresentação do sombreado do texto de boas-vindas ('true': sim; 'false': não). Por omissão, é igual a 'true'.
Mostrar o Nome do Utilizador | [true/false] | Comuta a apresentação do nome do utilizador ('true': sim; 'false': não). Por omissão é igual a 'true'.
Mostrar a Acção | [true/false] | Comuta a apresentação da acção que está a ser efectuada de momento ('true': sim; 'false': não). Por omissão é igual a 'true'.
Mostrar o Ícone | [true/false] | Indica se o ícone deverá ser mostrado ('true': sim; 'false': não). Por omissão, 'true'.
Usar o Ícone do Utilizador do KDM | [true/false] | Mostra o ícone da autenticação do utilizador ('true': sim; 'false': não). Por omissão, igual a 'true'.

#### Tema do MacX

#### Opções do Tema MacX

Nome | Argumento | Explicação
Tamanho Mínimo dos Ícones | [tamanho] | Atribui o tamanho mínimo para os ícones. Por omissão, é igual a 16.
Tamanho Máximo dos Ícones | [tamanho] | Atribui o tamanho máximo para os ícones. O valor por omissão é igual a 64.
Desenho Optimizado dos Ícones | [true/false] | Optimiza o processo de desenho dos ícones ('true': sim; 'false': não). Por omissão, 'true'.
Barra de Progresso Visível | [true/false] | Por omissão, igual a 'true' (sim). O outro valor possível será 'false' (não).
Posição da Barra de Progresso | [top/bottom] | Indica se a barra de estado deverá aparecer em cima ('top') ou em baixo ('bottom'). Por omissão é igual a 'bottom'.
Ícones Saltitantes | [true/false] | Indica se os ícones deverão estar saltitantes ('true': sim; 'false': não). Por omissão, é igual a 'false'.

#### Tema MacClassic

#### Opções do Tema MacClassic

Nome | Argumento | Explicação
Posição do Ícone | [0-3,10-13] | A posição dos ícones no ecrã. Por omissão, é igual a 'bottom left' (em baixo, à esquerda).
Ícones Saltitantes | [true/false] | Indica se os ícones deverão estar saltitantes ('true': sim; 'false': não). Por omissão, é igual a 'false'.
Ícones Visíveis | [true/false] | Indica se os ícones deverão estar visíveis ('true': sim; 'false': não). Por omissão, está a 'true'.
Ecrã Inicial | [nome] | Altera imagem do ecrã inicial que é mostrada.

#### Tema 2k

#### Opções do tema 2k

Nome | Argumento | Explicação
Cor de Fundo do Título | [cor] | A cor de fundo do título. Por omissão é 'dark blue' (azul escuro).
Cor do Texto do Título | [cor] | A cor do texto do título. Por omissão, é igual a 'white' (branco).
Cor do Texto do Estado | [cor] | A cor dos textos de estado. Por omissão, é a mesma que a Cor de Fundo do Título.
Cor da Rotação 1 | [cor] | Indica a cor da rotação 1. Por omissão, é igual a 'dark blue' (azul escuro).
Cor da Rotação 2 | [cor] | Indica a cor da rotação 2. Por omissão, é igual a 'cyan' (azul-cião).
Velocidade da Rotação | [valor] | Define a velocidade da rotação. Por omissão, é igual a 30.
Título da Janela | [texto] | Indica o texto de título para a janela.
Ficheiro do Logotipo | [ficheiro] | Define o logotipo a usar.

## Usar o &ksplash; na sua Própria Aplicação

Neste capítulo, nós descrevemos um método simples para usar o &ksplash; como o ecrã inicial para a sua aplicação do &kde;. Se não você não desenvolve aplicações para o &kde;, poderá ignorar este capítulo.

### Requisitos Básicos

A sua aplicação do &kde; deverá lidar com o &DCOP;. O &DCOP; é a tecnologia do &kde; que é usada para comunicar entre as aplicações. Se você usar a plataforma-padrão de aplicações do &kde;, isto é realizado automaticamente. Para mais informações sobre o &DCOP; e as tecnologias relacionadas do &kde; vá ao cantinho dos programadores do &kde;.

### Iniciar o &ksplash;

Antes de a sua aplicação iniciar o seu trabalho intensivo, ou antes de começar a carregar os 'plugins', &etc;, invoke o &ksplash; como se mostra a seguir:

    DCOPClient *c = kapp->dcopClient();
    QString erro;
    QCString NomeKSplash;
    int pid = 0;
    QStringList args;
    args << "--theme=OMeuTemaFixe" << "--managed";
    if (kapp->startServiceByDesktopName("ksplash", args, &erro, &NomeKSplash, &pid))
    {
      KMessageBox::sorry(0, erro, "Não é possível invocar o KSplash");
      // Algum processamento de erros aqui.
    }

Nós iremos assumir que só existe uma instância do &ksplash; a correr. Os outros casos são ligeiramente mais complexos. Por favor, veja a documentação do &DCOP; para mais detalhes.

### Mostrar as mensagens

Antes de você poder mostrar quaisquer mensagens, você precisa de configurar o número de passos que irá mostrar. Por exemplo, o procedimento de arranque do &kde; utiliza 7 passos.

    QByteArray dados;
        QDataStream arg(dados,IO_WriteOnly);
        arg << umNumero;
        if (!(c->send(NomeKSplash, "KSplashIface", "setStartupItemCount(int)", dados))
          // Algum processamento de erros aqui.

Sempre que quiser mostrar uma mensagem com um ícone ou sem nenhum, use

    arg << QString("nomeIcone") << QString("nomePrograma") << QString("Uma descrição");
        if (!(c->send(NomeKSplash, "KSplashIface", "programStarted(QString,QString,QString)", dados))
        {
          // Algum processamento de erros aqui.
        }

De cada vez que você invocar o `programStarted`, os passos completos são incrementados. Quando o seu programa tiver terminado o seu arranque, faça o seguinte para fazer desaparecer o ecrã inicial:

    if (!(c->send(NomeKSplash, "KSplashIface", "startupComplete()", dados))
        {
          // Algum processamento de erros aqui.
        }

Já está! Você não precisa de mais nada para tirar partido de tudo o que o &ksplash; tem para lhe oferecer.

## Criar novos 'plugins' do &ksplash;

A criação de novos 'plugins' para o &ksplash; não é difícil. Neste capítulo, nós iremos criar um 'plugin' simples que irá emular o ecrã inicial de um sistema operativo bem conhecido. Este tutorial assume que você conhece as bases do C++ e um pouco de programação com o KDE/Qt.

### Requisitos Básicos

Nós iremos criar um 'plugin' chamado `2k`. O nome do 'plugin' é usado em vários sítios, e é importante que você o use de forma consistente, de modo a que o 'plugin' seja reconhecido pelo &ksplash;. Os 'plugins' do &ksplash; são de factos bibliotecas carregadas dinamicamente com a seguinte convenção de nomes:

- A biblioteca dever-se-á chamar `ksplash+nomedotemaemminúsculas`. Para o nosso tema, chamar-se-á `ksplash2k`.
- Deverá ter um ficheiro 'desktop' correspondente com o nome formatado da seguinte forma `ksplash+nomedotemaemminúsculas.desktop`. Para o nosso tema, será igual a `ksplash2k.desktop`.
- Finalmente, o objecto que é devolvido pela biblioteca deverá ser uma classe chamada `Theme+nomedotema`. Para o nosso exemplo, será a `Theme2k`.

Não se preocupe com isso se não perceber nada da parte anterior. Nós vamos ter em consideração cada um desses pontos em detalhe mais tarde. O outro detalhe importante é que a classe do 'plugin' deverá ser derivada da classe `ThemeEngine`.

### Criar a plataforma de esqueleto

Nós iremos usar a plataforma de aplicações do &kde;, a qual tomará conta de construir o 'plugin' e que nos irá garantir alguma independência da plataforma, sem nenhum trabalho da nossa parte. Para o fazer, certifique-se que tem o pacote `kdesdk` instalado. Corra o comando `kapptemplate` para produzir uma aplicação chamada "2k". Ela irá criar uma pasta de topo que contém alguns ficheiros genéricos como o AUTHORS, &etc;. Nós estamos mais interessados na subpasta chamada `2k`. Vá para essa subpasta e remova todos os ficheiros que lá estejam. A partir de agora, temos o esqueleto que pretendemos.

O próximo passo é a criação de um ficheiro `.desktop` que, ao ser instalado, irá indicar ao &ksplash; que o nosso 'plugin' está disponível. Estando consistente com as convenções de nomes indicadas na secção anterior, crie um ficheiro chamado `ksplash2k.desktop` nessa pasta. Deverá conter as seguintes linhas:

    [Desktop Entry]
    Encoding=UTF-8
    Type=Service
    Comment=Plugin do KSplash
    Name=KSplash2k
    ServiceTypes=KSplash/Plugin
    X-KDE-Library=libksplash2k
    X-KSplash-Default=true
    X-KSplash-PluginName=2k
    X-KSplash-ObjectName=Tema2k

Os campos `Encoding`, `Type`, `Comment` e `ServiceTypes` são os mesmos para todos os 'plugins'. O nome do 'plugin' e da biblioteca seguem as convenções indicadas acima. O campo `X-KSplash-Default` usa um valor booleano que indica se deverá ser mostrado no módulo de configuração do painel de controlo por omissão. Excepto em casos muitos raros, deverá ser igual a `true`.

### Declaração da classe do 'plugin'

Agora que terminámos o trabalho preliminar, vamos para a parte divertida - criar uma classe que irá fornecer o comportamento que pretendemos. Embora tenhamos a liberdade de fazer com que esta classe faça praticamente tudo o que quisermos, existem algumas restrições.

1. As classes do 'plugin' deverão herdar da classe `ThemeEngine`.

2. As classes do 'plugin' deverão ter um nome de acordo com a regra: `Theme+NomePlugin`.

3. As classes do 'plugin' deverão oferecer uma função `static` chamada `names` que devolve uma lista com os nomes pela qual poderá ser invocada.

4. Se o 'plugin' puder ser configurado no módulo do centro de controlo, deverá oferecer uma classe baseada na `ThemeEngineConfig` para a configuração.

5. As classes do 'plugin' deverão reimplementar pelo menos uma das funções virtuais `slotSetText`, `slotSetPixmap`, `slotUpdateProgress` e `slotUpdateSteps` para serem úteis.

6. O construtor deverá ter a forma `ThemeEngine( QWidget *mae, const char *nome, const QStringList &argumentos )` para que possa ser usada com a `KGenericFactory`.

O último requisito poderá parecer complicado mas, como veremos mais tarde, ao adicionar uma única linha aos seus ficheiros de código, você poderá normalmente ignorá-lo.

### Código do ficheiro de inclusão

Dadas as restrições, nós veremos agora que o ficheiro de inclusão `theme2k.h` ficará como o seguinte:

#### Listagem do `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 Nomes;
        Nomes << "KSplash2k";
        Nomes << "ks2k";
        Nomes << "2k";
        Nomes << "2000";
        return( Nomes );
      };

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

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

      QLabel *mTexto;
      RotWidget *mRotacao;
      QColor mTCorFundo, mTCorTexto, mRotCor1, mRot2, mCorEstado;
      int mRotVelocidade;
      QString mTitulo, mLogotipo;
    };

    #endif

Vamos então analisar a listagem em cima. A classe `Theme2k` satisfaz as convenções de nomes e herda da classe `ThemeEngine`. Ela contém um método `Theme2k::names()`, e tem um construtor que recebe os parâmetros obrigatórios: `Theme2k( QWidget *, const char *, const QStringList& );` e também contém um método simples `Theme2k::slotSetText()`. De momento, não se preocupe com a classe `RotWidget`. É um pequeno item que oferece alguma beleza visual para o utilizador. O nosso 'plugin' é muito simples e não mostra nenhuns ícones nem nenhuma barra de progresso. Se você quiser mostrar os ícones, reimplemente a função `slotSetPixmap`. Existem funções semelhantes para definir o intervalo da barra de progresso (`slotUpdateSteps`) e para incrementar (`slotUpdateProgress`) o passo actual.

### Implementação do 'plugin'

Nós iremos examinar só as partes relevantes da implementação. Para uma listagem da implementação completa (e não traduzida), veja por favor o apêndice. A primeira coisa que será feita é descartar o requisito da biblioteca:

#### Requisito da biblioteca

    K_EXPORT_COMPONENT_FACTORY( ksplash2k, KGenericFactory<Theme2k> );

A macro `K_EXPORT_COMPONENT_FACTORY` é declarada no ficheiro `kgenericfactory.h`. Sigamos para o construtor! Dado que este é um 'plugin' muito simples, assim o é também o construtor.

#### Construtor do 'plugin'

    Theme2k::Theme2k( QWidget *mae, const char *nome, const QStringList &argumentos  )
        :ThemeEngine( mae, nome, argumentos )
    {
      readSettings();
      initUi();
    }

O método `readSettings()` ilustra a forma correcta de obter a configuração do seu tema. (Você deseja que as pessoas usem os seus 'plugins' nos temas delas, não deseja?)

#### Obter a configuração do tema

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

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

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

      QColor TCorFundoOmissao( Qt::darkBlue );
      QColor TCorTextoOmissao( Qt::white );

      mTCorFundo = cfg->readColorEntry( "Cor de Fundo do Título", &TCorFundoOmissao );
      mTCorTexto = cfg->readColorEntry( "Cor do Texto do Título", &TCorTextoOmissao );
      mCorEstado = cfg->readColorEntry("Cor do Texto do Estado", &mTCorFundo );

      QColor Rot1Omissao( Qt::darkBlue );
      QColor Rot2Omissao( Qt::cyan );
      mRotCor1 = cfg->readColorEntry( "Cor 1 da Rotação", &Rot1Omissao );
      mRotCor2 = cfg->readColorEntry( "Cor 2 da Rotação", &Rot2Omissao );

      mRotVelocidade = cfg->readNumEntry( "Velocidade da Rotação", 30 );
      mTitulo = cfg->readEntry( "Título da Janela", i18n("Espere por favor") );
      mLogotipo = cfg->readEntry( "Ficheiro do Logotipo", QString::null );
    }

Dado que gostamos dos nossos utilizadores, nós oferecemos valores razoáveis para os parâmetros que não estejam presentes no ficheiro do tema. Repare que devemos ser definir o nosso grupo para "KSplash Theme: nomedotema" para continuarmos compatíveis com as especificações dos temas futuras. O método `initUI()` não é muito interessante, dado que apenas cria a interface gráfica. Veja por favor o apêndice para mais detalhes.

### Compilar o 'plugin'

Dado que decidimos usar a plataforma do &kde; para compilar o 'plugin', nós iremos precisar de criar um `Makefile.am`. Deverá ficar algo do género:

#### Listagem do `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

Para mais informações sobre como criar os ficheiros `Makefile.am` para o &kde;, por favor veja o 'site' Web dos programadores do &kde;. A única coisa a notar é que nós oferecemos um tema por omissão baseado neste 'plugin' e oferecemos uma imagem de antevisão para o mesmo. Por razões de cortesia para os seus utilizadores, você deverá oferecer um `Theme.rc` de exemplo e que ilustre a utilização das várias opções.

## Perguntas e Respostas

&reporting.bugs; &updating.documentation;

Não consigo encontrar nenhuns temas que funcionem no &ksplash;. Porquê?

Você provavelmente não tem os 'plugins' correctos para o tema. Os 'plugins' estão no pacote `kde-artwork`. Obtenha-os e instale-os, e tente de novo mais tarde.

O que é o ficheiro `Theme.rc` e como é que crio um?

O `Theme.rc` é o ficheiro onde você poderá indicar a configuração de um tema. Para mais informações, dê uma vista de olhos em Como criar temas para o &ksplash;.

## Créditos e Licença

&ksplash;

Programa Copyright © 2003 &Ravikiran.Rajagopal; &Ravikiran.Rajagopal.mail;

## Contribuições

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

Documentação Copyright © 2003 &Teemu.Rytilahti; &Teemu.Rytilahti.mail;

&underFDL; &underGPL;

## Instalação

### Requisitos

Para conseguir usar com sucesso o &ksplash;, você necessita do &kde; versão 3.2 ou superior. Alguns temas poderão necessitar de 'plugins' específicos. Se um tema não funcionar, por favor contacte o autor do tema para descobrir onde obter o 'plugin' apropriado.

### Compilação e Instalação

&install.compile.documentation;

## Código-fonte

### Listagem não traduzida do `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 );
    }

### Listagem não traduzida do `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

### Listagem não traduzida `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;