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 567063 - Have a contact selector
Have a contact selector
Status: RESOLVED FIXED
Product: empathy
Classification: Core
Component: Contact List
unspecified
Other Linux
: Normal normal
: ---
Assigned To: empathy-maint
Depends on:
Blocks: 567065
 
 
Reported: 2009-01-08 19:03 UTC by Jonny Lamb
Modified: 2009-01-30 22:54 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Jonny Lamb 2009-01-08 19:03:01 UTC
Merge EmpathyContactSelector, as shown here:

http://people.collabora.co.uk/~elliot/contact-selector.png

It's in my "selector" branch of: git://git.collabora.co.uk/git/user/jonny/empathy.git
Comment 1 Cosimo Cecchi 2009-01-09 01:22:47 UTC
Hi Jonny, I read your branch, some comments:

- you should initialize all the GTK+ packing and signals inside empathy_contact_selector_init and drop the _constructor implementation.
- when you connect to the GtkComboBox signals, there's no need to cast the object with GTK_COMBO_BOX, just use g_signal_connect (foo, ...). Also, there's no need to cast the user_data to gpointer, and you can use EmpathyContactSelector * instead of GtkComboBox * in the callbacks prototypes to avoid a macro.
- as _dispose can be called multiple times from some bindings, you should have a dispose_run variable (usually inside priv) which is set to TRUE after the first dispose has run; you can have a look at EmpathyAccountManager for an example of this.
- in contact_selector_get_number_online_contacts (), and contact_selector_get_iter_for_blank_contact (), there's no need to go through a GtkTreePath to get the first iter, just use gtk_tree_model_get_iter_first ().
- in contact_selector_get_iter_for_blank_contact (), why do you go through all the list to see if there's a blank contact? Isn't it always saved in the first position if present? If I'm not overlooking something, you could have a boolean variable is_blank_present and just remove the first element if the variable is TRUE.
- when you need the private structure but not the EmpathyContactSelector itself, (e.g. in _set_property and _get_property), you can use GET_PRIV directly without casting the object to EmpathyContactSelector, as GET_PRIV already does the cast for you.
Comment 2 Jonny Lamb 2009-01-12 18:37:58 UTC
Cosimo, thanks for your review!

(In reply to comment #1)
> - you should initialize all the GTK+ packing and signals inside
> empathy_contact_selector_init and drop the _constructor implementation.

So, I'm a bit of a noob with GObjects, but surely the constructor is required as the store (priv->store) property isn't set in _init, whereas it is in _constructor. Feel free to tell me I'm wrong though.

> - when you connect to the GtkComboBox signals, there's no need to cast the
> object with GTK_COMBO_BOX, just use g_signal_connect (foo, ...). Also, there's
> no need to cast the user_data to gpointer, and you can use
> EmpathyContactSelector * instead of GtkComboBox * in the callbacks prototypes
> to avoid a macro.

Fixed.

> - as _dispose can be called multiple times from some bindings, you should have
> a dispose_run variable (usually inside priv) which is set to TRUE after the
> first dispose has run; you can have a look at EmpathyAccountManager for an
> example of this.

Done.

> - in contact_selector_get_number_online_contacts (), and
> contact_selector_get_iter_for_blank_contact (), there's no need to go through a
> GtkTreePath to get the first iter, just use gtk_tree_model_get_iter_first ().

Done.

> - in contact_selector_get_iter_for_blank_contact (), why do you go through all
> the list to see if there's a blank contact? Isn't it always saved in the first
> position if present? If I'm not overlooking something, you could have a boolean
> variable is_blank_present and just remove the first element if the variable is
> TRUE.

So, after a tiny bit of playing with this, it appears the store is ordered before you can just remove the first element, so as a result "Select a contact" remains present, but "Aaron Ardvark" gets removed..

> - when you need the private structure but not the EmpathyContactSelector
> itself, (e.g. in _set_property and _get_property), you can use GET_PRIV
> directly without casting the object to EmpathyContactSelector, as GET_PRIV
> already does the cast for you.

Done.
Comment 3 Jonny Lamb 2009-01-12 18:40:16 UTC
P.S. These changes are in my "selector" branch of 
git://git.collabora.co.uk/git/user/jonny/empathy.git
Comment 4 Jonny Lamb 2009-01-19 13:56:17 UTC
Cosimo has the latest branch:

http://git.collabora.co.uk/?p=user/cosimoc/empathy.git;a=shortlog;h=refs/heads/selector
Comment 5 Xavier Claessens 2009-01-19 15:24:06 UTC
Some comments:

 - empathy_contact_selector_get_selected() --> it returns a ref so it should be _dup_selected() and I'm sure there is places where the contact is leaked.

+  /* This is required otherwise the dispatcher isn't ref'd, and so it
+   * disappears by the time the callback gets called. It's deliberately not
+   * freed otherwise it segfaults... sigh */
+  empathy_dispatcher_dup_singleton ();
+  empathy_dispatcher_chat_with_contact (contact, chat_cb, NULL);
--> We should really fix that now instead of duplicating such hack everywhere and then forget to fix them. It is bad to leak empathy singletons in all processes.

 - empetit.c, destroy_cb() --> you can give gtk_main_quit directly as callback, no need for that function.

 - empathy_contact_selector_new() --> should return a GtkWidget* I think. GTK always return a GtkWidget* for constructors of widget subclasses. This should be fixed in other places in libempathy-gtk's API I guess...

 - instead of getting a EmpathyContactListStore as construct param and then change its properties, which the user could change later... I think we should get a EmpathyContactList iface as construct param and keep the store completely private. Especially since we add a blank contact in the store!

 - contact_selector_add_blank_contact: You can use gtk_tree_store_insert_with_values.

 - contact_selector_get_iter_for_blank_contact: tmp_contact is leaked. You can simplify a bit the code with a for loop:
for (ok = gtk_tree_model_get_iter_first(); ok; ok = gtk_tree_model_iter_next())

 - contact_selector_get_number_online_contacts: same as above.

 - contact_selector_manage_sensitivity: avoid calling function in var declaration. That FIXME should get fixed, no?

 - contact_selector_notify_popup_shown_cb, contact_selector_changed_cb and contact_selector_store_row_changed_cb --> they can be removed if you use g_signal_connect_swapped and give directly the function called from those cb as callback.

Otherwise it seems fine, thanks for the work!
Comment 6 Xavier Claessens 2009-01-19 15:30:24 UTC
Oh, forgot a little comment:

+  icon_path = g_build_path (G_DIR_SEPARATOR_S, PKGDATADIR, "icons", NULL);
+  gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), icon_path);
+  g_free (icon_path);

