<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook V3.1-Based Variant V1.0//EN" [
 <!ENTITY kdevelop "<application>kdevelop</application>">
 <!ENTITY tex "<application>TeX</application>">
 <!ENTITY latex "<application>LaTeX</application>">
 <!ENTITY etago "&lt;/">
 <!ENTITY % addindex "IGNORE">
 <![ %addindex; [ <!ENTITY docindex SYSTEM "docindex.docbook"> ]]>
]>
<book lang="pt">
<bookinfo>
<title>O Manual de Programação do KDevelop
</title>
<subtitle>O Guia do Utilizador para Desenvolvimento de Aplicações C++ para o Ambiente de Trabalho K (KDE) com o ambiente de trabalho KDevelop, Versão
2.1</subtitle>
<authorgroup>
<author>
<surname>Ralf Nolden </surname>
<affiliation>
	  <orgname>A Equipa do KDevelop</orgname>
<address><email><ulink url="mailto:Ralf.Nolden@post.rwth-aachen.de">&lt;Ralf.Nolden@post.rwth-aachen.de&gt;</ulink></email></address>
</affiliation>
</author>
</authorgroup>
<date>Versão 2.1 , 7 de Julho, 1999</date>
<releaseinfo><!-- information about this particular version --></releaseinfo>
<abstract>
<para>Este manual em si é parte do Ambiente de Desenvolvimento Integrado (IDE) KDevelop e é assim também licenciado sob a Licença Geral Pública
GNU; veja <link linkend="Copyright">Copyright</link> para mais informação.</para>
<para>KDE</para><!-- Merge this with the previous paragraph; it comes from <META NAME="description" CONTENT="..."> --></abstract>

</bookinfo>

<chapter id="introduo">
<title>Introdução</title>

<para>Como os Sistemas Unix estão a tornar-se mais e mais populares mesmo para iniciados no trabalho com computadores, devido às suas vantagens no
que toca a estabilidade e functionalidade, muitos estão de certo modo desapontados, porque as aplicações não têm um aspecto consistente e cada uma se
comporta de forma diferente das restantes. Com o KDE, os programadores têm uma forma quase perfeita de criar aplicações de primeira classe para ambientes de trabalho Unix
para obterem uma comunidade de utilizadores mais vasta apenas pela qualidade que as suas aplicações oferecem. Assim, o KDE torna-se mais e mais
popular como uma base para o desenvolvimento de aplicações, e os programadores desejam retirar vantagens das possibilidades que o sistema tem para oferecer.</para>

<sect1 id="o-que-j-deve-saber-neste-momento">
<title>O que já deve saber neste momento</title>

<para>Para obter a melhor utilização deste manual de programação, nós assumimos que você já conhece a linguagem de programação C++; se não, deve
familiarizar-se com ela primeiro. Informação sobre C++ está disponível através de várias fontes quer em formato impresso na sua
livraria local ou através de tutores encontrados na Internet. Conhecimentos sobre o desenho de Interfaces Gráficos de Utilizador não são requeridos, já
que este manual tenta cobrir o desenho de aplicações para programas KDE, o que também inclui uma introdução ao conjunto de ferramentas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> bem como
às bibliotecas KDE <indexterm remap="idx"><primary>bibliotecas KDE</primary></indexterm> e ao desenho de Interfaces de Utilizador. Também, já se deve ter familiarizado com o KDevelop tendo lido
<ulink url="index.html">O Manual do Utilizador do KDevelop</ulink>, que contém uma revisão descritiva das funcionalidades disponibilizadas pelo
ambiente de desenvolvimento (IDE).</para>
</sect1>

<sect1 id="sobre-este-manual">
<title>Sobre este Manual</title>

<para>Este manual foi escrito para dar aos programadores uma introdução ao desenvolvimento de aplicações para o KDE utilizando o Ambiente de Desenvolvimento
Integrado KDevelop.</para>

<para>Os capítulos seguintes dão-lhe assim uma introdução sobre como criar projectos, explica o código fonte já gerado e mostra
como ampliar o código fornecido em vários aspectos tais como as barras de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm>, barras de menu e áreas de vista.</para>

<para>Depois é discutido em detalhe o editor de diálogos, explicando como os widgets são criados e cobre a definição de propriedades dos widget's em detalhe
para todos os widgets disponibilizados.</para>

<para>Finalmente, você irá aprender sobre vários tópicos que irão completar o seu conhecimento no que respeita ao desenho de projectos e o ajuda a resolver
problemas adicionais para além de programar tais como adicionar documentação API <indexterm remap="idx"><primary>API</primary></indexterm> e extender os manuais electrónicos.</para>

<para><emphasis remap="bf">No capítulo seguinte</emphasis></para>

<para>iremos observar as bibliotecas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e KDE <indexterm remap="idx"><primary>KDE</primary></indexterm>, mostrando conceitos basicos e porque são as coisas do modo que são.
Também, iremos discutir como criar as aplicações de tutor disponibilizadas com o conjunto de ferramentas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> utilizando o KDevelop, para que os iniciados possam ver
já os primeiros resultados com alguns passos, e assim aprender como utilizar algumas das melhores funcionalidades do KDevelop.</para>

<para><emphasis remap="bf">Nos capítulos seguintes</emphasis> você irá aprender:
<itemizedlist>
<listitem>
<para>como criar uma aplicação com o KAppWizard,</para>
</listitem>
<listitem>
<para>o que o esqueleto do projecto já disponibiliza,</para>
</listitem>
<listitem>
<para>o que o código já criado significa,</para>
</listitem>
<listitem>
<para>como criar as suas próprias vistas,</para>
</listitem>
<listitem>
<para>como aumentar as funcionalidades da sua aplicação através de diálogos e barras de menu e ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm></para>
</listitem>
<listitem>
<para>como tornar a sua aplicação amiga do utilizador disponibilizando funções de ajuda e</para>
</listitem>
<listitem>
<para>como escrever documentação electrónica em SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="informao-adicional">
<title>Informação Adicional</title>

<para>Informação adicional sobre programação Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>/KDE é disponibilizada por várias fontes:</para>

<para><itemizedlist>
<listitem>
<para><emphasis>Programar com a Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></emphasis> por Matthias Kalle Dalheimer, publicado por O'Reilly (veja <ulink url="http://www.oreilly.com">\|\|</ulink>, cobrindo
quase todos os aspectos do conjunto de ferramentas GUI Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e contendo também exemplos.</para>
</listitem>
<listitem>
<para><ulink url="index.html">O Manual do Utilizador do KDevelop</ulink>, disponibilizado com o IDE KDevelop,</para>
</listitem>
<listitem>
<para><emphasis>Referência Electrónica</emphasis> para a biblioteca Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, disponibilizada com a sua cópia do conjunto de ferramentas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> em
HTML e disponível em PostScript em <ulink url="http://www.troll.no">\|\|</ulink></para>
</listitem>
<listitem>
<para>Na Internet, veja
<itemizedlist>
<listitem>
<para>a página da Troll Tech em <ulink url="http://www.troll.no">\|\|</ulink>,</para>
</listitem>
<listitem>
<para>a página do KDE em <ulink url="http://www.kde.org">\|\|</ulink>,</para>
</listitem>
<listitem>
<para>a página do programador KDE em <ulink url="http://developer.kde.org">\|\|</ulink></para>
</listitem>
<listitem>
<para>a página do KDevelop em <ulink url="http://www.kdevelop.org">\|\|</ulink></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>

<para>Adicionalmente, deverá procurar ajuda subscrevendo-se nas várias listas de discussão por e-mail, cujos endereços estão disponíveis nas páginas
mencionadas, e nos grupos de notícias da Usenet dedicados aos utilizadores do KDE e Sistemas Unix bem como sobre a linguagem de programação C e C++.</para>

<para>Para obter ajuda sobre o IDE KDevelop, deverá enviar pedidos para a nossa lista de discussão em <ulink url="mailto:kdevelop@fara3.cs.uni-potsdam.de">kdevelop@fara3.cs.uni-potsdam.de</ulink>. Lembre-se que a equipa do KDevelop é dedicada a
oferecer-lhe os meios para lhe permitir programar aplicações e assim não tem como objectivo ser uma equipa de suporte técnico em casos em que as
aplicações que está a desenvolver não funcionam devido a erros de implementação ou más configurações do seu sistema operativo. Posto isto, nós pedimos
a todos os utilizadores para aproveitarem a lista de discussão em todos os casos em que encontrarem problemas com a utilização do IDE em si, bem como
para reportar erros (bugs) e sugestões para melhorar a funcionalidade do ambiente de desenvolvimento.</para>
</sect1>
</chapter>

<chapter id="as-bibliotecas-kde-e-qt-qt">
<title>As Bibliotecas KDE e Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></title>

<para>A empresa Norueguesa Troll Tech (<ulink url="http://www.troll.no">\|\|</ulink>) disponibiliza um chamado conjunto de ferramentas de GUI, chamado Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. Assim, GUI significa
"<emphasis remap="bf">G</emphasis>raphical <emphasis remap="bf">U</emphasis>ser <emphasis remap="bf">I</emphasis>nterface - Interface Gráfico de Utilizador", e assim, as aplicações baseadas na Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> representam-se com botões, janelas etc,
permitindo inserção de dados do utilizador visualizando as funções que a aplicação disponibiliza. Este conjunto de ferramentas é necessário para o desenvolvimento de
aplicações gráficas que corram no Interface X-Window em Sistemas Unix, porque o X não contém um interface de utilizador pré-definido em si.
Apesar de outros conjuntos de ferramentas estarem também disponíveis para criar Interfaces de Utilizador, a Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> oferece algumas vantagens técnicas que tornam o desenho de aplicações
muito fácil. Adicionalmente, o conjunto de ferramentas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> também está disponível para o sistema Microsoft Windows, o que permite aos programadores disponibilizarem
as suas aplicações para ambas as plataformas.</para>

<para>A Equipa KDE (<ulink url="http://www.kde.org">\|\|</ulink>) juntou-se com o objectivo de tornar a utilização de Sistemas Unix
mais amigável, e decidiu utilizar o conjunto de ferramentas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> para o desenvolvimento de um gestor de janelas no X-Window, mais uma variedade de ferramentas
incluídas com os pacotes KDE. O Ambiente de Trabalho K  contém assim o gestor de janelas <emphasis>kwm</emphasis>, o gestor de ficheiros <emphasis>kfm</emphasis> e
o painel de controlo <emphasis>kpanel</emphasis> como sendo os componentes principais mais uma variedade de utilitários e aplicações de primeira classe. Depois do KDE ter saido, muitos
dos programadores voltaram os seus olhos no sentido deste novo ambiente e do que tem para lhes oferecer. As bibliotecas KDE <indexterm remap="idx"><primary>bibliotecas KDE</primary></indexterm> estão a disponibilizar
métodos e classes fundamentais que fazem com que todas as aplicações desenhadas com elas tenham um aspecto similar e consistente, e o utilizador tem a grande vantagem
de apenas ter de se acostumar com a utilização específica de uma aplicação, não com o manuseamento de diálogos ou botões. Também, os programas KDE integram-se
no ambiente de trabalho e são capazes de interagir com o gestor de ficheiros através do arrastar e largar <indexterm remap="idx"><primary>arrastar e largar</primary></indexterm> (drag and drop), oferecer gestão de sessões e muito mais,
se todas as funcionalidades oferecidas pelas bibliotecas KDE <indexterm remap="idx"><primary>bibliotecas KDE</primary></indexterm> forem utilizadas.</para>

<para>Ambos, o conjunto de ferramentas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e as bibliotecas KDE <indexterm remap="idx"><primary>bibliotecas KDE</primary></indexterm>, são implementadas na linguagem de programação C++; assim aplicações que façam uso
destas bibliotecas são também maioritariamente escritas em C++. No capítulo seguinte, faremos uma breve viagem através das bibliotecas para ver o que
já é disponibilizado e como as aplicações Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e KDE <indexterm remap="idx"><primary>KDE</primary></indexterm> são criadas em geral.</para>

<sect1 id="o-conjunto-de-ferramentas-gui-qt-qt">
<title>O Conjunto de Ferramentas GUI Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></title>

<para>Como foi dito, a biblioteca Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> é um conjunto de ferramentas que oferece elementos gráficos que são utilizados para criar GUI's de aplicações e são necessárias
para programação X-Window. Adicionalmente, este conjunto de ferramentas oferece:</para>

<para><itemizedlist>
<listitem>
<para>Um conjunto completo de classes e métodos prontos a utilizar para questões de programação não-gráfica,</para>
</listitem>
<listitem>
<para>Uma boa solução no sentido da interacção do utilizador através de métodos virtuais e mecanismos sinal/espaço,</para>
</listitem>
<listitem>
<para>Um conjunto de elementos GUI pré-definidos, chamados "widgets", que podem ser facilmente utilizados para criar elementos visíveis</para>
</listitem>
<listitem>
<para>Diálogos adicionais completamente pré-definidos que são muitas vezes utilizados em aplicaçãis tais como diálogos de progresso e de ficheiros.</para>
</listitem>
</itemizedlist>
</para>

<para>Posto isto conhecer as classes Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> é essêncial, mesmo se você apenas deseja programar aplicações KDE. Para ter uma ideia do conceito
basico sobre como as aplicações GUI são construidas e compiladas, iremos primeiro observar um programa exemplo apenas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>; depois extende-lo-emos
para um programa KDE.</para>

<sect2 id="a-primeira-aplicao-qt-qt">
<title>A Primeira Aplicação Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></title>

<para>Como normalmente, programas em C++ têm de conter a função <literal remap="tt">main()</literal>, que é o ponto de partida para a execução da aplicação. Como queremos que
seja graficamente visível em janelas e ofereça interacção do utilizador, temos primeiro que saber, como se podem mostrar a si próprias ao
utilizador. Por exemplo, iremos observar o primeiro programa de tutor incluido com a Documentação Electrónica de Referência Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e explicar os passos de
execução básicos; também como e porquê as janelas da aplicação aparecem:</para>

<para><screen>#include &lt;qapplication.h&gt;
#include &lt;qpushbutton.h&gt;

int main( int argc, char **argv )
{
QApplication a( argc, argv );

QPushButton hello( "Hello world!" );
hello.resize( 100, 30 );

a.setMainWidget( &&amp;;hello );
hello.show();
return a.exec();
}
</screen>
</para>

<para>Esta aplicação meramente pinta uma janela contendo um botão com "Hello world" ("Olá Mundo") como texto. Como todas as aplicações baseadas na Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, primeiro
tem de declarar uma instância da classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, representada por <literal remap="tt">a</literal>.</para>

<para>Depois, o programa cria uma instância da classe <literal remap="tt">QPushButton</literal> chamada <literal remap="tt">hello</literal>, isto será o botão. O constructor do
<literal remap="tt">hello</literal> obtém uma string (conjunto de caracteres) como parâmetro, que é o conteudo do widget visível como sendo o texto do botão.</para>

<para>Depois o método <literal remap="tt">resize()</literal> é chamado sobre o botão <literal remap="tt">hello</literal>. Isto muda o tamanho de defeito que um widget (que é neste caso
o QPushButton) tem quando criado para o comprimento de 100 pixels e a altura de 30 pixels. Finalmente, o método <literal remap="tt">setMainWidget()</literal>
é chamado para <literal remap="tt">a</literal> e o método <literal remap="tt">show()</literal> para <literal remap="tt">hello</literal>. A <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> é finalmente executada por <literal remap="tt">a.exec()</literal>,
entra no ciclo de acontecimento principal e aguarda até que tenha de devolver um valor inteiro para a camada do Sistema Operativo assinalando que
a aplicação terminou.</para>
</sect2>

<sect2 id="a-documentao-de-referncia-para-a-qt-qt">
<title>A Documentação de Referência para a Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></title>

<para>Agora, vamos observar rapidamente a documentação de referência da biblioteca Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. Para fazer isto, inicie o KDevelop e seleccione "biblioteca Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>" a partir
do menu "Ajuda" na barra de menu. O navegador de documentação abre e mostra-lhe a página inicial da referência Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. Isto irá ser o seu
primeiro local para obter informação sobre a Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, suas classes e as funções disponíveis que oferece. Também, o programa acima mostrado é o primeiro
que é incluído na secção dos tutores. Para obter as classes que desejamos observar, <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> e <literal remap="tt">QPushButton</literal>,
seleccione "Lista Alfabética de Classes" e procure os nomes correspondentes. Siga qualquer uma delas para observar a documentação de classes <indexterm remap="idx"><primary>documentação de classes</primary></indexterm>.</para>

<para>Para a <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, verá o construtor e todos os outros métodos que esta classe disponibiliza. Se seguir uma hiper-ligação, irá obter mais
informação sobre a utilização e significado dos métodos, o que é muito útil quando você às vezes não consegue detectar a utilização correcta
ou deseja ver um exemplo. Isto também vale para a documentação da biblioteca KDE, que utiliza um tipo de documentação similar; assim isto é
praticamente tudo o que tem de saber sobre a utilização da referência de classes com o navegador de documentação.</para>
</sect2>

<sect2 id="interpretao-do-exemplo">
<title>Interpretação do Exemplo</title>

<para>Começando com a <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>, você irá ver todos os métodos utilizados no nosso primeiro exemplo:</para>

<para><itemizedlist>
<listitem>
<para>o construtor <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication()</literal>,</para>
</listitem>
<listitem>
<para>o método <literal remap="tt">setMainWidget()</literal> e</para>
</listitem>
<listitem>
<para>o método <literal remap="tt">exec()</literal>.</para>
</listitem>
</itemizedlist>
</para>

<para>A interpretação sobre porque utilizamos estes métodos é muito simples:</para>

<para><orderedlist><listitem>
<para>primeiro criamos uma instância da classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> com o construtor, para que possamos utilizar os elementos GUI disponibilizados pela
Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>,</para>
</listitem>
<listitem>
<para>criamos um widget que será o contentor da janela do nosso programa,</para>
</listitem>
<listitem>
<para>definimos o widget como sendo o widget principal para <literal remap="tt">a</literal>,</para>
</listitem>
<listitem>
<para>executamos a instância <literal remap="tt">a</literal> da <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>.</para>
</listitem>
</orderedlist>
</para>

<para>O segundo objecto do nosso programa é o botão, como uma instância da classe <literal remap="tt">QPushButton</literal>. Dos dois construtores dados para
criar uma instância, nós utilizamos o segundo: este aceita um texto, que é a etiqueta do conteudo do botão; aqui, a etiqueta é o texto "Hello
world!". Depois chamamos o método <literal remap="tt">resize()</literal> para modificar o tamanho do botão de acordo com o seu conteudo- o botão tem de ser maior
para tornar o texto completamente visível.</para>

<para>Mas e então o método <literal remap="tt">show()</literal>? Agora, você vê que tal como a maior parte dos outros widgets, <literal remap="tt">QPushButton</literal> é baseado numa herança única-
aqui, a documentação diz, <emphasis>Herda</emphasis> <literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal>. Siga a hiper-ligação para a classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal>. Isto irá mostrar-lhe imensos outros
métodos que são herdados pelo QPushButton, que iremos utilizar mais tarde para explicar o mecanismo sinal/espaço. De qualquer modo, o método <literal remap="tt">show()</literal>
não está listado, pelo que, tem de ser um método que é disponibilizado também por herança. A classe que o <literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal> herda, é
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>. Basta seguir de novo a hiper-ligação, e irá ver imensos métodos que a classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> disponibiliza; incluindo o
método <literal remap="tt">show()</literal>. Agora nós compreendemos o que foi feito no exemplo com o botão:</para>

<para><orderedlist><listitem>
<para>criar uma instância do <literal remap="tt">QPushButton</literal>, utilizar uma segunda construção para definir o texto do botão,</para>
</listitem>
<listitem>
<para>redimensionar o widget para o seu conteudo,</para>
</listitem>
<listitem>
<para>definir o widget como sendo o widget principal da instância <literal remap="tt">a</literal> da <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>,</para>
</listitem>
<listitem>
<para>dizer ao widget para se mostrar no ecrã chamando <literal remap="tt">show()</literal>, um método herdado de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>.</para>
</listitem>
</orderedlist>
</para>

<para>Após chamar o método <literal remap="tt">exec()</literal>, a aplicação é visível para o utilizador, mostrando uma janela com um botão apresentando "Hello world!".
Agora, programas GUI comportam-se de um modo ligeiramenta diferente das aplicações processuais. A coisa principal aqui é que a aplicação entra num
chamado "ciclo de evento principal". Isto significa que o programa tem de aguardar por acções do utilizador e depois reagir a estas, também que para uma aplicação
Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, o programa tem de estar no ciclo de evento principal para iniciar o manuseamento de eventos. A secção seguinte diz-lhe de forma breve o que isto
significa para o utilizador e o que a Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> oferece para processar eventos do utilizador.</para>

<para>(Para utilizadores já avançados: O botão não tem pai declarado no construtor, por isso é por si só um widget de nível superior e corre num
ciclo de evento local que não tem de aguardar pelo ciclo de evento principal, veja a documentação de classe <indexterm remap="idx"><primary>documentação de classe</primary></indexterm> <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> e <ulink url="kde_libref.html">O Guia de Referência da Biblioteca KDE</ulink>)</para>

<para><emphasis remap="bf">Sumário:</emphasis></para>

<para>Uma aplicação Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> tem sempre de ter uma instância da classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>. Isto permite que possamos criar janelas que são a
representação gráfica de programas para o utilizador final e permitem interacção. O conteudo da janela em si é chamado o "Widget Principal", significando
que todos os elementos gráficos são baseados na classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> e podem ser qualquer tipo de widget que sirva as necessidades da aplicação para
comunicar com o utilizador. Assim, todos os elementos de utilizador têm de herdar de uma forma ou de outra <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> para serem visíveis.</para>
</sect2>

<sect2 id="user-interaction">
<title>Interacção do Utilizador</title>

<para>Após ler as secções anteriores, você já deverá saber:
<itemizedlist>
<listitem>
<para>o que a biblioteca Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> disponibiliza em termos de aplicações GUI,</para>
</listitem>
<listitem>
<para>como é que um programa que utilize a Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> é criado e</para>
</listitem>
<listitem>
<para>onde e como obter informação sobre classes que deseja utilizar com o navegador de documentação</para>
</listitem>
</itemizedlist>
</para>

<para>Agora iremos começar a dar "vida" à aplicação através do processamento de eventos do utilizador. Geralmente, o utilizador tem duas formas de interagir com o programa:
o rato e o teclado. Para ambas as formas, um interface gráfico de utilizador (GUI) tem de disponibilizar métodos que detectem acções e métodos que façam
alguma coisa como reacção a estas acções.</para>

<para>O sistema de Janelas assim envia todos os eventos de interacção para a respectiva aplicação. A <indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication envia-os então para a janela
activa como um <literal remap="tt"><indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent</literal> e os prórpios widgets têm de decidir o que fazer com os eventos. Um widget recebe o evento e processa
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>::event(<indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent*)/, que então decide que evento foi executado e como reagir; event() é assim quem faz o manuseamento
principal de eventos. Depois, a função <literal remap="tt">event()</literal> passa o evento para os chamados filtros de eventos, que determinam que aconteceu e o que fazer com
o evento. Se nenhum filtro encontra um responsável pelo evento, os manuseadores especializados de eventos são chamados. Assim podemos decidir entre:</para>

<para><emphasis remap="bf">a) Eventos de Teclado -- teclas TAB e Shift-TAB:</emphasis></para>

<para>muda o focus de entrada do teclado do widget actual para o widget seguinte na ordem de focus. O focus pode ser atribuido aos widgets
chamando <literal remap="tt">setFocusPolicy<indexterm remap="ncdx"><primary><literal>setFocusPolicy()</literal></primary></indexterm>()</literal> e processar os seguintes indicadores de eventos:</para>

