After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 619656 - CellRendererText property changes are not reflected in ComboBoxText
CellRendererText property changes are not reflected in ComboBoxText
Status: RESOLVED FIXED
Product: gtkmm
Classification: Bindings
Component: TreeView
2.4
Other Linux
: Normal normal
: ---
Assigned To: gtkmm-forge
gtkmm-forge
Depends on:
Blocks:
 
 
Reported: 2010-05-25 19:34 UTC by JimO
Modified: 2011-02-08 08:45 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Modification of the test case in comment 2 (3.11 KB, text/plain)
2010-10-29 17:23 UTC, Kjell Ahlstedt
Details

Description JimO 2010-05-25 19:34:22 UTC
I have a class derived from ComboBoxText in which I load the available font families. I want to display each font family entry in its corresponding font family by using a CellRendererText and setting the property_family(), but the entries are all displayed in the default font. In order to test, I also set property_style and property_size_points. The entries are all displayed in the default font family, style and size; however, changing the property_size_points changes the spacing between each entry.

Tested only on openSuSE 11.2.

Here is my class:

#include <set>
#include <iostream>
#include <gtkmm.h>

typedef std::set<Glib::ustring> FontSet;

class FontSelector : public Gtk::ComboBoxText {
public:
	FontSelector() {
	 	// add columns to model
		col_records.add(col1);
		refStore = Gtk::ListStore::create(col_records);
		set_model(refStore);
		
		// add the font family names to the combobox
		Glib::RefPtr<Pango::Context> pc = this->get_pango_context();
		if(pc) {
			FontSet fonts;
			Glib::ArrayHandle<Glib::RefPtr<Pango::FontFamily> > families = pc->list_families();
			for(Glib::ArrayHandle<Glib::RefPtr<Pango::FontFamily> >::iterator it = families.begin(); it < families.end(); it++) {
				fonts.insert((*it)->get_name());
			}
			for(FontSet::iterator it = fonts.begin(); it != fonts.end(); it++) {
				addrow(*it);
			}
		}
		
		// show font family text in the font family
		pack_start(renderer, true);
		add_attribute(renderer, "family", 0);
		sigc::slot<void, const Gtk::TreeIter> s = sigc::mem_fun(*this, &FontSelector::set_family);
		set_cell_data_func(renderer, s);

	}
			
private:
	Gtk::TreeModelColumnRecord col_records;
	Glib::RefPtr<Gtk::ListStore> refStore;
	Gtk::TreeModelColumn<Glib::ustring> col1;
	Gtk::CellRendererText renderer;
	
	void addrow(Glib::ustring family) {
		Gtk::ListStore::iterator it = refStore->append();
		Gtk::ListStore::Row row = *it;
		row[col1] = family;
	}

