GUI architecture

Still studying the code to try and sketch a global architecture of the application.

I’m presently focusing on how the GUI is initialised but I couldn’t figure out how menu items are connected to the related code.

As an example, take Family Trees>Manage Family Trees …. It is defined by a Glade XML description in gramps/gui/grampsgui.py as action ‘win.Open’. Obviously, this should be ultimately connected with DbManager class (in gramps/gui/dbman.py). An instance of this class is created in method __open_activate() of class ViewManager but I see nowhere a GTK-connect between ‘win.Open’ and some method. set_actions_visible() only deals with item visibility (enabled/disabled) in menus, not their connection or activation. As far as I can tell, *_action_group*() don’t manage the connection either.

So, where is the connection between Glade-XML GUI description and GTK widgets hidden?

Without this information, it is very difficult to experiment on a different GUI approach.

As you explore. Could you flowchart how elements are initialized?

When selecting a new view mode from the Navigator, my Gramps sessions eventually hit a problem where 2 category icon are highlighted and, although the main view & sidebars swap to the new category, the Toolbar & menu do not update to the new context nor does the focus follow active object changes. Having a processing hungry Gramplet (like Deep Connections) seems to be woven into this refresh problem.

Once this behavior begins in a a session, Gramps becomes increasingly unresponsive.

The context shift & redraw of the toolbar, menus & Navigator split bar seems to require completion of refresh of the status bar, sidebar splitbar, bottombar splitbar & main view.

It seems reasonable that, after the rough redraw of the overall application window outlines, the Statusbar should be the highest priority — since it gives error feedback. But the menu bar & tool bar ought to be next — so that a new action can be chosen that might interrupt refresh. And that the main View should be higher priority than the splits. And that the final refresh of the Navigator would indicate completed refresh of the main view content but only the splitbar refresh of the interior menus. (The content refresh of the Gramplet could be low priority and be interuptible.)

I don’t think this is how the cycle flows and I do not believe provision has been made for the re-initializing redraw of the Gramps app window if it did not successfully complete.

1 Like

In the present state of my knowledge, there are too many layers to traverse before reaching “useful” job (by that I mean significant genealogical processing or user interaction). I feel many contributors added their part without ever questioning the existing “skeleton”. This contributes to the confusion. There is no clear separation between data and presentation (the GUI) and both interact too closely.

Control flow is not obvious. The connection issue I mention is an indication of this “opacity”.

As an example, I’m playing with a prototype using Qt instead of GTK. Displaying the main window and its menus requires much less code than presently. Either the abstract models of Qt and GTK are dramatically different (there are differences of course but do they explain the huge dissimilarity in code?), or the structure has been cluttered to a point nobody knows now the logic behind it.

What you mention looks like code doesn’t disable some processing and from there on the GTK signal device works on its own in the wild: it dispatches “events” on both. That’s perfectly legitimate for GTK but Gramps is probably not prepared to react to simili-threads.

2 Likes

The connection you are looking for is in fact the action_groups. set_action_group tells the GIO code how to connect the win.Open to the appropriate callback. A relatively small example is in the
“gramps/gui/views/tags.py” module. At about line 256 a few of the actions are appended; you can see the correspondence between “NewTag” (which is win.NewTag) and the callback self.cb_new_tag. When the appropriate menu item is triggered in the GUI, the callback is made to our code.

The GIO action stuff is not as well documented as I would have wanted, it took me a while to figure out how to use all this when I was replacing the Gtk.UIManager that we used to use see GEPS 044: Replace Deprecated Gtk.UIManager - Gramps.

1 Like

@prculley thanks for this quick reply.

I already spotted the add_actions() method which records tuples of (signal_name, callback). But I don’t see the connection method used to activate the signals. This should be in uimanager.py where identifier Gio.… is used.

The connect function is probably so obvious that I don’t see the nose on the face :wink:

I’ve queried the whole source tree for “connect” and it didn’t bring relevant results. I also queried for Gio and readonlygroup (as a particular case) to no avail either.

Where am I blind?

GIO is a bit different than Gtk. The add actions to the action_group, and add_action_group to the app perform the same function as a ‘connect’ in Gtk. They tell GIO to tie the action to whatever menu item or icon click etc. that is also tied to the action name in the xml.

OK, thanks. Meanwhile, I found what I was looking for: the list of callbacks (they are in __init_lists() (viewmanager.py). I needed to understand the structure of the list. And your explanation makes clear there is no explicit “connect”.

Continuing to read and stydy code.