<appendix id="supportingadditionalfileformats">
<title
>Støtte for yderligere filformater</title>
<para
>Dette afsnit beskriver hvordan man laver yderligere læsere for filformater som ikke understøttes. Hvis du ikke allerede kender til begrebet  datakilder, så læs gerne <link linkend="supportingadditionalfileformatsdatasourceconcepts"
>Datakildebegreber</link
>. </para>



<sect1 id="supportingadditionalfileformatscreatingdatasource">
<title
>Opret læsere af datakilder</title>

<para
>Hvis du vil bruge et andet filformat end dem der for øjeblikket understøttes, kan du vælge at skrive egne datakildelæsere. </para>
<para
>Alle datakildelæsere i &kst; er almindelige &kde;-plugin. Som alle &kde;-plugin, skal hver datakildelæser have en delt objektfil og en <filename
>*.desktop</filename
>-fil. Inden læseren kodes, skal dit plugins biblioteksnavn bestemmes. Navnet skal være et gyldigt variabelnavn i C, eftersom det vil blive brugt som funktionsnavn for det delte objekt. Biblioteksnavnet for læseren af ASCII-filer er for eksempel <quote
>ascii</quote
>. </para>
<note>
<para
>&kde;-plugin er <emphasis
>ikke</emphasis
> det samme som de &kst;-plugin som bruges til databehandling. Alle referencer til plugin i dette afsnit gælder &kde;-plugin. </para>
</note>

<sect2 id="supportingadditionalfileformatscreatingdatasourceobjectfile">
<title
>Det delte objekt</title>
<para
>En af datakildelæser skal være en delklasse til den abstrakte klasse <classname
>KstDataSource</classname
>. Sørg for at du inkluderer deklarationsfilen for <classname
>KstDataSource</classname
> i kildekoden i din datakildelæser: <screen>
#include &lt;ksddatasource.h&gt;
</screen
> Der er visse krav som en datakildelæser skal opfylde. Et krav gælder tilstedeværelsen af eksporterede C-funktioner. Andre krav er konsekvenser af det faktum at datakildelæsere arver <classname
>KstDataSource</classname
>. Begge sæt krav, samt forslag og almene forklaringer, varetages i de følgende afsnit. </para>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfileexportedfxns">
<title
>Eksporterede C-funktioner</title>
<para
>De eksporterede C-funktioner er på listen nedenfor. I følgende eksempel skal hver forekomst af <varname
>&lt;biblioteksnavn&gt;</varname
> byttes ud mod dit plugins virkelige biblioteksnavn. </para>
<variablelist>
<varlistentry>
<term
><function
><returnvalue
>KstDataSource *</returnvalue
>create_&lt;biblioteksnavn&gt;(const QString&amp; <parameter
>filename</parameter
>, const QString&amp; <parameter
>type</parameter
>)</function
></term>
<listitem>
<para
>Denne funktion skal oprette en ny datakildelæser med typen <varname
>&lt;biblioteksnavn&gt;</varname
>, hvor <varname
>&lt;biblioteksnavn&gt;</varname
> er dit plugins biblioteksnavn. En peger af typen <classname
>KstDataSource</classname
> til den nye læser skal returneres. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
><returnvalue
>bool</returnvalue
> understands_&lt;biblioteksnavn&gt;(const QString&amp; <parameter
>filename</parameter
>)</function
></term>
<listitem>
<para
>Denne funktion skal returnere true hvis filen som angives af <varname
>filename</varname
> er af en gyldig type som understøttes af denne læser, og false ellers. Funktionen skal kontrollere at indholdet i filen er gyldigt, og ikke stole på filnavneendelser. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
><returnvalue
>QStringList</returnvalue
> provides_&lt;biblioteksnavn&gt;()</function
></term>
<listitem>
<para
>Denne funktion skal returnere en <classname
>QStringList</classname
> for filtyperne som understøttes af læseren. Strengene som returneres er vilkårlige, men bør være beskrivende og passende for de egentlige filtyper. </para>
</listitem>
</varlistentry>

</variablelist>

</sect3>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfilemembervars">
<title
>Beskyttede medlemsvariabler</title>
<para
><classname
>KstDataSource</classname
> indeholder diverse beskyttede medlemsvariabler som den egne datakildelæser kan bruge. Disse variabler beskrives nedenfor. </para>

