<appendix id="supportingadditionalfileformats">
<title
>Soporte para formatos adicionales de archivos</title>
<para
>Esta sección describe como crear lectores adicionales para la lectura de archivos de datos no soportados. Si no está familiarizado con los conceptos de fuentes de datos, por favor, lea <link linkend="supportingadditionalfileformatsdatasourceconcepts"
>Conceptos de fuentes de datos</link
> </para>



<sect1 id="supportingadditionalfileformatscreatingdatasource">
<title
>Creando lectores de fuentes de datos</title>

<para
>Si desea usar un formato de archivos diferente a aquellos que ya están soportados, puede escribir sus propios lectores de datos de fuentes. </para>
<para
>Todos los lectores de fuentes de &kst; son plugins normales de &kde;. Como todos los plugins de &kde;, cada lector de fuentes de datos debe tener una librería dinámica y un archivo <filename
>*.desktop</filename
>. Antes de escribir el lector, debe decidirse el nombre de la librería a usar por el plugin. Este debe ser un nombre válido como variable C, pues se usará en los nombres de las funciones de la librería dinámica. Por ejemplo, el nombre de librería del lector para archivos ASCII es <quote
>ascii</quote
>.  </para>
<note>
<para
>Los plugins de &kde; <emphasis
>no</emphasis
> son lo mismo que los plugins de &kst; que se usan para manipular datos. Todas las referencias a plugins que damos en esta sección se refieren a plugins de &kde;. </para>
</note>

<sect2 id="supportingadditionalfileformatscreatingdatasourceobjectfile">
<title
>La librería dinámica</title>
<para
>Un lector de fuentes de datos debe ser una subclase de la clase abstracta <classname
>KstDataSource</classname
>. Asegúrese de que incluye el archivo de cabecera para dicha <classname
>KstDataSource</classname
> en el código de su lector:<screen>
#include &lt;kstdatasource.h&gt;
</screen
> Hay ciertos requerimientos que su lector tiene que cumplir. Unos son que hay que exportar ciertas funciones C. Otros son consecuencia de heredar de la clase <classname
>KstDataSource</classname
>. A continuación explicamos tales requerimientos, junto con sugerencias y explicaciones generales.  </para>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfileexportedfxns">
<title
>Funciones en C a exportar</title>
<para
>A continuación se listan las funciones en C a exportar. En los ejemplos siguientes, se debe reemplazar todas las instancias de la <varname
>&lt;libname&gt;</varname
> con el nombre de librería del 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 función debe crear un nuevo lector de datos fuentes del tipo <varname
>&lt;libname&gt;</varname
>, donde <varname
>&lt;libname&gt;</varname
> es el nombre de librería del plugin. Se retorna un puntero al nuevo lector del tipo <classname
>KstDataSource</classname
>. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
><returnvalue
>bool</returnvalue
> understands_&lt;libname&gt;(const QString&amp; <parameter
>filename</parameter
>)</function
></term>
<listitem>
<para
>Esta función bebe retornar verdad si el archivo especificado por <varname
>filename</varname
> es de un tipo válido soportado por este lector, y falso si no lo es. Esta función solo debe examinar los contenidos del archivo para validar, y no debe basarse en la extensión del archivo. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
><returnvalue
>QStringList</returnvalue
> provides_&lt;libname&gt;()</function
></term>
<listitem>
<para
>Esta función retorna una lista del tipo <classname
>QStringList</classname
> con los tipos de archivos soportados por este lector. Las cadenas que se retornan son arbitrarias, pero deben ser descriptivas y apropiadas sobre el tipo de archivo. </para>
</listitem>
</varlistentry>

</variablelist>

</sect3>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfilemembervars">
<title
>Variables miembros protegidas</title>
<para
><classname
>KstDataSource</classname
> contiene varias variables miembro protegidas que el lector puede usar. Las describimos a continuación. </para>

