Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: Unknown

====== HACKING ======

All development documentation is part of the zim source code in the
form of python doc strings. Below is a collection of items in progress
and some general hints.

**NOTE:** Under the GPL license used for distributing this program all
plugins should also be licensed under GPL. A closed source plugin
extension is not allowed. A plugin is allowed to call any non-GPL
program as long as the plugin itself is under GPL and the non-GPL
program runs as a separate process with a clearly defined inter process communication interface.

===== Gtk+ libraries =====

Zim is build on top of pygtk and pygobject. However, the classes outside the 'gui' namespace are not allowed to use the gtk libraries, and should work when only gobject is available. This potentially allows zim to run without a graphical interface, also it gives a strict boundry between UI and data layers in the class hierarchy. The exception are modules in the 'plugin' namespace, which can of course package their own UI components. However, these should check on initialization if we are running in graphical mode or not.

For the moment we try to keep compatibility with Gtk+ version 2.6, this may change without notice when a new stable version is properly supported on all platforms.

# FIXME check what is actual current stable & check latest packaged for win32

===== Classes =====

Each class has inline documentation, use pydoc to view it.
The tree below is only a summary, run "dev/class_tree.py" to see
the full tree.

zim
|-- NotebookInterface() # Code for commandline export etc.
|-- gui             # Gtk interface
|   |-- GtkInterface(NotebookInterface)
|   |-- gtkutils
|   |-- pageview
|   |   |-- PageView()
|   |   |-- TextView
|   |   `-- TextBuffer
|   `-- pageindex
|       ` PageIndex()
|-- www             # WWW interface, both server and cgi-bin
|   |-- WWWInterface(NotebookInterface)
|	`-- Server()
|-- notebook
|   |-- Notebook()
|   |-- Page()
|   `-- Namespace()
|-- stores          # Data backends for notebooks
|   |-- files
|   |-- gjots
|   `-- memory
|-- templates
|   `-- Template()
|-- formats         # Parsers for various source formats
|   |-- html
|   |-- plain
|   `-- wiki
`-- fs              # File system objects
    |-- Path()
    |-- File(Path)
    |-- Dir(Path)
    `-- Buffer(StringIO)


Both gtk and www interfaces inherit from the Interface class defined
in zim. This class takes care of loading configuration files, plugins etc.

The Notebook object takes care of accessing and storing pages and
other data in the notebook. Each notebook can consist of one or more
store objects which implement the actual data backend. E.g. the 'files' store implements storing wiki pages a text files in a directory structure.

Parsing of wiki syntax and other import / export formats is handled by
modules in the 'formats' directory. These use a common parse tree structure to represent a single page.

Both the zim interface class and the notebook class derive from gobject
and use the gobject signal system. Only the GUI classes use gtk. So pygtk is only a dependency when running the GUI, however python-gobject is also required when only running the server.

===== Coding style =====

See the python style guide for best practices. Some items to keep in mind:

* GUI classes are only allowed to construct widgets and wire signals.  Any actual manipulation of pages, notebooks etc. should go elsewhere.
* Signal handlers have a method name starting with "do_"
* Only use "assert" for checks that could be removed when code is stable, these statements could be optimized away
* Do not rely on ''__doc__'' on run time, this data could be optimized away
* Have a look e.g. at zim.parsing and zim.gui.widgets for common code snippets

Other general guidelines:
* Writing test cases is good, full test coverage is better. Run "./test.py --cover" to get a coverage report.
* Wait with loading modules and constructing widgets untill they are  really needed, this should keep startup speed reasonable
* Try to do slow operations that could be done asynchronous using the idle event, e.g loading the side pane index, or a list with search results, or even running an external command to check in a new version of a file.

About formatting:
* I use TABs (not spaces) with a tabstop set to the equivalent of 4 spaces, (most) lines should fit within 80 character with this setting.
