<appendix id="supportingadditionalfileformats">
<title
>Suportar Formatos de Ficheiro Adicionais</title>
<para
>Este secção descreve como criar leitores adicionais para formatos de ficheiro não suportados. Se ainda não estiver familiarizado com os conceitos das fontes de dados, por favor leia <link linkend="supportingadditionalfileformatsdatasourceconcepts"
>Conceitos de Fontes de Dados</link
> </para>



<sect1 id="supportingadditionalfileformatscreatingdatasource">
<title
>Criar Leitores de Fontes de Dados</title>

<para
>Se deseja utilizar um formato de ficheiro que não é actualmente suportado, pode escolher escrever um leitor de fonte de dados personalizado. </para>
<para
>Todos os leitores de fontes de dados do &kst; são 'plugins' normais do &kde;. Como todos os 'plugins' do &kde;, cada leitor de fontes de dados terá de ter um ficheiro-objecto partilhado e um ficheiro <filename
>*.desktop</filename
>. Antes de criar o leitor, o nome da biblioteca do 'plugin' terá de ser decidido. Este nome deverá ser um nome de variável válido em C, dado que será usado nos nomes das funções do objecto partilhado .Por exemplo, o nome da biblioteca do leitor de ficheiros ASCII é <quote
>ascii</quote
>. </para>
<note>
<para
>Os 'plugins' do &kde; <emphasis
>não</emphasis
> são o mesmo que os 'plugins' que o &kst; utiliza para manipular dados. Todas as referências a 'plugins' nesta secção são a 'plugins' do &kde;. </para>
</note>

<sect2 id="supportingadditionalfileformatscreatingdatasourceobjectfile">
<title
>O Objecto Partilhado</title>
<para
>Um leitor de fontes de dados deverá ser uma sub-classe da classe abstracta <classname
>KstDataSource</classname
>. Garanta que inclui o ficheiro de inclusão do <classname
>KstDataSource</classname
> no ficheiro de código do seu leitor: <screen>
#include &lt;kstdatasource.h&gt;
</screen
> Existem certos requisitos que um leitor de fontes de dados deverá obedecer. Um dos requisitos respeita à presença das funções em C exportadas. Outros requisitos são uma consequência do facto de que os leitores de fontes de dados herdam da classe <classname
>KstDataSource</classname
>. Qualquer um dos conjuntos de requisitos, em conjunto com as sugestões e explicações gerais, são indicados nas secções seguintes. </para>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfileexportedfxns">
<title
>Funções C Exportadas</title>
<para
>As funções em C exportadas estão listadas em baixo. Nos exemplos seguintes, todas as instâncias de <varname
>&lt;libname&gt;</varname
> deverão ser substituídas pelo nome actual da biblioteca do 'plugin'. </para>
<variablelist>
<varlistentry>
<term
><function
><returnvalue
>KstDataSource *</returnvalue
>create_&lt;libname&gt;(const QString&amp; <parameter
>filename</parameter
>, const QString&amp; <parameter
>type</parameter
>)</function
></term>
<listitem>
<para
>Esta função deverá criar um novo leitor de fontes de dados do tipo <varname
>&lt;libname&gt;</varname
>, em que o <varname
>&lt;libname&gt;</varname
> é o nome da biblioteca do 'plugin'. Deverá ser devolvido um ponteiro do tipo <classname
>KstDataSource</classname
> para o novo leitor. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
><returnvalue
>bool</returnvalue
> understands_&lt;libname&gt;(const QString&amp; <parameter
>filename</parameter
>)</function
></term>
<listitem>
<para
>Este função deve devolver verdadeiro se o ficheiro indicado por <varname
>filename</varname
> é de um tipo válido suportado por este leitor, e falso em caso contrário. A função deve verificar a validade do conteúdo do ficheiro e não confiar apenas na extensão do ficheiro. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
><returnvalue
>QStringList</returnvalue
> provides_&lt;libname&gt;()</function
></term>
<listitem>
<para
>Esta função deve devolver uma <classname
>QStringList</classname
> dos tipos de ficheiro suportados por este leitor. Os textos devolvidos são arbitrários, mas devem descritivos e apropriados para os tipos de ficheiro envolvidos. </para>
</listitem>
</varlistentry>

</variablelist>

