====== Class Diagram ======

===== User interface =====

There is a central application object which is the single instantiation of the class "[[:man:Zim::GUI|Zim::GUI]]". This object manages a number of objects that handle certain parts of the interface. These can be either pieces of the program that are split out to a separate module or objects defined by plugins. Examples of such components are the main interface widgets like the [[:man:Zim::GUI::PageView|PageView]], the [[:man:Zim::GUI::TreeView|TreeView]] and the [[:man:Zim::GUI::PathBar|PathBar]], which are essentially wrappers around the coresponding gtk objects. From these components the main object is refered as "''{app}''".


{{./relations_gui_layer.png}}


===== Data backend =====

The "[[Repository]]" objects manage the collection of files. Their is a main dispatcher object [[:man:Zim|Zim]] that uses one or more handlers to do the actual work, like [[:man:Zim::Store::Files|Zim::Store::Files]] and [[:man:Zim::Store::Man|Zim::Store::Man]].

The "[[Page]]" objects represent for example one file.

The class Zim::Selection is used to handle groups of pages. It is bound to a repository object but can represent for example a subset of the repository.

The History object contains a sequence of pages together with records of for example the last cursor position and the undo stack for these pages.



{{./relations_data_layer.png}}



==== Sequences: ====


{{./sequence_data_layer.png}}




**----------------------------------------------------------------------------------------------**

===== Plans =====

Below ideas are collected for __future__ refactoring.

See also [[development:brainstorm:changes_and_versions|changes_and_versions]]

==== Filesystem interface ====

Have a general FileSystem object that catches all filesystem requests. This should be a factory for File objects. This should be a singleton object that knows which directories are under version control etc. 

Automatically check for revision control on the repository directory. Plugins should be able to add checks to this list (use global hash). Make sure the gui triggers a check of the dir after the plugins are loaded. Probably stores should tell the FS object which directories they intend to use and at the trigger these directories are checked. Any of these directories that turn out to be special will be handled by derived objects that can have triggers for all kinds of operations.

If you want to acces versioning from the repository you can just ask the FS for older versions of a file and see if you get something. The file objects themselves could have undo and redo methods. Doing a save after an undo makes the rollback permanent. (Disable autosave while looking at an older version to minimize delta.)

Make sure I can insert filters in the filesystem layer. E.g. if I want to use encryption, I should be able to filter all files that match a certain extension through the encryption utility on read / write. Idem for seamless compression support.


==== Repositories and Pages ====

Shell out more logic to the page objects. For example add an API to access their underlying namespace; after all this parent-child relation is just a priviledged type of link. Think of pages as the iteraters or pointers in a omni-directional graph.

Each store has a special "toplevel" page which allows access to the whole structure. Also there should be an index of special pages like "Home".

Besides page and stores there are also still Selection objects, which are like arrays of pages with possibly a table storing meta properties. Selections share part of the Store API so they can be used as sub-sets of Stores. Sub-classes of Selections are used for example to export pages or to return search results.

==== Subclassing Stores ====

Stores have a clear Class structure without any special design pattern. There will be a "Cached" class which uses a file cache to stores linking relations and potentially other meta-data. Later this class might optionally use a [[database|DB]] like SQLite .

Files will inherit from Cached and e.g. Album will inherit from Files. To make the file structure more flexible and embed multipart files, the format should be able to tell the repository that a file contains multiple pages.

==== Formats ====

Formats will use the decorator design pattern. That means they can wrap around each other. Main application will be to wrap a parser for 822 messages around a parser that parses the main body.

==== Files ====

Assume each repository to have a directory where we store meta data / templates / etc. This is not necessarily the location of the sources for the pages.

Add an API to the page objects for getting a directory where to store files below the namespace of this page. This is for media / attachements . The dir object returned could very well be under version control etc.

==== HTTP ====

Embed more HTTP style logic in the API. Start using 822 format as the standard way to safe meta data. Allow for multipart 822 files. Also think about using HTTP style status codes for responses of the repository to the GUI.

==== Zim::Changes ====
* Changes
	* RCS like - Zim::File::Deltas
		* API
			* new(version_file, [tmp_file])
			* ci(file)
			* co(version) # if version is "-1" take last - returns version of tmp_file after operation - idem for "+1"
			* ident() - versions
			* purge(version) - throw away all before this
 version + re-gzip for compression optimization
		* Routines
			* diff(file1, file2) - returns result
			* append(diff) - gzip + append
			* deltas(version, [version]) # extract deltas between versions - filter through gzip
			* reverse(delta) - reverse direction of patch
			* patch(delta => file)
		* only store deltas by appending
		* keep one checkout version for use with offline editing
		* use cache to detect offline editing
	* need API per page

* save page
	* delta current => old version
	* append delta to change file
* checkout version
	* read current
	* apply each delta till version
	* write version to tmp file
* purge
	* read all deltas since version
	* overwrite delta file


==== Zim::Selection ====
* support to select pages using globs
	* this replaces the semantic that /:$/ signifies recursion
* option "follow links"
* search() - returns a new selection
	* selections with search results need to contain columns with meta data
		* use a cache object, keep data in memory
	* store query for later comparison
* is_subquery()
	* check if a sub-query is possible
	* support only one level of AND using a hash
* list_pages()
* move(TARGET_NAMESPACE)
	* support glob in target
	* option for updating
* copy(TARGET_NAMESPACE)
	* support glob in target
* export should support merging pages into one

==== Zim::Formats ====
* Register formats with read/write/native
* Create base class functions to quickly hack new exporters
* How would base class functions for importers look ?
* better control of headings at export
	* add page name as heading if page does not start with heading
	* fix gaps in heading hierarchy, make sure to start at 1
	* optionally make headings fit a certain range (currently implemented)
	* have an hidden option to not do this fix - use this for print to browser