<variablelist>
<varlistentry>
<term
><varname
>bool _valid</varname
></term>
<listitem>
<para
>Denne variabel skal være <literal
>true</literal
> hvis den egne datakildelæser er gyldig. Læseren er formodentlig gyldig, hvis ikke en fejltilstand er opstået (som at datafilen ikke kan læses af læseren). Variablen bruges af funktionen <function
>isValid()</function
> i <classname
>KstDataSource</classname
>, hvilket oftest ikke genimplementeres i delklasser. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>QStringList _fieldList</varname
></term>
<listitem>
<para
>Denne variabel skal indeholde en liste med feltnavne i datakilden. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>QString _filename</varname
></term>
<listitem>
<para
>Denne variabel skal indehold navnet på datafilen som denne datakildelæser hører sammen med. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><varname
>QString _source</varname
></term>
<listitem>
<para
>Denne variabel skal indeholde kildens typenavn. </para>
</listitem>
</varlistentry>
</variablelist>

</sect3>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfilevirtualfxns">
<title
>Virtuelle funktioner</title>
<para
>Klassen <classname
>KstDataSource</classname
> indeholder mange virtuelle funktioner som skal omdefineres i den selvlavede datakildelæser. Disse funktioner findes i skabelonerne <filename
>template.h</filename
> og <filename
>template.cpp</filename
>, som er på listen i afsnittet <link linkend="supportingadditionalfileformatscreatingdatasourceobjectfileexample"
>Eksempelskabeloner</link
>. Beskrivelser af funktionerne følger. </para>

<variablelist>
<varlistentry>
<term
><function
>TemplateSource(const QString&amp;amp; <parameter
>filename</parameter
>, const QString&amp;amp; <parameter
>type</parameter
>) </function
></term>
<listitem>
<para
>Konstruktor for datakildelæseren. <varname
>filename</varname
> er navnet på filen fra hvilken data skal læses, og <varname
>type</varname
> er typen af data som filen indeholder. Konstruktoren skal formodentlig kalde konstruktoren <classname
>KstDataSource</classname
> i listen med konstruktorinitiering, og formodentlig kalde funktionen <function
>update</function
> som er på listen nedenfor for at initiere medlemsvariabler. I særdeleshed skal variablen <varname
>bool _valid</varname
> gives en passende værdi. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual ~TemplateSource()</function
></term>
<listitem>
<para
>Destruktoren for datakildelæseren. Alt dynamisk allokeret hukommelse skal frigøres. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>KstObject::UpdateType</returnvalue
> update(<parameter
>int = -1</parameter
>) </function
></term>
<listitem>
<para
>Denne funktion skal læse vilkårlig ny data indgivet til funktionen siden sidste gang <function
>update</function
> blev kaldet, og opdatere medlemsvariablerne på passende vis. Funktionen skal returnere <varname
>KstObject::UPDATE</varname
> hvis filen indeholder ændringer, og ellers <varname
>KstObject::NO_CHANGE</varname
>. </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
>Denne funktion skal læse <varname
>n</varname
> datarammer, startende fra rammen <varname
>s</varname
> fra feltet som angives af feltnavnet <varname
>field</varname
>, og returnere indholdet i <varname
>v</varname
>. Hvis <varname
>n</varname
> er mindre end 0, skal funktionen i stedet læse 1 sampling ved begyndelsen af rammen <varname
>s</varname
>. Antal rammer som blev læst skal returneres. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>bool</returnvalue
> isValidField(const QString &amp;<parameter
>field</parameter
>) const</function
></term>
<listitem>
<para
>Funktionen skal returnere true hvis feltet som angives af feltnavnet <varname
>field</varname
> er et gyldigt felt i den nuværende datakilde, eller false hvis feltet ikke er gyldigt. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>int</returnvalue
> samplesPerFrame(const QString&amp; <parameter
>field</parameter
>)</function
></term>
<listitem>
<para
>Denne funktion skal returnere forholdet mellem samplinger pr ramme for feltet som angives af feltnavnet <varname
>field</varname
>. For datakilder som ikke bruger begrebet, kan antal samplinger pr post angives som <literal
>1</literal
>. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>int</returnvalue
> frameCount() const</function
></term>
<listitem>
<para
>Denne funktion skal returnere det totale antal rammer i datakilden, som blev fundet sidste gang <function
>update</function
> blev kaldet. </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>QString</returnvalue
> fileType() const <parameter
></parameter
></function
></term>
<listitem>
<para
>Denne funktion skal returnere filtypen for datafilen som for øjeblikket bruges, oftest det samme som parameteren <varname
>type</varname
> som blev sendt til konstruktoren. Som et alternativ kan den returnere en fejlmeddelelse (for eksempel ved at angive at filen ikke er gyldig). </para>
</listitem>
</varlistentry>