</sect3>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfilemembervars">
<title
>Variáveis Membro Protegidas</title>
<para
><classname
>KstDataSource</classname
> contém várias variáveis membro protegidas que o leitor personalizado de fontes de dados pode utilizar. Esta variáveis são descritas de seguida. </para>

<variablelist>
<varlistentry>
<term
><varname
>bool _valid</varname
></term>
<listitem>
<para
>Esta variável deverá ser <literal
>true</literal
> (verdadeira) se o leitor personalizado da fonte de dados for válido. O mais provável é que o leitor será válido, a menos que haja uma condição de erro (como o facto de o ficheiro de dados ser ilegível para o leitor). Esta variável é usada pela função <function
>isValid()</function
> do <classname
>KstDataSource</classname
>, a qual não é normalmente implementada de novo pelas sub-classes. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>QStringList _fieldList</varname
></term>
<listitem>
<para
>Esta variável deve conter uma lista dos nomes dos campos da fonte de dados. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>QString _filename</varname
></term>
<listitem>
<para
>Esta variável deve conter o nome do ficheiro de dados a que este leitor de fonte de dados está associado. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>QString _source</varname
></term>
<listitem>
<para
>Esta variável deve conter o nome do tipo da fonte. </para>
</listitem>
</varlistentry>
</variablelist>

</sect3>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfilevirtualfxns">
<title
>Funções Virtuais</title>
<para
>A classe <classname
>KstDataSource</classname
> contém várias funções virtuais que têm de ser definidas de novo pelo leitor personalizado da fonte de dados. Estas funções estão nos ficheiros de modelo <filename
>template.h</filename
> e <filename
>template.cpp</filename
>, listados na secção dos <link linkend="supportingadditionalfileformatscreatingdatasourceobjectfileexample"
>Modelos de Exemplo</link
>. Seguem-se as descrições das funções. </para>

<variablelist>
<varlistentry>
<term
><function
>TemplateSource(const QString&amp;amp; <parameter
>filename</parameter
>, const QString&amp;amp; <parameter
>type</parameter
>) </function
></term>
<listitem>
<para
>O construtor do leitor da fonte de dados. O <varname
>filename</varname
> é o nome do ficheiro a partir do qual ler os dados e o <varname
>type</varname
> é o tipo de dados que o ficheiro contém. Este construtor deverá provavelmente invocar o construtor do <classname
>KstDataSource</classname
> na lista de inicialização do construtor e chamar a função <function
>update</function
> indicada em baixo para inicializar as variáveis-membro. Em particular, a variável <varname
>bool _valid</varname
> deverá ser configurada apropriadamente. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual ~TemplateSource()</function
></term>
<listitem>
<para
>O destrutor do leitor de fonte de dados. A memória alocada dinamicamente deve ser libertada. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>KstObject::UpdateType</returnvalue
> update(<parameter
>int = -1</parameter
>) </function
></term>
<listitem>
<para
>Esta função deverá ler os dados novos introduzidos no ficheiro de dados, desde a última vez que o <function
>update</function
> foi chamado, actualizando as variáveis-membro apropriadamente. A função deverá devolver <varname
>KstObject::UPDATE</varname
> se o ficheiro continha alterações ou <varname
>KstObject::NO_CHANGE</varname
>, caso contrário. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>int</returnvalue
> readField(double *<parameter
>v</parameter
>, const QString &amp;<parameter
>field</parameter
>, int <parameter
>s</parameter
>, int <parameter
>n</parameter
>)</function
></term>
<listitem>
<para
>Esta função deverá ler <varname
>n</varname
> tramas de dados, a começar na trama <varname
>s</varname
> do campo indicado pelo nome <varname
>field</varname
>, devolvendo o conteúdo no vector <varname
>v</varname
>. Se o <varname
>n</varname
> for menor que 0, a função deverá em alternativa ler uma amostra a começar na trama <varname
>s</varname
>. O número de tramas lidas deverá ser devolvido. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>bool</returnvalue
> isValidField(const QString &amp;<parameter
>field</parameter
>) const</function
></term>
<listitem>
<para
>Esta função deverá devolver um valor verdadeiro se o campo indicado pelo nome <varname
>field</varname
> for um campo válido na fonte de dados actual ou falso se o não for. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>int</returnvalue
> samplesPerFrame(const QString&amp; <parameter
>field</parameter
>)</function
></term>
<listitem>
<para
>Esta função deverá devolver a relação das amostras por trama para o campo indicado pelo nome <varname
>field</varname
>. Para as fontes de dados que não tirem partido deste conceito, o número de amostras por trama poderá ser igual a <literal
>1</literal
>. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>int</returnvalue
> frameCount() const</function
></term>
<listitem>
<para
>Esta função deverá devolver o número total de tramas na fonte de dados desde a última vez que o <function
>update</function
> foi chamado. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>QString</returnvalue
> fileType() const <parameter
></parameter
></function
></term>
<listitem>
<para
>Esta função deverá devolver o tipo do ficheiro de dados a ser usado de momento e que é normalmente o mesmo do parâmetro <varname
>type</varname
> que foi passado ao construtor. Em alternativa, poderá conter uma mensagem de erro (para indicar, por exemplo, que o ficheiro não é válido). </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>void</returnvalue
> save(QTextStream &amp;<parameter
>ts</parameter
>)</function
></term>
<listitem>
<para
>Esta função deverá gravar a informação de descrição do ficheiro no <varname
>ts</varname
>. Na maioria dos casos, a implementação oferecida pelo <classname
>KstDataSource</classname
> deverá ser suficiente. </para>
</listitem>
</varlistentry>