--> that can be replaced by empathy_gtk_init().
Comment 7 Jonny Lamb 2009-01-20 20:24:31 UTC
(In reply to comment #5)
>  - empathy_contact_selector_get_selected() --> it returns a ref so it should be
> _dup_selected() and I'm sure there is places where the contact is leaked.
> 
> +  /* This is required otherwise the dispatcher isn't ref'd, and so it
> +   * disappears by the time the callback gets called. It's deliberately not
> +   * freed otherwise it segfaults... sigh */
> +  empathy_dispatcher_dup_singleton ();
> +  empathy_dispatcher_chat_with_contact (contact, chat_cb, NULL);
> --> We should really fix that now instead of duplicating such hack everywhere
> and then forget to fix them. It is bad to leak empathy singletons in all
> processes.

Removed this comment and the ref. I fixed the ref problem in another branch that (at the time of writing) has not been merged. Therefore, the selector should obviously wait until that is fixed.

>  - empetit.c, destroy_cb() --> you can give gtk_main_quit directly as callback,
> no need for that function.

Done.

>  - empathy_contact_selector_new() --> should return a GtkWidget* I think. GTK
> always return a GtkWidget* for constructors of widget subclasses. This should
> be fixed in other places in libempathy-gtk's API I guess...

Done.

>  - instead of getting a EmpathyContactListStore as construct param and then
> change its properties, which the user could change later... I think we should
> get a EmpathyContactList iface as construct param and keep the store completely
> private. Especially since we add a blank contact in the store!

The store is now created in empathy_contact_selector_new. Is this okay or do you want the EmpathyContactList to be set as a GObject param?

>  - contact_selector_add_blank_contact: You can use
> gtk_tree_store_insert_with_values.

Done.

>  - contact_selector_get_iter_for_blank_contact: tmp_contact is leaked. You can
> simplify a bit the code with a for loop:
> for (ok = gtk_tree_model_get_iter_first(); ok; ok = gtk_tree_model_iter_next())
>  - contact_selector_get_number_online_contacts: same as above.

Cool, done.

>  - contact_selector_manage_sensitivity: avoid calling function in var
> declaration. That FIXME should get fixed, no?

Done.

>  - contact_selector_notify_popup_shown_cb, contact_selector_changed_cb and
> contact_selector_store_row_changed_cb --> they can be removed if you use
> g_signal_connect_swapped and give directly the function called from those cb as
> callback.

Done.

(In reply to comment #6)
> +  icon_path = g_build_path (G_DIR_SEPARATOR_S, PKGDATADIR, "icons", NULL);
> +  gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
> icon_path);
> +  g_free (icon_path);
> 
> --> that can be replaced by empathy_gtk_init().

Done.

My branch is at: http://git.collabora.co.uk/?p=user/jonny/empathy.git;a=shortlog;h=refs/heads/selector
Comment 8 Jonny Lamb 2009-01-30 22:54:43 UTC
Merged today.