<?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 % Portuguese "INCLUDE"> ]> <book lang="&language;"> <bookinfo> <title >O Manual do &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 >José</firstname ><surname >Pires</surname ><affiliation ><address ><email >zepires@gmail.com</email ></address ></affiliation ><contrib >Tradução</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 >O &ksplash; é um ecrã inicial bonito que mostra o progresso de uma aplicação que está a ser carregada.</para> </abstract> <keywordset> <keyword >KDE</keyword> <keyword >kdebase</keyword> <keyword >ksplash</keyword> <keyword >ksplashml</keyword> <keyword >ecrã inicial</keyword> <keyword >belezas visuais</keyword> </keywordset> </bookinfo> <chapter id="introduction"> <title >Introdução</title> <para >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: </para> <simplelist> <member >Temas Configuráveis</member> <member >Utiliza 'plugins' para uma personalização completa</member> <member >Pode ser usado por qualquer aplicação que utilize o DCOP</member> </simplelist> <para >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++. </para> </chapter> <chapter id="using-themes"> <title >Usar os temas</title> <para >Para usar os temas do <ulink url="http://www.kde-look.org" >KDE-Look</ulink >, extraia-os para a pasta <filename >~/.kde/share/apps/ksplash/Themes/</filename > para um único utilizador, ou para a <filename >$<envar >KDEDIR</envar >/share/apps/ksplash/Themes/</filename > para os tornar disponíveis para todos os utilizadores do seu sistema.</para> <para >Você também poderá usar o módulo <guilabel >Ecrã Inicial</guilabel > da <guilabel >Aparência</guilabel > no centro de controlo do &kde; para fazer isto automaticamente.</para> <sect1 id="using-kcontrol-module"> <title >Utilizar o Módulo do &kcontrol;</title> <para >Este módulo permite-lhe instalar, testar e remover temas do &ksplash;.</para> <para >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 <guibutton >OK</guibutton > ou em <guibutton >Aplicar</guibutton >. Carregue em <guibutton >Cancelar</guibutton > para sair do módulo sem ter feito nenhuma alteração ou em <guibutton >Predefinições</guibutton > para repor o ecrã inicial por omissão do sistema.</para> <para >Para instalar novos módulos, carregue em <guibutton >Adicionar...</guibutton > 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 <guibutton >OK</guibutton > ou em <guibutton >Aplicar</guibutton >.</para> <para >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 <guibutton >Testar</guibutton >.</para> <para >Você também poderá remover os temas que não deseja mais usar, se os seleccionar e carregar em <guibutton >Remover</guibutton >. 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 <guilabel >Por omissão</guilabel >.</para> </sect1> </chapter> <chapter id="themes"> <title >Como criar temas para o &ksplash;</title> <sect1 id="themes-general"> <title >Geral</title> <para >Criar os seus próprios temas do &ksplash; é simples. Depois de você ter terminado os seus temas poderá publicá-los no <ulink url="http://www.kde-look.org" >KDE-Look</ulink > para que as outras pessoas os possam usar.</para> <sect2 id="theme-syntax"> <title >Identificar o seu tema</title> <para >Vamos então criar um tema chamado <literal >OMeuTemaFixe</literal >. Para o tema ser reconhecido pelo &ksplash;, deverá ser guardado numa pasta chamada <filename class="directory" >OMeuTemaFixe</filename > em <filename class="directory" >~/.kde/apps/ksplash/Themes/</filename >. Deverá ter um ficheiro chamado <filename >Theme.rc</filename >, 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 <filename >Theme.rc</filename > é <literal >[opção] = [valor]</literal > Você poderá encontrar as definições das várias opções nas seguintes secções.</para> <example> <title >Ficheiro <filename >Theme.rc</filename > simples</title> <programlisting >[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 </programlisting> </example> <para >Depois de indicar o nome, a descrição e o autor do tema, você deverá 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.</para> <para >Garanta que o nome da pasta onde os ficheiros dos temas são gravados (<filename class="directory" >~/.kde/apps/ksplash/Themes/OMeuTemaFixe</filename > no nosso caso) e o identificador (<literal >[Tema do KSplash: OMeuTemaFixe] </literal >, também no nosso caso) do tema no ficheiro <filename >Theme.rc</filename > sejam idênticos. Caso contrário, o &ksplash; não irá reconhecer o tema. </para> </sect2> <sect2 id="theme-files"> <title >Ficheiros com fundos</title> <para >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: <filename >Background-<replaceable >LLLxAAA</replaceable >.png</filename >, com o LLL sendo a largura em pixels e o AAA, a altura..</para> <para >Por exemplo, você poderá usar um ficheiro chamado <filename >Background-1024x768</filename >. Se a imagem de fundo para a sua resolução não puder ser encontrada, ele tentará redimensionar o ficheiro original <filename >Background.png</filename > ou o ficheiro indicado no <filename >Theme.rc</filename > 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.</para> </sect2> </sect1> <sect1 id="theme-engines"> <title >Opções para os Motores de Temas</title> <sect2 id="standard-themes"> <title >Tema Padrão</title> <table> <title >Opções do Tema Padrão</title> <tgroup cols="3"> <tbody> <row> <entry >Nome</entry> <entry >Argumento</entry> <entry >Explicação</entry> </row> <!-- Statusbar --> <row> <entry >Posição da Barra de Estado</entry> <entry >[top/bottom]</entry> <entry >Comuta a posição da barra de estado no ecrã: 'top' (em cima) ou 'bottom' (em baixo). O valor por omissão é o 'bottom'.</entry> </row> <row> <entry >Barra de Estado Visível</entry> <entry >[true/false]</entry> <entry >Indica se a barra de estado deverá ser mostrada ('true': sim; 'false': não). O valor por omissão é o 'true'.</entry> </row> <row> <entry >Progresso Visível</entry> <entry >[true/false]</entry> <entry >Indica se o progresso do carregamento deverá ser mostrado ('true': sim; 'false': não). Por omissão é 'true'.</entry> </row> <!-- Fonts --> <row> <entry >Tipo de Letra da Barra de Estado</entry> <entry >[nome do tipo de letra]</entry> <entry >O tipo de letra usado na barra de estado. Por omissão é o Helvetica.</entry> </row> <row> <entry >Tamanho da Letra da Barra de Estado</entry> <entry >[tamanho]</entry> <entry >O tamanho da letra usado na barra de estado. Por omissão é igual a 16.</entry> </row> <row> <entry >Texto Negrito na Barra de Estado</entry> <entry >[true/false]</entry> <entry >Indica se o texto da barra de estado deverá aparecer negrito ('true': sim; 'false': não). Por omissão, é igual a 'true'.</entry> </row> <row> <entry >Texto Itálico na Barra de Estado</entry> <entry >[true/false]</entry> <entry >Indica se o texto da barra de estado deverá aparecer em itálico ('true': sim; 'false': não). Por omissão, é igual a 'false'.</entry> </row> <!-- Misc. things --> <row> <entry >Cor do Texto da Barra de Estado</entry> <entry >[cor]</entry> <entry >A cor do texto na barra de estado. Por omissão é igual a 'white' (branco).</entry> </row> <row> <entry >Cor de Fundo da Barra de Estado</entry> <entry >[cor]</entry> <entry >A cor de fundo na barra de estado. Por omissão é igual a 'black' (preto).</entry> </row> <row> <entry >Ícone da Barra de Estado</entry> <entry >[true/false]</entry> <entry >Indica se a barra de estado deverá ter um ícone.</entry> </row> <row> <entry >Ícones Visíveis</entry> <entry >[true/false]</entry> <entry >Indica se os ícones deverão estar visíveis ('true': sim; 'false': não). Por omissão, está a 'true'.</entry> </row> <row> <entry >Ícones Saltitantes</entry> <entry >[true/false]</entry> <entry >Indica se os ícones deverão estar intermitentes ('true': sim; 'false': não). Por omissão é igual a 'true'.</entry> </row> <row> <entry >Posição do Ícone</entry> <entry >[0-3,10-13]</entry> <entry >Posição onde os ícones são mostrados. Por omissão: 'bottom-left' (em baixo, à esquerda).</entry> </row> <row> <entry >Ecrã Inicial</entry> <entry >[nome]</entry> <entry >Altera imagem do ecrã inicial que é mostrada.</entry> </row> </tbody> </tgroup> </table> </sect2> <sect2 id="redmond-themes"> <title >Tema do Redmond</title> <table> <title >Opções do tema Redmond</title> <tgroup cols="3"> <tbody> <row> <entry >Nome</entry> <entry >Argumento</entry> <entry >Explicação</entry> </row> <!-- Main elements --> <row> <entry >Imagem de Fundo</entry> <entry >[ficheiro]</entry> <entry >A imagem de fundo definida pelo utilizador a usar.</entry> </row> <row> <entry >Ícone do Utilizador</entry> <entry >[Nome de ícone]</entry> <entry >O nome do ícone-padrão a mostrar para o utilizador. Por omissão é o <constant >go</constant >.</entry> </row> <row> <entry >Texto de Boas-Vindas</entry> <entry >[texto]</entry> <entry >O texto mostrado no ecrã inicial. Por omissão é "Bem-vindo".</entry> </row> <row> <entry >Texto do Nome do Utilizador</entry> <entry >[texto]</entry> <entry >O texto que é mostrado em vez do nome verdadeiro do utilizador.</entry> </row> <!-- Positioning elements --> <row> <entry >Posição do Texto de Boas-Vindas</entry> <entry >[x,y]</entry> <entry >A posição no ecrã onde é mostrado o texto de Boas-Vindas.</entry> </row> <row> <entry >Posição do Nome do Utilizador</entry> <entry >[x,y]</entry> <entry >A posição no ecrã onde é mostrado o nome do utilizador.</entry> </row> <row> <entry >Posição do Texto da Acção</entry> <entry >[x,y]</entry> <entry >A posição no ecrã onde é mostrada a acção a decorrer.</entry> </row> <row> <entry >Posição do Ícone</entry> <entry >[x,y]</entry> <entry >A posição no ecrã onde o ícone do utilizador é mostrado.</entry> </row> <!-- Show to show.. --> <row> <entry >Mostrar o Texto de Boas-Vindas</entry> <entry >[true/false]</entry> <entry >Comuta a apresentação do texto de boas-vindas ('true': sim; 'false': não). Por omissão, é igual a 'true'.</entry> </row> <row> <entry >Mostrar a Sombra das Boas-Vindas</entry> <entry >[true/false]</entry> <entry >Comuta a apresentação do sombreado do texto de boas-vindas ('true': sim; 'false': não). Por omissão, é igual a 'true'.</entry> </row> <row> <entry >Mostrar o Nome do Utilizador</entry> <entry >[true/false]</entry> <entry >Comuta a apresentação do nome do utilizador ('true': sim; 'false': não). Por omissão é igual a 'true'.</entry> </row> <row> <entry >Mostrar a Acção</entry> <entry >[true/false]</entry> <entry >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'.</entry> </row> <row> <entry >Mostrar o Ícone</entry> <entry >[true/false]</entry> <entry >Indica se o ícone deverá ser mostrado ('true': sim; 'false': não). Por omissão, 'true'.</entry> </row> <row> <entry >Usar o Ícone do Utilizador do KDM</entry> <entry >[true/false]</entry> <entry >Mostra o ícone da autenticação do utilizador ('true': sim; 'false': não). Por omissão, igual a 'true'.</entry> </row> </tbody> </tgroup> </table> </sect2> <sect2 id="macx-themes"> <title >Tema do MacX</title> <table> <title >Opções do Tema MacX</title> <tgroup cols="3"> <tbody> <row> <entry >Nome</entry> <entry >Argumento</entry> <entry >Explicação</entry> </row> <row> <entry >Tamanho Mínimo dos Ícones</entry> <entry >[tamanho]</entry> <entry >Atribui o tamanho mínimo para os ícones. Por omissão, é igual a 16.</entry> </row> <row> <entry >Tamanho Máximo dos Ícones</entry> <entry >[tamanho]</entry> <entry >Atribui o tamanho máximo para os ícones. O valor por omissão é igual a 64.</entry> </row> <row> <entry >Desenho Optimizado dos Ícones</entry> <entry >[true/false]</entry> <entry >Optimiza o processo de desenho dos ícones ('true': sim; 'false': não). Por omissão, 'true'.</entry> </row> <row> <entry >Barra de Progresso Visível</entry> <entry >[true/false]</entry> <entry >Por omissão, igual a 'true' (sim). O outro valor possível será 'false' (não).</entry> </row> <row> <entry >Posição da Barra de Progresso</entry> <entry >[top/bottom]</entry> <entry >Indica se a barra de estado deverá aparecer em cima ('top') ou em baixo ('bottom'). Por omissão é igual a 'bottom'.</entry> </row> <row> <entry >Ícones Saltitantes</entry> <entry >[true/false]</entry> <entry >Indica se os ícones deverão estar saltitantes ('true': sim; 'false': não). Por omissão, é igual a 'false'.</entry> </row> </tbody> </tgroup> </table> </sect2> <sect2 id="mac-classic-themes"> <title >Tema MacClassic</title> <table> <title >Opções do Tema MacClassic</title> <tgroup cols="3"> <tbody> <row> <entry >Nome</entry> <entry >Argumento</entry> <entry >Explicação</entry> </row> <row> <entry >Posição do Ícone</entry> <entry >[0-3,10-13]</entry> <entry >A posição dos ícones no ecrã. Por omissão, é igual a 'bottom left' (em baixo, à esquerda).</entry> </row> <row> <entry >Ícones Saltitantes</entry> <entry >[true/false]</entry> <entry >Indica se os ícones deverão estar saltitantes ('true': sim; 'false': não). Por omissão, é igual a 'false'.</entry> </row> <row> <entry >Ícones Visíveis</entry> <entry >[true/false]</entry> <entry >Indica se os ícones deverão estar visíveis ('true': sim; 'false': não). Por omissão, está a 'true'.</entry> </row> <row> <entry >Ecrã Inicial</entry> <entry >[nome]</entry> <entry >Altera imagem do ecrã inicial que é mostrada.</entry> </row> </tbody> </tgroup> </table> </sect2> <sect2 id="themes-2k"> <title >Tema 2k</title> <table> <title >Opções do tema 2k</title> <tgroup cols="3"> <tbody> <row> <entry >Nome</entry> <entry >Argumento</entry> <entry >Explicação</entry> </row> <row> <entry >Cor de Fundo do Título</entry> <entry >[cor]</entry> <entry >A cor de fundo do título. Por omissão é 'dark blue' (azul escuro).</entry> </row> <row> <entry >Cor do Texto do Título</entry> <entry >[cor]</entry> <entry >A cor do texto do título. Por omissão, é igual a 'white' (branco).</entry> </row> <row> <entry >Cor do Texto do Estado</entry> <entry >[cor]</entry> <entry >A cor dos textos de estado. Por omissão, é a mesma que a Cor de Fundo do Título.</entry> </row> <row> <entry >Cor da Rotação 1</entry> <entry >[cor]</entry> <entry >Indica a cor da rotação 1. Por omissão, é igual a 'dark blue' (azul escuro).</entry> </row> <row> <entry >Cor da Rotação 2</entry> <entry >[cor]</entry> <entry >Indica a cor da rotação 2. Por omissão, é igual a 'cyan' (azul-cião).</entry> </row> <row> <entry >Velocidade da Rotação</entry> <entry >[valor]</entry> <entry >Define a velocidade da rotação. Por omissão, é igual a 30.</entry> </row> <row> <entry >Título da Janela</entry> <entry >[texto]</entry> <entry >Indica o texto de título para a janela.</entry> </row> <row> <entry >Ficheiro do Logótipo</entry> <entry >[ficheiro]</entry> <entry >Define o logotipo a usar.</entry> </row> </tbody> </tgroup> </table> </sect2> </sect1> </chapter> <chapter id="from-other-applications"> <title >Usar o &ksplash; na sua Própria Aplicação</title> <para >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.</para> <sect1 id="basic-other-reqs"> <title >Requisitos Básicos</title> <para >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 <ulink url="http://developer.kde.org" >plataforma-padrão de aplicações do &kde;</ulink >, isto é realizado automaticamente. Para mais informações sobre o &DCOP; e as tecnologias relacionadas do &kde; vá ao <ulink url="http://developer.kde.org" >cantinho dos programadores do &kde;</ulink >.</para> </sect1> <sect1 id="other-using"> <title >Iniciar o &ksplash;</title> <para >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:</para> <programlisting >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. } </programlisting> <para >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.</para> </sect1> <sect1 id="show-messages"> <title >Mostrar as mensagens</title> <para >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.</para> <programlisting >QByteArray dados; QDataStream arg(dados,QIODevice::WriteOnly); arg << umNumero; if (!(c->send(NomeKSplash, "KSplashIface", "setStartupItemCount(int)", dados)) // Algum processamento de erros aqui. </programlisting> <para >Sempre que quiser mostrar uma mensagem com um ícone ou sem nenhum, use</para> <programlisting >arg << QString("nomeIcone") << QString("nomePrograma") << QString("Uma descrição"); if (!(c->send(NomeKSplash, "KSplashIface", "programStarted(QString,QString,QString)", dados)) { // Algum processamento de erros aqui. } </programlisting> <para >De cada vez que você invocar o <constant >programStarted</constant >, 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:</para> <programlisting >if (!(c->send(NomeKSplash, "KSplashIface", "startupComplete()", dados)) { // Algum processamento de erros aqui. } </programlisting> <para >Já está! Você não precisa de mais nada para tirar partido de tudo o que o &ksplash; tem para lhe oferecer.</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 >Criar novos 'plugins' do &ksplash;</title> <para >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.</para> <sect1 id="basic-requirements"> <title >Requisitos Básicos</title> <para >Nós iremos criar um 'plugin' chamado <literal >2k</literal >. 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: </para> <simplelist> <member >A biblioteca dever-se-á chamar <filename >ksplash+nomedotemaemminúsculas</filename >. Para o nosso tema, chamar-se-á <filename >ksplash2k</filename >.</member> <member >Deverá ter um ficheiro 'desktop' correspondente com o nome formatado da seguinte forma <filename >ksplash+nomedotemaemminúsculas.desktop</filename >. Para o nosso tema, será igual a <filename >ksplash2k.desktop</filename >. </member> <member >Finalmente, o objecto que é devolvido pela biblioteca deverá ser uma classe chamada <literal >Theme+nomedotema</literal >. Para o nosso exemplo, será a <literal >Theme2k</literal >.</member> </simplelist> <para >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 <literal >ThemeEngine</literal >. </para> </sect1> <sect1 id="skeleton"> <title >Criar a plataforma de esqueleto</title> <para >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 <filename >kdesdk</filename > instalado. Corra o comando <literal >kapptemplate</literal > 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 <filename class="directory" >2k</filename >. Vá para essa subpasta e remova todos os ficheiros que lá estejam. A partir de agora, temos o esqueleto que pretendemos. </para> <para >O próximo passo é a criação de um ficheiro <filename >.desktop</filename > 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 <link linkend="basic-requirements" >secção anterior</link >, crie um ficheiro chamado <filename >ksplash2k.desktop</filename > nessa pasta. Deverá conter as seguintes linhas: </para> <programlisting ><literal> [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 </literal > </programlisting> <para >Os campos <literal >Encoding</literal >, <literal >Type</literal >, <literal >Comment</literal > e <literal >ServiceTypes</literal > são os mesmos para todos os 'plugins'. O nome do 'plugin' e da biblioteca seguem as convenções indicadas acima. O campo <literal >X-KSplash-Default</literal > 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 <constant >true</constant >. </para> </sect1> <sect1 id="headerfile"> <title >Declaração da classe do 'plugin'</title> <para >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.</para> <orderedlist> <listitem ><para >As classes do 'plugin' deverão herdar da classe <constant >ThemeEngine</constant >.</para ></listitem> <listitem ><para >As classes do 'plugin' deverão ter um nome de acordo com a regra: <classname >Theme+NomePlugin</classname >.</para ></listitem> <listitem ><para >As classes do 'plugin' deverão oferecer uma função <literal >static</literal > chamada <function >names</function > que devolve uma lista com os nomes pela qual poderá ser invocada.</para ></listitem> <listitem ><para >Se o 'plugin' puder ser configurado no módulo do centro de controlo, deverá oferecer uma classe baseada na <literal >ThemeEngineConfig</literal > para a configuração.</para ></listitem> <listitem ><para >As classes do 'plugin' deverão reimplementar pelo menos uma das funções virtuais <function >slotSetText</function >, <function >slotSetPixmap</function >, <function >slotUpdateProgress</function > e <function >slotUpdateSteps</function > para serem úteis.</para ></listitem> <listitem ><para >O construtor deverá ter a forma <literal >ThemeEngine( QWidget *mae, const char *nome, const QStringList &argumentos )</literal > para que possa ser usada com a <classname >KGenericFactory</classname >.</para ></listitem> </orderedlist> <para >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.</para> </sect1> <sect1 id="headercode"> <title >Código do ficheiro de inclusão</title> <para >Dadas as restrições, nós veremos agora que o ficheiro de inclusão <filename >theme2k.h</filename > ficará como o seguinte:</para> <example> <title >Listagem do <filename >theme2k.h</filename ></title> <programlisting >#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 </programlisting> </example> <para >Vamos então analisar a listagem em cima. A classe <classname >Theme2k</classname > satisfaz as convenções de nomes e herda da classe <classname >ThemeEngine</classname >. Ela contém um método <methodname >Theme2k::names()</methodname >, e tem um construtor que recebe os parâmetros obrigatórios: <function >Theme2k( QWidget *, const char *, const QStringList& );</function > e também contém um método simples <methodname >Theme2k::slotSetText()</methodname >. De momento, não se preocupe com a classe <classname >RotWidget</classname >. É 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, implemente de novo a função <function >slotSetPixmap</function >. Existem funções semelhantes para definir o intervalo da barra de progresso (<function >slotUpdateSteps</function >) e para incrementar (<function >slotUpdateProgress</function >) o passo actual. </para> </sect1> <sect1 id="Implementation"> <title >Implementação do 'plugin'</title> <para >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:</para> <example> <title >Requisito da biblioteca</title> <programlisting >K_EXPORT_COMPONENT_FACTORY( ksplash2k, KGenericFactory<Theme2k> ); </programlisting> </example> <para >A macro <constant >K_EXPORT_COMPONENT_FACTORY</constant > é declarada no ficheiro <filename >kgenericfactory.h</filename >. Sigamos para o construtor! Dado que este é um 'plugin' muito simples, assim o é também o construtor.</para> <example> <title >Construtor do 'plugin'</title> <programlisting >Theme2k::Theme2k( QWidget *mae, const char *nome, const QStringList &argumentos ) :ThemeEngine( mae, nome, argumentos ) { readSettings(); initUi(); } </programlisting> </example> <para >O método <function >readSettings()</function > 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?)</para> <example> <title >Obter a configuração do tema</title> <programlisting >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 Logótipo", QString::null ); } </programlisting> </example> <para >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 <function >initUI()</function > não é muito interessante, dado que apenas cria a interface gráfica. Veja por favor o apêndice para mais detalhes. </para> </sect1> <sect1 id="compilingfile"> <title >Compilar o 'plugin'</title> <para >Dado que decidimos usar a plataforma do &kde; para compilar o 'plugin', nós iremos precisar de criar um <filename >Makefile.am</filename >. Deverá ficar algo do género:</para> <example> <title >Listagem do <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 >Para mais informações sobre como criar os ficheiros <filename >Makefile.am</filename > para o &kde;, por favor veja o <ulink url="http://developer.kde.org/documentation/other/makefile_am_howto.html" >'site' Web</ulink > 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 <filename >Theme.rc</filename > de exemplo e que ilustre a utilização das várias opções.</para> </sect1> </chapter> <chapter id="faq"> <title >Perguntas e Respostas</title> &reporting.bugs; &updating.documentation; <qandaset id="faqlist"> <qandaentry> <question> <para >Não consigo encontrar nenhuns temas que funcionem no &ksplash;. Porquê?</para> </question> <answer> <para >Você provavelmente não tem os 'plugins' correctos para o tema. Os 'plugins' estão no pacote <literal >kde-artwork</literal >. Obtenha-os e instale-os, e tente de novo mais tarde.</para> </answer> </qandaentry> <qandaentry> <question> <para >O que é o ficheiro <filename >Theme.rc</filename > e como é que crio um?</para> </question> <answer> <para >O <filename >Theme.rc</filename > é o ficheiro onde você poderá indicar a configuração de um tema. Para mais informações, dê uma vista de olhos em <link linkend="themes" >Como criar temas para o &ksplash;</link >. </para> </answer> </qandaentry> </qandaset> </chapter> <chapter id="credits"> <title >Créditos e Licença</title> <para >&ksplash;</para> <para >Programa Copyright © 2003 &Ravikiran.Rajagopal; &Ravikiran.Rajagopal.mail;</para> <itemizedlist> <title >Contribuições</title> <listitem ><para >&Brian.C.Ledbetter; &Brian.C.Ledbetter.mail;</para> </listitem> </itemizedlist> <para >Documentação Copyright © 2003 &Teemu.Rytilahti; &Teemu.Rytilahti.mail;</para> &underFDL; &underGPL; </chapter> <appendix id="installation"> <title >Instalação</title> <sect1 id="requirements"> <title >Requisitos</title> <para >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.</para> </sect1> <sect1 id="compilation"> <title >Compilação e Instalação</title> &install.compile.documentation; </sect1> </appendix> <appendix id="srccode"> <title >Código-fonte</title> <sect1 id="theme2kcpp"> <title >Listagem não traduzida do <filename >theme2k.cpp</filename ></title> <programlisting >#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 ); } </programlisting> </sect1> <sect1 id="rotwidgeth"> <title >Listagem não traduzida do <filename >rotwidget.h</filename ></title> <programlisting >#ifndef __ROTWIDGET_H__ #define __ROTWIDGET_H__ #include <qlabel.h> #include <qtimer.h> #include <qwidget.h> #include <kdialogbase.h> #include <kpixmap.h> /** * @short Mostrar um item de gradiente em rotação. */ 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_cor1, m_cor2; int m_passo, m_velocidade; QTimer *m_relogioPasso; QList<QPixmap> m_imagemPasso; }; #endif </programlisting> </sect1> <sect1 id="rotwidgetcpp"> <title >Listagem não traduzida <filename >rotwidget.cpp</filename ></title> <programlisting >#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 *mae, const QColor& c1, const QColor& c2, int vel ) :QWidget(mae), m_cor1(c1), m_cor2(c2), m_passo(0), m_velocidade(vel) { if( (m_velocidade <= 0) || (m_velocidade > 20) ) m_velocidade = 1; setFixedHeight( 6 ); for( int i = 0; i <= width(); i++ ) preparePixmap( i ); m_passoRelogio = new QTimer( this ); connect(m_passoRelogior, SIGNAL(timeout()), this, SLOT(stepEvent())); m_passoRelogio->start( 50 ); } RotWidget::~RotWidget() { } void RotWidget::stepEvent() { // This is inefficient as we create too many pixmaps, optimize later. m_passo += m_velocidade; if( m_passo > width() ) m_passo = 0; repaint( true ); } // Todo: Optimize drawing. void RotWidget::paintEvent( QPaintEvent *pe ) { QPainter p; p.begin( this ); QRect r = pe->rect(); if( m_imagemPasso.at( m_passo ) ) bitBlt( this, r.x(), r.y(), m_imagemPasso.at( m_passo ), r.x(), r.y(), r.width(), r.height() ); else p.fillRect( rect(), Qt::black ); p.end(); } void RotWidget::resizeEvent( QResizeEvent *re ) { m_imagemPasso.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 ) { QPixmap tmp; tmp.resize( size().width() / 2, size().height() ); QPixmap tmp2(tmp); KPixmapEffect::gradient( tmp, m_color1, m_color2, KPixmapEffect::HorizontalGradient ); KPixmapEffect::gradient( tmp2, m_color2, m_color1, KPixmapEffect::HorizontalGradient ); QPixmap *px = new QPixmap( size() ); QPainter p; p.begin( px ); p.drawPixmap( 0, 0, tmp ); p.drawPixmap( size().width()/2, 0, tmp2 ); p.end(); m_imagemPasso.append( px ); } else if( m_imagemPasso.at( step-1 ) ) { QPixmap *anterior = m_imagemPasso.at( step-1 ); QPixmap prox; prox.resize( size() ); // convert // anterior = "[------------]" // to // prox = "------------][" bitBlt( &prox, 0, 0, anterior, 1, 0, anterior->width()-1, anterior->height() ); bitBlt( &prox, width()-1, 0, anterior, 0, 0, 1, anterior->height() ); QPixmap *n = new QPixmap( prox ); m_imagemPasso.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 -->