# Støtte for yderligere filformater

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

## Opret læsere af datakilder

Hvis du vil bruge et andet filformat end dem der for øjeblikket understøttes, kan du vælge at skrive egne datakildelæsere.

Alle datakildelæsere i &kst; er almindelige &kde;-plugin. Som alle &kde;-plugin, skal hver datakildelæser have en delt objektfil og en `*.desktop`-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 ascii.

&kde;-plugin er ikke det samme som de &kst;-plugin som bruges til databehandling. Alle referencer til plugin i dette afsnit gælder &kde;-plugin.

### Det delte objekt

En af datakildelæser skal være en delklasse til den abstrakte klasse `KstDataSource`. Sørg for at du inkluderer deklarationsfilen for `KstDataSource` i kildekoden i din datakildelæser:

    #include <ksddatasource.h>

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 `KstDataSource`. Begge sæt krav, samt forslag og almene forklaringer, varetages i de følgende afsnit.

#### Eksporterede C-funktioner

De eksporterede C-funktioner er på listen nedenfor. I følgende eksempel skal hver forekomst af `<biblioteksnavn>` byttes ud mod dit plugins virkelige biblioteksnavn.

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

- Denne funktion skal oprette en ny datakildelæser med typen `<biblioteksnavn>`, hvor `<biblioteksnavn>` er dit plugins biblioteksnavn. En peger af typen `KstDataSource` til den nye læser skal returneres.

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

- Denne funktion skal returnere true hvis filen som angives af `filename` 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.

`QStringList provides_<biblioteksnavn>()`

- Denne funktion skal returnere en `QStringList` 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.

#### Beskyttede medlemsvariabler

`KstDataSource` indeholder diverse beskyttede medlemsvariabler som den egne datakildelæser kan bruge. Disse variabler beskrives nedenfor.

`bool _valid`

- Denne variabel skal være `true` 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 `isValid()` i `KstDataSource`, hvilket oftest ikke genimplementeres i delklasser.

`QStringList _fieldList`

- Denne variabel skal indeholde en liste med feltnavne i datakilden.

`QString _filename`

- Denne variabel skal indehold navnet på datafilen som denne datakildelæser hører sammen med.

`QString _source`

- Denne variabel skal indeholde kildens typenavn.

#### Virtuelle funktioner

Klassen `KstDataSource` indeholder mange virtuelle funktioner som skal omdefineres i den selvlavede datakildelæser. Disse funktioner findes i skabelonerne `template.h` og `template.cpp`, som er på listen i afsnittet Eksempelskabeloner. Beskrivelser af funktionerne følger.

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

- Konstruktor for datakildelæseren. `filename` er navnet på filen fra hvilken data skal læses, og `type` er typen af data som filen indeholder. Konstruktoren skal formodentlig kalde konstruktoren `KstDataSource` i listen med konstruktorinitiering, og formodentlig kalde funktionen `update` som er på listen nedenfor for at initiere medlemsvariabler. I særdeleshed skal variablen `bool _valid` gives en passende værdi.

`virtual ~TemplateSource()`

- Destruktoren for datakildelæseren. Alt dynamisk allokeret hukommelse skal frigøres.

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

- Denne funktion skal læse vilkårlig ny data indgivet til funktionen siden sidste gang `update` blev kaldet, og opdatere medlemsvariablerne på passende vis. Funktionen skal returnere `KstObject::UPDATE` hvis filen indeholder ændringer, og ellers `KstObject::NO_CHANGE`.

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

- Denne funktion skal læse `n` datarammer, startende fra rammen `s` fra feltet som angives af feltnavnet `field`, og returnere indholdet i `v`. Hvis `n` er mindre end 0, skal funktionen i stedet læse 1 sampling ved begyndelsen af rammen `s`. Antal rammer som blev læst skal returneres.

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

- Funktionen skal returnere true hvis feltet som angives af feltnavnet `field` er et gyldigt felt i den nuværende datakilde, eller false hvis feltet ikke er gyldigt.

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

- Denne funktion skal returnere forholdet mellem samplinger pr ramme for feltet som angives af feltnavnet `field`. For datakilder som ikke bruger begrebet, kan antal samplinger pr post angives som `1`.

`virtual int frameCount() const`

- Denne funktion skal returnere det totale antal rammer i datakilden, som blev fundet sidste gang `update` blev kaldet.

`virtual QString fileType() const ```

- Denne funktion skal returnere filtypen for datafilen som for øjeblikket bruges, oftest det samme som parameteren `type` som blev sendt til konstruktoren. Som et alternativ kan den returnere en fejlmeddelelse (for eksempel ved at angive at filen ikke er gyldig).

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

- Denne funktion skal gemme filbeskrivelsesinformation til `ts`. I de fleste tilfælde bør implementationen som sørges for af `KstDataSource` være tilstrækkelig.

#### Eksempelskabeloner

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.

    /***************************************************************************
                      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 &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  -  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& 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;
      // create the stringlist
      return rc;
    }

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

    }

### `.desktop`-filen

Følgende er et eksempel på en `.desktop`-fil for dit skabelon-plugin:

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

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 `[xx]` tilføjet i slutningen af feltnavnene, hvor `xx` er sprogkoden med to bogstaver. For eksempel for at tilføje en dansk oversættelse, skal følgende linjer tilføjes:

    Name[da]=Plugin til fillæsning
    Comment[da]=Plugin som virker som et komplement for fillæsning.

Feltet `X-Kst-Plugin-Library` skal være nøjagtigt det samme som biblioteksnavnet som blev bestemt for dit plugin.

### Kompilering og kopiering

For at kompilere og installere den nye selvlavede datakildelæser, oprettes en ny mappe under `kst/datasources` i kildekodepakken. Placér kildekodefilerne for objektet, sammen med `.desktop`-filen i den nye mappe. Redigér derefter `kst/datasources/Makefile.am` så `SUBDIRS` indeholder den nye undermappes navn. Hvis den nye undermappe for eksempel hedder `template`, kan `SUBDIRS` ændres til følgende:

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

Når filerne som kræves er i den nyoprettede undermappe, skal filen `Makefile.am` også laves der. Brug følgende eksempel som en skabelon, og erstat alle forekomster af template med dit eget biblioteksnavn i `kde_module_LTLIBRARIES`, `ksddata_template_la_SOURCES` og `services_DATA`.

    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

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 template brugt som eksempel). Gå først til rodmappen i &kst;-kildekodepakken. Skriv derefter

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

Genstart &kst; så skulle den nye datakildelæser blive indlæst.