	void set_family(const Gtk::TreeIter iter) {
			Gtk::TreeModel::Row row = *iter;
			Glib::ustring family = row[col1];
			renderer.property_family() = family;
			renderer.property_style() = Pango::STYLE_ITALIC;
			renderer.property_size_points() = 20;
	}
	
};
Comment 1 Murray Cumming 2010-05-25 20:28:19 UTC
Could you please try to create a full example that can be compiled, and please try to simplify it even more.
Comment 2 JimO 2010-05-26 15:53:54 UTC
(In reply to comment #1)
> Could you please try to create a full example that can be compiled, and please
> try to simplify it even more.

The following is the simplest that I can come up with that illustrates the problem and matches my comments. I could not find a way to simplify without actually resulting in a longer example.

#include <set>
#include <gtkmm.h>
#include <iostream>

using namespace std;

typedef std::set<Glib::ustring> FontSet;

class FontSelector : public Gtk::ComboBoxText {
public:
	FontSelector() {
	 	// add colummns to model
		col_records.add(col1);
		refStore = Gtk::ListStore::create(col_records);
		set_model(refStore);
		
		// add the font family names to the combobox
		Glib::RefPtr<Pango::Context> pc = this->get_pango_context();
		if(pc) {
			FontSet fonts;
			Glib::ArrayHandle<Glib::RefPtr<Pango::FontFamily> > families = pc->list_families();
			for(Glib::ArrayHandle<Glib::RefPtr<Pango::FontFamily> >::iterator it = families.begin(); it < families.end(); it++) {
				fonts.insert((*it)->get_name());
			}
			for(FontSet::iterator it = fonts.begin(); it != fonts.end(); it++) {
				addrow(*it);
			}
		}

		// show font family text in the font family
		pack_start(renderer, true);
		add_attribute(renderer, "family", 0);
		sigc::slot<void, const Gtk::TreeIter> s = sigc::mem_fun(*this, &FontSelector::set_family);
		set_cell_data_func(renderer, s);

	}
			
private:
	Gtk::TreeModelColumnRecord col_records;
	Glib::RefPtr<Gtk::ListStore> refStore;
	Gtk::TreeModelColumn<Glib::ustring> col1;
	Gtk::CellRendererText renderer;
	
	// add the font family into the combobox
	void addrow(Glib::ustring family) {
		Gtk::ListStore::iterator it = refStore->append();
		Gtk::ListStore::Row row = *it;
		row[col1] = family;
	}
	
	// set font properties for display of combobox items
	void set_family(const Gtk::TreeIter iter) {
		Gtk::TreeModel::Row row = *iter;
		Glib::ustring family = row[col1];
		renderer.property_family() = family;
		renderer.property_style() = Pango::STYLE_ITALIC;
		renderer.property_size_points() = 20;
	} 
	
};

int main(int argc, char** argv) {
	Gtk::Main kit(argc, argv);
	Gtk::Window window;
	FontSelector fs;
	window.add(fs);
	fs.show();
	Gtk::Main::run(window);
}
Comment 3 Kjell Ahlstedt 2010-10-29 17:23:50 UTC
Created attachment 173512 [details]
Modification of the test case in comment 2

My conclusions after some experiments with the source code in comment 2:

1. The cell renderer added to FontSelector with
      pack_start(renderer, true);
   is not used for showing the text in TreeModelColumn col1.
   Instead a second column is added to the ComboBoxText. This column contains
   only empty strings, and is therefore not seen, but it affects the
   line height. This becomes obvious if in set_family() you add
      renderer.property_text() = family;

2. Gtk::CellLayout::get_cells() gets all cell renderers. Before the call to
   pack_start(), there is only one renderer, and that's the one you shall use
   in add_attribute(). (Gtk::CellLayout is a base class of Gtk::ComboBox.)

See the attached slightly modified test case.
Tested on Ubuntu 10.10 with gtkmm version 2.20.3 and gtk+ 2.22.0.

I suppose that this behavior is by design, but it's not at all obvious.
E.g. it took quite a while before I realized that Gtk::CellLayout::get_cells()
is very useful here.
Comment 4 Murray Cumming 2010-11-17 13:10:14 UTC
Yeah, well, ComboBoxText is a convenience that's meant to do just one text column, and you should use ComboBox to do more complex things. ComboBoxText in gtkmm 3 is now a wrapper of a C class, but the same behaviour is probably still there.

I'd even be careful of using set_attribute() on a cell that was automatically added by the class itself. But admittedly I do a similar trick in Glom for ComboBoxEntryText (now ComboBoxText with has_entry=true).

I guess this just need a warning in the documentation.
Comment 5 Kjell Ahlstedt 2010-12-14 16:03:36 UTC
I can confirm that the behaviour is the same in gtkmm 3.

Something like this could be added to the description of ComboBoxText:

   Use this class only for a combo box which contains a single column of text
   with default properties. If you want to specify your own text properties,
   use a ComboBox, which lets you decide which cell renderer to use.

Some unrelated comments on the descriptions of ComboBox and ComboBoxText in
gtkmm 3:

   ComboBox: Mentions OptionMenu, which has been deprecated for some time, and
seems to be removed from gtkmm 3.

   ComboBoxText: In the class description methods are called append_text(),
insert_text(), and prepend_text(). In the code they are called append(),
insert(), and prepend().
There's a constructor with a 'model' parameter. When that constructor is used,
the model-view complexity is not hidden, is it? The function mentioned in
  _IGNORE(gtk_combo_box_text_new_with_model)
does not exist.
Comment 6 Murray Cumming 2011-01-14 23:03:22 UTC
(In reply to comment #5)
>    ComboBox: Mentions OptionMenu, which has been deprecated for some time, and
> seems to be removed from gtkmm 3.

Thanks. Fixed by this commit:
http://git.gnome.org/browse/gtkmm/commit/?id=d5674d69dc3770483760a55abe7d36d90ae9e270
(The commit message mentions ComboBoxText instead of ComboBox, but that is just a typo.)

>    ComboBoxText: In the class description methods are called append_text(),
> insert_text(), and prepend_text(). In the code they are called append(),
> insert(), and prepend().

Yes, also reported in bug #638405, now fixed:
Comment 7 Murray Cumming 2011-01-14 23:06:45 UTC
(In reply to comment #5)
> There's a constructor with a 'model' parameter. When that constructor is used,
> the model-view complexity is not hidden, is it? The function mentioned in
>   _IGNORE(gtk_combo_box_text_new_with_model)
> does not exist.

Thanks. It must be a copy/paste error. Fixed:
http://git.gnome.org/browse/gtkmm/commit/?id=fc66116ebddb7bbe4a45cfea1663859fc4be3cb3
Comment 8 Murray Cumming 2011-01-14 23:10:25 UTC
(In reply to comment #5)
> I can confirm that the behaviour is the same in gtkmm 3.
> 
> Something like this could be added to the description of ComboBoxText:
> 
>    Use this class only for a combo box which contains a single column of text
>    with default properties. If you want to specify your own text properties,
>    use a ComboBox, which lets you decide which cell renderer to use.

Can we be more specific. For instance, by adding this too.
"Do not attempt to call set_model() on a ComboBoxText, or to pack more cells into it via its CellLayout base class.".

I would add this to the C documentation too:
http://library.gnome.org/devel/gtk/unstable/GtkComboBoxText.html#GtkComboBoxText.description
Comment 9 Kjell Ahlstedt 2011-01-16 18:19:21 UTC
(In reply to comment #8)
> (In reply to comment #5)
> > Something like this could be added to the description of ComboBoxText:
> > 
> >    Use this class only for a combo box which contains a single column of text
> >    with default properties. If you want to specify your own text properties,
> >    use a ComboBox, which lets you decide which cell renderer to use.
> 
> Can we be more specific. For instance, by adding this too.
> "Do not attempt to call set_model() on a ComboBoxText, or to pack more cells
> into it via its CellLayout base class.".

Yes, that's fine. On second thought I also think that "properties" in my text
should be replaced by "attributes". The method that has caused much of the
confusion is CellLayout::add_attribute().
Comment 10 Murray Cumming 2011-02-08 08:33:20 UTC
(In reply to comment #9)
The method that has caused much of the
> confusion is CellLayout::add_attribute().

If you don't call set_model() then you'd have no reason to call add_attribute(), so that seems superfluous, just making the warning more complicated.
Comment 11 Murray Cumming 2011-02-08 08:45:36 UTC
This is the additional warning in gtkmm-2.24:
http://git.gnome.org/browse/gtkmm/commit/?h=gtkmm-2-24&id=4baa3dc789e61f3247ad2739d84aa44f85909f84

and in gtkmm 3:
http://git.gnome.org/browse/gtkmm/commit/?id=11decc65f8a57d265709da89147951dc7aea3551

So I think I can close this bug now. If you think any other warning is necessary, a patch would be welcome. Thanks.