First draft.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/branches/gnucash-gnome2-dev@9250 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
David Hampton
2003-09-06 21:49:21 +00:00
parent 0ac2c1f9a8
commit d15fd3a48d

149
src/doc/g2-architecture.txt Normal file
View File

@@ -0,0 +1,149 @@
0) Naming
---------
g1 - The gtk1 and gnome1 libraries.
g2 - The gtk2 and gnome2 libraries.
1) GTK2 Primer
--------------
In gtk2, an "action" is a g_object that represents some action that
the user might want to perform. This object could represent opening a
file, toggling the toolbar, etc. The action itself has *no* gui
component. There is no way to directly display an action to the user.
To do that, you assign the action to one or more proxy items. These
proxy items are the regular menu items, toolbar buttons, etc. that you
are familiar working with. There are several advantages to this new
system. The first is that you no longer have to write multiple action
routines; one for a menu selection and another for a button click.
There is a single code fragment written for when the action fires,
regardless of how it fired. The second advantage is that you no
longer have to enable/disable the individual menu items and buttons.
Enabling/disabling the action itself causes all proxy items to assume
the same state. For example, if an account isn't selected in the
account tree window, a single function call disables the "Open
Account" command in the main application menus, the "Open Account"
popup menu command, and the "Open Account" toolbar button.
A gtk2 "menu merge" takes descriptions of two sets of menus and merges
them into a single menu that is displayed on the screen. The first
menu must contain attachment points in it. These attachment points
are specified in the seconds set of menus and control where in the
combined menu the items from the second menu appear. This second
"merged" set of menus can easily be removed at any time.
Gtk2 has deprecated the clist and ctree widgets. The replacement is a
combination of a GtkTreeModel/GtkTreeView pair of objects.
In G1, most objects were based on a gtk_object, and were created,
destroyed, signaled, etc. using functions on this base object. In g2
the base object was moved from gtk2 to glib2, so most objects now need
to be based on the g_object object. There are still compatibility
functions on in gtk_object but you cannot mix and match calls to
g_object and gtk_object. You must use one function set or the other
for any given item.
2) Windowing Architecture
-------------------------
In the gtk1/gnome1 (hereafter g1) version of Gnucash, the windowing
was based on the "Multiple Document Interface" of g1. This code was
hard to use in the first place, and has been deprecated in g2.
The g2 version of gnucash is a series of plugin modules designed
around the g2 concepts of "actions" and "menu merging". These
concepts will be integrated into gtk2.4 release. We are currently
using the version of this code from the "egg" (proof of concept) code.
These files have been copied from libegg into the gnucash sources.
[Note: Some of these files may have been replaced with their gtk2.4
versions. Once gtk2.4 is targeted as out base platform level, they
can be removed from the gnucash sources.]
The first level of this architecture is an object representing a
"pluggable" window. This object is responsible for:
1) the window itself
2) providing a framework for plugins
3) providing a base set of menus (and actions)
Plugins can be one of two types. The first type is simply called a
"plugin" (e.g. gnc-plugin-register.c) and is used to add functionality
to the base window. This plugin provides only a menu/toolbar
description, and a way to create the second type of plugin. The
second type of plugin is called a "plugin page"
(e.g. gnc-plugin-page-register.c) and provides both a menu/toolbar
description, but also a widget that is displayed in the containing
window. This widget may be an account tree, a register, etc. The
plugin page must also provide a standard set of functions to interact
with the plugin manager code.
3) Model/View Architecture
--------------------------
As mentioned above, the ctree widget has been deprecated in g2. Some
parts of gnucash have been converted to the new style using either a
gtktreemodel/gtktreeview pair of widgets, or using a
gtktreemodel/eggtreemodelfilter/gtktreeview triplet of widgets. The
account tree is presented here as example of the latter.
In gnucash, all the accounts are stored in the engine. The account
tree "model" (a gtktreemodel) provides a representation of these
accounts that can be used by one or more views presented on the user's
screen. This code is designed so that there is only one single model
for the accounts in a given book, and this single model drives all
views. (This code should be easily expandable to multiple sets of
books once engine support is added.) The filters and views are
completely independent of each other, even though they share a common
model, so you may see different accounts in each view, have different
accounts selected in each view, etc.
The account tree model is designed as a tree and contains a "pseudo"
account that is the root node of this tree. Whether the root node is
visible is a per-view setting. Also in the model is code to display
the contents of any row/column intersection in the tree. The
gtktreemodel/view base code drives the actual display, and pulls
numbers from the account tree model as necessary to display them. For
all intents and purposes, the model is the sole gui representation of
the account tree. The overlaying filters and views simply limit what
the user sees to some subset of the information in the model. There
are very, very few instances where code interacts directly with the
account tree model. All interaction should be done through the
account tree view described later.
The next layer in the account tree is the treemodelfilter. This
filter is automatically created when the account tree view is created.
In most instances, this filter is used to install a "virtual root" on
the model that hides the top level "pseudo" account from the user. At
the time of this writing, only the account edit dialog leave this top
node visible (so the user can create a new "top level" account.) This
filter level is use in several places to install a visibility filter
onto the model, controlling which accounts are visible to the user and
which are hidden. These visibility decisions are made in real time as
the user clicks the disclosure triangle on an account to see what
sub-accounts it contains. This callback function for the visibility
filter is the only place where the code should interact directly with
the account tree model, and the only interaction should be to take the
provided model/iter pair and ask the account tree model for the
corresponding account. After that the callback may do whatever it
wants on the account and then return TRUE if it wants the account to
be visible, FALSE if not.
The top layer of the account tree is the account tree view. The
underlying gtktreeview object provides all the standard tree
manipulation functions; opening accounts to see sub-accounts, selecting
an item, etc. The account tree view is the programming interface that
should be used to manipulate an account tree. It provides the
functions to create a new view, to set a filter on an existing view to
control the visible rows, to configure the columns visible in the
view, to get/set the selected account(s) in the view, etc. There is
also a selection callback function available from the view, that may
be used to decide whether or not the user can select an account in the
view. It is used in the new account dialog, for instance, to limit
the accounts the user may select for the opening balance to an account
that has the same currency as the account being created.