Programming Guidelines
From BibleTime
BibleTime up to 1.6 never had strict rules for the implementation of the code. Looking at the code you'll see that the code is a total mess, not maintainable, not well put into an architecture. Part of the reasons were the lacking knowledge of the right techniques.
These guidelines are quite strict to enforce good code quality. They are mandatory for any newly written code.
Contents |
Source code policies
Headers and implementations
It is good C++ practice to work with header and implementation files. The following rules apply:
- One header and one implementation file for each major class
- Classes declared within another class may be in the same file
- The header files must #include only what is required for that particular header file. User forward declarations where possible.
- Include everything needed for the class in the implementation file
All source files must have the following beginning:
/********* * * This file is part of BibleTime's source code, http://www.bibletime.info/. * * Copyright 1999-2008 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/
Source code documentation
- Document classes, member variables and member functions in the header files. There should be at least a brief information about each class and member function.
- Implementation files should contain in-code documentation (à la "the next block does..."). Please document enough, so that other people can understand your code quickly.
Design and naming conventions
There are no rules for this (yet). For helpful hints, check out this trolltech article about a good API.
User-visible text
Texts in the UI that the user sees must be marked with QObject::tr() for translation.
Here is a list of old, internal names and their preferred equivalent that is to be used in existing and new code:
| Old names | Current name, to be used | explanation |
|---|---|---|
| (sword) module | work | literary work, all kinds of books |
| main index | bookshelf | the place to store your works |
| (sword) module manager | bookshelf manager | the tool to download/update/remove works |
| presenter, display window | read window | the mdi windows where you can read your works |
Read these instructions which are very enlightening and recommended for everyone working with user interface texts:
Text style and tone
- Neutral tone, not aggressive or impolite but not overly polite ("please" is not necessary, "You have failed to..." is bad)
- As short as possible - every word counts and must add new information
- Avoid redundancy (in one sentence but also between UI elements)
- Avoid obvious information which is easily deductible from the context (e.g. don't add the object of the action if user knows it already)
- Tooltips end with period only if there are several sentences. If there are several sentences they all end with period. Single, short, even incomplete sentences are preferred.
- Avoid snobbish or rare words or grammar, remember that the text must be understood by even non-native English users. (Example: use "indexes" instead of "indices", it's correct English and more understandable to the foreign users because it's a regular plural.)
Examples:
- Bad tooltip: You can go to the next verse of the current work by clicking this button.
- Better tooltip: Go to the next verse of the current work
- Good tooltip: Next verse
Capitalization
Use title-style capitalization for titles, sentence-style capitalization for all other UI elements. For details, see MS Vista HIG, User Interface Text.
- Window titles are title-style
- Buttons, tabs, menu items, labels etc. are sentence-style
- Even grouping headers are sentence-style
- Bookshelf Manager is a title, use title-case in all places, even in menu
Coding style
[more details will follow]
Tabs
Use tabs instead of spaces to indent your code. 1 tab = 4 spaces.
Constructors
After the definition of the constructor, list all base class constructors and member variable inititializations in separate lines. Then comes the main constructor code block.
CBibleKeyChooser::CBibleKeyChooser(ListCSwordModuleInfo modules, CSwordKey *key, QWidget *parent) :
CKeyChooser(modules, key, parent),
m_key(dynamic_cast<CSwordVerseKey*>(key))
{
...
}
Compiler strictness
In normal development builds, the compiler will perform a very strict error checking with the flags "-Wall -Werror -pedantic-errors". This means that all compiler warnings will abort the build. Therefore code is not allowed to produce any compiler warnings. For developers this may seem nasty at times, but I'm convinced this will prove very helpful in future (find bugs before they find you). One example where the stricter compiler checking can help find potential bugs is "inheritance / virtual functions".
Checkin restrictions
- Checked in code has to compile
- Don't check in commented out code
Mandatory programming principles
For basic programming guidelines we strongly recommend the book "The pragmatic programmer" and books like "Effective C++: 55 ways to improve your Programs and Designs" (by Rick Meyers) for C++ specific guidelines.
DRY (Don't Repeat Yourself)
This simple principle means that every piece of information (data or logic) may be represented only once in a system (= program).
Ideas, not mandatory
Unit testing
- Qt 4 has some integrated unit testing, which is also available for GUI elements. See http://doc.trolltech.com/4.2/qtestlib-manual.html.
- CPPUnit: http://sourceforge.net/projects/cppunit.
- CTest is another possibility, not sure what it is like
