# Täiendavate failivormingute toetus

Hetkel &kst;...toetab... See osa kirjeldab andmeallikate kontseptsioone ning seda, kuidas luua lisalugejaid toetamata failivormingutele.

## Andmeallikate kontseptsioonid

Järgnevad kontseptsioonid on äärmiselt olulised mõistmaks, kuidas &kst; kasutab erinevaid andmeallikaid, ning aitavad täiendavate andmeallikate lugejate kirjutamisel. Toome siin ära ka mõnevõrra terminite seletusi.

### Valimid

Andmefailide mõttes on valim fundamentaalne ühik. Valim vastab tavaliselt &kst; vektori ühele väärtusele.

### Raamid

Raam tähistab teatud hulka valimeid. Igal andmefaili väljal võib olla erinev raamidesse kaasatud valimite hulk. Andmefaili suurust mõõdetakse selles sisalduvate raamide arvuga. Enamasti on valimeid raamis ainult üks, kuid mõnikord võib raamis olla ka märksa rohkem valimeid.

### Väljad

Väli tähistab &kst;-s tavaliselt üht vektorit. Näiteks ASCII andmefaili veergu peetakse üheks väljaks. Igal väljal võib olla vaikimisi eeldatud või ka otseselt antud nimi. Andmeallika lugejad sisaldavad funktsioone väljade ja nende nimede lugemiseks ja hankimiseks.

## Andmeallika lugeja loomine

Kui soovid kasutada failivormingut, mida me praegu ei toeta, tuleks ise kirjutada ka vastav andmeallika lugeja.

Kõik &kst; andmeallikate lugejad on tavalised &kde; pluginad. Nagu &kde; pluginatel ikka, peab igal andmeallika lugejal olema ühisobjekti fail ning `*.desktop`-fail. Enne lugeja kirjutamist peab kindlaks määrama plugina teegi nime. See peab olema C-keele korrektse muutuja nimi, sest seda kasutatakse ühisobjekti funktsiooninimedes. Nii on näiteks ASCII failide lugeja teegi nimi ascii.

&kde; pluginad ei ole mitte needsamad, mida kasutab &kst; andmetega manipuleerimisel. Kõik viited pluginatele tähendavad käesolevas osas &kde; pluginaid.

### Ühisobjekt

Andmeallika lugeja peab olema abstratse klassi `KstDataSource` alamklass. Kontrolli, et kaasaksid oma andmelugeja lähtekoodi `KstDataSource`'i päisefaili:

    #include <kstdatasource.h>

Andmeallika lugega peab vastama teatud nõuetele. Üks neist on seotud eksporditud C funktsioonide olemasoluga. Teine nõue tuleneb asjaolust, et andmeallika lugejad peavad olema `KstDataSource`'i järglased. Mõlemaid nõudeid koos mõningate soovituste ja selgitustega tutvustatakse allpool.

#### Eksporditud C funktsioonid

Allpool on ära toodud eksporditud C funktsioonid. Järgnevates näidetes tuleb `<teeginimi>` kõikjal asendada plugina teegi tegeliku nimega.

`KstDataSource *create_<teeginimi>(const QString& `failinimi`, const QString& `tüüp`)`

  See funktsioon loob uue andmeallika lugeja tüübiga `<teeginimi>`, kus `<teeginimi>` on plugina teegi nimi. Uuele klassile osutav viit tüübiga `KstDataSource` peab olema tagastatav.

`bool understands_<teeginimi>(const QString& `failinimi`)`

  Funktsioon peab tagastama 'true', kui parameetriga `failinimi` määratud fail on antud lugeja toetusega tüübiga, vastasel juhul tagastatakse 'false'. Funktsioon peab kehtivuse leidmiseks kontrollima faili sisu, mitte toetuma ainult failinime laiendile.

`QStringList provides_<teeginimi>()`

  Funktsioon tagastab lugeja toetatud failitüüpide `QStringList`'i. Tagastatud stringid on suvalised, kuid peaks kirjeldama tegelikke failitüüpe.

#### Kaitstud liikme muutujad

`KstDataSource` sisaldab mitmeid kaitstud liikme muutujaid, mida omaloodud andmeallika lugeja saab tarvitada. Muutujaid kirjeldatakse allpool.

`bool _valid`

  See muutuja on `true`, kui omaloodud andmeallika lugeja on sobilik. Üldiselt peakski see nii olema, kui ei ole just mingit viga (kui näiteks lugeja ei suuda siiski andmefaili lugeda). Muutujat kasutab `KstDataSource`'i funktsioon `isValid()`, mida tavaliselt ei teostata uuesti alamklassides.

`QStringList _fieldList`

  See muutuja sisaldab andmeallika väljanimede loendit.

`QString _filename`

  See muutuja sisaldab andmefaili nime, millega andmeallika lugeja on seostatud.

`QString _source`

  See muutuja sisaldab allika tüübi nime.

#### Virtuaalsed funktsioonid

