Padrões de Codificação QGIS

Estes padrões devem ser seguidos por todos os desenvolvedores do QGIS.

Classes

Nomes

A classe no QGIS começa com Qgs e é formada usando o caso do camelo.

Exemplos:

  • QgsPoint
  • QgsMapCanvas
  • QgsRasterLayer

Membros

Os nomes dos membros da classe começam com um m minúsculo e são formados usando maiúsculas e minúsculas.

  • mMapCanvas
  • mCurrentExtent

Todos os alunos devem ser privados. Membros da classe pública são fortemente desencorajados

Funções de acesso

Os valores dos membros da classe devem ser obtidos por meio de acesso ou funções. A função deve ser nomeada sem um prefixo get. As funções de acesso para os dois membros particulares acima seriam:

  • mapCanvas()
  • currentExtent()

Funções

Os nomes das funções começam com uma letra minúscula e são formados usando maiúsculas e minúsculas. O nome da função deve transmitir algo sobre o propósito da função.

  • updateMapExtent()
  • setUserOptions()

Qt Designer

Classes Geradas

As classes do QGIS geradas a partir dos arquivos do Qt Designer (ui) devem ter um sufixo Base. Isso identifica a classe como uma classe base gerada.

Exemplos:

  • QgsPluginManagerBase
  • QgsUserOptionsBase

Diálogos

Todos os diálogos devem implementar o seguinte:

  • Ajuda da dica de ferramenta para todos os ícones da barra de ferramentas e outros widgets relevantes
  • WhatsThis ajuda para todos os widgets no diálogo
  • Um botão de ajuda sensível ao contexto opcional (embora altamente recomendado)
    que direciona o usuário para a página de ajuda apropriada, iniciando seu navegador da web

Arquivos C++

Nomes

A implementação de C++ e os arquivos de cabeçalho devem ter uma extensão .cpp e .h, respectivamente. O nome do arquivo deve ser todo em minúsculas e, no caso de classes, corresponder ao nome da classe.

Exemplo: Os arquivos fonte da classe Atributo do recurso Qgs são qgs apresentam atributo.cpp e `` qgs apresentam atributo.h``

Nota

No caso de não ficar claro na declaração acima, para um nome de arquivo corresponder a um nome de classe, implicitamente significa que cada classe deve ser declarada e implementada em seu próprio arquivo. Isso torna muito mais fácil para os recém-chegados identificar onde o código está relacionado a uma classe específica.

Cabeçalho e Licença Padrão

Cada arquivo de origem deve conter uma seção de cabeçalho padronizada após o seguinte exemplo:

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

Nota

Existe um modelo para o Qt Creator no git. Para usá-lo, copie-o de doc/qt_creator_license_template para uma localização local, ajuste o endereço de e-mail e - se necessário - o nome e configure o QtCreator para usá-lo: `` Ferramentas`` -> `` Opções`` - > `` C++ `` -> `` Nomenclatura de arquivos``.

Nomes Variáveis

Os nomes de variáveis locais começam com uma letra minúscula e são formados usando maiúsculas e minúsculas.

Exemplos:

  • mapCanvas
  • currentExtent

Tipos Enumerados

Os tipos enumerados devem ser nomeados no CamelCase com um dos principais capitais, por exemplo:

enum UnitType
{
  Meters,
  Feet,
  Degrees,
  UnknownUnit
};

Não use nomes de tipo genéricos que entrem em conflito com outros tipos. por exemplo. use `` Unidades desconhecidas`` ao invés de `` Desconhecido``

Constantes Globais & Macros

Constantes e macros globais devem ser escritos em sublinhado em maiúsculas, separados por exemplo:

const long GEOCRS_ID = 3344;

Comentários

Comentários para métodos de classe devem usar um estilo indicativo de terceira pessoa em vez do estilo imperativo:

/**
 * Creates a new QgsFeatureFilterModel, optionally specifying a \a parent.
 */
explicit QgsFeatureFilterModel( QObject *parent = nullptr );
~QgsFeatureFilterModel() override;

Editando