<para><itemizedlist>
<listitem>
<para><literal remap="tt">virtual void focusInEvent<indexterm remap="ncdx"><primary><literal>focusInEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QFocusEvent</literal></primary></indexterm>QFocusEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void focusOutEvent<indexterm remap="ncdx"><primary><literal>focusOutEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QFocusEvent</literal></primary></indexterm>QFocusEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">b) todos os restantes eventos de teclado:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void keyPressEvent<indexterm remap="ncdx"><primary><literal>keyPressEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void keyReleaseEvent<indexterm remap="ncdx"><primary><literal>keyReleaseEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">c) movimentos do rato:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void mouseMoveEvent ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void enterEvent ( <indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void leaveEvent ( <indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">d) acções de botões do rato:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void mousePressEvent ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void mouseReleaseEvent ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void mouseDoubleClickEvent ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">e) eventos da janela que contém o widget:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void moveEvent ( <indexterm remap="cdx"><primary><literal>QMoveEvent</literal></primary></indexterm>QMoveEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void resizeEvent ( <indexterm remap="cdx"><primary><literal>QResizeEvent</literal></primary></indexterm>QResizeEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void closeEvent ( <indexterm remap="cdx"><primary><literal>QCloseEvent</literal></primary></indexterm>QCloseEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para>Note que todas as funções de eventos são virtuais e protegidas; assim você pode re-implementar os eventos que necessitar nos seus próprios
widgets e especificar como o seu widget tem de reagir. O <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> também contém alguns outros métodos virtuais que podem ser úteis nos seus
programas; de qualquer modo, é suficiente saber sobre o <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> de uma forma geral.</para>
</sect2>

<sect2 id="interaco-de-objectos-atravs-de-sinais-e-espa">
<title>Interacção de Objectos através de Sinais e Espaços</title>

<para>Agora estamos a chegar às vantagens mais óbvias do conjunto de ferramentas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>: o mecanismo sinal/espaço. Isto oferece uma solução bastante "à-mão"
e útil para interacção de objectos, que é normalmente resolvido através de funções de <literal remap="tt">callback</literal> para conjuntos de ferramentas X-Window. Como esta comunicação
requer uma programação estrita e às vezes torna a criação de interfaces gráficos muito difícil (como referido pela documentação Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e
explicado em <emphasis>Programação com Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></emphasis> por K.Dalheimer), a Troll Tech inventou um novo sistema onde objectos podem emitir sinais que podem ser
conectados a métodos declarados como espaços. Para a parte C++ do programador, ele apenas tem de saber algumas coisas sobre este mecanismo:</para>

<para><orderedlist><listitem>
<para>a declaração de classe da classe que utiliza sinais/espaços tem de conter a macro <literal remap="tt">Q&&lowbar;;OBJECT</literal> no início (sem o
ponto e vírgula); e tem de derivar da classe <literal remap="tt">QObject</literal>,</para>
</listitem>
<listitem>
<para>um sinal pode ser emitido por uma palavra-chave <literal remap="tt">emit</literal>, por ex. <literal remap="tt">emit signal(parâmetros);</literal> a partir de qualquer função membra
de uma classe que permita sinais/espaços,</para>
</listitem>
<listitem>
<para>todos os sinais utilizados pelas classes que não são herdadas têm de ser adicionados à declaração da classe através de uma secção <literal remap="tt">signals:</literal>,</para>
</listitem>
<listitem>
<para>todos os métodos que podem ser conectados com um sinal são declarados em secções com a palavra-chave adicional <literal remap="tt">slot</literal>, por ex.
<literal remap="tt-bf">public slots:</literal> dentro da declaração da classe,</para>
</listitem>
<listitem>
<para>o compilador de meta-objectos <literal remap="tt">moc</literal> tem de correr sobre o ficheiro header para expandir as macros e produzir a implementação (que
não é necessário saber.). Os ficheiros resultantes do <literal remap="tt">moc</literal> são compilados também pelo compilador C++.</para>
</listitem>
</orderedlist>
</para>

<para>Outra forma de utilizar sinais sem derivar de <literal remap="tt">QObject</literal> é utilizar a classe <literal remap="tt">QSignal</literal>- veja a documentação de referência para
mais informação e exemplos de utilização. Nos exemplos seguintes, nós assumimos que você está a derivar da <literal remap="tt">QObject</literal>.</para>

<para>Desta forma, a sua classe é capaz de enviar sinais para qualquer lado e de disponibilizar espaços a onde se possam conectar sinais. Utilizando os sinais, você não
tem de se preocupar com quem os está a receber- você apenas tem de emitir o sinal e qualquer que seja o espaço que lhe queira conectar poderá reagir à
emissão. Também os espaços podem ser utilizados como métodos normais durante a implementação.</para>

<para>Agora, para conectar um sinal a um espaço, tem de utilizar os métodos <literal remap="tt">connect()</literal> que são disponibilizados através do <literal remap="tt">QObject</literal> ou, onde disponível,
métodos especiais que os objectos disponibilizam para definir a conecção para um certo sinal.</para>

<sect3 id="exemplo-de-utilizao">
<title>Exemplo de Utilização</title>

<para>Para explicar a forma como definir interacção de objectos, iremos agarrar de novo no nosso primeiro exemplo e extende-lo através de uma conecção simples:</para>

<para><screen>#include &lt;qapplication.h&gt;
#include &lt;qpushbutton.h&gt;

int main( int argc, char **argv )
{
QApplication a( argc, argv );

QPushButton hello( "Hello world!" );
hello.resize( 100, 30 );

a.setMainWidget( &&amp;;hello );

connect(&&amp;;hello, SIGNAL( clicked() ), &&amp;;a, SLOT( quit() ));

hello.show();
return a.exec();
}
</screen>
</para>

<para>Como vê, a única adição para dar ao botão mais interacção é utilizar um método <literal remap="tt">connect()</literal>:
<literal remap="tt">connect(&&amp;;hello, SIGNAL( clicked() ), &&amp;;a, SLOT( quit() ));</literal> é tudo o que temos de acrescentar. Qual é o significado agora? A declaração
da classe de <literal remap="tt">QObject</literal> diz sobre o método <literal remap="tt">connect()</literal>:</para>

<para><literal remap="tt">bool connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * member )</literal></para>

<para>Isto significa, você tem de especificar um ponteiro de uma instância de QObject que é o emissor do sinal, significando que pode emitir este sinal como
primeiro parâmetro; depois você tem de especificar o sinal a que se deseja conectar. Os dois últimos parâmetros são o objecto receptor que
disponibiliza um espaço, seguido pela função membro que <emphasis>é</emphasis> na realidade o espaço que será executado aquando da emissão do sinal.</para>

<para>Utilizando sinais e espaços, os objectos do seu programa podem interagir entre eles facilmente sem dependerem explicitamente do tipo
de objecto receptor. Você irá aprender mais sobre a utilização deste mecanismo para utilização produtiva mais tarde neste manual. Mais informação sobre
o mecanismo Sinal/Espaço pode ser encontrado no <ulink url="kde_libref.html">Guia de Referência da Biblioteca KDE</ulink> e na referência electrónica Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>.</para>
</sect3>
</sect2>
</sect1>

<sect1 id="o-que-o-kde-disponibiliza">
<title>O que o KDE disponibiliza</title>

<sect2 id="as-bibliotecas-kde-1.1.x">
<title>As bibliotecas KDE 1.1.x</title>

<para>À altura deste documento e devido ao facto de o KDevelop utilizar KDE 1.1, referimo-nos ao estado das bibliotecas KDE <indexterm remap="idx"><primary>bibliotecas KDE</primary></indexterm> nessa
distribuição. As bibliotecas KDE <indexterm remap="idx"><primary>bibliotecas KDE</primary></indexterm> principaos que irá utilizar para criar as suas próprias aplicações KDE <indexterm remap="idx"><primary>aplicações KDE</primary></indexterm> são:</para>

<para><itemizedlist>
<listitem>
<para>a biblioteca KDE-Core, contendo todas as classes que são elementos não-visíveis e disponibilizam funcionalidades que a sua aplicação pode utilizar.</para>
</listitem>
<listitem>
<para>a biblioteca KDE-UI, contendo elementos de interface com o utilizador tais como barras de menu, de ferramenta <indexterm remap="idx"><primary>ferramenta</primary></indexterm>s e afins,</para>
</listitem>
<listitem>
<para>a biblioteca KFile, contendo diálogos de selecção de ficheiros,</para>
</listitem>
</itemizedlist>
</para>

<para>Adicionalmente, para soluções específicas o KDE oferece as seguintes bibliotecas:</para>

<para><itemizedlist>
<listitem>
<para>a biblioteca KHTMLW, oferecendo um completo widget de interpretação HTML que é utilizado por vários programas como o KDEHelp <indexterm remap="idx"><primary>KDEHelp</primary></indexterm>, KFM, KDevelop,</para>
</listitem>
<listitem>
<para>a biblioteca KFM, permitindo a utilização do gestor de ficheiros do KDE a partir de dentro da sua aplicação.</para>
</listitem>
<listitem>
<para>a biblioteca KAb, o KAddressBook. Disponibiliza acesso a livro de endereços para por ex. aplicações de e-mail</para>
</listitem>
<listitem>
<para>a biblioteca KSpell, oferecendo widgets e funcionalidades para integrar a utilização do Ispell, o corrector ortográfico comum, em aplicações
tais como editores; utilizado na aplicação KEdit.</para>
</listitem>
</itemizedlist>
</para>

<para>De seguida, iremos observar o que é necessário para tornar a nossa primeira aplicação Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> numa KDE.</para>
</sect2>

<sect2 id="aplicao-kde-exemplo">
<title>Aplicação KDE Exemplo</title>

<para>No seguinte código, irá ver que escrever uma aplicação KDE não é muito mais difícil que uma aplicação Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>. Para a utilização das características
do KDE, apenas tem de utilizar algumas outras classes, e está quase tudo feito. Como um exemplo, iremos discutir a versão alterada do exemplo
Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> dado acima:</para>

<para><screen>#include &lt;kapp.h&gt;
#include &lt;qpushbutton.h&gt;

int main( int argc, char **argv )
{
KApplication a( argc, argv );

QPushButton hello( "Hello world!" );
hello.resize( 100, 30 );

a.setTopWidget( &&amp;;hello );

connect(&&amp;;hello, SIGNAL( clicked() ), &&amp;;a, SLOT( quit() ));

hello.show();
return a.exec();
}
</screen>
</para>

<para>Pode ver que primeiro alteramos de <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> para <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>. Além disso, tivemos de modificar o método <literal remap="tt">setMainWidget()</literal>
anteriormente utilizado para <literal remap="tt">setTopWidget</literal>, que a <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> utiliza para definir o widget principal. E é tudo! A sua primeira
aplicação KDE está pronta- apenas tem de dizer ao compilador o caminho dos ficheiros include do KDE e ao linker para ligar a biblioteca KDE-Core com
-lkdecore.</para>

<para>Como você agora saber o que pelo menos a função main() disponibiliza de forma geral e como uma aplicação se torna visível e permite a interacção de utilizadores e
objectos, iremos continuar com o capítulo seguinte, onde a nossa primeira aplicação é feita com o KDevelop- aí poderá também testar tudo o
que foi mencionado anteriormente e verificar os resultados.</para>

<para>O que deverá ter consultado adicionalmente até agora é a documentação de referência da Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, especialmente as classes <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal>,
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> e <literal remap="tt">QObject</literal> e a documentação da biblioteca KDE-Core para a classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>. O manual de <ulink url="kde_libref-3.html">Referência da Biblioteca KDE</ulink> também cobre uma descrição completa sobre a invocação dos construtores
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> e <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> incluindo processamento de argumentos de linha de comandos.</para>
</sect2>
</sect1>
</chapter>

<chapter id="creating-new-applications">
<title>Criar Novas Aplicações</title>

<para>O KAppWizard, ou também denominado Assistente de Aplicações KDE, destina-se a permitir-lhe começar a trabalhar em novos projectos com o KDevelop.
Assim, todos os seus projectos são primeiro criados através do assistente; depois você pode começar a construi-los e extender o código do esqueleto já
disponibilizado. O KAppWizard também permite escolher entre vários tipos de projectos de acordo com os objectivos do seu projecto:</para>

<para><itemizedlist>
<listitem>
<para>Aplicação KDE Normal: inclui código fonte para uma moldura de estrutura completa de uma aplicação KDE standard com suporte para o
modelo Controlador-de-Vista-de-Documento, uma barra de menu, ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm> e estados bem como um conjunto de documentação baseado em SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>, hiper-ligações KDE
e icons de aplicações. Este é o tipo de aplicação normalmente necessária para um novo projecto KDE.</para>
</listitem>
<listitem>
<para>Mini-Aplicação KDE: contém a mesma estrutura geral que a Aplicação KDE Normal mas com a diferença que o
código da aplicação apenas disponibiliza um widget como uma janela.</para>
</listitem>
<listitem>
<para>Aplicação Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Normal: trabalha como a Aplicação KDE Normal através do seu código com a diferença de que o projecto é baseado na biblioteca
Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> apenas e não contém suporte KDE. É destinado a projectos que têm de ser portáveis para plataformas Windows ou que não querem requerer
as bibliotecas KDE <indexterm remap="idx"><primary>bibliotecas KDE</primary></indexterm> por parte do utilizador final.</para>
</listitem>
<listitem>
<para>Aplicação C: É baseada apenas no compilador C e corre numa consola.</para>
</listitem>
<listitem>
<para>Aplicação C++: É baseada apenas no compilador C++ e corre numa consola tal como a aplicação C, pelo que não requer
o X-Window.</para>
</listitem>
<listitem>
<para>Projecto Costumizável: cria um projecto vazio sem qualquer código fonte. Este destina-se a projectos já existentes para serem
convertidos para o KDevelop ou para projectos onde deseja começar de raiz. Lembre-se que tem de tomar conta dos ficheiros makefiles e dos scripts de configuração
sozinho.</para>
</listitem>
</itemizedlist>
</para>

<para>Neste capítulo veremos como o KAppWizard pode ser invocado e o que tem de ser feito para gerar um projecto de aplicação KDE. Isto irá ser
também o passo inicial da nossa cobertura, onde iremos criar a versão inicial do projecto de exemplo. Para todos os outros tipos de projectos os
passos são normalmente os mesmos, apenas que poderá não necessitar de ter certas opções disponíveis.</para>

<sect1 id="invocar-o-kappwizard-e-a-gerao-do-projecto">
<title>Invocar o KAppWizard e a Geração do Projecto</title>

<sect2 id="iniciar-o-kappwizard-e-a-primeira-pgina">
<title>Iniciar o KAppWizard e a Primeira Página</title>

<para>Para começar com a sua primeira aplicação KDE, abra o KDevelop. Depois seleccione "Novo..." a partir do menu "Projecto". O KAppWizard inicia-se, e você
vê uma árvore na primeira página, contendo os tipos de projectos. Quando um tipo é seleccionado, você vê uma antevisão de como irá funcionar após o
processo inicial de construção. Escolha o ramo KDE, tipo Normal. Depois prima o botão "Seguinte" no fundo da primeira página do assistente. Isto
mudará para a página seguinte, onde você tem de definir as opções gerais do projecto.</para>
</sect2>

<sect2 id="a-pgina-de-gerao-de-definies">
<title>A Página de Geração de Definições</title>

<para>Para a nossa aplicação de exemplo, nos escolhemos o nome de projecto <literal remap="tt">KScribble</literal>; pelo que deverá inserir isto no campo "Nome do Projecto". Depois seleccione
o directório onde quer que o projecto seja construido; o defeito é o seu directório principal (home). Pode introduzir o caminho manualmente ou pode também
premir o botão à direita para seleccionar o directório através de um diálogo.</para>

<para>De seguida, tem de introduzir o número da Versão. Para a primeira versão, defina esta como <literal remap="tt">0.1</literal>. É normal numerar novas aplicações que estão
em desenvolvimento para a primeira distribuição abaixo de 1, e como a versão inicial irá apenas conter a estrutura standard, diremos que esta é
a versão 0.1.</para>

<para>Finalmente, adicione o seu nome ao campo "Autor" e o seu endereço de e-mail. Pode deixar todas as outras opções nos seus valores de defeito.</para>

<para>Para lhe dar algumas informações sobre outras opções, pode premir o botão direito do rato sobre as opções, e obterá uma janela de ajuda rápida
que descreve o objectivo da opção.</para>

<para>Estes são:
<itemizedlist>
<listitem>
<para><emphasis remap="bf">gerar código e headers:</emphasis>  gera o código fonte da aplicação</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Ficheiros-Standard-GNU:</emphasis>  adiciona uma cópia da Licença Pública Geral (GPL) GNU ao projecto bem como alguns outros ficheiros standard para informação
do utilizador quando distribuir o pacote.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Documentação do Utilizador:</emphasis> o manual do utilizador em SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>, já preparado para o seu projecto.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Documentação-API <indexterm remap="idx"><primary>API</primary></indexterm>:</emphasis> cria um conjunto de documentação HTML inicial para o <emphasis remap="bf">I</emphasis>nterface de <emphasis remap="bf">P</emphasis>rogramação da <emphasis remap="bf">A</emphasis>plicação (API).</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Ficheiro-lsm:</emphasis> o Mapa de Aplicações Linux, utilizado pelos servidores de distribuição e contém uma breve informação sobre os objectivos do projecto e
requerimentos.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Ficheiro-.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm>: </emphasis> um atalho KDE que irá instalar a sua aplicação na árvore "Aplicações" no Painel de Controlo KDE.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Icon de Programa: </emphasis> um Icon que representa o seu projecto e pode ser utilizado para criar um atalho para o ambiente de trabalho.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Mini-Icon: </emphasis> uma versão-Mini do icon de programa que representa a sua aplicação para além do nome dela no Painel de Controlo KDE e é
mostrado nos diálogos e janela principal da sua aplicação no canto superior esquerdo.</para>
</listitem>
</itemizedlist>
</para>

<para>Agora vamos para a página seguinte premindo o botão "Seguinte" de novo para definir o modelo para os ficheiros header do seu projecto.</para>
</sect2>

<sect2 id="os-modelos-de-header-e-cdigo">
<title>Os Modelos de Header e Código</title>

<para>A página de modelo de header permite-lhe incluir automaticamente um prefácio nos seus ficheiros header, contendo o nome do ficheiro, a data de construção, 
o ano do copyright, também o seu nome e endereço de e-mail. Você não tem de mudar essas partes em maiusculas por si, pois o
KAppWizard faz isto automaticamente e guarda o modelo para este projecto, para que possa ser utilizado de novo mais tarde para criar novos ficheiros.</para>

<para>A segunda parte do modelo de header de defeito contém uma informação de licença. Por defeito, o seu projecto está sob a Licença Pública Geral
GNU, que também é incluida no pacote. Esta licença é utilizada para proteger o seu código fonte contra qualquer pessoa que apenas
copie o seu código para os seus propósitos. A Licença Pública Geral (GPL) oferece-lhe esta licença gratuitamente e assim protege os seus direitos
como autor, e é comum para aplicações de distribuição livre. Para obter mais informação sobre a licença, deverá ler mais tarde o ficheiro
COPYING no directório base do seu novo projecto que é uma cópia da GPL e é já enviada com a sua aplicação.</para>

<para>De qualquer modo, você pode escolher outra licença ou outro modelo de header que já esteja a utilizar para os seus projectos. Sendo assim você pode
editar directamente o modelo de defeito dado. Para fazer isto, é-lhe dado o modelo numa janela de edição. Para limpar a página de defeito,
seleccione "Novo", para utilizar outro modelo, seleccione "Ler...", que lhe permite escolher um ficheiro de modelo.</para>

<para>Quando tiver terminado, vá para a página seguinte premindo "Seguinte". Esta é a página de modelo para os seus ficheiros de código fonte e é geralmente a mesma
que a página de modelo de header. A única diferença é que este modelo é utilizado para os seus ficheiros de implementação.</para>
</sect2>

<sect2 id="criar-o-projecto">
<title>Criar o Projecto</title>

<para>Agora que já definiu todas as opções para o <emphasis>KScribble</emphasis>, seleccione "Seguinte" e prima o botão "Gerar" no fundo da janela do assistente.
Se o botão não estiver disponível, você não definiu todas as opções correctamente. Para corrigir quaisquer erros, volte atrás no Assistente com "Regressar".</para>

<para>Depois você verá o que o KAppWizard faz- ele copia todos os modelos para o directório do seu projecto e cria o novo projecto. Após o KAppWizard
terminar, o botão "Cancelar" muda para um botão "Sair" para deixar o assistente.</para>

<para>Após este último passo, você terminou a criação do novo projecto. O KDevelop lê-o então e a vista de árvore permite-lhe navegar através
ficheiros e classes do projecto.</para>

<para>Na próxima secção, iremos discutir como construir e correr a sua primeira versão do <emphasis>KScribble</emphasis> e como o código fonte está organizado.</para>
</sect2>
</sect1>

<sect1 id="a-primeira-construo">
<title>A Primeira Construção</title>

<para>Após o seu projecto ser gerado, iremos primeiro fazer uma viagem através do código fonte para obter um entendimento geral de como funciona o esqueleto
da aplicação. Isto não só ajudará a começar como também saberemos onde mudar o quê em passos futuros.</para>

<para>Quando abrimos a página do VLF (Visualizador Lógico de Ficheiros)  na vista de árvore, você vê algumas pastas que já ordenam os ficheiros do projecto relevantes para
o programador. As duas primeiras pastas são "Header" e "Código". A pasta-Header assim sendo contém logicamente todos os ficheiros header do
projecto, a pasta-Código todo o código fonte. Todas as outras pastas não são de interesse por agora, pelo que voltaremos aqui mais tarde para ver o
que contêm.</para>

<para>Essas duas pastas contêm então os seguintes ficheiros:</para>

<para><emphasis remap="bf">Headers:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">kscribble.h :</emphasis> contém a declaração de classe para a classe <emphasis remap="bf">KScribbleApp</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbledoc.h :</emphasis> contém a declaração de classe para a classe <emphasis remap="bf">KScribbleDoc</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbleview.h :</emphasis> contém a declaração de classe para a classe <emphasis remap="bf">KScribbleView</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">resource.h :</emphasis> contém uma colecção de macro para os menu-ID's</para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">Código:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">kscribble.cpp :</emphasis> contém a implementação da classe <emphasis remap="bf">KScribbleApp</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbledoc.cpp :</emphasis> contém a implementação da classe <emphasis remap="bf">KScribbleDoc</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">kscribbleview.cpp :</emphasis> contém a implementação da classe <emphasis remap="bf">KScribbleView</emphasis>.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">main.cpp :</emphasis> contém a implementação da função <emphasis remap="bf">main()</emphasis>.</para>
</listitem>
</itemizedlist>
</para>

<para>Mas antes de mergulharmos no código, vamos deixar o KDevelop construir e correr a nossa nova aplicação. Para fazer isto, seleccione "Make" a partir do menu "Construir"
ou prima o botão correspondente na barra de ferramentas <indexterm remap="idx"><primary>barra de ferramentas</primary></indexterm>. A janela de output abre na base do KDevelop e deixa-o ver o que o <literal remap="tt">make</literal> está a fazer
através das mensagens que nos dá:</para>

<para><screen>1   Making all in docs
2   make[1]: Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'
3   Making all in en
4   make[2]: Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs/en'
5   make[2]: Nothing to be done for `all'.
6   make[2]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs/en'
7   make[2]: Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'
8   make[2]: Nothing to be done for `all-am'.
9   make[2]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'
10  make[1]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble/docs'
11  make[1]: Entering directory `/home/rnolden/Tutorial/kscribble1/kscribble'
12  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    kscribbleview.cpp
13  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    kscribbledoc.cpp
14  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c 		
    kscribble.cpp
15  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    main.cpp
16  /usr/bin/moc ./kscribble.h -o kscribble.moc.cpp
17  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    kscribble.moc.cpp 		
18  /usr/bin/moc ./kscribbledoc.h -o kscribbledoc.moc.cpp
19  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    kscribbledoc.moc.cpp
20  /usr/bin/moc ./kscribbleview.h -o kscribbleview.moc.cpp
21  g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/X11R6/include    -O0 -g -Wall  -c
    kscribbleview.moc.cpp

22  /bin/sh ../libtool --silent --mode=link g++  -O0 -g -Wall   -o kscribble -L/opt/kde/lib  -L/usr/X11R6/lib -rpath /opt/kde/lib
    -rpath /usr/X11R6/lib kscribbleview.o kscribbledoc.o kscribble.o main.o kscribble.moc.o kscribbledoc.moc.o kscribbleview.moc.o
    -lkfile -lkfm -lkdeui -lkdecore -lqt -lXext -lX11

23  make[1]: Leaving directory `/home/rnolden/Tutorial/kscribble1/kscribble'
</screen>
</para>

<para>Como pode ver, numeramos todas as linhas, o que não irá surgir no seu output; apenas torna mais fácil descrever agora o que
aconteceu durante a construção. Primeiro que tudo, o <literal remap="tt">make</literal> trabalha recursivamente. Isto é, comça no directório em que foi invocado e
então vai para os subdirectórios primeiro, regressa e processa o subdirectório seguinte. Finalmente, o directório em que foi iniciado é processado
e o <literal remap="tt">make</literal> termina. Assim, o <literal remap="tt">make</literal> começou primeiro no directório principal do projecto contendo o código. Nas linhas 1 e 2, você
vê como o processo <literal remap="tt">make</literal> entra no directório <literal remap="tt">docs</literal>, depois no subdirectório <literal remap="tt">en</literal>. Como não existe nada para fazer, ele
deixa estes directórios até regressar ao directório fonte <literal remap="tt">kscribble</literal> na linha 11. Depois, o verdadeiro trabalho começa: o <literal remap="tt">make</literal>
invoca o compilador, aqui o <literal remap="tt">g++</literal> para compilar o ficheiro de código <literal remap="tt">kscribbleview.cpp</literal>. A macro <literal remap="tt">-DHAVE&&lowbar;;CONFIG&&lowbar;;H</literal> diz que o ficheiro
<literal remap="tt">config.h</literal> deverá ser utilizado. Este é um ficheiro que contém macros para a plataforma e aplicação específicas e está localizado no
directório principal do projecto. Os comandos <literal remap="tt">-I</literal> seguintes adicionam o caminho include onde o <literal remap="tt">g++</literal> pode encontrar os includes de que necessita. O caminho é o
directório corrente, o directório principal do projecto (através de <literal remap="tt">-I..</literal>) e o caminho include para o KDE, Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e ficheiros header da biblioteca X11. Os
directórios para estes ficheiros include foram determinados pelo script <literal remap="tt">configure</literal> e definidos nos Makefiles, pelo que, o compilador
sabe onde estes se encontram. Finalmente, <literal remap="tt">-O0</literal> define a optimização para zero (sem optimização), <literal remap="tt">-g</literal> permite a depuração, <literal remap="tt">-Wall</literal>
define os avisos do compilador para <literal remap="tt">todos</literal> e <literal remap="tt">-c</literal> diz ao compilador para produzir um ficheiro de objecto, ou seja apenas compilar o ficheiro.</para>

<para>Isto é feito também para os outros ficheiros de código do nosso projecto nas linhas 13-15. Obviamente, o nosso código é compilado, mas em vez de
ligar os ficheiros objecto do código ao binário final, nós vemos alguns outros comandos. Na linha 16, você vê que o programa "moc" é
chamado para processar o ficheiro header <literal remap="tt">kscribble.h</literal>, com o seu resultado em <literal remap="tt">kscribble.moc.cpp</literal>. Depois, na linha 17, este ficheiro de código é
também compilado. O mesmo acontece com os outros ficheiros header do projecto até à linha 21. Agora, como o conjunto de ferramentas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> contém o mecanismo
sinal/espaço, mas continua a ser uma implementação C++, você está a utilizar algumas palavras-chave que não são originalmente linguagem C++, tais como
as declarações <literal remap="tt">signals:</literal> e <literal remap="tt">slots:</literal> nas suas classes. Isto dá-lhe a possibilidade de permitir facilmente comunicação entre objectos para todas
as classes de objectos que herdem a classe <literal remap="tt">QObject</literal>, pelo que pode evitar os normais ponteiros para funções de chamada (callback). Assim, a aplicação
necessita do código que implementa esta funcionalidade, e é por isto que o <literal remap="tt">moc</literal> é chamado. <literal remap="tt">Moc</literal> é o Compilador de Objectos Meta (Meta Object Compiler) do conjunto de
ferramentas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e constroi a implementação para mecanismos de sinais e espaços percorrendo os ficheiros header e produzindo um código de resultado que
tem de ser compilado no binário. Como os projectos do KDevelop utilizam o <literal remap="tt">automoc</literal> para determinar, que ficheiro header necessita de ser processado, você
não tem de se preocupar com nenhuma chamada ao <literal remap="tt">moc</literal> nem com o compilador C++ no ficheiro moc de resultado. Lembre-se apenas da regra que faz uma
classe utilizar os sinais e espaços- hereditariedade da <literal remap="tt">QObject</literal> ou qualquer classe que herde em si a <literal remap="tt">QObject</literal>, inclusão da
macro <literal remap="tt">Q&&lowbar;;OBJECT</literal> (sem ponto e vírgula !) no início da declaração de classe e a declaração para os sinais e espaços.</para>

<para>Finalmente, o seu binário é construido pelo compilador. O binário de resultado é chamado <literal remap="tt">kscribble</literal>, o linkador inclui o caminho para as bibliotecas
KDE e X11 e liga o código contra as bibliotecas <literal remap="tt">kfile, kfm, kdeui, kdecore, qt, Xext</literal> e <literal remap="tt">X11</literal>. Depois tudo está feito e
o make termina.</para>
</sect1>

<sect1 id="o-esqueleto-de-cdigo">
<title>O Esqueleto de Código</title>

<para>Para obter um conceito de como uma aplicação KDE funciona, teremos primeiro que olhar muito atentamente para o esqueleto de código já disponibilizado pelo
Assistente de Aplicação. Como nós já vimos, temos um conjunto de ficheiros de código e header que constroem o código inicial para a aplicação
e a tornam pronta-a-correr. Assim, a maneira mais fácil de explicar o código é seguir a implementação linha a linha como é
processado durante a execução do programa até entrar no ciclo principal de evento e está pronto a receber interacção do utilizador. Depois, iremos observar a
functionalidade que permite a interacção do utilizador e como certas coisas funcionam. Esta é provavelmente a melhor forma de explicar o esqueleto
e, como é similar a quase todas as aplicações KDE <indexterm remap="idx"><primary>aplicações KDE</primary></indexterm>, irá permitir-lhe ler também o código fonte de outros projectos; adicionalmente,
você saberá aqui onde alterar que parte do código para fazer com que as suas aplicações se comportem da forma para que foram desenhadas.</para>

<sect2 id="the-main-function">
<title>A Função <literal remap="tt">main()</literal></title>

<para>Como a aplicação inicia a sua execução entrando na função <literal remap="tt">main()</literal>, este será o ponto de partida do nosso exame ao código. A
função <literal remap="tt">main()</literal> do <emphasis>KScribble</emphasis> é implementada no ficheiro <literal remap="tt">main.cpp</literal> e pode também ser encontrada utilizando o Navegador de Classes
seleccionando a pasta "Globais", sub-pasta "Funções":</para>

<para><screen>1  #include "kscribble.h"
2
3  int main(int argc, char* argv[]) {
4    KApplication app(argc,argv,"KScribble");
5
6    if (app.isRestored())
7    {
8       RESTORE(KScribbleApp);
9    }
10   else
11   {
12      KScribbleApp* kscribble = new KScribbleApp;
13      kscribble-&gt;show();
14      if(argc &gt; 1){
15        kscribble-&gt;openFile(argv[1]);
16      }
17    }
18    return app.exec();
19  }
</screen>
</para>

<para>Agora, o que acontece primeiro é a normal criação do objecto <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>, que obtém o nome da nossa aplicação <emphasis>KScribble</emphasis> como terceiro
parâmetro. Quando se cria um novo <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>, uma nova instância de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> é criada também que é conectada ao ficheiro de
configuração em $HOME/.kde/share/config/appname + rc que guarda toda a informação que queremos utilizar quando iniciamos janelas da aplicação. O nome que
passamos ao construtor de <literal remap="tt">app</literal> será utilizado como o título da janela mais tarde.</para>

<para>Apesar do código de exemplo para tornar a primeira aplicação Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> numa KDE, o código seguinte é ligeiramente diferente. Após o
objecto <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> estar presente, nós testamos se a aplicação é iniciada através do gestor de sessões do <literal remap="tt">kwm</literal> ou manualmente através
do utilizador. Isto pode ser descoberto quando se chama <literal remap="tt">isRestored()</literal> no objecto <literal remap="tt">app</literal>, que retorna <literal remap="tt">true (verdade)</literal> para gestão de sessão
e <literal remap="tt">false (falso)</literal> para um início normal.</para>

<para>Como a gestão de sessão é uma característica principal das aplicações KDE <indexterm remap="idx"><primary>aplicações KDE</primary></indexterm> e vastamente utilizada pelo esqueleto mas com muito mais para explicar, nós vamos
seguir a secção <literal remap="tt">else&&lcub;;&&rcub;;</literal> primeiro; depois voltaremos e explicaremos a funcionalidade de sessão num passo seguinte.</para>
</sect2>

<sect2 id="aplicao-iniciada-pelo-utilizador">
<title>Aplicação Iniciada pelo Utilizador</title>

<para>A secção <literal remap="tt">else&&lcub;;&&rcub;;</literal> agora cria uma instância da classe <literal remap="tt">KScribbleApp</literal> na linha 12. Este objecto é chamado para se mostrar a sí próprio na linha
13 como normal; a linha 14 determina se um argumento de linha de comando foi passado e, como isto é normalmente o nome de um ficheiro, chama o
objecto <literal remap="tt">kscribble</literal> para o abrir com <literal remap="tt">openFile()</literal>.</para>

<para>Note que nós não chamamos o método <literal remap="tt">setTopWidget(kscribble)</literal> para a nossa aplicação- isto já foi feito pela classe que o <literal remap="tt">KScribbleApp</literal>
herda. Agora vamos observar o nosso objecto <literal remap="tt">KScribbleApp</literal>- o que é e o que é que já disponibiliza? A única coisa que nós sabemos
até agora é que tem de ser um Widget para representar o interface do utilizador na janela principal. Vamos ver a implementação da classe de
<literal remap="tt">KScribbleApp</literal>, que pode ser encontrada no ficheiro <literal remap="tt">kscribble.cpp</literal> ou através de um clique no icon da classe no Navegador de Classes. Como a
instância é criada pelo construtor.
Primeiro que tudo, vemos que herda a classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>, que é parte da biblioteca <literal remap="tt">kdeui</literal>. Esta classe em sí
herda <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>, pelo que, como normal, nós temos um widget normal como sendo a janela de topo. O <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> contém imensas functionalidades
de que a classe <literal remap="tt">KScribbleApp</literal> tira proveito. Disponibiliza barras de menu, ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm>, estados e suporte para gestão de sessões. A única coisa
que temos que fazer quando a criar sub-classes da <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> é criar todos os objectos de que necessitamos e criar outro widget que é gerido pela
instância <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> como a vista principal no centro da janela; normalmente este é o local onde o utilizador trabalha tal como
numa vista de edição de texto.</para>

<sect3 id="o-construtor">
<title>O Construtor</title>

<para>Vamos observar o código para o construtor e ver como a instância é criada:</para>

<para><screen>1   KScribbleApp::KScribbleApp()
2   {
3     config=kapp-&gt;getConfig();
4	
5
6     ///////////////////////////////////////////////////////////////////
7     // chama inits para invocar todas as outras partes de construção
8     initMenuBar();
9     initToolBar();
10    initStatusBar();
11    initKeyAccel();
12    initDocument();
13    initView();
14
15    readOptions();
16
17    ///////////////////////////////////////////////////////////////////
18    // desactiva itens de menu e barra de ferramentas no arranque
19    disableCommand(ID_FILE_SAVE);
20    disableCommand(ID_FILE_SAVE_AS);
21    disableCommand(ID_FILE_PRINT);
22
23    disableCommand(ID_EDIT_CUT);
24    disableCommand(ID_EDIT_COPY);
25    disableCommand(ID_EDIT_PASTE);
26  }
</screen>
</para>

<para>Nós vemos que a nossa instância de configuração do <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> aponta agora para a configuração da aplicação, pelo que podemos operar
mais tarde com as entradas de configuração do ficheiro.</para>

<para>Depois, todas as partes da aplicação que são necessárias são criadas pela sua correspondente função membro que é especificada na nossa janela
principal:</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">initMenuBar():</emphasis>  constroi a barra de menu,</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initToolBar():</emphasis>  constroi a barra de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm>,</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initStatusBar():</emphasis> cria a barra de estados,</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initKeyAccel():</emphasis>  define todos os atalhos de teclado<indexterm><primary>accelerator</primary></indexterm> para a nossa aplicação através da configuração de teclado global e específica
da aplicação</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initDocument():</emphasis> cria o objecto documento para a janela da aplicação</para>
</listitem>
<listitem>
<para><emphasis remap="bf">initView():</emphasis>      cria o widget principal para a nossa vista dentro da janela principal</para>
</listitem>
<listitem>
<para><emphasis remap="bf">readOptions():</emphasis>  lê todas as definições específicas da aplicação a partir do ficheiro de configuração e inicializa o resto da
aplicação tal como a lista de ficheiros recentes, as posições das barras e tamanho da janela.</para>
</listitem>
</itemizedlist>
</para>

<para>Finalmente, nós desactivamos alguns comandos que o utilizador pode realizar, porque não podem estar disponíveis no estado actual da aplicação.
Como temos agora uma visão genérica de como a janela da aplicação é criada, iremos olhar para os detalhes de como os elementos do utilizador são
construidos seguindo os métodos acima.</para>
</sect3>

<sect3 id="a-barra-de-menu">
<title>A Barra de Menu</title>

<para>Como mostrado acima, a barra de menu do <emphasis>KScribble</emphasis> é criada pelo método <literal remap="tt">initMenuBar()</literal>. Aí, nós criamos um conjunto de
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QPopupMenu</literal></primary></indexterm>QPopupMenu</literal>s que surgem quando o utilizador selecciona uma entrada de menu. Depois, nós inserimo-las na barra de menu e conectamo-las com as entradas.</para>

<para>Primeiro, nós criamos o nosso <literal remap="tt">recent&&lowbar;;file&&lowbar;;menu</literal>, que irá conter os nomes dos últimos 5 ficheiros abertos. Temos de fazer isto primeiro, porque
esta entrada de menu é inserida no <literal remap="tt">file&&lowbar;;menu</literal>. Quando adicionamos a conecção directamente- apenas obtemos o sinal que é emitido pela
entrada de menu com o seu número de entrada e chamamos a <literal remap="tt">slotFileOpenRecent( int )</literal>, que então chama o ficheiro correcto a partir da lista de ficheiros recentes
para ser aberto.</para>

<para>Depois criamos o nosso menu "Ficheiro". Este será o menu que irá ser visível na barra de menu. As acções standard são então inseridas no
menu de popup uma a uma- primeiro os comandos para criar um novo ficheiro, abrir um ficheiro, fechar um ficheiro etc., finalmente "S&&amp;;ir" para fechar a
aplicação. Todas as entradas de menu têm de ser criadas na ordem em que surgem mais tarde, pelo que temos de manter um olho no que queremos ter
em que lugar. Como um exemplo, nós olhamos para as seguintes entradas:</para>

<para><screen>file_menu-&gt;insertItem(Icon("fileopen.xpm"), i18n("&&amp;;Open..."), ID_FILE_OPEN );
file_menu-&gt;insertItem(i18n("Open &&amp;;recent"), recent_files_menu, ID_FILE_OPEN_RECENT );
</screen>
</para>

<para>A primeira insere a entrada "Abrir...". Como nós queremos te-la como um icon, nós utilizamos o método <literal remap="tt">insertItem()</literal> com o nome do
icon. Para entender o processo de leitura do icon, nós necessitamos de saber o que ou onde <literal remap="tt">Icon()</literal> é declarada- de facto, é uma macro disponibilizada
pela classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>:</para>

<para><screen>#define Icon(x) kapp-&gt;getIconLoader()-&gt;loadIcon(x)
</screen>

Adicionalmente, utiliza a seguinte macro internamente para obter acesso ao objecto da aplicação:
<screen>#define kapp KApplication::getKApplication()
</screen>
</para>

<para>Isto significa que o objecto <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> já contém uma instância de um leitor de Icons- nós apenas temos de ter acesso a ela; depois irá ler
o icon correspondente. Como os nossos icons são todos das bibliotecas KDE <indexterm remap="idx"><primary>bibliotecas KDE</primary></indexterm>, nós não temos de nos preocupar com mais nada- eles são instalados no
sistema automaticamente, pelo que também não temos de os incluir no pacote da nossa aplicação para os utilizar.</para>

<para>Após o parâmetro do icon (que é opcional), nós inserimos o nome da entrada de menu através de <literal remap="tt">i18n("&&amp;;Abrir...")</literal>. Aí, nós temos de observar duas
coisas: primeiro, a entrada é inserida com o método <literal remap="tt">i18n()</literal>. Tal como a entrada <literal remap="tt">Icon()</literal>, é uma macro também definida em <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal>
e chama o objecto <literal remap="tt">KLocale</literal> da <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> para traduzir a entrada para o idioma actualmente utilizado:</para>

<para><screen>#define i18n(X) KApplication::getKApplication()-&gt;getLocale()-&gt;translate(X)
</screen>
</para>

<para>Chegando aqui, deverá ser mencionado que uma pessoa poderia pensar "Eu não quero utilizar macros"- você pode fazer isso a maior parte dos casos. Mas aqui é
imprescindível a utilização da <literal remap="tt">i18n()</literal> porque para a internacionalização os ficheiros de idioma respectivos têm de ser construidos. Como este processo
de construção depende da string (conjunto de caracteres) <literal remap="tt">i18n</literal>, você tem de utilizar a macro.</para>

<para>Como já deve ter adivinhado, o & (i comercial) dentro das entradas de menu é mais tarde interpretado como uma linha por baixo da letra seguinte na
entrada de menu. isto permite um acesso rápido ao comando de menu através do teclado quando o utilizador prime a tecla <literal remap="tt">Alt</literal> em conjunto com a
letra sublinhada.</para>

<para>Finalmente, nós damos um ID (número identificativo) à entrada de menu, que é um número inteiro através do qual podemos encontrar a entrada mais tarde. Para
manter um controlo sobre os valores utilizados, estes são definidos através de macros e são coleccionados no ficheiro <literal remap="tt">resource.h</literal> dentro do seu projecto. Por
consistência, estas macros são todas maiúsculas e começam por ID&&lowbar;;, depois o nome do menu seguido pela entrada. Isto torna muito fácil
lembramo-nos do sentido de cada entrada em qualquer ponto do código, pelo que não temos de voltar à implementação da barra de menu de novo para
observar as entradas.</para>

<para>A segunda entrada de exemplo mostra outra variante do método <literal remap="tt">insertItem()</literal>. Aqui, nós acrescentamos o menu de popup recent&&lowbar;;files&&lowbar;;menu como
um item de menu. Isto significa, que a entrada mostra-se a sí própria com a string dada "Abrir recentes", seguida de uma seta para a direita. Na selecção, o
menu de popup de ficheiros recentes surge e o utilizador pode escolher o último ficheiro.</para>

<para>Por fim mas não menos importante existem muitas outras formas de inserir items de menu- o esqueleto de aplicação mantém isto o mais simples possível. Mais informação
pode ser obtida na documentação Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> sobre a classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>QMenuData</literal></primary></indexterm>QMenuData</literal>.</para>

<para>Agora, após termos criado os menus de popup <literal remap="tt">file&&lowbar;;menu, edit&&lowbar;;menu</literal> e <literal remap="tt">view&&lowbar;;menu</literal>, temos de incluir também um menu "Ajuda". Nós podiamos
fazer isto tal como os outros, mas a classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> oferece um método mais rápido e agradável para cobrir isto:</para>

<para><screen>help_menu = kapp-&gt;getHelpMenu(true, i18n("KScribble\n" VERSION ));
</screen>
</para>

<para>Isto é tudo o que temos de fazer para obter um menu de ajuda que contenha uma entrada para o conteudo da ajuda com o atalho<indexterm><primary>shortcuts</primary></indexterm> de teclado F1, uma caixa-sobre
para a aplicação e uma caixa-sobre para o KDE (que pode ser desactivada chamando <literal remap="tt">getHelpMenu(false,...);</literal>). O conteudo para a
caixa-sobre da nossa aplicação é definida de novo com a string <literal remap="tt">i18n()</literal> - VERSION fica com a macro que é definida para a numeração de versão do projecto
no ficheiro <literal remap="tt">config.h</literal>, pelo que não temos de modificar isto manualmente de cada vez que queremos fazer uma nova distribuição. Esteja à vontade para
adicionar aqui qualquer informação sobre a sua aplicação, por ex. o seu nome, endereço email, copyright e afins.</para>

<para>Agora apenas temos de inserir os pop-ups na barra de menu. Como o <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> já constroi uma barra de menu para nós, nós apenas os inserimos
chamando <literal remap="tt">menuBar()-&gt;insertItem();</literal>.</para>

<para>O que resta fazer é conectar as entradas de menu com os métodos que irão executar. Assim, nós conectamos cada menu de popup através do seu
sinal <literal remap="tt">activated( int )</literal> a um método <literal remap="tt">commandCallback( int )</literal>, que contém uma frase <literal remap="tt">switch</literal> que chama o método correspondente
para as entradas de menu. Adicionalmente, nós conectamos os pop-ups através do seu sinal <literal remap="tt">highlighted( int )</literal> para disponibilizar ajuda de barra de estados
para cada entrada. Sempre que o utilizador move o seu rato ou focus de teclado <indexterm remap="idx"><primary>focus de teclado</primary></indexterm> para uma entrada, a barra de estados mostra então a correspondente mensagem de ajuda.</para>

<para>Após termos terminado com a barra de menu, podemos continuar com a barra de ferramentas <indexterm remap="idx"><primary>barra de ferramentas</primary></indexterm> na secção seguinte. Lembre-se que uma instância de
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> apenas pode ter uma barra de menu visível de cada vez; assim se deseja construir diversas barras de menu, você tem de cria-las
separadamente com instâncias de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KMenuBar</literal></primary></indexterm>KMenuBar</literal> e definir uma delas através dos métodos correspondentes de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> como sendo a barra
de menu actual. Veja a documentação de classes <indexterm remap="idx"><primary>documentação de classes</primary></indexterm> da <literal remap="tt"><indexterm remap="cdx"><primary><literal>KMenuBar</literal></primary></indexterm>KMenuBar</literal> para informação mais detalhada sobre como extender as características, veja também <link linkend="Configuring-Menubars-and-Toolbars">Configurar Barras de Menu e Ferramentas</link>.</para>
</sect3>

<sect3 id="a-barra-de-ferramentas">
<title>A Barra de Ferramentas</title>

<para>A criação de barras de ferramenta <indexterm remap="idx"><primary>ferramenta</primary></indexterm>s é agora ainda mais simples que a das barras de menu. Como a <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> já disponibiliza barras de ferramenta <indexterm remap="idx"><primary>ferramenta</primary></indexterm>s, que são criadas
pela primeira inserção, você é livre de criar várias. Basta adicionar os botões para as funções que deseja disponibilizar:</para>

<para><screen>toolBar()-&gt;insertButton(Icon("filenew.xpm"), ID_FILE_NEW, true, i18n("New File") );
</screen>
</para>

<para>Isto adiciona um botão alinhado à esquerda com o icon "filenew.xpm" com o respectivo ID para a barra de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm>. O terceiro parâmetro decide se o
botão deverá estar activo ou não; por defeito nós definimos isto para <literal remap="tt">true (verdade)</literal>, porque o nosso método <literal remap="tt">disableCommand()</literal> no final do
construtor faz isto por nós automaticamente tanto para as entradas do menu como da barra de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm>. Finalmente, o último parâmetro é utilizado como uma
"Dica Rápida"- quando o utilizador move o ponteiro do rato sobre o botão de forma a ficar iluminado, uma pequena janela surge que contém uma
pequena mensagem de ajuda, cujo conteudo pode ser definido aqui.</para>

<para>Finalmente, todos os botões da barra de ferramentas <indexterm remap="idx"><primary>barra de ferramentas</primary></indexterm> estão conectados novamente ao nosso método  <literal remap="tt">commandCallback()</literal> através do seu sinal <literal remap="tt">clicked()</literal>. Ao sinal
<literal remap="tt">pressed()</literal>, nós permitimos ao utilizador receber a mensagem de ajuda correspondente na barra de estados.</para>

<para><emphasis remap="bf">Informação Adicional:</emphasis></para>

<para>Como as barras de ferramentas <indexterm remap="idx"><primary>barras de ferramentas</primary></indexterm> são criadas utilizando a classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal>, você deverá ler a respectiva documentação. Com a
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal>, imensas coisas necessárias na barra de ferramentas <indexterm remap="idx"><primary>barra de ferramentas</primary></indexterm> podem ser realizadas tais como pop-ups demorados se o seu botão deseja fazer surgir um menu
quando o botão é mantido premido ou até mesmo widgets como caixas de escolha. Também, por defeito, a barra de ferramentas <indexterm remap="idx"><primary>barra de ferramentas</primary></indexterm> preenche a largura total da
janela, o que a faz ter um aspecto melhor utilizando apenas uma barra. Quando se usa mais do que uma, você deverá também pensar na hipótese de definir o tamanho da
barra para terminar a seguir ao botão mais à direita, para que outras barras possam ser apresentadas na mesma linha por baixo da barra de menu. Iremos discutir algumas
tecnicas sobre desing e extensão de barras de ferramentas <indexterm remap="idx"><primary>barras de ferramentas</primary></indexterm> na secção <link linkend="Configuring-Menubars-and-Toolbars">Configurar Barras de Menu e Ferramentas</link>.</para>
</sect3>

<sect3 id="a-barra-de-estados">
<title>A Barra de Estados</title>

<para>A barra de estados é, bem como as outras barras, já disponibilizada pela instância <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>, pelo que apenas temos de inserir os nossos itens
como quisermos. Por defeito, o esqueleto contém apenas uma entrada que mostra a ajuda de barra de estados. Para muitas aplicações isto pode não
chegar; então você inserirá as entradas que necessite para mostrar por ex. coordenadas e afins.</para>

<para>Também, uma aplicação pode apenas ter uma barra de estados de cada vez como as barras de menu. Se desejar construir várias, deverá cria-las
separadamente e definir a barra corrente através do método correspondente da <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>. A barra de estados também permite inserir widgets,
que podem ser utilizador para produzir bons hábitos de apresentar barras de progresso como o KDevelop faz. Verifique a documentação de classes <indexterm remap="idx"><primary>documentação de classes</primary></indexterm> da
<literal remap="tt">KStatusBar</literal>.</para>
</sect3>

<sect3 id="atalhos-de-teclado">
<title>Atalhos de Teclado</title>

<para>Ao atingir o método <literal remap="tt">initKeyAccel()</literal>, já construimos os itens standard da janela principal de uma aplicação- as barras de menu,
ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm> e estados. Na verdade, não definimos nenhuns <indexterm><primary>atalhos</primary></indexterm> de teclado através dos quais utilizadores avançados que apenas queiram
trabalhar com o teclado possam aceder rapidamente a certos comandos que são utilizados mais frequentemente durante a utilização do programa. Para o fazer, nós
podiamos ter inserido as teclas de <indexterm><primary>atalhos</primary></indexterm> na inserção dos itens de menu por exemplo, mas o KDE oferece uma boa
solução para construir e manter <indexterm><primary>atalhos</primary></indexterm> de teclado. Imensos utilizadores querem te-los configuráveis por um lado
e por outro os <indexterm><primary>atalhos</primary></indexterm> standard deverão ser os mesmos em todas as aplicações. Assim, o Centro de Controlo do KDE
permite configurar <indexterm><primary>atalhos</primary></indexterm> de teclado standard globalmente através da utilização da classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal>. Adicionalmente, as
bibliotecas KDE <indexterm remap="idx"><primary>bibliotecas KDE</primary></indexterm> contêm um widget que permite aos utilizadores configurar <indexterm><primary>atalhos</primary></indexterm> de teclado específicos da aplicação facilmente. Como o
esqueleto da aplicação apenas utiliza itens de menu que têm acções standard tais como "Novo" ou "Sair", estes são definidos pelo método
<literal remap="tt">initKeyAccel()</literal>. Acções standard apenas têm de ser conectadas, para os valores de teclado específicos da sua aplicação, têm de os inserir
primeiro especificando o nome do <indexterm><primary>atalho</primary></indexterm> de teclado e depois conecta-lo. como os nossos <indexterm><primary>atalhos</primary></indexterm> estão
todos presentes na barra de menu, temos de modificar os <indexterm><primary>atalhos</primary></indexterm> para as entradas de popup. Finalmente chamamos
<literal remap="tt">readSettings()</literal>, que lê as definições correntes a partir da janela principal do KDE contendo as configurações de <indexterm><primary>atalhos</primary></indexterm> standard,
e depois as definições de <indexterm><primary>atalhos</primary></indexterm> específicos do ficheiro de configuração da aplicação. Quando
nós aprofundarmos mais o nosso projecto de exemplo, iremos também falar sobre como configurar os <indexterm><primary>atalhos</primary></indexterm> específicos da nossa aplicação
através de um diálogo de configuração, veja <link linkend="Configuring-Menubars-and-Toolbars">Configurar Barras de Menu e Ferramentas</link> para essa parte do processo de desenvolvimento.</para>
</sect3>

<sect3 id="o-modelo-de-vista-de-documento">
<title>O Modelo de Vista de Documento</title>

<para>As duas próximas chamadas de funções membros, <literal remap="tt">initDocument()</literal> e <literal remap="tt">initView()</literal>, vão finalmente construir a parte que é suposto as
janelas da aplicação disponibilizarem ao utilizador: um interface para trabalhar com os dados que é suposto a aplicação manipular; e essa é também a
razão pela qual o esqueleto da aplicação contém três classes, uma classe <literal remap="tt">*App</literal>, <literal remap="tt">*View</literal> e <literal remap="tt">*Doc</literal>. Para entender, porque esta
estrutura é útil, iremos olhar um pouco à margem do código e introduzir alguma teoria, depois voltaremos ao programa de novo para ver
como o esqueleto feito pelo KDevelop suporta esse modelo.</para>

<para>Basicamente, tudo o que tem sido explicado até agora sobre a estrutura é que necessitamos de uma instância de aplicação que contenha a janela principal. Esta
janela é responsável por disponibilizar o interface basico para o utilizador- contém as barras de menu, ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm> e estados e o controlo
de eventos para a interacção do utilizador. Também, contém uma área, que é descrita como uma "vista". Agora, o objecto da visra é genericamente,
mostrar os dados que o utilizador pode manipular, por ex. uma parte de um ficheiro de texto. Apesar do ficheiro de texto ser provavelmente maior que a vista é
capaz de mostrar no ecrã, disponibiliza ao utilizador a possibilidade de ir para a parte que deseja ver (pelo que é uma vista), e aí o utilizador
pode modificar os dados do conteudo do ficheiro. Para dar ao programador uma maneira melhor de separar as partes da aplicação através do código, o
Modelo Vista-Documento foi inventado. Apesar de não ser um standard, disponibiliza uma estrutura de como uma aplicação deveria funcionar:</para>

<para><itemizedlist>
<listitem>
<para> A aplicação contém um objecto controlador,</para>
</listitem>
<listitem>
<para> um objecto de Vista que mostra os dados com que o utilizador trabalha</para>
</listitem>
<listitem>
<para> e um objecto Documento que contém na realidade os dados a serem manipulados.</para>
</listitem>
</itemizedlist>
</para>

<para>De regresso ao exemplo de trabalhar com um ficheiro de texto- aí, este modelo iria funcionar de forma a que o Documento leria o conteudo do ficheiro e
disponibilizar os métodos para modificar os dados bem como para gravar o ficheiro de novo. A Vista então processa os eventos que o utilizador produz através do
teclado e rato e utiliza os métodos do objecto Documento para manipular os dados do documento.</para>

<para>Finalmente, o objecto controlador é responsável pela interacção do utilizador disponibilizando os objectos de Vista e de Documento bem como os
interfaces para enviar comandos tais como abrir e gravar. Adicionalmente, certos métodos do objecto Vista podem ser disponibilizados por comandos que
podem ser acedidos através de <indexterm><primary>atalhos</primary></indexterm> de teclado ou pelo rato ou barras de menu e ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm>.</para>

<para>Este Modelo Vista Documento tem algumas vantagens- separa o código do programa de uma forma mais orientada por objectos e por isso oferece mais flexibilidade
em geral, por ex. o mesmo objecto documento poderia ser apresentadps por duas vistas ao mesmo tempo; quer através de uma nova vista numa nova janela ou através
de mosaico da janela corrente que contém dois objectos vista que constroem a região de vista da janela actual.</para>

<para>Agora, se você vem dos sistemas MS-Windows poderá teralguma experiência com isso- o MFC já disponibiliza um modelo de documento que está
pronto a utilizar. Para as aplicações KDE e Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, as coisas são ligeiramente diferentes. A Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> é um poderoso conjunto de ferramentas pois disponibiliza as classes
mais necessárias, widgets etc. Mas não existiu nenhuma intenção de tomar conta do modelo documento-vista, e como o KDE herda a Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>,
também não existiram nenhumas tendências de introduzir este modelo. Isto de certa forma tem a sua justificação no facto de que normalmente as aplicações X
não funcionam com um MDI (Interface de Documento Multiplo). Cada janela principal é responsável pelos seus dados e isso reduz a necessidade de
um modelo de documento pelo facto de que métodos para trabalhar em documentos são sempre implícitos em widgets. A única excepção a isto actualmente é
o projecto <emphasis>KOffice</emphasis> que tenciona disponibilizar um conjunto de aplicações de produtividade completo tais como um processador de texto, uma folha de cálculo etc.
Tecnicamente, isto é realizado com duas alterações à utilização normal da Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e KDE:</para>

<para><itemizedlist>
<listitem>
<para>o KOffice utiliza KOM e a implementação gratuita de CORBA chamada MICO para comunicação de objectos,</para>
</listitem>
<listitem>
<para>as aplicações KOffice utilizam o modelo documento-vista para permitir a todas as aplicações trabalhar com quaisquer objectos de dados do KOffice</para>
</listitem>
</itemizedlist>
</para>

<para>Mas como o KDevelop actualmente se foca na utilização das actuasi bibliotecas do KDE 1.1.x e a Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> 1.4x, nós não podemos utilizar este modelo por defeito-
isto virá em distribuições futuras de um KDE 2, que irá (esperamos) conter duas modificações principais em relação à situação
actual:
<orderedlist><listitem>
<para>um interface MDI para a <indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</para>
</listitem>
<listitem>
<para>as bibliotecas KOM que disponibilizam um modelo de documento</para>
</listitem>
</orderedlist>
</para>

<para>Assim, a forma actual para os programadores de aplicações pode ser ou implementarem todos os métodos de documentos necessários dentro da sua vista ou
tentarem reproduzir um modelo de documento por si. O KDevelop assim contém essa reprodução disponibilizando as classes necessárias e
os métodos básicos que são geralmente utilizados para o Modelo Documento-Vista com a estrutura de aplicações para Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e KDE.</para>

<para>De regresso ao código, você pode agora imaginar o propósito dos dois métodos que mencionamos no início desta secção: as
funções <literal remap="tt">initDocument()</literal> e <literal remap="tt">initView()</literal>. O <literal remap="tt">initDocument()</literal> constroi o objecto documento que representa a
janela de dados da aplicação e inicializa atributos básicos tais como definir o bit de modificação que indica se os dados correntemente
em utilização foram modificados pelo utilizador. Depois, o método <literal remap="tt">initView()</literal> constroi o widget <literal remap="tt">*View</literal>, conecta-o com o documento e
chama o método <literal remap="tt">setView()</literal> de <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> para dizer à janela <literal remap="tt">*App</literal> para utilizar o widget <literal remap="tt">*View</literal> como a sua vista central.</para>

<para>Para o programador, é importante saber que durante o processo de desenvolvimento ele tem de:</para>

<para><itemizedlist>
<listitem>
<para>re-implementar os métodos virtuais para eventos de rato e teclado disponibilizados pela <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> no objecto <literal remap="tt">*View</literal> para disponibilizar
meios de manipular os dados,</para>
</listitem>
<listitem>
<para>re-implementar o <literal remap="tt">paintEvent()</literal> da <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> no objecto <literal remap="tt">*View</literal> para repaint() (re-desenhar) a cista após modificações,</para>
</listitem>
<listitem>
<para>completar a implementação para imprimir o documento através do método de impressão do objecto <literal remap="tt">*View</literal>,</para>
</listitem>
<listitem>
<para>adicionar a serialização para o objecto <literal remap="tt">*Doc</literal> para disponibilizar abertura e gravação de ficheiros,</para>
</listitem>
<listitem>
<para>adicionar a implementação da estrutura de dados do documento ao objecto <literal remap="tt">*Doc</literal> que está a representar os dados do documento logicamente em
memória.</para>
</listitem>
<listitem>
<para>adicionar quaiquer métodos que tenham de ser acessíveis pelo utilizador através de <indexterm><primary>atalhos</primary></indexterm> de teclado e menus/barras de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm>.</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="configurao-da-aplicao">
<title>Configuração da Aplicação</title>

<para>Agora, depois de termos criado todas as instâncias da instância <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> da nossa aplicação para criar a primeira janela, nós temos de
inicializar alguns valores que influenciam a aparência do programa. Para isto, chamamos <literal remap="tt">readOptions()</literal>, que obtém todos os valores e chama
os métodos necessários para definir os atributos correspondentes. A biblioteca KDE-Core contém a classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> que disponibiliza uma boa
possibilidade de guardar valores em ficheiros de configuração bem como de os ler novamente. Também, como cada instância <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>
já cria o seu ficheiro de recursos, apenas temos de aceder a este ficheiro e criar os nossos valores. Como o <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> nos disponibiliza o objecto
de ficheiro, temos de utilizar a classe <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfigBase</literal></primary></indexterm>KConfigBase</literal> para ler e escrever todas as entradas. Como escreve-lo é muito fácil de fazer com
métodos <literal remap="tt">writeEntry()</literal>, ler depende do tipo de atributo que queremos inicializar. Geralmente, uma entrada no ficheiro de
configuração contém um nome de valor e o valor. Valores que pertençam conjuntamente num contexto podem ser coleccionados em grupos, pelo que temos de
definir o nome do grupo antes de acedermos ao seu valor; o grupo tem de ser definido apenas uma vez para ler um conjunto de atributos que estão no
mesmo grupo. Vamos observar o que queremos ler:</para>

<para><screen>1   void KScribbleApp::readOptions()
2   {
3
4      config-&gt;setGroup("General Options");
5
6      // bar status settings
7      bool bViewToolbar = config-&gt;readBoolEntry("Show Toolbar", true);
8      view_menu-&gt;setItemChecked(ID_VIEW_TOOLBAR, bViewToolbar);
9      if(!bViewToolbar)
10       enableToolBar(KToolBar::Hide);
11
12     bool bViewStatusbar = config-&gt;readBoolEntry("Show Statusbar", true);
13     view_menu-&gt;setItemChecked(ID_VIEW_STATUSBAR, bViewStatusbar);
14     if(!bViewStatusbar)
15       enableStatusBar(KStatusBar::Hide);
16
17     // bar position settings
18     KMenuBar::menuPosition menu_bar_pos;
19     menu_bar_pos=(KMenuBar::menuPosition)config-&gt;readNumEntry("MenuBar Position", KMenuBar::Top);
20
21     KToolBar::BarPosition tool_bar_pos;
22     tool_bar_pos=(KToolBar::BarPosition)config-&gt;readNumEntry("ToolBar Position", KToolBar::Top);
23
24     menuBar()-&gt;setMenuBarPos(menu_bar_pos);
25     toolBar()-&gt;setBarPos(tool_bar_pos);
26
27     // initialize the recent file list
28     recent_files.setAutoDelete(TRUE);
29     config-&gt;readListEntry("Recent Files",recent_files);
30
31     uint i;
32     for ( i =0 ; i &lt; recent_files.count(); i++){
33       recent_files_menu-&gt;insertItem(recent_files.at(i));
34     }
35
36     QSize size=config-&gt;readSizeEntry("Geometry");
37     if(!size.isEmpty())
38       resize(size);
39   }
</screen>
</para>

<para>Como vimos numa das partes de código acima, a primeira acção que o nosso construtor faz é:</para>

<para><screen>config=kapp-&gt;getConfig();
</screen>
</para>

<para>que define o ponteiro <literal remap="tt">config</literal> tipp <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal> para a configuração da aplicação. Assim, não temos de nos preocupar com a localização do
ficheiro de configuração. Na verdade, o ficheiro está, de acordo com o Standard de Sistema de Ficheiros KDE (KDE FSS), localizado em
<literal remap="tt">&&dollar;;HOME/.kde/share/config/</literal>; iremos observar mais atentamente o KDE FSS num passo futuro quando estivermos a definir localizações de ficheiros
do projecto para instalação. Como o ficheiro de configuração é colocado no directório principal do utilizador, cada utilizador tem a sua aparência personalizada
da aplicação excepto para valores que estão localizados num ficheiro de configuração para todo o sistema que pode ser criado opcionalmente e instalado pelo
programador no directório do KDE. Mas, apesar de isto poder ajudar nalguns casos, devemos evitar quaiquer dependências da nossa aplicação no sentido
da existência de entradas de ficheiro. Assim, todos os métodos de leitura disponibilizados pelo <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfigBase</literal></primary></indexterm>KConfigBase</literal> permitem adicionar um valor de defeito a ser
utilizado quando a entrada não existe. Outra coisa importante para um programador é que o ficheiro de configuração é guardado em texto simples, e isto
é também por algumas razões pois tem de ter em atenção alguns critérios:</para>

<para><itemizedlist>
<listitem>
<para>o utilizador pode modificar o ficheiro de configuração através de um simples editor de texto</para>
</listitem>
<listitem>
<para>se o utilizador quiser modificar valores manualmente, as entradas deverão ser muito transparentes para determinar o seu propósito</para>
</listitem>
<listitem>
<para>para entradas que tenham de ser gravadas, mas são criticas em termos de segurança tal como chaves de acesso, você tem de procurar uma solução adequada
para assegurar a segurança.</para>
</listitem>
</itemizedlist>
</para>

<para>Agora que sabemos os básicos, vamos analizar o código. Como dissemos, apenas temos de utilizar o nosso ponteiro config para aceder aos valores.
Primeiro, na linha 4, nós definimos o grupo actual para "Opções Gerais". Isto indica que os valores estão de certo modo atributos gerais
para a aplicação. Depois nós lemos os valores para a barra de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm> e estados- estes têm de ser gravados quando a aplicação fecha para
repor os seus estadps de novo quando o utilizador reiniciar o programa. Como as barras apenas podem estar ligadas ou desligadas, nós utilizamos um valor boolean, pelo que,
o nosso método é <literal remap="tt">readBoolEntry()</literal>. O processo é idêntico para ambas as barras, pelo que apenas temos de olhar para as linhas 7-10 para observar o que está
a acontecer para a barra de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm>. Primeiro, nós lemos o valor para uma variável temporária <literal remap="tt">bViewToolbar</literal> na linha 7. O nome do valor no
ficheiro é "Mostrar Barra de Ferramentas" e, se o valor não estiver presente (o que seria o caso na primeira vez que a aplicação iniciasse), o
valor de defeito é definido para <literal remap="tt">true (verdade)</literal>. De seguida, nos definimos a marca de verificação da entrada de menu para (des)activar a barra de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm> através deste valor:
nós chamamos <literal remap="tt">setItemChecked()</literal> no menu ver, entrada <literal remap="tt">ID&&lowbar;;VIEW&&lowbar;;TOOLBAR</literal> com o nosso atributo. Finalmente, definimos a barra de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm> para utilizar
o valor. Por defeito, a barra de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm> é visível, pelo que, apenas temos de fazer algo se <literal remap="tt">bViewToolbar</literal> for <literal remap="tt">false (falso)</literal>. Com
<literal remap="tt">enableToolBar()</literal> (linha 10) estamos a definir a barra para se esconder automaticamente se for desactivada.</para>

<para>De seguida, temos de ler as posições da barra. Como o utilizador pode ter modificado a posição da barra arrastando-a com o rato para outra
área de cista, esta tem de ser gravada também e o seu estado reposto. Olhando para as classes <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal> e
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KMenuBar</literal></primary></indexterm>KMenuBar</literal>, vemos que as posições da barra podem ser:</para>

<para><screen>enum BarPosition {Top, Left, Bottom, Right, Floating, Flat}
/* {Topo, Esquerda, Baixo, Direita, Flutuante, Fixa} */
</screen>
</para>

<para>Como este valor foi escrito num valor numérico, temos de o ler com <literal remap="tt">readNumEntry()</literal> e converte-lo num valor de posição. Com
<literal remap="tt">setMenuBarPos()</literal> e <literal remap="tt">setBarPos()</literal> dizemos às barrass ode aparecerem.</para>

<para>Agora provavelmente notou que o nosso menu "Ficheiro" contém um menu para ficheiros utilizados recentemente. Os nomes de ficheiros são guardados numa lista de
strings (conjunto de caracteres), que tem de ser gravado ao fecho da aplicação e agora tem de ser lido para repor o menu. Primeiro, inicializamos a lista com
as entradas guardadas utilizando o <literal remap="tt">readListEntry()</literal>. Depois, num ciclo <literal remap="tt">for</literal>, criamos uma entrada de menu para cada item da lista.</para>

<para>Finalmente, apenas temos de tomar conta da geometria da nossa janela. Nós lemos na aparência através de uma variável <literal remap="tt">QSize</literal> contendo um valor x
e y para o comprimento e altura da janela. Como a janela é inicializada através da <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>, não temos de nos preocupar com o
valor de defeito e apenas utilizamos <literal remap="tt">resize()</literal> se a entrada não estiver vazia.</para>

<para>O que resta explicar na construção da nossa aplicação é que inicialmente temos de desactivar comandos do utilizador disponíveis que o não podem estar
no caso de algumas instâncias não corresponderem aos critérios necessários. Estes são gravação de ficheiros e operações que utilizem a área de transferência. Durante
o tempo de vida da aplicação, temos de tomar conta destes várias vezes, mas isso é bastante fácil. A estrutura apenas nos dá dois
métodos para (des)activar itens de barras de menu e ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm> com apenas uma chamada de método de cada vez.</para>
</sect3>

<sect3 id="executar">
<title>Executar</title>

<para>Durante a secção anterior, apenas veriicaos o que acontecia durante a chamada de construção da nossa instância do <literal remap="tt">KScribbleApp</literal> que nos disponibiliza
a janela principal. Após regressar à função <literal remap="tt">main()</literal>, temos de chamar <literal remap="tt">show()</literal> para mostrar a janela. O que é diferente de
qualquer <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> ou <literal remap="tt"><indexterm remap="cdx"><primary><literal>QApplication</literal></primary></indexterm>QApplication</literal> aqui é que quando estamos a utilizar <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> como a instância para o nosso
widget principal, não temos de o definir com <literal remap="tt">setMainWidget()</literal>. isto é feito pelo próprio <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> e não temos de nos
preocupar com isso.
A única coisa que resta então é interpretar a linha de comandos. Obtemos a opção de linha de comandos e perguntamos, se <literal remap="tt">int argc</literal> é &gt; 1, o que
indica que o utilizador chamou a nossa aplicação com <literal remap="tt">kscribble filename&&lowbar;;to&&lowbar;;open</literal>. A nossa janela recebe então o pedido de abertura do ficheiro pelo
se nome e chama <literal remap="tt">openDocumentFile()</literal> com o nome do ficheiro.</para>

<para>A última linha da função <literal remap="tt">main()</literal> faz o trabalho conhecido: executa a instância da aplicação e o programa entra no ciclo de
evento.</para>

<para>Agora, na secção <link linkend="The-main-Function">A Função main()</link>, nós começamos a separar o processo de execução através de
<literal remap="tt">if( app.isRestored() )</literal> e descrevemos o processo normal de invocação. De seguida daremos uma introdução à gestão de
sessão e como a nossa aplicação a utiliza.</para>
</sect3>
</sect2>

<sect2 id="invocao-por-gesto-de-sesso">
<title>Invocação por Gestão de Sessão</title>

<para>Como dissemos, a função <literal remap="tt">main()</literal> testa, se a aplicação foi invocada pelo gostor de sessão. O gestor de sessão é responsável por
gravar o estado actual de todas as janelas de aplicação abertas no ambiente de trabalho do utilizador e tem de os repor quando o utilizador entrar da próxima
vez, o que significa que a aplicação não é iniciada pelo utilizador mas invocada automaticamente. A parte do código executado
foi:
<screen>6    if (app.isRestored())
7    {
8       RESTORE(KScribbleApp);
9    }
</screen>
</para>

<para>Em <link linkend="The-main-Function">A Função main()</link>, nós afirmamos que nós testamos a invocação perguntando à
<literal remap="tt">app.isRestored()</literal>. Depois a linha 8 é executada. Parece uma afirmação simples, mas de facto irá resultar num processo de execução
complexo que queremos seguir nesta secção.</para>

<para>A própria RESTORE() é uma macro disponibilizada pela <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>. Expande-se para o seguinte código:</para>

<para><screen>if (app.isRestored()){
  int n = 1;
  while (KTMainWindow::canBeRestored(n)){
    (new KScribbleApp)-&gt;restore(n);
    n++;
  }
}
</screen>
</para>

<para>Isto irá repor todas as janelas de aplicação da classe <literal remap="tt">KScribbleApp</literal> criando as instâncias e chamando <literal remap="tt">restore()</literal> para a
nova janela. É importante compreender que se a nossa aplicação utiliza vários widgets diferentes que herdam <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>, você tem de
expandir a macro e determinar o tipo de widgets de topo utilizando <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow::classNameOfToplevel(n)</literal> em vez da classe
<literal remap="tt">KScribbleApp</literal>.
O método <literal remap="tt">restore()</literal> lê então a parte do ficheiro de sessão que contém a informação sobre a janela. Como a <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>
guarda tudo isto por nós, não temos de nos preocupar com mais nada. Apenas informação que pertence à nossa instância específica do
<literal remap="tt">KScribbleApp</literal> tem de ser então encontrada. Normalmente isto seria um ficheiro temporário que foi criado para guardar o documento ou outra
initialização de que poderiamos necessitar. Para obter esta informação de reposição, nós apenas temos de passar por cima de dois métodos virtuais de
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal>, <literal remap="tt">saveProperties()</literal> e <literal remap="tt">readProperties()</literal>. A informação que temos de gravar no final da sessão é se o documento
correntemente aberto está ou não modificado e o nome do ficheiro. Se o ficheiro estiver modificado, obteremos um nome de ficheiro temporário para o gravar. No
início da sessão, esta informação é agora utilizada para repor o conteudo do documento:</para>

<para><screen>void KScribbleApp::readProperties(KConfig*)
{
  QString filename = config-&gt;readEntry("filename","");
  bool modified = config-&gt;readBoolEntry("modified",false);
  if( modified ){
    bool b_canRecover;
    QString tempname = kapp-&gt;checkRecoverFile(filename,b_canRecover);

    if(b_canRecover){
      doc-&gt;openDocument(tempname);
      doc-&gt;setModified();
      QFileInfo info(filename);
      doc-&gt;pathName(info.absFilePath());
      doc-&gt;title(info.fileName());
      QFile::remove(tempname);
    }
  }
  else if(!filename.isEmpty()){
  doc-&gt;openDocument(filename);
  }
  setCaption(kapp-&gt;appName()+": "+doc-&gt;getTitle());
}		
</screen>

Aqui, a linha <literal remap="tt">kapp-&gt;checkRecoverFile()</literal> parece um pouco estranha, pois o <literal remap="tt">b&&lowbar;;canRecover</literal> não está inicializado. Isto é feito pelo método
que o define para <literal remap="tt">true</literal>, se existir um ficheiro de reposição. Como apenas gravamos um documento num ficheiro de recuperação se foi modificado, definimos o
bit de modificado directamente para indicar que a informação não foi gravada para o ficheiro correspondente. Também temos de ter em conta que
o ficheiro de recuperação tem outro nome de ficheiro diferente do ficheiro original que foi aberto. Assim, temos de colocar o nome de ficheiro e caminho do antigo
nome de ficheiro. Finalmente, temos a informação que queriamos recuperar e podemos apagar o ficheiro temporário através do gestor de sessão.</para>

<para><emphasis remap="bf">Sumário:</emphasis></para>

<para>Durante este capítulo, ficou a saber como a aplicação se inicia quer por invocação normal do utilizador ou pelo gestor de sessão. Verificamos
todo o código para aprender como as partes do interface visual da aplicação são construidas bem como inicializar os
atributos através de entradas em ficheiros de configuração. Agora podemos executar a aplicação esqueleto para testar estas funções e ver como a
janela do programa reage.</para>
</sect2>
</sect1>

<sect1 id="conteudos-adicionais-de-projectos-kdevelop">
<title>Conteudos Adicionais de Projectos KDevelop</title>

<para>Além do código fonte disponibilizado, os projectos KDevelop contêm imensas outras partes adicionais que são do interesse do programador. Estas
são:
<itemizedlist>
<listitem>
<para>um icon de programa</para>
</listitem>
<listitem>
<para>um mini-icon de programa</para>
</listitem>
<listitem>
<para>um ficheiro .kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>um ficheiro de documentação SGML <indexterm remap="idx"><primary>SGML</primary></indexterm> de exemplo</para>
</listitem>
<listitem>
<para>um conjunto de documentação API <indexterm remap="idx"><primary>API</primary></indexterm> gerada a partir do código do esqueleto</para>
</listitem>
</itemizedlist>
</para>

<para>Excepto a documentação API <indexterm remap="idx"><primary>API</primary></indexterm>, estes elementos do projecto serão instalados juntamente com o binário da aplicação. Como o esqueleto do
projecto tem de ser o mais aberto possível, tem de adaptar estas partes no sentido dos objectivos do seu projecto. Estas são primeiro editar os icons
disponibilizados. Isto dará à sua aplicação um identificador único através do qual o utilizador pode determinar a sua aplicação visualmente em menus de
gestão de janelas. O ficheiro .kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm> é um ficheiro que instala a sua aplicação no <literal remap="tt">kpanel</literal> no menu <literal remap="tt">Aplicações</literal>. Este tem
de ser editado definindo o caminho de instalação que será discutido mais tarde neste manual. Finalmente, a documentação que você irá
disponibilizar ao utilizador está escrita em SGML <indexterm remap="idx"><primary>SGML</primary></indexterm>. Isto torna muito fácil criar várias apresentações diferentes para a mesma fonte. Por defeito,
o KDevelop pode criar um conjunto de ficheiros HTML a partir desta fonte, para projectos KDE isto irá automaticamente utilizar o programa <literal remap="tt">ksgml2html <indexterm remap="idx"><primary>ksgml2html</primary></indexterm></literal>
para adicionar uma aparência e utilização consistente tipo KDE à documentação. Numa secção posterior, iremos ver como a fonte SGML <indexterm remap="idx"><primary>SGML</primary></indexterm> é editada e
o que temos de observar na instalação no utilizador final.</para>

<para>Finalmente, a documentação API <indexterm remap="idx"><primary>API</primary></indexterm> (Interface de Programação da Aplicação) permite-lhe e a outros programadores entender rapidamente o código e utilizar as
classes sem terem de adivinhar qual o objectivo de cada classe. Iremos aprender como expandir a documentação API <indexterm remap="idx"><primary>API</primary></indexterm> num passo posterior,
por ora basta saber que a documentação é gerada pelo programa <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal>, que processa os ficheiros de cabeçalho e cria o
resultado final em HTML, pelo que toda a documentação é colocada nos cabeçalhos.</para>
</sect1>
</chapter>

<chapter id="desenho-de-vista-de-aplicao">
<title>Desenho de Vista de Aplicação</title>

<para>Quando se está a desenvolver uma aplicação com um interface gráfico de utilização, o trabalho principal é feito a disponibilizar a chamada "vista" para a
aplicação. A vista geralmente é um widget que apresenta os dados de um documento e disponibiliza métodos para manipular o conteudo do
documento. Isto pode ser feito pelo utilizador através de eventos que emite pelo teclado ou rato; operações mais complexas são muitas vezes
processadas pelas barras de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm> e menus que interagem com a vista e o documento. A barra de estados apresenta informação sobre o estado
do documento, vista ou aplicação. Como exemplo, olhamos para como um editor está construido e onde podemos encontrar cada parte.</para>

<para>Um editor é suposto geralmente disponibilizar um interface para o utilizador ver e/ou modificar o conteudo de um documento de texto. Se você
iniciar o <emphasis>KEdit</emphasis>, vê o interface visual da seguinte forma:</para>

<para><itemizedlist>
<listitem>
<para>A barra de menu: disponibiliza operações complexas bem como abrir, gravar e fechar ficheiros e sair da aplicação.</para>
</listitem>
<listitem>
<para>A barra de ferramentas <indexterm remap="idx"><primary>ferramentas</primary></indexterm>: oferece icons que permitem um acesso rápido para as funções mais necessárias,</para>
</listitem>
<listitem>
<para>A barra de estados: apresenta o estado da posição do cursor através da linha e coluna actuais,</para>
</listitem>
<listitem>
<para>A vista no centro da janela, apresentando um documento e oferecendo um cursor conectado ao teclado e rato
para trabalhar sobre os dados.</para>
</listitem>
</itemizedlist>
</para>

<para>Agora é fácil compreender, que uma vista é uma parte única da aplicação e que o desenho da vista decide sobre a
usabilidade e aceitação de uma aplicação. Isto significa que um dos primeiros passos no desenvolvimento é determinar o objectivo da
aplicação e que tipo de desenho lhe iria mais de encontro para permitir a qualquer utilizador trabalhar com a aplicação com um mínimo de
trabalho de aprendizagem de como utilizar o interface gráfico.</para>

<para>Para alguns objectivos como edição de texto e apresentação de ficheiros HTML, as vistas são disponibilizadas pelas bibliotecas Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> e KDE <indexterm remap="idx"><primary>KDE</primary></indexterm>; iremos discutir alguns
aspectos destes widgets de alto-nível na próxima secção. Mas para a maioria das aplicações novos widgets têm de ser desenhados e implementados. É
isso que faz um programador e também um desenhador e onde as suas capacidades em criatividade são necessárias. De qualquer modo, deverá procurar a
intuição primeiro. Lembre-se que imensos utilizadores não aceitarão uma aplicação que não seja</para>

<para><itemizedlist>
<listitem>
<para>bonita graficamente,</para>
</listitem>
<listitem>
<para>oferece imensas funcionalidades,</para>
</listitem>
<listitem>
<para>fácil de utilizar,</para>
</listitem>
<listitem>
<para>rápida de aprender como utilizar.</para>
</listitem>
</itemizedlist>

Desnecessário dizer que a estabilidade é um dos objectivos principais. Ninguém pode impedir erros de código, mas um mínimo pode ser atingido pelo menos por objectivos de desenho
inteligentes e a utilização de desenho orientado por objectos. C++ torna a programação um prazer se você souber como explorar as suas capacidades- hereditariedade,
ocultação de informação e reutilização de código já existente.</para>

<para>Quando se cria um projecto KDE ou Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, você tem sempre de ter uma vista que herda <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>, quer por herança directa ou porque
a biblioteca do widget que quer utilizar herda <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>. Assim, o Assistente de Aplicação já constroi a vista que é uma
instância da classe <literal remap="tt">&&lt;;yourapp&&gt;;View</literal>, que já herda <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>. A aplicação cria a sua vista no método
<literal remap="tt">initView()</literal>, onde uma instãncia é criada e conectada com o widget principal como sua vista com  <literal remap="tt">KTMainWidget::setView()</literal>.</para>

<para>Este capítulo descreve assim como utilizar bibliotecas de widgets para criar vistas de aplicações KDE ou Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> que são geradas com o
KDevelop, depois iremos observar as bibliotecas e que tipos de vistas são já oferecidas.</para>

<sect1 id="utilizar-bibliotecas-de-vistas">
<title>Utilizar Bibliotecas de Vistas</title>

<para>Quando o desenho da sua aplicação estiver definido, você deverá primeiro procurar código já existente que fará a sua vida muito mais simples. Uma
parte desta busca é a procura de um widget que possa ser utilizado como vista ou pelo menos parte dela; quer directamente ou por hereditariedade.
As bibliotecas KDE e Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> já contêm um conjunto de widgets que podem ser utilizados para este propósito. Para os utilizar, você tem duas opções:</para>

<para><orderedlist><listitem>
<para> remover a nova classe de cista e criar uma instância de um widget de biblioteca; depois defini-lo como vista,</para>
</listitem>
<listitem>
<para> modificar a hereditariedade da classe de vista disponibilizada para a classe do widget de biblioteca a utilizar.</para>
</listitem>
</orderedlist>
</para>

<para>De qualquer uma das formas, é importante saber que se a estrutura de aplicação não está actualmente ligada a nenhuma biblioteca que contenha o
widget, o linker irá falhar. Depois de se decidir a utilizar um certo widget, procure a biblioteca a linkar; depois abra
"Projecto"-&gt;"Opções" na barra de menu do KDevelop. Vá para a página "Opções do Linker" e procure as caixas de selecção que indiquem as
bibliotecas que estão correntemente a serem utilizadas. Se a biblioteca do seu widget de vista já estiver seleccionada, pode deixar as opções do projecto intocadas
e começar a fazer as alterações necessárias devido à sua escolha. Caso contrário, a opção de linker permite adicionar a biblioteca através de uma caixa de selecção,
active-a e prima "OK" para sair de novo do diálogo de opções do projecto. Em qualquer outro caso, adicione a biblioteca na linha de edição por baixo da
opção <literal remap="tt">-l</literal>. Para bibliotecas que a sua aplicação tem de procurar antes de preparar os ficheiros Makefiles através do script <literal remap="tt">configure</literal> na
máquina do utilizador final, adicione a seguinte macro de procura ao ficheiro <literal remap="tt">configure.in</literal>  localizado na raiz do directório do seu projecto e
adicione a macro à linha de edição. Lembre-se que tem de correr "Construir"-&gt;"Autoconf e automake" e "Construir"-&gt;"Configurar" antes
dos Makefiles conterem as expansões correctas para a macro de biblioteca.</para>

<para>Também, se os ficheiros inclued para a biblioteca a adicionar não estiverem no caminho actual de include (que pode ser visto pela opção <literal remap="tt">-I</literal> na
janela de output ao fazer "Make"), tem de adicionar o caminho no diálogo de Opções de Projecto -página "Opções de Compilador" com a opção <literal remap="tt">-I</literal>
ou a correspondente macro de automake na linha de edição para "Opções Adicionais".</para>

<sect2 id="qt-qt-views">
<title>Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Views</title>

<para>Looking at the first page of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> online documentation, you will find a link to "Widget Screenshots" where you can have a look at
how the widgets Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> contains look like. These are ready to use and can be combined together to form complex widgets to create
application views or dialogs. In the following, we'll discuss some of these which are very usable for creating application views, but
keep in mind that the KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> sometimes contain other widgets for the same purpose; those will be reviewed in the next section.</para>

<para>Here are a set of hints for what purpose you could use which Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> component:
<orderedlist><listitem>
<para>if your view area isn't big enough to display all your data, the user must be enabled to scroll over the document with bars on
the left and bottom of the view. For this, Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> provides the class <literal remap="tt">QScrollView</literal>, which offers a scrollable child area. As explained,
you could inherit your own widget from <literal remap="tt">QScrollView</literal> or use an instance to manage your document's view widget.</para>
</listitem>
<listitem>
<para>to create a ScrollView yourself, inherit the View widget from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> and add vertical and horizontal <literal remap="tt">QScrollBar</literal>s.
(this is done by KDE`s KHTMLView widget).</para>
</listitem>
<listitem>
<para>for text processing, use <literal remap="tt">QMultiLineEdit</literal>. This class provides a complete text editor widget that is already capable to cut,
copy and paste text and is managed by a scrollview.</para>
</listitem>
<listitem>
<para>use <literal remap="tt">QTableView</literal> to display data that is arranged in a table. As <literal remap="tt">QTableView</literal> is managed by scrollbars as well, it offers a
good solution for table calculation applications.</para>
</listitem>
<listitem>
<para>to display two different widgets or two widget instances at the same time, use <literal remap="tt">QSplitter</literal>. This allows to tile views by
horizontal or vertical dividers. Netscape's Mail window is a good example how this would look like- the main view is separated by a
splitter vertically, the right window then is divided again horizontally.</para>
</listitem>
<listitem>
<para><literal remap="tt">QListView</literal> displays information in a list and tree. This is useful for creating file trees or any other hierarchical
information you want to interact with.</para>
</listitem>
</orderedlist>
</para>

<para>You see that Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> alone offers a whole set of widgets which are ready to use so you don't have to invent new solutions if these match
your needs. The sideffect when using standard widgets is that users already know how to handle them and only have to concentrate on
the displayed data.</para>
</sect2>

<sect2 id="kde-views">
<title>KDE Views</title>

<para>The KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> were invented to make designing applications for the K Desktop Environment easier and capable of more functionality
than what Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> alone is offering. To see what's available, we have a look at the documentation tree in KDevelop. You see that the KDE
libraries start with <literal remap="tt">kdecore</literal>, which is a base for all KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm>. Then,<literal remap="tt">kdeui</literal> offers user interface elements. This is
where we will find some useful things first. For creating new applications, the <literal remap="tt">kdeui</literal> library offers:</para>

<para><orderedlist><listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KTabListBox</literal></primary></indexterm>KTabListBox</literal>: offers a multi-column list box where the user can change the rows with drag'n drop <indexterm remap="idx"><primary>drag'n drop</primary></indexterm>.</para>
</listitem>
<listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KTreeList</literal></primary></indexterm>KTreeList</literal>: inherited from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QTableView</literal></primary></indexterm>QTableView</literal>, offering a collapsible tree. This could be used instead of
<literal remap="tt">QListView</literal>.</para>
</listitem>
<listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KEdit</literal></primary></indexterm>KEdit</literal>: the base classes for the <emphasis>KEdit</emphasis> application offered with KDE. This could be used instead of
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QMultiLineEdit</literal></primary></indexterm>QMultiLineEdit</literal>.</para>
</listitem>
<listitem>
<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KNewPanner</literal></primary></indexterm>KNewPanner</literal>: manage two child widgets like <literal remap="tt"><indexterm remap="cdx"><primary><literal>QSplitter</literal></primary></indexterm>QSplitter</literal>.</para>
</listitem>
</orderedlist>
</para>

<para>The <literal remap="tt">khtmlw</literal> library on the other hand offers a complete HTML-interpreting widget that is ready to use. It is scrollable already,
so you don't even have to take care for that. A possible use could be to integrate it as a preview widget for an HTML editor; used by
applications such as KFM, KDEHelp <indexterm remap="idx"><primary>KDEHelp</primary></indexterm> and KDevelop to display HTML files.</para>
</sect2>
</sect1>

<sect1 id="creating-your-own-views">
<title>Creating your own Views</title>

<para>Now that you have a general overview of what is already provided, you may notice that for a lot of purposes already existing widgets
can be used or combined together. KMail is an example as well as KDevelop itself makes use of library view components to display data.</para>

<para>For applications that use a special file format or have to deal with graphics, you are probably forced to create your own view widget
to allow data manipulation. This is realized in our sample by the class <literal remap="tt">KScribbleView</literal>, already providing a base for a view area.</para>

<para>The inheritance from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> is necessary to overwrite the virtual methods to process user events, this is probably the most work
besides providing popup menus for easier access of certain functions. Also it is likely that you have to implement a set of slots which
can be accessed by toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> buttons or menu bar commands to connect to as well as methods to manipulate variables such as e.g. a painter
color.</para>

<para>For completeness, we will repeat the necessary methods:</para>

<para><emphasis remap="bf">a) Keyboard events --TAB and Shift-TAB keys:</emphasis></para>

<para>changes the keyboard input focus from the current widget to the next widget in the focus order. The focus can be set to widgets by
calling <literal remap="tt">setFocusPolicy<indexterm remap="ncdx"><primary><literal>setFocusPolicy()</literal></primary></indexterm>()</literal> and process the following event handlers:</para>

<para><itemizedlist>
<listitem>
<para><literal remap="tt">virtual void focusInEvent<indexterm remap="ncdx"><primary><literal>focusInEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QFocusEvent</literal></primary></indexterm>QFocusEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void focusOutEvent<indexterm remap="ncdx"><primary><literal>focusOutEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QFocusEvent</literal></primary></indexterm>QFocusEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">b) all other keyboard input:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void keyPressEvent<indexterm remap="ncdx"><primary><literal>keyPressEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void keyReleaseEvent<indexterm remap="ncdx"><primary><literal>keyReleaseEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QKeyEvent</literal></primary></indexterm>QKeyEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">c) mouse movements:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void mouseMoveEvent<indexterm remap="ncdx"><primary><literal></literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void enterEvent<indexterm remap="ncdx"><primary><literal>enterEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void leaveEvent<indexterm remap="ncdx"><primary><literal>leaveEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QEvent</literal></primary></indexterm>QEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">d) mouse button actions:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void mousePressEvent<indexterm remap="ncdx"><primary><literal>mousePressEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void mouseReleaseEvent<indexterm remap="ncdx"><primary><literal>mouseReleaseEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void mouseDoubleClickEvent<indexterm remap="ncdx"><primary><literal>mouseDoubleClickEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMouseEvent</literal></primary></indexterm>QMouseEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">e) window events containing the widget:</emphasis>
<itemizedlist>
<listitem>
<para><literal remap="tt">virtual void moveEvent<indexterm remap="ncdx"><primary><literal>moveEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QMoveEvent</literal></primary></indexterm>QMoveEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void resizeEvent<indexterm remap="ncdx"><primary><literal>resizeEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QResizeEvent</literal></primary></indexterm>QResizeEvent * )</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">virtual void closeEvent<indexterm remap="ncdx"><primary><literal>closeEvent()</literal></primary></indexterm> ( <indexterm remap="cdx"><primary><literal>QCloseEvent</literal></primary></indexterm>QCloseEvent * )</literal></para>
</listitem>
</itemizedlist>
</para>

<para>When re-implementing these functions, you should watch certain issues to avoid implementation mistakes that will make it almost
impossible to change the widget's behavior afterwards:</para>

<para><orderedlist><listitem>
<para>declare your virtual methods as <emphasis remap="bf">virtual</emphasis> as well and keep the access to protected. This allows code-reuse by inheritance and
is consistent.</para>
</listitem>
<listitem>
<para>don't hard-code any event-processing which should be made configurable. This counts most for keyboard events which should be
realized with keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s if any function is called. This even counts for text processing ! (Imagine that a lot of users are
familiar with their favorite editor's behavior. If this is configurable, they can use the behavior they like and are used to)</para>
</listitem>
<listitem>
<para>forward popup menu highlighting signals to the main widget to enable statusbar help</para>
</listitem>
</orderedlist>
</para>
</sect1>
</chapter>

<chapter id="configuring-menubars-and-toolbars">
<title>Configuring Menubars and Toolbars</title>

<para>Menubars and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s are one of the most important parts of an application to provide methods to work with a document structure. As a
general rule, you should make all functions available by the menubar. Those methods that should not be available at a current stage of
the application process should be disabled.</para>

<para>Further, an application can only contain one menubar, but several toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s. Toolbars on the other hand should contain only the most
frequently used commands by pixmap icons or provide quick access methods like combos to select values.</para>

<sect1 id="how-does-it-work">
<title>How does it work ?</title>

<para>Each entry, may it be a menuentry or a toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> item, has a resource ID which is an integer value. As these values can't be used twice,
those are set by macros, where the numeric values are replaced by a descriptive ID name that can be used in your sources then.</para>

<para>All resource ID's are collected in the file <literal remap="tt">resource.h</literal>, where you can keep an overview over the used values. Anyway, the compiler
will inform you if you've used a value twice for constructing entries. Also, the resource file should contain all menu accelerator<indexterm><primary>accelerator</primary></indexterm>s by
IDK macro replacements. An example:</para>

<para><programlisting>(resource.h)

#define ID_VIEW_TOOLBAR             12010


(kscribble.cpp)

// menu entry Toolbar in the "view" menubar menu
view_menu-&gt;insertItem(i18n("&&amp;;Toolbar"), ID_VIEW_TOOLBAR);
</programlisting>
</para>

<para>This inserts the entry Toolbar to the View popup menu of the menubar in the kscribble application. The resource ID's name is held to
contain the menu name and the action's name visible. The ampersand is set in front of the letter that functions as a keyboard
accelerator<indexterm><primary>accelerator</primary></indexterm> and the entry itself is embraced by the i18n() internationalization macro.</para>

<para>On activating the menu item, the commandCallback() switch is called with the ID number. There, you have to add an according comparator
value with the method you want to execute on activating the menuentry:</para>

<para><programlisting>    case ID_VIEW_TOOLBAR:
    	slotViewToolBar();
    	break;</programlisting>
</para>

<para><note remap="comment"><para>Note: you don't have to use the ID system. If no ID is given, the menu gets numbered automatically. The KDevelop framework
uses this as it allows accessing menu and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> ID's to create <literal remap="tt">switch</literal> statements that select the slot to call on
<literal remap="tt">activated()</literal> for menus, <literal remap="tt">clicked()</literal> for toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> buttons. The connection can also be made directly using the provided methods of
the classes providing menus and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s.</para></note></para>
</sect1>

<sect1 id="adding-a-new-menu">
<title>Adding a new menu</title>

<para>A new menubar is added to an application by the following:</para>

<para><orderedlist><listitem>
<para>add a pointer to the new menu in the App-class header</para>
</listitem>
<listitem>
<para>call the constructor of <literal remap="tt"><indexterm remap="cdx"><primary><literal>QPopupMenu</literal></primary></indexterm>QPopupMenu</literal> to the pointer in <literal remap="tt">initMenuBar()</literal> at the location where your menubar should appear
later.</para>
</listitem>
<listitem>
<para>insert the according menu-items into the popup menu and set their resource ID's in the resource file</para>
</listitem>
<listitem>
<para>add connects for <literal remap="tt">commandCallback()</literal> and <literal remap="tt">statusCallback()</literal> to the menu at the end of <literal remap="tt">initMenuBar()</literal></para>
</listitem>
<listitem>
<para>add the methods you want to call by the menu-entries in the header and implementation file.</para>
</listitem>
<listitem>
<para>add the switch statements for the entries to the <literal remap="tt">commandCallback()</literal> and <literal remap="tt">statusCallback()</literal> methods</para>
</listitem>
</orderedlist>
</para>
</sect1>

<sect1 id="integrating-toolbar-buttons">
<title>Integrating Toolbar buttons</title>

<para>Toolbar buttons can be added like menu-entries with the difference that the used method is <literal remap="tt">insertButton()</literal> and takes a button
pixmap and tool-tip text instead of a menu text.</para>

<para>The icons you want to use can be loaded by <literal remap="tt">KIconLoader</literal>, where <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> offers the macros <literal remap="tt">ICON()</literal> and <literal remap="tt">Icon()</literal> to
access the icon loader and load the icon. These macros take the filename of the pixmap as their parameter to load the icon from the KDE
file system in a certain order (see <literal remap="tt">KIconLoader</literal> for the search order).</para>

<para>The KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> also offer a set of toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> buttons that can be used for standard actions. In cases where they don't meet your needs,
you will have to paint your own pixmaps. KDevelop supports this by selecting "New" from the "File" menu, then select Pixmap as the file
type. Usually you will place your toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> pixmaps in a project subdirectory "toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>" and install them into your application specific
toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> directory.</para>
</sect1>

<sect1 id="configuring-statusbars">
<title>Configuring Statusbars</title>

<para>The KDevelop projects already make use of the statusbar by providing statusbar messages for menu-entries and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> buttons. When
adding a menuentry, also add your status message in the method <literal remap="tt">statusCallback()</literal>.</para>

<para><literal remap="tt">statusCallback()</literal> uses the method <literal remap="tt">slotStatusHelpMsg()</literal> to display a statusbar message for two seconds. When executing a
command, you should use the method <literal remap="tt">slotStatusMsg()</literal> at the beginning with the string describing what your application does; before
a return or method end, you should reset the statusbar message with a "Ready." string calling the same method.</para>
</sect1>

<sect1 id="keyboard-accelerator-configuration">
<title>Keyboard Accelerator Configuration</title>

<para>A very professional thing you should always add to your application are keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s. Those are mainly used by experienced
users that want to work fast with their applications and are willing to learn shortcut<indexterm><primary>shortcuts</primary></indexterm>s. For this, the KDE libraries <indexterm remap="idx"><primary>KDE libraries</primary></indexterm> provide the class
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal>, which provides the keyboard accelerator<indexterm><primary>accelerator</primary></indexterm> keys and access to global configured standard keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s.</para>

<para>By default, frame applications generated by KDevelop only use standard keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s such as F1 for accessing online-help,
Ctrl+N for New File etc. You should look for the keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s already set in <literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal> first before adding a new
accelerator<indexterm><primary>accelerator</primary></indexterm>.</para>

<para>If your application contains a lot of accelerator<indexterm><primary>accelerator</primary></indexterm>s, you should make them configurable by an Options-menu; either it could be combined
with other application configuration in a <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> or stand alone. The KDE library already provides a <literal remap="tt">KKeyChooser</literal> for use
in tab dialogs, whereas <literal remap="tt">KKeyDialog</literal> provides a ready-to use key-configuration dialog.</para>

<para>See the following classes for more information:</para>

<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal>(<indexterm remap="cdx"><primary><literal>kdecore</literal></primary></indexterm>kdecore), <literal remap="tt"><indexterm remap="cdx"><primary><literal>KKeyChooser</literal></primary></indexterm>KKeyChooser</literal>, <literal remap="tt"><indexterm remap="cdx"><primary><literal>KKeyDialog</literal></primary></indexterm>KKeyDialog</literal> (<indexterm remap="cdx"><primary><literal>kdeui</literal></primary></indexterm>kdeui)</para>
</sect1>
</chapter>

<chapter id="the-dialogeditor-where-your-dialogs-are-buil">
<title>The Dialogeditor: Where your Dialogs are Build</title>

<sect1 id="what-the-dialogeditor-provides">
<title>What the Dialogeditor provides</title>

<para>The built-In dialogeditor of KDevelop is designed to help you construct widgets and dialogs that fit your application's purpose and
reduces the time rapidly to extend the GUI of your application. The only limitation for now is that the dialogeditor does not support
geometry management that is provided by Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>; therefore the dialogs are static in their size and this may lead to certain circumstances
where e.g. the label width is not long enough to support the full length of a translation.</para>

<para>On the other hand, the current state of the editor in conjunction with KDevelop's project management offers the fastest way to create
full-featured applications for the K Desktop Environment.</para>
</sect1>

<sect1 id="qt-qt-and-kde-widgets">
<title>Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> and KDE Widgets</title>

<para>Currently provided widgets are:</para>

<para><emphasis remap="bf">QT-Widgets:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</emphasis> - a widget that can be specified by yourself and can contain other widgets as well. This allows creating a widget
hierarchy within your dialog.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm></emphasis> - a label that represents text information on the widget. Use QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm> e.g. in front of lineedits to signal what the
purpose of the line-edit is or which variable e.g. a combo box allows to set.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QPushButton</emphasis> - a button that allows to e.g. call another dialog like QFileDialog for selecting a filename.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QCheckBox</emphasis> - a check box for e.g. enabling/disabling options. QCheckBox is widely used for configuration dialogs.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QLCDNumber</emphasis> - displays numbers in LCD style. Often used for clocks.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QRadioButton</emphasis> - like QCheckBox often used to let the user set any options. QRadioButton specializes the options setting when more
of them depend on each other, e.g. you have three radio-buttons, but you want the user to choose one of three offered options. See
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QButtonGroup</literal></primary></indexterm>QButtonGroup</literal> for additional information.</para>
</listitem>
<listitem>
<para><emphasis remap="bf"><indexterm remap="cdx"><primary><literal>QComboBox</literal></primary></indexterm>QComboBox</emphasis> - a combo box lets the user set a value by selecting it from a
drop-down menu or by inserting the value, if the box is write enabled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QListBox</emphasis> - provides a single-column list of items that can be scrolled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QListView</emphasis> - creates a multi-column list view that can be used to display e.g. file trees etc. in tree and table view.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QMultiLineEdit</emphasis> - offers a multi-line editor.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QProgressBar</emphasis> - displays the progress of an action that takes a longer time to be finished.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QSpinBox</emphasis> - allows choosing numeric values by up- and down buttons or insertion if write enabled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QSlider</emphasis> - sets a value in a program-defined range by a slider.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QScrollBar</emphasis> - indicates the range of a value and sets the current value by a slider as well as up- and down buttons; often
used for widgets whose contents is larger than the actually visible view area. By using the scrollbar, the visible area can be changed
to another part of the widgets' contents.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">QGroupBox</emphasis> - provides a group box frame with title to indicate that child widgets within the box belong together.</para>
</listitem>
</itemizedlist>
</para>

<para><emphasis remap="bf">KDE-Widgets:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">KColorButton</emphasis> - a pushbutton displaying a selected color. On a button press, the KDE Color dialog is shown where the user can
select another color. Often used for drawing applications or in any case where color values can be set.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KCombo</emphasis> - similar to <literal remap="tt"><indexterm remap="cdx"><primary><literal>QComboBox</literal></primary></indexterm>QComboBox</literal>. Lets the user choose a value by a drop-down list box.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KDatePicker</emphasis> - a complete widget to get a date value by the user.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KDateTable</emphasis> - a calendar table to select a date of a month. Used by <literal remap="tt">KDatePicker</literal> to build the date picker dialog.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KKeyButton</emphasis> - a button to select a key value. If the button is selected, it gets activated. Pressing a keyboard button will
change the key value for the button which can be used to configure key-bindings.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KLed</emphasis> - and LED (Light Emitting Diode) widget to display a certain state.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KLedLamp</emphasis> - and LED lamp that also supports click actions</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KProgress</emphasis> - similar to <literal remap="tt">QProgressBar</literal>, <literal remap="tt">KProgress</literal> supports certain other values.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KRestrictedLine</emphasis> - a <literal remap="tt">QLineEdit</literal> that only accepts certain user input. This can be used to restrict access to certain data
by password dialogs.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KSeparator</emphasis> - a separator widget to be used in all cases where KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm> require a separator to provide a unique look.
Often used in dialogs to separate logical parts where <literal remap="tt">QGroupBox</literal> doesn't fit.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KTreeList</emphasis> - a collapsible list view to display trees similar to <literal remap="tt">QListView</literal>.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="properties-of-qt-qt-supported-widgets">
<title>Properties of Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> supported Widgets</title>

<para>The following chapter gives a complete overview over the currently supported widgets of the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> toolkit. To achieve a better
understanding of the properties, these are separated to their inheritance. As all of them inherit <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>, this class is described
first. All <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> properties are available for all other widgets as well, so these are not listed for them again. For widget groups
that inherit an abstract subclass of <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> as their base-class, the base-classes' properties are listed first (though this class does
not provide a widget in the dialogeditor itself). Then the widget properties for the available widget of the group contains the
properties that are specific to it. For a better understanding the inheritance tree of the available widgets is listed below:</para>

<para><itemizedlist>
<listitem>
<para><link linkend="QWidget">&lt;cdx/QWidget/</link>
<itemizedlist>
<listitem>
<para><link linkend="QButton">&lt;cdx/QButton/</link> (abstract)
<itemizedlist>
<listitem>
<para><link linkend="QCheckBox">QCheckBox</link></para>
</listitem>
<listitem>
<para><link linkend="QPushButton">QPushButton</link></para>
</listitem>
<listitem>
<para><link linkend="QRadioButton">QRadioButton</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QComboBox">&lt;cdx/QComboBox/</link></para>
</listitem>
<listitem>
<para><link linkend="QFrame">QFrame</link> (abstract for now)
<itemizedlist>
<listitem>
<para><link linkend="QGroupBox">QGroupBox</link></para>
</listitem>
<listitem>
<para><link linkend="QLCDNumber">QLCDNumber</link></para>
</listitem>
<listitem>
<para><link linkend="QLabel">&lt;idx/QLabel/</link></para>
</listitem>
<listitem>
<para><link linkend="QProgressBar">QProgressBar</link></para>
</listitem>
<listitem>
<para><link linkend="QScrollView">QScrollView</link> (abstract for now)
<itemizedlist>
<listitem>
<para><link linkend="QListView">QListView</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QSpinBox">QSpinBox</link></para>
</listitem>
<listitem>
<para><link linkend="QTableView">QTableView</link> (abstract)
<itemizedlist>
<listitem>
<para><link linkend="QListBox">QListBox</link></para>
</listitem>
<listitem>
<para><link linkend="QMultiLineEdit">QMultiLineEdit</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QLineEdit">QLineEdit</link></para>
</listitem>
<listitem>
<para><link linkend="QScrollBar">QScrollBar</link></para>
</listitem>
<listitem>
<para><link linkend="QSlider">QSlider</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>

<sect2 id="qwidget">
<title><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget Properties </title>

<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> is the base class for almost all widgets in Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> and KDE. Therefore widgets that inherit <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> will allow to use the same
settings in most cases.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Appearance:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">BgColor:</emphasis> Background color of the widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">BgMode:</emphasis> Background mode of the widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">BgPalColor:</emphasis> Color pallette for the background</para>
</listitem>
<listitem>
<para><emphasis remap="bf">BgPixmap:</emphasis> filename for a background pixmap</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Cursor:</emphasis> Cursor over the widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Font:</emphasis> Font for the widget</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaskBitmap:</emphasis> filename for a masking bitmap.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">C++ Code:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">AcceptsDrops:</emphasis> if set to true, the widget item will accept drops by drag'n drop <indexterm remap="idx"><primary>drag'n drop</primary></indexterm> mechanisms (Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> drag'n drop <indexterm remap="idx"><primary>drag'n drop</primary></indexterm>
protocol, not KDE 1.x !)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Connections:</emphasis> connects the item's signals to slots</para>
</listitem>
<listitem>
<para><emphasis remap="bf">FocusProxy:</emphasis> the item that gives its focus to this widget.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">HasFocus:</emphasis> sets if the item has the focus by default. Mind that only one item per dialog can have this value as true</para>
</listitem>
<listitem>
<para><emphasis remap="bf">ResizeToParent:</emphasis> resizes the widget to its parent's size (not visible in editing mode)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">VarName:</emphasis> Variable name of the item. Change this to names that describe the item's purpose.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">IsEnabled:</emphasis> sets if the widget will accept user events</para>
</listitem>
<listitem>
<para><emphasis remap="bf">IsHidden:</emphasis> sets the item to be visible(false) or hidden(true)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Name:</emphasis> sets the name of the widget. Mind that the name is different from the VarName in C++ Code.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Geometry:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Height:</emphasis> height of the item</para>
</listitem>
<listitem>
<para><emphasis remap="bf">IsFixedSize:</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaxHeight:</emphasis> maximum value for Height</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaxWidth:</emphasis> maximum value for Width</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinHeight:</emphasis> minimum value for Height</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinWidth:</emphasis> minimum value for Width</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SizeIncX:</emphasis> pixel steps for resize actions to X direction</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SizeIncY:</emphasis> pixel steps for resize actions to Y direction</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Width:</emphasis> width of the item</para>
</listitem>
<listitem>
<para><emphasis remap="bf">X:</emphasis> position horizontal, counted from the left corner</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Y:</emphasis> position vertical, counted up to down</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="qbutton">
<title><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton inherited widgets </title>

<para><literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal> is an abstract widget class that provides properties common to buttons.</para>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link></para>

<para>Inherited by <link linkend="QCheckBox">QCheckBox</link>, <link linkend="QPushButton">QPushButton</link> and <link linkend="QRadioButton">QRadioButton</link> inherit <literal remap="tt"><indexterm remap="cdx"><primary><literal>QButton</literal></primary></indexterm>QButton</literal>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Appearance:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setPixmap:</emphasis> sets the pixmap filename to use</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setText:</emphasis> the text on labels, buttons and boxes, also pre-set text for lineedits.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">setAutoRepeat:</emphasis> if enabled, the clicked() signal is emitted at regular intervals while the button is down. No effect on
toggle buttons.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">setAutoResize:</emphasis> Enables auto-resizing if TRUE. When auto-resize is enabled, the button will resizes itself
whenever the contents changes.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>

<sect3 id="qcheckbox">
<title>QCheckBox Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <link linkend="QButton">&lt;cdx/QButton/</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isChecked: (setChecked)</emphasis> defines is the checkbox is set checked on construction</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qpushbutton">
<title>QPushButton Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <link linkend="QButton">&lt;cdx/QButton/</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isAutoDefault: (setAutoDefault)</emphasis> the auto-default button becomes the default push button if it receives the keyboard input focus.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isDefault: (setDefault)</emphasis> there can be only one default button and it is only allowed to use in a dialog (see <literal remap="tt">QDialog</literal>). The
default button emits <literal remap="tt">clicked()</literal> if the user presses the Enter key.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isMenuButton: (setIsMenuButton)</emphasis> tells the button to draw
a menu indication triangle if enabled. The menu has to be inserted separately.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isToggleButton::(setToggleButton)</emphasis> makes a push button a toggle button, so the button has a similar state as check
boxes.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isToggledOn: (setOn)</emphasis> (public slot) switches a toggle button on.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qradiobutton">
<title>QRadioButton Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <link linkend="QButton">&lt;cdx/QButton/</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isChecked: (setChecked)</emphasis> defines is the radio button is set checked on construction</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>
</sect2>

<sect2 id="qcombobox">
<title><indexterm remap="cdx"><primary><literal>QComboBox</literal></primary></indexterm>QComboBox Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link></para>

<para>( no additional properties for now)</para>
</sect2>

<sect2 id="qframe">
<title>QFrame inherited widgets </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link></para>

<para>For now only used as an abstract class.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Appearance:</emphasis>
<itemizedlist>
<listitem>
<para>Margin (setMargin): sets the margin, which is the distance from the innermost pixel of the frame and the outermost pixel of the
contents.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>

<sect3 id="qgroupbox">
<title>QGroupBox Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Title: (setTitle)</emphasis> sets the group box title that is displayed in the box frame.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qlcdnumber">
<title>QLCDNumber Properties  </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">NumDigits:(setNumDigits)</emphasis> sets the number of digits displayed in QLCDNumber</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value: (display)</emphasis> (public slot) sets the initial value for QLCDNumber</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qlabel">
<title>QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm> Properties  </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Appearance:</emphasis>
<itemizedlist>
<listitem>
<para>Margin (setMargin): sets the margin, which is for QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm> the distance from the frame to the first letter of the label text,
depending on the alignment of the label.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">C++ Code: </emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Buddy: (setBuddy)</emphasis> sets the buddy widget of the label.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Text: (setText)</emphasis> sets the label text.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoResize: (setAutoResize)</emphasis> if TRUE, the label will resize itself if the contents changes. The top left corner is not
moved.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qprogressbar">
<title>QProgressBar Properties  </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">TotalSteps: (setTotalSteps)</emphasis> (public slot) sets the total steps of the progress bar. During the iteration of your action to
display the progress, you have to call setProgress(int) to advance the progress step displayed to (int).</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qscrollview">
<title>QScrollView </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <link linkend="QFrame">QFrame</link></para>

<para>Inherited by <link linkend="QListBox">QListBox</link>
(abstract for now)</para>

<para>Provides a scrollable widget that manages the display of a child widget by a vertical and horizontal scrollbar.</para>

<sect4 id="qlistview">
<title>QListView</title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link>, <link linkend="QFrame">QFrame</link> and <link linkend="QListView">QListView</link></para>

<para>Provides a list view to display hierarchical data either in a table or a tree. Manages itself by scrollbars through <link linkend="QScrollView">QScrollView</link>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">Appearance:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">ListViewFont:</emphasis> (setFont()) Sets the font of the ListView items</para>
</listitem>
<listitem>
<para><emphasis remap="bf">ListViewPalette:</emphasis> (setPalette()) Sets the palette of the list view items</para>
</listitem>
<listitem>
<para><emphasis remap="bf">TreeStepSize:</emphasis> (setTreeStepSize(int)) Offset of pixels of a child item to its parent item</para>
</listitem>
<listitem>
<para><emphasis remap="bf">hScrollBarMode:</emphasis> Scrollbar mode provided by <link linkend="QScrollView">QScrollView</link> for the horizontal scrollbar</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAllColumnsShowFocus:</emphasis> (setAllColumnsShowFocus(bool)) displays focus on all columns of an item.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isMultiSelection:</emphasis> enables multi-selection of list items</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isRootDecorated:</emphasis> enables the + and - decoration to open and close trees</para>
</listitem>
<listitem>
<para><emphasis remap="bf">vScrollBarMode:</emphasis>Scrollbar mode provided by <link linkend="QScrollView">QScrollView</link> for the vertical scrollbar</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Entries:</emphasis> lets you insert a list of entries that are pre-set as QListViewItems.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate:</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect4>
</sect3>

<sect3 id="qspinbox">
<title>QSpinBox Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <link linkend="QFrame">QFrame</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">MaxValue:</emphasis>  the maximum value the user can choose</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinValue:</emphasis>  the minimum value the user can choose</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Prefix:</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">Suffix:</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value:</emphasis>     the pre-set value when the widget is shown</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isWrapping:</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect3>

<sect3 id="qtableview">
<title>QTableView inherited widgets </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link>, <link linkend="QFrame">QFrame</link> and <link linkend="QTableView">QTableView</link></para>

<para>Inherited by <link linkend="QListBox">QListBox</link> and <link linkend="QMultiLineEdit">QMultiLineEdit</link></para>

<sect4 id="qlistbox">
<title>QListBox Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link>, <link linkend="QFrame">QFrame</link> and <link linkend="QTableView">QTableView</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">isAutoBottomScrollBar: (setAutoBottomScrollBar)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoScroll: (setAutoScroll)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoScrollBar: (setAutoScrollBar)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate: (setAutoUpdate)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isBottomScrollBar: (setBottomScrollBar)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isDragSelect: (setDragSelect)</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isSmoothScrolling: (setSmoothScrolling)</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Geometry:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setFixedVisibleLines:</emphasis> sets a fixed height for the widget so that the given number of text lines are displayed using the
current font.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect4>

<sect4 id="qmultilineedit">
<title>QMultiLineEdit Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link>, <link linkend="QFrame">QFrame</link> and <link linkend="QTableView">QTableView</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Text: (setText) </emphasis> (public slot) sets the text of the widget.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate: (setAutoUpdate)</emphasis> used to avoid flicker during large changes; the view is not updated if disabled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isOverWriteMode: (setOverwriteMode) </emphasis>(public slot) sets overwrite enabled or disabled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isReadOnly: (setReadOnly)</emphasis> (public slot) sets the widget text to read only; disables text input.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTextSelected: (selectAll)</emphasis>(public slot) marks the whole text selected</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Geometry:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">setFixedVisibleLines:</emphasis> sets a fixed height for the widget so that the given number of text lines are displayed using the current font.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect4>
</sect3>
</sect2>

<sect2 id="qlineedit">
<title>QLineEdit Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link></para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">CursorPosition: (setCursorPosition)</emphasis> sets the default cursor position.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MaxLength: (setMaxLength) </emphasis> sets the maximum string length</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Text: (setText) </emphasis> (public slot) sets the contents displayed on construction</para>
</listitem>
<listitem>
<para><emphasis remap="bf">hasFrame: (setFrame) </emphasis> draws the line edit within a two-pixel frame if enabled.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTextSelected: (selectAll) </emphasis> (public slot) sets the text to be selected.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="qscrollbar">
<title>QScrollBar Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <literal remap="tt">QRangeControl</literal>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">MaxValue:</emphasis> sets the maximum slider value; used in constructor (optional)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinValue:</emphasis> sets the minimum slider value; used in constructor (optional)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Orientation: (setOrientation)</emphasis> sets the orientation of the scrollbar to horizontal or vertical.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value: </emphasis> sets the initial value of the scrollbar in the constructor (optional)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTracking: (setTracking)</emphasis> if enabled, the scrollbar emits <literal remap="tt">valueChanged()</literal> whenever the bar is dragged; otherwise only on
mouse release.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="qslider">
<title>QSlider Properties </title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link> and <literal remap="tt">QRangeControl</literal>.</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">General:</emphasis>
<itemizedlist>
<listitem>
<para><emphasis remap="bf">MaxValue:</emphasis> sets the maximum slider value; used in constructor (optional)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">MinValue:</emphasis> sets the minimum slider value; used in constructor (optional)</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Orientation: (setOrientation)</emphasis> sets the orientation of the slider to horizontal or vertical.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Value: (setValue)</emphasis> (public slot) uses <literal remap="tt">QRangeControl::setValue()</literal> to set the value.</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTracking:(setTracking)</emphasis> if enabled, the slider emits <literal remap="tt">valueChanged()</literal> whenever the slider is dragged; otherwise only on
mouse release.</para>
</listitem>
</itemizedlist>

</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>

<sect1 id="properties-of-kde-supported-widgets">
<title>Properties of KDE supported Widgets</title>

<para><itemizedlist>
<listitem>
<para><link linkend="QWidget">&lt;cdx/QWidget/</link>
<itemizedlist>
<listitem>
<para><link linkend="QButton">&lt;cdx/QButton/</link> (abstract)
<itemizedlist>
<listitem>
<para><link linkend="QPushButton">QPushButton</link>
<itemizedlist>
<listitem>
<para><link linkend="KColorButton">KColorButton</link></para>
</listitem>
<listitem>
<para><link linkend="KKeyButton">KKeyButton</link></para>
</listitem>
</itemizedlist>
		</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QComboBox">&lt;cdx/QComboBox/</link>
<itemizedlist>
<listitem>
<para><link linkend="KCombo">KCombo</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QFrame">QFrame</link> (abstract for now)
<itemizedlist>
<listitem>
<para><link linkend="KDatePicker">KDatePicker</link></para>
</listitem>
<listitem>
<para><link linkend="KLedLamp">KLedLamp</link></para>
</listitem>
<listitem>
<para><link linkend="KProgress">KProgress</link></para>
</listitem>
<listitem>
<para><link linkend="KSeparator">KSeparator</link></para>
</listitem>
<listitem>
<para><link linkend="QTableView">QTableView</link> (abstract)
<itemizedlist>
<listitem>
<para><link linkend="KDateTable">KDateTable</link></para>
</listitem>
<listitem>
<para><link linkend="KTreeList">KTreeList</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="QLineEdit">QLineEdit</link>
<itemizedlist>
<listitem>
<para><link linkend="KRestrictedLine">KRestrictedLine</link></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para><link linkend="KLed">KLed</link></para>
</listitem>
</itemizedlist>
</para>

<sect2 id="kcolorbutton">
<title>KColorButton</title>

<para>Inherits <link linkend="QPushButton">QPushButton</link></para>

<para><itemizedlist>
<listitem>
<para>General
<itemizedlist>
<listitem>
<para><emphasis remap="bf">DisplayedColor (setColor())</emphasis> the displayed color on the button</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="kkeybutton">
<title>KKeyButton</title>
	<para></para>
</sect2>

<sect2 id="kcombo">
<title>KCombo</title>

<para>Inherits: <link linkend="QComboBox">&lt;cdx/QComboBox/</link></para>

<para><itemizedlist>
<listitem>
<para>General
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Entries</emphasis> the string list of entries displayed in the combo box</para>
</listitem>
<listitem>
<para><emphasis remap="bf">Text</emphasis> the text displayed in the combo box currently</para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoResize</emphasis> resizes the combo box to the current item</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="kdatepicker">
<title>KDatePicker</title>

<para><itemizedlist>
<listitem>
<para>Appearance
<itemizedlist>
<listitem>
<para><emphasis remap="bf">FontSize</emphasis> the font size for the date picker</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="kledlamp">
<title>KLedLamp</title>
	<para></para>
</sect2>

<sect2 id="kprogress">
<title>KProgress</title>
	<para></para>
</sect2>

<sect2 id="kseparator">
<title>KSeparator</title>

<para><itemizedlist>
<listitem>
<para>General
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Orientation</emphasis> sets the orientation of the separator to horizontal or vertical; default is horizontal</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="kdatetable">
<title>KDateTable</title>
	<para></para>
</sect2>

<sect2 id="ktreelist">
<title>KTreeList</title>

<para><itemizedlist>
<listitem>
<para>Appearance
<itemizedlist>
<listitem>
<para><emphasis remap="bf">TreeListBgColor</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">TreeListPalette</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isBottomScrollbar</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isScrollBar</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isShowItemText</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isSmoothScrolling</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isTreeDrawing</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>General
<itemizedlist>
<listitem>
<para><emphasis remap="bf">Entries</emphasis></para>
</listitem>
<listitem>
<para><emphasis remap="bf">isAutoUpdate</emphasis></para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>

<sect2 id="krestrictedline">
<title>KRestrictedLine</title>
	<para></para>
</sect2>

<sect2 id="kled">
<title>KLed</title>

<para>Inherits <link linkend="QWidget">&lt;cdx/QWidget/</link></para>

<para><itemizedlist>
<listitem>
<para>Appearance
<itemizedlist>
<listitem>
<para><emphasis remap="bf">LedColor: (setColor())</emphasis> sets the displayed LED color</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>

<sect1 id="constructing-a-new-dialog">
<title>Constructing a new Dialog</title>

<para>Constructing a new dialog is very easy if you already have experience with graphical construction applications. KDevelop offers to
create a widget visually and displays the look as it will be shown to the user directly. Further, you can have a preview of your widget
by selecting "Preview" from the "View" menu.</para>

<para>To begin constructing a dialog or any other widget, switch to the Dialogeditor and select "New Dialog" from the "File" menu. Then enter
all needed information to the "New Dialog" dialog. Those are:</para>

<para><orderedlist><listitem>
<para>The Dialog inheritance. This is necessary because any widget is at least derived from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>. Besides the widget types
provided by Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>, you can inherit e.g. form an abstract base class you constructed yourself within your project. In this case, select
"custom" and enter the header file path to the line edit below.</para>
</listitem>
<listitem>
<para>The Dialog name. This sets the class name of the generated dialog. Select a classname that is descriptive for what the dialog
does; in cases of inheritance from <literal remap="tt">QDialog</literal>, you may enter a name that ends with <literal remap="tt">Dlg</literal> to remember yourself it's a dialog.
Naming convention should match that of KDE and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>: Use uppercase letters for your classname. For e.g. a grid-size selection dialog, you
would enter <literal remap="tt">GridSizeDlg</literal>.</para>
</listitem>
<listitem>
<para>The generated filenames. Those are preset when entering the dialog name, but can be changed afterwards. If you want to use other
filenames, the naming convention should also match that of KDE and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>: the filenames are all lowercase and contain the classname to
remember what class is kept where. The data file that has to be set will later contain the generated code that will build up your
dialog. You should not edit this file manually afterwards; use the implementation file for any additions towards dialog construction
code and method implementations.</para>
</listitem>
</orderedlist>
</para>

<para>The dialog will then show itself as a widget with a grid. As the dialogeditor uses the grid to snap any child widgets to the geometry,
you can change the grid size with the "Grid Size" entry in the "View" menu, if the preset values don't match your needs.</para>

<para>Then select the "Widgets" tabulator on the left pane and press the button for the widget item you want to add to the main widget. It
directly appears on the main widget's left upper corner and gets selected by a resizable frame. Then move or resize the widget with the
mouse. The cursor will change to indicate which action can be done at the current position.</para>

<para>After having finished the construction, select "Generate Files" from the "Build" menu or hit the according toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> button. The files
will then be generated at the preset location and included into your project sources. A rebuild or make will compile all generated
files within your project and you can add the according constructor call to the application to invoke the dialog or widget. For KDE
projects, all widget properties that will be visible later, e.g. label texts, are set with the <literal remap="tt">i18n()</literal> macro of <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> to
support internationalization. Therefore you should do a "Make Messages and merge" when finished with construction and implementation.</para>

<para>When creating a dialog or widget, you should watch the following guidelines:
<itemizedlist>
<listitem>
<para>Always try to be consistent! This is probably the most important rule when constructing GUI elements. Mind that the user will
only accept an application that is easy to understand no matter how complex it's purpose may be.</para>
</listitem>
<listitem>
<para>Add help wherever you can by tool-tips, What's this..? help or Quick-help. This allows getting direct information about the
purpose of the GUI elements.</para>
</listitem>
<listitem>
<para>watch the <emphasis remap="bf">keyboard focus <indexterm remap="idx"><primary>keyboard focus</primary></indexterm></emphasis> !  The generator does not take care of that- this has to be watched when constructing any widget;
otherwise you have to reorder your initialization code by hand which is a very unthankful job. The keyboard focus <indexterm remap="idx"><primary>keyboard focus</primary></indexterm> on any widget means
the oder on which items get the keyboard input focus when the user presses the tab and shift+tab button. It would be very annoying if
the focus changes everywhere but not to the next widget visible below or to the right of the current widget. Therefore start
constructing your widget top down from left to right to ensure the consistency of the focus.</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="setting-widget-properties">
<title>Setting Widget Properties</title>

<para><indexterm><primary>widget properties</primary></indexterm><indexterm><primary>dialogeditor</primary></indexterm><indexterm><primary>properties window</primary></indexterm>
Widget properties can be set easily with the properties window entries. When a widget gets selected, the properties window
automatically updates to the properties of the current widget. As all widgets are derived from <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal>, you can set the
<literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> properties plus an amount of properties that are specific to the selected widget. Properties can be:</para>

<para><itemizedlist>
<listitem>
<para>Integer values, such as the geometry of a widget or the font size</para>
</listitem>
<listitem>
<para>Boolean values to enable/disable certain parameters of the widget. Set with combos containing true and false</para>
</listitem>
<listitem>
<para>enumerable values of a widget, e.g. the palette. Set with combos containing all possible values</para>
</listitem>
<listitem>
<para>Color values for e.g. the displayed color. Set with the KDE Color Dialog</para>
</listitem>
<listitem>
<para>Font values for e.g. labels. Be careful to set Font values other than the default because this may prevent KDE from updating the
font. Set with the KDE Font Dialog</para>
</listitem>
<listitem>
<para>File names for e.g. background pixmaps. Do not use gif images here as these may get
unsupported by further Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> versions &gt; 1.42</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="integrating-the-dialog">
<title>Integrating the Dialog</title>

<para>Whenever you created a widget, you probably want to add it to the project to execute the action it is designed for. As a widget can be
constructed for several purposes, we will watch for two cases: a <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> inherited widget and a <literal remap="tt">QDialog</literal> one.</para>

<sect2 id="qwidgetqwidget-inherited">
<title><literal remap="tt"><indexterm remap="cdx"><primary><literal>QWidget</literal></primary></indexterm>QWidget</literal> inherited</title>

<para>Let's say you created a widget that will be part of the main view. If it fills the whole view area, you have to add an instance pointer
to the header declaration of your <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> instance replacing the currently set view widget. Then change the code in the
<literal remap="tt">initView</literal> method to set this widget the main view. Additionally, you could remove the View class of the generated project, but mind
that the document instance and the App instance depends on the view class. In this case, it is technically a much better way to create
a mini-KDE application and construct your <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> instance yourself.</para>

<para>More often the widget is intended to be a part of the view area, which means it is combined with other widgets. This can be done by
using one of the following classes that provide a divider to separate two widgets:</para>

<para><orderedlist><listitem>
<para><literal remap="tt">QSplitter</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">KPanner</literal></para>
</listitem>
<listitem>
<para><literal remap="tt">KNewPanner</literal></para>
</listitem>
</orderedlist>
</para>

<para>If the main view shall contain more than two widgets, you have to use another instance of the divider as one of the two managed widgets
by the first one. Then add the according widgets to each panner and set the first panner the view area.</para>
</sect2>

<sect2 id="qdialog-inherited">
<title><literal remap="tt">QDialog</literal> inherited</title>

<para>If your widget inherits <literal remap="tt">QDialog</literal>, it is probably intended to change one or more values; often this is used to set the application
preferences. To invoke the dialog, you have to add a slot to the <literal remap="tt">App</literal> class by adding the method declaration and the implementation
body. Then add the constructor call to the method as well as a call to <literal remap="tt">show()</literal> or <literal remap="tt">exec()</literal> the dialog. Finally, you should take
care for processing the results of the dialog; this can either be done by the dialog who changes values of the parent widget itself or
by retrieving the values from the dialog (which would make your dialog a lot more reusable in other projects). Mind that you should call
<literal remap="tt">delete</literal> if you called the dialog instance with <literal remap="tt">new</literal> to avoid memory leaks.</para>

<para>Finally, you have to connect a menuentry (with according statusbar help) to the new slot invoking the dialog; optionally a keyboard
accelerator<indexterm><primary>accelerator</primary></indexterm> and a toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> icon. For this, add a resource ID to the file <literal remap="tt">resource.h</literal> with a define. Then add
an according menuentry to one of the popup menus already present in the menubar or create a new popup to add your menuentry. The
menuentry consists of:</para>

<para><itemizedlist>
<listitem>
<para>an optional icon pixmap. Call this with the <literal remap="tt">Icon("iconname.xpm")</literal> macro of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> to use the provided
<literal remap="tt">KIconLoader</literal> instance.</para>
</listitem>
<listitem>
<para>the menuentry name. Add this with the <literal remap="tt">i18n("&&amp;;entryname")</literal> macro of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> to allow
internationalization. The ampersand should be in front of the letter that will be displayed underlined to access the entry directly by
keyboard acceleration.</para>
</listitem>
<listitem>
<para>the member instance to call. Normally this would be the <literal remap="tt">this</literal> pointer.</para>
</listitem>
<listitem>
<para>the member slot to call. Use <literal remap="tt">SLOT(yourmethod()</literal> to call the slot on the signal <literal remap="tt">activated()</literal>.</para>
</listitem>
<listitem>
<para>the accelerator<indexterm><primary>accelerator</primary></indexterm> key. This should be set to zero as this is done by an entry in <literal remap="tt">initKeyAccel()</literal> where you
have to introduce an accelerator<indexterm><primary>accelerator</primary></indexterm> key together with the slot to call. Then call <literal remap="tt">changeMenuAccel()</literal> to change the
menu item's accelerator<indexterm><primary>accelerator</primary></indexterm>. This will make it configurable by a key-chooser dialog later. For standard actions, use the
enumerable values given by <literal remap="tt"><indexterm remap="cdx"><primary><literal>KAccel</literal></primary></indexterm>KAccel</literal>. </para>
</listitem>
<listitem>
<para>the menu ID as set in <literal remap="tt">resource.h</literal></para>
</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
</chapter>

<chapter id="printing-support">
<title>Printing Support</title>

<para><indexterm remap="ncdx"><primary><literal>QPrinter</literal></primary></indexterm><indexterm remap="ncdx"><primary><literal>QPainter</literal></primary></indexterm><indexterm remap="ncdx"><primary><literal>QPrintdialog</literal></primary></indexterm><indexterm><primary>printing</primary></indexterm>
Printing is usually provided by your application to let the user create a printed version of the document he created with the
application; therefore only needed for those programs that are used to produce something the user may want to print out, e.g. text or
pictures. In any case, this requires an interface that is provided by the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> library by two classes: the <literal remap="tt">QPrintDialog</literal> class,
offering the printing dialog, and the <literal remap="tt">QPainter</literal> class that is also used to draw the widget's contents usually. As the view-class of
an application is responsible for displaying a document, it also is responsible for printing.</para>

<sect1 id="the-qt-qt-print-dialog">
<title>The Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Print Dialog</title>

<para>The Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Printer dialog can be used including <literal remap="tt">qprintdialog.h</literal>. When using the KDE framework application, this is already used by the
view class, so you only have to complete the implementation of the method <literal remap="tt">print()</literal> by using <literal remap="tt">QPainter</literal>.</para>
</sect1>

<sect1 id="the-qpainter-class">
<title>The QPainter Class</title>

<para>Independent of the printer's capabilities, you can use <literal remap="tt">QPainter</literal> to draw your document onto the printer provided by <literal remap="tt">QPrinter</literal>
like you would when drawing onto a widget. The only difficulty would be where you have to implement the way things have to be printed.</para>
</sect1>
</chapter>

<chapter id="help-functions">
<title>Help Functions</title>

<para>A very important part of the development process is to provide help functionality to the user wherever possible. Most developers tend
to delay this, but you should remember that a normal user isn't necessarily a Unix-expert. He may come from the the dark side of
computer software usage offering all sweets that a user may need to work himself into using an application even without ever touching
the manuals. Therefore, the KDE and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> library provide all means usually considered making an application professional in the eyes of
the normal user by help functions that are ready to use. Within the application, those are:</para>

<para><itemizedlist>
<listitem>
<para>Tool-Tips</para>
</listitem>
<listitem>
<para>Quick-Help</para>
</listitem>
<listitem>
<para>Statusbar help</para>
</listitem>
<listitem>
<para>What's this...? buttons</para>
</listitem>
</itemizedlist>
</para>

<para>Additionally, the application should provide means to access a HTML-based online manual directly using the standard help key F1.</para>

<para>As KDevelop also offers all types of help as well as the KDE framework generated by the application wizard already contains support for
this, this chapter will help you find out where and how to add your help functionality.</para>

<para>During the development of your application you should try to be consistent whatever you're doing; therefore you should do the necessary
steps directly while extending the code. This will prevent you from diving into the code again and figuring out what your application
does or what you intended by certain parts of the code.</para>

<sect1 id="tool-tips">
<title>Tool-Tips</title>

<para>A very easy mean of providing help are tool-tips. Those are small help messages popping up while the user moves the mouse over a widget
that provides a tool-tip and disappears when the mouse moves away. The most popular usage of tool-tips is made in toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s where your
tool-tips should be kept as small as possible because toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>s can be configured to display their contents in various ways: either
displaying the button, button with text on the right, button with text below, text only.  This possibility should be made configurable
by the user, but isn't a must-be. The text is shown as a tool-tip anyway and a toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> usually consists of buttons and other widgets
like lineedits and combo boxes. For a complete reference, see the <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal> class reference located in the KDE-UI library.</para>

<para>As an example, we have a look at the the "New File" button in a generic application:</para>

<para><screen>toolBar()-&gt;insertButton(Icon("filenew.xpm"), ID_FILE_NEW, true, i18n("New File") );
</screen>

<indexterm remap="ncdx"><primary><literal>toolBar()</literal></primary></indexterm><indexterm><primary>KToolBar</primary></indexterm>
There, the part <literal remap="tt">i18n("New File")</literal> provides a tool-tip message. It is enclosed by the i18n() macro provided by <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> to
translate the tool-tip towards the currently selected language.</para>

<para>Tool-tips can also be added to any custom widget by using the classes <literal remap="tt">QToolTip</literal> and <literal remap="tt"><indexterm remap="cdx"><primary><literal>QToolTipGroup</literal></primary></indexterm>QToolTipGroup</literal> provided by Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>.
An example of that would be:</para>

<para><screen>QToolTip::add( yourwidget, i18n("your Tip") );
</screen>

For more information, see the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm>-Online Reference, class <literal remap="tt"><indexterm remap="cdx"><primary><literal>QToolTip</literal></primary></indexterm>QToolTip</literal>.</para>
</sect1>

<sect1 id="adding-quick-help">
<title>Adding Quick-help</title>

<para>Quick-Help windows are another good example of providing help. The user can access the quick-help over a widget that it is connected to
by pressing the right mousebutton and selecting "Quick-Help" in the context menu. Therefore, Quick-Help can be placed somewhere in
between a detailed handbook reference help and tool-tips- the documentation would be too extensive and a tool-tip would not provide
enough information. To see how Quick-Help works, open any dialog within KDevelop and press the right mouse button over a dialog item.
Then select the Quick-Help menuentry and you're offered the help message. Additionally, those messages can be formatted by color, font
and even can be used for containing URL's to refer a certain webpage (and therefore can refer to the documentation handbook as well).</para>

<para>To make use of Quick-Help, add the include file <literal remap="tt"><indexterm remap="cdx"><primary><literal>kquickhelp.h</literal></primary></indexterm>kquickhelp.h</literal> to your sourcefile containing quick-help. As the
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KQuickHelp</literal></primary></indexterm>KQuickHelp</literal> class is part of the KDE-UI library, it should already be used by your application; if not, set the linker flags
of your project to use kdeui.</para>

<para>An example would be:</para>

<para><screen>KQuickHelp::add( yourwidget, i18n("your Tip") );
</screen>
</para>

<para>which is almost the same as with QToolTip. When constructing a dialog with the KDevelop dialogeditor, add your tool-tips and Quickhelp
in the implementation file- NOT within the data sourcefile as this is rebuild by the dialogeditor every time you edit the widget.</para>

<para>The <literal remap="tt"><indexterm remap="cdx"><primary><literal>KQuickHelp</literal></primary></indexterm>KQuickHelp</literal> class provides also formatting text by using tags. It allows hyperlinks including Internet protocols, colors,
font types and sizes. See the <ulink url="kde_libref.html">KDE Library Reference Guide</ulink> and the class documentation <indexterm remap="idx"><primary>class documentation</primary></indexterm> for
<literal remap="tt"><indexterm remap="cdx"><primary><literal>KQuickTip</literal></primary></indexterm>KQuickTip</literal> for more information.</para>
</sect1>

<sect1 id="extending-the-statusbar-help">
<title>Extending the Statusbar Help</title>

<para>As the frame applications provided by KDevelop contain a statusbar as well, it also offers a set of statusbar messages already for all
menu and toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> items. A statusbar help message is a short message that extends the meaning of a tool-tip or can be seen as a
replacement for a tool-tip over menubar items and is (as the name suggests) displayed in the statusbar when the user enters a menu and
highlights the menu entry; therefore all menu items connect their signal <literal remap="tt">highlighted(int)</literal> to the method <literal remap="tt">statusCallback(int)</literal>
which selects the according message in a switch statement. Whenever you add a menuitem to already existing menus or a toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>
item, add an according entry in this method with a short description of the action the user will cause when activating the button or
menuentry.</para>

<para>Example:</para>

<para><screen>    case ID_FILE_NEW:
 	  	slotStatusHelpMsg(i18n("Creates a new document"));
 	  	break;
</screen>
</para>

<para>This will display a statusbar message by calling the method <literal remap="tt">slotStatusHelpMsg()</literal> with the according translated help string whenever
the user highlights a menu or toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> item with the id ID&&lowbar;;FILE&&lowbar;;NEW that is connected to the <literal remap="tt">statusCallback()</literal> method.
Toolbars connect to this method by their signal <literal remap="tt">pressed(int)</literal>, which allows the user to press the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> button and move away the
mouse when he doesn't want to invoke the command. <literal remap="tt"><indexterm remap="cdx"><primary><literal>KToolBar</literal></primary></indexterm>KToolBar</literal> also offers the signal <literal remap="tt">highlighted(int, bool)</literal> which can be used to
display the message whenever the user highlights the button instead of the preset signal used.</para>
</sect1>

<sect1 id="the-whats-this...-button">
<title>The "What's This...?" Button</title>

<para>The "What's This...?" <indexterm remap="idx"><primary>"What's This...?"</primary></indexterm> button provides help windows like Quickhelp<indexterm><primary>KQuickHelp</primary></indexterm>, but with the intention that the user wants to
get help about a certain widget within the working view or a toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> item. It is placed in the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> and gets activated
once the user hits the button. The cursor changes to an arrow cursor with a question mark like the button itself looks like. The the
user can press on a visible widget item and gets a help window. As an exercise, you could try this behavior with the What's this...?
button within KDevelop.
To add the What's This...? button, do the following:</para>

<para><orderedlist><listitem>
<para>include <literal remap="tt">qwhatsthis.h</literal> into your sourcecode</para>
</listitem>
<listitem>
<para>add a private member <literal remap="tt"><indexterm remap="cdx"><primary><literal>QWhatsThis</literal></primary></indexterm>QWhatsThis</literal> whats&&lowbar;;this/ or with another member name to your <literal remap="tt"><indexterm remap="cdx"><primary><literal>KTMainWindow</literal></primary></indexterm>KTMainWindow</literal> derived class
declaration </para>
</listitem>
<listitem>
<para>define a resource id for your what's this button into the <literal remap="tt">resource.h</literal> file,e.g. <literal remap="tt">&&num;;define ID&&lowbar;;HELP&&lowbar;;WHATS&&lowbar;;THIS
10100</literal></para>
</listitem>
<listitem>
<para>in your method to create the toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> (usually <literal remap="tt">initToolBar()</literal>), add at the location you want to have the button
displayed:
<screen>  whats_this = new QWhatsThis;
  QToolButton *btnwhat = whats_this-&gt;whatsThisButton(toolBar());
  QToolTip::add(btnwhat, i18n("What's this...?"));
  toolBar()-&gt;insertWidget(ID_HELP_WHATS_THIS, btnwhat-&gt;sizeHint().width(), btnwhat);
  btnwhat-&gt;setFocusPolicy(QWidget::NoFocus);
</screen>

<indexterm remap="ncdx"><primary><literal>setFocusPolicy()</literal></primary></indexterm></para>
</listitem>
<listitem>
<para>finally, add the messages you want to have on a click over a certain widget like this:
<screen>whats_this-&gt;add(class_tree, i18n("Class Viewer\n\n"
                                  "The class viewer shows all classes, methods and variables "
                                  "of the current project files and allows switching to declarations "
                                  "and implementations. The right button popup-menu allows more specialized "
                                  "functionality."));
</screen>
</para>
</listitem>
</orderedlist>
</para>
</sect1>
</chapter>

<chapter id="extending-the-documentation-with-sgml-sgml">
<title>Extending the Documentation with SGML <indexterm remap="idx"><primary>SGML</primary></indexterm></title>

<para>Due to the fact that projects often lack a complete set of user documentation, all KDevelop projects contain a pre-build handbook that
can be easily adapted; therefore fulfilling another goal of KDE: providing enough online-help to support users that are not familiar
with an application. This chapter therefore introduces you on how to extend the provided documentation template and what you have to do
to make it available to the user.</para>

<sect1 id="why-sgml">
<title>Why SGML ?</title>

<para>SGML <indexterm remap="idx"><primary>SGML</primary></indexterm> (Standard Generalized Markup Language) itself is a language with which one can write specifications of a markup language,
but not a markup language itself. The specification for that markup language is called a DTD (Document Type Definition) which contains
the structure of a document and the valid tags to use. Then, an SGML system provides a set of replacement files that translate the DTD
tags into the desired output - and this is the way it works. The most used output is probably HTML to provide online help through
web-browsers in a time where Internet standards are available even on single-desktop systems. KDE makes extensive use of HTML
documentation by it's KDEHelp <indexterm remap="idx"><primary>KDEHelp</primary></indexterm> application where all KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm> are listed and give access to their user manuals as
well as by a helpmenu where the user can access the online-help directly from within the application.</para>

<para>Now, KDE (and therefore KDevelop) use the SGML-Tools 1.x package (see <ulink url="http://www.sgmltools.org">\|\|</ulink>), which was formerly known
as the LinuxDoc package. It contains a DTD called <literal remap="tt">LinuxDoc</literal>, and a set of mapping files for various output transformations and the
necessary tools that actually do the replacement of <literal remap="tt">LinuxDoc</literal> tags. The LinuxDoc DTD is based on the Qwertz DTD which itself was
written to provide a good mapping (replacement of tags) especially for the &latex; text system, therefore is very usable to produce a
good printed output. The package then got it's name from the usage for writing documentation for the LDP (Linux Documentation Project)
and has only changed it's name due to the fact that it is an sgml-system that does not necessarily have a direct connection with the
Linux project but can be used on any Unix-System; you can as well write your own DTD and mappings if you ever like to.</para>

<para>In the meantime, another DTD as been made up to fit the same purpose: the "DocBook DTD". DocBook has obviously some advantages over the
LinuxDoc DTD mostly in providing better tags and mappings for tables and the inclusion of graphics, but that is possible with LinuxDoc
as well. The SGML-Tools therefore switched to provide support for the DocBook DTD in the 2.x version series, which also includes a
converter to produce a DocBook sgml from a LinuxDoc master.</para>

<para>The current state of KDE development is that we're still using the LinuxDoc DTD for some reasons:
<itemizedlist><listitem>
<para>writing LinuxDoc documentation is easy</para>
</listitem>
<listitem>
<para>installing the SGML-Tools 1.x for using LinuxDoc is even much easier</para>
</listitem>
<listitem>
<para>KDE provides an additional tool called <literal remap="tt">ksgml2html</literal> which adds the KDE documentation style to the output produced by the
SGML-Tools' 1.x <literal remap="tt">sgml2html</literal> converter to produce HTML output.</para>
</listitem>
</itemizedlist></para>

<para>I personally have encountered that while writing the KDevelop handbooks using the LinuxDoc DTD is very easy and lasts for the
requirements I need for writing the documentation. The learning curve is very high, so you will be a sgml-tools/LinuxDoc DTD guru
within days and that will save you a lot of time to work yourself into any formatting system such as &tex; for printed output for your
documentation or a markup language for HTML output.</para>

<para>One major reason for still using the sgml-tools 1.x is that most distributions ship with the package and all additional tools you need
for other output formats. This makes the installation as easy as possible and the writing itself isn't very complicated as you will
see. The output formats you can achieve witht the sgml-tools are:</para>

<para><itemizedlist>
<listitem>
<para>HTML output, with KDE look'n feel when using <literal remap="tt">ksgml2html</literal> additionally</para>
</listitem>
<listitem>
<para>plain text</para>
</listitem>
<listitem>
<para>GNU info,</para>
</listitem>
<listitem>
<para>Lyx format</para>
</listitem>
<listitem>
<para>&tex;, DVI, PostScript and PDF format</para>
</listitem>
<listitem>
<para>Rich Text Format (RTF)</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="what-the-documentation-already-contains">
<title>What the Documentation already contains</title>

<para>When creating a KDevelop project, the subdirectory <literal remap="tt">docs/en</literal> already contains the english <literal remap="tt">index.sgml</literal> documentation file and
the already produced output HTML files. Those are already included into the project as well as their installation destination is preset
to the KDE HTML directory. The documentation is already adapted to your project name, version number and the programmer's information.
Further, the output covers the index.html file containing the table of contents (which is opened by KDE Help when the user requests
help); an installation introduction and a copyright information with regards to the GPL license.</para>

<para>Therefore, when extending the documentation, you only have to add the information that is specifically to your project. Mind that for
KDE projects you have to run "Make Doc-Handbook" from the "Project" menu again after the project is created. The index.sgml file is
again processed by <literal remap="tt">ksgml2html <indexterm remap="idx"><primary>ksgml2html</primary></indexterm></literal> and the KDE-Style is added to the HTML output. Open the <literal remap="tt">docs/en</literal> directory in the RFV
and add the <literal remap="tt">logotp3.gif</literal> file to the project by the context-menu; then set the file properties correctly to install the logo file
into the same location the HTML files will go - to <literal remap="tt">$(kde&&lowbar;;htmldir)/en/&&lt;;your&&lowbar;;project&&gt;;/logotp3.gif</literal>.</para>
</sect1>

<sect1 id="writing-sgml-documentation">
<title>Writing SGML Documentation</title>

<para>This section has been added because SGML (or to be more precise: the LinuxDoc DTD) still seems to be difficult for beginners that want
to write documentation. When looking at some KDE applications, I have seen some that contain an sgml file which is the template - but
the author went over to edit the html output instead of the sgml file. This results in problems that translators have - if they want to
provide documentation for your application in their native language, they will have to edit each file as well in HTML and this makes it
impossible to reuse the documetation for other formats not only in the english version but all internationalized versions as well. You
see that this is very short-thinking and a bad situation; personally I think that this results from the author's knowledge of HTML but
not of SGML. As most will try to avoid learning a new formatting language, they will use the HTML output as the template that they
edit. If you once find out how easy (and useful) SGML with LinuxDoc is, you will know that it's worth to learn a few more tags that
built the SGML formatting.</para>

<para>The following sections will therefore introduce you to the most important parts of an LinuxDoc sgml file and how to extend your
documentation.</para>

<sect2 id="the-dtd-declaration">
<title>The DTD Declaration</title>

<para>An SGML file, whatever DTD it may use, always has to start with the DTD declaration. This tells the SGML parser about which DTD to use.
Therefore, the first tag (a bracketed expression like &&lt;;yourtag&&gt;; your contents &&lt;;/yourtag&&gt;;) is always the DOCTYPE:</para>

<para><literal remap="verb">&&lt;;!doctype linuxdoc system&&gt;;</literal></para>

<para>That tells your sgml formatter that it shall use the LinuxDoc DTD.</para>

<sect3 id="the-document-structure">
<title>The Document Structure</title>

<para>Now, when using the LinuxDoc, the next tag is the start tag for the document style type. The LinuxDoc DTD offers a whole set of types
that you can select from, dependent on the purpose of your document or it's legth. Available formats are:</para>

<para><itemizedlist>
<listitem>
<para><literal remap="tt">&&lt;;notes&&gt;;</literal> for short explanations</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;article&&gt;;</literal> for writing articles with abt. 10-20 pages (suggested). This is used by the templates of KDevelop and most KDE
applications.</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;report&&gt;;</literal> for articles that are longer than an &&lt;;article&&gt;; type</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;book&&gt;;</literal> for writing large books - the KDevelop handbooks have been written using this document type</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;slides&&gt;;</literal> for slideshows. This is useful for presentations. You will use &latex; as output format in most cases, of
course.</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;letter&&gt;;</literal> for normal letters</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;telefax&&gt;;</literal> for a telefax</para>
</listitem>
<listitem>
<para><literal remap="tt">&&lt;;manpage&&gt;;</literal> for a manpage</para>
</listitem>
</itemizedlist>
</para>

<para>Mind that these are only describing how the document structure will look like in general - not the actual output. As mentionend, the
KDevelop default generated template is using the &&lt;;article&&gt;; structure. This is used by most applications except KDevelop itself
which uses the &&lt;;book&&gt;; format. In the HTML output this doesn't really matter much - but for &latex; e.g. this makes much difference.
The handbooks are really "books" with separate pages for each chapter as the main difference.</para>

<para>What follows is that the end of the sgml file must have an end-tag for the document structure type - for &&lt;;article&&gt;; this would be
&&etago;;article&&gt;;.</para>
</sect3>
</sect2>

<sect2 id="titlepages">
<title>Titlepages</title>

<para>Now, after the document structure follows a section that describes all entries usually found on a titlepage. The predefined template
doesn't use this explicitely but only sets the information for <literal remap="tt">&&lt;;title&&gt;;</literal>, <literal remap="tt">&&lt;;author&&gt;;</literal> and <literal remap="tt">&&lt;;date&&gt;;</literal> as this
lasts for most purposes. Especially when using a <literal remap="tt">&&lt;;book&&gt;;</literal> structure, you probably want to define a complete titlepage. The
following lists the according tags for this, taken from the sgml source of this handbook:</para>

<para><programlisting>&&lt;;!doctype linuxdoc system&&gt;;
&&lt;;book&&gt;;
&&lt;;titlepag&&gt;;
&&lt;;title&&gt;;The KDevelop Programming Handbook
&&lt;;subtitle&&gt;;The User Guide to C++ Application Design for the K Desktop Environment (KDE) with the KDevelop IDE, Version 1.0
&&lt;;author&&gt;;
&&lt;;name&&gt;;Ralf Nolden &&lt;;htmlurl url="mailto:Ralf.Nolden@post.rwth-aachen.de"
                                   name = "&&lt;;Ralf.Nolden@post.rwth-aachen.de&&gt;;"&&gt;;
&&lt;;inst&&gt;;The KDevelop Team
&&lt;;date&&gt;;Version 2.1 , July 7, 1999
&&lt;;abstract&&gt;;
This handbook itself is part of the KDevelop Integrated Development Environment
and is therefore also licensed under the GNU General Public License;
see &&lt;;ref id="Copyright" name="Copyright"&&gt;; for more information.
&&etago;;abstract&&gt;;</programlisting>
</para>

<para>This covers all a normal titlepage usually contains. The <literal remap="tt">&&lt;;author&&gt;;</literal> tag can also include a <literal remap="tt">&&lt;;thanks&&gt;;</literal> tag to insert
some thanks to co-authors, lecturers etc. <literal remap="tt">&&lt;;inst&&gt;;</literal> represents the institute or company for which the author wrote the
documentation; you could also use your team-name here like I did. <literal remap="tt">&&lt;;abstract&&gt;;</literal> now covers an short description that is placed
on the titlepage as well. This is somewhat annoying on a printed version where this section would be printed on the back of the title
page where the copyright notice etc. are collected; this can be changed for &latex; output when editing the &tex; file.</para>
</sect2>

<sect2 id="indices">
<title>Indices</title>

<para>The LinuxDoc DTD defines a set of tags for various indices as they occur in usual documents. Those are:</para>

<para><itemizedlist>
<listitem>
<para>&&lt;;toc&&gt;; for the table of contents</para>
</listitem>
<listitem>
<para>&&lt;;lof&&gt;; for the list of figures</para>
</listitem>
<listitem>
<para>&&lt;;lot&&gt;; for the list of tables</para>
</listitem>
</itemizedlist>
</para>

<para>The according start-tags don't necessarily require an end-tag; they're inserted just after the titlepage before the actual beginning of
the document with the according sections or chapters.</para>

<para>Now, when it comes to indexing keywords for an index that is placed at the end of the document, you are provided four different tags;
two which leave the indexed phrase within the page and two for index entries that are not displayed:</para>

<para><itemizedlist><listitem>
<para>&&lt;;idx&&gt;; for a normal index entry</para>
</listitem>
<listitem>
<para>&&lt;;cdx&&gt;; for a true-type index entry</para>
</listitem>
<listitem>
<para>&&lt;;nidx&&gt;; for an index entry not appearing in the text document</para>
</listitem>
<listitem>
<para>&&lt;;ncdx&&gt;; as before for a tt-index entry</para>
</listitem>
</itemizedlist></para>

<para>These tags are ignored by all backends (the tool that does the mapping of the sgml-tags to their document format) except
<literal remap="tt">sgml2latex</literal>, which generates an index file <literal remap="tt">index.idx</literal> that can be turned to a &tex;-index with <literal remap="tt">makeindex index.idx</literal>. The
index itself can be inserted into the &tex; output file afterwards with <literal remap="tt">\printindex</literal>. I patched my mapping for the &latex; output to do
this automatically (but still don't know how to include the index into the table of contents...).</para>
</sect2>

<sect2 id="the-document-contents">
<title>The Document Contents</title>

<para>Now, after explaining most details of the general structure, we're coming to the actual document contents. Dependent on the document
structure type, has to start with a <literal remap="tt">&&lt;;sect&&gt;;</literal> tag, when using <literal remap="tt">&&lt;;book&&gt;;</literal> you have to start with <literal remap="tt">&&lt;;chapt&&gt;;</literal>
for the chapters.</para>

<para>After the start tag, you can structurize each chapter with <literal remap="tt">&&lt;;sect1&&gt;;</literal>, <literal remap="tt">&&lt;;sect2&&gt;;</literal> etc. up to the allowed level of
sub-sections (4).</para>

<para>The chapter start tag is followed by the chapter's title. There, you have the additional choice to use <literal remap="tt">&&lt;;title&&gt;;</literal> and
&&etago;;title&&gt;; for the chapter's title (optional). Now, afte the title of the chapter, you have to add a &&lt;;p&&gt;; tag to actually
start with the subsection's contents. Within that, you have almost all means to format your document with list, enumerations,
itemizations and description lists. Further, quotations, code snippets and the like can be inserted by tags; see you <literal remap="tt">sgmltools</literal>
documentation guide for a complete list. What you should look for is the "special characters" section. This contains all valid
replacements for characters that are different from the usual alphabet like brackets, slashes and symbols like trademark etc. With the
given tags you can structurize your text contents as you application documentation requires.</para>
</sect2>
</sect1>

<sect1 id="how-to-call-help-in-dialogs">
<title>How to call Help in Dialogs</title>

<para><indexterm><primary>help functions</primary></indexterm>
Calling help in dialogs is often done by adding a Help-button; then you add a slot that is called when the button gets pressed. Within
the slot implementation, call</para>

<para><screen>kapp-&gt;invokeHTMLHelp( QString aFilename, QString aTopic );
</screen>
</para>

<para>where <literal remap="tt">aFilename</literal> is the the filename to be called within your HTML documentation directory of the application; e.g index-3.html.
<literal remap="tt">aTopic</literal> then is the topic that is to be called. The hash prefix is automatically added; just enter the chapter you want to have on
this page, actually this would be a subsection's name.</para>
</sect1>
</chapter>

<chapter id="class-documentation-with-kdoc-kdoc">
<title>Class Documentation with KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></title>

<para>Another important part of the documentation is including a descriptive help for your class interfaces. This will allow you and other
programmers to use your classes by reading the HTML class documentation <indexterm remap="idx"><primary>class documentation</primary></indexterm> that can be created with <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal>. KDevelop supports the use
of <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal> completely by creating the KDE-library documentation, also your application frameworks are already documented. To work
yourself into the provided code, it would be a good start to read the included documentation online. The following describes what to do
to get the API <indexterm remap="idx"><primary>API</primary></indexterm> documentation, where KDevelop helps you add it and what kind of special tags <literal remap="tt">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm></literal> provides additionally.</para>

<sect1 id="how-to-use-kdevelops-documentation-features">
<title>How to use KDevelop's Documentation features</title>

<para>To create the API <indexterm remap="idx"><primary>API</primary></indexterm> documentation after you generated a project, select "Make API <indexterm remap="idx"><primary>API</primary></indexterm>-Doc" from the "Project" menu. This will process all
header files and create the HTML output. Then you can access the documentation by selecting "API <indexterm remap="idx"><primary>API</primary></indexterm>-Documentation" from the Help-menu or
the according book symbol in the Documentation tree, folder "Current Project".</para>

<para>The documentation is already cross-referenced to the KDE and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> online-class documentation <indexterm remap="idx"><primary>class documentation</primary></indexterm>, so you can follow the inheritance easily
with the inheritance overview. This may help you getting started with the KDE and Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> documentation as well.</para>
</sect1>

<sect1 id="adding-class-and-member-documentation">
<title>Adding Class and Member Documentation</title>

<para>As KDevelop provides all means to add code automatically, it also offers direct documentation. Whenever you're using the Class
Generator by choosing "Project"-&gt;"New Class", add a descriptive help message to the documentation field. This will add the
documentation to the class header.</para>

<para>When adding class member functions and attributes with the classtools <indexterm remap="idx"><primary>classtools</primary></indexterm>, add the member documentation to the according documentation
fields as well.</para>

<para>You may think that documentation is a part of the development process that isn't very necessary. But remember that the more your
project grows and the more people take part on the development process, class documentation <indexterm remap="idx"><primary>class documentation</primary></indexterm> is the best help to save time. If
developers have to guess by method names what exactly the method does, it is even more likely that the meaning is misunderstood and the
method apparently doesn't do the job a developer guessed it would do. Therefore keep track of your documentation and rebuild it as
often as possible.</para>

<para>Besides this, the documentation files are NOT included into the project, nor do they have any internationalization support. Therefore
all API <indexterm remap="idx"><primary>API</primary></indexterm> documentation should be held in English to allow international development groups to work with your sources.</para>

<para>Whenever you may want to add documentation by hand into the header file, just add the documentation <emphasis remap="bf">above</emphasis> the method or class in a
C-comment style with the difference that the first line has to begin with a slash and a double asterisk.</para>

<para>Example:</para>

<para><screen>  /** enables menuentries/toolbar items
  	*/
  void enableCommand(int id_);
</screen>
</para>
</sect1>

<sect1 id="special-tags">
<title>Special Tags</title>

<para><emphasis remap="bf">NOTE:</emphasis> The following documentation of this chapter is taken from the KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm> documentation provided with KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm> by
Sirtaj S. Kang <ulink url="mailto:taj@.kde.org">taj@.kde.org</ulink>), author of KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm>; Copyright (c) 1997</para>

<para>The documentation is a mixture of:</para>

<para><itemizedlist>
<listitem>
<para>Normal text. Paragraphs must be separated by at least one blank line.
</para>
</listitem>
<listitem>
<para>text of the form
<programlisting>&&lt;;pre&&gt;;
.....code fragments....
&&lt;;/pre&&gt;;</programlisting>
</para>
</listitem>
<listitem>
<para>Various tags of the form:
<screen>@tagname [tag parameters]
</screen>
</para>
</listitem>
</itemizedlist>
</para>

<para>The valid tags for each type of source code entity are:</para>

<para><itemizedlist>
<listitem>
<para>Classes
<screen>  @short [one sentence of text]
    A short description of the class
  @author [one sentence of text]
    Class author
  @version [once sentence of text]
    Class version (I normally set this to the RCS/CVS tag "Id")
  @see [one or more references to classes or methods] 	
    References to other related documentation.
</screen>

</para>
</listitem>
<listitem>
<para>Methods

<screen>  @see
    as above
  @return [one sentence]
    A sentence describing the return value
  @param [param name identifier] [param description]
    Describe a parameter. The param description can span multiple
    lines and will be terminated by a blank line, the end of the
    comment, or another param entry. For this reason, param entries
    should normally be the last part of the doc comment.
</screen>

</para>
</listitem>
<listitem>
<para>Constants, Enums, Properties
<screen>  @see
    as above
</screen>
</para>
</listitem>
<listitem>
<para>ALSO <literal remap="tt">@ref</literal>
As a departure from the javadoc format, the metatag "@ref" has the same format as @see, but can appear anywhere in the documentation
(all other tags must appear on a line by themselves).</para>
</listitem>
</itemizedlist>
</para>
</sect1>
</chapter>

<chapter id="internationalization">
<title>Internationalization</title>

<sect1 id="what-is-i18n">
<title>What is i18n ?</title>

<para>i18n is an internationalization system that is used to offer internationalized versions of an application or project. The difficulty
with writing applications is that they only support the language they originally are composed with; visually this can be seen on
labels, menu entries and the like. Goal of the internationalization is to provide applications and library functions in the language of
the user; therefore enabling users that are not capable of the original language to make use of the provided functionality and feel
more comfortable.</para>
</sect1>

<sect1 id="how-kde-supports-internationalization">
<title>How KDE supports Internationalization</title>

<para>KDE, as one of the most modern desktop environments, has set one of its numerous goals to provide applications for users in their
native languages, and simplifies the work for developers to provide their application in any of the supported language.</para>

<para>Technically, this is realized by the KDE File System <indexterm remap="idx"><primary>KDE File System</primary></indexterm> Standard which contains localization support for languages in terms of
documentation and by providing application internationalization through the use of the KDE-core library class <literal remap="tt">KLocale</literal>. This class
does all the translation, dependent on the preferred language set in the KDE Control Center.</para>

<para>The developer on the other hand only has to know two things to make his application able to use this feature:</para>

<para><orderedlist><listitem>
<para>include <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> into your sourcecode wherever a visible text appears in your application, e.g. in source files that contain
QLabel <indexterm remap="idx"><primary>QLabel</primary></indexterm>s.</para>
</listitem>
<listitem>
<para>wherever you set the visual string, embrace it with the <literal remap="tt">i18n()</literal> macro provided by <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal> to enable translation.</para>
</listitem>
<listitem>
<para>whenever you have to access a locale object, use the <literal remap="tt">klocale</literal> macro provided by <literal remap="tt"><indexterm remap="cdx"><primary><literal>kapp.h</literal></primary></indexterm>kapp.h</literal></para>
</listitem>
</orderedlist>
</para>

<para>That is almost all you have to watch for while coding. Mind that you should not internationalize any configuration strings that are
used by <literal remap="tt"><indexterm remap="cdx"><primary><literal>KConfig</literal></primary></indexterm>KConfig</literal>, because this is not necessary on one hand and doesn't work for reading in values on the other.</para>
</sect1>

<sect1 id="adding-a-language-to-your-project">
<title>Adding a Language to your Project</title>

<para>KDevelop also takes part on making life easier for developers to include native language support to their applications. Whenever you
create a new KDE project, a <literal remap="tt">po</literal> directory is added to the main project directory. There, your <emphasis>&&lt;;application&&gt;;</emphasis>.pot file
will be placed after the generation is complete. The .pot file already contains all strings that are set up with the i18n() macro,
therefore you only have to write your code using the macro again. From time to time, you should do a "Project"-"Make messages and
merge", which will automatically extract all macros again and rebuilds the potfile.
<indexterm><primary>"Project"-menu</primary></indexterm><indexterm><primary>PO-files</primary></indexterm><indexterm><primary>translations</primary></indexterm><indexterm remap="ncdx"><primary><literal>KLocale</literal></primary></indexterm></para>

<para>To add a language to your application, choose "Project"-"Add translation file", which opens the language selection dialog. Select the
desired language and press OK. Then, the according <emphasis>&&lt;;lang&&gt;;</emphasis>.po file will be build in the <literal remap="tt">po</literal> directory. Then start
translating the po file by selecting it from the po directory in the Real File Viewer or from the LFV, folder "Translations". If you
have KTranslator <indexterm remap="idx"><primary>KTranslator</primary></indexterm> installed, it will be opened in the "Tools" window with KTranslator <indexterm remap="idx"><primary>KTranslator</primary></indexterm>, otherwise as a text file in the header/resource
window.
KTranslator <indexterm remap="idx"><primary>KTranslator</primary></indexterm> makes it very easy to translate strings by scanning the existing translations of your local KDE installation, so they can
be used already.</para>

<para>For editing by hand, we'll have a look at an example:
<screen>#: kscribble.cpp:619
msgid "Opens an existing document"
msgstr ""
</screen>
</para>

<para>The above shows a string that was extracted from the file <literal remap="tt">kscribble.cpp</literal> at line 619. <literal remap="tt"><indexterm remap="cdx"><primary><literal>msgid</literal></primary></indexterm>msgid</literal> and <literal remap="tt"><indexterm remap="cdx"><primary><literal>msgstr</literal></primary></indexterm>msgstr</literal> are the tags which
give the information for the translation; <literal remap="tt"><indexterm remap="cdx"><primary><literal>msgstr</literal></primary></indexterm>msgstr</literal> will contain the translated string. There, you have to watch escape sequences
such as \n or \t, which have to be included into the translation string. A German translation would therefore look like this:</para>

<para><screen>#: kscribble.cpp:619
msgid "Opens an existing document"
msgstr "Öffnet ein existierendes Dokument"
</screen>
</para>

<para>That would be all to watch for translation; after you're done, save the file. When make is run within the po directory, the message
files will be processed and errors may occur if strings are not translated consistently, e.g. escape sequences are missing. Then edit
the according message string again and make sure that make runs without errors.</para>

<para>Additionally, you should be very careful when translating ampersands within text strings. The letters after ampersands are used as
keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>s in conjunction with the ALT key to access menubar or popup menu items to change the keyboard focus <indexterm remap="idx"><primary>keyboard focus</primary></indexterm> to the
selected item more quickly. Now, if the same accelerator<indexterm><primary>accelerator</primary></indexterm> letter appears in the same keyboard focus <indexterm remap="idx"><primary>keyboard focus</primary></indexterm> area (which would be the main widget
on one time, and a dialog at another), each widget after the first one cannot be accessed by the supposed keyboard accelerator<indexterm><primary>accelerator</primary></indexterm>. So even
translators have a responsibility for the usage of the application under their language. There is also no guarantee that the original
letter will occur in the translation, so translators have to choose very carefully and should test the application under their language
after they installed the translation to ensure it runs without these malfunctions.</para>
</sect1>

<sect1 id="translation-team-contacts">
<title>Translation Team Contacts</title>

<para>The KDE Team also provides numerous contacts to developers that are contributing to the KDE project as translators. Those are organized
in language teams and coordinate the translation work.
For an actual list and information who to ask for translating your application, see <ulink url="http://www.kde.org">\|\|</ulink>.</para>

<para>The information below is taken from the KDE web site and contains the current contact addresses as of March 06, 1999. If you want to join
a team please write directly to one of the team coordinators.</para>

<para>The translation of the KDE is organized by Juraj Bednar <ulink url="mailto:bednar@rak.isternet.sk">mailto:bednar@rak.isternet.sk</ulink> and Matthias Elter <ulink url="mailto:me@kde.org">me@kde.org</ulink></para>

<para>You can subscribe KDE internationalization mailing list kde-i18n-doc@kde.org by sending a mail to <ulink url="mailto:kde-i18n-doc-request@kde.org?subject=subscribe">kde-i18n-doc-request@kde.org</ulink> with the word "subscribe" in the
subject line.</para>

<para>Before starting any translation work, please contact the according translation team leaders for coordination to avoid double work.</para>

<variablelist>
<varlistentry>
<term>br Breton translation team:</term>
<listitem>
<para>team coordinators: Jañ-Mai DRAPIER <ulink url="mailto:jdrapier@club-internet.fr">jdrapier@club-internet.fr</ulink>
website: <ulink url="http://perso.club-internet.fr/jdrapier">http://perso.club-internet.fr/jdrapier</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ca Catalan translation team:</term>
<listitem>
<para>team coordinators: Sebastià Pla <ulink url="mailto:sastia@redestb.es">sastia@redestb.es</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>cs Czech translation team:</term>
<listitem>
<para>team coordinators:  Miroslav Flídr <ulink url="mailto:flidr@kky.zcu.cz">flidr@kky.zcu.cz</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>da Danish translation team:</term>
<listitem>
<para>team coordinators:  Erik Kjær Pedersen <ulink url="mailto:erik@binghamton.edu">erik@binghamton.edu</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>de German translation team:</term>
<listitem>
<para>team coordinators: Thomas Diehl <ulink url="mailto:th.diehl@gmx.net">th.diehl@gmx.net</ulink>
website: <ulink url="http://www.dtp-service.com/kde/de/">\|\|</ulink>
mailing list:  send a mail with 'subscribe' in the subject line to: <ulink url="mailto:kde-i18n-de-request@kde.org?subject=subscribe">kde-i18n-de-request@kde.org</ulink> Webforum for discussions and user feedback: <ulink url="http://www.dtp-service.com/discus_d">\|\|</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>el Greek translation team:</term>
<listitem>
<para>team coordinators:  Theodore J. Soldatos <ulink url="mailto:theodore@eexi.gr">theodore@eexi.gr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>eo Esperanto translation team:</term>
<listitem>
<para>team coordinators:  Wolfram Diestel <ulink url="mailto:diestel@rzaix340.rz-uni-leipzig.de">diestel@rzaix340.rz-uni-leipzig.de</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>es Spanish translation team:</term>
<listitem>
<para>team coordinators:  Boris Wesslowski, Alonso Lara <ulink url="mailto:Boris@Wesslowski.com">Boris@Wesslowski.com</ulink>
website: <ulink url="http://members.xoom.com/keko5/">\|\|</ulink>
mailing list: send a mail with 'subscribe' in the subject line to <ulink url="mailto:kde-es@kde.org?subject=subscribe">kde-es@kde.org</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>et Estonian translation team:</term>
<listitem>
<para>team coordinators:  Hasso C. Tepper <ulink url="mailto:hasso@ewsound.estnet.ee">hasso@ewsound.estnet.ee</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>fi Finnish translation team:</term>
<listitem>
<para>team coordinators: Kim Enkovaara <ulink url="mailto:kim.enkovaara@iki.fi">kim.enkovaara@iki.fi</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>fr French translation team:</term>
<listitem>
<para>team coordinators:  Francois-Xavier Duranceau <ulink url="mailto:Francois-Xavier.Duranceau@loria.fr">Francois-Xavier.Duranceau@loria.fr</ulink>
website: <ulink url="http://www.loria.fr/~durancea/kde/wip-apps.html">\|\|</ulink>
mailing list: send an empty mail to:  <ulink url="mailto:kde-traduc-fr-subscribe@egroups.com">kde-traduc-fr-subscribe@egroups.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>he Hebrew translation team:</term>
<listitem>
<para>team coordinators:  Erez Nir <ulink url="mailto:erez-n@actcom.co.il">erez-n@actcom.co.il</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>hr Croatian translation team:</term>
<listitem>
<para>team coordinators:  Vladimir Vuksan <ulink url="mailto:vuksan@veus.hr">vuksan@veus.hr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>hu Hungarian translation team:</term>
<listitem>
<para>team coordinators:  Marcell Lengyel <ulink url="mailto:miketkf@yahoo.com">miketkf@yahoo.com</ulink>
website:<ulink url="http://sophia.jpte.hu/~kde">\|\|</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>is Icelandic translation team:</term>
<listitem>
<para>team coordinators:
Logi Ragnarsson, <ulink url="mailto:logir@imf.au.dk">logir@imf.au.dk</ulink>
Thorarinn R. Einarsson, <ulink url="mailto:thori@mindspring.com">thori@mindspring.com</ulink>
Bjarni R. Einarsson, <ulink url="mailto:bre@netverjar.is">bre@netverjar.is</ulink>
Hrafnkell Eiriksson, <ulink url="mailto:hkelle@rhi.hi.is">hkelle@rhi.hi.is</ulink>
Gudmundur Erlingsson, <ulink url="mailto:gudmuner@lexis.hi.is">gudmuner@lexis.hi.is</ulink>
Richard Allen <ulink url="mailto:ra@hp.is">ra@hp.is</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>it Italian translation team:</term>
<listitem>
<para>team coordinators:  Andrea Rizzi <ulink url="mailto:rizzi@kde.org">rizzi@kde.org</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ko Korean translation team:</term>
<listitem>
<para>team coordinators:  LinuxKorea Co. <ulink url="mailto:kde@linuxkorea.co.kr">kde@linuxkorea.co.kr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>mk Macedonian translation team:</term>
<listitem>
<para>team coordinators:  Sasha Konecni <ulink url="mailto:sasha@msi-uk.com">sasha@msi-uk.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>nl Dutch translation team:</term>
<listitem>
<para>team coordinators:  flidr@CyberGate.zcu.cz <ulink url="mailto:flidr@CyberGate.zcu.cz">flidr@CyberGate.zcu.cz</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>no Norwegian translation team:</term>
<listitem>
<para>team coordinators:  Hans Petter Bieker <ulink url="mailto:zerium@webindex.no">zerium@webindex.no</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>pl Polish translation team:</term>
<listitem>
<para>team coordinators:  Piotr Roszatycki <ulink url="mailto:dexter@fnet.pl">dexter@fnet.pl</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>pt Portuguese translation team:</term>
<listitem>
<para>team coordinators:  Pedro Morais <ulink url="mailto:pmmm@camoes.rnl.ist.utl.pt">pmmm@camoes.rnl.ist.utl.pt</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>pt&&lowbar;;BR Brazil Portuguese translation team:</term>
<listitem>
<para>team coordinators:  Elvis Pfützenreuter <ulink url="mailto:epx@netville.com.br">epx@netville.com.br</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ro Romanian translation team:</term>
<listitem>
<para>team coordinators:  Paul Ionescu <ulink url="mailto:ipaul@romsys.ro">ipaul@romsys.ro</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>ru Russian translation team:</term>
<listitem>
<para>team coordinators:  Denis Y. Pershin <ulink url="mailto:dyp@inetlab.com">dyp@inetlab.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>sk Slovak translation team:</term>
<listitem>
<para>team coordinators:  Juraj Bednar <ulink url="mailto:bednar@isternet.sk">bednar@isternet.sk</ulink>
mailling list:  send a mail with 'subscribe' in the subject line to: <ulink url="mailto:sk-i18n@rak.isternet.sk?subject=subscribe">sk-i18n@rak.isternet.sk</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>sl Slovenian translation team:</term>
<listitem>
<para>team coordinators:  blazzupancic@hotmail.com <ulink url="mailto:blazzupancic@hotmail.com">blazzupancic@hotmail.com</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>sv Swedish translation team:</term>
<listitem>
<para>team coordinators:  Anders Widell <ulink url="mailto:d95-awi@nada.kth.se">d95-awi@nada.kth.se</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>tr Turkish translation team:</term>
<listitem>
<para>team coordinators:  Gorkem Cetin <ulink url="mailto:gorkem@linux.org.tr">gorkem@linux.org.tr</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>zh&&lowbar;;GB2312 Simplified Chinese translation team:</term>
<listitem>
<para>team coordinators:  Wang Jian <ulink url="mailto:larkw@263.net">larkw@263.net</ulink></para>
</listitem>
</varlistentry>
<varlistentry>
<term>zh&&lowbar;;TW&&lowbar;;Big5 Chinese BIG5 translation team:</term>
<listitem>
<para>team coordinators:  Chou Yeh-Jyi <ulink url="mailto:ycchou@ccca.nctu.edu.tw">ycchou@ccca.nctu.edu.tw</ulink></para>
</listitem>
</varlistentry>
</variablelist>

</sect1>
</chapter>

<chapter id="finding-errors">
<title>Finding Errors</title>

<para><indexterm><primary>debugging macros</primary></indexterm></para>

<sect1 id="debugging-macros-provided-by-qt-qt">
<title>Debugging Macros provided by Qt <indexterm remap="idx"><primary>Qt</primary></indexterm></title>

<para>The Debugging Macros provided by the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> library can be read on the debug.html page of your Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Online Reference
Documentation, acessable on the link "Debugging Techniques" at the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Documentation index page.</para>

<para>The most recently used macros are</para>

<para><itemizedlist>
<listitem>
<para>ASSERT(b)</para>
</listitem>
<listitem>
<para>CHECK&&lowbar;;PTR(p)</para>
</listitem>
</itemizedlist>
</para>

<para>Thereby, b is a boolean expression. Gives out a debugging warning if b is false; p is a pointer which is checked and gives out a
warning, if p is null.</para>

<para>Details can be found in the Qt <indexterm remap="idx"><primary>Qt</primary></indexterm> Online Reference.</para>
</sect1>

<sect1 id="kde-macros">
<title>KDE Macros</title>

<para><emphasis remap="bf">NOTE:</emphasis> This chapter is a copy of Kalle Dalheimer's <ulink url="mailto:kalle@kde.org">kalle@kde.org</ulink> explanation document
about the KDEBUG <indexterm remap="idx"><primary>KDEBUG</primary></indexterm> macros included with the KDE libs package as kdebug.html</para>

<para>Last modified: Sat Sep 13 11:56:01 CEST 1997</para>

<para><emphasis remap="bf">What is KDebug</emphasis></para>

<para>KDebug is a system of macros and functions that makes using diagnostic messages in your code more efficient. You can give a message
one out of four severity level and an area. You can choose at runtime where diagnostic messages should go and which of them should be
printed at all. How to use KDebug in your code</para>

<para><emphasis remap="bf">The macro KDEBUG <indexterm remap="idx"><primary>KDEBUG</primary></indexterm></emphasis></para>

<para>Using KDebug is very simple. All you have to do is to &&num;;include &&lt;;kdebug.h&&gt;; at the beginning of every source file in which you want
to use diagnostic messages and output the messages by calling the macro KDEBUG <indexterm remap="idx"><primary>KDEBUG</primary></indexterm>. This macro expects three parameters. The first is the
severity level. Use one of the following constants:</para>

<para><itemizedlist>
<listitem>
<para>KDEBUG&&lowbar;;INFO <indexterm remap="idx"><primary>KDEBUG&&lowbar;;INFO</primary></indexterm></para>
</listitem>
<listitem>
<para>KDEBUG&&lowbar;;WARN <indexterm remap="idx"><primary>KDEBUG&&lowbar;;WARN</primary></indexterm></para>
</listitem>
<listitem>
<para>KDEBUG&&lowbar;;ERROR <indexterm remap="idx"><primary>KDEBUG&&lowbar;;ERROR</primary></indexterm></para>
</listitem>
<listitem>
<para>KDEBUG&&lowbar;;FATAL <indexterm remap="idx"><primary>KDEBUG&&lowbar;;FATAL</primary></indexterm></para>
</listitem>
</itemizedlist>
</para>

<para>The second parameter is the area. An area is a part of KDE that you define yourself. You can then at runtime choose from which areas
diagnostic messages should be printed. Please see the file kdelibs/kdecore/kdebugareas.txt for a list of already allocated area ranges.
Choose an area within the range allocated for your application. If your application is not yet in here and you have CVS access, you can
allocate a range for your application here, otherwise just mail me. It is probably a good idea to define symbolic constants for the
areas you want to use, but this is completely up to you. The third parameter, finally, is the text you want to output. KDebug
automatically prepends the logical application name if you output to a file, to stderr or to syslog. A newline is always appended, you
need not (and should not) use one yourself. If you need parameters, you can use one of the macros KDEBUG1, ..., KDEBUG9. These allow
for one to nine additional arguments. The syntax is exactly the same as with printf, i.e. you have to include format specifiers in your
message which get replaced by the additional parameters. An example:</para>

<para><screen>KDEBUG3( &lt;idx/KDEBUG_INFO/, kmail_composer, "Message no. %d to %s has %d bytes",
          message_no, aMessage.to(), aMessage.length() );
</screen>
</para>

<para><emphasis remap="bf">KASSERT <indexterm remap="idx"><primary>KASSERT</primary></indexterm></emphasis></para>

<para>There are also the macros KASSERT, KASSERT1, ..., KASSERT9 which work just like their KDEBUG <indexterm remap="idx"><primary>KDEBUG</primary></indexterm>-counterparts, except that they have an
additional bool as their first parameter. Only if this evaluates to false will the message be output. Note: You should not use neither
KDEBUG <indexterm remap="idx"><primary>KDEBUG</primary></indexterm> nor KASSERT <indexterm remap="idx"><primary>KASSERT</primary></indexterm> before the <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication object is constructed. Note 2: KDebug provides no means for internationalization because it
is meant strictly for developers only. If you want to inform the user about an erroneous condition (like "this file is not writable"),
use KMsgBox.</para>

<para><emphasis remap="bf">Compiler switches</emphasis></para>

<para>You do not need any special compiler switches in order to use KDebug. But when you ship your
product (this mainly applies to people who create distributions like .rpm or .deb packages), you should compile with the switch
-DNDEBUG. This will simply remove all the debugging code from your application and make it smaller and faster (e.g. it uses 256K less
non-shareable memory).</para>

<para><emphasis remap="bf">How to manage diagnostic messages at runtime</emphasis></para>

<para>You can press Ctrl-Shift-F12 in every <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication at any time, and the "Debug Settings"-Dialog will appear. Here you can define
separately for every severity level what should be done with the diagnostic messages of that level. The following settings are
available:</para>

<para><itemizedlist>
<listitem>
<para>Output: In this Combobox, you can choose where the messages should be output. The choices are: "File", "Message Box", "Shell"
(meaning stderr) and "syslog". Please do not direct fatal messages to syslog unless you are the system administrator yourself. The
default is "Message Box".</para>
</listitem>
<listitem>
<para>File: This is only meaningful when you have chosen "File" as the output and provides the name of that file (which is interpreted
relatively to the current directory). The default is kdebug.dbg.
</para>
</listitem>
<listitem>
<para>Area: The areas which should only be output. Every message that is not mentioned here will simply not be output (unless this
field remains empty which is the default and means that all messages should be output). Your can enter several areas separated by
commas here, and you can also use area ranges with the syntax start-end. Thus a valid entry could be: 117,214-289,356-359,221. Please
do not use whitespace.</para>
</listitem>
</itemizedlist>
</para>

<para>Apart from this, you can also tick the checkbox "Abort on fatal errors". In this case, if a diagnostic message with the severity level
"KDEBUG&&lowbar;;FATAL <indexterm remap="idx"><primary>KDEBUG&&lowbar;;FATAL</primary></indexterm>" is output, the application aborts with a SIGABRT after outputting the message. When you close the dialog with OK, your
entries apply immediately and saved in your application's configuration file. Please note that these settings are specific for one
singular application! When you press cancel, your entries are discarded and the old ones are restored.</para>
</sect1>
</chapter>

<chapter id="the-kde-file-system-standard">
<title>The KDE File System Standard</title>

<para>This chapter is a copy of the KDE-File System Standard as published on the KDE website at <ulink url="http://www.kde.org">\|\|</ulink>, written by
Richard Moore <ulink url="rich@kde.org">rich@kde.org</ulink></para>

<para><emphasis remap="bf">KDE File System Standard</emphasis></para>

<para>This file documents the directory structure that KDE and all KDE compliant applications should use. This is version 0.0.4 of the
standard.</para>

<sect1 id="introduction">
<title>Introduction</title>

<para>The purpose of the KDE FSSTD <indexterm remap="idx"><primary>KDE FSSTD</primary></indexterm> is to ensure that all resources (icons, mimetypes etc.) needed for KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm> are stored in a
consistent directory structure. Following this structure allows applications to make use of tools such as the KIconLoader class and
allows separation of the platform specific data needed by KDE from platform independent data (making installations on multiple
architectures possible). In this document directory names have been suffixed with a `/` character. Where the word 'appname' appears in
angle brackets &&lt;;like this&&gt;; it means that there should be an entry corresponding to every installed KDE application. The word
'lang' is used in the same way to indicate that there should be an entry for every supported language named according to the standard
two letter language codes eg. 'fr' for French, 'de' for German etc.</para>
</sect1>

<sect1 id="directory-layout">
<title>Directory Layout</title>

<para>The KDE directory structure is as shown below, the top of the KDE installation tree is usually '/opt/kde' and can be found at run time
by using the kdedir() method of <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication (this replaces the KDEDIR environment variable the use of which is now deprecated). This
document will refer to this directory as kdedir().
<indexterm><primary>KDE File System</primary></indexterm><indexterm><primary>.kdelnk files</primary></indexterm></para>

<para><itemizedlist>
<listitem>
<para>kdedir()/
<itemizedlist>
<listitem>
<para>bin/
<itemizedlist>
<listitem>
<para>Application binaries</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>lib/
<itemizedlist>
<listitem>
<para>standard kde libraries (libkdecore etc.)</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>Application specific data that is platform dependent</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>include/
<itemizedlist>
<listitem>
<para>standard kde header files</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>parts/</para>
</listitem>
<listitem>
<para>cgi-bin/
<itemizedlist>
<listitem>
<para>CGI programs for kdehelp</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>share/
<itemizedlist>
<listitem>
<para>doc/
<itemizedlist>
<listitem>
<para>HTML/
<itemizedlist>
<listitem>
<para>default --&gt; Link to kdedir()/share/doc/HTML/en</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;lang&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>index.html</para>
</listitem>
<listitem>
<para>other application help files</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>config/</para>
</listitem>
<listitem>
<para>applnk/
<itemizedlist>
<listitem>
<para>System/</para>
</listitem>
<listitem>
<para>Utilities/</para>
</listitem>
<listitem>
<para>Applications/</para>
</listitem>
<listitem>
<para>Games/</para>
</listitem>
<listitem>
<para>kfind.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>khelp.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>khome.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
<listitem>
<para>krefresh.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>mimelnk/
<itemizedlist>
<listitem>
<para>magic</para>
</listitem>
<listitem>
<para>text/</para>
</listitem>
<listitem>
<para>audio/</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>partlnk/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;partname&&gt;;</emphasis>.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm></para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>icons/
<itemizedlist>
<listitem>
<para>Icons used in kdelnk files</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>.xpm</para>
</listitem>
<listitem>
<para>mini/
<itemizedlist>
<listitem>
<para>Mini Icons for kpanel</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>/
<itemizedlist>
<listitem>
<para>Standard toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> pixmaps (eg. fileopen.xpm)</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>wallpapers/
<itemizedlist>
<listitem>
<para>Wallpapers used by kdisplay</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>apps/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>/
<itemizedlist>
<listitem>
<para>Toolbar pixmaps</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>pics/
<itemizedlist>
<listitem>
<para>Other application pixmaps</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>application specific data (must be platform independent)</para>
</listitem>
</itemizedlist>
				</para>
</listitem>
<listitem>
<para><emphasis>&&lt;;libname&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>pics/</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>locale/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;lang&&gt;;</emphasis>/
<itemizedlist>
<listitem>
<para>LC&&lowbar;;MESSAGES/
<itemizedlist>
<listitem>
<para><emphasis>&&lt;;appname&&gt;;</emphasis>.mo</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="what-does-this-mean-to-application-developer">
<title>What does this mean to application developers?</title>

<para>A standard KDE application will install files into several places in the above structure. The only required items are the application
binary, the application kdelnk file, the application icon and the application help files - all others are optional. The most common
things that are installed are:</para>

<para><screen>Type of file                                      Location

Application binary (required)                     kdedir()/bin/
Application kdelnk file (required)                kdedir()/share/applnk/
Application icon (required)                       kdedir()/share/icons/&&lt;;appname&&gt;;.xpm
Application help files (required)                 kdedir()/share/doc/default/HTML/&&lt;;appname&&gt;;/&&lt;;index&&gt;;.html
Application toolbar pixmaps                       kdedir()/share/apps/&&lt;;appname&&gt;;/toolbar/
Application platform independent data             kdedir()/share/apps/&&lt;;appname&&gt;;/
Application platform specific data                kdedir()/lib/&&lt;;appname&&gt;;/
</screen>

<indexterm><primary>KDE File System</primary></indexterm></para>
</sect1>

<sect1 id="application-documentation">
<title>Application Documentation</title>

<para>I've suggested making putting at least a single page in</para>

<para>kdedir()/doc/default/HTML/&&lt;;appname&&gt;;/&&lt;;appname&&gt;;.html</para>

<para>a requirement for KDE compliance. The application is free to use the directory to store any help data it requires.</para>

<para>Applications that support more than one language would place the other languages inkdedir()/doc/&&lt;;lang&&gt;;/HTML/&&lt;;appname&&gt;;/&&lt;;appname&&gt;;.html
with there being one 'lang' directory for each language code as usual. Arranging the files like this would allow links between the help
files of two different applications that both support a given language.</para>

<para>I am not 100&&percnt;; happy with the solution I've suggested as it does not allow any way to fall back to the default language if a required
translation is not available.</para>
</sect1>

<sect1 id="what-does-this-mean-to-library-developers">
<title>What does this mean to library developers?</title>

<para><itemizedlist>
<listitem>
<para>kdedir()/share/apps/&&lt;;libname&&gt;;/toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></para>
</listitem>
</itemizedlist>

Toolbar icons for library widgets.</para>

<para><itemizedlist>
<listitem>
<para>kdedir()/share/apps/&&lt;;libname&&gt;;/pics</para>
</listitem>
</itemizedlist>

Any other bitmaps for library widgets.</para>
</sect1>
</chapter>

<chapter id="file-system-usage-for-kdevelop-projects">
<title>File System Usage for KDevelop Projects</title>

<para>As the last chapter covered the KDE File System Standard, this chapter deals with what you have to do to use the file system. A KDE
project uses the file system at least for installation routines; therefore we will discuss setting installation properties for your
project files. Your application may make use of files that are installed afterwards, where it is important to know how to get the
relative pathname by the standard. This enables your application to work wherever the KDE file system may be and prevents hard-coding
any file information.</para>

<sect1 id="accessing-files-during-runtime">
<title>Accessing Files during Runtime</title>

<para>After the installation of your project by end-users, your application may require file information during runtime. During the
development process, you will experience at least one error which is caused when running your application within the KDevelop IDE and
requiring the application manual by "Help"-"Contents" or pressing the F1 key. This will result in a message box, saying that the
index.html file could not be found- if you haven't installed your application on your local KDE file system. Your application asks
KDEHelp <indexterm remap="idx"><primary>KDEHelp</primary></indexterm> to open your index page with detecting the installation directory first through <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal>'s methods to access the file
system, therefore, we will have a look at what <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> offers and make some example usage. Also other classes of
<literal remap="tt">KDE-Core</literal> make use of the KDE File System like <literal remap="tt">KIconLoader</literal> and <literal remap="tt">KLocale</literal>, which will be reviewed afterwards.</para>
</sect1>

<sect1 id="kapplicationkapplication-methods">
<title><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication Methods</title>

<para>The <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication class offers the following methods to access the KDE File System:
<screen>void invokeHTMLHelp ( QString aFilename, QString aTopic ) const
static const QString& kde_htmldir ()
static const QString& kde_appsdir ()
static const QString& kde_icondir ()
static const QString& kde_datadir ()
static const QString& kde_localedir ()
static const QString& kde_cgidir ()
static const QString& kde_sounddir ()
static const QString& kde_toolbardir ()
static const QString& kde_wallpaperdir ()
static const QString& kde_bindir ()
static const QString& kde_configdir ()
static const QString& kde_mimedir ()
static QString localkdedir ()
static QString localconfigdir ()
static QString findFile ( const char *file )
</screen>

<indexterm><primary>KDE File System</primary></indexterm>
The methods are generally used with the <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> object of your application, where <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> offers the macro
<literal remap="tt">kapp</literal> to receive the pointer:</para>

<para>&&num;;define kapp <indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication::getKApplication()</para>

<para>Therefore, the methods are generally used like this:
<screen>QString sounddir=kapp-&gt;kde_sounddir();
</screen>

This example stores the path of the KDE sounddirectory under a <literal remap="tt">QString</literal>, where you would append e.g. the sound filename. Then you
can process this information and play a sound file that is located there. You should always test for the existence of a file by using
<literal remap="tt">QFileInfo</literal>'s <literal remap="tt">exists()</literal> method.</para>

<para>Within these methods,</para>

<para><screen>void invokeHTMLHelp( QString aFilename, QString aTopic ) const [public]
</screen>
</para>

<para>takes a special position to invoke the KDE help. Generally, you should use it everywhere a user needs to access information, e.g. when
he is presented a modal dialog. The F1 key will not work to invoke the help contents, also the user should be presented the according
help page. To make a good use of it, add a "Help" button to your dialog and create a slot that is used to connect on signal
<literal remap="tt">pressed()</literal>. In this method, use <literal remap="tt"><indexterm remap="cdx"><primary><literal>invokeHTMLHelp()</literal></primary></indexterm>invokeHTMLHelp()</literal> with the according page and subject; in case your application's documentation
isn't written completely yet, leave this open to complete it after the documentation is in sync with the application.</para>

<para>The documentation of <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> says:</para>

<para>Invoke the kdehelp HTML help viewer.</para>

<para>Parameters: aTopic
This allows context-sensitive help. Its value will be appended to the filename, prefixed with a "&&num;;" (hash) character.</para>

<para>aFilename: The filename that is to be loaded. Its location is computed automatically according to the KFSSTND. If aFilename is empty,
the logical appname with .html appended to it is used.</para>

<para>The methods of  <literal remap="tt"><indexterm remap="cdx"><primary><literal>KApplication</literal></primary></indexterm>KApplication</literal> will retrieve the following path's.</para>

<para><screen>kde_htmldir()         kdedir()/share/doc/HTML         Returns the directory where KDE stores
                                                      its HTML documentation

kde_appsdir()         kdedir()/share/applnk           Returns the directory where KDE applications
                                                      store their .kdelnk file

kde_icondir()         kdedir()/share/icons            Returns the directory where KDE icons are stored

kde_datadir()         kdedir()/share/apps             Returns the directory where KDE applications
                                                      store their specific data

kde_localedir()       kdedir()/share/locale           Returns the directory where locale-specific
                                                      information (like translated on-screen messages) are stored

kde_cgidir()          kdedir()/cgi-bin                Returns the directory where cgi scripts are stored

kde_sounddir()        kdedir()/share/sounds           Returns the directory where sound data are stored.
                                                      This directory is for KDE specific sounds.
                                                      Sound data of Applications should go
                                                      into kde_datadir()

kde_toolbardir()      kdedir()/share/toolbar          Returns the directory where toolbar icons are stored

kde_wallpaperdir()    kdedir()/share/wallpapers       Returns the directory where KDE wallpaper files are stored

kde_bindir()          kdedir()/bin                    Returns the directory where KDE application binaries are stored

kde_configdir()       kdedir()/share/config           Returns the directory where config files are stored

kde_mimedir()         kdedir()/share/mimelnk          Returns the directory where mimetypes are stored

localkdedir()         $HOME/.kde                      Get the local KDE base dir

localconfigdir()      $HOME/.kde/share/config         Get the local KDE config dir
</screen>
</para>

<para>To search for a specific file, use <literal remap="tt">findFile(const char *file)</literal> which will search several path's of the KDE File System:</para>

<para><orderedlist><listitem>
<para>$KDEDIR,</para>
</listitem>
<listitem>
<para>$KDEPATH,</para>
</listitem>
<listitem>
<para>"&&lsqb;;KDE Setup&&rsqb;;:Path=" entry in a config file.</para>
</listitem>
</orderedlist>
</para>

<para>If the file is not found, the QString method isEmpty() will  return True</para>
</sect1>

<sect1 id="kiconloader-methods">
<title>KIconLoader Methods</title>

<para>QPixmap loadIcon ( const QString &&amp;;name, int w = 0, int h = 0 )</para>

<para>QPixmap reloadIcon ( const QString &&amp;;name, int w = 0, int h = 0)</para>

<para>QPixmap loadMiniIcon ( const QString &&amp;;name , int w = 0, int h = 0 )</para>

<para>QPixmap loadApplicationIcon ( const QString &&amp;;name, int w = 0, int h = 0 )</para>

<para>QPixmap loadApplicationMiniIcon ( const QString &&amp;;name, int w = 0, int h = 0 )</para>

<para>bool insertDirectory ( int index, const QString &&amp;;dir&&lowbar;;name )</para>
</sect1>

<sect1 id="setting-file-installation-properties">
<title>Setting File Installation Properties</title>

<para>As the above explained where KDE applications <indexterm remap="idx"><primary>KDE applications</primary></indexterm> should place their files and how to access them at runtime, the following will explain
how to set the file properties correctly to ensure the files get installed at the right place. The Makefiles support a set of macros to
install your files into the KDE File System and which have to be used for setting the file installation properties.</para>

<para>To set the properties, open your project and select "Project"-"File Properties" which opens the File Properties dialog.
The file properties are displayed if you select a filename currently included in the project. First of all, a file has a type property,
which can be one of the following:</para>

<para><itemizedlist>
<listitem>
<para><emphasis remap="bf">HEADER:</emphasis>  specifies a file as a header file</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SOURCE:</emphasis> specifies a file as a source file</para>
</listitem>
<listitem>
<para><emphasis remap="bf">SCRIPT:</emphasis> specifies a file as a script file</para>
</listitem>
<listitem>
<para><emphasis remap="bf">DATA:</emphasis> specifies a file as a data file that usually gets installed like pixmaps or HTML documentation files</para>
</listitem>
<listitem>
<para><emphasis remap="bf">PO:</emphasis> specifies a file as a translation file</para>
</listitem>
<listitem>
<para><emphasis remap="bf">KDEV&&lowbar;;DIALOG:</emphasis> specifies a file as a dialog file to be interpreted by the dialog library</para>
</listitem>
</itemizedlist>
</para>

<para>Further, a file is included in the project, if "Include in Distribution" is checked. This ensures that the file is included in the
distribution tarball or package.</para>

<para>If a file has to be installed, you have to enable "Install". This will allow setting the Installation path for the selected file, where
the filename is already inserted.</para>

<para>Now, as said above, the Makefile already is capable of a set of macros for the KDE File System Standard. These are used to set the
installation path and ensure that the files actually will land in the KDE file system and not somewhere else. Macros that can be used,
have to be embraced in round brackets and are marked with the dollar sign in front of the macro. When configure builds the Makefiles on
the end-user's system, it will determine values for these macros that match the real directory name and will expand the Makefile.am
macro towards the actual destination.</para>

<para>When looking a standard KDE application project, you will see on the file property of your <literal remap="tt">index.html</literal> file that it already uses a
macro to determine where it should go:</para>

<para>$(kde&&lowbar;;htmldir)/en/kscribble/index.html</para>

<para>This says, that make should install the file index.html in the kde-html directory, subdirectory en for English, the application
subdirectory and the filename. You could as well use another filename if you like to rename the file on the installation destination.</para>

<para>For the destination of your binary you currently have to edit the project's Makefile.am if your destination should be different form
the "Applications" section of kpanel:</para>

<para>APPSDIR = $(kde&&lowbar;;appsdir)/Applications</para>

<para>Possible values are (as the KDE-File System Standard says):</para>

<para><itemizedlist>
<listitem>
<para>Applications</para>
</listitem>
<listitem>
<para>Games</para>
</listitem>
<listitem>
<para>Graphics</para>
</listitem>
<listitem>
<para>Internet</para>
</listitem>
<listitem>
<para>Multimedia</para>
</listitem>
<listitem>
<para>Settings</para>
</listitem>
<listitem>
<para>System</para>
</listitem>
<listitem>
<para>Utilities</para>
</listitem>
</itemizedlist>
</para>

<para>Setting no directory will end your applnk directly in kpanel's root.</para>

<para>The following list contains the macros that can be used in the installation setup for files:</para>

<para><screen>kde_htmldir       Where your docs should go to. (contains lang subdirs)
kde_appsdir       Where your application file (.kdelnk) should go to.
kde_icondir       Where your icon should go to.
kde_minidir       Where your mini icon should go to.
kde_datadir       Where you install application data. (Use a subdir)
kde_locale        Where translation files should go to.(contains lang subdirs)
kde_cgidir        Where cgi-bin executables should go to.
kde_confdir       Where config files should go to.
kde_mimedir       Where mimetypes should go to.
kde_toolbardir    Where general toolbar icons should go to.
kde_wallpaperdir  Where general wallpapers should go to.
</screen>
</para>

<para>Use these macros in conjunction with the according necessary subdirectories and the filename for setting the installation properties.
By default, the currently created HTML documentation files, the kdelnk file, Icon, Miniicon and the translation files (also newly
create ones) are already set up for their destination; therefore you don't have to make any changes for your default installation
routine that has been set up by the application wizard of KDevelop.</para>
</sect1>

<sect1 id="organizing-project-data">
<title>Organizing Project Data</title>

<para>Another issue in creating projects often appears to the programmer if he has or wants to include additional data that have to be
installed with the project. You already know where to install it, but what about organizing it in the source tree ?</para>

<para>A good advice here may be to collect all data in directories that more or less match the KDE File System Standard, e.g. your
application needs additional toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> icons. Creating these icons in the main project directory is potentially not a good idea as they
will be difficult to locate in the real file viewer and a removal will result in much work for each icon. Therefore, create your icon
with "File"- "New" and choose a subdirectory <literal remap="tt">toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></literal>; if it doesn't exist, it can be easily created with the "select directory"
dialog. Existing icons can be copied and included into the project with "Project"-"Add existing file(s)", where you have to choose the
files and the destination. When selecting the destination directory, you can create the <literal remap="tt">toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></literal> subdirectory first within the
selection dialog. After being finished, press OK and the files will be copied as well as included in the project.</para>

<para>As an example, a toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> icon should go to the following:</para>

<para>$(kde&&lowbar;;datadir)/<emphasis>&&lt;;appname&&gt;;</emphasis>/toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm>/<emphasis>&&lt;;youricon&&gt;;</emphasis>.xpm</para>

<para>Pictures or additional icons that are not used as toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm> icons should go to a subdirectory <emphasis>pics</emphasis> instead of <emphasis>toolbar <indexterm remap="idx"><primary>toolbar</primary></indexterm></emphasis>.</para>
</sect1>

<sect1 id="the-kdelnk-file">
<title>The <literal remap="tt">kdelnk</literal> File</title>

<para>The <emphasis>&&lt;;appname&&gt;;</emphasis>.kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm> file currently included in your project will install itself in KDE's kpanel structure. You should think
it is already created and complete, therefore shouldn't require any further notification. Despite of KDevelop's advanced qualities to
help you with creating, programming and designing applications, it cannot determine the exact purpose of your application- and that is
the information you have to add to the kdelnk file. As this is a text file, select it from the RFV or the LFV; it will be opened in the
Header/Resource window.</para>

<para>The sample kdelnk file would look like this:
<screen># KDE Config File
&&lsqb;;KDE Desktop Entry&&rsqb;;
Type=Application
Exec=kscribble
Icon=kscribble.xpm
DocPath=kscribble/index.html
Comment=
Comment&&lsqb;;de&&rsqb;;=
Terminal=0
Name=kscribble
Name&&lsqb;;de&&rsqb;;=kscribble
</screen>
</para>

<para>This already contains the basic configuration for the application specific data such as the icon, binary name, application name etc.
You see that the section Comment is still empty. There you have to insert the Quick-Tip that will be displayed when the mouse cursor
moves over the kdelnk file icon on the desktop or in kpanel. If scribble would be a small drawing program, you would enter e.g.</para>

<para><screen>Comment=A simple drawing program
</screen>
</para>

<para>Each comment line afterwards will contain the same description translated in the language the brackets symbolize. Ask translators to
insert a good translation in their native language or include the kdelnk file when asking for translating the application's po file;
the same applies to the name of the application set in the Name lines.
<footnote>
<para>for more information about the purpose of the .kdelnk <indexterm remap="idx"><primary>.kdelnk</primary></indexterm> file, especially its use for commandline processing, see
<ulink url="kde_libref.html">The KDE Library Reference Guide</ulink></para>
</footnote>
</para>
</sect1>
</chapter>

<chapter id="programming-guidelines">
<title>Programming Guidelines</title>

<para>Close to the end of this handbook, I want to summarize several issues that programmers should watch out while coding. These are mostly
C++ programming tips that relate to KDE and Qt programming especially and are taken from the KDE Developer's Center which can be found
on the Internet at <ulink url="http://www.kde.org">\|\|</ulink>.</para>

<para><variablelist>
<varlistentry>
<term>Filenames</term>
<listitem>
<para>First of all, when creating sourcefiles, you should always use lowercase filenames. KDevelop supports
this guideline already if you stick to its filename aut-suggestion. This makes it easier for other developers to remember what source
files to look for when they have to debug your application.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Classnames</term>
<listitem>
<para>The classnaming for KDE projects is recommended to be:
<itemizedlist>
<listitem>
<para>class names should begin with a prefixed <emphasis remap="bf">K</emphasis> followed by the name of the class by purpose (your choice). This would be e.g.
<literal remap="tt">KMyWidget</literal> for an application specific widget.</para>
</listitem>
<listitem>
<para>the class members should always begin with lowercase letters, followed by uppercase beginnings for the next word, e.g.
<literal remap="tt">myWidgetPointer()</literal></para>
</listitem>
<listitem>
<para>methods that return a private members value shouldn't use the <literal remap="tt">get</literal>-prefix. You should prefer using a descriptive name for
those types of classmembers. Example: <literal remap="tt">b&&lowbar;;myboolean</literal> is a private member. The method returning the current value would be e.g.
<literal remap="tt">myBoolean()</literal>.</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>File access within code</term>
<listitem>
<para>Hardcoding any path should be avoided by using the KDE File System Standard. You only have to watch the installation path for your
files by the according macros of the <literal remap="tt">Makefile.am</literal> as described in this handbook. Within the code, you should use the methods of
<literal remap="tt">KApplication</literal> to retrieve the actual path.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Class documentation</term>
<listitem>
<para>Another thing already mentionend is class documentation. You should stick to use <literal remap="tt">KDoc</literal> formatting rules as they are used by all KDE
developers to document their classes. You should at least add a single line to all of your classmembers for yourself to remember the
prurpose and for others to reuse code. The code-reuse by the GPL makes much more sense if you know where to find an already existing
solution if classes are documented. The Qt library referece is a good example of well-documented interfaces, though it doesn't use
<literal remap="tt">KDoc</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Use <literal remap="tt">new</literal> to create widgets</term>
<listitem>
<para>Within your implementation, you should always prefer to create widgets on the heap with <literal remap="tt">new</literal>. The Qt library has a nice habbit to
automatically delete all child widgets you created with <literal remap="tt">new</literal>, so you don't ever have to use <literal remap="tt">delete</literal> again in those cases. This
is one of the most important practical features of the Qt library and you should make wide use of this.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Debugging</term>
<listitem>
<para>When it comes to debugging, you should make use of the macros <literal remap="tt">KDebug</literal> provides. Those are similar to the Qt macros, but can be
retrieved by the keycode STRG+ALT+F12. See the <ulink url="kde_libref-4.html#ss4.4">KDE Library Reference Guide</ulink> for more
information about the event filtering of these Macros. You could as well use <literal remap="tt">assert()</literal>, but should try to be consistent with your
debugging code.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal remap="tt">const</literal>-declarations</term>
<listitem>
<para>Further, you should use <literal remap="tt">const</literal> declarations for member functions that should or do not change any private member. This would be the
case for all methods that only return the current value of a private member. This avoids changing the value accidently and will catch
those logical errors at compile time. Now, towards initializing const members you should stick to do that together with using
<literal remap="tt">static</literal> in the declaration and initialize the value outside the constructor like this:
<screen>class foo {
	static const int value;
};

const foo::value = 10;
</screen>

ANSI C++ allows to initialize the member inside the constructor but you should avoid this as a few compilers are not capable of this
feature.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Virtual methods</term>
<listitem>
<para>As explained in section <link linkend="User-Interaction">User Interaction</link>, you should stick to the access rights and the declaration
by <literal remap="tt">virtual</literal> when overwriting virtual methods. At least you shouldn't reduce the access of a virtual method from protected to
private.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Forward declarations</term>
<listitem>
<para>Class-headers should be included where you dereference any object or instance of a class in your sourcecode. That means if your class
uses a member of another class, replace the &&num;;include directive with a forward declaration of the class, e.g  instead of:</para>
<para><screen>#include &lt;qpushbutton.h&gt;

class KMyWidget:public QWidget
{

private:
  QPushButton* ok_button;
};
</screen>
</para>
<para>you should prefer to only declaring the class <literal remap="tt">QPushButton</literal> in the header file:</para>
<para><screen>class QPushButton;

class KMyWidget:public QWidget
{

private:
  QPushButton* ok_button;
};
</screen>
</para>
<para>and place the include directive into the according sourcefile where e.g. the instance <literal remap="tt">ok&&lowbar;;button</literal> is dereferenced with any method of
the class <literal remap="tt">QPushButton</literal>. This saves compile time at any rate, especially if you're using instances of classes that your're working
on. The compiler will recompile all souces that include the header file if you made any changes on the interface of the class,
therefore a simple addition of a method that only returns an internal value will lead to a recompilation of all sources tha include
the header file of the class.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Unused Parmeter Warnings and default arguments</term>
<listitem>
<para>Also you should leave out formal parameters of methods that don't necessarily require the actual parameter to work. This avoids the
<literal remap="tt">unused parameter</literal> warnings of your compiler when he sees a method that retrieves a formal parameter but doesn't use it in its
implementation. Usually, you will set some default arguments for several methods. Those should always be placed in the declaration of
the class member instead of setting them in the member implementation.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Using <literal remap="tt">config.h</literal></term>
<listitem>
<para>KDevelop projects as well as any other project that is using <literal remap="tt">autoconf</literal> to create a <literal remap="tt">configure</literal>-script produce a file
<literal remap="tt">config.h</literal> after executing the <literal remap="tt">configure</literal>-script on the target machine. The values found by <literal remap="tt">configure</literal> are listed there and
can be used within the sourcecode. The directive to include the <literal remap="tt">config.h</literal> file is:</para>
<para><screen>#ifdef HAVE_CONFIG_H
#include &lt;config.h&gt;
#endif
</screen>
</para>
<para>One of the most recently used entries of <literal remap="tt">config.h</literal> is probably the type-definition of <literal remap="tt">bool</literal> for compilers that don't comply
with the newest ANSI C++ draft.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Use <literal remap="tt">0</literal> instead of <literal remap="tt">NULL</literal></term>
<listitem>
<para>You should stickt to using <literal remap="tt">0</literal> directly instead of <literal remap="tt">NULL</literal> for preset values like the Qt and KDE libraries already do. This
increases portablility of your applications towards different compilers that have problems with <literal remap="tt">NULL</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Temporaries</term>
<listitem>
<para>You should declare temporary instances always before using them. This is generally considered better than direct use. Example:
<screen>// Don't:
for( int i=0; i&lt;n; i++){
  //do something
  };

// Do:
int i;

for(i=0; i&lt;n; i++){
  //do something
  };
</screen>
</para>
<para>This also counts on using temporaries in function calls:
<screen>// Don't:
setColor( &&amp;;(QColor(black)) );

// Do:
QColor color(black);
setColor( &&amp;;color );
</screen>
</para>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</para>
</chapter>

<chapter id="references">
<title>References</title>

<para>The KDevelop Programming Handbook contains information that are taken from various sources on the Internet and by mails to various
mailing lists, as:</para>

<para><emphasis remap="bf">KDoc <indexterm remap="idx"><primary>KDoc</primary></indexterm> documentation:</emphasis> Sirtaj S. Kang <ulink url="mailto:taj@.kde.org">taj@.kde.org</ulink></para>

<para><emphasis remap="bf">KDE Developer's Center</emphasis> maintained by Sirtaj S. Kang <ulink url="mailto:taj@.kde.org">taj@.kde.org</ulink></para>

<para><emphasis remap="bf">KDE Internationalization:</emphasis> Matthias Elter <ulink url="mailto:me@kde.org">me@kde.org</ulink></para>

<para><emphasis remap="bf">KDebug documentation:</emphasis> Kalle Dalheimer <ulink url="mailto:kalle@kde.org">kalle@kde.org</ulink></para>

<para><emphasis remap="bf">The KDE File System Standard:</emphasis> Richard Moore <ulink url="mailto:rich@kde.org">rich@kde.org</ulink></para>

<para><emphasis remap="bf">KDE-Developer's mini-HOWTO:</emphasis> David Sweet <ulink url="mailto:dsweet@chaos.umd.edu">&lt;dsweet@chaos.umd.edu&gt;</ulink></para>

<para>The contents of the according chapters are copyright of the original authors.</para>
</chapter>

<chapter id="copyright">
<title>Copyright</title>

<para><screen>
KDevelop Copyright 1998,1999 The KDevelop Team.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</screen>
</para>
</chapter>
<appendix id="additional-information">
<title>Additional Information</title>

<sect1 id="example-makefile.am-for-a-shared-library">
<title>Example Makefile.am for a Shared Library</title>

<para><screen># Example Makefile.am for a shared library.  It makes a library
#  called "example" as libexample.so.2.1.2
# This Makefile.am was taken from the kdelibs distribution and modified
#  to serve as an example.
#
# David Sweet
#

INCLUDES=  $(all_includes)

lib_LTLIBRARIES  = libexample.la

# Note:  If you specify a:b:c as the version in the next line,
#  the library that is made has version (a-c).c.b.  In this
#  example, the version is 2.1.2.
libexample_la_LDFLAGS = -version-info 3:2:1 $(all_libraries)

include_HEADERS = header1.h header2.h\
                  header3.h

# Which headers shouldn't be installed when a   make install  is done?
noinst_HEADERS = version.h

libexample_la_SOURCES = code1.cpp code2.cpp
                        code3.cpp

#  USE_AUTOMOC is great.  This takes care of all of your  moc'ing
#   dependencies.
#  (You still need to include, for example, header1.moc in code1.cpp.)
libexample_la_METASOURCES = USE_AUTOMOC
</screen>
</para>
</sect1>
  </appendix>
<![ %addindex; [ &docindex; ]]>
</book>
<!--
Local Variables:
mode: sgml
sgml-omittag: nil
sgml-shorttag: t
sgml-general-insert-case: lower
End:
-->