<variablelist>
<varlistentry>
<term
><varname
>bool _valid</varname
></term>
<listitem>
<para
>Esta variable debe ser <literal
>true</literal
> (verdad) si nuestro lector de fuentes de datos es válido. Lo más probable es que así sea, a menos de que exista una condición de error (tal que el archivo de datos no sea legible por el lector). Esta variable se usa en conjunción con la función <function
>isValid()</function
> de <classname
>KstDataSource</classname
>, la cual no suele reimplementarse en las subclases. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>QStringList _fieldList</varname
></term>
<listitem>
<para
>Esta variable debe contener una lista de los nombres de los campos en la fuente de datos. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>QString _filename</varname
></term>
<listitem>
<para
>Esta variable debe asociarse al nombre del archivo de datos al que se asocia el lector de datos. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>QString _source</varname
></term>
<listitem>
<para
>Esta variable debe contener el nombre del tipo de la fuente. </para>
</listitem>
</varlistentry>
</variablelist>

</sect3>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfilevirtualfxns">
<title
>Funciones virtuales</title>
<para
>La clase <classname
>KstDataSource</classname
> contiene numerosas funciones virtuales que deben redefinirse en nuestro lector de datos. Estas funciones están en los archivos de plantilla <filename
>template.h</filename
> y <filename
>template.cpp</filename
>, listados la sección <link linkend="supportingadditionalfileformatscreatingdatasourceobjectfileexample"
>Plantillas ejemplo</link
>. A continuación se presenta una descripción de las funciones. </para>

<variablelist>
<varlistentry>
<term
><function
>TemplateSource(const QString&amp;amp; <parameter
>filename</parameter
>, const QString&amp;amp; <parameter
>type</parameter
>) </function
></term>
<listitem>
<para
>El constructor del lector de datos. El nombre del archivo del cual se leen los datos es <varname
>filename</varname
>, y el tipo de datos que contiene es <varname
>type</varname
>. Lo más normal es que este constructor invoque el constructor de la clase <classname
>KstDataSource</classname
> en la lista de inicialización del constructor, y que llame a la función <function
>update</function
> (ver más abajo) para inicializar las variables miembro. En particular, hay que asignar la variable <varname
>bool _valid</varname
> de forma adecuada. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual ~TemplateSource()</function
></term>
<listitem>
<para
>El destructor del lector de datos. Debe liberar la memoria dinámica que se halla requerido al sistema. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>KstObject::UpdateType</returnvalue
> update(<parameter
>int = -1</parameter
>) </function
></term>
<listitem>
<para
>Esta función debe leer cualesquiera datos nuevos que se hayan añadido al archivo de datos desde la última llamada a <function
>update</function
>, y actualizar las variables miembro de forma apropiada. La función debe retornar <varname
>KstObject::UPDATE</varname
> si ha habido cambios en el archivo, y  <varname
>KstObject::NO_CHANGE</varname
> si no. </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 función debe leer <varname
>n</varname
> estructuras de datos, comenzando en la estructura <varname
>s</varname
> desde el campo especificado por el campo <varname
>campo</varname
>, y retornar los contenidos en el vector <varname
>v</varname
>. Si <varname
>n</varname
> vale menos que 0, la función debe leer 1 muestra comenzando en la estructura <varname
>s</varname
>. Debe retornarse el número de estructuras que se hayan leído. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>bool</returnvalue
> isValidField(const QString &amp;<parameter
>field</parameter
>) const</function
></term>
<listitem>
<para
>Esta función debe retornar verdad cuando el campo <varname
>field</varname
> es un campo válido en la fuente de datos actual, o falso cuando no lo es. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>int</returnvalue
> samplesPerFrame(const QString&amp; <parameter
>field</parameter
>)</function
></term>
<listitem>
<para
>Esta función retorna la tasa de muestras por estructuras para el campo especificado por <varname
>field</varname
>. Si las fuentes de datos no hacen uso de este concepto, el número de muestras por estructura debe valer <literal
>1</literal
>. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>int</returnvalue
> frameCount() const</function
></term>
<listitem>
<para
>Esta función debe retornar el número de estructuras en la fuente de datos existentes en el momento de la última llamada <function
>update</function
>. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>QString</returnvalue
> fileType() const <parameter
></parameter
></function
></term>
<listitem>
<para
>Esta función debe retornar el tipo del archivo de datos que se está usando, normalmente el mismo que el parámetro <varname
>type</varname
> que se pasó al constructor. Alternativamente, puede contener un mensaje de error (para indicar, por ejemplo, que el campo no es válido). </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>void</returnvalue
> save(QTextStream &amp;<parameter
>ts</parameter
>)</function
></term>
<listitem>
<para
>Esta función debe guardar la información de descripción del archivo a <varname
>ts</varname
>. En la mayoría de los casos es suficiente usar la implementación dada por <classname
>KstDataSource</classname
>. </para>
</listitem>
</varlistentry>


