[gnome-contacts] Initial work on TypeCombo widget
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-contacts] Initial work on TypeCombo widget
- Date: Wed, 22 Jun 2011 12:36:25 +0000 (UTC)
commit 2574080b1f994b29a5f00cb3a26121bd769387bf
Author: Alexander Larsson <alexl redhat com>
Date: Wed Jun 22 12:04:25 2011 +0200
Initial work on TypeCombo widget
src/contacts-contact-pane.vala | 12 ++-
src/contacts-types.vala | 163 ++++++++++++++++++++++++++++++++++++---
2 files changed, 158 insertions(+), 17 deletions(-)
---
diff --git a/src/contacts-contact-pane.vala b/src/contacts-contact-pane.vala
index 7bc56b3..c8f3db9 100644
--- a/src/contacts-contact-pane.vala
+++ b/src/contacts-contact-pane.vala
@@ -210,8 +210,10 @@ public class Contacts.ContactPane : EventBox {
var emails = email_details.email_addresses;
if (!emails.is_empty) {
foreach (var email in Contact.sort_fields (emails)) {
- var type = TypeSet.general.format_type (email);
- layout.add_label_detail (type, email.value);
+ var combo = new TypeCombo (TypeSet.general);
+ combo.set_active (email);
+ layout.add_widget_label (combo);
+ layout.add_detail (email.value);
}
}
}
@@ -235,8 +237,10 @@ public class Contacts.ContactPane : EventBox {
var phone_numbers = phone_details.phone_numbers;
if (!phone_numbers.is_empty) {
foreach (var p in Contact.sort_fields (phone_numbers)) {
- var type = TypeSet.phone.format_type (p);
- layout.add_label_detail (type, p.value);
+ var combo = new TypeCombo (TypeSet.phone);
+ combo.set_active (p);
+ layout.add_widget_label (combo);
+ layout.add_detail (p.value);
}
}
}
diff --git a/src/contacts-types.vala b/src/contacts-types.vala
index 673305f..f59bc07 100644
--- a/src/contacts-types.vala
+++ b/src/contacts-types.vala
@@ -22,33 +22,137 @@ using Gee;
using Folks;
public class Contacts.TypeCombo : Grid {
+ TypeSet type_set;
+ ComboBox combo;
+ Entry entry;
+ bool custom_mode;
+ public TypeCombo (TypeSet type_set) {
+ this.type_set = type_set;
+
+ combo = new ComboBox.with_model (type_set.store);
+ this.add (combo);
+
+ var renderer = new CellRendererText ();
+ combo.pack_start (renderer, true);
+ combo.set_attributes (renderer,
+ "text", 0);
+ combo.set_row_separator_func ( (model, iter) => {
+ string? s;
+ model.get (iter, 0, out s);
+ return s == null;
+ });
+
+ entry = new Entry ();
+ entry.width_chars = 10;
+
+ this.add (entry);
+
+ combo.set_no_show_all (true);
+ entry.set_no_show_all (true);
+
+ combo.show ();
+
+ combo.changed.connect (combo_changed);
+ entry.focus_out_event.connect (entry_focus_out_event);
+ entry.activate.connect (entry_activate);
+ }
+
+ private void finish_custom () {
+ if (!custom_mode)
+ return;
+
+ custom_mode = false;
+ var text = entry.get_text ();
+
+ TreeIter iter;
+ type_set.add_custom_label (text, out iter);
+
+ combo.set_active_iter (iter);
+
+ combo.show ();
+ entry.hide ();
+ }
+
+ private void entry_activate () {
+ finish_custom ();
+ }
+
+ private bool entry_focus_out_event (Gdk.EventFocus event) {
+ finish_custom ();
+ return false;
+ }
+
+ private void combo_changed (ComboBox combo) {
+ TreeIter iter;
+ if (combo.get_active_iter (out iter) &&
+ type_set.is_custom (iter)) {
+ custom_mode = true;
+ combo.hide ();
+ entry.show ();
+ entry.grab_focus ();
+ }
+ }
+
+ public void set_active (FieldDetails details) {
+ TreeIter iter;
+ type_set.lookup_detail (details, out iter);
+ combo.set_active_iter (iter);
+ }
}
public class Contacts.TypeSet : Object {
const int MAX_TYPES = 3;
+ private struct Data {
+ InitData *init_data;
+ TreeIter iter;
+ }
private struct InitData {
unowned string display_name;
unowned string types[3]; //MAX_TYPES
}
- private static HashTable<unowned string, GLib.List<InitData *> > hash;
+ static InitData custom_dummy;
+
+ private HashTable<unowned string, GLib.List<Data?> > hash;
+ private HashTable<unowned string, TreeIter?> custom_hash;
+ public ListStore store;
+ private TreeIter other_iter;
+ private TreeIter custom_iter;
private TypeSet () {
- hash = new HashTable<unowned string, GLib.List<InitData*> > (str_hash, str_equal);
+ hash = new HashTable<unowned string, GLib.List<Data?> > (str_hash, str_equal);
+ custom_hash = new HashTable<unowned string, TreeIter? > (str_hash, str_equal);
+ store = new ListStore (2, typeof(string?), typeof (InitData *));
}
- private void add_data (InitData *data) {
- unowned GLib.List<InitData *> l = hash.lookup (data.types[0]);
+ private void add_data (InitData *init_data) {
+ Data data = Data();
+ data.init_data = init_data;
+ store.append (out data.iter);
+ store.set (data.iter, 0, dgettext (Config.GETTEXT_PACKAGE, init_data.display_name), 1, data);
+
+ unowned GLib.List<Data?> l = hash.lookup (init_data.types[0]);
if (l != null) {
l.append (data);
} else {
- GLib.List<InitData *> l2 = null;
+ GLib.List<Data?> l2 = null;
l2.append (data);
- hash.insert (data.types[0], (owned) l2);
+ hash.insert (init_data.types[0], (owned) l2);
}
}
+ private void add_data_done () {
+ store.append (out other_iter);
+ store.set (other_iter, 0, _("Other"), 1, null);
+
+ TreeIter iter;
+ store.append (out iter);
+ store.set (iter, 0, null);
+ store.append (out custom_iter);
+ store.set (custom_iter, 0, _("Custom..."), 1, custom_dummy);
+ }
+
private static TypeSet _general;
private static TypeSet _phone;
@@ -65,6 +169,7 @@ public class Contacts.TypeSet : Object {
for (int i = 0; i < data.length; i++) {
_general.add_data (&data[i]);
}
+ _general.add_data_done ();
}
return _general;
@@ -103,6 +208,7 @@ public class Contacts.TypeSet : Object {
for (int i = 0; i < data.length; i++) {
_phone.add_data (&data[i]);
}
+ _phone.add_data_done ();
}
return _phone;
@@ -123,7 +229,7 @@ public class Contacts.TypeSet : Object {
return int.parse (s);
}
- public InitData *lookup_data (FieldDetails detail) {
+ private unowned Data? lookup_data (FieldDetails detail) {
var i = detail.get_parameter_values ("type");
if (i == null || i.is_empty)
return null;
@@ -142,11 +248,11 @@ public class Contacts.TypeSet : Object {
list.sort ();
- unowned GLib.List<InitData *>? l = hash.lookup (list[0]);
- foreach (var d in l) {
+ unowned GLib.List<Data?>? l = hash.lookup (list[0]);
+ foreach (unowned Data? d in l) {
bool all_found = true;
- for (int j = 0; j < MAX_TYPES && d.types[j] != null; j++) {
- if (!list.contains (d.types[j])) {
+ for (int j = 0; j < MAX_TYPES && d.init_data.types[j] != null; j++) {
+ if (!list.contains (d.init_data.types[j])) {
all_found = false;
break;
}
@@ -163,11 +269,42 @@ public class Contacts.TypeSet : Object {
return get_first_string (detail.parameters.get ("x-google-label"));
}
- var d = lookup_data (detail);
+ unowned Data? d = lookup_data (detail);
if (d != null) {
- return dgettext (Config.GETTEXT_PACKAGE, d.display_name);
+ return dgettext (Config.GETTEXT_PACKAGE, d.init_data.display_name);
}
return _("Other");
}
+
+ public void lookup_detail (FieldDetails detail, out TreeIter iter) {
+ if (detail.parameters.contains ("x-google-label")) {
+ var label = get_first_string (detail.parameters.get ("x-google-label"));
+ add_custom_label (label, out iter);
+ return;
+ }
+
+ unowned Data? d = lookup_data (detail);
+ if (d != null)
+ iter = d.iter;
+ else
+ iter = other_iter;
+ }
+
+ public bool is_custom (TreeIter iter) {
+ InitData *data;
+ store.get (iter, 1, out data);
+ return data == &custom_dummy;
+ }
+
+ public void add_custom_label (string label, out TreeIter iter) {
+ unowned TreeIter? iterp = custom_hash.lookup (label);
+ if (iterp != null) {
+ iter = iterp;
+ return;
+ }
+ store.insert_before (out iter, custom_iter);
+ store.set (iter, 0, label, 1, null);
+ custom_hash.insert (label, iter);
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]