# Suportar Formatos de Ficheiro Adicionais

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 Conceitos de Fontes de Dados

## Criar Leitores de Fontes de Dados

Se deseja utilizar um formato de ficheiro que não é actualmente suportado, pode escolher escrever um leitor de fonte de dados personalizado.

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 `*.desktop`. 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 é ascii.

Os 'plugins' do &kde; não 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;.

### O Objecto Partilhado

Um leitor de fontes de dados deverá ser uma sub-classe da classe abstracta `KstDataSource`. Garanta que inclui o ficheiro de inclusão do `KstDataSource` no ficheiro de código do seu leitor:

    #include <kstdatasource.h>

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 `KstDataSource`. Qualquer um dos conjuntos de requisitos, em conjunto com as sugestões e explicações gerais, são indicados nas secções seguintes.

#### Funções C Exportadas

As funções em C exportadas estão listadas em baixo. Nos exemplos seguintes, todas as instâncias de `<libname>` deverão ser substituídas pelo nome actual da biblioteca do 'plugin'.

`KstDataSource *create_<libname>(const QString& `filename`, const QString& `type`)`

  Esta função deverá criar um novo leitor de fontes de dados do tipo `<libname>`, em que o `<libname>` é o nome da biblioteca do 'plugin'. Deverá ser devolvido um ponteiro do tipo `KstDataSource` para o novo leitor.

`bool understands_<libname>(const QString& `filename`)`

  Este função deve devolver verdadeiro se o ficheiro indicado por `filename` é 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.

`QStringList provides_<libname>()`

  Esta função deve devolver uma `QStringList` 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.

#### Variáveis Membro Protegidas

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

`bool _valid`

  Esta variável deverá ser `true` (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 `isValid()` do `KstDataSource`, a qual não é normalmente implementada de novo pelas sub-classes.

`QStringList _fieldList`

  Esta variável deve conter uma lista dos nomes dos campos da fonte de dados.

`QString _filename`

  Esta variável deve conter o nome do ficheiro de dados a que este leitor de fonte de dados está associado.

`QString _source`

  Esta variável deve conter o nome do tipo da fonte.

#### Funções Virtuais

A classe `KstDataSource` 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 `template.h` e `template.cpp`, listados na secção dos Modelos de Exemplo. Seguem-se as descrições das funções.

`TemplateSource(const QString&amp; `filename`, const QString&amp; `type`)`

  O construtor do leitor da fonte de dados. O `filename` é o nome do ficheiro a partir do qual ler os dados e o `type` é o tipo de dados que o ficheiro contém. Este construtor deverá provavelmente invocar o construtor do `KstDataSource` na lista de inicialização do construtor e chamar a função `update` indicada em baixo para inicializar as variáveis-membro. Em particular, a variável `bool _valid` deverá ser configurada apropriadamente.

`virtual ~TemplateSource()`

  O destrutor do leitor de fonte de dados. A memória alocada dinamicamente deve ser libertada.

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

  Esta função deverá ler os dados novos introduzidos no ficheiro de dados, desde a última vez que o `update` foi chamado, actualizando as variáveis-membro apropriadamente. A função deverá devolver `KstObject::UPDATE` se o ficheiro continha alterações ou `KstObject::NO_CHANGE`, caso contrário.

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

  Esta função deverá ler `n` tramas de dados, a começar na trama `s` do campo indicado pelo nome `field`, devolvendo o conteúdo no vector `v`. Se o `n` for menor que 0, a função deverá em alternativa ler uma amostra a começar na trama `s`. O número de tramas lidas deverá ser devolvido.

`virtual bool isValidField(const QString &`field`) const`

  Esta função deverá devolver um valor verdadeiro se o campo indicado pelo nome `field` for um campo válido na fonte de dados actual ou falso se o não for.

`virtual int samplesPerFrame(const QString& `field`)`

  Esta função deverá devolver a relação das amostras por trama para o campo indicado pelo nome `field`. Para as fontes de dados que não tirem partido deste conceito, o número de amostras por trama poderá ser igual a `1`.

`virtual int frameCount() const`

  Esta função deverá devolver o número total de tramas na fonte de dados desde a última vez que o `update` foi chamado.

`virtual QString fileType() const ```

  Esta função deverá devolver o tipo do ficheiro de dados a ser usado de momento e que é normalmente o mesmo do parâmetro `type` que foi passado ao construtor. Em alternativa, poderá conter uma mensagem de erro (para indicar, por exemplo, que o ficheiro não é válido).

`virtual void save(QTextStream &`ts`)`

  Esta função deverá gravar a informação de descrição do ficheiro no `ts`. Na maioria dos casos, a implementação oferecida pelo `KstDataSource` deverá ser suficiente.

#### Modelos de Exemplo

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.

    /***************************************************************************
                      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 &lt;kstdatasource.h&gt;

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

      virtual ~TemplateSource();

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

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

      virtual bool isValidField(const QString &field) const;

      virtual int samplesPerFrame(const QString &field);

      virtual int frameCount() const;

      virtual QString fileType() const;

      virtual void save(QTextStream &ts);
    };

    #endif

    /***************************************************************************
                        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& filename, const QString& 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& field, int s, int n) {
      Q_UNUSED(v)
      Q_UNUSED(field)
      Q_UNUSED(s)
      Q_UNUSED(n)
      return -1;
    }

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

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

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

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

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

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

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

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

    }

### O ficheiro `.desktop`

Segue-se um exemplo de um ficheiro `.desktop` para o 'plugin' modelo:

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

Você deverá adicionar as traduções nas línguas adicionais para os campos Name e Comment, adicionando campos extra Name e Comment com o `[xx]` adicionado ao fim do nome dos campos, em que o `xx` é 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:

    Name[pt]=Modelo de leitor de ficheiros
    Comment[pt]=Descrição longa do modelo de leitor de ficheiros.

O campo `X-Kst-Plugin-Library` deve conter exactamente o nome utilizado para a biblioteca do 'plugin'.

### Compilar e Copiar

Para compilar e instalar o novo leitor de fonte de dados personalizado, crie uma pasta nova dentro de `kst/datasources` do pacote de código. Coloque os ficheiros de código do objecto, em conjunto com o ficheiro `.desktop`, na pasta nova. Depois, edite o `kst/datasources/Makefile.am` para que o `SUBDIRS` contenha o nome da subpasta nova. Por exemplo, se a nova subpasta se chamar `modelo`, o `SUBDIRS` poderá ser alterado para o seguinte:

    SUBDIRS=ascii dirfile frame indirect modelo $(PIOLIB_SUBDIR) $(FITSIO_SUBDIR)

Depois de os ficheiros necessários estarem na subpasta criada, é necessário criar um ficheiro `Makefile.am` dentro desta. Use o exemplo seguinte como modelo, substituindo todas as instâncias de modelo com o nome da sua biblioteca personalizada em `kde_module_LTLIBRARIES`, `kstdata_modelo_la_SOURCES` e `services_DATA`.

    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

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 modelo como exemplo). Mude primeiro para a pasta de topo do pacote de código do &kst;. De seguida,

    ./configure --prefix=`kde-config --prefix`
    cd ./kst/datasources/template
    make
    make install

Reinicie o &kst; e o novo leitor de fonte de dados de ser carregado.