</variablelist>

</sect3>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfileexample">
<title
>Modelos de Exemplo</title>
<para
>De um modo geral, os dois ficheiros de modelo seguintes poderão ser usados para criar novos ficheiros-objecto partilhados. Basta modificar o conteúdo das funções de forma apropriada à sua fonte de dados em particular. </para>
<informalexample>
<screen
>/***************************************************************************
                  template.h  -  modelo de 'plugin' de fonte de dados
                             -------------------
    begin                : Fri Oct 17 2003
    copyright            : (C) 2003 The University of Toronto
    email                :
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef TEMPLATE_H
#define TEMPLATE_H

#include &amp;lt;kstdatasource.h&amp;gt;


class TemplateSource : public KstDataSource {
public:
  TemplateSource(const QString&amp; filename, const QString&amp; type);

  virtual ~TemplateSource();

  virtual KstObject::UpdateType update(int = -1);

  virtual int readField(double *v, const QString &amp;field, int s, int n);

  virtual bool isValidField(const QString &amp;field) const;

  virtual int samplesPerFrame(const QString &amp;field);

  virtual int frameCount() const;

  virtual QString fileType() const;

  virtual void save(QTextStream &amp;ts);
};


#endif
</screen>
</informalexample>
 
<informalexample>
<screen
>/***************************************************************************
                    template.cpp  -  modelo de fonte de dados
                             -------------------
    begin                : Fri Oct 17 2003
    copyright            : (C) 2003 The University of Toronto
    email                :
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "template.h"


TemplateSource::TemplateSource(const QString&amp; filename, const QString&amp; type)
: KstDataSource(filename, type) {
}


TemplateSource::~TemplateSource() {
}


KstObject::UpdateType TemplateSource::update(int u) {
  Q_UNUSED(u)
  return KstObject::NO_CHANGE;
}


int TemplateSource::readField(double *v, const QString&amp; field, int s, int n) {
  Q_UNUSED(v)
  Q_UNUSED(field)
  Q_UNUSED(s)
  Q_UNUSED(n)
  return -1;
}


bool TemplateSource::isValidField(const QString&amp; field) const {
  Q_UNUSED(field)
  return false;
}


int TemplateSource::samplesPerFrame(const QString &amp;field) {
  Q_UNUSED(field)
  return 0;
}


int TemplateSource::frameCount() const {
  return 0;
}


QString TemplateSource::fileType() const {
  return QString::null;
}


void TemplateSource::save(QTextStream &amp;ts) {
  KstDataSource::save(ts);
}


extern "C" {
KstDataSource *create_template(const QString&amp; filename, const QString&amp; type) {
  return new TemplateSource(filename, type);
}

QStringList provides_template() {
  QStringList rc;
  // criar a lista de strings
  return rc;
}

bool understands_template(const QString&amp; filename) {
  // determinar se é um ficheiro X
  Q_UNUSED(filename)
  return false;
}

}
</screen>
</informalexample>
</sect3>

</sect2>

<sect2 id="supportingadditionalfileformatscreatingdatasourcedesktopfile">
<title
>O ficheiro <filename
>.desktop</filename
></title>
<para
>Segue-se um exemplo de um ficheiro <filename
>.desktop</filename
> para o 'plugin' modelo: </para>
<informalexample>
<screen
>[Desktop Entry]
Encoding=UTF-8
Type=Service
ServiceTypes=Kst Data Source
X-KDE-ModuleType=Plugin
X-Kst-Plugin-Library=template
X-Kst-Plugin-Author=The University of Toronto
Name=File Reader Template
Comment=Long description of the file reader template.
</screen>
</informalexample>

<para
>Você deverá adicionar as traduções nas línguas adicionais para os campos Name e Comment, adicionando campos extra Name e Comment com o <literal
>[xx]</literal
> adicionado ao fim do nome dos campos, em que o <literal
>xx</literal
> é o código de duas letras da língua. Por exemplo, para adicionar as traduções para Português, teriam de ser adicionadas as seguintes linhas: </para>
<informalexample>
<screen
>Name[pt]=Modelo de leitor de ficheiros
Comment[pt]=Descrição longa do modelo de leitor de ficheiros.
</screen>
</informalexample>
<para
>O campo <literal
>X-Kst-Plugin-Library</literal
> deve conter exactamente o nome utilizado para a biblioteca do 'plugin'. </para>
</sect2>

<sect2 id="supportingadditionalfileformatscreatingdatasourcecompiling">
<title
>Compilar e Copiar</title>
<para
>Para compilar e instalar o novo leitor de fonte de dados personalizado, crie uma pasta nova dentro de <filename
>kst/datasources</filename
> do pacote de código. Coloque os ficheiros de código do objecto, em conjunto com o ficheiro <filename
>.desktop</filename
>, na pasta nova. Depois, edite o <filename
>kst/datasources/Makefile.am</filename
> para que o <varname
>SUBDIRS</varname
> contenha o nome da subpasta nova. Por exemplo, se a nova subpasta se chamar <filename
>modelo</filename
>, o <varname
>SUBDIRS</varname
> poderá ser alterado para o seguinte: <informalexample
> <screen
>SUBDIRS=ascii dirfile frame indirect modelo $(PIOLIB_SUBDIR) $(FITSIO_SUBDIR)
</screen>
</informalexample>
</para>


<para
>Depois de os ficheiros necessários estarem na subpasta criada, é necessário criar um ficheiro <filename
>Makefile.am</filename
> dentro desta. Use o exemplo seguinte como modelo, substituindo todas as instâncias de <quote
>modelo</quote
> com o nome da sua biblioteca personalizada em <varname
>kde_module_LTLIBRARIES</varname
>, <varname
>kstdata_modelo_la_SOURCES</varname
> e <varname
>services_DATA</varname
>. </para>
<informalexample>
<screen
>INCLUDES=-I$(srcdir)/../.. $(all_includes)

kde_module_LTLIBRARIES=kstdata_modelo.la

kstdata_modelo_la_LDFLAGS=$(all_libraries) -module -avoid-version
kstdata_modelo_la_SOURCES=modelo.cpp

METASOURCES=AUTO

services_DATA=kstdata_modelo.desktop
servicesdir=$(kde_servicesdir)/kst
</screen>
</informalexample>

<para
>Logo que isto tenha sido feito, você poderá compilar e reinstalar o &kst; a partir do pacote de código modificado ou, em alternativa, instale apenas as bibliotecas novas, como se segue (usando a subpasta <quote
>modelo</quote
> como exemplo). Mude primeiro para a pasta de topo do pacote de código do &kst;. De seguida, <screen
><userinput
><command
>./configure --prefix=`kde-config --prefix`</command>
<command
>cd ./kst/datasources/template</command>
<command
>make</command>
<command
>make install</command
></userinput
></screen>
</para>

<para
>Reinicie o &kst; e o novo leitor de fonte de dados de ser carregado. </para>
</sect2>

</sect1>


</appendix>


<!-- Keep this comment at the end of the file
Local variables:
mode: xml
sgml-omittag:nil
sgml-shorttag:nil
sgml-namecase-general:nil
sgml-general-insert-case:lower
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:0
sgml-indent-data:true
sgml-parent-document:("index.docbook" "book" "appendix")
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