<varlistentry>
<term
><function
>virtual <returnvalue
>void</returnvalue
> save(QTextStream &amp;<parameter
>ts</parameter
>)</function
></term>
<listitem>
<para
>Denne funktion skal gemme filbeskrivelsesinformation til <varname
>ts</varname
>. I de fleste tilfælde bør implementationen som sørges for af <classname
>KstDataSource</classname
> være tilstrækkelig. </para>
</listitem>
</varlistentry>


</variablelist>

</sect3>

<sect3 id="supportingadditionalfileformatscreatingdatasourceobjectfileexample">
<title
>Eksempelskabeloner</title>
<para
>I almindelighed kan følgende to skabelonfiler bruges til at oprette nye delte objektfiler. Ændr helt enkelt indholdet i funktionerne til det som passer sig for din specielle datakilde. </para>
<informalexample>
<screen
>/***************************************************************************
                  template.h  -  data source plugin template
                             -------------------
    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  -  data source template
                             -------------------
    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
><filename
>.desktop</filename
>-filen</title>
<para
>Følgende er et eksempel på en <filename
>.desktop</filename
>-fil for dit skabelon-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
>Du kan tilføje oversættelser til yderligere sprog for felterne Name og Comments, ved at tilføje yderligere felter for Name og Comments med <literal
>[xx]</literal
> tilføjet i slutningen af feltnavnene, hvor <literal
>xx</literal
> er sprogkoden med to bogstaver. For eksempel for at tilføje en dansk oversættelse, skal følgende linjer tilføjes: </para>
<informalexample>
<screen
>Name[da]=Plugin til fillæsning
Comment[da]=Plugin som virker som et komplement for fillæsning.
</screen>
</informalexample>
<para
>Feltet <literal
>X-Kst-Plugin-Library</literal
> skal være nøjagtigt det samme som biblioteksnavnet som blev bestemt for dit plugin. </para>
</sect2>

<sect2 id="supportingadditionalfileformatscreatingdatasourcecompiling">
<title
>Kompilering og kopiering</title>
<para
>For at kompilere og installere den nye selvlavede datakildelæser, oprettes en ny mappe under <filename
>kst/datasources</filename
> i kildekodepakken. Placér kildekodefilerne for objektet, sammen med <filename
>.desktop</filename
>-filen i den nye mappe. Redigér derefter <filename
>kst/datasources/Makefile.am</filename
> så <varname
>SUBDIRS</varname
> indeholder den nye undermappes navn. Hvis den nye undermappe for eksempel hedder <filename
>template</filename
>, kan <varname
>SUBDIRS</varname
> ændres til følgende: <informalexample
> <screen
>SUBDIRS=ascii dirfile frame indirect template $(PIOLIB_SUBDIR) $(FITSIO_SUBDIR)
</screen>
</informalexample>
</para>


<para
>Når filerne som kræves er i den nyoprettede undermappe, skal filen <filename
>Makefile.am</filename
> også laves der. Brug følgende eksempel som en skabelon, og erstat alle forekomster af <quote
>template</quote
> med dit eget biblioteksnavn i <varname
>kde_module_LTLIBRARIES</varname
>, <varname
>ksddata_template_la_SOURCES</varname
> og <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
>Så snart dette er klart, kan du omkompilere og ominstallere &kst; ud fra den ændrede kildekodepakke, eller alternativt, kun installere de nye biblioteker på følgende måde (med undermappen <quote
>template</quote
> brugt som eksempel). Gå først til rodmappen i &kst;-kildekodepakken. Skriv derefter <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
>Genstart &kst; så skulle den nye datakildelæser blive indlæst. </para>
</sect2>

</sect1>


</appendix>