Klass `KstDataSource` sisaldab mitmeid virtuaalseid funktsioone, mis tuleb omaloodud andmeallika lugejas uuesti defineerida. Need funktsioonid on mallifailid `template.h` ja `template.cpp`, mis on ära toodud näidismallide osas. Siinkohal toome ära funktsioonide kirjeldused.

`TemplateSource(const QString&amp; `failinimi`, const QString&amp; `tüüp`)`

  Andmeallika lugeja konstruktor. `failinimi` on selle faili nimi, millest andmed loetakse, `tüüp` failis sisalduvate andmete tüüp. Konstruktor peab üldjuhul välja kutsuma `KstDataSource`'i konstruktori konstruktori initsialiseerija loendis ning tõenäoliselt esitama liikme muutujate initsialiseerimiseks väljakutse allpool toodud funktsioonile `update`. Eriti tuleb silmas pidada muutuja `bool_valid` korrektset määramist.

`virtual ~TemplateSource()`

  Andmeallika lugeja destruktor. Kogu dünaamiliselt eraldatud mälu vabastatakse.

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

  See funktsioon loeb andmefailist kõik uued andmed, mis on sinna lisandunud pärast viimast funktsiooni `update` väljakutset ning uuendab vastavalt liikme muutujaid. Funktsioon tagastab `KstObject::UPDATE`, kui failis on muudatusi, või `KstObject::NO_CHANGE`, kui neid ei ole.

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

  See funktsioon peab lugema andmetest `n` raami, alustades raamist `s` väljal, mille määrab ära välja nimi `väli`, ning tagastama sisu massiivina `v`. Kui `n` on väiksem kui 0, peab funktsioon lugema 1 valimi alates raamist `s`. Tagastatakse loetud raamide arv.

`virtual bool isValidField(const QString &`väli`) const`

  See funktsioon peab tagastama 'true', kui väli, mille määrab välja nimi `väli`, on antud andmeallikas sobilik väli, või 'false', kui see ei ole sobilik väli.

`virtual int samplesPerFrame(const QString& `väli`)`

  See funktsioon peab tagastama valimite arvu raami kohta väljal, mille määrab välja nimi `väli`. Andmeallikate puhul, mis sellist kontseptsiooni ei kasuta, määratakse valimite arvuks raami kohta `1`.

`virtual int frameCount() const`

  See funktsioon peab tagastama andmeallika raamide koguarvu, nagu see oli siis, kui viimati kutsuti välja `update`.

`virtual QString fileType() const ```

  See funktsioon peab tagastama parajasti kasutatava andmefaili failitüübi, mis tavaliselt on sama, mis konstruktorile edastatud parameeter `tüüp`. Vastasel juhul sisaldab see veateadet (mis näiteks annab teada, et tegemist ei ole sobiliku failiga).

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

  See funktsioon peaks salvestama failikirjelduse info `ts`-i. Enamasti peaks piisama `KstDataSource`'i pakutavast teostusest.

#### Näidismallid

Üldiselt saab uute ühisobjekti failide loomiseks kasutada kaht allpool todud mallifaili. Muuda neis lihtsalt oma andmeallika vajadusi arvestades funktsioonide sisu.

    /***************************************************************************
                      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`-fail

Siin toome mallplugina `.desktop`-faili näite:

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

Väljadele 'Name' ja 'Comment' võib lisada tõlkeid mis tahes keelde, lisades täiendavalt samanimelised väljad, millele on lisatud sümbolid `[xx]`, kus `xx` kujutab endast vajaliku keele kahetähelist koodi, Näiteks eestikeelse tõlke lisamiseks tuleb lisada sellised read:

    Name[et]=Faililugeja mall
    Comment[et]=Failidest andmete lugemise vahendi mall.

Väli `X-Kst-Plugin-Library` peab täpselt vastama plugina teegi nimele.

### Kompileerimine ja kopeerimine

Uue omaloodud andmeallika lugeja kompileerimiseks ja paigaldamiseks loo uus alamkataloog lähtepaketi kataloogis `kst/datasources`. Aseta uude kataloogi objekti lähtekoodifailid ning `.desktop`-fail. Seejärel muuda faili `kst/datasources/Makefile.am`, nii et `SUBDIRS` sisaldaks uue alamkataloogi nime. Kui näiteks uus alamkataloog kannab nime `template`, siis tuleks `SUBDIRS` muuta järgmiselt:

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

Pärast kõigi vajalike failide asetamist uude alamkataloogi, tuleb ka seal luua fail `Makefile.am`. Kasuta alltoodut näidisena, asendades kõik sõnad template enda teegi nimega kirjetes `kde_module_LTLIBRARIES`, `kstdata_template_la_SOURCES` ja `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

Kui see tehtud, võid &kst; muudetud lähteteksti kompileerida ja uuesti paigaldada või siis ka paigaldada ainult uued teegid, nagu näidatud allpool (seal on kasutatud alamkataloogi template). Esmalt liigu &kst; lähteteksti baaskataloogi ja seejärel:

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

Käivita &kst; uuesti ja uus andmeallika lugeja peaks olema laetud.