</variablelist>

</sect3>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfileexample">
<title
>Plantillas ejemplo</title>
<para
>Puede usar los dos archivos plantilla siguientes para crear nuevas librerías dinámicas. Simplemente modifique los cuerpos de las funciones como sea necesario para su fuente de datos particular. </para>
<informalexample>
<screen
>/***************************************************************************
                  template.h  -  Plantilla de plugin para fuentes de datos
                             -------------------
    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  -  Plantilla de fuente de datos
                             -------------------
    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;
  // create the stringlist
  return rc;
}

bool understands_template(const QString&amp; filename) {
  // determine if it is an X file
  Q_UNUSED(filename)
  return false;
}

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

</sect2>

<sect2 id="supportingadditionalfileformatscreatingdatasourcedesktopfile">
<title
>El archivo  <filename
>.desktop</filename
></title>
<para
>A continación se muestra un ejemplo del archivo <filename
>.desktop</filename
> para la plantilla del plugin: </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
>Debería añadir traducciones en lenguajes adicionales para los campos Name y Comment, añadiendo campos Name y Comment adicionales con el sufijo <literal
>[xx]</literal
> añadido, donde <literal
>xx</literal
> es el código de dos letras del lenguaje. Por ejemplo, para añadir la traducción española, deberían añadirser estas líneas: </para>
<informalexample>
<screen
>Name[es]=Plantilla de lectura de ficheros
Comment[es]=Plantilla de código para hacer un complemento de lectura de ficheros.
</screen>
</informalexample>
<para
>El campo  <literal
>X-Kst-Plugin-Library</literal
> debe ser exactamente igual al nombre de librería del plugin. </para>
</sect2>

<sect2 id="supportingadditionalfileformatscreatingdatasourcecompiling">
<title
>Compilando y copiando</title>
<para
>Para compilar e instalar una versión personalizada de nuestro lector de datos, cree un nuevo directorio bajo <filename
>kst/datasources</filename
> del paquete con las fuentes de kst. Ponga sus fuentes junto con el archivo <filename
>.desktop</filename
> en tal directorio. Entonces edite <filename
>kst/datasources/Makefile.am</filename
> tal que <varname
>SUBDIRS</varname
> contenga el nombre del nuevo subdirectorio. Por ejemplo, si el nuevo subdirectorio se llama <filename
>template</filename
>, <varname
>SUBDIRS</varname
> puede cambiarse a: <informalexample
> <screen
>SUBDIRS=ascii dirfile frame indirect template $(PIOLIB_SUBDIR) $(FITSIO_SUBDIR)
</screen>
</informalexample>
</para>


<para
>Despues de tener a los archivos en el directorio ya creado, se necesita crear ahí un archivo <filename
>Makefile.am</filename
>. Use el ejemplo siguiente como plantilla, reemplazando <quote
>template</quote
> con el nombre de su librería en <varname
>kde_module_LTLIBRARIES</varname
>, <varname
>kstdata_template_la_SOURCES</varname
> y <varname
>services_DATA</varname
>. </para>
<informalexample>
<screen
>INCLUDES=-I$(srcdir)/../.. $(all_includes)

kde_module_LTLIBRARIES=kstdata_template.la

kstdata_template_la_LDFLAGS=$(all_libraries) -module -avoid-version
kstdata_template_la_SOURCES=template.cpp

METASOURCES=AUTO

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

<para
>Una vez que se haya hecho esto, puede compilar y reinstalar &kst; desde el paquete fuente modificado, o alternativamente, solo instalar las nuevas librerías, como sigue (usando el subdirectorio <quote
>template</quote
> como ejemplo). Primero cambie las directorio raíz de las fuentes de &kst;. Entonces, <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
>Vuelva a lanzar &kst; y se debería cargar el nuevo lector de datos. </para>
</sect2>

</sect1>


</appendix>