Qualquer editor de texto / IDE pode ser usado para editar o código QGIS, desde que os seguintes requisitos sejam atendidos.

abas

Configure seu editor para emular guias com espaços. O espaçamento de tabulação deve ser definido para 2 espaços.

Nota

No vim isto é feito com `` conjunto expandtab ts = 2``

Indentação

O código fonte deve ser recuado para melhorar a legibilidade. Existe um scripts/prepare-commit.sh que procura os arquivos alterados e os reindica usando astyle. Isso deve ser executado antes de confirmar. Você também pode usar scripts/astyle.sh para recuar arquivos individuais.

Como as versões mais novas do astle indent diferentemente da versão usada para fazer uma reindentação completa da fonte, o script usa uma versão antiga do astyle, que incluímos em nosso repositório (permite que o WITH_ASTYLE no cmake o inclua na compilação).

Suspensórios

O aparelho deve começar na linha seguinte à expressão:

if(foo == 1)
{
  // do stuff
  ...
}
else
{
  // do something else
  ...
}

Compatibilidade de API

Existe documentação da API para C++.

Tentamos manter a API estável e compatível com versões anteriores. As limpezas para a API devem ser feitas de maneira similar ao código-fonte do Qt, por ex.

class Foo
{
  public:
    /** This method will be deprecated, you are encouraged to use
     *  doSomethingBetter() rather.
     *  @deprecated 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();
}

Estilo de Codificação

Aqui estão descritas algumas sugestões e dicas de programação que reduzirão os erros, o tempo de desenvolvimento e a manutenção.

Sempre que possível, generalize o código

Se você estiver digitando um código ou digitando a mesma coisa mais de uma vez, considere consolidar o código em uma única função.

Isso vai:

  • permita mudanças serem feitas em um lugar ao invés de múltiplos lugares
  • ajudar a evitar o inchaço do código
  • tornar mais difícil para várias cópias evoluir as diferenças ao longo do tempo, tornando assim mais difícil de entender e manter para os outros

Prefiro ter constantes primeiro em predicados

Prefiro colocar constantes primeiro em predicados.

0 == valor em vez de` valor == 0`

Isso ajudará a evitar que os programadores usem acidentalmente = quando tiverem que usar == ``, o que pode introduzir bugs lógicos muito sutis. O compilador irá gerar um erro se você acidentalmente usar ``= em vez de == para comparações, já que constantes não podem ser atribuídas valores inerentemente.

Espaço em branco pode ser seu amigo

Adicionar espaços entre operadores, instruções e funções torna mais fácil para os humanos analisarem o código.

Qual é mais fácil de ler, isso:

if (!a&&b)

ou isto:

if ( ! a && b )

Nota

scripts/prepare-commit.sh vai cuidar disso.

Colocar comandos em linhas separadas

Ao ler o código é fácil perder comandos, se eles não estiverem no início da linha. Ao ler rapidamente o código, é comum pular linhas se elas não se parecem com o que você está procurando nos primeiros caracteres. Também é comum esperar um comando após uma condição como `` if``.

Considere:

if (foo) bar();

baz(); bar();

É muito fácil perder parte do fluxo de controle. Em vez disso, use

if (foo)
  bar();

baz();
bar();

Modificadores de acesso de recuo

Os modificadores de acesso estruturam uma classe em seções de API pública, API protegida e API privada. Os modificadores de acesso agrupam o código nessa estrutura. Recuar o modificador de acesso e declarações.

class QgsStructure
{
  public:
    /**
     * Constructor
     */
     explicit QgsStructure();
}

Recomendações de livros

  • C++ moderno eficaz <http://shop.oreilly.com/product/0636920033707.do> _, Scott Meyers
  • C++ mais eficaz <http://www.informit.com/store/more-effective-c-plus-plus-35-new-ways-to-improve-your-9780201633719> _, Scott Meyers
  • STL efetivo, Scott Meyers
  • Padrões de design, GoF

Você também deve ler este artigo de Qt Quarterly no designing Qt style (APIs)

Créditos por contribuições

Contribuidores de novas funcionalidades são encorajados a divulgar sobre suas contribuições: