# Stöd för ytterligare filformat

Det här avsnittet beskriver hur man skapar ytterligare läsare för filformat som för närvarande inte stöds. Om du inte redan känner till begrepp relaterade till datakällor, läs då gärna Begrepp för datakällor.

## Skapa läsare av datakällor

Om du vill använda ett annat filformat än de som för närvarande stöds, kan du välja att skriva en egen läsare av datakällor.

Alla läsare av datakällor i &kst; är vanliga &kde;-insticksprogram. Som alla &kde;-insticksprogram, måste varje läsare av datakällor ha en delad objektfil och en `.desktop`-fil. Innan läsaren kodas, måste insticksprogrammets biblioteksnamn bestämmas. Namnet måste vara ett giltigt variabelnamn i C, eftersom det kommer att användas som funktionsnamn för det delade objektet. Biblioteksnamnet för läsaren av ASCII-filer är till exempel ascii.

&kde;-insticksprogram är inte samma som &kst;-insticksprogrammen som används för databehandling. Alla referenser till insticksprogram i det här avsnittet gäller &kde;-insticksprogram.

### Det delade objektet

En läsare av datakällor ska vara en delklass till den abstrakta klassen `KstDataSource`. Försäkra dig om att du inkluderar deklarationsfilen för `KstDataSource` i källkoden i din läsare av datakällor:

    #include <kstdatasource.h>

Det finns vissa krav som en läsare av datakällor måste uppfylla. Ett krav gäller närvaron av exporterade C-funktioner. Andra krav är konsekvenser av det faktum att läsare av datakällor ärver `KstDataSource`. Båda uppsättningarna med krav, samt förslag och allmänna förklaringar, tillhandahålls i följande avsnitt.

#### Exporterade C-funktioner

De exporterade C-funktionerna listas nedan. I följande exempel ska varje förekomst av biblioteksnamn bytas ut mot insticksprogrammets verkliga biblioteksnamn.

`KstDataSource *create_biblioteksnamn(KConfig* `cfg`, const QString& `filename`, const QString& `type`)`

  Den här funktionen ska skapa en ny läsare av datakällor med typen biblioteksnamn, där biblioteksnamn är insticksprogrammets biblioteksnamn. En pekare av typen `KstDataSource` till den nya läsaren ska returneras.

[valfri] `KstDataSource *load_biblioteksnamn( KConfig* `cfg`, const QString& `filename`, const QString& `type`, const QDomElement& `e` )`

  Den här funktionen ska skapa en ny läsare av datakällor med typen biblioteksnamn, där biblioteksnamn är insticksprogrammets biblioteksnamn. En pekare av typen `KstDataSource` till den nya läsaren ska returneras.

`int understands_biblioteksnamn(const QString& `filename`)`

  Den här funktionen ska returnera ett heltal från 0 till 100. Värdet 0 anger att datakällan fullständigt saknar möjlighet att läsa filen som anges av `filename`, medan värdet 100 anger att datakällan är helt övertygad om att den har bäst möjlighet att förstå filen som anges av `filename`. Funktionen ska kontrollera att innehållet i filen är giltigt, och inte helt enkelt lita på filnamnsändelser.

[valfri] `QStringList fieldList_biblioteksnamn( KConfig* `cfg`, const QString& `filename`, const QString& `type`, QString* `typeSuggestion`, bool* `complete` )`

  Funktionen ska returnera en lista med fält som hittas i filen, om den kan förstå filen som anges av `filename`, annars ska den returnera en tom `QStringList`. Värdet av `typeSuggestion` ska sättas till filtypen och värdet av `complete` ska sättas till falskt om inga fält hittas, annars ska det sättas till sant.

[valfri] `QStringList matrixList_biblioteksnamn( KConfig* `cfg`, const QString& `filename`, const QString& `type`, QString* `typeSuggestion`, bool* `complete` )`

  Funktionen ska returnera en lista med matriser som hittas i filen, om den kan förstå filen som anges av `filename`, annars ska den returnera en tom `QStringList`. Värdet av `typeSuggestion` ska sättas till filtypen och värdet av `complete` ska sättas till falskt om inga matriser hittas, annars ska det sättas till sant.

