Важно

Prevod je zajednički napor možete se pridružiti. Ova stranica je trenutno prevedena na 100.00%.

1. QGIS standardi kodiranja

Standardi kodiranja QGIS-a opisani su u dokumentu o politikama dostupnom na adresi QEP #314. Svi programeri su dužni da se pridržavaju tih politika. Imajte u vidu da je QEP #314 aktivni dokument i da se ove politike mogu menjati tokom vremena.

1.1. Časovi

1.1.1. Funkcije pristupnika

Uverite se da su pristupnici pravilno označeni sa „const“. Gde je to potrebno, ovo može zahtevati da keširane promenljive članice tipa vrednosti budu označene sa „mutable“.

1.1.2. Argumenti funkcije

Obratite pažnju kada argumente treba prosleđivati referencom. Osim ako objekti argumenata nisu mali i trivijalno se kopiraju (kao što su QPoint objekti), treba ih prosleđivati konstantnom referencom. Radi doslednosti sa Qt API-jem, čak se i implicitno deljeni objekti prosleđuju konstantnom referencom (npr. setTitle( const QString& title ) umesto setTitle( QString title ).

1.1.3. Vrednosti koje vraća funkcija

Vraćajte male i trivijalno kopirane objekte kao vrednosti. Veće objekte treba vraćati konstantnom referencom. Jedini izuzetak od ovoga su implicitno deljeni objekti, koji se uvek vraćaju kao vrednost. Vraćajte QObject ili izvedene objekte kao pokazivače.

  • int maximumValue() const

  • const LayerSet& layers() const

  • QString title() const (QString je implicitno deljen)

  • QList< QgsMapLayer* > layers() const (QList je implicitno deljen)

  • QgsVectorLayer *layer() const; (QgsVectorLayer nasleđuje QObject)

  • QgsAbstractGeometry *geometry() const; (QgsAbstractGeometry je apstraktan i verovatno će morati da se kastuje)

1.2. Dokumentacija API-ja

Obavezno je pisati dokumentaciju API-ja za svaku klasu, metod, nabrajanje i drugi kôd dostupan u javnom API-ju.

QGIS koristi Doxygen za dokumentaciju. Pišite opisne i smislene komentare koji čitaocu daju informacije o tome šta da očekuje, šta se dešava u graničnim slučajevima i daju nagoveštaje o drugim interfejsima koje bi mogao tražiti, o najboljim praksama i primerima koda.

1.2.1. Promenljive članice

Promenljive članice obično treba da budu u private odeljku i dostupne preko getera i setera. Jedan izuzetak od ovoga su kontejneri podataka, kao za prijavljivanje grešaka. U takvim slučajevima nemojte članu dodavati prefiks m.

1.3. Qt Designer

1.3.1. Generisane klase

QGIS klase generisane iz Qt Designer (ui) datoteka treba da imaju sufiks Base. Time se klasa identifikuje kao generisana bazna klasa.

Primeri:

  • QgsPluginManagerBase

  • QgsUserOptionsBase

1.3.2. Dijalozi

Svi dijalozi treba da implementiraju pomoć u vidu iskačuće pomoći za sve ikone palete alatki i druge relevantne vidžete. Iskačuća pomoć znatno doprinosi otkrivljivosti mogućnosti kako za nove tako i za iskusne korisnike.

Uverite se da se redosled tabulacije za vidžete ažurira svaki put kada se raspored dijaloga promeni.

1.4. C++ datoteke

1.4.1. Standardno zaglavlje i licenca

Svaka izvorna datoteka treba da sadrži odeljak zaglavlja po uzoru na sledeći primer:

/***************************************************************************
  qgsfield.cpp - Describes a field in a layer or table
  --------------------------------------
  Date : 01-Jan-2004
  Copyright: (C) 2004 by Gary E.Sherman
  Email: sherman at mrcc.com
/***************************************************************************
 *
 * 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.
 *
 ***************************************************************************/

Белешка

U git repozitorijumu postoji šablon za Qt Creator. Da biste ga koristili, kopirajte ga iz qt_creator_license_template na lokalnu lokaciju, prilagodite adresu e-pošte i - ako je potrebno - ime i konfigurišite QtCreator da ga koristi: Tools ► Options ► C++ ► File Naming.

1.5. Uređivanje

Za uređivanje QGIS koda može se koristiti bilo koji tekstualni uređivač/IDE, pod uslovom da su ispunjeni sledeći zahtevi.

1.5.1. Tabulatori

Podesite svoj uređivač da emulira tabulatore razmacima. Razmak tabulatora treba postaviti na 2 razmaka.

Белешка

U vim-u se to radi pomoću set expandtab ts=2

1.5.2. Uvlačenje

Izvorni kôd treba uvlačiti radi bolje čitljivosti. Postoji datoteka prepare_commit.sh koja pronalazi izmenjene datoteke i ponovo ih uvlači pomoću astyle. Ovo treba pokrenuti pre komitovanja. Za uvlačenje pojedinačnih datoteka možete koristiti i astyle.sh.

Pošto novije verzije astyle uvlače drugačije od verzije korišćene za potpuno ponovno uvlačenje izvornog koda, skripta koristi staru verziju astyle, koju uključujemo u naš repozitorijum (omogućite WITH_ASTYLE u cmake da biste ga uključili u build).

1.6. Kompatibilnost API-ja

Postoji dokumentacija API-ja za C++.

Trudimo se da API bude stabilan i unazad kompatibilan. Čišćenja API-ja treba raditi na način sličan Qt izvornom kodu, npr.

class Foo
{
  public:
    /**
     * This method will be deprecated, you are encouraged to use
     * doSomethingBetter() rather.
     * \deprecated use doSomethingBetter()
     */
    Q_DECL_DEPRECATED bool doSomething();

    /**
     * Does something a better way.
     * \note added in 1.1
     */
    bool doSomethingBetter();

  signals:
    /**
     * This signal will be deprecated, you are encouraged to
     * connect to somethingHappenedBetter() rather.
     * \deprecated use somethingHappenedBetter()
     */
#ifndef Q_MOC_RUN
    Q_DECL_DEPRECATED
#endif
    bool somethingHappened();

    /**
     * Something happened
     * \note added in 1.1
     */
    bool somethingHappenedBetter();
}

1.7. SIP vezivanja

Neke SIP datoteke se automatski generišu pomoću posebne skripte.

1.7.1. Predobrada zaglavlja

Sve informacije za ispravno pravljenje SIP datoteke moraju se nalaziti u C++ datoteci zaglavlja. Za takvu definiciju dostupno je nekoliko makroa:

  • Koristite #ifdef SIP_RUN za generisanje koda samo u SIP datotekama ili #ifndef SIP_RUN samo za C++ kôd. Naredbe #else se rukuju u oba slučaja.

  • Koristite SIP_SKIP da biste odbacili liniju

  • Sledeće anotacije se rukuju:

    • SIP_FACTORY: /Factory/

    • SIP_OUT: /Out/

    • SIP_INOUT: /In,Out/

    • SIP_TRANSFER: /Transfer/

    • SIP_PYNAME(name): /PyName=name/

    • SIP_KEEPREFERENCE: /KeepReference/

    • SIP_TRANSFERTHIS: /TransferThis/

    • SIP_TRANSFERBACK: /TransferBack/

  • private odeljci se ne prikazuju, osim ako u tom bloku koristite naredbu #ifdef SIP_RUN.

  • SIP_PYDEFAULTVALUE(value) može se koristiti za definisanje alternativne podrazumevane vrednosti python metoda. Ako podrazumevana vrednost sadrži zarez ,, vrednost treba okružiti jednostrukim navodnicima '

  • SIP_PYTYPE(type) može se koristiti za definisanje alternativnog tipa za argument python metoda. Ako tip sadrži zarez ,, tip treba okružiti jednostrukim navodnicima '

Dostupna je i demo datoteka, sipifyheader.h.

1.7.2. Generisanje SIP datoteke

SIP datoteka se može generisati pomoću posebne skripte. Na primer:

scripts/sipify.pl src/core/qgsvectorlayer.h > python/core/qgsvectorlayer.sip

Za automatsko generisanje SIP datoteke novododate C++ datoteke potrebno je izvršiti sip_include.sh.

Čim se SIP datoteka doda u jednu od izvornih datoteka (core_auto.sip, gui_auto.sip ili analysis_auto.sip), smatraće se automatski generisanom. Test će obezbediti da ova datoteka bude ažurna sa svojim odgovarajućim zaglavljem.

Da biste prisilili ponovno pravljenje SIP datoteka, treba izvršiti sipify_all.sh.

1.7.3. Poboljšanje sipify skripte

Ako su za sipify skriptu potrebna neka poboljšanja, dodajte delove koji nedostaju u demo datoteku sipifyheader.h i napravite očekivanu datoteku zaglavlja sipifyheader.expected.sip. I ovo će biti automatski testirano kao jedinični test same skripte.

1.8. Podešavanja

QGIS kodna baza nudi mehanizam za deklarisanje, registrovanje i korišćenje podešavanja.

  • podešavanja treba definisati pomoću jedne od dostupnih implementacija (QgsSettingsEntryString, QgsSettingsEntryInteger, …).

  • podešavanja moraju biti integrisana u stablo podešavanja (QgsSettingsTree); ovo se automatski radi pri korišćenju konstruktora sa nadređenim čvorom (QgsSettingsTreeNode).

  • deklarišu se kao const static bilo u posebnoj klasi ili direktno u registru (core, gui, app, …).

  • ključ podešavanja treba da koristi kebab-case.

1.9. Stil kodiranja

Ovde su opisani neki saveti i trikovi za programiranje koji će, nadamo se, smanjiti greške, vreme razvoja i održavanje.

1.9.1. Gde god je moguće, generalizujte kôd

Ako sečete i lepite kôd, ili na drugi način pišete istu stvar više puta, razmotrite objedinjavanje koda u jednu funkciju.

Ovo će:

  • omogućiti da se izmene naprave na jednom mestu umesto na više mesta

  • pomoći u sprečavanju bujanja koda

  • otežati da više kopija tokom vremena razvije razlike, čime se drugima otežava razumevanje i održavanje

1.9.2. Stavljajte komande u zasebne linije

Pri čitanju koda lako je propustiti komande ako nisu na početku linije. Pri brzom čitanju koda uobičajeno je preskočiti linije ako u prvih nekoliko znakova ne izgledaju kao ono što tražite. Takođe je uobičajeno očekivati komandu posle uslova kao što je if.

Razmotrite:

if (foo) bar();

baz(); bar();

Veoma je lako propustiti deo toka kontrole. Umesto toga koristite

if (foo)
  bar();

baz();
bar();

1.9.3. Preporuke knjiga

Takođe biste zaista trebalo da pročitate ovaj članak iz Qt Quarterly o projektovanju u Qt stilu (API-ji)

1.10. Zasluge za doprinose

Autore novih funkcija ohrabrujemo da obaveste ljude o svom doprinosu: