GNOME Bugzilla – Bug 490678
GtkBuilder support
Last modified: 2009-02-17 06:38:43 UTC
Glade 3 should support the new GtkBuilder format. I'm going to attach a patch which adds very basic support for it.
Created attachment 97952 [details] [review] patch This is a work in progress. It saves the structure of the widgets in a format gtkbuilder understands. I made sure that responses for widgets in a GtkDialog are converted to a way which GtkBuilder understands. There are about 15 other conversions that needs to be done, not sure if it's correct to do it at an XML node level.
awesome that you looking into this :) I am currently on the road but let me take at least a half hour right now to explain some internals and how to make it simplest to make glade read/write to both formats. currently in glade we have a little bit hacked parser (as you can notice, its completely borrowed from libglade and molded a bit to work in glade), you have all the widget data represented in GladeWidgets and GladeProperties, then when we save, we let GladeWidget & GladeProperty fill in the GladeInterface structure and then use the code borrowed from libglade to write the glade file this is not a good long term solution because the GladeInterface structure makes alot of assumptions about how a glade file is formatted (i.e. it has properties, atk properties, signals etc all hardcoded into the structure), following this scheme would mean that we would continually have to extend the glade interface structure for new items such as a ui description used to build a GtkUIManager or any fields which are not properties per se (like the "widgets" of a GtkSizeGroup). I would like to eliminate the GladeInterface structure completely since I dont think we need to do the parse/save in 2 passes, code will get redundant and harder to follow. Now, we use the code in GladeWidgetAdapter (glade-widget-adaptor.c) to allow plugin backends to specify how to do all operations that need to be done for any said widget class (all the functions from plugins/gtk+/glade-gtk.c are assigned as methods to a dynamically created/derived widget adapter for each said class) The basic plan was to rip out the code in glade-widget.c & glade-property.c that loads/saves widgets/properties and put that code in the adaptor, the base gobject class adaptor would provide a generic way to load/save widgets & properties (the format of the current glade file could be determined at load time and saved on the GladeProject object, which the user could change in some project options) This way for example, the GladeWidgetAdapter created for GtkUIManager would have the code needed to load & save a ui description, any special case (or class specific) code would go in its proper adapter. abstractly, we would be using 4 new apis something like this: glade_widget_adapter_read_widget (adapter, widget, xmlnode) glade_widget_adapter_read_property (adapter, widget, xmlnode) glade_widget_adapter_write_widget (adapter, widget, xmlnode) glade_widget_adapter_write_property (adapter, widget, xmlnode) An implementation of glade_widget_adaptor_write_widget() would be responsible for calling glade_widget_adaptor_write_widget() for all the child objects of that object (in this way we'll also handle cases where some children need to be saved before other, the parenting class would be responsible for knowing the appropriate order). Again thankyou for taking an interest, please look into this plan a little and I'll be happy to hear any thoughts, feedback, suggestions etc.
I'm not currently working on this, and I do not plan to work on it in the near future.
I think I would like to have a look at it, Tristan. So, if I understood correctly, glade_widget_write, glade_widget_read, glade_widget_write_child and glade_widget_write_special_child_prop (from gladeui/glade-widget.c) and glade_property_write_impl, glade_property_write, glade_property_read and family functions (from gladeui/glade-property.c), would have to go away and new backends need to be written into new files (say, gladeui/glade-gtkbuilder.c for GtkBuilder?). These will extend the new (write|read)_(property|widget) abstract functions from GladeWidgetAdaptor. Anything else?
Very cool. So the new backends should not go into a new file, in fact, we will be getting rid of glade-parser.[ch] this way. The juice of the code will be going into glade_widget_adaptor.c, this will contain the base implementation of how to serialize/deserialize a widget. Any widget specific (i.e. potentially the UIManager object or sizegroup object) code will be going into derived adapter code in glade-gtk.c. (notably, atk properties are now considered specific domain of the GtkWidget object, this code will have to go into glade-gtk.c in the adaptor for GtkWidgetClass). Now, the code in glade-property-class.c that serializes/deserializes properties I think should stay in place. glade_property_read()/write() also should stay in place and be used from glade_widget_adaptor_read/write_property() in order to read and write properties from/to xml trees. Basically, GladeWidget, using its GladeWidgetAdaptor will recursively read or write all the subwidgets in its hierarchy, the implementations will be periodically using GladeProperty (and its GladePropertyClass backend in turn) to read or write properties of the said widgets along the way (the way GladeSignal is saved will have to be modified in a similar way, but that is the most trivial issue at hand). So I hope you are having an easy time navigating the source base, if you have any questions we'll be around :D Note about the future of glade that might be good to keep in mind: Sooner or later I am planning on splitting up GladePropertyClass into separate files based on pspecs, instead of a huge switch case saying how to serialize/deserialize properties, it will written in OO style like GladeWidgetAdaptor is: one subclass or GladePropertyAdaptor for each possible kind of property (these classes will also take on the role of deciding how properties are edited in the glade editor, and will be subclassable from plugin backends).
Created attachment 108462 [details] [review] megapatch against trunk Ok guys heres the deal. Ive been working on this for the past 2 nights (its a nocturnal thing), I managed to add 3 new adaptor entry points: - adaptor->read_widget() - adaptor->create_eprop() - adaptor->
Created attachment 108464 [details] [review] megapatch against trunk Ok guys heres the deal. Ive been working on this for the past 2 nights (its a nocturnal thing), I managed to add 3 new adaptor entry points: - adaptor->read_widget() Takes a widget and an xml node for that widget and updates it - adaptor->create_eprop() Returns a customized editing widget derived from GladeEditorProperty for GParamSpecs introduced by the plugin - adaptor->string_from_value() Convenience detail really, incase you have custom pspecs and want to put a string representation in the undo/redo menu. The point ofcourse is, to allow widget-class level definitions of the xml layout. Currently I moved all the Accelerator property handling into the plugin, that includes loading from the file and editing support. Same thing for Atk properties, only they use built in editing support. The old hacked out parser is completely removed. Currently this revision of glade loads files and edits, seemingly fine - Im sure there are still a few regressions wrt special children like notebook tabs and frame labels, probably more I dont know about. It doesnt save files yet, thats next. After Im done with dynamic widget-class level xml layout descriptions (i.e. allowing you to put special case code for size-group "widgets" property etc), and all is loading and saving well - then we move on to supporting both formats. By the way, this work is available also in branches/builder, you can follow my progress there. Please comment on the patch if you have something to say, all input is greatly appriciated ;-)
Created attachment 108567 [details] [review] megapatch against head... take 2 This patch against trunk (taken from trunk vs branches/builder) completes load & save functionalities with the new model. since the last patch I made, ofcourse many many changes, but added the adaptor->write_widget() and allow the plugin to save data in custom ways. Atk properties and accelerator properties are all loaded and saved by the backend now - This patch is about to hit trunk so we can start dealing with any regressions it caused, but frankly, there is so much less code, and it seems to inadvertently have fixed a crasher when loading message dialogs too.
By the way guys, branches/builder is closed now and the parser rewrite is in trunk, we'll continue to track builder related work in this bug though.
Ok for the record I changed the nature of the parser a bit. Now the parser code is recursive in the plugin, so when you implement read_widget() for example, you can do stuff before and after the normal properties and children are read in: my_read_widget() { /* Read stuff before building children */ /* build widget and set properties and build children */ parent_class->read_widget (); /* Read stuff after building children */ } I also added a read_child() and write_child() entrypoint in the adaptor, this will allow for custom handling of packing properties which I dont expect to be needed, but mostly to allow you to ignore some things, like the faked out AtkObject that builder uses to save atk properties.
I misworded that, the widget is infact already contructed by the time read_widget() is called.
Created attachment 108696 [details] First builder file saved by glade3 Ok, now we have the basics of builder load/save, no fancy uimanager objects or anything like that, but we have support for tag differences, and also special child types such as notebook tabs and frame labels. This attached builder file can be loaded and saved in both formats without errors... moving on to accelerators and atk properties... (are accelerators even supported yet in gtk builder ?...)
Ok, it was another long and stormy night of hacking... I implemented dual formats for atk properties, verified that accelerators are still saved the same way. Currently with this recursive model, glade_gtk_widget_write_widget() is calling the parent first, which writes out properties and children, then it goes on to write accelerators, a11y props and in builder format there is a trailing child object for the atk props - ideally we should probably have something at the glade-xml-utils level to sort things out after writing if we want a specific format. Note that glade is quite indifferent to the order in which these tag are loaded when parsing, not sure the order should be of any relevance anyway. That said, currently in trunk we have a "format" menu item in the "edit" menu that allows you to chose your format, formats are introspected at load time. Currently glade still does not support any fancy GObjects or weird exceptions like uimanager, and when saving glade files in builder format, glade is unaware about depricated widgets which may not be supported by the builder... aside from that, builder support in glade seems to be here.
Hi Tristan, First Great work!!! Second, I just built glade-3 from SVN but I don't see an option to load or save gtkbuilder files. It seems to only accept glade files in the GUI. If I give the builder file as a command line argument glade-3 loads it but I can't save it is another file (i.e. the Save button in the Save As dialog doesn't seem to do anything) Thanks Jaap
Just read your blog. The option to choose the format of your project is in the edit menu. I think the most common place where you would expect this option is in the save dialogs. At the moment even in Builder mode in the Save dialog you see the type set to Glade.
Yes the UI is definitly not final lol, I was thinking of having it in a project preferences dialog at first but your suggestion is very good. Note also we'll probably want to adjust that dialog to also see files with the ".ui" extention and probably automatically suggest that suggestion, to avoid overwriting files youve recently converted.
(In reply to comment #16) > > Note also we'll probably want to adjust that dialog to also > see files with the ".ui" extention and probably automatically > suggest that suggestion, to avoid overwriting files youve > recently converted. > +1 from me
Committed a better UI in trunk. No more edit menu option, now simply, when hitting "save as..." you can chose the output format as a dialog option (could use some work wrt default file name) Next plan is to add data about what widgets/propeties/signals are supported in which catalog, and run a GladeProject routine to see if the current project is savable without loss, if there is any loss then clicling on "Save" from the "Save as" dialog will lead to another dialog displaying what losses there will be, and asking if you are sure you want to continue with the save... comments on this UI plan ?
(In reply to comment #18) > > comments on this UI plan ? > Sound like a good plan to me
Added full versioning support in trunk, see ChangeLog for details. Now have the said dialog on "save as...", and a new projects preferences dialog in "Edit" menu.
Tristan, Can this bug now be closed or is GtkBuilder still not fully supported in your opinion
Strictly speaking I think as soon as we can get normal toolbars and menus working, we can consider our conversions functional and close this bug - then go on to integrate UIManager's sizegroups and friends after, as separate excersizes yes.
Tristan, I've noticed that glade3 development is pretty active again, are the remaining issues for GtkBuilder fixed by now or being worked on?
I am missing only uimanager integration, I may be missing something but other than that I think we are feature complete for builder (I am right now working on getting treeview editing to "be nice").
Any timeframe for this (is 3.6.0 realistic, or sth like 2.26.2, or 2.27.1?), because basically http://live.gnome.org/GnomeGoals/RemoveLibGladeUseGtkBuilder depends on this?
Yeah sure, whatever remains to be done in Glade is minor enhancements and some bug fixes - we can close this bug now. Regarding my previous comment, I dont know if Glade will ever have or really need uimanager support.