[valfri] `QWidget* widget_biblioteksnamn( )`

  Om datakällan vill tillhandahålla en egen inställningsdialogruta, ska den implementera funktionen och returnera den nyskapade klassen härledd från `QWidget` här.

`QStringList provides_biblioteksnamn( )`

  Den här funktionen ska returnera en `QStringList` med filtyperna som stöds av läsaren. Strängarna som returneras är godtyckliga, men bör vara beskrivande och passande för de verkliga filtyperna.

[valfri] `bool supportsHierarchy_biblioteksnamn( )`

  Funktionen ska returnera sant om datakällan stöder hierarkiska fältnamn. Hierarkin anges av tecknet `/`.

#### Skyddade medlemsvariabler

`KstDataSource` innehåller diverse skyddade medlemsvariabler som den egna läsaren av datakällor kan använda. Dessa variabler beskrivs nedan.

`bool _valid`

  Den här variabeln ska vara `true` om den egna läsaren av datakällor är giltig. Läsaren är troligen giltig, om inte ett feltillstånd har uppstått (som att datafilen inte kan läsas av läsaren). Variabeln används av funktionen `isValid()` i `KstDataSource`, vilken oftast inte implementeras om i delklasser.

`QStringList _fieldList`

  Den här variabeln ska innehålla en lista med fältnamnen i datakällan.

`QString _filename`

  Den här variabeln ska innehålla namnet på datafilen som den här läsaren av datakälla hör ihop med.

`QString _source`

  Den här variabeln ska innehålla källans typnamn.

#### Virtuella funktioner

Klassen `KstDataSource` innehåller många virtuella funktioner som ska definieras om i den egna läsaren av datakällor. Det är bara nödvändigt att överskrida funktionerna när den fördefinierade implementeringen inte är tillräcklig. Dessa funktioner finns i mallfilerna `template.h` och `template.cpp`, som listas i avsnittet Exempelmallar. Beskrivningar av funktionerna följer.

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

  Konstruktor för läsaren av datakällor. `filename` är namnet på filen från vilken data ska läsas, och `type` är typ av data som filen innehåller. Konstruktorn ska troligen anropa konstruktorn `KstDataSource` i listan med konstruktorinitiering, och troligen anropa funktionen `update` som listas nedan för att initiera medlemsvariabler. I synnerhet ska variabeln `_valid` ges lämpligt värde.

`virtual ~TemplateSource()`

  Destruktorn för läsaren av datakällor. Allt dynamiskt allokerat minne ska frigöras.

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

  Den här funktionen ska läsa eventuell ny data tillagd i funktionen sedan senaste gången `update` anropades, och uppdatera medlemsvariablerna på lämpligt sätt. Funktionen ska returnera `KstObject::UPDATE` om filen innehåller ändringar, eller annars `KstObject::NO_CHANGE`.

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

  Den här funktionen ska läsa `n` dataposter, med start från post `s` från fältet som anges av fältnamnet `field`, och returnera innehållet i fältet `v`. Om `n` är mindre än 0, ska funktionen istället läsa 1 sampling med början på post `s`. Antal poster som lästes ska returneras.

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

  Funktionen ska returnera true om fältet som anges av fältnamnet `field` är ett giltigt fält i den aktuella datakällan, eller false om fältet inte är giltigt.

`virtual int readMatrix( KstMatrixData *`data`, const QString &`matrix`, int `xStart`, int `yStart`, int `xNumSteps`, int `yNumSteps` )`

  Funktionen ska läsa angiven del av matrisen, genom att läsa `xNumSteps` med början på `xStart` och `yNumSteps` med början på `yStart` från matrisen som anges av matrisnamnet `matrix`, och returnera innehållet i `KstMatrixData` `data`. Om `xNumSteps` är mindre än 0, ska funktionen istället läsa 1 sampling med början på `xStart`. Om `yNumSteps` är minder än 0, ska funktionen istället läsa 1 sampling med början på `yStart`.

`virtual bool isValidMatrix(const QString &`matrix`) const`

  Funktionen ska returnera true om matrisen som anges av matrisnamnet `matrix` är en giltig matris i den aktuella datakällan, eller false om matrisen inte är giltigt.

`virtual bool matrixDimensions( const QString &`matrix`, int* `xDim`, int* `yDim` )`

  Funktionen ska returnera sant om matrisen som anges av matrisnamnet `matrix` är en giltig matris i den aktuellla datakällan, eller falskt om matrisen inte är en giltig matris. Om matrisen är en giltig matris ska värdet av `xDim` och `yDim` sättas till matrisens respektive X-dimension och Y-dimension.

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

  Den här funktionen ska returnera förhållandet samplingar per post för fältet som anges av fältnamnet `field`. För datakällor som inte använder begreppet, kan antal samplingar per post anges som `1`.

`virtual int frameCount() const`

  Den här funktionen ska returnera totalt antal poster i datakällan, som fanns den senaste gången `update` anropades.

`virtual QString fileType() const ```

  Den här funktionen ska returnera filtypen för datafilen som för närvarande används, oftast samma sak som parametern `type` som skickades till konstruktorn. Som ett alternativ kan den returnera ett felmeddelande (för att till exempel ange att filen inte är giltig).

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

  Den här funktionen ska spara filbeskrivningsinformation till `ts`. I de flesta fall bör implementeringen som tillhandahålls av `KstDataSource` vara tillräcklig.

#### Exempelmallar

I allmänhet kan de följande två mallfilerna användas för att skapa nya delade objektfiler. Ändra helt enkelt innehållet i funktionerna till vad som lämpar sig för din speciella datakälla.

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

    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;
    }
    }

### Filen `.desktop`

Följande är ett exempel på en `.desktop`-fil för mallinsticksprogrammet:

    [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 British Columbia
    Name=File Reader Template
    Comment=Long description of the file reader template.

Du kan lägga till översättningar på ytterligare språk för fälten Name och Comments, genom att lägga till ytterligare fält för Name och Comments med `[xx]` tillagt i slutet på fältnamnen, där `xx` är språkkoden med två bokstäver. För att till exempel lägga till en svensk översättning, skulle följande rader behöva läggas till:

    Name[sv]=Insticksprogram för filläsning
    Comment[sv]=Insticksprogram som fungerar som ett tillägg för filläsning.

Fältet `X-Kst-Plugin-Library` måste vara exakt samma som biblioteksnamnet som bestämts för insticksprogrammet.

### Kompilering och kopiering

För att kompilera och installera den nya egna läsaren av datakällor, skapa en ny katalog under `kst/datasources` i källkodspaketet. Placera källkodsfilerna för objektet, tillsammans med `.desktop`-filen i den nya katalogen. Redigera därefter `kst/datasources/Makefile.am` så att `SUBDIRS` innehåller den nya underkatalogens namn. Om den nya underkatalogen till exempel heter `template`, kan `SUBDIRS` ändras till följande:

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

När filerna som krävs finns i den nyskapade underkatalogen, måste filen `Makefile.am` också skapas där. Använd följande exempel som en mall, och ersätt alla förekomster av template med ditt eget biblioteksnamn i `kde_module_LTLIBRARIES`, `kstdata_template_la_SOURCES` och `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å fort detta är klart, kan du kompilera och installera om &kst; från det ändrade källkodspaketet, eller som ett alternativ, bara installera de nya biblioteken på följande sätt (med underkatalogen template använd som exempel). Gå först till rotkatalogen i &kst;-källkodspaketet. Skriv därefter

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

Starta om &kst; så ska den nya datakällans läsare automatiskt laddas.