aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2007-11-29 04:54:19 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2007-11-29 04:54:19 +0800
commit4bca50f1c5060efbfe2f0c9d011e4d51f1e8be0f (patch)
tree670e42776b90bc2b22ab060828d944b8b1c6af6d
parentcfbb09abfdba072800304ab46146323b3b2ff785 (diff)
downloadgsoc2013-evolution-4bca50f1c5060efbfe2f0c9d011e4d51f1e8be0f.tar.gz
gsoc2013-evolution-4bca50f1c5060efbfe2f0c9d011e4d51f1e8be0f.tar.zst
gsoc2013-evolution-4bca50f1c5060efbfe2f0c9d011e4d51f1e8be0f.zip
** Fixes bug #489652
2007-11-28 Matthew Barnes <mbarnes@redhat.com> ** Fixes bug #489652 Migrate the contact list editor from ETable to GtkTreeView and fix some HIG issues. * addressbook/gui/contact-list-editor/Makefile.am: Remove e-contact-list-editor.etspec Remove e-contact-list-editor-marshal.list * addressbook/gui/contact-list-editor/contact-list-editor.glade: Fix some HIG issues and give all the widgets proper names. * addressbook/gui/contact-list-editor/e-contact-list-model.c: * addressbook/gui/contact-list-editor/e-contact-list-model.h: EContactListModel is now a subclass of GtkListStore. * addressbook/gui/contact-list-editor/e-contact-list.c: * addressbook/gui/contact-list-editor/e-contact-list.h: Use a GtkTreeView instead of an ETable for displaying members. Refactor everything; see bug #489652 for more details. svn path=/trunk/; revision=34610
-rw-r--r--addressbook/ChangeLog23
-rw-r--r--addressbook/gui/contact-list-editor/Makefile.am9
-rw-r--r--addressbook/gui/contact-list-editor/contact-list-editor.glade769
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor-marshal.list2
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.c2063
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.etspec7
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.h110
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-model.c307
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-model.h68
9 files changed, 1720 insertions, 1638 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index 9badf8e50d..b94ff7c4e2 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,3 +1,26 @@
+2007-11-28 Matthew Barnes <mbarnes@redhat.com>
+
+ ** Fixes bug #489652
+
+ Migrate the contact list editor from ETable to GtkTreeView and
+ fix some HIG issues.
+
+ * gui/contact-list-editor/Makefile.am:
+ Remove e-contact-list-editor.etspec
+ Remove e-contact-list-editor-marshal.list
+
+ * gui/contact-list-editor/contact-list-editor.glade:
+ Fix some HIG issues and give all the widgets proper names.
+
+ * gui/contact-list-editor/e-contact-list-model.c:
+ * gui/contact-list-editor/e-contact-list-model.h:
+ EContactListModel is now a subclass of GtkListStore.
+
+ * gui/contact-list-editor/e-contact-list.c:
+ * gui/contact-list-editor/e-contact-list.h:
+ Use a GtkTreeView instead of an ETable for displaying members.
+ Refactor everything; see bug #489652 for more details.
+
2007-11-23 Milan Crha <mcrha@redhat.com>
** Fix for bug #495711
diff --git a/addressbook/gui/contact-list-editor/Makefile.am b/addressbook/gui/contact-list-editor/Makefile.am
index 71516c33bb..76122c2421 100644
--- a/addressbook/gui/contact-list-editor/Makefile.am
+++ b/addressbook/gui/contact-list-editor/Makefile.am
@@ -10,7 +10,6 @@ INCLUDES = \
-I$(top_srcdir)/addressbook/gui/contact-editor \
-I$(top_builddir)/shell \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
- -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
-DG_LOG_DOMAIN=\"contact-list-editor\" \
$(EVOLUTION_ADDRESSBOOK_CFLAGS)
@@ -35,15 +34,9 @@ libecontactlisteditor_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
$(EVOLUTION_ADDRESSBOOK_LIBS)
-MARSHAL_GENERATED = e-contact-list-editor-marshal.c e-contact-list-editor-marshal.h
-@EVO_MARSHAL_RULE@
-
glade_DATA = contact-list-editor.glade
-etspec_DATA = e-contact-list-editor.etspec
BUILT_SOURCES = $(MARSHAL_GENERATED)
CLEANFILES = $(BUILT_SOURCES)
-EXTRA_DIST = $(glade_DATA) \
- $(etspec_DATA) \
- e-contact-list-editor-marshal.list
+EXTRA_DIST = $(glade_DATA)
diff --git a/addressbook/gui/contact-list-editor/contact-list-editor.glade b/addressbook/gui/contact-list-editor/contact-list-editor.glade
index 64280c2c52..3402e27542 100644
--- a/addressbook/gui/contact-list-editor/contact-list-editor.glade
+++ b/addressbook/gui/contact-list-editor/contact-list-editor.glade
@@ -1,432 +1,341 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
<glade-interface>
-
-<widget class="GtkDialog" id="contact list editor">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Contact List Editor</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="has_separator">True</property>
-
- <child internal-child="vbox">
- <widget class="GtkVBox" id="dialog-vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child internal-child="action_area">
- <widget class="GtkHButtonBox" id="dialog-action_area1">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_END</property>
-
- <child>
- <widget class="GtkButton" id="cancel-button">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-cancel</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="response_id">-6</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="ok-button">
- <property name="visible">True</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-ok</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="response_id">-5</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox8">
- <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkHBox" id="hbox6">
- <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkTable" id="table1">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">6</property>
- <property name="column_spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label10">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_List name:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">list-name-entry</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="list-name-entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="has_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="source-label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Where:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="source-combo-box-source">
- <property name="visible">True</property>
- <property name="creation_function">e_contact_list_editor_create_source_combo_box</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Tue, 01 Jun 2004 18:22:38 GMT</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="list-image">
- <property name="visible">True</property>
- <property name="creation_function">eab_create_image_chooser_widget</property>
- <property name="string1">stock_addressbook</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Sat, 23 Jun 2001 05:59:21 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFrame" id="frame3">
- <property name="border_width">3</property>
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkHBox" id="hbox7">
- <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkVBox" id="vbox9">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkLabel" id="label11">
- <property name="visible">True</property>
- <property name="label" translatable="yes">_Type an email address or drag a contact into the list below:</property>
- <property name="use_underline">True</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="mnemonic_widget">email-entry</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="email-entry">
- <property name="visible">True</property>
- <property name="creation_function">e_contact_list_editor_create_name_selector</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Sat, 27 Aug 2005 13:47:20 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="Custom" id="contact-list-table">
- <property name="visible">True</property>
- <property name="creation_function">e_contact_list_editor_create_table</property>
- <property name="int1">0</property>
- <property name="int2">0</property>
- <property name="last_modification_time">Sat, 23 Jun 2001 06:00:16 GMT</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkCheckButton" id="visible-addrs-checkbutton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Hide addresses when sending mail to this list</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox10">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label12">
- <property name="visible">True</property>
- <property name="label" translatable="yes">
-</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVButtonBox" id="vbuttonbox4">
- <property name="visible">True</property>
- <property name="layout_style">GTK_BUTTONBOX_START</property>
- <property name="spacing">6</property>
-
- <child>
- <widget class="GtkButton" id="add-email-button">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Add an email to the List</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-add</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="remove-button">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Remove an email address from the List</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label">gtk-remove</property>
- <property name="use_stock">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="select-button">
- <property name="visible">True</property>
- <property name="tooltip" translatable="yes">Insert email addresses from Address Book</property>
- <property name="can_default">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Select</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- </widget>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label11">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Members</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
+ <widget class="GtkDialog" id="dialog">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes" context="yes">Contact List Editor</property>
+ <property name="window_position">GTK_WIN_POS_CENTER</property>
+ <property name="icon_name">stock_contact-list</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <property name="has_separator">False</property>
+ <signal name="delete_event" handler="contact_list_editor_delete_event_cb"/>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkTable" id="table">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">6</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <widget class="GtkImage" id="image">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="icon_size">6</property>
+ <property name="icon_name">stock_addressbook</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options"></property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="source-table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="list-name-label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes" context="yes">_List name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">list-name-entry</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="source-label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes" context="yes">_Where:</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="list-name-entry">
+ <property name="visible">True</property>
+ <property name="invisible_char">*</property>
+ <signal name="changed" handler="contact_list_editor_list_name_entry_changed_cb"/>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="source-combo-box">
+ <property name="creation_function">contact_list_editor_create_source_combo_box</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="members-vbox">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="members-label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes">&lt;b&gt;Members&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="members-alignment">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkTable" id="members-table">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="members-instructions">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="yes">_Type an email address or drag a contact into the list below:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ </widget>
+ <packing>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="Custom" id="email-entry">
+ <property name="creation_function">contact_list_editor_create_name_selector</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolled-window">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+ <child>
+ <widget class="GtkTreeView" id="tree-view">
+ <property name="visible">True</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <signal name="drag_motion" handler="contact_list_editor_drag_motion_cb"/>
+ <signal name="key_press_event" handler="contact_list_editor_tree_view_key_press_event_cb"/>
+ <signal name="drag_data_received" handler="contact_list_editor_drag_data_received_cb"/>
+ <signal name="drag_drop" handler="contact_list_editor_drag_drop_cb"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="check-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="label" translatable="yes" context="yes">_Hide addresses when sending mail to this list</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <signal name="toggled" handler="contact_list_editor_check_button_toggled_cb"/>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="members-buttons">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkButton" id="add-button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup">Add an email to the List</property>
+ <property name="tooltip_text">Add an email to the List</property>
+ <property name="label" context="yes">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="xalign">0</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="contact_list_editor_add_button_clicked_cb"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="remove-button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup">Remove an email address from the List</property>
+ <property name="tooltip_text">Remove an email address from the List</property>
+ <property name="label" context="yes">gtk-remove</property>
+ <property name="use_stock">True</property>
+ <property name="xalign">0</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="contact_list_editor_remove_button_clicked_cb"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="select-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_markup">Insert email addresses from Address Book</property>
+ <property name="tooltip_text">Insert email addresses from Address Book</property>
+ <property name="label" translatable="yes" context="yes">Select...</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="contact_list_editor_select_button_clicked_cb"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="members-buttons-alignment">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action-area">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="cancel-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label" context="yes">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="contact_list_editor_cancel_button_clicked_cb"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="ok-button">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="label" context="yes">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ <signal name="clicked" handler="contact_list_editor_ok_button_clicked_cb"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
</glade-interface>
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor-marshal.list b/addressbook/gui/contact-list-editor/e-contact-list-editor-marshal.list
deleted file mode 100644
index 32b8e41ecb..0000000000
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor-marshal.list
+++ /dev/null
@@ -1,2 +0,0 @@
-INT:OBJECT
-NONE:INT,OBJECT
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.c b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
index 85a7b507d5..a40be485da 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
@@ -21,27 +21,19 @@
#include <config.h>
#include "e-contact-list-editor.h"
-#include <e-util/e-icon-factory.h>
#include <e-util/e-util-private.h>
#include <e-util/e-error.h>
#include <string.h>
+#include <gtk/gtk.h>
#include <glib/gi18n.h>
-#include <libgnomeui/gnome-window-icon.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtktogglebutton.h>
-#include <gtk/gtkdialog.h>
+#include <gdk/gdkkeysyms.h>
#include <libedataserverui/e-source-combo-box.h>
-#include <table/e-table-scrolled.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
-
#include "shell/evolution-shell-component-utils.h"
-#include "misc/e-image-chooser.h"
-
#include "addressbook/gui/component/addressbook.h"
#include "addressbook/gui/widgets/eab-gui-util.h"
#include "addressbook/util/eab-book-util.h"
@@ -49,66 +41,43 @@
#include "eab-editor.h"
#include "e-contact-editor.h"
#include "e-contact-list-model.h"
-#include "e-contact-list-editor-marshal.h"
#include "eab-contact-merging.h"
-#include <gdk/gdkkeysyms.h>
-
-static void e_contact_list_editor_init (EContactListEditor *editor);
-static void e_contact_list_editor_class_init (EContactListEditorClass *klass);
-static void e_contact_list_editor_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void e_contact_list_editor_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
-static void e_contact_list_editor_dispose (GObject *object);
-
-static void e_contact_list_editor_show (EABEditor *editor);
-static void e_contact_list_editor_raise (EABEditor *editor);
-static void e_contact_list_editor_close (EABEditor *editor);
-static void e_contact_list_editor_save_contact (EABEditor *editor, gboolean should_close);
-static gboolean e_contact_list_editor_is_valid (EABEditor *editor);
-static gboolean e_contact_list_editor_is_changed (EABEditor *editor);
-static GtkWindow* e_contact_list_editor_get_window (EABEditor *editor);
-
-static void set_editable (EContactListEditor *editor);
-static void command_state_changed (EContactListEditor *editor);
-static void extract_info(EContactListEditor *editor);
-static void fill_in_info(EContactListEditor *editor);
-
-static void add_email_cb (GtkWidget *w, EContactListEditor *editor);
-static void remove_entry_cb (GtkWidget *w, EContactListEditor *editor);
-static void select_cb (GtkWidget *w, EContactListEditor *editor);
-static void list_name_changed_cb (GtkWidget *w, EContactListEditor *editor);
-static void list_image_changed_cb (GtkWidget *w, EContactListEditor *editor);
-static void visible_addrs_toggled_cb (GtkWidget *w, EContactListEditor *editor);
-static void source_changed_cb (ESourceComboBox *source_combo_box, EContactListEditor *editor);
-static gboolean email_key_pressed (GtkWidget *w, GdkEventKey *event, EContactListEditor *editor);
-static void email_match_selected (GtkWidget *w, EDestination *destination, EContactListEditor *editor);
-
-static void close_cb (GtkWidget *widget, EContactListEditor *editor);
-static void save_and_close_cb (GtkWidget *widget, EContactListEditor *editor);
-
-static gint app_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data);
-static gboolean table_drag_drop_cb (ETable *table, int row, int col, GdkDragContext *context,
- gint x, gint y, guint time, EContactListEditor *editor);
-static gboolean table_drag_motion_cb (ETable *table, int row, int col, GdkDragContext *context,
- gint x, gint y, guint time, EContactListEditor *editor);
-static void table_drag_data_received_cb (ETable *table, int row, int col,
- GdkDragContext *context,
- gint x, gint y,
- GtkSelectionData *selection_data, guint info, guint time,
- EContactListEditor *editor);
-
-static EABEditorClass *parent_class = NULL;
-
-enum DndTargetType {
- DND_TARGET_TYPE_VCARD,
-};
-#define VCARD_TYPE "text/x-vcard"
-static GtkTargetEntry list_drag_types[] = {
- { VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD },
-};
-static const int num_list_drag_types = sizeof (list_drag_types) / sizeof (list_drag_types[0]);
+#define E_CONTACT_LIST_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditorPrivate))
+
+#define CONTACT_LIST_EDITOR_WIDGET(editor, name) \
+ (glade_xml_get_widget \
+ (E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor)->xml, name))
+
+/* More macros, less typos. */
+#define CONTACT_LIST_EDITOR_WIDGET_ADD_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "add-button")
+#define CONTACT_LIST_EDITOR_WIDGET_CHECK_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "check-button")
+#define CONTACT_LIST_EDITOR_WIDGET_DIALOG(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "dialog")
+#define CONTACT_LIST_EDITOR_WIDGET_EMAIL_ENTRY(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "email-entry")
+#define CONTACT_LIST_EDITOR_WIDGET_LIST_NAME_ENTRY(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "list-name-entry")
+#define CONTACT_LIST_EDITOR_WIDGET_MEMBERS_VBOX(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "members-vbox")
+#define CONTACT_LIST_EDITOR_WIDGET_OK_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "ok-button")
+#define CONTACT_LIST_EDITOR_WIDGET_REMOVE_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "remove-button")
+#define CONTACT_LIST_EDITOR_WIDGET_SOURCE_MENU(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "source-combo-box")
+#define CONTACT_LIST_EDITOR_WIDGET_TREE_VIEW(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "tree-view")
+
+/* Shorthand, requires a variable named "editor". */
+#define WIDGET(name) (CONTACT_LIST_EDITOR_WIDGET_##name (editor))
+
+#define TOPLEVEL_KEY (g_type_name (E_TYPE_CONTACT_LIST_EDITOR))
-/* The arguments we take */
enum {
PROP_0,
PROP_BOOK,
@@ -117,1160 +86,1444 @@ enum {
PROP_EDITABLE
};
-GType
-e_contact_list_editor_get_type (void)
-{
- static GType cle_type = 0;
+typedef struct {
+ EContactListEditor *editor;
+ gboolean should_close;
+} EditorCloseStruct;
- if (!cle_type) {
- static const GTypeInfo cle_info = {
- sizeof (EContactListEditorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) e_contact_list_editor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EContactListEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_contact_list_editor_init,
- };
+struct _EContactListEditorPrivate {
- cle_type = g_type_register_static (EAB_TYPE_EDITOR, "EContactListEditor", &cle_info, 0);
- }
+ EBook *book;
+ EContact *contact;
- return cle_type;
-}
+ GladeXML *xml;
+ GtkTreeModel *model;
+ ENameSelector *name_selector;
+ /* Whether we are editing a new contact or an existing one. */
+ guint is_new_list : 1;
-static void
-e_contact_list_editor_class_init (EContactListEditorClass *klass)
+ /* Whether the contact has been changed since bringing up the
+ * contact editor. */
+ guint changed : 1;
+
+ /* Whether the contact editor will accept modifications. */
+ guint editable : 1;
+
+ /* Whether the target book accepts storing of contact lists. */
+ guint allows_contact_lists : 1;
+
+ /* Whether an async wombat call is in progress. */
+ guint in_async_call : 1;
+
+ /* ID for async load_source call */
+ guint load_source_id;
+ EBook *load_book;
+};
+
+#define VCARD_TYPE "text/x-vcard"
+
+enum {
+ TARGET_TYPE_VCARD,
+};
+
+static GtkTargetEntry targets[] = {
+ { VCARD_TYPE, 0, TARGET_TYPE_VCARD },
+};
+
+static gpointer parent_class;
+
+static EContactListEditor *
+contact_list_editor_extract (GtkWidget *widget)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- EABEditorClass *editor_class = EAB_EDITOR_CLASS (klass);
-
- parent_class = g_type_class_ref (EAB_TYPE_EDITOR);
-
- editor_class->show = e_contact_list_editor_show;
- editor_class->raise = e_contact_list_editor_raise;
- editor_class->close = e_contact_list_editor_close;
- editor_class->save_contact = e_contact_list_editor_save_contact;
- editor_class->is_valid = e_contact_list_editor_is_valid;
- editor_class->is_changed = e_contact_list_editor_is_changed;
- editor_class->get_window = e_contact_list_editor_get_window;
-
- object_class->set_property = e_contact_list_editor_set_property;
- object_class->get_property = e_contact_list_editor_get_property;
- object_class->dispose = e_contact_list_editor_dispose;
-
- g_object_class_install_property (object_class, PROP_BOOK,
- g_param_spec_object ("book",
- _("Book"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_BOOK,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_CONTACT,
- g_param_spec_object ("contact",
- _("Contact"),
- /*_( */"XXX blurb" /*)*/,
- E_TYPE_CONTACT,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_IS_NEW_LIST,
- g_param_spec_boolean ("is_new_list",
- _("Is New List"),
- /*_( */"XXX blurb" /*)*/,
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class, PROP_EDITABLE,
- g_param_spec_boolean ("editable",
- _("Editable"),
- /*_( */"XXX blurb" /*)*/,
- FALSE,
- G_PARAM_READWRITE));
+ GtkWidget *toplevel;
+
+ toplevel = gtk_widget_get_toplevel (widget);
+ return g_object_get_data (G_OBJECT (toplevel), TOPLEVEL_KEY);
}
static void
-e_contact_list_editor_init (EContactListEditor *editor)
+contact_list_editor_scroll_to_end (EContactListEditor *editor)
{
- GladeXML *gui;
- GList *icon_list;
- char *gladefile;
-
- editor->contact = NULL;
- editor->changed = FALSE;
- editor->image_set = FALSE;
- editor->editable = TRUE;
- editor->allows_contact_lists = TRUE;
- editor->in_async_call = FALSE;
- editor->is_new_list = FALSE;
-
- editor->load_source_id = 0;
- editor->load_book = NULL;
-
- gladefile = g_build_filename (EVOLUTION_GLADEDIR,
- "contact-list-editor.glade",
- NULL);
- gui = glade_xml_new (gladefile, NULL, NULL);
- g_free (gladefile);
-
- editor->gui = gui;
-
- editor->app = glade_xml_get_widget (gui, "contact list editor");
-
- editor->table = glade_xml_get_widget (gui, "contact-list-table");
- editor->model = g_object_get_data (G_OBJECT(editor->table), "model");
-
- /* XXX need this for libglade-2 it seems */
- gtk_widget_show (editor->table);
-
- editor->add_button = glade_xml_get_widget (editor->gui, "add-email-button");
- editor->remove_button = glade_xml_get_widget (editor->gui, "remove-button");
- editor->select_button = glade_xml_get_widget (editor->gui, "select-button");
-
- editor->email_entry = glade_xml_get_widget (gui, "email-entry");
- editor->list_name_entry = glade_xml_get_widget (gui, "list-name-entry");
- editor->list_image = glade_xml_get_widget (gui, "list-image");
- editor->visible_addrs_checkbutton = glade_xml_get_widget (gui, "visible-addrs-checkbutton");
- editor->source_menu = glade_xml_get_widget (gui, "source-combo-box-source");
-
- editor->ok_button = glade_xml_get_widget (gui, "ok-button");
- editor->cancel_button = glade_xml_get_widget (gui, "cancel-button");
-
- /* connect signals */
- g_signal_connect (editor->add_button,
- "clicked", G_CALLBACK(add_email_cb), editor);
- g_signal_connect (editor->email_entry,
- "activate", G_CALLBACK(add_email_cb), editor);
- g_signal_connect ((ENameSelectorEntry *)editor->email_entry,
- "updated", G_CALLBACK(email_match_selected), editor);
- g_signal_connect (editor->remove_button,
- "clicked", G_CALLBACK(remove_entry_cb), editor);
- g_signal_connect (editor->select_button,
- "clicked", G_CALLBACK(select_cb), editor);
- g_signal_connect (editor->list_name_entry,
- "changed", G_CALLBACK(list_name_changed_cb), editor);
- g_signal_connect (editor->visible_addrs_checkbutton,
- "toggled", G_CALLBACK(visible_addrs_toggled_cb), editor);
- g_signal_connect (editor->email_entry,
- "key-press-event", G_CALLBACK(email_key_pressed), editor);
-
- e_table_drag_dest_set (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
- 0, list_drag_types, num_list_drag_types, GDK_ACTION_LINK);
-
- g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
- "table_drag_motion", G_CALLBACK(table_drag_motion_cb), editor);
- g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
- "table_drag_drop", G_CALLBACK (table_drag_drop_cb), editor);
- g_signal_connect (e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table)),
- "table_drag_data_received", G_CALLBACK(table_drag_data_received_cb), editor);
-
- g_signal_connect (editor->ok_button,
- "clicked", G_CALLBACK(save_and_close_cb), editor);
- g_signal_connect (editor->cancel_button,
- "clicked", G_CALLBACK(close_cb), editor);
-
-
- g_signal_connect (editor->list_image,
- "changed", G_CALLBACK(list_image_changed_cb), editor);
-
- g_signal_connect (editor->source_menu,
- "changed", G_CALLBACK (source_changed_cb), editor);
-
- command_state_changed (editor);
-
- /* Connect to the deletion of the dialog */
- g_signal_connect (editor->app, "delete_event",
- G_CALLBACK (app_delete_event_cb), editor);
-
- gtk_dialog_set_has_separator (GTK_DIALOG (editor->app), FALSE);
-
- /* set the icon */
- icon_list = e_icon_factory_get_icon_list ("stock_contact-list");
- if (icon_list) {
- gtk_window_set_icon_list (GTK_WINDOW (editor->app), icon_list);
- g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
- g_list_free (icon_list);
- }
+ GtkTreeView *view;
+ GtkTreePath *path;
+ gint n_rows;
- gtk_widget_show_all (editor->app);
+ view = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ n_rows = gtk_tree_model_iter_n_children (editor->priv->model, NULL);
+
+ path = gtk_tree_path_new_from_indices (n_rows - 1, -1);
+ gtk_tree_view_scroll_to_cell (view, path, NULL, FALSE, 0., 0.);
+ gtk_tree_view_set_cursor (view, path, NULL, FALSE);
+ gtk_tree_path_free (path);
}
static void
-new_target_cb (EBook *new_book, EBookStatus status, EContactListEditor *editor)
+contact_list_editor_update (EContactListEditor *editor)
{
- editor->load_source_id = 0;
- editor->load_book = NULL;
+ EContactListEditorPrivate *priv = editor->priv;
- if (status != E_BOOK_ERROR_OK || new_book == NULL) {
- eab_load_error_dialog (NULL, e_book_get_source (new_book), status);
+ gtk_widget_set_sensitive (
+ WIDGET (OK_BUTTON),
+ eab_editor_is_valid (EAB_EDITOR (editor)) &&
+ priv->allows_contact_lists);
- e_source_combo_box_set_active (
- E_SOURCE_COMBO_BOX (editor->source_menu),
- e_book_get_source (editor->book));
+ gtk_widget_set_sensitive (
+ WIDGET (SOURCE_MENU), priv->is_new_list);
+}
- if (new_book)
- g_object_unref (new_book);
- return;
- }
- e_contact_store_add_book (((ENameSelectorEntry *)editor->email_entry)->contact_store, new_book);
+static void
+contact_list_editor_notify_cb (EContactListEditor *editor,
+ GParamSpec *pspec)
+{
+ EContactListEditorPrivate *priv = editor->priv;
+ gboolean sensitive;
- g_object_set (editor, "book", new_book, NULL);
- g_object_unref (new_book);
+ sensitive = priv->editable && priv->allows_contact_lists;
+
+ gtk_widget_set_sensitive (WIDGET (LIST_NAME_ENTRY), sensitive);
+ gtk_widget_set_sensitive (WIDGET (MEMBERS_VBOX), sensitive);
}
static void
-cancel_load (EContactListEditor *editor)
+contact_list_editor_add_email (EContactListEditor *editor)
{
- if (editor->load_source_id) {
- addressbook_load_cancel (editor->load_source_id);
- editor->load_source_id = 0;
-
- g_object_unref (editor->load_book);
- editor->load_book = NULL;
+ EContactListEditorPrivate *priv = editor->priv;
+ EContactListModel *model;
+ GtkEntry *entry;
+ const gchar *text;
+
+ entry = GTK_ENTRY (WIDGET (EMAIL_ENTRY));
+ model = E_CONTACT_LIST_MODEL (priv->model);
+
+ text = gtk_entry_get_text (entry);
+ if (text != NULL && *text != '\0') {
+ e_contact_list_model_add_email (model, text);
+ contact_list_editor_scroll_to_end (editor);
+ priv->changed = TRUE;
}
+
+ gtk_entry_set_text (entry, "");
+ contact_list_editor_update (editor);
}
static void
-source_changed_cb (ESourceComboBox *source_combo_box, EContactListEditor *editor)
+contact_list_editor_book_loaded (EBook *new_book,
+ EBookStatus status,
+ EContactListEditor *editor)
{
- ESource *source;
-
- source = e_source_combo_box_get_active (source_combo_box);
+ EContactListEditorPrivate *priv = editor->priv;
+ ENameSelectorEntry *entry;
- cancel_load (editor);
+ priv->load_source_id = 0;
+ priv->load_book = NULL;
- if (e_source_equal (e_book_get_source (editor->book), source))
+ if (status != E_BOOK_ERROR_OK || new_book == NULL) {
+ eab_load_error_dialog (
+ NULL, e_book_get_source (new_book), status);
+ e_source_combo_box_set_active (
+ E_SOURCE_COMBO_BOX (WIDGET (SOURCE_MENU)),
+ e_book_get_source (priv->book));
+ if (new_book)
+ g_object_unref (new_book);
return;
+ }
- editor->load_book = e_book_new (source, NULL);
- editor->load_source_id = addressbook_load (editor->load_book,
- (EBookCallback) new_target_cb, editor);
+ entry = E_NAME_SELECTOR_ENTRY (WIDGET (EMAIL_ENTRY));
+ e_contact_store_add_book (entry->contact_store, new_book);
+ e_contact_list_editor_set_book (editor, new_book);
+ g_object_unref (new_book);
}
static void
-e_contact_list_editor_dispose (GObject *object)
+contact_list_editor_cancel_load (EContactListEditor *editor)
{
- EContactListEditor *editor = E_CONTACT_LIST_EDITOR (object);
+ EContactListEditorPrivate *priv = editor->priv;
- cancel_load (editor);
+ if (priv->load_source_id == 0)
+ return;
- if (editor->name_selector) {
- g_object_unref (editor->name_selector);
- editor->name_selector = NULL;
- }
+ addressbook_load_cancel (priv->load_source_id);
+ priv->load_source_id = 0;
- if (G_OBJECT_CLASS (parent_class)->dispose)
- (* G_OBJECT_CLASS (parent_class)->dispose) (object);
+ g_object_unref (priv->load_book);
+ priv->load_book = NULL;
}
-typedef struct {
- EContactListEditor *cle;
- gboolean should_close;
-} EditorCloseStruct;
+static gboolean
+contact_list_editor_contact_exists (EContactListModel *model,
+ const gchar *email)
+{
+ const gchar *tag = "addressbook:ask-list-add-exists";
+
+ if (!e_contact_list_model_has_email (model, email))
+ return FALSE;
+
+ return (e_error_run (NULL, tag, email) != GTK_RESPONSE_YES);
+}
static void
-list_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruct *ecs)
+contact_list_editor_list_added_cb (EBook *book,
+ EBookStatus status,
+ const gchar *id,
+ EditorCloseStruct *ecs)
{
- EContactListEditor *cle = ecs->cle;
+ EContactListEditor *editor = ecs->editor;
+ EContactListEditorPrivate *priv = editor->priv;
gboolean should_close = ecs->should_close;
- if (cle->app)
- gtk_widget_set_sensitive (cle->app, TRUE);
- cle->in_async_call = FALSE;
+ gtk_widget_set_sensitive (WIDGET (DIALOG), TRUE);
+ priv->in_async_call = FALSE;
- e_contact_set (cle->contact, E_CONTACT_UID, (char*)id);
+ e_contact_set (priv->contact, E_CONTACT_UID, (gchar *) id);
- eab_editor_contact_added (EAB_EDITOR (cle), status, cle->contact);
+ eab_editor_contact_added (
+ EAB_EDITOR (editor), status, priv->contact);
if (status == E_BOOK_ERROR_OK) {
- cle->is_new_list = FALSE;
+ priv->is_new_list = FALSE;
if (should_close)
- eab_editor_close (EAB_EDITOR (cle));
+ eab_editor_close (EAB_EDITOR (editor));
else
- command_state_changed (cle);
+ contact_list_editor_update (editor);
}
- g_object_unref (cle);
+ g_object_unref (editor);
g_free (ecs);
}
static void
-list_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
+contact_list_editor_list_modified_cb (EBook *book,
+ EBookStatus status,
+ EditorCloseStruct *ecs)
{
- EContactListEditor *cle = ecs->cle;
+ EContactListEditor *editor = ecs->editor;
+ EContactListEditorPrivate *priv = editor->priv;
gboolean should_close = ecs->should_close;
- if (cle->app)
- gtk_widget_set_sensitive (cle->app, TRUE);
- cle->in_async_call = FALSE;
+ gtk_widget_set_sensitive (WIDGET (DIALOG), TRUE);
+ priv->in_async_call = FALSE;
- eab_editor_contact_modified (EAB_EDITOR (cle), status, cle->contact);
+ eab_editor_contact_modified (
+ EAB_EDITOR (editor), status, priv->contact);
if (status == E_BOOK_ERROR_OK) {
if (should_close)
- eab_editor_close (EAB_EDITOR (cle));
+ eab_editor_close (EAB_EDITOR (editor));
}
- g_object_unref (cle); /* release ref held for ebook callback */
+ g_object_unref (editor);
g_free (ecs);
}
static void
-save_contact (EContactListEditor *cle, gboolean should_close)
+contact_list_editor_render_destination (GtkTreeViewColumn *column,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter)
{
- extract_info (cle);
-
- if (cle->book) {
- EditorCloseStruct *ecs = g_new(EditorCloseStruct, 1);
-
- ecs->cle = cle;
- g_object_ref (cle);
- ecs->should_close = should_close;
+ /* XXX Would be nice if EDestination had a text property
+ * that we could just bind the GtkCellRenderer to. */
- if (cle->app)
- gtk_widget_set_sensitive (cle->app, FALSE);
- cle->in_async_call = TRUE;
+ EDestination *destination;
+ const gchar *textrep;
- if (cle->is_new_list)
- eab_merging_book_add_contact (cle->book, cle->contact, (EBookIdCallback)list_added_cb, ecs);
- else
- eab_merging_book_commit_contact (cle->book, cle->contact, (EBookCallback)list_modified_cb, ecs);
-
- cle->changed = FALSE;
- }
+ gtk_tree_model_get (model, iter, 0, &destination, -1);
+ textrep = e_destination_get_textrep (destination, TRUE);
+ g_object_set (renderer, "text", textrep, NULL);
+ g_object_unref (destination);
}
-static gboolean
-is_named (EContactListEditor *editor)
+static void
+contact_list_editor_row_deleted_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ EContactListEditor *editor)
{
- char *string = gtk_editable_get_chars(GTK_EDITABLE (editor->list_name_entry), 0, -1);
- gboolean named = FALSE;
-
- if (string && *string) {
- named = TRUE;
- }
-
- g_free (string);
+ gint n_children;
- return named;
+ n_children = gtk_tree_model_iter_n_children (model, NULL);
+ gtk_widget_set_sensitive (WIDGET (REMOVE_BUTTON), n_children > 0);
}
static void
-e_contact_list_editor_save_contact (EABEditor *editor, gboolean should_close)
+contact_list_editor_row_inserted_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ EContactListEditor *editor)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (editor);
-
- save_contact (cle, should_close);
+ gtk_widget_set_sensitive (WIDGET (REMOVE_BUTTON), TRUE);
}
-static gboolean
-e_contact_list_editor_is_valid (EABEditor *editor)
-{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (editor);
+/*********************** Autoconnected Signal Handlers ***********************/
- return is_named (cle);
-}
+void
+contact_list_editor_add_button_clicked_cb (GtkWidget *widget);
-static gboolean
-e_contact_list_editor_is_changed (EABEditor *editor)
+void
+contact_list_editor_add_button_clicked_cb (GtkWidget *widget)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (editor);
+ EContactListEditor *editor;
- return cle->changed;
-}
+ editor = contact_list_editor_extract (widget);
-static GtkWindow*
-e_contact_list_editor_get_window (EABEditor *editor)
-{
- return GTK_WINDOW (E_CONTACT_LIST_EDITOR (editor)->app);
+ contact_list_editor_add_email (editor);
}
-static void
-close_cb (GtkWidget *widget, EContactListEditor *cle)
-{
- eab_editor_prompt_to_save_changes (EAB_EDITOR (cle), GTK_WINDOW (cle->app));
-}
+void
+contact_list_editor_cancel_button_clicked_cb (GtkWidget *widget);
-static void
-save_and_close_cb (GtkWidget *widget, EContactListEditor *cle)
+void
+contact_list_editor_cancel_button_clicked_cb (GtkWidget *widget)
{
- EABEditor *editor = EAB_EDITOR (cle);
- if (! (cle->editable && cle->allows_contact_lists))
- eab_editor_close(editor);
- else
- save_contact (cle, TRUE);
+ EContactListEditor *editor;
+ GtkWindow *window;
+
+ editor = contact_list_editor_extract (widget);
+ window = GTK_WINDOW (WIDGET (DIALOG));
+
+ eab_editor_prompt_to_save_changes (EAB_EDITOR (editor), window);
}
-static void
-contact_list_editor_destroy_notify (gpointer data,
- GObject *where_the_object_was)
+void
+contact_list_editor_check_button_toggled_cb (GtkWidget *widget);
+
+void
+contact_list_editor_check_button_toggled_cb (GtkWidget *widget)
{
- eab_editor_remove (EAB_EDITOR (data));
+ EContactListEditor *editor;
+
+ editor = contact_list_editor_extract (widget);
+
+ editor->priv->changed = TRUE;
+ contact_list_editor_update (editor);
}
-EContactListEditor *
-e_contact_list_editor_new (EBook *book,
- EContact *list_contact,
- gboolean is_new_list,
- gboolean editable)
+gboolean
+contact_list_editor_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event);
+
+gboolean
+contact_list_editor_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event)
{
- EContactListEditor *ce = g_object_new (E_TYPE_CONTACT_LIST_EDITOR, NULL);
+ EContactListEditor *editor;
+ GtkWindow *window;
- eab_editor_add (EAB_EDITOR (ce));
- g_object_weak_ref (G_OBJECT (ce), contact_list_editor_destroy_notify, ce);
+ editor = contact_list_editor_extract (widget);
+ window = GTK_WINDOW (WIDGET (DIALOG));
- g_object_set (ce,
- "book", book,
- "contact", list_contact,
- "is_new_list", is_new_list,
- "editable", editable,
- NULL);
+ /* If we're in an async call, don't allow the dialog to close. */
+ if (!editor->priv->in_async_call)
+ eab_editor_prompt_to_save_changes (
+ EAB_EDITOR (editor), window);
- return ce;
+ return TRUE;
}
-static void
-e_contact_list_editor_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
+void
+contact_list_editor_drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time);
+
+void
+contact_list_editor_drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
{
EContactListEditor *editor;
+ EContactListModel *model;
+ gchar *target_type;
+ gboolean changed = FALSE;
+ gboolean handled = FALSE;
+ GList *list, *iter;
+
+ editor = contact_list_editor_extract (widget);
+
+ model = E_CONTACT_LIST_MODEL (editor->priv->model);
+ target_type = gdk_atom_name (selection_data->target);
+
+ if (strcmp (target_type, VCARD_TYPE) != 0)
+ goto exit;
- editor = E_CONTACT_LIST_EDITOR (object);
+ list = eab_contact_list_from_string ((gchar *) selection_data->data);
- switch (prop_id){
- case PROP_BOOK: {
- gboolean changed;
+ if (list != NULL)
+ handled = TRUE;
- if (editor->book)
- g_object_unref (editor->book);
- editor->book = E_BOOK(g_value_get_object (value));
- g_object_ref (editor->book);
- /* XXX more here about editable/etc. */
+ for (iter = list; iter != NULL; iter = iter->next) {
+ EContact *contact = iter->data;
+ const gchar *email;
- changed = (editor->allows_contact_lists != e_book_check_static_capability (editor->book,
- "contact-lists"));
- editor->allows_contact_lists = e_book_check_static_capability (editor->book,
- "contact-lists");
+ if (e_contact_get (contact, E_CONTACT_IS_LIST))
+ continue;
- if (changed) {
- set_editable (editor);
- command_state_changed (editor);
+ email = e_contact_get (contact, E_CONTACT_EMAIL_1);
+ if (email == NULL) {
+ g_warning (
+ "Contact with no email-ids listed "
+ "can't be added to a Contact-List");
+ continue;
+ }
+
+ if (!contact_list_editor_contact_exists (model, email)) {
+ /* Hard-wired for default e-mail */
+ e_contact_list_model_add_contact (model, contact, 0);
+ changed = TRUE;
}
- break;
}
- case PROP_CONTACT:
- if (editor->contact)
- g_object_unref (editor->contact);
- editor->contact = e_contact_duplicate(E_CONTACT(g_value_get_object (value)));
- fill_in_info(editor);
- editor->changed = FALSE;
- command_state_changed (editor);
- break;
- case PROP_IS_NEW_LIST: {
- gboolean new_value = g_value_get_boolean (value);
- gboolean changed = (editor->is_new_list != new_value);
-
- editor->is_new_list = new_value;
-
- if (changed)
- command_state_changed (editor);
- break;
+
+ g_list_foreach (list, (GFunc) g_object_unref, NULL);
+ g_list_free (list);
+
+ contact_list_editor_scroll_to_end (editor);
+
+ if (changed) {
+ editor->priv->changed = TRUE;
+ contact_list_editor_update (editor);
}
- case PROP_EDITABLE: {
- gboolean new_value = g_value_get_boolean (value);
- gboolean changed = (editor->editable != new_value);
- editor->editable = new_value;
+exit:
+ gtk_drag_finish (context, handled, FALSE, time);
+}
+
+gboolean
+contact_list_editor_drag_drop_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ guint time);
+
+gboolean
+contact_list_editor_drag_drop_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ guint time)
+{
+ EContactListEditor *editor;
+ GList *iter;
+
+ editor = contact_list_editor_extract (widget);
- if (changed) {
- set_editable (editor);
- command_state_changed (editor);
+ for (iter = context->targets; iter != NULL; iter = iter->next) {
+ GdkAtom target = GDK_POINTER_TO_ATOM (iter->data);
+ gchar *possible_type;
+ gboolean match;
+
+ possible_type = gdk_atom_name (target);
+ match = (strcmp (possible_type, VCARD_TYPE) == 0);
+ g_free (possible_type);
+
+ if (match) {
+ gtk_drag_get_data (widget, context, target, time);
+ return TRUE;
}
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
}
+
+ return FALSE;
}
-static void
-e_contact_list_editor_get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
+gboolean
+contact_list_editor_drag_motion_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ guint time);
+
+gboolean
+contact_list_editor_drag_motion_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x, gint y,
+ guint time)
{
EContactListEditor *editor;
+ GList *iter;
- editor = E_CONTACT_LIST_EDITOR (object);
+ editor = contact_list_editor_extract (widget);
- switch (prop_id) {
- case PROP_BOOK:
- g_value_set_object (value, editor->book);
- break;
+ for (iter = context->targets; iter != NULL; iter = iter->next) {
+ GdkAtom target = GDK_POINTER_TO_ATOM (iter->data);
+ gchar *possible_type;
+ gboolean match;
- case PROP_CONTACT:
- extract_info(editor);
- g_value_set_object (value, editor->contact);
- break;
-
- case PROP_IS_NEW_LIST:
- g_value_set_boolean (value, editor->is_new_list);
- break;
+ possible_type = gdk_atom_name (target);
+ match = (strcmp (possible_type, VCARD_TYPE) == 0);
+ g_free (possible_type);
- case PROP_EDITABLE:
- g_value_set_boolean (value, editor->editable);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
+ if (match) {
+ gdk_drag_status (context, GDK_ACTION_LINK, time);
+ return TRUE;
+ }
}
+
+ return FALSE;
}
-static void
-e_contact_list_editor_show (EABEditor *editor)
+void
+contact_list_editor_email_entry_activate_cb (GtkWidget *widget);
+
+void
+contact_list_editor_email_entry_activate_cb (GtkWidget *widget)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (editor);
- gtk_widget_show (cle->app);
+ EContactListEditor *editor;
+
+ editor = contact_list_editor_extract (widget);
+
+ contact_list_editor_add_email (editor);
}
-static void
-e_contact_list_editor_raise (EABEditor *editor)
+void
+contact_list_editor_email_entry_changed_cb (GtkWidget *widget);
+
+void
+contact_list_editor_email_entry_changed_cb (GtkWidget *widget)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (editor);
- gdk_window_raise (GTK_WIDGET (cle->app)->window);
+ EContactListEditor *editor;
+ const gchar *text;
+ gboolean sensitive;
+
+ editor = contact_list_editor_extract (widget);
+ text = gtk_entry_get_text (GTK_ENTRY (widget));
+
+ sensitive = (text != NULL && *text != '\0');
+ gtk_widget_set_sensitive (WIDGET (ADD_BUTTON), sensitive);
}
-static void
-e_contact_list_editor_close (EABEditor *editor)
+gboolean
+contact_list_editor_email_entry_key_press_event_cb (GtkWidget *widget,
+ GdkEventKey *event);
+
+gboolean
+contact_list_editor_email_entry_key_press_event_cb (GtkWidget *widget,
+ GdkEventKey *event)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (editor);
- g_return_if_fail (cle->app != NULL);
+ EContactListEditor *editor;
- gtk_widget_destroy (cle->app);
- cle->app = NULL;
+ editor = contact_list_editor_extract (widget);
- eab_editor_closed (EAB_EDITOR (cle));
+ if (event->keyval == GDK_comma || event->keyval == GDK_Return) {
+ g_signal_emit_by_name (widget, "activate", 0);
+ contact_list_editor_add_email (editor);
+
+ return TRUE;
+ }
+
+ return FALSE;
}
-GtkWidget *
-e_contact_list_editor_create_table(gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2);
+void
+contact_list_editor_email_entry_updated_cb (GtkWidget *widget,
+ EDestination *destination);
-GtkWidget *
-e_contact_list_editor_create_table(gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2)
+void
+contact_list_editor_email_entry_updated_cb (GtkWidget *widget,
+ EDestination *destination)
{
+ EContactListEditor *editor;
+ ENameSelectorEntry *entry;
+ EContactListModel *model;
+ EDestinationStore *store;
+ gchar *email;
- ETableModel *model;
- GtkWidget *table;
- char *etspecfile;
+ editor = contact_list_editor_extract (widget);
- model = e_contact_list_model_new ();
+ entry = E_NAME_SELECTOR_ENTRY (widget);
+ model = E_CONTACT_LIST_MODEL (editor->priv->model);
- etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
- "e-contact-list-editor.etspec",
- NULL);
- table = e_table_scrolled_new_from_spec_file (model,
- NULL,
- etspecfile,
- NULL);
- g_free (etspecfile);
+ email = g_strdup (e_destination_get_address (destination));
+ store = e_name_selector_entry_peek_destination_store (entry);
+ e_destination_store_remove_destination (store, destination);
+ gtk_entry_set_text (GTK_ENTRY (WIDGET (EMAIL_ENTRY)), "");
- g_object_set_data(G_OBJECT(table), "model", model);
+ if (email && *email) {
+ e_contact_list_model_add_email (model, email);
+ contact_list_editor_scroll_to_end (editor);
+ editor->priv->changed = TRUE;
+ }
- return table;
+ g_free (email);
+ contact_list_editor_update (editor);
}
-static gboolean
-contact_already_exists (EContactListModel *model, const char *email)
+void
+contact_list_editor_list_name_entry_changed_cb (GtkWidget *widget);
+
+void
+contact_list_editor_list_name_entry_changed_cb (GtkWidget *widget)
{
- int row_count;
- int row;
- char *list_email;
- row_count = e_table_model_row_count (E_TABLE_MODEL (model));
- for (row = 0; row < row_count; row ++) {
- list_email = (char *) e_destination_get_email(e_contact_list_model_get_destination (model, row));
- if (strcmp (list_email, email) == 0) {
- if (e_error_run (NULL, "addressbook:ask-list-add-exists",
- email) != GTK_RESPONSE_YES)
- return TRUE;
- else
- return FALSE;
- break;
- }
- }
- return FALSE;
+ EContactListEditor *editor;
+ const gchar *title;
+
+ editor = contact_list_editor_extract (widget);
+
+ title = gtk_entry_get_text (GTK_ENTRY (widget));
+
+ if (title == NULL || *title == '\0')
+ title = _("Contact List Editor");
+
+ gtk_window_set_title (GTK_WINDOW (WIDGET (DIALOG)), title);
+
+ editor->priv->changed = TRUE;
+ contact_list_editor_update (editor);
}
-static void
-add_to_model (EContactListEditor *editor, GList *destinations)
+void
+contact_list_editor_ok_button_clicked_cb (GtkWidget *widget);
+
+void
+contact_list_editor_ok_button_clicked_cb (GtkWidget *widget)
{
- GList *l;
-
- for (l = destinations; l; l = g_list_next (l)) {
- EDestination *destination = l->data;
- if (e_destination_get_email (destination)) {
- if (! contact_already_exists (E_CONTACT_LIST_MODEL (editor->model)
- , e_destination_get_email (destination))) {
- e_contact_list_model_add_destination (E_CONTACT_LIST_MODEL (editor->model),
- destination);
- }
- }
- }
+ EContactListEditor *editor;
+ gboolean save_contact;
+
+ editor = contact_list_editor_extract (widget);
+
+ save_contact =
+ editor->priv->editable &&
+ editor->priv->allows_contact_lists;
+
+ if (save_contact)
+ eab_editor_save_contact (EAB_EDITOR (editor), TRUE);
+ else
+ eab_editor_close (EAB_EDITOR (editor));
}
-static void
-select_names_ok_cb (GtkWidget *widget, gint response, gpointer data)
+void
+contact_list_editor_remove_button_clicked_cb (GtkWidget *widget);
+
+void
+contact_list_editor_remove_button_clicked_cb (GtkWidget *widget)
{
- EContactListEditor *ce;
- ENameSelectorDialog *name_selector_dialog;
- ENameSelectorModel *name_selector_model;
- EDestinationStore *destination_store;
- GList *destinations;
+ EContactListEditor *editor;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeView *view;
+ GList *list, *iter;
+
+ editor = contact_list_editor_extract (widget);
+
+ view = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ selection = gtk_tree_view_get_selection (view);
+ list = gtk_tree_selection_get_selected_rows (selection, &model);
- ce = E_CONTACT_LIST_EDITOR (data);
+ /* Convert the GtkTreePaths to GtkTreeRowReferences. */
+ for (iter = list; iter != NULL; iter = iter->next) {
+ GtkTreePath *path = iter->data;
- name_selector_dialog = e_name_selector_peek_dialog (ce->name_selector);
- gtk_widget_hide (GTK_WIDGET (name_selector_dialog));
+ iter->data = gtk_tree_row_reference_new (model, path);
+ gtk_tree_path_free (path);
+ }
+
+ /* Delete each row in the list. */
+ for (iter = list; iter != NULL; iter = iter->next) {
+ GtkTreeRowReference *reference = iter->data;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gboolean valid;
- name_selector_model = e_name_selector_peek_model (ce->name_selector);
- e_name_selector_model_peek_section (name_selector_model, "Members", NULL, &destination_store);
- destinations = e_destination_store_list_destinations (destination_store);
+ path = gtk_tree_row_reference_get_path (reference);
+ valid = gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+ g_assert (valid);
- add_to_model (ce, destinations);
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ gtk_tree_row_reference_free (reference);
+ }
- g_list_free (destinations);
+ g_list_free (list);
- ce->changed = TRUE;
- command_state_changed (ce);
+ editor->priv->changed = TRUE;
+ contact_list_editor_update (editor);
}
-static void
-setup_name_selector (EContactListEditor *editor)
+void
+contact_list_editor_select_button_clicked_cb (GtkWidget *widget);
+
+void
+contact_list_editor_select_button_clicked_cb (GtkWidget *widget)
{
- ENameSelectorModel *name_selector_model;
- ENameSelectorDialog *name_selector_dialog;
+ EContactListEditor *editor;
+ EContactListModel *model;
+ ENameSelectorDialog *dialog;
+ EDestinationStore *store;
+ GList *list, *iter;
- if (editor->name_selector)
- return;
+ editor = contact_list_editor_extract (widget);
- editor->name_selector = e_name_selector_new ();
+ model = E_CONTACT_LIST_MODEL (editor->priv->model);
+ dialog = e_name_selector_peek_dialog (editor->priv->name_selector);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Contact List Members"));
- name_selector_model = e_name_selector_peek_model (editor->name_selector);
- e_name_selector_model_add_section (name_selector_model, "Members", gettext ("_Members"), NULL);
+ /* We need to empty out the destination store, since we copy its
+ * contents every time. This sucks, we should really be wired
+ * directly to the EDestinationStore that the name selector uses
+ * in true MVC fashion. */
- name_selector_dialog = e_name_selector_peek_dialog (editor->name_selector);
- gtk_window_set_title (GTK_WINDOW (name_selector_dialog), _("Contact List Members"));
- g_signal_connect (name_selector_dialog, "response",
- G_CALLBACK (select_names_ok_cb), editor);
+ e_name_selector_model_peek_section (
+ e_name_selector_peek_model (editor->priv->name_selector),
+ "Members", NULL, &store);
+
+ list = e_destination_store_list_destinations (store);
+
+ for (iter = list; iter != NULL; iter = iter->next)
+ e_destination_store_remove_destination (store, iter->data);
+
+ g_list_free (list);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_hide (GTK_WIDGET (dialog));
+
+ list = e_destination_store_list_destinations (store);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ EDestination *destination = iter->data;
+ const gchar *email = e_destination_get_email (destination);
+
+ if (email == NULL)
+ continue;
+
+ if (!contact_list_editor_contact_exists (model, email))
+ e_contact_list_model_add_destination (
+ model, destination);
+ }
+
+ g_list_free (list);
+
+ editor->priv->changed = TRUE;
+ contact_list_editor_update (editor);
}
-static void
-select_cb (GtkWidget *w, EContactListEditor *editor)
+void
+contact_list_editor_source_menu_changed_cb (GtkWidget *widget);
+
+void
+contact_list_editor_source_menu_changed_cb (GtkWidget *widget)
{
- ENameSelectorModel *name_selector_model;
- ENameSelectorDialog *name_selector_dialog;
- EDestinationStore *destination_store;
- GList *destinations;
- GList *l;
+ EContactListEditor *editor;
+ ESource *source;
- setup_name_selector (editor);
+ editor = contact_list_editor_extract (widget);
+ source = e_source_combo_box_get_active (E_SOURCE_COMBO_BOX (widget));
- /* We need to empty out the destination store, since we copy its contents every time.
- * This sucks, we should really be wired directly to the EDestinationStore that
- * the name selector uses in true MVC fashion. */
+ if (e_source_equal (e_book_get_source (editor->priv->book), source))
+ return;
- name_selector_model = e_name_selector_peek_model (editor->name_selector);
- e_name_selector_model_peek_section (name_selector_model, "Members", NULL, &destination_store);
- destinations = e_destination_store_list_destinations (destination_store);
+ editor->priv->load_book = e_book_new (source, NULL);
+ editor->priv->load_source_id = addressbook_load (
+ editor->priv->load_book, (EBookCallback)
+ contact_list_editor_book_loaded, editor);
+}
- for (l = destinations; l; l = g_list_next (l)) {
- EDestination *destination = l->data;
- e_destination_store_remove_destination (destination_store, destination);
- }
+gboolean
+contact_list_editor_tree_view_key_press_event_cb (GtkWidget *widget,
+ GdkEventKey *event);
+gboolean
+contact_list_editor_tree_view_key_press_event_cb (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ EContactListEditor *editor;
- g_list_free (destinations);
+ editor = contact_list_editor_extract (widget);
- name_selector_dialog = e_name_selector_peek_dialog (editor->name_selector);
- gtk_widget_show (GTK_WIDGET (name_selector_dialog));
+ if (event->keyval == GDK_Delete) {
+ g_signal_emit_by_name (WIDGET (REMOVE_BUTTON), "clicked");
+ return TRUE;
+ }
+
+ return FALSE;
}
+/*********************** Glade Custom Widget Factories ***********************/
+
GtkWidget *
-e_contact_list_editor_create_source_combo_box (gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2);
+contact_list_editor_create_source_combo_box (gchar *name,
+ gchar *string1,
+ gchar *string2,
+ gint int1,
+ gint int2);
GtkWidget *
-e_contact_list_editor_create_source_combo_box (gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2)
+contact_list_editor_create_source_combo_box (gchar *name,
+ gchar *string1,
+ gchar *string2,
+ gint int1,
+ gint int2)
{
+ const gchar *key = "/apps/evolution/addressbook/sources";
- GtkWidget *combo_box;
- GConfClient *gconf_client;
+ GtkWidget *combo_box;
+ GConfClient *client;
ESourceList *source_list;
- gconf_client = gconf_client_get_default ();
- source_list = e_source_list_new_for_gconf (gconf_client, "/apps/evolution/addressbook/sources");
-
+ client = gconf_client_get_default ();
+ source_list = e_source_list_new_for_gconf (client, key);
combo_box = e_source_combo_box_new (source_list);
g_object_unref (source_list);
+ g_object_unref (client);
+
+ g_signal_connect (
+ combo_box, "changed", G_CALLBACK (
+ contact_list_editor_source_menu_changed_cb), NULL);
gtk_widget_show (combo_box);
+
return combo_box;
}
GtkWidget *
-e_contact_list_editor_create_name_selector (gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2);
+contact_list_editor_create_name_selector (gchar *name,
+ gchar *string1,
+ gchar *string2,
+ gint int1,
+ gint int2);
GtkWidget *
-e_contact_list_editor_create_name_selector (gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2)
+contact_list_editor_create_name_selector (gchar *name,
+ gchar *string1,
+ gchar *string2,
+ gint int1,
+ gint int2)
{
- ENameSelectorModel *name_selector_model;
ENameSelectorEntry *name_selector_entry;
- ENameSelector *name_selector = e_name_selector_new ();
+ ENameSelector *name_selector;
+
+ name_selector = e_name_selector_new ();
- name_selector_model = e_name_selector_peek_model (name_selector);
- e_name_selector_model_add_section (name_selector_model, "Members", "Members", NULL);
+ e_name_selector_model_add_section (
+ e_name_selector_peek_model (name_selector),
+ "Members", "Members", NULL);
- name_selector_entry = e_name_selector_peek_section_entry (name_selector, "Members");
+ name_selector_entry = e_name_selector_peek_section_entry (
+ name_selector, "Members");
- e_name_selector_entry_set_contact_editor_func (name_selector_entry, e_contact_editor_new);
- e_name_selector_entry_set_contact_list_editor_func (name_selector_entry, e_contact_list_editor_new);
+ e_name_selector_entry_set_contact_editor_func (
+ name_selector_entry, e_contact_editor_new);
+ e_name_selector_entry_set_contact_list_editor_func (
+ name_selector_entry, e_contact_list_editor_new);
gtk_widget_show (GTK_WIDGET (name_selector_entry));
- return (GtkWidget *)name_selector_entry;
+ g_signal_connect (
+ name_selector_entry, "activate", G_CALLBACK (
+ contact_list_editor_email_entry_activate_cb), NULL);
+ g_signal_connect (
+ name_selector_entry, "changed", G_CALLBACK (
+ contact_list_editor_email_entry_changed_cb), NULL);
+ g_signal_connect (
+ name_selector_entry, "key-press-event", G_CALLBACK (
+ contact_list_editor_email_entry_key_press_event_cb), NULL);
+ g_signal_connect (
+ name_selector_entry, "updated", G_CALLBACK (
+ contact_list_editor_email_entry_updated_cb), NULL);
+
+ return GTK_WIDGET (name_selector_entry);
}
+/**************************** EABEditor Callbacks ****************************/
+
static void
-add_email_cb (GtkWidget *w, EContactListEditor *editor)
+contact_list_editor_show (EABEditor *editor)
{
- GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (editor->table));
- const char *text = gtk_entry_get_text (GTK_ENTRY(editor->email_entry));
-
- if (text && *text) {
- e_contact_list_model_add_email (E_CONTACT_LIST_MODEL(editor->model), text);
-
- /* Skip to the end of the list */
- if (adj->upper - adj->lower > adj->page_size)
- gtk_adjustment_set_value (adj, adj->upper);
-
- editor->changed = TRUE;
+ gtk_widget_show (WIDGET (DIALOG));
+}
- }
+static void
+contact_list_editor_close (EABEditor *editor)
+{
+ gtk_widget_destroy (WIDGET (DIALOG));
+ eab_editor_closed (editor);
+}
- gtk_entry_set_text (GTK_ENTRY(editor->email_entry), "");
- command_state_changed (editor);
+static void
+contact_list_editor_raise (EABEditor *editor)
+{
+ gdk_window_raise (WIDGET (DIALOG)->window);
}
static void
-email_match_selected (GtkWidget *w, EDestination *destination, EContactListEditor *editor)
+contact_list_editor_save_contact (EABEditor *eab_editor,
+ gboolean should_close)
{
- char *email;
- EDestinationStore *store;
- GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (editor->table));
+ EContactListEditor *editor = E_CONTACT_LIST_EDITOR (eab_editor);
+ EContactListEditorPrivate *priv = editor->priv;
+ EditorCloseStruct *ecs;
+ EContact *contact;
- email = g_strdup(e_destination_get_address (destination));
- store = e_name_selector_entry_peek_destination_store ((ENameSelectorEntry *)w);
- e_destination_store_remove_destination (store, destination);
- gtk_entry_set_text (GTK_ENTRY(editor->email_entry), "");
+ contact = e_contact_list_editor_get_contact (editor);
- if (email && *email) {
- e_contact_list_model_add_email (E_CONTACT_LIST_MODEL(editor->model), email);
+ if (priv->book == NULL)
+ return;
- /* Skip to the end of the list */
- if (adj->upper - adj->lower > adj->page_size)
- gtk_adjustment_set_value (adj, adj->upper);
+ ecs = g_new (EditorCloseStruct, 1);
+ ecs->editor = g_object_ref (editor);
+ ecs->should_close = should_close;
- editor->changed = TRUE;
- }
+ gtk_widget_set_sensitive (WIDGET (DIALOG), FALSE);
+ priv->in_async_call = TRUE;
- g_free (email);
- command_state_changed (editor);
+ if (priv->is_new_list)
+ eab_merging_book_add_contact (
+ priv->book, contact, (EBookIdCallback)
+ contact_list_editor_list_added_cb, ecs);
+ else
+ eab_merging_book_commit_contact (
+ priv->book, contact, (EBookCallback)
+ contact_list_editor_list_modified_cb, ecs);
+
+ priv->changed = FALSE;
}
-static void
-prepend_selected_rows (int model_row, GList **list)
+static gboolean
+contact_list_editor_is_valid (EABEditor *editor)
{
- int *idx = g_new (int, 1);
- *idx = model_row;
- *list = g_list_append (*list, idx);
+ GtkEditable *editable;
+ gboolean valid;
+ gchar *chars;
+
+ editable = GTK_EDITABLE (WIDGET (LIST_NAME_ENTRY));
+ chars = gtk_editable_get_chars (editable, 0, -1);
+ valid = (chars != NULL && *chars != '\0');
+ g_free (chars);
+
+ return valid;
}
-static void
-remove_entry_cb (GtkWidget *w, EContactListEditor *editor)
+static gboolean
+contact_list_editor_is_changed (EABEditor *editor)
{
- int *idx = NULL;
- GList *list = NULL;
- int num_rows_deleted = 0;
- e_table_selected_row_foreach (e_table_scrolled_get_table(E_TABLE_SCROLLED(editor->table)),
- (EForeachFunc)prepend_selected_rows, &list);
-
- if (!list) return ;
-
- for(; list; list=list->next, num_rows_deleted++) {
- idx = (int *)(list->data);
- e_contact_list_model_remove_row (E_CONTACT_LIST_MODEL (editor->model), (*idx - num_rows_deleted));
- g_free (idx);
- list->data = NULL;
- }
-
- list = g_list_first (list);
- g_list_free (list);
- editor->changed = TRUE;
- command_state_changed (editor);
+ return E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor)->changed;
}
-static void
-list_name_changed_cb (GtkWidget *w, EContactListEditor *editor)
+static GtkWindow*
+contact_list_editor_get_window (EABEditor *editor)
{
- char *string = gtk_editable_get_chars(GTK_EDITABLE (w), 0, -1);
- char *title;
+ return GTK_WINDOW (WIDGET (DIALOG));
+}
- editor->changed = TRUE;
+/***************************** GObject Callbacks *****************************/
- if (string && *string)
- title = string;
- else
- title = _("Contact List Editor");
+static GObject *
+contact_list_editor_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GObject *object;
- gtk_window_set_title (GTK_WINDOW (editor->app), title);
+ /* Chain up to parent's constructor() method. */
+ object = G_OBJECT_CLASS (parent_class)->constructor (
+ type, n_construct_properties, construct_properties);
- g_free (string);
+ contact_list_editor_update (E_CONTACT_LIST_EDITOR (object));
- command_state_changed (editor);
+ return object;
}
static void
-list_image_changed_cb (GtkWidget *w, EContactListEditor *editor)
+contact_list_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- editor->image_set = TRUE;
- editor->changed = TRUE;
- command_state_changed (editor);
+ switch (property_id) {
+ case PROP_BOOK:
+ e_contact_list_editor_set_book (
+ E_CONTACT_LIST_EDITOR (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_CONTACT:
+ e_contact_list_editor_set_contact (
+ E_CONTACT_LIST_EDITOR (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_IS_NEW_LIST:
+ e_contact_list_editor_set_is_new_list (
+ E_CONTACT_LIST_EDITOR (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_EDITABLE:
+ e_contact_list_editor_set_editable (
+ E_CONTACT_LIST_EDITOR (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-visible_addrs_toggled_cb (GtkWidget *w, EContactListEditor *editor)
+contact_list_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- editor->changed = TRUE;
- command_state_changed (editor);
+ switch (property_id) {
+ case PROP_BOOK:
+ g_value_set_object (
+ value,
+ e_contact_list_editor_get_book (
+ E_CONTACT_LIST_EDITOR (object)));
+ return;
+
+ case PROP_CONTACT:
+ g_value_set_object (
+ value,
+ e_contact_list_editor_get_contact (
+ E_CONTACT_LIST_EDITOR (object)));
+ return;
+
+ case PROP_IS_NEW_LIST:
+ g_value_set_boolean (
+ value,
+ e_contact_list_editor_get_is_new_list (
+ E_CONTACT_LIST_EDITOR (object)));
+ return;
+
+ case PROP_EDITABLE:
+ g_value_set_boolean (
+ value,
+ e_contact_list_editor_get_editable (
+ E_CONTACT_LIST_EDITOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
-static gboolean
-email_key_pressed (GtkWidget *w, GdkEventKey *event, EContactListEditor *editor)
+static void
+contact_list_editor_dispose (GObject *object)
{
+ EContactListEditor *editor = E_CONTACT_LIST_EDITOR (object);
+ EContactListEditorPrivate *priv = editor->priv;
- if (event->keyval == GDK_comma || event->keyval == GDK_Return) {
- ENameSelectorEntry *entry = (ENameSelectorEntry *)w;
+ contact_list_editor_cancel_load (editor);
- g_signal_emit_by_name (entry, "activate", 0);
- add_email_cb (w, editor);
+ if (priv->name_selector) {
+ g_object_unref (priv->name_selector);
+ priv->name_selector = NULL;
+ }
- return TRUE;
- }
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
- return FALSE;
+/****************************** GType Callbacks ******************************/
+
+static void
+contact_list_editor_class_init (EContactListEditorClass *class)
+{
+ GObjectClass *object_class;
+ EABEditorClass *editor_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EContactListEditorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructor = contact_list_editor_constructor;
+ object_class->set_property = contact_list_editor_set_property;
+ object_class->get_property = contact_list_editor_get_property;
+ object_class->dispose = contact_list_editor_dispose;
+
+ editor_class = EAB_EDITOR_CLASS (class);
+ editor_class->show = contact_list_editor_show;
+ editor_class->close = contact_list_editor_close;
+ editor_class->raise = contact_list_editor_raise;
+ editor_class->save_contact = contact_list_editor_save_contact;
+ editor_class->is_valid = contact_list_editor_is_valid;
+ editor_class->is_changed = contact_list_editor_is_changed;
+ editor_class->get_window = contact_list_editor_get_window;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_BOOK,
+ g_param_spec_object (
+ "book",
+ _("Book"),
+ /*_( */"XXX blurb" /*)*/,
+ E_TYPE_BOOK,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CONTACT,
+ g_param_spec_object (
+ "contact",
+ _("Contact"),
+ /*_( */"XXX blurb" /*)*/,
+ E_TYPE_CONTACT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IS_NEW_LIST,
+ g_param_spec_boolean (
+ "is_new_list",
+ _("Is New List"),
+ /*_( */"XXX blurb" /*)*/,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ _("Editable"),
+ /*_( */"XXX blurb" /*)*/,
+ FALSE,
+ G_PARAM_READWRITE));
}
static void
-set_editable (EContactListEditor *editor)
+contact_list_editor_init (EContactListEditor *editor)
{
- gtk_widget_set_sensitive (editor->email_entry, editor->editable && editor->allows_contact_lists);
- gtk_widget_set_sensitive (editor->list_name_entry, editor->editable && editor->allows_contact_lists);
- gtk_widget_set_sensitive (editor->add_button, editor->editable && editor->allows_contact_lists);
- gtk_widget_set_sensitive (editor->remove_button, editor->editable && editor->allows_contact_lists);
- gtk_widget_set_sensitive (editor->select_button, editor->editable && editor->allows_contact_lists);
- gtk_widget_set_sensitive (editor->cancel_button, editor->editable && editor->allows_contact_lists);
- gtk_widget_set_sensitive (editor->visible_addrs_checkbutton, editor->editable && editor->allows_contact_lists);
+ EContactListEditorPrivate *priv;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkTreeView *view;
+ gchar *filename;
+
+ priv = E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor);
+
+ priv->editable = TRUE;
+ priv->allows_contact_lists = TRUE;
+
+ filename = g_build_filename (
+ EVOLUTION_GLADEDIR, "contact-list-editor.glade", NULL);
+ priv->xml = glade_xml_new (filename, NULL, NULL);
+ glade_xml_signal_autoconnect (priv->xml);
+ g_free (filename);
+
+ /* Embed a pointer to the EContactListEditor in the top-level
+ * widget. Signal handlers can then access the pointer from any
+ * child widget by calling contact_list_editor_extract(widget). */
+ g_object_set_data (G_OBJECT (WIDGET (DIALOG)), TOPLEVEL_KEY, editor);
+
+ view = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ priv->model = e_contact_list_model_new ();
+ gtk_tree_view_set_model (view, priv->model);
+
+ gtk_tree_selection_set_mode (
+ gtk_tree_view_get_selection (view), GTK_SELECTION_MULTIPLE);
+ gtk_tree_view_enable_model_drag_dest (
+ view, targets, G_N_ELEMENTS (targets), GDK_ACTION_LINK);
+
+ g_signal_connect (
+ priv->model, "row-deleted",
+ G_CALLBACK (contact_list_editor_row_deleted_cb), editor);
+ g_signal_connect (
+ priv->model, "row-inserted",
+ G_CALLBACK (contact_list_editor_row_inserted_cb), editor);
+
+ column = gtk_tree_view_column_new ();
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_append_column (view, column);
+
+ gtk_tree_view_column_set_cell_data_func (
+ column, renderer, (GtkTreeCellDataFunc)
+ contact_list_editor_render_destination, NULL, NULL);
+
+ priv->name_selector = e_name_selector_new ();
+
+ e_name_selector_model_add_section (
+ e_name_selector_peek_model (priv->name_selector),
+ "Members", _("_Members"), NULL);
+
+ g_signal_connect (
+ editor, "notify::book",
+ G_CALLBACK (contact_list_editor_notify_cb), NULL);
+ g_signal_connect (
+ editor, "notify::editable",
+ G_CALLBACK (contact_list_editor_notify_cb), NULL);
+
+ gtk_widget_show_all (WIDGET (DIALOG));
+
+ editor->priv = priv;
}
-/* Callback used when the editor is destroyed */
-static gint
-app_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+/***************************** Public Interface ******************************/
+
+GType
+e_contact_list_editor_get_type (void)
{
- EContactListEditor *ce;
+ static GType type = 0;
- ce = E_CONTACT_LIST_EDITOR (data);
+ if (G_UNLIKELY (type == 0))
+ type = g_type_register_static_simple (
+ EAB_TYPE_EDITOR,
+ "EContactListEditor",
+ sizeof (EContactListEditorClass),
+ (GClassInitFunc) contact_list_editor_class_init,
+ sizeof (EContactListEditor),
+ (GInstanceInitFunc) contact_list_editor_init, 0);
- /* if we're in an async call, don't allow the dialog to close */
- if (ce->in_async_call)
- return TRUE;
+ return type;
+}
- eab_editor_prompt_to_save_changes (EAB_EDITOR (ce), GTK_WINDOW (ce->app));
- return TRUE;
+static void
+contact_list_editor_destroy_notify (gpointer data,
+ GObject *where_the_object_was)
+{
+ eab_editor_remove (EAB_EDITOR (data));
}
-static gboolean
-table_drag_motion_cb (ETable *table, int row, int col,
- GdkDragContext *context,
- gint x, gint y, guint time, EContactListEditor *editor)
+EContactListEditor *
+e_contact_list_editor_new (EBook *book,
+ EContact *list_contact,
+ gboolean is_new_list,
+ gboolean editable)
{
- GList *p;
+ EContactListEditor *editor;
- for (p = context->targets; p != NULL; p = p->next) {
- char *possible_type;
+ editor = g_object_new (E_TYPE_CONTACT_LIST_EDITOR, NULL);
- possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
- if (!strcmp (possible_type, VCARD_TYPE)) {
- g_free (possible_type);
- gdk_drag_status (context, GDK_ACTION_LINK, time);
- return TRUE;
- }
+ eab_editor_add (EAB_EDITOR (editor));
+ g_object_weak_ref (
+ G_OBJECT (editor), contact_list_editor_destroy_notify, editor);
- g_free (possible_type);
- }
+ g_object_set (editor,
+ "book", book,
+ "contact", list_contact,
+ "is_new_list", is_new_list,
+ "editable", editable,
+ NULL);
- return FALSE;
+ return editor;
}
-static gboolean
-table_drag_drop_cb (ETable *table, int row, int col,
- GdkDragContext *context,
- gint x, gint y, guint time, EContactListEditor *editor)
+EBook *
+e_contact_list_editor_get_book (EContactListEditor *editor)
{
- GList *p;
+ g_return_val_if_fail (E_IS_CONTACT_LIST_EDITOR (editor), NULL);
- for (p = context->targets; p != NULL; p = p->next) {
- char *possible_type;
+ return editor->priv->book;
+}
- possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
- if (!strcmp (possible_type, VCARD_TYPE)) {
- g_free (possible_type);
- break;
- }
+void
+e_contact_list_editor_set_book (EContactListEditor *editor,
+ EBook *book)
+{
+ g_return_if_fail (E_IS_CONTACT_LIST_EDITOR (editor));
+ g_return_if_fail (E_IS_BOOK (book));
- g_free (possible_type);
- }
+ if (editor->priv->book != NULL)
+ g_object_unref (editor->priv->book);
+ editor->priv->book = g_object_ref (book);
+ editor->priv->allows_contact_lists =
+ e_book_check_static_capability (
+ editor->priv->book, "contact-lists");
- if (p) {
- gtk_drag_get_data (GTK_WIDGET (table), context,
- GDK_POINTER_TO_ATOM (p->data),
- time);
- return TRUE;
- }
+ contact_list_editor_update (editor);
- return FALSE;
+ g_object_notify (G_OBJECT (editor), "book");
}
-static void
-table_drag_data_received_cb (ETable *table, int row, int col,
- GdkDragContext *context,
- gint x, gint y,
- GtkSelectionData *selection_data,
- guint info, guint time, EContactListEditor *editor)
+EContact *
+e_contact_list_editor_get_contact (EContactListEditor *editor)
{
- GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (editor->table));
- char *target_type;
- gboolean changed = FALSE;
- gboolean handled = FALSE;
+ GtkTreeModel *model;
+ EContact *contact;
+ GtkTreeIter iter;
+ gboolean iter_valid;
+ const gchar *text;
- target_type = gdk_atom_name (selection_data->target);
+ g_return_val_if_fail (E_IS_CONTACT_LIST_EDITOR (editor), NULL);
- if (!strcmp (target_type, VCARD_TYPE)) {
+ model = editor->priv->model;
+ contact = editor->priv->contact;
- GList *contact_list = eab_contact_list_from_string ((char *)selection_data->data);
- GList *c;
+ if (contact == NULL)
+ return NULL;
- if (contact_list)
- handled = TRUE;
+ text = gtk_entry_get_text (GTK_ENTRY (WIDGET (LIST_NAME_ENTRY)));
+ if (text != NULL && *text != '\0') {
+ e_contact_set (contact, E_CONTACT_FILE_AS, (gpointer) text);
+ e_contact_set (contact, E_CONTACT_FULL_NAME, (gpointer) text);
+ }
- for (c = contact_list; c; c = c->next) {
- EContact *contact = c->data;
+ e_contact_set (contact, E_CONTACT_LOGO, NULL);
+ e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE));
- if (!e_contact_get (contact, E_CONTACT_IS_LIST)) {
- if (e_contact_get (contact, E_CONTACT_EMAIL_1)) {
- if (! contact_already_exists (E_CONTACT_LIST_MODEL (editor->model)
- , e_contact_get (contact, E_CONTACT_EMAIL_1))) {
- e_contact_list_model_add_contact (E_CONTACT_LIST_MODEL (editor->model),
- contact,
- 0 /* Hard-wired for default e-mail */);
+ e_contact_set (
+ contact, E_CONTACT_LIST_SHOW_ADDRESSES,
+ GINT_TO_POINTER (!gtk_toggle_button_get_active (
+ GTK_TOGGLE_BUTTON (WIDGET (CHECK_BUTTON)))));
- changed = TRUE;
- }
- }
- else
- g_warning ("Contact with no email-ids listed can't be added to a Contact-List");
- }
- }
- g_list_foreach (contact_list, (GFunc)g_object_unref, NULL);
- g_list_free (contact_list);
+ e_vcard_remove_attributes (E_VCARD (contact), "", EVC_EMAIL);
- /* Skip to the end of the list */
- if (adj->upper - adj->lower > adj->page_size)
- gtk_adjustment_set_value (adj, adj->upper);
+ iter_valid = gtk_tree_model_get_iter_first (model, &iter);
- if (changed) {
- editor->changed = TRUE;
- command_state_changed (editor);
- }
+ while (iter_valid) {
+ EDestination *dest;
+ EVCardAttribute *attr;
+
+ gtk_tree_model_get (model, &iter, 0, &dest, -1);
+ attr = e_vcard_attribute_new (NULL, EVC_EMAIL);
+ e_vcard_add_attribute (E_VCARD (contact), attr);
+ e_destination_export_to_vcard_attribute (dest, attr);
+ g_object_unref (dest);
+
+ iter_valid = gtk_tree_model_iter_next (model, &iter);
}
- gtk_drag_finish (context, handled, FALSE, time);
+ return contact;
}
+/* Helper for e_contact_list_editor_set_contact() */
static void
-command_state_changed (EContactListEditor *editor)
+contact_list_editor_add_destination (EVCardAttribute *attr,
+ EContactListEditor *editor)
{
- gboolean valid = eab_editor_is_valid (EAB_EDITOR (editor));
+ EDestination *destination;
+ gchar *contact_uid = NULL;
+ gint email_num = -1;
+ GList *list, *iter;
+ GList *values;
+
+ destination = e_destination_new ();
+
+ list = e_vcard_attribute_get_params (attr);
+ for (iter = list; iter; iter = iter->next) {
+ EVCardAttributeParam *param = iter->data;
+ const gchar *param_name;
+ gpointer param_data;
+
+ values = e_vcard_attribute_param_get_values (param);
+ if (values == NULL)
+ continue;
+
+ param_name = e_vcard_attribute_param_get_name (param);
+ param_data = values->data;
+
+ if (!g_ascii_strcasecmp (param_name, EVC_X_DEST_CONTACT_UID))
+ contact_uid = param_data;
+ else if (!g_ascii_strcasecmp (param_name, EVC_X_DEST_EMAIL_NUM))
+ email_num = atoi (param_data);
+ else if (!g_ascii_strcasecmp (param_name, EVC_X_DEST_NAME))
+ e_destination_set_name (destination, param_data);
+ else if (!g_ascii_strcasecmp (param_name, EVC_X_DEST_EMAIL))
+ e_destination_set_email (destination, param_data);
+ else if (!g_ascii_strcasecmp (param_name, EVC_X_DEST_HTML_MAIL))
+ e_destination_set_html_mail_pref (
+ destination,
+ !g_ascii_strcasecmp (param_data, "true"));
+ }
+
+ if (contact_uid != NULL)
+ e_destination_set_contact_uid (
+ destination, contact_uid, email_num);
- /* FIXME set the ok button to ok */
- gtk_widget_set_sensitive (editor->ok_button, valid && editor->allows_contact_lists);
- gtk_widget_set_sensitive (editor->source_menu, editor->is_new_list);
- gtk_widget_set_sensitive (glade_xml_get_widget (editor->gui, "source-label"), editor->is_new_list);
+ e_contact_list_model_add_destination (
+ E_CONTACT_LIST_MODEL (editor->priv->model), destination);
+
+ e_vcard_attribute_free (attr);
}
-static void
-extract_info(EContactListEditor *editor)
+void
+e_contact_list_editor_set_contact (EContactListEditor *editor,
+ EContact *contact)
{
- EContact *contact = editor->contact;
- if (contact) {
- int i;
- char *image_data;
- gsize image_data_len;
- char *string = gtk_editable_get_chars(GTK_EDITABLE (editor->list_name_entry), 0, -1);
-
- if (string && *string) {
- e_contact_set (contact, E_CONTACT_FILE_AS, string);
- e_contact_set (contact, E_CONTACT_FULL_NAME, string);
- }
+ EContactListEditorPrivate *priv;
- g_free (string);
+ g_return_if_fail (E_IS_CONTACT_LIST_EDITOR (editor));
+ g_return_if_fail (E_IS_CONTACT (contact));
- e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE));
- e_contact_set (contact, E_CONTACT_LIST_SHOW_ADDRESSES,
- GINT_TO_POINTER (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(editor->visible_addrs_checkbutton))));
+ priv = editor->priv;
- e_vcard_remove_attributes (E_VCARD (contact), "", EVC_EMAIL);
+ if (priv->contact != NULL)
+ g_object_unref (priv->contact);
+ priv->contact = e_contact_duplicate (contact);
- /* then refill it from the contact list model */
- for (i = 0; i < e_table_model_row_count (editor->model); i ++) {
- const EDestination *dest = e_contact_list_model_get_destination (E_CONTACT_LIST_MODEL (editor->model), i);
- EVCardAttribute *attr;
+ if (priv->contact != NULL) {
+ const gchar *file_as;
+ gboolean show_addresses;
+ GList *email_list;
- attr = e_vcard_attribute_new (NULL, EVC_EMAIL);
+ file_as = e_contact_get_const (
+ priv->contact, E_CONTACT_FILE_AS);
+ email_list = e_contact_get_attributes (
+ priv->contact, E_CONTACT_EMAIL);
+ show_addresses = GPOINTER_TO_INT (e_contact_get (
+ priv->contact, E_CONTACT_LIST_SHOW_ADDRESSES));
- e_vcard_add_attribute (E_VCARD (contact), attr);
+ if (file_as == NULL)
+ file_as = "";
- e_destination_export_to_vcard_attribute ((EDestination*)dest, attr);
- }
+ gtk_entry_set_text (
+ GTK_ENTRY (WIDGET (LIST_NAME_ENTRY)), file_as);
- if (editor->image_set
- && e_image_chooser_get_image_data (E_IMAGE_CHOOSER (editor->list_image),
- &image_data,
- &image_data_len)) {
- EContactPhoto photo;
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (WIDGET (CHECK_BUTTON)),
+ !show_addresses);
- photo.type = E_CONTACT_PHOTO_TYPE_INLINED;
- photo.data.inlined.mime_type = NULL;
- photo.data.inlined.data = (unsigned char *)image_data;
- photo.data.inlined.length = image_data_len;
+ e_contact_list_model_remove_all (
+ E_CONTACT_LIST_MODEL (priv->model));
- e_contact_set (contact, E_CONTACT_LOGO, &photo);
- g_free (image_data);
- }
- else {
- e_contact_set (contact, E_CONTACT_LOGO, NULL);
- }
+ g_list_foreach (
+ email_list, (GFunc)
+ contact_list_editor_add_destination, editor);
+ g_list_free (email_list);
}
+
+ if (priv->book != NULL) {
+ e_source_combo_box_set_active (
+ E_SOURCE_COMBO_BOX (WIDGET (SOURCE_MENU)),
+ e_book_get_source (priv->book));
+ gtk_widget_set_sensitive (
+ WIDGET (SOURCE_MENU), priv->is_new_list);
+ }
+
+ priv->changed = FALSE;
+ contact_list_editor_update (editor);
+
+ g_object_notify (G_OBJECT (editor), "contact");
}
-static void
-fill_in_info(EContactListEditor *editor)
+gboolean
+e_contact_list_editor_get_is_new_list (EContactListEditor *editor)
{
- if (editor->contact) {
- EContactPhoto *photo;
- const char *file_as;
- gboolean show_addresses = FALSE;
- GList *email_list;
- GList *iter;
+ g_return_val_if_fail (E_IS_CONTACT_LIST_EDITOR (editor), FALSE);
- file_as = e_contact_get_const (editor->contact, E_CONTACT_FILE_AS);
- email_list = e_contact_get_attributes (editor->contact, E_CONTACT_EMAIL);
- show_addresses = GPOINTER_TO_INT (e_contact_get (editor->contact, E_CONTACT_LIST_SHOW_ADDRESSES));
+ return editor->priv->is_new_list;
+}
- gtk_editable_delete_text (GTK_EDITABLE (editor->list_name_entry), 0, -1);
- if (file_as) {
- int position = 0;
+void
+e_contact_list_editor_set_is_new_list (EContactListEditor *editor,
+ gboolean is_new_list)
+{
- gtk_editable_insert_text (GTK_EDITABLE (editor->list_name_entry), file_as, strlen (file_as), &position);
- }
+ g_return_if_fail (E_IS_CONTACT_LIST_EDITOR (editor));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(editor->visible_addrs_checkbutton), !show_addresses);
-
- e_contact_list_model_remove_all (E_CONTACT_LIST_MODEL (editor->model));
-
- for (iter = email_list; iter; iter = iter->next) {
- EVCardAttribute *attr = iter->data;
- GList *p;
- EDestination *list_dest = e_destination_new ();
- char *contact_uid = NULL;
- char *email = NULL;
- char *name = NULL;
- int email_num = -1;
- gboolean html_pref = FALSE;
-
- for (p = e_vcard_attribute_get_params (attr); p; p = p->next) {
- EVCardAttributeParam *param = p->data;
- const char *param_name = e_vcard_attribute_param_get_name (param);
- if (!g_ascii_strcasecmp (param_name,
- EVC_X_DEST_CONTACT_UID)) {
- GList *v = e_vcard_attribute_param_get_values (param);
- contact_uid = v ? v->data : NULL;
- }
- else if (!g_ascii_strcasecmp (param_name,
- EVC_X_DEST_EMAIL_NUM)) {
- GList *v = e_vcard_attribute_param_get_values (param);
- email_num = v ? atoi (v->data) : -1;
- }
- else if (!g_ascii_strcasecmp (param_name,
- EVC_X_DEST_NAME)) {
- GList *v = e_vcard_attribute_param_get_values (param);
- name = v ? v->data : NULL;
- }
- else if (!g_ascii_strcasecmp (param_name,
- EVC_X_DEST_EMAIL)) {
- GList *v = e_vcard_attribute_param_get_values (param);
- email = v ? v->data : NULL;
- }
- else if (!g_ascii_strcasecmp (param_name,
- EVC_X_DEST_HTML_MAIL)) {
- GList *v = e_vcard_attribute_param_get_values (param);
- html_pref = v ? !g_ascii_strcasecmp (v->data, "true") : FALSE;
- }
- }
-
- if (contact_uid) e_destination_set_contact_uid (list_dest, contact_uid, email_num);
- if (name) e_destination_set_name (list_dest, name);
- if (email) e_destination_set_email (list_dest, email);
- e_destination_set_html_mail_pref (list_dest, html_pref);
-
- e_contact_list_model_add_destination (E_CONTACT_LIST_MODEL (editor->model), list_dest);
- }
+ editor->priv->is_new_list = is_new_list;
+ contact_list_editor_update (editor);
- g_list_foreach (email_list, (GFunc) e_vcard_attribute_free, NULL);
- g_list_free (email_list);
+ g_object_notify (G_OBJECT (editor), "is_new_list");
+}
- photo = e_contact_get (editor->contact, E_CONTACT_LOGO);
- if (photo && photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
- e_image_chooser_set_image_data (E_IMAGE_CHOOSER (editor->list_image), (char *)photo->data.inlined.data, photo->data.inlined.length);
- e_contact_photo_free (photo);
- }
- }
+gboolean
+e_contact_list_editor_get_editable (EContactListEditor *editor)
+{
+ g_return_val_if_fail (E_IS_CONTACT_LIST_EDITOR (editor), FALSE);
- if (editor->book) {
- e_source_combo_box_set_active (
- E_SOURCE_COMBO_BOX (editor->source_menu),
- e_book_get_source (editor->book));
- gtk_widget_set_sensitive (editor->source_menu, editor->is_new_list);
- gtk_widget_set_sensitive (glade_xml_get_widget (editor->gui, "source-label"), editor->is_new_list);
- }
+ return editor->priv->editable;
+}
+
+void
+e_contact_list_editor_set_editable (EContactListEditor *editor,
+ gboolean editable)
+{
+ g_return_if_fail (E_IS_CONTACT_LIST_EDITOR (editor));
+
+ editor->priv->editable = editable;
+ contact_list_editor_update (editor);
+
+ g_object_notify (G_OBJECT (editor), "editable");
}
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.etspec b/addressbook/gui/contact-list-editor/e-contact-list-editor.etspec
deleted file mode 100644
index f4337c3f90..0000000000
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.etspec
+++ /dev/null
@@ -1,7 +0,0 @@
-<ETableSpecification no-headers="true" cursor-mode="line" selection-mode="multiple">
-<ETableColumn model_col= "0" _title="Contact" expansion="1.0" minimum_width="20" resizable="true" cell="string" compare="collate" />
- <ETableState>
- <column source="0"/>
- <grouping> </grouping>
- </ETableState>
-</ETableSpecification>
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.h b/addressbook/gui/contact-list-editor/e-contact-list-editor.h
index 00fb30fae1..41b6078f67 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.h
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.h
@@ -17,13 +17,13 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
#ifndef __E_CONTACT_LIST_EDITOR_H__
#define __E_CONTACT_LIST_EDITOR_H__
#include <libgnomeui/gnome-app.h>
#include <libgnomeui/gnome-app-helper.h>
#include <glade/glade.h>
-#include <table/e-table-model.h>
#include <libedataserverui/e-name-selector.h>
#include "addressbook/gui/contact-editor/eab-editor.h"
@@ -32,66 +32,34 @@
#include <libebook/e-contact.h>
#include <libebook/e-destination.h>
-G_BEGIN_DECLS
+#define E_TYPE_CONTACT_LIST_EDITOR \
+ (e_contact_list_editor_get_type ())
+#define E_CONTACT_LIST_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditor))
+#define E_CONTACT_LIST_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditorClass))
+#define E_IS_CONTACT_LIST_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR))
+#define E_IS_CONTACT_LIST_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR))
+#define E_CONTACT_LIST_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditorClass))
-#define E_TYPE_CONTACT_LIST_EDITOR (e_contact_list_editor_get_type ())
-#define E_CONTACT_LIST_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditor))
-#define E_CONTACT_LIST_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditorClass))
-#define E_IS_CONTACT_LIST_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT_LIST_EDITOR))
-#define E_IS_CONTACT_LIST_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_CONTACT_LIST_EDITOR))
+G_BEGIN_DECLS
-typedef struct _EContactListEditor EContactListEditor;
-typedef struct _EContactListEditorClass EContactListEditorClass;
+typedef struct _EContactListEditor EContactListEditor;
+typedef struct _EContactListEditorClass EContactListEditorClass;
+typedef struct _EContactListEditorPrivate EContactListEditorPrivate;
struct _EContactListEditor
{
EABEditor parent;
-
- /* item specific fields */
- EBook *book;
-
- EContact *contact;
-
- GladeXML *gui;
- GtkWidget *app;
-
- GtkWidget *table;
- ETableModel *model;
- GtkWidget *email_entry;
- GtkWidget *list_name_entry;
- GtkWidget *add_button;
- GtkWidget *remove_button;
- GtkWidget *select_button;
- GtkWidget *list_image_button;
- GtkWidget *visible_addrs_checkbutton;
- GtkWidget *list_image;
- GtkWidget *source_menu;
- GtkWidget *ok_button;
- GtkWidget *cancel_button;
-
- ENameSelector *name_selector;
-
- /* Whether we are editing a new contact or an existing one */
- guint is_new_list : 1;
-
- /* Whether the image chooser widget has been changed. */
- guint image_set : 1;
-
- /* Whether the contact has been changed since bringing up the contact editor */
- guint changed : 1;
-
- /* Whether the contact editor will accept modifications */
- guint editable : 1;
-
- /* Whether the target book accepts storing of contact lists */
- guint allows_contact_lists : 1;
-
- /* Whether an async wombat call is in progress */
- guint in_async_call : 1;
-
- /* ID for async load_source call */
- guint load_source_id;
- EBook *load_book;
+ EContactListEditorPrivate *priv;
};
struct _EContactListEditorClass
@@ -99,15 +67,31 @@ struct _EContactListEditorClass
EABEditorClass parent_class;
};
-EContactListEditor *e_contact_list_editor_new (EBook *book,
- EContact *list_contact,
- gboolean is_new_list,
- gboolean editable);
-GType e_contact_list_editor_get_type (void);
-
-gboolean e_contact_list_editor_request_close_all (void);
+GType e_contact_list_editor_get_type (void);
+EContactListEditor * e_contact_list_editor_new (EBook *book,
+ EContact *list_contact,
+ gboolean is_new_list,
+ gboolean editable);
+EBook * e_contact_list_editor_get_book (EContactListEditor *editor);
+void e_contact_list_editor_set_book (EContactListEditor *editor,
+ EBook *book);
+EContact * e_contact_list_editor_get_contact
+ (EContactListEditor *editor);
+void e_contact_list_editor_set_contact
+ (EContactListEditor *editor,
+ EContact *contact);
+gboolean e_contact_list_editor_get_is_new_list
+ (EContactListEditor *editor);
+void e_contact_list_editor_set_is_new_list
+ (EContactListEditor *editor,
+ gboolean is_new_list);
+gboolean e_contact_list_editor_get_editable
+ (EContactListEditor *editor);
+void e_contact_list_editor_set_editable
+ (EContactListEditor *editor,
+ gboolean editable);
+gboolean e_contact_list_editor_request_close_all (void);
G_END_DECLS
-
#endif /* __E_CONTACT_LIST_EDITOR_H__ */
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-model.c b/addressbook/gui/contact-list-editor/e-contact-list-model.c
index 767e461d87..d596919481 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-model.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-model.c
@@ -2,283 +2,198 @@
#include <config.h>
#include <string.h>
+
#include "e-contact-list-model.h"
#include "e-util/e-error.h"
-#include <gtk/gtkmessagedialog.h>
-#define PARENT_TYPE e_table_model_get_type()
-static ETableModelClass *parent_class;
-
-#define COLS 1
-
-/* This function returns the number of columns in our ETableModel. */
-static int
-contact_list_col_count (ETableModel *etc)
-{
- return COLS;
-}
-
-/* This function returns the number of rows in our ETableModel. */
-static int
-contact_list_row_count (ETableModel *etc)
-{
- EContactListModel *model = E_CONTACT_LIST_MODEL (etc);
- return model->data_count;
-}
-
-/* This function returns the value at a particular point in our ETableModel. */
-static void *
-contact_list_value_at (ETableModel *etc, int col, int row)
-{
- EContactListModel *model = E_CONTACT_LIST_MODEL (etc);
-
- return (void *) e_destination_get_textrep (model->data[row], TRUE);
-}
-
-/* This function sets the value at a particular point in our ETableModel. */
-static void
-contact_list_set_value_at (ETableModel *etc, int col, int row, const void *val)
-{
- /* nothing */
-}
+static gpointer parent_class;
-/* This function returns whether a particular cell is editable. */
static gboolean
-contact_list_is_cell_editable (ETableModel *etc, int col, int row)
+contact_list_get_iter (EContactListModel *model,
+ GtkTreeIter *iter,
+ gint row)
{
- return FALSE;
-}
-
-/* This function duplicates the value passed to it. */
-static void *
-contact_list_duplicate_value (ETableModel *etc, int col, const void *value)
-{
- return g_strdup(value);
-}
+ GtkTreePath *path;
+ gboolean iter_valid;
-/* This function frees the value passed to it. */
-static void
-contact_list_free_value (ETableModel *etc, int col, void *value)
-{
- g_free(value);
-}
+ path = gtk_tree_path_new_from_indices (row, -1);
+ iter_valid = gtk_tree_model_get_iter (
+ GTK_TREE_MODEL (model), iter, path);
+ gtk_tree_path_free (path);
-static void *
-contact_list_initialize_value (ETableModel *etc, int col)
-{
- return g_strdup("");
+ return iter_valid;
}
-static gboolean
-contact_list_value_is_empty (ETableModel *etc, int col, const void *value)
+static GObject *
+contact_list_model_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
{
- return !(value && *(char *)value);
-}
+ GObject *object;
+ GType types[1];
-static char *
-contact_list_value_to_string (ETableModel *etc, int col, const void *value)
-{
- return g_strdup(value);
-}
+ types[0] = E_TYPE_DESTINATION;
-static void
-contact_list_model_dispose (GObject *o)
-{
- EContactListModel *model = E_CONTACT_LIST_MODEL (o);
- int i;
-
- if (model->data != NULL) {
- for (i = 0; i < model->data_count; i ++) {
- g_object_unref (model->data[i]);
- }
- g_free (model->data);
- model->data = NULL;
- }
+ /* Chain up to parent's constructor() method. */
+ object = G_OBJECT_CLASS (parent_class)->constructor (
+ type, n_construct_properties, construct_properties);
- model->data_count = 0;
- model->data_alloc = 0;
+ gtk_list_store_set_column_types (
+ GTK_LIST_STORE (object), G_N_ELEMENTS (types), types);
- (* G_OBJECT_CLASS (parent_class)->dispose) (o);
+ return object;
}
static void
-e_contact_list_model_class_init (GObjectClass *object_class)
+contact_list_model_class_init (EContactListModelClass *class)
{
- ETableModelClass *model_class = (ETableModelClass *) object_class;
-
- parent_class = g_type_class_ref (PARENT_TYPE);
-
- object_class->dispose = contact_list_model_dispose;
-
- model_class->column_count = contact_list_col_count;
- model_class->row_count = contact_list_row_count;
- model_class->value_at = contact_list_value_at;
- model_class->set_value_at = contact_list_set_value_at;
- model_class->is_cell_editable = contact_list_is_cell_editable;
- model_class->duplicate_value = contact_list_duplicate_value;
- model_class->free_value = contact_list_free_value;
- model_class->initialize_value = contact_list_initialize_value;
- model_class->value_is_empty = contact_list_value_is_empty;
- model_class->value_to_string = contact_list_value_to_string;
-}
+ GObjectClass *object_class;
-static void
-e_contact_list_model_init (GObject *object)
-{
- EContactListModel *model = E_CONTACT_LIST_MODEL(object);
+ parent_class = g_type_class_peek_parent (class);
- model->data_alloc = 10;
- model->data_count = 0;
- model->data = g_new (EDestination*, model->data_alloc);
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructor = contact_list_model_constructor;
}
GType
e_contact_list_model_get_type (void)
{
- static GType cle_type = 0;
+ static GType type = 0;
- if (!cle_type) {
- static const GTypeInfo cle_info = {
+ if (G_UNLIKELY (type == 0))
+ type = g_type_register_static_simple (
+ GTK_TYPE_LIST_STORE,
+ "EContactListModel",
sizeof (EContactListModelClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) e_contact_list_model_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
+ (GClassInitFunc) contact_list_model_class_init,
sizeof (EContactListModel),
- 0, /* n_preallocs */
- (GInstanceInitFunc) e_contact_list_model_init,
- };
-
- cle_type = g_type_register_static (E_TABLE_MODEL_TYPE, "EContactListModel", &cle_info, 0);
- }
+ (GInstanceInitFunc) NULL, 0);
- return cle_type;
+ return type;
}
-void
-e_contact_list_model_construct (EContactListModel *model)
+GtkTreeModel *
+e_contact_list_model_new (void)
{
+ return g_object_new (E_TYPE_CONTACT_LIST_MODEL, NULL);
}
-ETableModel *
-e_contact_list_model_new (void)
+gboolean
+e_contact_list_model_has_email (EContactListModel *model,
+ const gchar *email)
{
- EContactListModel *model;
+ GtkTreeIter iter;
+ gboolean iter_valid;
+ gboolean has_email = FALSE;
+
+ g_return_val_if_fail (E_IS_CONTACT_LIST_MODEL (model), FALSE);
+ g_return_val_if_fail (email != NULL, FALSE);
- model = g_object_new (E_TYPE_CONTACT_LIST_MODEL, NULL);
+ iter_valid = gtk_tree_model_get_iter_first (
+ GTK_TREE_MODEL (model), &iter);
- e_contact_list_model_construct (model);
+ while (!has_email && iter_valid) {
+ EDestination *destination;
+ const gchar *textrep;
- return E_TABLE_MODEL(model);
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), &iter, 0, &destination, -1);
+ textrep = e_destination_get_textrep (destination, TRUE);
+ has_email = (strcmp (email, textrep) == 0);
+ g_object_unref (destination);
+
+ iter_valid = gtk_tree_model_iter_next (
+ GTK_TREE_MODEL (model), &iter);
+ }
+
+ return has_email;
}
void
-e_contact_list_model_add_destination (EContactListModel *model, EDestination *dest)
+e_contact_list_model_add_destination (EContactListModel *model,
+ EDestination *destination)
{
- g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
- g_return_if_fail (E_IS_DESTINATION (dest));
+ GtkTreeIter iter;
- e_table_model_pre_change (E_TABLE_MODEL (model));
-
- if (model->data_count + 1 >= model->data_alloc) {
- model->data_alloc *= 2;
- model->data = g_renew (EDestination*, model->data, model->data_alloc);
- }
-
- model->data[model->data_count ++] = dest;
- g_object_ref (dest);
+ g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
+ g_return_if_fail (E_IS_DESTINATION (destination));
- e_table_model_row_inserted (E_TABLE_MODEL (model), model->data_count - 1);
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, destination, -1);
}
void
e_contact_list_model_add_email (EContactListModel *model,
- const char *email)
+ const gchar *email)
{
- EDestination *new_dest;
- char *list_email;
- int row;
- int row_count;
+ const gchar *tag = "addressbook:ask-list-add-exists";
+ EDestination *destination;
g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
g_return_if_fail (email != NULL);
- row_count = e_table_model_row_count (E_TABLE_MODEL (model));
+ if (e_contact_list_model_has_email (model, email))
+ if (e_error_run (NULL, tag, email) != GTK_RESPONSE_YES)
+ return;
- for (row = 0; row < row_count; row++) {
- list_email = (char *) e_table_model_value_at (E_TABLE_MODEL (model), 1, row);
-
- if (strcmp (list_email, email) == 0) {
- if (e_error_run (NULL, "addressbook:ask-list-add-exists",
- email) != GTK_RESPONSE_YES)
- return;
- break;
- }
- }
-
- new_dest = e_destination_new ();
- e_destination_set_email (new_dest, email);
-
- e_contact_list_model_add_destination (model, new_dest);
+ destination = e_destination_new ();
+ e_destination_set_email (destination, email);
+ e_contact_list_model_add_destination (model, destination);
}
void
e_contact_list_model_add_contact (EContactListModel *model,
- EContact *contact,
- int email_num)
+ EContact *contact,
+ gint email_num)
{
- EDestination *new_dest;
+ EDestination *destination;
g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
g_return_if_fail (E_IS_CONTACT (contact));
- new_dest = e_destination_new ();
- e_destination_set_contact (new_dest, contact, email_num);
-
- e_contact_list_model_add_destination (model, new_dest);
+ destination = e_destination_new ();
+ e_destination_set_contact (destination, contact, email_num);
+ e_contact_list_model_add_destination (model, destination);
}
void
-e_contact_list_model_remove_row (EContactListModel *model, int row)
+e_contact_list_model_remove_row (EContactListModel *model,
+ gint row)
{
- g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
- g_return_if_fail (0 <= row && row < model->data_count);
+ GtkTreeIter iter;
+ gboolean iter_valid;
- e_table_model_pre_change (E_TABLE_MODEL (model));
+ g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
- g_object_unref (model->data[row]);
- memmove (model->data + row, model->data + row + 1, sizeof (EDestination*) * (model->data_count - row - 1));
- model->data_count --;
+ iter_valid = contact_list_get_iter (model, &iter, row);
+ g_return_if_fail (iter_valid);
- e_table_model_row_deleted (E_TABLE_MODEL (model), row);
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
}
void
e_contact_list_model_remove_all (EContactListModel *model)
{
- int i;
-
g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
- e_table_model_pre_change (E_TABLE_MODEL (model));
-
- for (i = 0; i < model->data_count; i ++) {
- g_object_unref (model->data[i]);
- model->data[i] = NULL;
- }
-
- model->data_count = 0;
-
- e_table_model_changed (E_TABLE_MODEL (model));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
}
-
-const EDestination *
-e_contact_list_model_get_destination (EContactListModel *model, int row)
+EDestination *
+e_contact_list_model_get_destination (EContactListModel *model,
+ gint row)
{
+ EDestination *destination;
+ GtkTreeIter iter;
+ gboolean iter_valid;
+
g_return_val_if_fail (E_IS_CONTACT_LIST_MODEL (model), NULL);
- g_return_val_if_fail (0 <= row && row < model->data_count, NULL);
- return model->data[row];
+ iter_valid = contact_list_get_iter (model, &iter, row);
+ g_return_val_if_fail (iter_valid, NULL);
+
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), &iter, 0, &destination, -1);
+
+ return destination;
}
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-model.h b/addressbook/gui/contact-list-editor/e-contact-list-model.h
index 55fe251ad2..68de720286 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-model.h
+++ b/addressbook/gui/contact-list-editor/e-contact-list-model.h
@@ -1,48 +1,62 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
#ifndef _E_CONTACT_LIST_MODEL_H_
#define _E_CONTACT_LIST_MODEL_H_
-#include <table/e-table-model.h>
+#include <gtk/gtk.h>
#include <libebook/e-contact.h>
#include <libebook/e-destination.h>
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_CONTACT_LIST_MODEL \
+ (e_contact_list_model_get_type ())
+#define E_CONTACT_LIST_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CONTACT_LIST_MODEL, EContactListModel))
+#define E_CONTACT_LIST_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CONTACT_LIST_MODEL, EContactListModelClass))
+#define E_IS_CONTACT_LIST_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CONTACT_LIST_MODEL))
+#define E_IS_CONTACT_LIST_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CONTACT_LIST_MODEL))
+#define E_CONTACT_LIST_MODEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CONTACT_LIST_MODEL, EContactListModelClass))
-#define E_TYPE_CONTACT_LIST_MODEL (e_contact_list_model_get_type ())
-#define E_CONTACT_LIST_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_CONTACT_LIST_MODEL, EContactListModel))
-#define E_CONTACT_LIST_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_CONTACT_LIST_MODEL, EContactListModelClass))
-#define E_IS_CONTACT_LIST_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_CONTACT_LIST_MODEL))
-#define E_IS_CONTACT_LIST_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_CONTACT_LIST_MODEL))
+G_BEGIN_DECLS
typedef struct _EContactListModel EContactListModel;
typedef struct _EContactListModelClass EContactListModelClass;
struct _EContactListModel {
- ETableModel parent;
-
- EDestination **data;
- int data_count;
- int data_alloc;
+ GtkListStore parent;
};
-
struct _EContactListModelClass {
- ETableModelClass parent_class;
+ GtkListStoreClass parent_class;
};
-
-GType e_contact_list_model_get_type (void);
-void e_contact_list_model_construct (EContactListModel *model);
-ETableModel *e_contact_list_model_new (void);
-
-void e_contact_list_model_add_destination (EContactListModel *model, EDestination *dest);
-void e_contact_list_model_add_email (EContactListModel *model, const char *email);
-void e_contact_list_model_add_contact (EContactListModel *model, EContact *contact, int email_num);
-
-void e_contact_list_model_remove_row (EContactListModel *model, int row);
-void e_contact_list_model_remove_all (EContactListModel *model);
-
-const EDestination *e_contact_list_model_get_destination (EContactListModel *model, int row);
+GType e_contact_list_model_get_type (void);
+GtkTreeModel * e_contact_list_model_new (void);
+gboolean e_contact_list_model_has_email (EContactListModel *model,
+ const gchar *email);
+void e_contact_list_model_add_destination
+ (EContactListModel *model,
+ EDestination *dest);
+void e_contact_list_model_add_email (EContactListModel *model,
+ const gchar *email);
+void e_contact_list_model_add_contact(EContactListModel *model,
+ EContact *contact,
+ gint email_num);
+void e_contact_list_model_remove_row (EContactListModel *model,
+ gint row);
+void e_contact_list_model_remove_all (EContactListModel *model);
+EDestination * e_contact_list_model_get_destination
+ (EContactListModel *model,
+ gint row);
G_END_DECLS