Envision
A visual programming IDE for object-oriented languages
Contributing to Envision

All contributions to the Envision source code such as enhancements or bug fixes are much appreciated.

If you want to join the development effort please read the information on this page.

Workflow

The main repository for the project is maintained by Dimitar and can be found here. There are two main branches:

  • development - Contains the latest changes and features. This branch is updated regularly, and any contributions should be based on it.
  • master - The idea is that this branch contains a somewhat more stable version of the IDE. However currently, it simply contains an older version, that is occasionally synchronized with the development branch.

Contributors should create their own forks of Envision on github and create a feature branch based on the development branch. Work on new features or bug fixes should be done in this branch and the branch should be rebased prior to being merged back into the development branch of the main Envision repository.

This simple workflow is sufficient for the small team of people who are currently contributing to Envision.

Build environment and getting started

For instructions on how to compile Envision see here.

Introductory tutorials that you should read to familiarize yourself with Envision's model-view-controller implementation can be found here.

Code style

All contributions to Envision must adhere to the following coding guidelines.

Setting up Eclipse and Qt Creator

  • License template - Please set the license template to the Envision BSD license file. You can find the LICENSE file in the main directory of the repository.
    • Qt Creator: Tools > Options > C++ > File Naming > License Template.
    • Eclipse: Window > Preferences > C/C++ > Code Style > Code Templates > Comments > Files.
  • Code style - Use the following code style configurations:
    • Qt Creator: style file. Set up here: Tools > Options > C++ > Code Style > Import.
    • Eclipse: style file. Set up here: Window > Preferences > C/C++ > Code Style > Formatter > Import.

Formatting and white space

  • Always use TABs for indentation and never spaces. Configure your editor to display a tab as 3 spaces.
  • Lines should be at most 120 characters. A TAB counts as 3 characters.
  • If the body of an if, while, or for is a single statement, do not use curly braces around it. If the condition and statement fit nicely on the same line write them on one line, otherwise put the statement on a newline:
    // Wrong:
    if (foo)
    {
    bar();
    }
    if (aMoreComplicatedOrMultilineCondition) anExtremelyLongAndComplicatedStatement();
    // Correct:
    if (foo) bar();
    if (aMoreComplicatedOrMultilineCondition)
    anExtremelyLongAndComplicatedStatement();
  • Curly braces should appear in a line on their own, except when using lambdas:
    // Wrong:
    if (foo) {
    }
    // Correct:
    if (foo)
    {
    }
  • Leave a single space after a // comment delimiter.
  • For pointers or references, do not leave any space between the type and '*' or '&', but write a single space between the '*' or '&' and the variable name:
    QString& string;
    Item* item;
    const QString& message;

Of course you can always have a look at the existing code in case you are not sure about something. If you feel like some additional clarifications should be added here, let us know.

Naming

All names in envision plug-in should use CamelCase:

  • The names of type definitions (classes, structs, typedefs, using, enums, etc.) should start with a capital case letter.
  • Function, method, variable, and field names should start with a small case letter.
  • Field names should end with a trailing underscore (e.g. data_, instead of data):
    private:
    int length_;
    Item* myFirstItem_;
  • Names should be descriptive, especially names of function arguments. Avoid abbreviations and shortened words. The exception is the name of local variables, which can be short provided there is no ambiguity.
  • When declaring a class, list the members in the following order starting from the top: public, protected, private.
  • In the .cpp file defining a class, define all members in the following order starting from the top: static, constructors, destructors, the rest

Language features

  • Strive for const-correctness.
  • Use exceptions Qt's assertions Q_ASSERT. Exceptions should be thrown in situation where a problem is caused due the user's input or the user's actions, and this problem can not be prevented in code. For all other situations you should use assertions. In particular use assertions to introduce checks at various places in the code where you expect the assertion to hold. The presumption should be that if an assertion fails, this indicates a buggy and incomplete code, and it is possible to fix this once and for all in the code.
  • Use RTTI where appropriate. Avoid C casts and use C++ casts instead: (static_cast, dynamic_cast, const_cast, reinterpret_cast). Better still, is to use the Envision provided DCast, instead of C++'s dynamic_cast, whenever possibly. DCast is faster but you can only use it if the class hierarchy you're trying to cast within supports it. These are currently all Node subclasses and all Item subclasses. Any other type can be made to support DCast by using the Super template to inherit from a base class and using the appropriate type id macros from Core/src/reflect/typeIdMacros.h
  • Make use of C++11 features.
  • All class members should have a default initializer using the new C++11 syntax with curly braces in the class declaration:
    // Wrong:
    class PointAndItem
    {
    public:
    PointAnditem();
    private:
    int x_;
    int y_;
    Item* item_;
    }
    PointAndItem::PointAndItem() : x_(0), y_(0), item_(nullptr)
    {
    }
    // Correct:
    class PointAndItem
    {
    private:
    int x_{};
    int y_{};
    Item* item_{};
    }
  • When reimplementing a virtual method, put the virtual and the override keywords in your method declaration.
  • Only define private fields, never public or protected.
  • All non-virtual methods that are simple and short should be declared inline. The method definition of inlined methods should appear after the class body:
    // Wrong:
    class Cell
    {
    public:
    int value() const { return value_;}
    private:
    int value_;
    }
    // Correct:
    class Cell
    {
    public:
    int value() const;
    private:
    int value_;
    }
    inline int Cell::value() const { return value_;}
    object value(const NamedProperty &self)
    Definition: DataApi.cpp:50
  • Wherever possible prefer to use classes provided by Qt over STL or other libraries.
  • If you are defining new templates make sure those work across platforms and shared object boundaries.

Miscellaneous

  • If you want to introduce dependencies to new libraries, discuss this with a maintainer first.
  • Generally, do not copy code from other sources to Envision. Small snippets from stack overflow are ok, but large pieces of code or entire files are forbidden. An exception may be made for BSD/MIT licensed files, but you must discuss this with a maintainer first. GPL/LGPL code is not allowed.

Further reading

Qt is an excellent framework and is used throughout the Envision project. Many Qt conventions have been adopted by Envision. You may want to have a look at:

Commit policy

  • A single commit should focus on a single bug fix, or a single aspect of an enhancement. Unrelated changes should be committed separately.
  • Do not squash multiple commits into one. A bug fix or enhancement should have its own branch that contains all necessary commits.
  • Always include a commit message which should at a minimum contain at least a title
  • Commit titles should be limited to 72 characters and use the present tense to indicate what the commit will do:
    Right: Fix a bug where typing 42 would crash Envision
    Wrong: Fixes a bug where typing 42 would crash Envision
    Wrong: Fixed a bug where typing 42 would crash Envision
    
  • If the commit title does not sufficiently describe the commit, also include a more detailed commit description.